diff --git a/.gitignore b/.gitignore index 7351463bdd..a7fde6bd31 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,9 @@ Products *.pbxuser *.perspectivev3 *.mode1v3 +xcuserdata .DS_Store +config src/Three20/*.h src/Three20Core/*.h src/Three20Network/*.h @@ -13,3 +15,11 @@ src/Three20Style/*.h src/Three20UICommon/*.h src/Three20UINavigator/*.h src/Three20UI/*.h +extensions/ + +*.pyc +Docs + +# we don't support xcworkspaces for single projects. Use Three20.xcworkspace instead +*.xcworkspace +!Three20.xcworkspace diff --git a/AUTHORS b/AUTHORS index 7ce7c897c8..d387e31c3d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,8 +7,12 @@ Joe Hewitt github.com/joehewitt @joehewitt Current Maintainers ------------------- -Owen Yamauchi github.com/oyamauchi oyamauchi@facebook.com -Jeff Verkoeyen github.com/jverkoey jverkoey@gmail.com +Owen Yamauchi github.com/oyamauchi oyamauchi@facebook.com +Jeff Verkoeyen github.com/jverkoey jverkoey@gmail.com +John Wang github.com/jwang jwang392@gmail.com +Stephan Diederich github.com/diederich stephan.diederich@googlemail.com +Adar Porat github.com/aporat adar.porat@gmail.com +Tobias Klonk github.com/tonklon me@tonklon.com Contributors ------------ @@ -26,5 +30,11 @@ Petr Reichl github.com/meap Pavel Repin github.com/paxan Skotch Vail github.com/skotchvail Brian Chapados github.com/chapados +Enormego github.com/enormego/EGOTableViewPullRefresh + - Drag-to-refresh header +David Morford github.com/davidmorford/UXKit + - Inspiration for the New Three20 project structure. +Chih-Wei Lee github.com/dlackty + - iPad improvements Brandon Walkin diff --git a/Articles/AboutModules.mdown b/Articles/AboutModules.mdown deleted file mode 100644 index 26d37806fb..0000000000 --- a/Articles/AboutModules.mdown +++ /dev/null @@ -1,273 +0,0 @@ - -The Three20 Modularized Build System -==================================== - -First, some history. - -Three20 was originally built by Joe Hewitt as part of the Facebook for iPhone app. Since -then, the library has gone on to be used by countless developers in their efforts to -create amazing apps for the App Store. The Three20 community itself has blossomed to -include more than 800 developers in the Google Group and more than 2000 watchers on GitHub. - -The library originally debuted with a number of powerful features, including the style system, -rethought table controllers and data sources, and a navigator with persistence. As time -progressed, more features were added to the library, and Three20 continued to prove to be a -versatile tool in many iPhone developers' arsenals on the App Store battlefield. Debug -utilities, JSON and XML support, and a growing set of sample applications and tutorials -were introduced over time. - -But as Three20 grew, it began to experience growing pains. Many developers derided the -lack of documentation and comprehensive unit tests. More pointed out that some of the new -features being included in the Three20 library weren't critical for their needs, or -that they were already including some components, such as JSON parsers, in their own -projects. And some argued that if outside libraries were going to be included in Three20, -then the developer should still have a choice as to which library they actually want to use. - -All of these requests were incredibly hard to satisfy given the way the Three20 library was -originally designed: **as a single library**. - -### The Conceptual Split - -In late 2009, when Jeff took over Three20, he spent a fair amount of time absorbing the -framework. He determined that there were four primary aspects to Three20: Core, Network, -Style, and UI. Each was dependent upon the previous aspect in the list, and collectively they -formed the Three20 library. Over the next five months a great deal of time was invested in -drawing lines in the sand in order to create a conceptual divide between the four aspects. - -### Building the New Three20 - -With the lines in the sand drawn, it became much easier to begin tearing apart -interdependencies between the four components of Three20. Two new libraries for Core and Network -were then built separately from the rest of the source. For the first time since Three20 -was introduced, it was possible to use aspects of Three20 **without pulling in the entire library**. - -But a limitation with this system was quickly brought to light. If we were to -continue building separate libraries for each subsection of Three20, then the libraries -would somehow need to share common configuration properties. - -### Enter UXKit - -David Morford built the UXKit project in late 2009 as a fork of Three20 with significant project -layout and organizational changes, and then released the code under the Apache 2.0 license. -Thanks to this generous contribution to the open source community, there was a working -example of a way to build a set of modular libraries that all shared common configurations -using .xcconfig files. - -Three20's new modular system is based on this design. - -Modular Three20 ---------------- - -Three20 is now split into a set of libraries that, brought together, compose the original -Three20 library. The libraries are listed below for your information (kept up-to-date in the -DependencyCharts.mdown article): - - ------------------------------------------ - | UI | - ------------------------------------------ - | UINavigator | | Style | - |--------------| |------------| - | UICommon | | Network | - ------------------------------------------ - | Core | - ------------------------------------------ - -And then there are the extensions. - - ------------- ------------ - | extJSON | | extXML | - ------------- ------------ - ---------------------------- - | Network | - ---------------------------- - | Core | - ---------------------------- - -If the diagrams aren't particularly clear to you, they're drawn as though the libs -were structured like a building; the lowest levels are the foundation and -the upper levels depend on the lower levels for support. Each "box" in the diagram -is a library. - - -What's Changed --------------- - -A lot has changed in order to make Three20 a modular library. Many changes will -undoubtedly spur debate, but from a high perspective this new modular project structure -is going to be the way Three20 progresses into the future. - - -### Source Code Layout - -**Who does this impact?** Anyone who has modified or wishes to modify the internals -of Three20. - -#### The Old - - samples/ <- All sample code - src/Three20/ <- All header files for Three20 - src/ <- All implementation files for Three20 - src/Three20.bundle <- The Three20 bundle - src/Three20.xcodeproj <- The project for the Three20 library - -#### The New - - Articles/ <- Articles, such as this one, discussing Three20 - Build/ <- All build output, including Products - Build/Products/ <- The products of all libs and samples - samples/ <- All sample code - src/ <- All project directories (see below) - src/common/ <- Common files used by most libs - src/scripts/ <- Common scripts used by most libs - - src/Three20.bundle <- The Three20 bundle - src/Three20.xcodeproj <- The Legacy project for the Three20 library - -A project directory looks as follows: - - Three20UI/Configurations/ <- Project-specific configurations - Three20UI/Headers/ <- The lib's headers - Three20UI/Sources/ <- The lib's implementation files - Three20UI/Three20UI.xcodeproj <- The lib project - Three20UI/UnitTests/ <- The lib's unit tests and related resources - -#### Rationale behind the new project structure. - -The biggest change of note is the movement of all source files to their specific -library's sub-directories. The reasoning for this is that, by separating the code -at some high level, it will be much easier to pull out a component of Three20 and -use it by itself. - -Another notable change is the unification of the build output into a single -directory. This was done because of the way that headers are now handled; -all headers are copied into the `Build/Products/three20/` directory. Go check it out right now -if you've already built any of the new libs. This makes it possible to define the -noted directory as the "header search path" for all libraries instead of adding -each project's `Headers` directory to the header search path. - -A nice side effect of having a unified build directory is that it makes it possible -to delete all build output by deleting a single directory. When hacking on -Three20 it can often be necessary to start from a clean slate in order to ensure -that the library isn't being built with phantom files. - - -### Imports - -**Who does this impact?** Anyone who has imported headers other than -`Three20/Three20.h` in their projects. - -When Three20 was built as a single library, all header files were in the src/Three20 -directory. This made importing files as simple as - - #import "Three20/TTNavigator.h" - -Now that all headers are placed in their respective library's `Headers/` directory, the -above import is no longer how you will import Three20 headers. - -Instead, you need to be aware of which library the header is in. In the above example, -we were importing `TTNavigator.h`, which resides in the `Three20UINavigator` library, -so we'd now use - - #import "Three20UINavigator/TTNavigator.h" - -This follows for every library in the new Three20. - -You will also need to update your header search path to use `Build/Products/three20` instead -of `src/Three20` (see ***Migrating to the New Three20***). - - -Backwards-Compatibility ------------------------ - -The new Three20 provides backwards-compatibility with projects that still use the -single library design. This has been accomplished by maintaining the paths of the -old project and bundle, and making the old Three20 project (referred to as the -"legacy" project/lib) link to the new Three20 libs. A script has been added to the legacy -lib that copies all headers into their old location in the event that a project -directly references any headers. - -A fair effort has been placed in making it likely that when you pull the latest -Three20, you'll still be able to build your project. However, no endeavor of this -magnitude is likely to go off without a hiccup, so if you have any questions please -feel free to email Jeff (jverkoey@gmail.com) or the Google news group -(three20@googlegroups.com). - - -Migrating to the New Three20 ----------------------------- - -If you use the old Three20 library, migrating to the new one is a fairly simple process. -**Estimated time: 5 minutes.** - -1. Delete the old `Three20.xcodeproj` reference from your project. -2. Drag `Three20.xcodeproj` from `three20/src/Three20/` into your project. -3. Open the Three20 Xcode Project that you just added to your app and expand the "Dependencies" - group. Select all of the projects listed there and drag them to your app as well. You should - now have the following list of Three20 projects added to your app: - * Three20Core - * Three20Network - * Three20Style - * Three20UICommon - * Three20UINavigator - * Three20UI - * Three20 -3. Select all of the `xcodeproj` items in Xcode that you just created and look at - the "Detail" tab. -4. Ensure that the checkbox beside each `lib` file is checked. If not, check it. - Alternatively, you can expand each Three20 project and drag the `.a` file to your - target's "Link Binary With Libraries" action. -5. In Xcode's app menu, click `Project => Edit Active Target`. -6. Click the "General" tab. -7. Click the plus button below "Direct Dependencies" and add `Three20`. -8. Click the "Build" tab. -9. Add `../three20/Build/Products/three20` to "Header Search Paths" and remove - `../three20/src/` - **Note:** Change the relative path (`../`) accordingly. -10. Hit build. You will now be building your app with the new modular libs. - - -Troubleshooting ---------------- - -This is a modest attempt at covering the bases with respect to troubleshooting, but is -by no means guaranteed to be comprehensive. - -### Where'd the XML parser go? - -If you were using `TTXMLParser` or `TTURLXMLResponse`, you will now have to -include the `extThree20XML` library into your project and include -`extThree20XML/extThree20XML.h`. This will only work once you've -migrated your project (see ***Migrating to the New Three20***). - -### Where'd the JSON parser go? - -If you were using `TTURLJSONResponse`, you will now have to include the -`extThree20JSON` library into your project and include -`extThree20JSON/extThree20JSON.h`. This will only work once you've -migrated your project (see ***Migrating to the New Three20***). - -You have a choice of JSON parsers to use when adding the library to your -project. There will be two targets, one for SBJSON and another for YAJL. Select one -or the other to link to as a library, but **not both**. - -### I'm getting a "No such file or directory" error for a Three20 import. - -All headers are now grouped by the library in which they reside. This means that if -you're importing a header from the UINavigator library, that you'll need to use -`Three20UINavigator/` instead of `Three20/`. If you're not sure which library a particular -header resides in, just do a `find src -name SomeHeader.h` to find which library it's -in. - -### I'm getting a linker error when I build my app. - -Double-check and triple-check that you're actually linking all of the necessary -libraries in your target. Look at the "Link Binary with Libraries" section and ensure -that everything is as you expect it to be. - -Things to note: the new Three20 lib is actually a composite lib composed of `Core`, -`Network`, `Style`, `UICommon`, `UINavigator`, and `UI`. If you are linking to the -Three20 lib, you don't need to link to any of the listed libs again. Notice that none -of the extensions are included in the composite lib. - -This article written by: --- Jeff Verkoeyen (@featherless) *Created on May 2, 2010.* diff --git a/Articles/DependencyCharts.mdown b/Articles/DependencyCharts.mdown deleted file mode 100644 index 7b0fcf3673..0000000000 --- a/Articles/DependencyCharts.mdown +++ /dev/null @@ -1,49 +0,0 @@ - -Dependency Charts -================= - -Three20 -------- - - ------------------------------------------ - | UI | - ------------------------------------------ - | UINavigator | | Style | - |--------------| |------------| - | UICommon | | Network | - ------------------------------------------ - | Core | - ------------------------------------------ - -Extensions ----------- - -Extensions are denoted by the `ext` prefix. - - ------------- ------------ - | extJSON | | extXML | - ------------- ------------ - ---------------------------- - | Network | - ---------------------------- - | Core | - ---------------------------- - - ---------------------------- - | extCSSStyle | - ---------------------------- - ---------------------------- - | Style | - ---------------------------- - | Network | - ---------------------------- - | Core | - ---------------------------- - -If the diagrams aren't particularly clear to you, they're drawn as though the libs -were structured like a building; the lowest levels are the foundation and -the upper levels depend on the lower levels for support. Each "box" in the diagram -is a library. - -This article written by: --- Jeff Verkoeyen (@featherless) *Created on May 2, 2010.* diff --git a/Articles/Network/Etag.mdown b/Articles/Network/Etag.mdown deleted file mode 100644 index 5d71d5e31c..0000000000 --- a/Articles/Network/Etag.mdown +++ /dev/null @@ -1,32 +0,0 @@ - -Etag Cache Support -================== - -First order of business, read up on [Etags](http://en.wikipedia.org/wiki/HTTP_ETag). - -In summary: - -> An ETag (entity tag) is part of HTTP, the protocol for the World Wide Web. It is -> a response header that may be returned by an HTTP/1.1 compliant web server and is -> used to determine change in content at a given URL. When a new HTTP response -> contains the same ETag as an older HTTP response, the client can conclude that the -> content is the same without further downloading. The header is useful for -> intermediary devices that perform caching, as well as for client web browsers that -> cache results. How the server generates an ETag is entirely up to the server. One -> possible method of generating the ETag is based on the last modified time of the -> file and the size of the file, another is using a checksum. - -Three20 supports Etag internally with the `TTURLRequestCachePolicyEtag` cache policy. By -adding it to your request's cache policy, Three20 will follow the procedure required to -support Etags. - - request.cachePolicy = cachePolicy | TTURLRequestCachePolicyEtag; - -See `TTFacebook` for an example. - -The Three20 Etag procedure is as follows: - -* When a request is made, check whether we are using the Etag cache policy. -* If we are, make the request and provide the cached Etag, if one exists. -* Upon receipt of a 200 response, cache the Etag key if present. -* Upon receipt of a 304 response, load the data from the cache. diff --git a/Articles/UI/GarbageCollection.mdown b/Articles/UI/GarbageCollection.mdown deleted file mode 100644 index 92f6031367..0000000000 --- a/Articles/UI/GarbageCollection.mdown +++ /dev/null @@ -1,66 +0,0 @@ - -View Controller Garbage Collection -================================== - -Due to use of TTSwapMethods in Three20UI and Apple's denial of its use, we have had to remove -the method swizzling of dealloc in `UIViewController`. The dealloc method was swapped because -we had needed to override the default dealloc for all `UIViewController` instances. This made it -possible to do some necessary cleanup when a controller was released. - -Now that we can't override `UIViewController`'s dealloc globally, we need a more creative solution. -The solution proposed here is one that uses a lightweight form of garbage collection to provide -similar functionality. - -How it works ------------- - -To begin, `TTViewController` has now been split into a more base implementation, -`TTBaseViewController`, which can be found in UICommon. This base view controller does what -the old method swizzling did in the dealloc, but now it's a safer implementation due to -proper inheritance. - -Some functionality of TTViewController has also been placed in the new `TTNavigatorViewController`, -which inherits from `TTBaseController`. `TTViewController` itself inherits from -`TTNavigatorViewController`. The inheritance diagram follows. - - [UICommon] TTBaseViewController - ^ - | - [UINavigator] TTNavigatorViewController - ^ - | - [UI] TTViewController - -This is only half of the solution, however, because we need to consider that the original -method swizzling allowed us to dealloc the necessary global properties on *all* -`UIViewControllers`, not just those that inherit from what is now `TTBaseViewController`. - -In order to ensure that all `UIViewControllers` properly execute their shutdown logic, we -start a timer whenever a `UIViewController` is added to any of the global data structures. -This timer checks the retain count of the controller every n seconds. If the only thing -retaining this object is the garbage collector, we can safely call the shutdown logic and -release the view controller entirely. - -Repercussions of this new design --------------------------------- - -Garbage collection is a term that I'm personally scared of. For me it implies loss of control -over the management of memory. However, in this particular case we can rest easy because we -have direct control over the garbage collector. If you are afraid of a view controller not -being released in a timely manner, or perhaps you've received a `didReceiveMemoryWarning` -notification, then you simply need to call - - [TTViewController doGarbageCollection] - -This will force both the UINavigator and UICommon components to initiate their garbage collection. - -Advantages of using TTViewController ------------------------------------- - -If all of your view controllers inherit from `TTViewController`, then the garbage collector will -never actually be needed because `TTViewControllers` properly shut themselves down in their -dealloc. - - -This article written by: --- Jeff Verkoeyen (@featherless) *Created on May 28, 2010.* diff --git a/Articles/WritingArticles.mdown b/Articles/WritingArticles.mdown deleted file mode 100644 index 34a3ae4787..0000000000 --- a/Articles/WritingArticles.mdown +++ /dev/null @@ -1,22 +0,0 @@ - -How to Write a Three20 Article -============================== - -* Use [Markdown](http://daringfireball.net/projects/markdown/). - -* Consider that your audience can be anywhere from fresh to seasoned veterans. - -* Get someone to read it over before you commit, even if that someone is you. - -* Structure your document in a logical order. Use headers wisely. - -* If you're discussing a technical feature, provide a Troubleshooting section in the form - of a Q&A (question and answer). - -* Sign any article you work on and denote the action you took. Use the following format: - - This article written by: - -- John Smith (@twitter) * on .* - - Yes, git provides adequate versioning support, but signing the articles makes it easy - to see who's had their pen in an article at a glance. diff --git a/CHANGES b/CHANGES deleted file mode 100644 index 986292d916..0000000000 --- a/CHANGES +++ /dev/null @@ -1,263 +0,0 @@ -Changes since May 31, 2010 - -- [NEW] CSSStyle extension. View the README in src/extThree20CSSStyle - -- [FIXED] Warnings related to OS 4.0 and 3.2. - -Changes since May 28, 2010 - -- [APPSTORE] Remove use of TTSwapMethods. See Articles/UI/GarbageCollection and - eb45ca0a6336022367998ac41ced2df39af384d2. - -- [NEW] Add nib support again. - -- [FIXED] Issue #77. moveDataForURL and removeURL:fromDisk: have been fixed. - -Changes since May 18, 2010 - -- [NEW] TTEntityTables added to Core. - -- [DEPRECATED] NSArray perform:. You should now use makeObjectsPerformSelector. - -- [UNITTESTS] Added unit tests for the markup stripper. - -- [MINOR] Removed additions from Three20Core.h. - -Changes since April 23, 2010 - -- [NEW] Three20 has been split into modular libraries. Please read the - Articles/AboutModules.mdown file to learn more about the process. - -- [NEW] Add templates for Three20 projects and source files. - -- [NEW] Add Articles/ directory dedicated to in-depth discussions of Three20 - components. - -- [NEW] Etag support. See Articles/Network/Etag.mdown for more details. - -Changes since April 09, 2010 - -- [NEW] New +Additions library header files. - -- [NEW] Network unit tests. - -- [NEW] Nib support moved to a separate 'nibs' branch. - -- [NEW] Added the JSON library. - -- [NEW] Add a TTFacebook sample project using the new Open Graph API. - -- [DOX] Style consistency throughout the entire framework. - -Changes since March 30, 2010 - -- [NEW] New showTableShadows option for table gutter shadows. - -- [NEW] Nib support for TTViewControllers. - -- [NEW] TTNibDemo app demoing new Nib support. - -- [NEW] TTNetwork library. - -- [NEW] TTNetworkDemo example project. - -- [MINOR] Don't hard code the HTTP User-Agent. - -- [MINOR] Convert TTLink to use TTURLAction instead of just a URL. - -- [MINOR] Cleaning up and standardizing the coding style, about 70% complete. - -Changes since February 26, 2010 - -- [NEW] arrayForKey in the TTXMLAdditions. - -- [NEW] Support for successful HTTP status codes from [200, 300). - -- [NEW] Three20Core library. - -- [NEW] TTCoreDemo example project. - -- [FIXED] UIImage's transformWidth:height:rotate: implementation. - -- [FIXED] Keyboard display notifications. - -- [DOX] Doug Barth contributed complete documentation of TTMessageController. - -Changes since February 1, 2010 - -- [NEW] TTTwitter sample app. See the README.mdown file for in-depth details. - -- [NEW] TTXMLParser - A barebones XML parser that takes an XML string and creates an NSObject. - Options include support for RSS feeds. See the new TTTwitter sample app for an example. - -- [NEW] TTTableHeaderDragRefreshView, TTTableViewDragRefreshDelegate. These two new objects - together implement the "drag-to-refresh" table header seen in other apps on the app - store. Thanks to uprise78 for this fix. - -- [NEW] Add support for PUT HTTP methods. Thanks to dima. - -- [FIXED] github#71 navigationBarTintColor and toolbarTintColor issues for TTDefaultSheet - and TTWebController. - -- [FIXED] github#148 Add _toolbar.tintColor to TTPhotoViewController. - -- [DOCUMENTATION] TTURLRequestDelegate, TTURLRequest, TTURLRequestQueue, TTWebController, - TTYouTubeView, TTTableViewDelegate*. - -- [BUILD] Add a prefix header to Debug and Release builds. - -- [BUILD] Add a new build mode "Debug Dev" for use when hacking on Three20. - -- [BUILD] Reduced include scope of TTDebugFlags.h for faster rebuild times when debugging. - -Changes since January 22, 2010 - -- [NEW] TTURLAction object for TTNavigator. - -- [DEPRECATED] openURL methods of TTNavigator. - -- [DEPRECATED] TTImageView.URL => TTImageView.urlPath. - -- [DOCUMENTATION] Documented TTView, TTImageView, TTScrollView, TTYouTubeView, - TTNavigator and co. - -- [MINOR] Cleaned up the debugging documentation. - -Changes since December 25, 2009 - -- [NEW] TTURLRequest didReceiveAuthenticationChallenge for authentication challenges. - -- [DEPRECATED] isWhitespace. Use isWhitespaceAndNewlines instead. - -- [XCODE] Refactoring problems solved. TTUserInfo weak/strong properties renamed - to weakRef/strongRef, respectively. - -- [MINOR] Use __PRETTY_FUNCTION__ for debug logs. (@steipete) - -Changes from December 18, 2009 - -- [NEW] TTRecursiveProgress object for recursive progress (go figure!) - See TTRecursiveProgress.h for more details - -- [LOCALE] Numerous fixes to diffstrings - -- [LOCALE] Make --merge in diffstrings actually work - -- [LOCALE] Update German, Spanish, Italian, Japanese, Chinese, and Taiwanese - -- [NETWORK] TTNetworkRequestStarted/Stopped now threadsafe. - -- [CRASHFIX] Synchronous connections modifying non-threadsafe members - -Changes from December 11, 2009 - -- [NEW] -[NSDate formatShortRelativeTime] - -- [NEW] Unit tests for most of Core and part of UI - -- [APPSTORE] Rename previousViewController to ttPreviousViewController - -- [APPSTORE] Rename lineHeight to ttLineHeight - -- [APPSTORE] Rename screenX and screenY to ttScreenX and ttScreenY - -- [FIXED] diffstrings sorts strings tables to make diffs more sensible - -- [DEPRECATED] TTLOG - -- [DEPRECATED] TTIsEmpty* methods - -- [MINOR] Properly calculate the scroll height in the "Styled Views" - example in TTCatalog - -Changes from December 5, 2009 - -- [NEW] TTDCONDITIONLOG added to TTDebug.h - -- [NEW] TTDPRINTMETHODNAME added to TTDebug.h - -- [NEW] -[NSString versionStringCompare:] - -- [NEW] charsetForMultipart added to TTURLRequest - -- [FIXED] Table view delete-row animation slides to left, not up - -- [FIXED] Potentially uninitialized variable in NSStringAdditions - -- [FIXED] Layout problems in TTTextEditor - -- [FIXED] github#109 TTScrollView bug: displaying landscape views in - landscape orientation have a wrong size - -- [MINOR] Stylistic consistency changes - -- [MINOR] Duplicate TTIsEmptyArray in TTGlobal.h now TTIsEmptySet - -- [MINOR] Reset TTTableMessageItemCell properties when preparing for reuse - -- [MINOR] Fix potential crash when asking for a nonexistent - previousViewController - -- [MINOR] Use the same bytes per row in the destination bitmap for - transformWidth - - -Changes from November 27, 2009 - -- [NEW] loadSynchronous added to TTURLRequest. - -- [NEW] TTHighlightBorderStyle New border style with a highlight. - http://three20.info/api/TTStyle#TTHighlightBorderStyle - -- [NEW] TTReflectiveFillStyle styleWithColor:withBottomHighlight:next: - http://three20.info/api/TTStyle#styleWithColor:withBottomHighlight:next: - -- [FIXED] TTReflectiveFillStyle's rendering algorithm now works without magic - numbers. - -- [FIXED] github#108 Show the proper accessoryType for shared URLs. - -- [FIXED] github#107 Check for known URL schemes case-insensitively. - -- [FIXED] github#106 Update the README to reference the new repo location. - -- [FIXED] github#104 Properly show TTTabStrip left/right images. - -- [FIXED] github#78 In TTScrollView notify the delegate when the page has - changed. - -Changes from November 19, 2009 - -- [FIXED] Revert to previous TTIsKeyboardVisible() check - -- [FIXED] Zero no longer signifies "cached object never expires" - - -Changes from November 17, 2009 - -- [NEW] TTD* logging macros. See TTDebug.h for info. - -- [NEW] [NSMutableArray addNonEmptyString:(NSString*)string] - -- [NEW] [NSMutableDictionary setNonEmptyString:(NSString*)string forKey:(id)key] - -- [NEW] [NSArray containsObject:(id)object withSelector:(SEL)selector] - -- [NEW] [NSData md5Hash] - -- [DEPRECATED] TTLOG macros should no longer be used, consider switching to TTD* macros. - -- [SECURITY] Don't write passwords to the console in TTURLRequests. - -- [FIXED] github#67 Set the default cache expiration date for TTURLRequests to - TT_DEFAULT_CACHE_EXPIRATION_AGE. - -- [FIXED] github#85 Disallow recursive calls to wobble. - -- [FIXED] github#92 Fix memory leak in TTViewController. - -- [FIXED] github#75 Fix memory leak in UIColorAdditions. - -- [FIXED] github#11 Add autoresizingMask to TTActivityLabel. - -- [FIXED] references to private APIs: firstResponder, UIView additions diff --git a/Icon.png b/Icon.png new file mode 100644 index 0000000000..5d22c55d6f Binary files /dev/null and b/Icon.png differ diff --git a/LICENSE b/LICENSE index 4dc16d122d..3d258963c1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2008 Joe Hewitt +Copyright 2009-2011 Facebook Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.mdown b/README.mdown index 0ef13729ae..1c9de39c42 100644 --- a/README.mdown +++ b/README.mdown @@ -19,13 +19,29 @@ If you would like to ask any questions regarding Three20, please check out any o * [Three20.info][] * [Three20 Mailing List][] -* [Three20 Scope][] +* [Three20 Tagged Questions on StackOverflow][] + +Documentation +============================== + +You can access Three20 API documentation in several ways: + +1. Online: http://facebook.github.com/three20/api +1. Within Xcode: + 1. Open your Xcode Preferences (`⌘,`) and switch to Documentation tab. + 1. Click the `+` button + 1. Add the Three20 doc set feed: `feed://facebook.github.com/three20/api/com.facebook.Three20.atom` +1. Generate the documentation from the project repository with the `src/scripts/docs.py` script Adding Three20 to your project ============================== -Three20 is compiled as a static library, and the easiest way to add it to your -project is to use Xcode's "dependent project" facilities. Here is how: +Three20 is compiled as static libraries. It use Xcode's "dependent project" facilities. +There are two methods of adding Three20 to your project. + +The first is with the [TTModule Python Script][]. + +The Second option is to add it to your project manually. Here is how: **Estimated time:** 5 minutes. 1. Clone the three20 git repository: `git clone git://github.com/facebook/three20.git`. Make sure @@ -155,7 +171,7 @@ Learn more at [Three20.info][] [Facebook iPhone app]: http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284882215&mt=8 [Three20.info]: http://Three20.info [Three20 Mailing List]: http://groups.google.com/group/three20/ -[Three20 Scope]: http://three20.stackexchange.com +[Three20 Tagged Questions on StackOverflow]: http://stackoverflow.com/questions/tagged/three20 [TTPhotoViewController]: http://github.com/facebook/three20/blob/master/src/Three20UI/Headers/TTPhotoViewController.h [TTMessageController]: http://github.com/facebook/three20/blob/master/src/Three20UI/Headers/TTMessageController.h [TTImageView]: http://github.com/facebook/three20/blob/master/src/Three20UI/Headers/TTImageView.h @@ -165,3 +181,4 @@ Learn more at [Three20.info][] [TTTextEditor]: http://github.com/facebook/three20/blob/master/src/Three20UI/Headers/TTTextEditor.h [TTPickerTextField]: http://github.com/facebook/three20/blob/master/src/Three20UI/Headers/TTPickerTextField.h [TTNavigator]: http://github.com/facebook/three20/blob/master/src/Three20UI/Headers/TTNavigator.h +[TTModule Python Script]: http://three20.info/article/2010-10-06-Adding-Three20-To-Your-Project \ No newline at end of file diff --git a/Three20.xcworkspace/contents.xcworkspacedata b/Three20.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..7543a13347 --- /dev/null +++ b/Three20.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Three20.xcworkspace/xcshareddata/xcschemes/Samples.xcscheme b/Three20.xcworkspace/xcshareddata/xcschemes/Samples.xcscheme new file mode 100644 index 0000000000..2af6bd44dc --- /dev/null +++ b/Three20.xcworkspace/xcshareddata/xcschemes/Samples.xcscheme @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Three20.xcworkspace/xcshareddata/xcschemes/UnitTests.xcscheme b/Three20.xcworkspace/xcshareddata/xcschemes/UnitTests.xcscheme new file mode 100644 index 0000000000..63221c2a04 --- /dev/null +++ b/Three20.xcworkspace/xcshareddata/xcschemes/UnitTests.xcscheme @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config.template b/config.template new file mode 100644 index 0000000000..b955f4622b --- /dev/null +++ b/config.template @@ -0,0 +1,17 @@ +; +; This Three20 config file is used by various scripts in the Three20 ecosystem to +; change configuration settings. +; +; NOTICE: This is just a template. Changes to this file will not be noticed by scripts. +; To configure Three20, copy this file and rename it to "config" in the same folder. +; +; This file represents the assumed "defaults" when the config file does not exist. +; + +; The Three20 lint tool validates source code for the Three20 style guidelines to ensure a +; consistent style across the code base. +[lint] + +; By default, Three20 will run the linter on all Three20 projects. If you are hacking on +; Three20 and don't really care about stylistic consistency, set this to false. +enabled_for_projects = true diff --git a/extensions/ignoreme b/extensions/ignoreme new file mode 100644 index 0000000000..e69de29bb2 diff --git a/samples/Core/TTCoreDemo/Classes/AppDelegate.h b/samples/Core/TTCoreDemo/Classes/AppDelegate.h index a58056a19f..3ef3eb0265 100644 --- a/samples/Core/TTCoreDemo/Classes/AppDelegate.h +++ b/samples/Core/TTCoreDemo/Classes/AppDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Core/TTCoreDemo/Classes/AppDelegate.m b/samples/Core/TTCoreDemo/Classes/AppDelegate.m index 62e83d9926..51f2f8331a 100644 --- a/samples/Core/TTCoreDemo/Classes/AppDelegate.m +++ b/samples/Core/TTCoreDemo/Classes/AppDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Core/TTCoreDemo/Classes/PlaygroundViewController.h b/samples/Core/TTCoreDemo/Classes/PlaygroundViewController.h index d8a6258c67..9c94c56340 100644 --- a/samples/Core/TTCoreDemo/Classes/PlaygroundViewController.h +++ b/samples/Core/TTCoreDemo/Classes/PlaygroundViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Core/TTCoreDemo/Classes/PlaygroundViewController.m b/samples/Core/TTCoreDemo/Classes/PlaygroundViewController.m index 4b3e9afc6c..5d52d91a4b 100644 --- a/samples/Core/TTCoreDemo/Classes/PlaygroundViewController.m +++ b/samples/Core/TTCoreDemo/Classes/PlaygroundViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Core/TTCoreDemo/Configurations/App.xcconfig b/samples/Core/TTCoreDemo/Configurations/App.xcconfig index 63eef2d52c..fb121e8537 100644 --- a/samples/Core/TTCoreDemo/Configurations/App.xcconfig +++ b/samples/Core/TTCoreDemo/Configurations/App.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTCoreDemo +BASE_PRODUCT_NAME = TTCoreDemo +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/samples/Core/TTCoreDemo/Configurations/Project.xcconfig b/samples/Core/TTCoreDemo/Configurations/Project.xcconfig index 0f02ea7f79..fc1966a5f7 100644 --- a/samples/Core/TTCoreDemo/Configurations/Project.xcconfig +++ b/samples/Core/TTCoreDemo/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Core/TTCoreDemo/Configurations/RelPath.xcconfig b/samples/Core/TTCoreDemo/Configurations/RelPath.xcconfig index 7510c4e4be..e869ea439f 100644 --- a/samples/Core/TTCoreDemo/Configurations/RelPath.xcconfig +++ b/samples/Core/TTCoreDemo/Configurations/RelPath.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Core/TTCoreDemo/Configurations/UnitTests.xcconfig b/samples/Core/TTCoreDemo/Configurations/UnitTests.xcconfig index a5897425ae..6356960958 100644 --- a/samples/Core/TTCoreDemo/Configurations/UnitTests.xcconfig +++ b/samples/Core/TTCoreDemo/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Core/TTCoreDemo/TTCoreDemo.xcodeproj/project.pbxproj b/samples/Core/TTCoreDemo/TTCoreDemo.xcodeproj/project.pbxproj index 0514dc5da1..27cbeaa073 100755 --- a/samples/Core/TTCoreDemo/TTCoreDemo.xcodeproj/project.pbxproj +++ b/samples/Core/TTCoreDemo/TTCoreDemo.xcodeproj/project.pbxproj @@ -3,13 +3,14 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 668DCFEB1262FA51004C9828 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 668DCFEA1262FA51004C9828 /* Default@2x.png */; }; 6E645D6E1187999F00F08CB1 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E645D6B1187999700F08CB1 /* libThree20Core.a */; }; 6E64601B1187B3CD00F08CB1 /* Three20.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 6E64601A1187B3CD00F08CB1 /* Three20.bundle */; }; 6E94C67A116D97FF0012B12C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E94C678116D97FF0012B12C /* Default.png */; }; @@ -49,6 +50,7 @@ 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 1D6058910D05DD3D006BFB54 /* TTCoreDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TTCoreDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 668DCFEA1262FA51004C9828 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "../../Resources/Default@2x.png"; sourceTree = SOURCE_ROOT; }; 6E645D621187999700F08CB1 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../../../src/Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; 6E645DCD11879B0400F08CB1 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Project.xcconfig; path = ../Configurations/Project.xcconfig; sourceTree = ""; }; 6E645DCE11879B0400F08CB1 /* UnitTests.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = UnitTests.xcconfig; path = ../Configurations/UnitTests.xcconfig; sourceTree = ""; }; @@ -128,6 +130,7 @@ children = ( 6E64601A1187B3CD00F08CB1 /* Three20.bundle */, 6E94C678116D97FF0012B12C /* Default.png */, + 668DCFEA1262FA51004C9828 /* Default@2x.png */, 6E94C679116D97FF0012B12C /* Icon.png */, 8D1107310486CEB800E47090 /* TTCoreDemo-Info.plist */, ); @@ -208,9 +211,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTCoreDemo" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -251,6 +265,7 @@ 6E94C67A116D97FF0012B12C /* Default.png in Resources */, 6E94C67B116D97FF0012B12C /* Icon.png in Resources */, 6E64601B1187B3CD00F08CB1 /* Three20.bundle in Resources */, + 668DCFEB1262FA51004C9828 /* Default@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -286,8 +301,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - INFOPLIST_FILE = "TTCoreDemo-Info.plist"; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -296,8 +310,7 @@ baseConfigurationReference = 6E645DDE11879B3500F08CB1 /* App.xcconfig */; buildSettings = { COPY_PHASE_STRIP = YES; - INFOPLIST_FILE = "TTCoreDemo-Info.plist"; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -305,13 +318,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E645DCD11879B0400F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.1.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -319,13 +330,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E645DCD11879B0400F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.1.2; + SDKROOT = iphoneos; }; name = Release; }; diff --git a/samples/Core/TTCoreDemo/main.m b/samples/Core/TTCoreDemo/main.m index 3292416c2b..e0f8c871de 100644 --- a/samples/Core/TTCoreDemo/main.m +++ b/samples/Core/TTCoreDemo/main.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Network/TTNetworkDemo/Classes/AppDelegate.h b/samples/Network/TTNetworkDemo/Classes/AppDelegate.h index a58056a19f..3ef3eb0265 100644 --- a/samples/Network/TTNetworkDemo/Classes/AppDelegate.h +++ b/samples/Network/TTNetworkDemo/Classes/AppDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Network/TTNetworkDemo/Classes/AppDelegate.m b/samples/Network/TTNetworkDemo/Classes/AppDelegate.m index cbdd2dcdf3..719feec0a3 100644 --- a/samples/Network/TTNetworkDemo/Classes/AppDelegate.m +++ b/samples/Network/TTNetworkDemo/Classes/AppDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Network/TTNetworkDemo/Classes/PlaygroundViewController.h b/samples/Network/TTNetworkDemo/Classes/PlaygroundViewController.h index e11e248328..e0c28f8ca3 100644 --- a/samples/Network/TTNetworkDemo/Classes/PlaygroundViewController.h +++ b/samples/Network/TTNetworkDemo/Classes/PlaygroundViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Network/TTNetworkDemo/Classes/PlaygroundViewController.m b/samples/Network/TTNetworkDemo/Classes/PlaygroundViewController.m index 00ec884931..ff4e919fb8 100644 --- a/samples/Network/TTNetworkDemo/Classes/PlaygroundViewController.m +++ b/samples/Network/TTNetworkDemo/Classes/PlaygroundViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Network/TTNetworkDemo/Configurations/App.xcconfig b/samples/Network/TTNetworkDemo/Configurations/App.xcconfig index d2ef8314bd..fbccaba14b 100644 --- a/samples/Network/TTNetworkDemo/Configurations/App.xcconfig +++ b/samples/Network/TTNetworkDemo/Configurations/App.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTNetworkDemo +BASE_PRODUCT_NAME = TTNetworkDemo +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/samples/Network/TTNetworkDemo/Configurations/Project.xcconfig b/samples/Network/TTNetworkDemo/Configurations/Project.xcconfig index 066eb87356..659d27c976 100644 --- a/samples/Network/TTNetworkDemo/Configurations/Project.xcconfig +++ b/samples/Network/TTNetworkDemo/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Network/TTNetworkDemo/Configurations/UnitTests.xcconfig b/samples/Network/TTNetworkDemo/Configurations/UnitTests.xcconfig index ea98c46dfd..bb7a159b61 100644 --- a/samples/Network/TTNetworkDemo/Configurations/UnitTests.xcconfig +++ b/samples/Network/TTNetworkDemo/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,5 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTNetworkDemoUnitTests +BASE_PRODUCT_NAME = TTNetworkDemoUnitTests BUILD_BUNDLE_VERSION = 1.0 diff --git a/samples/Network/TTNetworkDemo/TTNetworkDemo.xcodeproj/project.pbxproj b/samples/Network/TTNetworkDemo/TTNetworkDemo.xcodeproj/project.pbxproj index 95b21a9645..5658f138b1 100755 --- a/samples/Network/TTNetworkDemo/TTNetworkDemo.xcodeproj/project.pbxproj +++ b/samples/Network/TTNetworkDemo/TTNetworkDemo.xcodeproj/project.pbxproj @@ -3,13 +3,14 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 663DAE791266189B00CF8CEA /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 663DAE781266189B00CF8CEA /* Default@2x.png */; }; 6E645FE71187B39900F08CB1 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E645FDF1187B38B00F08CB1 /* libThree20Network.a */; }; 6E645FF01187B3C300F08CB1 /* Three20.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 6E645FEF1187B3C300F08CB1 /* Three20.bundle */; }; 6E6460551187B46A00F08CB1 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E645FD21187B38400F08CB1 /* libThree20Core.a */; }; @@ -71,6 +72,7 @@ 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 1D6058910D05DD3D006BFB54 /* TTNetworkDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TTNetworkDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 663DAE781266189B00CF8CEA /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "../../Resources/Default@2x.png"; sourceTree = SOURCE_ROOT; }; 6E645FA61187B2E400F08CB1 /* TTNetworkDemo_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTNetworkDemo_Prefix.pch; path = Headers/TTNetworkDemo_Prefix.pch; sourceTree = ""; }; 6E645FC01187B30100F08CB1 /* App.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = App.xcconfig; path = Configurations/App.xcconfig; sourceTree = ""; }; 6E645FC11187B30100F08CB1 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Project.xcconfig; path = Configurations/Project.xcconfig; sourceTree = ""; }; @@ -151,6 +153,7 @@ children = ( 6E645FEF1187B3C300F08CB1 /* Three20.bundle */, 6E94C678116D97FF0012B12C /* Default.png */, + 663DAE781266189B00CF8CEA /* Default@2x.png */, 6E94C679116D97FF0012B12C /* Icon.png */, 6E94CACF11700C370012B12C /* TTNetworkDemo-Info.plist */, ); @@ -199,7 +202,7 @@ isa = PBXGroup; children = ( 6E645FDF1187B38B00F08CB1 /* libThree20Network.a */, - 6E645FE11187B38B00F08CB1 /* UnitTests.octest */, + 6E645FE11187B38B00F08CB1 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -240,9 +243,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTNetworkDemo" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -284,10 +298,10 @@ remoteRef = 6E645FDE1187B38B00F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E645FE11187B38B00F08CB1 /* UnitTests.octest */ = { + 6E645FE11187B38B00F08CB1 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E645FE01187B38B00F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -301,6 +315,7 @@ 6E94C67A116D97FF0012B12C /* Default.png in Resources */, 6E94C67B116D97FF0012B12C /* Icon.png in Resources */, 6E645FF01187B3C300F08CB1 /* Three20.bundle in Resources */, + 663DAE791266189B00CF8CEA /* Default@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -341,8 +356,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - INFOPLIST_FILE = "TTNetworkDemo-Info.plist"; - SDKROOT = iphoneos3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -351,8 +365,7 @@ baseConfigurationReference = 6E645FC01187B30100F08CB1 /* App.xcconfig */; buildSettings = { COPY_PHASE_STRIP = YES; - INFOPLIST_FILE = "TTNetworkDemo-Info.plist"; - SDKROOT = iphoneos3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -360,13 +373,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E645FC11187B30100F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.0; + SDKROOT = iphoneos; }; name = Debug; }; @@ -374,13 +385,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E645FC11187B30100F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.0; + SDKROOT = iphoneos; }; name = Release; }; diff --git a/samples/Network/TTNetworkDemo/main.m b/samples/Network/TTNetworkDemo/main.m index 2915dbbb29..1cefab29fe 100644 --- a/samples/Network/TTNetworkDemo/main.m +++ b/samples/Network/TTNetworkDemo/main.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Resources/Default-Landscape.png b/samples/Resources/Default-Landscape.png new file mode 100644 index 0000000000..4a635b1f29 Binary files /dev/null and b/samples/Resources/Default-Landscape.png differ diff --git a/samples/Resources/Default-Landscape.psd b/samples/Resources/Default-Landscape.psd new file mode 100644 index 0000000000..2e8318677a Binary files /dev/null and b/samples/Resources/Default-Landscape.psd differ diff --git a/samples/Resources/Default-Portrait.png b/samples/Resources/Default-Portrait.png new file mode 100644 index 0000000000..f066dbca81 Binary files /dev/null and b/samples/Resources/Default-Portrait.png differ diff --git a/samples/Resources/Default-Portrait.psd b/samples/Resources/Default-Portrait.psd new file mode 100644 index 0000000000..986a1064b1 Binary files /dev/null and b/samples/Resources/Default-Portrait.psd differ diff --git a/samples/Resources/Default.png b/samples/Resources/Default.png index 99035c7a18..6ca8e06cb6 100644 Binary files a/samples/Resources/Default.png and b/samples/Resources/Default.png differ diff --git a/samples/Resources/Default.psd b/samples/Resources/Default.psd new file mode 100644 index 0000000000..6222edcb18 Binary files /dev/null and b/samples/Resources/Default.psd differ diff --git a/samples/Resources/Default@2x.png b/samples/Resources/Default@2x.png new file mode 100644 index 0000000000..a52c5f7b34 Binary files /dev/null and b/samples/Resources/Default@2x.png differ diff --git a/samples/Resources/Default@2x.psd b/samples/Resources/Default@2x.psd new file mode 100644 index 0000000000..9b1370021f Binary files /dev/null and b/samples/Resources/Default@2x.psd differ diff --git a/samples/Resources/Icon.png b/samples/Resources/Icon.png index 2f027a6921..5d22c55d6f 100644 Binary files a/samples/Resources/Icon.png and b/samples/Resources/Icon.png differ diff --git a/samples/Resources/Icon.psd b/samples/Resources/Icon.psd new file mode 100644 index 0000000000..b9f590f9ee Binary files /dev/null and b/samples/Resources/Icon.psd differ diff --git a/samples/Resources/Icon@2x.png b/samples/Resources/Icon@2x.png new file mode 100644 index 0000000000..9843307b93 Binary files /dev/null and b/samples/Resources/Icon@2x.png differ diff --git a/samples/Resources/Icon@2x.psd b/samples/Resources/Icon@2x.psd new file mode 100644 index 0000000000..c1c9b3d796 Binary files /dev/null and b/samples/Resources/Icon@2x.psd differ diff --git a/samples/Style/TTCSSStyleSheets/Classes/AppDelegate.h b/samples/Style/TTCSSStyleSheets/Classes/AppDelegate.h index aa8771c199..f8d3d93ac0 100644 --- a/samples/Style/TTCSSStyleSheets/Classes/AppDelegate.h +++ b/samples/Style/TTCSSStyleSheets/Classes/AppDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTCSSStyleSheets/Classes/AppDelegate.m b/samples/Style/TTCSSStyleSheets/Classes/AppDelegate.m index ee13e66208..2d89416828 100644 --- a/samples/Style/TTCSSStyleSheets/Classes/AppDelegate.m +++ b/samples/Style/TTCSSStyleSheets/Classes/AppDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTCSSStyleSheets/Classes/Atlas.h b/samples/Style/TTCSSStyleSheets/Classes/Atlas.h index d034d07e49..9202a84c07 100644 --- a/samples/Style/TTCSSStyleSheets/Classes/Atlas.h +++ b/samples/Style/TTCSSStyleSheets/Classes/Atlas.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTCSSStyleSheets/Classes/Atlas.m b/samples/Style/TTCSSStyleSheets/Classes/Atlas.m index 98d547a1fa..678284fbe9 100644 --- a/samples/Style/TTCSSStyleSheets/Classes/Atlas.m +++ b/samples/Style/TTCSSStyleSheets/Classes/Atlas.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTCSSStyleSheets/Classes/SampleCSSStyleSheet.h b/samples/Style/TTCSSStyleSheets/Classes/SampleCSSStyleSheet.h new file mode 100644 index 0000000000..494a0adff9 --- /dev/null +++ b/samples/Style/TTCSSStyleSheets/Classes/SampleCSSStyleSheet.h @@ -0,0 +1,18 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@interface SampleCSSStyleSheet : TTDefaultCSSStyleSheet {} +@end diff --git a/samples/Style/TTCSSStyleSheets/Classes/SampleCSSStyleSheet.m b/samples/Style/TTCSSStyleSheets/Classes/SampleCSSStyleSheet.m new file mode 100644 index 0000000000..ffb01b6960 --- /dev/null +++ b/samples/Style/TTCSSStyleSheets/Classes/SampleCSSStyleSheet.m @@ -0,0 +1,36 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "SampleCSSStyleSheet.h" + +@implementation SampleCSSStyleSheet + +- (TTStyle *)h3:(UIControlState)state { + return + [TTSolidFillStyle styleWithColor:TTCSSSTATE(@"h3", backgroundColor, state) next: + [TTTextStyle styleWithCssSelector:@"h3" forState:state next: + nil]]; +} + +- (TTStyle *)h4:(UIControlState)state { + return + [TTSolidFillStyle styleWithColor:TTCSSSTATE(@"h4text", backgroundColor, state) next: + [TTShadowStyle styleWithCssSelector:@"h4shadow" forState:state next: + [TTTextStyle styleWithCssSelector:@"h4text" forState:state next: + nil]]]; +} + +@end diff --git a/samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.h b/samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.h index bfa8288c6c..98e6f5c517 100644 --- a/samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.h +++ b/samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ @interface StyleSheetViewController : TTViewController { @private - TTCSSStyleSheet* _styleSheet; - BOOL _loadedSuccessfully; } diff --git a/samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.m b/samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.m index 27727396af..7209033ca8 100644 --- a/samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.m +++ b/samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "StyleSheetViewController.h" +#import "SampleCSSStyleSheet.h" +#import "extThree20CSSStyle/TTCSSRuleSet.h" + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -25,25 +28,18 @@ @implementation StyleSheetViewController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { - _styleSheet = [[TTCSSStyleSheet alloc] init]; - + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + SampleCSSStyleSheet *_styleSheet = [[[SampleCSSStyleSheet alloc] init] autorelease]; _loadedSuccessfully = [_styleSheet - loadFromFilename:TTPathForBundleResource(@"stylesheet.css")]; + addStyleSheetFromDisk:TTPathForBundleResource(@"stylesheet.css")]; + [TTStyleSheet setGlobalStyleSheet:_styleSheet]; } return self; } -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)dealloc { - TT_RELEASE_SAFELY(_styleSheet); - - [super dealloc]; -} - - /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)loadView { [super loadView]; @@ -55,23 +51,61 @@ - (void)loadView { } self.title = @"Three20 CSS extension"; + self.view.backgroundColor = TTCSS( @"body", background_color ); - self.view.backgroundColor = [_styleSheet backgroundColorWithCssSelector: @"body" - forState: UIControlStateNormal]; - + // Using helper macro UILabel* headerLabel = [[UILabel alloc] initWithFrame:CGRectZero]; headerLabel.text = @"Header text"; - headerLabel.font = [_styleSheet fontWithCssSelector:@"h1" forState:UIControlStateNormal]; - headerLabel.textColor = [_styleSheet colorWithCssSelector:@"h1" forState:UIControlStateNormal]; - headerLabel.backgroundColor = [_styleSheet backgroundColorWithCssSelector: @"h1" - forState: UIControlStateNormal]; - headerLabel.shadowColor = [_styleSheet textShadowColorWithCssSelector: @"h1" - forState: UIControlStateNormal]; - headerLabel.shadowOffset = [_styleSheet textShadowOffsetWithCssSelector: @"h1" - forState: UIControlStateNormal]; + + // When using TTCSS you specify the Rule Set Name and the CSS property. + headerLabel.font = TTCSS(@"h1", font); + headerLabel.textColor = TTCSS(@"h1", color); + headerLabel.backgroundColor = TTCSS(@"h1", background_color); + + // Some CSS property have sub properties. + headerLabel.shadowColor = TTCSS(@"h1", text_shadow).shadowColor; + headerLabel.shadowOffset = TTCSS(@"h1", text_shadow).shadowOffset; + [headerLabel sizeToFit]; [self.view addSubview:headerLabel]; + + // Using UILabel addition + UILabel* headerLabel2 = [[UILabel alloc] initWithFrame:CGRectZero]; + headerLabel2.text = @"Header 2 text"; + + // Use the Helper Function TTApplyCSS and specify the Rule Set Name then the object to apply. + TTApplyCSS( @"h2", headerLabel2 ); + + // This will work too! + [headerLabel applyCssSelector:@"h2"]; + + [headerLabel2 sizeToFit]; + CGFloat top = headerLabel.frame.size.height; + CGRect frame = headerLabel2.frame; + frame.origin.y = top; + headerLabel2.frame = frame; + [self.view addSubview:headerLabel2]; + + // Using TTTextStyle addition + TTButton* headerLabel3 = [TTButton buttonWithStyle:@"h3:" title:@"Header 3 text"]; + [headerLabel3 sizeToFit]; + top += headerLabel2.frame.size.height; + frame = headerLabel3.frame; + frame.origin.y = top; + headerLabel3.frame = frame; + [self.view addSubview:headerLabel3]; + + // Using TTTextStyle + TTShadowStyle addition + TTButton* headerLabel4 = [TTButton buttonWithStyle:@"h4:" title:@"Header 4 text"]; + [headerLabel4 sizeToFit]; + top += headerLabel2.frame.size.height; + frame = headerLabel4.frame; + frame.origin.y = top; + headerLabel4.frame = frame; + [self.view addSubview:headerLabel4]; + TT_RELEASE_SAFELY(headerLabel); + TT_RELEASE_SAFELY(headerLabel2); } diff --git a/samples/Style/TTCSSStyleSheets/Configurations/App.xcconfig b/samples/Style/TTCSSStyleSheets/Configurations/App.xcconfig index 2126d88d48..194e82a226 100644 --- a/samples/Style/TTCSSStyleSheets/Configurations/App.xcconfig +++ b/samples/Style/TTCSSStyleSheets/Configurations/App.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTCSSStyleSheets +BASE_PRODUCT_NAME = TTCSSStyleSheets +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/samples/Style/TTCSSStyleSheets/Configurations/Project.xcconfig b/samples/Style/TTCSSStyleSheets/Configurations/Project.xcconfig index 0f02ea7f79..fc1966a5f7 100644 --- a/samples/Style/TTCSSStyleSheets/Configurations/Project.xcconfig +++ b/samples/Style/TTCSSStyleSheets/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTCSSStyleSheets/Configurations/RelPath.xcconfig b/samples/Style/TTCSSStyleSheets/Configurations/RelPath.xcconfig index 7510c4e4be..e869ea439f 100644 --- a/samples/Style/TTCSSStyleSheets/Configurations/RelPath.xcconfig +++ b/samples/Style/TTCSSStyleSheets/Configurations/RelPath.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTCSSStyleSheets/Configurations/UnitTests.xcconfig b/samples/Style/TTCSSStyleSheets/Configurations/UnitTests.xcconfig index 24e87d2649..fa3d200761 100644 --- a/samples/Style/TTCSSStyleSheets/Configurations/UnitTests.xcconfig +++ b/samples/Style/TTCSSStyleSheets/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTCSSStyleSheetsUnitTests +BASE_PRODUCT_NAME = TTCSSStyleSheetsUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_BUNDLE_VERSION = 1.0 diff --git a/samples/Style/TTCSSStyleSheets/Headers/TTCSSStyleSheets_Prefix.pch b/samples/Style/TTCSSStyleSheets/Headers/TTCSSStyleSheets_Prefix.pch index 50fceb5312..ba95f7894a 100644 --- a/samples/Style/TTCSSStyleSheets/Headers/TTCSSStyleSheets_Prefix.pch +++ b/samples/Style/TTCSSStyleSheets/Headers/TTCSSStyleSheets_Prefix.pch @@ -6,6 +6,6 @@ #import #import #import "Three20/Three20.h" - #import "extThree20CSSStyle/extThree20CSSStyle.h" + #import "extThree20CSSStyle/extThree20CSSStyle+Additions.h" #import "Atlas.h" #endif diff --git a/samples/Style/TTCSSStyleSheets/Resources/stylesheet.css b/samples/Style/TTCSSStyleSheets/Resources/stylesheet.css index f9f859b9e9..0228f6492b 100644 --- a/samples/Style/TTCSSStyleSheets/Resources/stylesheet.css +++ b/samples/Style/TTCSSStyleSheets/Resources/stylesheet.css @@ -15,13 +15,44 @@ */ body { - background-color: #111; + background-color: #114; } h1 { font-weight: bold; font-size: 50pt; - color: #666; + color: #FF6; background-color: transparent; - text-shadow: 1px 1px 1px #999; /* blur amount (3rd value) doesn't do anything */ + text-shadow: 2px 2px 0px #F99; } + +h2 { + font-size: 45pt; + color: white; + background-color: transparent; + text-shadow: 0px 1px 3px #9BF; +} + +h3, h3:hover { + font-size: 35pt; + font-weight: bold; + color: white; + background-color: transparent; + text-shadow: 3px -3px 3px #99F; +} + +h3:hover { + color: #99F; + text-shadow: 3px 3px 3px white; +} + +h4text, h4text:hover { + color: white; + font-size: 35pt; + background-color: transparent; +} + +h4text:hover { color: gray; } + +h4shadow { text-shadow: 3px 3px 4px rgba(0, 255, 0, .5); } +h4shadow:hover { text-shadow: 0px 0px 4px green; } diff --git a/samples/Style/TTCSSStyleSheets/TTCSSStyleSheets.xcodeproj/project.pbxproj b/samples/Style/TTCSSStyleSheets/TTCSSStyleSheets.xcodeproj/project.pbxproj index e81481daf3..daca92d125 100755 --- a/samples/Style/TTCSSStyleSheets/TTCSSStyleSheets.xcodeproj/project.pbxproj +++ b/samples/Style/TTCSSStyleSheets/TTCSSStyleSheets.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -12,6 +12,7 @@ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 663DB50E1266288E00CF8CEA /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 663DB50D1266288E00CF8CEA /* Default@2x.png */; }; 6E036BD011B38E550025E8EE /* libextThree20CSSStyle.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E036BCD11B38E520025E8EE /* libextThree20CSSStyle.a */; }; 6E036BF511B38EDC0025E8EE /* stylesheet.css in Resources */ = {isa = PBXBuildFile; fileRef = 6E036BF411B38EDC0025E8EE /* stylesheet.css */; }; 6E036BF811B38F3C0025E8EE /* StyleSheetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E036BF711B38F3C0025E8EE /* StyleSheetViewController.m */; }; @@ -27,6 +28,7 @@ 6E850FAE11B176F10071A4FD /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E850FAC11B176F10071A4FD /* Default.png */; }; 6E850FAF11B176F10071A4FD /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E850FAD11B176F10071A4FD /* Icon.png */; }; 6E850FB811B1795F0071A4FD /* Atlas.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E850FB711B1795F0071A4FD /* Atlas.m */; }; + 90C3A1C1132BF66B00AC06A2 /* SampleCSSStyleSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 90C3A1C0132BF66B00AC06A2 /* SampleCSSStyleSheet.m */; }; EB383B6510BBF62B0000B2D2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB383B6410BBF62B0000B2D2 /* QuartzCore.framework */; }; /* End PBXBuildFile section */ @@ -209,6 +211,7 @@ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 663DB50D1266288E00CF8CEA /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "../../Resources/Default@2x.png"; sourceTree = SOURCE_ROOT; }; 6E036BC711B38E520025E8EE /* extThree20CSSStyle.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = extThree20CSSStyle.xcodeproj; path = ../../../src/extThree20CSSStyle/extThree20CSSStyle.xcodeproj; sourceTree = SOURCE_ROOT; }; 6E036BF411B38EDC0025E8EE /* stylesheet.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = stylesheet.css; path = Resources/stylesheet.css; sourceTree = ""; }; 6E036BF611B38F3C0025E8EE /* StyleSheetViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetViewController.h; sourceTree = ""; }; @@ -232,6 +235,8 @@ 6E850FB711B1795F0071A4FD /* Atlas.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Atlas.m; sourceTree = ""; }; 6E8513D111B19B080071A4FD /* TTCSSStyleSheets_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTCSSStyleSheets_Prefix.pch; path = Headers/TTCSSStyleSheets_Prefix.pch; sourceTree = ""; }; 6E8513D211B19B0E0071A4FD /* TTCSSStyleSheets-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TTCSSStyleSheets-Info.plist"; sourceTree = ""; }; + 90C3A1BF132BF66B00AC06A2 /* SampleCSSStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SampleCSSStyleSheet.h; sourceTree = ""; }; + 90C3A1C0132BF66B00AC06A2 /* SampleCSSStyleSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SampleCSSStyleSheet.m; sourceTree = ""; }; EB383B6410BBF62B0000B2D2 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -266,6 +271,8 @@ 1D3623250D0F684500981E51 /* AppDelegate.m */, 6E850FB611B1795F0071A4FD /* Atlas.h */, 6E850FB711B1795F0071A4FD /* Atlas.m */, + 90C3A1BF132BF66B00AC06A2 /* SampleCSSStyleSheet.h */, + 90C3A1C0132BF66B00AC06A2 /* SampleCSSStyleSheet.m */, ); path = Classes; sourceTree = ""; @@ -308,6 +315,7 @@ 6E0835B311B4C42100B99C32 /* extThree20CSSStyle.bundle */, 6E8513D211B19B0E0071A4FD /* TTCSSStyleSheets-Info.plist */, 6E850FAC11B176F10071A4FD /* Default.png */, + 663DB50D1266288E00CF8CEA /* Default@2x.png */, 6E850FAD11B176F10071A4FD /* Icon.png */, 6E036BF411B38EDC0025E8EE /* stylesheet.css */, ); @@ -347,7 +355,7 @@ isa = PBXGroup; children = ( 6E3793EF11B9B59D0011C497 /* libThree20Network.a */, - 6E3793F111B9B59D0011C497 /* UnitTests.octest */, + 6E3793F111B9B59D0011C497 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -356,7 +364,7 @@ isa = PBXGroup; children = ( 6E3793F511B9B59D0011C497 /* libThree20Style.a */, - 6E3793F711B9B59D0011C497 /* UnitTests.octest */, + 6E3793F711B9B59D0011C497 /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -365,7 +373,7 @@ isa = PBXGroup; children = ( 6E3793FB11B9B59D0011C497 /* libThree20UICommon.a */, - 6E3793FD11B9B59D0011C497 /* UnitTests.octest */, + 6E3793FD11B9B59D0011C497 /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -374,7 +382,7 @@ isa = PBXGroup; children = ( 6E37940111B9B59D0011C497 /* libThree20UINavigator.a */, - 6E37940311B9B59D0011C497 /* UnitTests.octest */, + 6E37940311B9B59D0011C497 /* UINavigatorUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -383,7 +391,7 @@ isa = PBXGroup; children = ( 6E37940711B9B59D0011C497 /* libThree20UI.a */, - 6E37940911B9B59D0011C497 /* UnitTests.octest */, + 6E37940911B9B59D0011C497 /* UIUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -425,7 +433,7 @@ isa = PBXGroup; children = ( 6E850F8811B1762B0071A4FD /* libThree20.a */, - 6E850F8A11B1762B0071A4FD /* UnitTests.octest */, + 6E850F8A11B1762B0071A4FD /* Three20UnitTests.octest */, ); name = Products; sourceTree = ""; @@ -481,9 +489,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTCSSStyleSheets" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -563,10 +582,10 @@ remoteRef = 6E3793EE11B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3793F111B9B59D0011C497 /* UnitTests.octest */ = { + 6E3793F111B9B59D0011C497 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E3793F011B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -577,10 +596,10 @@ remoteRef = 6E3793F411B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3793F711B9B59D0011C497 /* UnitTests.octest */ = { + 6E3793F711B9B59D0011C497 /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E3793F611B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -591,10 +610,10 @@ remoteRef = 6E3793FA11B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3793FD11B9B59D0011C497 /* UnitTests.octest */ = { + 6E3793FD11B9B59D0011C497 /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6E3793FC11B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -605,10 +624,10 @@ remoteRef = 6E37940011B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37940311B9B59D0011C497 /* UnitTests.octest */ = { + 6E37940311B9B59D0011C497 /* UINavigatorUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UINavigatorUnitTests.octest; remoteRef = 6E37940211B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -619,10 +638,10 @@ remoteRef = 6E37940611B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37940911B9B59D0011C497 /* UnitTests.octest */ = { + 6E37940911B9B59D0011C497 /* UIUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UIUnitTests.octest; remoteRef = 6E37940811B9B59D0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -633,10 +652,10 @@ remoteRef = 6E850F8711B1762B0071A4FD /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E850F8A11B1762B0071A4FD /* UnitTests.octest */ = { + 6E850F8A11B1762B0071A4FD /* Three20UnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = Three20UnitTests.octest; remoteRef = 6E850F8911B1762B0071A4FD /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -652,6 +671,7 @@ 6E850FAE11B176F10071A4FD /* Default.png in Resources */, 6E850FAF11B176F10071A4FD /* Icon.png in Resources */, 6E036BF511B38EDC0025E8EE /* stylesheet.css in Resources */, + 663DB50E1266288E00CF8CEA /* Default@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -666,6 +686,7 @@ 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, 6E850FB811B1795F0071A4FD /* Atlas.m in Sources */, 6E036BF811B38F3C0025E8EE /* StyleSheetViewController.m in Sources */, + 90C3A1C1132BF66B00AC06A2 /* SampleCSSStyleSheet.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -726,7 +747,7 @@ GCC_PREPROCESSOR_DEFINITIONS = DEBUG; INFOPLIST_FILE = "TTCSSStyleSheets-Info.plist"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - SDKROOT = iphoneos3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -738,7 +759,7 @@ COPY_PHASE_STRIP = YES; INFOPLIST_FILE = "TTCSSStyleSheets-Info.plist"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - SDKROOT = iphoneos3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -746,13 +767,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E850F4911B175FD0071A4FD /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.1.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -760,13 +779,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E850F4911B175FD0071A4FD /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.1.2; + SDKROOT = iphoneos; }; name = Release; }; diff --git a/samples/Style/TTCSSStyleSheets/main.m b/samples/Style/TTCSSStyleSheets/main.m index 3292416c2b..e0f8c871de 100644 --- a/samples/Style/TTCSSStyleSheets/main.m +++ b/samples/Style/TTCSSStyleSheets/main.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/AppDelegate.h b/samples/Style/TTStyleCatalog/Classes/AppDelegate.h index aa8771c199..f8d3d93ac0 100644 --- a/samples/Style/TTStyleCatalog/Classes/AppDelegate.h +++ b/samples/Style/TTStyleCatalog/Classes/AppDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/AppDelegate.m b/samples/Style/TTStyleCatalog/Classes/AppDelegate.m index 31f5445e63..d16b022291 100644 --- a/samples/Style/TTStyleCatalog/Classes/AppDelegate.m +++ b/samples/Style/TTStyleCatalog/Classes/AppDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/Atlas.h b/samples/Style/TTStyleCatalog/Classes/Atlas.h index d034d07e49..9202a84c07 100644 --- a/samples/Style/TTStyleCatalog/Classes/Atlas.h +++ b/samples/Style/TTStyleCatalog/Classes/Atlas.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/Atlas.m b/samples/Style/TTStyleCatalog/Classes/Atlas.m index 98d547a1fa..678284fbe9 100644 --- a/samples/Style/TTStyleCatalog/Classes/Atlas.m +++ b/samples/Style/TTStyleCatalog/Classes/Atlas.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/MainMenuViewController.h b/samples/Style/TTStyleCatalog/Classes/MainMenuViewController.h index 279b92c536..f64677195d 100644 --- a/samples/Style/TTStyleCatalog/Classes/MainMenuViewController.h +++ b/samples/Style/TTStyleCatalog/Classes/MainMenuViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/MainMenuViewController.m b/samples/Style/TTStyleCatalog/Classes/MainMenuViewController.m index 2cdf885d7a..c97318bcf2 100644 --- a/samples/Style/TTStyleCatalog/Classes/MainMenuViewController.m +++ b/samples/Style/TTStyleCatalog/Classes/MainMenuViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/StyleView.h b/samples/Style/TTStyleCatalog/Classes/StyleView.h index 617694618e..8650e405d8 100644 --- a/samples/Style/TTStyleCatalog/Classes/StyleView.h +++ b/samples/Style/TTStyleCatalog/Classes/StyleView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/StyleView.m b/samples/Style/TTStyleCatalog/Classes/StyleView.m index 30914d7062..f3ad8eb12a 100644 --- a/samples/Style/TTStyleCatalog/Classes/StyleView.m +++ b/samples/Style/TTStyleCatalog/Classes/StyleView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/StyleViewController.h b/samples/Style/TTStyleCatalog/Classes/StyleViewController.h index a64a0ea23b..c9d0093073 100644 --- a/samples/Style/TTStyleCatalog/Classes/StyleViewController.h +++ b/samples/Style/TTStyleCatalog/Classes/StyleViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Classes/StyleViewController.m b/samples/Style/TTStyleCatalog/Classes/StyleViewController.m index 98b857b97f..7018b5efe7 100644 --- a/samples/Style/TTStyleCatalog/Classes/StyleViewController.m +++ b/samples/Style/TTStyleCatalog/Classes/StyleViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Configurations/App.xcconfig b/samples/Style/TTStyleCatalog/Configurations/App.xcconfig index 414f555630..2d70dac123 100644 --- a/samples/Style/TTStyleCatalog/Configurations/App.xcconfig +++ b/samples/Style/TTStyleCatalog/Configurations/App.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTStyleCatalog +BASE_PRODUCT_NAME = TTStyleCatalog +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/samples/Style/TTStyleCatalog/Configurations/Project.xcconfig b/samples/Style/TTStyleCatalog/Configurations/Project.xcconfig index 0f02ea7f79..fc1966a5f7 100644 --- a/samples/Style/TTStyleCatalog/Configurations/Project.xcconfig +++ b/samples/Style/TTStyleCatalog/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Configurations/RelPath.xcconfig b/samples/Style/TTStyleCatalog/Configurations/RelPath.xcconfig index 7510c4e4be..e869ea439f 100644 --- a/samples/Style/TTStyleCatalog/Configurations/RelPath.xcconfig +++ b/samples/Style/TTStyleCatalog/Configurations/RelPath.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/Configurations/UnitTests.xcconfig b/samples/Style/TTStyleCatalog/Configurations/UnitTests.xcconfig index 47cc39465d..1b2fd344db 100644 --- a/samples/Style/TTStyleCatalog/Configurations/UnitTests.xcconfig +++ b/samples/Style/TTStyleCatalog/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/Style/TTStyleCatalog/TTStyleCatalog.xcodeproj/project.pbxproj b/samples/Style/TTStyleCatalog/TTStyleCatalog.xcodeproj/project.pbxproj index 0fcecc0862..2f5c3ba6fc 100755 --- a/samples/Style/TTStyleCatalog/TTStyleCatalog.xcodeproj/project.pbxproj +++ b/samples/Style/TTStyleCatalog/TTStyleCatalog.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -12,6 +12,7 @@ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 665E980D12662D0C0025FA42 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 665E980C12662D0C0025FA42 /* Default@2x.png */; }; 6E37949111B9B63E0011C497 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37946E11B9B6300011C497 /* libThree20Core.a */; }; 6E37949211B9B63E0011C497 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37947411B9B6300011C497 /* libThree20Network.a */; }; 6E37949311B9B63F0011C497 /* libThree20Style.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37947A11B9B6300011C497 /* libThree20Style.a */; }; @@ -187,6 +188,7 @@ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 665E980C12662D0C0025FA42 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "../../Resources/Default@2x.png"; sourceTree = SOURCE_ROOT; }; 6E37945911B9B6300011C497 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../../../src/Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; 6E37945C11B9B6300011C497 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../../../src/Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; 6E37945F11B9B6300011C497 /* Three20Style.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Style.xcodeproj; path = ../../../src/Three20Style/Three20Style.xcodeproj; sourceTree = SOURCE_ROOT; }; @@ -285,6 +287,7 @@ 6E850F4E11B1761D0071A4FD /* Three20.bundle */, 6E8513D211B19B0E0071A4FD /* TTStyleCatalog-Info.plist */, 6E850FAC11B176F10071A4FD /* Default.png */, + 665E980C12662D0C0025FA42 /* Default@2x.png */, 6E850FAD11B176F10071A4FD /* Icon.png */, ); name = Resources; @@ -314,7 +317,7 @@ isa = PBXGroup; children = ( 6E37947411B9B6300011C497 /* libThree20Network.a */, - 6E37947611B9B6300011C497 /* UnitTests.octest */, + 6E37947611B9B6300011C497 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -323,7 +326,7 @@ isa = PBXGroup; children = ( 6E37947A11B9B6300011C497 /* libThree20Style.a */, - 6E37947C11B9B6300011C497 /* UnitTests.octest */, + 6E37947C11B9B6300011C497 /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -332,7 +335,7 @@ isa = PBXGroup; children = ( 6E37948011B9B6300011C497 /* libThree20UICommon.a */, - 6E37948211B9B6300011C497 /* UnitTests.octest */, + 6E37948211B9B6300011C497 /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -341,7 +344,7 @@ isa = PBXGroup; children = ( 6E37948611B9B6300011C497 /* libThree20UINavigator.a */, - 6E37948811B9B6300011C497 /* UnitTests.octest */, + 6E37948811B9B6300011C497 /* UINavigatorUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -350,7 +353,7 @@ isa = PBXGroup; children = ( 6E37948C11B9B6300011C497 /* libThree20UI.a */, - 6E37948E11B9B6300011C497 /* UnitTests.octest */, + 6E37948E11B9B6300011C497 /* UIUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -384,7 +387,7 @@ isa = PBXGroup; children = ( 6E850F8811B1762B0071A4FD /* libThree20.a */, - 6E850F8A11B1762B0071A4FD /* UnitTests.octest */, + 6E850F8A11B1762B0071A4FD /* Three20UnitTests.octest */, ); name = Products; sourceTree = ""; @@ -448,13 +451,13 @@ buildRules = ( ); dependencies = ( - 6E850F8D11B176330071A4FD /* PBXTargetDependency */, - 6E37949811B9B64D0011C497 /* PBXTargetDependency */, 6E37949A11B9B64D0011C497 /* PBXTargetDependency */, - 6E37949C11B9B64D0011C497 /* PBXTargetDependency */, + 6E37949811B9B64D0011C497 /* PBXTargetDependency */, 6E37949E11B9B64D0011C497 /* PBXTargetDependency */, + 6E37949C11B9B64D0011C497 /* PBXTargetDependency */, 6E3794A011B9B64D0011C497 /* PBXTargetDependency */, 6E3794A211B9B64D0011C497 /* PBXTargetDependency */, + 6E850F8D11B176330071A4FD /* PBXTargetDependency */, ); name = TTStyleCatalog; productName = TTStylePreview; @@ -466,9 +469,19 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTStyleCatalog" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -530,10 +543,10 @@ remoteRef = 6E37947311B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37947611B9B6300011C497 /* UnitTests.octest */ = { + 6E37947611B9B6300011C497 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E37947511B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -544,10 +557,10 @@ remoteRef = 6E37947911B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37947C11B9B6300011C497 /* UnitTests.octest */ = { + 6E37947C11B9B6300011C497 /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E37947B11B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -558,10 +571,10 @@ remoteRef = 6E37947F11B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37948211B9B6300011C497 /* UnitTests.octest */ = { + 6E37948211B9B6300011C497 /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6E37948111B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -572,10 +585,10 @@ remoteRef = 6E37948511B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37948811B9B6300011C497 /* UnitTests.octest */ = { + 6E37948811B9B6300011C497 /* UINavigatorUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UINavigatorUnitTests.octest; remoteRef = 6E37948711B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -586,10 +599,10 @@ remoteRef = 6E37948B11B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37948E11B9B6300011C497 /* UnitTests.octest */ = { + 6E37948E11B9B6300011C497 /* UIUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UIUnitTests.octest; remoteRef = 6E37948D11B9B6300011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -600,10 +613,10 @@ remoteRef = 6E850F8711B1762B0071A4FD /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E850F8A11B1762B0071A4FD /* UnitTests.octest */ = { + 6E850F8A11B1762B0071A4FD /* Three20UnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = Three20UnitTests.octest; remoteRef = 6E850F8911B1762B0071A4FD /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -617,6 +630,7 @@ 6E850F4F11B1761D0071A4FD /* Three20.bundle in Resources */, 6E850FAE11B176F10071A4FD /* Default.png in Resources */, 6E850FAF11B176F10071A4FD /* Icon.png in Resources */, + 665E980D12662D0C0025FA42 /* Default@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -685,8 +699,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - INFOPLIST_FILE = "TTStyleCatalog-Info.plist"; - SDKROOT = iphoneos3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -695,8 +708,7 @@ baseConfigurationReference = 6E850F4811B175FD0071A4FD /* App.xcconfig */; buildSettings = { COPY_PHASE_STRIP = YES; - INFOPLIST_FILE = "TTStyleCatalog-Info.plist"; - SDKROOT = iphoneos3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -704,13 +716,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E850F4911B175FD0071A4FD /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.1.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -718,13 +728,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E850F4911B175FD0071A4FD /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.1.2; + SDKROOT = iphoneos; }; name = Release; }; diff --git a/samples/Style/TTStyleCatalog/main.m b/samples/Style/TTStyleCatalog/main.m index 3292416c2b..e0f8c871de 100644 --- a/samples/Style/TTStyleCatalog/main.m +++ b/samples/Style/TTStyleCatalog/main.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTCatalog/Classes/AppDelegate.m b/samples/TTCatalog/Classes/AppDelegate.m index 1987b63f2b..583203828a 100644 --- a/samples/TTCatalog/Classes/AppDelegate.m +++ b/samples/TTCatalog/Classes/AppDelegate.m @@ -1,4 +1,5 @@ #import "AppDelegate.h" +#import "SplitCatalogController.h" #import "CatalogController.h" #import "PhotoTest1Controller.h" #import "PhotoTest2Controller.h" @@ -6,9 +7,12 @@ #import "TableImageTestController.h" #import "YouTubeTestController.h" #import "TableItemTestController.h" +#import "TableItemGroupedTestController.h" #import "TableControlsTestController.h" #import "TableTestController.h" +#import "TableWithBannerController.h" #import "TableWithShadowController.h" +#import "TableDragRefreshController.h" #import "SearchTestController.h" #import "MessageTestController.h" #import "ActivityTestController.h" @@ -19,6 +23,7 @@ #import "StyleTestController.h" #import "ButtonTestController.h" #import "TabBarTestController.h" +#import "DownloadProgressTestController.h" @implementation AppDelegate @@ -32,27 +37,159 @@ - (void)applicationDidFinishLaunching:(UIApplication*)application { TTURLMap* map = navigator.URLMap; [map from:@"*" toViewController:[TTWebController class]]; - [map from:@"tt://catalog" toViewController:[CatalogController class]]; - [map from:@"tt://photoTest1" toViewController:[PhotoTest1Controller class]]; - [map from:@"tt://photoTest2" toViewController:[PhotoTest2Controller class]]; - [map from:@"tt://imageTest1" toViewController:[ImageTest1Controller class]]; - [map from:@"tt://tableTest" toViewController:[TableTestController class]]; - [map from:@"tt://tableItemTest" toViewController:[TableItemTestController class]]; - [map from:@"tt://tableControlsTest" toViewController:[TableControlsTestController class]]; - [map from:@"tt://styledTextTableTest" toViewController:[StyledTextTableTestController class]]; - [map from:@"tt://tableWithShadow" toViewController:[TableWithShadowController class]]; - [map from:@"tt://composerTest" toViewController:[MessageTestController class]]; - [map from:@"tt://searchTest" toViewController:[SearchTestController class]]; - [map from:@"tt://activityTest" toViewController:[ActivityTestController class]]; - [map from:@"tt://styleTest" toViewController:[StyleTestController class]]; - [map from:@"tt://styledTextTest" toViewController:[StyledTextTestController class]]; - [map from:@"tt://buttonTest" toViewController:[ButtonTestController class]]; - [map from:@"tt://tabBarTest" toViewController:[TabBarTestController class]]; - [map from:@"tt://youTubeTest" toViewController:[YouTubeTestController class]]; - [map from:@"tt://imageTest2" toViewController:[TableImageTestController class]]; - [map from:@"tt://scrollViewTest" toViewController:[ScrollViewTestController class]]; - [map from:@"tt://launcherTest" toViewController:[LauncherViewTestController class]]; + + if (TTIsPad()) { + [map from: @"tt://catalog" + toSharedViewController: [SplitCatalogController class]]; + + SplitCatalogController* controller = + (SplitCatalogController*)[[TTNavigator navigator] viewControllerForURL:@"tt://catalog"]; + TTDASSERT([controller isKindOfClass:[SplitCatalogController class]]); + map = controller.rightNavigator.URLMap; + + } else { + [map from: @"tt://catalog" + toSharedViewController: [CatalogController class]]; + } + + [map from: @"tt://photoTest1" + parent: @"tt://catalog" + toViewController: [PhotoTest1Controller class] + selector: nil + transition: 0]; + [map from: @"tt://photoTest2" + parent: @"tt://catalog" + toViewController: [PhotoTest2Controller class] + selector: nil + transition: 0]; + + [map from: @"tt://imageTest1" + parent: @"tt://catalog" + toViewController: [ImageTest1Controller class] + selector: nil + transition: 0]; + + [map from: @"tt://tableTest" + parent: @"tt://catalog" + toViewController: [TableTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://tableItemTest" + parent: @"tt://catalog" + toViewController: [TableItemTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://tableItemGroupedTest" + parent: @"tt://catalog" + toViewController: [TableItemGroupedTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://tableControlsTest" + parent: @"tt://catalog" + toViewController: [TableControlsTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://styledTextTableTest" + parent: @"tt://catalog" + toViewController: [StyledTextTableTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://tableWithShadow" + parent: @"tt://catalog" + toViewController: [TableWithShadowController class] + selector: nil + transition: 0]; + + [map from: @"tt://tableWithBanner" + parent: @"tt://catalog" + toViewController: [TableWithBannerController class] + selector: nil + transition: 0]; + + [map from: @"tt://tableDragRefresh" + parent: @"tt://catalog" + toViewController: [TableDragRefreshController class] + selector: nil + transition: 0]; + + [map from: @"tt://composerTest" + parent: @"tt://catalog" + toViewController: [MessageTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://searchTest" + parent: @"tt://catalog" + toViewController: [SearchTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://activityTest" + parent: @"tt://catalog" + toViewController: [ActivityTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://styleTest" + parent: @"tt://catalog" + toViewController: [StyleTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://styledTextTest" + parent: @"tt://catalog" + toViewController: [StyledTextTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://buttonTest" + parent: @"tt://catalog" + toViewController: [ButtonTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://tabBarTest" + parent: @"tt://catalog" + toViewController: [TabBarTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://youTubeTest" + parent: @"tt://catalog" + toViewController: [YouTubeTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://imageTest2" + parent: @"tt://catalog" + toViewController: [TableImageTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://scrollViewTest" + parent: @"tt://catalog" + toViewController: [ScrollViewTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://launcherTest" + parent: @"tt://catalog" + toViewController: [LauncherViewTestController class] + selector: nil + transition: 0]; + + [map from: @"tt://dlprogress" + parent: @"tt://catalog" + toViewController: [DownloadProgressTestController class] + selector: nil + transition: 0]; + if (![navigator restoreViewControllers]) { [navigator openURLAction:[TTURLAction actionWithURLPath:@"tt://catalog"]]; } diff --git a/samples/TTCatalog/Classes/ButtonTestController.m b/samples/TTCatalog/Classes/ButtonTestController.m index 4740636f21..15f8c97c03 100644 --- a/samples/TTCatalog/Classes/ButtonTestController.m +++ b/samples/TTCatalog/Classes/ButtonTestController.m @@ -78,6 +78,18 @@ - (TTStyle*)dropButton:(UIControlState)state { } } +- (TTStyle*)remoteAvatarButton:(UIControlState)state { + if (state == UIControlStateHighlighted) { + return [TTSolidFillStyle styleWithColor:[UIColor whiteColor] next:nil]; + } else { + return [TTImageStyle styleWithImageURL:nil + defaultImage:[UIImage imageNamed:@"defaultPerson.png"] + contentMode:UIViewContentModeCenter + size:CGSizeMake(50, 50) + next:nil]; + } +} + @end @implementation ButtonTestController @@ -142,6 +154,9 @@ - (void)loadView { scrollView.delaysContentTouches = NO; self.view = scrollView; + TTButton* remoteAvatarButton = [TTButton buttonWithStyle:@"remoteAvatarButton:"]; + [remoteAvatarButton setImage:@"url" forState:UIControlStateNormal]; + NSArray* buttons = [NSArray arrayWithObjects: [TTButton buttonWithStyle:@"toolbarButton:" title:@"Toolbar Button"], [TTButton buttonWithStyle:@"toolbarRoundButton:" title:@"Round Button"], @@ -152,6 +167,7 @@ - (void)loadView { [TTButton buttonWithStyle:@"blueToolbarButton:" title:@"Blue Button"], [TTButton buttonWithStyle:@"embossedButton:" title:@"Embossed Button"], [TTButton buttonWithStyle:@"dropButton:" title:@"Shadow Button"], + remoteAvatarButton, nil]; for (TTButton* button in buttons) { diff --git a/samples/TTCatalog/Classes/CatalogController.m b/samples/TTCatalog/Classes/CatalogController.m index 5141e98a6b..2feb79c6d2 100644 --- a/samples/TTCatalog/Classes/CatalogController.m +++ b/samples/TTCatalog/Classes/CatalogController.m @@ -37,10 +37,13 @@ - (void)createModel { @"Tables", [TTTableTextItem itemWithText:@"Table Items" URL:@"tt://tableItemTest"], + [TTTableTextItem itemWithText:@"Table Items Grouped" URL:@"tt://tableItemGroupedTest"], [TTTableTextItem itemWithText:@"Table Controls" URL:@"tt://tableControlsTest"], [TTTableTextItem itemWithText:@"Styled Labels in Table" URL:@"tt://styledTextTableTest"], [TTTableTextItem itemWithText:@"Web Images in Table" URL:@"tt://imageTest2"], + [TTTableTextItem itemWithText:@"Table With Banner" URL:@"tt://tableWithBanner"], [TTTableTextItem itemWithText:@"Table With Shadow" URL:@"tt://tableWithShadow"], + [TTTableTextItem itemWithText:@"Table With Drag Refresh" URL:@"tt://tableDragRefresh"], @"Models", [TTTableTextItem itemWithText:@"Model Search" URL:@"tt://searchTest"], @@ -51,6 +54,7 @@ - (void)createModel { [TTTableTextItem itemWithText:@"YouTube Player" URL:@"tt://youTubeTest"], [TTTableTextItem itemWithText:@"Web Browser" URL:@"http://github.com/joehewitt/three20"], [TTTableTextItem itemWithText:@"Activity Labels" URL:@"tt://activityTest"], + [TTTableTextItem itemWithText:@"Download Progress" URL:@"tt://dlprogress"], [TTTableTextItem itemWithText:@"Scroll View" URL:@"tt://scrollViewTest"], [TTTableTextItem itemWithText:@"Launcher" URL:@"tt://launcherTest"], nil]; diff --git a/samples/TTCatalog/Classes/DownloadProgressTestController.h b/samples/TTCatalog/Classes/DownloadProgressTestController.h new file mode 100644 index 0000000000..2150205521 --- /dev/null +++ b/samples/TTCatalog/Classes/DownloadProgressTestController.h @@ -0,0 +1,10 @@ +#import + +@class DownloadTestModel; +@interface DownloadProgressTestController : TTViewController { + NSUInteger _defaultMaxContentLength; + TTActivityLabel *_activityLabel; + DownloadTestModel *_loadingModel; + NSTimer *_progressTimer; +} +@end diff --git a/samples/TTCatalog/Classes/DownloadProgressTestController.m b/samples/TTCatalog/Classes/DownloadProgressTestController.m new file mode 100644 index 0000000000..3dd1fb57bb --- /dev/null +++ b/samples/TTCatalog/Classes/DownloadProgressTestController.m @@ -0,0 +1,142 @@ +#import "DownloadProgressTestController.h" +#import +#import "DownloadTestModel.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DownloadProgressTestController + +static NSString* const k1MBDownloadUrl = @"http://cachefly.cachefly.net/1mb.test"; +static NSString* const k5MBDownloadUrl = @"http://cachefly.cachefly.net/5mb.test"; +static NSString* const k10MBDownloadUrl = @"http://cachefly.cachefly.net/10mb.test"; + +static NSString* const k1MBDownloadTitle = @"Download 1MB File"; +static NSString* const k5MBDownloadTitle = @"Download 5MB File"; +static NSString* const k10MBDownloadTitle = @"Download 10MB File"; +/////////////////////////////////////////////////////////////////////////////////////////////////// +// initiation + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self.title = @"Download Progress"; + } + return self; +} + +- (void)dealloc { + [super dealloc]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// private + +- (void)loadWithUrl:(NSString*)url { + TT_RELEASE_SAFELY(_loadingModel); + _loadingModel = [[DownloadTestModel alloc] init]; + [_loadingModel.delegates addObject: self]; + [_loadingModel setDownloadUrl: url]; + [_loadingModel load: TTURLRequestCachePolicyNoCache more: NO]; +} + +- (void)updateProgress:(NSTimer*)timer { + [_activityLabel setProgress: [_loadingModel downloadProgress]]; +} + +- (void)layout { + TTGridLayout *gridLayout = [[[TTGridLayout alloc] init] autorelease]; + [gridLayout setColumnCount: 1]; + [gridLayout setSpacing: 20.0f]; + [gridLayout setPadding: 10.0f]; + + CGSize size = [gridLayout layoutSubviews:self.view.subviews forView:self.view]; + + UIScrollView *scrollView = (UIScrollView*)self.view; + scrollView.contentSize = CGSizeMake(scrollView.width, size.height); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// UIViewController + +- (void)loadView { + [self setView: [[[UIScrollView alloc] initWithFrame:TTNavigationFrame()] autorelease]]; + [self.view setBackgroundColor: [UIColor groupTableViewBackgroundColor]]; + + TT_RELEASE_SAFELY(_activityLabel); + _activityLabel = [[TTActivityLabel alloc] initWithStyle: TTActivityLabelStyleBlackBezel]; + [_activityLabel setText: @"View Loaded"]; + [self.view addSubview: _activityLabel]; + + NSArray *buttons = [NSArray arrayWithObjects: + [TTButton buttonWithStyle:@"toolbarRoundButton:" title:k1MBDownloadTitle], + [TTButton buttonWithStyle:@"toolbarRoundButton:" title:k5MBDownloadTitle], + [TTButton buttonWithStyle:@"toolbarRoundButton:" title:k10MBDownloadTitle], + nil]; + for (TTButton* button in buttons) { + [button setFont: [UIFont systemFontOfSize: 16.0f]]; + [button sizeToFit]; + [button addTarget:self action:@selector(downloadButtonAction:) forControlEvents: UIControlEventTouchUpInside]; + [self.view addSubview: button]; + } + + [self layout]; +} + +- (void)viewDidAppear:(BOOL)animated { + _defaultMaxContentLength = [[TTURLRequestQueue mainQueue] maxContentLength]; + [[TTURLRequestQueue mainQueue] setMaxContentLength: 0]; + [[TTURLRequestQueue mainQueue] setSuspended: NO]; +} + +- (void)viewWillDisappear:(BOOL)animated { + TT_RELEASE_SAFELY(_loadingModel); + [[TTURLRequestQueue mainQueue] setMaxContentLength: _defaultMaxContentLength]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// public + +- (void)downloadButtonAction:(TTButton*)button { + if ([[button titleForState:UIControlStateNormal] isEqualToString:k1MBDownloadTitle]) { + [self loadWithUrl:k1MBDownloadUrl]; + } + else if ([[button titleForState:UIControlStateNormal] isEqualToString: k5MBDownloadTitle]) { + [self loadWithUrl:k5MBDownloadUrl]; + } + else if ([[button titleForState:UIControlStateNormal] isEqualToString: k10MBDownloadTitle]) { + [self loadWithUrl: k10MBDownloadUrl]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// TTURLRequestDelegate + + +- (void)modelDidStartLoad:(id )model { + TT_INVALIDATE_TIMER(_progressTimer); + _progressTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0f/24.0f) target:self selector:@selector(updateProgress:) userInfo:nil repeats: YES]; + [_activityLabel setText:@"Download Started"]; + [_activityLabel setProgress: 0.0f]; +} + +- (void)modelDidFinishLoad:(id )model { + TT_INVALIDATE_TIMER(_progressTimer); + [_activityLabel setText:@"Download Finished"]; + [_activityLabel setProgress: 1.0f]; +} + +- (void)model:(id )model didFailLoadWithError:(NSError *)error { + TT_INVALIDATE_TIMER(_progressTimer); + [_activityLabel setText:@"Download Failed"]; + [_activityLabel setProgress: 0.0f]; +} + +- (void)modelDidCancelLoad:(id )model { + TT_INVALIDATE_TIMER(_progressTimer); + [_activityLabel setText:@"Download Canceled"]; + [_activityLabel setProgress: 0.0f]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +@end diff --git a/samples/TTCatalog/Classes/DownloadTestModel.h b/samples/TTCatalog/Classes/DownloadTestModel.h new file mode 100644 index 0000000000..66d0cfe5be --- /dev/null +++ b/samples/TTCatalog/Classes/DownloadTestModel.h @@ -0,0 +1,10 @@ +#import + +@interface DownloadTestModel : TTURLRequestModel { + NSString *_downloadUrl; +} + +@property (nonatomic, assign) NSString* downloadUrl; + +@end + diff --git a/samples/TTCatalog/Classes/DownloadTestModel.m b/samples/TTCatalog/Classes/DownloadTestModel.m new file mode 100644 index 0000000000..7516e72ae8 --- /dev/null +++ b/samples/TTCatalog/Classes/DownloadTestModel.m @@ -0,0 +1,34 @@ +#import "DownloadTestModel.h" +#import + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DownloadTestModel + +@synthesize downloadUrl = _downloadUrl; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// initiation + +- (id)init { + if (self = [super init]) { + } + return self; +} + +- (void)dealloc { + TT_RELEASE_SAFELY(_downloadUrl); + [super dealloc]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// TTURLRequestModel + +- (void)load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more { + TTURLRequest *request = [[[TTURLRequest alloc] initWithURL: _downloadUrl delegate: self] autorelease]; + [request setResponse: [[[TTURLDataResponse alloc] init] autorelease]]; + [request setCachePolicy: cachePolicy]; + [request send]; +} + +@end diff --git a/samples/TTCatalog/Classes/ImageTest1Controller.m b/samples/TTCatalog/Classes/ImageTest1Controller.m index 54ef62e94c..bdac129313 100644 --- a/samples/TTCatalog/Classes/ImageTest1Controller.m +++ b/samples/TTCatalog/Classes/ImageTest1Controller.m @@ -3,6 +3,8 @@ @implementation ImageTest1Controller +static NSString * kDataUrlImage = @"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAEGxJREFUeNqMW2lvXOd1ft737sPhIpEURVHW5kiyC1uW5SZKa9d10cZJgKD9kqT9Bf0d/VSgRX9C+7GFmxZFUbSpYRSolyaO18iSFSlKTVILxU2khpzl7vf2w/A5c+5Qrj1AQGvmLmd5znOW98T85Rs/rz3PQ1VVqOsanuehLEuUZQnf9+G6LoqiAAAURSHXOY6Duq7hui7qukZZlnBdF2VZwnEcGGNQFIX87jgOkiSB67rgp6oqBEEg16VpKu+z1sIYgzzPEQQByrKEtRZ1XTdkTdMUxhjUdQ1jDADAdV1UVTV6ZhRFyLIM1lp5sbVWlE2SBMYYeJ4Ha60owuvqupa/AOTFnueJslTYWivXUrAsy+B5HoqiQF3XYjgKaa1FWZYN2QDI9zSa4zjI81ye77oujDHDe+gxXmitRVVV6PV6Yi1rLdI0BQB5MJUoy1IU1YJ6nicvyfP8kCA0VF3XKIpCDM17iI6qqmCMEU/yfUEQiOJVVYnsdESWZYIUa4xBv9+Xi3kjocqXuK4r1qFQFBAAfN+H4zgAgCAIkGUZ+v2+/M4PEQJA4EWhaQx6Oc9zQQLfy+cRYfxfVVViFMKe39nxB9MSVMAYIxBhjFBZz/Mkpvg949kYg1ar1YgRKsVnEQ2e54mntQEcxxHj89n8S+QYYxAEgcQ7w4ae9TwP1vM8tFotwXGapnAcR15I6xE+jDlCgl6mpTWkrbUIgkCQQQIiuWiPUXB6mrHFe6y1aLfbYryqqiSWB4NBgyv4O8nSpUuJe9/3GyTB+NCs6vs+8jyH7/tiZe31qqoaBgAgMa2FJjMS5jRQGIYSu77vI45jIRtrLZIkQavVQhzHDY/zXYSyxKkWREOAghK+QRBI2qAV8zxHVVXiwTzPUde1eE3HRxAEYKqiwq7rChnpVKXRxPsJxTRN4fs+9vb2hBSttQjDUOSmMSX8+B+aBIwxyLLsUCxRcHpS50lCzfM8YTZCTyPBGAPf92GtFfIKgqCR78IwlN/IDbw3iiLJnby33+83oM3QYny6zD2MKcYd45TQpVK0PF+kPU9FKACVJ/TIhFRApxL+Rm+laSrPobeIHM/zkCSJQHxqagrdblfu1zkcACzzGKHkOA4GgwHyPJe4ovcYyHVdI4oiSR3aiiQmxgOZTsdcq9WSeGWIaOQQfpSH7w3DUGKezzfGYDAYiEFoBBotz/MhuzJXBkEgcOLDdTrxPA9hGMp39C7hodHAf5OMNMGQ7gk/YwwmJiYakKYR+HwiIEkSFEUhZEMGJ0n5vi8Gs9YOjcGHEHo6DkjLVJxkxCRN6NJQjFvtIZ07dY6loAwHGoepizFFcmLdTOQQjmVZIssyuZ9Vjo5pSwswffBmPpR/SSaEH/HOPKqLcx3nYk1FbvQSDUh2p9CEueYDGoeK01ssRHRjkSSJyOF53jAmi6KQqkHXnjqeKBBJQqcLphNanIigVygchWDhrmtPGpBxOY4kPk93GlQ0DEMkSYIwDIUv+L48z0dlXRzH8hB6Nk1TUYq45ws9z4Pv+42yj6TA+NLe18lc51atnCYq8oKOSRqbBDOe/OM4lqoNAKIoGl6nE+qTekVdDelg5oPoRZIWez9d6zJ+mW5IYlRcQ6uuayRJIuUgiYUlJr/XSZ+lImObn36/PwwHem8wGEgK4EsEtlWBc4tHMN3yReH13R7WO4nEZpZlQk6MaxqA1l2an0bkD2Nr83EfcVY02i0qSgOQYEgsk60Qc1Mjdl/d3BOPUi6mNYaPtRYuH8Aqo6oqRFGENE0RBR5+95njeO70LELPwfin009xfWUb799aQ6vVktRAKydJgoXZaXzr/ALOn5hBMPaMzc4Any1v4eM7D8WoFJTsa4zBqflJXL24iNPHpg7JcG15C+/fWsP+IEVZlpIldDFg/uZfPq51ycZkPhEF+NErF3D8yAS+6nNvu4uffnIX3X4ssHQcBwszLfzolQuHlHuSoP/50RfSmqVpKqx6+ekFfP+3z/2/9yd5iZ+8exsPd7rCJ4z3Ayi7jeRsjEEYhvjjq+e+loIAcGp+ElfOzeGdG/cldmfaIX6oFHz38we4fX8HvbRE4Fo8fXwKr106hdB3cfncMeRljfdursk4pKoqnD8511DwnRv3cX31EdK8xPREgKsXF3HpzBxCz8GPX30Gf/vmdfSTrMH21lo4r//pn/8FcyTjY+loCy//1lJDkfduruE/PlrB2zfuY3ljD4FrMTfdkt+XZtv41f1d1GZIWq88u4il2TYA4L+u3cOnX2yhqIaIKaoaO70M97a7uLB0BK5jsTTbxvXlTdTGETlev3IGMxPDMcdPP7mL6yvbKMoh2ydZgZXNfVgDnJybhOtYJHmJ3cFo/sTnWOKX+ctai2dOHj2k4Id3NrDfj1GWJbb2Yvz7RyvY7Awa111cOiIjjAsHz1jd3MMvv9hsxBvT0PpuDx/+el3uP7MwLcXAVORJDN7b7uLG8oZkAbJ/mqb49IttJNmQUV84O9+ot8kNlmUTGbKqKpxZmG4Iv7zZbUzsmLdu399pXMecNhM5QlT3truSKpjraAgqyk/oj6Z0506MDL2y0REIk205OhmkubxjeiLA7NRoKsDc7jIx04tZlqHTT9Hpp/KS9UcdyWG6ZYoCr6FkWgyfNTkxMtLWXtyY3TCBM5+xANDVVZZlDTbf6WWN6R2nF8zj67s9XFg6AgBohy62O6PRZZ7ncNk/Mi6DIMC/frAiRUCaplIu6QnAyflpXDo731ByZauHMAyxsdvDP757G8YYbDzuSxJnBaUTt0bNdqcn12rSW9/poqoqab90h+I4Djq9UW+5eLSN1c09gWwURcNigDfqDpzQoBeqqsLVi4uw1mJuKjwUt29+vIx+PMxV8Dzcf9QTa2tSoyeSJEE7CvD8mTlJA6ube3Bddzg/ckce7idZo8piapAxTVk3QoZwlUqNNzOJ0oOMPRqhLEu8+tzJJ+aof/vF/2J5/bH0hhJjYSjPowCk91bo44cvnxdYfnD7ISpYGFM1Gm5CmgW5niLSm7o+ppOIFN/3h/0kyy7dz+nmVw+Cxz+h5+D1K2fwwtOL0pmQrVk4p2naUHAydPHj37uIhQNIXlvewi9uP5QSkPSvY5VlJ40WRdET45rf0UFFUcCN47hRAunaj0TBCdl7N9fgui6OTng4vTAtXpiZCPD9l06jF6dY2x3IHJTxq88zvnXhOK5eXEToD3//4NfrePv6vcZ79aEQ4RmGIXS6I8OOG4STPdbSaZoO4Up46OETO3DWtQDw8189EIh4jsGf/f6zWJgZFQSvXzmDv3vrc/EYW66qqjDb9vHdl87K9Xv9FG9+soKHj2OZsxJJlGNcUXqSnT+rK86fdEzqTsrVk2d6ZTIaDYKSAtjY2RvF0sFQNy4q3Li701ByuuVjfirEg+0hgbDV+Z1nlxrx/O7nD3Bj9RGSfOgRQlLHWJqXI2S5Vv6tOYJw9B1zKF8zJquqGubJPM/FmudPzOAPXjjdEOjh9mMp3rvdLjzPg+u6DermJwo8SdztKMB3XzqL8ydmAAB3t/bx1qer2O70JJlzXsuinF3M9n6CZw6eeWw6wtruoHF8x/41z3NMH5R+zMv6vKSqKljGAr/MyyZMLp48OrpYHY0ZY+A55kuLdmMMXn3+KVHwrV/exT/89010+mlj4ifwPyg2WPLFad7IfXp8wrEGIT0/FTZyLZHJowyrWyNrLTbG6tGFmRbOLEw3xpKE9uVzx57YdhljcOnsPC4d5MC/f/s2PlveQhAEkgfpOQpDBZMkgbUW9x71GjWtTiW6fm2FPk4f/L7XT7E/yISU5PiDFQ1zylZngNXNvYbgf/Ltb+DKN45jamJI28ePTOAH3zx7qIm9sfpIqPvbFxcF7huP+wI1xhILAh1D+rdHnR7ubu1LK3f53DHJf7r2fe35p4Tlrx0YkvrIsR9LNtKtMQYf/WazUW6FvovvvHga33nx9Jc3rlmB926uwfM8zLZ9iZPdbowTR6LGkGrEgJOiGAA83OmiqCAc8f6tNTHkH77wFFwL3Fobjjxmp1p48exso2L6/O6OjG44f6rrGuav//nDmglbD48unzuGP7p86ms1zUlW4Cf/cwdbnQGMMXjp6Xm8dunr3as/b7xzCw92+jJWTJIEz506iu991WQgK/DGO7ewvZ8I7Mkxxpghu7ItYeFbFAWuLW9hez/By88u4tT85JeOHe482MXPbq1jkOZS/4ZfMe74sk8URbA2RlVVMgO+s9FD72e/wTfPLzxxxvPZ8hY+vLOBnf1BY+eB8ej7Psxf/dMHtT531/NRstjc9AQWj7Yx1fIlT23vJ1jZ6DRqXj171eWWzlks0MmAURRBV116mE2Dl2U5LCyKDItH25LOVjf3RDEeyHLQrNdjXF1N6LKOlY4xBnuDDJ3+TiM9sPrQR9l68i5LCWPrL2TToigEkvxLpXQy1yNT13Vxd2v/UHcURZHkXb1FIn85GdCTaha5LIqZfFkC6lUV/Z2+V6+46CMG1peTk5OHRv+sTWmMKIpEkfHdHhqAh748E2F30mi1yHj8US838KLxcxAKw38T3nyxPr/QU219DY/J9Zif6YFN/PgpGBXVewq63qXD9LTedd2hJ7mMQO3HT680HLmoNL7rQyQQshREjzoZCrqB1utl+khAG47HcDru9VKFPi7US1AyF6KnWNVTUVpVn0FQsMFggFarJafRjDl9eMtD0/GDHX2mwvmSNANJIt5jQ8CuY7xk5JCKwzcSGxXV0w3Ll+j1M7qZ1Qcfxu94zMf4ohdIYBSQ7Ron42RVKipz0YM45PXa84Q2PUtiI7J4ukw5nrRcZakgj9o0YZBd9VkioUSFOarUnbgWins39Cxzsj6n1HtzFJYhRMgzFvkMhobuogh9HjtySCd7PGEYynk7lYrjWAhg/Py/UeWr7RFeo09+uZ6mSY6Eow9n9Fal67oYDAaNNRjdDPNaQp+hoxc3xIDMK+Mw0h+9kah38ZhK9IGrHk9QGL1nwN84p9H7cONLjIxN5mNNSoQs107ZyZDxdTNuuapC4tHn+iwKNLMyyBkPVVUhjmOZ2Wqo6a0Qvcs6fmKsv6fSvIdQ1yfRugvhkSPRqA+DhV0Z+CQHMqweIWp21Ce52vuEMK0/fnyuaZ+LgCwmAGB/f7+x6ka5KDQV1ovDOh0RKeSNoigQx/EohbBSIDPq0ouC0qt6g5k1pC4iaAxOyxiTTA1JkjRGnfRmq9UShVmi6V6ThKjnr3r0yOdQJl11WU0mevFIT6iptC4EiHm9dEiP8vs4jmUaIEfbiup1bqNAei1cI4YG57aXhrXePdBFhkw89ChQz06oNB9Ab+gNRz1w1mWYtj4F1MbUTEmvdrtdISl6YXxvnXHHTkh3PYSwXnhkXevStYSiLr9IyXpfTZdhegOLrKmtqPOn3qUlUehFJSKErZuuUfU6GmdAmpH1vJgcMRgMRrGt2yYKzhwGAK1Wq1EJ6RqSFQqR0G63G2cpOi/SMLolYw/IOGMhwUqLYUGo9/v90TbyAex1V8TNEaYVWTQkG3Hxln0docYlfH0Or9sdHc+a8fQyoe4YaBAqQ+VZsWgj6oTOooMTcyrCgoX/9wudooi+/xsAy+4QmddLQNUAAAAASUVORK5CYII="; + - (void)loadView { self.view = [[[UIView alloc] init] autorelease]; self.view.backgroundColor = [UIColor whiteColor]; @@ -12,6 +14,13 @@ - (void)loadView { imageView.autoresizesToImage = YES; imageView.urlPath = @"http://farm4.static.flickr.com/3163/3110335722_7a906f9d8b_m.jpg"; [self.view addSubview:imageView]; + + TTImageView* dataImageView = [[[TTImageView alloc] initWithFrame:CGRectMake(130, 200, 0, 0)] + autorelease]; + dataImageView.autoresizesToImage = YES; + dataImageView.urlPath = kDataUrlImage; + [self.view addSubview:dataImageView]; + } - (void)dealloc { diff --git a/samples/TTCatalog/Classes/LauncherViewTestController.m b/samples/TTCatalog/Classes/LauncherViewTestController.m index 14c98d0e8f..5e0d59e470 100644 --- a/samples/TTCatalog/Classes/LauncherViewTestController.m +++ b/samples/TTCatalog/Classes/LauncherViewTestController.m @@ -28,44 +28,60 @@ - (void)loadView { _launcherView.backgroundColor = [UIColor blackColor]; _launcherView.delegate = self; _launcherView.columnCount = 4; - _launcherView.pages = [NSArray arrayWithObjects: - [NSArray arrayWithObjects: - [[[TTLauncherItem alloc] initWithTitle:@"Button 1" + _launcherView.persistenceMode = TTLauncherPersistenceModeAll; + + if (![_launcherView restoreLauncherItems]) { + _launcherView.pages = [NSArray arrayWithObjects: + [NSArray arrayWithObjects: + [[[TTLauncherItem alloc] initWithTitle:@"Button 1" image:@"bundle://Icon.png" URL:nil canDelete:YES] autorelease], - [[[TTLauncherItem alloc] initWithTitle:@"Button 2" + [[[TTLauncherItem alloc] initWithTitle:@"Button 2" image:@"bundle://Icon.png" URL:nil canDelete:YES] autorelease], - [[[TTLauncherItem alloc] initWithTitle:@"Button 3" + [[[TTLauncherItem alloc] initWithTitle:@"Button 3" image:@"bundle://Icon.png" URL:@"fb://item3" canDelete:YES] autorelease], - [[[TTLauncherItem alloc] initWithTitle:@"Button 4" + [[[TTLauncherItem alloc] initWithTitle:@"Button 4" image:@"bundle://Icon.png" URL:@"fb://item4" canDelete:YES] autorelease], - [[[TTLauncherItem alloc] initWithTitle:@"Button 5" + [[[TTLauncherItem alloc] initWithTitle:@"Button 5" image:@"bundle://Icon.png" - URL:nil canDelete:YES] autorelease], - [[[TTLauncherItem alloc] initWithTitle:@"Button 6" + URL:@"fb://item5" canDelete:YES] autorelease], + [[[TTLauncherItem alloc] initWithTitle:@"Button 6" image:@"bundle://Icon.png" - URL:nil canDelete:YES] autorelease], - [[[TTLauncherItem alloc] initWithTitle:@"Button 7" + URL:@"fb://item6" canDelete:YES] autorelease], + [[[TTLauncherItem alloc] initWithTitle:@"Button 7" image:@"bundle://Icon.png" - URL:nil canDelete:YES] autorelease], - nil], - [NSArray arrayWithObjects: - [[[TTLauncherItem alloc] initWithTitle:@"Button 8" + URL:@"fb://item7" canDelete:YES] autorelease], + nil], + [NSArray arrayWithObjects: + [[[TTLauncherItem alloc] initWithTitle:@"Button 8" image:@"bundle://Icon.png" URL:nil canDelete:YES] autorelease], - [[[TTLauncherItem alloc] initWithTitle:@"Button 9" + [[[TTLauncherItem alloc] initWithTitle:@"Button 9" image:@"bundle://Icon.png" URL:nil canDelete:YES] autorelease], - nil], - nil - ]; + nil], + nil + ]; + } [self.view addSubview:_launcherView]; TTLauncherItem* item = [_launcherView itemWithURL:@"fb://item3"]; item.badgeNumber = 4; + + item = [_launcherView itemWithURL:@"fb://item4"]; + item.badgeNumber = 0; + + item = [_launcherView itemWithURL:@"fb://item5"]; + item.badgeValue = @"100!"; + + item = [_launcherView itemWithURL:@"fb://item6"]; + item.badgeValue = @"Off"; + + item = [_launcherView itemWithURL:@"fb://item7"]; + item.badgeNumber = 300; } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/samples/TTCatalog/Classes/MessageTestController.m b/samples/TTCatalog/Classes/MessageTestController.m index 4bb719c913..bee8d24a57 100644 --- a/samples/TTCatalog/Classes/MessageTestController.m +++ b/samples/TTCatalog/Classes/MessageTestController.m @@ -21,7 +21,10 @@ - (UIViewController*)composeTo:(NSString*)recipient { } - (UIViewController*)post:(NSDictionary*)query { - TTPostController* controller = [[[TTPostController alloc] init] autorelease]; + TTPostController* controller = [[[TTPostController alloc] initWithNavigatorURL:nil + query: + [NSDictionary dictionaryWithObjectsAndKeys:@"Default Text", @"text", nil]] + autorelease]; controller.originView = [query objectForKey:@"__target__"]; return controller; } diff --git a/samples/TTCatalog/Classes/MockDataSource.h b/samples/TTCatalog/Classes/MockDataSource.h index f7db88b111..9f98b0e995 100644 --- a/samples/TTCatalog/Classes/MockDataSource.h +++ b/samples/TTCatalog/Classes/MockDataSource.h @@ -1,21 +1,28 @@ #import +/* + * a searchable model which can be configured with a + * loading and/or search time + */ @interface MockAddressBook : NSObject { NSMutableArray* _delegates; NSMutableArray* _names; NSArray* _allNames; NSTimer* _fakeSearchTimer; NSTimeInterval _fakeSearchDuration; + NSTimer* _fakeLoadingTimer; + NSTimeInterval _fakeLoadingDuration; } @property(nonatomic,retain) NSArray* names; @property(nonatomic) NSTimeInterval fakeSearchDuration; +@property(nonatomic) NSTimeInterval fakeLoadingDuration; + (NSMutableArray*)fakeNames; - (id)initWithNames:(NSArray*)names; -- (void)loadNames; + - (void)search:(NSString*)text; @end diff --git a/samples/TTCatalog/Classes/MockDataSource.m b/samples/TTCatalog/Classes/MockDataSource.m index 4d470cdfb5..44f307f2de 100644 --- a/samples/TTCatalog/Classes/MockDataSource.m +++ b/samples/TTCatalog/Classes/MockDataSource.m @@ -1,11 +1,15 @@ #import "MockDataSource.h" +@interface MockAddressBook () +- (void) loadNames; +@end + /////////////////////////////////////////////////////////////////////////////////////////////////// @implementation MockAddressBook -@synthesize names = _names, fakeSearchDuration = _fakeSearchDuration; +@synthesize names = _names, fakeSearchDuration = _fakeSearchDuration, fakeLoadingDuration = _fakeLoadingDuration; /////////////////////////////////////////////////////////////////////////////////////////////////// // class public @@ -356,6 +360,7 @@ - (id)initWithNames:(NSArray*)names { - (void)dealloc { TT_INVALIDATE_TIMER(_fakeSearchTimer); + TT_INVALIDATE_TIMER(_fakeLoadingTimer) TT_RELEASE_SAFELY(_delegates); TT_RELEASE_SAFELY(_allNames); TT_RELEASE_SAFELY(_names); @@ -385,14 +390,32 @@ - (BOOL)isLoaded { } - (BOOL)isLoading { - return !!_fakeSearchTimer; + return !!_fakeSearchTimer || !!_fakeLoadingTimer; } - (BOOL)isEmpty { return !_names.count; } +- (void) fakeLoadingReady { + _fakeLoadingTimer = nil; + + [self loadNames]; + + [_delegates perform:@selector(modelDidFinishLoad:) withObject:self]; +} + - (void)load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more { + [_delegates perform:@selector(modelDidStartLoad:) withObject:self]; + if (_fakeLoadingDuration) { + TT_INVALIDATE_TIMER(_fakeLoadingTimer); + _fakeLoadingTimer = [NSTimer scheduledTimerWithTimeInterval:_fakeLoadingDuration target:self + selector:@selector(fakeLoadingReady) userInfo:nil repeats:NO]; + [_delegates perform:@selector(modelDidStartLoad:) withObject:self]; + } else { + [self loadNames]; + [_delegates perform:@selector(modelDidFinishLoad:) withObject:self]; + } } - (void)invalidate:(BOOL)erase { @@ -402,6 +425,9 @@ - (void)cancel { if (_fakeSearchTimer) { TT_INVALIDATE_TIMER(_fakeSearchTimer); [_delegates perform:@selector(modelDidCancelLoad:) withObject:self]; + } else if(_fakeLoadingTimer) { + TT_INVALIDATE_TIMER(_fakeLoadingTimer); + [_delegates perform:@selector(modelDidCancelLoad:) withObject:self]; } } @@ -416,6 +442,7 @@ - (void)loadNames { - (void)search:(NSString*)text { [self cancel]; + TT_RELEASE_SAFELY(_names); if (text.length) { if (_fakeSearchDuration) { TT_INVALIDATE_TIMER(_fakeSearchTimer); @@ -427,7 +454,6 @@ - (void)search:(NSString*)text { [_delegates perform:@selector(modelDidFinishLoad:) withObject:self]; } } else { - TT_RELEASE_SAFELY(_names); [_delegates perform:@selector(modelDidChange:) withObject:self]; } } @@ -446,7 +472,6 @@ @implementation MockDataSource - (id)init { if (self = [super init]) { _addressBook = [[MockAddressBook alloc] initWithNames:[MockAddressBook fakeNames]]; - [_addressBook loadNames]; self.model = _addressBook; } return self; @@ -473,7 +498,7 @@ - (void)tableViewDidLoadModel:(UITableView*)tableView { NSMutableDictionary* groups = [NSMutableDictionary dictionary]; for (NSString* name in _addressBook.names) { - NSString* letter = [NSString stringWithFormat:@"%c", [name characterAtIndex:0]]; + NSString* letter = [NSString stringWithFormat:@"%C", [name characterAtIndex:0]]; NSMutableArray* section = [groups objectForKey:letter]; if (!section) { section = [NSMutableArray array]; @@ -492,6 +517,10 @@ - (void)tableViewDidLoadModel:(UITableView*)tableView { } } +- (id)model { + return _addressBook; +} + @end /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/samples/TTCatalog/Classes/PhotoTest2Controller.m b/samples/TTCatalog/Classes/PhotoTest2Controller.m index 21d1f27476..28fb223425 100644 --- a/samples/TTCatalog/Classes/PhotoTest2Controller.m +++ b/samples/TTCatalog/Classes/PhotoTest2Controller.m @@ -4,13 +4,13 @@ @implementation PhotoTest2Controller - (void)viewDidLoad { - self.photoSource = [[MockPhotoSource alloc] + self.photoSource = [[[MockPhotoSource alloc] initWithType:MockPhotoSourceNormal //initWithType:MockPhotoSourceDelayed // initWithType:MockPhotoSourceLoadError // initWithType:MockPhotoSourceDelayed|MockPhotoSourceLoadError title:@"Flickr Photos" - photos:[[NSArray alloc] initWithObjects: + photos:[NSArray arrayWithObjects: [[[MockPhoto alloc] initWithURL:@"http://farm4.static.flickr.com/3246/2957580101_33c799fc09_o.jpg" smallURL:@"http://farm4.static.flickr.com/3246/2957580101_d63ef56b15_t.jpg" @@ -273,7 +273,7 @@ - (void)viewDidLoad { // smallURL:@"http://farm4.static.flickr.com/3280/2949707060_8139284ba5_t.jpg" // size:CGSizeMake(800, 533)] autorelease], // nil] - ]; + ] autorelease]; } @end diff --git a/samples/TTCatalog/Classes/ScrollViewTestController.h b/samples/TTCatalog/Classes/ScrollViewTestController.h index caab25716a..ab6f4877e9 100644 --- a/samples/TTCatalog/Classes/ScrollViewTestController.h +++ b/samples/TTCatalog/Classes/ScrollViewTestController.h @@ -1,7 +1,8 @@ #import -@interface ScrollViewTestController : TTViewController { +@interface ScrollViewTestController : TTViewController { TTScrollView* _scrollView; + TTPageControl* _pageControl; NSArray* _colors; } diff --git a/samples/TTCatalog/Classes/ScrollViewTestController.m b/samples/TTCatalog/Classes/ScrollViewTestController.m index 442c1c38d8..6e649c2dc9 100644 --- a/samples/TTCatalog/Classes/ScrollViewTestController.m +++ b/samples/TTCatalog/Classes/ScrollViewTestController.m @@ -9,33 +9,52 @@ - (void)dealloc { _scrollView.delegate = nil; _scrollView.dataSource = nil; TT_RELEASE_SAFELY(_scrollView); + TT_RELEASE_SAFELY(_pageControl); TT_RELEASE_SAFELY(_colors); [super dealloc]; } +- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nil bundle:nil]; + if ( self ){ + _colors = [[NSArray arrayWithObjects: + [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1], + [UIColor blueColor], + [UIColor redColor], + [UIColor yellowColor], + [UIColor orangeColor], + [UIColor cyanColor], + [UIColor purpleColor], + [UIColor brownColor], + [UIColor magentaColor], + [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1], + nil + ] retain]; + } + return self; +} + - (void)loadView { CGRect appFrame = [UIScreen mainScreen].applicationFrame; CGRect frame = CGRectMake(0, 0, appFrame.size.width, appFrame.size.height - 44); self.view = [[[UIView alloc] initWithFrame:frame] autorelease]; - - _scrollView = [[TTScrollView alloc] initWithFrame:self.view.bounds]; + + _pageControl = [[TTPageControl alloc] initWithFrame:CGRectMake(0,0, self.view.width, 20)]; + _pageControl.autoresizingMask = UIViewAutoresizingFlexibleWidth; + _pageControl.backgroundColor = [UIColor grayColor]; + _pageControl.currentPage = 0; + _pageControl.numberOfPages = [_colors count]; + [_pageControl addTarget:self action:@selector(changePage:) forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:_pageControl]; + + _scrollView = [[TTScrollView alloc] initWithFrame:CGRectMake(0,_pageControl.bottom, self.view.bounds.size.width, self.view.bounds.size.height - _pageControl.height - 5.f)]; + _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth; _scrollView.dataSource = self; + _scrollView.delegate = self; _scrollView.backgroundColor = [UIColor whiteColor]; [self.view addSubview:_scrollView]; - - _colors = [[NSArray arrayWithObjects: - [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1], - [UIColor blueColor], - [UIColor redColor], - [UIColor yellowColor], - [UIColor orangeColor], - [UIColor cyanColor], - [UIColor purpleColor], - [UIColor brownColor], - [UIColor magentaColor], - [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1], - nil - ] retain]; + + } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -61,7 +80,7 @@ - (UIView*)scrollView:(TTScrollView*)scrollView pageAtIndex:(NSInteger)pageIndex color2:[UIColor whiteColor] next: [TTSolidBorderStyle styleWithColor:[UIColor blueColor] width:1 next: nil]]]]; - + return pageView; } @@ -69,4 +88,29 @@ - (CGSize)scrollView:(TTScrollView*)scrollView sizeOfPageAtIndex:(NSInteger)page return CGSizeMake(320, 416); } +#pragma mark - +#pragma mark TTScrollViewDelegate + +- (void)scrollView:(TTScrollView*)scrollView didMoveToPageAtIndex:(NSInteger)pageIndex { + _pageControl.currentPage = pageIndex; +} + +#pragma mark - +#pragma mark UIViewController overrides +- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { + return YES; +} + +- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; +} + +#pragma mark - +#pragma mark TTPageControl + +- (IBAction)changePage:(id)sender { + int page = _pageControl.currentPage; + [_scrollView setCenterPageIndex:page]; +} + @end diff --git a/samples/TTCatalog/Classes/SplitCatalogController.h b/samples/TTCatalog/Classes/SplitCatalogController.h new file mode 100644 index 0000000000..88ea3dca21 --- /dev/null +++ b/samples/TTCatalog/Classes/SplitCatalogController.h @@ -0,0 +1,5 @@ + +@interface SplitCatalogController : TTSplitViewController { +} + +@end diff --git a/samples/TTCatalog/Classes/SplitCatalogController.m b/samples/TTCatalog/Classes/SplitCatalogController.m new file mode 100644 index 0000000000..35c054702f --- /dev/null +++ b/samples/TTCatalog/Classes/SplitCatalogController.m @@ -0,0 +1,89 @@ +#import "SplitCatalogController.h" + +#import "CatalogController.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface SplitCatalogController() + +- (void)setupURLRouting; + +@end + + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation SplitCatalogController + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + [self setupURLRouting]; + } + + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [self.leftNavigator openURLs:@"tt://catalog", nil]; + [self.rightNavigator openURLs:@"http://three20.info/", nil]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)willOpenUrlPath:(NSURL*)url { + [self.rightNavigator openURLAction:[TTURLAction actionWithURLPath:[url absoluteString]]]; + + [self.popoverSplitController dismissPopoverAnimated:YES]; + + // We need to do this because the right navigator clobbered the right navigation controller + // and our button along with it. + [self updateSplitViewButton]; + + // Don't create a view controller here; we're forwarding the URL routing. + return nil; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)routeLeftNavigator { + TTURLMap* map = self.leftNavigator.URLMap; + + // Forward all unhandled URL actions to the right navigator. + [map from: @"*" + toObject: self + selector: @selector(willOpenUrlPath:)]; + + [map from: @"tt://catalog" + toViewController: [CatalogController class]]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)routeRightNavigator { + TTURLMap* map = self.rightNavigator.URLMap; + + + [map from: @"*" + toViewController: [TTWebController class]]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setupURLRouting { + [self routeLeftNavigator]; + [self routeRightNavigator]; +} + + +@end + diff --git a/samples/TTCatalog/Classes/StyleTestController.m b/samples/TTCatalog/Classes/StyleTestController.m index 7b7a654cb9..87f80cf841 100644 --- a/samples/TTCatalog/Classes/StyleTestController.m +++ b/samples/TTCatalog/Classes/StyleTestController.m @@ -45,20 +45,49 @@ - (void)loadView { [TTSolidFillStyle styleWithColor:[UIColor whiteColor] next: [TTSolidBorderStyle styleWithColor:black width:1 next:nil]]], - // SpeechBubble - [TTShapeStyle styleWithShape:[TTSpeechBubbleShape shapeWithRadius:5 pointLocation:60 - pointAngle:90 - pointSize:CGSizeMake(20,10)] next: - [TTSolidFillStyle styleWithColor:[UIColor whiteColor] next: - [TTSolidBorderStyle styleWithColor:black width:1 next:nil]]], - - // SpeechBubble - [TTShapeStyle styleWithShape:[TTSpeechBubbleShape shapeWithRadius:5 pointLocation:290 - pointAngle:270 - pointSize:CGSizeMake(20,10)] next: - [TTSolidFillStyle styleWithColor:[UIColor whiteColor] next: - [TTSolidBorderStyle styleWithColor:black width:1 next:nil]]], - + // SpeechBubble with pointer left of the centre on the top edge + // Locations for top edge are 45 on the left, 90 in the centre, 134.999 on the right + [TTShapeStyle styleWithShape:[TTSpeechBubbleShape shapeWithRadius:5 + pointLocation:60 + pointAngle:90 + pointSize:CGSizeMake(20,10)] next: + [TTSolidFillStyle styleWithColor:[UIColor whiteColor] next: + [TTSolidBorderStyle styleWithColor:black width:1 next:nil]]], + + // SpeechBubble with pointer on the extreme left on the bottom edge + // Locations for bottom edge are 225 on the left, 270 in the centre, 314.999 on the left + [TTShapeStyle styleWithShape:[TTSpeechBubbleShape shapeWithRadius:5 + pointLocation:314 + pointAngle:270 + pointSize:CGSizeMake(20,10)] next: + [TTSolidFillStyle styleWithColor:[UIColor whiteColor] next: + [TTSolidBorderStyle styleWithColor:black width:1 next:nil]]], + + // SpeechBubble with pointer on the bottom of the left edge + // Locations for left edge are 315 on the bottom, 0 in the centre, 44.999 on top + [TTShapeStyle styleWithShape:[TTSpeechBubbleShape shapeWithRadius:5 + pointLocation:315 + pointAngle:0 + pointSize:CGSizeMake(10,20)] next: + [TTSolidFillStyle styleWithColor:[UIColor whiteColor] next: + [TTSolidBorderStyle styleWithColor:black width:1 next:nil]]], + + // SpeechBubble with pointer on the centre of the left edge + // Locations for left edge are 315 on the bottom, 0 in the centre, 44.999 on top + [TTShapeStyle styleWithShape:[TTSpeechBubbleShape shapeWithRadius:5 pointLocation:0 + pointAngle:0 + pointSize:CGSizeMake(20,10)] next: + [TTSolidFillStyle styleWithColor:[UIColor whiteColor] next: + [TTSolidBorderStyle styleWithColor:black width:1 next:nil]]], + + // SpeechBubble with pointer on the bottom of the right hand edge + // Locations for right edge are 135 on top, 180 in the middle, 314.999 on the bottom + [TTShapeStyle styleWithShape:[TTSpeechBubbleShape shapeWithRadius:5 pointLocation:224 + pointAngle:180 + pointSize:CGSizeMake(15,15)] next: + [TTSolidFillStyle styleWithColor:[UIColor whiteColor] next: + [TTSolidBorderStyle styleWithColor:black width:1 next:nil]]], + // Drop shadow [TTShapeStyle styleWithShape:[TTRoundedRectangleShape shapeWithRadius:10] next: [TTShadowStyle styleWithColor:RGBACOLOR(0,0,0,0.5) blur:5 offset:CGSizeMake(2, 2) next: @@ -121,9 +150,14 @@ - (void)loadView { [TTLinearGradientFillStyle styleWithColor1:RGBCOLOR(0, 180, 231) color2:RGBCOLOR(0, 0, 255) next:nil]], + // simple bottom only border + [TTShapeStyle styleWithShape:[TTRectangleShape shape] next: + [TTSolidFillStyle styleWithColor:RGBCOLOR(255, 255, 255) next: + [TTFourBorderStyle styleWithTop:nil right:nil bottom:black left:nil width:5 next:nil]]], + nil]; - CGFloat padding = 10; + CGFloat padding = 10.0f; CGFloat viewWidth = scrollView.width/2 - padding*2; CGFloat viewHeight = TT_ROW_HEIGHT; diff --git a/samples/TTCatalog/Classes/StyledTextTestController.m b/samples/TTCatalog/Classes/StyledTextTestController.m index e564541299..bf6fd1a775 100644 --- a/samples/TTCatalog/Classes/StyledTextTestController.m +++ b/samples/TTCatalog/Classes/StyledTextTestController.m @@ -51,10 +51,11 @@ - (TTStyle*)inlineBox2 { @implementation StyledTextTestController /////////////////////////////////////////////////////////////////////////////////////////////////// -// NSObject +// UIViewController -- (id)init { - if (self = [super init]) { +- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nil bundle:nil]; + if (self) { [TTStyleSheet setGlobalStyleSheet:[[[TextTestStyleSheet alloc] init] autorelease]]; } return self; @@ -113,6 +114,7 @@ - (void)loadView { label1.text = [TTStyledText textFromXHTML:kText lineBreaks:YES URLs:YES]; label1.contentInset = UIEdgeInsetsMake(10, 10, 10, 10); //label1.backgroundColor = [UIColor grayColor]; + //label1.textAlignment = UITextAlignmentCenter; [label1 sizeToFit]; [self.view addSubview:label1]; } diff --git a/samples/TTCatalog/Classes/TableDragRefreshController.h b/samples/TTCatalog/Classes/TableDragRefreshController.h new file mode 100644 index 0000000000..6dca7a9084 --- /dev/null +++ b/samples/TTCatalog/Classes/TableDragRefreshController.h @@ -0,0 +1,5 @@ +#import + +@interface TableDragRefreshController : TTTableViewController + +@end diff --git a/samples/TTCatalog/Classes/TableDragRefreshController.m b/samples/TTCatalog/Classes/TableDragRefreshController.m new file mode 100644 index 0000000000..b00ffd5e0c --- /dev/null +++ b/samples/TTCatalog/Classes/TableDragRefreshController.m @@ -0,0 +1,36 @@ + +#import "TableDragRefreshController.h" +#import "MockDataSource.h" + +@implementation TableDragRefreshController + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// private + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + } + return self; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// UIViewController + +- (void)loadView { + [super loadView]; +} + +- (void) createModel { + MockDataSource *ds = [[MockDataSource alloc] init]; + ds.addressBook.fakeLoadingDuration = 1.0; + self.dataSource = ds; + [ds release]; +} + +- (id)createDelegate { + return [[[TTTableViewDragRefreshDelegate alloc] initWithController:self] autorelease]; +} + +@end + diff --git a/samples/TTCatalog/Classes/TableItemGroupedTestController.h b/samples/TTCatalog/Classes/TableItemGroupedTestController.h new file mode 100644 index 0000000000..13f4b2e773 --- /dev/null +++ b/samples/TTCatalog/Classes/TableItemGroupedTestController.h @@ -0,0 +1,6 @@ +#import +#import "TableItemTestController.h" + +@interface TableItemGroupedTestController : TableItemTestController + +@end diff --git a/samples/TTCatalog/Classes/TableItemGroupedTestController.m b/samples/TTCatalog/Classes/TableItemGroupedTestController.m new file mode 100644 index 0000000000..fe80983b5f --- /dev/null +++ b/samples/TTCatalog/Classes/TableItemGroupedTestController.m @@ -0,0 +1,52 @@ +#import "TableItemGroupedTestController.h" +#import + +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface TableItemGroupedTestStyleSheet : TTDefaultStyleSheet +@end + +@implementation TableItemGroupedTestStyleSheet +- (TTStyle*)tableHeaderGrouped { + + UIColor* textColor = TTSTYLEVAR(tableTitleTextColor); + UIColor* labelColor = [UIColor whiteColor]; + int fontSize = 18; + + return + [TTShapeStyle styleWithShape:[TTRoundedRectangleShape shapeWithRadius:TT_ROUNDED] next: + [TTInsetStyle styleWithInset:UIEdgeInsetsMake(6, 10, 6, 100) next: + [TTSolidFillStyle styleWithColor:labelColor next: + [TTBoxStyle styleWithPadding:UIEdgeInsetsMake(5, 25, 5, 0) next: + [TTTextStyle styleWithFont:[UIFont boldSystemFontOfSize:fontSize] + color:textColor + textAlignment:UITextAlignmentLeft + next:nil]]]]]; +} +@end + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation TableItemGroupedTestController + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// NSObject + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self.title = @"Table Items Grouped"; + self.tableViewStyle = UITableViewStyleGrouped; + + // Uncomment this to see how the table cells look against a custom background color + //self.tableView.backgroundColor = [UIColor yellowColor]; + + [TTStyleSheet setGlobalStyleSheet:[[[TableItemGroupedTestStyleSheet alloc] init] autorelease]]; + } + return self; +} + +- (void)dealloc { + [TTStyleSheet setGlobalStyleSheet:nil]; + [super dealloc]; +} + +@end diff --git a/samples/TTCatalog/Classes/TableItemTestController.m b/samples/TTCatalog/Classes/TableItemTestController.m index 05924fd9e7..8c7f5d2ec1 100644 --- a/samples/TTCatalog/Classes/TableItemTestController.m +++ b/samples/TTCatalog/Classes/TableItemTestController.m @@ -21,8 +21,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil self.title = @"Table Items"; self.variableHeightRows = YES; - // Uncomment this to see how the table looks with the grouped style - //self.tableViewStyle = UITableViewStyleGrouped; + // comment this to see how the table looks with the standard style + self.tableViewStyle = UITableViewStyleGrouped; // Uncomment this to see how the table cells look against a custom background color //self.tableView.backgroundColor = [UIColor yellowColor]; @@ -34,9 +34,12 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil // This demonstrates how to create a table with standard table "fields". Many of these // fields with URLs that will be visited when the row is selected self.dataSource = [TTSectionedDataSource dataSourceWithObjects: - @"Links and Buttons", + @"Generic Items", + [TTTableSettingsItem itemWithText:Three20Version caption:@"Three20 Version" + URL:@"tt://tableItemTest"], [TTTableTextItem itemWithText:@"TTTableTextItem" URL:@"tt://tableItemTest" accessoryURL:@"http://www.google.com"], + [TTTableSection sectionWithHeaderTitle:@"Links & Buttons" footerTitle:nil], [TTTableLink itemWithText:@"TTTableLink" URL:@"tt://tableItemTest"], [TTTableButton itemWithText:@"TTTableButton"], [TTTableCaptionItem itemWithText:@"TTTableCaptionItem" caption:@"caption" @@ -47,7 +50,7 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil text:kLoremIpsum timestamp:[NSDate date] URL:@"tt://tableItemTest"], [TTTableMoreButton itemWithText:@"TTTableMoreButton"], - @"Images", + [TTTableSection sectionWithHeaderTitle:@"Images" footerTitle:@"Usage of images inside TTTableView"], [TTTableImageItem itemWithText:@"TTTableImageItem" imageURL:localImage URL:@"tt://tableItemTest"], [TTTableRightImageItem itemWithText:@"TTTableRightImageItem" imageURL:localImage @@ -61,7 +64,7 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil imageURL:remoteImage URL:@"tt://tableItemTest"], @"Static Text", - [TTTableTextItem itemWithText:@"TTTableItem"], + [TTTableTextItem itemWithText:@"TTTableTextItem"], [TTTableCaptionItem itemWithText:@"TTTableCaptionItem which wraps to several lines" caption:@"Text"], [TTTableSubtextItem itemWithText:@"TTTableSubtextItem" diff --git a/src/extThree20CSSStyle/Sources/TTDefaultCSSStyleSheet.h b/samples/TTCatalog/Classes/TableWithBannerController.h similarity index 52% rename from src/extThree20CSSStyle/Sources/TTDefaultCSSStyleSheet.h rename to samples/TTCatalog/Classes/TableWithBannerController.h index e0c6a76609..2f9f640697 100644 --- a/src/extThree20CSSStyle/Sources/TTDefaultCSSStyleSheet.h +++ b/samples/TTCatalog/Classes/TableWithBannerController.h @@ -14,24 +14,13 @@ // limitations under the License. // -#import "Three20Style/TTDefaultStyleSheet.h" +#import -@class TTCSSStyleSheet; +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface TableWithBannerController : TTTableViewController { -#define TTCSSBGCOLOR(selector) [[TTDefaultCSSStyleSheet globalCSSStyleSheet] \ - backgroundColorForCSSSelector:selector] - -@interface TTDefaultCSSStyleSheet : TTDefaultStyleSheet { -@private - TTCSSStyleSheet* _styleSheet; } -@property (nonatomic, readonly) TTCSSStyleSheet* styleSheet; - -- (BOOL)addStyleSheetFromDisk:(NSString*)filename; - -- (UIColor*)backgroundColorForCSSSelector:(NSString*)cssSelector; - -+ (TTDefaultCSSStyleSheet*)globalCSSStyleSheet; - @end diff --git a/samples/TTCatalog/Classes/TableWithBannerController.m b/samples/TTCatalog/Classes/TableWithBannerController.m new file mode 100644 index 0000000000..192056f6c5 --- /dev/null +++ b/samples/TTCatalog/Classes/TableWithBannerController.m @@ -0,0 +1,78 @@ +// +// Copyright 2009-2010 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "TableWithBannerController.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TableWithBannerController + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + } + return self; +} + +- (void) createModel { + //add enough items to see changes for content and scrollindicator insets + self.dataSource = + [TTListDataSource dataSourceWithObjects: + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + [TTTableTextItem itemWithText:@"Table Item"], + nil]; +} + +- (void) viewDidLoad { + [super viewDidLoad]; + + UIBarButtonItem *bannerItem = [[UIBarButtonItem alloc] initWithTitle:@"Toggle Banner" style:UIBarButtonItemStyleBordered target:self action:@selector(toggleBanner)]; + self.navigationItem.rightBarButtonItem = bannerItem; + [bannerItem release]; +} + +- (void) toggleBanner { + if(self.tableBannerView) { + [self setTableBannerView:nil animated:YES]; + } else { + //bannerview is adjusted by the TTTableView. it takes the full width + //and gets its height from TTStyleSheet + TTImageView *imageView = [[TTImageView alloc] initWithFrame:CGRectZero]; + [self setTableBannerView:imageView animated:YES]; + [imageView release]; + } +} +@end + diff --git a/samples/TTCatalog/Configurations/App.xcconfig b/samples/TTCatalog/Configurations/App.xcconfig index 173e0fd22c..50efa07749 100644 --- a/samples/TTCatalog/Configurations/App.xcconfig +++ b/samples/TTCatalog/Configurations/App.xcconfig @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTCatalog +BASE_PRODUCT_NAME = TTCatalog +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/samples/TTCatalog/Info.plist b/samples/TTCatalog/TTCatalog-Info.plist similarity index 91% rename from samples/TTCatalog/Info.plist rename to samples/TTCatalog/TTCatalog-Info.plist index 085e52f4dd..adcab91ebf 100644 --- a/samples/TTCatalog/Info.plist +++ b/samples/TTCatalog/TTCatalog-Info.plist @@ -11,7 +11,7 @@ CFBundleIconFile CFBundleIdentifier - com.facebook.${PRODUCT_NAME:identifier} + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/samples/TTCatalog/TTCatalog.xcodeproj/project.pbxproj b/samples/TTCatalog/TTCatalog.xcodeproj/project.pbxproj index c0bb65602e..a49140acd0 100755 --- a/samples/TTCatalog/TTCatalog.xcodeproj/project.pbxproj +++ b/samples/TTCatalog/TTCatalog.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -13,6 +13,61 @@ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; 28C286E10D94DF7D0034E888 /* CatalogController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* CatalogController.m */; }; + 664B27F612846A220008D569 /* TableWithBannerController.m in Sources */ = {isa = PBXBuildFile; fileRef = E46662FD127F91A4001A0F20 /* TableWithBannerController.m */; }; + 664DFEC112663122004C20C2 /* tableIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = BE6E4DBF0F46A352001CE9B4 /* tableIcon.png */; }; + 664DFEC212663122004C20C2 /* person.jpg in Resources */ = {isa = PBXBuildFile; fileRef = BECB1CC10F46AE9600AE5B52 /* person.jpg */; }; + 664DFEC312663122004C20C2 /* Three20.bundle in Resources */ = {isa = PBXBuildFile; fileRef = BEDCFBB30F4FFF820060B7D1 /* Three20.bundle */; }; + 664DFEC412663122004C20C2 /* smiley.png in Resources */ = {isa = PBXBuildFile; fileRef = BE3188A00F822E2C00E3067D /* smiley.png */; }; + 664DFEC512663122004C20C2 /* mask.png in Resources */ = {isa = PBXBuildFile; fileRef = BE1289C10F91811E00F65EA2 /* mask.png */; }; + 664DFEC612663122004C20C2 /* defaultPerson.png in Resources */ = {isa = PBXBuildFile; fileRef = BEA6BA7E101431DA00B83B3A /* defaultPerson.png */; }; + 664DFEC712663122004C20C2 /* defaultMusic.png in Resources */ = {isa = PBXBuildFile; fileRef = BEA6BAAC101436AC00B83B3A /* defaultMusic.png */; }; + 664DFEC812663122004C20C2 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E94C6AB116D98220012B12C /* Default.png */; }; + 664DFEC912663122004C20C2 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E94C6AC116D98220012B12C /* Icon.png */; }; + 664DFECB12663122004C20C2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 664DFECC12663122004C20C2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 664DFECD12663122004C20C2 /* CatalogController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* CatalogController.m */; }; + 664DFECE12663122004C20C2 /* MockPhotoSource.m in Sources */ = {isa = PBXBuildFile; fileRef = BE80E2490EAEFF6100743358 /* MockPhotoSource.m */; }; + 664DFECF12663122004C20C2 /* TableImageTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE80E3700EAF0F3000743358 /* TableImageTestController.m */; }; + 664DFED012663122004C20C2 /* ImageTest1Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = BE80E3A60EAF108500743358 /* ImageTest1Controller.m */; }; + 664DFED112663122004C20C2 /* ActivityTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE38E800EB288BA00189902 /* ActivityTestController.m */; }; + 664DFED212663122004C20C2 /* PhotoTest1Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE0FDDA0EB2A6850052C05F /* PhotoTest1Controller.m */; }; + 664DFED312663122004C20C2 /* PhotoTest2Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = BE5F25910EBA5F0400FD59A6 /* PhotoTest2Controller.m */; }; + 664DFED412663122004C20C2 /* YouTubeTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE8C0F7C0F2018C600EB0E98 /* YouTubeTestController.m */; }; + 664DFED512663122004C20C2 /* ScrollViewTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF6EC360F280CB300CF4096 /* ScrollViewTestController.m */; }; + 664DFED612663122004C20C2 /* TabBarTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE6E46EB0F4578BA001CE9B4 /* TabBarTestController.m */; }; + 664DFED712663122004C20C2 /* TableItemTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE6E4AA40F4655A4001CE9B4 /* TableItemTestController.m */; }; + 664DFED812663122004C20C2 /* MessageTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE341B30F480C76008C826E /* MessageTestController.m */; }; + 664DFED912663122004C20C2 /* SearchTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE346BB0F48F15C008C826E /* SearchTestController.m */; }; + 664DFEDA12663122004C20C2 /* MockDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE348AB0F490F43008C826E /* MockDataSource.m */; }; + 664DFEDB12663122004C20C2 /* TableTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE69B7580F62874900C02928 /* TableTestController.m */; }; + 664DFEDC12663122004C20C2 /* StyledTextTableTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF1991F0F818E720010D36E /* StyledTextTableTestController.m */; }; + 664DFEDD12663122004C20C2 /* StyledTextTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF199210F818E720010D36E /* StyledTextTestController.m */; }; + 664DFEDE12663122004C20C2 /* StyleTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE1288300F8973CD00F65EA2 /* StyleTestController.m */; }; + 664DFEDF12663122004C20C2 /* ButtonTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC5EC670F8C307E007622CD /* ButtonTestController.m */; }; + 664DFEE012663122004C20C2 /* TableControlsTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE20A49B0FF418B2008791F4 /* TableControlsTestController.m */; }; + 664DFEE112663122004C20C2 /* LauncherViewTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC787621040A430005C00CF /* LauncherViewTestController.m */; }; + 664DFEE212663122004C20C2 /* TableWithShadowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E002566116A6D1A00D1F0CB /* TableWithShadowController.m */; }; + 664DFEE412663122004C20C2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 664DFEE512663122004C20C2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 664DFEE612663122004C20C2 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 664DFEE712663122004C20C2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE1D84390F8D104B00EC8BB8 /* QuartzCore.framework */; }; + 664DFF261266315F004C20C2 /* libThree20Core-Xcode3.2.5.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 665E992912662FE30025FA42 /* libThree20Core-Xcode3.2.5.a */; }; + 664DFF271266315F004C20C2 /* libThree20Network-Xcode3.2.5.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 665E993612662FE30025FA42 /* libThree20Network-Xcode3.2.5.a */; }; + 664DFF281266315F004C20C2 /* libThree20Style-Xcode3.2.5.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 665E994312662FE30025FA42 /* libThree20Style-Xcode3.2.5.a */; }; + 664DFF291266315F004C20C2 /* libThree20UICommon-Xcode3.2.5.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 665E995012662FE30025FA42 /* libThree20UICommon-Xcode3.2.5.a */; }; + 664DFF2A1266315F004C20C2 /* libThree20UINavigator-Xcode3.2.5.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 665E995D12662FE30025FA42 /* libThree20UINavigator-Xcode3.2.5.a */; }; + 664DFF2B1266315F004C20C2 /* libThree20UI-Xcode3.2.5.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 665E996A12662FE30025FA42 /* libThree20UI-Xcode3.2.5.a */; }; + 664DFF2C1266315F004C20C2 /* libThree20-Xcode3.2.5.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 665E997712662FE30025FA42 /* libThree20-Xcode3.2.5.a */; }; + 666E183012944D23001C1D97 /* SplitCatalogController.m in Sources */ = {isa = PBXBuildFile; fileRef = 666E182F12944D23001C1D97 /* SplitCatalogController.m */; }; + 666E183112944D23001C1D97 /* SplitCatalogController.m in Sources */ = {isa = PBXBuildFile; fileRef = 666E182F12944D23001C1D97 /* SplitCatalogController.m */; }; + 6675F5F412945622008DE0A6 /* Default-Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 6675F5F012945622008DE0A6 /* Default-Landscape.png */; }; + 6675F5F512945622008DE0A6 /* Default-Portrait.png in Resources */ = {isa = PBXBuildFile; fileRef = 6675F5F112945622008DE0A6 /* Default-Portrait.png */; }; + 6675F5F612945622008DE0A6 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6675F5F212945622008DE0A6 /* Default@2x.png */; }; + 6675F5F712945622008DE0A6 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6675F5F312945622008DE0A6 /* Icon@2x.png */; }; + 6675F5F812945622008DE0A6 /* Default-Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 6675F5F012945622008DE0A6 /* Default-Landscape.png */; }; + 6675F5F912945622008DE0A6 /* Default-Portrait.png in Resources */ = {isa = PBXBuildFile; fileRef = 6675F5F112945622008DE0A6 /* Default-Portrait.png */; }; + 6675F5FA12945622008DE0A6 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6675F5F212945622008DE0A6 /* Default@2x.png */; }; + 6675F5FB12945622008DE0A6 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6675F5F312945622008DE0A6 /* Icon@2x.png */; }; 6E002567116A6D1A00D1F0CB /* TableWithShadowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E002566116A6D1A00D1F0CB /* TableWithShadowController.m */; }; 6E3794F511B9B6DB0011C497 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3794D411B9B6D70011C497 /* libThree20Core.a */; }; 6E3794F611B9B6DC0011C497 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3794DA11B9B6D70011C497 /* libThree20Network.a */; }; @@ -23,6 +78,10 @@ 6E7F97A9118E37C700443B46 /* libThree20.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E7F977E118E37BB00443B46 /* libThree20.a */; }; 6E94C6AD116D98220012B12C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E94C6AB116D98220012B12C /* Default.png */; }; 6E94C6AE116D98220012B12C /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E94C6AC116D98220012B12C /* Icon.png */; }; + 7000C4C0130CCAE3006D7ADE /* DownloadTestModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7000C4BE130CCAE3006D7ADE /* DownloadTestModel.m */; }; + 7000C4C1130CCAE3006D7ADE /* DownloadProgressTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7000C4BF130CCAE3006D7ADE /* DownloadProgressTestController.m */; }; + A96808E8131A91FB00EB3DAF /* TableItemGroupedTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = A96808E7131A91FB00EB3DAF /* TableItemGroupedTestController.m */; }; + A96808E9131A91FB00EB3DAF /* TableItemGroupedTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = A96808E7131A91FB00EB3DAF /* TableItemGroupedTestController.m */; }; BE1288310F8973CD00F65EA2 /* StyleTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE1288300F8973CD00F65EA2 /* StyleTestController.m */; }; BE1289C20F91811E00F65EA2 /* mask.png in Resources */ = {isa = PBXBuildFile; fileRef = BE1289C10F91811E00F65EA2 /* mask.png */; }; BE1D843A0F8D104B00EC8BB8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE1D84390F8D104B00EC8BB8 /* QuartzCore.framework */; }; @@ -51,9 +110,158 @@ BEF199220F818E720010D36E /* StyledTextTableTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF1991F0F818E720010D36E /* StyledTextTableTestController.m */; }; BEF199230F818E720010D36E /* StyledTextTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF199210F818E720010D36E /* StyledTextTestController.m */; }; BEF6EC370F280CB300CF4096 /* ScrollViewTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF6EC360F280CB300CF4096 /* ScrollViewTestController.m */; }; + E46662FE127F91A4001A0F20 /* TableWithBannerController.m in Sources */ = {isa = PBXBuildFile; fileRef = E46662FD127F91A4001A0F20 /* TableWithBannerController.m */; }; + E4D1D1D61306D2670090AE0C /* TableDragRefreshController.m in Sources */ = {isa = PBXBuildFile; fileRef = E4D1D1D51306D2670090AE0C /* TableDragRefreshController.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 664DFF181266314B004C20C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794C211B9B6D70011C497 /* Three20Network.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 662D81C912630516005851C2; + remoteInfo = "Three20Network-Xcode3.2.5"; + }; + 664DFF1A1266314B004C20C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E7F9752118E37BA00443B46 /* Three20.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 665A55C6126521740032D0BE; + remoteInfo = "Three20-Xcode3.2.5"; + }; + 664DFF1C1266314B004C20C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794CB11B9B6D70011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 665A541D1264DAF70032D0BE; + remoteInfo = "Three20UINavigator-Xcode3.2.5"; + }; + 664DFF1E1266314B004C20C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794C811B9B6D70011C497 /* Three20UICommon.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 665A53601264D54B0032D0BE; + remoteInfo = "Three20UICommon-Xcode3.2.5"; + }; + 664DFF201266314B004C20C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794C511B9B6D70011C497 /* Three20Style.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 66C16B6012639E2700A7825A; + remoteInfo = "Three20Style-Xcode3.2.5"; + }; + 664DFF221266314B004C20C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794CE11B9B6D70011C497 /* Three20UI.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 66FC2AB51264E3A400F56B19; + remoteInfo = "Three20UI-Xcode3.2.5"; + }; + 664DFF241266314B004C20C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794BF11B9B6D70011C497 /* Three20Core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 6650CA791262F6E2003FF804; + remoteInfo = "Three20Core-Xcode3.2.5"; + }; + 665E992812662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794BF11B9B6D70011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 6650CAA21262F6E2003FF804; + remoteInfo = "Three20Core-Xcode3.2.5"; + }; + 665E992C12662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794BF11B9B6D70011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 664961641262EE5000C2C80E; + remoteInfo = "Three20CoreUnitTests-Xcode3.2.5"; + }; + 665E993512662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794C211B9B6D70011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 662D81EF12630516005851C2; + remoteInfo = "Three20Network-Xcode3.2.5"; + }; + 665E993912662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794C211B9B6D70011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 662D81B2126304EB005851C2; + remoteInfo = "Three20NetworkUnitTests-Xcode3.2.5"; + }; + 665E994212662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794C511B9B6D70011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 66C16BE912639E2700A7825A; + remoteInfo = "Three20Style-Xcode3.2.5"; + }; + 665E994612662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794C511B9B6D70011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 66C16C0112639E4500A7825A; + remoteInfo = "Three20StyleUnitTests-Xcode3.2.5"; + }; + 665E994F12662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794C811B9B6D70011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 665A53761264D54B0032D0BE; + remoteInfo = "Three20UICommon-Xcode3.2.5"; + }; + 665E995312662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794C811B9B6D70011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 665A53891264D54B0032D0BE; + remoteInfo = "Three20UICommonUnitTests-Xcode3.2.5"; + }; + 665E995C12662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794CB11B9B6D70011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 665A54521264DAF70032D0BE; + remoteInfo = "Three20UINavigator-Xcode3.2.5"; + }; + 665E996012662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794CB11B9B6D70011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 665A54681264DAF70032D0BE; + remoteInfo = "Three20UINavigatorUnitTests-Xcode3.2.5"; + }; + 665E996912662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794CE11B9B6D70011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 66FC2BC81264E3A400F56B19; + remoteInfo = "Three20UI-Xcode3.2.5"; + }; + 665E996D12662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3794CE11B9B6D70011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 66FC2BE61264E3A500F56B19; + remoteInfo = "Three20UIUnitTests-Xcode3.2.5"; + }; + 665E997612662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E7F9752118E37BA00443B46 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 665A55DE126521740032D0BE; + remoteInfo = "Three20-Xcode3.2.5"; + }; + 665E997A12662FE30025FA42 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E7F9752118E37BA00443B46 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 665A55FB126521740032D0BE; + remoteInfo = "Three20UnitTests-Xcode3.2.5"; + }; 6E3794D311B9B6D70011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3794BF11B9B6D70011C497 /* Three20Core.xcodeproj */; @@ -213,6 +421,14 @@ 28C286DF0D94DF7D0034E888 /* CatalogController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CatalogController.h; sourceTree = ""; }; 28C286E00D94DF7D0034E888 /* CatalogController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CatalogController.m; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 664DFEF212663122004C20C2 /* TTCatalog-v3.2.5.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TTCatalog-v3.2.5.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 665E998712662FFA0025FA42 /* TTCatalog-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TTCatalog-Info.plist"; sourceTree = ""; }; + 666E182E12944D23001C1D97 /* SplitCatalogController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SplitCatalogController.h; sourceTree = ""; }; + 666E182F12944D23001C1D97 /* SplitCatalogController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SplitCatalogController.m; sourceTree = ""; }; + 6675F5F012945622008DE0A6 /* Default-Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-Landscape.png"; path = "../Resources/Default-Landscape.png"; sourceTree = SOURCE_ROOT; }; + 6675F5F112945622008DE0A6 /* Default-Portrait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-Portrait.png"; path = "../Resources/Default-Portrait.png"; sourceTree = SOURCE_ROOT; }; + 6675F5F212945622008DE0A6 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "../Resources/Default@2x.png"; sourceTree = SOURCE_ROOT; }; + 6675F5F312945622008DE0A6 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "../Resources/Icon@2x.png"; sourceTree = SOURCE_ROOT; }; 6E002565116A6D1A00D1F0CB /* TableWithShadowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableWithShadowController.h; sourceTree = ""; }; 6E002566116A6D1A00D1F0CB /* TableWithShadowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableWithShadowController.m; sourceTree = ""; }; 6E3794BF11B9B6D70011C497 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../../src/Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; @@ -229,7 +445,12 @@ 6E7F9964118E3A7600443B46 /* TTCatalog_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTCatalog_Prefix.pch; path = Headers/TTCatalog_Prefix.pch; sourceTree = ""; }; 6E94C6AB116D98220012B12C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = ../Resources/Default.png; sourceTree = SOURCE_ROOT; }; 6E94C6AC116D98220012B12C /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = ../Resources/Icon.png; sourceTree = SOURCE_ROOT; }; - 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7000C4BE130CCAE3006D7ADE /* DownloadTestModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DownloadTestModel.m; sourceTree = ""; }; + 7000C4BF130CCAE3006D7ADE /* DownloadProgressTestController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DownloadProgressTestController.m; sourceTree = ""; }; + 7000C4C2130CCB0F006D7ADE /* DownloadTestModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadTestModel.h; sourceTree = ""; }; + 7000C4C3130CCB0F006D7ADE /* DownloadProgressTestController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadProgressTestController.h; sourceTree = ""; }; + A96808E6131A91FB00EB3DAF /* TableItemGroupedTestController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableItemGroupedTestController.h; sourceTree = ""; }; + A96808E7131A91FB00EB3DAF /* TableItemGroupedTestController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableItemGroupedTestController.m; sourceTree = ""; }; BE12882F0F8973CD00F65EA2 /* StyleTestController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleTestController.h; sourceTree = ""; }; BE1288300F8973CD00F65EA2 /* StyleTestController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StyleTestController.m; sourceTree = ""; }; BE1289C10F91811E00F65EA2 /* mask.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mask.png; sourceTree = ""; }; @@ -278,6 +499,10 @@ BEF199210F818E720010D36E /* StyledTextTestController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StyledTextTestController.m; sourceTree = ""; }; BEF6EC350F280CB300CF4096 /* ScrollViewTestController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollViewTestController.h; sourceTree = ""; }; BEF6EC360F280CB300CF4096 /* ScrollViewTestController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScrollViewTestController.m; sourceTree = ""; }; + E46662FC127F91A4001A0F20 /* TableWithBannerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableWithBannerController.h; sourceTree = ""; }; + E46662FD127F91A4001A0F20 /* TableWithBannerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableWithBannerController.m; sourceTree = ""; }; + E4D1D1D41306D2670090AE0C /* TableDragRefreshController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableDragRefreshController.h; sourceTree = ""; }; + E4D1D1D51306D2670090AE0C /* TableDragRefreshController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableDragRefreshController.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -299,6 +524,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 664DFEE312663122004C20C2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 664DFF261266315F004C20C2 /* libThree20Core-Xcode3.2.5.a in Frameworks */, + 664DFF271266315F004C20C2 /* libThree20Network-Xcode3.2.5.a in Frameworks */, + 664DFF281266315F004C20C2 /* libThree20Style-Xcode3.2.5.a in Frameworks */, + 664DFF291266315F004C20C2 /* libThree20UICommon-Xcode3.2.5.a in Frameworks */, + 664DFF2A1266315F004C20C2 /* libThree20UINavigator-Xcode3.2.5.a in Frameworks */, + 664DFF2B1266315F004C20C2 /* libThree20UI-Xcode3.2.5.a in Frameworks */, + 664DFF2C1266315F004C20C2 /* libThree20-Xcode3.2.5.a in Frameworks */, + 664DFEE412663122004C20C2 /* Foundation.framework in Frameworks */, + 664DFEE512663122004C20C2 /* UIKit.framework in Frameworks */, + 664DFEE612663122004C20C2 /* CoreGraphics.framework in Frameworks */, + 664DFEE712663122004C20C2 /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -307,6 +550,8 @@ children = ( 1D3623240D0F684500981E51 /* AppDelegate.h */, 1D3623250D0F684500981E51 /* AppDelegate.m */, + 666E182E12944D23001C1D97 /* SplitCatalogController.h */, + 666E182F12944D23001C1D97 /* SplitCatalogController.m */, 28C286DF0D94DF7D0034E888 /* CatalogController.h */, 28C286E00D94DF7D0034E888 /* CatalogController.m */, EA1080F1101B37E90098AAC2 /* Photos */, @@ -324,6 +569,7 @@ isa = PBXGroup; children = ( 1D6058910D05DD3D006BFB54 /* TTCatalog.app */, + 664DFEF212663122004C20C2 /* TTCatalog-v3.2.5.app */, ); name = Products; sourceTree = ""; @@ -356,6 +602,10 @@ children = ( BEDCFBB30F4FFF820060B7D1 /* Three20.bundle */, 6E94C6AB116D98220012B12C /* Default.png */, + 6675F5F012945622008DE0A6 /* Default-Landscape.png */, + 6675F5F112945622008DE0A6 /* Default-Portrait.png */, + 6675F5F212945622008DE0A6 /* Default@2x.png */, + 6675F5F312945622008DE0A6 /* Icon@2x.png */, 6E94C6AC116D98220012B12C /* Icon.png */, BEA6BAAC101436AC00B83B3A /* defaultMusic.png */, BEA6BA7E101431DA00B83B3A /* defaultPerson.png */, @@ -363,7 +613,7 @@ BECB1CC10F46AE9600AE5B52 /* person.jpg */, BE3188A00F822E2C00E3067D /* smiley.png */, BE1289C10F91811E00F65EA2 /* mask.png */, - 8D1107310486CEB800E47090 /* Info.plist */, + 665E998712662FFA0025FA42 /* TTCatalog-Info.plist */, ); name = Resources; sourceTree = ""; @@ -392,7 +642,9 @@ isa = PBXGroup; children = ( 6E3794D411B9B6D70011C497 /* libThree20Core.a */, + 665E992912662FE30025FA42 /* libThree20Core-Xcode3.2.5.a */, 6E3794D611B9B6D70011C497 /* CoreUnitTests.octest */, + 665E992D12662FE30025FA42 /* CoreUnitTests-Xcode3.2.5.octest */, ); name = Products; sourceTree = ""; @@ -401,7 +653,9 @@ isa = PBXGroup; children = ( 6E3794DA11B9B6D70011C497 /* libThree20Network.a */, - 6E3794DC11B9B6D70011C497 /* UnitTests.octest */, + 665E993612662FE30025FA42 /* libThree20Network-Xcode3.2.5.a */, + 6E3794DC11B9B6D70011C497 /* NetworkUnitTests.octest */, + 665E993A12662FE30025FA42 /* NetworkUnitTests-Xcode3.2.5.octest */, ); name = Products; sourceTree = ""; @@ -410,7 +664,9 @@ isa = PBXGroup; children = ( 6E3794E011B9B6D70011C497 /* libThree20Style.a */, - 6E3794E211B9B6D70011C497 /* UnitTests.octest */, + 665E994312662FE30025FA42 /* libThree20Style-Xcode3.2.5.a */, + 6E3794E211B9B6D70011C497 /* StyleUnitTests.octest */, + 665E994712662FE30025FA42 /* StyleUnitTests-Xcode3.2.5.octest */, ); name = Products; sourceTree = ""; @@ -419,7 +675,9 @@ isa = PBXGroup; children = ( 6E3794E611B9B6D70011C497 /* libThree20UICommon.a */, - 6E3794E811B9B6D70011C497 /* UnitTests.octest */, + 665E995012662FE30025FA42 /* libThree20UICommon-Xcode3.2.5.a */, + 6E3794E811B9B6D70011C497 /* UICommonUnitTests.octest */, + 665E995412662FE30025FA42 /* UICommonUnitTests-Xcode3.2.5.octest */, ); name = Products; sourceTree = ""; @@ -428,7 +686,9 @@ isa = PBXGroup; children = ( 6E3794EC11B9B6D70011C497 /* libThree20UINavigator.a */, - 6E3794EE11B9B6D70011C497 /* UnitTests.octest */, + 665E995D12662FE30025FA42 /* libThree20UINavigator-Xcode3.2.5.a */, + 6E3794EE11B9B6D70011C497 /* UINavigatorUnitTests.octest */, + 665E996112662FE30025FA42 /* UINavigatorUnitTests-Xcode3.2.5.octest */, ); name = Products; sourceTree = ""; @@ -437,7 +697,9 @@ isa = PBXGroup; children = ( 6E3794F211B9B6D70011C497 /* libThree20UI.a */, - 6E3794F411B9B6D70011C497 /* UnitTests.octest */, + 665E996A12662FE30025FA42 /* libThree20UI-Xcode3.2.5.a */, + 6E3794F411B9B6D70011C497 /* UIUnitTests.octest */, + 665E996E12662FE30025FA42 /* UIUnitTests-Xcode3.2.5.octest */, ); name = Products; sourceTree = ""; @@ -460,7 +722,9 @@ isa = PBXGroup; children = ( 6E7F977E118E37BB00443B46 /* libThree20.a */, - 6E7F9780118E37BB00443B46 /* UnitTests.octest */, + 665E997712662FE30025FA42 /* libThree20-Xcode3.2.5.a */, + 6E7F9780118E37BB00443B46 /* Three20UnitTests.octest */, + 665E997B12662FE30025FA42 /* Three20UnitTests-Xcode3.2.5.octest */, ); name = Products; sourceTree = ""; @@ -484,6 +748,26 @@ name = Configurations; sourceTree = ""; }; + 7000C4B7130CCAC7006D7ADE /* Download Progress */ = { + isa = PBXGroup; + children = ( + 7000C4C2130CCB0F006D7ADE /* DownloadTestModel.h */, + 7000C4BE130CCAE3006D7ADE /* DownloadTestModel.m */, + 7000C4C3130CCB0F006D7ADE /* DownloadProgressTestController.h */, + 7000C4BF130CCAE3006D7ADE /* DownloadProgressTestController.m */, + ); + name = "Download Progress"; + sourceTree = ""; + }; + A96808E5131A91C400EB3DAF /* Table Items Grouped */ = { + isa = PBXGroup; + children = ( + A96808E6131A91FB00EB3DAF /* TableItemGroupedTestController.h */, + A96808E7131A91FB00EB3DAF /* TableItemGroupedTestController.m */, + ); + name = "Table Items Grouped"; + sourceTree = ""; + }; BEC7875C1040A405005C00CF /* Launcher */ = { isa = PBXGroup; children = ( @@ -493,6 +777,24 @@ name = Launcher; sourceTree = ""; }; + E46662F9127F916C001A0F20 /* Table with Banner */ = { + isa = PBXGroup; + children = ( + E46662FC127F91A4001A0F20 /* TableWithBannerController.h */, + E46662FD127F91A4001A0F20 /* TableWithBannerController.m */, + ); + name = "Table with Banner"; + sourceTree = ""; + }; + E4D1D1C41306D12D0090AE0C /* Table Drag Refresh */ = { + isa = PBXGroup; + children = ( + E4D1D1D41306D2670090AE0C /* TableDragRefreshController.h */, + E4D1D1D51306D2670090AE0C /* TableDragRefreshController.m */, + ); + name = "Table Drag Refresh"; + sourceTree = ""; + }; EA1080F1101B37E90098AAC2 /* Photos */ = { isa = PBXGroup; children = ( @@ -618,6 +920,7 @@ EA108141101B39510098AAC2 /* General */ = { isa = PBXGroup; children = ( + 7000C4B7130CCAC7006D7ADE /* Download Progress */, EA108148101B39660098AAC2 /* Web Image */, EA108149101B396A0098AAC2 /* YouTube Player */, EA10814F101B398C0098AAC2 /* Activity Labels */, @@ -666,10 +969,13 @@ isa = PBXGroup; children = ( EA108177101B3A630098AAC2 /* Table Items */, + A96808E5131A91C400EB3DAF /* Table Items Grouped */, EA108175101B3A5C0098AAC2 /* Table Controls */, EA108172101B3A4A0098AAC2 /* Styled Labels in Table */, EA108169101B3A3A0098AAC2 /* Web Images in Table */, + E46662F9127F916C001A0F20 /* Table with Banner */, 6E002564116A6CF900D1F0CB /* Table With Shadow */, + E4D1D1C41306D12D0090AE0C /* Table Drag Refresh */, ); name = Tables; sourceTree = ""; @@ -737,13 +1043,42 @@ productReference = 1D6058910D05DD3D006BFB54 /* TTCatalog.app */; productType = "com.apple.product-type.application"; }; + 664DFEB112663122004C20C2 /* TTCatalog-Xcode3.2.5 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 664DFEEF12663122004C20C2 /* Build configuration list for PBXNativeTarget "TTCatalog-Xcode3.2.5" */; + buildPhases = ( + 664DFEC012663122004C20C2 /* Resources */, + 664DFECA12663122004C20C2 /* Sources */, + 664DFEE312663122004C20C2 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 664DFF191266314B004C20C2 /* PBXTargetDependency */, + 664DFF1B1266314B004C20C2 /* PBXTargetDependency */, + 664DFF1D1266314B004C20C2 /* PBXTargetDependency */, + 664DFF1F1266314B004C20C2 /* PBXTargetDependency */, + 664DFF211266314B004C20C2 /* PBXTargetDependency */, + 664DFF231266314B004C20C2 /* PBXTargetDependency */, + 664DFF251266314B004C20C2 /* PBXTargetDependency */, + ); + name = "TTCatalog-Xcode3.2.5"; + productName = PhotoBrowser; + productReference = 664DFEF212663122004C20C2 /* TTCatalog-v3.2.5.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTCatalog" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, @@ -787,11 +1122,110 @@ projectRoot = ""; targets = ( 1D6058900D05DD3D006BFB54 /* TTCatalog */, + 664DFEB112663122004C20C2 /* TTCatalog-Xcode3.2.5 */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ + 665E992912662FE30025FA42 /* libThree20Core-Xcode3.2.5.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libThree20Core-Xcode3.2.5.a"; + remoteRef = 665E992812662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E992D12662FE30025FA42 /* CoreUnitTests-Xcode3.2.5.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "CoreUnitTests-Xcode3.2.5.octest"; + remoteRef = 665E992C12662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E993612662FE30025FA42 /* libThree20Network-Xcode3.2.5.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libThree20Network-Xcode3.2.5.a"; + remoteRef = 665E993512662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E993A12662FE30025FA42 /* NetworkUnitTests-Xcode3.2.5.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "NetworkUnitTests-Xcode3.2.5.octest"; + remoteRef = 665E993912662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E994312662FE30025FA42 /* libThree20Style-Xcode3.2.5.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libThree20Style-Xcode3.2.5.a"; + remoteRef = 665E994212662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E994712662FE30025FA42 /* StyleUnitTests-Xcode3.2.5.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "StyleUnitTests-Xcode3.2.5.octest"; + remoteRef = 665E994612662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E995012662FE30025FA42 /* libThree20UICommon-Xcode3.2.5.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libThree20UICommon-Xcode3.2.5.a"; + remoteRef = 665E994F12662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E995412662FE30025FA42 /* UICommonUnitTests-Xcode3.2.5.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "UICommonUnitTests-Xcode3.2.5.octest"; + remoteRef = 665E995312662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E995D12662FE30025FA42 /* libThree20UINavigator-Xcode3.2.5.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libThree20UINavigator-Xcode3.2.5.a"; + remoteRef = 665E995C12662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E996112662FE30025FA42 /* UINavigatorUnitTests-Xcode3.2.5.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "UINavigatorUnitTests-Xcode3.2.5.octest"; + remoteRef = 665E996012662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E996A12662FE30025FA42 /* libThree20UI-Xcode3.2.5.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libThree20UI-Xcode3.2.5.a"; + remoteRef = 665E996912662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E996E12662FE30025FA42 /* UIUnitTests-Xcode3.2.5.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "UIUnitTests-Xcode3.2.5.octest"; + remoteRef = 665E996D12662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E997712662FE30025FA42 /* libThree20-Xcode3.2.5.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libThree20-Xcode3.2.5.a"; + remoteRef = 665E997612662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 665E997B12662FE30025FA42 /* Three20UnitTests-Xcode3.2.5.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "Three20UnitTests-Xcode3.2.5.octest"; + remoteRef = 665E997A12662FE30025FA42 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 6E3794D411B9B6D70011C497 /* libThree20Core.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -813,10 +1247,10 @@ remoteRef = 6E3794D911B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3794DC11B9B6D70011C497 /* UnitTests.octest */ = { + 6E3794DC11B9B6D70011C497 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E3794DB11B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -827,10 +1261,10 @@ remoteRef = 6E3794DF11B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3794E211B9B6D70011C497 /* UnitTests.octest */ = { + 6E3794E211B9B6D70011C497 /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E3794E111B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -841,10 +1275,10 @@ remoteRef = 6E3794E511B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3794E811B9B6D70011C497 /* UnitTests.octest */ = { + 6E3794E811B9B6D70011C497 /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6E3794E711B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -855,10 +1289,10 @@ remoteRef = 6E3794EB11B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3794EE11B9B6D70011C497 /* UnitTests.octest */ = { + 6E3794EE11B9B6D70011C497 /* UINavigatorUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UINavigatorUnitTests.octest; remoteRef = 6E3794ED11B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -869,10 +1303,10 @@ remoteRef = 6E3794F111B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3794F411B9B6D70011C497 /* UnitTests.octest */ = { + 6E3794F411B9B6D70011C497 /* UIUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UIUnitTests.octest; remoteRef = 6E3794F311B9B6D70011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -883,10 +1317,10 @@ remoteRef = 6E7F977D118E37BB00443B46 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E7F9780118E37BB00443B46 /* UnitTests.octest */ = { + 6E7F9780118E37BB00443B46 /* Three20UnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = Three20UnitTests.octest; remoteRef = 6E7F977F118E37BB00443B46 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -906,6 +1340,30 @@ BEA6BAAD101436AC00B83B3A /* defaultMusic.png in Resources */, 6E94C6AD116D98220012B12C /* Default.png in Resources */, 6E94C6AE116D98220012B12C /* Icon.png in Resources */, + 6675F5F412945622008DE0A6 /* Default-Landscape.png in Resources */, + 6675F5F512945622008DE0A6 /* Default-Portrait.png in Resources */, + 6675F5F612945622008DE0A6 /* Default@2x.png in Resources */, + 6675F5F712945622008DE0A6 /* Icon@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 664DFEC012663122004C20C2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 664DFEC112663122004C20C2 /* tableIcon.png in Resources */, + 664DFEC212663122004C20C2 /* person.jpg in Resources */, + 664DFEC312663122004C20C2 /* Three20.bundle in Resources */, + 664DFEC412663122004C20C2 /* smiley.png in Resources */, + 664DFEC512663122004C20C2 /* mask.png in Resources */, + 664DFEC612663122004C20C2 /* defaultPerson.png in Resources */, + 664DFEC712663122004C20C2 /* defaultMusic.png in Resources */, + 664DFEC812663122004C20C2 /* Default.png in Resources */, + 664DFEC912663122004C20C2 /* Icon.png in Resources */, + 6675F5F812945622008DE0A6 /* Default-Landscape.png in Resources */, + 6675F5F912945622008DE0A6 /* Default-Portrait.png in Resources */, + 6675F5FA12945622008DE0A6 /* Default@2x.png in Resources */, + 6675F5FB12945622008DE0A6 /* Icon@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -940,12 +1398,87 @@ BE20A49C0FF418B2008791F4 /* TableControlsTestController.m in Sources */, BEC787631040A430005C00CF /* LauncherViewTestController.m in Sources */, 6E002567116A6D1A00D1F0CB /* TableWithShadowController.m in Sources */, + E46662FE127F91A4001A0F20 /* TableWithBannerController.m in Sources */, + 666E183012944D23001C1D97 /* SplitCatalogController.m in Sources */, + E4D1D1D61306D2670090AE0C /* TableDragRefreshController.m in Sources */, + 7000C4C0130CCAE3006D7ADE /* DownloadTestModel.m in Sources */, + 7000C4C1130CCAE3006D7ADE /* DownloadProgressTestController.m in Sources */, + A96808E8131A91FB00EB3DAF /* TableItemGroupedTestController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 664DFECA12663122004C20C2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 664DFECB12663122004C20C2 /* main.m in Sources */, + 664DFECC12663122004C20C2 /* AppDelegate.m in Sources */, + 664DFECD12663122004C20C2 /* CatalogController.m in Sources */, + 664DFECE12663122004C20C2 /* MockPhotoSource.m in Sources */, + 664DFECF12663122004C20C2 /* TableImageTestController.m in Sources */, + 664DFED012663122004C20C2 /* ImageTest1Controller.m in Sources */, + 664DFED112663122004C20C2 /* ActivityTestController.m in Sources */, + 664DFED212663122004C20C2 /* PhotoTest1Controller.m in Sources */, + 664DFED312663122004C20C2 /* PhotoTest2Controller.m in Sources */, + 664DFED412663122004C20C2 /* YouTubeTestController.m in Sources */, + 664DFED512663122004C20C2 /* ScrollViewTestController.m in Sources */, + 664DFED612663122004C20C2 /* TabBarTestController.m in Sources */, + 664DFED712663122004C20C2 /* TableItemTestController.m in Sources */, + 664DFED812663122004C20C2 /* MessageTestController.m in Sources */, + 664DFED912663122004C20C2 /* SearchTestController.m in Sources */, + 664DFEDA12663122004C20C2 /* MockDataSource.m in Sources */, + 664DFEDB12663122004C20C2 /* TableTestController.m in Sources */, + 664DFEDC12663122004C20C2 /* StyledTextTableTestController.m in Sources */, + 664DFEDD12663122004C20C2 /* StyledTextTestController.m in Sources */, + 664DFEDE12663122004C20C2 /* StyleTestController.m in Sources */, + 664DFEDF12663122004C20C2 /* ButtonTestController.m in Sources */, + 664DFEE012663122004C20C2 /* TableControlsTestController.m in Sources */, + 664DFEE112663122004C20C2 /* LauncherViewTestController.m in Sources */, + 664DFEE212663122004C20C2 /* TableWithShadowController.m in Sources */, + 664B27F612846A220008D569 /* TableWithBannerController.m in Sources */, + 666E183112944D23001C1D97 /* SplitCatalogController.m in Sources */, + A96808E9131A91FB00EB3DAF /* TableItemGroupedTestController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 664DFF191266314B004C20C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Three20Network-Xcode3.2.5"; + targetProxy = 664DFF181266314B004C20C2 /* PBXContainerItemProxy */; + }; + 664DFF1B1266314B004C20C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Three20-Xcode3.2.5"; + targetProxy = 664DFF1A1266314B004C20C2 /* PBXContainerItemProxy */; + }; + 664DFF1D1266314B004C20C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Three20UINavigator-Xcode3.2.5"; + targetProxy = 664DFF1C1266314B004C20C2 /* PBXContainerItemProxy */; + }; + 664DFF1F1266314B004C20C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Three20UICommon-Xcode3.2.5"; + targetProxy = 664DFF1E1266314B004C20C2 /* PBXContainerItemProxy */; + }; + 664DFF211266314B004C20C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Three20Style-Xcode3.2.5"; + targetProxy = 664DFF201266314B004C20C2 /* PBXContainerItemProxy */; + }; + 664DFF231266314B004C20C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Three20UI-Xcode3.2.5"; + targetProxy = 664DFF221266314B004C20C2 /* PBXContainerItemProxy */; + }; + 664DFF251266314B004C20C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Three20Core-Xcode3.2.5"; + targetProxy = 664DFF241266314B004C20C2 /* PBXContainerItemProxy */; + }; 6E37950011B9B6EE0011C497 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Three20UI; @@ -988,14 +1521,16 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E7F9960118E3A6000443B46 /* App.xcconfig */; buildSettings = { - CODE_SIGN_IDENTITY = "Don't Code Sign"; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + BUILD_STYLE = Debug; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphoneos4.0; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -1003,10 +1538,64 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E7F9960118E3A6000443B46 /* App.xcconfig */; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + BUILD_STYLE = Release; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 664DFEF012663122004C20C2 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6E7F9960118E3A6000443B46 /* App.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + BUILD_STYLE = Debug; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + OTHER_LDFLAGS = ( + "$(THREE20CORE325_LIB)", + "$(THREE20NETWORK325_LIB)", + "$(THREE20STYLE325_LIB)", + "$(THREE20UICOMMON325_LIB)", + "$(THREE20UINAVIGATOR325_LIB)", + "$(THREE20UI325_LIB)", + "$(THREE20325_LIB)", + ); + PRODUCT_NAME = "$(BASE_PRODUCT_NAME)-v3.2.5"; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 664DFEF112663122004C20C2 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6E7F9960118E3A6000443B46 /* App.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + BUILD_STYLE = Release; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphoneos4.0; + OTHER_LDFLAGS = ( + "$(THREE20CORE325_LIB)", + "$(THREE20NETWORK325_LIB)", + "$(THREE20STYLE325_LIB)", + "$(THREE20UICOMMON325_LIB)", + "$(THREE20UINAVIGATOR325_LIB)", + "$(THREE20UI325_LIB)", + "$(THREE20325_LIB)", + ); + PRODUCT_NAME = "$(BASE_PRODUCT_NAME)-v3.2.5"; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; @@ -1015,13 +1604,14 @@ baseConfigurationReference = 6E7F9961118E3A6000443B46 /* Project.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - CODE_SIGN_IDENTITY = "iPhone Developer"; + BUILD_STYLE = Debug; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; - SDKROOT = iphonesimulator2.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -1030,13 +1620,13 @@ baseConfigurationReference = 6E7F9961118E3A6000443B46 /* Project.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + BUILD_STYLE = Release; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - "PROVISIONING_PROFILE[sdk=iphoneos*]" = DefaultProfileUuid; - SDKROOT = iphonesimulator2.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -1052,6 +1642,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 664DFEEF12663122004C20C2 /* Build configuration list for PBXNativeTarget "TTCatalog-Xcode3.2.5" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 664DFEF012663122004C20C2 /* Debug */, + 664DFEF112663122004C20C2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTCatalog" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/samples/TTFacebook/Atlas.h b/samples/TTFacebook/Atlas.h index 31a02fe300..d8c52812e2 100644 --- a/samples/TTFacebook/Atlas.h +++ b/samples/TTFacebook/Atlas.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,4 +16,5 @@ #import +extern NSString* kAppPrefixURLPath; extern NSString* kAppRootURLPath; diff --git a/samples/TTFacebook/Atlas.m b/samples/TTFacebook/Atlas.m index 20b86c60b7..6f583ee0fd 100644 --- a/samples/TTFacebook/Atlas.m +++ b/samples/TTFacebook/Atlas.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,5 +16,6 @@ #import "Atlas.h" -NSString* kAppRootURLPath = @"tt://root"; +NSString* kAppPrefixURLPath = @"tt://"; +NSString* kAppRootURLPath = @"tt://root"; diff --git a/samples/TTFacebook/Classes/AppDelegate.h b/samples/TTFacebook/Classes/AppDelegate.h index 18ea3bbb96..bd4b72b499 100644 --- a/samples/TTFacebook/Classes/AppDelegate.h +++ b/samples/TTFacebook/Classes/AppDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Classes/AppDelegate.m b/samples/TTFacebook/Classes/AppDelegate.m index 25ad67bc4b..6911f72059 100644 --- a/samples/TTFacebook/Classes/AppDelegate.m +++ b/samples/TTFacebook/Classes/AppDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,6 +27,8 @@ @implementation AppDelegate /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)applicationDidFinishLaunching:(UIApplication *)application { + [TTExtensionLoader loadAllExtensions]; + TTDefaultCSSStyleSheet* styleSheet = [[TTDefaultCSSStyleSheet alloc] init]; [styleSheet addStyleSheetFromDisk:TTPathForBundleResource(@"stylesheet.css")]; [TTStyleSheet setGlobalStyleSheet:styleSheet]; @@ -40,6 +42,9 @@ - (void)applicationDidFinishLaunching:(UIApplication *)application { [map from:@"*" toViewController:[TTWebController class]]; [map from:kAppRootURLPath toViewController:[TTFacebookSearchFeedViewController class]]; + [TTExtensionsController registerUrlPathsWithNavigator: navigator + prefix: kAppPrefixURLPath]; + if (![navigator restoreViewControllers]) { [navigator openURLAction:[TTURLAction actionWithURLPath:kAppRootURLPath]]; } diff --git a/samples/TTFacebook/Classes/TTFacebookPost.h b/samples/TTFacebook/Classes/TTFacebookPost.h index 0fed511896..82a43d94d6 100644 --- a/samples/TTFacebook/Classes/TTFacebookPost.h +++ b/samples/TTFacebook/Classes/TTFacebookPost.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Classes/TTFacebookPost.m b/samples/TTFacebook/Classes/TTFacebookPost.m index 000f8d54e7..1a8ce285a3 100644 --- a/samples/TTFacebook/Classes/TTFacebookPost.m +++ b/samples/TTFacebook/Classes/TTFacebookPost.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Classes/TTFacebookSearchFeedDataSource.h b/samples/TTFacebook/Classes/TTFacebookSearchFeedDataSource.h index 4e42342321..081ecefce7 100644 --- a/samples/TTFacebook/Classes/TTFacebookSearchFeedDataSource.h +++ b/samples/TTFacebook/Classes/TTFacebookSearchFeedDataSource.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Classes/TTFacebookSearchFeedDataSource.m b/samples/TTFacebook/Classes/TTFacebookSearchFeedDataSource.m index 6fd3bc79ac..670b7425e0 100644 --- a/samples/TTFacebook/Classes/TTFacebookSearchFeedDataSource.m +++ b/samples/TTFacebook/Classes/TTFacebookSearchFeedDataSource.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Classes/TTFacebookSearchFeedModel.h b/samples/TTFacebook/Classes/TTFacebookSearchFeedModel.h index 4c897db1dd..e69fbf1dff 100644 --- a/samples/TTFacebook/Classes/TTFacebookSearchFeedModel.h +++ b/samples/TTFacebook/Classes/TTFacebookSearchFeedModel.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Classes/TTFacebookSearchFeedModel.m b/samples/TTFacebook/Classes/TTFacebookSearchFeedModel.m index a6bd30e8a1..9110abe1ab 100644 --- a/samples/TTFacebook/Classes/TTFacebookSearchFeedModel.m +++ b/samples/TTFacebook/Classes/TTFacebookSearchFeedModel.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Classes/TTFacebookSearchFeedViewController.h b/samples/TTFacebook/Classes/TTFacebookSearchFeedViewController.h index 18067c4cfb..f733f4159e 100644 --- a/samples/TTFacebook/Classes/TTFacebookSearchFeedViewController.h +++ b/samples/TTFacebook/Classes/TTFacebookSearchFeedViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Classes/TTFacebookSearchFeedViewController.m b/samples/TTFacebook/Classes/TTFacebookSearchFeedViewController.m index 4016b2d925..1e10f2ef26 100644 --- a/samples/TTFacebook/Classes/TTFacebookSearchFeedViewController.m +++ b/samples/TTFacebook/Classes/TTFacebookSearchFeedViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,6 +30,12 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { self.title = @"Facebook feed"; self.variableHeightRows = YES; + + self.navigationItem.rightBarButtonItem = + [[[UIBarButtonItem alloc] initWithTitle: @"Extensions" + style: UIBarButtonItemStyleBordered + target: @"tt://extensions" + action: @selector(openURLFromButton:)] autorelease]; } return self; diff --git a/samples/TTFacebook/Configurations/App.xcconfig b/samples/TTFacebook/Configurations/App.xcconfig index 31d797d361..cfdd10f214 100644 --- a/samples/TTFacebook/Configurations/App.xcconfig +++ b/samples/TTFacebook/Configurations/App.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTFacebook +BASE_PRODUCT_NAME = TTFacebook +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/samples/TTFacebook/Configurations/Project.xcconfig b/samples/TTFacebook/Configurations/Project.xcconfig index 0f02ea7f79..fc1966a5f7 100644 --- a/samples/TTFacebook/Configurations/Project.xcconfig +++ b/samples/TTFacebook/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Configurations/RelPath.xcconfig b/samples/TTFacebook/Configurations/RelPath.xcconfig index e7425443d8..d6d201d36a 100644 --- a/samples/TTFacebook/Configurations/RelPath.xcconfig +++ b/samples/TTFacebook/Configurations/RelPath.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/Configurations/UnitTests.xcconfig b/samples/TTFacebook/Configurations/UnitTests.xcconfig index 5339d2a25e..c16ed3f5c1 100644 --- a/samples/TTFacebook/Configurations/UnitTests.xcconfig +++ b/samples/TTFacebook/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTFacebook/TTFacebook.xcodeproj/project.pbxproj b/samples/TTFacebook/TTFacebook.xcodeproj/project.pbxproj index 5fc058a023..fc0cf44ad7 100755 --- a/samples/TTFacebook/TTFacebook.xcodeproj/project.pbxproj +++ b/samples/TTFacebook/TTFacebook.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -425,7 +425,7 @@ isa = PBXGroup; children = ( 6E37930311B7F2A40011C497 /* libThree20Network.a */, - 6E37930511B7F2A40011C497 /* UnitTests.octest */, + 6E37930511B7F2A40011C497 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -434,7 +434,7 @@ isa = PBXGroup; children = ( 6E37930911B7F2A40011C497 /* libThree20Style.a */, - 6E37930B11B7F2A40011C497 /* UnitTests.octest */, + 6E37930B11B7F2A40011C497 /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -443,7 +443,7 @@ isa = PBXGroup; children = ( 6E37930F11B7F2A40011C497 /* libThree20UICommon.a */, - 6E37931111B7F2A40011C497 /* UnitTests.octest */, + 6E37931111B7F2A40011C497 /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -452,7 +452,7 @@ isa = PBXGroup; children = ( 6E37931511B7F2A40011C497 /* libThree20UINavigator.a */, - 6E37931711B7F2A40011C497 /* UnitTests.octest */, + 6E37931711B7F2A40011C497 /* UINavigatorUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -461,7 +461,7 @@ isa = PBXGroup; children = ( 6E37931B11B7F2A40011C497 /* libThree20UI.a */, - 6E37931D11B7F2A40011C497 /* UnitTests.octest */, + 6E37931D11B7F2A40011C497 /* UIUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -531,7 +531,7 @@ children = ( 6E6462881187DF2C00F08CB1 /* libextThree20JSON+SBJSON.a */, 6E64628A1187DF2C00F08CB1 /* libextThree20JSON+YAJL.a */, - 6E64628C1187DF2C00F08CB1 /* extJSONUnitTests.octest */, + 6E64628C1187DF2C00F08CB1 /* extJSONUnitTests+SBJSON.octest */, ); name = Products; sourceTree = ""; @@ -540,7 +540,7 @@ isa = PBXGroup; children = ( 6E7F981A118E385E00443B46 /* libThree20.a */, - 6E7F981C118E385E00443B46 /* UnitTests.octest */, + 6E7F981C118E385E00443B46 /* Three20UnitTests.octest */, ); name = Products; sourceTree = ""; @@ -579,9 +579,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTFacebook" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -665,10 +676,10 @@ remoteRef = 6E37930211B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37930511B7F2A40011C497 /* UnitTests.octest */ = { + 6E37930511B7F2A40011C497 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E37930411B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -679,10 +690,10 @@ remoteRef = 6E37930811B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37930B11B7F2A40011C497 /* UnitTests.octest */ = { + 6E37930B11B7F2A40011C497 /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E37930A11B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -693,10 +704,10 @@ remoteRef = 6E37930E11B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37931111B7F2A40011C497 /* UnitTests.octest */ = { + 6E37931111B7F2A40011C497 /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6E37931011B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -707,10 +718,10 @@ remoteRef = 6E37931411B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37931711B7F2A40011C497 /* UnitTests.octest */ = { + 6E37931711B7F2A40011C497 /* UINavigatorUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UINavigatorUnitTests.octest; remoteRef = 6E37931611B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -721,10 +732,10 @@ remoteRef = 6E37931A11B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37931D11B7F2A40011C497 /* UnitTests.octest */ = { + 6E37931D11B7F2A40011C497 /* UIUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UIUnitTests.octest; remoteRef = 6E37931C11B7F2A40011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -742,10 +753,10 @@ remoteRef = 6E6462891187DF2C00F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E64628C1187DF2C00F08CB1 /* extJSONUnitTests.octest */ = { + 6E64628C1187DF2C00F08CB1 /* extJSONUnitTests+SBJSON.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = extJSONUnitTests.octest; + path = "extJSONUnitTests+SBJSON.octest"; remoteRef = 6E64628B1187DF2C00F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -756,10 +767,10 @@ remoteRef = 6E7F9819118E385E00443B46 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E7F981C118E385E00443B46 /* UnitTests.octest */ = { + 6E7F981C118E385E00443B46 /* Three20UnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = Three20UnitTests.octest; remoteRef = 6E7F981B118E385E00443B46 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -854,9 +865,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - INFOPLIST_FILE = "TTFacebook-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphoneos4.0; + SDKROOT = iphoneos; }; name = Debug; }; @@ -865,9 +874,7 @@ baseConfigurationReference = 6E64627C1187DF0F00F08CB1 /* App.xcconfig */; buildSettings = { COPY_PHASE_STRIP = YES; - INFOPLIST_FILE = "TTFacebook-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphoneos4.0; + SDKROOT = iphoneos; }; name = Release; }; @@ -875,14 +882,12 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64627D1187DF0F00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - SDKROOT = iphoneos3.0; + SDKROOT = iphoneos; }; name = Debug; }; @@ -890,14 +895,12 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64627D1187DF0F00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - SDKROOT = iphoneos3.0; + SDKROOT = iphoneos; }; name = Release; }; diff --git a/samples/TTFacebook/main.m b/samples/TTFacebook/main.m index 2915dbbb29..1cefab29fe 100644 --- a/samples/TTFacebook/main.m +++ b/samples/TTFacebook/main.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTNavigatorDemo/Classes/ContentController.m b/samples/TTNavigatorDemo/Classes/ContentController.m index e4f6e5df85..292cf08d08 100644 --- a/samples/TTNavigatorDemo/Classes/ContentController.m +++ b/samples/TTNavigatorDemo/Classes/ContentController.m @@ -69,7 +69,7 @@ - (id)initWithNutrition:(NSString*)food { - (id)initWithAbout:(NSString*)about { if (self = [super init]) { - _contentType = ContentTypeNutrition; + _contentType = ContentTypeAbout; self.content = about; self.text = [NSString stringWithFormat:@"%@ is the name of this page. Exciting.", about]; @@ -113,6 +113,9 @@ - (void)loadView { self.view.backgroundColor = [UIColor grayColor]; label.backgroundColor = self.view.backgroundColor; self.hidesBottomBarWhenPushed = YES; + } else if (_contentType == ContentTypeAbout) { + self.view.backgroundColor = [UIColor grayColor]; + label.backgroundColor = self.view.backgroundColor; } else if (_contentType == ContentTypeOrder) { UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setTitle:@"What do you want to eat?" forState:UIControlStateNormal]; diff --git a/samples/TTNavigatorDemo/Configurations/App.xcconfig b/samples/TTNavigatorDemo/Configurations/App.xcconfig index da8c6f6360..b57ac69293 100644 --- a/samples/TTNavigatorDemo/Configurations/App.xcconfig +++ b/samples/TTNavigatorDemo/Configurations/App.xcconfig @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTNavigatorDemo +BASE_PRODUCT_NAME = TTNavigatorDemo +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/samples/TTNavigatorDemo/TTNavigatorDemo.xcodeproj/project.pbxproj b/samples/TTNavigatorDemo/TTNavigatorDemo.xcodeproj/project.pbxproj index 757243e37b..79e9d274f9 100755 --- a/samples/TTNavigatorDemo/TTNavigatorDemo.xcodeproj/project.pbxproj +++ b/samples/TTNavigatorDemo/TTNavigatorDemo.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -317,7 +317,7 @@ isa = PBXGroup; children = ( 6E37958B11B9B7560011C497 /* libThree20Network.a */, - 6E37958D11B9B7560011C497 /* UnitTests.octest */, + 6E37958D11B9B7560011C497 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -326,7 +326,7 @@ isa = PBXGroup; children = ( 6E37959111B9B7560011C497 /* libThree20Style.a */, - 6E37959311B9B7560011C497 /* UnitTests.octest */, + 6E37959311B9B7560011C497 /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -335,7 +335,7 @@ isa = PBXGroup; children = ( 6E37959711B9B7560011C497 /* libThree20UICommon.a */, - 6E37959911B9B7560011C497 /* UnitTests.octest */, + 6E37959911B9B7560011C497 /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -344,7 +344,7 @@ isa = PBXGroup; children = ( 6E37959D11B9B7560011C497 /* libThree20UINavigator.a */, - 6E37959F11B9B7560011C497 /* UnitTests.octest */, + 6E37959F11B9B7560011C497 /* UINavigatorUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -353,7 +353,7 @@ isa = PBXGroup; children = ( 6E3795A311B9B7560011C497 /* libThree20UI.a */, - 6E3795A511B9B7560011C497 /* UnitTests.octest */, + 6E3795A511B9B7560011C497 /* UIUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -387,7 +387,7 @@ isa = PBXGroup; children = ( 6E7F9906118E396F00443B46 /* libThree20.a */, - 6E7F9908118E396F00443B46 /* UnitTests.octest */, + 6E7F9908118E396F00443B46 /* Three20UnitTests.octest */, ); name = Products; sourceTree = ""; @@ -424,8 +424,12 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTNavigatorDemo" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, @@ -495,10 +499,10 @@ remoteRef = 6E37958A11B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37958D11B9B7560011C497 /* UnitTests.octest */ = { + 6E37958D11B9B7560011C497 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E37958C11B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -509,10 +513,10 @@ remoteRef = 6E37959011B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37959311B9B7560011C497 /* UnitTests.octest */ = { + 6E37959311B9B7560011C497 /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E37959211B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -523,10 +527,10 @@ remoteRef = 6E37959611B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37959911B9B7560011C497 /* UnitTests.octest */ = { + 6E37959911B9B7560011C497 /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6E37959811B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -537,10 +541,10 @@ remoteRef = 6E37959C11B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37959F11B9B7560011C497 /* UnitTests.octest */ = { + 6E37959F11B9B7560011C497 /* UINavigatorUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UINavigatorUnitTests.octest; remoteRef = 6E37959E11B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -551,10 +555,10 @@ remoteRef = 6E3795A211B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3795A511B9B7560011C497 /* UnitTests.octest */ = { + 6E3795A511B9B7560011C497 /* UIUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UIUnitTests.octest; remoteRef = 6E3795A411B9B7560011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -565,10 +569,10 @@ remoteRef = 6E7F9905118E396F00443B46 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E7F9908118E396F00443B46 /* UnitTests.octest */ = { + 6E7F9908118E396F00443B46 /* Three20UnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = Three20UnitTests.octest; remoteRef = 6E7F9907118E396F00443B46 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -651,8 +655,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphonesimulator4.0; + SDKROOT = iphoneos; }; name = Debug; }; @@ -662,8 +665,7 @@ buildSettings = { COPY_PHASE_STRIP = YES; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphonesimulator4.0; + SDKROOT = iphoneos; }; name = Release; }; @@ -671,14 +673,10 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E7F9923118E39B500443B46 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; - PREBINDING = NO; - SDKROOT = iphonesimulator3.0; }; name = Debug; }; @@ -686,14 +684,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E7F9923118E39B500443B46 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; "PROVISIONING_PROFILE[sdk=iphoneos*]" = DefaultProfileUuid; - SDKROOT = iphonesimulator3.0; }; name = Release; }; diff --git a/samples/TTTwitter/Classes/AppDelegate.h b/samples/TTTwitter/Classes/AppDelegate.h index 94edd0ca1d..1a81bc5da2 100644 --- a/samples/TTTwitter/Classes/AppDelegate.h +++ b/samples/TTTwitter/Classes/AppDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Classes/AppDelegate.m b/samples/TTTwitter/Classes/AppDelegate.m index 7097b4ae3e..7240200cb6 100644 --- a/samples/TTTwitter/Classes/AppDelegate.m +++ b/samples/TTTwitter/Classes/AppDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Classes/Atlas.h b/samples/TTTwitter/Classes/Atlas.h index 31a02fe300..93a059d460 100644 --- a/samples/TTTwitter/Classes/Atlas.h +++ b/samples/TTTwitter/Classes/Atlas.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Classes/Atlas.m b/samples/TTTwitter/Classes/Atlas.m index fabf6e96c2..f40b1da198 100644 --- a/samples/TTTwitter/Classes/Atlas.m +++ b/samples/TTTwitter/Classes/Atlas.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Classes/TTTwitterSearchFeedDataSource.h b/samples/TTTwitter/Classes/TTTwitterSearchFeedDataSource.h index 69cba8c25a..a43ca385b6 100644 --- a/samples/TTTwitter/Classes/TTTwitterSearchFeedDataSource.h +++ b/samples/TTTwitter/Classes/TTTwitterSearchFeedDataSource.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Classes/TTTwitterSearchFeedDataSource.m b/samples/TTTwitter/Classes/TTTwitterSearchFeedDataSource.m index d1fb938942..fa7a1b42ba 100644 --- a/samples/TTTwitter/Classes/TTTwitterSearchFeedDataSource.m +++ b/samples/TTTwitter/Classes/TTTwitterSearchFeedDataSource.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -72,6 +72,10 @@ - (void)tableViewDidLoadModel:(UITableView*)tableView { TTDASSERT(nil != styledText); [items addObject:[TTTableStyledTextItem itemWithText:styledText]]; } + + if (!_searchFeedModel.finished) { + [items addObject:[TTTableMoreButton itemWithText:@"more…"]]; + } self.items = items; TT_RELEASE_SAFELY(items); diff --git a/samples/TTTwitter/Classes/TTTwitterSearchFeedModel.h b/samples/TTTwitter/Classes/TTTwitterSearchFeedModel.h index 38ecbdf221..fc3ca22a4c 100644 --- a/samples/TTTwitter/Classes/TTTwitterSearchFeedModel.h +++ b/samples/TTTwitter/Classes/TTTwitterSearchFeedModel.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,11 +20,18 @@ @interface TTTwitterSearchFeedModel : TTURLRequestModel { NSString* _searchQuery; - NSArray* _tweets; + NSMutableArray* _tweets; + + NSUInteger _page; // page of search request + NSUInteger _resultsPerPage; // results per page, once the initial query is made + // this value shouldn't be changed + BOOL _finished; } -@property (nonatomic, copy) NSString* searchQuery; -@property (nonatomic, readonly) NSArray* tweets; +@property (nonatomic, copy) NSString* searchQuery; +@property (nonatomic, readonly) NSMutableArray* tweets; +@property (nonatomic, assign) NSUInteger resultsPerPage; +@property (nonatomic, readonly) BOOL finished; - (id)initWithSearchQuery:(NSString*)searchQuery; diff --git a/samples/TTTwitter/Classes/TTTwitterSearchFeedModel.m b/samples/TTTwitter/Classes/TTTwitterSearchFeedModel.m index dc7a99f1bf..f27b0865f0 100644 --- a/samples/TTTwitter/Classes/TTTwitterSearchFeedModel.m +++ b/samples/TTTwitter/Classes/TTTwitterSearchFeedModel.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,7 +20,10 @@ #import -static NSString* kTwitterSearchFeedFormat = @"http://search.twitter.com/search.json?q=%@"; +// Twitter search API documented here: +// http://apiwiki.twitter.com/w/page/22554756/Twitter-Search-API-Method:-search +static NSString* kTwitterSearchFeedFormat = + @"http://search.twitter.com/search.json?q=%@&rpp=%u&page=%u"; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -28,14 +31,18 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// @implementation TTTwitterSearchFeedModel -@synthesize searchQuery = _searchQuery; -@synthesize tweets = _tweets; - +@synthesize searchQuery = _searchQuery; +@synthesize tweets = _tweets; +@synthesize resultsPerPage = _resultsPerPage; +@synthesize finished = _finished; /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithSearchQuery:(NSString*)searchQuery { if (self = [super init]) { self.searchQuery = searchQuery; + _resultsPerPage = 10; + _page = 1; + _tweets = [[NSMutableArray array] retain]; } return self; @@ -53,7 +60,16 @@ - (void) dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more { if (!self.isLoading && TTIsStringWithAnyText(_searchQuery)) { - NSString* url = [NSString stringWithFormat:kTwitterSearchFeedFormat, _searchQuery]; + if (more) { + _page++; + } + else { + _page = 1; + _finished = NO; + [_tweets removeAllObjects]; + } + + NSString* url = [NSString stringWithFormat:kTwitterSearchFeedFormat, _searchQuery, _resultsPerPage, _page]; TTURLRequest* request = [TTURLRequest requestWithURL: url @@ -85,8 +101,7 @@ - (void)requestDidFinishLoad:(TTURLRequest*)request { [dateFormatter setTimeStyle:NSDateFormatterFullStyle]; [dateFormatter setDateFormat:@"EEE, dd MMMM yyyy HH:mm:ss ZZ"]; - TT_RELEASE_SAFELY(_tweets); - NSMutableArray* tweets = [[NSMutableArray alloc] initWithCapacity:[entries count]]; + NSMutableArray* tweets = [NSMutableArray arrayWithCapacity:[entries count]]; for (NSDictionary* entry in entries) { TTTwitterTweet* tweet = [[TTTwitterTweet alloc] init]; @@ -101,7 +116,8 @@ - (void)requestDidFinishLoad:(TTURLRequest*)request { [tweets addObject:tweet]; TT_RELEASE_SAFELY(tweet); } - _tweets = tweets; + _finished = tweets.count < _resultsPerPage; + [_tweets addObjectsFromArray: tweets]; TT_RELEASE_SAFELY(dateFormatter); diff --git a/samples/TTTwitter/Classes/TTTwitterSearchFeedViewController.h b/samples/TTTwitter/Classes/TTTwitterSearchFeedViewController.h index 0c2abd4b72..6460a281e1 100644 --- a/samples/TTTwitter/Classes/TTTwitterSearchFeedViewController.h +++ b/samples/TTTwitter/Classes/TTTwitterSearchFeedViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Classes/TTTwitterSearchFeedViewController.m b/samples/TTTwitter/Classes/TTTwitterSearchFeedViewController.m index f8abb235ac..20d3577df1 100644 --- a/samples/TTTwitter/Classes/TTTwitterSearchFeedViewController.m +++ b/samples/TTTwitter/Classes/TTTwitterSearchFeedViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,8 +26,8 @@ @implementation TTTwitterSearchFeedViewController /////////////////////////////////////////////////////////////////////////////////////////////////// -- (id) init { - if (self = [super init]) { +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { self.title = @"Twitter feed"; self.variableHeightRows = YES; } diff --git a/samples/TTTwitter/Classes/TTTwitterTweet.h b/samples/TTTwitter/Classes/TTTwitterTweet.h index 247a546915..829db37fae 100644 --- a/samples/TTTwitter/Classes/TTTwitterTweet.h +++ b/samples/TTTwitter/Classes/TTTwitterTweet.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Classes/TTTwitterTweet.m b/samples/TTTwitter/Classes/TTTwitterTweet.m index f26e30fe11..d07cc7b2c8 100644 --- a/samples/TTTwitter/Classes/TTTwitterTweet.m +++ b/samples/TTTwitter/Classes/TTTwitterTweet.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Configurations/App.xcconfig b/samples/TTTwitter/Configurations/App.xcconfig index 7d30249d64..8785da6916 100644 --- a/samples/TTTwitter/Configurations/App.xcconfig +++ b/samples/TTTwitter/Configurations/App.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTTwitter +BASE_PRODUCT_NAME = TTTwitter +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/samples/TTTwitter/Configurations/Project.xcconfig b/samples/TTTwitter/Configurations/Project.xcconfig index 0f02ea7f79..fc1966a5f7 100644 --- a/samples/TTTwitter/Configurations/Project.xcconfig +++ b/samples/TTTwitter/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Configurations/RelPath.xcconfig b/samples/TTTwitter/Configurations/RelPath.xcconfig index e7425443d8..d6d201d36a 100644 --- a/samples/TTTwitter/Configurations/RelPath.xcconfig +++ b/samples/TTTwitter/Configurations/RelPath.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/Configurations/UnitTests.xcconfig b/samples/TTTwitter/Configurations/UnitTests.xcconfig index 73574607ba..22f4ab0e7f 100644 --- a/samples/TTTwitter/Configurations/UnitTests.xcconfig +++ b/samples/TTTwitter/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/TTTwitter/TTTwitter.xcodeproj/project.pbxproj b/samples/TTTwitter/TTTwitter.xcodeproj/project.pbxproj index 48886582eb..0bd7d60050 100755 --- a/samples/TTTwitter/TTTwitter.xcodeproj/project.pbxproj +++ b/samples/TTTwitter/TTTwitter.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -388,7 +388,7 @@ isa = PBXGroup; children = ( 6E3795EC11B9B79C0011C497 /* libThree20.a */, - 6E3795EE11B9B79C0011C497 /* UnitTests.octest */, + 6E3795EE11B9B79C0011C497 /* Three20UnitTests.octest */, ); name = Products; sourceTree = ""; @@ -440,7 +440,7 @@ children = ( 6E6462E51187E6C800F08CB1 /* libextThree20JSON+SBJSON.a */, 6E6462E71187E6C800F08CB1 /* libextThree20JSON+YAJL.a */, - 6E6462E91187E6C800F08CB1 /* extJSONUnitTests.octest */, + 6E6462E91187E6C800F08CB1 /* extJSONUnitTests+SBJSON.octest */, ); name = Products; sourceTree = ""; @@ -458,7 +458,7 @@ isa = PBXGroup; children = ( 6E64631D1187E7E800F08CB1 /* libThree20Network.a */, - 6E64631F1187E7E800F08CB1 /* UnitTests.octest */, + 6E64631F1187E7E800F08CB1 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -467,7 +467,7 @@ isa = PBXGroup; children = ( 6E6463261187E7F000F08CB1 /* libThree20Style.a */, - 6E6463281187E7F000F08CB1 /* UnitTests.octest */, + 6E6463281187E7F000F08CB1 /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -476,7 +476,7 @@ isa = PBXGroup; children = ( 6E64632F1187E7F600F08CB1 /* libThree20UI.a */, - 6E6463311187E7F600F08CB1 /* UnitTests.octest */, + 6E6463311187E7F600F08CB1 /* UIUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -485,7 +485,7 @@ isa = PBXGroup; children = ( 6E877627118D0052001691E0 /* libThree20UICommon.a */, - 6E877629118D0052001691E0 /* UnitTests.octest */, + 6E877629118D0052001691E0 /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -494,7 +494,7 @@ isa = PBXGroup; children = ( 6E877630118D005A001691E0 /* libThree20UINavigator.a */, - 6E877632118D005A001691E0 /* UnitTests.octest */, + 6E877632118D005A001691E0 /* UINavigatorUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -532,9 +532,19 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTTwitter" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -586,10 +596,10 @@ remoteRef = 6E3795EB11B9B79C0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3795EE11B9B79C0011C497 /* UnitTests.octest */ = { + 6E3795EE11B9B79C0011C497 /* Three20UnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = Three20UnitTests.octest; remoteRef = 6E3795ED11B9B79C0011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -607,10 +617,10 @@ remoteRef = 6E6462E61187E6C800F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E6462E91187E6C800F08CB1 /* extJSONUnitTests.octest */ = { + 6E6462E91187E6C800F08CB1 /* extJSONUnitTests+SBJSON.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = extJSONUnitTests.octest; + path = "extJSONUnitTests+SBJSON.octest"; remoteRef = 6E6462E81187E6C800F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -635,10 +645,10 @@ remoteRef = 6E64631C1187E7E800F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E64631F1187E7E800F08CB1 /* UnitTests.octest */ = { + 6E64631F1187E7E800F08CB1 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E64631E1187E7E800F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -649,10 +659,10 @@ remoteRef = 6E6463251187E7F000F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E6463281187E7F000F08CB1 /* UnitTests.octest */ = { + 6E6463281187E7F000F08CB1 /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E6463271187E7F000F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -663,10 +673,10 @@ remoteRef = 6E64632E1187E7F600F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E6463311187E7F600F08CB1 /* UnitTests.octest */ = { + 6E6463311187E7F600F08CB1 /* UIUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UIUnitTests.octest; remoteRef = 6E6463301187E7F600F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -677,10 +687,10 @@ remoteRef = 6E877626118D0052001691E0 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E877629118D0052001691E0 /* UnitTests.octest */ = { + 6E877629118D0052001691E0 /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6E877628118D0052001691E0 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -691,10 +701,10 @@ remoteRef = 6E87762F118D005A001691E0 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E877632118D005A001691E0 /* UnitTests.octest */ = { + 6E877632118D005A001691E0 /* UINavigatorUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UINavigatorUnitTests.octest; remoteRef = 6E877631118D005A001691E0 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -782,9 +792,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - INFOPLIST_FILE = "TTTwitter-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphoneos4.0; + SDKROOT = iphoneos; }; name = Debug; }; @@ -793,9 +801,7 @@ baseConfigurationReference = 6E6462D91187E6A900F08CB1 /* App.xcconfig */; buildSettings = { COPY_PHASE_STRIP = YES; - INFOPLIST_FILE = "TTTwitter-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphoneos4.0; + SDKROOT = iphoneos; }; name = Release; }; @@ -803,13 +809,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6462DA1187E6A900F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.0; + SDKROOT = iphoneos; }; name = Debug; }; @@ -817,13 +821,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6462DA1187E6A900F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.0; + SDKROOT = iphoneos; }; name = Release; }; diff --git a/samples/TTTwitter/main.m b/samples/TTTwitter/main.m index 2915dbbb29..1cefab29fe 100644 --- a/samples/TTTwitter/main.m +++ b/samples/TTTwitter/main.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/DemoMessageController.h b/samples/UI/TTNibDemo/Classes/DemoMessageController.h index b860947806..5e808c0011 100644 --- a/samples/UI/TTNibDemo/Classes/DemoMessageController.h +++ b/samples/UI/TTNibDemo/Classes/DemoMessageController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/DemoMessageController.m b/samples/UI/TTNibDemo/Classes/DemoMessageController.m index fd752565fb..cf74977244 100644 --- a/samples/UI/TTNibDemo/Classes/DemoMessageController.m +++ b/samples/UI/TTNibDemo/Classes/DemoMessageController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/DemoPostController.h b/samples/UI/TTNibDemo/Classes/DemoPostController.h index ad554b20ff..ef6683644e 100644 --- a/samples/UI/TTNibDemo/Classes/DemoPostController.h +++ b/samples/UI/TTNibDemo/Classes/DemoPostController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/DemoPostController.m b/samples/UI/TTNibDemo/Classes/DemoPostController.m index c9bf9fd654..926bab7e87 100644 --- a/samples/UI/TTNibDemo/Classes/DemoPostController.m +++ b/samples/UI/TTNibDemo/Classes/DemoPostController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/DemoTableViewController.h b/samples/UI/TTNibDemo/Classes/DemoTableViewController.h index 66e1d4535c..4383f5e23c 100644 --- a/samples/UI/TTNibDemo/Classes/DemoTableViewController.h +++ b/samples/UI/TTNibDemo/Classes/DemoTableViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/DemoTableViewController.m b/samples/UI/TTNibDemo/Classes/DemoTableViewController.m index 7d040f6386..667bdde15a 100644 --- a/samples/UI/TTNibDemo/Classes/DemoTableViewController.m +++ b/samples/UI/TTNibDemo/Classes/DemoTableViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/DemoViewController.h b/samples/UI/TTNibDemo/Classes/DemoViewController.h index dadb1a077a..86459b7d30 100644 --- a/samples/UI/TTNibDemo/Classes/DemoViewController.h +++ b/samples/UI/TTNibDemo/Classes/DemoViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/DemoViewController.m b/samples/UI/TTNibDemo/Classes/DemoViewController.m index 53b0630705..4f8bdb6233 100644 --- a/samples/UI/TTNibDemo/Classes/DemoViewController.m +++ b/samples/UI/TTNibDemo/Classes/DemoViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/NibDemoAppDelegate.h b/samples/UI/TTNibDemo/Classes/NibDemoAppDelegate.h index 643c0c6744..ff7d5ded97 100644 --- a/samples/UI/TTNibDemo/Classes/NibDemoAppDelegate.h +++ b/samples/UI/TTNibDemo/Classes/NibDemoAppDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/NibDemoAppDelegate.m b/samples/UI/TTNibDemo/Classes/NibDemoAppDelegate.m index 947e952529..f1bcb0a108 100644 --- a/samples/UI/TTNibDemo/Classes/NibDemoAppDelegate.m +++ b/samples/UI/TTNibDemo/Classes/NibDemoAppDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/RootViewController.h b/samples/UI/TTNibDemo/Classes/RootViewController.h index 5b4157c565..dce677a88c 100644 --- a/samples/UI/TTNibDemo/Classes/RootViewController.h +++ b/samples/UI/TTNibDemo/Classes/RootViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/RootViewController.m b/samples/UI/TTNibDemo/Classes/RootViewController.m index 8c01b95a12..2c6e6cab36 100644 --- a/samples/UI/TTNibDemo/Classes/RootViewController.m +++ b/samples/UI/TTNibDemo/Classes/RootViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/StyleSheet.h b/samples/UI/TTNibDemo/Classes/StyleSheet.h index 67f1608619..67a9b9a489 100644 --- a/samples/UI/TTNibDemo/Classes/StyleSheet.h +++ b/samples/UI/TTNibDemo/Classes/StyleSheet.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Classes/StyleSheet.m b/samples/UI/TTNibDemo/Classes/StyleSheet.m index a94a38377c..8f623cba0e 100644 --- a/samples/UI/TTNibDemo/Classes/StyleSheet.m +++ b/samples/UI/TTNibDemo/Classes/StyleSheet.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Configurations/App.xcconfig b/samples/UI/TTNibDemo/Configurations/App.xcconfig index 327e213447..febefe95fb 100644 --- a/samples/UI/TTNibDemo/Configurations/App.xcconfig +++ b/samples/UI/TTNibDemo/Configurations/App.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,6 @@ #include "../../common/Configurations/Libraries.xcconfig" #include "RelPath.xcconfig" -PRODUCT_NAME = TTNibDemo +BASE_PRODUCT_NAME = TTNibDemo +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/samples/UI/TTNibDemo/Configurations/Project.xcconfig b/samples/UI/TTNibDemo/Configurations/Project.xcconfig index 0f02ea7f79..fc1966a5f7 100644 --- a/samples/UI/TTNibDemo/Configurations/Project.xcconfig +++ b/samples/UI/TTNibDemo/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Configurations/RelPath.xcconfig b/samples/UI/TTNibDemo/Configurations/RelPath.xcconfig index 7510c4e4be..e869ea439f 100644 --- a/samples/UI/TTNibDemo/Configurations/RelPath.xcconfig +++ b/samples/UI/TTNibDemo/Configurations/RelPath.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/Configurations/UnitTests.xcconfig b/samples/UI/TTNibDemo/Configurations/UnitTests.xcconfig index 414adbafb1..a568db59da 100644 --- a/samples/UI/TTNibDemo/Configurations/UnitTests.xcconfig +++ b/samples/UI/TTNibDemo/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/UI/TTNibDemo/TTNibDemo.xcodeproj/project.pbxproj b/samples/UI/TTNibDemo/TTNibDemo.xcodeproj/project.pbxproj index da5782e97f..22d0090fb0 100755 --- a/samples/UI/TTNibDemo/TTNibDemo.xcodeproj/project.pbxproj +++ b/samples/UI/TTNibDemo/TTNibDemo.xcodeproj/project.pbxproj @@ -343,7 +343,7 @@ isa = PBXGroup; children = ( 6E37964011B9B8400011C497 /* libThree20Network.a */, - 6E37964211B9B8400011C497 /* UnitTests.octest */, + 6E37964211B9B8400011C497 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -352,7 +352,7 @@ isa = PBXGroup; children = ( 6E37964611B9B8400011C497 /* libThree20Style.a */, - 6E37964811B9B8400011C497 /* UnitTests.octest */, + 6E37964811B9B8400011C497 /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -361,7 +361,7 @@ isa = PBXGroup; children = ( 6E37964C11B9B8400011C497 /* libThree20UICommon.a */, - 6E37964E11B9B8400011C497 /* UnitTests.octest */, + 6E37964E11B9B8400011C497 /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -370,7 +370,7 @@ isa = PBXGroup; children = ( 6E37965211B9B8400011C497 /* libThree20UINavigator.a */, - 6E37965411B9B8400011C497 /* UnitTests.octest */, + 6E37965411B9B8400011C497 /* UINavigatorUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -379,7 +379,7 @@ isa = PBXGroup; children = ( 6E37965811B9B8400011C497 /* libThree20UI.a */, - 6E37965A11B9B8400011C497 /* UnitTests.octest */, + 6E37965A11B9B8400011C497 /* UIUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -421,7 +421,7 @@ isa = PBXGroup; children = ( 6E60855711B0DED900C93CD4 /* libThree20.a */, - 6E60855911B0DED900C93CD4 /* UnitTests.octest */, + 6E60855911B0DED900C93CD4 /* Three20UnitTests.octest */, ); name = Products; sourceTree = ""; @@ -532,8 +532,13 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TTNibDemo" */; compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, @@ -603,10 +608,10 @@ remoteRef = 6E37963F11B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37964211B9B8400011C497 /* UnitTests.octest */ = { + 6E37964211B9B8400011C497 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E37964111B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -617,10 +622,10 @@ remoteRef = 6E37964511B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37964811B9B8400011C497 /* UnitTests.octest */ = { + 6E37964811B9B8400011C497 /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E37964711B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -631,10 +636,10 @@ remoteRef = 6E37964B11B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37964E11B9B8400011C497 /* UnitTests.octest */ = { + 6E37964E11B9B8400011C497 /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6E37964D11B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -645,10 +650,10 @@ remoteRef = 6E37965111B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37965411B9B8400011C497 /* UnitTests.octest */ = { + 6E37965411B9B8400011C497 /* UINavigatorUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UINavigatorUnitTests.octest; remoteRef = 6E37965311B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -659,10 +664,10 @@ remoteRef = 6E37965711B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E37965A11B9B8400011C497 /* UnitTests.octest */ = { + 6E37965A11B9B8400011C497 /* UIUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UIUnitTests.octest; remoteRef = 6E37965911B9B8400011C497 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -673,10 +678,10 @@ remoteRef = 6E60855611B0DED900C93CD4 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E60855911B0DED900C93CD4 /* UnitTests.octest */ = { + 6E60855911B0DED900C93CD4 /* Three20UnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = Three20UnitTests.octest; remoteRef = 6E60855811B0DED900C93CD4 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -767,9 +772,7 @@ COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - INFOPLIST_FILE = "TTNibDemo-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphoneos4.0; + SDKROOT = iphoneos; }; name = Debug; }; @@ -778,9 +781,7 @@ baseConfigurationReference = 6E6084F311B0DEA600C93CD4 /* App.xcconfig */; buildSettings = { COPY_PHASE_STRIP = YES; - INFOPLIST_FILE = "TTNibDemo-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.2; - SDKROOT = iphoneos4.0; + SDKROOT = iphoneos; }; name = Release; }; @@ -788,27 +789,23 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6084F411B0DEA600C93CD4 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.0; + SDKROOT = iphoneos; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = iphoneos3.0; + SDKROOT = iphoneos; }; name = Release; }; diff --git a/samples/UI/TTNibDemo/main.m b/samples/UI/TTNibDemo/main.m index 5e37373d1a..8dfb69ae35 100644 --- a/samples/UI/TTNibDemo/main.m +++ b/samples/UI/TTNibDemo/main.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/common/Configurations/App.xcconfig b/samples/common/Configurations/App.xcconfig index 6042e3f3e3..df39effefb 100644 --- a/samples/common/Configurations/App.xcconfig +++ b/samples/common/Configurations/App.xcconfig @@ -15,12 +15,17 @@ // GCC_PRECOMPILE_PREFIX_HEADER = YES -GCC_PREFIX_HEADER = $(SRCROOT)/Headers/$(PRODUCT_NAME)_Prefix.pch +GCC_PREFIX_HEADER = $(SRCROOT)/Headers/$(BASE_PRODUCT_NAME)_Prefix.pch RUN_CLANG_STATIC_ANALYZER = NO +FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)/Developer/Library/Frameworks" +IPHONEOS_DEPLOYMENT_TARGET = 3.0 + +INFOPLIST_FILE = $(BASE_PRODUCT_NAME)-Info.plist + // Linker Flags -OTHER_LDFLAGS = $(OBJC_LIBRARY) $(OBJC_ALLLOAD) +OTHER_LDFLAGS = $(OBJC_LIBRARY) // Warning flags diff --git a/src/Three20.bundle/cs.lproj/Localizable.strings b/src/Three20.bundle/cs.lproj/Localizable.strings new file mode 100644 index 0000000000..1a7262a07e Binary files /dev/null and b/src/Three20.bundle/cs.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/de.lproj/Localizable.strings b/src/Three20.bundle/de.lproj/Localizable.strings index 3b1fdc44fa..34a498d50a 100644 Binary files a/src/Three20.bundle/de.lproj/Localizable.strings and b/src/Three20.bundle/de.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/es.lproj/Localizable.strings b/src/Three20.bundle/es.lproj/Localizable.strings index 35ba8b10f5..55c0b98242 100644 Binary files a/src/Three20.bundle/es.lproj/Localizable.strings and b/src/Three20.bundle/es.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/fr.lproj/Localizable.strings b/src/Three20.bundle/fr.lproj/Localizable.strings index 1cd192de65..6a139eb509 100644 Binary files a/src/Three20.bundle/fr.lproj/Localizable.strings and b/src/Three20.bundle/fr.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/he.lproj/Localizable.strings b/src/Three20.bundle/he.lproj/Localizable.strings new file mode 100755 index 0000000000..8cab26ee6a Binary files /dev/null and b/src/Three20.bundle/he.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/images/backIcon.png b/src/Three20.bundle/images/backIcon.png index 12515d11b1..946ce2a8e2 100644 Binary files a/src/Three20.bundle/images/backIcon.png and b/src/Three20.bundle/images/backIcon.png differ diff --git a/src/Three20.bundle/images/backIcon@2x.png b/src/Three20.bundle/images/backIcon@2x.png new file mode 100644 index 0000000000..2694eac538 Binary files /dev/null and b/src/Three20.bundle/images/backIcon@2x.png differ diff --git a/src/Three20.bundle/images/blueArrow.png b/src/Three20.bundle/images/blueArrow.png old mode 100755 new mode 100644 index 9ee946b5f9..51aefeaacd Binary files a/src/Three20.bundle/images/blueArrow.png and b/src/Three20.bundle/images/blueArrow.png differ diff --git a/src/Three20.bundle/images/blueArrow@2x.png b/src/Three20.bundle/images/blueArrow@2x.png new file mode 100644 index 0000000000..91399cea8f Binary files /dev/null and b/src/Three20.bundle/images/blueArrow@2x.png differ diff --git a/src/Three20.bundle/images/forwardIcon.png b/src/Three20.bundle/images/forwardIcon.png index 8aceddeffb..fd59ee3048 100644 Binary files a/src/Three20.bundle/images/forwardIcon.png and b/src/Three20.bundle/images/forwardIcon.png differ diff --git a/src/Three20.bundle/images/forwardIcon@2x.png b/src/Three20.bundle/images/forwardIcon@2x.png new file mode 100644 index 0000000000..732d9e6612 Binary files /dev/null and b/src/Three20.bundle/images/forwardIcon@2x.png differ diff --git a/src/Three20.bundle/images/photoDefault.png b/src/Three20.bundle/images/photoDefault.png index 35d940fb83..d38e49a4d1 100644 Binary files a/src/Three20.bundle/images/photoDefault.png and b/src/Three20.bundle/images/photoDefault.png differ diff --git a/src/Three20.bundle/images/photoDefault@2x.png b/src/Three20.bundle/images/photoDefault@2x.png new file mode 100644 index 0000000000..c6a49d6816 Binary files /dev/null and b/src/Three20.bundle/images/photoDefault@2x.png differ diff --git a/src/Three20.bundle/images/reloadButton.png b/src/Three20.bundle/images/reloadButton.png new file mode 100644 index 0000000000..8342763025 Binary files /dev/null and b/src/Three20.bundle/images/reloadButton.png differ diff --git a/src/Three20.bundle/images/reloadButton@2x.png b/src/Three20.bundle/images/reloadButton@2x.png new file mode 100644 index 0000000000..c47752c121 Binary files /dev/null and b/src/Three20.bundle/images/reloadButton@2x.png differ diff --git a/src/Three20.bundle/images/reloadButtonActive.png b/src/Three20.bundle/images/reloadButtonActive.png new file mode 100644 index 0000000000..2bf3fce281 Binary files /dev/null and b/src/Three20.bundle/images/reloadButtonActive.png differ diff --git a/src/Three20.bundle/images/reloadButtonActive@2x.png b/src/Three20.bundle/images/reloadButtonActive@2x.png new file mode 100644 index 0000000000..97c7558d4c Binary files /dev/null and b/src/Three20.bundle/images/reloadButtonActive@2x.png differ diff --git a/src/Three20.bundle/it.lproj/Localizable.strings b/src/Three20.bundle/it.lproj/Localizable.strings index bff0f6a4f0..3281672c03 100644 Binary files a/src/Three20.bundle/it.lproj/Localizable.strings and b/src/Three20.bundle/it.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/ja.lproj/Localizable.strings b/src/Three20.bundle/ja.lproj/Localizable.strings index 3a8c047dba..b994a64592 100644 Binary files a/src/Three20.bundle/ja.lproj/Localizable.strings and b/src/Three20.bundle/ja.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/ko.lproj/Localizable.strings b/src/Three20.bundle/ko.lproj/Localizable.strings index 137e6bc470..6058ca146e 100644 Binary files a/src/Three20.bundle/ko.lproj/Localizable.strings and b/src/Three20.bundle/ko.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/nl.lproj/Localizable.strings b/src/Three20.bundle/nl.lproj/Localizable.strings index 353675eefd..c3effcd7c5 100644 Binary files a/src/Three20.bundle/nl.lproj/Localizable.strings and b/src/Three20.bundle/nl.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/pl.lproj/Localizable.strings b/src/Three20.bundle/pl.lproj/Localizable.strings deleted file mode 100644 index 196431f212..0000000000 Binary files a/src/Three20.bundle/pl.lproj/Localizable.strings and /dev/null differ diff --git a/src/Three20.bundle/pt.lproj/Localizable.strings b/src/Three20.bundle/pt.lproj/Localizable.strings index 6866570592..fd554071a5 100644 Binary files a/src/Three20.bundle/pt.lproj/Localizable.strings and b/src/Three20.bundle/pt.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/ru.lproj/Localizable.strings b/src/Three20.bundle/ru.lproj/Localizable.strings index bef4d373b7..7ebd0c8ffe 100644 Binary files a/src/Three20.bundle/ru.lproj/Localizable.strings and b/src/Three20.bundle/ru.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/tr.lproj/Localizable.strings b/src/Three20.bundle/tr.lproj/Localizable.strings new file mode 100644 index 0000000000..b12eef3106 Binary files /dev/null and b/src/Three20.bundle/tr.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/zh_cn.lproj/Localizable.strings b/src/Three20.bundle/zh_cn.lproj/Localizable.strings index 3e020cb819..d29cff6ae3 100644 Binary files a/src/Three20.bundle/zh_cn.lproj/Localizable.strings and b/src/Three20.bundle/zh_cn.lproj/Localizable.strings differ diff --git a/src/Three20.bundle/zh_tw.lproj/Localizable.strings b/src/Three20.bundle/zh_tw.lproj/Localizable.strings index 2e9c1684f7..d9d62e1636 100644 Binary files a/src/Three20.bundle/zh_tw.lproj/Localizable.strings and b/src/Three20.bundle/zh_tw.lproj/Localizable.strings differ diff --git a/src/Three20/Configurations/Library.xcconfig b/src/Three20/Configurations/Library.xcconfig index 9a91824223..328eac0bd1 100644 --- a/src/Three20/Configurations/Library.xcconfig +++ b/src/Three20/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,5 +17,5 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = Three20 +BASE_PRODUCT_NAME = Three20 BUILD_LIBRARY_VERSION = 1.0 diff --git a/src/Three20/Configurations/Project.xcconfig b/src/Three20/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/Three20/Configurations/Project.xcconfig +++ b/src/Three20/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20/Configurations/UnitTests.xcconfig b/src/Three20/Configurations/UnitTests.xcconfig index ea4fd0ccbc..73d683fd8e 100644 --- a/src/Three20/Configurations/UnitTests.xcconfig +++ b/src/Three20/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = Three20UnitTests +BASE_PRODUCT_NAME = Three20UnitTests BUILD_BUNDLE_VERSION = 1.0 -OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(COREGRAPHICS_FX) +OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(COREGRAPHICS_FX) $(QUARTZCORE_FX) diff --git a/src/Three20/Headers/Three20+Additions.h b/src/Three20/Headers/Three20+Additions.h index 8615d8f4b5..dd2e5274f5 100644 --- a/src/Three20/Headers/Three20+Additions.h +++ b/src/Three20/Headers/Three20+Additions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20/Headers/Three20.h b/src/Three20/Headers/Three20.h index 333a462f26..db1a872adc 100644 --- a/src/Three20/Headers/Three20.h +++ b/src/Three20/Headers/Three20.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,46 +14,6 @@ // limitations under the License. // -/*! \mainpage Three20 API Documentation - * - * \section intro_sec Introduction - * - * All of the API documentation you see here has been generated from the Three20 source. - * - * Get the source: http://github.com/facebook/three20 - * - * Three20 is a rather large iPhone development library. It is composed of a stack of four - * components: - * - *
- * UI - * Style - * Network - * Core - *
- * - * \section Core - * - * Three20's foundation includes debugging utilities and a plethora of useful additions to common - * objects. - * - * \section Network - * - * A full network+cache implementation has been built around NSURLRequests with support for - * disc and memory caching. - * - * \section Style - * - * A robust style framework that makes it easy to create gradients, shadows, and rounded borders. - * - * \section UI - * - * Three20 includes a growing set of common controls. Photo browsers, table view cells, and - * springboard implementations are just a few. The UI component includes the TTNavigator object - * that makes building persistent applications easy. - * - */ - // Core #import "Three20Core/Three20Core.h" diff --git a/src/Three20/Source/Three20.m b/src/Three20/Source/Three20.m index ced309ec27..e5183a44ac 100644 --- a/src/Three20/Source/Three20.m +++ b/src/Three20/Source/Three20.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20/Three20.xcodeproj/project.pbxproj b/src/Three20/Three20.xcodeproj/project.pbxproj index 1ed4ed9fcf..10823f8fbf 100755 --- a/src/Three20/Three20.xcodeproj/project.pbxproj +++ b/src/Three20/Three20.xcodeproj/project.pbxproj @@ -3,10 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 665A56D71265240E0032D0BE /* BasicTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 665A56D61265240E0032D0BE /* BasicTests.m */; }; 6E6454741184D2CD00F08CB1 /* Three20.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E6454731184D2CD00F08CB1 /* Three20.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E6454931184D3ED00F08CB1 /* Three20+Additions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E6454921184D3ED00F08CB1 /* Three20+Additions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E6454AA1184D43100F08CB1 /* libThree20Style.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E6454A71184D42800F08CB1 /* libThree20Style.a */; }; @@ -19,6 +20,55 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 66FC2E291265264C00F56B19 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = "Three20-Xcode3.2.4"; + }; + 66FC2E2B1265264C00F56B19 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = EB9E6C6110B6A8F800DE563C; + remoteInfo = "UnitTests-Xcode3.2.4"; + }; + 66FC2E2D1265264C00F56B19 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EE7389D1184ADB400A35176 /* Three20Network.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = EB9E6C6110B6A8F800DE563C; + remoteInfo = "UnitTests-Xcode3.2.4"; + }; + 66FC2E2F1265264C00F56B19 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EDAEA03118CA5B50008133C /* Three20UICommon.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = EB9E6C6110B6A8F800DE563C; + remoteInfo = "UnitTests-Xcode3.2.4"; + }; + 66FC2E311265264C00F56B19 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EDAEA0C118CA5BE0008133C /* Three20UINavigator.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = EB9E6C6110B6A8F800DE563C; + remoteInfo = "UnitTests-Xcode3.2.4"; + }; + 66FC2E331265264C00F56B19 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E6454A11184D42800F08CB1 /* Three20Style.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = EB9E6C6110B6A8F800DE563C; + remoteInfo = "UnitTests-Xcode3.2.4"; + }; + 66FC2E351265264C00F56B19 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E7F9677118E353700443B46 /* Three20UI.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = EB9E6C6110B6A8F800DE563C; + remoteInfo = "UnitTests-Xcode3.2.4"; + }; 6E6454A61184D42800F08CB1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E6454A11184D42800F08CB1 /* Three20Style.xcodeproj */; @@ -33,13 +83,6 @@ remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; - 6E6454AC1184D45600F08CB1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6E6454A11184D42800F08CB1 /* Three20Style.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = EB9E6C6110B6A8F800DE563C; - remoteInfo = UnitTests; - }; 6E6454AE1184D46800F08CB1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E6454A11184D42800F08CB1 /* Three20Style.xcodeproj */; @@ -110,20 +153,6 @@ remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UINavigator; }; - 6EDAEA19118CA5D30008133C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6EDAEA03118CA5B50008133C /* Three20UICommon.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2; - remoteInfo = Three20UICommon; - }; - 6EDAEA1B118CA5D30008133C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6EDAEA0C118CA5BE0008133C /* Three20UINavigator.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2; - remoteInfo = Three20UINavigator; - }; 6EE7366B11849C5800A35176 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */; @@ -145,20 +174,6 @@ remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Core; }; - 6EE736C411849F9D00A35176 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = EB9E6C6110B6A8F800DE563C; - remoteInfo = UnitTests; - }; - 6EE736C611849FA000A35176 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2; - remoteInfo = Three20; - }; 6EE738A21184ADB400A35176 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6EE7389D1184ADB400A35176 /* Three20Network.xcodeproj */; @@ -180,16 +195,10 @@ remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Network; }; - 6EE738AC1184ADE300A35176 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6EE7389D1184ADB400A35176 /* Three20Network.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = EB9E6C6110B6A8F800DE563C; - remoteInfo = UnitTests; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 665A56D61265240E0032D0BE /* BasicTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BasicTests.m; path = UnitTests/BasicTests.m; sourceTree = ""; }; 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Project.xcconfig; path = Configurations/Project.xcconfig; sourceTree = ""; }; 6E6454731184D2CD00F08CB1 /* Three20.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Three20.h; path = Headers/Three20.h; sourceTree = ""; }; 6E6454921184D3ED00F08CB1 /* Three20+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Three20+Additions.h"; path = "Headers/Three20+Additions.h"; sourceTree = ""; }; @@ -205,7 +214,7 @@ 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; 6EE7389D1184ADB400A35176 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; BEF31F3A0F352DF5000DE5D2 /* libThree20.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libThree20.a; sourceTree = BUILT_PRODUCTS_DIR; }; - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB9E6C6210B6A8F800DE563C /* Three20UnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Three20UnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -236,7 +245,7 @@ isa = PBXGroup; children = ( BEF31F3A0F352DF5000DE5D2 /* libThree20.a */, - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */, + EB9E6C6210B6A8F800DE563C /* Three20UnitTests.octest */, ); name = Products; sourceTree = ""; @@ -260,6 +269,7 @@ isa = PBXGroup; children = ( 6EE7364611849AF200A35176 /* Resources */, + 665A56D61265240E0032D0BE /* BasicTests.m */, ); name = Tests; sourceTree = ""; @@ -281,7 +291,7 @@ isa = PBXGroup; children = ( 6E6454A71184D42800F08CB1 /* libThree20Style.a */, - 6E6454A91184D42800F08CB1 /* UnitTests.octest */, + 6E6454A91184D42800F08CB1 /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -290,7 +300,7 @@ isa = PBXGroup; children = ( 6E7F9685118E353800443B46 /* libThree20UI.a */, - 6E7F9687118E353800443B46 /* UnitTests.octest */, + 6E7F9687118E353800443B46 /* UIUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -307,7 +317,7 @@ isa = PBXGroup; children = ( 6EDAEA09118CA5B50008133C /* libThree20UICommon.a */, - 6EDAEA0B118CA5B50008133C /* UnitTests.octest */, + 6EDAEA0B118CA5B50008133C /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -316,7 +326,7 @@ isa = PBXGroup; children = ( 6EDAEA12118CA5BE0008133C /* libThree20UINavigator.a */, - 6EDAEA14118CA5BE0008133C /* UnitTests.octest */, + 6EDAEA14118CA5BE0008133C /* UINavigatorUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -352,7 +362,7 @@ isa = PBXGroup; children = ( 6EE738A31184ADB400A35176 /* libThree20Network.a */, - 6EE738A51184ADB400A35176 /* UnitTests.octest */, + 6EE738A51184ADB400A35176 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -379,6 +389,7 @@ BEF31F360F352DF5000DE5D2 /* Headers */, 6E645F461187B01F00F08CB1 /* Protect Copied Headers */, BEF31F370F352DF5000DE5D2 /* Sources */, + 668E6653131ADFFD00ACE4AB /* Lint */, BEF31F380F352DF5000DE5D2 /* Frameworks */, ); buildRules = ( @@ -396,9 +407,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libThree20.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTests */ = { + EB9E6C6110B6A8F800DE563C /* Three20UnitTests */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20UnitTests" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -408,16 +419,17 @@ buildRules = ( ); dependencies = ( - 6EE736C511849F9D00A35176 /* PBXTargetDependency */, - 6EE738AD1184ADE300A35176 /* PBXTargetDependency */, - 6E6454AD1184D45600F08CB1 /* PBXTargetDependency */, - 6EE736C711849FA000A35176 /* PBXTargetDependency */, - 6EDAEA1A118CA5D30008133C /* PBXTargetDependency */, - 6EDAEA1C118CA5D30008133C /* PBXTargetDependency */, - ); - name = UnitTests; + 66FC2E2A1265264C00F56B19 /* PBXTargetDependency */, + 66FC2E2C1265264C00F56B19 /* PBXTargetDependency */, + 66FC2E2E1265264C00F56B19 /* PBXTargetDependency */, + 66FC2E341265264C00F56B19 /* PBXTargetDependency */, + 66FC2E301265264C00F56B19 /* PBXTargetDependency */, + 66FC2E321265264C00F56B19 /* PBXTargetDependency */, + 66FC2E361265264C00F56B19 /* PBXTargetDependency */, + ); + name = Three20UnitTests; productName = CoreUnitTests; - productReference = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + productReference = EB9E6C6210B6A8F800DE563C /* Three20UnitTests.octest */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -425,9 +437,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Three20" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -459,7 +482,7 @@ projectRoot = ""; targets = ( BEF31F390F352DF5000DE5D2 /* Three20 */, - EB9E6C6110B6A8F800DE563C /* UnitTests */, + EB9E6C6110B6A8F800DE563C /* Three20UnitTests */, ); }; /* End PBXProject section */ @@ -472,10 +495,10 @@ remoteRef = 6E6454A61184D42800F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E6454A91184D42800F08CB1 /* UnitTests.octest */ = { + 6E6454A91184D42800F08CB1 /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E6454A81184D42800F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -486,10 +509,10 @@ remoteRef = 6E7F9684118E353800443B46 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E7F9687118E353800443B46 /* UnitTests.octest */ = { + 6E7F9687118E353800443B46 /* UIUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UIUnitTests.octest; remoteRef = 6E7F9686118E353800443B46 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -500,10 +523,10 @@ remoteRef = 6EDAEA08118CA5B50008133C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6EDAEA0B118CA5B50008133C /* UnitTests.octest */ = { + 6EDAEA0B118CA5B50008133C /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6EDAEA0A118CA5B50008133C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -514,10 +537,10 @@ remoteRef = 6EDAEA11118CA5BE0008133C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6EDAEA14118CA5BE0008133C /* UnitTests.octest */ = { + 6EDAEA14118CA5BE0008133C /* UINavigatorUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UINavigatorUnitTests.octest; remoteRef = 6EDAEA13118CA5BE0008133C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -542,10 +565,10 @@ remoteRef = 6EE738A21184ADB400A35176 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6EE738A51184ADB400A35176 /* UnitTests.octest */ = { + 6EE738A51184ADB400A35176 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6EE738A41184ADB400A35176 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -562,6 +585,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 668E6653131ADFFD00ACE4AB /* Lint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = Lint; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/usr/bin/env python ../scripts/lint"; + shellScript = ""; + showEnvVarsInLog = 0; + }; 6E645F461187B01F00F08CB1 /* Protect Copied Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -604,16 +642,47 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 665A56D71265240E0032D0BE /* BasicTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 6E6454AD1184D45600F08CB1 /* PBXTargetDependency */ = { + 66FC2E2A1265264C00F56B19 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BEF31F390F352DF5000DE5D2 /* Three20 */; + targetProxy = 66FC2E291265264C00F56B19 /* PBXContainerItemProxy */; + }; + 66FC2E2C1265264C00F56B19 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "UnitTests-Xcode3.2.4"; + targetProxy = 66FC2E2B1265264C00F56B19 /* PBXContainerItemProxy */; + }; + 66FC2E2E1265264C00F56B19 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "UnitTests-Xcode3.2.4"; + targetProxy = 66FC2E2D1265264C00F56B19 /* PBXContainerItemProxy */; + }; + 66FC2E301265264C00F56B19 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "UnitTests-Xcode3.2.4"; + targetProxy = 66FC2E2F1265264C00F56B19 /* PBXContainerItemProxy */; + }; + 66FC2E321265264C00F56B19 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "UnitTests-Xcode3.2.4"; + targetProxy = 66FC2E311265264C00F56B19 /* PBXContainerItemProxy */; + }; + 66FC2E341265264C00F56B19 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "UnitTests-Xcode3.2.4"; + targetProxy = 66FC2E331265264C00F56B19 /* PBXContainerItemProxy */; + }; + 66FC2E361265264C00F56B19 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = UnitTests; - targetProxy = 6E6454AC1184D45600F08CB1 /* PBXContainerItemProxy */; + name = "UnitTests-Xcode3.2.4"; + targetProxy = 66FC2E351265264C00F56B19 /* PBXContainerItemProxy */; }; 6E6454AF1184D46800F08CB1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -635,41 +704,16 @@ name = Three20UINavigator; targetProxy = 6EDAEA17118CA5CA0008133C /* PBXContainerItemProxy */; }; - 6EDAEA1A118CA5D30008133C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Three20UICommon; - targetProxy = 6EDAEA19118CA5D30008133C /* PBXContainerItemProxy */; - }; - 6EDAEA1C118CA5D30008133C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Three20UINavigator; - targetProxy = 6EDAEA1B118CA5D30008133C /* PBXContainerItemProxy */; - }; 6EE7367111849C6300A35176 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Three20Core; targetProxy = 6EE7367011849C6300A35176 /* PBXContainerItemProxy */; }; - 6EE736C511849F9D00A35176 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = UnitTests; - targetProxy = 6EE736C411849F9D00A35176 /* PBXContainerItemProxy */; - }; - 6EE736C711849FA000A35176 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = BEF31F390F352DF5000DE5D2 /* Three20 */; - targetProxy = 6EE736C611849FA000A35176 /* PBXContainerItemProxy */; - }; 6EE738AB1184ADD000A35176 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Three20Network; targetProxy = 6EE738AA1184ADD000A35176 /* PBXContainerItemProxy */; }; - 6EE738AD1184ADE300A35176 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = UnitTests; - targetProxy = 6EE738AC1184ADE300A35176 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -677,14 +721,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; @@ -696,9 +737,11 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + PRODUCT_NAME = "$(BASE_PRODUCT_NAME)"; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; @@ -706,19 +749,14 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + PRODUCT_NAME = "$(BASE_PRODUCT_NAME)"; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Internal; @@ -731,7 +769,8 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + PRODUCT_NAME = "$(BASE_PRODUCT_NAME)"; + SDKROOT = iphoneos; }; name = Debug; }; @@ -741,8 +780,8 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PREBINDING = NO; + PRODUCT_NAME = "$(BASE_PRODUCT_NAME)"; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -751,14 +790,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -766,13 +802,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -780,19 +814,14 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + PRODUCT_NAME = "$(BASE_PRODUCT_NAME)"; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Debug; @@ -801,18 +830,12 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - HEADER_SEARCH_PATHS = .; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + PRODUCT_NAME = "$(BASE_PRODUCT_NAME)"; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; ZERO_LINK = NO; }; @@ -841,7 +864,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20UnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/Three20/UnitTests/BasicTests.m b/src/Three20/UnitTests/BasicTests.m new file mode 100644 index 0000000000..4bbf68b021 --- /dev/null +++ b/src/Three20/UnitTests/BasicTests.m @@ -0,0 +1,42 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// See: http://bit.ly/hS5nNh for unit test macros. + +#import +#import + +#import "Three20Style/TTGlobalStyle.h" + +@interface BasicTests : SenTestCase { +} + +@end + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation BasicTests + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testTruth { + STAssertTrue(true, @"True!"); +} + + +@end diff --git a/src/Three20Core/Configurations/Library.xcconfig b/src/Three20Core/Configurations/Library.xcconfig index 63dcd42977..9dfc080955 100644 --- a/src/Three20Core/Configurations/Library.xcconfig +++ b/src/Three20Core/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,5 +17,6 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = Three20Core +BASE_PRODUCT_NAME = Three20Core +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/src/Three20Core/Configurations/Project.xcconfig b/src/Three20Core/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/Three20Core/Configurations/Project.xcconfig +++ b/src/Three20Core/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Configurations/UnitTests.xcconfig b/src/Three20Core/Configurations/UnitTests.xcconfig index f26fa9715d..0b45d49c09 100644 --- a/src/Three20Core/Configurations/UnitTests.xcconfig +++ b/src/Three20Core/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = CoreUnitTests -BUILD_BUNDLE_VERSION = 1.0 +BASE_PRODUCT_NAME = CoreUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME) +BUILD_BUNDLE_VERSION = 1.0 -OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(COREGRAPHICS_FX) +OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(COREGRAPHICS_FX) diff --git a/src/Three20Core/Headers/NSArrayAdditions.h b/src/Three20Core/Headers/NSArrayAdditions.h index 37a948c566..e904a70093 100644 --- a/src/Three20Core/Headers/NSArrayAdditions.h +++ b/src/Three20Core/Headers/NSArrayAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/NSDataAdditions.h b/src/Three20Core/Headers/NSDataAdditions.h index 84d5bd6cc0..48df7bd918 100644 --- a/src/Three20Core/Headers/NSDataAdditions.h +++ b/src/Three20Core/Headers/NSDataAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,4 +25,26 @@ */ @property (nonatomic, readonly) NSString* md5Hash; +/** + * Calculate the SHA1 hash of this data using CC_SHA1. + * + * @return SHA1 hash of this data + */ +@property (nonatomic, readonly) NSString* sha1Hash; + + +/** + * Create an NSData from a base64 encoded representation + * Padding '=' characters are optional. Whitespace is ignored. + * @return the NSData object + */ ++ (id)dataWithBase64EncodedString:(NSString *)string; + +/** + * Marshal the data into a base64 encoded representation + * + * @return the base64 encoded string + */ +- (NSString *)base64Encoding; + @end diff --git a/src/Three20Core/Headers/NSDateAdditions.h b/src/Three20Core/Headers/NSDateAdditions.h index de5bb7d730..649c0987bd 100644 --- a/src/Three20Core/Headers/NSDateAdditions.h +++ b/src/Three20Core/Headers/NSDateAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/NSMutableArrayAdditions.h b/src/Three20Core/Headers/NSMutableArrayAdditions.h index 56156b263c..a95f320709 100644 --- a/src/Three20Core/Headers/NSMutableArrayAdditions.h +++ b/src/Three20Core/Headers/NSMutableArrayAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/NSMutableDictionaryAdditions.h b/src/Three20Core/Headers/NSMutableDictionaryAdditions.h index a7d4ee7a4c..b01ad1c40d 100644 --- a/src/Three20Core/Headers/NSMutableDictionaryAdditions.h +++ b/src/Three20Core/Headers/NSMutableDictionaryAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/NSObjectAdditions.h b/src/Three20Core/Headers/NSObjectAdditions.h index 8a469f8b5f..23684c645b 100644 --- a/src/Three20Core/Headers/NSObjectAdditions.h +++ b/src/Three20Core/Headers/NSObjectAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/NSStringAdditions.h b/src/Three20Core/Headers/NSStringAdditions.h index 87dc6abe05..0482fd3bfa 100644 --- a/src/Three20Core/Headers/NSStringAdditions.h +++ b/src/Three20Core/Headers/NSStringAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ // #import +#import "Three20Core/TTCorePreprocessorMacros.h" // For __TTDEPRECATED_METHOD /** * Doxygen does not handle categories very well, so please refer to the .m file in general @@ -29,19 +30,59 @@ /** * Determines if the string is empty or contains only whitespace. + * @deprecated Use TTIsStringWithAnyText() instead. Updating your use of + * this method is non-trivial. See the note below. + * + * Notes for updating your use of isEmptyOrWhitespace: + * + * if (!textField.text.isEmptyOrWhitespace) { + * + * becomes + * + * if (TTIsStringWithAnyText(textField.text) && !textField.text.isWhitespaceAndNewlines) { + * + * and + * + * if (textField.text.isEmptyOrWhitespace) { + * + * becomes + * + * if (0 == textField.text.length || textField.text.isWhitespaceAndNewlines) { */ -- (BOOL)isEmptyOrWhitespace; +- (BOOL)isEmptyOrWhitespace __TTDEPRECATED_METHOD; /** * Parses a URL query string into a dictionary. + * + * @deprecated Use queryContentsUsingEncoding: instead. + */ +- (NSDictionary*)queryDictionaryUsingEncoding:(NSStringEncoding)encoding __TTDEPRECATED_METHOD; + +/** + * Parses a URL query string into a dictionary where the values are arrays. */ -- (NSDictionary*)queryDictionaryUsingEncoding:(NSStringEncoding)encoding; +- (NSDictionary*)queryContentsUsingEncoding:(NSStringEncoding)encoding; /** * Parses a URL, adds query parameters to its query, and re-encodes it as a new URL. */ - (NSString*)stringByAddingQueryDictionary:(NSDictionary*)query; +/** + * Parses a URL, adds urlEncoded query parameters to its query, and re-encodes it as a new URL. + * + * This method encodes keys and values of query using [NSString urlEncoded] and calls + * stringByAddingQueryDictionary with the resulting dictionary. + * + * @throw NSInvalidArgumentException If any value or key does not respond to urlEncoded. + */ +- (NSString*)stringByAddingURLEncodedQueryDictionary:(NSDictionary*)query; + +/** + * Returns a URL Encoded String + */ +- (NSString*)urlEncoded; + /** * Returns a string with all HTML tags removed. */ @@ -88,5 +129,12 @@ */ @property (nonatomic, readonly) NSString* md5Hash; +/** + * Calculate the SHA1 hash of this string using CommonCrypto CC_SHA1. + * + * @return NSString with SHA1 hash of this string + */ +@property (nonatomic, readonly) NSString* sha1Hash; + @end diff --git a/src/Three20Core/Headers/TTAvailability.h b/src/Three20Core/Headers/TTAvailability.h new file mode 100644 index 0000000000..95c5d61562 --- /dev/null +++ b/src/Three20Core/Headers/TTAvailability.h @@ -0,0 +1,87 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +/** + * SDK definitions useful in availability checks for conditionally compiling code. + * + * Example: + * + * #if __IPHONE_OS_VERSION_MAX_ALLOWED >= TTIOS_3_2 + * // This code will only compile on versions >= iOS 3.2 + * #endif + * + * These macros are defined unconditionally and separately from the __IPHONE_* macros + * because there might be methods that use the #ifdef state of one of the __IPHONE_ macros + * to conditionally compile their code (however incorrect this may be). + */ +#define TTIOS_2_0 20000 +#define TTIOS_2_1 20100 +#define TTIOS_2_2 20200 +#define TTIOS_3_0 30000 +#define TTIOS_3_1 30100 +#define TTIOS_3_2 30200 +#define TTIOS_4_0 40000 +#define TTIOS_4_1 40100 +#define TTIOS_4_2 40200 + +/** + * Flesh out the known SDK version numbers. + */ +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_0 +#define kCFCoreFoundationVersionNumber_iPhoneOS_2_0 478.23 +#endif + +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_1 +#define kCFCoreFoundationVersionNumber_iPhoneOS_2_1 478.26 +#endif + +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_2 +#define kCFCoreFoundationVersionNumber_iPhoneOS_2_2 478.29 +#endif + +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_0 +#define kCFCoreFoundationVersionNumber_iPhoneOS_3_0 478.47 +#endif + +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_1 +#define kCFCoreFoundationVersionNumber_iPhoneOS_3_1 478.52 +#endif + +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_2 +#define kCFCoreFoundationVersionNumber_iPhoneOS_3_2 478.61 +#endif + +#ifndef kCFCoreFoundationVersionNumber_iOS_4_0 +#define kCFCoreFoundationVersionNumber_iOS_4_0 550.32 +#endif + +/** + * Checks whether the device's OS version is at least the given version number. + * + * @param versionNumber Any value of kCFCoreFoundationVersionNumber from above. + */ +BOOL TTDeviceOSVersionIsAtLeast(double versionNumber); + +/** + * Use NSClassFromString to fetch the popover controller class. + * + * The class is cached to avoid repeated lookups. + */ +Class TTUIPopoverControllerClass(); + diff --git a/src/Three20Core/Headers/TTCorePreprocessorMacros.h b/src/Three20Core/Headers/TTCorePreprocessorMacros.h index ffafb9e191..47828ab5f2 100644 --- a/src/Three20Core/Headers/TTCorePreprocessorMacros.h +++ b/src/Three20Core/Headers/TTCorePreprocessorMacros.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,9 @@ // limitations under the License. // +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Code Management + /** * Borrowed from Apple's AvailabiltyInternal.h header. There's no reason why we shouldn't be * able to use this macro, as it's a gcc-supported flag. @@ -22,12 +25,14 @@ */ #define __TTDEPRECATED_METHOD __attribute__((deprecated)) -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Errors - -#define TT_ERROR_DOMAIN @"three20.net" - -#define TT_EC_INVALID_IMAGE 101 +/** + * Add this macro before each category implementation, so we don't have to use + * -all_load or -force_load to load object files from static libraries that only contain + * categories and no classes. + * See http://developer.apple.com/library/mac/#qa/qa2006/qa1490.html for more info. + */ +#define TT_FIX_CATEGORY_BUG(name) @interface TT_FIX_CATEGORY_BUG_##name @end \ + @implementation TT_FIX_CATEGORY_BUG_##name @end /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Three20Core/Headers/TTDebug.h b/src/Three20Core/Headers/TTDebug.h index 3c9558e0a0..f4e910d1c8 100644 --- a/src/Three20Core/Headers/TTDebug.h +++ b/src/Three20Core/Headers/TTDebug.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -68,11 +68,11 @@ int TTIsInDebugger(); // We leave the __asm__ in this macro so that when a break occurs, we don't have to step out of // a "breakInDebugger" function. - #define TTDASSERT(xx) { if(!(xx)) { TTDPRINT(@"TTDASSERT failed: %s", #xx); \ - if(TTIsInDebugger()) { __asm__("int $3\n" : : ); }; } \ + #define TTDASSERT(xx) { if (!(xx)) { TTDPRINT(@"TTDASSERT failed: %s", #xx); \ + if (TTIsInDebugger()) { __asm__("int $3\n" : : ); }; } \ } ((void)0) #else - #define TTDASSERT(xx) { if(!(xx)) { TTDPRINT(@"TTDASSERT failed: %s", #xx); } } ((void)0) + #define TTDASSERT(xx) { if (!(xx)) { TTDPRINT(@"TTDASSERT failed: %s", #xx); } } ((void)0) #endif // #if TARGET_IPHONE_SIMULATOR #else diff --git a/src/Three20Core/Headers/TTDebugFlags.h b/src/Three20Core/Headers/TTDebugFlags.h index 0a350da939..9c64b4cbef 100644 --- a/src/Three20Core/Headers/TTDebugFlags.h +++ b/src/Three20Core/Headers/TTDebugFlags.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/TTEntityTables.h b/src/Three20Core/Headers/TTEntityTables.h index ed1d1b0541..8c824b92dc 100644 --- a/src/Three20Core/Headers/TTEntityTables.h +++ b/src/Three20Core/Headers/TTEntityTables.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/TTExtensionAuthor.h b/src/Three20Core/Headers/TTExtensionAuthor.h new file mode 100644 index 0000000000..c595be39c4 --- /dev/null +++ b/src/Three20Core/Headers/TTExtensionAuthor.h @@ -0,0 +1,46 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@interface TTExtensionAuthor : NSObject { +@private + NSString* _name; + NSString* _github; + NSString* _twitter; + NSString* _website; +} + +@property (nonatomic, copy) NSString* name; +@property (nonatomic, copy) NSString* github; +@property (nonatomic, copy) NSString* twitter; +@property (nonatomic, copy) NSString* website; + ++ (id)authorWithName: (NSString*)name; + ++ (id)authorWithName: (NSString*)name + github: (NSString*)github + twitter: (NSString*)twitter + website: (NSString*)website; + +// Designated initializer +- (id)initWithName: (NSString*)name + github: (NSString*)github + twitter: (NSString*)twitter + website: (NSString*)website; + +@end diff --git a/src/Three20Core/Headers/TTExtensionInfo.h b/src/Three20Core/Headers/TTExtensionInfo.h new file mode 100644 index 0000000000..d701342f68 --- /dev/null +++ b/src/Three20Core/Headers/TTExtensionInfo.h @@ -0,0 +1,39 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@interface TTExtensionInfo : NSObject { +@private + NSString* _id; + NSString* _name; + NSString* _description; + NSString* _version; + NSString* _copyright; + NSString* _license; + NSArray* _authors; +} + +@property (nonatomic, readonly) NSString* identifier; +@property (nonatomic, copy) NSString* name; +@property (nonatomic, copy) NSString* description; +@property (nonatomic, copy) NSString* version; +@property (nonatomic, copy) NSString* copyright; +@property (nonatomic, copy) NSString* license; +@property (nonatomic, copy) NSArray* authors; // NSArray of TTExtensionAuthor* objects. + +@end diff --git a/src/Three20Core/Headers/TTExtensionInfoPrivate.h b/src/Three20Core/Headers/TTExtensionInfoPrivate.h new file mode 100644 index 0000000000..244ca04204 --- /dev/null +++ b/src/Three20Core/Headers/TTExtensionInfoPrivate.h @@ -0,0 +1,25 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/TTExtensionInfo.h" + + +@interface TTExtensionInfo (TTPrivate) + +- (void)setIdentifier:(NSString*)identifier; + +@end + diff --git a/src/Three20Core/Headers/TTExtensionLoader.h b/src/Three20Core/Headers/TTExtensionLoader.h new file mode 100644 index 0000000000..3729063a29 --- /dev/null +++ b/src/Three20Core/Headers/TTExtensionLoader.h @@ -0,0 +1,88 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +/** + * The extension loader provides basic utility methods to load extensions once an application + * has started running. + * + * [TTExtensionLoader loadAllExtensions]; + * + * is likely the only method you'll need to use. + * + * How it works: + * + * An extension creates a TTExtensionLoader category, e.g.: + * + * @interface TTExtensionLoader (TTXMLExtension) + * + * The extension then implements a method in this category with the prefix "loadExtensionNamed" + * + * - (BOOL)loadExtensionNamedThree20XML; + * + * This method will be called when loadAllExtensions is called and should be used to initialize + * any extension-specific functionality. A simple example of this might be to register some global + * navigator URLs for use by the application. + * + * The extension can then optionally implement a second method with the prefix + * "extensionInfoNamed". The text after the prefix should match that of the load method. + * + * - (TTExtensionInfo*)extensionInfoNamedThree20XML; + * + * This method should return an autoreleased TTExtensionInfo object that has been populated with + * any information the extension wishes to provide. If this method isn't implemented, a default + * TTExtensionInfo object will be created. + */ +@interface TTExtensionLoader : NSObject { + +} + +/** + * Load all extensions that provide a method of the following signature: + * - (BOOL)loadExtensionNamed + * + * For example: + * - (BOOL)loadExtensionNamedThree20XML + */ ++ (void)loadAllExtensions; + +/** + * Retrieve the map of available extensions. + * + * Format: + * [(NSString*)identifier] => (TTExtensionInfo*)extension + */ ++ (NSDictionary*)availableExtensions; + +/** + * Retrieve the map of loaded extensions. + * + * Format: + * [(NSString*)identifier] => (TTExtensionInfo*)extension + */ ++ (NSDictionary*)loadedExtensions; + +/** + * Retrieve the map of extensions that failed to load. + * + * Format: + * [(NSString*)identifier] => (TTExtensionInfo*)extension + */ ++ (NSDictionary*)failedExtensions; + +@end diff --git a/src/Three20Core/Headers/TTGlobalCore.h b/src/Three20Core/Headers/TTGlobalCore.h index 31578b8680..60b4f8a973 100644 --- a/src/Three20Core/Headers/TTGlobalCore.h +++ b/src/Three20Core/Headers/TTGlobalCore.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/TTGlobalCoreLocale.h b/src/Three20Core/Headers/TTGlobalCoreLocale.h index 1714bcbc66..eca9ae49ce 100644 --- a/src/Three20Core/Headers/TTGlobalCoreLocale.h +++ b/src/Three20Core/Headers/TTGlobalCoreLocale.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/TTGlobalCorePaths.h b/src/Three20Core/Headers/TTGlobalCorePaths.h index c9ad4fd41f..9bde321e4b 100644 --- a/src/Three20Core/Headers/TTGlobalCorePaths.h +++ b/src/Three20Core/Headers/TTGlobalCorePaths.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,6 +26,24 @@ BOOL TTIsBundleURL(NSString* URL); */ BOOL TTIsDocumentsURL(NSString* URL); +/** + * Used by TTPathForBundleResource to construct the bundle path. + * + * Retains the given bundle. + * + * @default nil (See TTGetDefaultBundle for what this means) + */ +void TTSetDefaultBundle(NSBundle* bundle); + +/** + * Retrieves the default bundle. + * + * If the default bundle is nil, returns [NSBundle mainBundle]. + * + * @see TTSetDefaultBundle + */ +NSBundle* TTGetDefaultBundle(); + /** * @return The main bundle path concatenated with the given relative path. */ diff --git a/src/Three20Core/Headers/TTGlobalCoreRects.h b/src/Three20Core/Headers/TTGlobalCoreRects.h index 75a29c729e..073f62c6f9 100644 --- a/src/Three20Core/Headers/TTGlobalCoreRects.h +++ b/src/Three20Core/Headers/TTGlobalCoreRects.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/TTMarkupStripper.h b/src/Three20Core/Headers/TTMarkupStripper.h index 89c077f4d4..eec1518267 100644 --- a/src/Three20Core/Headers/TTMarkupStripper.h +++ b/src/Three20Core/Headers/TTMarkupStripper.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/Three20.h b/src/Three20Core/Headers/Three20.h new file mode 100644 index 0000000000..948b026b81 --- /dev/null +++ b/src/Three20Core/Headers/Three20.h @@ -0,0 +1,75 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * General-purpose information about the Three20 ecosystem. + * + * This information is present in the core because Three20 versioning is done across all of + * the primary Three20 modules. + * + * This is the only object in the Three20 ecosystem that doesn't follow the standard TT* prefix. + * This is by design. [Three20 version] is much clearer than [TTVersion version]. + */ +@interface Three20 : NSObject + + +#pragma mark - +#pragma mark General Purpose Version Information + +/** + * @see Three20Version + */ ++ (NSString*)version; + + +#pragma mark - +#pragma mark Version Breakdown + +/** + * Major release number. + * + * Major releases involve large structural changes that will break compatibility + * with older versions. + */ ++ (NSInteger)majorVersion; + +/** + * Minor release number. + * + * Minor releases involve minimal structural changes that might break compatibility + * with older versions but should only involve minimal effort to transition to. + */ ++ (NSInteger)minorVersion; + +/** + * Bugfix release number. + * + * Bugfix releases involve no structural modifications, but may introduce new code and + * fix existing bugs. + */ ++ (NSInteger)bugfixVersion; + +/** + * Hotfix release number. + * + * Hotfix releases fix crashing bugs and compilation errors that may have slipped through the + * release process. + */ ++ (NSInteger)hotfixVersion; + +@end diff --git a/src/Three20Core/Headers/Three20Core+Additions.h b/src/Three20Core/Headers/Three20Core+Additions.h index 56f3ebe043..c9a7c6770c 100644 --- a/src/Three20Core/Headers/Three20Core+Additions.h +++ b/src/Three20Core/Headers/Three20Core+Additions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Headers/Three20Core.h b/src/Three20Core/Headers/Three20Core.h index a70eaced6a..6064582c1e 100644 --- a/src/Three20Core/Headers/Three20Core.h +++ b/src/Three20Core/Headers/Three20Core.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,14 +19,22 @@ // - Global #import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/Three20.h" +#import "Three20Core/Three20Version.h" #import "Three20Core/TTGlobalCore.h" #import "Three20Core/TTGlobalCoreLocale.h" #import "Three20Core/TTGlobalCorePaths.h" #import "Three20Core/TTGlobalCoreRects.h" +#import "Three20Core/TTAvailability.h" // - Debug #import "Three20Core/TTDebug.h" +// - Extensions +#import "Three20Core/TTExtensionInfo.h" +#import "Three20Core/TTExtensionAuthor.h" +#import "Three20Core/TTExtensionLoader.h" + // - Entity Tables #import "Three20Core/TTEntityTables.h" diff --git a/src/Three20Core/Headers/Three20Version.h b/src/Three20Core/Headers/Three20Version.h new file mode 100644 index 0000000000..c8194feb00 --- /dev/null +++ b/src/Three20Core/Headers/Three20Version.h @@ -0,0 +1,33 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * Expressed in MAJOR.MINOR.BUGFIX(.HOTFIX) notation. + * + * For example, 1.0.5.1 is: + * - the first major release, + * - with no minor updates, + * - with 5 bugfix patches, + * - and 1 hotfix patch. + * + * The .HOTFIX version will only be present if hotfixVersion is > 0. + * + * Check out the versionStringCompare: addition to NSString if you need to compare Three20 + * versions. You will need to import Three20+Additions.h in order to use it. + */ +extern NSString* const Three20Version; diff --git a/src/Three20Core/Sources/NSArrayAdditions.m b/src/Three20Core/Sources/NSArrayAdditions.m index 96f97a3902..90949dd16d 100644 --- a/src/Three20Core/Sources/NSArrayAdditions.m +++ b/src/Three20Core/Sources/NSArrayAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,7 +16,9 @@ #import "Three20Core/NSArrayAdditions.h" +// Core #import "Three20Core/NSObjectAdditions.h" +#import "Three20Core/TTCorePreprocessorMacros.h" /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -25,50 +27,60 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(NSArrayAdditions) + @implementation NSArray (TTCategory) /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)perform:(SEL)selector { - NSEnumerator* e = [[[self copy] autorelease] objectEnumerator]; + NSArray *copy = [[NSArray alloc] initWithArray:self]; + NSEnumerator* e = [copy objectEnumerator]; for (id delegate; (delegate = [e nextObject]); ) { if ([delegate respondsToSelector:selector]) { [delegate performSelector:selector]; } } + [copy release]; } /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)perform:(SEL)selector withObject:(id)p1 { - NSEnumerator* e = [[[self copy] autorelease] objectEnumerator]; + NSArray *copy = [[NSArray alloc] initWithArray:self]; + NSEnumerator* e = [copy objectEnumerator]; for (id delegate; (delegate = [e nextObject]); ) { if ([delegate respondsToSelector:selector]) { [delegate performSelector:selector withObject:p1]; } } + [copy release]; } /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)perform:(SEL)selector withObject:(id)p1 withObject:(id)p2 { - NSEnumerator* e = [[[self copy] autorelease] objectEnumerator]; + NSArray *copy = [[NSArray alloc] initWithArray:self]; + NSEnumerator* e = [copy objectEnumerator]; for (id delegate; (delegate = [e nextObject]); ) { if ([delegate respondsToSelector:selector]) { [delegate performSelector:selector withObject:p1 withObject:p2]; } } + [copy release]; } /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)perform:(SEL)selector withObject:(id)p1 withObject:(id)p2 withObject:(id)p3 { - NSEnumerator* e = [[[self copy] autorelease] objectEnumerator]; + NSArray *copy = [[NSArray alloc] initWithArray:self]; + NSEnumerator* e = [copy objectEnumerator]; for (id delegate; (delegate = [e nextObject]); ) { if ([delegate respondsToSelector:selector]) { [delegate performSelector:selector withObject:p1 withObject:p2 withObject:p3]; } } + [copy release]; } diff --git a/src/Three20Core/Sources/NSDataAdditions.m b/src/Three20Core/Sources/NSDataAdditions.m index d50db48a3e..61165d0395 100644 --- a/src/Three20Core/Sources/NSDataAdditions.m +++ b/src/Three20Core/Sources/NSDataAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,9 @@ #import +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -25,6 +28,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(NSDataAdditions) + @implementation NSData (TTCategory) @@ -41,4 +46,125 @@ - (NSString*)md5Hash { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString*)sha1Hash { + unsigned char result[CC_SHA1_DIGEST_LENGTH]; + CC_SHA1([self bytes], [self length], result); + + return [NSString stringWithFormat: + @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], + result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15], + result[16], result[17], result[18], result[19] + ]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// base64 code found on http://www.cocoadev.com/index.pl?BaseSixtyFour +// where the poster released it to public domain +// style not exactly congruous with normal three20 style, but kept mostly intact with the original +static const char encodingTable[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (NSData*)dataWithBase64EncodedString:(NSString *)string { + if ([string length] == 0) + return [NSData data]; + + static char *decodingTable = NULL; + if (decodingTable == NULL) + { + decodingTable = malloc(256); + if (decodingTable == NULL) + return nil; + memset(decodingTable, CHAR_MAX, 256); + NSUInteger i; + for (i = 0; i < 64; i++) + decodingTable[(short)encodingTable[i]] = i; + } + + const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding]; + if (characters == NULL) // Not an ASCII string! + return nil; + char *bytes = malloc((([string length] + 3) / 4) * 3); + if (bytes == NULL) + return nil; + NSUInteger length = 0; + + NSUInteger i = 0; + while (YES) + { + char buffer[4]; + short bufferLength; + for (bufferLength = 0; bufferLength < 4; i++) + { + if (characters[i] == '\0') + break; + if (isspace(characters[i]) || characters[i] == '=') + continue; + buffer[bufferLength] = decodingTable[(short)characters[i]]; + if (buffer[bufferLength++] == CHAR_MAX) // Illegal character! + { + free(bytes); + return nil; + } + } + + if (bufferLength == 0) + break; + if (bufferLength == 1) // At least two characters are needed to produce one byte! + { + free(bytes); + return nil; + } + + // Decode the characters in the buffer to bytes. + bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4); + if (bufferLength > 2) + bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2); + if (bufferLength > 3) + bytes[length++] = (buffer[2] << 6) | buffer[3]; + } + + realloc(bytes, length); + return [NSData dataWithBytesNoCopy:bytes length:length]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString *)base64Encoding { + if ([self length] == 0) + return @""; + + char *characters = malloc((([self length] + 2) / 3) * 4); + if (characters == NULL) + return nil; + NSUInteger length = 0; + + NSUInteger i = 0; + while (i < [self length]) + { + char buffer[3] = {0,0,0}; + short bufferLength = 0; + while (bufferLength < 3 && i < [self length]) + buffer[bufferLength++] = ((char *)[self bytes])[i++]; + + // Encode the bytes in the buffer to four characters, + // including padding "=" characters if necessary. + characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2]; + characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)]; + if (bufferLength > 1) + characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)]; + else characters[length++] = '='; + if (bufferLength > 2) + characters[length++] = encodingTable[buffer[2] & 0x3F]; + else characters[length++] = '='; + } + + return [[[NSString alloc] initWithBytesNoCopy:characters length:length + encoding:NSASCIIStringEncoding freeWhenDone:YES] + autorelease]; +} +// end recycled base64 code +/////////////////////////////////////////////////////////////////////////////////////////////////// + @end diff --git a/src/Three20Core/Sources/NSDateAdditions.m b/src/Three20Core/Sources/NSDateAdditions.m index cef219c6b2..f172cf1252 100644 --- a/src/Three20Core/Sources/NSDateAdditions.m +++ b/src/Three20Core/Sources/NSDateAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,6 +27,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(NSDateAdditions) + @implementation NSDate (TTCategory) @@ -38,14 +40,7 @@ @implementation NSDate (TTCategory) /////////////////////////////////////////////////////////////////////////////////////////////////// + (NSDate*)dateWithToday { - NSDateFormatter* formatter = [[NSDateFormatter alloc] init]; - formatter.dateFormat = @"yyyy-d-M"; - - NSString* formattedTime = [formatter stringFromDate:[NSDate date]]; - NSDate* date = [formatter dateFromString:formattedTime]; - TT_RELEASE_SAFELY(formatter); - - return date; + return [[NSDate date] dateAtMidnight]; } @@ -57,21 +52,20 @@ + (NSDate*)dateWithToday { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSDate*)dateAtMidnight { - NSDateFormatter* formatter = [[NSDateFormatter alloc] init]; - formatter.dateFormat = @"yyyy-d-M"; - - NSString* formattedTime = [formatter stringFromDate:self]; - NSDate* date = [formatter dateFromString:formattedTime]; - TT_RELEASE_SAFELY(formatter); - - return date; + NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + NSDateComponents *comps = [gregorian components: + (NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) + fromDate:[NSDate date]]; + NSDate *midnight = [gregorian dateFromComponents:comps]; + [gregorian release]; + return midnight; } /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)formatTime { static NSDateFormatter* formatter = nil; - if (!formatter) { + if (nil == formatter) { formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = TTLocalizedString(@"h:mm a", @"Date format: 1:05 pm"); formatter.locale = TTCurrentLocale(); @@ -83,7 +77,7 @@ - (NSString*)formatTime { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)formatDate { static NSDateFormatter* formatter = nil; - if (!formatter) { + if (nil == formatter) { formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = TTLocalizedString(@"EEEE, LLLL d, YYYY", @"Date format: Monday, July 27, 2009"); @@ -102,7 +96,7 @@ - (NSString*)formatShortTime { } else if (diff < TT_5_DAYS) { static NSDateFormatter* formatter = nil; - if (!formatter) { + if (nil == formatter) { formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = TTLocalizedString(@"EEEE", @"Date format: Monday"); formatter.locale = TTCurrentLocale(); @@ -111,7 +105,7 @@ - (NSString*)formatShortTime { } else { static NSDateFormatter* formatter = nil; - if (!formatter) { + if (nil == formatter) { formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = TTLocalizedString(@"M/d/yy", @"Date format: 7/27/09"); formatter.locale = TTCurrentLocale(); @@ -129,7 +123,7 @@ - (NSString*)formatDateTime { } else if (diff < TT_5_DAYS) { static NSDateFormatter* formatter = nil; - if (!formatter) { + if (nil == formatter) { formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = TTLocalizedString(@"EEE h:mm a", @"Date format: Mon 1:05 pm"); formatter.locale = TTCurrentLocale(); @@ -138,7 +132,7 @@ - (NSString*)formatDateTime { } else { static NSDateFormatter* formatter = nil; - if (!formatter) { + if (nil == formatter) { formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = TTLocalizedString(@"MMM d h:mm a", @"Date format: Jul 27 1:05 pm"); formatter.locale = TTCurrentLocale(); @@ -150,30 +144,61 @@ - (NSString*)formatDateTime { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)formatRelativeTime { - NSTimeInterval elapsed = abs([self timeIntervalSinceNow]); - if (elapsed <= 1) { - return TTLocalizedString(@"just a moment ago", @""); + NSTimeInterval elapsed = [self timeIntervalSinceNow]; + if (elapsed > 0) { + if (elapsed <= 1) { + return TTLocalizedString(@"in just a moment", @""); + } + else if (elapsed < TT_MINUTE) { + int seconds = (int)(elapsed); + return [NSString stringWithFormat:TTLocalizedString(@"in %d seconds", @""), seconds]; + + } + else if (elapsed < 2*TT_MINUTE) { + return TTLocalizedString(@"in about a minute", @""); + } + else if (elapsed < TT_HOUR) { + int mins = (int)(elapsed/TT_MINUTE); + return [NSString stringWithFormat:TTLocalizedString(@"in %d minutes", @""), mins]; + } + else if (elapsed < TT_HOUR*1.5) { + return TTLocalizedString(@"in about an hour", @""); + } + else if (elapsed < TT_DAY) { + int hours = (int)((elapsed+TT_HOUR/2)/TT_HOUR); + return [NSString stringWithFormat:TTLocalizedString(@"in %d hours", @""), hours]; + } + else { + return [self formatDateTime]; + } + } + else { + elapsed = -elapsed; - } else if (elapsed < TT_MINUTE) { - int seconds = (int)(elapsed); - return [NSString stringWithFormat:TTLocalizedString(@"%d seconds ago", @""), seconds]; + if (elapsed <= 1) { + return TTLocalizedString(@"just a moment ago", @""); - } else if (elapsed < 2*TT_MINUTE) { - return TTLocalizedString(@"about a minute ago", @""); + } else if (elapsed < TT_MINUTE) { + int seconds = (int)(elapsed); + return [NSString stringWithFormat:TTLocalizedString(@"%d seconds ago", @""), seconds]; - } else if (elapsed < TT_HOUR) { - int mins = (int)(elapsed/TT_MINUTE); - return [NSString stringWithFormat:TTLocalizedString(@"%d minutes ago", @""), mins]; + } else if (elapsed < 2*TT_MINUTE) { + return TTLocalizedString(@"about a minute ago", @""); - } else if (elapsed < TT_HOUR*1.5) { - return TTLocalizedString(@"about an hour ago", @""); + } else if (elapsed < TT_HOUR) { + int mins = (int)(elapsed/TT_MINUTE); + return [NSString stringWithFormat:TTLocalizedString(@"%d minutes ago", @""), mins]; - } else if (elapsed < TT_DAY) { - int hours = (int)((elapsed+TT_HOUR/2)/TT_HOUR); - return [NSString stringWithFormat:TTLocalizedString(@"%d hours ago", @""), hours]; + } else if (elapsed < TT_HOUR*1.5) { + return TTLocalizedString(@"about an hour ago", @""); - } else { - return [self formatDateTime]; + } else if (elapsed < TT_DAY) { + int hours = (int)((elapsed+TT_HOUR/2)/TT_HOUR); + return [NSString stringWithFormat:TTLocalizedString(@"%d hours ago", @""), hours]; + + } else { + return [self formatDateTime]; + } } } @@ -206,7 +231,7 @@ - (NSString*)formatShortRelativeTime { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)formatDay:(NSDateComponents*)today yesterday:(NSDateComponents*)yesterday { static NSDateFormatter* formatter = nil; - if (!formatter) { + if (nil == formatter) { formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = TTLocalizedString(@"MMMM d", @"Date format: July 27"); formatter.locale = TTCurrentLocale(); @@ -218,9 +243,11 @@ - (NSString*)formatDay:(NSDateComponents*)today yesterday:(NSDateComponents*)yes if (day.day == today.day && day.month == today.month && day.year == today.year) { return TTLocalizedString(@"Today", @""); + } else if (day.day == yesterday.day && day.month == yesterday.month && day.year == yesterday.year) { return TTLocalizedString(@"Yesterday", @""); + } else { return [formatter stringFromDate:self]; } @@ -230,7 +257,7 @@ - (NSString*)formatDay:(NSDateComponents*)today yesterday:(NSDateComponents*)yes /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)formatMonth { static NSDateFormatter* formatter = nil; - if (!formatter) { + if (nil == formatter) { formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = TTLocalizedString(@"MMMM", @"Date format: July"); formatter.locale = TTCurrentLocale(); @@ -242,7 +269,7 @@ - (NSString*)formatMonth { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)formatYear { static NSDateFormatter* formatter = nil; - if (!formatter) { + if (nil == formatter) { formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = TTLocalizedString(@"yyyy", @"Date format: 2009"); formatter.locale = TTCurrentLocale(); diff --git a/src/Three20Core/Sources/NSMutableArrayAdditions.m b/src/Three20Core/Sources/NSMutableArrayAdditions.m index f2087000de..c996605538 100644 --- a/src/Three20Core/Sources/NSMutableArrayAdditions.m +++ b/src/Three20Core/Sources/NSMutableArrayAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ #import "Three20Core/NSMutableArrayAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" #import "Three20Core/TTGlobalCore.h" @@ -25,6 +27,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(NSMutableArrayAdditions) + @implementation NSMutableArray (TTCategory) diff --git a/src/Three20Core/Sources/NSMutableDictionaryAdditions.m b/src/Three20Core/Sources/NSMutableDictionaryAdditions.m index ee6d7bd38b..8fd20bec44 100644 --- a/src/Three20Core/Sources/NSMutableDictionaryAdditions.m +++ b/src/Three20Core/Sources/NSMutableDictionaryAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ #import "Three20Core/NSMutableDictionaryAdditions.h" // Core +#import "Three20Core/TTCorePreprocessorMacros.h" #import "Three20Core/TTGlobalCore.h" @@ -26,6 +27,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(NSMutableDictionaryAdditions) + @implementation NSMutableDictionary (TTCategory) diff --git a/src/Three20Core/Sources/NSObjectAdditions.m b/src/Three20Core/Sources/NSObjectAdditions.m index 3132ea25a2..1c72bd7370 100644 --- a/src/Three20Core/Sources/NSObjectAdditions.m +++ b/src/Three20Core/Sources/NSObjectAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20Core/NSObjectAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -23,6 +26,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(NSObjectAdditions) + @implementation NSObject (TTAdditions) @@ -41,9 +46,11 @@ - (id)performSelector:(SEL)selector withObject:(id)p1 withObject:(id)p2 withObje id anObject; [invo getReturnValue:&anObject]; return anObject; + } else { return nil; } + } else { return nil; } @@ -67,9 +74,11 @@ - (id)performSelector:(SEL)selector withObject:(id)p1 withObject:(id)p2 withObje id anObject; [invo getReturnValue:&anObject]; return anObject; + } else { return nil; } + } else { return nil; } @@ -94,9 +103,11 @@ - (id)performSelector:(SEL)selector withObject:(id)p1 withObject:(id)p2 withObje id anObject; [invo getReturnValue:&anObject]; return anObject; + } else { return nil; } + } else { return nil; } @@ -122,9 +133,11 @@ - (id)performSelector:(SEL)selector withObject:(id)p1 withObject:(id)p2 withObje id anObject; [invo getReturnValue:&anObject]; return anObject; + } else { return nil; } + } else { return nil; } @@ -151,9 +164,11 @@ - (id)performSelector:(SEL)selector withObject:(id)p1 withObject:(id)p2 withObje id anObject; [invo getReturnValue:&anObject]; return anObject; + } else { return nil; } + } else { return nil; } diff --git a/src/Three20Core/Sources/NSStringAdditions.m b/src/Three20Core/Sources/NSStringAdditions.m index c42c31e25b..574aa3c200 100644 --- a/src/Three20Core/Sources/NSStringAdditions.m +++ b/src/Three20Core/Sources/NSStringAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ #import "Three20Core/NSStringAdditions.h" // Core +#import "Three20Core/TTCorePreprocessorMacros.h" #import "Three20Core/TTMarkupStripper.h" #import "Three20Core/NSDataAdditions.h" @@ -24,6 +25,11 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Additions. + */ +TT_FIX_CATEGORY_BUG(NSStringAdditions) + @implementation NSString (TTAdditions) @@ -41,8 +47,12 @@ - (BOOL)isWhitespaceAndNewlines { /////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Deprecated - https://github.com/facebook/three20/issues/367 + */ - (BOOL)isEmptyOrWhitespace { - return !self.length || + // A nil or NULL string is not the same as an empty string + return 0 == self.length || ![self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].length; } @@ -55,7 +65,10 @@ - (NSString*)stringByRemovingHTMLTags { /////////////////////////////////////////////////////////////////////////////////////////////////// -// Copied and pasted from http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg28175.html +/** + * Copied and pasted from http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg28175.html + * Deprecated + */ - (NSDictionary*)queryDictionaryUsingEncoding:(NSStringEncoding)encoding { NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"]; NSMutableDictionary* pairs = [NSMutableDictionary dictionary]; @@ -77,6 +90,36 @@ - (NSDictionary*)queryDictionaryUsingEncoding:(NSStringEncoding)encoding { return [NSDictionary dictionaryWithDictionary:pairs]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSDictionary*)queryContentsUsingEncoding:(NSStringEncoding)encoding { + NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"]; + NSMutableDictionary* pairs = [NSMutableDictionary dictionary]; + NSScanner* scanner = [[[NSScanner alloc] initWithString:self] autorelease]; + while (![scanner isAtEnd]) { + NSString* pairString = nil; + [scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString]; + [scanner scanCharactersFromSet:delimiterSet intoString:NULL]; + NSArray* kvPair = [pairString componentsSeparatedByString:@"="]; + if (kvPair.count == 1 || kvPair.count == 2) { + NSString* key = [[kvPair objectAtIndex:0] + stringByReplacingPercentEscapesUsingEncoding:encoding]; + NSMutableArray* values = [pairs objectForKey:key]; + if (nil == values) { + values = [NSMutableArray array]; + [pairs setObject:values forKey:key]; + } + if (kvPair.count == 1) { + [values addObject:[NSNull null]]; + + } else if (kvPair.count == 2) { + NSString* value = [[kvPair objectAtIndex:1] + stringByReplacingPercentEscapesUsingEncoding:encoding]; + [values addObject:value]; + } + } + } + return [NSDictionary dictionaryWithDictionary:pairs]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)stringByAddingQueryDictionary:(NSDictionary*)query { @@ -92,11 +135,39 @@ - (NSString*)stringByAddingQueryDictionary:(NSDictionary*)query { NSString* params = [pairs componentsJoinedByString:@"&"]; if ([self rangeOfString:@"?"].location == NSNotFound) { return [self stringByAppendingFormat:@"?%@", params]; + } else { return [self stringByAppendingFormat:@"&%@", params]; } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString*)stringByAddingURLEncodedQueryDictionary:(NSDictionary*)query { + NSMutableDictionary* encodedQuery = [NSMutableDictionary dictionaryWithCapacity:[query count]]; + + for (NSString* key in [query keyEnumerator]) { + NSParameterAssert([key respondsToSelector:@selector(urlEncoded)]); + NSString* value = [query objectForKey:key]; + NSParameterAssert([value respondsToSelector:@selector(urlEncoded)]); + value = [value urlEncoded]; + key = [key urlEncoded]; + [encodedQuery setValue:value forKey:key]; + } + + return [self stringByAddingQueryDictionary:encodedQuery]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)urlEncoded { + CFStringRef cfUrlEncodedString = CFURLCreateStringByAddingPercentEscapes(NULL, + (CFStringRef)self,NULL, + (CFStringRef)@"!#$%&'()*+,/:;=?@[]", + kCFStringEncodingUTF8); + + NSString *urlEncoded = [NSString stringWithString:(NSString *)cfUrlEncodedString]; + CFRelease(cfUrlEncodedString); + return urlEncoded; +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSComparisonResult)versionStringCompare:(NSString *)other { @@ -117,8 +188,10 @@ - (NSComparisonResult)versionStringCompare:(NSString *)other { // If one has an alpha part and the other doesn't, the one without is newer if ([oneComponents count] < [twoComponents count]) { return NSOrderedDescending; + } else if ([oneComponents count] > [twoComponents count]) { return NSOrderedAscending; + } else if ([oneComponents count] == 1) { // Neither has an alpha part, and we know the main parts are the same return NSOrderedSame; @@ -138,5 +211,9 @@ - (NSString*)md5Hash { } -@end +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString*)sha1Hash { + return [[self dataUsingEncoding:NSUTF8StringEncoding] sha1Hash]; +} +@end diff --git a/src/Three20Core/Sources/TTAvailability.m b/src/Three20Core/Sources/TTAvailability.m new file mode 100644 index 0000000000..2f5366f28b --- /dev/null +++ b/src/Three20Core/Sources/TTAvailability.m @@ -0,0 +1,33 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/TTAvailability.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL TTDeviceOSVersionIsAtLeast(double versionNumber) { + return kCFCoreFoundationVersionNumber >= versionNumber; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +Class TTUIPopoverControllerClass() { + static Class sClass = nil; + if (nil == sClass) { + sClass = NSClassFromString(@"UIPopoverController"); + } + return sClass; +} diff --git a/src/Three20Core/Sources/TTDebug.m b/src/Three20Core/Sources/TTDebug.m index e1c0fd8347..e3e9c8529f 100644 --- a/src/Three20Core/Sources/TTDebug.m +++ b/src/Three20Core/Sources/TTDebug.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Sources/TTEntityTables.m b/src/Three20Core/Sources/TTEntityTables.m index 3c31afdbd3..2c57c7362a 100644 --- a/src/Three20Core/Sources/TTEntityTables.m +++ b/src/Three20Core/Sources/TTEntityTables.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -162,7 +162,7 @@ @implementation TTEntityTables (TTSingleton) static TTEntityTables* sharedInstance = nil; -//////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + (id)sharedInstance { @synchronized(self) { if (nil == sharedInstance) { @@ -173,13 +173,13 @@ + (id)sharedInstance { } -//////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// - (oneway void)superRelease { [super release]; } -//////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + (void)releaseSharedInstance { @synchronized(self) { [sharedInstance superRelease]; @@ -189,7 +189,7 @@ + (void)releaseSharedInstance { //////////////////////////////////////////////////////////////////////////////////////////////////// -// Ensure that [TTEntityTables alloc] returns the singleton object. +/////////////////////////////////////////////////////////////////////////////////////////////////// + (id)allocWithZone:(NSZone*)zone { @synchronized(self) { if (nil == sharedInstance) { @@ -201,31 +201,31 @@ + (id)allocWithZone:(NSZone*)zone { } -//////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// - (id)copyWithZone:(NSZone *)zone { return sharedInstance; } -//////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// - (id)retain { return sharedInstance; } -//////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// - (unsigned)retainCount { return NSUIntegerMax; } -//////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// - (oneway void)release { // Do nothing. } -//////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// - (id)autorelease { return sharedInstance; } diff --git a/src/Three20Core/Sources/TTExtensionAuthor.m b/src/Three20Core/Sources/TTExtensionAuthor.m new file mode 100644 index 0000000000..b1144a3835 --- /dev/null +++ b/src/Three20Core/Sources/TTExtensionAuthor.m @@ -0,0 +1,89 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/TTExtensionAuthor.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTExtensionAuthor + +@synthesize name = _name; +@synthesize github = _github; +@synthesize twitter = _twitter; +@synthesize website = _website; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (id)authorWithName:(NSString*)name { + return [[[self alloc] initWithName: name + github: nil + twitter: nil + website: nil] autorelease]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (id)authorWithName: (NSString*)name + github: (NSString*)github + twitter: (NSString*)twitter + website: (NSString*)website { + return [[[self alloc] initWithName: name + github: github + twitter: twitter + website: website] autorelease]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithName: (NSString*)name + github: (NSString*)github + twitter: (NSString*)twitter + website: (NSString*)website { + self = [super init]; + if (self) { + self.name = name; + self.github = github; + self.twitter = twitter; + self.website = website; + } + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)init { + return [self initWithName:@"Unknown" github:nil twitter:nil website:nil]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)dealloc { + TT_RELEASE_SAFELY(_name); + TT_RELEASE_SAFELY(_github); + TT_RELEASE_SAFELY(_twitter); + TT_RELEASE_SAFELY(_website); + + [super dealloc]; +} + + +@end + diff --git a/src/Three20Core/Sources/TTExtensionInfo.m b/src/Three20Core/Sources/TTExtensionInfo.m new file mode 100644 index 0000000000..85bd5b488d --- /dev/null +++ b/src/Three20Core/Sources/TTExtensionInfo.m @@ -0,0 +1,84 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/TTExtensionInfo.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + +// Core (private) +#import "Three20Core/private/TTExtensionInfoPrivate.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTExtensionInfo + +@synthesize identifier = _id; +@synthesize name = _name; +@synthesize description = _description; +@synthesize version = _version; +@synthesize copyright = _copyright; +@synthesize license = _license; +@synthesize authors = _authors; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)init { + self = [super init]; + if (self) { + self.version = @"No version provided."; + self.description = @"No description provided."; + self.copyright = @"No copyright provided."; + self.license = @"No license provided."; + } + + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)dealloc { + TT_RELEASE_SAFELY(_id); + TT_RELEASE_SAFELY(_description); + TT_RELEASE_SAFELY(_name); + TT_RELEASE_SAFELY(_version); + TT_RELEASE_SAFELY(_copyright); + TT_RELEASE_SAFELY(_license); + TT_RELEASE_SAFELY(_authors); + + [super dealloc]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)isEqual:(TTExtensionInfo*)extension { + return [_id isEqualToString:extension.identifier]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setIdentifier:(NSString*)identifier { + if (_id != identifier) { + [_id release]; + _id = [identifier copy]; + } +} + + +@end + diff --git a/src/Three20Core/Sources/TTExtensionLoader.m b/src/Three20Core/Sources/TTExtensionLoader.m new file mode 100644 index 0000000000..4035f1ab3a --- /dev/null +++ b/src/Three20Core/Sources/TTExtensionLoader.m @@ -0,0 +1,167 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/TTExtensionLoader.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/TTDebug.h" +#import "Three20Core/TTExtensionInfo.h" + +// Core (private) +#import "Three20Core/private/TTExtensionInfoPrivate.h" + +#import + +static NSString* kLoadExtensionMethodPrefix = @"loadExtensionNamed"; +static NSString* kExtensionInfoMethodPrefix = @"extensionInfoNamed"; + +static NSMutableDictionary* sTTAvailableExtensions = nil; +static NSMutableDictionary* sTTLoadedExtensions = nil; +static NSMutableDictionary* sTTFailedExtensions = nil; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTExtensionLoader + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)callExtensionID:(NSString*)extensionID methodWithPrefix:(NSString*)prefix { + SEL selector = NSSelectorFromString([prefix + stringByAppendingString:extensionID]); + + id result = nil; + if ([self respondsToSelector:selector]) { + result = [self performSelector:selector]; + } + return result; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTExtensionInfo*)extensionWithID:(NSString*)extensionID { + TTExtensionInfo* extension = [self callExtensionID: extensionID + methodWithPrefix: kExtensionInfoMethodPrefix]; + if (nil == extension) { + extension = [[[TTExtensionInfo alloc] init] autorelease]; + } + extension.identifier = extensionID; + return extension; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)loadExtension:(TTExtensionInfo*)extension { + BOOL succeeded = [self callExtensionID: extension.identifier + methodWithPrefix: kLoadExtensionMethodPrefix] ? YES : NO; + + if (succeeded) { + [sTTLoadedExtensions setObject:extension forKey:extension.identifier]; + + } else { + [sTTFailedExtensions setObject:extension forKey:extension.identifier]; + } + + return succeeded; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (void)setupStaticData { + if (nil == sTTLoadedExtensions) { + sTTLoadedExtensions = [[NSMutableDictionary alloc] init]; + } + if (nil == sTTFailedExtensions) { + sTTFailedExtensions = [[NSMutableDictionary alloc] init]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (void)loadAllExtensions { + [self setupStaticData]; + + NSDictionary* availableExtensions = [self availableExtensions]; + + if ([availableExtensions count] > 0) { + TTExtensionLoader* loader = [[TTExtensionLoader alloc] init]; + + for (NSString* extensionID in availableExtensions) { + TTExtensionInfo* extension = [availableExtensions objectForKey:extensionID]; + [loader loadExtension:extension]; + } + + TT_RELEASE_SAFELY(loader); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (NSDictionary*)availableExtensions { + if (nil == sTTAvailableExtensions) { + sTTAvailableExtensions = [[NSMutableDictionary alloc] init]; + + unsigned int methodCount = 0; + Method* methods = class_copyMethodList([self class], &methodCount); + + if (nil != methods) { + TTExtensionLoader* loader = [[TTExtensionLoader alloc] init]; + + for (unsigned int ix = 0; ix < methodCount; ++ix) { + Method method = methods[ix]; + + SEL methodSelector = method_getName(method); + + NSString* methodName = [NSString stringWithCString: sel_getName(methodSelector) + encoding: NSUTF8StringEncoding]; + + if ([methodName hasPrefix:kLoadExtensionMethodPrefix]) { + NSString* extensionID = [methodName substringFromIndex: + [kLoadExtensionMethodPrefix length]]; + + TTExtensionInfo* extension = [loader extensionWithID:extensionID]; + TTDASSERT(nil != extension); + + if (nil != extension) { + [sTTAvailableExtensions setObject:extension forKey:extensionID]; + } + } + } + + TT_RELEASE_SAFELY(loader); + } + } + + return [NSDictionary dictionaryWithDictionary:sTTAvailableExtensions]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (NSDictionary*)loadedExtensions { + return [NSDictionary dictionaryWithDictionary:sTTLoadedExtensions]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (NSDictionary*)failedExtensions { + return [NSDictionary dictionaryWithDictionary:sTTFailedExtensions]; +} + + +@end + diff --git a/src/Three20Core/Sources/TTGlobalCore.m b/src/Three20Core/Sources/TTGlobalCore.m index 6763c576ac..5fe212642d 100644 --- a/src/Three20Core/Sources/TTGlobalCore.m +++ b/src/Three20Core/Sources/TTGlobalCore.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Sources/TTGlobalCoreLocale.m b/src/Three20Core/Sources/TTGlobalCoreLocale.m index 481ebbeb71..4a3e3baa0b 100644 --- a/src/Three20Core/Sources/TTGlobalCoreLocale.m +++ b/src/Three20Core/Sources/TTGlobalCoreLocale.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,11 +22,11 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// NSLocale* TTCurrentLocale() { - NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - NSArray* languages = [defaults objectForKey:@"AppleLanguages"]; + NSArray* languages = [NSLocale preferredLanguages]; if (languages.count > 0) { NSString* currentLanguage = [languages objectAtIndex:0]; return [[[NSLocale alloc] initWithLocaleIdentifier:currentLanguage] autorelease]; + } else { return [NSLocale currentLocale]; } @@ -36,7 +36,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// NSString* TTLocalizedString(NSString* key, NSString* comment) { static NSBundle* bundle = nil; - if (!bundle) { + if (nil == bundle) { NSString* path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Three20.bundle"]; bundle = [[NSBundle bundleWithPath:path] retain]; @@ -54,8 +54,10 @@ // Note: If new error codes are added here, be sure to document them in the header. if (error.code == NSURLErrorTimedOut) { return TTLocalizedString(@"Connection Timed Out", @""); + } else if (error.code == NSURLErrorNotConnectedToInternet) { return TTLocalizedString(@"No Internet Connection", @""); + } else { return TTLocalizedString(@"Connection Error", @""); } diff --git a/src/Three20Core/Sources/TTGlobalCorePaths.m b/src/Three20Core/Sources/TTGlobalCorePaths.m index a15f1002e1..7b60759b03 100644 --- a/src/Three20Core/Sources/TTGlobalCorePaths.m +++ b/src/Three20Core/Sources/TTGlobalCorePaths.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,9 @@ #import "Three20Core/TTGlobalCorePaths.h" +static NSBundle* globalBundle = nil; + + /////////////////////////////////////////////////////////////////////////////////////////////////// BOOL TTIsBundleURL(NSString* URL) { return [URL hasPrefix:@"bundle://"]; @@ -29,9 +32,23 @@ BOOL TTIsDocumentsURL(NSString* URL) { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +void TTSetDefaultBundle(NSBundle* bundle) { + [bundle retain]; + [globalBundle release]; + globalBundle = bundle; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +NSBundle* TTGetDefaultBundle() { + return (nil != globalBundle) ? globalBundle : [NSBundle mainBundle]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// NSString* TTPathForBundleResource(NSString* relativePath) { - NSString* resourcePath = [[NSBundle mainBundle] resourcePath]; + NSString* resourcePath = [TTGetDefaultBundle() resourcePath]; return [resourcePath stringByAppendingPathComponent:relativePath]; } @@ -39,7 +56,7 @@ BOOL TTIsDocumentsURL(NSString* URL) { /////////////////////////////////////////////////////////////////////////////////////////////////// NSString* TTPathForDocumentsResource(NSString* relativePath) { static NSString* documentsPath = nil; - if (!documentsPath) { + if (nil == documentsPath) { NSArray* dirs = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES); documentsPath = [[dirs objectAtIndex:0] retain]; diff --git a/src/Three20Core/Sources/TTGlobalCoreRects.m b/src/Three20Core/Sources/TTGlobalCoreRects.m index 6de4a8597d..8d13f1d00c 100644 --- a/src/Three20Core/Sources/TTGlobalCoreRects.m +++ b/src/Three20Core/Sources/TTGlobalCoreRects.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Sources/TTMarkupStripper.m b/src/Three20Core/Sources/TTMarkupStripper.m index 6f2c51f85a..736e1e07d4 100644 --- a/src/Three20Core/Sources/TTMarkupStripper.m +++ b/src/Three20Core/Sources/TTMarkupStripper.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Core/Sources/Three20.m b/src/Three20Core/Sources/Three20.m new file mode 100644 index 0000000000..e8da57f20c --- /dev/null +++ b/src/Three20Core/Sources/Three20.m @@ -0,0 +1,64 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/Three20.h" + +#import "Three20Core/Three20Version.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation Three20 + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (NSInteger)majorVersion { + return [[[Three20Version componentsSeparatedByString:@"."] objectAtIndex:0] intValue]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (NSInteger)minorVersion { + return [[[Three20Version componentsSeparatedByString:@"."] objectAtIndex:1] intValue]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (NSInteger)bugfixVersion { + return [[[Three20Version componentsSeparatedByString:@"."] objectAtIndex:2] intValue]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (NSInteger)hotfixVersion { + NSArray* components = [Three20Version componentsSeparatedByString:@"."]; + if ([components count] > 3) { + return [[components objectAtIndex:3] intValue]; + + } else { + return 0; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (NSString*)version { + return Three20Version; +} + + +@end diff --git a/src/Three20Core/Sources/Three20Version.m b/src/Three20Core/Sources/Three20Version.m new file mode 100644 index 0000000000..c90da7026a --- /dev/null +++ b/src/Three20Core/Sources/Three20Version.m @@ -0,0 +1,23 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/Three20Version.h" + +/*! \mainpage Three20 API Documentation + * + * Generated from Three20 Release 1.0.11. + */ +NSString* const Three20Version = @"1.0.11"; diff --git a/src/Three20Core/Three20Core.xcodeproj/project.pbxproj b/src/Three20Core/Three20Core.xcodeproj/project.pbxproj index e6c08d7951..635886d880 100755 --- a/src/Three20Core/Three20Core.xcodeproj/project.pbxproj +++ b/src/Three20Core/Three20Core.xcodeproj/project.pbxproj @@ -3,10 +3,23 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 660E7375135A560A00531398 /* Three20Version.h in Headers */ = {isa = PBXBuildFile; fileRef = 660E7374135A560A00531398 /* Three20Version.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6656B2531354035900B34AB5 /* TTAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 6656B2521354035900B34AB5 /* TTAvailability.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6656B2551354035F00B34AB5 /* TTAvailability.m in Sources */ = {isa = PBXBuildFile; fileRef = 6656B2541354035F00B34AB5 /* TTAvailability.m */; }; + 66A0530A132EB47900132434 /* Three20.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A05309132EB47900132434 /* Three20.m */; }; + 66A0530C132EB47F00132434 /* Three20.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A0530B132EB47F00132434 /* Three20.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66ADC9091290B23A00855386 /* TTExtensionInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 66ADC9071290B23A00855386 /* TTExtensionInfo.m */; }; + 66ADC90F1290B24D00855386 /* TTExtensionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 66ADC90E1290B24D00855386 /* TTExtensionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66ADCE681291BC1E00855386 /* TTExtensionInfoPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 66ADCE661291BC1E00855386 /* TTExtensionInfoPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 66ADCE871291BEAE00855386 /* TTExtensionAuthor.m in Sources */ = {isa = PBXBuildFile; fileRef = 66ADCE811291BEAE00855386 /* TTExtensionAuthor.m */; }; + 66ADCE8B1291BEBB00855386 /* TTExtensionAuthor.h in Headers */ = {isa = PBXBuildFile; fileRef = 66ADCE881291BEBB00855386 /* TTExtensionAuthor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66CE68FB135B320F00E127E2 /* Three20Version.m in Sources */ = {isa = PBXBuildFile; fileRef = 66CE68FA135B320F00E127E2 /* Three20Version.m */; }; + 66ECA257128DFE28006C78C2 /* TTExtensionLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 66ECA251128DFE28006C78C2 /* TTExtensionLoader.m */; }; + 66ECA25B128DFE34006C78C2 /* TTExtensionLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 66ECA258128DFE34006C78C2 /* TTExtensionLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E178E811183C8E5003B099E /* TTGlobalCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E178E7B1183C8E5003B099E /* TTGlobalCore.m */; }; 6E178E821183C8E5003B099E /* TTGlobalCoreLocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E178E7C1183C8E5003B099E /* TTGlobalCoreLocale.m */; }; 6E178E831183C8E5003B099E /* TTGlobalCorePaths.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E178E7D1183C8E5003B099E /* TTGlobalCorePaths.m */; }; @@ -56,6 +69,19 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 660E7374135A560A00531398 /* Three20Version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Three20Version.h; path = Headers/Three20Version.h; sourceTree = ""; }; + 6656B2521354035900B34AB5 /* TTAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTAvailability.h; path = Headers/TTAvailability.h; sourceTree = ""; }; + 6656B2541354035F00B34AB5 /* TTAvailability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTAvailability.m; path = Sources/TTAvailability.m; sourceTree = ""; }; + 66A05309132EB47900132434 /* Three20.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Three20.m; path = Sources/Three20.m; sourceTree = ""; }; + 66A0530B132EB47F00132434 /* Three20.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Three20.h; path = Headers/Three20.h; sourceTree = ""; }; + 66ADC9071290B23A00855386 /* TTExtensionInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTExtensionInfo.m; path = Sources/TTExtensionInfo.m; sourceTree = ""; }; + 66ADC90E1290B24D00855386 /* TTExtensionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTExtensionInfo.h; path = Headers/TTExtensionInfo.h; sourceTree = ""; }; + 66ADCE661291BC1E00855386 /* TTExtensionInfoPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTExtensionInfoPrivate.h; path = Headers/TTExtensionInfoPrivate.h; sourceTree = ""; }; + 66ADCE811291BEAE00855386 /* TTExtensionAuthor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTExtensionAuthor.m; path = Sources/TTExtensionAuthor.m; sourceTree = ""; }; + 66ADCE881291BEBB00855386 /* TTExtensionAuthor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTExtensionAuthor.h; path = Headers/TTExtensionAuthor.h; sourceTree = ""; }; + 66CE68FA135B320F00E127E2 /* Three20Version.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Three20Version.m; path = Sources/Three20Version.m; sourceTree = ""; }; + 66ECA251128DFE28006C78C2 /* TTExtensionLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTExtensionLoader.m; path = Sources/TTExtensionLoader.m; sourceTree = ""; }; + 66ECA258128DFE34006C78C2 /* TTExtensionLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTExtensionLoader.h; path = Headers/TTExtensionLoader.h; sourceTree = ""; }; 6E178E751183C8AE003B099E /* Three20Core_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Three20Core_Prefix.pch; path = Headers/Three20Core_Prefix.pch; sourceTree = ""; }; 6E178E761183C8B6003B099E /* TTDebugFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTDebugFlags.h; path = Headers/TTDebugFlags.h; sourceTree = ""; }; 6E178E771183C8D3003B099E /* TTCorePreprocessorMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTCorePreprocessorMacros.h; path = Headers/TTCorePreprocessorMacros.h; sourceTree = ""; }; @@ -147,6 +173,28 @@ name = CustomTemplate; sourceTree = ""; }; + 6664448A129386CB0045A174 /* Private */ = { + isa = PBXGroup; + children = ( + 66ADCE661291BC1E00855386 /* TTExtensionInfoPrivate.h */, + ); + name = Private; + sourceTree = ""; + }; + 66ECA24F128DFE10006C78C2 /* Extensions */ = { + isa = PBXGroup; + children = ( + 66ECA258128DFE34006C78C2 /* TTExtensionLoader.h */, + 66ECA251128DFE28006C78C2 /* TTExtensionLoader.m */, + 66ADC90E1290B24D00855386 /* TTExtensionInfo.h */, + 66ADC9071290B23A00855386 /* TTExtensionInfo.m */, + 6664448A129386CB0045A174 /* Private */, + 66ADCE881291BEBB00855386 /* TTExtensionAuthor.h */, + 66ADCE811291BEAE00855386 /* TTExtensionAuthor.m */, + ); + name = Extensions; + sourceTree = ""; + }; 6E607CAE11AF2DE800C93CD4 /* Entity Tables */ = { isa = PBXGroup; children = ( @@ -178,6 +226,7 @@ 6ED117D21183BDBF0096AEBF /* Global */, 6ED118141183BF9D0096AEBF /* Additions */, 6ED118C21183C2310096AEBF /* Debug */, + 66ECA24F128DFE10006C78C2 /* Extensions */, 6E607CAE11AF2DE800C93CD4 /* Entity Tables */, 6E78061A1183BD810078A30B /* Classes */, ); @@ -187,6 +236,10 @@ 6ED117D21183BDBF0096AEBF /* Global */ = { isa = PBXGroup; children = ( + 660E7374135A560A00531398 /* Three20Version.h */, + 66CE68FA135B320F00E127E2 /* Three20Version.m */, + 66A0530B132EB47F00132434 /* Three20.h */, + 66A05309132EB47900132434 /* Three20.m */, 6E178E771183C8D3003B099E /* TTCorePreprocessorMacros.h */, 6E178E781183C8DA003B099E /* TTGlobalCore.h */, 6E178E7B1183C8E5003B099E /* TTGlobalCore.m */, @@ -196,6 +249,8 @@ 6E178E7D1183C8E5003B099E /* TTGlobalCorePaths.m */, 6EDAE9C6118CA1720008133C /* TTGlobalCoreRects.h */, 6EDAE9C8118CA1790008133C /* TTGlobalCoreRects.m */, + 6656B2521354035900B34AB5 /* TTAvailability.h */, + 6656B2541354035F00B34AB5 /* TTAvailability.m */, ); name = Global; sourceTree = ""; @@ -293,6 +348,13 @@ 6E6454561184BE8600F08CB1 /* Three20Core+Additions.h in Headers */, 6EDAE9C7118CA1720008133C /* TTGlobalCoreRects.h in Headers */, 6E607CF211AF2FE400C93CD4 /* TTEntityTables.h in Headers */, + 66ECA25B128DFE34006C78C2 /* TTExtensionLoader.h in Headers */, + 66ADC90F1290B24D00855386 /* TTExtensionInfo.h in Headers */, + 66ADCE681291BC1E00855386 /* TTExtensionInfoPrivate.h in Headers */, + 66ADCE8B1291BEBB00855386 /* TTExtensionAuthor.h in Headers */, + 6656B2531354035900B34AB5 /* TTAvailability.h in Headers */, + 66A0530C132EB47F00132434 /* Three20.h in Headers */, + 660E7375135A560A00531398 /* Three20Version.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -306,6 +368,7 @@ BEF31F360F352DF5000DE5D2 /* Headers */, 6E645EC91187AB0500F08CB1 /* Protect Copied Headers */, BEF31F370F352DF5000DE5D2 /* Sources */, + 668E63EA131A42F500ACE4AB /* Lint */, BEF31F380F352DF5000DE5D2 /* Frameworks */, ); buildRules = ( @@ -317,9 +380,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libThree20Core.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTests */ = { + EB9E6C6110B6A8F800DE563C /* Three20CoreUnitTests */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20CoreUnitTests" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -331,7 +394,7 @@ dependencies = ( 6EB460DE1183D8D400685649 /* PBXTargetDependency */, ); - name = UnitTests; + name = Three20CoreUnitTests; productName = CoreUnitTests; productReference = EB9E6C6210B6A8F800DE563C /* CoreUnitTests.octest */; productType = "com.apple.product-type.bundle"; @@ -342,17 +405,25 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = NO; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Three20Core" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectRoot = ""; targets = ( BEF31F390F352DF5000DE5D2 /* Three20Core */, - EB9E6C6110B6A8F800DE563C /* UnitTests */, + EB9E6C6110B6A8F800DE563C /* Three20CoreUnitTests */, ); }; /* End PBXProject section */ @@ -368,6 +439,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 668E63EA131A42F500ACE4AB /* Lint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = Lint; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/usr/bin/env python ../scripts/lint"; + shellScript = ""; + showEnvVarsInLog = 0; + }; 6E645EC91187AB0500F08CB1 /* Protect Copied Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -416,6 +502,12 @@ 6EB460631183CFB900685649 /* NSMutableDictionaryAdditions.m in Sources */, 6EDAE9C9118CA1790008133C /* TTGlobalCoreRects.m in Sources */, 6E607CF111AF2FE400C93CD4 /* TTEntityTables.m in Sources */, + 66ECA257128DFE28006C78C2 /* TTExtensionLoader.m in Sources */, + 66ADC9091290B23A00855386 /* TTExtensionInfo.m in Sources */, + 66ADCE871291BEAE00855386 /* TTExtensionAuthor.m in Sources */, + 6656B2551354035F00B34AB5 /* TTAvailability.m in Sources */, + 66A0530A132EB47900132434 /* Three20.m in Sources */, + 66CE68FB135B320F00E127E2 /* Three20Version.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -444,14 +536,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; @@ -463,9 +552,10 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; @@ -475,12 +565,11 @@ buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - SDKROOT = iphonesimulator4.0; + SDKROOT = iphoneos; }; name = Internal; }; @@ -492,7 +581,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -502,8 +591,7 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -512,14 +600,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -527,14 +612,12 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -544,11 +627,11 @@ buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -558,9 +641,9 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - PREBINDING = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -588,7 +671,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20CoreUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/Three20Core/UnitTests/CoreAdditionTests.m b/src/Three20Core/UnitTests/CoreAdditionTests.m index d4236eb263..80872bae29 100644 --- a/src/Three20Core/UnitTests/CoreAdditionTests.m +++ b/src/Three20Core/UnitTests/CoreAdditionTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,10 +14,8 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. - -// See Also: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html +// See: http://bit.ly/hS5nNh for unit test macros. +// See Also: http://bit.ly/hgpqd2 #import @@ -38,8 +36,7 @@ * NSDateAdditions cannot be easily tested from a library unit test due to their dependence upon * TTLocalizedString. This is because the Three20.bundle file needs to be loaded for * TTLocalizedString to work, but the octest framework does not play well with bundles. - * It tries to load the bundle from - * /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/Developer/usr/bin + * It tries to load the bundle from the simulator's /bin directory * which is not a place we can normally copy to from the Xcode project settings. */ @@ -73,6 +70,18 @@ - (void)testNSData_md5Hash { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testNSData_sha1Hash { + const char* bytes = "three20"; + NSData* data = [[NSData alloc] initWithBytes:bytes length:strlen(bytes)]; + + STAssertTrue([[data sha1Hash] isEqualToString:@"ca264456199abfcc3023a880b6e924026ca57164"], + @"SHA1 hashes don't match."); + + TT_RELEASE_SAFELY(data); +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - @@ -93,7 +102,8 @@ - (void)testNSString_isWhitespace { // Unicode whitespace for (int unicode = 0x000A; unicode <= 0x000D; ++unicode) { NSString* str = [NSString stringWithFormat:@"%C", unicode]; - STAssertTrue([str isWhitespaceAndNewlines], @"Unicode string #%X should be whitespace.", unicode); + STAssertTrue([str isWhitespaceAndNewlines], + @"Unicode string #%X should be whitespace.", unicode); } NSString* str = [NSString stringWithFormat:@"%C", 0x0085]; @@ -197,6 +207,80 @@ - (void)testNSString_queryDictionaryUsingEncoding { STAssertTrue([query count] == 0, @"Query: %@", query); } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testNSString_queryContentsUsingEncoding { + NSDictionary* query; + + query = [@"" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertTrue([query count] == 0, @"Query: %@", query); + + query = [@"q" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertTrue([[query objectForKey:@"q"] isEqual:[NSArray arrayWithObject:[NSNull null]]], + @"Query: %@", query); + + query = [@"q=" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertTrue([[query objectForKey:@"q"] isEqual:[NSArray arrayWithObject:@""]], + @"Query: %@", query); + + query = [@"q=three20" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertTrue([[query objectForKey:@"q"] isEqual:[NSArray arrayWithObject:@"three20"]], + @"Query: %@", query); + + query = [@"q=three20%20github" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertTrue([[query objectForKey:@"q"] isEqual:[NSArray arrayWithObject:@"three20 github"]], + @"Query: %@", query); + + query = [@"q=three20&hl=en" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertTrue([[query objectForKey:@"q"] isEqual:[NSArray arrayWithObject:@"three20"]], + @"Query: %@", query); + STAssertTrue([[query objectForKey:@"hl"] isEqual:[NSArray arrayWithObject:@"en"]], + @"Query: %@", query); + + query = [@"q=three20&hl=" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertTrue([[query objectForKey:@"q"] isEqual:[NSArray arrayWithObject:@"three20"]], + @"Query: %@", query); + STAssertTrue([[query objectForKey:@"hl"] isEqual:[NSArray arrayWithObject:@""]], + @"Query: %@", query); + + query = [@"q=&&hl=" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertTrue([[query objectForKey:@"q"] isEqual:[NSArray arrayWithObject:@""]], + @"Query: %@", query); + STAssertTrue([[query objectForKey:@"hl"] isEqual:[NSArray arrayWithObject:@""]], + @"Query: %@", query); + + query = [@"q=three20=repo&hl=en" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertNil([query objectForKey:@"q"], @"Query: %@", query); + STAssertTrue([[query objectForKey:@"hl"] isEqual:[NSArray arrayWithObject:@"en"]], + @"Query: %@", query); + + query = [@"&&" queryContentsUsingEncoding:NSUTF8StringEncoding]; + STAssertTrue([query count] == 0, @"Query: %@", query); + + query = [@"q=foo&q=three20" queryContentsUsingEncoding:NSUTF8StringEncoding]; + NSArray* qArr = [NSArray arrayWithObjects:@"foo", @"three20", nil]; + STAssertTrue([[query objectForKey:@"q"] isEqual:qArr], @"Query: %@", query); + + query = [@"q=foo&q=three20&hl=en" queryContentsUsingEncoding:NSUTF8StringEncoding]; + qArr = [NSArray arrayWithObjects:@"foo", @"three20", nil]; + STAssertTrue([[query objectForKey:@"q"] isEqual:qArr], @"Query: %@", query); + STAssertTrue([[query objectForKey:@"hl"] isEqual:[NSArray arrayWithObject:@"en"]], + @"Query: %@", query); + + query = [@"q=foo&q=three20&hl=en&g" queryContentsUsingEncoding:NSUTF8StringEncoding]; + qArr = [NSArray arrayWithObjects:@"foo", @"three20", nil]; + STAssertTrue([[query objectForKey:@"q"] isEqual:qArr], @"Query: %@", query); + STAssertTrue([[query objectForKey:@"hl"] isEqual:[NSArray arrayWithObject:@"en"]], + @"Query: %@", query); + STAssertTrue([[query objectForKey:@"g"] isEqual:[NSArray arrayWithObject:[NSNull null]]], + @"Query: %@", query); + + query = [@"q&q=three20&hl=en&g" queryContentsUsingEncoding:NSUTF8StringEncoding]; + qArr = [NSArray arrayWithObjects:[NSNull null], @"three20", nil]; + STAssertTrue([[query objectForKey:@"q"] isEqual:qArr], @"Query: %@", query); + STAssertTrue([[query objectForKey:@"hl"] isEqual:[NSArray arrayWithObject:@"en"]], + @"Query: %@", query); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)testNSString_stringByAddingQueryDictionary { @@ -224,6 +308,76 @@ - (void)testNSString_stringByAddingQueryDictionary { @"Additional query parameters not correct. %@", [baseUrl stringByAddingQueryDictionary:query]); } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testNSString_stringByAddingURLEncodedQueryDictionary { + NSString* baseUrl = @"http://google.com/search"; + STAssertEqualObjects([baseUrl stringByAddingURLEncodedQueryDictionary:nil], + [baseUrl stringByAppendingString:@"?"], + @"Empty dictionary fail."); + + STAssertEqualObjects([baseUrl stringByAddingURLEncodedQueryDictionary:[NSDictionary dictionary]], + [baseUrl stringByAppendingString:@"?"], + @"Empty dictionary fail."); + + baseUrl = @"http://google.com/search?hl=foo"; + STAssertEqualObjects([baseUrl stringByAddingURLEncodedQueryDictionary:[NSDictionary + dictionaryWithObject:@"Ö " forKey:@"Ü"]], + [baseUrl stringByAppendingString:@"&%C3%9C=%C3%96%20"], + @"Single parameter fail."); + + + NSDictionary* query = [NSDictionary + dictionaryWithObjectsAndKeys: + @"%(", @"\u1234", + @"§/", @"hl", + nil]; + NSString* baseUrlWithQuery = [baseUrl stringByAddingURLEncodedQueryDictionary:query]; + STAssertTrue([baseUrlWithQuery isEqualToString:[baseUrl + stringByAppendingString:@"&%E1%88%B4=%25%28&hl=%C2%A7%2F"]] + || [baseUrlWithQuery isEqualToString:[baseUrl + stringByAppendingString:@"&hl=%C2%A7%2F&%E1%88%B4=%25%28"]], + @"Additional query parameters not correct. %@", + [baseUrl stringByAddingQueryDictionary:query]); + + NSDictionary* malformedQueryDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] + forKey:@""]; + STAssertNoThrowSpecificNamed([@"" stringByAddingURLEncodedQueryDictionary:malformedQueryDict], + NSException, NSInvalidArgumentException, + @"Doesn't thow expected exception"); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testNSString_urlEncoded { + NSString* reservedCharacters = @"!#$%&'()*+,/:;=?@[] "; + + STAssertEqualObjects([reservedCharacters + urlEncoded], + @"%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D%20", + @"incorrect url encoding"); + + NSString* aLittleBitOfWhiteSpace = @"\r\n\t"; + + STAssertEqualObjects([aLittleBitOfWhiteSpace + urlEncoded], + @"%0D%0A%09", + @"incorrect url encoding"); + + NSString* someHighCodeCharacters = @"äÄöÖüÜñàÀáÀîÎ"; + + STAssertEqualObjects([someHighCodeCharacters + urlEncoded], + @"%C3%A4%C3%84%C3%B6%C3%96%C3%BC%C3%9C%C3%B1%" + @"C3%A0%C3%80%C3%A1%C3%80%C3%AE%C3%8E", + @"incorrect url encoding"); + + NSString* someUnusualCharacters = @"Ƕဿᴞ🆒"; + + STAssertEqualObjects([someUnusualCharacters + urlEncoded], + @"%C7%B6%E1%80%BF%E1%B4%9E%F0%9F%86%92", + @"incorrect url encoding"); +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)testNSString_versionStringCompare { diff --git a/src/Three20Core/UnitTests/CoreGlobalTests.m b/src/Three20Core/UnitTests/CoreGlobalTests.m index c0ca5d2cbb..2e9b22e4ce 100644 --- a/src/Three20Core/UnitTests/CoreGlobalTests.m +++ b/src/Three20Core/UnitTests/CoreGlobalTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,13 +14,15 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. +// See: http://bit.ly/hS5nNh for unit test macros. #import // Core +#import "Three20Core/Three20.h" +#import "Three20Core/Three20Version.h" #import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/TTGlobalCorePaths.h" #import "Three20Core/TTGlobalCore.h" /** @@ -47,6 +49,27 @@ - (void)testSuccess { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Versioning + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testThree20Versioning { + STAssertTrue([[Three20 version] isEqualToString:Three20Version], + @"The latest version has not been updated correctly."); + STAssertEquals([Three20 majorVersion], 1, + @"The latest major version has not been updated correctly."); + STAssertEquals([Three20 minorVersion], 0, + @"The latest minor version has not been updated correctly."); + STAssertEquals([Three20 bugfixVersion], 11, + @"The latest bugfix version has not been updated correctly."); + STAssertEquals([Three20 hotfixVersion], 0, + @"The latest hotfix version has not been updated correctly."); +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - @@ -62,6 +85,37 @@ - (void)testIsMaskSet { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Bundles + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testDefaultBundles { + STAssertEquals([NSBundle mainBundle], TTGetDefaultBundle(), + @"Default bundle should be mainBundle"); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testSettingDefaultBundles { + NSBundle* testBundle = [NSBundle bundleWithIdentifier:@"com.facebook.three20.UnitTests"]; + STAssertTrue(nil != testBundle, @"Unable to find the bundle %@", [NSBundle allBundles]); + + TTSetDefaultBundle(testBundle); + + STAssertEquals(testBundle, TTGetDefaultBundle(), + @"Default bundle should be set to the unit test bundle"); + + TTSetDefaultBundle(nil); + + STAssertEquals([NSBundle mainBundle], TTGetDefaultBundle(), + @"Default bundle should be back to mainBundle"); +} + + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - diff --git a/src/Three20Core/UnitTests/CoreMarkupStripperTests.m b/src/Three20Core/UnitTests/CoreMarkupStripperTests.m index c464226909..3e405820b6 100644 --- a/src/Three20Core/UnitTests/CoreMarkupStripperTests.m +++ b/src/Three20Core/UnitTests/CoreMarkupStripperTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,8 +14,7 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. +// See: http://bit.ly/hS5nNh for unit test macros. #import diff --git a/src/Three20Network/Configurations/Library.xcconfig b/src/Three20Network/Configurations/Library.xcconfig index 400247d618..a3f80e7ae7 100644 --- a/src/Three20Network/Configurations/Library.xcconfig +++ b/src/Three20Network/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,5 +17,6 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = Three20Network +BASE_PRODUCT_NAME = Three20Network +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/src/Three20Network/Configurations/Project.xcconfig b/src/Three20Network/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/Three20Network/Configurations/Project.xcconfig +++ b/src/Three20Network/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Configurations/UnitTests.xcconfig b/src/Three20Network/Configurations/UnitTests.xcconfig index ffd440c449..f057aca3a2 100644 --- a/src/Three20Network/Configurations/UnitTests.xcconfig +++ b/src/Three20Network/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,5 +17,6 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = NetworkUnitTests -BUILD_BUNDLE_VERSION = 1.0 +BASE_PRODUCT_NAME = NetworkUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME) +BUILD_BUNDLE_VERSION = 1.0 diff --git a/src/Three20Network/Headers/TTErrorCodes.h b/src/Three20Network/Headers/TTErrorCodes.h new file mode 100644 index 0000000000..3e47c3a89e --- /dev/null +++ b/src/Three20Network/Headers/TTErrorCodes.h @@ -0,0 +1,21 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +extern NSString* const kTTNetworkErrorDomain; +extern NSInteger const kTTNetworkErrorCodeInvalidImage; +extern NSString* const kTTErrorResponseDataKey; diff --git a/src/Three20Network/Headers/TTGlobalNetwork.h b/src/Three20Network/Headers/TTGlobalNetwork.h index f26a84dbce..a6a558fff2 100644 --- a/src/Three20Network/Headers/TTGlobalNetwork.h +++ b/src/Three20Network/Headers/TTGlobalNetwork.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Headers/TTModel.h b/src/Three20Network/Headers/TTModel.h index dd3ac9cfc1..8d22df5149 100644 --- a/src/Three20Network/Headers/TTModel.h +++ b/src/Three20Network/Headers/TTModel.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Headers/TTModelDelegate.h b/src/Three20Network/Headers/TTModelDelegate.h index 30a74a25db..1573239093 100644 --- a/src/Three20Network/Headers/TTModelDelegate.h +++ b/src/Three20Network/Headers/TTModelDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Headers/TTRequestLoader.h b/src/Three20Network/Headers/TTRequestLoader.h index ad26fd4687..d42cc8cd8d 100644 --- a/src/Three20Network/Headers/TTRequestLoader.h +++ b/src/Three20Network/Headers/TTRequestLoader.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,7 +36,8 @@ * TTURLRequestQueue's sendRequest. * For all other TTURLRequest types, they will each have their own loader. */ -@interface TTRequestLoader : NSObject { +@interface TTRequestLoader : NSObject +{ NSString* _urlPath; TTURLRequestQueue* _queue; diff --git a/src/Three20Network/Headers/TTURLCache.h b/src/Three20Network/Headers/TTURLCache.h index a2ec1f3ae5..28ff465859 100644 --- a/src/Three20Network/Headers/TTURLCache.h +++ b/src/Three20Network/Headers/TTURLCache.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Headers/TTURLDataResponse.h b/src/Three20Network/Headers/TTURLDataResponse.h index e2274cdb8b..4cd295d950 100644 --- a/src/Three20Network/Headers/TTURLDataResponse.h +++ b/src/Three20Network/Headers/TTURLDataResponse.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Headers/TTURLImageResponse.h b/src/Three20Network/Headers/TTURLImageResponse.h index d4682e5e62..dd52a0d7c5 100644 --- a/src/Three20Network/Headers/TTURLImageResponse.h +++ b/src/Three20Network/Headers/TTURLImageResponse.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Headers/TTURLRequest.h b/src/Three20Network/Headers/TTURLRequest.h index 895545e3d9..9d3e7eb3db 100644 --- a/src/Three20Network/Headers/TTURLRequest.h +++ b/src/Three20Network/Headers/TTURLRequest.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,6 +22,14 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" // For __TTDEPRECATED_METHOD +/** + * A constant to improve code readabillity, when using negative numbers for + * timeoutInterval. + * + * @see timeoutInterval + */ +extern const NSTimeInterval TTURLRequestUseQueueTimeout; + @protocol TTURLRequestDelegate; @protocol TTURLResponse; @@ -54,6 +62,11 @@ NSInteger _totalBytesLoaded; NSInteger _totalBytesExpected; + + NSTimeInterval _timeoutInterval; + + NSInteger _totalBytesDownloaded; + NSInteger _totalContentLength; id _userInfo; @@ -61,6 +74,7 @@ BOOL _shouldHandleCookies; BOOL _respondedFromCache; BOOL _filterPasswordLogging; + BOOL _multiPartForm; NSMutableArray* _delegates; } @@ -141,7 +155,7 @@ * * By setting the cacheKey, you may override the default cache key generator with your own. */ -@property (nonatomic, retain) NSString* cacheKey; +@property (nonatomic, copy) NSString* cacheKey; /** * A dummy object used to uniquely identify this request object once it's been sent into the fray. @@ -171,15 +185,54 @@ @property (nonatomic) BOOL shouldHandleCookies; /** - * The number of bytes loaded by this request. + * The number of request body bytes already uploaded by this request. */ @property (nonatomic) NSInteger totalBytesLoaded; /** - * The number of expected bytes from this request. + * The total number of request body bytes expected to be uploaded for this request. */ @property (nonatomic) NSInteger totalBytesExpected; +/** + * The number of downloaded bytes from server. + */ +@property (nonatomic) NSInteger totalBytesDownloaded; + +/** + * The number of content length of request. + */ +@property (nonatomic) NSInteger totalContentLength; + +/** + * The timeout to use for the request. + * + * If a negative value is set the request uses + * the defaultTimeout of the TTURLRequestQueue. This differs from behaviour of + * NSURLRequest. Given a negative timeoutInterval NSURLRequest always fails. + * + * You should use the TTURLRequestUseQueueTimeout constant to improve + * code readabillity, instead of negative numbers. + * + * The default value is TTURLRequestUseQueueTimeout + * + * @par from NSURLRequest.h: + * + * The timeout interval specifies the limit on the idle + * interval alloted to a request in the process of loading. The "idle + * interval" is defined as the period of time that has passed since the + * last instance of load activity occurred for a request that is in the + * process of loading. Hence, when an instance of load activity occurs + * (e.g. bytes are received from the network for a request), the idle + * interval for a request is reset to 0. If the idle interval ever + * becomes greater than or equal to the timeout interval, the request + * is considered to have timed out. This timeout interval is measured + * in seconds. + * + * @see TTURLRequestQueue::defaultTimeout + */ +@property (nonatomic) NSTimeInterval timeoutInterval; + /** * Whether or not the request was loaded from the cache. * @@ -204,6 +257,11 @@ */ @property (nonatomic, readonly) NSMutableArray* delegates; +/** + * Determine whether to construct a multipart form or to instead encode the http body as the W3C default + * of application/x-www-form-urlencoded + */ +@property (nonatomic, assign) BOOL multiPartForm; + (TTURLRequest*)request; diff --git a/src/Three20Network/Headers/TTURLRequestCachePolicy.h b/src/Three20Network/Headers/TTURLRequestCachePolicy.h index c52132e31b..03971884d3 100644 --- a/src/Three20Network/Headers/TTURLRequestCachePolicy.h +++ b/src/Three20Network/Headers/TTURLRequestCachePolicy.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ typedef enum { TTURLRequestCachePolicyNetwork = 4, TTURLRequestCachePolicyNoCache = 8, TTURLRequestCachePolicyEtag = 16 | TTURLRequestCachePolicyDisk, + TTURLRequestCachePolicyReadThrough = 32, TTURLRequestCachePolicyLocal = (TTURLRequestCachePolicyMemory | TTURLRequestCachePolicyDisk), TTURLRequestCachePolicyDefault diff --git a/src/Three20Network/Headers/TTURLRequestDelegate.h b/src/Three20Network/Headers/TTURLRequestDelegate.h index 3d7ce97849..de1455b4b3 100644 --- a/src/Three20Network/Headers/TTURLRequestDelegate.h +++ b/src/Three20Network/Headers/TTURLRequestDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Headers/TTURLRequestModel.h b/src/Three20Network/Headers/TTURLRequestModel.h index 2522c3134c..4d1a870b27 100644 --- a/src/Three20Network/Headers/TTURLRequestModel.h +++ b/src/Three20Network/Headers/TTURLRequestModel.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -54,5 +54,11 @@ */ - (void)reset; +/** + * Valid while loading. Returns download progress as between 0 and 1. + */ + +- (float)downloadProgress; + @end diff --git a/src/Three20Network/Headers/TTURLRequestQueue.h b/src/Three20Network/Headers/TTURLRequestQueue.h index 0c62a4c89b..9d73a9b609 100644 --- a/src/Three20Network/Headers/TTURLRequestQueue.h +++ b/src/Three20Network/Headers/TTURLRequestQueue.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,6 +32,8 @@ NSString* _userAgent; CGFloat _imageCompressionQuality; + + NSTimeInterval _defaultTimeout; BOOL _suspended; } @@ -72,6 +74,18 @@ */ @property (nonatomic) CGFloat imageCompressionQuality; + +/** + * The default Timeout used for all TTURLRequests. + * + * This timeout is applied to all requests that have a negative timeout set. + * + * The default value is defined as kTimeout in TTURLRequestQueue.m + * + * @see TTURLRequest::timeoutInterval + */ +@property (nonatomic) NSTimeInterval defaultTimeout; + /** * Get the shared cache singleton used across the application. */ diff --git a/src/Three20Network/Headers/TTURLRequestQueueInternal.h b/src/Three20Network/Headers/TTURLRequestQueueInternal.h index d589ade1ec..f47de8600c 100644 --- a/src/Three20Network/Headers/TTURLRequestQueueInternal.h +++ b/src/Three20Network/Headers/TTURLRequestQueueInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Headers/TTURLResponse.h b/src/Three20Network/Headers/TTURLResponse.h index 104a41aed1..7b3591bfad 100644 --- a/src/Three20Network/Headers/TTURLResponse.h +++ b/src/Three20Network/Headers/TTURLResponse.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -45,4 +45,17 @@ - (NSError*)request:(TTURLRequest*)request processResponse:(NSHTTPURLResponse*)response data:(id)data; +@optional +/** + * Processes the data from a unsuccessful request to construct a custom NSError object. + * + * @param request The request this response is bound to. + * @param response The response object, useful for getting the status code. + * @param data The data received from the TTURLRequest. + * @return NSError to construct for this response. + * + * @optional + */ +- (NSError*)request:(TTURLRequest*)request processErrorResponse:(NSHTTPURLResponse*)response + data:(id)data; @end diff --git a/src/Three20Network/Headers/TTUserInfo.h b/src/Three20Network/Headers/TTUserInfo.h index 3f392a2830..dbe82a9a1f 100644 --- a/src/Three20Network/Headers/TTUserInfo.h +++ b/src/Three20Network/Headers/TTUserInfo.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ id _weakRef; } -@property (nonatomic, retain) NSString* topic; +@property (nonatomic, copy) NSString* topic; @property (nonatomic, retain) id strongRef; @property (nonatomic, assign) id weakRef; diff --git a/src/Three20Network/Headers/Three20Network.h b/src/Three20Network/Headers/Three20Network.h index 94a91c7cae..2f10515458 100644 --- a/src/Three20Network/Headers/Three20Network.h +++ b/src/Three20Network/Headers/Three20Network.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,11 +14,14 @@ // limitations under the License. // +#import "Three20Core/Three20Core.h" + // Network // - Global #import "Three20Network/TTGlobalNetwork.h" #import "Three20Network/TTURLRequestCachePolicy.h" +#import "Three20Network/TTErrorCodes.h" // - Models #import "Three20Network/TTModel.h" diff --git a/src/Three20Network/Sources/TTErrorCodes.m b/src/Three20Network/Sources/TTErrorCodes.m new file mode 100644 index 0000000000..9c1f36f832 --- /dev/null +++ b/src/Three20Network/Sources/TTErrorCodes.m @@ -0,0 +1,21 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Network/TTErrorCodes.h" + +NSString* const kTTNetworkErrorDomain = @"three20.network"; +NSInteger const kTTNetworkErrorCodeInvalidImage = 100; +NSString* const kTTErrorResponseDataKey = @"responsedata"; diff --git a/src/Three20Network/Sources/TTGlobalNetwork.m b/src/Three20Network/Sources/TTGlobalNetwork.m index 21d6241397..a337612d16 100644 --- a/src/Three20Network/Sources/TTGlobalNetwork.m +++ b/src/Three20Network/Sources/TTGlobalNetwork.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Sources/TTModel.m b/src/Three20Network/Sources/TTModel.m index 020147f885..b411a2d74e 100644 --- a/src/Three20Network/Sources/TTModel.m +++ b/src/Three20Network/Sources/TTModel.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSMutableArray*)delegates { - if (!_delegates) { + if (nil == _delegates) { _delegates = TTCreateNonRetainingArray(); } return _delegates; diff --git a/src/Three20Network/Sources/TTRequestLoader.m b/src/Three20Network/Sources/TTRequestLoader.m index efdbc156b5..37efcd04a1 100644 --- a/src/Three20Network/Sources/TTRequestLoader.m +++ b/src/Three20Network/Sources/TTRequestLoader.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,10 @@ // limitations under the License. // -#import "Three20Network/TTRequestLoader.h" +#import "Three20Network/private/TTRequestLoader.h" + +//Global +#import "Three20Network/TTErrorCodes.h" // Network #import "Three20Network/TTGlobalNetwork.h" @@ -27,10 +30,16 @@ #import "Three20Network/private/TTURLRequestQueueInternal.h" // Core +#import "Three20Core/NSDataAdditions.h" #import "Three20Core/NSObjectAdditions.h" #import "Three20Core/TTDebug.h" #import "Three20Core/TTDebugFlags.h" +@interface TTRequestLoader (Private) +- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response ; +- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data ; +- (void)connectionDidFinishLoading:(NSURLConnection *)connection ; +@end static const NSInteger kLoadMaxRetries = 2; @@ -48,7 +57,8 @@ @implementation TTRequestLoader /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initForRequest:(TTURLRequest*)request queue:(TTURLRequestQueue*)queue { - if (self = [super init]) { + self = [super init]; + if (self) { _urlPath = [request.urlPath copy]; _queue = queue; _cacheKey = [request.cacheKey retain]; @@ -81,13 +91,49 @@ - (void)dealloc { #pragma mark - #pragma mark Private +////////////////////////////////////////////////////////////////////////////////////////////////// +// This method not called from outside, +// used as a separate entry point for performSelector outside connectToURL below +- (void)deliverDataResponse:(NSURL*)URL { + // http://tools.ietf.org/html/rfc2397 + NSArray * dataSplit = [[URL resourceSpecifier] componentsSeparatedByString:@","]; + if([dataSplit count]!=2) { + TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @"UNRECOGNIZED data: URL %@", self.urlPath); + return; + } + if([[dataSplit objectAtIndex:0] rangeOfString:@"base64"].location == NSNotFound) { + // Strictly speaking, to be really conformant need to interpret %xx hex encoded entities. + // The [NSString dataUsingEncoding] doesn't do that correctly, but most documents don't use that. + // Skip for now. + _responseData = [[NSMutableData dataWithData:[[dataSplit objectAtIndex:1] dataUsingEncoding:NSASCIIStringEncoding]] retain]; + } else { + _responseData = [[NSData dataWithBase64EncodedString:[dataSplit objectAtIndex:1]] retain]; + } + + [_queue performSelector:@selector(loader:didLoadResponse:data:) + withObject:self + withObject:_response + withObject:_responseData]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)connectToURL:(NSURL*)URL { TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @"Connecting to %@", _urlPath); + // If this is a data: url, we can decode right here ... after a delay to get out of calling thread + if([[URL scheme] isEqualToString:@"data"]) { + [self performSelector:@selector(deliverDataResponse:) withObject:URL afterDelay:0.1]; + return; + } TTNetworkRequestStarted(); - TTURLRequest* request = _requests.count == 1 ? [_requests objectAtIndex:0] : nil; + TTURLRequest* request = _requests.count >= 1 ? [_requests objectAtIndex:0] : nil; + + // there are situations where urlPath is somehow nil (therefore crashing in + // createNSURLRequest:URL:, even if we checked for non-blank values before + // adding the request to the queue. + if (!request.urlPath.length) + [self cancel:request]; + NSURLRequest* URLRequest = [_queue createNSURLRequest:request URL:URL]; _connection = [[NSURLConnection alloc] initWithRequest:URLRequest delegate:self]; @@ -136,7 +182,7 @@ - (void)removeRequest:(TTURLRequest*)request { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)load:(NSURL*)URL { - if (!_connection) { + if (nil == _connection) { [self connectToURL:URL]; } } @@ -148,7 +194,7 @@ - (void)loadSynchronously:(NSURL*)URL { // correctly, this would be the place to start tracing for errors. TTNetworkRequestStarted(); - TTURLRequest* request = _requests.count == 1 ? [_requests objectAtIndex:0] : nil; + TTURLRequest* request = _requests.count >= 1 ? [_requests objectAtIndex:0] : nil; NSURLRequest* URLRequest = [_queue createNSURLRequest:request URL:URL]; NSHTTPURLResponse* response = nil; @@ -165,6 +211,7 @@ - (void)loadSynchronously:(NSURL*)URL { TT_RELEASE_SAFELY(_connection); [_queue loader:self didFailLoadWithError:error]; + } else { [self connection:nil didReceiveResponse:(NSHTTPURLResponse*)response]; [self connection:nil didReceiveData:data]; @@ -207,7 +254,24 @@ - (BOOL)cancel:(TTURLRequest*)request { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSError*)processResponse:(NSHTTPURLResponse*)response data:(id)data { for (TTURLRequest* request in _requests) { - NSError* error = [request.response request:request processResponse:response data:data]; + NSError* error = nil; + // We need to accept valid HTTP status codes, not only 200. + if (!response || ![response respondsToSelector:@selector(statusCode)] + || (response.statusCode >= 200 && response.statusCode < 300) + || response.statusCode == 304) { + error = [request.response request:request processResponse:response data:data]; + } else { + if ([request.response respondsToSelector:@selector(request:processErrorResponse:data:)]) { + error = [request.response request:request processErrorResponse:response data:data]; + } + // Supply an NSError object if request.response's + // request:processErrorResponse:data: does not return one. + if (!error) { + TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @" FAILED LOADING (%d) %@", _response.statusCode, _urlPath); + NSDictionary* userInfo = [NSDictionary dictionaryWithObject:data forKey:kTTErrorResponseDataKey]; + error = [NSError errorWithDomain:NSURLErrorDomain code:_response.statusCode userInfo:userInfo]; + } + } if (error) { return error; } @@ -277,29 +341,41 @@ - (void)cancel { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response { _response = [response retain]; - NSDictionary* headers = [response allHeaderFields]; - int contentLength = [[headers objectForKey:@"Content-Length"] intValue]; - - // If you hit this assertion it's because a massive file is about to be downloaded. - // If you're sure you want to do this, add the following line to your app delegate startup - // method. Setting the max content length to zero allows anything to go through. If you just - // want to raise the limit, set it to any positive byte size. - // [[TTURLRequestQueue mainQueue] setMaxContentLength:0] - TTDASSERT(0 == _queue.maxContentLength || contentLength <=_queue.maxContentLength); - - if (contentLength > _queue.maxContentLength && _queue.maxContentLength) { - TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @"MAX CONTENT LENGTH EXCEEDED (%d) %@", - contentLength, _urlPath); - [self cancel]; + if ([response respondsToSelector:@selector(allHeaderFields)]){ + NSDictionary* headers = [response allHeaderFields]; + int contentLength = [[headers objectForKey:@"Content-Length"] intValue]; + + // If you hit this assertion it's because a massive file is about to be downloaded. + // If you're sure you want to do this, add the following line to your app delegate startup + // method. Setting the max content length to zero allows anything to go through. If you just + // want to raise the limit, set it to any positive byte size. + // [[TTURLRequestQueue mainQueue] setMaxContentLength:0] + TTDASSERT(0 == _queue.maxContentLength || contentLength <=_queue.maxContentLength); + + if (contentLength > _queue.maxContentLength && _queue.maxContentLength) { + TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @"MAX CONTENT LENGTH EXCEEDED (%d) %@", + contentLength, _urlPath); + [self cancel]; + } + + _responseData = [[NSMutableData alloc] initWithCapacity:contentLength]; + + for (TTURLRequest* request in [[_requests copy] autorelease]) { + request.totalContentLength = contentLength; + } + + }else { + _responseData = [[NSMutableData alloc] init]; } - - _responseData = [[NSMutableData alloc] initWithCapacity:contentLength]; } /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { [_responseData appendData:data]; + for (TTURLRequest* request in [[_requests copy] autorelease]) { + request.totalBytesDownloaded += [data length]; + } } @@ -324,20 +400,12 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection { TTNetworkRequestStopped(); TTDCONDITIONLOG(TTDFLAG_ETAGS, @"Response status code: %d", _response.statusCode); - - // We need to accept valid HTTP status codes, not only 200. - if (_response.statusCode >= 200 && _response.statusCode < 300) { - [_queue loader:self didLoadResponse:_response data:_responseData]; - + if (![_response respondsToSelector:@selector(statusCode)]){ + [_queue loader:self didLoadResponse:_response data:_responseData]; } else if (_response.statusCode == 304) { [_queue loader:self didLoadUnmodifiedResponse:_response]; - } else { - TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @" FAILED LOADING (%d) %@", - _response.statusCode, _urlPath); - NSError* error = [NSError errorWithDomain:NSURLErrorDomain code:_response.statusCode - userInfo:nil]; - [_queue loader:self didFailLoadWithError:error]; + [_queue loader:self didLoadResponse:_response data:_responseData]; } TT_RELEASE_SAFELY(_responseData); @@ -388,7 +456,9 @@ - (BOOL)isLoading { /////////////////////////////////////////////////////////////////////////////////////////////////// -// Deprecated +/** + * Deprecated + */ - (NSString*)URL { return _urlPath; } diff --git a/src/Three20Network/Sources/TTURLCache.m b/src/Three20Network/Sources/TTURLCache.m index d91be13c5e..679548f62a 100644 --- a/src/Three20Network/Sources/TTURLCache.m +++ b/src/Three20Network/Sources/TTURLCache.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ #import "Three20Core/TTDebugFlags.h" #import "Three20Core/NSStringAdditions.h" -static const CGFloat kLargeImageSize = 600 * 400; +static const CGFloat kLargeImageSize = 600.0f * 400.0f; static NSString* kDefaultCacheName = @"Three20"; static NSString* kEtagCacheDirectoryName = @"etag"; @@ -40,6 +40,9 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// @interface TTURLCache() +/** + * Creates paths as necessary and returns the cache path for the given name. + */ + (NSString*)cachePathWithName:(NSString*)name; @end @@ -59,7 +62,8 @@ @implementation TTURLCache /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithName:(NSString*)name { - if (self == [super init]) { + self = [super init]; + if (self) { _name = [name copy]; _cachePath = [[TTURLCache cachePathWithName:name] retain]; _invalidationAge = TT_DEFAULT_CACHE_INVALIDATION_AGE; @@ -82,7 +86,8 @@ - (id)initWithName:(NSString*)name { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithName:kDefaultCacheName]) { + self = [self initWithName:kDefaultCacheName]; + if (self) { } return self; @@ -113,11 +118,11 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// + (TTURLCache*)cacheWithName:(NSString*)name { - if (!gNamedCaches) { + if (nil == gNamedCaches) { gNamedCaches = [[NSMutableDictionary alloc] init]; } TTURLCache* cache = [gNamedCaches objectForKey:name]; - if (!cache) { + if (nil == cache) { cache = [[[TTURLCache alloc] initWithName:name] autorelease]; [gNamedCaches setObject:cache forKey:name]; } @@ -127,7 +132,7 @@ + (TTURLCache*)cacheWithName:(NSString*)name { /////////////////////////////////////////////////////////////////////////////////////////////////// + (TTURLCache*)sharedCache { - if (!gSharedCache) { + if (nil == gSharedCache) { gSharedCache = [[TTURLCache alloc] init]; } return gSharedCache; @@ -204,17 +209,22 @@ - (void)storeImage:(UIImage*)image forURL:(NSString*)URL force:(BOOL)force { int pixelCount = image.size.width * image.size.height; if (force || pixelCount < kLargeImageSize) { + UIImage* existingImage = [_imageCache objectForKey:URL]; + if (nil != existingImage) { + _totalPixelCount -= existingImage.size.width * existingImage.size.height; + [_imageSortedList removeObject:URL]; + } _totalPixelCount += pixelCount; if (_totalPixelCount > _maxPixelCount && _maxPixelCount) { [self expireImagesFromMemory]; } - if (!_imageCache) { + if (nil == _imageCache) { _imageCache = [[NSMutableDictionary alloc] init]; } - if (!_imageSortedList) { + if (nil == _imageSortedList) { _imageSortedList = [[NSMutableArray alloc] init]; } @@ -226,7 +236,9 @@ - (void)storeImage:(UIImage*)image forURL:(NSString*)URL force:(BOOL)force { /////////////////////////////////////////////////////////////////////////////////////////////////// -// TODO (jverkoey May 3, 2010): Clean up this redundant code. +/** + * TODO (jverkoey May 3, 2010): Clean up this redundant code. + */ - (BOOL)imageExistsFromBundle:(NSString*)URL { NSString* path = TTPathForBundleResource([URL substringFromIndex:9]); NSFileManager* fm = [NSFileManager defaultManager]; @@ -244,16 +256,15 @@ - (BOOL)imageExistsFromDocuments:(NSString*)URL { /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIImage*)loadImageFromBundle:(NSString*)URL { - NSString* path = [URL substringFromIndex:9]; - return [UIImage imageNamed:path]; + NSString* path = TTPathForBundleResource([URL substringFromIndex:9]); + return [UIImage imageWithContentsOfFile:path]; } /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIImage*)loadImageFromDocuments:(NSString*)URL { NSString* path = TTPathForDocumentsResource([URL substringFromIndex:12]); - NSData* data = [NSData dataWithContentsOfFile:path]; - return [UIImage imageWithData:data]; + return [UIImage imageWithContentsOfFile:path]; } @@ -397,6 +408,37 @@ - (NSData*)dataForKey:(NSString*)key expires:(NSTimeInterval)expirationAge } +/////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * This method needs to handle urlPaths with and without extensions. + * So @"path.png" will resolve to @"path@2x.png" and + * @"path" will resolve to @"path@2x" + * + * Paths beginning with @"." will not be changed. + */ ++ (NSString*)doubleImageURLPath:(NSString*)urlPath { + if ([[urlPath substringToIndex:1] isEqualToString:@"."]) { + return urlPath; + } + + // We'd ideally use stringByAppendingPathExtension: in this method, but it seems + // to wreck bundle:// urls by replacing them with bundle:/ prefixes. Strange. + NSString* pathExtension = [urlPath pathExtension]; + + NSString* urlPathWithNoExtension = [urlPath substringToIndex: + [urlPath length] - [pathExtension length] + - (([pathExtension length] > 0) ? 1 : 0)]; + + urlPath = [urlPathWithNoExtension stringByAppendingString:@"@2x"]; + + if ([pathExtension length] > 0) { + urlPath = [urlPath stringByAppendingFormat:@".%@", pathExtension]; + } + + return urlPath; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)hasImageForURL:(NSString*)URL fromDisk:(BOOL)fromDisk { BOOL hasImage = (nil != [_imageCache objectForKey:URL]); @@ -404,9 +446,16 @@ - (BOOL)hasImageForURL:(NSString*)URL fromDisk:(BOOL)fromDisk { if (!hasImage && fromDisk) { if (TTIsBundleURL(URL)) { hasImage = [self imageExistsFromBundle:URL]; + if (!hasImage) { + hasImage = [self imageExistsFromBundle:[TTURLCache doubleImageURLPath:URL]]; + } } else if (TTIsDocumentsURL(URL)) { hasImage = [self imageExistsFromDocuments:URL]; + if (!hasImage) { + hasImage = [self imageExistsFromDocuments:[TTURLCache doubleImageURLPath:URL]]; + } + } } diff --git a/src/Three20Network/Sources/TTURLDataResponse.m b/src/Three20Network/Sources/TTURLDataResponse.m index d6c6fe0a4b..50422d1219 100644 --- a/src/Three20Network/Sources/TTURLDataResponse.m +++ b/src/Three20Network/Sources/TTURLDataResponse.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/Sources/TTURLImageResponse.m b/src/Three20Network/Sources/TTURLImageResponse.m index 49dd44d32d..fed7d97c9d 100644 --- a/src/Three20Network/Sources/TTURLImageResponse.m +++ b/src/Three20Network/Sources/TTURLImageResponse.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ #import "Three20Network/TTURLImageResponse.h" // Network +#import "Three20Network/TTErrorCodes.h" #import "Three20Network/TTURLRequest.h" #import "Three20Network/TTURLCache.h" @@ -60,12 +61,13 @@ - (NSError*)request:(TTURLRequest*)request processResponse:(NSHTTPURLResponse*)r // TODO(jverkoey Feb 10, 2010): This logic doesn't entirely make sense. Why don't we just store // the data in the cache if there was a cache miss, and then just retain the image data we // downloaded? This needs to be tested in production. - UIImage* image = [[TTURLCache sharedCache] imageForURL:request.urlPath fromDisk:NO]; - + UIImage* image = nil; + if(!(request.cachePolicy | TTURLRequestCachePolicyNoCache)) { + image = [[TTURLCache sharedCache] imageForURL:request.urlPath fromDisk:NO]; + } if (nil == image) { image = [UIImage imageWithData:data]; } - if (nil != image) { if (!request.respondedFromCache) { // XXXjoe Working on option to scale down really large images to a smaller size to save memory @@ -81,8 +83,9 @@ - (NSError*)request:(TTURLRequest*)request processResponse:(NSHTTPURLResponse*)r _image = [image retain]; } else { - return [NSError errorWithDomain:TT_ERROR_DOMAIN code:TT_EC_INVALID_IMAGE - userInfo:nil]; + return [NSError errorWithDomain:kTTNetworkErrorDomain + code:kTTNetworkErrorCodeInvalidImage + userInfo:nil]; } } diff --git a/src/Three20Network/Sources/TTURLRequest.m b/src/Three20Network/Sources/TTURLRequest.m index e8d7cb4f72..301af9aa1b 100644 --- a/src/Three20Network/Sources/TTURLRequest.m +++ b/src/Three20Network/Sources/TTURLRequest.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ #import "Three20Network/TTURLRequest.h" + // Network #import "Three20Network/TTGlobalNetwork.h" #import "Three20Network/TTURLResponse.h" @@ -28,7 +29,7 @@ #import "Three20Core/NSStringAdditions.h" static NSString* kStringBoundary = @"3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f"; - +const NSTimeInterval TTURLRequestUseQueueTimeout = -1.0; /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -55,31 +56,38 @@ @implementation TTURLRequest @synthesize totalBytesLoaded = _totalBytesLoaded; @synthesize totalBytesExpected = _totalBytesExpected; +@synthesize totalBytesDownloaded = _totalBytesDownloaded; +@synthesize totalContentLength = _totalContentLength; + +@synthesize timeoutInterval = _timeoutInterval; + @synthesize userInfo = _userInfo; @synthesize isLoading = _isLoading; @synthesize shouldHandleCookies = _shouldHandleCookies; @synthesize respondedFromCache = _respondedFromCache; @synthesize filterPasswordLogging = _filterPasswordLogging; +@synthesize multiPartForm = _multiPartForm; @synthesize delegates = _delegates; /////////////////////////////////////////////////////////////////////////////////////////////////// + (TTURLRequest*)request { - return [[[TTURLRequest alloc] init] autorelease]; + return [[[self alloc] init] autorelease]; } /////////////////////////////////////////////////////////////////////////////////////////////////// + (TTURLRequest*)requestWithURL:(NSString*)URL delegate:(id /**/)delegate { - return [[[TTURLRequest alloc] initWithURL:URL delegate:delegate] autorelease]; + return [[[self alloc] initWithURL:URL delegate:delegate] autorelease]; } /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithURL:(NSString*)URL delegate:(id /**/)delegate { - if (self = [self init]) { + self = [self init]; + if (self) { _urlPath = [URL retain]; if (nil != delegate) { [_delegates addObject:delegate]; @@ -91,12 +99,15 @@ - (id)initWithURL:(NSString*)URL delegate:(id /**/)delegat /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { _delegates = TTCreateNonRetainingArray(); _cachePolicy = TTURLRequestCachePolicyDefault; _cacheExpirationAge = TT_DEFAULT_CACHE_EXPIRATION_AGE; _shouldHandleCookies = YES; _charsetForMultipart = NSUTF8StringEncoding; + _multiPartForm = YES; + _timeoutInterval = TTURLRequestUseQueueTimeout; } return self; } @@ -123,7 +134,7 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)description { - return [NSString stringWithFormat:@"", _urlPath]; + return [NSString stringWithFormat:@"<%@ %@>", [super description], _urlPath]; } @@ -143,28 +154,68 @@ - (NSString*)generateCacheKey { } return [joined md5Hash]; + } else { return [self.urlPath md5Hash]; } } +////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSData *)generateNonMultipartPostBody { + NSMutableArray *paramsArray = [NSMutableArray array]; + for (id key in [_parameters keyEnumerator]) { + NSString *value = [_parameters valueForKey:key]; + if ([key isKindOfClass:[NSString class]] && [value isKindOfClass:[NSString class]]) { + [paramsArray addObject:[NSString stringWithFormat:@"%@=%@", + key, + [[value stringByReplacingOccurrencesOfString:@" " withString:@"+"] urlEncoded]]]; + } + } + NSString *stringBody = [paramsArray componentsJoinedByString:@"&"]; + return [stringBody dataUsingEncoding:NSUTF8StringEncoding]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// -- (NSData*)generatePostBody { - NSMutableData* body = [NSMutableData data]; - NSString* beginLine = [NSString stringWithFormat:@"\r\n--%@\r\n", kStringBoundary]; +- (void)appendImageData:(NSData*)data + withName:(NSString*)name + toBody:(NSMutableData*)body { + NSString *beginLine = [NSString stringWithFormat:@"--%@\r\n", kStringBoundary]; + NSString *endLine = @"\r\n"; + + [body appendData:[beginLine dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[[NSString stringWithFormat: + @"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", + name] + dataUsingEncoding:_charsetForMultipart]]; + [body appendData:[[NSString + stringWithFormat:@"Content-Length: %d\r\n", data.length] + dataUsingEncoding:_charsetForMultipart]]; + [body appendData:[[NSString + stringWithString:@"Content-Type: image/jpeg\r\n\r\n"] + dataUsingEncoding:_charsetForMultipart]]; + [body appendData:data]; + [body appendData:[endLine dataUsingEncoding:NSUTF8StringEncoding]]; +} - [body appendData:[[NSString stringWithFormat:@"--%@\r\n", kStringBoundary] - dataUsingEncoding:NSUTF8StringEncoding]]; +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSData*)generatePostBody { + + NSMutableData* body = [NSMutableData data]; + NSString* beginLine = [NSString stringWithFormat:@"--%@\r\n", kStringBoundary]; + NSString *endLine = @"\r\n"; + for (id key in [_parameters keyEnumerator]) { NSString* value = [_parameters valueForKey:key]; - if (![value isKindOfClass:[UIImage class]]) { + // Really, this can only be an NSString. We're cheating here. + if (![value isKindOfClass:[UIImage class]] && + ![value isKindOfClass:[NSData class]]) { [body appendData:[beginLine dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:_charsetForMultipart]]; [body appendData:[value dataUsingEncoding:_charsetForMultipart]]; + [body appendData:[endLine dataUsingEncoding:NSUTF8StringEncoding]]; } } @@ -175,18 +226,12 @@ - (NSData*)generatePostBody { CGFloat quality = [TTURLRequestQueue mainQueue].imageCompressionQuality; NSData* data = UIImageJPEGRepresentation(image, quality); - [body appendData:[beginLine dataUsingEncoding:NSUTF8StringEncoding]]; - [body appendData:[[NSString stringWithFormat: - @"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", - key] - dataUsingEncoding:_charsetForMultipart]]; - [body appendData:[[NSString - stringWithFormat:@"Content-Length: %d\r\n", data.length] - dataUsingEncoding:_charsetForMultipart]]; - [body appendData:[[NSString - stringWithString:@"Content-Type: image/jpeg\r\n\r\n"] - dataUsingEncoding:_charsetForMultipart]]; - [body appendData:data]; + [self appendImageData:data withName:key toBody:body]; + imageKey = key; + + } else if ([[_parameters objectForKey:key] isKindOfClass:[NSData class]]) { + NSData* data = [_parameters objectForKey:key]; + [self appendImageData:data withName:key toBody:body]; imageKey = key; } } @@ -206,9 +251,10 @@ - (NSData*)generatePostBody { [body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimeType] dataUsingEncoding:_charsetForMultipart]]; [body appendData:data]; + [body appendData:[endLine dataUsingEncoding:NSUTF8StringEncoding]]; } - [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", kStringBoundary] + [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", kStringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; // If an image was found, remove it from the dictionary to save memory while we @@ -231,13 +277,26 @@ - (NSMutableDictionary*)parameters { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSMutableDictionary*)headers { + if (!_headers) { + _headers = [[NSMutableDictionary alloc] init]; + } + return _headers; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSData*)httpBody { if (_httpBody) { return _httpBody; - } else if ([[_httpMethod uppercaseString] isEqualToString:@"POST"] - || [[_httpMethod uppercaseString] isEqualToString:@"PUT"]) { - return [self generatePostBody]; + } else if (([[_httpMethod uppercaseString] isEqualToString:@"POST"] + || [[_httpMethod uppercaseString] isEqualToString:@"PUT"])) { + if (_multiPartForm) { + return [self generatePostBody]; + } else { + return [self generateNonMultipartPostBody]; + } } else { return nil; } @@ -248,9 +307,15 @@ - (NSData*)httpBody { - (NSString*)contentType { if (_contentType) { return _contentType; + } else if ([_httpMethod isEqualToString:@"POST"] || [_httpMethod isEqualToString:@"PUT"]) { - return [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kStringBoundary]; + if (_multiPartForm) { + return [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kStringBoundary]; + } else { + return [NSString stringWithFormat:@"application/x-www-form-urlencoded", kStringBoundary]; + } + } else { return nil; } @@ -305,7 +370,6 @@ - (BOOL)send { return [[TTURLRequestQueue mainQueue] sendRequest:self]; } - /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)sendSynchronously { return [[TTURLRequestQueue mainQueue] sendSynchronousRequest:self]; @@ -330,7 +394,9 @@ - (NSURLRequest*)createNSURLRequest { /////////////////////////////////////////////////////////////////////////////////////////////////// -// Deprecated +/** + * Deprecated + */ - (void)setURL:(NSString*)urlPath { NSString* aUrlPath = [urlPath copy]; [_urlPath release]; @@ -339,7 +405,9 @@ - (void)setURL:(NSString*)urlPath { /////////////////////////////////////////////////////////////////////////////////////////////////// -// Deprecated +/** + * Deprecated + */ - (NSString*)URL { return _urlPath; } diff --git a/src/Three20Network/Sources/TTURLRequestModel.m b/src/Three20Network/Sources/TTURLRequestModel.m index 37f6994de8..432f266a1b 100644 --- a/src/Three20Network/Sources/TTURLRequestModel.m +++ b/src/Three20Network/Sources/TTURLRequestModel.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -158,5 +158,15 @@ - (void)requestDidCancelLoad:(TTURLRequest*)request { [self didCancelLoad]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (float)downloadProgress { + if ([self isLoading]) { + if (!_loadingRequest.totalContentLength) { + return 0; + } + return (float)_loadingRequest.totalBytesDownloaded / (float)_loadingRequest.totalContentLength; + } + return 0.0f; +} @end diff --git a/src/Three20Network/Sources/TTURLRequestQueue.m b/src/Three20Network/Sources/TTURLRequestQueue.m index dc94e5d17d..06aa705c4e 100644 --- a/src/Three20Network/Sources/TTURLRequestQueue.m +++ b/src/Three20Network/Sources/TTURLRequestQueue.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -50,6 +50,7 @@ @implementation TTURLRequestQueue @synthesize userAgent = _userAgent; @synthesize suspended = _suspended; @synthesize imageCompressionQuality = _imageCompressionQuality; +@synthesize defaultTimeout = _defaultTimeout; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -72,11 +73,13 @@ + (void)setMainQueue:(TTURLRequestQueue*)queue { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self == [super init]) { + self = [super init]; + if (self) { _loaders = [[NSMutableDictionary alloc] init]; _loaderQueue = [[NSMutableArray alloc] init]; _maxContentLength = kDefaultMaxContentLength; _imageCompressionQuality = 0.75; + _defaultTimeout = kTimeout; } return self; } @@ -93,7 +96,9 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// -// TODO (jverkoey May 3, 2010): Clean up this redundant code. +/** + * TODO (jverkoey May 3, 2010): Clean up this redundant code. + */ - (BOOL)dataExistsInBundle:(NSString*)URL { NSString* path = TTPathForBundleResource([URL substringFromIndex:9]); NSFileManager* fm = [NSFileManager defaultManager]; @@ -115,6 +120,7 @@ - (NSData*)loadFromBundle:(NSString*)URL error:(NSError**)error { NSFileManager* fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath:path]) { return [NSData dataWithContentsOfFile:path]; + } else if (error) { *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadNoSuchFileError userInfo:nil]; @@ -129,6 +135,7 @@ - (NSData*)loadFromDocuments:(NSString*)URL error:(NSError**)error { NSFileManager* fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath:path]) { return [NSData dataWithContentsOfFile:path]; + } else if (error) { *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadNoSuchFileError userInfo:nil]; @@ -235,6 +242,7 @@ - (BOOL)loadRequestFromCache:(TTURLRequest*)request { [delegate request:request didFailLoadWithError:error]; } } + } else { request.timestamp = timestamp ? timestamp : [NSDate date]; request.respondedFromCache = YES; @@ -272,9 +280,11 @@ - (void)executeLoader:(TTRequestLoader*)loader { } if (error) { [loader dispatchError:error]; + } else { [loader dispatchLoaded:timestamp]; } + } else { ++_totalLoading; [loader load:[NSURL URLWithString:loader.urlPath]]; @@ -325,6 +335,7 @@ - (void)setSuspended:(BOOL)isSuspended { if (!_suspended) { [self loadNextInQueue]; + } else if (_loaderQueueTimer) { [_loaderQueueTimer invalidate]; _loaderQueueTimer = nil; @@ -334,7 +345,8 @@ - (void)setSuspended:(BOOL)isSuspended { /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)sendRequest:(TTURLRequest*)request { - if ([self loadRequestFromCache:request]) { + BOOL readThroughCache = IS_MASK_SET(request.cachePolicy, TTURLRequestCachePolicyReadThrough); + if ([self loadRequestFromCache:request] && !readThroughCache) { return YES; } @@ -375,6 +387,7 @@ - (BOOL)sendRequest:(TTURLRequest*)request { [_loaders setObject:loader forKey:request.cacheKey]; if (_suspended || _totalLoading == kMaxConcurrentLoads) { [_loaderQueue addObject:loader]; + } else { ++_totalLoading; [loader load:[NSURL URLWithString:request.urlPath]]; @@ -484,10 +497,16 @@ - (NSURLRequest*)createNSURLRequest:(TTURLRequest*)request URL:(NSURL*)URL { if (!URL) { URL = [NSURL URLWithString:request.urlPath]; } - + + NSTimeInterval usedTimeout = request.timeoutInterval; + + if (usedTimeout < 0.0 || request == nil) { + usedTimeout = self.defaultTimeout; + } + NSMutableURLRequest* URLRequest = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData - timeoutInterval:kTimeout]; + timeoutInterval:usedTimeout]; if (self.userAgent) { [URLRequest setValue:self.userAgent forHTTPHeaderField:@"User-Agent"]; @@ -675,6 +694,7 @@ - (void)loaderDidCancel:(TTRequestLoader*)loader wasLoading:(BOOL)wasLoading { if (wasLoading) { [self removeLoader:loader]; [self loadNextInQueue]; + } else { [_loaders removeObjectForKey:loader.cacheKey]; } diff --git a/src/Three20Network/Sources/TTUserInfo.m b/src/Three20Network/Sources/TTUserInfo.m index 205e7f8ba8..19b16282bf 100644 --- a/src/Three20Network/Sources/TTUserInfo.m +++ b/src/Three20Network/Sources/TTUserInfo.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,9 +20,9 @@ #import "Three20Core/TTCorePreprocessorMacros.h" -////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// @implementation TTUserInfo @synthesize topic = _topic; @@ -30,27 +30,28 @@ @implementation TTUserInfo @synthesize weakRef = _weakRef; -////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + (id)topic:(NSString*)topic strongRef:(id)strongRef weakRef:(id)weakRef { return [[[TTUserInfo alloc] initWithTopic:topic strongRef:strongRef weakRef:weakRef] autorelease]; } -////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + (id)topic:(NSString*)topic { return [[[TTUserInfo alloc] initWithTopic:topic strongRef:nil weakRef:nil] autorelease]; } -////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + (id)weakRef:(id)weakRef { return [[[TTUserInfo alloc] initWithTopic:nil strongRef:nil weakRef:weakRef] autorelease]; } -////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTopic:(NSString*)topic strongRef:(id)strongRef weakRef:(id)weakRef { - if (self = [super init]) { + self = [super init]; + if (self) { self.topic = topic; self.strongRef = strongRef; self.weakRef = weakRef; @@ -59,7 +60,7 @@ - (id)initWithTopic:(NSString*)topic strongRef:(id)strongRef weakRef:(id)weakRef } -////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dealloc { TT_RELEASE_SAFELY(_topic); TT_RELEASE_SAFELY(_strongRef); diff --git a/src/Three20Network/Three20Network.xcodeproj/project.pbxproj b/src/Three20Network/Three20Network.xcodeproj/project.pbxproj index e2cc2b9552..2d98207876 100755 --- a/src/Three20Network/Three20Network.xcodeproj/project.pbxproj +++ b/src/Three20Network/Three20Network.xcodeproj/project.pbxproj @@ -3,10 +3,17 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 664B29BF12848AA50008D569 /* TTErrorCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 664B29BC12848AA50008D569 /* TTErrorCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 664B29C312848AAD0008D569 /* TTErrorCodes.m in Sources */ = {isa = PBXBuildFile; fileRef = 664B29C012848AAD0008D569 /* TTErrorCodes.m */; }; + 66F955B0126662E300BEF6F0 /* NetworkURLCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F955AF126662E300BEF6F0 /* NetworkURLCacheTests.m */; }; + 66F955BA1266647A00BEF6F0 /* both.png in Resources */ = {isa = PBXBuildFile; fileRef = 66F955B71266647A00BEF6F0 /* both.png */; }; + 66F955BB1266647A00BEF6F0 /* both@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 66F955B81266647A00BEF6F0 /* both@2x.png */; }; + 66F955BC1266647A00BEF6F0 /* only@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 66F955B91266647A00BEF6F0 /* only@2x.png */; }; + 6DB66E8614B90568003581DF /* NetworkRequestTimeoutTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D64C15814B7C9C100BF5E23 /* NetworkRequestTimeoutTests.m */; }; 6EE735F8118499D300A35176 /* Three20Network.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE735F7118499D300A35176 /* Three20Network.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6EE735FA118499FB00A35176 /* TTGlobalNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE735F9118499FB00A35176 /* TTGlobalNetwork.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6EE735FC11849A0C00A35176 /* TTGlobalNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 6EE735FB11849A0C00A35176 /* TTGlobalNetwork.m */; }; @@ -79,6 +86,13 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 664B29BC12848AA50008D569 /* TTErrorCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTErrorCodes.h; path = Headers/TTErrorCodes.h; sourceTree = ""; }; + 664B29C012848AAD0008D569 /* TTErrorCodes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTErrorCodes.m; path = Sources/TTErrorCodes.m; sourceTree = ""; }; + 66F955AF126662E300BEF6F0 /* NetworkURLCacheTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NetworkURLCacheTests.m; path = UnitTests/NetworkURLCacheTests.m; sourceTree = ""; }; + 66F955B71266647A00BEF6F0 /* both.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = both.png; path = UnitTests/Resources/both.png; sourceTree = ""; }; + 66F955B81266647A00BEF6F0 /* both@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "both@2x.png"; path = "UnitTests/Resources/both@2x.png"; sourceTree = ""; }; + 66F955B91266647A00BEF6F0 /* only@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "only@2x.png"; path = "UnitTests/Resources/only@2x.png"; sourceTree = ""; }; + 6D64C15814B7C9C100BF5E23 /* NetworkRequestTimeoutTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NetworkRequestTimeoutTests.m; path = UnitTests/NetworkRequestTimeoutTests.m; sourceTree = ""; }; 6E64541F1184BDF900F08CB1 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Project.xcconfig; path = Configurations/Project.xcconfig; sourceTree = ""; }; 6EE735F7118499D300A35176 /* Three20Network.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Three20Network.h; path = Headers/Three20Network.h; sourceTree = ""; }; 6EE735F9118499FB00A35176 /* TTGlobalNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTGlobalNetwork.h; path = Headers/TTGlobalNetwork.h; sourceTree = ""; }; @@ -115,7 +129,7 @@ 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; 6EF96404118EFCF0003902E7 /* TTURLRequestQueueInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTURLRequestQueueInternal.h; path = Headers/TTURLRequestQueueInternal.h; sourceTree = ""; }; BEF31F3A0F352DF5000DE5D2 /* libThree20Network.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libThree20Network.a; sourceTree = BUILT_PRODUCTS_DIR; }; - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB9E6C6210B6A8F800DE563C /* NetworkUnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NetworkUnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -142,7 +156,7 @@ isa = PBXGroup; children = ( BEF31F3A0F352DF5000DE5D2 /* libThree20Network.a */, - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */, + EB9E6C6210B6A8F800DE563C /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -167,6 +181,8 @@ 6EE7364611849AF200A35176 /* Resources */, 6E08B27D118282F700DA1579 /* Mocks */, 6EE7363B11849AA100A35176 /* NetworkModelTests.m */, + 6D64C15814B7C9C100BF5E23 /* NetworkRequestTimeoutTests.m */, + 66F955AF126662E300BEF6F0 /* NetworkURLCacheTests.m */, ); name = Tests; sourceTree = ""; @@ -194,6 +210,8 @@ 6E08B86E1183B38400DA1579 /* Global */, 6EE7360111849A1F00A35176 /* TTUserInfo.h */, 6EE735FE11849A1600A35176 /* TTUserInfo.m */, + 664B29BC12848AA50008D569 /* TTErrorCodes.h */, + 664B29C012848AAD0008D569 /* TTErrorCodes.m */, 6E08B8091183B28A00DA1579 /* Model */, 6E08B8101183B28A00DA1579 /* Response */, 6E08B8191183B28A00DA1579 /* Request */, @@ -295,6 +313,9 @@ 6EE7364611849AF200A35176 /* Resources */ = { isa = PBXGroup; children = ( + 66F955B71266647A00BEF6F0 /* both.png */, + 66F955B81266647A00BEF6F0 /* both@2x.png */, + 66F955B91266647A00BEF6F0 /* only@2x.png */, 6EE7363D11849AD500A35176 /* UnitTests-Info.plist */, ); name = Resources; @@ -351,6 +372,7 @@ 6EE7361F11849A3500A35176 /* TTURLResponse.h in Headers */, 6EE7364911849B1D00A35176 /* Three20Network_Prefix.pch in Headers */, 6EF96405118EFCF0003902E7 /* TTURLRequestQueueInternal.h in Headers */, + 664B29BF12848AA50008D569 /* TTErrorCodes.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -376,9 +398,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libThree20Network.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTests */ = { + EB9E6C6110B6A8F800DE563C /* Three20NetworkUnitTests */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20NetworkUnitTests" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -391,9 +413,9 @@ 6EE736C511849F9D00A35176 /* PBXTargetDependency */, 6EE736C711849FA000A35176 /* PBXTargetDependency */, ); - name = UnitTests; + name = Three20NetworkUnitTests; productName = CoreUnitTests; - productReference = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + productReference = EB9E6C6210B6A8F800DE563C /* NetworkUnitTests.octest */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -401,9 +423,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Three20Network" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -415,7 +448,7 @@ projectRoot = ""; targets = ( BEF31F390F352DF5000DE5D2 /* Three20Network */, - EB9E6C6110B6A8F800DE563C /* UnitTests */, + EB9E6C6110B6A8F800DE563C /* Three20NetworkUnitTests */, ); }; /* End PBXProject section */ @@ -442,6 +475,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 66F955BA1266647A00BEF6F0 /* both.png in Resources */, + 66F955BB1266647A00BEF6F0 /* both@2x.png in Resources */, + 66F955BC1266647A00BEF6F0 /* only@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -492,6 +528,7 @@ 6EE7362D11849A4000A35176 /* TTURLRequest.m in Sources */, 6EE7362E11849A4000A35176 /* TTURLRequestModel.m in Sources */, 6EE7362F11849A4000A35176 /* TTURLRequestQueue.m in Sources */, + 664B29C312848AAD0008D569 /* TTErrorCodes.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -501,6 +538,8 @@ files = ( 6EE7363A11849A9800A35176 /* MockModelDelegate.m in Sources */, 6EE7363C11849AA100A35176 /* NetworkModelTests.m in Sources */, + 66F955B0126662E300BEF6F0 /* NetworkURLCacheTests.m in Sources */, + 6DB66E8614B90568003581DF /* NetworkRequestTimeoutTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -529,14 +568,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64541F1184BDF900F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; @@ -547,10 +583,9 @@ COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; @@ -558,21 +593,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; - SDKROOT = iphonesimulator4.0; - WRAPPER_EXTENSION = octest; + SDKROOT = iphoneos; }; name = Internal; }; @@ -584,7 +611,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -594,8 +621,7 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -604,14 +630,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64541F1184BDF900F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -619,13 +642,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64541F1184BDF900F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -633,20 +654,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; - WRAPPER_EXTENSION = octest; + SDKROOT = iphoneos; }; name = Debug; }; @@ -654,19 +668,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - HEADER_SEARCH_PATHS = .; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; - WRAPPER_EXTENSION = octest; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -694,7 +700,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20NetworkUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/Three20Network/UnitTests/NetworkModelTests.m b/src/Three20Network/UnitTests/NetworkModelTests.m index 99b288ff5c..503c81af9f 100644 --- a/src/Three20Network/UnitTests/NetworkModelTests.m +++ b/src/Three20Network/UnitTests/NetworkModelTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,10 +14,8 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. - -// See Also: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html +// See: http://bit.ly/hS5nNh for unit test macros. +// See Also: http://bit.ly/hgpqd2 #import diff --git a/src/Three20Network/UnitTests/NetworkRequestTimeoutTests.m b/src/Three20Network/UnitTests/NetworkRequestTimeoutTests.m new file mode 100644 index 0000000000..b2bab8f716 --- /dev/null +++ b/src/Three20Network/UnitTests/NetworkRequestTimeoutTests.m @@ -0,0 +1,140 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 +// for unit test macros. + +// See Also: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html + +#import + +// Network +#import "Three20Network/TTURLRequest.h" +#import "Three20Network/TTURLRequestQueue.h" + +// Core +#import "Three20Core/TTGlobalCorePaths.h" + +// duplicate constant for testing declared in Three20Network/TTURLRequestQueue.h +static const NSTimeInterval kTimeout = 300.0; + +/** + * Unit tests for configurable request timeouts. + * + */ + +@interface NetworkRequestTimeout : SenTestCase { +} + +@end + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation NetworkRequestTimeout + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark TTURLRequest + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testTTURLRequest_timeoutIntervalAccess { + STAssertEqualsWithAccuracy([[[[TTURLRequest alloc] init] autorelease] timeoutInterval], + (NSTimeInterval)TTURLRequestUseQueueTimeout, + 0.1, + @"default timeout should be set on initialization"); + + TTURLRequest * request = [[TTURLRequest alloc] init]; + request.timeoutInterval = 20.0; + STAssertEqualsWithAccuracy(request.timeoutInterval,(NSTimeInterval)20.0,0.1, + @"should return the previously set timeout"); + + TT_RELEASE_SAFELY(request); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testTTURLRequestQueue_timeoutIntervalAccess { + STAssertEqualsWithAccuracy([[[[TTURLRequestQueue alloc] init] autorelease] defaultTimeout], + (NSTimeInterval)kTimeout, + 0.1, + @"default timeout should be set on initialization"); + + TTURLRequestQueue * queue = [[TTURLRequestQueue alloc] init]; + queue.defaultTimeout = 20.0; + STAssertEqualsWithAccuracy(queue.defaultTimeout,(NSTimeInterval)20.0,0.1, + @"should return the previously set timeout"); + + TT_RELEASE_SAFELY(queue); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testTTURLRequestQueue_timeoutIntervalUsage { + + TTURLRequestQueue* queue = [[TTURLRequestQueue alloc] init]; + + TTURLRequest* request = [[TTURLRequest alloc] init]; + request.urlPath = @"http://www.three20.info"; + + NSURL* url = [NSURL URLWithString:request.urlPath]; + + NSURLRequest* urlRequest = nil; + + urlRequest = [queue createNSURLRequest:request URL:url]; + + STAssertNotNil(urlRequest,@"request queue didn't return an NSURLRequest"); + STAssertEqualsWithAccuracy([urlRequest timeoutInterval],kTimeout,0.1,@"wrong timeoutInterval set"); + + queue.defaultTimeout = 48.5; + + urlRequest = [queue createNSURLRequest:request URL:url]; + + STAssertNotNil(urlRequest,@"request queue didn't return an NSURLRequest"); + STAssertEqualsWithAccuracy([urlRequest timeoutInterval],48.5,0.1,@"wrong timeoutInterval set"); + + request.timeoutInterval = 5.3; + + urlRequest = [queue createNSURLRequest:request URL:url]; + + STAssertNotNil(urlRequest,@"request queue didn't return an NSURLRequest"); + STAssertEqualsWithAccuracy([urlRequest timeoutInterval],5.3,0.1,@"wrong timeoutInterval set"); + + request.timeoutInterval = -17; + + urlRequest = [queue createNSURLRequest:request URL:url]; + + STAssertNotNil(urlRequest,@"request queue didn't return an NSURLRequest"); + STAssertEqualsWithAccuracy([urlRequest timeoutInterval],48.5,0.1,@"wrong timeoutInterval set"); +} + +- (void)testTTURLRequestQueue_useDefaultTimeoutForNilRequest_gh680 { + TTURLRequestQueue* queue = [[TTURLRequestQueue alloc] init]; + + NSURL* url = [NSURL URLWithString:@"http://three20.info"]; + + NSURLRequest* urlRequest = nil; + + urlRequest = [queue createNSURLRequest:nil URL:url]; + + STAssertNotNil(urlRequest,@"request queue didn't return an NSURLRequest"); + STAssertEqualsWithAccuracy([urlRequest timeoutInterval],kTimeout,0.1,@"wrong timeoutInterval set"); +} + +@end diff --git a/src/Three20Network/UnitTests/NetworkURLCacheTests.m b/src/Three20Network/UnitTests/NetworkURLCacheTests.m new file mode 100644 index 0000000000..428b57783e --- /dev/null +++ b/src/Three20Network/UnitTests/NetworkURLCacheTests.m @@ -0,0 +1,110 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// See: http://bit.ly/hS5nNh for unit test macros. +// See Also: http://bit.ly/hgpqd2 + +#import + +// Network +#import "Three20Network/TTURLCache.h" + +// Core +#import "Three20Core/TTGlobalCorePaths.h" + +@interface TTURLCache() + +/** + * Reveal these private methods for testing. + */ ++ (NSString*)doubleImageURLPath:(NSString*)urlPath; + +@end + +/** + * Unit tests for the TTURLCache object. + * + * These tests are a part of the comprehensive test suite for the Network + * functionality of the library. + */ + +@interface NetworkURLCacheTests : SenTestCase { +} + +@end + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation NetworkURLCacheTests + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark TTURLCache + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testTTURLCache_doubleImageURLPath { + STAssertNil([TTURLCache doubleImageURLPath:nil], + @"nil should be nil."); + + STAssertTrue([[TTURLCache doubleImageURLPath:@"."] + isEqualToString:@"."], + @". should resolve to ."); + + STAssertTrue([[TTURLCache doubleImageURLPath:@".gif"] + isEqualToString:@".gif"], + @".gif should resolve to .gif"); + + STAssertTrue([[TTURLCache doubleImageURLPath:@"bundle://both.png"] + isEqualToString:@"bundle://both@2x.png"], + @"both.png should resolve to both@2x.png."); + + STAssertTrue([[TTURLCache doubleImageURLPath:@"bundle://both"] + isEqualToString:@"bundle://both@2x"], + @"both should resolve to both@2x."); + + STAssertTrue([[TTURLCache doubleImageURLPath:@"bundle://images/both"] + isEqualToString:@"bundle://images/both@2x"], + @"images/both should resolve to images/both@2x."); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testTTURLCache_hasImageForURL { + NSBundle* testBundle = [NSBundle bundleWithIdentifier:@"com.facebook.three20.UnitTests"]; + STAssertTrue(nil != testBundle, @"Unable to find the bundle %@", [NSBundle allBundles]); + + TTSetDefaultBundle(testBundle); + + STAssertTrue([[TTURLCache sharedCache] hasImageForURL:@"bundle://both.png" fromDisk:YES], + @"both.png should exist."); + + STAssertTrue([[TTURLCache sharedCache] hasImageForURL:@"bundle://only.png" fromDisk:YES], + @"only@2x.png should exist."); + + STAssertNotNil([[TTURLCache sharedCache] imageForURL:@"bundle://both.png" fromDisk:YES], + @"both@2x.png should exist."); + + // Release the default bundle now that we're done with it. + TTSetDefaultBundle(nil); +} + + +@end diff --git a/src/Three20Network/UnitTests/Resources/both.png b/src/Three20Network/UnitTests/Resources/both.png new file mode 100644 index 0000000000..6ca8e06cb6 Binary files /dev/null and b/src/Three20Network/UnitTests/Resources/both.png differ diff --git a/src/Three20Network/UnitTests/Resources/both@2x.png b/src/Three20Network/UnitTests/Resources/both@2x.png new file mode 100644 index 0000000000..a52c5f7b34 Binary files /dev/null and b/src/Three20Network/UnitTests/Resources/both@2x.png differ diff --git a/src/Three20Network/UnitTests/Resources/only@2x.png b/src/Three20Network/UnitTests/Resources/only@2x.png new file mode 100644 index 0000000000..a52c5f7b34 Binary files /dev/null and b/src/Three20Network/UnitTests/Resources/only@2x.png differ diff --git a/src/Three20Network/UnitTests/mocks/MockModelDelegate.h b/src/Three20Network/UnitTests/mocks/MockModelDelegate.h index f02b82f90b..30f1963aaa 100644 --- a/src/Three20Network/UnitTests/mocks/MockModelDelegate.h +++ b/src/Three20Network/UnitTests/mocks/MockModelDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Network/UnitTests/mocks/MockModelDelegate.m b/src/Three20Network/UnitTests/mocks/MockModelDelegate.m index 6d27d0834a..32638471cd 100644 --- a/src/Three20Network/UnitTests/mocks/MockModelDelegate.m +++ b/src/Three20Network/UnitTests/mocks/MockModelDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Configurations/Library.xcconfig b/src/Three20Style/Configurations/Library.xcconfig index e11851aca0..82423aae45 100644 --- a/src/Three20Style/Configurations/Library.xcconfig +++ b/src/Three20Style/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,5 +17,6 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = Three20Style +BASE_PRODUCT_NAME = Three20Style +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/src/Three20Style/Configurations/Project.xcconfig b/src/Three20Style/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/Three20Style/Configurations/Project.xcconfig +++ b/src/Three20Style/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Configurations/UnitTests.xcconfig b/src/Three20Style/Configurations/UnitTests.xcconfig index 35296c9191..09befc6b7b 100644 --- a/src/Three20Style/Configurations/UnitTests.xcconfig +++ b/src/Three20Style/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = StyleUnitTests -BUILD_BUNDLE_VERSION = 1.0 +BASE_PRODUCT_NAME = StyleUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME) +BUILD_BUNDLE_VERSION = 1.0 OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) $(COREGRAPHICS_FX) diff --git a/src/Three20Style/Headers/TTBevelBorderStyle.h b/src/Three20Style/Headers/TTBevelBorderStyle.h index 434abdf7af..cac84b4b53 100644 --- a/src/Three20Style/Headers/TTBevelBorderStyle.h +++ b/src/Three20Style/Headers/TTBevelBorderStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,7 +31,10 @@ + (TTBevelBorderStyle*)styleWithColor:(UIColor*)color width:(CGFloat)width next:(TTStyle*)next; -+ (TTBevelBorderStyle*)styleWithHighlight:(UIColor*)highlight shadow:(UIColor*)shadow - width:(CGFloat)width lightSource:(NSInteger)lightSource next:(TTStyle*)next; ++ (TTBevelBorderStyle*)styleWithHighlight:(UIColor*)highlight + shadow:(UIColor*)shadow + width:(CGFloat)width + lightSource:(NSInteger)lightSource + next:(TTStyle*)next; @end diff --git a/src/Three20Style/Headers/TTBlendStyle.h b/src/Three20Style/Headers/TTBlendStyle.h index 27913549df..b6f1eb4ca3 100644 --- a/src/Three20Style/Headers/TTBlendStyle.h +++ b/src/Three20Style/Headers/TTBlendStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTBoxStyle.h b/src/Three20Style/Headers/TTBoxStyle.h index 194042c156..ed6fa5806a 100644 --- a/src/Three20Style/Headers/TTBoxStyle.h +++ b/src/Three20Style/Headers/TTBoxStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTContentStyle.h b/src/Three20Style/Headers/TTContentStyle.h index a4823cb107..7ba6969a16 100644 --- a/src/Three20Style/Headers/TTContentStyle.h +++ b/src/Three20Style/Headers/TTContentStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTDefaultStyleSheet+DragRefreshHeader.h b/src/Three20Style/Headers/TTDefaultStyleSheet+DragRefreshHeader.h index d6ab3fe52c..e89f64877b 100644 --- a/src/Three20Style/Headers/TTDefaultStyleSheet+DragRefreshHeader.h +++ b/src/Three20Style/Headers/TTDefaultStyleSheet+DragRefreshHeader.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTDefaultStyleSheet.h b/src/Three20Style/Headers/TTDefaultStyleSheet.h index 55d8073fef..0d12c4f810 100644 --- a/src/Three20Style/Headers/TTDefaultStyleSheet.h +++ b/src/Three20Style/Headers/TTDefaultStyleSheet.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ // Common styles @property (nonatomic, readonly) UIColor* textColor; @property (nonatomic, readonly) UIColor* highlightedTextColor; +@property (nonatomic, readonly) UIColor* backgroundTextColor; @property (nonatomic, readonly) UIFont* font; @property (nonatomic, readonly) UIColor* backgroundColor; @property (nonatomic, readonly) UIColor* navigationBarTintColor; @@ -32,7 +33,11 @@ // Tables @property (nonatomic, readonly) UIColor* tablePlainBackgroundColor; +@property (nonatomic, readonly) UIColor* tablePlainCellSeparatorColor; +@property (nonatomic, readonly) UITableViewCellSeparatorStyle tablePlainCellSeparatorStyle; @property (nonatomic, readonly) UIColor* tableGroupedBackgroundColor; +@property (nonatomic, readonly) UIColor* tableGroupedCellSeparatorColor; +@property (nonatomic, readonly) UITableViewCellSeparatorStyle tableGroupedCellSeparatorStyle; @property (nonatomic, readonly) UIColor* searchTableBackgroundColor; @property (nonatomic, readonly) UIColor* searchTableSeparatorColor; @@ -41,6 +46,7 @@ @property (nonatomic, readonly) UIColor* tableHeaderShadowColor; @property (nonatomic, readonly) CGSize tableHeaderShadowOffset; @property (nonatomic, readonly) UIColor* tableHeaderTintColor; +@property (nonatomic, readonly) TTStyle* tableHeaderGrouped; // Photo Captions @property (nonatomic, readonly) UIColor* photoCaptionTextColor; @@ -77,6 +83,7 @@ @property (nonatomic, readonly) UIFont* tableSummaryFont; @property (nonatomic, readonly) UIFont* tableHeaderPlainFont; @property (nonatomic, readonly) UIFont* tableHeaderGroupedFont; +@property (nonatomic, readonly) CGFloat tableBannerViewHeight; @property (nonatomic, readonly) UIFont* photoCaptionFont; @property (nonatomic, readonly) UIFont* messageFont; @property (nonatomic, readonly) UIFont* errorTitleFont; diff --git a/src/Three20Style/Headers/TTFlowLayout.h b/src/Three20Style/Headers/TTFlowLayout.h index eb06dec239..bc088aa3d5 100644 --- a/src/Three20Style/Headers/TTFlowLayout.h +++ b/src/Three20Style/Headers/TTFlowLayout.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTFourBorderStyle.h b/src/Three20Style/Headers/TTFourBorderStyle.h index 9ff4abc2e7..930f9705ef 100644 --- a/src/Three20Style/Headers/TTFourBorderStyle.h +++ b/src/Three20Style/Headers/TTFourBorderStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTGlobalStyle.h b/src/Three20Style/Headers/TTGlobalStyle.h index acf7d6bdf6..1d1f765dc0 100644 --- a/src/Three20Style/Headers/TTGlobalStyle.h +++ b/src/Three20Style/Headers/TTGlobalStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,14 +31,14 @@ extern const CGFloat ttkRounded; /////////////////////////////////////////////////////////////////////////////////////////////////// // Color helpers -#define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1] -#define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 \ +#define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1] +#define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f \ alpha:(a)] #define HSVCOLOR(h,s,v) [UIColor colorWithHue:(h) saturation:(s) value:(v) alpha:1] #define HSVACOLOR(h,s,v,a) [UIColor colorWithHue:(h) saturation:(s) value:(v) alpha:(a)] -#define RGBA(r,g,b,a) (r)/255.0, (g)/255.0, (b)/255.0, (a) +#define RGBA(r,g,b,a) (r)/255.0f, (g)/255.0f, (b)/255.0f, (a) /////////////////////////////////////////////////////////////////////////////////////////////////// // Style helpers diff --git a/src/Three20Style/Headers/TTGridLayout.h b/src/Three20Style/Headers/TTGridLayout.h index cf094e045a..7dbfdce911 100644 --- a/src/Three20Style/Headers/TTGridLayout.h +++ b/src/Three20Style/Headers/TTGridLayout.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTHighlightBorderStyle.h b/src/Three20Style/Headers/TTHighlightBorderStyle.h index 7916a6aaef..b6958d9a6e 100644 --- a/src/Three20Style/Headers/TTHighlightBorderStyle.h +++ b/src/Three20Style/Headers/TTHighlightBorderStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTImageStyle.h b/src/Three20Style/Headers/TTImageStyle.h index 88219f8367..67ff2c7b09 100644 --- a/src/Three20Style/Headers/TTImageStyle.h +++ b/src/Three20Style/Headers/TTImageStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTInnerShadowStyle.h b/src/Three20Style/Headers/TTInnerShadowStyle.h index 140fab6eab..e26bc0e0fc 100644 --- a/src/Three20Style/Headers/TTInnerShadowStyle.h +++ b/src/Three20Style/Headers/TTInnerShadowStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTInsetStyle.h b/src/Three20Style/Headers/TTInsetStyle.h index 902ef095d9..ce1ff15e7f 100644 --- a/src/Three20Style/Headers/TTInsetStyle.h +++ b/src/Three20Style/Headers/TTInsetStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTLayout.h b/src/Three20Style/Headers/TTLayout.h index b3ccce2ab8..8d6544951c 100644 --- a/src/Three20Style/Headers/TTLayout.h +++ b/src/Three20Style/Headers/TTLayout.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTLinearGradientBorderStyle.h b/src/Three20Style/Headers/TTLinearGradientBorderStyle.h index 2565cb875f..7f9c3e90ac 100644 --- a/src/Three20Style/Headers/TTLinearGradientBorderStyle.h +++ b/src/Three20Style/Headers/TTLinearGradientBorderStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTLinearGradientFillStyle.h b/src/Three20Style/Headers/TTLinearGradientFillStyle.h index 6780e74a4e..2e9c0de702 100644 --- a/src/Three20Style/Headers/TTLinearGradientFillStyle.h +++ b/src/Three20Style/Headers/TTLinearGradientFillStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTMaskStyle.h b/src/Three20Style/Headers/TTMaskStyle.h index 3ba3e323d3..c631860045 100644 --- a/src/Three20Style/Headers/TTMaskStyle.h +++ b/src/Three20Style/Headers/TTMaskStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTPartStyle.h b/src/Three20Style/Headers/TTPartStyle.h index 973adcb3b6..ac212b7ee5 100644 --- a/src/Three20Style/Headers/TTPartStyle.h +++ b/src/Three20Style/Headers/TTPartStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTPosition.h b/src/Three20Style/Headers/TTPosition.h index 0856bb2e0b..36ddb7a316 100644 --- a/src/Three20Style/Headers/TTPosition.h +++ b/src/Three20Style/Headers/TTPosition.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTRectangleShape.h b/src/Three20Style/Headers/TTRectangleShape.h index ea9cdf9f14..378f21c455 100644 --- a/src/Three20Style/Headers/TTRectangleShape.h +++ b/src/Three20Style/Headers/TTRectangleShape.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTReflectiveFillStyle.h b/src/Three20Style/Headers/TTReflectiveFillStyle.h index 3fc9e33d09..bf3b19f4a6 100644 --- a/src/Three20Style/Headers/TTReflectiveFillStyle.h +++ b/src/Three20Style/Headers/TTReflectiveFillStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTRoundedLeftArrowShape.h b/src/Three20Style/Headers/TTRoundedLeftArrowShape.h index 2e7c928984..d47fb11124 100644 --- a/src/Three20Style/Headers/TTRoundedLeftArrowShape.h +++ b/src/Three20Style/Headers/TTRoundedLeftArrowShape.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTRoundedRectangleShape.h b/src/Three20Style/Headers/TTRoundedRectangleShape.h index e020d74a52..8cc20dbe56 100644 --- a/src/Three20Style/Headers/TTRoundedRectangleShape.h +++ b/src/Three20Style/Headers/TTRoundedRectangleShape.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTRoundedRightArrowShape.h b/src/Three20Style/Headers/TTRoundedRightArrowShape.h index ca4397c704..eafcabebad 100644 --- a/src/Three20Style/Headers/TTRoundedRightArrowShape.h +++ b/src/Three20Style/Headers/TTRoundedRightArrowShape.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTShadowStyle.h b/src/Three20Style/Headers/TTShadowStyle.h index 8634704111..c505410b66 100644 --- a/src/Three20Style/Headers/TTShadowStyle.h +++ b/src/Three20Style/Headers/TTShadowStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTShape.h b/src/Three20Style/Headers/TTShape.h index 6585962966..b65dc7ab46 100644 --- a/src/Three20Style/Headers/TTShape.h +++ b/src/Three20Style/Headers/TTShape.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTShapeInternal.h b/src/Three20Style/Headers/TTShapeInternal.h index a5e2d4bfbf..5a80b638d8 100644 --- a/src/Three20Style/Headers/TTShapeInternal.h +++ b/src/Three20Style/Headers/TTShapeInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTShapeStyle.h b/src/Three20Style/Headers/TTShapeStyle.h index 14dbcabf2c..844a16ace8 100644 --- a/src/Three20Style/Headers/TTShapeStyle.h +++ b/src/Three20Style/Headers/TTShapeStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTSolidBorderStyle.h b/src/Three20Style/Headers/TTSolidBorderStyle.h index 1cd7617f9b..5004224d0e 100644 --- a/src/Three20Style/Headers/TTSolidBorderStyle.h +++ b/src/Three20Style/Headers/TTSolidBorderStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTSolidFillStyle.h b/src/Three20Style/Headers/TTSolidFillStyle.h index f942b4706d..248dac4d44 100644 --- a/src/Three20Style/Headers/TTSolidFillStyle.h +++ b/src/Three20Style/Headers/TTSolidFillStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTSpeechBubbleShape.h b/src/Three20Style/Headers/TTSpeechBubbleShape.h index 71b5995321..96a5f53b5a 100644 --- a/src/Three20Style/Headers/TTSpeechBubbleShape.h +++ b/src/Three20Style/Headers/TTSpeechBubbleShape.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,10 @@ // Style #import "Three20Style/TTShape.h" +/** + * The shape that defines a rectangular shape with a pointer. + * + */ @interface TTSpeechBubbleShape : TTShape { CGFloat _radius; CGFloat _pointLocation; @@ -29,7 +33,25 @@ @property (nonatomic) CGFloat pointAngle; @property (nonatomic) CGSize pointSize; -+ (TTSpeechBubbleShape*)shapeWithRadius:(CGFloat)radius pointLocation:(CGFloat)pointLocation - pointAngle:(CGFloat)pointAngle pointSize:(CGSize)pointSize; +/** + * The shape that defines a rectangular shape with a pointer. + * Radius - number of pixels for the rounded corners + * pointLocation - location of the point where the top edge starts at 45, the right edge at 135, + * the bottom edge at 225 and the left edge at 315. + * pointAngle - not fgunctional yet. Make this equal to pointLocation in order to point it in the + * right direction. + * pointSize - the square in which the pointer will be defined, should be narrower or less high than + * the shape minus the radiuses. + * + * Pointers are not placed on the rounded corners. + * + * pointSize should be less wide or high than the edge that it is placed on minus 2 * radius. + * radius should be smaller than the length of the edge / 2. + * + */ ++ (TTSpeechBubbleShape*)shapeWithRadius:(CGFloat)radius + pointLocation:(CGFloat)pointLocation + pointAngle:(CGFloat)pointAngle + pointSize:(CGSize)pointSize; @end diff --git a/src/Three20Style/Headers/TTStyle.h b/src/Three20Style/Headers/TTStyle.h index 9b79b6e6f7..ab216e2061 100644 --- a/src/Three20Style/Headers/TTStyle.h +++ b/src/Three20Style/Headers/TTStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyleContext.h b/src/Three20Style/Headers/TTStyleContext.h index b086f18519..60a9deca72 100644 --- a/src/Three20Style/Headers/TTStyleContext.h +++ b/src/Three20Style/Headers/TTStyleContext.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyleDelegate.h b/src/Three20Style/Headers/TTStyleDelegate.h index 7f6f2a9ac5..4492998e25 100644 --- a/src/Three20Style/Headers/TTStyleDelegate.h +++ b/src/Three20Style/Headers/TTStyleDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyleInternal.h b/src/Three20Style/Headers/TTStyleInternal.h index 3c7fa14477..81aa6bcaa7 100644 --- a/src/Three20Style/Headers/TTStyleInternal.h +++ b/src/Three20Style/Headers/TTStyleInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyleSheet.h b/src/Three20Style/Headers/TTStyleSheet.h index 7f699e300b..bd3e8c33ab 100644 --- a/src/Three20Style/Headers/TTStyleSheet.h +++ b/src/Three20Style/Headers/TTStyleSheet.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledBlock.h b/src/Three20Style/Headers/TTStyledBlock.h index f447e5a22b..fd11b39985 100644 --- a/src/Three20Style/Headers/TTStyledBlock.h +++ b/src/Three20Style/Headers/TTStyledBlock.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledBoldNode.h b/src/Three20Style/Headers/TTStyledBoldNode.h index 37e6774667..cf666dd765 100644 --- a/src/Three20Style/Headers/TTStyledBoldNode.h +++ b/src/Three20Style/Headers/TTStyledBoldNode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledBoxFrame.h b/src/Three20Style/Headers/TTStyledBoxFrame.h index 3fe106fa2a..dbc3f15f14 100644 --- a/src/Three20Style/Headers/TTStyledBoxFrame.h +++ b/src/Three20Style/Headers/TTStyledBoxFrame.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledButtonNode.h b/src/Three20Style/Headers/TTStyledButtonNode.h index 61f387b632..3dc6210626 100644 --- a/src/Three20Style/Headers/TTStyledButtonNode.h +++ b/src/Three20Style/Headers/TTStyledButtonNode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,8 +22,8 @@ BOOL _highlighted; } -@property (nonatomic) BOOL highlighted; -@property (nonatomic, retain) NSString* URL; +@property (nonatomic) BOOL highlighted; +@property (nonatomic, copy) NSString* URL; - (id)initWithURL:(NSString*)URL; - (id)initWithURL:(NSString*)URL next:(TTStyledNode*)nextSibling; diff --git a/src/Three20Style/Headers/TTStyledElement.h b/src/Three20Style/Headers/TTStyledElement.h index a4003984ab..ebbff31ad3 100644 --- a/src/Three20Style/Headers/TTStyledElement.h +++ b/src/Three20Style/Headers/TTStyledElement.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ @property (nonatomic, readonly) TTStyledNode* firstChild; @property (nonatomic, readonly) TTStyledNode* lastChild; -@property (nonatomic, retain) NSString* className; +@property (nonatomic, copy) NSString* className; - (id)initWithText:(NSString*)text; diff --git a/src/Three20Style/Headers/TTStyledFrame.h b/src/Three20Style/Headers/TTStyledFrame.h index de88a6bae1..e94edc39c7 100644 --- a/src/Three20Style/Headers/TTStyledFrame.h +++ b/src/Three20Style/Headers/TTStyledFrame.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledImageFrame.h b/src/Three20Style/Headers/TTStyledImageFrame.h index dd35076754..150d1a4591 100644 --- a/src/Three20Style/Headers/TTStyledImageFrame.h +++ b/src/Three20Style/Headers/TTStyledImageFrame.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledImageNode.h b/src/Three20Style/Headers/TTStyledImageNode.h index 0e1929200e..cce101e174 100644 --- a/src/Three20Style/Headers/TTStyledImageNode.h +++ b/src/Three20Style/Headers/TTStyledImageNode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ CGFloat _height; } -@property (nonatomic, retain) NSString* URL; +@property (nonatomic, copy) NSString* URL; @property (nonatomic, retain) UIImage* image; @property (nonatomic, retain) UIImage* defaultImage; @property (nonatomic) CGFloat width; diff --git a/src/Three20Style/Headers/TTStyledInline.h b/src/Three20Style/Headers/TTStyledInline.h index 8752a62b59..12638a6c82 100644 --- a/src/Three20Style/Headers/TTStyledInline.h +++ b/src/Three20Style/Headers/TTStyledInline.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledInlineBlock.h b/src/Three20Style/Headers/TTStyledInlineBlock.h index dd6a419b5c..ff98fc1984 100644 --- a/src/Three20Style/Headers/TTStyledInlineBlock.h +++ b/src/Three20Style/Headers/TTStyledInlineBlock.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledInlineFrame.h b/src/Three20Style/Headers/TTStyledInlineFrame.h index a304f9da9a..a0de0baf6c 100644 --- a/src/Three20Style/Headers/TTStyledInlineFrame.h +++ b/src/Three20Style/Headers/TTStyledInlineFrame.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledItalicNode.h b/src/Three20Style/Headers/TTStyledItalicNode.h index 07f03d326e..b853333469 100644 --- a/src/Three20Style/Headers/TTStyledItalicNode.h +++ b/src/Three20Style/Headers/TTStyledItalicNode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledLayout.h b/src/Three20Style/Headers/TTStyledLayout.h index 120f5c4f7b..e92c67e9fb 100644 --- a/src/Three20Style/Headers/TTStyledLayout.h +++ b/src/Three20Style/Headers/TTStyledLayout.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -45,6 +45,8 @@ UIFont* _boldFont; UIFont* _italicFont; + UITextAlignment _textAlignment; + TTStyle* _linkStyle; TTStyledNode* _rootNode; TTStyledNode* _lastNode; @@ -55,6 +57,7 @@ @property (nonatomic) CGFloat width; @property (nonatomic) CGFloat height; @property (nonatomic, retain) UIFont* font; +@property (nonatomic) UITextAlignment textAlignment; @property (nonatomic, readonly) TTStyledFrame* rootFrame; @property (nonatomic, retain) NSMutableArray* invalidImages; diff --git a/src/Three20Style/Headers/TTStyledLineBreakNode.h b/src/Three20Style/Headers/TTStyledLineBreakNode.h index 1a5c7108b6..3f8ab7da7b 100644 --- a/src/Three20Style/Headers/TTStyledLineBreakNode.h +++ b/src/Three20Style/Headers/TTStyledLineBreakNode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledLinkNode.h b/src/Three20Style/Headers/TTStyledLinkNode.h index 7d4d1ce8f7..63842cbedc 100644 --- a/src/Three20Style/Headers/TTStyledLinkNode.h +++ b/src/Three20Style/Headers/TTStyledLinkNode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,8 +22,8 @@ BOOL _highlighted; } -@property (nonatomic) BOOL highlighted; -@property (nonatomic, retain) NSString* URL; +@property (nonatomic) BOOL highlighted; +@property (nonatomic, copy) NSString* URL; - (id)initWithURL:(NSString*)URL; - (id)initWithURL:(NSString*)URL next:(TTStyledNode*)nextSibling; diff --git a/src/Three20Style/Headers/TTStyledNode.h b/src/Three20Style/Headers/TTStyledNode.h index 37606b1aa7..ecc8cab3ba 100644 --- a/src/Three20Style/Headers/TTStyledNode.h +++ b/src/Three20Style/Headers/TTStyledNode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledNodeInternal.h b/src/Three20Style/Headers/TTStyledNodeInternal.h index 2e3fe0c56e..fcabe174bc 100644 --- a/src/Three20Style/Headers/TTStyledNodeInternal.h +++ b/src/Three20Style/Headers/TTStyledNodeInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledText.h b/src/Three20Style/Headers/TTStyledText.h index 0cd6d9ed3c..09c7f8309f 100644 --- a/src/Three20Style/Headers/TTStyledText.h +++ b/src/Three20Style/Headers/TTStyledText.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ TTStyledNode* _rootNode; TTStyledFrame* _rootFrame; UIFont* _font; + UITextAlignment _textAlignment; CGFloat _width; CGFloat _height; NSMutableArray* _invalidImages; @@ -53,6 +54,11 @@ */ @property (nonatomic, retain) UIFont* font; +/** + * The text alignment used for all text. + */ +@property (nonatomic) UITextAlignment textAlignment; + /** * The width that the text should be constrained to fit within. */ diff --git a/src/Three20Style/Headers/TTStyledTextDelegate.h b/src/Three20Style/Headers/TTStyledTextDelegate.h index ade2cc0bff..115793b5fe 100644 --- a/src/Three20Style/Headers/TTStyledTextDelegate.h +++ b/src/Three20Style/Headers/TTStyledTextDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledTextFrame.h b/src/Three20Style/Headers/TTStyledTextFrame.h index ae71d1b479..72d5024165 100644 --- a/src/Three20Style/Headers/TTStyledTextFrame.h +++ b/src/Three20Style/Headers/TTStyledTextFrame.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTStyledTextNode.h b/src/Three20Style/Headers/TTStyledTextNode.h index 9258dcb0cf..8605294bef 100644 --- a/src/Three20Style/Headers/TTStyledTextNode.h +++ b/src/Three20Style/Headers/TTStyledTextNode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ NSString* _text; } -@property (nonatomic, retain) NSString* text; +@property (nonatomic, copy) NSString* text; - (id)initWithText:(NSString*)text; diff --git a/src/Three20Style/Headers/TTStyledTextParser.h b/src/Three20Style/Headers/TTStyledTextParser.h index fc1e148b5b..488f1a559c 100644 --- a/src/Three20Style/Headers/TTStyledTextParser.h +++ b/src/Three20Style/Headers/TTStyledTextParser.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/TTTextStyle.h b/src/Three20Style/Headers/TTTextStyle.h index 5fa0939337..65b2f92ddd 100644 --- a/src/Three20Style/Headers/TTTextStyle.h +++ b/src/Three20Style/Headers/TTTextStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/Three20Style+Additions.h b/src/Three20Style/Headers/Three20Style+Additions.h index 849760828d..2c7cc08aed 100644 --- a/src/Three20Style/Headers/Three20Style+Additions.h +++ b/src/Three20Style/Headers/Three20Style+Additions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/Three20Style.h b/src/Three20Style/Headers/Three20Style.h index bd914a075e..ec8e87a640 100644 --- a/src/Three20Style/Headers/Three20Style.h +++ b/src/Three20Style/Headers/Three20Style.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/UIColorAdditions.h b/src/Three20Style/Headers/UIColorAdditions.h index 6c4f11e2c8..d60ce12cf9 100644 --- a/src/Three20Style/Headers/UIColorAdditions.h +++ b/src/Three20Style/Headers/UIColorAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/UIFontAdditions.h b/src/Three20Style/Headers/UIFontAdditions.h index 365f024694..0d87fbb82d 100644 --- a/src/Three20Style/Headers/UIFontAdditions.h +++ b/src/Three20Style/Headers/UIFontAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Headers/UIImageAdditions.h b/src/Three20Style/Headers/UIImageAdditions.h index 1a5fef4f00..7dcbf8eed9 100644 --- a/src/Three20Style/Headers/UIImageAdditions.h +++ b/src/Three20Style/Headers/UIImageAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTBevelBorderStyle.m b/src/Three20Style/Sources/TTBevelBorderStyle.m index 88ecf07267..638cf745eb 100644 --- a/src/Three20Style/Sources/TTBevelBorderStyle.m +++ b/src/Three20Style/Sources/TTBevelBorderStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -41,7 +41,8 @@ @implementation TTBevelBorderStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _width = 1; _lightSource = kDefaultLightSource; } @@ -73,8 +74,11 @@ + (TTBevelBorderStyle*)styleWithColor:(UIColor*)color width:(CGFloat)width next: /////////////////////////////////////////////////////////////////////////////////////////////////// -+ (TTBevelBorderStyle*)styleWithHighlight:(UIColor*)highlight shadow:(UIColor*)shadowColor - width:(CGFloat)width lightSource:(NSInteger)lightSource next:(TTStyle*)next { ++ (TTBevelBorderStyle*)styleWithHighlight:(UIColor*)highlight + shadow:(UIColor*)shadowColor + width:(CGFloat)width + lightSource:(NSInteger)lightSource + next:(TTStyle*)next { TTBevelBorderStyle* style = [[[TTBevelBorderStyle alloc] initWithNext:next] autorelease]; style.highlight = highlight; style.shadow = shadowColor; @@ -101,7 +105,7 @@ - (void)draw:(TTStyleContext*)context { UIColor* topColor = _lightSource >= 0 && _lightSource <= 180 ? _highlight : _shadow; UIColor* leftColor = _lightSource >= 90 && _lightSource <= 270 ? _highlight : _shadow; - UIColor* bottomColor = _lightSource >= 180 && _lightSource <= 360 || _lightSource == 0 + UIColor* bottomColor = (_lightSource >= 180 && _lightSource <= 360) || _lightSource == 0 ? _highlight : _shadow; UIColor* rightColor = (_lightSource >= 270 && _lightSource <= 360) || (_lightSource >= 0 && _lightSource <= 90) @@ -115,6 +119,7 @@ - (void)draw:(TTStyleContext*)context { rect.origin.y += _width; rect.size.height -= _width; + } else { [[UIColor clearColor] setStroke]; } @@ -125,6 +130,7 @@ - (void)draw:(TTStyleContext*)context { [rightColor setStroke]; rect.size.width -= _width; + } else { [[UIColor clearColor] setStroke]; } @@ -135,6 +141,7 @@ - (void)draw:(TTStyleContext*)context { [bottomColor setStroke]; rect.size.height -= _width; + } else { [[UIColor clearColor] setStroke]; } @@ -146,6 +153,7 @@ - (void)draw:(TTStyleContext*)context { rect.origin.x += _width; rect.size.width -= _width; + } else { [[UIColor clearColor] setStroke]; } diff --git a/src/Three20Style/Sources/TTBlendStyle.m b/src/Three20Style/Sources/TTBlendStyle.m index 75346ee1a1..d643646e72 100644 --- a/src/Three20Style/Sources/TTBlendStyle.m +++ b/src/Three20Style/Sources/TTBlendStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,7 +27,8 @@ @implementation TTBlendStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _blendMode = kCGBlendModeNormal; } diff --git a/src/Three20Style/Sources/TTBoxStyle.m b/src/Three20Style/Sources/TTBoxStyle.m index ad1e9579a3..0eb0608150 100644 --- a/src/Three20Style/Sources/TTBoxStyle.m +++ b/src/Three20Style/Sources/TTBoxStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,7 +36,8 @@ @implementation TTBoxStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _margin = UIEdgeInsetsZero; _padding = UIEdgeInsetsZero; _minSize = CGSizeZero; diff --git a/src/Three20Style/Sources/TTContentStyle.m b/src/Three20Style/Sources/TTContentStyle.m index 0d471bb263..040ef4ac32 100644 --- a/src/Three20Style/Sources/TTContentStyle.m +++ b/src/Three20Style/Sources/TTContentStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTDefaultStyleSheet.m b/src/Three20Style/Sources/TTDefaultStyleSheet.m index 59e66be85b..c6158815d5 100644 --- a/src/Three20Style/Sources/TTDefaultStyleSheet.m +++ b/src/Three20Style/Sources/TTDefaultStyleSheet.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -67,6 +67,7 @@ - (TTStyle*)linkText:(UIControlState)state { [TTSolidFillStyle styleWithColor:[UIColor colorWithWhite:0.75 alpha:1] next: [TTInsetStyle styleWithInset:UIEdgeInsetsMake(3, 4, 3, 4) next: [TTTextStyle styleWithColor:self.linkTextColor next:nil]]]]]; + } else { return [TTTextStyle styleWithColor:self.linkTextColor next:nil]; @@ -90,6 +91,7 @@ - (TTStyle*)thumbView:(UIControlState)state { contentMode:UIViewContentModeScaleAspectFill size:CGSizeZero next: [TTSolidBorderStyle styleWithColor:RGBACOLOR(0,0,0,0.2) width:1 next: [TTSolidFillStyle styleWithColor:RGBACOLOR(0,0,0,0.5) next:nil]]]; + } else { return [TTImageStyle styleWithImageURL:nil defaultImage:nil @@ -378,16 +380,22 @@ - (TTStyle*)tabGridTab:(UIControlState)state corner:(short)corner { TTShape* shape = nil; if (corner == 1) { shape = [TTRoundedRectangleShape shapeWithTopLeft:8 topRight:0 bottomRight:0 bottomLeft:0]; + } else if (corner == 2) { shape = [TTRoundedRectangleShape shapeWithTopLeft:0 topRight:8 bottomRight:0 bottomLeft:0]; + } else if (corner == 3) { shape = [TTRoundedRectangleShape shapeWithTopLeft:0 topRight:0 bottomRight:8 bottomLeft:0]; + } else if (corner == 4) { shape = [TTRoundedRectangleShape shapeWithTopLeft:0 topRight:0 bottomRight:0 bottomLeft:8]; + } else if (corner == 5) { shape = [TTRoundedRectangleShape shapeWithTopLeft:8 topRight:0 bottomRight:0 bottomLeft:8]; + } else if (corner == 6) { shape = [TTRoundedRectangleShape shapeWithTopLeft:0 topRight:8 bottomRight:8 bottomLeft:0]; + } else { shape = [TTRectangleShape shape]; } @@ -405,10 +413,14 @@ - (TTStyle*)tabGridTab:(UIControlState)state corner:(short)corner { [TTTextStyle styleWithFont:[UIFont boldSystemFontOfSize:11] color:RGBCOLOR(255, 255, 255) minimumFontSize:8 shadowColor:RGBACOLOR(0,0,0,0.1) shadowOffset:CGSizeMake(-1,-1) next:nil]]]]]]; + } else { return [TTShapeStyle styleWithShape:shape next: - [TTBevelBorderStyle styleWithHighlight:highlight shadow:shadowColor width:1 lightSource:125 next: + [TTBevelBorderStyle styleWithHighlight:highlight + shadow:shadowColor + width:1 + lightSource:125 next: [TTBoxStyle styleWithPadding:UIEdgeInsetsMake(11, 10, 9, 10) next: [TTPartStyle styleWithName:@"image" style:[self tabGridTabImage:state] next: [TTTextStyle styleWithFont:[UIFont boldSystemFontOfSize:11] color:self.linkTextColor @@ -476,6 +488,7 @@ - (TTStyle*)tab:(UIControlState)state { [TTTextStyle styleWithFont:[UIFont boldSystemFontOfSize:14] color:TTSTYLEVAR(textColor) minimumFontSize:8 shadowColor:[UIColor colorWithWhite:1 alpha:0.8] shadowOffset:CGSizeMake(0, -1) next:nil]]]]]]]; + } else { return [TTInsetStyle styleWithInset:UIEdgeInsetsMake(5, 1, 1, 1) next: @@ -501,6 +514,7 @@ - (TTStyle*)tabRound:(UIControlState)state { [TTTextStyle styleWithFont:[UIFont boldSystemFontOfSize:13] color:[UIColor whiteColor] minimumFontSize:8 shadowColor:[UIColor colorWithWhite:0 alpha:0.5] shadowOffset:CGSizeMake(0, -1) next:nil]]]]]]]]; + } else { return [TTBoxStyle styleWithPadding:UIEdgeInsetsMake(0, 10, 0, 10) next: @@ -580,6 +594,7 @@ - (TTStyle*)photoStatusLabel { - (TTStyle*)pageDot:(UIControlState)state { if (state == UIControlStateSelected) { return [self pageDotWithColor:[UIColor whiteColor]]; + } else { return [self pageDotWithColor:RGBCOLOR(77, 77, 77)]; } @@ -648,8 +663,10 @@ - (TTStyle*)textBar { return [TTLinearGradientFillStyle styleWithColor1:RGBCOLOR(237, 239, 241) color2:RGBCOLOR(206, 208, 212) next: - [TTFourBorderStyle styleWithTop:RGBCOLOR(187, 189, 190) right:nil bottom:nil left:nil width:1 next: - [TTFourBorderStyle styleWithTop:RGBCOLOR(255, 255, 255) right:nil bottom:nil left:nil width:1 + [TTFourBorderStyle styleWithTop:RGBCOLOR(187, 189, 190) + right:nil bottom:nil left:nil width:1 next: + [TTFourBorderStyle styleWithTop:RGBCOLOR(255, 255, 255) + right:nil bottom:nil left:nil width:1 next:nil]]]; } @@ -659,8 +676,10 @@ - (TTStyle*)textBarFooter { return [TTLinearGradientFillStyle styleWithColor1:RGBCOLOR(206, 208, 212) color2:RGBCOLOR(184, 186, 190) next: - [TTFourBorderStyle styleWithTop:RGBCOLOR(161, 161, 161) right:nil bottom:nil left:nil width:1 next: - [TTFourBorderStyle styleWithTop:RGBCOLOR(230, 232, 235) right:nil bottom:nil left:nil width:1 + [TTFourBorderStyle styleWithTop:RGBCOLOR(161, 161, 161) + right:nil bottom:nil left:nil width:1 next: + [TTFourBorderStyle styleWithTop:RGBCOLOR(230, 232, 235) + right:nil bottom:nil left:nil width:1 next:nil]]]; } @@ -722,6 +741,11 @@ - (UIColor*)highlightedTextColor { return [UIColor whiteColor]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UIColor*)backgroundTextColor { + return [UIColor clearColor]; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIFont*)font { @@ -764,12 +788,32 @@ - (UIColor*)tablePlainBackgroundColor { return nil; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UIColor*)tablePlainCellSeparatorColor { + return nil; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UITableViewCellSeparatorStyle)tablePlainCellSeparatorStyle { + return UITableViewCellSeparatorStyleSingleLine; +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIColor*)tableGroupedBackgroundColor { return [UIColor groupTableViewBackgroundColor]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UIColor*)tableGroupedCellSeparatorColor { + return nil; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UITableViewCellSeparatorStyle)tableGroupedCellSeparatorStyle { + return [self tablePlainCellSeparatorStyle]; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIColor*)searchTableBackgroundColor { @@ -782,6 +826,24 @@ - (UIColor*)searchTableSeparatorColor { return [UIColor colorWithWhite:0.85 alpha:1]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTStyle*)tableReloadButton:(UIControlState)state { + if (state == UIControlStateHighlighted) { + return + [TTImageStyle styleWithImageURL:@"bundle://Three20.bundle/images/reloadButtonActive.png" + defaultImage:nil + contentMode:UIViewContentModeCenter + size:CGSizeMake(50,50) next:nil]; + + } else { + return + [TTImageStyle styleWithImageURL:@"bundle://Three20.bundle/images/reloadButton.png" + defaultImage:nil + contentMode:UIViewContentModeCenter + size:CGSizeMake(50,50) next:nil]; + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -836,6 +898,10 @@ - (UIColor*)tableHeaderTintColor { return nil; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTStyle*)tableHeaderGrouped { + return nil; +} /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -990,6 +1056,12 @@ - (UIFont*)tableHeaderGroupedFont { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (CGFloat) tableBannerViewHeight { + return 22; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIFont*)photoCaptionFont { return [UIFont boldSystemFontOfSize:12]; @@ -1040,14 +1112,18 @@ - (UIColor*)toolbarButtonColorWithTintColor:(UIColor*)color forState:(UIControlS if (state & UIControlStateHighlighted || state & UIControlStateSelected) { if (color.value < 0.2) { return [color addHue:0 saturation:0 value:0.2]; + } else if (color.saturation > 0.3) { return [color multiplyHue:1 saturation:1 value:0.4]; + } else { return [color multiplyHue:1 saturation:2.3 value:0.64]; } + } else { if (color.saturation < 0.5) { return [color multiplyHue:1 saturation:1.6 value:0.97]; + } else { return [color multiplyHue:1 saturation:1.25 value:0.75]; } @@ -1059,6 +1135,7 @@ - (UIColor*)toolbarButtonColorWithTintColor:(UIColor*)color forState:(UIControlS - (UIColor*)toolbarButtonTextColorForState:(UIControlState)state { if (state & UIControlStateDisabled) { return [UIColor colorWithWhite:1 alpha:0.4]; + } else { return [UIColor whiteColor]; } @@ -1124,7 +1201,7 @@ - (UIFont*)tableRefreshHeaderLastUpdatedFont { /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIFont*)tableRefreshHeaderStatusFont { - return [UIFont boldSystemFontOfSize:13.0f]; + return [UIFont boldSystemFontOfSize:14.0f]; } @@ -1136,13 +1213,13 @@ - (UIColor*)tableRefreshHeaderBackgroundColor { /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIColor*)tableRefreshHeaderTextColor { - return RGBCOLOR(87, 108, 137); + return RGBCOLOR(109, 128, 153); } /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIColor*)tableRefreshHeaderTextShadowColor { - return [UIColor colorWithWhite:0.9 alpha:1]; + return [[UIColor whiteColor] colorWithAlphaComponent:0.9]; } diff --git a/src/Three20Style/Sources/TTFlowLayout.m b/src/Three20Style/Sources/TTFlowLayout.m index 382f97a4ec..d7e35e605f 100644 --- a/src/Three20Style/Sources/TTFlowLayout.m +++ b/src/Three20Style/Sources/TTFlowLayout.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,22 +35,25 @@ @implementation TTFlowLayout /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGSize)layoutSubviews:(NSArray*)subviews forView:(UIView*)view { CGFloat x = _padding, y = _padding; - CGFloat maxX = 0, lastHeight = 0; + CGFloat maxX = 0.0f, rowHeight = 0.0f; CGFloat maxWidth = view.frame.size.width - _padding*2; for (UIView* subview in subviews) { - if (x + subview.frame.size.width > maxWidth) { + if (x > _padding && x + subview.frame.size.width > maxWidth) { x = _padding; - y += subview.frame.size.height + _spacing; + y += rowHeight + _spacing; + rowHeight = 0; } subview.frame = CGRectMake(x, y, subview.frame.size.width, subview.frame.size.height); x += subview.frame.size.width + _spacing; if (x > maxX) { maxX = x; } - lastHeight = subview.frame.size.height; + if (subview.frame.size.height > rowHeight) { + rowHeight = subview.frame.size.height; + } } - return CGSizeMake(maxX+_padding, y+lastHeight+_padding); + return CGSizeMake(maxX+_padding, y+rowHeight+_padding); } diff --git a/src/Three20Style/Sources/TTFourBorderStyle.m b/src/Three20Style/Sources/TTFourBorderStyle.m index 30b39e2856..ea7fc233e5 100644 --- a/src/Three20Style/Sources/TTFourBorderStyle.m +++ b/src/Three20Style/Sources/TTFourBorderStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/TTGlobalCoreRects.h" /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -41,7 +42,8 @@ @implementation TTFourBorderStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _width = 1; } @@ -124,7 +126,11 @@ + (TTFourBorderStyle*)styleWithLeft:(UIColor*)left width:(CGFloat)width next:(TT /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)draw:(TTStyleContext*)context { CGRect rect = context.frame; - CGRect strokeRect = CGRectInset(rect, _width/2, _width/2); + UIEdgeInsets insets = UIEdgeInsetsMake(_top ? _width/2. : 0, + _left ? _width/2 : 0, + _bottom ? _width/2 : 0, + _right ? _width/2 : 0); + CGRect strokeRect = TTRectInset(rect, insets); [context.shape openPath:strokeRect]; CGContextRef ctx = UIGraphicsGetCurrentContext(); @@ -133,6 +139,7 @@ - (void)draw:(TTStyleContext*)context { [context.shape addTopEdgeToPath:strokeRect lightSource:kDefaultLightSource]; if (_top) { [_top setStroke]; + } else { [[UIColor clearColor] setStroke]; } @@ -141,6 +148,7 @@ - (void)draw:(TTStyleContext*)context { [context.shape addRightEdgeToPath:strokeRect lightSource:kDefaultLightSource]; if (_right) { [_right setStroke]; + } else { [[UIColor clearColor] setStroke]; } @@ -149,6 +157,7 @@ - (void)draw:(TTStyleContext*)context { [context.shape addBottomEdgeToPath:strokeRect lightSource:kDefaultLightSource]; if (_bottom) { [_bottom setStroke]; + } else { [[UIColor clearColor] setStroke]; } @@ -157,6 +166,7 @@ - (void)draw:(TTStyleContext*)context { [context.shape addLeftEdgeToPath:strokeRect lightSource:kDefaultLightSource]; if (_left) { [_left setStroke]; + } else { [[UIColor clearColor] setStroke]; } diff --git a/src/Three20Style/Sources/TTGlobalStyle.m b/src/Three20Style/Sources/TTGlobalStyle.m index 18ca3034a8..ba78fc17c4 100644 --- a/src/Three20Style/Sources/TTGlobalStyle.m +++ b/src/Three20Style/Sources/TTGlobalStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,4 +16,4 @@ #import "Three20Style/TTGlobalStyle.h" -const CGFloat ttkRounded = -1; +const CGFloat ttkRounded = -1.0f; diff --git a/src/Three20Style/Sources/TTGridLayout.m b/src/Three20Style/Sources/TTGridLayout.m index 5dc1436ca8..c573939e27 100644 --- a/src/Three20Style/Sources/TTGridLayout.m +++ b/src/Three20Style/Sources/TTGridLayout.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,7 +29,8 @@ @implementation TTGridLayout /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { _columnCount = 1; } @@ -47,10 +48,10 @@ - (id)init { - (CGSize)layoutSubviews:(NSArray*)subviews forView:(UIView*)view { CGFloat innerWidth = (view.frame.size.width - _padding*2); CGFloat width = ceil(innerWidth / _columnCount); - CGFloat rowHeight = 0; + CGFloat rowHeight = 0.0f; CGFloat x = _padding, y = _padding; - CGFloat maxX = 0, lastHeight = 0; + CGFloat maxX = 0.0f, lastHeight = 0.0f; NSInteger column = 0; for (UIView* subview in subviews) { if (column % _columnCount == 0) { diff --git a/src/Three20Style/Sources/TTHighlightBorderStyle.m b/src/Three20Style/Sources/TTHighlightBorderStyle.m index 0d583680d0..d5f7f15253 100644 --- a/src/Three20Style/Sources/TTHighlightBorderStyle.m +++ b/src/Three20Style/Sources/TTHighlightBorderStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,7 +36,8 @@ @implementation TTHighlightBorderStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _width = 1; } diff --git a/src/Three20Style/Sources/TTImageStyle.m b/src/Three20Style/Sources/TTImageStyle.m index 10d2e2fddc..a9ede0c5cd 100644 --- a/src/Three20Style/Sources/TTImageStyle.m +++ b/src/Three20Style/Sources/TTImageStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -43,7 +43,8 @@ @implementation TTImageStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _contentMode = UIViewContentModeScaleToFill; _size = CGSizeZero; } @@ -87,8 +88,11 @@ + (TTImageStyle*)styleWithImageURL:(NSString*)imageURL defaultImage:(UIImage*)de /////////////////////////////////////////////////////////////////////////////////////////////////// -+ (TTImageStyle*)styleWithImageURL:(NSString*)imageURL defaultImage:(UIImage*)defaultImage - contentMode:(UIViewContentMode)contentMode size:(CGSize)size next:(TTStyle*)next { ++ (TTImageStyle*)styleWithImageURL:(NSString*)imageURL + defaultImage:(UIImage*)defaultImage + contentMode:(UIViewContentMode)contentMode + size:(CGSize)size + next:(TTStyle*)next { TTImageStyle* style = [[[self alloc] initWithNext:next] autorelease]; style.imageURL = imageURL; style.defaultImage = defaultImage; @@ -117,8 +121,11 @@ + (TTImageStyle*)styleWithImage:(UIImage*)image defaultImage:(UIImage*)defaultIm /////////////////////////////////////////////////////////////////////////////////////////////////// -+ (TTImageStyle*)styleWithImage:(UIImage*)image defaultImage:(UIImage*)defaultImage - contentMode:(UIViewContentMode)contentMode size:(CGSize)size next:(TTStyle*)next { ++ (TTImageStyle*)styleWithImage:(UIImage*)image + defaultImage:(UIImage*)defaultImage + contentMode:(UIViewContentMode)contentMode + size:(CGSize)size + next:(TTStyle*)next { TTImageStyle* style = [[[self alloc] initWithNext:next] autorelease]; style.image = image; style.defaultImage = defaultImage; @@ -173,6 +180,7 @@ - (CGSize)addToSize:(CGSize)size context:(TTStyleContext*)context { if (_size.width || _size.height) { size.width += _size.width; size.height += _size.height; + } else if (_contentMode != UIViewContentModeScaleToFill && _contentMode != UIViewContentModeScaleAspectFill && _contentMode != UIViewContentModeScaleAspectFit) { diff --git a/src/Three20Style/Sources/TTInnerShadowStyle.m b/src/Three20Style/Sources/TTInnerShadowStyle.m index 6f813e15b9..9251dfa0ef 100644 --- a/src/Three20Style/Sources/TTInnerShadowStyle.m +++ b/src/Three20Style/Sources/TTInnerShadowStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -69,6 +69,7 @@ - (void)draw:(TTStyleContext*)context { - (CGSize)addToSize:(CGSize)size context:(TTStyleContext*)context { if (_next) { return [self.next addToSize:size context:context]; + } else { return size; } diff --git a/src/Three20Style/Sources/TTInsetStyle.m b/src/Three20Style/Sources/TTInsetStyle.m index a6317c47c5..4735a9d94e 100644 --- a/src/Three20Style/Sources/TTInsetStyle.m +++ b/src/Three20Style/Sources/TTInsetStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,7 +30,8 @@ @implementation TTInsetStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _inset = UIEdgeInsetsZero; } @@ -76,6 +77,7 @@ - (UIEdgeInsets)addToInsets:(UIEdgeInsets)insets forSize:(CGSize)size { insets.left += _inset.left; if (self.next) { return [self.next addToInsets:insets forSize:size]; + } else { return insets; } diff --git a/src/Three20Style/Sources/TTLayout.m b/src/Three20Style/Sources/TTLayout.m index 70ae61c832..214bfaf745 100644 --- a/src/Three20Style/Sources/TTLayout.m +++ b/src/Three20Style/Sources/TTLayout.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTLinearGradientBorderStyle.m b/src/Three20Style/Sources/TTLinearGradientBorderStyle.m index 39fda71f15..dbe75d7888 100644 --- a/src/Three20Style/Sources/TTLinearGradientBorderStyle.m +++ b/src/Three20Style/Sources/TTLinearGradientBorderStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -41,7 +41,8 @@ @implementation TTLinearGradientBorderStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _location2 = 1; _width = 1; } diff --git a/src/Three20Style/Sources/TTLinearGradientFillStyle.m b/src/Three20Style/Sources/TTLinearGradientFillStyle.m index 4349c5bae7..e3c91e74e8 100644 --- a/src/Three20Style/Sources/TTLinearGradientFillStyle.m +++ b/src/Three20Style/Sources/TTLinearGradientFillStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTMaskStyle.m b/src/Three20Style/Sources/TTMaskStyle.m index 23ad35ec0d..cf97a016fe 100644 --- a/src/Three20Style/Sources/TTMaskStyle.m +++ b/src/Three20Style/Sources/TTMaskStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTPartStyle.m b/src/Three20Style/Sources/TTPartStyle.m index bd8b760ab4..04837acd6e 100644 --- a/src/Three20Style/Sources/TTPartStyle.m +++ b/src/Three20Style/Sources/TTPartStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTRectangleShape.m b/src/Three20Style/Sources/TTRectangleShape.m index 1b7671778e..c94820ee6c 100644 --- a/src/Three20Style/Sources/TTRectangleShape.m +++ b/src/Three20Style/Sources/TTRectangleShape.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -64,7 +64,7 @@ - (void)addInverseToPath:(CGRect)rect { CGFloat fw = rect.size.width; CGFloat fh = rect.size.height; - CGFloat width = 5; + CGFloat width = 5.0f; CGRect shadowRect = CGRectMake(-width, -width, fw+width*2, fh+width*2); CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, nil, shadowRect); diff --git a/src/Three20Style/Sources/TTReflectiveFillStyle.m b/src/Three20Style/Sources/TTReflectiveFillStyle.m index 70cb45e758..9da92aa895 100644 --- a/src/Three20Style/Sources/TTReflectiveFillStyle.m +++ b/src/Three20Style/Sources/TTReflectiveFillStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -96,8 +96,9 @@ - (void)draw:(TTStyleContext*)context { UIColor* clearColor = [UIColor colorWithWhite:1.0 alpha:0.0]; UIColor* botEndHighlight; - if( _withBottomHighlight ) { + if ( _withBottomHighlight ) { botEndHighlight = [UIColor colorWithWhite:1.0 alpha:0.27]; + } else { botEndHighlight = clearColor; } diff --git a/src/Three20Style/Sources/TTRoundedLeftArrowShape.m b/src/Three20Style/Sources/TTRoundedLeftArrowShape.m index c8ce1426b9..bdee2e3f78 100644 --- a/src/Three20Style/Sources/TTRoundedLeftArrowShape.m +++ b/src/Three20Style/Sources/TTRoundedLeftArrowShape.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -112,6 +112,7 @@ - (void)addTopEdgeToPath:(CGRect)rect lightSource:(NSInteger)lightSource { if (lightSource >= 0 && lightSource <= 90) { CGContextAddLineToPoint(context, floor(fw-radius), 0); + } else { CGContextAddArcToPoint(context, fw, 0, fw, floor(radius), radius); } @@ -128,6 +129,7 @@ - (void)addRightEdgeToPath:(CGRect)rect lightSource:(NSInteger)lightSource { if (lightSource >= 0 && lightSource <= 90) { CGContextMoveToPoint(context, floor(fw-radius), 0); CGContextAddArcToPoint(context, fw, 0, fw, floor(radius), radius); + } else { CGContextMoveToPoint(context, fw, radius); CGContextAddLineToPoint(context, fw, fh-radius); diff --git a/src/Three20Style/Sources/TTRoundedRectangleShape.m b/src/Three20Style/Sources/TTRoundedRectangleShape.m index e462c49459..881feb4425 100644 --- a/src/Three20Style/Sources/TTRoundedRectangleShape.m +++ b/src/Three20Style/Sources/TTRoundedRectangleShape.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -89,7 +89,7 @@ - (void)addInverseToPath:(CGRect)rect { CGFloat fw = rect.size.width; CGFloat fh = rect.size.height; - CGFloat width = 5; + CGFloat width = 5.0f; CGRect shadowRect = CGRectMake(-width, -width, fw+width*2, fh+width*2); CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, nil, shadowRect); @@ -118,6 +118,7 @@ - (void)addTopEdgeToPath:(CGRect)rect lightSource:(NSInteger)lightSource { if (lightSource >= 0 && lightSource <= 90) { CGContextMoveToPoint(context, RD(_topLeftRadius), 0); + } else { CGContextMoveToPoint(context, 0, RD(_topLeftRadius)); CGContextAddArcToPoint(context, 0, 0, RD(_topLeftRadius), 0, RD(_topLeftRadius)); diff --git a/src/Three20Style/Sources/TTRoundedRightArrowShape.m b/src/Three20Style/Sources/TTRoundedRightArrowShape.m index 82783ee6cb..959d2530e4 100644 --- a/src/Three20Style/Sources/TTRoundedRightArrowShape.m +++ b/src/Three20Style/Sources/TTRoundedRightArrowShape.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -81,6 +81,7 @@ - (void)addTopEdgeToPath:(CGRect)rect lightSource:(NSInteger)lightSource { if (lightSource >= 0 && lightSource <= 90) { CGContextMoveToPoint(context, radius, 0); + } else { CGContextMoveToPoint(context, 0, radius); CGContextAddArcToPoint(context, 0, 0, radius, 0, radius); diff --git a/src/Three20Style/Sources/TTShadowStyle.m b/src/Three20Style/Sources/TTShadowStyle.m index 219600553f..08626f1e44 100644 --- a/src/Three20Style/Sources/TTShadowStyle.m +++ b/src/Three20Style/Sources/TTShadowStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,7 +38,8 @@ @implementation TTShadowStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _offset = CGSizeZero; } @@ -84,6 +85,7 @@ - (void)draw:(TTStyleContext*)context { if (_offset.width < 0) { inset.left += fabs(_offset.width) + blurSize*2; inset.right -= blurSize; + } else if (_offset.width > 0) { inset.right += fabs(_offset.width) + blurSize*2; inset.left -= blurSize; @@ -91,6 +93,7 @@ - (void)draw:(TTStyleContext*)context { if (_offset.height < 0) { inset.top += fabs(_offset.height) + blurSize*2; inset.bottom -= blurSize; + } else if (_offset.height > 0) { inset.bottom += fabs(_offset.height) + blurSize*2; inset.top -= blurSize; @@ -130,6 +133,7 @@ - (CGSize)addToSize:(CGSize)size context:(TTStyleContext*)context { if (_next) { return [self.next addToSize:size context:context]; + } else { return size; } diff --git a/src/Three20Style/Sources/TTShape.m b/src/Three20Style/Sources/TTShape.m index f47185ee38..e01c1e1c22 100644 --- a/src/Three20Style/Sources/TTShape.m +++ b/src/Three20Style/Sources/TTShape.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTShapeInternal.m b/src/Three20Style/Sources/TTShapeInternal.m index e50f1ae091..5af0dfd6b9 100644 --- a/src/Three20Style/Sources/TTShapeInternal.m +++ b/src/Three20Style/Sources/TTShapeInternal.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,6 @@ #import "Three20Style/private/TTShapeInternal.h" -const CGFloat kArrowPointWidth = 2.8; -const CGFloat kArrowRadius = 2; +const CGFloat kArrowPointWidth = 2.8f; +const CGFloat kArrowRadius = 2.0f; diff --git a/src/Three20Style/Sources/TTShapeStyle.m b/src/Three20Style/Sources/TTShapeStyle.m index 4e59113109..691a4a9fa8 100644 --- a/src/Three20Style/Sources/TTShapeStyle.m +++ b/src/Three20Style/Sources/TTShapeStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTSolidBorderStyle.m b/src/Three20Style/Sources/TTSolidBorderStyle.m index c3a5e998f0..b4ab395172 100644 --- a/src/Three20Style/Sources/TTSolidBorderStyle.m +++ b/src/Three20Style/Sources/TTSolidBorderStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,7 +35,8 @@ @implementation TTSolidBorderStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _width = 1; } diff --git a/src/Three20Style/Sources/TTSolidFillStyle.m b/src/Three20Style/Sources/TTSolidFillStyle.m index 86d163f6a7..c12a588df2 100644 --- a/src/Three20Style/Sources/TTSolidFillStyle.m +++ b/src/Three20Style/Sources/TTSolidFillStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTSpeechBubbleShape.m b/src/Three20Style/Sources/TTSpeechBubbleShape.m index 4fab23d460..26d8b04a12 100644 --- a/src/Three20Style/Sources/TTSpeechBubbleShape.m +++ b/src/Three20Style/Sources/TTSpeechBubbleShape.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ // Style (private) #import "Three20Style/private/TTShapeInternal.h" -static const CGFloat kInsetWidth = 5; +static const CGFloat kInsetWidth = 5.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -59,31 +59,31 @@ + (TTSpeechBubbleShape*)shapeWithRadius:(CGFloat)radius pointLocation:(CGFloat)p /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGRect)subtractPointFromRect:(CGRect)rect { - CGFloat x = 0; - CGFloat y = 0; + CGFloat x = 0.0f; + CGFloat y = 0.0f; CGFloat w = rect.size.width; CGFloat h = rect.size.height; if ((_pointLocation >= 0 && _pointLocation < 45) || (_pointLocation >= 315 && _pointLocation < 360)) { - if ((_pointAngle >= 270 && _pointAngle < 360) || (_pointAngle >= 0 && _pointAngle < 90)) { + if ((_pointAngle >= 270 && _pointAngle <= 360) || (_pointAngle >= 0 && _pointAngle <= 90)) { x += _pointSize.width; w -= _pointSize.width; } } else if (_pointLocation >= 45 && _pointLocation < 135) { - if (_pointAngle >= 0 && _pointAngle < 180) { + if (_pointAngle >= 0 && _pointAngle <= 180) { y += _pointSize.height; h -= _pointSize.height; } } else if (_pointLocation >= 135 && _pointLocation < 225) { - if (_pointAngle >= 90 && _pointAngle < 270) { + if (_pointAngle >= 90 && _pointAngle <= 270) { w -= _pointSize.width; } - } else if (_pointLocation >= 225 && _pointLocation <= 315) { - if (_pointAngle >= 180 && _pointAngle < 360) { + } else if (_pointLocation >= 225 && _pointLocation < 315) { + if (_pointAngle >= 180 && _pointAngle <= 360) { h -= _pointSize.height; } } @@ -97,30 +97,32 @@ - (void)addTopEdge:(CGSize)size lightSource:(NSInteger)lightSource toPath:(CGMut reset:(BOOL)reset { CGFloat fw = size.width; CGFloat fh = size.height; - CGFloat pointX = 0; + CGFloat pointX = 0.0f; + CGFloat radius = RD(_radius); if (lightSource >= 0 && lightSource <= 90) { if (reset) { - CGPathMoveToPoint(path, nil, RD(_radius), 0); + CGPathMoveToPoint(path, nil, radius, 0); } } else { if (reset) { - CGPathMoveToPoint(path, nil, 0, RD(_radius)); + CGPathMoveToPoint(path, nil, 0, radius); } - CGPathAddArcToPoint(path, nil, 0, 0, RD(_radius), 0, RD(_radius)); + CGPathAddArcToPoint(path, nil, 0, 0, radius, 0, radius); } - if (_pointLocation >= 45 && _pointLocation <= 135) { - CGFloat ph = _pointAngle >= 0 && _pointAngle < 180 ? _pointSize.height : -_pointSize.height; - pointX = ((_pointLocation-45)/90) * fw; + if (_pointLocation >= 45 && _pointLocation < 135) { + CGFloat ph = _pointAngle >= 0 && _pointAngle <= 180 ? _pointSize.height : -_pointSize.height; + pointX = (((_pointLocation-45)/90) * (fw - 2 *radius - _pointSize.width) + + radius + floor(_pointSize.width/2)); CGPathAddLineToPoint(path, nil, pointX-floor(_pointSize.width/2), 0); CGPathAddLineToPoint(path, nil, pointX, -ph); CGPathAddLineToPoint(path, nil, pointX+floor(_pointSize.width/2), 0); } - CGPathAddArcToPoint(path, nil, fw, 0, fw, RD(_radius), RD(_radius)); + CGPathAddArcToPoint(path, nil, fw, 0, fw, radius, radius); } @@ -129,12 +131,24 @@ - (void)addRightEdge:(CGSize)size lightSource:(NSInteger)lightSource toPath:(CGM reset:(BOOL)reset { CGFloat fw = size.width; CGFloat fh = size.height; + CGFloat pointY = 0.0f; + CGFloat radius = RD(_radius); if (reset) { - CGPathMoveToPoint(path, nil, fw, RD(_radius)); + CGPathMoveToPoint(path, nil, fw, radius); } - CGPathAddArcToPoint(path, nil, fw, fh, fw-RD(_radius), fh, RD(_radius)); + if (_pointLocation >= 135 && _pointLocation < 225) { + CGFloat pw = _pointAngle >= 90 && _pointAngle <= 270 ? _pointSize.width : -_pointSize.width; + pointY = (((_pointLocation-135)/90) * (fh - 2 * radius - _pointSize.height) + + radius + floor(_pointSize.height/2)); + + CGPathAddLineToPoint(path, nil, fw, pointY-floor(_pointSize.height/2)); + CGPathAddLineToPoint(path, nil, fw+pw, pointY); + CGPathAddLineToPoint(path, nil, fw, pointY+floor(_pointSize.height/2)); + } + + CGPathAddArcToPoint(path, nil, fw, fh, fw-radius, fh, radius); } @@ -143,31 +157,32 @@ - (void)addBottomEdge:(CGSize)size lightSource:(NSInteger)lightSource toPath:(CG reset:(BOOL)reset { CGFloat fw = size.width; CGFloat fh = size.height; - CGFloat pointX = 0; + CGFloat pointX = 0.0f; + CGFloat radius = RD(_radius); if (reset) { - CGPathMoveToPoint(path, nil, fw-RD(_radius), fh); + CGPathMoveToPoint(path, nil, fw-radius, fh); } - if (_pointLocation >= 225 && _pointLocation <= 315) { + if (_pointLocation >= 225 && _pointLocation < 315) { CGFloat ph; - if (_pointAngle >= 0 && _pointAngle < 180) { + if (_pointAngle >= 0 && _pointAngle <= 180) { ph = _pointSize.height; } else { ph = -_pointSize.height; } - pointX = fw - (((_pointLocation-225)/90) * fw); - CGPathAddArcToPoint(path, nil, fw-RD(_radius), fh, floor(fw/2), fh, RD(_radius)); + pointX = fw - (((_pointLocation-225)/90) * (fw - 2 *radius - _pointSize.width) + + radius + floor(_pointSize.width/2)); + CGPathAddLineToPoint(path, nil, pointX+floor(_pointSize.width/2), fh); CGPathAddLineToPoint(path, nil, pointX, fh-ph); CGPathAddLineToPoint(path, nil, pointX-floor(_pointSize.width/2), fh); - CGPathAddLineToPoint(path, nil, RD(_radius), fh); } - CGPathAddArcToPoint(path, nil, 0, fh, 0, fh-RD(_radius), RD(_radius)); + CGPathAddArcToPoint(path, nil, 0, fh, 0, fh-radius, radius); } @@ -175,16 +190,44 @@ - (void)addBottomEdge:(CGSize)size lightSource:(NSInteger)lightSource toPath:(CG - (void)addLeftEdge:(CGSize)size lightSource:(NSInteger)lightSource toPath:(CGMutablePathRef)path reset:(BOOL)reset { CGFloat fh = size.height; + CGFloat pointY = 0.0f; + CGFloat radius = RD(_radius); if (reset) { - CGPathMoveToPoint(path, nil, 0, fh-RD(_radius)); + CGPathMoveToPoint(path, nil, 0, fh-radius); + } + + // Use a custom pointLocation with a value between 315 and 405 instead of 0-45 and 315-360 + // to ease calculations + CGFloat myPointLocation = _pointLocation; + if (myPointLocation >= 0 && myPointLocation < 45) { + myPointLocation += 360; + } + + if (myPointLocation >= 315 && myPointLocation < 405) { + + // Compute extension of arrow + CGFloat pw = _pointAngle >= 270 || _pointAngle <= 90 ? -_pointSize.width : _pointSize.width; + + // Compute location of arrow on line + // Do not place the arrow on the arcs at the corner! + pointY = fh - (((myPointLocation - 315) / 90) * (fh - 2 * radius - _pointSize.height) + + radius + _pointSize.height/2); + + // Draw the lines, first to the arrow... + CGPathAddLineToPoint(path, nil, 0, pointY+floor(_pointSize.height/2)); + // Then up to the point... + CGPathAddLineToPoint(path, nil, pw, pointY); + // And back again to the rectangle.. + CGPathAddLineToPoint(path, nil, 0, pointY-floor(_pointSize.height/2)); } + // Then continue the rest of the line if (lightSource >= 0 && lightSource <= 90) { - CGPathAddArcToPoint(path, nil, 0, 0, RD(_radius), 0, RD(_radius)); + CGPathAddArcToPoint(path, nil, 0, 0, radius, 0, radius); } else { - CGPathAddLineToPoint(path, nil, 0, RD(_radius)); + CGPathAddLineToPoint(path, nil, 0, radius); } } diff --git a/src/Three20Style/Sources/TTStyle.m b/src/Three20Style/Sources/TTStyle.m index 3d8d19250f..a1d1976697 100644 --- a/src/Three20Style/Sources/TTStyle.m +++ b/src/Three20Style/Sources/TTStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,7 +36,8 @@ @implementation TTStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super init]) { + self = [super init]; + if (self) { _next = [next retain]; } @@ -46,7 +47,8 @@ - (id)initWithNext:(TTStyle*)next { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithNext:nil]) { + self = [self initWithNext:nil]; + if (self) { } return self; diff --git a/src/Three20Style/Sources/TTStyleContext.m b/src/Three20Style/Sources/TTStyleContext.m index fbdc89c1c0..9c1c8d8946 100644 --- a/src/Three20Style/Sources/TTStyleContext.m +++ b/src/Three20Style/Sources/TTStyleContext.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,7 +38,8 @@ @implementation TTStyleContext /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { _frame = CGRectZero; _contentFrame = CGRectZero; } diff --git a/src/Three20Style/Sources/TTStyleInternal.m b/src/Three20Style/Sources/TTStyleInternal.m index 216ace612e..84836af016 100644 --- a/src/Three20Style/Sources/TTStyleInternal.m +++ b/src/Three20Style/Sources/TTStyleInternal.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,12 +16,18 @@ #import "Three20Style/private/TTStyleInternal.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + + const NSInteger kDefaultLightSource = 125; /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +TT_FIX_CATEGORY_BUG(TTStyleInternal) + @implementation TTStyle (TTInternal) @@ -38,6 +44,7 @@ - (CGGradientRef)newGradientWithColors:(UIColor**)colors locations:(CGFloat*)loc components[i*4+1] = rgba[0]; components[i*4+2] = rgba[0]; components[i*4+3] = rgba[1]; + } else if (n == 4) { components[i*4] = rgba[0]; components[i*4+1] = rgba[1]; @@ -62,4 +69,3 @@ - (CGGradientRef)newGradientWithColors:(UIColor**)colors count:(int)count { @end - diff --git a/src/Three20Style/Sources/TTStyleSheet.m b/src/Three20Style/Sources/TTStyleSheet.m index 986ad56bb3..5f1749f424 100644 --- a/src/Three20Style/Sources/TTStyleSheet.m +++ b/src/Three20Style/Sources/TTStyleSheet.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,7 +33,8 @@ @implementation TTStyleSheet /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(didReceiveMemoryWarning:) diff --git a/src/Three20Style/Sources/TTStyledBlock.m b/src/Three20Style/Sources/TTStyledBlock.m index 5ea5f34795..3d44179ee6 100644 --- a/src/Three20Style/Sources/TTStyledBlock.m +++ b/src/Three20Style/Sources/TTStyledBlock.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTStyledBoldNode.m b/src/Three20Style/Sources/TTStyledBoldNode.m index 9a0da53369..04cd272285 100644 --- a/src/Three20Style/Sources/TTStyledBoldNode.m +++ b/src/Three20Style/Sources/TTStyledBoldNode.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTStyledBoxFrame.m b/src/Three20Style/Sources/TTStyledBoxFrame.m index d8e25556c0..43b58ef0f5 100644 --- a/src/Three20Style/Sources/TTStyledBoxFrame.m +++ b/src/Three20Style/Sources/TTStyledBoxFrame.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -71,18 +71,22 @@ - (void)drawLayer:(TTStyleContext*)context withStyle:(TTStyle*)style { TTTextStyle* textStyle = (TTTextStyle*)style; UIFont* font = context.font; context.font = textStyle.font; + + CGContextRef ctx = UIGraphicsGetCurrentContext(); + CGContextSaveGState(ctx); + if (textStyle.color) { - CGContextRef ctx = UIGraphicsGetCurrentContext(); - CGContextSaveGState(ctx); [textStyle.color setFill]; + } - [self drawSubframes]; + if (textStyle.shadowColor) { + CGSize offset = CGSizeMake(textStyle.shadowOffset.width, -textStyle.shadowOffset.height); + CGContextSetShadowWithColor(ctx, offset, 0, textStyle.shadowColor.CGColor); + } - CGContextRestoreGState(ctx); + [self drawSubframes]; - } else { - [self drawSubframes]; - } + CGContextRestoreGState(ctx); context.font = font; diff --git a/src/Three20Style/Sources/TTStyledButtonNode.m b/src/Three20Style/Sources/TTStyledButtonNode.m index 39a458f0e7..b5fc65c6fe 100644 --- a/src/Three20Style/Sources/TTStyledButtonNode.m +++ b/src/Three20Style/Sources/TTStyledButtonNode.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,7 +31,8 @@ @implementation TTStyledButtonNode /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithURL:(NSString*)URL { - if (self = [self initWithText:nil URL:URL next:nil]) { + self = [self initWithText:nil URL:URL next:nil]; + if (self) { } return self; @@ -40,7 +41,8 @@ - (id)initWithURL:(NSString*)URL { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithURL:(NSString*)URL next:(TTStyledNode*)nextSibling { - if (self = [self initWithText:nil URL:URL next:nextSibling]) { + self = [self initWithText:nil URL:URL next:nextSibling]; + if (self) { } return self; @@ -49,7 +51,8 @@ - (id)initWithURL:(NSString*)URL next:(TTStyledNode*)nextSibling { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithText:(NSString*)text URL:(NSString*)URL next:(TTStyledNode*)nextSibling { - if (self = [super initWithText:text next:nextSibling]) { + self = [super initWithText:text next:nextSibling]; + if (self) { self.URL = URL; } @@ -59,7 +62,8 @@ - (id)initWithText:(NSString*)text URL:(NSString*)URL next:(TTStyledNode*)nextSi /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithText:nil URL:nil next:nil]) { + self = [self initWithText:nil URL:nil next:nil]; + if (self) { } return self; diff --git a/src/Three20Style/Sources/TTStyledElement.m b/src/Three20Style/Sources/TTStyledElement.m index cf55458649..01554ac4d2 100644 --- a/src/Three20Style/Sources/TTStyledElement.m +++ b/src/Three20Style/Sources/TTStyledElement.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ #import "Three20Style/TTStyledTextNode.h" // Style (private) -#import "Three20Style/TTStyledNodeInternal.h" +#import "Three20Style/private/TTStyledNodeInternal.h" // Core #import "Three20Core/TTCorePreprocessorMacros.h" @@ -38,7 +38,8 @@ @implementation TTStyledElement /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithText:(NSString*)text { - if (self = [self initWithText:text next:nil]) { + self = [self initWithText:text next:nil]; + if (self) { } return self; @@ -47,7 +48,8 @@ - (id)initWithText:(NSString*)text { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithText:(NSString*)text next:(TTStyledNode*)nextSibling { - if (self = [super initWithNextSibling:nextSibling]) { + self = [super initWithNextSibling:nextSibling]; + if (self) { if (nil != text) { [self addChild:[[[TTStyledTextNode alloc] initWithText:text] autorelease]]; } @@ -59,7 +61,8 @@ - (id)initWithText:(NSString*)text next:(TTStyledNode*)nextSibling { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithText:nil next:nil]) { + self = [self initWithText:nil next:nil]; + if (self) { } return self; @@ -95,6 +98,7 @@ - (NSString*)outerText { [strings addObject:node.outerText]; } return [strings componentsJoinedByString:@""]; + } else { return [super outerText]; } @@ -106,11 +110,13 @@ - (NSString*)outerHTML { NSString* html = nil; if (_firstChild) { html = [NSString stringWithFormat:@"
%@
", _firstChild.outerHTML]; + } else { html = @"
"; } if (_nextSibling) { return [NSString stringWithFormat:@"%@%@", html, _nextSibling.outerHTML]; + } else { return html; } @@ -128,6 +134,7 @@ - (void)addChild:(TTStyledNode*)child { if (!_firstChild) { _firstChild = [child retain]; _lastChild = [self findLastSibling:child]; + } else { _lastChild.nextSibling = child; _lastChild = [self findLastSibling:child]; @@ -162,6 +169,7 @@ - (void)replaceChild:(TTStyledNode*)oldChild withChild:(TTStyledNode*)newChild { if (newChild) { newChild.nextSibling = oldChild.nextSibling; node.nextSibling = newChild; + } else { node.nextSibling = oldChild.nextSibling; } diff --git a/src/Three20Style/Sources/TTStyledFrame.m b/src/Three20Style/Sources/TTStyledFrame.m index 31b0fb4918..fde079ca69 100644 --- a/src/Three20Style/Sources/TTStyledFrame.m +++ b/src/Three20Style/Sources/TTStyledFrame.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,7 +32,8 @@ @implementation TTStyledFrame /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithElement:(TTStyledElement*)element { - if (self = [super init]) { + self = [super init]; + if (self) { _element = element; _bounds = CGRectZero; } diff --git a/src/Three20Style/Sources/TTStyledImageFrame.m b/src/Three20Style/Sources/TTStyledImageFrame.m index 859abb5a65..6f5693f4aa 100644 --- a/src/Three20Style/Sources/TTStyledImageFrame.m +++ b/src/Three20Style/Sources/TTStyledImageFrame.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,7 +38,8 @@ @implementation TTStyledImageFrame /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithElement:(TTStyledElement*)element node:(TTStyledImageNode*)node { - if (self = [super initWithElement:element]) { + self = [super initWithElement:element]; + if (self) { _imageNode = node; } diff --git a/src/Three20Style/Sources/TTStyledImageNode.m b/src/Three20Style/Sources/TTStyledImageNode.m index 94c0a6de95..e65ad8e120 100644 --- a/src/Three20Style/Sources/TTStyledImageNode.m +++ b/src/Three20Style/Sources/TTStyledImageNode.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -37,7 +37,8 @@ @implementation TTStyledImageNode /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithURL:(NSString*)URL { - if (self = [super initWithText:nil next:nil]) { + self = [super initWithText:nil next:nil]; + if (self) { self.URL = URL; } @@ -47,7 +48,8 @@ - (id)initWithURL:(NSString*)URL { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithURL:nil]) { + self = [self initWithURL:nil]; + if (self) { } return self; diff --git a/src/Three20Style/Sources/TTStyledInline.m b/src/Three20Style/Sources/TTStyledInline.m index 52f280a98e..02c232ed54 100644 --- a/src/Three20Style/Sources/TTStyledInline.m +++ b/src/Three20Style/Sources/TTStyledInline.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTStyledInlineBlock.m b/src/Three20Style/Sources/TTStyledInlineBlock.m index 3e278be188..ac023e96ff 100644 --- a/src/Three20Style/Sources/TTStyledInlineBlock.m +++ b/src/Three20Style/Sources/TTStyledInlineBlock.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTStyledInlineFrame.m b/src/Three20Style/Sources/TTStyledInlineFrame.m index 18cd4c6734..4d00238805 100644 --- a/src/Three20Style/Sources/TTStyledInlineFrame.m +++ b/src/Three20Style/Sources/TTStyledInlineFrame.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTStyledItalicNode.m b/src/Three20Style/Sources/TTStyledItalicNode.m index 6a5e8e62f0..24cb9a3d38 100644 --- a/src/Three20Style/Sources/TTStyledItalicNode.m +++ b/src/Three20Style/Sources/TTStyledItalicNode.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTStyledLayout.m b/src/Three20Style/Sources/TTStyledLayout.m index 1191338cd3..a56248d50e 100644 --- a/src/Three20Style/Sources/TTStyledLayout.m +++ b/src/Three20Style/Sources/TTStyledLayout.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -51,12 +51,14 @@ @implementation TTStyledLayout @synthesize height = _height; @synthesize rootFrame = _rootFrame; @synthesize font = _font; +@synthesize textAlignment = _textAlignment; @synthesize invalidImages = _invalidImages; /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithRootNode:(TTStyledNode*)rootNode { - if (self = [super init]) { + self = [super init]; + if (self) { _rootNode = rootNode; } @@ -66,7 +68,8 @@ - (id)initWithRootNode:(TTStyledNode*)rootNode { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithX:(CGFloat)x width:(CGFloat)width height:(CGFloat)height { - if (self = [super init]) { + self = [super init]; + if (self) { _x = x; _minX = x; _width = width; @@ -117,6 +120,7 @@ - (TTStyledNode*)findLastNode:(TTStyledNode*)node { if ([node isKindOfClass:[TTStyledElement class]]) { TTStyledElement* element = (TTStyledElement*)node; lastNode = [self findLastNode:element.firstChild]; + } else { lastNode = node; } @@ -176,6 +180,20 @@ - (void)offsetFrame:(TTStyledFrame*)frame by:(CGFloat)y { } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)offsetFrame:(TTStyledFrame*)frame byX:(CGFloat)x { + frame.x += x; + + if ([frame isKindOfClass:[TTStyledInlineFrame class]]) { + TTStyledInlineFrame* inlineFrame = (TTStyledInlineFrame*)frame; + TTStyledFrame* child = inlineFrame.firstChildFrame; + while (child) { + [self offsetFrame:child byX:x]; + child = child.nextFrame; + } + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)expandLineWidth:(CGFloat)width { @@ -209,12 +227,15 @@ - (void)inflateLineHeight:(CGFloat)height { - (void)addFrame:(TTStyledFrame*)frame { if (!_rootFrame) { _rootFrame = [frame retain]; + } else if (_topFrame) { if (!_topFrame.firstChildFrame) { _topFrame.firstChildFrame = frame; + } else { _lastFrame.nextFrame = frame; } + } else { _lastFrame.nextFrame = frame; } @@ -336,18 +357,45 @@ - (void)breakLine { // Vertically align all frames on the current line if (_lineFirstFrame.nextFrame) { - TTStyledFrame* frame = _lineFirstFrame; + TTStyledFrame* frame; + + // Find the descender that descends the farthest below the baseline. + // font.descender is a negative number if the descender descends below + // the baseline (as most descenders do), but can also be a positive + // number for a descender above the baseline. + CGFloat lowestDescender = MAXFLOAT; + frame = _lineFirstFrame; + while (frame) { + UIFont* font = frame.font ? frame.font : _font; + lowestDescender = MIN(lowestDescender, font.descender); + frame = frame.nextFrame; + } + + frame = _lineFirstFrame; while (frame) { // Align to the text baseline // XXXjoe Support top, bottom, and center alignment also if (frame.height < _lineHeight) { UIFont* font = frame.font ? frame.font : _font; - [self offsetFrame:frame by:(_lineHeight - (frame.height - font.descender))]; + [self offsetFrame:frame by:(_lineHeight - (frame.height - + (lowestDescender - font.descender)))]; } frame = frame.nextFrame; } } + // Horizontally align all frames on current line if required + if (_textAlignment != UITextAlignmentLeft) { + CGFloat remainingSpace = _width - _lineWidth; + CGFloat offset = _textAlignment == UITextAlignmentCenter ? remainingSpace/2 : remainingSpace; + + TTStyledFrame* frame = _lineFirstFrame; + while (frame) { + [self offsetFrame:frame byX:offset]; + frame = frame.nextFrame; + } + } + _height += _lineHeight; [self checkFloats]; @@ -402,8 +450,10 @@ - (void)layoutElement:(TTStyledElement*)elt { if ([elt isKindOfClass:[TTStyledLinkNode class]] || [elt isKindOfClass:[TTStyledBoldNode class]]) { font = self.boldFont; + } else if ([elt isKindOfClass:[TTStyledItalicNode class]]) { font = self.italicFont; + } else { font = self.font; } @@ -445,6 +495,7 @@ - (void)layoutElement:(TTStyledElement*)elt { } _minX += contentWidth; _width -= contentWidth; + } else if (padding.position == TTPositionFloatRight) { frame.x += _width - (_floatRightWidth + contentWidth); _floatRightWidth += contentWidth; @@ -458,6 +509,7 @@ - (void)layoutElement:(TTStyledElement*)elt { blockFrame.width = layout.width + padding.padding.left + padding.padding.right; blockFrame.height = frameHeight + padding.padding.top + padding.padding.bottom; } + } else { CGFloat minX = _minX, width = _width, floatLeftWidth = _floatLeftWidth, floatRightWidth = _floatRightWidth, floatHeight = _floatHeight; @@ -481,6 +533,7 @@ - (void)layoutElement:(TTStyledElement*)elt { if (style) { blockFrame = [self addBlockFrame:style element:elt width:_width height:_height]; } + } else { if (padding) { _x += padding.margin.left; @@ -527,6 +580,7 @@ - (void)layoutElement:(TTStyledElement*)elt { _height += padding.margin.bottom; } + } else if (!isBlock && style) { if (padding) { _x += padding.padding.right + padding.margin.right; @@ -585,6 +639,7 @@ - (void)layoutImage:(TTStyledImageNode*)imageNode container:(TTStyledElement*)el // The image will be placed on the next line, so create a new frame for // the current line and mark it with a line break [self breakLine]; + } else { _width = contentWidth; } @@ -598,10 +653,12 @@ - (void)layoutImage:(TTStyledImageNode*)imageNode container:(TTStyledElement*)el [self addContentFrame:frame width:imageWidth height:imageHeight]; [self expandLineWidth:contentWidth]; [self inflateLineHeight:contentHeight]; + } else if (padding.position == TTPositionAbsolute) { [self addAbsoluteFrame:frame width:imageWidth height:imageHeight]; frame.x += padding.margin.left; frame.y += padding.margin.top; + } else if (padding.position == TTPositionFloatLeft) { [self addContentFrame:frame width:imageWidth height:imageHeight]; @@ -612,6 +669,7 @@ - (void)layoutImage:(TTStyledImageNode*)imageNode container:(TTStyledElement*)el } _minX += contentWidth; _width -= contentWidth; + } else if (padding.position == TTPositionFloatRight) { [self addContentFrame:frame width:imageWidth height:imageHeight]; @@ -651,7 +709,8 @@ - (void)layoutText:(TTStyledTextNode*)textNode container:(TTStyledElement*)eleme NSInteger stringIndex = 0; NSInteger lineStartIndex = 0; - CGFloat frameWidth = 0; + CGFloat frameWidth = 0.0f; + NSInteger frameStart = 0; while (stringIndex < length) { // Search for the next whitespace character @@ -679,8 +738,11 @@ - (void)layoutText:(TTStyledTextNode*)textNode container:(TTStyledElement*)eleme NSRange lineRange = NSMakeRange(lineStartIndex, stringIndex - lineStartIndex); if (lineRange.length) { NSString* line = [text substringWithRange:lineRange]; + frameWidth = [[text substringWithRange:NSMakeRange(frameStart, + stringIndex - frameStart)] + sizeWithFont:_font].width; [self addFrameForText:line element:element node:textNode width:frameWidth - height:_lineHeight ? _lineHeight : [_font ttLineHeight]]; + height:[_font ttLineHeight]]; } if (_lineWidth) { @@ -688,10 +750,9 @@ - (void)layoutText:(TTStyledTextNode*)textNode container:(TTStyledElement*)eleme } lineStartIndex = lineRange.location + lineRange.length; - frameWidth = 0; + frameStart = stringIndex; } - frameWidth += letterSize.width; [self expandLineWidth:letterSize.width]; [self inflateLineHeight:wordSize.height]; ++stringIndex; @@ -700,12 +761,15 @@ - (void)layoutText:(TTStyledTextNode*)textNode container:(TTStyledElement*)eleme NSRange lineRange = NSMakeRange(lineStartIndex, stringIndex - lineStartIndex); if (lineRange.length) { NSString* line = [text substringWithRange:lineRange]; + frameWidth = [[text substringWithRange:NSMakeRange(frameStart, stringIndex - frameStart)] + sizeWithFont:_font].width; [self addFrameForText:line element:element node:textNode width:frameWidth - height:_lineHeight ? _lineHeight : [_font ttLineHeight]]; + height:[_font ttLineHeight]]; lineStartIndex = lineRange.location + lineRange.length; - frameWidth = 0; + frameStart = stringIndex; } + } else { if (_lineWidth + wordSize.width > _width) { // The word will be placed on the next line, so create a new frame for @@ -713,15 +777,17 @@ - (void)layoutText:(TTStyledTextNode*)textNode container:(TTStyledElement*)eleme NSRange lineRange = NSMakeRange(lineStartIndex, stringIndex - lineStartIndex); if (lineRange.length) { NSString* line = [text substringWithRange:lineRange]; + frameWidth = [[text substringWithRange:NSMakeRange(frameStart, stringIndex - frameStart)] + sizeWithFont:_font].width; [self addFrameForText:line element:element node:textNode width:frameWidth - height:_lineHeight ? _lineHeight : [_font ttLineHeight]]; + height:[_font ttLineHeight]]; } if (_lineWidth) { [self breakLine]; } lineStartIndex = lineRange.location + lineRange.length; - frameWidth = 0; + frameStart = stringIndex; } if (!_lineWidth && textNode == _lastNode) { @@ -739,7 +805,6 @@ - (void)layoutText:(TTStyledTextNode*)textNode container:(TTStyledElement*)eleme break; } - frameWidth += wordSize.width; [self expandLineWidth:wordSize.width]; [self inflateLineHeight:wordSize.height]; @@ -749,6 +814,8 @@ - (void)layoutText:(TTStyledTextNode*)textNode container:(TTStyledElement*)eleme NSRange lineRange = NSMakeRange(lineStartIndex, (wordRange.location + wordRange.length) - lineStartIndex); NSString* line = !_lineWidth ? word : [text substringWithRange:lineRange]; + frameWidth = [[text substringWithRange:NSMakeRange(frameStart, stringIndex - frameStart)] + sizeWithFont:_font].width; [self addFrameForText:line element:element node:textNode width:frameWidth height:[_font ttLineHeight]]; frameWidth = 0; @@ -790,9 +857,11 @@ - (void)layout:(TTStyledNode*)node container:(TTStyledElement*)element { if ([node isKindOfClass:[TTStyledImageNode class]]) { TTStyledImageNode* imageNode = (TTStyledImageNode*)node; [self layoutImage:imageNode container:element]; + } else if ([node isKindOfClass:[TTStyledElement class]]) { TTStyledElement* elt = (TTStyledElement*)node; [self layoutElement:elt]; + } else if ([node isKindOfClass:[TTStyledTextNode class]]) { TTStyledTextNode* textNode = (TTStyledTextNode*)node; [self layoutText:textNode container:element]; diff --git a/src/Three20Style/Sources/TTStyledLineBreakNode.m b/src/Three20Style/Sources/TTStyledLineBreakNode.m index 92fa6b99c5..e2660ca336 100644 --- a/src/Three20Style/Sources/TTStyledLineBreakNode.m +++ b/src/Three20Style/Sources/TTStyledLineBreakNode.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20Style/Sources/TTStyledLinkNode.m b/src/Three20Style/Sources/TTStyledLinkNode.m index 52f73671da..e0e635fb83 100644 --- a/src/Three20Style/Sources/TTStyledLinkNode.m +++ b/src/Three20Style/Sources/TTStyledLinkNode.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,7 +31,8 @@ @implementation TTStyledLinkNode /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithURL:(NSString*)URL { - if (self = [self initWithText:nil URL:URL next:nil]) { + self = [self initWithText:nil URL:URL next:nil]; + if (self) { } return self; @@ -40,7 +41,8 @@ - (id)initWithURL:(NSString*)URL { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithURL:(NSString*)URL next:(TTStyledNode*)nextSibling { - if (self = [self initWithText:nil URL:URL next:nextSibling]) { + self = [self initWithText:nil URL:URL next:nextSibling]; + if (self) { } return self; @@ -49,7 +51,8 @@ - (id)initWithURL:(NSString*)URL next:(TTStyledNode*)nextSibling { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithText:(NSString*)text URL:(NSString*)URL next:(TTStyledNode*)nextSibling { - if (self = [super initWithText:text next:nextSibling]) { + self = [super initWithText:text next:nextSibling]; + if (self) { self.URL = URL; } @@ -59,7 +62,8 @@ - (id)initWithText:(NSString*)text URL:(NSString*)URL next:(TTStyledNode*)nextSi /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithText:nil URL:nil next:nil]) { + self = [self initWithText:nil URL:nil next:nil]; + if (self) { } return self; diff --git a/src/Three20Style/Sources/TTStyledNode.m b/src/Three20Style/Sources/TTStyledNode.m index 74fa9bc8d8..71f5c95373 100644 --- a/src/Three20Style/Sources/TTStyledNode.m +++ b/src/Three20Style/Sources/TTStyledNode.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,7 +31,8 @@ @implementation TTStyledNode /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNextSibling:(TTStyledNode*)nextSibling { - if (self = [super init]) { + self = [super init]; + if (self) { self.nextSibling = nextSibling; } @@ -41,7 +42,8 @@ - (id)initWithNextSibling:(TTStyledNode*)nextSibling { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithNextSibling:nil]) { + self = [self initWithNextSibling:nil]; + if (self) { } return self; @@ -82,6 +84,7 @@ - (NSString*)outerText { - (NSString*)outerHTML { if (_nextSibling) { return _nextSibling.outerHTML; + } else { return @""; } @@ -92,6 +95,7 @@ - (NSString*)outerHTML { - (id)ancestorOrSelfWithClass:(Class)cls { if ([self isKindOfClass:cls]) { return self; + } else { return [_parentNode ancestorOrSelfWithClass:cls]; } diff --git a/src/Three20Style/Sources/TTStyledNodeInternal.m b/src/Three20Style/Sources/TTStyledNodeInternal.m index 882c3a74df..7cded31c2b 100644 --- a/src/Three20Style/Sources/TTStyledNodeInternal.m +++ b/src/Three20Style/Sources/TTStyledNodeInternal.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,12 +14,17 @@ // limitations under the License. // -#import "Three20Style/TTStyledNodeInternal.h" +#import "Three20Style/private/TTStyledNodeInternal.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +TT_FIX_CATEGORY_BUG(TTStyledNodeInternal) + @implementation TTStyledNode (TTInternal) @@ -36,4 +41,3 @@ - (TTStyledNode*)findLastSibling:(TTStyledNode*)sibling { @end - diff --git a/src/Three20Style/Sources/TTStyledText.m b/src/Three20Style/Sources/TTStyledText.m index bd58b42d0f..14e4aa449f 100644 --- a/src/Three20Style/Sources/TTStyledText.m +++ b/src/Three20Style/Sources/TTStyledText.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -42,6 +42,9 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// @interface TTStyledText() +/** + * Cancels all network requests. + */ - (void)stopLoadingImages; @end @@ -54,6 +57,7 @@ @implementation TTStyledText @synthesize rootNode = _rootNode; @synthesize font = _font; +@synthesize textAlignment = _textAlignment; @synthesize width = _width; @synthesize height = _height; @synthesize invalidImages = _invalidImages; @@ -62,7 +66,8 @@ @implementation TTStyledText /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNode:(TTStyledNode*)rootNode { - if (self = [super init]) { + self = [super init]; + if (self) { _rootNode = [rootNode retain]; } @@ -296,6 +301,14 @@ - (void)setFont:(UIFont*)font { } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setTextAlignment:(UITextAlignment)textAlignment { + if (textAlignment != _textAlignment) { + _textAlignment = textAlignment; + [self setNeedsLayout]; + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setWidth:(CGFloat)width { @@ -324,6 +337,7 @@ - (void)layoutFrames { TTStyledLayout* layout = [[TTStyledLayout alloc] initWithRootNode:_rootNode]; layout.width = _width; layout.font = _font; + layout.textAlignment = _textAlignment; [layout layout:_rootNode]; [_rootFrame release]; @@ -390,6 +404,7 @@ - (TTStyledFrame*)getFrameForNode:(TTStyledNode*)node { - (void)addChild:(TTStyledNode*)child { if (!_rootNode) { self.rootNode = child; + } else { TTStyledNode* previousNode = _rootNode; TTStyledNode* node = _rootNode.nextSibling; @@ -412,9 +427,11 @@ - (void)addText:(NSString*)text { - (void)insertChild:(TTStyledNode*)child atIndex:(NSInteger)insertIndex { if (!_rootNode) { self.rootNode = child; + } else if (insertIndex == 0) { child.nextSibling = _rootNode; self.rootNode = child; + } else { NSInteger i = 0; TTStyledNode* previousNode = _rootNode; diff --git a/src/Three20Style/Sources/TTStyledTextFrame.m b/src/Three20Style/Sources/TTStyledTextFrame.m index cd3760d23a..b6950936e5 100644 --- a/src/Three20Style/Sources/TTStyledTextFrame.m +++ b/src/Three20Style/Sources/TTStyledTextFrame.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,7 +32,8 @@ @implementation TTStyledTextFrame /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithText:(NSString*)text element:(TTStyledElement*)element node:(TTStyledTextNode*)node { - if (self = [super initWithElement:element]) { + self = [super initWithElement:element]; + if (self) { _text = [text copy]; _node = node; } diff --git a/src/Three20Style/Sources/TTStyledTextNode.m b/src/Three20Style/Sources/TTStyledTextNode.m index f26dda5df4..0ebd23967c 100644 --- a/src/Three20Style/Sources/TTStyledTextNode.m +++ b/src/Three20Style/Sources/TTStyledTextNode.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,7 +30,8 @@ @implementation TTStyledTextNode /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithText:(NSString*)text { - if (self = [self initWithText:text next:nil]) { + self = [self initWithText:text next:nil]; + if (self) { } return self; @@ -39,7 +40,8 @@ - (id)initWithText:(NSString*)text { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithText:(NSString*)text next:(TTStyledNode*)nextSibling { - if (self = [super initWithNextSibling:nextSibling]) { + self = [super initWithNextSibling:nextSibling]; + if (self) { self.text = text; } diff --git a/src/Three20Style/Sources/TTStyledTextParser.m b/src/Three20Style/Sources/TTStyledTextParser.m index 2182976d22..22afcc8dc8 100644 --- a/src/Three20Style/Sources/TTStyledTextParser.m +++ b/src/Three20Style/Sources/TTStyledTextParser.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -114,8 +114,22 @@ - (void)parseURLs:(NSString*)string { while (stringIndex < string.length) { NSRange searchRange = NSMakeRange(stringIndex, string.length - stringIndex); - NSRange startRange = [string rangeOfString:@"http://" options:NSCaseInsensitiveSearch + NSRange httpRange = [string rangeOfString:@"http://" options:NSCaseInsensitiveSearch + range:searchRange]; + NSRange httpsRange = [string rangeOfString:@"https://" options:NSCaseInsensitiveSearch range:searchRange]; + + NSRange startRange; + if (httpRange.location == NSNotFound) { + startRange = httpsRange; + + } else if (httpsRange.location == NSNotFound) { + startRange = httpRange; + + } else { + startRange = (httpRange.location < httpsRange.location) ? httpRange : httpsRange; + } + if (startRange.location == NSNotFound) { NSString* text = [string substringWithRange:searchRange]; TTStyledTextNode* node = [[[TTStyledTextNode alloc] initWithText:text] autorelease]; @@ -131,7 +145,8 @@ - (void)parseURLs:(NSString*)string { [self addNode:node]; } - NSRange subSearchRange = NSMakeRange(startRange.location, string.length - startRange.location); + NSRange subSearchRange = NSMakeRange(startRange.location, + string.length - startRange.location); NSRange endRange = [string rangeOfString:@" " options:NSCaseInsensitiveSearch range:subSearchRange]; if (endRange.location == NSNotFound) { @@ -183,17 +198,18 @@ - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName node.className = [attributeDict objectForKey:@"class"]; [self pushNode:node]; - } else if ([tag isEqualToString:@"b"]) { + } else if ([tag isEqualToString:@"b"] || [tag isEqualToString:@"strong"]) { TTStyledBoldNode* node = [[[TTStyledBoldNode alloc] init] autorelease]; [self pushNode:node]; - } else if ([tag isEqualToString:@"i"]) { + } else if ([tag isEqualToString:@"i"] || [tag isEqualToString:@"em"]) { TTStyledItalicNode* node = [[[TTStyledItalicNode alloc] init] autorelease]; [self pushNode:node]; } else if ([tag isEqualToString:@"a"]) { TTStyledLinkNode* node = [[[TTStyledLinkNode alloc] init] autorelease]; node.URL = [attributeDict objectForKey:@"href"]; + node.className = [attributeDict objectForKey:@"class"]; [self pushNode:node]; } else if ([tag isEqualToString:@"button"]) { @@ -238,7 +254,9 @@ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName /////////////////////////////////////////////////////////////////////////////////////////////////// -- (NSData *)parser:(NSXMLParser *)parser resolveExternalEntityName:(NSString *)entityName systemID:(NSString *)systemID { +- (NSData *) parser:(NSXMLParser *)parser + resolveExternalEntityName:(NSString *)entityName + systemID:(NSString *)systemID { static NSDictionary* entityTable = nil; if (!entityTable) { entityTable = [[NSDictionary alloc] initWithObjectsAndKeys: @@ -253,6 +271,18 @@ - (NSData *)parser:(NSXMLParser *)parser resolveExternalEntityName:(NSString *)e } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)parseText:(NSString*)string URLs:(BOOL)shouldParseURLs { + if (shouldParseURLs) { + [self parseURLs:string]; + } + else { + TTStyledTextNode* node = [[[TTStyledTextNode alloc] initWithText:string] autorelease]; + [self addNode:node]; + } +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - @@ -283,7 +313,7 @@ - (void)parseText:(NSString*)string { // Find all text before the line break and parse it NSRange textRange = NSMakeRange(stringIndex, range.location - stringIndex); NSString* substr = [string substringWithRange:textRange]; - [self parseURLs:substr]; + [self parseText:substr URLs:_parseURLs]; // Add a line break node after the text TTStyledLineBreakNode* br = [[[TTStyledLineBreakNode alloc] init] autorelease]; @@ -291,20 +321,18 @@ - (void)parseText:(NSString*)string { stringIndex = stringIndex + substr.length + 1; - } else { + } + else { // Find all text until the end of hte string and parse it NSString* substr = [string substringFromIndex:stringIndex]; - [self parseURLs:substr]; + [self parseText:substr URLs:_parseURLs]; break; } } - } else if (_parseURLs) { - [self parseURLs:string]; - - } else { - TTStyledTextNode* node = [[[TTStyledTextNode alloc] initWithText:string] autorelease]; - [self addNode:node]; + } + else { + [self parseText:string URLs:_parseURLs]; } } diff --git a/src/Three20Style/Sources/TTTextStyle.m b/src/Three20Style/Sources/TTTextStyle.m index f87200f775..b22c33d337 100644 --- a/src/Three20Style/Sources/TTTextStyle.m +++ b/src/Three20Style/Sources/TTTextStyle.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #import "Three20Style/UIFontAdditions.h" // Core +#import "Three20Core/NSStringAdditions.h" #import "Three20Core/TTCorePreprocessorMacros.h" @@ -43,7 +44,8 @@ @implementation TTTextStyle /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNext:(TTStyle*)next { - if (self = [super initWithNext:next]) { + self = [super initWithNext:next]; + if (self) { _shadowOffset = CGSizeZero; _numberOfLines = 1; _textAlignment = UITextAlignmentCenter; @@ -189,6 +191,7 @@ - (CGRect)rectForText:(NSString*)text forSize:(CGSize)size withFont:(UIFont*)fon if (_textAlignment == UITextAlignmentLeft && _verticalAlignment == UIControlContentVerticalAlignmentTop) { rect.size = size; + } else { CGSize textSize = [self sizeOfText:text withFont:font size:size]; @@ -200,12 +203,14 @@ - (CGRect)rectForText:(NSString*)text forSize:(CGSize)size withFont:(UIFont*)fon if (_textAlignment == UITextAlignmentCenter) { rect.origin.x = round(size.width/2 - textSize.width/2); + } else if (_textAlignment == UITextAlignmentRight) { rect.origin.x = size.width - textSize.width; } if (_verticalAlignment == UIControlContentVerticalAlignmentCenter) { rect.origin.y = round(size.height/2 - textSize.height/2); + } else if (_verticalAlignment == UIControlContentVerticalAlignmentBottom) { rect.origin.y = size.height - textSize.height; } @@ -226,7 +231,16 @@ - (void)drawText:(NSString*)text context:(TTStyleContext*)context { } if (_shadowColor) { - CGSize offset = CGSizeMake(_shadowOffset.width, -_shadowOffset.height); + // Due to a bug in OS versions 3.2 and 4.0, the shadow appears upside-down. It pains me to + // write this, but a lot of research has failed to turn up a way to detect the flipped shadow + // programmatically + float shadowYOffset = -_shadowOffset.height; + NSString *osVersion = [UIDevice currentDevice].systemVersion; + if ([osVersion versionStringCompare:@"3.2"] != NSOrderedAscending) { + shadowYOffset = _shadowOffset.height; + } + + CGSize offset = CGSizeMake(_shadowOffset.width, shadowYOffset); CGContextSetShadowWithColor(ctx, offset, 0, _shadowColor.CGColor); } @@ -239,12 +253,14 @@ - (void)drawText:(NSString*)text context:(TTStyleContext*)context { if (_numberOfLines == 1) { CGRect titleRect = [self rectForText:text forSize:rect.size withFont:font]; titleRect.size = [text drawAtPoint: - CGPointMake(titleRect.origin.x+rect.origin.x, titleRect.origin.y+rect.origin.y) + CGPointMake(titleRect.origin.x+rect.origin.x, + titleRect.origin.y+rect.origin.y) forWidth:rect.size.width withFont:font minFontSize:_minimumFontSize ? _minimumFontSize : font.pointSize actualFontSize:nil lineBreakMode:_lineBreakMode baselineAdjustment:UIBaselineAdjustmentAlignCenters]; context.contentFrame = titleRect; + } else { CGRect titleRect = [self rectForText:text forSize:rect.size withFont:font]; titleRect = CGRectOffset(titleRect, rect.origin.x, rect.origin.y); @@ -303,6 +319,7 @@ - (CGSize)addToSize:(CGSize)size context:(TTStyleContext*)context { if (_next) { return [self.next addToSize:size context:context]; + } else { return size; } diff --git a/src/Three20Style/Sources/UIColorAdditions.m b/src/Three20Style/Sources/UIColorAdditions.m index f06f56b92d..05b285ed22 100644 --- a/src/Three20Style/Sources/UIColorAdditions.m +++ b/src/Three20Style/Sources/UIColorAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,10 @@ #import "Three20Style/UIColorAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + + /////////////////////////////////////////////////////////////////////////////////////////////////// // Color algorithms from http://www.cs.rit.edu/~ncs/color/t_convert.html @@ -30,7 +34,7 @@ void RGBtoHSV(float r, float g, float b, float* h, float* s, float* v) { max = MAX3(r, g, b); *v = max; // v delta = max - min; - if( max != 0 ) + if ( max != 0 ) *s = delta / max; // s else { // r = g = b = 0 // s = 0, v is undefined @@ -38,14 +42,14 @@ void RGBtoHSV(float r, float g, float b, float* h, float* s, float* v) { *h = -1; return; } - if( r == max ) + if ( r == max ) *h = ( g - b ) / delta; // between yellow & magenta - else if( g == max ) + else if ( g == max ) *h = 2 + ( b - r ) / delta; // between cyan & yellow else *h = 4 + ( r - g ) / delta; // between magenta & cyan *h *= 60; // degrees - if( *h < 0 ) + if ( *h < 0 ) *h += 360; } @@ -54,7 +58,7 @@ void RGBtoHSV(float r, float g, float b, float* h, float* s, float* v) { void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v ) { int i; float f, p, q, t; - if( s == 0 ) { + if ( s == 0 ) { // achromatic (grey) *r = *g = *b = v; return; @@ -106,6 +110,8 @@ void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v ) { /** * Additions. */ +TT_FIX_CATEGORY_BUG(UIColorAdditions) + @implementation UIColor (TTCategory) diff --git a/src/Three20Style/Sources/UIFontAdditions.m b/src/Three20Style/Sources/UIFontAdditions.m index aba29f0632..24652d7aa0 100644 --- a/src/Three20Style/Sources/UIFontAdditions.m +++ b/src/Three20Style/Sources/UIFontAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20Style/UIFontAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -23,6 +26,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UIFontAdditions) + @implementation UIFont (TTCategory) diff --git a/src/Three20Style/Sources/UIImageAdditions.m b/src/Three20Style/Sources/UIImageAdditions.m index a9d500442e..8003cbb4f6 100644 --- a/src/Three20Style/Sources/UIImageAdditions.m +++ b/src/Three20Style/Sources/UIImageAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20Style/UIImageAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -23,6 +26,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UIImageAdditions) + @implementation UIImage (TTCategory) @@ -40,6 +45,7 @@ - (void)addRoundedRectToPath:(CGContextRef)context rect:(CGRect)rect radius:(flo if (radius == 0) { CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextAddRect(context, rect); + } else { CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextScaleCTM(context, radius, radius); @@ -92,9 +98,11 @@ - (UIImage*)transformWidth:(CGFloat)width height:(CGFloat)height rotate:(BOOL)ro if (self.imageOrientation == UIImageOrientationDown) { CGContextTranslateCTM(bitmap, sourceW, sourceH); CGContextRotateCTM(bitmap, 180 * (M_PI/180)); + } else if (self.imageOrientation == UIImageOrientationLeft) { CGContextTranslateCTM(bitmap, sourceH, 0); CGContextRotateCTM(bitmap, 90 * (M_PI/180)); + } else if (self.imageOrientation == UIImageOrientationRight) { CGContextTranslateCTM(bitmap, 0, sourceW); CGContextRotateCTM(bitmap, -90 * (M_PI/180)); @@ -119,44 +127,54 @@ - (CGRect)convertRect:(CGRect)rect withContentMode:(UIViewContentMode)contentMod return CGRectMake(rect.origin.x, rect.origin.y + floor(rect.size.height/2 - self.size.height/2), self.size.width, self.size.height); + } else if (contentMode == UIViewContentModeRight) { return CGRectMake(rect.origin.x + (rect.size.width - self.size.width), rect.origin.y + floor(rect.size.height/2 - self.size.height/2), self.size.width, self.size.height); + } else if (contentMode == UIViewContentModeTop) { return CGRectMake(rect.origin.x + floor(rect.size.width/2 - self.size.width/2), rect.origin.y, self.size.width, self.size.height); + } else if (contentMode == UIViewContentModeBottom) { return CGRectMake(rect.origin.x + floor(rect.size.width/2 - self.size.width/2), rect.origin.y + floor(rect.size.height - self.size.height), self.size.width, self.size.height); + } else if (contentMode == UIViewContentModeCenter) { return CGRectMake(rect.origin.x + floor(rect.size.width/2 - self.size.width/2), rect.origin.y + floor(rect.size.height/2 - self.size.height/2), self.size.width, self.size.height); + } else if (contentMode == UIViewContentModeBottomLeft) { return CGRectMake(rect.origin.x, rect.origin.y + floor(rect.size.height - self.size.height), self.size.width, self.size.height); + } else if (contentMode == UIViewContentModeBottomRight) { return CGRectMake(rect.origin.x + (rect.size.width - self.size.width), rect.origin.y + (rect.size.height - self.size.height), self.size.width, self.size.height); + } else if (contentMode == UIViewContentModeTopLeft) { return CGRectMake(rect.origin.x, rect.origin.y, self.size.width, self.size.height); + } else if (contentMode == UIViewContentModeTopRight) { return CGRectMake(rect.origin.x + (rect.size.width - self.size.width), rect.origin.y, self.size.width, self.size.height); + } else if (contentMode == UIViewContentModeScaleAspectFill) { CGSize imageSize = self.size; if (imageSize.height < imageSize.width) { imageSize.width = floor((imageSize.width/imageSize.height) * rect.size.height); imageSize.height = rect.size.height; + } else { imageSize.height = floor((imageSize.height/imageSize.width) * rect.size.width); imageSize.width = rect.size.width; @@ -164,11 +182,13 @@ - (CGRect)convertRect:(CGRect)rect withContentMode:(UIViewContentMode)contentMod return CGRectMake(rect.origin.x + floor(rect.size.width/2 - imageSize.width/2), rect.origin.y + floor(rect.size.height/2 - imageSize.height/2), imageSize.width, imageSize.height); + } else if (contentMode == UIViewContentModeScaleAspectFit) { CGSize imageSize = self.size; if (imageSize.height < imageSize.width) { imageSize.height = floor((imageSize.height/imageSize.width) * rect.size.width); imageSize.width = rect.size.width; + } else { imageSize.width = floor((imageSize.width/imageSize.height) * rect.size.height); imageSize.height = rect.size.height; diff --git a/src/Three20Style/Three20Style.xcodeproj/project.pbxproj b/src/Three20Style/Three20Style.xcodeproj/project.pbxproj index 0fade321b1..eef24f09d3 100755 --- a/src/Three20Style/Three20Style.xcodeproj/project.pbxproj +++ b/src/Three20Style/Three20Style.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -205,6 +205,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 66313A7D1267B4E800C09C9F /* Three20Style_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Three20Style_Prefix.pch; path = Headers/Three20Style_Prefix.pch; sourceTree = ""; }; 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Project.xcconfig; path = Configurations/Project.xcconfig; sourceTree = ""; }; 6E64548F1184D3BC00F08CB1 /* Three20Style+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Three20Style+Additions.h"; path = "Headers/Three20Style+Additions.h"; sourceTree = ""; }; 6E6464021187F5CB00F08CB1 /* TTStyledButtonNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTStyledButtonNode.h; path = Headers/TTStyledButtonNode.h; sourceTree = ""; }; @@ -338,7 +339,7 @@ 6EE739981184B9CE00A35176 /* StyleAdditionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StyleAdditionTests.m; path = UnitTests/StyleAdditionTests.m; sourceTree = ""; }; 6EE739991184B9CE00A35176 /* StyleGlobalTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StyleGlobalTests.m; path = UnitTests/StyleGlobalTests.m; sourceTree = ""; }; BEF31F3A0F352DF5000DE5D2 /* libThree20Style.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libThree20Style.a; sourceTree = BUILT_PRODUCTS_DIR; }; - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB9E6C6210B6A8F800DE563C /* StyleUnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StyleUnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -366,7 +367,7 @@ isa = PBXGroup; children = ( BEF31F3A0F352DF5000DE5D2 /* libThree20Style.a */, - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */, + EB9E6C6210B6A8F800DE563C /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -376,6 +377,7 @@ children = ( 6EE738C11184AE4A00A35176 /* Three20Style.h */, 6E64548F1184D3BC00F08CB1 /* Three20Style+Additions.h */, + 66313A7D1267B4E800C09C9F /* Three20Style_Prefix.pch */, 6EE737001184A1D500A35176 /* Source */, 6E08B743118397FA00DA1579 /* Dependencies */, 6EE7364D11849B4200A35176 /* Configurations */, @@ -724,7 +726,7 @@ isa = PBXGroup; children = ( 6EE738A31184ADB400A35176 /* libThree20Network.a */, - 6EE738A51184ADB400A35176 /* UnitTests.octest */, + 6EE738A51184ADB400A35176 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -814,6 +816,7 @@ BEF31F360F352DF5000DE5D2 /* Headers */, 6E645F2C1187AFFE00F08CB1 /* Protect Copied Headers */, BEF31F370F352DF5000DE5D2 /* Sources */, + 668E65BA131ADFB500ACE4AB /* Lint */, BEF31F380F352DF5000DE5D2 /* Frameworks */, ); buildRules = ( @@ -827,9 +830,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libThree20Style.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTests */ = { + EB9E6C6110B6A8F800DE563C /* Three20StyleUnitTests */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20StyleUnitTests" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -843,9 +846,9 @@ 6EE738AD1184ADE300A35176 /* PBXTargetDependency */, 6EE736C711849FA000A35176 /* PBXTargetDependency */, ); - name = UnitTests; + name = Three20StyleUnitTests; productName = CoreUnitTests; - productReference = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + productReference = EB9E6C6210B6A8F800DE563C /* StyleUnitTests.octest */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -853,9 +856,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0430; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Three20Style" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -871,7 +885,7 @@ projectRoot = ""; targets = ( BEF31F390F352DF5000DE5D2 /* Three20Style */, - EB9E6C6110B6A8F800DE563C /* UnitTests */, + EB9E6C6110B6A8F800DE563C /* Three20StyleUnitTests */, ); }; /* End PBXProject section */ @@ -898,10 +912,10 @@ remoteRef = 6EE738A21184ADB400A35176 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6EE738A51184ADB400A35176 /* UnitTests.octest */ = { + 6EE738A51184ADB400A35176 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6EE738A41184ADB400A35176 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -918,6 +932,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 668E65BA131ADFB500ACE4AB /* Lint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = Lint; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/usr/bin/env python ../scripts/lint"; + shellScript = ""; + showEnvVarsInLog = 0; + }; 6E645F2C1187AFFE00F08CB1 /* Protect Copied Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1058,14 +1087,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; @@ -1077,9 +1103,10 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; @@ -1094,13 +1121,12 @@ "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; - SDKROOT = iphonesimulator4.0; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Internal; @@ -1113,7 +1139,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -1123,8 +1149,7 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -1133,14 +1158,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -1148,13 +1170,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -1169,12 +1189,11 @@ "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Debug; @@ -1190,11 +1209,10 @@ "\"$(SDKROOT)/Developer/Library/Frameworks\"", "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", ); - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; HEADER_SEARCH_PATHS = .; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; ZERO_LINK = NO; }; @@ -1223,7 +1241,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20StyleUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/Three20Style/UnitTests/StyleAdditionTests.m b/src/Three20Style/UnitTests/StyleAdditionTests.m index b3668cb18d..64009628dd 100644 --- a/src/Three20Style/UnitTests/StyleAdditionTests.m +++ b/src/Three20Style/UnitTests/StyleAdditionTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,8 +14,7 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. +// See: http://bit.ly/hS5nNh for unit test macros. #import #import diff --git a/src/Three20Style/UnitTests/StyleGlobalTests.m b/src/Three20Style/UnitTests/StyleGlobalTests.m index f104d36ec7..6573b09bfe 100644 --- a/src/Three20Style/UnitTests/StyleGlobalTests.m +++ b/src/Three20Style/UnitTests/StyleGlobalTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,8 +14,7 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. +// See: http://bit.ly/hS5nNh for unit test macros. #import #import diff --git a/src/Three20UI/Configurations/Library.xcconfig b/src/Three20UI/Configurations/Library.xcconfig index 398804fbc0..1caac98245 100644 --- a/src/Three20UI/Configurations/Library.xcconfig +++ b/src/Three20UI/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,5 +17,6 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = Three20UI +BASE_PRODUCT_NAME = Three20UI +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/src/Three20UI/Configurations/Project.xcconfig b/src/Three20UI/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/Three20UI/Configurations/Project.xcconfig +++ b/src/Three20UI/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Configurations/UnitTests.xcconfig b/src/Three20UI/Configurations/UnitTests.xcconfig index 9220f171ff..16b0a5342f 100644 --- a/src/Three20UI/Configurations/UnitTests.xcconfig +++ b/src/Three20UI/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = UIUnitTests -BUILD_BUNDLE_VERSION = 1.0 +BASE_PRODUCT_NAME = UIUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME) +BUILD_BUNDLE_VERSION = 1.0 -OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) $(COREGRAPHICS_FX) $(QUARTZCORE_FX) +OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) $(COREGRAPHICS_FX) $(QUARTZCORE_FX) diff --git a/src/Three20UI/Headers/TTActionSheet.h b/src/Three20UI/Headers/TTActionSheet.h index af07b607c2..a1e706e7ea 100644 --- a/src/Three20UI/Headers/TTActionSheet.h +++ b/src/Three20UI/Headers/TTActionSheet.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTActionSheetController.h b/src/Three20UI/Headers/TTActionSheetController.h index df5256850a..c69a56d498 100644 --- a/src/Three20UI/Headers/TTActionSheetController.h +++ b/src/Three20UI/Headers/TTActionSheetController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTActionSheetControllerDelegate.h b/src/Three20UI/Headers/TTActionSheetControllerDelegate.h index 46257cccc0..d65ca5c4ad 100644 --- a/src/Three20UI/Headers/TTActionSheetControllerDelegate.h +++ b/src/Three20UI/Headers/TTActionSheetControllerDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTActivityLabel.h b/src/Three20UI/Headers/TTActivityLabel.h index c04a3684b6..a153cd6669 100644 --- a/src/Three20UI/Headers/TTActivityLabel.h +++ b/src/Three20UI/Headers/TTActivityLabel.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -45,8 +45,8 @@ typedef enum { @property (nonatomic, readonly) TTActivityLabelStyle style; -@property (nonatomic, assign) NSString* text; -@property (nonatomic, assign) UIFont* font; +@property (nonatomic, copy) NSString* text; +@property (nonatomic, retain) UIFont* font; @property (nonatomic) float progress; @property (nonatomic) BOOL isAnimating; diff --git a/src/Three20UI/Headers/TTAlertView.h b/src/Three20UI/Headers/TTAlertView.h index bcd47b0692..95b278f65c 100644 --- a/src/Three20UI/Headers/TTAlertView.h +++ b/src/Three20UI/Headers/TTAlertView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTAlertViewController.h b/src/Three20UI/Headers/TTAlertViewController.h index 9c0f746e58..0bc0c4da3e 100644 --- a/src/Three20UI/Headers/TTAlertViewController.h +++ b/src/Three20UI/Headers/TTAlertViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTAlertViewControllerDelegate.h b/src/Three20UI/Headers/TTAlertViewControllerDelegate.h index 929c2ade53..073cb27886 100644 --- a/src/Three20UI/Headers/TTAlertViewControllerDelegate.h +++ b/src/Three20UI/Headers/TTAlertViewControllerDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTButton.h b/src/Three20UI/Headers/TTButton.h index b96412fe80..ab250acb48 100644 --- a/src/Three20UI/Headers/TTButton.h +++ b/src/Three20UI/Headers/TTButton.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ - (void)setTitle:(NSString*)title forState:(UIControlState)state; - (NSString*)imageForState:(UIControlState)state; -- (void)setImage:(NSString*)title forState:(UIControlState)state; +- (void)setImage:(NSString*)imageURL forState:(UIControlState)state; - (TTStyle*)styleForState:(UIControlState)state; - (void)setStyle:(TTStyle*)style forState:(UIControlState)state; diff --git a/src/Three20UI/Headers/TTButtonBar.h b/src/Three20UI/Headers/TTButtonBar.h index fe8a88a44b..0fea86fb7f 100644 --- a/src/Three20UI/Headers/TTButtonBar.h +++ b/src/Three20UI/Headers/TTButtonBar.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,8 +25,8 @@ NSString* _buttonStyle; } -@property (nonatomic, retain) NSArray* buttons; -@property (nonatomic, copy) NSString* buttonStyle; +@property (nonatomic, copy) NSArray* buttons; +@property (nonatomic, copy) NSString* buttonStyle; - (void)addButton:(NSString*)title target:(id)target action:(SEL)selector; - (void)removeButtons; diff --git a/src/Three20UI/Headers/TTButtonContent.h b/src/Three20UI/Headers/TTButtonContent.h index 8d0875c4ba..9299622c32 100644 --- a/src/Three20UI/Headers/TTButtonContent.h +++ b/src/Three20UI/Headers/TTButtonContent.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTErrorView.h b/src/Three20UI/Headers/TTErrorView.h index 3e6ee78b99..4341eb42da 100644 --- a/src/Three20UI/Headers/TTErrorView.h +++ b/src/Three20UI/Headers/TTErrorView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,19 +14,30 @@ // limitations under the License. // -#import -#import +// UI +#import "Three20UI/TTButton.h" @interface TTErrorView : UIView { UIImageView* _imageView; UILabel* _titleView; UILabel* _subtitleView; + TTButton* _reloadButton; } @property (nonatomic, retain) UIImage* image; @property (nonatomic, copy) NSString* title; @property (nonatomic, copy) NSString* subtitle; +@property (nonatomic, copy) TTButton* reloadButton; + +/** + * creates an error view + */ - (id)initWithTitle:(NSString*)title subtitle:(NSString*)subtitle image:(UIImage*)image; +/** + * adds a reload button into the error view + */ +- (void)addReloadButton; + @end diff --git a/src/Three20UI/Headers/TTExtensionInfoController.h b/src/Three20UI/Headers/TTExtensionInfoController.h new file mode 100644 index 0000000000..3390661996 --- /dev/null +++ b/src/Three20UI/Headers/TTExtensionInfoController.h @@ -0,0 +1,32 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UI/TTTableViewController.h" + +@class TTExtensionInfo; + +/** + * Display information about a specific extension. + * + * @see TTExtensionInfo + */ +@interface TTExtensionInfoController : TTTableViewController { +@private + TTExtensionInfo* _extension; + +} + +@end diff --git a/src/Three20UI/Headers/TTExtensionsController.h b/src/Three20UI/Headers/TTExtensionsController.h new file mode 100644 index 0000000000..06bad6b0ea --- /dev/null +++ b/src/Three20UI/Headers/TTExtensionsController.h @@ -0,0 +1,46 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UI/TTTableViewController.h" + +@class TTNavigator; + +/** + * A list of all available, loaded, and failed extensions. This controller is used in + * conjunction with the TTExtensionLoader. It is intended to provide helpful information + * about the extensions linked in the application. It can also be used as a means of + * crediting the extensions whose licenses require it. + * + * @see TTExtensionLoader + */ +@interface TTExtensionsController : TTTableViewController { + +} + +/** + * Registers two URLs with the given navigator (e.g. with a prefix of @"tt://") + * + * * @"tt://extensions" -> [TTExtensionsController class] + * * @"tt://extensions/(initWithExtensionID:)" -> [TTExtensionInfoController class] + * + * You can use any prefix (e.g. @"myApp://three20/") + * + * * @"myApp://three20/extensions" -> [TTExtensionsController class] + * * @"myApp://three20/extensions/(initWithExtensionID:)" -> [TTExtensionInfoController class] + */ ++ (void)registerUrlPathsWithNavigator:(TTNavigator*)navigator prefix:(NSString*)prefix; + +@end diff --git a/src/Three20UI/Headers/TTImageLayer.h b/src/Three20UI/Headers/TTImageLayer.h index 7dcaea4354..61ef9fc7d7 100644 --- a/src/Three20UI/Headers/TTImageLayer.h +++ b/src/Three20UI/Headers/TTImageLayer.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTImageView.h b/src/Three20UI/Headers/TTImageView.h index 98d7ba6303..d456c9627f 100644 --- a/src/Three20UI/Headers/TTImageView.h +++ b/src/Three20UI/Headers/TTImageView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -76,6 +76,11 @@ */ @property (nonatomic, assign) id delegate; +/** + * The TTURLRequest requester used to load this image. + */ +@property (nonatomic, readonly) TTURLRequest* request; + /** * Cancel any pending request, remove the image, and redraw the view. */ diff --git a/src/Three20UI/Headers/TTImageViewDelegate.h b/src/Three20UI/Headers/TTImageViewDelegate.h index f9c7abaebe..ecea9b5264 100644 --- a/src/Three20UI/Headers/TTImageViewDelegate.h +++ b/src/Three20UI/Headers/TTImageViewDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,4 +38,11 @@ */ - (void)imageView:(TTImageView*)imageView didFailLoadWithError:(NSError*)error; +/** + * Called before the image view send a network request. + * At this point we have the opportunity to configure the requester + * with some custom options (to use ETAGs, for example). + */ +- (void)imageView:(TTImageView*)imageView willSendARequest:(TTURLRequest*)requester; + @end diff --git a/src/Three20UI/Headers/TTImageViewInternal.h b/src/Three20UI/Headers/TTImageViewInternal.h index 5d17954859..16490bcfba 100644 --- a/src/Three20UI/Headers/TTImageViewInternal.h +++ b/src/Three20UI/Headers/TTImageViewInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTLabel.h b/src/Three20UI/Headers/TTLabel.h index f51395cdbb..36fe1b67a1 100644 --- a/src/Three20UI/Headers/TTLabel.h +++ b/src/Three20UI/Headers/TTLabel.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTLauncherButton.h b/src/Three20UI/Headers/TTLauncherButton.h index bb9fa88a7c..06824ecc4c 100644 --- a/src/Three20UI/Headers/TTLauncherButton.h +++ b/src/Three20UI/Headers/TTLauncherButton.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTLauncherHighlightView.h b/src/Three20UI/Headers/TTLauncherHighlightView.h index d2fe85d662..13344ed896 100644 --- a/src/Three20UI/Headers/TTLauncherHighlightView.h +++ b/src/Three20UI/Headers/TTLauncherHighlightView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ TTLauncherView* _parentView; CGRect _highlightRect; CGFloat _highlightScale; + UIWindow* _statusBarCover; UILabel* _textLabel; } diff --git a/src/Three20UI/Headers/TTLauncherItem.h b/src/Three20UI/Headers/TTLauncherItem.h index 403f399bc0..7dfd6caa08 100644 --- a/src/Three20UI/Headers/TTLauncherItem.h +++ b/src/Three20UI/Headers/TTLauncherItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,9 +27,10 @@ NSString* _URL; NSString* _style; - NSInteger _badgeNumber; + NSString* _badgeValue; BOOL _canDelete; + id _userInfo; } @property (nonatomic, assign) TTLauncherView* launcher; @@ -38,7 +39,9 @@ @property (nonatomic, copy) NSString* URL; @property (nonatomic, copy) NSString* style; @property (nonatomic) NSInteger badgeNumber; +@property (nonatomic, copy) NSString* badgeValue; @property (nonatomic) BOOL canDelete; +@property (nonatomic, retain) id userInfo; - (id)initWithTitle:(NSString*)title image:(NSString*)image URL:(NSString*)URL; - (id)initWithTitle:(NSString*)title image:(NSString*)image URL:(NSString*)URL diff --git a/src/Three20UI/Headers/TTLauncherPersistenceMode.h b/src/Three20UI/Headers/TTLauncherPersistenceMode.h new file mode 100644 index 0000000000..c7404a073d --- /dev/null +++ b/src/Three20UI/Headers/TTLauncherPersistenceMode.h @@ -0,0 +1,21 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +typedef enum { + TTLauncherPersistenceModeNone, // no persistence + TTLauncherPersistenceModeAll, // persists all pages and buttons +} TTLauncherPersistenceMode; + diff --git a/src/Three20UI/Headers/TTLauncherScrollView.h b/src/Three20UI/Headers/TTLauncherScrollView.h index 74b75e4824..be9f7dd609 100644 --- a/src/Three20UI/Headers/TTLauncherScrollView.h +++ b/src/Three20UI/Headers/TTLauncherScrollView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTLauncherView.h b/src/Three20UI/Headers/TTLauncherView.h index 7285a90cdf..dd3c3d15ef 100644 --- a/src/Three20UI/Headers/TTLauncherView.h +++ b/src/Three20UI/Headers/TTLauncherView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,9 @@ #import #import +// UI +#import "Three20UI/TTLauncherPersistenceMode.h" + @protocol TTLauncherViewDelegate; @class TTPageControl; @class TTLauncherButton; @@ -49,6 +52,10 @@ BOOL _editing; BOOL _springing; + BOOL _editable; + + NSString* _persistenceKey; + TTLauncherPersistenceMode _persistenceMode; id _delegate; } @@ -61,11 +68,28 @@ @property (nonatomic, readonly) NSInteger rowCount; +@property (nonatomic, readonly) TTPageControl* pager; + @property (nonatomic) NSInteger currentPageIndex; @property (nonatomic, copy) NSString* prompt; @property (nonatomic, readonly) BOOL editing; +@property (nonatomic, assign) BOOL editable; + +/** + * The key to use for storing persistence information. + * + * @default launcherViewPages + */ +@property (nonatomic, copy) NSString* persistenceKey; + +/** + * How buttons are automatically persisted on termination and restored on launch. + * + * @default TTLauncherPersistenceModeNone + */ +@property (nonatomic) TTLauncherPersistenceMode persistenceMode; - (void)addItem:(TTLauncherItem*)item animated:(BOOL)animated; @@ -81,6 +105,21 @@ - (void)endEditing; +/** + * Persists all pages & buttons to user defaults. + */ +- (void)persistLauncherItems; + +/** + * Restores all pages & button from user defaults and returns if sucess + */ +- (BOOL)restoreLauncherItems; + +/** + * Erases all data stored in user defaults. + */ +- (void)resetDefaults; + /** * Dims the launcher view except for a transparent circle around the given item. The given text * will also be shown center-aligned below or above the circle, as appropriate. The item can be diff --git a/src/Three20UI/Headers/TTLauncherViewDelegate.h b/src/Three20UI/Headers/TTLauncherViewDelegate.h index 3ca17c519c..116f09d5b0 100644 --- a/src/Three20UI/Headers/TTLauncherViewDelegate.h +++ b/src/Three20UI/Headers/TTLauncherViewDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,6 +31,8 @@ - (void)launcherView:(TTLauncherView*)launcher didSelectItem:(TTLauncherItem*)item; +- (void)launcherViewDidEndDragging:(TTLauncherView*)launcher; + - (void)launcherViewDidBeginEditing:(TTLauncherView*)launcher; - (void)launcherViewDidEndEditing:(TTLauncherView*)launcher; diff --git a/src/Three20UI/Headers/TTLink.h b/src/Three20UI/Headers/TTLink.h index 6101344304..d5375bf29a 100644 --- a/src/Three20UI/Headers/TTLink.h +++ b/src/Three20UI/Headers/TTLink.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTListDataSource.h b/src/Three20UI/Headers/TTListDataSource.h index 1a99675771..a8aa106e7a 100644 --- a/src/Three20UI/Headers/TTListDataSource.h +++ b/src/Three20UI/Headers/TTListDataSource.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTMessageController.h b/src/Three20UI/Headers/TTMessageController.h index 604b017bba..8c2ff4402d 100644 --- a/src/Three20UI/Headers/TTMessageController.h +++ b/src/Three20UI/Headers/TTMessageController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -49,6 +49,7 @@ BOOL _showsRecipientPicker; BOOL _isModified; + BOOL _requireNonEmptyMessageBody; id _dataSource; id _delegate; @@ -71,20 +72,20 @@ * An array of TTMessageField instances representing the editable fields. These * fields are rendered in order using appropriate views for each field type. */ -@property (nonatomic, retain) NSArray* fields; +@property (nonatomic, copy) NSArray* fields; /** * A convenience property for editing the text value of the * TTMessageSubjectField. If no TTMessageSubjectField is found in the fields * array, nil will be returned from the getter and the setter will be a no-op. */ -@property (nonatomic, retain) NSString* subject; +@property (nonatomic, copy) NSString* subject; /** * The body of the message. The body is not required for the user to send a * message. */ -@property (nonatomic, retain) NSString* body; +@property (nonatomic, copy) NSString* body; /** * Controls whether a contact add button is shown in the views for @@ -99,6 +100,13 @@ */ @property (nonatomic, readonly) BOOL isModified; +/** + * Indicates if the user must enter text in the editor field to be allowed to + * send the message. + * + * @default NO + */ +@property (nonatomic) BOOL requireNonEmptyMessageBody; /** * Initializes the class with an array of recipients. These recipients will diff --git a/src/Three20UI/Headers/TTMessageControllerDelegate.h b/src/Three20UI/Headers/TTMessageControllerDelegate.h index 52fd4d1467..608a438ba6 100644 --- a/src/Three20UI/Headers/TTMessageControllerDelegate.h +++ b/src/Three20UI/Headers/TTMessageControllerDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTMessageField.h b/src/Three20UI/Headers/TTMessageField.h index cf9909bb7d..9ae3db7be6 100644 --- a/src/Three20UI/Headers/TTMessageField.h +++ b/src/Three20UI/Headers/TTMessageField.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTMessageRecipientField.h b/src/Three20UI/Headers/TTMessageRecipientField.h index 650d3076ca..15fd64e668 100644 --- a/src/Three20UI/Headers/TTMessageRecipientField.h +++ b/src/Three20UI/Headers/TTMessageRecipientField.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,6 +26,6 @@ NSArray* _recipients; } -@property (nonatomic, retain) NSArray* recipients; +@property (nonatomic, copy) NSArray* recipients; @end diff --git a/src/Three20UI/Headers/TTMessageSubjectField.h b/src/Three20UI/Headers/TTMessageSubjectField.h index 0f20c156ac..b931591795 100644 --- a/src/Three20UI/Headers/TTMessageSubjectField.h +++ b/src/Three20UI/Headers/TTMessageSubjectField.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTMessageTextField.h b/src/Three20UI/Headers/TTMessageTextField.h index 145ec67675..9a27df253b 100644 --- a/src/Three20UI/Headers/TTMessageTextField.h +++ b/src/Three20UI/Headers/TTMessageTextField.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTModelViewController.h b/src/Three20UI/Headers/TTModelViewController.h index d14ce08241..65ce8cd6cc 100644 --- a/src/Three20UI/Headers/TTModelViewController.h +++ b/src/Three20UI/Headers/TTModelViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTNavigationController.h b/src/Three20UI/Headers/TTNavigationController.h index 3944c83f66..1b8e24adc7 100644 --- a/src/Three20UI/Headers/TTNavigationController.h +++ b/src/Three20UI/Headers/TTNavigationController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTNavigator.h b/src/Three20UI/Headers/TTNavigator.h index 9201e4b3e3..f9476855f2 100644 --- a/src/Three20UI/Headers/TTNavigator.h +++ b/src/Three20UI/Headers/TTNavigator.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,11 @@ */ UIViewController* TTOpenURL(NSString* URL); +/** + * Shortcut for calling [[TTBaseNavigator navigatorForView:view] openURL:] + */ +UIViewController* TTOpenURLFromView(NSString* URL, UIView* view); + /** * A URL-based navigation system with built-in persistence. * Add support for model-based controllers and implement the legacy global instance accessor. diff --git a/src/Three20UI/Headers/TTNavigatorWindow.h b/src/Three20UI/Headers/TTNavigatorWindow.h index 1824c2e330..6c0785a6f2 100644 --- a/src/Three20UI/Headers/TTNavigatorWindow.h +++ b/src/Three20UI/Headers/TTNavigatorWindow.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTPageControl.h b/src/Three20UI/Headers/TTPageControl.h index c7a1fd2783..907ad320a9 100644 --- a/src/Three20UI/Headers/TTPageControl.h +++ b/src/Three20UI/Headers/TTPageControl.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -37,6 +37,11 @@ @property (nonatomic) NSInteger currentPage; @property (nonatomic, copy) NSString* dotStyle; +/** + * Set to YES to hide the pagecontrol if only one page is present + * + * @default NO + */ @property (nonatomic) BOOL hidesForSinglePage; @end diff --git a/src/Three20UI/Headers/TTPhoto.h b/src/Three20UI/Headers/TTPhoto.h index 08ae04d737..bb9f3f2d80 100644 --- a/src/Three20UI/Headers/TTPhoto.h +++ b/src/Three20UI/Headers/TTPhoto.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ @property (nonatomic, assign) id photoSource; /** - * The index of the photo within its photo source. + * The size of the photo. */ @property (nonatomic) CGSize size; diff --git a/src/Three20UI/Headers/TTPhotoSource.h b/src/Three20UI/Headers/TTPhotoSource.h index 6ca79ad4e2..749ed229f7 100644 --- a/src/Three20UI/Headers/TTPhotoSource.h +++ b/src/Three20UI/Headers/TTPhotoSource.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTPhotoVersion.h b/src/Three20UI/Headers/TTPhotoVersion.h index 9c4648b36e..19cd126895 100644 --- a/src/Three20UI/Headers/TTPhotoVersion.h +++ b/src/Three20UI/Headers/TTPhotoVersion.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTPhotoView.h b/src/Three20UI/Headers/TTPhotoView.h index ffab7691f9..7618d84b96 100644 --- a/src/Three20UI/Headers/TTPhotoView.h +++ b/src/Three20UI/Headers/TTPhotoView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTPhotoViewController.h b/src/Three20UI/Headers/TTPhotoViewController.h index d92b18382d..c59b652fd0 100644 --- a/src/Three20UI/Headers/TTPhotoViewController.h +++ b/src/Three20UI/Headers/TTPhotoViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTPickerTextField.h b/src/Three20UI/Headers/TTPickerTextField.h index 4644074d4f..7442f8abc0 100644 --- a/src/Three20UI/Headers/TTPickerTextField.h +++ b/src/Three20UI/Headers/TTPickerTextField.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTPickerTextFieldDelegate.h b/src/Three20UI/Headers/TTPickerTextFieldDelegate.h index 57687a2b6e..5377a8a4a6 100644 --- a/src/Three20UI/Headers/TTPickerTextFieldDelegate.h +++ b/src/Three20UI/Headers/TTPickerTextFieldDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTPickerViewCell.h b/src/Three20UI/Headers/TTPickerViewCell.h index 2accb194f0..c229bd730e 100644 --- a/src/Three20UI/Headers/TTPickerViewCell.h +++ b/src/Three20UI/Headers/TTPickerViewCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTPopupViewController.h b/src/Three20UI/Headers/TTPopupViewController.h index 068510d353..23d6a388a7 100644 --- a/src/Three20UI/Headers/TTPopupViewController.h +++ b/src/Three20UI/Headers/TTPopupViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,5 +32,7 @@ - (void)showInView:(UIView*)view animated:(BOOL)animated; - (void)dismissPopupViewControllerAnimated:(BOOL)animated; +- (void)showFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated; +- (void)showFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated; @end diff --git a/src/Three20UI/Headers/TTPostController.h b/src/Three20UI/Headers/TTPostController.h index 2c6f031a79..4bf4b750ac 100644 --- a/src/Three20UI/Headers/TTPostController.h +++ b/src/Three20UI/Headers/TTPostController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTPostControllerDelegate.h b/src/Three20UI/Headers/TTPostControllerDelegate.h index 43739a3adc..68d408afa9 100644 --- a/src/Three20UI/Headers/TTPostControllerDelegate.h +++ b/src/Three20UI/Headers/TTPostControllerDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTRecursiveProgress.h b/src/Three20UI/Headers/TTRecursiveProgress.h index 6019d98193..1092c174bc 100644 --- a/src/Three20UI/Headers/TTRecursiveProgress.h +++ b/src/Three20UI/Headers/TTRecursiveProgress.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTScrollView.h b/src/Three20UI/Headers/TTScrollView.h index e3bdd59c81..4c9e3c5b84 100755 --- a/src/Three20UI/Headers/TTScrollView.h +++ b/src/Three20UI/Headers/TTScrollView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -77,6 +77,11 @@ NSUInteger _touchCount; CGFloat _overshoot; + // Scroll animation. + // Set the engine to animate the next relayout. + BOOL _nextLayoutAnimated; + NSTimeInterval _centerPageAnimationDuration; + // The first touch in this view. UITouch* _touch1; @@ -91,10 +96,22 @@ } /** - * The current page index. + * Retrieve or set the current page index. + * If you inform anew value for this page, the Scroll View will + * load this page on the center of the view. + * This operatin is not animated, you should use setCenterPageIndex:animated: + * if you want to control the animation. */ @property (nonatomic) NSInteger centerPageIndex; +/** + * Set the duration for the animation performed by the setCenterPageIndex:animated: + * method. + * + * @default Is the value setted on the TT_TRANSITION_DURATION constant. + */ +@property (assign) NSTimeInterval centerPageAnimationDuration; + /** * Whether or not the current page is zoomed. */ @@ -105,34 +122,51 @@ * out. (read-only) * * The value of this property is YES if user is making a zoom gesture, otherwise it is NO - * */ @property (nonatomic, readonly) BOOL zooming; +/** + * A Boolean value that indicates whether the user is scrolling the + * view with his finger. If the scroll is scrolling by animation this + * value is NO. (read-only) + */ +@property (readonly) BOOL isDragging; + +/** + * The scroller is performing an "hold" action. + */ @property (nonatomic, readonly) BOOL holding; /** * Returns whether the content is moving in the scroll view after the user lifted their * finger. (read-only) */ -@property(nonatomic,readonly,getter=isDecelerating) BOOL decelerating; +@property (nonatomic,readonly,getter=isDecelerating) BOOL decelerating; /** + * A Boolean value that determines whether scrolling is enabled. + * * @default YES */ @property (nonatomic) BOOL scrollEnabled; -/** +/* + * A Boolean value that determines whether zooming is enabled. + * * @default YES */ @property (nonatomic) BOOL zoomEnabled; /** + * A Boolean value that determines whether rotation is enabled. + * * @default YES */ @property (nonatomic) BOOL rotateEnabled; /** + * A CGFloat value that determines the gap between the pages. + * * @default 40 */ @property (nonatomic) CGFloat pageSpacing; @@ -165,7 +199,7 @@ * * @default 1.0 */ -@property(nonatomic,assign) CGFloat zoomScale; +@property (nonatomic,assign) CGFloat zoomScale; /** * A floating-point value that specifies the maximum scale factor that @@ -173,7 +207,7 @@ * * @default 4.0 */ -@property(nonatomic) CGFloat maximumZoomScale; +@property (nonatomic) CGFloat maximumZoomScale; @property (nonatomic, assign) id delegate; @property (nonatomic, assign) id dataSource; @@ -214,6 +248,13 @@ - (void)zoomToDistance:(CGFloat)distance; +/** + * Set the current center page and optionally animate the transition. + * Only animate if the distance between the actual page and the informed + * is one. Example: If is one page 1 and you inform page 3, will not animate. + */ +- (void)setCenterPageIndex:(NSInteger)centerPageIndex animated:(BOOL)animated; + /** * Cancels any active touches and resets everything to an untouched state. */ diff --git a/src/Three20UI/Headers/TTScrollViewDataSource.h b/src/Three20UI/Headers/TTScrollViewDataSource.h index 873c16644d..1e7bbecfcb 100644 --- a/src/Three20UI/Headers/TTScrollViewDataSource.h +++ b/src/Three20UI/Headers/TTScrollViewDataSource.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTScrollViewDelegate.h b/src/Three20UI/Headers/TTScrollViewDelegate.h index 6ee66f3d11..33c4631a0c 100644 --- a/src/Three20UI/Headers/TTScrollViewDelegate.h +++ b/src/Three20UI/Headers/TTScrollViewDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTSearchBar.h b/src/Three20UI/Headers/TTSearchBar.h index 2930f8964b..5243f14fc5 100644 --- a/src/Three20UI/Headers/TTSearchBar.h +++ b/src/Three20UI/Headers/TTSearchBar.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTSearchDisplayController.h b/src/Three20UI/Headers/TTSearchDisplayController.h index 9377cdc1cf..5cbe136237 100644 --- a/src/Three20UI/Headers/TTSearchDisplayController.h +++ b/src/Three20UI/Headers/TTSearchDisplayController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTSearchTextField.h b/src/Three20UI/Headers/TTSearchTextField.h index ed48d4d45c..3f2bf2ae25 100644 --- a/src/Three20UI/Headers/TTSearchTextField.h +++ b/src/Three20UI/Headers/TTSearchTextField.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTSearchTextFieldDelegate.h b/src/Three20UI/Headers/TTSearchTextFieldDelegate.h index 7968331d66..32527d4a2e 100644 --- a/src/Three20UI/Headers/TTSearchTextFieldDelegate.h +++ b/src/Three20UI/Headers/TTSearchTextFieldDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTSearchTextFieldInternal.h b/src/Three20UI/Headers/TTSearchTextFieldInternal.h index 8269670c9e..e19bdfe2fd 100644 --- a/src/Three20UI/Headers/TTSearchTextFieldInternal.h +++ b/src/Three20UI/Headers/TTSearchTextFieldInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTSearchlightLabel.h b/src/Three20UI/Headers/TTSearchlightLabel.h index e54be59a73..812b960726 100644 --- a/src/Three20UI/Headers/TTSearchlightLabel.h +++ b/src/Three20UI/Headers/TTSearchlightLabel.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTSectionedDataSource.h b/src/Three20UI/Headers/TTSectionedDataSource.h index f14828e472..30e20cc56d 100644 --- a/src/Three20UI/Headers/TTSectionedDataSource.h +++ b/src/Three20UI/Headers/TTSectionedDataSource.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTSplitViewController.h b/src/Three20UI/Headers/TTSplitViewController.h new file mode 100644 index 0000000000..16a2b7f3e0 --- /dev/null +++ b/src/Three20UI/Headers/TTSplitViewController.h @@ -0,0 +1,49 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UINavigator/TTNavigatorRootContainer.h" + +@class TTNavigator; + +/** + * A split view controller that implements the navigator root protocol. + * + * See the TTCatalog sample app for an example of this controller in action. + */ +@interface TTSplitViewController : UISplitViewController < + UISplitViewControllerDelegate, + TTNavigatorRootContainer +> { +@private + TTNavigator* _leftNavigator; + TTNavigator* _rightNavigator; + + UIBarButtonItem* _splitViewButton; + UIPopoverController* _popoverSplitController; +} + +@property (nonatomic, readonly) TTNavigator* leftNavigator; +@property (nonatomic, readonly) TTNavigator* rightNavigator; +@property (nonatomic, retain) UIBarButtonItem* splitViewButton; +@property (nonatomic, retain) UIPopoverController* popoverSplitController; + + +/** + * Show/hide the button as the right-side navigator's root navigation item's left button. + */ +- (void)updateSplitViewButton; + +@end diff --git a/src/Three20UI/Headers/TTStyledTextLabel.h b/src/Three20UI/Headers/TTStyledTextLabel.h index 6181636847..b79e460948 100644 --- a/src/Three20UI/Headers/TTStyledTextLabel.h +++ b/src/Three20UI/Headers/TTStyledTextLabel.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -68,7 +68,7 @@ @property (nonatomic, retain) UIColor* highlightedTextColor; /** - * The alignment of the text. (NOT YET IMPLEMENTED) + * The alignment of the text. */ @property (nonatomic) UITextAlignment textAlignment; diff --git a/src/Three20UI/Headers/TTStyledTextTableCell.h b/src/Three20UI/Headers/TTStyledTextTableCell.h index f2df7232c5..34d1c8dd13 100644 --- a/src/Three20UI/Headers/TTStyledTextTableCell.h +++ b/src/Three20UI/Headers/TTStyledTextTableCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTStyledTextTableItemCell.h b/src/Three20UI/Headers/TTStyledTextTableItemCell.h index 425b60666d..30884d978b 100644 --- a/src/Three20UI/Headers/TTStyledTextTableItemCell.h +++ b/src/Three20UI/Headers/TTStyledTextTableItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTab.h b/src/Three20UI/Headers/TTTab.h index debaf2517d..5cfa39cea8 100644 --- a/src/Three20UI/Headers/TTTab.h +++ b/src/Three20UI/Headers/TTTab.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTabBar.h b/src/Three20UI/Headers/TTTabBar.h index caaf4403c1..de6eb48869 100644 --- a/src/Three20UI/Headers/TTTabBar.h +++ b/src/Three20UI/Headers/TTTabBar.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ @property (nonatomic, assign) TTTab* selectedTabView; @property (nonatomic) NSInteger selectedTabIndex; -@property (nonatomic, retain) NSArray* tabItems; +@property (nonatomic, copy) NSArray* tabItems; @property (nonatomic, readonly) NSArray* tabViews; @property (nonatomic, assign) id delegate; diff --git a/src/Three20UI/Headers/TTTabBarInternal.h b/src/Three20UI/Headers/TTTabBarInternal.h index 9ee2e0874e..9fac32a001 100644 --- a/src/Three20UI/Headers/TTTabBarInternal.h +++ b/src/Three20UI/Headers/TTTabBarInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTabDelegate.h b/src/Three20UI/Headers/TTTabDelegate.h index b61f6d3c6f..9df290d673 100644 --- a/src/Three20UI/Headers/TTTabDelegate.h +++ b/src/Three20UI/Headers/TTTabDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTabGrid.h b/src/Three20UI/Headers/TTTabGrid.h index 8447ff6f37..b687fba15f 100644 --- a/src/Three20UI/Headers/TTTabGrid.h +++ b/src/Three20UI/Headers/TTTabGrid.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTabItem.h b/src/Three20UI/Headers/TTTabItem.h index 0ff908f149..65ab449277 100644 --- a/src/Three20UI/Headers/TTTabItem.h +++ b/src/Three20UI/Headers/TTTabItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTabStrip.h b/src/Three20UI/Headers/TTTabStrip.h index 318f320c93..470b26f787 100644 --- a/src/Three20UI/Headers/TTTabStrip.h +++ b/src/Three20UI/Headers/TTTabStrip.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,10 +17,15 @@ // UI #import "Three20UI/TTTabBar.h" -@interface TTTabStrip : TTTabBar { +@interface TTTabStrip : TTTabBar { +@private TTView* _overflowLeft; TTView* _overflowRight; UIScrollView* _scrollView; + + BOOL _contentSizeCached; + CGSize _contentSize; + } @end diff --git a/src/Three20UI/Headers/TTTableActivityItem.h b/src/Three20UI/Headers/TTTableActivityItem.h index d0b77cf46e..2fecd341ad 100644 --- a/src/Three20UI/Headers/TTTableActivityItem.h +++ b/src/Three20UI/Headers/TTTableActivityItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableActivityItemCell.h b/src/Three20UI/Headers/TTTableActivityItemCell.h index 6207fc78a2..5e769750fc 100644 --- a/src/Three20UI/Headers/TTTableActivityItemCell.h +++ b/src/Three20UI/Headers/TTTableActivityItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableButton.h b/src/Three20UI/Headers/TTTableButton.h index 99e9e04e31..64191e4806 100644 --- a/src/Three20UI/Headers/TTTableButton.h +++ b/src/Three20UI/Headers/TTTableButton.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableCaptionItem.h b/src/Three20UI/Headers/TTTableCaptionItem.h index c84dce458d..b990db9ebb 100644 --- a/src/Three20UI/Headers/TTTableCaptionItem.h +++ b/src/Three20UI/Headers/TTTableCaptionItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableCaptionItemCell.h b/src/Three20UI/Headers/TTTableCaptionItemCell.h index d8ecaafced..af57673e02 100644 --- a/src/Three20UI/Headers/TTTableCaptionItemCell.h +++ b/src/Three20UI/Headers/TTTableCaptionItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableControlCell.h b/src/Three20UI/Headers/TTTableControlCell.h index cac87104ca..2d10eebe7c 100644 --- a/src/Three20UI/Headers/TTTableControlCell.h +++ b/src/Three20UI/Headers/TTTableControlCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableControlItem.h b/src/Three20UI/Headers/TTTableControlItem.h index 91ca1ed5d1..7247883667 100644 --- a/src/Three20UI/Headers/TTTableControlItem.h +++ b/src/Three20UI/Headers/TTTableControlItem.h @@ -1,6 +1,6 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableFlushViewCell.h b/src/Three20UI/Headers/TTTableFlushViewCell.h index af6f21562e..cf8e27a1a8 100644 --- a/src/Three20UI/Headers/TTTableFlushViewCell.h +++ b/src/Three20UI/Headers/TTTableFlushViewCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableFooterInfiniteScrollView.h b/src/Three20UI/Headers/TTTableFooterInfiniteScrollView.h new file mode 100644 index 0000000000..62aff396a8 --- /dev/null +++ b/src/Three20UI/Headers/TTTableFooterInfiniteScrollView.h @@ -0,0 +1,29 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@interface TTTableFooterInfiniteScrollView : UIView { + UIActivityIndicatorView* _indicator; + BOOL _loading; +} + +@property (nonatomic, retain) UIActivityIndicatorView* indicator; + +- (void)setLoading:(BOOL)loading; + +@end diff --git a/src/Three20UI/Headers/TTTableGrayTextItem.h b/src/Three20UI/Headers/TTTableGrayTextItem.h index d433d436ed..e79c65eaef 100644 --- a/src/Three20UI/Headers/TTTableGrayTextItem.h +++ b/src/Three20UI/Headers/TTTableGrayTextItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableHeaderDragRefreshView.h b/src/Three20UI/Headers/TTTableHeaderDragRefreshView.h index 8fac3f5133..341bc7364b 100644 --- a/src/Three20UI/Headers/TTTableHeaderDragRefreshView.h +++ b/src/Three20UI/Headers/TTTableHeaderDragRefreshView.h @@ -1,17 +1,27 @@ // -// Copyright 2009-2010 Facebook +// Created by Devin Doty on 10/14/09. +// http://github.com/enormego/EGOTableViewPullRefresh +// Copyright 2009 enormego. All rights reserved. // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +// Modifications copyright 2010 Facebook. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // #import diff --git a/src/Three20UI/Headers/TTTableHeaderView.h b/src/Three20UI/Headers/TTTableHeaderView.h index fd7de0aa49..b2443e84b6 100644 --- a/src/Three20UI/Headers/TTTableHeaderView.h +++ b/src/Three20UI/Headers/TTTableHeaderView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableImageItem.h b/src/Three20UI/Headers/TTTableImageItem.h index 7d3767c541..4a1964f5eb 100644 --- a/src/Three20UI/Headers/TTTableImageItem.h +++ b/src/Three20UI/Headers/TTTableImageItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableImageItemCell.h b/src/Three20UI/Headers/TTTableImageItemCell.h index 14e0a5911b..81db620e97 100644 --- a/src/Three20UI/Headers/TTTableImageItemCell.h +++ b/src/Three20UI/Headers/TTTableImageItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableItem.h b/src/Three20UI/Headers/TTTableItem.h index 62d42f353b..260ee0c0bd 100644 --- a/src/Three20UI/Headers/TTTableItem.h +++ b/src/Three20UI/Headers/TTTableItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableLink.h b/src/Three20UI/Headers/TTTableLink.h index 7d03361b48..0b6772b940 100644 --- a/src/Three20UI/Headers/TTTableLink.h +++ b/src/Three20UI/Headers/TTTableLink.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableLinkedItem.h b/src/Three20UI/Headers/TTTableLinkedItem.h index 16a2bc99a8..cdb36cf257 100644 --- a/src/Three20UI/Headers/TTTableLinkedItem.h +++ b/src/Three20UI/Headers/TTTableLinkedItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableLinkedItemCell.h b/src/Three20UI/Headers/TTTableLinkedItemCell.h index 35c02c8399..297a9c9c74 100644 --- a/src/Three20UI/Headers/TTTableLinkedItemCell.h +++ b/src/Three20UI/Headers/TTTableLinkedItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableLongTextItem.h b/src/Three20UI/Headers/TTTableLongTextItem.h index 8836597130..dcdd565a97 100644 --- a/src/Three20UI/Headers/TTTableLongTextItem.h +++ b/src/Three20UI/Headers/TTTableLongTextItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableMessageItem.h b/src/Three20UI/Headers/TTTableMessageItem.h index 74e4ed43dc..08af588370 100644 --- a/src/Three20UI/Headers/TTTableMessageItem.h +++ b/src/Three20UI/Headers/TTTableMessageItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableMessageItemCell.h b/src/Three20UI/Headers/TTTableMessageItemCell.h index 34d6ebfa1d..3c3d3d2922 100644 --- a/src/Three20UI/Headers/TTTableMessageItemCell.h +++ b/src/Three20UI/Headers/TTTableMessageItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableMoreButton.h b/src/Three20UI/Headers/TTTableMoreButton.h index 5d30a149f4..d99171456c 100644 --- a/src/Three20UI/Headers/TTTableMoreButton.h +++ b/src/Three20UI/Headers/TTTableMoreButton.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableMoreButtonCell.h b/src/Three20UI/Headers/TTTableMoreButtonCell.h index f7167c6325..109228cde9 100644 --- a/src/Three20UI/Headers/TTTableMoreButtonCell.h +++ b/src/Three20UI/Headers/TTTableMoreButtonCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableRightCaptionItem.h b/src/Three20UI/Headers/TTTableRightCaptionItem.h index a6530ced22..168d9151de 100644 --- a/src/Three20UI/Headers/TTTableRightCaptionItem.h +++ b/src/Three20UI/Headers/TTTableRightCaptionItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableRightCaptionItemCell.h b/src/Three20UI/Headers/TTTableRightCaptionItemCell.h index 634ffe2bd7..98de6a4066 100644 --- a/src/Three20UI/Headers/TTTableRightCaptionItemCell.h +++ b/src/Three20UI/Headers/TTTableRightCaptionItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableRightImageItem.h b/src/Three20UI/Headers/TTTableRightImageItem.h index 07852b9017..95064cabd4 100644 --- a/src/Three20UI/Headers/TTTableRightImageItem.h +++ b/src/Three20UI/Headers/TTTableRightImageItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableSection.h b/src/Three20UI/Headers/TTTableSection.h new file mode 100644 index 0000000000..e9f07e04c1 --- /dev/null +++ b/src/Three20UI/Headers/TTTableSection.h @@ -0,0 +1,31 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + + +@interface TTTableSection : NSObject { + NSString* _headerTitle; + NSString* _footerTitle; +} + +@property (nonatomic, copy) NSString* headerTitle; +@property (nonatomic, copy) NSString* footerTitle; + + ++ (id)sectionWithHeaderTitle:(NSString*)headerTitle footerTitle:(NSString*)footerTitle; + +@end diff --git a/src/Three20UI/Headers/TTTableSettingsItem.h b/src/Three20UI/Headers/TTTableSettingsItem.h new file mode 100644 index 0000000000..a67396d1b8 --- /dev/null +++ b/src/Three20UI/Headers/TTTableSettingsItem.h @@ -0,0 +1,22 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// UI +#import "Three20UI/TTTableCaptionItem.h" + +@interface TTTableSettingsItem : TTTableCaptionItem + +@end diff --git a/src/Three20UI/Headers/TTTableSettingsItemCell.h b/src/Three20UI/Headers/TTTableSettingsItemCell.h new file mode 100644 index 0000000000..7e235946e9 --- /dev/null +++ b/src/Three20UI/Headers/TTTableSettingsItemCell.h @@ -0,0 +1,24 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// UI +#import "Three20UI/TTTableLinkedItemCell.h" + +@interface TTTableSettingsItemCell : TTTableLinkedItemCell + +@property (nonatomic, readonly) UILabel* captionLabel; + +@end diff --git a/src/Three20UI/Headers/TTTableStyledTextItem.h b/src/Three20UI/Headers/TTTableStyledTextItem.h index 4a9e1804d1..fab85cf3e2 100644 --- a/src/Three20UI/Headers/TTTableStyledTextItem.h +++ b/src/Three20UI/Headers/TTTableStyledTextItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableSubtextItem.h b/src/Three20UI/Headers/TTTableSubtextItem.h index 4430ea7fc7..0d85ff6f63 100644 --- a/src/Three20UI/Headers/TTTableSubtextItem.h +++ b/src/Three20UI/Headers/TTTableSubtextItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableSubtextItemCell.h b/src/Three20UI/Headers/TTTableSubtextItemCell.h index bc7883a851..ed28497330 100644 --- a/src/Three20UI/Headers/TTTableSubtextItemCell.h +++ b/src/Three20UI/Headers/TTTableSubtextItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableSubtitleItem.h b/src/Three20UI/Headers/TTTableSubtitleItem.h index b0341725f7..9a28cd9044 100644 --- a/src/Three20UI/Headers/TTTableSubtitleItem.h +++ b/src/Three20UI/Headers/TTTableSubtitleItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableSubtitleItemCell.h b/src/Three20UI/Headers/TTTableSubtitleItemCell.h index de59cf1f89..e6988d722a 100644 --- a/src/Three20UI/Headers/TTTableSubtitleItemCell.h +++ b/src/Three20UI/Headers/TTTableSubtitleItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableSummaryItem.h b/src/Three20UI/Headers/TTTableSummaryItem.h index 7f1dfe61db..1783f66396 100644 --- a/src/Three20UI/Headers/TTTableSummaryItem.h +++ b/src/Three20UI/Headers/TTTableSummaryItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableTextItem.h b/src/Three20UI/Headers/TTTableTextItem.h index 8fc6db6e18..6a893495e5 100644 --- a/src/Three20UI/Headers/TTTableTextItem.h +++ b/src/Three20UI/Headers/TTTableTextItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableTextItemCell.h b/src/Three20UI/Headers/TTTableTextItemCell.h index 7e8a4ac917..ecdc92c6ce 100644 --- a/src/Three20UI/Headers/TTTableTextItemCell.h +++ b/src/Three20UI/Headers/TTTableTextItemCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableView.h b/src/Three20UI/Headers/TTTableView.h index 79b119ef19..e71c293086 100644 --- a/src/Three20UI/Headers/TTTableView.h +++ b/src/Three20UI/Headers/TTTableView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -49,4 +49,7 @@ - (void)tableView:(UITableView*)tableView touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event; - (void)tableView:(UITableView*)tableView touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event; +@optional +- (void)tableView:(UITableView*)tableView touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event; + @end diff --git a/src/Three20UI/Headers/TTTableViewCell.h b/src/Three20UI/Headers/TTTableViewCell.h index 63dd2bba76..373737b970 100644 --- a/src/Three20UI/Headers/TTTableViewCell.h +++ b/src/Three20UI/Headers/TTTableViewCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableViewController.h b/src/Three20UI/Headers/TTTableViewController.h index 8449f040ed..f08a3377b7 100644 --- a/src/Three20UI/Headers/TTTableViewController.h +++ b/src/Three20UI/Headers/TTTableViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -28,8 +28,6 @@ UIView* _errorView; UIView* _emptyView; - NSTimer* _bannerTimer; - UIView* _menuView; UITableViewCell* _menuCell; @@ -39,6 +37,7 @@ BOOL _variableHeightRows; BOOL _showTableShadows; + BOOL _clearsSelectionOnViewWillAppear; id _dataSource; id _tableDelegate; @@ -88,6 +87,12 @@ */ @property (nonatomic) BOOL showTableShadows; +/** + * A Boolean value indicating if the controller clears the selection when the table appears. + * Default is YES. + */ +@property (nonatomic) BOOL clearsSelectionOnViewWillAppear; + /** * Initializes and returns a controller having the given style. */ diff --git a/src/Three20UI/Headers/TTTableViewDataSource.h b/src/Three20UI/Headers/TTTableViewDataSource.h index 9bcc520c7d..a369833c78 100644 --- a/src/Three20UI/Headers/TTTableViewDataSource.h +++ b/src/Three20UI/Headers/TTTableViewDataSource.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,6 +30,8 @@ - (id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)indexPath; +- (void)setCellClass:(NSString*)cellClass forItemClass:(NSString*)itemClass; + - (Class)tableView:(UITableView*)tableView cellClassForObject:(id)object; - (NSString*)tableView:(UITableView*)tableView labelForObject:(id)object; @@ -54,6 +56,12 @@ - (NSString*)subtitleForEmpty; + +/** + * return YES to include a reload button in the TTErrorView. + */ +- (BOOL)reloadButtonForEmpty; + - (UIImage*)imageForError:(NSError*)error; - (NSString*)titleForError:(NSError*)error; @@ -79,6 +87,7 @@ @interface TTTableViewDataSource : NSObject { id _model; + NSMutableDictionary * _itemCellClassMapping; } @end diff --git a/src/Three20UI/Headers/TTTableViewDelegate.h b/src/Three20UI/Headers/TTTableViewDelegate.h index 88081c2745..ede17f014e 100644 --- a/src/Three20UI/Headers/TTTableViewDelegate.h +++ b/src/Three20UI/Headers/TTTableViewDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableViewDragRefreshDelegate.h b/src/Three20UI/Headers/TTTableViewDragRefreshDelegate.h index c0752d2082..2bc18a2d72 100644 --- a/src/Three20UI/Headers/TTTableViewDragRefreshDelegate.h +++ b/src/Three20UI/Headers/TTTableViewDragRefreshDelegate.h @@ -1,17 +1,27 @@ // -// Copyright 2009-2010 Facebook +// Created by Devin Doty on 10/14/09. +// http://github.com/enormego/EGOTableViewPullRefresh +// Copyright 2009 enormego. All rights reserved. // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +// Modifications copyright 2010 Facebook. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // // UI diff --git a/src/Three20UI/Headers/TTTableViewGroupedVarHeightDelegate.h b/src/Three20UI/Headers/TTTableViewGroupedVarHeightDelegate.h index d454f4d0d8..01dc01e795 100644 --- a/src/Three20UI/Headers/TTTableViewGroupedVarHeightDelegate.h +++ b/src/Three20UI/Headers/TTTableViewGroupedVarHeightDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableViewItem.h b/src/Three20UI/Headers/TTTableViewItem.h index b522aef527..d780480906 100644 --- a/src/Three20UI/Headers/TTTableViewItem.h +++ b/src/Three20UI/Headers/TTTableViewItem.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableViewNetworkEnabledDelegate.h b/src/Three20UI/Headers/TTTableViewNetworkEnabledDelegate.h new file mode 100644 index 0000000000..c1c064134d --- /dev/null +++ b/src/Three20UI/Headers/TTTableViewNetworkEnabledDelegate.h @@ -0,0 +1,44 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UI/TTTableViewVarHeightDelegate.h" + +@class TTTableHeaderDragRefreshView, TTTableFooterInfiniteScrollView; +@protocol TTModel, TTTableNetworkEnabledTableViewController; + +@interface TTTableViewNetworkEnabledDelegate : TTTableViewVarHeightDelegate { + TTTableHeaderDragRefreshView* _headerView; + TTTableFooterInfiniteScrollView* _footerView; + id _model; + BOOL _dragRefreshEnabled; + BOOL _infiniteScrollEnabled; +} + +@property (nonatomic, retain) TTTableHeaderDragRefreshView* headerView; +@property (nonatomic, retain) TTTableFooterInfiniteScrollView* footerView; +@property (readonly) BOOL dragRefreshEnabled; +@property (readonly) BOOL infiniteScrollEnabled; + +- (id)initWithController:(TTTableViewController*)controller + withDragRefresh:(BOOL)enableDragRefresh + withInfiniteScroll:(BOOL)enableInfiniteScroll; + +@end + +@protocol TTTableNetworkEnabledTableViewController +@optional +- (BOOL)shouldLoadAtScrollRatio:(CGFloat)scrollRatio; +@end diff --git a/src/Three20UI/Headers/TTTableViewPlainDelegate.h b/src/Three20UI/Headers/TTTableViewPlainDelegate.h index d00b8e7cee..bcb410bea2 100644 --- a/src/Three20UI/Headers/TTTableViewPlainDelegate.h +++ b/src/Three20UI/Headers/TTTableViewPlainDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableViewPlainVarHeightDelegate.h b/src/Three20UI/Headers/TTTableViewPlainVarHeightDelegate.h index aefffe1ac9..4eee064e31 100644 --- a/src/Three20UI/Headers/TTTableViewPlainVarHeightDelegate.h +++ b/src/Three20UI/Headers/TTTableViewPlainVarHeightDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTableViewVarHeightDelegate.h b/src/Three20UI/Headers/TTTableViewVarHeightDelegate.h index b995dd3862..b5e815b18e 100644 --- a/src/Three20UI/Headers/TTTableViewVarHeightDelegate.h +++ b/src/Three20UI/Headers/TTTableViewVarHeightDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTextBarController.h b/src/Three20UI/Headers/TTTextBarController.h index 7c1d82b95b..fd667f5fe3 100644 --- a/src/Three20UI/Headers/TTTextBarController.h +++ b/src/Three20UI/Headers/TTTextBarController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTextBarDelegate.h b/src/Three20UI/Headers/TTTextBarDelegate.h index 8d019a6334..35b31ed74e 100644 --- a/src/Three20UI/Headers/TTTextBarDelegate.h +++ b/src/Three20UI/Headers/TTTextBarDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTextEditor.h b/src/Three20UI/Headers/TTTextEditor.h index 3faa98c3bf..c55ee9d1c3 100644 --- a/src/Three20UI/Headers/TTTextEditor.h +++ b/src/Three20UI/Headers/TTTextEditor.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTextEditorDelegate.h b/src/Three20UI/Headers/TTTextEditorDelegate.h index 552a6df413..3eec54ced3 100644 --- a/src/Three20UI/Headers/TTTextEditorDelegate.h +++ b/src/Three20UI/Headers/TTTextEditorDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTextEditorInternal.h b/src/Three20UI/Headers/TTTextEditorInternal.h index 9cadf74149..9e90cc828d 100644 --- a/src/Three20UI/Headers/TTTextEditorInternal.h +++ b/src/Three20UI/Headers/TTTextEditorInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTTextView.h b/src/Three20UI/Headers/TTTextView.h index 24645d288c..553a7b89f0 100644 --- a/src/Three20UI/Headers/TTTextView.h +++ b/src/Three20UI/Headers/TTTextView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTThumbView.h b/src/Three20UI/Headers/TTThumbView.h index 40477b97ac..4da39f01fb 100644 --- a/src/Three20UI/Headers/TTThumbView.h +++ b/src/Three20UI/Headers/TTThumbView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTThumbsDataSource.h b/src/Three20UI/Headers/TTThumbsDataSource.h index d4d0d768ce..b26730121c 100644 --- a/src/Three20UI/Headers/TTThumbsDataSource.h +++ b/src/Three20UI/Headers/TTThumbsDataSource.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTThumbsTableViewCell.h b/src/Three20UI/Headers/TTThumbsTableViewCell.h index 57261da2ba..86fac4574d 100644 --- a/src/Three20UI/Headers/TTThumbsTableViewCell.h +++ b/src/Three20UI/Headers/TTThumbsTableViewCell.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTThumbsTableViewCellDelegate.h b/src/Three20UI/Headers/TTThumbsTableViewCellDelegate.h index df7fbe0d89..0413f3e956 100644 --- a/src/Three20UI/Headers/TTThumbsTableViewCellDelegate.h +++ b/src/Three20UI/Headers/TTThumbsTableViewCellDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTThumbsViewController.h b/src/Three20UI/Headers/TTThumbsViewController.h index 4802ae3a24..10bbdbe2ff 100644 --- a/src/Three20UI/Headers/TTThumbsViewController.h +++ b/src/Three20UI/Headers/TTThumbsViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTThumbsViewControllerDelegate.h b/src/Three20UI/Headers/TTThumbsViewControllerDelegate.h index bf15a636b0..5f253bc7a5 100644 --- a/src/Three20UI/Headers/TTThumbsViewControllerDelegate.h +++ b/src/Three20UI/Headers/TTThumbsViewControllerDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTView.h b/src/Three20UI/Headers/TTView.h index 584198b2ef..203a879f60 100644 --- a/src/Three20UI/Headers/TTView.h +++ b/src/Three20UI/Headers/TTView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTViewController.h b/src/Three20UI/Headers/TTViewController.h index 153aaeef91..19c4004d4b 100644 --- a/src/Three20UI/Headers/TTViewController.h +++ b/src/Three20UI/Headers/TTViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/TTWebController.h b/src/Three20UI/Headers/TTWebController.h index 6d96663926..86f83f217f 100644 --- a/src/Three20UI/Headers/TTWebController.h +++ b/src/Three20UI/Headers/TTWebController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ UIBarButtonItem* _activityItem; NSURL* _loadingURL; - + UIActionSheet* _actionSheet; id _delegate; @@ -53,7 +53,7 @@ @property (nonatomic, retain) UIView* headerView; /** - * The web controller delegate, currently does nothing. + * The web controller delegate */ @property (nonatomic, assign) id delegate; @@ -71,10 +71,18 @@ @end - -/////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * The web controller delegate, similar to UIWebViewDelegate, but prefixed with controller + */ @protocol TTWebControllerDelegate -// XXXjoe Need to make this similar to UIWebViewDelegate + +@optional +- (BOOL)webController:(TTWebController *)controller webView:(UIWebView *)webView + shouldStartLoadWithRequest:(NSURLRequest *)request + navigationType:(UIWebViewNavigationType)navigationType; +- (void)webController:(TTWebController *)controller webViewDidStartLoad:(UIWebView *)webView; +- (void)webController:(TTWebController *)controller webViewDidFinishLoad:(UIWebView *)webView; +- (void)webController:(TTWebController *)controller webView:(UIWebView *)webView + didFailLoadWithError:(NSError *)error; + @end diff --git a/src/Three20UI/Headers/TTYouTubeView.h b/src/Three20UI/Headers/TTYouTubeView.h index dda06b58b9..d39d892eab 100644 --- a/src/Three20UI/Headers/TTYouTubeView.h +++ b/src/Three20UI/Headers/TTYouTubeView.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/Three20UI+Additions.h b/src/Three20UI/Headers/Three20UI+Additions.h index aff9f79d69..ca4eb37d95 100644 --- a/src/Three20UI/Headers/Three20UI+Additions.h +++ b/src/Three20UI/Headers/Three20UI+Additions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/Three20UI.h b/src/Three20UI/Headers/Three20UI.h index 2297bb8616..6040ac455c 100644 --- a/src/Three20UI/Headers/Three20UI.h +++ b/src/Three20UI/Headers/Three20UI.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,9 @@ // UI Controllers #import "Three20UI/TTNavigator.h" #import "Three20UI/TTViewController.h" +#import "Three20UI/TTSplitViewController.h" #import "Three20UI/TTNavigationController.h" +#import "Three20UI/TTExtensionsController.h" #import "Three20UI/TTWebController.h" #import "Three20UI/TTMessageController.h" #import "Three20UI/TTMessageControllerDelegate.h" @@ -44,9 +46,11 @@ #import "Three20UI/TTScrollViewDelegate.h" #import "Three20UI/TTScrollViewDataSource.h" +// Launcher #import "Three20UI/TTLauncherView.h" #import "Three20UI/TTLauncherViewDelegate.h" #import "Three20UI/TTLauncherItem.h" +#import "Three20UI/TTLauncherPersistenceMode.h" #import "Three20UI/TTLabel.h" #import "Three20UI/TTStyledTextLabel.h" @@ -69,6 +73,7 @@ #import "Three20UI/TTSearchTextField.h" #import "Three20UI/TTSearchTextFieldDelegate.h" #import "Three20UI/TTPickerTextField.h" +#import "Three20UI/TTPickerTextFieldDelegate.h" #import "Three20UI/TTSearchBar.h" #import "Three20UI/TTTableViewController.h" @@ -80,10 +85,14 @@ #import "Three20UI/TTTableViewPlainDelegate.h" #import "Three20UI/TTTableViewPlainVarHeightDelegate.h" #import "Three20UI/TTTableViewDragRefreshDelegate.h" +#import "Three20UI/TTTableViewNetworkEnabledDelegate.h" #import "Three20UI/TTListDataSource.h" #import "Three20UI/TTSectionedDataSource.h" #import "Three20UI/TTTableHeaderView.h" +#import "Three20UI/TTTableSection.h" +#import "Three20UI/TTTableFooterInfiniteScrollView.h" +#import "Three20UI/TTTableHeaderDragRefreshView.h" #import "Three20UI/TTTableViewCell.h" // Table Items @@ -107,6 +116,7 @@ #import "Three20UI/TTTableStyledTextItem.h" #import "Three20UI/TTTableControlItem.h" #import "Three20UI/TTTableViewItem.h" +#import "Three20UI/TTTableSettingsItem.h" // Table Item Cells #import "Three20UI/TTTableLinkedItemCell.h" @@ -123,6 +133,7 @@ #import "Three20UI/TTTableActivityItemCell.h" #import "Three20UI/TTTableControlCell.h" #import "Three20UI/TTTableFlushViewCell.h" +#import "Three20UI/TTTableSettingsItemCell.h" #import "Three20UI/TTErrorView.h" diff --git a/src/Three20UI/Headers/UINSObjectAdditions.h b/src/Three20UI/Headers/UINSObjectAdditions.h index 5b7f3d202a..43ab7170d8 100644 --- a/src/Three20UI/Headers/UINSObjectAdditions.h +++ b/src/Three20UI/Headers/UINSObjectAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/UINSStringAdditions.h b/src/Three20UI/Headers/UINSStringAdditions.h index d17c4f72b2..36428cb604 100644 --- a/src/Three20UI/Headers/UINSStringAdditions.h +++ b/src/Three20UI/Headers/UINSStringAdditions.h @@ -1,4 +1,4 @@ -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain diff --git a/src/Three20UI/Headers/UINavigationControllerAdditions.h b/src/Three20UI/Headers/UINavigationControllerAdditions.h index 9d03ce4d4e..16c67803df 100644 --- a/src/Three20UI/Headers/UINavigationControllerAdditions.h +++ b/src/Three20UI/Headers/UINavigationControllerAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/UITabBarControllerAdditions.h b/src/Three20UI/Headers/UITabBarControllerAdditions.h index 6db782f896..b6e77871ac 100644 --- a/src/Three20UI/Headers/UITabBarControllerAdditions.h +++ b/src/Three20UI/Headers/UITabBarControllerAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/UITableViewAdditions.h b/src/Three20UI/Headers/UITableViewAdditions.h index 9710a1248d..fdc47b6030 100644 --- a/src/Three20UI/Headers/UITableViewAdditions.h +++ b/src/Three20UI/Headers/UITableViewAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/UIToolbarAdditions.h b/src/Three20UI/Headers/UIToolbarAdditions.h index cd065020e9..b717f9fcef 100644 --- a/src/Three20UI/Headers/UIToolbarAdditions.h +++ b/src/Three20UI/Headers/UIToolbarAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Headers/UIViewAdditions.h b/src/Three20UI/Headers/UIViewAdditions.h index 80e529b2b9..d5adc69c82 100644 --- a/src/Three20UI/Headers/UIViewAdditions.h +++ b/src/Three20UI/Headers/UIViewAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -138,7 +138,7 @@ /** * WARNING: This depends on undocumented APIs and may be fragile. For testing only. */ -#ifdef DEBUG +#ifdef DEBUG_TOUCHES - (void)simulateTapAtPoint:(CGPoint)location; #endif @@ -172,9 +172,4 @@ */ - (void)dismissAsKeyboard:(BOOL)animated; -/** - * The view controller whose view contains this view. - */ -- (UIViewController*)viewController; - @end diff --git a/src/Three20UI/Headers/UIWebViewAdditions.h b/src/Three20UI/Headers/UIWebViewAdditions.h index 0c0cc9b1fd..e9c6c64070 100644 --- a/src/Three20UI/Headers/UIWebViewAdditions.h +++ b/src/Three20UI/Headers/UIWebViewAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTActionSheet.m b/src/Three20UI/Sources/TTActionSheet.m index 2ed609a483..92f1eb9a9e 100644 --- a/src/Three20UI/Sources/TTActionSheet.m +++ b/src/Three20UI/Sources/TTActionSheet.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTActionSheetController.m b/src/Three20UI/Sources/TTActionSheetController.m index 291ed205b9..476d37bca9 100644 --- a/src/Three20UI/Sources/TTActionSheetController.m +++ b/src/Three20UI/Sources/TTActionSheetController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,7 +36,8 @@ @implementation TTActionSheetController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { _URLs = [[NSMutableArray alloc] init]; } @@ -46,7 +47,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title delegate:(id)delegate { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { _delegate = delegate; if (nil != title) { @@ -60,7 +62,8 @@ - (id)initWithTitle:(NSString*)title delegate:(id)delegate { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title { - if (self = [self initWithTitle:title delegate:nil]) { + self = [self initWithTitle:title delegate:nil]; + if (self) { } return self; @@ -69,7 +72,8 @@ - (id)initWithTitle:(NSString*)title { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithTitle:nil delegate:nil]) { + self = [self initWithTitle:nil delegate:nil]; + if (self) { } return self; @@ -128,6 +132,22 @@ - (void)showInView:(UIView*)view animated:(BOOL)animated { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)showFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated { + [self viewWillAppear:animated]; + [self.actionSheet showFromBarButtonItem:item animated:animated]; + [self viewDidAppear:animated]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)showFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated { + [self viewWillAppear:animated]; + [self.actionSheet showFromRect:rect inView:view animated:animated]; + [self viewDidAppear:animated]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dismissPopupViewControllerAnimated:(BOOL)animated { [self viewWillDisappear:animated]; @@ -221,6 +241,7 @@ - (UIActionSheet*)actionSheet { - (NSInteger)addButtonWithTitle:(NSString*)title URL:(NSString*)URL { if (URL) { [_URLs addObject:URL]; + } else { [_URLs addObject:[NSNull null]]; } @@ -247,6 +268,7 @@ - (NSString*)buttonURLAtIndex:(NSInteger)buttonIndex { if (buttonIndex < _URLs.count) { id URL = [_URLs objectAtIndex:buttonIndex]; return URL != [NSNull null] ? URL : nil; + } else { return nil; } diff --git a/src/Three20UI/Sources/TTActivityLabel.m b/src/Three20UI/Sources/TTActivityLabel.m index 6ab12d2022..ced0049b32 100644 --- a/src/Three20UI/Sources/TTActivityLabel.m +++ b/src/Three20UI/Sources/TTActivityLabel.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,11 +32,11 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static CGFloat kMargin = 10; -static CGFloat kPadding = 15; -static CGFloat kBannerPadding = 8; -static CGFloat kSpacing = 6; -static CGFloat kProgressMargin = 6; +static CGFloat kMargin = 10.0f; +static CGFloat kPadding = 15.0f; +static CGFloat kBannerPadding = 8.0f; +static CGFloat kSpacing = 6.0f; +static CGFloat kProgressMargin = 6.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -51,7 +51,8 @@ @implementation TTActivityLabel /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame style:(TTActivityLabelStyle)style text:(NSString*)text { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _style = style; _progress = 0; _smoothesProgress = NO; @@ -63,20 +64,25 @@ - (id)initWithFrame:(CGRect)frame style:(TTActivityLabelStyle)style text:(NSStri _bezelView.backgroundColor = [UIColor clearColor]; _bezelView.style = TTSTYLE(blackBezel); self.backgroundColor = [UIColor clearColor]; + } else if (_style == TTActivityLabelStyleWhiteBezel) { _bezelView.backgroundColor = [UIColor clearColor]; _bezelView.style = TTSTYLE(whiteBezel); self.backgroundColor = [UIColor clearColor]; + } else if (_style == TTActivityLabelStyleWhiteBox) { _bezelView.backgroundColor = [UIColor clearColor]; self.backgroundColor = [UIColor whiteColor]; + } else if (_style == TTActivityLabelStyleBlackBox) { _bezelView.backgroundColor = [UIColor clearColor]; self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8]; + } else if (_style == TTActivityLabelStyleBlackBanner) { _bezelView.backgroundColor = [UIColor clearColor]; _bezelView.style = TTSTYLE(blackBanner); self.backgroundColor = [UIColor clearColor]; + } else { _bezelView.backgroundColor = [UIColor clearColor]; self.backgroundColor = [UIColor clearColor]; @@ -96,6 +102,7 @@ - (id)initWithFrame:(CGRect)frame style:(TTActivityLabelStyle)style text:(NSStri UIActivityIndicatorViewStyleWhite]; _label.font = TTSTYLEVAR(activityLabelFont); _label.textColor = [UIColor whiteColor]; + } else if (_style == TTActivityLabelStyleGray || _style == TTActivityLabelStyleWhiteBox || _style == TTActivityLabelStyleWhiteBezel) { @@ -103,6 +110,7 @@ - (id)initWithFrame:(CGRect)frame style:(TTActivityLabelStyle)style text:(NSStri UIActivityIndicatorViewStyleGray]; _label.font = TTSTYLEVAR(activityLabelFont); _label.textColor = TTSTYLEVAR(tableActivityTextColor); + } else if (_style == TTActivityLabelStyleBlackBezel || _style == TTActivityLabelStyleBlackBox) { _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhiteLarge]; @@ -111,6 +119,7 @@ - (id)initWithFrame:(CGRect)frame style:(TTActivityLabelStyle)style text:(NSStri _label.textColor = [UIColor whiteColor]; _label.shadowColor = [UIColor colorWithWhite:0 alpha:0.3]; _label.shadowOffset = CGSizeMake(1, 1); + } else if (_style == TTActivityLabelStyleBlackBanner) { _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhite]; @@ -131,7 +140,8 @@ - (id)initWithFrame:(CGRect)frame style:(TTActivityLabelStyle)style text:(NSStri /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame style:(TTActivityLabelStyle)style { - if (self = [self initWithFrame:frame style:style text:nil]) { + self = [self initWithFrame:frame style:style text:nil]; + if (self) { } return self; @@ -140,7 +150,8 @@ - (id)initWithFrame:(CGRect)frame style:(TTActivityLabelStyle)style { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(TTActivityLabelStyle)style { - if (self = [self initWithFrame:CGRectZero style:style text:nil]) { + self = [self initWithFrame:CGRectZero style:style text:nil]; + if (self) { } return self; @@ -149,7 +160,8 @@ - (id)initWithStyle:(TTActivityLabelStyle)style { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [self initWithFrame:frame style:TTActivityLabelStyleWhiteBox text:nil]) { + self = [self initWithFrame:frame style:TTActivityLabelStyleWhiteBox text:nil]; + if (self) { } return self; @@ -179,11 +191,12 @@ - (void)layoutSubviews { CGSize textSize = [_label.text sizeWithFont:_label.font]; - CGFloat indicatorSize = 0; + CGFloat indicatorSize = 0.0f; [_activityIndicator sizeToFit]; if (_activityIndicator.isAnimating) { if (_activityIndicator.height > textSize.height) { indicatorSize = textSize.height; + } else { indicatorSize = _activityIndicator.height; } @@ -203,6 +216,7 @@ - (void)layoutSubviews { padding = kPadding; bezelWidth = contentWidth + padding*2; bezelHeight = contentHeight + padding*2; + } else { margin = 0; padding = kBannerPadding; @@ -250,6 +264,7 @@ - (CGSize)sizeThatFits:(CGSize)size { CGFloat padding; if (_style == TTActivityLabelStyleBlackBezel || _style == TTActivityLabelStyleWhiteBezel) { padding = kPadding; + } else { padding = kBannerPadding; } @@ -267,6 +282,7 @@ - (CGSize)sizeThatFits:(CGSize)size { - (void)smoothTimer { if (_progressView.progress < _progress) { _progressView.progress += 0.01; + } else { TT_INVALIDATE_TIMER(_smoothTimer); } @@ -338,6 +354,7 @@ - (void)setProgress:(float)progress { _smoothTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(smoothTimer) userInfo:nil repeats:YES]; } + } else { _progressView.progress = progress; } diff --git a/src/Three20UI/Sources/TTAlertView.m b/src/Three20UI/Sources/TTAlertView.m index 1a2ef8abc2..cafc6de7bf 100644 --- a/src/Three20UI/Sources/TTAlertView.m +++ b/src/Three20UI/Sources/TTAlertView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTAlertViewController.m b/src/Three20UI/Sources/TTAlertViewController.m index f8fcb366c6..02e732a095 100644 --- a/src/Three20UI/Sources/TTAlertViewController.m +++ b/src/Three20UI/Sources/TTAlertViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,7 +36,8 @@ @implementation TTAlertViewController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { _URLs = [[NSMutableArray alloc] init]; } @@ -46,7 +47,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title message:(NSString*)message delegate:(id)delegate { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { _delegate = delegate; if (nil != title) { @@ -64,7 +66,8 @@ - (id)initWithTitle:(NSString*)title message:(NSString*)message delegate:(id)del /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title message:(NSString*)message { - if (self = [self initWithTitle:title message:message delegate:nil]) { + self = [self initWithTitle:title message:message delegate:nil]; + if (self) { } return self; @@ -73,7 +76,8 @@ - (id)initWithTitle:(NSString*)title message:(NSString*)message { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithTitle:nil message:nil delegate:nil]) { + self = [self initWithTitle:nil message:nil delegate:nil]; + if (self) { } return self; @@ -190,7 +194,8 @@ - (void)alertView:(UIAlertView*)alertView willDismissWithButtonIndex:(NSInteger) - (void)alertView:(UIAlertView*)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { NSString* URL = [self buttonURLAtIndex:buttonIndex]; BOOL canOpenURL = YES; - if ([_delegate respondsToSelector:@selector(alertViewController:didDismissWithButtonIndex:URL:)]) { + if ([_delegate respondsToSelector: + @selector(alertViewController:didDismissWithButtonIndex:URL:)]) { canOpenURL = [_delegate alertViewController:self didDismissWithButtonIndex:buttonIndex URL:URL]; } if (URL && canOpenURL) { @@ -218,6 +223,7 @@ - (UIAlertView*)alertView { - (NSInteger)addButtonWithTitle:(NSString*)title URL:(NSString*)URL { if (URL) { [_URLs addObject:URL]; + } else { [_URLs addObject:[NSNull null]]; } diff --git a/src/Three20UI/Sources/TTButton.m b/src/Three20UI/Sources/TTButton.m index 3784d64357..6107f6cdc3 100644 --- a/src/Three20UI/Sources/TTButton.m +++ b/src/Three20UI/Sources/TTButton.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ #import "Three20UI/TTButton.h" // UI (private) -#import "Three20UI/TTButtonContent.h" +#import "Three20UI/private/TTButtonContent.h" // UI #import "Three20UI/TTImageViewDelegate.h" @@ -35,8 +35,8 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kHPadding = 8; -static const CGFloat kVPadding = 7; +static const CGFloat kHPadding = 8.0f; +static const CGFloat kVPadding = 7.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -51,7 +51,8 @@ @implementation TTButton /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { self.backgroundColor = [UIColor clearColor]; self.contentMode = UIViewContentModeRedraw; } @@ -106,10 +107,13 @@ - (id)keyForState:(UIControlState)state { static NSString* disabled = @"disabled"; if (state & UIControlStateHighlighted) { return highlighted; + } else if (state & UIControlStateSelected) { return selected; + } else if (state & UIControlStateDisabled) { return disabled; + } else { return normalKey; } @@ -138,8 +142,10 @@ - (TTButtonContent*)contentForCurrentState { TTButtonContent* content = nil; if (self.selected) { content = [self contentForState:UIControlStateSelected]; + } else if (self.highlighted) { content = [self contentForState:UIControlStateHighlighted]; + } else if (!self.enabled) { content = [self contentForState:UIControlStateDisabled]; } @@ -173,11 +179,13 @@ - (TTStyle*)styleForCurrentState { - (UIFont*)fontForCurrentState { if (_font) { return _font; + } else { TTStyle* style = [self styleForCurrentState]; TTTextStyle* textStyle = (TTTextStyle*)[style firstStyleOfClass:[TTTextStyle class]]; if (textStyle.font) { return textStyle.font; + } else { return self.font; } @@ -210,6 +218,7 @@ - (void)drawRect:(CGRect)rect { CGFloat height = imageSize.height + imageBoxStyle.margin.top + imageBoxStyle.margin.bottom; textFrame.origin.y += height; textFrame.size.height -= height; + } else { textFrame.origin.x += imageSize.width + imageBoxStyle.margin.right; textFrame.size.width -= imageSize.width + imageBoxStyle.margin.right; @@ -229,6 +238,7 @@ - (void)drawRect:(CGRect)rect { frame = self.bounds; frame.origin.x += imageBoxStyle.margin.left; frame.origin.y += imageBoxStyle.margin.top; + } else { frame.size = imageSize; frame.origin.x += imageBoxStyle.margin.left; @@ -254,6 +264,7 @@ - (CGSize)sizeThatFits:(CGSize)size { TTStyle* style = [self styleForCurrentState]; if (style) { return [style addToSize:CGSizeZero context:context]; + } else { return size; } @@ -432,6 +443,7 @@ - (void)suspendLoadingImages:(BOOL)suspended { TTButtonContent* content = [self contentForCurrentState]; if (suspended) { [content stopLoading]; + } else if (!content.image) { [content reload]; } @@ -456,6 +468,7 @@ - (CGRect)rectForImage { frame = self.bounds; frame.origin.x += imageBoxStyle.margin.left; frame.origin.y += imageBoxStyle.margin.top; + } else { frame.size = imageSize; frame.origin.x += imageBoxStyle.margin.left; diff --git a/src/Three20UI/Sources/TTButtonBar.m b/src/Three20UI/Sources/TTButtonBar.m index 1ea9cf2da6..a8bc34390e 100644 --- a/src/Three20UI/Sources/TTButtonBar.m +++ b/src/Three20UI/Sources/TTButtonBar.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,9 +23,9 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static CGFloat kPadding = 10; -static CGFloat kButtonHeight = 30; -static CGFloat kButtonMaxWidth = 120; +static CGFloat kPadding = 10.0f; +static CGFloat kButtonHeight = 30.0f; +static CGFloat kButtonMaxWidth = 120.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -39,7 +39,8 @@ @implementation TTButtonBar /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _buttons = [[NSMutableArray alloc] init]; self.buttonStyle = @"toolbarButton:"; diff --git a/src/Three20UI/Sources/TTButtonContent.m b/src/Three20UI/Sources/TTButtonContent.m index 720ae261a2..27a1fb3af1 100644 --- a/src/Three20UI/Sources/TTButtonContent.m +++ b/src/Three20UI/Sources/TTButtonContent.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,10 @@ // limitations under the License. // -#import "Three20UI/TTButtonContent.h" +#import "Three20UI/private/TTButtonContent.h" + +// Style +#import "Three20Style/TTImageStyle.h" // UI #import "Three20UI/TTImageViewDelegate.h" @@ -42,7 +45,8 @@ @implementation TTButtonContent /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithButton:(TTButton*)button { - if (self = [super init]) { + self = [super init]; + if (self) { _button = button; } return self; @@ -146,7 +150,13 @@ - (void)reload { if ([_delegate respondsToSelector:@selector(imageView:didLoadImage:)]) { [_delegate imageView:nil didLoadImage:image]; } + } else { + TTImageStyle* imageStyle = [_style firstStyleOfClass:[TTImageStyle class]]; + if (imageStyle && imageStyle.defaultImage) { + self.image = imageStyle.defaultImage; + } + TTURLRequest* request = [TTURLRequest requestWithURL:_imageURL delegate:self]; request.response = [[[TTURLImageResponse alloc] init] autorelease]; [request send]; diff --git a/src/Three20UI/Sources/TTErrorView.m b/src/Three20UI/Sources/TTErrorView.m index 5e6ee3df3a..0b8e5de6dd 100644 --- a/src/Three20UI/Sources/TTErrorView.m +++ b/src/Three20UI/Sources/TTErrorView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,9 +26,10 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kVPadding1 = 30; -static const CGFloat kVPadding2 = 20; -static const CGFloat kHPadding = 10; +static const CGFloat kVPadding1 = 30.0f; +static const CGFloat kVPadding2 = 10.0f; +static const CGFloat kVPadding3 = 15.0f; +static const CGFloat kHPadding = 10.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -36,10 +37,25 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// @implementation TTErrorView +@synthesize reloadButton = _reloadButton; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)addReloadButton { + _reloadButton = [[TTButton buttonWithStyle:@"tableReloadButton:"] retain]; + [_reloadButton setImage:@"bundle://Three20.bundle/images/reloadButton.png" + forState:UIControlStateNormal]; + [_reloadButton sizeToFit]; + [self addSubview:_reloadButton]; + + [self layoutSubviews]; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title subtitle:(NSString*)subtitle image:(UIImage*)image { - if (self = [self init]) { + self = [self init]; + if (self) { self.title = title; self.subtitle = subtitle; self.image = image; @@ -51,7 +67,8 @@ - (id)initWithTitle:(NSString*)title subtitle:(NSString*)subtitle image:(UIImage /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _imageView = [[UIImageView alloc] init]; _imageView.contentMode = UIViewContentModeCenter; [self addSubview:_imageView]; @@ -81,6 +98,7 @@ - (void)dealloc { TT_RELEASE_SAFELY(_imageView); TT_RELEASE_SAFELY(_titleView); TT_RELEASE_SAFELY(_subtitleView); + TT_RELEASE_SAFELY(_reloadButton); [super dealloc]; } @@ -102,7 +120,7 @@ - (void)layoutSubviews { + kVPadding1 + kVPadding2; BOOL canShowImage = _imageView.image && self.height > maxHeight; - CGFloat totalHeight = 0; + CGFloat totalHeight = 0.0f; if (canShowImage) { totalHeight += _imageView.height; @@ -114,12 +132,15 @@ - (void)layoutSubviews { totalHeight += (totalHeight ? kVPadding2 : 0) + _subtitleView.height; } + totalHeight += (totalHeight ? kVPadding3 : 0) + _reloadButton.height; + CGFloat top = floor(self.height/2 - totalHeight/2); if (canShowImage) { _imageView.origin = CGPointMake(floor(self.width/2 - _imageView.width/2), top); _imageView.hidden = NO; top += _imageView.height + kVPadding1; + } else { _imageView.hidden = YES; } @@ -129,6 +150,11 @@ - (void)layoutSubviews { } if (_subtitleView.text.length) { _subtitleView.origin = CGPointMake(floor(self.width/2 - _subtitleView.width/2), top); + top += _subtitleView.height + kVPadding3; + } + + if (_reloadButton!=nil) { + _reloadButton.origin = CGPointMake(floor(self.width/2 - _reloadButton.width/2), top); } } @@ -175,4 +201,6 @@ - (void)setImage:(UIImage*)image { } + + @end diff --git a/src/Three20UI/Sources/TTExtensionInfoController.m b/src/Three20UI/Sources/TTExtensionInfoController.m new file mode 100644 index 0000000000..3f24d4425d --- /dev/null +++ b/src/Three20UI/Sources/TTExtensionInfoController.m @@ -0,0 +1,105 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UI/TTExtensionInfoController.h" + +// UI +#import "Three20UI/TTSectionedDataSource.h" +#import "Three20UI/TTTableCaptionItem.h" +#import "Three20UI/TTTableLongTextItem.h" +#import "Three20UI/TTTableTextItem.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/TTDebug.h" +#import "Three20Core/TTExtensionInfo.h" +#import "Three20Core/TTExtensionAuthor.h" +#import "Three20Core/TTExtensionLoader.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTExtensionInfoController + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithExtensionID:(NSString*)identifier { + self = [super initWithNibName:nil bundle:nil]; + if (self) { + self.title = @"Extension Info"; + self.tableViewStyle = UITableViewStyleGrouped; + + _extension = [[[TTExtensionLoader availableExtensions] objectForKey:identifier] retain]; + + self.variableHeightRows = YES; + } + + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + return [self initWithExtensionID:nil]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)dealloc { + TT_RELEASE_SAFELY(_extension); + [super dealloc]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)viewDidLoad { + [super viewDidLoad]; + + NSMutableArray* items = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray* titles = [[[NSMutableArray alloc] init] autorelease]; + + [titles addObject:@"Description"]; + [items addObject:[NSArray arrayWithObjects: + [TTTableLongTextItem itemWithText:_extension.description], + nil]]; + + [titles addObject:@"General Info"]; + [items addObject:[NSArray arrayWithObjects: + [TTTableCaptionItem itemWithText:_extension.name caption:@"Name:"], + [TTTableCaptionItem itemWithText:_extension.version caption:@"Version:"], + [TTTableCaptionItem itemWithText:_extension.license caption:@"License:"], + [TTTableCaptionItem itemWithText:_extension.copyright caption:@"Copyright:"], + nil]]; + + if ([_extension.authors count] > 0) { + [titles addObject:@"Authors"]; + NSMutableArray* authorItems = [[[NSMutableArray alloc] initWithCapacity: + [_extension.authors count]] autorelease]; + for (TTExtensionAuthor* author in _extension.authors) { + TTDASSERT([author isKindOfClass:[TTExtensionAuthor class]]); + [authorItems addObject:[TTTableTextItem itemWithText:author.name]]; + } + + [items addObject:authorItems]; + } + + self.dataSource = [TTSectionedDataSource dataSourceWithItems:items sections:titles]; +} + + +@end + diff --git a/src/Three20UI/Sources/TTExtensionsController.m b/src/Three20UI/Sources/TTExtensionsController.m new file mode 100644 index 0000000000..2742927578 --- /dev/null +++ b/src/Three20UI/Sources/TTExtensionsController.m @@ -0,0 +1,138 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "TTExtensionsController.h" + +// UI +#import "Three20UI/TTExtensionInfoController.h" +#import "Three20UI/TTNavigator.h" +#import "Three20UI/TTSectionedDataSource.h" +#import "Three20UI/TTTableSubtitleItem.h" +#import "Three20UI/TTTableLongTextItem.h" + +// UINavigator +#import "Three20UINavigator/TTURLMap.h" +#import "Three20UINavigator/UIViewController+TTNavigator.h" + +// Core +#import "Three20Core/TTExtensionInfo.h" +#import "Three20Core/TTExtensionLoader.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTExtensionsController + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + self.title = @"Extensions"; + self.variableHeightRows = YES; + + self.tableViewStyle = UITableViewStyleGrouped; + } + + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (void)registerUrlPathsWithNavigator:(TTNavigator*)navigator prefix:(NSString*)prefix { + TTURLMap* map = navigator.URLMap; + + NSString* extensionsUrlPath = [prefix stringByAppendingString:@"extensions"]; + [map from: extensionsUrlPath + toViewController: [TTExtensionsController class]]; + [map from: [extensionsUrlPath + stringByAppendingString:@"/(initWithExtensionID:)"] + toViewController: [TTExtensionInfoController class]]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTTableItem*)tableItemForExtension:(TTExtensionInfo*)extension { + NSString* urlPath = [[self navigatorURL] stringByAppendingFormat:@"/%@", + extension.identifier]; + TTTableSubtitleItem* item = [TTTableSubtitleItem itemWithText: extension.name + subtitle: extension.version + URL: urlPath]; + + return item; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)viewDidLoad { + [super viewDidLoad]; + + NSDictionary* loadedExtensions = [TTExtensionLoader loadedExtensions]; + NSDictionary* failedExtensions = [TTExtensionLoader failedExtensions]; + NSMutableDictionary* availableExtensions = [NSMutableDictionary dictionaryWithDictionary: + [TTExtensionLoader availableExtensions]]; + + NSMutableArray* loadedItems = [[[NSMutableArray alloc] + initWithCapacity:[loadedExtensions count]] autorelease]; + NSMutableArray* failedItems = [[[NSMutableArray alloc] + initWithCapacity:[failedExtensions count]] autorelease]; + NSMutableArray* availableItems = [[[NSMutableArray alloc] + initWithCapacity:[availableExtensions count]] autorelease]; + + NSMutableArray* sectionTitles = [[[NSMutableArray alloc] initWithCapacity:3] autorelease]; + NSMutableArray* sectionItems = [[[NSMutableArray alloc] initWithCapacity:3] autorelease]; + + if ([loadedExtensions count] > 0) { + [sectionTitles addObject:@"Loaded extensions"]; + for (NSString* extensionID in loadedExtensions) { + [availableExtensions removeObjectForKey:extensionID]; + + TTExtensionInfo* extension = [loadedExtensions objectForKey:extensionID]; + [loadedItems addObject:[self tableItemForExtension:extension]]; + } + [sectionItems addObject:loadedItems]; + } + + if ([failedExtensions count] > 0) { + [sectionTitles addObject:@"Failed extensions"]; + for (NSString* extensionID in failedExtensions) { + [availableExtensions removeObjectForKey:extensionID]; + + TTExtensionInfo* extension = [failedExtensions objectForKey:extensionID]; + [failedItems addObject:[self tableItemForExtension:extension]]; + } + [sectionItems addObject:failedItems]; + } + + if ([availableExtensions count] > 0) { + [sectionTitles addObject:@"Linked, but not loaded extensions"]; + for (NSString* extensionID in availableExtensions) { + TTExtensionInfo* extension = [availableExtensions objectForKey:extensionID]; + [availableItems addObject:[self tableItemForExtension:extension]]; + } + [availableItems addObject: + [TTTableLongTextItem itemWithText: + @"Call [TTExtensionLoader loadAllExtensions] in your app delegate to load extensions."]]; + [sectionItems addObject:availableItems]; + } + + self.dataSource = [TTSectionedDataSource dataSourceWithItems: sectionItems + sections: sectionTitles]; +} + +@end + diff --git a/src/Three20UI/Sources/TTImageLayer.m b/src/Three20UI/Sources/TTImageLayer.m index c368edbe35..101583c4a0 100644 --- a/src/Three20UI/Sources/TTImageLayer.m +++ b/src/Three20UI/Sources/TTImageLayer.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // -#import "Three20UI/TTImageLayer.h" +#import "Three20UI/private/TTImageLayer.h" // UI #import "Three20UI/TTImageView.h" @@ -32,6 +32,7 @@ @implementation TTImageLayer - (void)display { if (nil != _override) { self.contents = (id)_override.image.CGImage; + } else { return [super display]; } diff --git a/src/Three20UI/Sources/TTImageView.m b/src/Three20UI/Sources/TTImageView.m index 342ff9aa96..18e2d5211a 100644 --- a/src/Three20UI/Sources/TTImageView.m +++ b/src/Three20UI/Sources/TTImageView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,10 +18,10 @@ // UI #import "Three20UI/TTImageViewDelegate.h" -#import "Three20UI/TTImageLayer.h" // UI (private) -#import "Three20UI/TTImageViewInternal.h" +#import "Three20UI/private/TTImageLayer.h" +#import "Three20UI/private/TTImageViewInternal.h" // Style #import "Three20Style/TTShape.h" @@ -44,13 +44,15 @@ @implementation TTImageView @synthesize image = _image; @synthesize defaultImage = _defaultImage; @synthesize autoresizesToImage = _autoresizesToImage; +@synthesize request = _request; @synthesize delegate = _delegate; /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _autoresizesToImage = NO; } return self; @@ -99,6 +101,7 @@ - (void)drawRect:(CGRect)rect { - (void)drawContent:(CGRect)rect { if (nil != _image) { [_image drawInRect:rect contentMode:self.contentMode]; + } else { [_defaultImage drawInRect:rect contentMode:self.contentMode]; } @@ -207,9 +210,14 @@ - (void)reload { TTURLRequest* request = [TTURLRequest requestWithURL:_urlPath delegate:self]; request.response = [[[TTURLImageResponse alloc] init] autorelease]; + // Give the delegate one chance to configure the requester. + if ([_delegate respondsToSelector:@selector(imageView:willSendARequest:)]) { + [_delegate imageView:self willSendARequest:request]; + } + if (![request send]) { // Put the default image in place while waiting for the request to load - if (_defaultImage && self.image != _defaultImage) { + if (_defaultImage && nil == self.image) { self.image = _defaultImage; } } @@ -252,6 +260,19 @@ - (void)unsetImage { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setDefaultImage:(UIImage*)theDefaultImage { + if (_defaultImage != theDefaultImage) { + [_defaultImage release]; + _defaultImage = [theDefaultImage retain]; + } + if (nil == _urlPath || 0 == _urlPath.length) { + //no url path set yet, so use it as the current image + self.image = _defaultImage; + } +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setUrlPath:(NSString*)urlPath { // Check for no changes. diff --git a/src/Three20UI/Sources/TTImageViewInternal.m b/src/Three20UI/Sources/TTImageViewInternal.m index 00fa96349d..7826ce06ea 100644 --- a/src/Three20UI/Sources/TTImageViewInternal.m +++ b/src/Three20UI/Sources/TTImageViewInternal.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,19 +14,24 @@ // limitations under the License. // -#import "Three20UI/TTImageViewInternal.h" +#import "Three20UI/private/TTImageViewInternal.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" // UI #import "Three20UI/TTImageViewDelegate.h" #import "Three20UI/UIViewAdditions.h" // UI (private) -#import "Three20UI/TTImageLayer.h" +#import "Three20UI/private/TTImageLayer.h" /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +TT_FIX_CATEGORY_BUG(TTImageViewInternal) + @implementation TTImageView (TTInternal) @@ -67,11 +72,13 @@ - (void)setImage:(UIImage*)image { // If a width was specified, but no height, then resize the image with the correct aspect // ratio. + } else if (frame.size.width && !frame.size.height) { self.height = floor((image.size.height/image.size.width) * frame.size.width); // If a height was specified, but no width, then resize the image with the correct aspect // ratio. + } else if (frame.size.height && !frame.size.width) { self.width = floor((image.size.width/image.size.height) * frame.size.height); } diff --git a/src/Three20UI/Sources/TTLabel.m b/src/Three20UI/Sources/TTLabel.m index acfbbfc436..3d4af53018 100644 --- a/src/Three20UI/Sources/TTLabel.m +++ b/src/Three20UI/Sources/TTLabel.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -37,7 +37,8 @@ @implementation TTLabel /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithText:(NSString*)text { - if (self = [self init]) { + self = [self init]; + if (self) { self.text = text; } return self; @@ -46,7 +47,8 @@ - (id)initWithText:(NSString*)text { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _text = nil; _font = nil; } diff --git a/src/Three20UI/Sources/TTLauncherButton.m b/src/Three20UI/Sources/TTLauncherButton.m index c9d22eeaf8..7ed90725a5 100644 --- a/src/Three20UI/Sources/TTLauncherButton.m +++ b/src/Three20UI/Sources/TTLauncherButton.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,6 +36,9 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// @interface TTLauncherButton() +/** + * Adds the badge view to this button and sets its display values. + */ - (void)updateBadge; @end @@ -54,7 +57,8 @@ @implementation TTLauncherButton /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithItem:(TTLauncherItem*)item { - if (self = [self init]) { + self = [self init]; + if (self) { _item = [item retain]; NSString* title = [[NSBundle mainBundle] localizedStringForKey:item.title value:nil table:nil]; @@ -77,7 +81,8 @@ - (id)initWithItem:(TTLauncherItem*)item { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { self.isVertical = YES; } @@ -103,7 +108,7 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)updateBadge { - if (!_badge && _item.badgeNumber) { + if (_badge == nil && _item.badgeValue != nil) { _badge = [[TTLabel alloc] init]; _badge.style = TTSTYLE(largeBadge); _badge.backgroundColor = [UIColor clearColor]; @@ -111,16 +116,23 @@ - (void)updateBadge { [self addSubview:_badge]; } - if (_item.badgeNumber > 0) { - if (_item.badgeNumber <= kMaxBadgeNumber) { - _badge.text = [NSString stringWithFormat:@"%d", _item.badgeNumber]; + NSString *badgeText = nil; + NSString *badgeValue = _item.badgeValue; + + if (badgeValue != nil) { + NSRange range = [badgeValue rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] + invertedSet]]; + + if (range.location == NSNotFound && _item.badgeNumber > kMaxBadgeNumber) { + badgeText = [NSString stringWithFormat:@"%d+", kMaxBadgeNumber]; } else { - _badge.text = [NSString stringWithFormat:@"%d+", kMaxBadgeNumber]; + badgeText = badgeValue; } } - _badge.hidden = _item.badgeNumber <= 0; + _badge.text = badgeText; + _badge.hidden = badgeValue == nil; [_badge sizeToFit]; [self setNeedsLayout]; } @@ -182,7 +194,9 @@ - (void)layoutSubviews { if (_badge || _closeButton) { CGRect imageRect = [self rectForImage]; if (_badge) { - _badge.origin = CGPointMake((imageRect.origin.x + imageRect.size.width) - (floor(_badge.width*0.7)), + _badge.origin = CGPointMake((imageRect.origin.x + + imageRect.size.width) + - (floor(_badge.width*0.7)), imageRect.origin.y - (floor(_badge.height*0.25))); } @@ -222,6 +236,7 @@ - (void)setDragging:(BOOL)dragging { if (dragging) { self.transform = CGAffineTransformMakeScale(1.4, 1.4); self.alpha = 0.7; + } else { self.transform = CGAffineTransformIdentity; self.alpha = 1; diff --git a/src/Three20UI/Sources/TTLauncherHighlightView.m b/src/Three20UI/Sources/TTLauncherHighlightView.m index 9bbd4843ec..e8aa4bd529 100644 --- a/src/Three20UI/Sources/TTLauncherHighlightView.m +++ b/src/Three20UI/Sources/TTLauncherHighlightView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // -#import "Three20UI/TTLauncherHighlightView.h" +#import "Three20UI/private/TTLauncherHighlightView.h" // UI #import "Three20UI/TTLauncherButton.h" @@ -59,6 +59,13 @@ - (id)initWithFrame:(CGRect)frame { _textLabel.shadowOffset = CGSizeMake(1, 1); [self addSubview:_textLabel]; + + CGRect coverFrame = [UIApplication sharedApplication].statusBarFrame; + _statusBarCover = [[UIWindow alloc] initWithFrame:coverFrame]; + _statusBarCover.backgroundColor = [UIColor colorWithWhite:0.0 alpha:kHighlightOverlayAlpha]; + _statusBarCover.windowLevel = UIWindowLevelStatusBar; + _statusBarCover.alpha = 0.0; + _statusBarCover.hidden = NO; } return self; @@ -68,6 +75,7 @@ - (id)initWithFrame:(CGRect)frame { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dealloc { TT_RELEASE_SAFELY(_textLabel); + TT_RELEASE_SAFELY(_statusBarCover); self.parentView = nil; [super dealloc]; @@ -93,14 +101,16 @@ - (void)animateTextIn { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)layoutLabel { - CGFloat width = self.bounds.size.width - 2 * kHighlightTextPadding; + CGSize superviewSize = self.superview.bounds.size; + CGFloat width = superviewSize.width - 2 * kHighlightTextPadding; CGFloat height = [_textLabel.text sizeWithFont:_textLabel.font - constrainedToSize:CGSizeMake(width, self.bounds.size.height)].height; + constrainedToSize:CGSizeMake(width, superviewSize.height)].height; // If the highlighted rect is above center, put the text below it; otherwise, above it. - CGFloat y = 0.0; - if (_highlightRect.origin.y + (_highlightRect.size.height / 2) < self.bounds.size.height / 2) { + CGFloat y = 0.0f; + if (_highlightRect.origin.y + (_highlightRect.size.height / 2) < superviewSize.height / 2) { y = _highlightRect.origin.y + _highlightRect.size.height + kHighlightTextPadding; + } else { y = _highlightRect.origin.y - height - kHighlightTextPadding; } @@ -108,7 +118,6 @@ - (void)layoutLabel { _textLabel.frame = CGRectMake(kHighlightTextPadding, y, width, height); } - /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - @@ -135,6 +144,13 @@ - (void)setText:(NSString*)text { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setAlpha:(CGFloat)alpha { + [super setAlpha:alpha]; + _statusBarCover.alpha = alpha; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)appear:(BOOL)animated { // The expanded frame needs to be 3.5 times the original size, and the expansion needs to emanate @@ -159,8 +175,11 @@ - (void)appear:(BOOL)animated { } self.alpha = 1.0; self.frame = self.superview.bounds; + _statusBarCover.alpha = 1.0; + if (animated) { [UIView commitAnimations]; + } else { _textLabel.alpha = 1.0; } diff --git a/src/Three20UI/Sources/TTLauncherItem.m b/src/Three20UI/Sources/TTLauncherItem.m index b484f3d47a..9a9635039d 100644 --- a/src/Three20UI/Sources/TTLauncherItem.m +++ b/src/Three20UI/Sources/TTLauncherItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,8 +30,9 @@ @implementation TTLauncherItem @synthesize image = _image; @synthesize URL = _URL; @synthesize style = _style; -@synthesize badgeNumber = _badgeNumber; +@synthesize badgeValue = _badgeValue; @synthesize canDelete = _canDelete; +@synthesize userInfo = _userInfo; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -42,7 +43,8 @@ @implementation TTLauncherItem /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title image:(NSString*)image URL:(NSString*)URL { - if (self = [self initWithTitle:title image:image URL:URL canDelete:NO]) { + self = [self initWithTitle:title image:image URL:URL canDelete:NO]; + if (self) { } return self; @@ -52,7 +54,8 @@ - (id)initWithTitle:(NSString*)title image:(NSString*)image URL:(NSString*)URL { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title image:(NSString*)image URL:(NSString*)URL canDelete:(BOOL)canDelete { - if (self = [super init]) { + self = [super init]; + if (self) { _canDelete = canDelete; self.title = title; @@ -66,10 +69,12 @@ - (id)initWithTitle:(NSString*)title image:(NSString*)image URL:(NSString*)URL /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dealloc { + TT_RELEASE_SAFELY(_badgeValue); TT_RELEASE_SAFELY(_title); TT_RELEASE_SAFELY(_image); TT_RELEASE_SAFELY(_URL); TT_RELEASE_SAFELY(_style); + TT_RELEASE_SAFELY(_userInfo); [super dealloc]; } @@ -83,7 +88,8 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super init]) { + self = [super init]; + if (self) { self.title = [decoder decodeObjectForKey:@"title"]; self.image = [decoder decodeObjectForKey:@"image"]; self.URL = [decoder decodeObjectForKey:@"URL"]; @@ -111,12 +117,31 @@ - (void)encodeWithCoder:(NSCoder*)encoder { #pragma mark Public +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSInteger)badgeNumber { + return [self.badgeValue integerValue]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setBadgeNumber:(NSInteger)badgeNumber { - _badgeNumber = badgeNumber; + if (badgeNumber == 0) { + [self setBadgeValue:nil]; - [_launcher performSelector:@selector(updateItemBadge:) withObject:self]; + } else { + [self setBadgeValue:[NSString stringWithFormat:@"%d",badgeNumber]]; + } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setBadgeValue:(NSString *)badgeValue { + if (_badgeValue != badgeValue) { + [_badgeValue release]; + _badgeValue = [badgeValue copy]; + } + + [_launcher performSelector:@selector(updateItemBadge:) withObject:self]; +} + @end diff --git a/src/Three20UI/Sources/TTLauncherScrollView.m b/src/Three20UI/Sources/TTLauncherScrollView.m index 36354e2dd3..38a6b18d36 100644 --- a/src/Three20UI/Sources/TTLauncherScrollView.m +++ b/src/Three20UI/Sources/TTLauncherScrollView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // -#import "Three20UI/TTLauncherScrollView.h" +#import "Three20UI/private/TTLauncherScrollView.h" /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Three20UI/Sources/TTLauncherView.m b/src/Three20UI/Sources/TTLauncherView.m index efe8937ba5..cff463e688 100644 --- a/src/Three20UI/Sources/TTLauncherView.m +++ b/src/Three20UI/Sources/TTLauncherView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,9 +23,10 @@ #import "Three20UI/TTPageControl.h" #import "Three20UI/UIViewAdditions.h" + // UI (private) -#import "Three20UI/TTLauncherScrollView.h" -#import "Three20UI/TTLauncherHighlightView.h" +#import "Three20UI/private/TTLauncherScrollView.h" +#import "Three20UI/private/TTLauncherHighlightView.h" // UICommon #import "Three20UICommon/TTGlobalUICommon.h" @@ -42,12 +43,12 @@ #import "Three20Core/TTDebugFlags.h" #import "Three20Core/TTGlobalCoreRects.h" -static const CGFloat kMargin = 0; -static const CGFloat kPadding = 0; -static const CGFloat kPromptMargin = 40; -static const CGFloat kPagerHeight = 20; -static const CGFloat kWobbleRadians = 1.5; -static const CGFloat kSpringLoadFraction = 0.18; +static const CGFloat kMargin = 0.0f; +static const CGFloat kPadding = 0.0f; +static const CGFloat kPromptMargin = 40.0f; +static const CGFloat kPagerHeight = 20.0f; +static const CGFloat kWobbleRadians = 1.5f; +static const CGFloat kSpringLoadFraction = 0.18f; static const NSTimeInterval kEditHoldTimeInterval = 1; static const NSTimeInterval kSpringLoadTimeInterval = 0.5; @@ -64,14 +65,18 @@ @implementation TTLauncherView @synthesize columnCount = _columnCount; +@synthesize pager = _pager; @synthesize prompt = _prompt; @synthesize editing = _editing; @synthesize delegate = _delegate; - +@synthesize editable = _editable; +@synthesize persistenceMode = _persistenceMode; +@synthesize persistenceKey = _persistenceKey; /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _scrollView = [[TTLauncherScrollView alloc] initWithFrame: CGRectMake(0, 0, self.width, self.height - kPagerHeight)]; _scrollView.delegate = self; @@ -96,6 +101,10 @@ - (id)initWithFrame:(CGRect)frame { self.autoresizesSubviews = YES; self.columnCount = kDefaultColumnCount; + self.editable = YES; + self.persistenceKey = @"launcherViewPages"; + self.persistenceMode = TTLauncherPersistenceModeNone; + } return self; @@ -131,11 +140,7 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGFloat)rowHeight { -// if (UIInterfaceOrientationIsPortrait(TTInterfaceOrientation())) { - return 103; -// } else { -// return 74; -// } + return round(_scrollView.height / 3); } @@ -148,6 +153,7 @@ - (TTLauncherButton*)buttonForItem:(TTLauncherItem*)item { NSInteger itemIndex = [path indexAtPosition:1]; return [buttonPage objectAtIndex:itemIndex]; + } else { return nil; } @@ -172,6 +178,7 @@ - (NSMutableArray*)pageWithButton:(TTLauncherButton*)button { if (path) { NSInteger pageIndex = [path indexAtPosition:0]; return [_buttons objectAtIndex:pageIndex]; + } else { return nil; } @@ -259,7 +266,7 @@ - (void)layoutButtons { CGFloat buttonHeight = [self rowHeight]; CGFloat pageWidth = _scrollView.width; - CGFloat x = kMargin, minX = 0; + CGFloat x = kMargin, minX = 0.0f; for (NSMutableArray* buttonPage in _buttons) { CGFloat y = kMargin; for (TTLauncherButton* button in buttonPage) { @@ -327,6 +334,7 @@ - (void)checkButtonOverflow:(NSInteger)pageIndex { [_buttons addObject:nextButtonPage]; nextItemsPage = [NSMutableArray array]; [_pages addObject:nextItemsPage]; + } else { nextButtonPage = [_buttons objectAtIndex:pageIndex+1]; nextItemsPage = [_pages objectAtIndex:pageIndex+1]; @@ -381,6 +389,7 @@ - (void)startDraggingButton:(TTLauncherButton*)button withEvent:(UIEvent*)event button.dragging = YES; _scrollView.scrollEnabled = NO; + } else { [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(releaseButtonDidStop)]; @@ -414,6 +423,7 @@ - (void)springLoadTimer:(NSTimer*)timer { _springing = YES; [self performSelector:@selector(springingDidStop) withObject:nil afterDelay:0.3]; } + } else { CGFloat newX = _scrollView.contentOffset.x + _scrollView.width; if (newX <= _scrollView.contentSize.width - _scrollView.width) { @@ -449,6 +459,7 @@ - (void)buttonTouchedUpInside:(TTLauncherButton*)button { if (button == _dragButton) { [self startDraggingButton:nil withEvent:nil]; } + } else { TT_INVALIDATE_TIMER(_editHoldTimer); [button setSelected:YES]; @@ -470,6 +481,7 @@ - (void)buttonTouchedUpOutside:(TTLauncherButton*)button { if (button == _dragButton) { [self startDraggingButton:nil withEvent:nil]; } + } else { TT_INVALIDATE_TIMER(_editHoldTimer); } @@ -478,10 +490,14 @@ - (void)buttonTouchedUpOutside:(TTLauncherButton*)button { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)buttonTouchedDown:(TTLauncherButton*)button withEvent:(UIEvent*)event { + if (!self.editable) + return; + if (_editing) { if (!_dragButton) { [self startDraggingButton:button withEvent:event]; } + } else { TT_INVALIDATE_TIMER(_editHoldTimer); @@ -525,6 +541,7 @@ - (void)wobble { ++nWobblyButtons; if (i % 2) { button.transform = wobblesLeft ? wobbleRight : wobbleLeft; + } else { button.transform = wobblesLeft ? wobbleLeft : wobbleRight; } @@ -538,6 +555,7 @@ - (void)wobble { [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(wobble)]; wobblesLeft = !wobblesLeft; + } else { [NSObject cancelPreviousPerformRequestsWithTarget:self]; [self performSelector:@selector(wobble) withObject:nil afterDelay:kWobbleTime]; @@ -641,6 +659,7 @@ - (void)updateTouch { target:self selector:@selector(springLoadTimer:) userInfo:[NSNumber numberWithBool:goToPreviousPage] repeats:NO]; } + } else { TT_INVALIDATE_TIMER(_springLoadTimer); } @@ -674,6 +693,12 @@ - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent *)event { if (_dragTouch) { for (UITouch* touch in touches) { if (touch == _dragTouch) { + + // New delegate method + if ([_delegate respondsToSelector:@selector(launcherViewDidEndDragging:)]) { + [_delegate launcherViewDidEndDragging:self]; + } + _dragTouch = nil; break; } @@ -688,6 +713,13 @@ - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent *)event { #pragma mark UIView +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setFrame:(CGRect)newFrame { + [super setFrame:newFrame]; + [self layoutButtons]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)layoutSubviews { [super layoutSubviews]; @@ -714,7 +746,13 @@ - (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { - [self updatePagerWithContentOffset:_scrollView.contentOffset]; + [self updatePagerWithContentOffset:scrollView.contentOffset]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { + [self updatePagerWithContentOffset:scrollView.contentOffset]; } @@ -806,6 +844,7 @@ - (void)addItem:(TTLauncherItem*)item animated:(BOOL)animated { if (!_pages) { _pages = [[NSMutableArray arrayWithObject:[NSMutableArray arrayWithObject:item]] retain]; + } else { NSMutableArray* page = [self pageWithFreeSpace:self.currentPageIndex]; [page addObject:item]; @@ -841,11 +880,13 @@ - (void)removeItem:(TTLauncherItem*)item animated:(BOOL)animated { [UIView beginAnimations:nil context:button]; [UIView setAnimationDuration:TT_FAST_TRANSITION_DURATION]; [UIView setAnimationDelegate:self]; - [UIView setAnimationDidStopSelector:@selector(removeButtonAnimationDidStop:finished:context:)]; + [UIView setAnimationDidStopSelector: + @selector(removeButtonAnimationDidStop:finished:context:)]; [self layoutButtons]; button.transform = CGAffineTransformMakeScale(0.01, 0.01); button.alpha = 0; [UIView commitAnimations]; + } else { [button removeFromSuperview]; [self layoutButtons]; @@ -893,6 +934,9 @@ - (void)scrollToItem:(TTLauncherItem*)item animated:(BOOL)animated { NSUInteger page = [path indexAtPosition:0]; CGFloat x = page * _scrollView.width; [_scrollView setContentOffset:CGPointMake(x, 0) animated:animated]; + if (!animated) { + [self updatePagerWithContentOffset:CGPointMake(x, 0)]; + } } } @@ -956,16 +1000,55 @@ - (void)endEditing { [self layoutButtons]; + if (self.persistenceMode == TTLauncherPersistenceModeAll) { + [self persistLauncherItems]; + } + if ([_delegate respondsToSelector:@selector(launcherViewDidEndEditing:)]) { [_delegate launcherViewDidEndEditing:self]; } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)persistLauncherItems { + NSData* pagesData = [NSKeyedArchiver archivedDataWithRootObject:self.pages]; + [[NSUserDefaults standardUserDefaults] setValue:pagesData forKey:self.persistenceKey]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)restoreLauncherItems { + if (self.persistenceMode == TTLauncherPersistenceModeAll) { + NSData* pagesData = [[NSUserDefaults standardUserDefaults] objectForKey:self.persistenceKey]; + + NSObject* pages; + if (pagesData!=nil) { + pages = [NSKeyedUnarchiver unarchiveObjectWithData:pagesData]; + } + + if (pagesData!=nil && pages!=nil && [pages isKindOfClass:[NSArray class]]) { + self.pages = (NSArray*)pages; + return YES; + } + } + + return NO; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)resetDefaults { + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + + [defaults removeObjectForKey:_persistenceKey]; + [defaults synchronize]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)beginHighlightItem:(TTLauncherItem*)item withText:(NSString*)text { if (nil == _highlightView) { - _highlightView = [[TTLauncherHighlightView alloc] initWithFrame:self.window.bounds]; + _highlightView = [[TTLauncherHighlightView alloc] initWithFrame:CGRectZero]; _highlightView.parentView = self; [self.window addSubview:_highlightView]; } diff --git a/src/Three20UI/Sources/TTLink.m b/src/Three20UI/Sources/TTLink.m index e44f26f01a..cf99fc9c9d 100644 --- a/src/Three20UI/Sources/TTLink.m +++ b/src/Three20UI/Sources/TTLink.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -42,7 +42,8 @@ @implementation TTLink /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { self.userInteractionEnabled = NO; [self addTarget: self action: @selector(linkTouched) forControlEvents:UIControlEventTouchUpInside]; @@ -69,7 +70,7 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)linkTouched { - [[TTNavigator navigator] openURLAction:_URLAction]; + [[TTBaseNavigator navigatorForView:self] openURLAction:_URLAction]; } @@ -93,6 +94,7 @@ - (void)setHighlighted:(BOOL)highlighted { _screenView.frame = self.bounds; _screenView.hidden = NO; + } else { _screenView.hidden = YES; } diff --git a/src/Three20UI/Sources/TTListDataSource.m b/src/Three20UI/Sources/TTListDataSource.m index 4d8e81ca10..4702d5e1ca 100644 --- a/src/Three20UI/Sources/TTListDataSource.m +++ b/src/Three20UI/Sources/TTListDataSource.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,7 +33,8 @@ @implementation TTListDataSource /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithItems:(NSArray*)items { - if (self = [self init]) { + self = [self init]; + if (self) { _items = [items mutableCopy]; } @@ -98,6 +99,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger - (id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)indexPath { if (indexPath.row < _items.count) { return [_items objectAtIndex:indexPath.row]; + } else { return nil; } diff --git a/src/Three20UI/Sources/TTMessageController.m b/src/Three20UI/Sources/TTMessageController.m index d5d99b2f0f..4836b4bbd2 100644 --- a/src/Three20UI/Sources/TTMessageController.m +++ b/src/Three20UI/Sources/TTMessageController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ #import "Three20Core/TTGlobalCoreLocale.h" #import "Three20Core/TTGlobalCoreRects.h" #import "Three20Core/NSStringAdditions.h" +#import "Three20Core/TTGlobalCore.h" /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -50,16 +51,18 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// @implementation TTMessageController -@synthesize fields = _fields; -@synthesize isModified = _isModified; -@synthesize showsRecipientPicker = _showsRecipientPicker; -@synthesize dataSource = _dataSource; -@synthesize delegate = _delegate; +@synthesize fields = _fields; +@synthesize isModified = _isModified; +@synthesize showsRecipientPicker = _showsRecipientPicker; +@synthesize requireNonEmptyMessageBody = _requireNonEmptyMessageBody; +@synthesize dataSource = _dataSource; +@synthesize delegate = _delegate; /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { _fields = [[NSArray alloc] initWithObjects: [[[TTMessageRecipientField alloc] initWithTitle: TTLocalizedString(@"To:", @"") required: YES] autorelease], @@ -88,7 +91,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithRecipients:(NSArray*)recipients { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { _initialRecipients = [recipients retain]; } @@ -143,6 +147,7 @@ - (void)createFieldViews { label.text = field.title; label.font = TTSTYLEVAR(messageFont); label.textColor = TTSTYLEVAR(messageFieldTextColor); + label.backgroundColor = TTSTYLEVAR(backgroundColor); [label sizeToFit]; label.frame = CGRectInset(label.frame, -2, 0); textField.leftView = label; @@ -164,7 +169,7 @@ - (void)createFieldViews { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)layoutViews { - CGFloat y = 0; + CGFloat y = 0.0f; for (UIView* view in _scrollView.subviews) { view.frame = CGRectMake(0, y, self.view.width, view.height); @@ -188,7 +193,8 @@ - (BOOL)hasEnteredText { } else if ([field isKindOfClass:[TTMessageTextField class]]) { UITextField* textField = [_fieldViews objectAtIndex:i]; - if (!textField.text.isEmptyOrWhitespace) { + if (TTIsStringWithAnyText(textField.text) + && !textField.text.isWhitespaceAndNewlines) { return YES; } } @@ -201,7 +207,9 @@ - (BOOL)hasEnteredText { /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)hasRequiredText { - BOOL compliant = YES; + if (_requireNonEmptyMessageBody && [_textEditor.text isWhitespaceAndNewlines]) { + return NO; + } for (int i = 0; i < _fields.count; ++i) { TTMessageField* field = [_fields objectAtIndex:i]; @@ -209,19 +217,19 @@ - (BOOL)hasRequiredText { if ([field isKindOfClass:[TTMessageRecipientField class]]) { TTPickerTextField* textField = [_fieldViews objectAtIndex:i]; if (!textField.cells.count) { - compliant = NO; + return NO; } } else if ([field isKindOfClass:[TTMessageTextField class]]) { UITextField* textField = [_fieldViews objectAtIndex:i]; - if (textField.text.isEmptyOrWhitespace) { - compliant = NO; + if (0 == textField.text.length || textField.text.isWhitespaceAndNewlines) { + return NO; } } } } - return compliant && _textEditor.text.length; + return YES; } @@ -391,6 +399,7 @@ - (BOOL)persistView:(NSMutableDictionary*)state { id data = [field persistField:view]; if (data) { [fields addObject:data]; + } else { [fields addObject:@""]; } @@ -414,7 +423,7 @@ - (BOOL)persistView:(NSMutableDictionary*)state { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)restoreView:(NSDictionary*)state { - self.view; + [self view]; TT_RELEASE_SAFELY(_initialRecipients); NSMutableArray* fields = [state objectForKey:@"fields"]; for (NSInteger i = 0; i < fields.count; ++i) { @@ -531,7 +540,7 @@ - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)butto /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)subject { - self.view; + [self view]; for (int i = 0; i < _fields.count; ++i) { id field = [_fields objectAtIndex:i]; if ([field isKindOfClass:[TTMessageSubjectField class]]) { @@ -545,7 +554,7 @@ - (NSString*)subject { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setSubject:(NSString*)subject { - self.view; + [self view]; for (int i = 0; i < _fields.count; ++i) { id field = [_fields objectAtIndex:i]; if ([field isKindOfClass:[TTMessageSubjectField class]]) { @@ -565,7 +574,7 @@ - (NSString*)body { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setBody:(NSString*)body { - self.view; + [self view]; _textEditor.text = body; } @@ -601,7 +610,7 @@ - (void)setFields:(NSArray*)fields { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)addRecipient:(id)recipient forFieldAtIndex:(NSUInteger)fieldIndex { - self.view; + [self view]; TTPickerTextField* textField = [_fieldViews objectAtIndex:fieldIndex]; if ([textField isKindOfClass:[TTPickerTextField class]]) { NSString* label = [_dataSource tableView:textField.tableView labelForObject:recipient]; @@ -614,11 +623,12 @@ - (void)addRecipient:(id)recipient forFieldAtIndex:(NSUInteger)fieldIndex { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString*)textForFieldAtIndex:(NSUInteger)fieldIndex { - self.view; + [self view]; NSString* text = nil; if (fieldIndex == _fieldViews.count) { text = _textEditor.text; + } else { TTPickerTextField* textField = [_fieldViews objectAtIndex:fieldIndex]; if ([textField isKindOfClass:[TTPickerTextField class]]) { @@ -633,9 +643,10 @@ - (NSString*)textForFieldAtIndex:(NSUInteger)fieldIndex { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setText:(NSString*)text forFieldAtIndex:(NSUInteger)fieldIndex { - self.view; + [self view]; if (fieldIndex == _fieldViews.count) { _textEditor.text = text; + } else { TTPickerTextField* textField = [_fieldViews objectAtIndex:fieldIndex]; if ([textField isKindOfClass:[TTPickerTextField class]]) { @@ -647,18 +658,23 @@ - (void)setText:(NSString*)text forFieldAtIndex:(NSUInteger)fieldIndex { /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)fieldHasValueAtIndex:(NSUInteger)fieldIndex { - self.view; + [self view]; if (fieldIndex == _fieldViews.count) { return _textEditor.text.length > 0; + } else { TTMessageField* field = [_fields objectAtIndex:fieldIndex]; if ([field isKindOfClass:[TTMessageRecipientField class]]) { TTPickerTextField* pickerTextField = [_fieldViews objectAtIndex:fieldIndex]; - return !pickerTextField.text.isEmptyOrWhitespace || pickerTextField.cellViews.count > 0; + return (TTIsStringWithAnyText(pickerTextField.text) + && !pickerTextField.text.isWhitespaceAndNewlines) + || pickerTextField.cellViews.count > 0; + } else { UITextField* textField = [_fieldViews objectAtIndex:fieldIndex]; - return !textField.text.isEmptyOrWhitespace; + return (TTIsStringWithAnyText(textField.text) + && !textField.text.isWhitespaceAndNewlines); } } } @@ -666,10 +682,11 @@ - (BOOL)fieldHasValueAtIndex:(NSUInteger)fieldIndex { /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIView*)viewForFieldAtIndex:(NSUInteger)fieldIndex { - self.view; + [self view]; if (fieldIndex == _fieldViews.count) { return _textEditor; + } else { return [_fieldViews objectAtIndex:fieldIndex]; } @@ -684,6 +701,7 @@ - (void)send { if ([field isKindOfClass:[TTMessageRecipientField class]]) { TTPickerTextField* textField = [_fieldViews objectAtIndex:i]; [(TTMessageRecipientField*)field setRecipients:textField.cells]; + } else if ([field isKindOfClass:[TTMessageTextField class]]) { UITextField* textField = [_fieldViews objectAtIndex:i]; [(TTMessageTextField*)field setText:textField.text]; @@ -711,6 +729,7 @@ - (void)send { - (void)cancel:(BOOL)confirmIfNecessary { if (confirmIfNecessary && ![self messageShouldCancel]) { [self confirmCancellation]; + } else { if ([_delegate respondsToSelector:@selector(composeControllerWillCancel:)]) { [_delegate composeControllerWillCancel:self]; @@ -745,6 +764,7 @@ - (void)showActivityView:(BOOL)show { _activityView.autoresizingMask = UIViewAutoresizingFlexibleWidth; [self.view addSubview:_activityView]; } + } else { [_activityView removeFromSuperview]; TT_RELEASE_SAFELY(_activityView); diff --git a/src/Three20UI/Sources/TTMessageField.m b/src/Three20UI/Sources/TTMessageField.m index aea7ac8807..58e3414a68 100644 --- a/src/Three20UI/Sources/TTMessageField.m +++ b/src/Three20UI/Sources/TTMessageField.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,7 +31,8 @@ @implementation TTMessageField /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title required:(BOOL)required { - if (self = [self init]) { + self = [self init]; + if (self) { _title = [title copy]; _required = required; } diff --git a/src/Three20UI/Sources/TTMessageRecipientField.m b/src/Three20UI/Sources/TTMessageRecipientField.m index 19ac3d5ebb..f6e9c0c34d 100644 --- a/src/Three20UI/Sources/TTMessageRecipientField.m +++ b/src/Three20UI/Sources/TTMessageRecipientField.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTMessageSubjectField.m b/src/Three20UI/Sources/TTMessageSubjectField.m index 93bbf439a9..5e03b952c0 100644 --- a/src/Three20UI/Sources/TTMessageSubjectField.m +++ b/src/Three20UI/Sources/TTMessageSubjectField.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTMessageTextField.m b/src/Three20UI/Sources/TTMessageTextField.m index 0eab29f118..f30d89eeef 100644 --- a/src/Three20UI/Sources/TTMessageTextField.m +++ b/src/Three20UI/Sources/TTMessageTextField.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTModelViewController.m b/src/Three20UI/Sources/TTModelViewController.m index 23c1b6db41..422b183892 100644 --- a/src/Three20UI/Sources/TTModelViewController.m +++ b/src/Three20UI/Sources/TTModelViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40,7 +40,8 @@ @implementation TTModelViewController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { _flags.isViewInvalid = YES; } @@ -50,7 +51,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { } return self; @@ -116,12 +118,14 @@ - (void)updateViewStates { if ([self canShowModel]) { showModel = !_flags.isShowingModel; _flags.isShowingModel = YES; + } else { if (_flags.isShowingModel) { [self showModel:NO]; _flags.isShowingModel = NO; } } + } else { if (_flags.isShowingModel) { [self showModel:NO]; @@ -132,6 +136,7 @@ - (void)updateViewStates { if (_model.isLoading) { showLoading = !_flags.isShowingLoading; _flags.isShowingLoading = YES; + } else { if (_flags.isShowingLoading) { [self showLoading:NO]; @@ -142,6 +147,7 @@ - (void)updateViewStates { if (_modelError) { showError = !_flags.isShowingError; _flags.isShowingError = YES; + } else { if (_flags.isShowingError) { [self showError:NO]; @@ -152,6 +158,7 @@ - (void)updateViewStates { if (!_flags.isShowingLoading && !_flags.isShowingModel && !_flags.isShowingError) { showEmpty = !_flags.isShowingEmpty; _flags.isShowingEmpty = YES; + } else { if (_flags.isShowingEmpty) { [self showEmpty:NO]; @@ -203,6 +210,7 @@ - (void)viewWillAppear:(BOOL)animated { - (void)didReceiveMemoryWarning { if (_hasViewAppeared && !_isViewAppearing) { [super didReceiveMemoryWarning]; + [self resetViewStates]; [self refresh]; } else { @@ -369,7 +377,7 @@ - (void)invalidateModel { [_model.delegates removeObject:self]; TT_RELEASE_SAFELY(_model); if (wasModelCreated) { - self.model; + [self model]; } } @@ -428,10 +436,13 @@ - (void)refresh { BOOL loaded = self.model.isLoaded; if (!loading && !loaded && [self shouldLoad]) { [self.model load:TTURLRequestCachePolicyDefault more:NO]; + } else if (!loading && loaded && [self shouldReload]) { [self.model load:TTURLRequestCachePolicyNetwork more:NO]; + } else if (!loading && [self shouldLoadMore]) { [self.model load:TTURLRequestCachePolicyDefault more:YES]; + } else { _flags.isModelDidLoadInvalid = YES; if (_isViewAppearing) { @@ -469,9 +480,9 @@ - (void)updateView { _flags.isUpdatingView = YES; // Ensure the model is created - self.model; + [self model]; // Ensure the view is created - self.view; + [self view]; [self updateViewStates]; diff --git a/src/Three20UI/Sources/TTNavigationController.m b/src/Three20UI/Sources/TTNavigationController.m index 1c14eede22..acf0ff787d 100644 --- a/src/Three20UI/Sources/TTNavigationController.m +++ b/src/Three20UI/Sources/TTNavigationController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTNavigator.m b/src/Three20UI/Sources/TTNavigator.m index 2f98e3954d..7e5cf027e1 100644 --- a/src/Three20UI/Sources/TTNavigator.m +++ b/src/Three20UI/Sources/TTNavigator.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -47,6 +47,14 @@ } +/////////////////////////////////////////////////////////////////////////////////////////////////// +UIViewController* TTOpenURLFromView(NSString* URL, UIView* view) { + return [[TTBaseNavigator navigatorForView:view] openURLAction: + [[TTURLAction actionWithURLPath:URL] + applyAnimated:YES]]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -57,10 +65,9 @@ @implementation TTNavigator + (TTNavigator*)navigator { TTBaseNavigator* navigator = [TTBaseNavigator globalNavigator]; if (nil == navigator) { - navigator = [[TTNavigator alloc] init]; + navigator = [[[TTNavigator alloc] init] autorelease]; // setNavigator: retains. [super setGlobalNavigator:navigator]; - [navigator release]; } // If this asserts, it's likely that you're attempting to use two different navigator // implementations simultaneously. Be consistent! @@ -85,11 +92,17 @@ - (Class)windowClass { */ - (void)presentPopupController: (TTPopupViewController*)controller parentController: (UIViewController*)parentController - animated: (BOOL)animated { - parentController.popupViewController = controller; - controller.superController = parentController; - [controller showInView: parentController.view - animated: animated]; + action: (TTURLAction*)action { + if (nil != action.sourceButton) { + [controller showFromBarButtonItem: action.sourceButton + animated: action.animated]; + + } else { + parentController.popupViewController = controller; + controller.superController = parentController; + [controller showInView: parentController.view + animated: action.animated]; + } } @@ -102,21 +115,19 @@ - (void)presentPopupController: (TTPopupViewController*)controller - (void)presentDependantController: (UIViewController*)controller parentController: (UIViewController*)parentController mode: (TTNavigationMode)mode - animated: (BOOL)animated - transition: (NSInteger)transition { + action: (TTURLAction*)action { if ([controller isKindOfClass:[TTPopupViewController class]]) { TTPopupViewController* popupViewController = (TTPopupViewController*)controller; [self presentPopupController: popupViewController parentController: parentController - animated: animated]; + action: action]; } else { [super presentDependantController: controller parentController: parentController mode: mode - animated: animated - transition: transition]; + action: action]; } } @@ -128,7 +139,7 @@ - (void)presentDependantController: (UIViewController*)controller - (void)didRestoreController:(UIViewController*)controller { if ([controller isKindOfClass:[TTModelViewController class]]) { TTModelViewController* modelViewController = (TTModelViewController*)controller; - modelViewController.model; + [modelViewController model]; } } diff --git a/src/Three20UI/Sources/TTNavigatorWindow.m b/src/Three20UI/Sources/TTNavigatorWindow.m index c51d30b015..670a145b81 100644 --- a/src/Three20UI/Sources/TTNavigatorWindow.m +++ b/src/Three20UI/Sources/TTNavigatorWindow.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // -#import "Three20UI/TTNavigatorWindow.h" +#import "Three20UI/private/TTNavigatorWindow.h" // UI #import "Three20UI/TTNavigator.h" @@ -31,7 +31,7 @@ @implementation TTNavigatorWindow /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { - if (event.type == UIEventSubtypeMotionShake + if (UIEventSubtypeMotionShake == motion && [TTNavigator navigator].supportsShakeToReload) { // If you're going to use a custom navigator implementation, you need to ensure that you // implement the reload method. If you're inheriting from TTNavigator, then you're fine. diff --git a/src/Three20UI/Sources/TTPageControl.m b/src/Three20UI/Sources/TTPageControl.m index 4134898086..4917abfe2a 100644 --- a/src/Three20UI/Sources/TTPageControl.m +++ b/src/Three20UI/Sources/TTPageControl.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ #import "Three20Style/TTBoxStyle.h" // Core +#import "Three20Core/TTDebug.h" #import "Three20Core/TTCorePreprocessorMacros.h" @@ -41,9 +42,12 @@ @implementation TTPageControl /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { self.backgroundColor = [UIColor clearColor]; self.dotStyle = @"pageDot:"; + self.hidesForSinglePage = NO; + self.contentMode = UIViewContentModeRedraw; } return self; @@ -94,31 +98,34 @@ - (TTStyle*)currentDotStyle { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)drawRect:(CGRect)rect { - if (_numberOfPages > 1 || _hidesForSinglePage) { - TTStyleContext* context = [[[TTStyleContext alloc] init] autorelease]; - TTBoxStyle* boxStyle = [self.normalDotStyle firstStyleOfClass:[TTBoxStyle class]]; - - CGSize dotSize = [self.normalDotStyle addToSize:CGSizeZero context:context]; - - CGFloat dotWidth = dotSize.width + boxStyle.margin.left + boxStyle.margin.right; - CGFloat totalWidth = (dotWidth * _numberOfPages) - (boxStyle.margin.left + boxStyle.margin.right); - CGRect contentRect = CGRectMake(round(self.width/2 - totalWidth/2), - round(self.height/2 - dotSize.height/2), - dotSize.width, dotSize.height); - - for (NSInteger i = 0; i < _numberOfPages; ++i) { - contentRect.origin.x += boxStyle.margin.left; - - context.frame = contentRect; - context.contentFrame = contentRect; - - if (i == _currentPage) { - [self.currentDotStyle draw:context]; - } else { - [self.normalDotStyle draw:context]; - } - contentRect.origin.x += dotSize.width + boxStyle.margin.right; + if (_numberOfPages <= 1 && _hidesForSinglePage) { + return; + } + + TTStyleContext* context = [[[TTStyleContext alloc] init] autorelease]; + TTBoxStyle* boxStyle = [self.normalDotStyle firstStyleOfClass:[TTBoxStyle class]]; + + CGSize dotSize = [self.normalDotStyle addToSize:CGSizeZero context:context]; + + CGFloat dotWidth = dotSize.width + boxStyle.margin.left + boxStyle.margin.right; + CGFloat totalWidth = (dotWidth * _numberOfPages) - (boxStyle.margin.left + boxStyle.margin.right); + CGRect contentRect = CGRectMake(round(self.width/2 - totalWidth/2), + round(self.height/2 - dotSize.height/2), + dotSize.width, dotSize.height); + + for (NSInteger i = 0; i < _numberOfPages; ++i) { + contentRect.origin.x += boxStyle.margin.left; + + context.frame = contentRect; + context.contentFrame = contentRect; + + if (i == _currentPage) { + [self.currentDotStyle draw:context]; + + } else { + [self.normalDotStyle draw:context]; } + contentRect.origin.x += dotSize.width + boxStyle.margin.right; } } @@ -128,7 +135,7 @@ - (CGSize)sizeThatFits:(CGSize)size { TTStyleContext* context = [[[TTStyleContext alloc] init] autorelease]; CGSize dotSize = [self.normalDotStyle addToSize:CGSizeZero context:context]; - CGFloat margin = 0; + CGFloat margin = 0.0f; TTBoxStyle* boxStyle = [self.normalDotStyle firstStyleOfClass:[TTBoxStyle class]]; if (boxStyle) { margin = boxStyle.margin.right + boxStyle.margin.left; @@ -149,7 +156,14 @@ - (CGSize)sizeThatFits:(CGSize)size { - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { if (self.touchInside) { CGPoint point = [touch locationInView:self]; - self.currentPage = round(point.x / self.width); + + if (point.x < self.width / 2) { + self.currentPage = self.currentPage - 1; + + } else { + self.currentPage = self.currentPage + 1; + } + [self sendActionsForControlEvents:UIControlEventValueChanged]; } } @@ -164,7 +178,9 @@ - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setNumberOfPages:(NSInteger)numberOfPages { if (numberOfPages != _numberOfPages) { - _numberOfPages = numberOfPages; + TTDASSERT(numberOfPages >= 0); + + _numberOfPages = MAX(0, numberOfPages); [self setNeedsDisplay]; } } @@ -173,7 +189,7 @@ - (void)setNumberOfPages:(NSInteger)numberOfPages { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setCurrentPage:(NSInteger)currentPage { if (currentPage != _currentPage) { - _currentPage = currentPage; + _currentPage = MAX(0, MIN(_numberOfPages - 1,currentPage)); [self setNeedsDisplay]; } } diff --git a/src/Three20UI/Sources/TTPhotoView.m b/src/Three20UI/Sources/TTPhotoView.m index 8e330fe33a..dcd626719c 100644 --- a/src/Three20UI/Sources/TTPhotoView.m +++ b/src/Three20UI/Sources/TTPhotoView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ #import "Three20UI/UIViewAdditions.h" // UI (private) -#import "Three20UI/TTImageViewInternal.h" +#import "Three20UI/private/TTImageViewInternal.h" // UINavigator #import "Three20UINavigator/TTGlobalNavigatorMetrics.h" @@ -57,7 +57,8 @@ @implementation TTPhotoView /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _photoVersion = TTPhotoVersionNone; self.clipsToBounds = NO; } @@ -127,7 +128,9 @@ - (void)showCaption:(NSString*)caption { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setImage:(UIImage*)image { - if (image != _defaultImage || !_photo || self.urlPath != [_photo URLForVersion:TTPhotoVersionLarge]) { + if (image != _defaultImage + || !_photo + || self.urlPath != [_photo URLForVersion:TTPhotoVersionLarge]) { if (image == _defaultImage) { self.contentMode = UIViewContentModeCenter; @@ -182,7 +185,7 @@ - (void)layoutSubviews { CGFloat height = self.height; CGFloat cx = self.bounds.origin.x + width/2; CGFloat cy = self.bounds.origin.y + height/2; - CGFloat marginRight = 0, marginLeft = 0, marginBottom = TTToolbarHeight(); + CGFloat marginRight = 0.0f, marginLeft = 0.0f, marginBottom = TTToolbarHeight(); // Since the photo view is constrained to the size of the image, but we want to position // the status views relative to the screen, offset by the difference @@ -277,14 +280,13 @@ - (void)setHidesCaption:(BOOL)hidesCaption { /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)loadPreview:(BOOL)fromNetwork { - if (![self loadVersion:TTPhotoVersionLarge fromNetwork:NO]) { - if (![self loadVersion:TTPhotoVersionSmall fromNetwork:NO]) { - if (![self loadVersion:TTPhotoVersionThumbnail fromNetwork:fromNetwork]) { - return NO; + if (![self loadVersion:TTPhotoVersionLarge fromNetwork:NO]) { + if (![self loadVersion:TTPhotoVersionSmall fromNetwork:NO]) { + if (![self loadVersion:TTPhotoVersionThumbnail fromNetwork:fromNetwork]) { + return NO; + } } } - } - return YES; } diff --git a/src/Three20UI/Sources/TTPhotoViewController.m b/src/Three20UI/Sources/TTPhotoViewController.m index 4dd68ad2e3..2177eaec39 100644 --- a/src/Three20UI/Sources/TTPhotoViewController.m +++ b/src/Three20UI/Sources/TTPhotoViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ #import "Three20UI/UIToolbarAdditions.h" // UINavigator +#import "Three20UINavigator/TTGlobalNavigatorMetrics.h" #import "Three20UINavigator/TTURLObject.h" #import "Three20UINavigator/TTURLMap.h" #import "Three20UINavigator/TTBaseNavigationController.h" @@ -70,7 +71,8 @@ @implementation TTPhotoViewController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle: @@ -95,7 +97,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithPhoto:(id)photo { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { self.centerPhoto = photo; } @@ -105,7 +108,8 @@ - (id)initWithPhoto:(id)photo { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithPhotoSource:(id)photoSource { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { self.photoSource = photoSource; } @@ -115,7 +119,8 @@ - (id)initWithPhotoSource:(id)photoSource { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { } return self; @@ -160,8 +165,11 @@ - (void)loadImageDelayed { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)startImageLoadTimer:(NSTimeInterval)delay { [_loadTimer invalidate]; - _loadTimer = [NSTimer scheduledTimerWithTimeInterval:delay target:self - selector:@selector(loadImageDelayed) userInfo:nil repeats:NO]; + _loadTimer = [NSTimer scheduledTimerWithTimeInterval:delay + target:self + selector:@selector(loadImageDelayed) + userInfo:nil + repeats:NO]; } @@ -178,6 +186,7 @@ - (void)loadImages { for (TTPhotoView* photoView in _scrollView.visiblePages.objectEnumerator) { if (photoView == centerPhotoView) { [photoView loadPreview:NO]; + } else { [photoView loadPreview:YES]; } @@ -186,6 +195,7 @@ - (void)loadImages { if (_delayLoad) { _delayLoad = NO; [self startImageLoadTimer:kPhotoLoadLongDelay]; + } else { [centerPhotoView loadImage]; } @@ -196,6 +206,7 @@ - (void)loadImages { - (void)updateChrome { if (_photoSource.numberOfPhotos < 2) { self.title = _photoSource.title; + } else { self.title = [NSString stringWithFormat: TTLocalizedString(@"%d of %d", @"Current page in photo browser (1 of 10)"), @@ -204,12 +215,18 @@ - (void)updateChrome { if (![self.ttPreviousViewController isKindOfClass:[TTThumbsViewController class]]) { if (_photoSource.numberOfPhotos > 1) { - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] - initWithTitle:TTLocalizedString(@"See All", @"See all photo thumbnails") - style:UIBarButtonItemStyleBordered target:self action:@selector(showThumbnails)]; + self.navigationItem.rightBarButtonItem = + [[[UIBarButtonItem alloc] initWithTitle:TTLocalizedString(@"See All", + @"See all photo thumbnails") + style:UIBarButtonItemStyleBordered + target:self + action:@selector(showThumbnails)] + autorelease]; + } else { self.navigationItem.rightBarButtonItem = nil; } + } else { self.navigationItem.rightBarButtonItem = nil; } @@ -223,11 +240,7 @@ - (void)updateChrome { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)updateToolbarWithOrientation:(UIInterfaceOrientation)interfaceOrientation { - if (UIInterfaceOrientationIsPortrait(interfaceOrientation)) { - _toolbar.height = TT_TOOLBAR_HEIGHT; - } else { - _toolbar.height = TT_LANDSCAPE_TOOLBAR_HEIGHT+1; - } + _toolbar.height = TTToolbarHeight(); _toolbar.top = self.view.height - _toolbar.height; } @@ -316,6 +329,7 @@ - (void)showProgress:(CGFloat)progress { if ((self.hasViewAppeared || self.isViewAppearing) && progress >= 0 && !self.centerPhotoView) { [self.statusView showProgress:progress]; self.statusView.hidden = NO; + } else { _photoStatusView.hidden = YES; } @@ -330,6 +344,7 @@ - (void)showStatus:(NSString*)status { if ((self.hasViewAppeared || self.isViewAppearing) && status && !self.centerPhotoView) { [self.statusView showStatus:status]; self.statusView.hidden = NO; + } else { _photoStatusView.hidden = YES; } @@ -349,6 +364,7 @@ - (NSString*)URLForThumbnails { if ([self.photoSource respondsToSelector:@selector(URLValueWithName:)]) { return [self.photoSource performSelector:@selector(URLValueWithName:) withObject:@"TTThumbsViewController"]; + } else { return nil; } @@ -362,8 +378,11 @@ - (void)showThumbnails { if (URL) { // The photo source has a URL mapping in TTURLMap, so we use that to show the thumbs NSDictionary* query = [NSDictionary dictionaryWithObject:self forKey:@"delegate"]; - _thumbsController = [[[TTNavigator navigator] viewControllerForURL:URL query:query] retain]; - [[TTNavigator navigator].URLMap setObject:_thumbsController forURL:URL]; + TTBaseNavigator* navigator = [TTBaseNavigator navigatorForView:self.view]; + _thumbsController = (TTThumbsViewController*)[[navigator viewControllerForURL:URL + query:query] retain]; + [navigator.URLMap setObject:_thumbsController forURL:URL]; + } else { // The photo source had no URL mapping in TTURLMap, so we let the subclass show the thumbs _thumbsController = [[self createThumbsViewController] retain]; @@ -372,7 +391,8 @@ - (void)showThumbnails { } if (URL) { - TTOpenURL(URL); + TTOpenURLFromView(URL, self.view); + } else { if ([self.navigationController isKindOfClass:[TTNavigationController class]]) { [(TTNavigationController*)self.navigationController @@ -390,6 +410,7 @@ - (void)showThumbnails { - (void)slideshowTimer { if (_centerPhotoIndex == _photoSource.numberOfPhotos-1) { _scrollView.centerPageIndex = 0; + } else { _scrollView.centerPageIndex = _centerPhotoIndex+1; } @@ -399,14 +420,20 @@ - (void)slideshowTimer { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)playAction { if (!_slideshowTimer) { - UIBarButtonItem* pauseButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: - UIBarButtonSystemItemPause target:self action:@selector(pauseAction)] autorelease]; + UIBarButtonItem* pauseButton = + [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemPause + target: self + action: @selector(pauseAction)] + autorelease]; pauseButton.tag = 1; [_toolbar replaceItemWithTag:1 withItem:pauseButton]; _slideshowTimer = [NSTimer scheduledTimerWithTimeInterval:kSlideshowInterval - target:self selector:@selector(slideshowTimer) userInfo:nil repeats:YES]; + target:self + selector:@selector(slideshowTimer) + userInfo:nil + repeats:YES]; } } @@ -414,8 +441,11 @@ - (void)playAction { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)pauseAction { if (_slideshowTimer) { - UIBarButtonItem* playButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: - UIBarButtonSystemItemPlay target:self action:@selector(playAction)] autorelease]; + UIBarButtonItem* playButton = + [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay + target:self + action:@selector(playAction)] + autorelease]; playButton.tag = 1; [_toolbar replaceItemWithTag:1 withItem:playButton]; @@ -476,19 +506,28 @@ - (void)loadView { _scrollView = [[TTScrollView alloc] initWithFrame:screenFrame]; _scrollView.delegate = self; _scrollView.dataSource = self; + _scrollView.rotateEnabled = NO; _scrollView.backgroundColor = [UIColor blackColor]; _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; [_innerView addSubview:_scrollView]; - _nextButton = [[UIBarButtonItem alloc] initWithImage: - TTIMAGE(@"bundle://Three20.bundle/images/nextIcon.png") - style:UIBarButtonItemStylePlain target:self action:@selector(nextAction)]; - _previousButton = [[UIBarButtonItem alloc] initWithImage: - TTIMAGE(@"bundle://Three20.bundle/images/previousIcon.png") - style:UIBarButtonItemStylePlain target:self action:@selector(previousAction)]; - - UIBarButtonItem* playButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: - UIBarButtonSystemItemPlay target:self action:@selector(playAction)] autorelease]; + _nextButton = + [[UIBarButtonItem alloc] initWithImage:TTIMAGE(@"bundle://Three20.bundle/images/nextIcon.png") + style:UIBarButtonItemStylePlain + target:self + action:@selector(nextAction)]; + _previousButton = + [[UIBarButtonItem alloc] initWithImage: + TTIMAGE(@"bundle://Three20.bundle/images/previousIcon.png") + style:UIBarButtonItemStylePlain + target:self + action:@selector(previousAction)]; + + UIBarButtonItem* playButton = + [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay + target:self + action:@selector(playAction)] + autorelease]; playButton.tag = 1; UIBarItem* space = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: @@ -582,12 +621,15 @@ - (void)showBars:(BOOL)show animated:(BOOL)animated { [UIView setAnimationDelegate:self]; if (show) { [UIView setAnimationDidStopSelector:@selector(showBarsAnimationDidStop)]; + } else { [UIView setAnimationDidStopSelector:@selector(hideBarsAnimationDidStop)]; } + } else { if (show) { [self showBarsAnimationDidStop]; + } else { [self hideBarsAnimationDidStop]; } @@ -654,6 +696,7 @@ - (void)showEmpty:(BOOL)show { if (show) { [_scrollView reloadData]; [self showStatus:TTLocalizedString(@"This photo set contains no photos.", @"")]; + } else { [self showStatus:nil]; } @@ -664,6 +707,7 @@ - (void)showEmpty:(BOOL)show { - (void)showError:(BOOL)show { if (show) { [self showStatus:TTDescriptionForError(_modelError)]; + } else { [self showStatus:nil]; } @@ -675,6 +719,7 @@ - (void)moveToNextValidPhoto { if (_centerPhotoIndex >= _photoSource.numberOfPhotos) { // We were positioned at an index that is past the end, so move to the last photo [self moveToPhotoAtIndex:_photoSource.numberOfPhotos - 1 withDelay:NO]; + } else { [self moveToPhotoAtIndex:_centerPhotoIndex withDelay:NO]; } @@ -694,6 +739,7 @@ - (void)modelDidFinishLoad:(id)model { [self moveToNextValidPhoto]; [_scrollView reloadData]; [self resetVisiblePhotoViews]; + } else { [self updateVisiblePhotoViews]; } @@ -805,6 +851,7 @@ - (void)scrollViewDidEndZooming:(TTScrollView*)scrollView { - (void)scrollView:(TTScrollView*)scrollView tapped:(UITouch*)touch { if ([self isShowingChrome]) { [self showBars:NO animated:YES]; + } else { [self showBars:YES animated:NO]; } @@ -901,6 +948,7 @@ - (void)setCenterPhoto:(id)photo { [self moveToPhotoAtIndex:photo.index withDelay:NO]; self.model = _photoSource; + } else { [self moveToPhotoAtIndex:photo.index withDelay:NO]; [self refresh]; @@ -937,6 +985,7 @@ - (void)showActivity:(NSString*)title { [_innerView addSubview:label]; _scrollView.scrollEnabled = NO; + } else { UIView* label = [_innerView viewWithTag:kActivityLabelTag]; if (label) { diff --git a/src/Three20UI/Sources/TTPickerTextField.m b/src/Three20UI/Sources/TTPickerTextField.m index 660106fa05..fc821d9d65 100644 --- a/src/Three20UI/Sources/TTPickerTextField.m +++ b/src/Three20UI/Sources/TTPickerTextField.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,12 +32,12 @@ static NSString* kEmpty = @" "; static NSString* kSelected = @"`"; -static const CGFloat kCellPaddingY = 3; -static const CGFloat kPaddingX = 8; -static const CGFloat kSpacingY = 6; -static const CGFloat kPaddingRatio = 1.75; -static const CGFloat kClearButtonSize = 38; -static const CGFloat kMinCursorWidth = 50; +static const CGFloat kCellPaddingY = 3.0f; +static const CGFloat kPaddingX = 8.0f; +static const CGFloat kSpacingY = 6.0f; +static const CGFloat kPaddingRatio = 1.75f; +static const CGFloat kClearButtonSize = 38.0f; +static const CGFloat kMinCursorWidth = 50.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -52,7 +52,8 @@ @implementation TTPickerTextField /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _cellViews = [[NSMutableArray alloc] init]; _lineCount = 1; _cursorOrigin = CGPointZero; @@ -129,9 +130,8 @@ - (void)updateHeight { self.height = newHeight; [self setNeedsDisplay]; - SEL sel = @selector(textFieldDidResize:); - if ([self.delegate respondsToSelector:sel]) { - [self.delegate performSelector:sel withObject:self]; + if ([self.delegate respondsToSelector:@selector(textFieldDidResize:)]) { + [(id)self.delegate textFieldDidResize:self]; } [self scrollToVisibleLine:YES]; @@ -149,6 +149,7 @@ - (CGFloat)marginY { - (CGFloat)topOfLine:(int)lineNumber { if (lineNumber == 0) { return 0; + } else { CGFloat ttLineHeight = self.font.ttLineHeight; CGFloat lineSpacing = kCellPaddingY*2 + kSpacingY; @@ -202,6 +203,7 @@ - (NSString*)labelForObject:(id)object { - (void)layoutSubviews { if (_dataSource) { [self layoutCells]; + } else { _cursorOrigin.x = kPaddingX; _cursorOrigin.y = [self marginY]; @@ -230,6 +232,7 @@ - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { UITouch* touch = [touches anyObject]; if (touch.view == self) { self.selectedCell = nil; + } else { if ([touch.view isKindOfClass:[TTPickerViewCell class]]) { self.selectedCell = (TTPickerViewCell*)touch.view; @@ -260,6 +263,7 @@ - (CGRect)textRectForBounds:(CGRect)bounds { if (_dataSource && [self.text isEqualToString:kSelected]) { // Hide the cursor while a cell is selected return CGRectMake(-10, 0, 0, 0); + } else { CGRect frame = CGRectOffset(bounds, _cursorOrigin.x, _cursorOrigin.y); frame.size.width -= (_cursorOrigin.x + kPaddingX + (self.rightView ? kClearButtonSize : 0)); @@ -286,6 +290,7 @@ - (CGRect)leftViewRectForBounds:(CGRect)bounds { return CGRectMake( bounds.origin.x+kPaddingX, self.marginY, self.leftView.frame.size.width, self.leftView.frame.size.height); + } else { return bounds; } @@ -297,6 +302,7 @@ - (CGRect)rightViewRectForBounds:(CGRect)bounds { if (self.rightView) { return CGRectMake(bounds.size.width - kClearButtonSize, bounds.size.height - kClearButtonSize, kClearButtonSize, kClearButtonSize); + } else { return bounds; } @@ -321,6 +327,7 @@ - (void)showSearchResults:(BOOL)show { [super showSearchResults:show]; if (show) { [self scrollToEditingLine:YES]; + } else { [self scrollToVisibleLine:YES]; } @@ -344,14 +351,17 @@ - (BOOL)shouldUpdate:(BOOL)emptyText { if (emptyText && !self.hasText && !self.selectedCell && self.cells.count) { [self selectLastCell]; return NO; + } else if (emptyText && self.selectedCell) { [self removeSelectedCell]; [super shouldUpdate:emptyText]; return NO; + } else if (!emptyText && !self.hasText && self.selectedCell) { [self removeSelectedCell]; [super shouldUpdate:emptyText]; return YES; + } else { return [super shouldUpdate:emptyText]; } @@ -413,9 +423,8 @@ - (void)addCellWithObject:(id)object { // Reset text so the cursor moves to be at the end of the cellViews self.text = kEmpty; - SEL sel = @selector(textField:didAddCellAtIndex:); - if ([self.delegate respondsToSelector:sel]) { - [self.delegate performSelector:sel withObject:self withObject:(id)_cellViews.count-1]; + if ([self.delegate respondsToSelector:@selector(textField:didAddCellAtIndex:)]) { + [(id)self.delegate textField:self didAddCellAtIndex:_cellViews.count-1]; } } @@ -428,9 +437,8 @@ - (void)removeCellWithObject:(id)object { [_cellViews removeObjectAtIndex:i]; [cell removeFromSuperview]; - SEL sel = @selector(textField:didRemoveCellAtIndex:); - if ([self.delegate respondsToSelector:sel]) { - [self.delegate performSelector:sel withObject:self withObject:(id)i]; + if ([self.delegate respondsToSelector:@selector(textField:didRemoveCellAtIndex:)]) { + [(id)self.delegate textField:self didRemoveCellAtIndex:i]; } break; } @@ -479,6 +487,7 @@ - (void)removeSelectedCell { if (_cellViews.count) { self.text = kEmpty; + } else { self.text = @""; } diff --git a/src/Three20UI/Sources/TTPickerViewCell.m b/src/Three20UI/Sources/TTPickerViewCell.m index 537f4a7cb8..40a318c5fd 100644 --- a/src/Three20UI/Sources/TTPickerViewCell.m +++ b/src/Three20UI/Sources/TTPickerViewCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,9 +23,9 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kPaddingX = 8; -static const CGFloat kPaddingY = 3; -static const CGFloat kMaxWidth = 250; +static const CGFloat kPaddingX = 8.0f; +static const CGFloat kPaddingY = 3.0f; +static const CGFloat kMaxWidth = 250.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -39,7 +39,8 @@ @implementation TTPickerViewCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _labelView = [[UILabel alloc] init]; _labelView.backgroundColor = [UIColor clearColor]; _labelView.textColor = TTSTYLEVAR(textColor); @@ -88,6 +89,7 @@ - (CGSize)sizeThatFits:(CGSize)size { - (TTStyle*)style { if (self.selected) { return TTSTYLESTATE(pickerCell:, UIControlStateSelected); + } else { return TTSTYLESTATE(pickerCell:, UIControlStateNormal); } diff --git a/src/Three20UI/Sources/TTPopupViewController.m b/src/Three20UI/Sources/TTPopupViewController.m index 5ca58af64c..285edb8793 100644 --- a/src/Three20UI/Sources/TTPopupViewController.m +++ b/src/Three20UI/Sources/TTPopupViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -28,7 +28,8 @@ @implementation TTPopupViewController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { _statusBarStyle = [UIApplication sharedApplication].statusBarStyle; } @@ -38,7 +39,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { } return self; @@ -63,6 +65,13 @@ - (void)dealloc { - (void)showInView:(UIView*)view animated:(BOOL)animated { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)showFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated { +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)showFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated { +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dismissPopupViewControllerAnimated:(BOOL)animated { diff --git a/src/Three20UI/Sources/TTPostController.m b/src/Three20UI/Sources/TTPostController.m index 16497c90a1..fdc55e871b 100644 --- a/src/Three20UI/Sources/TTPostController.m +++ b/src/Three20UI/Sources/TTPostController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,9 +38,10 @@ #import "Three20Core/TTGlobalCoreLocale.h" #import "Three20Core/TTCorePreprocessorMacros.h" #import "Three20Core/NSStringAdditions.h" +#import "Three20Core/TTGlobalCore.h" -static const CGFloat kMarginX = 5; -static const CGFloat kMarginY = 6; +static const CGFloat kMarginX = 5.0f; +static const CGFloat kMarginY = 6.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -57,7 +58,8 @@ @implementation TTPostController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemCancel target: self @@ -75,7 +77,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { if (nil != query) { _delegate = [query objectForKey:@"delegate"]; _defaultText = [[query objectForKey:@"text"] copy]; @@ -203,6 +206,8 @@ - (void)layoutTextEditor { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)showAnimationDidStop { _textView.hidden = NO; + + [self.superController viewDidDisappear:YES]; } @@ -245,7 +250,10 @@ - (void)dismissWithCancel { [_delegate postControllerDidCancel:self]; } - [self dismissPopupViewControllerAnimated:YES]; + BOOL animated = YES; + + [self.superController viewWillAppear:animated]; + [self dismissPopupViewControllerAnimated:animated]; } @@ -367,6 +375,9 @@ - (void)restoreView:(NSDictionary*)state { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)showInView:(UIView*)view animated:(BOOL)animated { [self retain]; + + [self.superController viewWillDisappear:animated]; + UIWindow* window = view.window ? view.window : [UIApplication sharedApplication].keyWindow; self.view.transform = [self transformForOrientation]; @@ -375,7 +386,7 @@ - (void)showInView:(UIView*)view animated:(BOOL)animated { if (_defaultText) { _textView.text = _defaultText; - TT_RELEASE_SAFELY(_defaultText); + } else { _defaultText = [_textView.text retain]; } @@ -396,6 +407,7 @@ - (void)showInView:(UIView*)view animated:(BOOL)animated { if (!CGRectIsEmpty(originRect)) { _screenView.frame = CGRectOffset(originRect, 0, -TTStatusHeight()); + } else { [self layoutTextEditor]; _screenView.transform = CGAffineTransformMakeScale(0.00001, 0.00001); @@ -411,6 +423,7 @@ - (void)showInView:(UIView*)view animated:(BOOL)animated { if (originRect.size.width) { [self layoutTextEditor]; + } else { _screenView.transform = CGAffineTransformIdentity; } @@ -438,7 +451,6 @@ - (void)dismissPopupViewControllerAnimated:(BOOL)animated { [self.view removeFromSuperview]; [self release]; superController.popupViewController = nil; - [superController viewWillAppear:animated]; [superController viewDidAppear:animated]; } } @@ -466,7 +478,7 @@ - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)butto /////////////////////////////////////////////////////////////////////////////////////////////////// - (UITextView*)textView { - self.view; + [self view]; return _textView; } @@ -474,7 +486,7 @@ - (UITextView*)textView { /////////////////////////////////////////////////////////////////////////////////////////////////// - (UINavigationBar*)navigatorBar { if (!_navigationBar) { - self.view; + [self view]; } return _navigationBar; } @@ -499,6 +511,7 @@ - (void)post { if (shouldDismiss) { [self dismissWithResult:nil animated:YES]; + } else { [self showActivity:[self titleForActivity]]; } @@ -507,7 +520,8 @@ - (void)post { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)cancel { - if (!_textView.text.isEmptyOrWhitespace + if (TTIsStringWithAnyText(_textView.text) + && !_textView.text.isWhitespaceAndNewlines && !(_defaultText && [_defaultText isEqualToString:_textView.text])) { UIAlertView* cancelAlertView = [[[UIAlertView alloc] initWithTitle: TTLocalizedString(@"Cancel", @"") @@ -515,6 +529,7 @@ - (void)cancel { delegate:self cancelButtonTitle:TTLocalizedString(@"Yes", @"") otherButtonTitles:TTLocalizedString(@"No", @""), nil] autorelease]; [cancelAlertView show]; + } else { [self dismissWithCancel]; } @@ -526,6 +541,8 @@ - (void)dismissWithResult:(id)result animated:(BOOL)animated { [_result release]; _result = [result retain]; + [self.superController viewWillAppear:animated]; + if (animated) { if ([_delegate respondsToSelector:@selector(postController:willAnimateTowards:)]) { CGRect rect = [_delegate postController:self willAnimateTowards:_originRect]; @@ -551,6 +568,7 @@ - (void)dismissWithResult:(id)result animated:(BOOL)animated { if (!CGRectIsEmpty(originRect)) { _screenView.frame = CGRectOffset(originRect, 0, -TTStatusHeight()); + } else { _screenView.transform = CGAffineTransformMakeScale(0.00001, 0.00001); } diff --git a/src/Three20UI/Sources/TTRecursiveProgress.m b/src/Three20UI/Sources/TTRecursiveProgress.m index 98f64be39d..f57c94233d 100644 --- a/src/Three20UI/Sources/TTRecursiveProgress.m +++ b/src/Three20UI/Sources/TTRecursiveProgress.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -48,7 +48,8 @@ + (id)progressWithParent: (TTRecursiveProgress*)parent /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithDelegate:(id)delegate { - if (self = [super init]) { + self = [super init]; + if (self) { _firstPercent = 0; _lastPercent = 1; _parent = nil; @@ -63,7 +64,8 @@ - (id)initWithDelegate:(id)delegate { - (id)initWithParent:(TTRecursiveProgress*)parent firstPercent: (CGFloat)firstPercent lastPercent: (CGFloat)lastPercent { - if (self = [super init]) { + self = [super init]; + if (self) { _firstPercent = firstPercent; _lastPercent = lastPercent; _parent = parent; @@ -85,6 +87,7 @@ - (void)setPercent:(CGFloat)percent { CGFloat mappedProgress = [self percentWidth] * percent + _firstPercent; if (nil == _parent) { [_delegate didSetProgress:mappedProgress]; + } else { [_parent setPercent:mappedProgress]; } diff --git a/src/Three20UI/Sources/TTScrollView.m b/src/Three20UI/Sources/TTScrollView.m index dc23841225..b1d015f850 100755 --- a/src/Three20UI/Sources/TTScrollView.m +++ b/src/Three20UI/Sources/TTScrollView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -28,17 +28,17 @@ #import "Three20Core/TTCorePreprocessorMacros.h" static const NSInteger kOffscreenPages = 1; -static const CGFloat kDefaultPageSpacing = 40.0; -static const CGFloat kFlickThreshold = 60.0; -static const CGFloat kTapZoom = 0.75; -static const CGFloat kResistance = 0.15; +static const CGFloat kDefaultPageSpacing = 40.0f; +static const CGFloat kFlickThreshold = 60.0f; +static const CGFloat kTapZoom = 0.75f; +static const CGFloat kResistance = 0.15f; static const NSInteger kInvalidIndex = -1; static const NSTimeInterval kFlickDuration = 0.4; static const NSTimeInterval kBounceDuration = 0.3; static const NSTimeInterval kOvershoot = 2; -static const CGFloat kIncreaseSpeed = 1.5; // How much increase after release touch. +static const CGFloat kIncreaseSpeed = 1.5f; // How much increase after release touch. // (Residual movement). -static const CGFloat kFrameDuration = 1.0/40.0; +static const CGFloat kFrameDuration = 1.0/40.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -64,10 +64,15 @@ @implementation TTScrollView @synthesize zoomScale = _zoomScale; @synthesize zooming = _executingZoomGesture; +@synthesize isDragging = _dragging; + +@synthesize centerPageAnimationDuration = _centerPageAnimationDuration; + /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { self.clipsToBounds = YES; self.multipleTouchEnabled = YES; self.userInteractionEnabled = YES; @@ -80,9 +85,10 @@ - (id)initWithFrame:(CGRect)frame { _scrollEnabled = YES; _zoomEnabled = YES; _rotateEnabled = YES; - _orientation = UIDeviceOrientationPortrait; + _orientation = UIInterfaceOrientationPortrait; _decelerationRate = 0.9; // Inertia, how faster slow the residual movement. _maximumZoomScale = 4.0; // Maximum zoom scale default value. + _centerPageAnimationDuration = TT_TRANSITION_DURATION; for (NSInteger i = 0; i < _maxPages; ++i) { [_pages addObject:[NSNull null]]; @@ -109,6 +115,9 @@ - (void)dealloc { TT_RELEASE_SAFELY(_pages); TT_RELEASE_SAFELY(_pageQueue); + TT_RELEASE_SAFELY(_touch1); + TT_RELEASE_SAFELY(_touch2); + [super dealloc]; } @@ -163,16 +172,21 @@ - (BOOL)flicked { if (!self.flipped) { if (_pageEdges.left > kFlickThreshold && ![self isFirstPage]) { return YES; + } else if (_pageEdges.right < -kFlickThreshold && ![self isLastPage]) { return YES; + } else { return NO; } + } else { if (_pageEdges.left > kFlickThreshold && ![self isLastPage]) { return YES; + } else if (_pageEdges.right < -kFlickThreshold && ![self isFirstPage]) { return YES; + } else { return NO; } @@ -184,6 +198,7 @@ - (BOOL)flicked { - (CGFloat)pageWidth { if (UIInterfaceOrientationIsLandscape(_orientation)) { return self.height; + } else { return self.width; } @@ -194,6 +209,7 @@ - (CGFloat)pageWidth { - (CGFloat)pageHeight { if (UIInterfaceOrientationIsLandscape(_orientation)) { return self.width; + } else { return self.height; } @@ -229,23 +245,27 @@ - (CGRect)frameOfPageAtIndex:(NSInteger)pageIndex { if (0 == size.width || 0 == size.height) { size = CGSizeMake(self.pageWidth, self.pageHeight); } + } else { size = CGSizeMake(self.pageWidth, self.pageHeight); } CGFloat width, height; if (UIInterfaceOrientationIsLandscape(_orientation)) { - if (size.width > size.height) { + if (size.width / size.height > self.width / self.height) { height = self.height; width = size.height/size.width * self.height; + } else { height = size.width/size.height * self.width; width = self.width; } + } else { - if (size.width > size.height) { + if (size.width / size.height > self.width / self.height) { width = self.width; height = size.height/size.width * self.width; + } else { width = size.width/size.height * self.height; height = self.height; @@ -262,6 +282,7 @@ - (CGRect)frameOfPageAtIndex:(NSInteger)pageIndex { - (CGFloat)overflowForFrame:(CGRect)frame { if (UIInterfaceOrientationIsLandscape(_orientation)) { return frame.origin.y < 0 ? fabs(frame.origin.y) : 0; + } else { return frame.origin.x < 0 ? fabs(frame.origin.x) : 0; } @@ -272,6 +293,7 @@ - (CGFloat)overflowForFrame:(CGRect)frame { - (CGPoint)offsetForOrientation:(CGFloat)x y:(CGFloat)y { if (UIInterfaceOrientationIsLandscape(_orientation)) { return CGPointMake(y, x); + } else { return CGPointMake(x, y); } @@ -297,10 +319,13 @@ - (BOOL)supportsOrientation:(UIInterfaceOrientation)orientation { - (CGAffineTransform)rotateTransform:(CGAffineTransform)transform { if (_orientation == UIInterfaceOrientationLandscapeLeft) { return CGAffineTransformRotate(transform, M_PI*1.5); + } else if (_orientation == UIInterfaceOrientationLandscapeRight) { return CGAffineTransformRotate(transform, M_PI/2); + } else if (_orientation == UIInterfaceOrientationPortraitUpsideDown) { return CGAffineTransformRotate(transform, -M_PI); + } else { return transform; } @@ -316,6 +341,7 @@ - (CGPoint)touchLocation:(UITouch*)touch { CGPoint point = [touch locationInView:self]; if (UIInterfaceOrientationIsLandscape(_orientation)) { return CGPointMake(point.y, point.x); + } else { return point; } @@ -356,8 +382,10 @@ - (NSInteger)realPageIndex { } else if (!self.flipped) { if (_pageEdges.left > kFlickThreshold && ![self isFirstPage]) { return _centerPageIndex - 1; + } else if (_pageEdges.right < -kFlickThreshold && ![self isLastPage]) { return _centerPageIndex + 1; + } else { return _centerPageIndex; } @@ -365,8 +393,10 @@ - (NSInteger)realPageIndex { } else { if (_pageEdges.left > kFlickThreshold && ![self isLastPage]) { return _centerPageIndex + 1; + } else if (_pageEdges.right < -kFlickThreshold && ![self isFirstPage]) { return _centerPageIndex - 1; + } else { return _centerPageIndex; } @@ -389,6 +419,7 @@ - (UIView*)pageAtIndex:(NSInteger)pageIndex create:(BOOL)create { page.userInteractionEnabled = YES; [self addSubview:page]; [_pages replaceObjectAtIndex:arrayIndex withObject:page]; + } else { return nil; } @@ -459,11 +490,12 @@ - (void)adjustPageEdgesForPageAtIndex:(NSInteger)pageIndex { /////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges { +- (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges animated:(BOOL)animated { if (resetEdges) { _pageEdges = _pageStartEdges = UIEdgeInsetsZero; _zooming = NO; [self setNeedsLayout]; + } else if (pageIndex != _centerPageIndex) { [self adjustPageEdgesForPageAtIndex:pageIndex]; _zooming = NO; @@ -478,6 +510,7 @@ - (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges { for (int i = edgeIndex; i < newEdgeIndex; ++i) { [self enqueuePageAtIndex:i]; } + } else if (indexDiff < 0) { NSInteger edgeIndex = _centerPageIndex + kOffscreenPages; NSInteger newEdgeIndex = pageIndex + kOffscreenPages; @@ -485,6 +518,7 @@ - (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges { [self enqueuePageAtIndex:i]; } } + } else { [self reloadData]; } @@ -492,13 +526,22 @@ - (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges { _pageArrayIndex = [self arrayIndexForPageIndex:pageIndex relativeToIndex:_centerPageIndex]; _centerPageIndex = pageIndex; [self setNeedsLayout]; + + // Should animate the next relayout? + _nextLayoutAnimated = animated; } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges { + [self moveToPageAtIndex:pageIndex resetEdges:resetEdges animated:NO]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)layoutPage { UIView* page = [self pageAtIndex:_centerPageIndex create:YES]; + + // Layout. if (nil != page) { CGAffineTransform rotation = TTRotateTransformForOrientation(_orientation); CGPoint offset = [self offsetForOrientation:_pageEdges.left y:_pageEdges.top]; @@ -509,13 +552,37 @@ - (void)layoutPage { page.transform = [self rotateTransform:CGAffineTransformScale( CGAffineTransformMakeTranslation(offset.x, offset.y), zoom, zoom)]; + + // Should animate the relayout? + if ( _nextLayoutAnimated ) { + [UIView beginAnimations:@"pageAnimation" context:nil]; + [UIView setAnimationDuration:_centerPageAnimationDuration]; + } page.frame = CGRectMake(offset.x + frame.origin.x*zoom, offset.y + frame.origin.y*zoom, frame.size.width*zoom, frame.size.height*zoom); + // Should animate the relayout? + if ( _nextLayoutAnimated ) { + [UIView commitAnimations]; + } + } else { + page.transform = rotation; + + // Should animate the relayout? + if ( _nextLayoutAnimated ) { + [UIView beginAnimations:@"pageAnimation" context:nil]; + [UIView setAnimationDuration:_centerPageAnimationDuration]; + } + page.frame = CGRectMake(offset.x + frame.origin.x, offset.y + frame.origin.y, frame.size.width, frame.size.height); + + // Should animate the relayout? + if ( _nextLayoutAnimated ) { + [UIView commitAnimations]; + } } } } @@ -530,6 +597,9 @@ - (void)layoutAdjacentPages { NSInteger minPageIndex = _centerPageIndex - kOffscreenPages; NSInteger maxPageIndex = _centerPageIndex + kOffscreenPages; + // Determine the direction. + BOOL isGoingLeft = _centerPageIndex < _visiblePageIndex; + CGRect centerFrame = [self frameOfPageAtIndex:_centerPageIndex]; CGFloat centerPageOverflow = [self overflowForFrame:centerFrame] * self.zoomFactor; @@ -547,9 +617,21 @@ - (void)layoutAdjacentPages { CGPoint offset = [self offsetForOrientation:x y:0]; page.transform = rotation; + + // Should animate the the "going right" relayout? + if ( _nextLayoutAnimated && !isGoingLeft ) { + [UIView beginAnimations:@"pageAnimation" context:nil]; + [UIView setAnimationDuration:_centerPageAnimationDuration]; + } + page.frame = CGRectMake(offset.x + frame.origin.x, offset.y + frame.origin.y, frame.size.width, frame.size.height); page.hidden = pinched; + + // Should animate the the "going right" relayout? + if ( _nextLayoutAnimated && !isGoingLeft) { + [UIView commitAnimations]; + } } } @@ -568,9 +650,22 @@ - (void)layoutAdjacentPages { CGPoint offset = [self offsetForOrientation:x y:0]; page.transform = rotation; + + // Should animate the "going left" relayout? + if ( _nextLayoutAnimated && isGoingLeft ) { + [UIView beginAnimations:@"pageAnimation" context:nil]; + [UIView setAnimationDuration:_centerPageAnimationDuration]; + } + page.frame = CGRectMake(offset.x + frame.origin.x, offset.y + frame.origin.y, frame.size.width, frame.size.height); page.hidden = pinched; + + // Should animate the "going left" relayout? + if ( _nextLayoutAnimated && isGoingLeft) { + [UIView commitAnimations]; + } + } } } @@ -606,6 +701,7 @@ - (UIEdgeInsets)touchEdgesForPoint:(CGPoint)point { - (UIEdgeInsets)squareTouchEdges:(UIEdgeInsets)edges { //if (_touchCount == 1) { return edges; + //} else { // ******** // @@ -647,6 +743,7 @@ - (UIEdgeInsets)zoomPageEdgesTo:(CGPoint)point { if (edges.left > 0) { edges.right += edges.left; edges.left = 0; + } else if (edges.right < 0) { edges.left += -edges.right; edges.right = 0; @@ -655,6 +752,7 @@ - (UIEdgeInsets)zoomPageEdgesTo:(CGPoint)point { if (edges.top > 0) { edges.bottom += edges.top; edges.top = 0; + } else if (edges.bottom < 0) { edges.top += -edges.bottom; edges.bottom = 0; @@ -720,6 +818,7 @@ - (UIEdgeInsets)resistPageEdges:(UIEdgeInsets)edges { top = [self resist:_pageEdges.top to:top max:height]; if (_touchCount == 2) { bottom = bottom + (top - _pageEdges.top); + } else { bottom = _pageEdges.bottom + (top - _pageEdges.top); } @@ -734,6 +833,7 @@ - (UIEdgeInsets)resistPageEdges:(UIEdgeInsets)edges { bottom = [self resist:_pageEdges.bottom to:bottom max:height]; if (_touchCount == 2) { top = top + (bottom - _pageEdges.bottom); + } else { top = _pageEdges.top + (bottom - _pageEdges.bottom); } @@ -753,6 +853,7 @@ - (UIEdgeInsets)resistPageEdges:(UIEdgeInsets)edges { left = [self resist:_pageEdges.left to:left max:width]; if (_touchCount == 2) { right = right + (left - _pageEdges.left); + } else { right = _pageEdges.right + (left - _pageEdges.left); } @@ -762,10 +863,12 @@ - (UIEdgeInsets)resistPageEdges:(UIEdgeInsets)edges { CGFloat yd = newHeight - (-top + height + bottom); top -= yd/2; bottom += yd/2; + } else if (flickNext && [self isLastPage] && !self.zoomed) { right = [self resist:_pageEdges.right to:right max:width]; if (_touchCount == 2) { left = left + (right - _pageEdges.right); + } else { left = _pageEdges.left + (right - _pageEdges.right); } @@ -801,16 +904,19 @@ - (UIEdgeInsets)pageEdgesForAnimation { if (fabs(_pageStartEdges.left) >= fabs(_pageEdges.right)) { left = right = -((self.pageWidth + _pageSpacing) + _pageEdges.right + _overshoot + overflow); + } else { left = right = -((self.pageWidth + _pageSpacing) + _pageEdges.left + _overshoot + overflow); } + } else { CGRect frame = [self frameOfPageAtIndex:_centerPageIndex + (self.flipped ? 1 : -1)]; CGFloat overflow = centerPageOverflow + [self overflowForFrame:frame]; if (fabs(_pageEdges.left) >= fabs(_pageEdges.right)) { left = right = ((self.pageWidth + _pageSpacing) - _pageEdges.right + _overshoot + overflow); + } else { left = right = ((self.pageWidth + _pageSpacing) - _pageEdges.left + _overshoot + overflow); @@ -820,12 +926,14 @@ - (UIEdgeInsets)pageEdgesForAnimation { } else { if (_pageEdges.left > 0) { left = right = -_pageEdges.left; + } else if (_pageEdges.right < 0) { left = right = -_pageEdges.right; } if (_pageEdges.top > 0) { top = bottom = -_pageEdges.top; + } else if (_pageEdges.bottom < 0) { top = bottom = -_pageEdges.bottom; } @@ -838,10 +946,13 @@ - (UIEdgeInsets)pageEdgesForAnimation { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)acquireTouch:(UITouch*)touch { if (nil == _touch1) { - _touch1 = touch; + TT_RELEASE_SAFELY(_touch1); + _touch1 = [touch retain]; ++_touchCount; + } else if (nil == _touch2) { - _touch2 = touch; + TT_RELEASE_SAFELY(_touch2); + _touch2 = [touch retain]; ++_touchCount; } } @@ -850,12 +961,12 @@ - (void)acquireTouch:(UITouch*)touch { /////////////////////////////////////////////////////////////////////////////////////////////////// - (UITouch*)removeTouch:(UITouch*)touch { if (touch == _touch1) { - _touch1 = nil; + TT_RELEASE_SAFELY(_touch1); --_touchCount; return _touch2; } else if (touch == _touch2) { - _touch2 = nil; + TT_RELEASE_SAFELY(_touch2); --_touchCount; return _touch1; @@ -1005,7 +1116,8 @@ - (void)stopAnimation:(BOOL)resetEdges { /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGFloat)tween:(NSTimeInterval)t b:(NSTimeInterval)b c:(NSTimeInterval)c d:(NSTimeInterval)d { - return c*((t=t/d-1)*t*t + 1) + b; + t = t/d-1; + return c*(t*t*t + 1) + b; } @@ -1231,6 +1343,21 @@ - (UIEdgeInsets)squareEdgesUsingFingerDistancesAndAnchorPoint:(CGPoint)anchorPoi andAnchorPoint:anchorPoint]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Solution for the issue discussed here: + * http://discussions.apple.com/message.jspa?messageID=7139722 + */ +- (void) ensureTouches { + if (_touch1.phase == UITouchPhaseEnded) { + [self removeTouch: _touch1]; + } + if (_touch2.phase == UITouchPhaseEnded) { + [self removeTouch: _touch2]; + } +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1242,8 +1369,7 @@ - (UIEdgeInsets)squareEdgesUsingFingerDistancesAndAnchorPoint:(CGPoint)anchorPoi - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { [super touchesBegan:touches withEvent:event]; - NSLog( @"_touchCount: %i", _touchCount ); - NSLog( @"touches count: %i", [touches count] ); + [self ensureTouches]; if (_touchCount < 2) { [self stopAnimation:NO]; @@ -1318,8 +1444,8 @@ - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent *)event { } // Declare common. - UIEdgeInsets pageEdges; - UIEdgeInsets newEdges; + UIEdgeInsets pageEdges = UIEdgeInsetsZero; + UIEdgeInsets newEdges = UIEdgeInsetsZero; UIEdgeInsets edges = [self squareTouchEdges:_touchEdges]; CGFloat left = _pageStartEdges.left + (edges.left - _touchStartEdges.left); @@ -1341,6 +1467,7 @@ - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent *)event { _executingZoomGesture = YES; // Dragging. + } else if ( _touchCount == 1 ) { newEdges = UIEdgeInsetsMake(top, left, bottom, right); pageEdges = [self resistPageEdges:newEdges]; @@ -1413,6 +1540,7 @@ - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { [self startTapTimer:touch]; // Double tap, zoom out to fit or zoom in to the 1/3 of the maximum scale. + } else if (touch.tapCount == 2 && self.canZoom) { CGPoint pointToZoom = [self touchLocation:touch]; @@ -1479,6 +1607,9 @@ - (void)layoutSubviews { _visiblePageIndex = _centerPageIndex; [_delegate scrollView:self didMoveToPageAtIndex:_centerPageIndex]; } + + // Reset the layout animated flag. + _nextLayoutAnimated = NO; } @@ -1526,6 +1657,13 @@ - (void)setDataSource:(id)dataSource { [self reloadData]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setCenterPageIndex:(NSInteger)centerPageIndex animated:(BOOL)animated { + // TODO: Fix limitation, for now only animate the distance of one page .. :( + animated = ( _centerPageIndex-centerPageIndex >= -1 || _centerPageIndex+centerPageIndex <= 1 ); + + [self moveToPageAtIndex:centerPageIndex resetEdges:!_touchCount animated:animated]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setCenterPageIndex:(NSInteger)centerPageIndex { @@ -1597,6 +1735,7 @@ - (void)setOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animat [UIView setAnimationDidStopSelector:@selector(rotationDidStop)]; [self layoutPage]; [UIView commitAnimations]; + } else { [self rotationDidStop]; [self setNeedsLayout]; @@ -1611,6 +1750,7 @@ - (UIView*)dequeueReusablePage { UIView* page = [[_pageQueue.lastObject retain] autorelease]; [_pageQueue removeLastObject]; return page; + } else { return nil; } @@ -1638,15 +1778,19 @@ - (UIView*)pageAtIndex:(NSInteger)pageIndex { /////////////////////////////////////////////////////////////////////////////////////////////////// -// A floating-point value that specifies the current scale factor applied to the scroll -// view's content. +/** + * A floating-point value that specifies the current scale factor applied to the scroll + * view's content. + */ -(CGFloat)zoomScale { return self.zoomFactor; } /////////////////////////////////////////////////////////////////////////////////////////////////// -// A floating-point value that specifies the current zoom scale. +/** + * A floating-point value that specifies the current zoom scale. + */ -(void)setZoomScale:(CGFloat)scale { [self setZoomScale:scale animated:YES]; } @@ -1715,8 +1859,8 @@ - (void)cancelTouches { [self stopAnimation:YES]; [self stopDragging:NO]; [self updateZooming:UIEdgeInsetsZero]; - _touch1 = nil; - _touch2 = nil; + TT_RELEASE_SAFELY(_touch1); + TT_RELEASE_SAFELY(_touch2); _touchCount = 0; } diff --git a/src/Three20UI/Sources/TTSearchBar.m b/src/Three20UI/Sources/TTSearchBar.m index 907c0f7602..71df4e5948 100644 --- a/src/Three20UI/Sources/TTSearchBar.m +++ b/src/Three20UI/Sources/TTSearchBar.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -34,16 +34,16 @@ #import "Three20Core/TTCorePreprocessorMacros.h" #import "Three20Core/TTGlobalCoreLocale.h" -static const CGFloat kMarginX = 5; -static const CGFloat kMarginY = 7; -static const CGFloat kPaddingX = 10; -static const CGFloat kPaddingY = 10; -static const CGFloat kSpacingX = 4; +static const CGFloat kMarginX = 5.0f; +static const CGFloat kMarginY = 7.0f; +static const CGFloat kPaddingX = 10.0f; +static const CGFloat kPaddingY = 10.0f; +static const CGFloat kSpacingX = 4.0f; -static const CGFloat kButtonSpacing = 12; -static const CGFloat kButtonHeight = 30; +static const CGFloat kButtonSpacing = 12.0f; +static const CGFloat kButtonHeight = 30.0f; -static const CGFloat kIndexViewMargin = 4; +static const CGFloat kIndexViewMargin = 4.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -59,7 +59,8 @@ @implementation TTSearchBar /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _boxView = [[TTView alloc] init]; _boxView.backgroundColor = [UIColor clearColor]; [self addSubview:_boxView]; @@ -128,6 +129,7 @@ - (void)showIndexView:(BOOL)show { CGRect frame = indexView.frame; frame.origin.x = self.width - (indexView.width + kIndexViewMargin); indexView.frame = frame; + } else { indexView.frame = CGRectOffset(indexView.frame, indexView.width + kIndexViewMargin, 0); } @@ -304,6 +306,7 @@ - (void)setShowsCancelButton:(BOOL)showsCancelButton { [_cancelButton addTarget:_searchField action:@selector(resignFirstResponder) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:_cancelButton]; + } else { [_cancelButton removeFromSuperview]; TT_RELEASE_SAFELY(_cancelButton); @@ -319,12 +322,16 @@ - (void)setShowsSearchIcon:(BOOL)showsSearchIcon { if (_showsSearchIcon) { UIImageView* iconView = [[[UIImageView alloc] initWithImage: - [UIImage imageNamed:@"Three20.bundle/images/searchIcon.png"]] autorelease]; + [UIImage imageWithContentsOfFile: + [[[NSBundle mainBundle] bundlePath] + stringByAppendingString:@"/Three20.bundle/images/searchIcon.png"]]] + autorelease]; [iconView sizeToFit]; iconView.contentMode = UIViewContentModeLeft; iconView.frame = CGRectInset(iconView.frame, -floor(kMarginX/2), 0); _searchField.leftView = iconView; _searchField.leftViewMode = UITextFieldViewModeAlways; + } else { _searchField.leftView = nil; _searchField.leftViewMode = UITextFieldViewModeNever; diff --git a/src/Three20UI/Sources/TTSearchDisplayController.m b/src/Three20UI/Sources/TTSearchDisplayController.m index 4f717483af..3b1b573c92 100644 --- a/src/Three20UI/Sources/TTSearchDisplayController.m +++ b/src/Three20UI/Sources/TTSearchDisplayController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -42,7 +42,8 @@ @implementation TTSearchDisplayController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithSearchBar:(UISearchBar*)searchBar contentsController:(UIViewController*)controller { - if (self = [super initWithSearchBar:searchBar contentsController:controller]) { + self = [super initWithSearchBar:searchBar contentsController:controller]; + if (self) { self.delegate = self; } @@ -132,6 +133,7 @@ - (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController*)control [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:TT_FAST_TRANSITION_DURATION]; backgroundView.alpha = 1; + _searchResultsViewController.tableOverlayView.alpha = 0; [UIView commitAnimations]; } @@ -182,6 +184,7 @@ - (BOOL)searchDisplayController:(UISearchDisplayController*)controller shouldReloadTableForSearchString:(NSString*)searchString { if (_pausesBeforeSearching) { [self restartPauseTimer]; + } else { [_searchResultsViewController.dataSource search:searchString]; } diff --git a/src/Three20UI/Sources/TTSearchTextField.m b/src/Three20UI/Sources/TTSearchTextField.m index c7ba09ce4b..beac63f8bc 100644 --- a/src/Three20UI/Sources/TTSearchTextField.m +++ b/src/Three20UI/Sources/TTSearchTextField.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ #import "Three20UI/UIViewAdditions.h" // UI (private) -#import "Three20UI/TTSearchTextFieldInternal.h" +#import "Three20UI/private/TTSearchTextFieldInternal.h" // UINavigator #import "Three20UINavigator/TTGlobalNavigatorMetrics.h" @@ -41,8 +41,8 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kShadowHeight = 24; -static const CGFloat kDesiredTableHeight = 150; +static const CGFloat kShadowHeight = 24.0f; +static const CGFloat kDesiredTableHeight = 150.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -59,7 +59,8 @@ @implementation TTSearchTextField /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _internal = [[TTSearchTextFieldInternal alloc] initWithTextField:self]; self.autocorrectionType = UITextAutocorrectionTypeNo; @@ -107,6 +108,7 @@ - (void)showDoneButton:(BOOL)show { initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneAction)] autorelease]; [controller.navigationItem setRightBarButtonItem:doneButton animated:YES]; + } else { [_previousNavigationItem setRightBarButtonItem:_previousRightBarButtonItem animated:YES]; TT_RELEASE_SAFELY(_previousRightBarButtonItem); @@ -146,6 +148,7 @@ - (void)showDarkScreen:(BOOL)show { - (NSString*)searchText { if (!self.hasText) { return @""; + } else { NSCharacterSet* whitespace = [NSCharacterSet whitespaceCharacterSet]; return [self.text stringByTrimmingCharactersInSet:whitespace]; @@ -155,7 +158,7 @@ - (NSString*)searchText { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)autoSearch { - if (_searchesAutomatically || !self.text.length) { + if (_searchesAutomatically && self.text.length) { [self search]; } } @@ -192,6 +195,7 @@ - (void)reloadTable { [self layoutIfNeeded]; [self showSearchResults:YES]; [self.tableView reloadData]; + } else { [self showSearchResults:NO]; } @@ -251,6 +255,7 @@ - (void)setText:(NSString*)text { - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath { if (_rowHeight) { return _rowHeight; + } else { id object = [_dataSource tableView:tableView objectForRowAtIndexPath:indexPath]; Class cls = [_dataSource tableView:tableView cellClassForObject:object]; @@ -264,7 +269,7 @@ - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*) if ([_internal.delegate respondsToSelector:@selector(textField:didSelectObject:)]) { id object = [_dataSource tableView:tableView objectForRowAtIndexPath:indexPath]; UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath]; - if (cell.selectionStyle != UITableViewCellSeparatorStyleNone) { + if (cell.selectionStyle != UITableViewCellSelectionStyleNone) { [_internal.delegate performSelector:@selector(textField:didSelectObject:) withObject:self withObject:object]; } @@ -388,6 +393,7 @@ - (void)setSearchesAutomatically:(BOOL)searchesAutomatically { if (searchesAutomatically) { self.returnKeyType = UIReturnKeyDone; self.enablesReturnKeyAutomatically = NO; + } else { self.returnKeyType = UIReturnKeySearch; self.enablesReturnKeyAutomatically = YES; @@ -413,7 +419,7 @@ - (void)search { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)showSearchResults:(BOOL)show { if (show && _dataSource) { - self.tableView; + [self tableView]; if (!_shadowView) { _shadowView = [[TTView alloc] init]; @@ -436,6 +442,7 @@ - (void)showSearchResults:(BOOL)show { } [_tableView deselectRowAtIndexPath:_tableView.indexPathForSelectedRow animated:NO]; + } else { [_tableView removeFromSuperview]; [_shadowView removeFromSuperview]; @@ -448,6 +455,7 @@ - (UIView*)superviewForSearchResults { UIScrollView* scrollView = (UIScrollView*)[self ancestorOrSelfWithClass:[UIScrollView class]]; if (scrollView) { return scrollView; + } else { for (UIView* view = self.superview; view; view = view.superview) { if (view.height > kDesiredTableHeight) { @@ -464,7 +472,7 @@ - (UIView*)superviewForSearchResults { - (CGRect)rectForSearchResults:(BOOL)withKeyboard { UIView* superview = self.superviewForSearchResults; - CGFloat y = 0; + CGFloat y = 0.0f; UIView* view = self; while (view != superview) { y += view.top; @@ -473,7 +481,7 @@ - (CGRect)rectForSearchResults:(BOOL)withKeyboard { CGFloat height = self.height; CGFloat keyboardHeight = withKeyboard ? TTKeyboardHeight() : 0; - CGFloat tableHeight = self.window.height - (self.ttScreenY + height + keyboardHeight); + CGFloat tableHeight = self.window.height - (self.screenViewY + height + keyboardHeight); return CGRectMake(0, y + self.height-1, superview.frame.size.width, tableHeight+1); } diff --git a/src/Three20UI/Sources/TTSearchTextFieldInternal.m b/src/Three20UI/Sources/TTSearchTextFieldInternal.m index 5c645e2a7c..17308555e1 100644 --- a/src/Three20UI/Sources/TTSearchTextFieldInternal.m +++ b/src/Three20UI/Sources/TTSearchTextFieldInternal.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,10 @@ // limitations under the License. // -#import "Three20UI/TTSearchTextFieldInternal.h" +#import "Three20UI/private/TTSearchTextFieldInternal.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" // UI #import "Three20UI/TTSearchTextField.h" @@ -23,6 +26,8 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +TT_FIX_CATEGORY_BUG(TTSearchTextFieldInternal) + @implementation TTSearchTextFieldInternal @synthesize delegate = _delegate; @@ -30,7 +35,8 @@ @implementation TTSearchTextFieldInternal /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTextField:(TTSearchTextField*)textField { - if (self = [super init]) { + self = [super init]; + if (self) { _textField = textField; } @@ -48,6 +54,7 @@ - (id)initWithTextField:(TTSearchTextField*)textField { - (BOOL)textFieldShouldBeginEditing:(UITextField*)textField { if ([_delegate respondsToSelector:@selector(textFieldShouldBeginEditing:)]) { return [_delegate textFieldShouldBeginEditing:textField]; + } else { return YES; } @@ -66,6 +73,7 @@ - (void)textFieldDidBeginEditing:(UITextField*)textField { - (BOOL)textFieldShouldEndEditing:(UITextField*)textField { if ([_delegate respondsToSelector:@selector(textFieldShouldEndEditing:)]) { return [_delegate textFieldShouldEndEditing:textField]; + } else { return YES; } @@ -92,6 +100,7 @@ - (BOOL) textField: (UITextField*)textField if ([_delegate respondsToSelector:sel]) { return [_delegate textField:textField shouldChangeCharactersInRange:range replacementString:string]; + } else { return YES; } @@ -104,6 +113,7 @@ - (BOOL)textFieldShouldClear:(UITextField*)textField { if ([_delegate respondsToSelector:@selector(textFieldShouldClear:)]) { return [_delegate textFieldShouldClear:textField]; + } else { return YES; } @@ -120,6 +130,7 @@ - (BOOL)textFieldShouldReturn:(UITextField*)textField { if (shouldReturn) { if (!_textField.searchesAutomatically) { [_textField search]; + } else { [_textField performSelector:@selector(doneAction)]; } diff --git a/src/Three20UI/Sources/TTSearchlightLabel.m b/src/Three20UI/Sources/TTSearchlightLabel.m index 2994636603..e6a68d3730 100644 --- a/src/Three20UI/Sources/TTSearchlightLabel.m +++ b/src/Three20UI/Sources/TTSearchlightLabel.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,7 +38,8 @@ @implementation TTSearchlightLabel /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { self.text = @""; self.font = TTSTYLEVAR(font); self.textColor = [UIColor colorWithWhite:0.25 alpha:1]; @@ -132,18 +133,21 @@ - (void)drawRect:(CGRect)rect { CGSize textSize = [self sizeThatFits:CGSizeZero]; - CGFloat x = 0; + CGFloat x = 0.0f; if (_textAlignment == UITextAlignmentRight) { x = self.frame.size.width - textSize.width; + } else if (_textAlignment == UITextAlignmentCenter) { x = ceil(self.frame.size.width/2 - textSize.width/2); } - CGFloat y = 0; + CGFloat y = 0.0f; if (self.contentMode == UIViewContentModeCenter) { y = ceil(rect.size.height/2 + _font.capHeight/2); + } else if (self.contentMode == UIViewContentModeBottom) { y = rect.size.height + _font.descender; + } else { y = _font.capHeight; } diff --git a/src/Three20UI/Sources/TTSectionedDataSource.m b/src/Three20UI/Sources/TTSectionedDataSource.m index 3577ffe8cd..5925554acc 100644 --- a/src/Three20UI/Sources/TTSectionedDataSource.m +++ b/src/Three20UI/Sources/TTSectionedDataSource.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ // UI #import "Three20UI/TTTableItem.h" +#import "Three20UI/TTTableSection.h" // Core #import "Three20Core/TTCorePreprocessorMacros.h" @@ -34,7 +35,8 @@ @implementation TTSectionedDataSource /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithItems:(NSArray*)items sections:(NSArray*)sections { - if (self = [self init]) { + self = [self init]; + if (self) { _items = [items mutableCopy]; _sections = [sections mutableCopy]; } @@ -66,10 +68,12 @@ + (TTSectionedDataSource*)dataSourceWithObjects:(id)object,... { va_list ap; va_start(ap, object); while (object) { - if ([object isKindOfClass:[NSString class]]) { + if ([object isKindOfClass:[NSString class]] || + [object isKindOfClass:[TTTableSection class]]) { [sections addObject:object]; section = [NSMutableArray array]; [items addObject:section]; + } else { [section addObject:object]; } @@ -88,8 +92,10 @@ + (TTSectionedDataSource*)dataSourceWithArrays:(id)object,... { va_list ap; va_start(ap, object); while (object) { - if ([object isKindOfClass:[NSString class]]) { + if ([object isKindOfClass:[NSString class]] || + [object isKindOfClass:[TTTableSection class]]) { [sections addObject:object]; + } else { [items addObject:object]; } @@ -124,6 +130,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger if (_sections) { NSArray* items = [_items objectAtIndex:section]; return items.count; + } else { return _items.count; } @@ -133,7 +140,27 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { if (_sections.count) { - return [_sections objectAtIndex:section]; + if ([[_sections objectAtIndex:section] isKindOfClass:[TTTableSection class]]) { + TTTableSection* sectionInfo = [_sections objectAtIndex:section]; + return sectionInfo.headerTitle; + + } else { + return [_sections objectAtIndex:section]; + } + + } else { + return nil; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { + if (tableView.style==UITableViewStyleGrouped && + _sections.count && + [[_sections objectAtIndex:section] isKindOfClass:[TTTableSection class]]) { + TTTableSection* sectionInfo = [_sections objectAtIndex:section]; + return sectionInfo.footerTitle; + } else { return nil; } @@ -151,6 +178,7 @@ - (id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)in if (_sections) { NSArray* section = [_items objectAtIndex:indexPath.section]; return [section objectAtIndex:indexPath.row]; + } else { return [_items objectAtIndex:indexPath.row]; } @@ -167,6 +195,7 @@ - (NSIndexPath*)tableView:(UITableView*)tableView indexPathForObject:(id)object return [NSIndexPath indexPathForRow:objectIndex inSection:i]; } } + } else { NSUInteger objectIndex = [_items indexOfObject:object]; if (objectIndex != NSNotFound) { @@ -196,6 +225,7 @@ - (NSIndexPath*)indexPathOfItemWithUserInfo:(id)userInfo { } } } + } else { for (NSInteger i = 0; i < _items.count; ++i) { TTTableItem* item = [_items objectAtIndex:i]; @@ -219,11 +249,12 @@ - (BOOL)removeItemAtIndexPath:(NSIndexPath*)indexPath andSectionIfEmpty:(BOOL)an if (_sections.count) { NSMutableArray* items = [_items objectAtIndex:indexPath.section]; [items removeObjectAtIndex:indexPath.row]; - if (!items.count) { + if (andSection && !items.count) { [_sections removeObjectAtIndex:indexPath.section]; [_items removeObjectAtIndex:indexPath.section]; return YES; } + } else if (!indexPath.section) { [_items removeObjectAtIndex:indexPath.row]; } diff --git a/src/Three20UI/Sources/TTSplitViewController.m b/src/Three20UI/Sources/TTSplitViewController.m new file mode 100644 index 0000000000..2e44bc0e68 --- /dev/null +++ b/src/Three20UI/Sources/TTSplitViewController.m @@ -0,0 +1,193 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UI/TTSplitViewController.h" + +// UI +#import "Three20UI/TTNavigator.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/TTDebug.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTSplitViewController + +@synthesize leftNavigator = _leftNavigator; +@synthesize rightNavigator = _rightNavigator; +@synthesize splitViewButton = _splitViewButton; +@synthesize popoverSplitController = _popoverSplitController; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + self.delegate = self; + + self.viewControllers = [NSArray arrayWithObjects: + [[[UINavigationController alloc] initWithNibName: nil + bundle: nil] autorelease], + [[[UINavigationController alloc] initWithNibName: nil + bundle: nil] autorelease], + nil]; + + _leftNavigator = [[TTNavigator alloc] init]; + _leftNavigator.rootContainer = self; + _leftNavigator.persistenceKey = @"splitNavPersistenceLeft"; + + _rightNavigator = [[TTNavigator alloc] init]; + _rightNavigator.rootContainer = self; + _rightNavigator.persistenceKey = @"splitNavPersistenceRight"; + } + + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)dealloc { + self.delegate = nil; + TT_RELEASE_SAFELY(_leftNavigator); + TT_RELEASE_SAFELY(_rightNavigator); + TT_RELEASE_SAFELY(_splitViewButton); + TT_RELEASE_SAFELY(_popoverSplitController); + + [super dealloc]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)updateSplitViewButton { + if (nil != _rightNavigator.rootViewController) { + + if (nil != _leftNavigator.rootViewController) { + UINavigationController* navController = + (UINavigationController*)_leftNavigator.rootViewController; + UIViewController* topViewController = navController.topViewController; + if (nil != topViewController) { + self.splitViewButton.title = topViewController.title; + } + } + + if (nil == self.splitViewButton.title) { + self.splitViewButton.title = @"Default Title"; + } + + UINavigationController* navController = + (UINavigationController*)_rightNavigator.rootViewController; + UIViewController* topViewController = navController.topViewController; + UINavigationItem* navItem = topViewController.navigationItem; + + navItem.leftBarButtonItem = _splitViewButton; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + [self updateSplitViewButton]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark TTNavigatorRootContainer + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTBaseNavigator*)getNavigatorForController:(UIViewController*)controller { + if (controller == [self.viewControllers objectAtIndex:0]) { + return _leftNavigator; + + } else if (controller == [self.viewControllers objectAtIndex:1]) { + return _rightNavigator; + } + + return nil; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)navigator:(TTBaseNavigator*)navigator setRootViewController:(UIViewController*)controller { + if (_rightNavigator == navigator) { + self.viewControllers = [NSArray arrayWithObjects: + [self.viewControllers objectAtIndex:0], + controller, + nil]; + + [self updateSplitViewButton]; + + } else if (_leftNavigator == navigator) { + self.viewControllers = [NSArray arrayWithObjects: + controller, + [self.viewControllers objectAtIndex:1], + nil]; + + [self updateSplitViewButton]; + + } else { + // Invalid navigator sent here. + TTDASSERT(NO); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark UISplitViewControllerDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)splitViewController: (UISplitViewController*)svc + willHideViewController: (UIViewController *)aViewController + withBarButtonItem: (UIBarButtonItem*)barButtonItem + forPopoverController: (UIPopoverController*)pc { + self.splitViewButton = barButtonItem; + + [self updateSplitViewButton]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)splitViewController: (UISplitViewController*)svc + willShowViewController: (UIViewController *)aViewController + invalidatingBarButtonItem: (UIBarButtonItem *)barButtonItem { + self.splitViewButton = nil; + + [self updateSplitViewButton]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)splitViewController: (UISplitViewController*)svc + popoverController: (UIPopoverController*)pc + willPresentViewController: (UIViewController *)aViewController { + self.popoverSplitController = pc; + + pc.contentViewController = aViewController; +} + + +@end + diff --git a/src/Three20UI/Sources/TTStyledTextLabel.m b/src/Three20UI/Sources/TTStyledTextLabel.m index e1a4c75f25..4c8295e84f 100644 --- a/src/Three20UI/Sources/TTStyledTextLabel.m +++ b/src/Three20UI/Sources/TTStyledTextLabel.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ #import "Three20Core/TTCorePreprocessorMacros.h" #import "Three20Core/TTDebug.h" -static const CGFloat kCancelHighlightThreshold = 4; +static const CGFloat kCancelHighlightThreshold = 4.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -59,7 +59,8 @@ @implementation TTStyledTextLabel /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _textAlignment = UITextAlignmentLeft; _contentInset = UIEdgeInsetsZero; @@ -94,7 +95,9 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// -// UITableView looks for this function and crashes if it is not found when you select a cell +/** + * UITableView looks for this function and crashes if it is not found when you select a cell + */ - (BOOL)isHighlighted { return _highlighted; } @@ -111,6 +114,7 @@ - (void)setStyle:(TTStyle*)style forFrame:(TTStyledBoxFrame*)frame { inlineFrame.style = style; inlineFrame = inlineFrame.inlineNextFrame; } + } else { frame.style = style; } @@ -139,6 +143,7 @@ - (void)setHighlightedFrame:(TTStyledBoxFrame*)frame{ [_highlightedNode release]; _highlightedNode = [frame.element retain]; tableView.highlightedLabel = self; + } else { TTStyle* style = [TTSTYLESHEET styleWithSelector:className forState:UIControlStateNormal]; [self setStyle:style forFrame:_highlightedFrame]; @@ -155,7 +160,8 @@ - (void)setHighlightedFrame:(TTStyledBoxFrame*)frame{ /////////////////////////////////////////////////////////////////////////////////////////////////// -- (NSString*)combineTextFromFrame:(TTStyledTextFrame*)fromFrame toFrame:(TTStyledTextFrame*)toFrame { +- (NSString*)combineTextFromFrame:(TTStyledTextFrame*)fromFrame + toFrame:(TTStyledTextFrame*)toFrame { NSMutableArray* strings = [NSMutableArray array]; for (TTStyledTextFrame* frame = fromFrame; frame && frame != toFrame; frame = (TTStyledTextFrame*)frame.nextFrame) { @@ -177,6 +183,7 @@ - (void)addAccessibilityElementFromFrame:(TTStyledTextFrame*)fromFrame acc.accessibilityTraits = UIAccessibilityTraitStaticText; if (fromFrame == toFrame) { acc.accessibilityLabel = fromFrame.text; + } else { acc.accessibilityLabel = [self combineTextFromFrame:fromFrame toFrame:toFrame]; } @@ -202,16 +209,20 @@ - (void)addAccessibilityElementsForNode:(TTStyledNode*)node { acc.accessibilityTraits = UIAccessibilityTraitLink; acc.accessibilityLabel = [node outerText]; [_accessibilityElements addObject:acc]; + } else if ([node isKindOfClass:[TTStyledTextNode class]]) { TTStyledTextFrame* startFrame = (TTStyledTextFrame*)[_text getFrameForNode:node]; UIEdgeInsets edges = [self edgesForRect:startFrame.bounds]; TTStyledTextFrame* frame = (TTStyledTextFrame*)startFrame.nextFrame; - for (; [frame isKindOfClass:[TTStyledTextFrame class]]; frame = (TTStyledTextFrame*)frame.nextFrame) { + for (; + [frame isKindOfClass:[TTStyledTextFrame class]]; + frame = (TTStyledTextFrame*)frame.nextFrame) { if (frame.bounds.origin.x < edges.left) { [self addAccessibilityElementFromFrame:startFrame toFrame:frame withEdges:edges]; edges = [self edgesForRect:frame.bounds]; startFrame = frame; + } else { if (frame.bounds.origin.x+frame.bounds.size.width > edges.right) { edges.right = frame.bounds.origin.x+frame.bounds.size.width; @@ -225,6 +236,7 @@ - (void)addAccessibilityElementsForNode:(TTStyledNode*)node { if (frame != startFrame) { [self addAccessibilityElementFromFrame:startFrame toFrame:frame withEdges:edges]; } + } else if ([node isKindOfClass:[TTStyledElement class]]) { TTStyledElement* element = (TTStyledElement*)node; for (TTStyledNode* child = element.firstChild; child; child = child.nextSibling) { @@ -346,6 +358,7 @@ - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { - (void)drawRect:(CGRect)rect { if (_highlighted) { [self.highlightedTextColor setFill]; + } else { [self.textColor setFill]; } @@ -442,6 +455,7 @@ - (void)setText:(TTStyledText*)text { _text = [text retain]; _text.delegate = self; _text.font = _font; + _text.textAlignment = _textAlignment; [self setNeedsLayout]; [self setNeedsDisplay]; } @@ -470,6 +484,14 @@ - (void)setFont:(UIFont*)font { } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setTextAlignment:(UITextAlignment)textAlignment { + if (textAlignment != _textAlignment) { + _textAlignment = textAlignment; + _text.textAlignment = _textAlignment; + [self setNeedsLayout]; + } +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIColor*)textColor { @@ -504,6 +526,7 @@ - (void)setHighlightedNode:(TTStyledElement*)node { if (node != _highlightedNode) { if (!node) { [self setHighlightedFrame:nil]; + } else { [_highlightedNode release]; _highlightedNode = [node retain]; diff --git a/src/Three20UI/Sources/TTStyledTextTableCell.m b/src/Three20UI/Sources/TTStyledTextTableCell.m index c9a03f2145..a359746856 100644 --- a/src/Three20UI/Sources/TTStyledTextTableCell.m +++ b/src/Three20UI/Sources/TTStyledTextTableCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40,7 +40,8 @@ @implementation TTStyledTextTableCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:style reuseIdentifier:identifier]) { + self = [super initWithStyle:style reuseIdentifier:identifier]; + if (self) { _label = [[TTStyledTextLabel alloc] init]; _label.contentMode = UIViewContentModeLeft; [self.contentView addSubview:_label]; diff --git a/src/Three20UI/Sources/TTStyledTextTableItemCell.m b/src/Three20UI/Sources/TTStyledTextTableItemCell.m index 5aaed0076c..e36441a3db 100644 --- a/src/Three20UI/Sources/TTStyledTextTableItemCell.m +++ b/src/Three20UI/Sources/TTStyledTextTableItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kDisclosureIndicatorWidth = 23; +static const CGFloat kDisclosureIndicatorWidth = 23.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -43,7 +43,8 @@ @implementation TTStyledTextTableItemCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:style reuseIdentifier:identifier]) { + self = [super initWithStyle:style reuseIdentifier:identifier]; + if (self) { _label = [[TTStyledTextLabel alloc] init]; _label.contentMode = UIViewContentModeLeft; [self.contentView addSubview:_label]; @@ -79,9 +80,12 @@ + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { padding += kDisclosureIndicatorWidth; } - item.text.width = tableView.width - padding; + CGFloat margin = item.margin.left + item.margin.right; - return item.text.height + item.padding.top + item.padding.bottom; + item.text.width = tableView.width - padding - margin; + + return item.text.height + item.padding.top + item.padding.bottom + + item.margin.top + item.margin.bottom; } @@ -96,7 +100,7 @@ - (void)layoutSubviews { [super layoutSubviews]; TTTableStyledTextItem* item = self.object; - _label.frame = CGRectOffset(self.contentView.bounds, item.margin.left, item.margin.top); + _label.frame = UIEdgeInsetsInsetRect(self.contentView.bounds, item.margin); } diff --git a/src/Three20UI/Sources/TTTab.m b/src/Three20UI/Sources/TTTab.m index d15448628f..5cd2f39a7e 100644 --- a/src/Three20UI/Sources/TTTab.m +++ b/src/Three20UI/Sources/TTTab.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ #import "Three20UI/UIViewAdditions.h" // UI (private) -#import "Three20UI/TTTabBarInternal.h" +#import "Three20UI/private/TTTabBarInternal.h" // Style #import "Three20Style/TTGlobalStyle.h" @@ -42,7 +42,8 @@ @implementation TTTab /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithItem:(TTTabItem*)tabItem tabBar:(TTTabBar*)tabBar { - if (self = [self init]) { + self = [self init]; + if (self) { self.tabItem = tabItem; } @@ -72,6 +73,7 @@ - (void)updateBadgeNumber { } if (_tabItem.badgeNumber <= kMaxBadgeNumber) { _badge.text = [NSString stringWithFormat:@"%d", _tabItem.badgeNumber]; + } else { _badge.text = [NSString stringWithFormat:@"%d+", kMaxBadgeNumber]; } @@ -79,6 +81,7 @@ - (void)updateBadgeNumber { _badge.frame = CGRectMake(self.width - _badge.width-1, 1, _badge.width, _badge.height); _badge.hidden = NO; + } else { _badge.hidden = YES; } diff --git a/src/Three20UI/Sources/TTTabBar.m b/src/Three20UI/Sources/TTTabBar.m index 48c07f7493..a9b01eda0f 100644 --- a/src/Three20UI/Sources/TTTabBar.m +++ b/src/Three20UI/Sources/TTTabBar.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ #import "Three20UI/TTTabDelegate.h" // UI (private) -#import "Three20UI/TTTabBarInternal.h" +#import "Three20UI/private/TTTabBarInternal.h" // Style #import "Three20Style/TTGlobalStyle.h" @@ -47,7 +47,8 @@ @implementation TTTabBar /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _selectedTabIndex = NSIntegerMax; _tabViews = [[NSMutableArray alloc] init]; @@ -176,7 +177,9 @@ - (void)setTabItems:(NSArray*)tabItems { TTTabItem* tabItem = [_tabItems objectAtIndex:i]; TTTab* tab = [[[TTTab alloc] initWithItem:tabItem tabBar:self] autorelease]; [tab setStylesWithSelector:self.tabStyle]; - [tab addTarget:self action:@selector(tabTouchedUp:) forControlEvents:UIControlEventTouchUpInside]; + [tab addTarget: self + action: @selector(tabTouchedUp:) + forControlEvents: UIControlEventTouchUpInside]; [self addTab:tab]; [_tabViews addObject:tab]; if (i == _selectedTabIndex) { diff --git a/src/Three20UI/Sources/TTTabBarInternal.m b/src/Three20UI/Sources/TTTabBarInternal.m index 97cb469690..fae880fe1f 100644 --- a/src/Three20UI/Sources/TTTabBarInternal.m +++ b/src/Three20UI/Sources/TTTabBarInternal.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,20 +14,25 @@ // limitations under the License. // -#import "Three20UI/TTTabBarInternal.h" +#import "Three20UI/private/TTTabBarInternal.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" // UI #import "Three20UI/TTTab.h" #import "Three20UI/UIViewAdditions.h" - CGFloat kTabMargin = 10; -const NSInteger kMaxBadgeNumber = 99; -static CGFloat kPadding = 10; + CGFloat kTabMargin = 10.0f; +const NSInteger kMaxBadgeNumber = 99.0f; +static CGFloat kPadding = 10.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +TT_FIX_CATEGORY_BUG(TTTabBarInternal) + @implementation TTTabBar (TTInternal) @@ -37,9 +42,9 @@ - (CGSize)layoutTabs { if (self.contentMode == UIViewContentModeScaleToFill) { CGFloat maxTextWidth = self.width - (kTabMargin*2 + kPadding*2*_tabViews.count); - CGFloat totalTextWidth = 0; + CGFloat totalTextWidth = 0.0f; CGFloat totalTabWidth = kTabMargin*2; - CGFloat maxTabWidth = 0; + CGFloat maxTabWidth = 0.0f; for (int i = 0; i < _tabViews.count; ++i) { TTTab* tab = [_tabViews objectAtIndex:i]; [tab sizeToFit]; @@ -58,6 +63,7 @@ - (CGSize)layoutTabs { tab.frame = CGRectMake(x, 0, ceil(textWidth * shrinkFactor) + kPadding*2 , self.height); x += tab.width; } + } else { CGFloat averageTabWidth = ceil((self.width - kTabMargin*2)/_tabViews.count); if (maxTabWidth > averageTabWidth && self.width - totalTabWidth < kTabMargin) { @@ -66,6 +72,7 @@ - (CGSize)layoutTabs { tab.frame = CGRectMake(x, 0, tab.width, self.height); x += tab.width; } + } else { for (int i = 0; i < _tabViews.count; ++i) { TTTab* tab = [_tabViews objectAtIndex:i]; @@ -74,6 +81,7 @@ - (CGSize)layoutTabs { } } } + } else { for (int i = 0; i < _tabViews.count; ++i) { TTTab* tab = [_tabViews objectAtIndex:i]; diff --git a/src/Three20UI/Sources/TTTabGrid.m b/src/Three20UI/Sources/TTTabGrid.m index 5dc939fcad..f66ea577a4 100644 --- a/src/Three20UI/Sources/TTTabGrid.m +++ b/src/Three20UI/Sources/TTTabGrid.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -39,7 +39,8 @@ @implementation TTTabGrid /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { self.style = TTSTYLE(tabGrid); _columnCount = 3; } @@ -70,24 +71,31 @@ - (void)updateTabStyles { for (TTTab* tab in self.tabViews) { if (column == 0) { [tab setStylesWithSelector:@"tabGridTabTopLeft:"]; + } else if (column == columnCount-1) { [tab setStylesWithSelector:@"tabGridTabTopRight:"]; + } else if (column == cellCount - columnCount) { [tab setStylesWithSelector:@"tabGridTabBottomLeft:"]; + } else if (column == cellCount - 1) { [tab setStylesWithSelector:@"tabGridTabBottomRight:"]; + } else { [tab setStylesWithSelector:@"tabGridTabCenter:"]; } ++column; } + } else { int column = 0; for (TTTab* tab in self.tabViews) { if (column == 0) { [tab setStylesWithSelector:@"tabGridTabLeft:"]; + } else if (column == columnCount-1) { [tab setStylesWithSelector:@"tabGridTabRight:"]; + } else { [tab setStylesWithSelector:@"tabGridTabCenter:"]; } @@ -104,6 +112,7 @@ - (CGSize)layoutTabs { layout.padding = 1; layout.columnCount = [self columnCount]; return [layout layoutSubviews:self.tabViews forView:self]; + } else { return self.frame.size; } diff --git a/src/Three20UI/Sources/TTTabItem.m b/src/Three20UI/Sources/TTTabItem.m index aa8b0af0df..23dee62f42 100644 --- a/src/Three20UI/Sources/TTTabItem.m +++ b/src/Three20UI/Sources/TTTabItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,7 +33,8 @@ @implementation TTTabItem /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title { - if (self = [self init]) { + self = [self init]; + if (self) { self.title = title; } diff --git a/src/Three20UI/Sources/TTTabStrip.m b/src/Three20UI/Sources/TTTabStrip.m index 426fdf1ec4..56c28d49ab 100644 --- a/src/Three20UI/Sources/TTTabStrip.m +++ b/src/Three20UI/Sources/TTTabStrip.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ #import "Three20UI/UIViewAdditions.h" // UI (private) -#import "Three20UI/TTTabBarInternal.h" +#import "Three20UI/private/TTTabBarInternal.h" // Style #import "Three20Style/TTGlobalStyle.h" @@ -39,16 +39,20 @@ @implementation TTTabStrip /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _scrollView = [[UIScrollView alloc] init]; _scrollView.scrollEnabled = YES; _scrollView.scrollsToTop = NO; _scrollView.showsVerticalScrollIndicator = NO; _scrollView.showsHorizontalScrollIndicator = NO; + _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth; + _scrollView.delegate = self; [self addSubview:_scrollView]; self.style = TTSTYLE(tabStrip); self.tabStyle = @"tabRound:"; + self.autoresizingMask = UIViewAutoresizingFlexibleWidth; } return self; @@ -74,6 +78,7 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)addTab:(TTTab*)tab { [_scrollView addSubview:tab]; + _contentSizeCached = NO; } @@ -91,6 +96,7 @@ - (void)updateOverflow { _overflowRight.left = self.width-_overflowRight.width; _overflowRight.hidden = NO; + } else { _overflowRight.hidden = YES; } @@ -105,6 +111,7 @@ - (void)updateOverflow { } _overflowLeft.hidden = NO; + } else { _overflowLeft.hidden = YES; } @@ -113,6 +120,10 @@ - (void)updateOverflow { /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGSize)layoutTabs { + if (_contentSizeCached) { + return _contentSize; + } + CGSize size = [super layoutTabs]; CGPoint contentOffset = _scrollView.contentOffset; @@ -120,6 +131,9 @@ - (CGSize)layoutTabs { _scrollView.contentSize = CGSizeMake(size.width + kTabMargin, self.height); _scrollView.contentOffset = contentOffset; + _contentSize = size; + _contentSizeCached = YES; + return size; } @@ -137,6 +151,18 @@ - (void)layoutSubviews { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark UIScrollViewDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)scrollViewDidScroll:(UIScrollView *)scrollView { + [self updateOverflow]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - @@ -146,6 +172,7 @@ - (void)layoutSubviews { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setTabItems:(NSArray*)tabItems { [super setTabItems:tabItems]; + _contentSizeCached = NO; [self updateOverflow]; } diff --git a/src/Three20UI/Sources/TTTableActivityItem.m b/src/Three20UI/Sources/TTTableActivityItem.m index 5aab2299b1..30eb916d5c 100644 --- a/src/Three20UI/Sources/TTTableActivityItem.m +++ b/src/Three20UI/Sources/TTTableActivityItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableActivityItemCell.m b/src/Three20UI/Sources/TTTableActivityItemCell.m index 1aab898cf4..6147248e15 100644 --- a/src/Three20UI/Sources/TTTableActivityItemCell.m +++ b/src/Three20UI/Sources/TTTableActivityItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -34,7 +34,8 @@ @implementation TTTableActivityItemCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:style reuseIdentifier:identifier]) { + self = [super initWithStyle:style reuseIdentifier:identifier]; + if (self) { _activityLabel = [[TTActivityLabel alloc] initWithStyle:TTActivityLabelStyleGray]; [self.contentView addSubview:_activityLabel]; @@ -49,7 +50,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)ident /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dealloc { TT_RELEASE_SAFELY(_activityLabel); - + TT_RELEASE_SAFELY(_item); [super dealloc]; } @@ -67,6 +68,7 @@ - (void)layoutSubviews { UITableView* tableView = (UITableView*)self.superview; if (tableView.style == UITableViewStylePlain) { _activityLabel.frame = self.contentView.bounds; + } else { _activityLabel.frame = CGRectInset(self.contentView.bounds, -1, -1); } diff --git a/src/Three20UI/Sources/TTTableButton.m b/src/Three20UI/Sources/TTTableButton.m index 5f456ff076..205341da48 100644 --- a/src/Three20UI/Sources/TTTableButton.m +++ b/src/Three20UI/Sources/TTTableButton.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableCaptionItem.m b/src/Three20UI/Sources/TTTableCaptionItem.m index 44f8637f3f..31ddaa7283 100644 --- a/src/Three20UI/Sources/TTTableCaptionItem.m +++ b/src/Three20UI/Sources/TTTableCaptionItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -81,7 +81,8 @@ + (id)itemWithText:(NSString*)text caption:(NSString*)caption URL:(NSString*)URL /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super initWithCoder:decoder]) { + self = [super initWithCoder:decoder]; + if (self) { self.caption = [decoder decodeObjectForKey:@"caption"]; } return self; diff --git a/src/Three20UI/Sources/TTTableCaptionItemCell.m b/src/Three20UI/Sources/TTTableCaptionItemCell.m index 2ba178bcc8..8826ba6a9c 100644 --- a/src/Three20UI/Sources/TTTableCaptionItemCell.m +++ b/src/Three20UI/Sources/TTTableCaptionItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,8 +26,8 @@ #import "Three20Style/TTGlobalStyle.h" #import "Three20Style/TTDefaultStyleSheet.h" -static const CGFloat kKeySpacing = 12; -static const CGFloat kKeyWidth = 75; +static const CGFloat kKeySpacing = 12.0f; +static const CGFloat kKeyWidth = 75.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -38,10 +38,12 @@ @implementation TTTableCaptionItemCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]) { + self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]; + if (self) { self.textLabel.font = TTSTYLEVAR(tableTitleFont); self.textLabel.textColor = TTSTYLEVAR(linkTextColor); self.textLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.textLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); self.textLabel.textAlignment = UITextAlignmentRight; self.textLabel.lineBreakMode = UILineBreakModeTailTruncation; self.textLabel.numberOfLines = 1; @@ -50,6 +52,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)ident self.detailTextLabel.font = TTSTYLEVAR(tableSmallFont); self.detailTextLabel.textColor = TTSTYLEVAR(textColor); self.detailTextLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.detailTextLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); self.detailTextLabel.adjustsFontSizeToFitWidth = YES; self.detailTextLabel.minimumFontSize = 8; self.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap; @@ -77,7 +80,11 @@ + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { constrainedToSize:CGSizeMake(width, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap]; - return detailTextSize.height + kTableCellVPadding*2; + CGSize captionTextSize = [item.caption sizeWithFont:TTSTYLEVAR(tableTitleFont) + constrainedToSize:CGSizeMake(kKeyWidth, CGFLOAT_MAX) + lineBreakMode:UILineBreakModeTailTruncation]; + + return MAX(detailTextSize.height, captionTextSize.height) + kTableCellVPadding*2; } diff --git a/src/Three20UI/Sources/TTTableControlCell.m b/src/Three20UI/Sources/TTTableControlCell.m index f7bfb6d5d1..33ad58ec8e 100644 --- a/src/Three20UI/Sources/TTTableControlCell.m +++ b/src/Three20UI/Sources/TTTableControlCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -28,8 +28,8 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kDefaultTextViewLines = 5; -static const CGFloat kControlPadding = 8; +static const CGFloat kDefaultTextViewLines = 5.0f; +static const CGFloat kControlPadding = 8.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -43,7 +43,8 @@ @implementation TTTableControlCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:style reuseIdentifier:identifier]) { + self = [super initWithStyle:style reuseIdentifier:identifier]; + if (self) { self.selectionStyle = UITableViewCellSelectionStyleNone; } @@ -128,6 +129,7 @@ + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { if (height < TT_ROW_HEIGHT) { return TT_ROW_HEIGHT; + } else { return height; } @@ -165,6 +167,7 @@ - (void)layoutSubviews { if ([TTTableControlCell shouldConsiderControlIntrinsicSize:_control]) { minX += contentWidth - _control.width; + contentWidth = _control.width; } // XXXjoe For some reason I need to re-add the control as a subview or else @@ -191,7 +194,13 @@ - (id)object { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setObject:(id)object { if (object != _control && object != _item) { - [_control removeFromSuperview]; + if (_control.superview == self.contentView) { + //on cell reuse it is possible that another + //cell is already the owner of _control, so + //check if we're its superview first + [_control removeFromSuperview]; + } + TT_RELEASE_SAFELY(_control); TT_RELEASE_SAFELY(_item); diff --git a/src/Three20UI/Sources/TTTableControlItem.m b/src/Three20UI/Sources/TTTableControlItem.m index 8f10e4a461..2c5d4e892b 100644 --- a/src/Three20UI/Sources/TTTableControlItem.m +++ b/src/Three20UI/Sources/TTTableControlItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -61,7 +61,8 @@ + (id)itemWithCaption:(NSString*)caption control:(UIControl*)control { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super initWithCoder:decoder]) { + self = [super initWithCoder:decoder]; + if (self) { self.caption = [decoder decodeObjectForKey:@"caption"]; self.control = [decoder decodeObjectForKey:@"control"]; } diff --git a/src/Three20UI/Sources/TTTableFlushViewCell.m b/src/Three20UI/Sources/TTTableFlushViewCell.m index 67c10ee3ba..6e34ab2d98 100644 --- a/src/Three20UI/Sources/TTTableFlushViewCell.m +++ b/src/Three20UI/Sources/TTTableFlushViewCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -37,7 +37,8 @@ @implementation TTTableFlushViewCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:style reuseIdentifier:identifier]) { + self = [super initWithStyle:style reuseIdentifier:identifier]; + if (self) { self.selectionStyle = UITableViewCellSelectionStyleNone; } @@ -100,6 +101,7 @@ - (void)setObject:(id)object { if ([object isKindOfClass:[UIView class]]) { _view = [object retain]; + } else if ([object isKindOfClass:[TTTableViewItem class]]) { _item = [object retain]; _view = [_item.view retain]; diff --git a/src/Three20UI/Sources/TTTableFooterInfiniteScrollView.m b/src/Three20UI/Sources/TTTableFooterInfiniteScrollView.m new file mode 100644 index 0000000000..48329ba9fc --- /dev/null +++ b/src/Three20UI/Sources/TTTableFooterInfiniteScrollView.m @@ -0,0 +1,92 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "Three20UI/TTTableFooterInfiniteScrollView.h" + +// UI +#import "Three20UI/UIViewAdditions.h" + +// Style +#import "Three20Style/TTGlobalStyle.h" +#import "Three20Style/TTDefaultStyleSheet.h" + +// Network +#import "Three20Network/TTURLCache.h" + +// Core +#import "Three20Core/TTGlobalCoreLocale.h" + +#import + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTTableFooterInfiniteScrollView + +@synthesize indicator = _indicator; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame])) { + self.indicator = [[[UIActivityIndicatorView alloc] + initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] + autorelease]; + self.indicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | + UIViewAutoresizingFlexibleRightMargin; + + [self addSubview:self.indicator]; + } + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)drawRect:(CGRect)rect{ + CGContextRef contextRef = UIGraphicsGetCurrentContext(); + CGContextSetRGBFillColor(contextRef, 1, 1, 1, 1); + CGContextFillRect(contextRef, rect); + if (!_loading) { + CGFloat dotSize = 5.0f; + CGFloat x = roundf((self.width / 2) - (dotSize / 2)); + CGFloat y = roundf((self.height / 2) - (dotSize / 2)); + CGContextSetRGBFillColor(contextRef, 0.75, 0.75, 0.75, 1.0); + CGContextFillEllipseInRect(contextRef, CGRectMake(x, y, dotSize, dotSize)); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)layoutSubviews { + [super layoutSubviews]; + self.indicator.left = roundf((self.width / 2) - (self.indicator.width / 2)); + self.indicator.top = roundf((self.height / 2) - (self.indicator.height / 2)); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setLoading:(BOOL)loading { + _loading = loading; + if (_loading) { + [self.indicator startAnimating]; + + } else { + [self.indicator stopAnimating]; + } + [self setNeedsDisplay]; +} + +@end diff --git a/src/Three20UI/Sources/TTTableGrayTextItem.m b/src/Three20UI/Sources/TTTableGrayTextItem.m index ddc7d37e33..1f87c86eec 100644 --- a/src/Three20UI/Sources/TTTableGrayTextItem.m +++ b/src/Three20UI/Sources/TTTableGrayTextItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableHeaderDragRefreshView.m b/src/Three20UI/Sources/TTTableHeaderDragRefreshView.m index ef4d4083cb..9bc82d197f 100644 --- a/src/Three20UI/Sources/TTTableHeaderDragRefreshView.m +++ b/src/Three20UI/Sources/TTTableHeaderDragRefreshView.m @@ -1,17 +1,27 @@ // -// Copyright 2009-2010 Facebook +// Created by Devin Doty on 10/14/09. +// http://github.com/enormego/EGOTableViewPullRefresh +// Copyright 2009 enormego. All rights reserved. // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +// Modifications copyright 2010 Facebook. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // #import "Three20UI/TTTableHeaderDragRefreshView.h" @@ -49,6 +59,7 @@ @implementation TTTableHeaderDragRefreshView - (void)showActivity:(BOOL)shouldShow animated:(BOOL)animated { if (shouldShow) { [_activityView startAnimating]; + } else { [_activityView stopAnimating]; } @@ -79,7 +90,7 @@ - (void)setImageFlipped:(BOOL)flipped { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if(self = [super initWithFrame:frame]) { + if (self = [super initWithFrame:frame]) { self.autoresizingMask = UIViewAutoresizingFlexibleWidth; _lastUpdatedLabel = [[UILabel alloc] @@ -109,11 +120,11 @@ - (id)initWithFrame:(CGRect)frame { [self setStatus:TTTableHeaderDragRefreshPullToReload]; [self addSubview:_statusLabel]; + UIImage* arrowImage = TTSTYLEVAR(tableRefreshHeaderArrowImage); _arrowImage = [[UIImageView alloc] - initWithFrame:CGRectMake(25.0f, frame.size.height - 65.0f, - 30.0f, 55.0f)]; - _arrowImage.contentMode = UIViewContentModeScaleAspectFit; - _arrowImage.image = TTSTYLEVAR(tableRefreshHeaderArrowImage); + initWithFrame:CGRectMake(25.0f, frame.size.height - 60.0f, + arrowImage.size.width, arrowImage.size.height)]; + _arrowImage.image = arrowImage; [_arrowImage layer].transform = CATransform3DMakeRotation(M_PI, 0.0f, 0.0f, 1.0f); [self addSubview:_arrowImage]; @@ -133,6 +144,8 @@ - (void)dealloc { TT_RELEASE_SAFELY(_statusLabel); TT_RELEASE_SAFELY(_arrowImage); TT_RELEASE_SAFELY(_lastUpdatedLabel); + TT_RELEASE_SAFELY(_lastUpdatedDate); + [super dealloc]; } diff --git a/src/Three20UI/Sources/TTTableHeaderView.m b/src/Three20UI/Sources/TTTableHeaderView.m index 1e0bcd90a1..16bda360ff 100644 --- a/src/Three20UI/Sources/TTTableHeaderView.m +++ b/src/Three20UI/Sources/TTTableHeaderView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,7 +35,8 @@ @implementation TTTableHeaderView /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTitle:(NSString*)title { - if (self = [super init]) { + self = [super init]; + if (self) { self.backgroundColor = [UIColor clearColor]; self.style = TTSTYLE(tableHeader); @@ -73,7 +74,9 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)layoutSubviews { - _label.frame = CGRectMake(12, 0, self.width, self.height); + _label.size = [_label sizeThatFits:CGSizeMake(self.bounds.size.width - 12, + self.bounds.size.height)]; + _label.origin = CGPointMake(12, floorf((self.bounds.size.height - _label.size.height)/2.f)); } diff --git a/src/Three20UI/Sources/TTTableImageItem.m b/src/Three20UI/Sources/TTTableImageItem.m index 7f5279e4e1..a49af3698f 100644 --- a/src/Three20UI/Sources/TTTableImageItem.m +++ b/src/Three20UI/Sources/TTTableImageItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -98,7 +98,8 @@ + (id)itemWithText:(NSString*)text imageURL:(NSString*)imageURL defaultImage:(UI /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super initWithCoder:decoder]) { + self = [super initWithCoder:decoder]; + if (self) { self.imageURL = [decoder decodeObjectForKey:@"imageURL"]; } return self; diff --git a/src/Three20UI/Sources/TTTableImageItemCell.m b/src/Three20UI/Sources/TTTableImageItemCell.m index ecde7a2ed6..a49edb74bb 100644 --- a/src/Three20UI/Sources/TTTableImageItemCell.m +++ b/src/Three20UI/Sources/TTTableImageItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,8 +33,8 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kKeySpacing = 12; -static const CGFloat kDefaultImageSize = 50; +static const CGFloat kKeySpacing = 12.0f; +static const CGFloat kDefaultImageSize = 50.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -47,7 +47,8 @@ @implementation TTTableImageItemCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:style reuseIdentifier:identifier]) { + self = [super initWithStyle:style reuseIdentifier:identifier]; + if (self) { _imageView2 = [[TTImageView alloc] init]; [self.contentView addSubview:_imageView2]; } @@ -64,6 +65,23 @@ - (void)dealloc { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Private helpers + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (UIFont*)fontForImageItem:(id)imageItem { + if ([imageItem isKindOfClass:[TTTableRightImageItem class]]) { + return TTSTYLEVAR(tableSmallFont); + + } else { + return TTSTYLEVAR(tableFont); + } +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - @@ -85,6 +103,7 @@ + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { if (style && !CGSizeEqualToSize(style.size, CGSizeZero)) { imageWidth = style.size.width + kKeySpacing; imageHeight = style.size.height; + } else { imageWidth = image ? image.size.width + kKeySpacing @@ -96,7 +115,7 @@ + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { CGFloat maxWidth = tableView.width - (imageWidth + kTableCellHPadding*2 + kTableCellMargin*2); - CGSize textSize = [imageItem.text sizeWithFont:TTSTYLEVAR(tableSmallFont) + CGSize textSize = [imageItem.text sizeWithFont:[self fontForImageItem:imageItem] constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeTailTruncation]; @@ -129,22 +148,25 @@ - (void)layoutSubviews { ? image.size.height : (item.imageURL ? kDefaultImageSize : 0); - if (_imageView2.urlPath) { - CGFloat innerWidth = self.contentView.width - (kTableCellHPadding*2 + imageWidth + kKeySpacing); + if (_imageView2.urlPath || image) { + CGFloat innerWidth = self.contentView.width - (kTableCellHPadding*2 + + imageWidth + kKeySpacing); CGFloat innerHeight = self.contentView.height - kTableCellVPadding*2; - self.textLabel.frame = CGRectMake(kTableCellHPadding, kTableCellVPadding, innerWidth, innerHeight); + self.textLabel.frame = CGRectMake(kTableCellHPadding, kTableCellVPadding, + innerWidth, innerHeight); _imageView2.frame = CGRectMake(self.textLabel.right + kKeySpacing, floor(self.height/2 - imageHeight/2), imageWidth, imageHeight); } else { - self.textLabel.frame = CGRectInset(self.contentView.bounds, kTableCellHPadding, kTableCellVPadding); + self.textLabel.frame = CGRectInset(self.contentView.bounds, + kTableCellHPadding, kTableCellVPadding); _imageView2.frame = CGRectZero; } } else { - if (_imageView2.urlPath) { + if (_imageView2.urlPath || image) { CGFloat iconWidth = image ? image.size.width : (item.imageURL ? kDefaultImageSize : 0); @@ -168,12 +190,16 @@ - (void)layoutSubviews { _imageView2.frame = CGRectMake(kTableCellHPadding, floor(self.height/2 - iconHeight/2), iconWidth, iconHeight); - CGFloat innerWidth = self.contentView.width - (kTableCellHPadding*2 + iconWidth + kKeySpacing); + CGFloat innerWidth = self.contentView.width - (kTableCellHPadding*2 + + iconWidth + kKeySpacing); CGFloat innerHeight = self.contentView.height - kTableCellVPadding*2; - self.textLabel.frame = CGRectMake(kTableCellHPadding + iconWidth + kKeySpacing, kTableCellVPadding, + self.textLabel.frame = CGRectMake(kTableCellHPadding + iconWidth + kKeySpacing, + kTableCellVPadding, innerWidth, innerHeight); + } else { - self.textLabel.frame = CGRectInset(self.contentView.bounds, kTableCellHPadding, kTableCellVPadding); + self.textLabel.frame = CGRectInset(self.contentView.bounds, + kTableCellHPadding, kTableCellVPadding); _imageView2.frame = CGRectZero; } } @@ -206,12 +232,13 @@ - (void)setObject:(id)object { _imageView2.defaultImage = item.defaultImage; _imageView2.urlPath = item.imageURL; + self.textLabel.font = [[self class] fontForImageItem:item]; + if ([_item isKindOfClass:[TTTableRightImageItem class]]) { - self.textLabel.font = TTSTYLEVAR(tableSmallFont); self.textLabel.textAlignment = UITextAlignmentCenter; self.accessoryType = UITableViewCellAccessoryNone; + } else { - self.textLabel.font = TTSTYLEVAR(tableFont); self.textLabel.textAlignment = UITextAlignmentLeft; } } diff --git a/src/Three20UI/Sources/TTTableItem.m b/src/Three20UI/Sources/TTTableItem.m index b1e2e7a879..4e8d636187 100644 --- a/src/Three20UI/Sources/TTTableItem.m +++ b/src/Three20UI/Sources/TTTableItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -44,7 +44,8 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [self init]) { + self = [self init]; + if (self) { } return self; diff --git a/src/Three20UI/Sources/TTTableLink.m b/src/Three20UI/Sources/TTTableLink.m index 956edeb774..a93919711e 100644 --- a/src/Three20UI/Sources/TTTableLink.m +++ b/src/Three20UI/Sources/TTTableLink.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableLinkedItem.m b/src/Three20UI/Sources/TTTableLinkedItem.m index 43450cfa23..5a76c5d1de 100644 --- a/src/Three20UI/Sources/TTTableLinkedItem.m +++ b/src/Three20UI/Sources/TTTableLinkedItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -50,7 +50,8 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super initWithCoder:decoder]) { + self = [super initWithCoder:decoder]; + if (self) { self.URL = [decoder decodeObjectForKey:@"URL"]; self.accessoryURL = [decoder decodeObjectForKey:@"accessoryURL"]; } diff --git a/src/Three20UI/Sources/TTTableLinkedItemCell.m b/src/Three20UI/Sources/TTTableLinkedItemCell.m index 6b77b466a8..c373e599fc 100644 --- a/src/Three20UI/Sources/TTTableLinkedItemCell.m +++ b/src/Three20UI/Sources/TTTableLinkedItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -81,6 +81,10 @@ - (void)setObject:(id)object { self.selectionStyle = TTSTYLEVAR(tableSelectionStyle); + } else if (nil != item.delegate && nil != item.selector) { + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + self.selectionStyle = TTSTYLEVAR(tableSelectionStyle); + } else { self.accessoryType = UITableViewCellAccessoryNone; self.selectionStyle = UITableViewCellSelectionStyleNone; diff --git a/src/Three20UI/Sources/TTTableLongTextItem.m b/src/Three20UI/Sources/TTTableLongTextItem.m index f7b797876e..228349c77b 100644 --- a/src/Three20UI/Sources/TTTableLongTextItem.m +++ b/src/Three20UI/Sources/TTTableLongTextItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableMessageItem.m b/src/Three20UI/Sources/TTTableMessageItem.m index d765179f7a..68d925d251 100644 --- a/src/Three20UI/Sources/TTTableMessageItem.m +++ b/src/Three20UI/Sources/TTTableMessageItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -83,7 +83,8 @@ + (id)itemWithTitle:(NSString*)title caption:(NSString*)caption text:(NSString*) /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super initWithCoder:decoder]) { + self = [super initWithCoder:decoder]; + if (self) { self.title = [decoder decodeObjectForKey:@"title"]; self.caption = [decoder decodeObjectForKey:@"caption"]; self.timestamp = [decoder decodeObjectForKey:@"timestamp"]; diff --git a/src/Three20UI/Sources/TTTableMessageItemCell.m b/src/Three20UI/Sources/TTTableMessageItemCell.m index 748b3e1c8b..aff2bd6191 100644 --- a/src/Three20UI/Sources/TTTableMessageItemCell.m +++ b/src/Three20UI/Sources/TTTableMessageItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,8 +31,8 @@ #import "Three20Core/NSDateAdditions.h" static const NSInteger kMessageTextLineCount = 2; -static const CGFloat kDefaultMessageImageWidth = 34; -static const CGFloat kDefaultMessageImageHeight = 34; +static const CGFloat kDefaultMessageImageWidth = 34.0f; +static const CGFloat kDefaultMessageImageHeight = 34.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -43,10 +43,12 @@ @implementation TTTableMessageItemCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]) { + self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]; + if (self) { self.textLabel.font = TTSTYLEVAR(font); self.textLabel.textColor = TTSTYLEVAR(textColor); self.textLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.textLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); self.textLabel.textAlignment = UITextAlignmentLeft; self.textLabel.lineBreakMode = UILineBreakModeTailTruncation; self.textLabel.adjustsFontSizeToFitWidth = YES; @@ -55,6 +57,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)ident self.detailTextLabel.font = TTSTYLEVAR(font); self.detailTextLabel.textColor = TTSTYLEVAR(tableSubTextColor); self.detailTextLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.detailTextLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); self.detailTextLabel.textAlignment = UITextAlignmentLeft; self.detailTextLabel.contentMode = UIViewContentModeTop; self.detailTextLabel.lineBreakMode = UILineBreakModeTailTruncation; @@ -101,6 +104,7 @@ - (void)prepareForReuse { [_imageView2 unsetImage]; _titleLabel.text = nil; _timestampLabel.text = nil; + self.captionLabel.text = nil; } @@ -108,11 +112,12 @@ - (void)prepareForReuse { - (void)layoutSubviews { [super layoutSubviews]; - CGFloat left = 0; + CGFloat left = 0.0f; if (_imageView2) { _imageView2.frame = CGRectMake(kTableCellSmallMargin, kTableCellSmallMargin, kDefaultMessageImageWidth, kDefaultMessageImageHeight); left += kTableCellSmallMargin + kDefaultMessageImageHeight + kTableCellSmallMargin; + } else { left = kTableCellMargin; } @@ -123,6 +128,7 @@ - (void)layoutSubviews { if (_titleLabel.text.length) { _titleLabel.frame = CGRectMake(left, top, width, _titleLabel.font.ttLineHeight); top += _titleLabel.height; + } else { _titleLabel.frame = CGRectZero; } @@ -130,6 +136,7 @@ - (void)layoutSubviews { if (self.captionLabel.text.length) { self.captionLabel.frame = CGRectMake(left, top, width, self.captionLabel.font.ttLineHeight); top += self.captionLabel.height; + } else { self.captionLabel.frame = CGRectZero; } @@ -137,6 +144,7 @@ - (void)layoutSubviews { if (self.detailTextLabel.text.length) { CGFloat textHeight = self.detailTextLabel.font.ttLineHeight * kMessageTextLineCount; self.detailTextLabel.frame = CGRectMake(left, top, width, textHeight); + } else { self.detailTextLabel.frame = CGRectZero; } @@ -147,8 +155,9 @@ - (void)layoutSubviews { _timestampLabel.left = self.contentView.width - (_timestampLabel.width + kTableCellSmallMargin); _timestampLabel.top = _titleLabel.top; _titleLabel.width -= _timestampLabel.width + kTableCellSmallMargin*2; + } else { - _titleLabel.frame = CGRectZero; + _timestampLabel.frame = CGRectZero; } } diff --git a/src/Three20UI/Sources/TTTableMoreButton.m b/src/Three20UI/Sources/TTTableMoreButton.m index cbffe50288..f0dddb5d39 100644 --- a/src/Three20UI/Sources/TTTableMoreButton.m +++ b/src/Three20UI/Sources/TTTableMoreButton.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableMoreButtonCell.m b/src/Three20UI/Sources/TTTableMoreButtonCell.m index 802c95426b..5c04863b6d 100644 --- a/src/Three20UI/Sources/TTTableMoreButtonCell.m +++ b/src/Three20UI/Sources/TTTableMoreButtonCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kMoreButtonMargin = 40; +static const CGFloat kMoreButtonMargin = 40.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -43,8 +43,10 @@ @implementation TTTableMoreButtonCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier]) { + self = [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier]; + if (self) { self.textLabel.font = TTSTYLEVAR(tableSmallFont); + self.textLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); } return self; @@ -89,14 +91,17 @@ + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { - (void)layoutSubviews { [super layoutSubviews]; - _activityIndicatorView.left = kMoreButtonMargin - (_activityIndicatorView.width + kTableCellSmallMargin); + _activityIndicatorView.left = kMoreButtonMargin - (_activityIndicatorView.width + + kTableCellSmallMargin); _activityIndicatorView.top = floor(self.contentView.height/2 - _activityIndicatorView.height/2); self.textLabel.frame = CGRectMake(kMoreButtonMargin, self.textLabel.top, - self.contentView.width - (kMoreButtonMargin + kTableCellSmallMargin), + self.contentView.width - (kMoreButtonMargin + + kTableCellSmallMargin), self.textLabel.height); self.detailTextLabel.frame = CGRectMake(kMoreButtonMargin, self.detailTextLabel.top, - self.contentView.width - (kMoreButtonMargin + kTableCellSmallMargin), + self.contentView.width - (kMoreButtonMargin + + kTableCellSmallMargin), self.detailTextLabel.height); } @@ -118,6 +123,7 @@ - (void)setObject:(id)object { self.textLabel.textColor = TTSTYLEVAR(moreLinkTextColor); self.selectionStyle = TTSTYLEVAR(tableSelectionStyle); + self.accessoryType = UITableViewCellAccessoryNone; } } diff --git a/src/Three20UI/Sources/TTTableRightCaptionItem.m b/src/Three20UI/Sources/TTTableRightCaptionItem.m index 22ac8f7698..a13b270865 100644 --- a/src/Three20UI/Sources/TTTableRightCaptionItem.m +++ b/src/Three20UI/Sources/TTTableRightCaptionItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableRightCaptionItemCell.m b/src/Three20UI/Sources/TTTableRightCaptionItemCell.m index dbe1619260..75b9b0cfc4 100644 --- a/src/Three20UI/Sources/TTTableRightCaptionItemCell.m +++ b/src/Three20UI/Sources/TTTableRightCaptionItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,12 +35,15 @@ @implementation TTTableRightCaptionItemCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]) { + self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]; + if (self) { self.textLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.textLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); self.textLabel.lineBreakMode = UILineBreakModeWordWrap; self.textLabel.numberOfLines = 0; self.detailTextLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.detailTextLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); // XXXjoe TODO } diff --git a/src/Three20UI/Sources/TTTableRightImageItem.m b/src/Three20UI/Sources/TTTableRightImageItem.m index c6befa3781..d74d13b2e5 100644 --- a/src/Three20UI/Sources/TTTableRightImageItem.m +++ b/src/Three20UI/Sources/TTTableRightImageItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableSection.m b/src/Three20UI/Sources/TTTableSection.m new file mode 100644 index 0000000000..7c42c0fc85 --- /dev/null +++ b/src/Three20UI/Sources/TTTableSection.m @@ -0,0 +1,51 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UI/TTTableSection.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTTableSection + +@synthesize headerTitle = _headerTitle; +@synthesize footerTitle = _footerTitle; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (id)sectionWithHeaderTitle:(NSString*)headerTitle footerTitle:(NSString*)footerTitle { + TTTableSection* item = [[[self alloc] init] autorelease]; + item.headerTitle = headerTitle; + item.footerTitle = footerTitle; + return item; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)dealloc { + TT_RELEASE_SAFELY(_headerTitle); + TT_RELEASE_SAFELY(_footerTitle); + + [super dealloc]; +} + + +@end + diff --git a/src/Three20UI/Sources/TTTableSettingsItem.m b/src/Three20UI/Sources/TTTableSettingsItem.m new file mode 100644 index 0000000000..5e721efa54 --- /dev/null +++ b/src/Three20UI/Sources/TTTableSettingsItem.m @@ -0,0 +1,26 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UI/TTTableSettingsItem.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTTableSettingsItem + +@end + diff --git a/src/Three20UI/Sources/TTTableSettingsItemCell.m b/src/Three20UI/Sources/TTTableSettingsItemCell.m new file mode 100644 index 0000000000..05efe903e4 --- /dev/null +++ b/src/Three20UI/Sources/TTTableSettingsItemCell.m @@ -0,0 +1,69 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UI/TTTableSettingsItemCell.h" + +// UI +#import "Three20UI/TTTableSettingsItem.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTTableSettingsItemCell + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { + self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier]; + if (self) { + + } + + return self; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark TTTableViewCell + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setObject:(id)object { + if (_item != object) { + [super setObject:object]; + + TTTableSettingsItem* item = object; + self.textLabel.text = item.caption; + self.detailTextLabel.text = item.text; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Public + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UILabel*)captionLabel { + return self.textLabel; +} + + +@end diff --git a/src/Three20UI/Sources/TTTableStyledTextItem.m b/src/Three20UI/Sources/TTTableStyledTextItem.m index 298753c1c1..591c633ba7 100644 --- a/src/Three20UI/Sources/TTTableStyledTextItem.m +++ b/src/Three20UI/Sources/TTTableStyledTextItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,7 +32,8 @@ @implementation TTTableStyledTextItem /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { _margin = UIEdgeInsetsZero; _padding = UIEdgeInsetsMake(6, 6, 6, 6); } @@ -90,7 +91,8 @@ + (id)itemWithText:(TTStyledText*)text URL:(NSString*)URL accessoryURL:(NSString /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super initWithCoder:decoder]) { + self = [super initWithCoder:decoder]; + if (self) { self.text = [decoder decodeObjectForKey:@"text"]; } return self; diff --git a/src/Three20UI/Sources/TTTableSubtextItem.m b/src/Three20UI/Sources/TTTableSubtextItem.m index 616a4f1f52..6f560b8f2b 100644 --- a/src/Three20UI/Sources/TTTableSubtextItem.m +++ b/src/Three20UI/Sources/TTTableSubtextItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableSubtextItemCell.m b/src/Three20UI/Sources/TTTableSubtextItemCell.m index 7ca97485f1..4506a28b77 100644 --- a/src/Three20UI/Sources/TTTableSubtextItemCell.m +++ b/src/Three20UI/Sources/TTTableSubtextItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #import "Three20UI/TTTableSubtextItemCell.h" // UI -#import "Three20UI/TTTableCaptionItem.h" +#import "Three20UI/TTTableSubtextItem.h" +#import "Three20UI/UITableViewAdditions.h" #import "Three20UI/UIViewAdditions.h" // Style @@ -33,15 +34,18 @@ @implementation TTTableSubtextItemCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]) { + self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]; + if (self) { self.detailTextLabel.font = TTSTYLEVAR(tableFont); self.detailTextLabel.textColor = TTSTYLEVAR(textColor); self.detailTextLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.detailTextLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); self.detailTextLabel.adjustsFontSizeToFitWidth = YES; self.textLabel.font = TTSTYLEVAR(font); self.textLabel.textColor = TTSTYLEVAR(tableSubTextColor); self.textLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.textLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); self.textLabel.textAlignment = UITextAlignmentLeft; self.textLabel.contentMode = UIViewContentModeTop; self.textLabel.lineBreakMode = UILineBreakModeWordWrap; @@ -60,9 +64,9 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)ident /////////////////////////////////////////////////////////////////////////////////////////////////// + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { - TTTableCaptionItem* item = object; + TTTableSubtextItem* item = object; - CGFloat width = tableView.width - kTableCellHPadding*2; + CGFloat width = tableView.width - [tableView tableCellMargin]*2 - kTableCellHPadding*2; CGSize detailTextSize = [item.text sizeWithFont:TTSTYLEVAR(tableFont) constrainedToSize:CGSizeMake(width, CGFLOAT_MAX) @@ -120,7 +124,7 @@ - (void)setObject:(id)object { if (_item != object) { [super setObject:object]; - TTTableCaptionItem* item = object; + TTTableSubtextItem* item = object; self.textLabel.text = item.caption; self.detailTextLabel.text = item.text; } diff --git a/src/Three20UI/Sources/TTTableSubtitleItem.m b/src/Three20UI/Sources/TTTableSubtitleItem.m index 06df52834f..295f2b6353 100644 --- a/src/Three20UI/Sources/TTTableSubtitleItem.m +++ b/src/Three20UI/Sources/TTTableSubtitleItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -111,7 +111,8 @@ + (id)itemWithText:(NSString*)text subtitle:(NSString*)subtitle imageURL:(NSStri /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super initWithCoder:decoder]) { + self = [super initWithCoder:decoder]; + if (self) { self.subtitle = [decoder decodeObjectForKey:@"subtitle"]; self.imageURL = [decoder decodeObjectForKey:@"imageURL"]; } diff --git a/src/Three20UI/Sources/TTTableSubtitleItemCell.m b/src/Three20UI/Sources/TTTableSubtitleItemCell.m index 8f4f9deed3..a606fa49df 100644 --- a/src/Three20UI/Sources/TTTableSubtitleItemCell.m +++ b/src/Three20UI/Sources/TTTableSubtitleItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,10 +38,12 @@ @implementation TTTableSubtitleItemCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]) { + self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]; + if (self) { self.textLabel.font = TTSTYLEVAR(tableFont); self.textLabel.textColor = TTSTYLEVAR(textColor); self.textLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.textLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); self.textLabel.textAlignment = UITextAlignmentLeft; self.textLabel.lineBreakMode = UILineBreakModeTailTruncation; self.textLabel.adjustsFontSizeToFitWidth = YES; @@ -49,6 +51,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)ident self.detailTextLabel.font = TTSTYLEVAR(font); self.detailTextLabel.textColor = TTSTYLEVAR(tableSubTextColor); self.detailTextLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); + self.detailTextLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); self.detailTextLabel.textAlignment = UITextAlignmentLeft; self.detailTextLabel.contentMode = UIViewContentModeTop; self.detailTextLabel.lineBreakMode = UILineBreakModeTailTruncation; @@ -91,6 +94,11 @@ + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { #pragma mark - #pragma mark UIView +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)prepareForReuse { + [super prepareForReuse]; + [_imageView2 unsetImage]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)layoutSubviews { @@ -98,11 +106,12 @@ - (void)layoutSubviews { CGFloat height = self.contentView.height; CGFloat width = self.contentView.width - (height + kTableCellSmallMargin); - CGFloat left = 0; + CGFloat left = 0.0f; if (_imageView2) { _imageView2.frame = CGRectMake(0, 0, height, height); left = _imageView2.right + kTableCellSmallMargin; + } else { left = kTableCellHPadding; } diff --git a/src/Three20UI/Sources/TTTableSummaryItem.m b/src/Three20UI/Sources/TTTableSummaryItem.m index 25bbca74f9..91a1d15680 100644 --- a/src/Three20UI/Sources/TTTableSummaryItem.m +++ b/src/Three20UI/Sources/TTTableSummaryItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableTextItem.m b/src/Three20UI/Sources/TTTableTextItem.m index 63c3feef0a..7c841009e6 100644 --- a/src/Three20UI/Sources/TTTableTextItem.m +++ b/src/Three20UI/Sources/TTTableTextItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -87,7 +87,8 @@ + (id)itemWithText:(NSString*)text delegate:(id)delegate selector:(SEL)selector /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super initWithCoder:decoder]) { + self = [super initWithCoder:decoder]; + if (self) { self.text = [decoder decodeObjectForKey:@"text"]; } return self; diff --git a/src/Three20UI/Sources/TTTableTextItemCell.m b/src/Three20UI/Sources/TTTableTextItemCell.m index 58a2bd7c96..85ca58fac7 100644 --- a/src/Three20UI/Sources/TTTableTextItemCell.m +++ b/src/Three20UI/Sources/TTTableTextItemCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,8 +32,8 @@ #import "Three20Style/TTDefaultStyleSheet.h" #import "Three20Style/TTGlobalStyle.h" -static const CGFloat kMaxLabelHeight = 2000; - +static const CGFloat kMaxLabelHeight = 2000.0f; +static const UILineBreakMode kLineBreakMode = UILineBreakModeWordWrap; /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -43,9 +43,10 @@ @implementation TTTableTextItemCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:style reuseIdentifier:identifier]) { + self = [super initWithStyle:style reuseIdentifier:identifier]; + if (self) { self.textLabel.highlightedTextColor = TTSTYLEVAR(highlightedTextColor); - self.textLabel.lineBreakMode = UILineBreakModeWordWrap; + self.textLabel.lineBreakMode = kLineBreakMode; self.textLabel.numberOfLines = 0; } @@ -63,8 +64,10 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)ident + (UIFont*)textFontForItem:(TTTableTextItem*)item { if ([item isKindOfClass:[TTTableLongTextItem class]]) { return TTSTYLEVAR(font); + } else if ([item isKindOfClass:[TTTableGrayTextItem class]]) { return TTSTYLEVAR(font); + } else { return TTSTYLEVAR(tableFont); } @@ -85,7 +88,7 @@ + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { UIFont* font = [self textFontForItem:item]; CGSize size = [item.text sizeWithFont:font constrainedToSize:CGSizeMake(width, CGFLOAT_MAX) - lineBreakMode:UILineBreakModeTailTruncation]; + lineBreakMode:kLineBreakMode]; if (size.height > kMaxLabelHeight) { size.height = kMaxLabelHeight; } @@ -122,6 +125,7 @@ - (void)setObject:(id)object { TTTableTextItem* item = object; self.textLabel.text = item.text; + self.textLabel.backgroundColor = TTSTYLEVAR(backgroundTextColor); if ([object isKindOfClass:[TTTableButton class]]) { self.textLabel.font = TTSTYLEVAR(tableButtonFont); diff --git a/src/Three20UI/Sources/TTTableView.m b/src/Three20UI/Sources/TTTableView.m index 8f08e0ca9d..f5ec66b754 100644 --- a/src/Three20UI/Sources/TTTableView.m +++ b/src/Three20UI/Sources/TTTableView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,9 @@ #import "Three20UI/TTStyledTextLabel.h" #import "Three20UI/UIViewAdditions.h" +// UICommon +#import "Three20UICommon/UIWindowAdditions.h" + // Style #import "Three20Style/TTStyledNode.h" #import "Three20Style/TTStyledButtonNode.h" @@ -29,10 +32,10 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kShadowHeight = 20.0; -static const CGFloat kShadowInverseHeight = 10.0; +static const CGFloat kShadowHeight = 20.0f; +static const CGFloat kShadowInverseHeight = 10.0f; -static const CGFloat kCancelHighlightThreshold = 4; +static const CGFloat kCancelHighlightThreshold = 4.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -47,7 +50,8 @@ @implementation TTTableView /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style { - if (self = [super initWithFrame:frame style:style]) { + self = [super initWithFrame:frame style:style]; + if (self) { _highlightStartPoint = CGPointZero; } @@ -88,6 +92,7 @@ - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { // CGPoint point = [touch locationInView:_menuView]; // if (point.y < 0 || point.y > _menuView.height) { // [self hideMenu:YES]; + // } else { // UIView* hit = [_menuView hitTest:point withEvent:event]; // if (![hit isKindOfClass:[UIControl class]]) { @@ -97,6 +102,15 @@ - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { // } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + [super touchesMoved:touches withEvent:event]; + + if ([self.delegate respondsToSelector:@selector(tableView:touchesMoved:withEvent:)]) { + id delegate = (id)self.delegate; + [delegate tableView:self touchesMoved:touches withEvent:event]; + } +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { @@ -113,10 +127,10 @@ - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { // the node implementation. One potential fix would be to provide some protocol for these // nodes to converse with. if ([element isKindOfClass:[TTStyledLinkNode class]]) { - TTOpenURL([(TTStyledLinkNode*)element URL]); + TTOpenURLFromView([(TTStyledLinkNode*)element URL], self); } else if ([element isKindOfClass:[TTStyledButtonNode class]]) { - TTOpenURL([(TTStyledButtonNode*)element URL]); + TTOpenURLFromView([(TTStyledButtonNode*)element URL], self); } else { @@ -174,9 +188,17 @@ - (void)setContentOffset:(CGPoint)point { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)reloadData { + // -[UITableView reloadData] takes away first responder status if the first responder is a + // subview, so remember it and then restore it afterward to avoid awkward keyboard disappearance + UIResponder* firstResponder = [self.window findFirstResponderInView:self]; + CGFloat y = self.contentOffset.y; [super reloadData]; + if (nil != firstResponder) { + [firstResponder becomeFirstResponder]; + } + if (_highlightedLabel) { self.highlightedLabel = nil; } @@ -236,7 +258,9 @@ - (void)layoutSubviews { } else if (![[self.layer.sublayers objectAtIndex:0] isEqual:_originShadow]) { [_originShadow removeFromSuperlayer]; - [self.layer insertSublayer:_originShadow atIndex:0]; + + _originShadow = [self shadowAsInverse:NO]; + [self.layer insertSublayer:_originShadow atIndex:0]; } [CATransaction begin]; diff --git a/src/Three20UI/Sources/TTTableViewCell.m b/src/Three20UI/Sources/TTTableViewCell.m index d8fe1ec041..0a36fd15e2 100644 --- a/src/Three20UI/Sources/TTTableViewCell.m +++ b/src/Three20UI/Sources/TTTableViewCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,11 +19,11 @@ // UICommon #import "Three20UICommon/TTGlobalUICommon.h" -const CGFloat kTableCellSmallMargin = 6; -const CGFloat kTableCellSpacing = 8; -const CGFloat kTableCellMargin = 10; -const CGFloat kTableCellHPadding = 10; -const CGFloat kTableCellVPadding = 10; +const CGFloat kTableCellSmallMargin = 6.0f; +const CGFloat kTableCellSpacing = 8.0f; +const CGFloat kTableCellMargin = 10.0f; +const CGFloat kTableCellHPadding = 10.0f; +const CGFloat kTableCellVPadding = 10.0f; const NSInteger kTableMessageTextLineCount = 2; @@ -49,6 +49,8 @@ + (CGFloat)tableView:(UITableView*)tableView rowHeightForObject:(id)object { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)prepareForReuse { self.object = nil; + self.textLabel.text = nil; + self.detailTextLabel.text = nil; [super prepareForReuse]; } diff --git a/src/Three20UI/Sources/TTTableViewController.m b/src/Three20UI/Sources/TTTableViewController.m index 342629a96c..428de39e4c 100644 --- a/src/Three20UI/Sources/TTTableViewController.m +++ b/src/Three20UI/Sources/TTTableViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -45,8 +45,6 @@ #import "Three20Core/TTDebug.h" #import "Three20Core/TTDebugFlags.h" -static const CGFloat kBannerViewHeight = 22; - /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -63,14 +61,17 @@ @implementation TTTableViewController @synthesize tableViewStyle = _tableViewStyle; @synthesize variableHeightRows = _variableHeightRows; @synthesize showTableShadows = _showTableShadows; +@synthesize clearsSelectionOnViewWillAppear = _clearsSelectionOnViewWillAppear; @synthesize dataSource = _dataSource; /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { _lastInterfaceOrientation = self.interfaceOrientation; _tableViewStyle = UITableViewStylePlain; + _clearsSelectionOnViewWillAppear = YES; } return self; @@ -79,7 +80,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewStyle)style { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { _tableViewStyle = style; } @@ -142,7 +144,7 @@ - (void)addToOverlayView:(UIView*)view { _tableOverlayView = [[UIView alloc] initWithFrame:frame]; _tableOverlayView.autoresizesSubviews = YES; _tableOverlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth - | UIViewAutoresizingFlexibleBottomMargin; + | UIViewAutoresizingFlexibleHeight; NSInteger tableIndex = [_tableView.superview.subviews indexOfObject:_tableView]; if (tableIndex != NSNotFound) { [_tableView.superview addSubview:_tableOverlayView]; @@ -163,6 +165,14 @@ - (void)resetOverlayView { } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)addSubviewOverTableView:(UIView*)view { + NSInteger tableIndex = [_tableView.superview.subviews + indexOfObject:_tableView]; + if (NSNotFound != tableIndex) { + [_tableView.superview addSubview:view]; + } +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)layoutOverlayView { @@ -218,7 +228,16 @@ - (void)hideMenuAnimationDidStop:(NSString*)animationID finished:(NSNumber*)fini /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)loadView { [super loadView]; - self.tableView; + [self tableView]; + + // If this view was unloaded and is now being reloaded, and it was previously + // showing a table banner, then redisplay that banner now. + if (_tableBannerView) { + UIView* savedTableBannerView = [_tableBannerView retain]; + [self setTableBannerView:nil animated:NO]; + [self setTableBannerView:savedTableBannerView animated:NO]; + [savedTableBannerView release]; + } } @@ -229,8 +248,6 @@ - (void)viewDidUnload { _tableView.dataSource = nil; TT_RELEASE_SAFELY(_tableDelegate); TT_RELEASE_SAFELY(_tableView); - [_tableBannerView removeFromSuperview]; - TT_RELEASE_SAFELY(_tableBannerView); [_tableOverlayView removeFromSuperview]; TT_RELEASE_SAFELY(_tableOverlayView); [_loadingView removeFromSuperview]; @@ -243,6 +260,9 @@ - (void)viewDidUnload { TT_RELEASE_SAFELY(_menuView); [_menuCell removeFromSuperview]; TT_RELEASE_SAFELY(_menuCell); + + // Do not release _tableBannerView, because we have no way to recreate it on demand if + // this view gets reloaded. } @@ -253,13 +273,25 @@ - (void)viewWillAppear:(BOOL)animated { if (_lastInterfaceOrientation != self.interfaceOrientation) { _lastInterfaceOrientation = self.interfaceOrientation; [_tableView reloadData]; + } else if ([_tableView isKindOfClass:[TTTableView class]]) { TTTableView* tableView = (TTTableView*)_tableView; tableView.highlightedLabel = nil; tableView.showShadows = _showTableShadows; } - [_tableView deselectRowAtIndexPath:[_tableView indexPathForSelectedRow] animated:NO]; + if (_clearsSelectionOnViewWillAppear) { + [_tableView deselectRowAtIndexPath:[_tableView indexPathForSelectedRow] animated:animated]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + if (_flags.isShowingModel) { + [_tableView flashScrollIndicators]; + } } @@ -295,9 +327,11 @@ - (BOOL)persistView:(NSMutableDictionary*)state { - (void)restoreView:(NSDictionary*)state { CGFloat scrollY = [[state objectForKey:@"scrollOffsetY"] floatValue]; if (scrollY) { - CGFloat maxY = _tableView.contentSize.height - _tableView.height; + //set to 0 if contentSize is smaller than the tableView.height + CGFloat maxY = MAX(0, _tableView.contentSize.height - _tableView.height); if (scrollY <= maxY) { _tableView.contentOffset = CGPointMake(0, scrollY); + } else { _tableView.contentOffset = CGPointMake(0, maxY); } @@ -377,12 +411,15 @@ - (BOOL)canShowModel { NSInteger numberOfSections = [_dataSource numberOfSectionsInTableView:_tableView]; if (!numberOfSections) { return NO; + } else if (numberOfSections == 1) { NSInteger numberOfRows = [_dataSource tableView:_tableView numberOfRowsInSection:0]; return numberOfRows > 0; + } else { return YES; } + } else { NSInteger numberOfRows = [_dataSource tableView:_tableView numberOfRowsInSection:0]; return numberOfRows > 0; @@ -400,7 +437,7 @@ - (void)didLoadModel:(BOOL)firstTime { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)didShowModel:(BOOL)firstTime { [super didShowModel:firstTime]; - if (firstTime) { + if (![self isViewAppearing] && firstTime) { [_tableView flashScrollIndicators]; } } @@ -412,6 +449,7 @@ - (void)showModel:(BOOL)show { if (show) { [self updateTableDelegate]; _tableView.dataSource = _dataSource; + } else { _tableView.dataSource = nil; } @@ -427,13 +465,15 @@ - (void)showLoading:(BOOL)show { ? [_dataSource titleForLoading:NO] : [self defaultTitleForLoading]; if (title.length) { - TTActivityLabel* label = [[[TTActivityLabel alloc] initWithStyle:TTActivityLabelStyleWhiteBox] - autorelease]; + TTActivityLabel* label = + [[[TTActivityLabel alloc] initWithStyle:TTActivityLabelStyleWhiteBox] + autorelease]; label.text = title; label.backgroundColor = _tableView.backgroundColor; self.loadingView = label; } } + } else { self.loadingView = nil; } @@ -451,14 +491,23 @@ - (void)showError:(BOOL)show { TTErrorView* errorView = [[[TTErrorView alloc] initWithTitle:title subtitle:subtitle image:image] autorelease]; + if ([_dataSource reloadButtonForEmpty]) { + [errorView addReloadButton]; + [errorView.reloadButton addTarget:self + action:@selector(reload) + forControlEvents:UIControlEventTouchUpInside]; + } errorView.backgroundColor = _tableView.backgroundColor; + self.errorView = errorView; + } else { self.errorView = nil; } _tableView.dataSource = nil; [_tableView reloadData]; } + } else { self.errorView = nil; } @@ -477,11 +526,13 @@ - (void)showEmpty:(BOOL)show { image:image] autorelease]; errorView.backgroundColor = _tableView.backgroundColor; self.emptyView = errorView; + } else { self.emptyView = nil; } _tableView.dataSource = nil; [_tableView reloadData]; + } else { self.emptyView = nil; } @@ -497,26 +548,30 @@ - (void)showEmpty:(BOOL)show { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)model:(id)model didUpdateObject:(id)object atIndexPath:(NSIndexPath*)indexPath { if (model == _model) { - if (_isViewAppearing && _flags.isShowingModel) { + if (_flags.isShowingModel) { if ([_dataSource respondsToSelector:@selector(tableView:willUpdateObject:atIndexPath:)]) { NSIndexPath* newIndexPath = [_dataSource tableView:_tableView willUpdateObject:object atIndexPath:indexPath]; if (newIndexPath) { if (newIndexPath.length == 1) { - TTDCONDITIONLOG(TTDFLAG_TABLEVIEWMODIFICATIONS, @"UPDATING SECTION AT %@", newIndexPath); + TTDCONDITIONLOG(TTDFLAG_TABLEVIEWMODIFICATIONS, + @"UPDATING SECTION AT %@", newIndexPath); NSInteger sectionIndex = [newIndexPath indexAtPosition:0]; [_tableView reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationTop]; + } else if (newIndexPath.length == 2) { TTDCONDITIONLOG(TTDFLAG_TABLEVIEWMODIFICATIONS, @"UPDATING ROW AT %@", newIndexPath); [_tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationTop]; } [self invalidateView]; + } else { [_tableView reloadData]; } } + } else { [self refresh]; } @@ -527,29 +582,30 @@ - (void)model:(id)model didUpdateObject:(id)object atIndexPath:(NSIndex /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)model:(id)model didInsertObject:(id)object atIndexPath:(NSIndexPath*)indexPath { if (model == _model) { - if (_isViewAppearing && _flags.isShowingModel) { + if (_flags.isShowingModel) { if ([_dataSource respondsToSelector:@selector(tableView:willInsertObject:atIndexPath:)]) { NSIndexPath* newIndexPath = [_dataSource tableView:_tableView willInsertObject:object atIndexPath:indexPath]; if (newIndexPath) { if (newIndexPath.length == 1) { - TTDCONDITIONLOG(TTDFLAG_TABLEVIEWMODIFICATIONS, @"INSERTING SECTION AT %@", newIndexPath); + TTDCONDITIONLOG(TTDFLAG_TABLEVIEWMODIFICATIONS, + @"INSERTING SECTION AT %@", newIndexPath); NSInteger sectionIndex = [newIndexPath indexAtPosition:0]; [_tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationTop]; + } else if (newIndexPath.length == 2) { TTDCONDITIONLOG(TTDFLAG_TABLEVIEWMODIFICATIONS, @"INSERTING ROW AT %@", newIndexPath); [_tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationTop]; - - [_tableView scrollToRowAtIndexPath:newIndexPath - atScrollPosition:UITableViewScrollPositionNone animated:NO]; } [self invalidateView]; + } else { [_tableView reloadData]; } } + } else { [self refresh]; } @@ -560,26 +616,30 @@ - (void)model:(id)model didInsertObject:(id)object atIndexPath:(NSIndex /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)model:(id)model didDeleteObject:(id)object atIndexPath:(NSIndexPath*)indexPath { if (model == _model) { - if (_isViewAppearing && _flags.isShowingModel) { + if (_flags.isShowingModel) { if ([_dataSource respondsToSelector:@selector(tableView:willRemoveObject:atIndexPath:)]) { NSIndexPath* newIndexPath = [_dataSource tableView:_tableView willRemoveObject:object atIndexPath:indexPath]; if (newIndexPath) { if (newIndexPath.length == 1) { - TTDCONDITIONLOG(TTDFLAG_TABLEVIEWMODIFICATIONS, @"DELETING SECTION AT %@", newIndexPath); + TTDCONDITIONLOG(TTDFLAG_TABLEVIEWMODIFICATIONS, + @"DELETING SECTION AT %@", newIndexPath); NSInteger sectionIndex = [newIndexPath indexAtPosition:0]; [_tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationLeft]; + } else if (newIndexPath.length == 2) { TTDCONDITIONLOG(TTDFLAG_TABLEVIEWMODIFICATIONS, @"DELETING ROW AT %@", newIndexPath); [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationLeft]; } [self invalidateView]; + } else { [_tableView reloadData]; } } + } else { [self refresh]; } @@ -600,6 +660,17 @@ - (UITableView*)tableView { _tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + UIColor* separatorColor = _tableViewStyle == UITableViewStyleGrouped + ? TTSTYLEVAR(tableGroupedCellSeparatorColor) + : TTSTYLEVAR(tablePlainCellSeparatorColor); + if (separatorColor) { + _tableView.separatorColor = separatorColor; + } + + _tableView.separatorStyle = _tableViewStyle == UITableViewStyleGrouped + ? TTSTYLEVAR(tableGroupedCellSeparatorStyle) + : TTSTYLEVAR(tablePlainCellSeparatorStyle); + UIColor* backgroundColor = _tableViewStyle == UITableViewStyleGrouped ? TTSTYLEVAR(tableGroupedBackgroundColor) : TTSTYLEVAR(tablePlainBackgroundColor); @@ -634,11 +705,11 @@ - (void)setTableBannerView:(UIView*)tableBannerView { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setTableBannerView:(UIView*)tableBannerView animated:(BOOL)animated { - TT_INVALIDATE_TIMER(_bannerTimer); if (tableBannerView != _tableBannerView) { if (_tableBannerView) { if (animated) { [self fadeOutView:_tableBannerView]; + } else { [_tableBannerView removeFromSuperview]; } @@ -648,18 +719,26 @@ - (void)setTableBannerView:(UIView*)tableBannerView animated:(BOOL)animated { _tableBannerView = [tableBannerView retain]; if (_tableBannerView) { + self.tableView.contentInset = UIEdgeInsetsMake(0, 0, TTSTYLEVAR(tableBannerViewHeight), 0); + self.tableView.scrollIndicatorInsets = self.tableView.contentInset; _tableBannerView.frame = [self rectForBannerView]; - _tableBannerView.userInteractionEnabled = NO; - [self addToOverlayView:_tableBannerView]; + _tableBannerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth + | UIViewAutoresizingFlexibleTopMargin); + [self addSubviewOverTableView:_tableBannerView]; + if (animated) { - _tableBannerView.top += kBannerViewHeight; + _tableBannerView.top += TTSTYLEVAR(tableBannerViewHeight); [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:TT_TRANSITION_DURATION]; [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; - _tableBannerView.top -= kBannerViewHeight; + _tableBannerView.top -= TTSTYLEVAR(tableBannerViewHeight); [UIView commitAnimations]; } + + } else { + self.tableView.contentInset = UIEdgeInsetsZero; + self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero; } } } @@ -671,6 +750,7 @@ - (void)setTableOverlayView:(UIView*)tableOverlayView animated:(BOOL)animated { if (_tableOverlayView) { if (animated) { [self fadeOutView:_tableOverlayView]; + } else { [_tableOverlayView removeFromSuperview]; } @@ -723,6 +803,7 @@ - (void)setLoadingView:(UIView*)view { _loadingView = [view retain]; if (_loadingView) { [self addToOverlayView:_loadingView]; + } else { [self resetOverlayView]; } @@ -741,6 +822,7 @@ - (void)setErrorView:(UIView*)view { if (_errorView) { [self addToOverlayView:_errorView]; + } else { [self resetOverlayView]; } @@ -758,6 +840,7 @@ - (void)setEmptyView:(UIView*)view { _emptyView = [view retain]; if (_emptyView) { [self addToOverlayView:_emptyView]; + } else { [self resetOverlayView]; } @@ -769,6 +852,7 @@ - (void)setEmptyView:(UIView*)view { - (id)createDelegate { if (_variableHeightRows) { return [[[TTTableViewVarHeightDelegate alloc] initWithController:self] autorelease]; + } else { return [[[TTTableViewDelegate alloc] initWithController:self] autorelease]; } @@ -822,6 +906,7 @@ - (void)hideMenu:(BOOL)animated { if (animated) { [UIView commitAnimations]; + } else { [_menuView removeFromSuperview]; } @@ -837,7 +922,7 @@ - (void)didSelectObject:(id)object atIndexPath:(NSIndexPath*)indexPath { if ([object respondsToSelector:@selector(URLValue)]) { NSString* URL = [object URLValue]; if (URL) { - TTOpenURL(URL); + TTOpenURLFromView(URL, self.view); } } } @@ -869,10 +954,23 @@ - (CGRect)rectForOverlayView { /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGRect)rectForBannerView { CGRect tableFrame = [_tableView frameWithKeyboardSubtracted:0]; + const CGFloat bannerViewHeight = TTSTYLEVAR(tableBannerViewHeight); return CGRectMake(tableFrame.origin.x, - (tableFrame.origin.y + tableFrame.size.height) - kBannerViewHeight, - tableFrame.size.width, kBannerViewHeight); + (tableFrame.origin.y + tableFrame.size.height) - bannerViewHeight, + tableFrame.size.width, bannerViewHeight); } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)invalidateModel { + [super invalidateModel]; + + // Renew the tableView delegate when the model is refreshed. + // Otherwise the delegate will be retained the model. + + // You need to set it to nil before changing it or it won't have any effect + _tableView.delegate = nil; + [self updateTableDelegate]; +} + @end diff --git a/src/Three20UI/Sources/TTTableViewDataSource.m b/src/Three20UI/Sources/TTTableViewDataSource.m index 33a77bf763..ceacf1aa99 100644 --- a/src/Three20UI/Sources/TTTableViewDataSource.m +++ b/src/Three20UI/Sources/TTTableViewDataSource.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ #import "Three20UI/TTTableTextItem.h" #import "Three20UI/TTTableActivityItem.h" #import "Three20UI/TTTableControlItem.h" +#import "Three20UI/TTTableSettingsItem.h" // - Table Cells #import "Three20UI/TTTableMoreButtonCell.h" @@ -47,6 +48,7 @@ #import "Three20UI/TTTableTextItemCell.h" #import "Three20UI/TTStyledTextTableCell.h" #import "Three20UI/TTTableFlushViewCell.h" +#import "Three20UI/TTTableSettingsItemCell.h" // Style #import "Three20Style/TTStyledText.h" @@ -69,6 +71,7 @@ @implementation TTTableViewDataSource /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dealloc { TT_RELEASE_SAFELY(_model); + TT_RELEASE_SAFELY(_itemCellClassMapping); [super dealloc]; } @@ -123,7 +126,8 @@ - (UITableViewCell*)tableView:(UITableView *)tableView length:strlen(className) encoding:NSASCIIStringEncoding freeWhenDone:NO]; - UITableViewCell* cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:identifier]; + UITableViewCell* cell = + (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:identifier]; if (cell == nil) { cell = [[[cellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease]; @@ -169,6 +173,7 @@ - (NSInteger)tableView:(UITableView*)tableView sectionForSectionIndexTitle:(NSSt } if (sectionIndex >= sectionCount) { return sectionCount-1; + } else { return sectionIndex; } @@ -243,39 +248,67 @@ - (id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)in return nil; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setCellClass:(NSString*)cellClass forItemClass:(NSString*)itemClass { + if (!_itemCellClassMapping) { + _itemCellClassMapping = [[NSMutableDictionary alloc] init]; + } + [_itemCellClassMapping setObject:cellClass forKey:itemClass]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (Class)tableView:(UITableView*)tableView cellClassForObject:(id)object { - if ([object isKindOfClass:[TTTableItem class]]) { + if ([object respondsToSelector:@selector(cellClass)]) + return [object performSelector:@selector(cellClass)]; + else if (_itemCellClassMapping && [_itemCellClassMapping objectForKey:NSStringFromClass([object class])]) { + return NSClassFromString([_itemCellClassMapping objectForKey:NSStringFromClass([object class])]); + } + else if ([object isKindOfClass:[TTTableItem class]]) { if ([object isKindOfClass:[TTTableMoreButton class]]) { return [TTTableMoreButtonCell class]; + + } else if ([object isKindOfClass:[TTTableSettingsItem class]]) { + return [TTTableSettingsItemCell class]; + } else if ([object isKindOfClass:[TTTableSubtextItem class]]) { return [TTTableSubtextItemCell class]; + } else if ([object isKindOfClass:[TTTableRightCaptionItem class]]) { return [TTTableRightCaptionItemCell class]; + } else if ([object isKindOfClass:[TTTableCaptionItem class]]) { return [TTTableCaptionItemCell class]; + } else if ([object isKindOfClass:[TTTableSubtitleItem class]]) { return [TTTableSubtitleItemCell class]; + } else if ([object isKindOfClass:[TTTableMessageItem class]]) { return [TTTableMessageItemCell class]; + } else if ([object isKindOfClass:[TTTableImageItem class]]) { return [TTTableImageItemCell class]; + } else if ([object isKindOfClass:[TTTableStyledTextItem class]]) { return [TTStyledTextTableItemCell class]; + } else if ([object isKindOfClass:[TTTableActivityItem class]]) { return [TTTableActivityItemCell class]; + } else if ([object isKindOfClass:[TTTableControlItem class]]) { return [TTTableControlCell class]; + } else { return [TTTableTextItemCell class]; } + } else if ([object isKindOfClass:[TTStyledText class]]) { return [TTStyledTextTableCell class]; + } else if ([object isKindOfClass:[UIControl class]] || [object isKindOfClass:[UITextView class]] || [object isKindOfClass:[TTTextEditor class]]) { return [TTTableControlCell class]; + } else if ([object isKindOfClass:[UIView class]]) { return [TTTableFlushViewCell class]; } @@ -291,6 +324,7 @@ - (NSString*)tableView:(UITableView*)tableView labelForObject:(id)object { if ([object isKindOfClass:[TTTableTextItem class]]) { TTTableTextItem* item = object; return item.text; + } else { return [NSString stringWithFormat:@"%@", object]; } @@ -323,6 +357,7 @@ - (void)search:(NSString*)text { - (NSString*)titleForLoading:(BOOL)reloading { if (reloading) { return TTLocalizedString(@"Updating...", @""); + } else { return TTLocalizedString(@"Loading...", @""); } @@ -347,6 +382,12 @@ - (NSString*)subtitleForEmpty { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)reloadButtonForEmpty { + return YES; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIImage*)imageForError:(NSError*)error { return nil; diff --git a/src/Three20UI/Sources/TTTableViewDelegate.m b/src/Three20UI/Sources/TTTableViewDelegate.m index d5f36b8d42..51c70006fa 100644 --- a/src/Three20UI/Sources/TTTableViewDelegate.m +++ b/src/Three20UI/Sources/TTTableViewDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ #import "Three20UI/TTTableHeaderView.h" #import "Three20UI/TTTableView.h" #import "Three20UI/TTStyledTextLabel.h" +#import "Three20UI/TTLabel.h" // - Table Items #import "Three20UI/TTTableItem.h" @@ -36,6 +37,8 @@ // Style #import "Three20Style/TTGlobalStyle.h" #import "Three20Style/TTDefaultStyleSheet.h" +#import "Three20Style/TTStyleContext.h" +#import "Three20Style/TTStyle.h" // Network #import "Three20Network/TTURLRequestQueue.h" @@ -43,6 +46,11 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" +static const CGFloat kEmptyHeaderHeight = 0.0f; +static const CGFloat kSectionHeaderHeight = 22.0f; +static const CGFloat kGroupedSectionHeaderHeight = 36.0f; +static const CGFloat kGroupedSectionFirstHeaderHeight = 36.0f + 10.0f; +static const NSUInteger kFirstTableSection = 0; /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -60,7 +68,8 @@ @implementation TTTableViewDelegate /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithController:(TTTableViewController*)controller { - if (self = [super init]) { + self = [super init]; + if (self) { _controller = controller; } return self; @@ -86,19 +95,56 @@ - (void)dealloc { * (i.e. not a grouped one), then we create header view objects for each header and handle the * drawing ourselves. */ +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + TTView * header = (TTView*)[self tableView:tableView viewForHeaderInSection:section]; + if (header) { + //! Is it a bug in -TTView sizeThatFits: that it ignores the size argument? -- sia 20110226 + // return [header sizeThatFits:CGSizeMake(320,[tableView sectionHeaderHeight])].height; + TTStyleContext* context = [[[TTStyleContext alloc] init] autorelease]; + context.delegate = header; + context.font = nil; + CGSize size = [header.style addToSize:CGSizeMake(0, [tableView sectionHeaderHeight]) + context:context]; + return size.height; + } + else { + CGFloat height = [tableView sectionHeaderHeight]; + //! For some reason, [tableView sectionHeaderHeight] returns (clearly wrong) 10 + //for grouped tables. Bug? Work around -- sic 20110227 + if ([tableView style] == UITableViewStyleGrouped) { + height = 36; + } + return height; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// - (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { - if (tableView.style == UITableViewStylePlain && TTSTYLEVAR(tableHeaderTintColor)) { - if ([tableView.dataSource respondsToSelector:@selector(tableView:titleForHeaderInSection:)]) { - NSString* title = [tableView.dataSource tableView:tableView titleForHeaderInSection:section]; - if (title.length > 0) { - TTTableHeaderView* header = [_headers objectForKey:title]; - if (nil == header) { - if (nil == _headers) { - _headers = [[NSMutableDictionary alloc] init]; - } - header = [[[TTTableHeaderView alloc] initWithTitle:title] autorelease]; - [_headers setObject:header forKey:title]; - } + if ([tableView.dataSource respondsToSelector:@selector(tableView:titleForHeaderInSection:)]) { + NSString* title = [tableView.dataSource tableView:tableView titleForHeaderInSection:section]; + if (title.length > 0) { + TTView* header = [_headers objectForKey:title]; + if (header) { + return header; + } + + if (nil == _headers) { + _headers = [[NSMutableDictionary alloc] init]; + } + + if (tableView.style == UITableViewStylePlain && TTSTYLEVAR(tableHeaderTintColor)) { + header = [[[TTTableHeaderView alloc] initWithTitle:title] autorelease]; + } + else if (tableView.style == UITableViewStyleGrouped && TTSTYLEVAR(tableHeaderGrouped)) { + TTLabel * label = [[[TTLabel alloc] initWithText:title] autorelease]; + label.style = TTSTYLE(tableHeaderGrouped); + label.backgroundColor = [UIColor clearColor]; + header = label; + [_headers setObject:header forKey:[NSNumber numberWithInteger:section]]; + } + + if (header) { + [_headers setObject:header forKey:title]; return header; } } @@ -118,15 +164,16 @@ - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*) if ([object isKindOfClass:[TTTableLinkedItem class]]) { TTTableLinkedItem* item = object; if (item.URL && [_controller shouldOpenURL:item.URL]) { - TTOpenURL(item.URL); - - } else if (item.delegate && item.selector) { + TTOpenURLFromView(item.URL, tableView); + } + else if (item.delegate && item.selector) { [item.delegate performSelector:item.selector withObject:object]; } if ([object isKindOfClass:[TTTableButton class]]) { [tableView deselectRowAtIndexPath:indexPath animated:YES]; - } else if ([object isKindOfClass:[TTTableMoreButton class]]) { + } + else if ([object isKindOfClass:[TTTableMoreButton class]]) { TTTableMoreButton* moreLink = (TTTableMoreButton*)object; moreLink.isLoading = YES; TTTableMoreButtonCell* cell @@ -136,7 +183,8 @@ - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*) if (moreLink.model) { [moreLink.model load:TTURLRequestCachePolicyDefault more:YES]; - } else { + } + else { [_controller.model load:TTURLRequestCachePolicyDefault more:YES]; } } @@ -158,7 +206,7 @@ - (void)tableView:(UITableView*)tableView if ([object isKindOfClass:[TTTableLinkedItem class]]) { TTTableLinkedItem* item = object; if (item.accessoryURL && [_controller shouldOpenURL:item.accessoryURL]) { - TTOpenURL(item.accessoryURL); + TTOpenURLFromView(item.accessoryURL, tableView); } } } diff --git a/src/Three20UI/Sources/TTTableViewDragRefreshDelegate.m b/src/Three20UI/Sources/TTTableViewDragRefreshDelegate.m index e018f97563..1ff1d57b07 100644 --- a/src/Three20UI/Sources/TTTableViewDragRefreshDelegate.m +++ b/src/Three20UI/Sources/TTTableViewDragRefreshDelegate.m @@ -1,17 +1,27 @@ // -// Copyright 2009-2010 Facebook +// Created by Devin Doty on 10/14/09. +// http://github.com/enormego/EGOTableViewPullRefresh +// Copyright 2009 enormego. All rights reserved. // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +// Modifications copyright 2010 Facebook. // -// http://www.apache.org/licenses/LICENSE-2.0 +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // #import "Three20UI/TTTableViewDragRefreshDelegate.h" @@ -37,6 +47,9 @@ // The number of pixels the table needs to be pulled down by in order to initiate the refresh. static const CGFloat kRefreshDeltaY = -65.0f; +// The height of the refresh header when it is in its "loading" state. +static const CGFloat kHeaderVisibleHeight = 60.0f; + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -54,7 +67,8 @@ @implementation TTTableViewDragRefreshDelegate /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithController:(TTTableViewController*)controller { - if (self = [super initWithController:controller]) { + self = [super initWithController:controller]; + if (self) { // Add our refresh header _headerView = [[TTTableHeaderDragRefreshView alloc] initWithFrame:CGRectMake(0, @@ -86,6 +100,7 @@ - (id)initWithController:(TTTableViewController*)controller { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dealloc { [_model.delegates removeObject:self]; + [_headerView removeFromSuperview]; TT_RELEASE_SAFELY(_headerView); TT_RELEASE_SAFELY(_model); @@ -112,6 +127,18 @@ - (void)scrollViewDidScroll:(UIScrollView*)scrollView { [_headerView setStatus:TTTableHeaderDragRefreshReleaseToReload]; } } + + // This is to prevent odd behavior with plain table section headers. They are affected by the + // content inset, so if the table is scrolled such that there might be a section header abutting + // the top, we need to clear the content inset. + if (_model.isLoading) { + if (scrollView.contentOffset.y >= 0) { + _controller.tableView.contentInset = UIEdgeInsetsZero; + + } else if (scrollView.contentOffset.y < 0) { + _controller.tableView.contentInset = UIEdgeInsetsMake(kHeaderVisibleHeight, 0, 0, 0); + } + } } @@ -141,7 +168,9 @@ - (void)modelDidStartLoad:(id)model { [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:ttkDefaultFastTransitionDuration]; - _controller.tableView.contentInset = UIEdgeInsetsMake(60.0f, 0.0f, 00.0f, 0.0f); + if (_controller.tableView.contentOffset.y < 0) { + _controller.tableView.contentInset = UIEdgeInsetsMake(kHeaderVisibleHeight, 0.0f, 0.0f, 0.0f); + } [UIView commitAnimations]; } diff --git a/src/Three20UI/Sources/TTTableViewGroupedVarHeightDelegate.m b/src/Three20UI/Sources/TTTableViewGroupedVarHeightDelegate.m index 2e00ef8bcc..463c21ca09 100644 --- a/src/Three20UI/Sources/TTTableViewGroupedVarHeightDelegate.m +++ b/src/Three20UI/Sources/TTTableViewGroupedVarHeightDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ #import "Three20UI/TTTableViewGroupedVarHeightDelegate.h" -static const CGFloat kEmptyHeaderHeight = 1; -static const CGFloat kSectionHeaderHeight = 35; +static const CGFloat kEmptyHeaderHeight = 1.0f; +static const CGFloat kSectionHeaderHeight = 35.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -31,6 +31,7 @@ - (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger NSString* title = [tableView.dataSource tableView:tableView titleForHeaderInSection:section]; if (!title.length) { return kEmptyHeaderHeight; + } else { return kSectionHeaderHeight; } diff --git a/src/Three20UI/Sources/TTTableViewItem.m b/src/Three20UI/Sources/TTTableViewItem.m index 1f0bfe62f5..9df5beed6a 100644 --- a/src/Three20UI/Sources/TTTableViewItem.m +++ b/src/Three20UI/Sources/TTTableViewItem.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -61,7 +61,8 @@ + (id)itemWithCaption:(NSString*)caption view:(UIControl*)view { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithCoder:(NSCoder*)decoder { - if (self = [super initWithCoder:decoder]) { + self = [super initWithCoder:decoder]; + if (self) { self.caption = [decoder decodeObjectForKey:@"caption"]; self.view = [decoder decodeObjectForKey:@"view"]; } diff --git a/src/Three20UI/Sources/TTTableViewNetworkEnabledDelegate.m b/src/Three20UI/Sources/TTTableViewNetworkEnabledDelegate.m new file mode 100644 index 0000000000..f0a358e95d --- /dev/null +++ b/src/Three20UI/Sources/TTTableViewNetworkEnabledDelegate.m @@ -0,0 +1,273 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20UI/TTTableViewNetworkEnabledDelegate.h" + +// UI +#import "Three20UI/TTTableHeaderDragRefreshView.h" +#import "Three20UI/TTTableFooterInfiniteScrollView.h" +#import "Three20UI/TTTableViewController.h" +#import "Three20UI/UIViewAdditions.h" + +// UICommon +#import "Three20UICommon/TTGlobalUICommon.h" + +// Network +#import "Three20Network/TTModel.h" + +// Style +#import "Three20Style/TTGlobalStyle.h" +#import "Three20Style/TTDefaultStyleSheet+DragRefreshHeader.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + + +// The number of pixels the table needs to be pulled down by in order to initiate the refresh. +static const CGFloat kRefreshDeltaY = -65.0f; + +// The height of the refresh header when it is in its "loading" state. +static const CGFloat kHeaderVisibleHeight = 60.0f; + +// The height of the infinite scroll footer view +static const CGFloat kInfiniteScrollFooterHeight = 40.0f; + +// The percentage of table scrolling to trigger infinite scroll agter +static const CGFloat kInfiniteScrollThreshold = 0.5f; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTTableViewNetworkEnabledDelegate + +@synthesize headerView = _headerView, footerView = _footerView, + dragRefreshEnabled = _dragRefreshEnabled, + infiniteScrollEnabled = _infiniteScrollEnabled; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark NSObject + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithController:(TTTableViewController*)controller + withDragRefresh:(BOOL)enableDragRefresh + withInfiniteScroll:(BOOL)enableInfiniteScroll { + self = [super initWithController:controller]; + if (self) { + _dragRefreshEnabled = enableDragRefresh; + _infiniteScrollEnabled = enableInfiniteScroll; + + // Hook up to the model to listen for changes. + _model = [controller.model retain]; + [_model.delegates addObject:self]; + + if (_dragRefreshEnabled) { + // Add our refresh header + _headerView = [[TTTableHeaderDragRefreshView alloc] + initWithFrame:CGRectMake(0, + -_controller.tableView.bounds.size.height, + _controller.tableView.width, + _controller.tableView.bounds.size.height)]; + _headerView.autoresizingMask = UIViewAutoresizingFlexibleWidth; + _headerView.backgroundColor = TTSTYLEVAR(tableRefreshHeaderBackgroundColor); + [_headerView setStatus:TTTableHeaderDragRefreshPullToReload]; + [_controller.tableView addSubview:_headerView]; + + + // Grab the last refresh date if there is one. + if ([_model respondsToSelector:@selector(loadedTime)] && enableDragRefresh) { + NSDate* date = [_model performSelector:@selector(loadedTime)]; + + if (nil != date) { + [_headerView setUpdateDate:date]; + } + } + } + + if (_infiniteScrollEnabled) { + _footerView = [[TTTableFooterInfiniteScrollView alloc] + initWithFrame:CGRectMake(0, + 0, + _controller.tableView.width, + kInfiniteScrollFooterHeight)]; + _footerView.autoresizingMask = UIViewAutoresizingFlexibleWidth; + _controller.tableView.tableFooterView = _footerView; + } + } + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)dealloc { + _controller.tableView.tableFooterView = nil; + [_model.delegates removeObject:self]; + [_headerView removeFromSuperview]; + TT_RELEASE_SAFELY(_headerView); + TT_RELEASE_SAFELY(_footerView); + TT_RELEASE_SAFELY(_model); + + [super dealloc]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark UIScrollViewDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)scrollViewDidScroll:(UIScrollView*)scrollView { + [super scrollViewDidScroll:scrollView]; + + if (_dragRefreshEnabled) { + if (scrollView.dragging && !_model.isLoading) { + if (scrollView.contentOffset.y > kRefreshDeltaY + && scrollView.contentOffset.y < 0.0f) { + [_headerView setStatus:TTTableHeaderDragRefreshPullToReload]; + + } else if (scrollView.contentOffset.y < kRefreshDeltaY) { + [_headerView setStatus:TTTableHeaderDragRefreshReleaseToReload]; + } + } + + // This is to prevent odd behavior with plain table section headers. They are affected by the + // content inset, so if the table is scrolled such that there might be a section header abutting + // the top, we need to clear the content inset. + if (_model.isLoading) { + if (scrollView.contentOffset.y >= 0) { + _controller.tableView.contentInset = UIEdgeInsetsZero; + + } else if (scrollView.contentOffset.y < 0) { + _controller.tableView.contentInset = UIEdgeInsetsMake(kHeaderVisibleHeight, 0, 0, 0); + } + } + } + + if (_infiniteScrollEnabled && !_model.isLoading) { + CGFloat scrollRatio = scrollView.contentOffset.y / + (scrollView.contentSize.height - scrollView.height); + scrollRatio = MAX(MIN(scrollRatio, 1),0); + BOOL shouldLoad; + if ([_controller respondsToSelector:@selector(shouldLoadAtScrollRatio:)]) { + shouldLoad = [(id )_controller + shouldLoadAtScrollRatio:scrollRatio]; + + } else { + shouldLoad = scrollRatio > kInfiniteScrollThreshold; + } + + if (shouldLoad) { + [_model load:TTURLRequestCachePolicyDefault more:YES]; + [(TTTableFooterInfiniteScrollView*)_controller.tableView.tableFooterView setLoading:YES]; + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate:(BOOL)decelerate { + [super scrollViewDidEndDragging:scrollView willDecelerate:decelerate]; + + if (_dragRefreshEnabled) { + // If dragging ends and we are far enough to be fully showing the header view trigger a + // load as long as we arent loading already + if (scrollView.contentOffset.y <= kRefreshDeltaY && !_model.isLoading) { + [[NSNotificationCenter defaultCenter] + postNotificationName:@"DragRefreshTableReload" object:nil]; + [_model load:TTURLRequestCachePolicyNetwork more:NO]; + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark TTModelDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)modelDidStartLoad:(id)model { + if (_dragRefreshEnabled) { + [_headerView setStatus:TTTableHeaderDragRefreshLoading]; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:ttkDefaultFastTransitionDuration]; + if (_controller.tableView.contentOffset.y < 0) { + _controller.tableView.contentInset = UIEdgeInsetsMake(kHeaderVisibleHeight, 0.0f, 0.0f, 0.0f); + } + [UIView commitAnimations]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)modelDidFinishLoad:(id)model { + if (_dragRefreshEnabled) { + [_headerView setStatus:TTTableHeaderDragRefreshPullToReload]; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:ttkDefaultTransitionDuration]; + _controller.tableView.contentInset = UIEdgeInsetsZero; + [UIView commitAnimations]; + + if ([model respondsToSelector:@selector(loadedTime)]) { + NSDate* date = [model performSelector:@selector(loadedTime)]; + [_headerView setUpdateDate:date]; + + } else { + [_headerView setCurrentDate]; + } + } + + if (_infiniteScrollEnabled) { + [(TTTableFooterInfiniteScrollView*)_controller.tableView.tableFooterView setLoading:NO]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)model:(id)model didFailLoadWithError:(NSError*)error { + if (_dragRefreshEnabled) { + [_headerView setStatus:TTTableHeaderDragRefreshPullToReload]; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:ttkDefaultTransitionDuration]; + _controller.tableView.contentInset = UIEdgeInsetsZero; + [UIView commitAnimations]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)modelDidCancelLoad:(id)model { + if (_dragRefreshEnabled) { + [_headerView setStatus:TTTableHeaderDragRefreshPullToReload]; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:ttkDefaultTransitionDuration]; + _controller.tableView.contentInset = UIEdgeInsetsZero; + [UIView commitAnimations]; + } +} + + +@end diff --git a/src/Three20UI/Sources/TTTableViewPlainDelegate.m b/src/Three20UI/Sources/TTTableViewPlainDelegate.m index 02e2af9d25..27148a11de 100644 --- a/src/Three20UI/Sources/TTTableViewPlainDelegate.m +++ b/src/Three20UI/Sources/TTTableViewPlainDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableViewPlainVarHeightDelegate.m b/src/Three20UI/Sources/TTTableViewPlainVarHeightDelegate.m index 35db4eb6cd..c1484ccf63 100644 --- a/src/Three20UI/Sources/TTTableViewPlainVarHeightDelegate.m +++ b/src/Three20UI/Sources/TTTableViewPlainVarHeightDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTableViewVarHeightDelegate.m b/src/Three20UI/Sources/TTTableViewVarHeightDelegate.m index a2a62d0d66..e0e1049cf3 100644 --- a/src/Three20UI/Sources/TTTableViewVarHeightDelegate.m +++ b/src/Three20UI/Sources/TTTableViewVarHeightDelegate.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UI/Sources/TTTextBarController.m b/src/Three20UI/Sources/TTTextBarController.m index 0e3cd49e11..950405f5c4 100644 --- a/src/Three20UI/Sources/TTTextBarController.m +++ b/src/Three20UI/Sources/TTTextBarController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ // UICommon #import "Three20UICommon/TTGlobalUICommon.h" #import "Three20UICommon/UIViewControllerAdditions.h" +#import "Three20UICommon/UIView+TTUICommon.h" // Style #import "Three20Style/TTGlobalStyle.h" @@ -38,9 +39,10 @@ #import "Three20Core/TTGlobalCoreLocale.h" #import "Three20Core/TTCorePreprocessorMacros.h" #import "Three20Core/NSStringAdditions.h" +#import "Three20Core/TTGlobalCore.h" -static CGFloat kMargin = 1; -static CGFloat kPadding = 5; +static CGFloat kMargin = 1.0f; +static CGFloat kPadding = 5.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -57,7 +59,8 @@ @implementation TTTextBarController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { } return self; @@ -66,7 +69,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { if (nil != query) { _delegate = [query objectForKey:@"delegate"]; _defaultText = [[query objectForKey:@"text"] copy]; @@ -79,7 +83,8 @@ - (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithNavigatorURL:nil query:nil]) { + self = [self initWithNavigatorURL:nil query:nil]; + if (self) { } return self; @@ -244,6 +249,7 @@ - (void)showInView:(UIView*)view animated:(BOOL)animated { if (_defaultText) { _textEditor.text = _defaultText; TT_RELEASE_SAFELY(_defaultText); + } else { _defaultText = [_textEditor.text retain]; } @@ -258,6 +264,7 @@ - (void)showInView:(UIView*)view animated:(BOOL)animated { - (void)dismissPopupViewControllerAnimated:(BOOL)animated { if (animated) { [_textEditor resignFirstResponder]; + } else { UIViewController* superController = self.superController; [self.view removeFromSuperview]; @@ -382,7 +389,9 @@ - (TTButton*)postButton { if (!_postButton) { _postButton = [[TTButton buttonWithStyle:@"textBarPostButton:" title:NSLocalizedString(@"Post", @"")] retain]; - [_postButton addTarget:self action:@selector(post) forControlEvents:UIControlEventTouchUpInside]; + [_postButton addTarget: self + action: @selector(post) + forControlEvents: UIControlEventTouchUpInside]; [_postButton setEnabled:NO]; } return _postButton; @@ -401,6 +410,7 @@ - (void)post { if (shouldDismiss) { [self dismissWithResult:nil animated:YES]; + } else { [self showActivity:[self titleForActivity]]; } @@ -409,7 +419,8 @@ - (void)post { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)cancel { - if (!_textEditor.text.isEmptyOrWhitespace + if (!TTIsStringWithAnyText(_textEditor.text) + && !_textEditor.text.isWhitespaceAndNewlines && !(_defaultText && [_defaultText isEqualToString:_textEditor.text])) { UIAlertView* cancelAlertView = [[[UIAlertView alloc] initWithTitle: TTLocalizedString(@"Cancel", @"") @@ -417,6 +428,7 @@ - (void)cancel { delegate:self cancelButtonTitle:TTLocalizedString(@"Yes", @"") otherButtonTitles:TTLocalizedString(@"No", @""), nil] autorelease]; [cancelAlertView show]; + } else { [self dismissWithCancel]; } @@ -455,6 +467,7 @@ - (void)dismissWithResult:(id)result animated:(BOOL)animated { // // if (!CGRectIsEmpty(originRect)) { // _screenView.frame = CGRectOffset(originRect, 0, -TTStatusHeight()); +// // } else { // _screenView.transform = CGAffineTransformMakeScale(0.00001, 0.00001); // } @@ -463,6 +476,7 @@ - (void)dismissWithResult:(id)result animated:(BOOL)animated { // _navigationBar.alpha = 0; // // [UIView commitAnimations]; +// // } else { // [self dismissAnimationDidStop]; // } diff --git a/src/Three20UI/Sources/TTTextEditor.m b/src/Three20UI/Sources/TTTextEditor.m index 09ba979602..7acb735599 100644 --- a/src/Three20UI/Sources/TTTextEditor.m +++ b/src/Three20UI/Sources/TTTextEditor.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,12 +17,14 @@ #import "Three20UI/TTTextEditor.h" // UI -#import "Three20UI/TTTextView.h" -#import "Three20UI/TTTextEditorInternal.h" #import "Three20UI/TTTextEditorDelegate.h" #import "Three20UI/UIViewAdditions.h" #import "Three20Style/UIFontAdditions.h" +// UI (private) +#import "Three20UI/private/TTTextView.h" +#import "Three20UI/private/TTTextEditorInternal.h" + // Style #import "Three20Style/TTGlobalStyle.h" #import "Three20Style/TTDefaultStyleSheet.h" @@ -31,16 +33,16 @@ #import "Three20Core/TTCorePreprocessorMacros.h" #import "Three20Core/TTGlobalCoreRects.h" -static const CGFloat kPaddingX = 8; -static const CGFloat kPaddingY = 9; +static const CGFloat kPaddingX = 8.0f; +static const CGFloat kPaddingY = 9.0f; // XXXjoe This number is very sensitive - it is specifically calculated for precise word wrapping // with 15pt normal helvetica. If you change this number at all, UITextView may wrap the text // before or after the TTTextEditor expands or contracts its height to match. Obviously, // hard-coding this value here sucks, and I need to implement a solution that works for any font. -static const CGFloat kTextViewInset = 31; +static const CGFloat kTextViewInset = 31.0f; -static const CGFloat kUITextViewVerticalPadding = 6; +static const CGFloat kUITextViewVerticalPadding = 6.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -58,7 +60,8 @@ @implementation TTTextEditor /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { _internal = [[TTTextEditorInternal alloc] initWithTextEditor:self]; _autoresizesToText = YES; @@ -91,6 +94,7 @@ - (void)dealloc { - (UIResponder*)activeTextField { if (_textView && !_textView.hidden) { return _textView; + } else { return _textField; } @@ -191,6 +195,7 @@ - (void)constrainToText { _internal.ignoreBeginAndEnd = YES; [_textView becomeFirstResponder]; [self performSelector:@selector(stopIgnoringBeginAndEnd) withObject:nil afterDelay:0]; + } else if (numberOfLines == 1 && _textField.hidden) { _textField.hidden = NO; _textView.hidden = YES; @@ -250,6 +255,18 @@ - (void)didChangeText:(BOOL)insertReturn { #pragma mark UIResponder +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)isFirstResponder { + return [[self activeTextField] isFirstResponder]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)canBecomeFirstResponder { + return [[self activeTextField] canBecomeFirstResponder]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)becomeFirstResponder { return [[self activeTextField] becomeFirstResponder]; @@ -390,6 +407,7 @@ - (void)setDelegate:(id)delegate { - (NSString*)text { if (_textView && !_textView.hidden) { return _textView.text; + } else { return _textField.text; } @@ -457,6 +475,7 @@ - (void)scrollContainerToCursor:(UIScrollView*)scrollView { [scrollView scrollRectToVisible:CGRectMake(0,scrollView.contentSize.height-1,1,1) animated:NO]; } + } else { [scrollView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO]; } diff --git a/src/Three20UI/Sources/TTTextEditorInternal.m b/src/Three20UI/Sources/TTTextEditorInternal.m index 003e3d5758..2db4ce9d4f 100644 --- a/src/Three20UI/Sources/TTTextEditorInternal.m +++ b/src/Three20UI/Sources/TTTextEditorInternal.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,10 @@ // limitations under the License. // -#import "Three20UI/TTTextEditorInternal.h" +#import "Three20UI/private/TTTextEditorInternal.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" // UI #import "Three20UI/TTTextEditorDelegate.h" @@ -23,6 +26,8 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +TT_FIX_CATEGORY_BUG(TTTextEditorInternal) + @implementation TTTextEditorInternal @synthesize ignoreBeginAndEnd = _ignoreBeginAndEnd; @@ -31,7 +36,8 @@ @implementation TTTextEditorInternal /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTextEditor:(TTTextEditor*)textEditor { - if (self = [super init]) { + self = [super init]; + if (self) { _textEditor = textEditor; } @@ -104,8 +110,10 @@ - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range } } - if ([_delegate respondsToSelector:@selector(textEditor:shouldChangeTextInRange:replacementText:)]) { + if ([_delegate respondsToSelector: + @selector(textEditor:shouldChangeTextInRange:replacementText:)]) { return [_delegate textEditor:_textEditor shouldChangeTextInRange:range replacementText:text]; + } else { return YES; } @@ -135,7 +143,8 @@ - (void)textViewDidChangeSelection:(UITextView *)textView { /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)textFieldShouldBeginEditing:(UITextField*)textField { - if (!_ignoreBeginAndEnd && [_delegate respondsToSelector:@selector(textEditorShouldBeginEditing:)]) { + if (!_ignoreBeginAndEnd + && [_delegate respondsToSelector:@selector(textEditorShouldBeginEditing:)]) { return [_delegate textEditorShouldBeginEditing:_textEditor]; } else { @@ -146,8 +155,10 @@ - (BOOL)textFieldShouldBeginEditing:(UITextField*)textField { /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)textFieldShouldEndEditing:(UITextField*)textField { - if (!_ignoreBeginAndEnd && [_delegate respondsToSelector:@selector(textEditorShouldEndEditing:)]) { + if (!_ignoreBeginAndEnd + && [_delegate respondsToSelector:@selector(textEditorShouldEndEditing:)]) { return [_delegate textEditorShouldEndEditing:_textEditor]; + } else { return YES; } @@ -183,7 +194,8 @@ - (BOOL) textField: (UITextField*)textField shouldChangeCharactersInRange: (NSRange)range replacementString: (NSString*)string { BOOL shouldChange = YES; - if ([_delegate respondsToSelector:@selector(textEditor:shouldChangeTextInRange:replacementText:)]) { + if ([_delegate respondsToSelector: + @selector(textEditor:shouldChangeTextInRange:replacementText:)]) { shouldChange = [_delegate textEditor:_textEditor shouldChangeTextInRange:range replacementText:string]; } diff --git a/src/Three20UI/Sources/TTTextView.m b/src/Three20UI/Sources/TTTextView.m index 6ac5975598..9febd5e6fe 100644 --- a/src/Three20UI/Sources/TTTextView.m +++ b/src/Three20UI/Sources/TTTextView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // -#import "Three20UI/TTTextView.h" +#import "Three20UI/private/TTTextView.h" // UI #import "Three20UI/UIViewAdditions.h" diff --git a/src/Three20UI/Sources/TTThumbView.m b/src/Three20UI/Sources/TTThumbView.m index 7dec27eb62..f041eec864 100644 --- a/src/Three20UI/Sources/TTThumbView.m +++ b/src/Three20UI/Sources/TTThumbView.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,7 +29,9 @@ @implementation TTThumbView /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = TTSTYLEVAR(thumbnailBackgroundColor); self.clipsToBounds = YES; diff --git a/src/Three20UI/Sources/TTThumbsDataSource.m b/src/Three20UI/Sources/TTThumbsDataSource.m index 01cf2667ac..d195a50961 100644 --- a/src/Three20UI/Sources/TTThumbsDataSource.m +++ b/src/Three20UI/Sources/TTThumbsDataSource.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,8 +32,8 @@ #import "Three20Core/TTGlobalCoreLocale.h" #import "Three20Core/TTCorePreprocessorMacros.h" -static CGFloat kThumbSize = 75; -static CGFloat kThumbSpacing = 4; +static CGFloat kThumbSize = 75.0f; +static CGFloat kThumbSpacing = 4.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -48,7 +48,8 @@ @implementation TTThumbsDataSource /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithPhotoSource:(id)photoSource delegate:(id)delegate { - if (self = [super init]) { + self = [super init]; + if (self) { _photoSource = [photoSource retain]; _delegate = delegate; } @@ -78,9 +79,9 @@ - (BOOL)hasMoreToLoad { /////////////////////////////////////////////////////////////////////////////////////////////////// -- (NSInteger)columnCount { - CGFloat width = TTScreenBounds().size.width; - return round((width - kThumbSpacing*2) / (kThumbSize+kThumbSpacing)); +- (NSInteger)columnCountForView:(UIView *)view { + CGFloat width = view.bounds.size.width; + return floorf((width - kThumbSpacing*2) / (kThumbSize+kThumbSpacing) + 0.1); } @@ -93,15 +94,17 @@ - (NSInteger)columnCount { /////////////////////////////////////////////////////////////////////////////////////////////////// - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { NSInteger maxIndex = _photoSource.maxPhotoIndex; - NSInteger columnCount = self.columnCount; + NSInteger columnCount = [self columnCountForView:tableView]; if (maxIndex >= 0) { maxIndex += 1; NSInteger count = ceil((maxIndex / columnCount) + (maxIndex % columnCount ? 1 : 0)); if (self.hasMoreToLoad) { return count + 1; + } else { return count; } + } else { return 0; } @@ -128,6 +131,7 @@ - (id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)in if (_photoSource.numberOfPhotos == -1) { caption = [NSString stringWithFormat:TTLocalizedString(@"Showing %@ Photos", @""), TTFormatInteger(_photoSource.maxPhotoIndex+1)]; + } else { caption = [NSString stringWithFormat:TTLocalizedString(@"Showing %@ of %@ Photos", @""), TTFormatInteger(_photoSource.maxPhotoIndex+1), @@ -135,8 +139,9 @@ - (id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)in } return [TTTableMoreButton itemWithText:text subtitle:caption]; + } else { - NSInteger columnCount = self.columnCount; + NSInteger columnCount = [self columnCountForView:tableView]; return [_photoSource photoAtIndex:indexPath.row * columnCount]; } } @@ -146,6 +151,7 @@ - (id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)in - (Class)tableView:(UITableView*)tableView cellClassForObject:(id)object { if ([object conformsToProtocol:@protocol(TTPhoto)]) { return [TTThumbsTableViewCell class]; + } else { return [super tableView:tableView cellClassForObject:object]; } @@ -159,7 +165,7 @@ - (void) tableView: (UITableView*)tableView if ([cell isKindOfClass:[TTThumbsTableViewCell class]]) { TTThumbsTableViewCell* thumbsCell = (TTThumbsTableViewCell*)cell; thumbsCell.delegate = _delegate; - thumbsCell.columnCount = self.columnCount; + thumbsCell.columnCount = [self columnCountForView:tableView]; } } @@ -190,6 +196,12 @@ - (NSString*)subtitleForEmpty { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)reloadButtonForEmpty { + return NO; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIImage*)imageForError:(NSError*)error { return TTIMAGE(@"bundle://Three20.bundle/images/photoDefault.png"); diff --git a/src/Three20UI/Sources/TTThumbsTableViewCell.m b/src/Three20UI/Sources/TTThumbsTableViewCell.m index 099ec3ed10..d9196cc846 100644 --- a/src/Three20UI/Sources/TTThumbsTableViewCell.m +++ b/src/Three20UI/Sources/TTThumbsTableViewCell.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,8 +26,8 @@ // Core #import "Three20Core/TTCorePreprocessorMacros.h" -static const CGFloat kSpacing = 4; -static const CGFloat kDefaultThumbSize = 75; +static const CGFloat kSpacing = 4.0f; +static const CGFloat kDefaultThumbSize = 75.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -44,7 +44,8 @@ @implementation TTThumbsTableViewCell /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier { - if (self = [super initWithStyle:style reuseIdentifier:identifier]) { + self = [super initWithStyle:style reuseIdentifier:identifier]; + if (self) { _thumbViews = [[NSMutableArray alloc] init]; _thumbSize = kDefaultThumbSize; _thumbOrigin = CGPointMake(kSpacing, 0); @@ -78,6 +79,7 @@ - (void)assignPhotoAtIndex:(int)photoIndex toView:(TTThumbView*)thumbView { if (photo) { thumbView.thumbURL = [photo URLForVersion:TTPhotoVersionThumbnail]; thumbView.hidden = NO; + } else { thumbView.thumbURL = nil; thumbView.hidden = YES; @@ -161,12 +163,10 @@ - (void)setThumbOrigin:(CGPoint)thumbOrigin { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)setColumnCount:(NSInteger)columnCount { if (_columnCount != columnCount) { - if (columnCount > _columnCount) { - for (TTThumbView* thumbView in _thumbViews) { - [thumbView removeFromSuperview]; - } - [_thumbViews removeAllObjects]; + for (TTThumbView* thumbView in _thumbViews) { + [thumbView removeFromSuperview]; } + [_thumbViews removeAllObjects]; _columnCount = columnCount; diff --git a/src/Three20UI/Sources/TTThumbsViewController.m b/src/Three20UI/Sources/TTThumbsViewController.m index 1314eff52e..fcfe4fe907 100644 --- a/src/Three20UI/Sources/TTThumbsViewController.m +++ b/src/Three20UI/Sources/TTThumbsViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ #import "Three20Core/TTGlobalCoreRects.h" #import "Three20Core/TTCorePreprocessorMacros.h" -static CGFloat kThumbnailRowHeight = 79; +static CGFloat kThumbnailRowHeight = 79.0f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -55,7 +55,8 @@ @implementation TTThumbsViewController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { self.statusBarStyle = UIStatusBarStyleBlackTranslucent; self.navigationBarStyle = UIBarStyleBlackTranslucent; self.navigationBarTintColor = nil; @@ -69,7 +70,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithDelegate:(id)delegate { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { self.delegate = delegate; } @@ -93,7 +95,8 @@ - (id)initWithQuery:(NSDictionary*)query { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { } return self; @@ -140,6 +143,7 @@ - (void)updateTableLayout { - (NSString*)URLForPhoto:(id)photo { if ([photo respondsToSelector:@selector(URLValueWithName:)]) { return [photo URLValueWithName:@"TTPhotoViewController"]; + } else { return nil; } @@ -280,7 +284,8 @@ - (void)thumbsTableViewCell:(TTThumbsTableViewCell*)cell didSelectPhoto:(id\ @@ -51,7 +51,8 @@ @implementation TTYouTubeView /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithURLPath:(NSString*)urlPath { - if (self = [self initWithFrame:CGRectMake(0, 0, kDefaultWidth, kDefaultHeight)]) { + self = [self initWithFrame:CGRectMake(0, 0, kDefaultWidth, kDefaultHeight)]; + if (self) { self.urlPath = urlPath; } return self; diff --git a/src/Three20UI/Sources/UINSObjectAdditions.m b/src/Three20UI/Sources/UINSObjectAdditions.m index a236d629aa..6939013af8 100644 --- a/src/Three20UI/Sources/UINSObjectAdditions.m +++ b/src/Three20UI/Sources/UINSObjectAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20UI/UINSObjectAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + // UI #import "Three20UI/TTNavigator.h" @@ -29,6 +32,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UINSObjectAdditions) + @implementation NSObject (TTCategory) diff --git a/src/Three20UI/Sources/UINSStringAdditions.m b/src/Three20UI/Sources/UINSStringAdditions.m index cac21adeb4..dba10446e7 100644 --- a/src/Three20UI/Sources/UINSStringAdditions.m +++ b/src/Three20UI/Sources/UINSStringAdditions.m @@ -1,4 +1,4 @@ -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain @@ -14,6 +14,9 @@ #import "Three20UI/UINSStringAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + // UI #import "Three20UI/TTNavigator.h" @@ -29,6 +32,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UINSStringAdditions) + @implementation NSString (TTCategory) @@ -48,9 +53,10 @@ - (void)openURL { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)openURLFromButton:(UIView*)button { NSDictionary* query = [NSDictionary dictionaryWithObjectsAndKeys:button, @"__target__", nil]; - [[TTNavigator navigator] openURLAction:[[[TTURLAction actionWithURLPath: self] - applyQuery: query] - applyAnimated: YES]]; + [[TTBaseNavigator navigatorForView:button] + openURLAction:[[[TTURLAction actionWithURLPath: self] + applyQuery: query] + applyAnimated: YES]]; } diff --git a/src/Three20UI/Sources/UINavigationControllerAdditions.m b/src/Three20UI/Sources/UINavigationControllerAdditions.m index 0c42f43120..3192d5e893 100644 --- a/src/Three20UI/Sources/UINavigationControllerAdditions.m +++ b/src/Three20UI/Sources/UINavigationControllerAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20UI/UINavigationControllerAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + // UI #import "Three20UI/TTNavigator.h" #import "Three20UI/TTNavigationController.h" @@ -38,6 +41,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UINavigationControllerAdditions) + @implementation UINavigationController (TTCategory) @@ -52,6 +57,7 @@ - (UIView*)rotatingHeaderView { UIViewController* popup = [self popupViewController]; if (popup) { return [popup rotatingHeaderView]; + } else { return [super rotatingHeaderView]; } @@ -83,9 +89,11 @@ - (void)addSubcontroller:(UIViewController*)controller animated:(BOOL)animated if ([self isKindOfClass:[TTNavigationController class]]) { [(TTNavigationController*)self pushViewController: controller animatedWithTransition: transition]; + } else { [self pushViewController:controller animated:YES]; } + } else { [self pushViewController:controller animated:animated]; } @@ -106,6 +114,7 @@ - (NSString*)keyForSubcontroller:(UIViewController*)controller { NSInteger controllerIndex = [self.viewControllers indexOfObject:controller]; if (controllerIndex != NSNotFound) { return [NSNumber numberWithInt:controllerIndex].stringValue; + } else { return nil; } @@ -117,6 +126,7 @@ - (UIViewController*)subcontrollerForKey:(NSString*)key { NSInteger controllerIndex = key.intValue; if (controllerIndex < self.viewControllers.count) { return [self.viewControllers objectAtIndex:controllerIndex]; + } else { return nil; } diff --git a/src/Three20UI/Sources/UITabBarControllerAdditions.m b/src/Three20UI/Sources/UITabBarControllerAdditions.m index 548c876363..8ab4ca739d 100644 --- a/src/Three20UI/Sources/UITabBarControllerAdditions.m +++ b/src/Three20UI/Sources/UITabBarControllerAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20UI/UITabBarControllerAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + // UI #import "Three20UI/TTNavigator.h" #import "Three20UI/TTNavigationController.h" @@ -30,6 +33,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UITabBarControllerAdditions) + @implementation UITabBarController (TTCategory) @@ -43,6 +48,7 @@ @implementation UITabBarController (TTCategory) - (UIViewController*)rootControllerForController:(UIViewController*)controller { if ([controller canContainControllers]) { return controller; + } else { TTNavigationController* navController = [[[TTNavigationController alloc] init] autorelease]; [navController pushViewController:controller animated:NO]; @@ -65,7 +71,12 @@ - (BOOL)canContainControllers { /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIViewController*)topSubcontroller { - return self.selectedViewController; + if (self.tabBar.selectedItem == self.moreNavigationController.tabBarItem) { + return self.moreNavigationController; + } + else { + return self.selectedViewController; + } } diff --git a/src/Three20UI/Sources/UITableViewAdditions.m b/src/Three20UI/Sources/UITableViewAdditions.m index 5ce4ebe4d2..e1acc0af80 100644 --- a/src/Three20UI/Sources/UITableViewAdditions.m +++ b/src/Three20UI/Sources/UITableViewAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,11 +16,15 @@ #import "Three20UI/UITableViewAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + // UI #import "Three20UI/UIViewAdditions.h" // UICommon #import "Three20UICommon/UIWindowAdditions.h" +#import "Three20UICommon/TTGlobalUICommon.h" /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -29,6 +33,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UITableViewAdditions) + @implementation UITableView (TTCategory) @@ -48,8 +54,14 @@ - (UIView*)indexView { /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGFloat)tableCellMargin { if (self.style == UITableViewStyleGrouped) { - return 10; - } else { + if (TTIsPad()) { + return 45.0; + } + else { + return 10.0; + } + } + else { return 0; } } @@ -103,7 +115,8 @@ - (void)scrollToLastRow:(BOOL)animated { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)scrollFirstResponderIntoView { UIView* responder = [self.window findFirstResponder]; - UITableViewCell* cell = (UITableViewCell*)[responder ancestorOrSelfWithClass:[UITableViewCell class]]; + UITableViewCell* cell = (UITableViewCell*)[responder + ancestorOrSelfWithClass:[UITableViewCell class]]; if (cell) { NSIndexPath* indexPath = [self indexPathForCell:cell]; if (indexPath) { diff --git a/src/Three20UI/Sources/UIToolbarAdditions.m b/src/Three20UI/Sources/UIToolbarAdditions.m index 058a389fbc..600dfc04bf 100644 --- a/src/Three20UI/Sources/UIToolbarAdditions.m +++ b/src/Three20UI/Sources/UIToolbarAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20UI/UIToolbarAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -23,6 +26,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UIToolbarAdditions) + @implementation UIToolbar (TTCategory) diff --git a/src/Three20UI/Sources/UIViewAdditions.m b/src/Three20UI/Sources/UIViewAdditions.m index b2d9f2f31f..8aeb96bf6e 100644 --- a/src/Three20UI/Sources/UIViewAdditions.m +++ b/src/Three20UI/Sources/UIViewAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20UI/UIViewAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + // UINavigator #import "Three20UINavigator/TTGlobalNavigatorMetrics.h" @@ -24,7 +27,7 @@ // Remove GSEvent and UITouchAdditions from Release builds -#ifdef DEBUG +#ifdef DEBUG_TOUCHES /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -80,7 +83,14 @@ @implementation UIEventFake /////////////////////////////////////////////////////////////////////////////////////////////////// @interface UITouch (TTCategory) +/** + * + */ - (id)initInView:(UIView *)view location:(CGPoint)location; + +/** + * + */ - (void)changeToPhase:(UITouchPhase)phase; @end @@ -94,7 +104,8 @@ @implementation UITouch (TTCategory) /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initInView:(UIView *)view location:(CGPoint)location { - if (self = [super init]) { + self = [super init]; + if (self) { _tapCount = 1; _locationInWindow = location; _previousLocationInWindow = location; @@ -129,7 +140,8 @@ @implementation UIEvent (TTCategory) /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTouch:(UITouch *)touch { - if (self == [super init]) { + self = [super init]; + if (self) { UIEventFake *selfFake = (UIEventFake*)self; selfFake->_touches = [[NSMutableSet setWithObject:touch] retain]; selfFake->_timestamp = [NSDate timeIntervalSinceReferenceDate]; @@ -158,6 +170,11 @@ - (id)initWithTouch:(UITouch *)touch { /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Additions. + */ +TT_FIX_CATEGORY_BUG(UIViewAdditions) + @implementation UIView (TTCategory) @@ -271,7 +288,7 @@ - (void)setHeight:(CGFloat)height { /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGFloat)ttScreenX { - CGFloat x = 0; + CGFloat x = 0.0f; for (UIView* view = self; view; view = view.superview) { x += view.left; } @@ -281,7 +298,7 @@ - (CGFloat)ttScreenX { /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGFloat)ttScreenY { - CGFloat y = 0; + CGFloat y = 0.0f; for (UIView* view = self; view; view = view.superview) { y += view.top; } @@ -291,7 +308,7 @@ - (CGFloat)ttScreenY { /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGFloat)screenViewX { - CGFloat x = 0; + CGFloat x = 0.0f; for (UIView* view = self; view; view = view.superview) { x += view.left; @@ -387,8 +404,10 @@ - (UIView*)descendantOrSelfWithClass:(Class)cls { - (UIView*)ancestorOrSelfWithClass:(Class)cls { if ([self isKindOfClass:cls]) { return self; + } else if (self.superview) { return [self.superview ancestorOrSelfWithClass:cls]; + } else { return nil; } @@ -404,7 +423,8 @@ - (void)removeAllSubviews { } -#ifdef DEBUG +#ifdef DEBUG_TOUCHES + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)simulateTapAtPoint:(CGPoint)location { @@ -424,7 +444,7 @@ - (void)simulateTapAtPoint:(CGPoint)location { /////////////////////////////////////////////////////////////////////////////////////////////////// - (CGPoint)offsetFromView:(UIView*)otherView { - CGFloat x = 0, y = 0; + CGFloat x = 0.0f, y = 0.0f; for (UIView* view = self; view && view != otherView; view = view.superview) { x += view.left; y += view.top; @@ -470,7 +490,8 @@ - (NSDictionary *)userInfoForKeyboardNotification { - (void)presentAsKeyboardAnimationDidStop { [[NSNotificationCenter defaultCenter] postNotificationName:UIKeyboardDidShowNotification object:self - userInfo:[self userInfoForKeyboardNotification]]; + userInfo:[self + userInfoForKeyboardNotification]]; } @@ -478,7 +499,8 @@ - (void)presentAsKeyboardAnimationDidStop { - (void)dismissAsKeyboardAnimationDidStop { [[NSNotificationCenter defaultCenter] postNotificationName:UIKeyboardDidHideNotification object:self - userInfo:[self userInfoForKeyboardNotification]]; + userInfo:[self + userInfoForKeyboardNotification]]; [self removeFromSuperview]; } @@ -487,7 +509,8 @@ - (void)dismissAsKeyboardAnimationDidStop { - (void)presentAsKeyboardInView:(UIView*)containingView { [[NSNotificationCenter defaultCenter] postNotificationName:UIKeyboardWillShowNotification object:self - userInfo:[self userInfoForKeyboardNotification]]; + userInfo:[self + userInfoForKeyboardNotification]]; self.top = containingView.height; [containingView addSubview:self]; @@ -505,7 +528,8 @@ - (void)presentAsKeyboardInView:(UIView*)containingView { - (void)dismissAsKeyboard:(BOOL)animated { [[NSNotificationCenter defaultCenter] postNotificationName:UIKeyboardWillHideNotification object:self - userInfo:[self userInfoForKeyboardNotification]]; + userInfo:[self + userInfoForKeyboardNotification]]; if (animated) { [UIView beginAnimations:nil context:nil]; @@ -518,22 +542,11 @@ - (void)dismissAsKeyboard:(BOOL)animated { if (animated) { [UIView commitAnimations]; + } else { [self dismissAsKeyboardAnimationDidStop]; } } -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (UIViewController*)viewController { - for (UIView* next = [self superview]; next; next = next.superview) { - UIResponder* nextResponder = [next nextResponder]; - if ([nextResponder isKindOfClass:[UIViewController class]]) { - return (UIViewController*)nextResponder; - } - } - return nil; -} - - @end diff --git a/src/Three20UI/Sources/UIWebViewAdditions.m b/src/Three20UI/Sources/UIWebViewAdditions.m index eeeaa939ff..f4973f4465 100644 --- a/src/Three20UI/Sources/UIWebViewAdditions.m +++ b/src/Three20UI/Sources/UIWebViewAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20UI/UIWebViewAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + // UI #import "Three20UI/UIViewAdditions.h" @@ -26,6 +29,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UIWebViewAdditions) + @implementation UIWebView (TTCategory) diff --git a/src/Three20UI/Three20UI.xcodeproj/project.pbxproj b/src/Three20UI/Three20UI.xcodeproj/project.pbxproj index 9e72755478..cf04d2a855 100755 --- a/src/Three20UI/Three20UI.xcodeproj/project.pbxproj +++ b/src/Three20UI/Three20UI.xcodeproj/project.pbxproj @@ -3,10 +3,27 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 666E18E912945430001C1D97 /* TTSplitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 666E18E712945430001C1D97 /* TTSplitViewController.m */; }; + 666E18F51294543F001C1D97 /* TTSplitViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 666E18F41294543F001C1D97 /* TTSplitViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66ADC8C91290AC0200855386 /* TTExtensionsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66ADC8C61290AC0200855386 /* TTExtensionsController.m */; }; + 66ADC8CF1290AC1200855386 /* TTExtensionsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 66ADC8CC1290AC1200855386 /* TTExtensionsController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66ADCD9D1291AA7100855386 /* TTExtensionInfoController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66ADCD9B1291AA7100855386 /* TTExtensionInfoController.m */; }; + 66ADCDA31291AA7E00855386 /* TTExtensionInfoController.h in Headers */ = {isa = PBXBuildFile; fileRef = 66ADCDA21291AA7E00855386 /* TTExtensionInfoController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66F2E85412D426A5006FB485 /* TTTableFooterInfiniteScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 66F2E85212D426A5006FB485 /* TTTableFooterInfiniteScrollView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66F2E85712D426AF006FB485 /* TTTableFooterInfiniteScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F2E85512D426AF006FB485 /* TTTableFooterInfiniteScrollView.m */; }; + 66F2E85F12D426DA006FB485 /* TTTableViewNetworkEnabledDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 66F2E85D12D426DA006FB485 /* TTTableViewNetworkEnabledDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66F2E86512D426EF006FB485 /* TTTableViewNetworkEnabledDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F2E86312D426EF006FB485 /* TTTableViewNetworkEnabledDelegate.m */; }; + 6D31FEDB14312683006C6B7F /* TTTableSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D31FEDA14312683006C6B7F /* TTTableSection.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D31FEDD1431268C006C6B7F /* TTTableSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D31FEDC1431268C006C6B7F /* TTTableSection.m */; }; + 6DB1E37D13CA885B00A72466 /* TTLauncherPersistenceMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DB1E37C13CA885B00A72466 /* TTLauncherPersistenceMode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6DD20D35141D0C1B00916A4A /* TTTableSettingsItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DD20D34141D0C1B00916A4A /* TTTableSettingsItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6DD20D37141D0C2800916A4A /* TTTableSettingsItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DD20D36141D0C2800916A4A /* TTTableSettingsItem.m */; }; + 6DD20D39141D0C3A00916A4A /* TTTableSettingsItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DD20D38141D0C3A00916A4A /* TTTableSettingsItemCell.m */; }; + 6DD20D3B141D0C4800916A4A /* TTTableSettingsItemCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DD20D3A141D0C4800916A4A /* TTTableSettingsItemCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E60820111B0C31400C93CD4 /* TTNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E6081FF11B0C31400C93CD4 /* TTNavigationController.m */; }; 6E60820311B0C32600C93CD4 /* TTNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E60820211B0C32600C93CD4 /* TTNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E6454741184D2CD00F08CB1 /* Three20UI.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E6454731184D2CD00F08CB1 /* Three20UI.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -423,6 +440,23 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 666E18E712945430001C1D97 /* TTSplitViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTSplitViewController.m; path = Sources/TTSplitViewController.m; sourceTree = ""; }; + 666E18F41294543F001C1D97 /* TTSplitViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTSplitViewController.h; path = Headers/TTSplitViewController.h; sourceTree = ""; }; + 66ADC8C61290AC0200855386 /* TTExtensionsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTExtensionsController.m; path = Sources/TTExtensionsController.m; sourceTree = ""; }; + 66ADC8CC1290AC1200855386 /* TTExtensionsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTExtensionsController.h; path = Headers/TTExtensionsController.h; sourceTree = ""; }; + 66ADCD9B1291AA7100855386 /* TTExtensionInfoController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTExtensionInfoController.m; path = Sources/TTExtensionInfoController.m; sourceTree = ""; }; + 66ADCDA21291AA7E00855386 /* TTExtensionInfoController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTExtensionInfoController.h; path = Headers/TTExtensionInfoController.h; sourceTree = ""; }; + 66F2E85212D426A5006FB485 /* TTTableFooterInfiniteScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTTableFooterInfiniteScrollView.h; path = Headers/TTTableFooterInfiniteScrollView.h; sourceTree = ""; }; + 66F2E85512D426AF006FB485 /* TTTableFooterInfiniteScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTTableFooterInfiniteScrollView.m; path = Sources/TTTableFooterInfiniteScrollView.m; sourceTree = ""; }; + 66F2E85D12D426DA006FB485 /* TTTableViewNetworkEnabledDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTTableViewNetworkEnabledDelegate.h; path = Headers/TTTableViewNetworkEnabledDelegate.h; sourceTree = ""; }; + 66F2E86312D426EF006FB485 /* TTTableViewNetworkEnabledDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTTableViewNetworkEnabledDelegate.m; path = Sources/TTTableViewNetworkEnabledDelegate.m; sourceTree = ""; }; + 6D31FEDA14312683006C6B7F /* TTTableSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTTableSection.h; path = Headers/TTTableSection.h; sourceTree = ""; }; + 6D31FEDC1431268C006C6B7F /* TTTableSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTTableSection.m; path = Sources/TTTableSection.m; sourceTree = ""; }; + 6DB1E37C13CA885B00A72466 /* TTLauncherPersistenceMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTLauncherPersistenceMode.h; path = Headers/TTLauncherPersistenceMode.h; sourceTree = ""; }; + 6DD20D34141D0C1B00916A4A /* TTTableSettingsItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTTableSettingsItem.h; path = Headers/TTTableSettingsItem.h; sourceTree = ""; }; + 6DD20D36141D0C2800916A4A /* TTTableSettingsItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTTableSettingsItem.m; path = Sources/TTTableSettingsItem.m; sourceTree = ""; }; + 6DD20D38141D0C3A00916A4A /* TTTableSettingsItemCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTTableSettingsItemCell.m; path = Sources/TTTableSettingsItemCell.m; sourceTree = ""; }; + 6DD20D3A141D0C4800916A4A /* TTTableSettingsItemCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTTableSettingsItemCell.h; path = Headers/TTTableSettingsItemCell.h; sourceTree = ""; }; 6E6081FF11B0C31400C93CD4 /* TTNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTNavigationController.m; path = Sources/TTNavigationController.m; sourceTree = ""; }; 6E60820211B0C32600C93CD4 /* TTNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTNavigationController.h; path = Headers/TTNavigationController.h; sourceTree = ""; }; 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Project.xcconfig; path = Configurations/Project.xcconfig; sourceTree = ""; }; @@ -691,7 +725,7 @@ 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; 6EE7389D1184ADB400A35176 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; BEF31F3A0F352DF5000DE5D2 /* libThree20UI.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libThree20UI.a; sourceTree = BUILT_PRODUCTS_DIR; }; - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB9E6C6210B6A8F800DE563C /* UIUnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIUnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -722,7 +756,7 @@ isa = PBXGroup; children = ( BEF31F3A0F352DF5000DE5D2 /* libThree20UI.a */, - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */, + EB9E6C6210B6A8F800DE563C /* UIUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -742,6 +776,26 @@ name = CustomTemplate; sourceTree = ""; }; + 66ADC8C31290ABDD00855386 /* Extensions */ = { + isa = PBXGroup; + children = ( + 66ADC8CC1290AC1200855386 /* TTExtensionsController.h */, + 66ADC8C61290AC0200855386 /* TTExtensionsController.m */, + 66ADCDA21291AA7E00855386 /* TTExtensionInfoController.h */, + 66ADCD9B1291AA7100855386 /* TTExtensionInfoController.m */, + ); + name = Extensions; + sourceTree = ""; + }; + 6D31FED61431266E006C6B7F /* Table Section */ = { + isa = PBXGroup; + children = ( + 6D31FEDA14312683006C6B7F /* TTTableSection.h */, + 6D31FEDC1431268C006C6B7F /* TTTableSection.m */, + ); + name = "Table Section"; + sourceTree = ""; + }; 6E08B274118282F700DA1579 /* Tests */ = { isa = PBXGroup; children = ( @@ -767,7 +821,7 @@ isa = PBXGroup; children = ( 6E6454A71184D42800F08CB1 /* libThree20Style.a */, - 6E6454A91184D42800F08CB1 /* UnitTests.octest */, + 6E6454A91184D42800F08CB1 /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -800,10 +854,13 @@ children = ( 6E6455501184D4C500F08CB1 /* TTViewController.h */, 6E6456791184D4DA00F08CB1 /* TTViewController.m */, + 666E18F41294543F001C1D97 /* TTSplitViewController.h */, + 666E18E712945430001C1D97 /* TTSplitViewController.m */, 6E60820211B0C32600C93CD4 /* TTNavigationController.h */, 6E6081FF11B0C31400C93CD4 /* TTNavigationController.m */, 6E6457A81184D85D00F08CB1 /* Action Sheet Controller */, 6E6457A91184D86F00F08CB1 /* Alert Controller */, + 66ADC8C31290ABDD00855386 /* Extensions */, 6E6457A51184D80F00F08CB1 /* Message Controller */, 6E6457A21184D7D600F08CB1 /* Model Controller */, 6E6457A31184D7E600F08CB1 /* Photo Controller */, @@ -1250,6 +1307,7 @@ 6E6458271184DF1E00F08CB1 /* Tables */ = { isa = PBXGroup; children = ( + 6D31FED61431266E006C6B7F /* Table Section */, 6E6458281184DF5F00F08CB1 /* Table Controller */, 6E6458291184DF6C00F08CB1 /* Table Delegate */, 6E64582C1184DFC500F08CB1 /* Table Data Source */, @@ -1288,6 +1346,8 @@ 6E64565C1184D4DA00F08CB1 /* TTTableViewDragRefreshDelegate.m */, 6E64552D1184D4C500F08CB1 /* TTTableViewGroupedVarHeightDelegate.h */, 6E64565D1184D4DA00F08CB1 /* TTTableViewGroupedVarHeightDelegate.m */, + 66F2E85D12D426DA006FB485 /* TTTableViewNetworkEnabledDelegate.h */, + 66F2E86312D426EF006FB485 /* TTTableViewNetworkEnabledDelegate.m */, 6E64552F1184D4C500F08CB1 /* TTTableViewPlainDelegate.h */, 6E64565F1184D4DA00F08CB1 /* TTTableViewPlainDelegate.m */, 6E6455301184D4C500F08CB1 /* TTTableViewPlainVarHeightDelegate.h */, @@ -1343,6 +1403,8 @@ children = ( 6E6455101184D4C500F08CB1 /* TTTableHeaderView.h */, 6E6456401184D4DA00F08CB1 /* TTTableHeaderView.m */, + 66F2E85212D426A5006FB485 /* TTTableFooterInfiniteScrollView.h */, + 66F2E85512D426AF006FB485 /* TTTableFooterInfiniteScrollView.m */, 6E64550F1184D4C500F08CB1 /* TTTableHeaderDragRefreshView.h */, 6E64563F1184D4DA00F08CB1 /* TTTableHeaderDragRefreshView.m */, ); @@ -1372,6 +1434,8 @@ 6E6458321184E06F00F08CB1 /* Table Items */ = { isa = PBXGroup; children = ( + 6DD20D34141D0C1B00916A4A /* TTTableSettingsItem.h */, + 6DD20D36141D0C2800916A4A /* TTTableSettingsItem.m */, 6E6455061184D4C500F08CB1 /* TTTableActivityItem.h */, 6E6456361184D4DA00F08CB1 /* TTTableActivityItem.m */, 6E6455081184D4C500F08CB1 /* TTTableButton.h */, @@ -1417,6 +1481,8 @@ 6E6458361184E10200F08CB1 /* Table Cells */ = { isa = PBXGroup; children = ( + 6DD20D3A141D0C4800916A4A /* TTTableSettingsItemCell.h */, + 6DD20D38141D0C3A00916A4A /* TTTableSettingsItemCell.m */, 6E6454FE1184D4C500F08CB1 /* TTStyledTextTableCell.h */, 6E64562F1184D4DA00F08CB1 /* TTStyledTextTableCell.m */, 6E6454FF1184D4C500F08CB1 /* TTStyledTextTableItemCell.h */, @@ -1523,6 +1589,7 @@ 6E64583E1184E26500F08CB1 /* Launcher */ = { isa = PBXGroup; children = ( + 6DB1E37C13CA885B00A72466 /* TTLauncherPersistenceMode.h */, 6E6454D61184D4C500F08CB1 /* TTLauncherView.h */, 6E6456121184D4DA00F08CB1 /* TTLauncherView.m */, 6E6454D71184D4C500F08CB1 /* TTLauncherViewDelegate.h */, @@ -1603,7 +1670,7 @@ isa = PBXGroup; children = ( 6EDAEA09118CA5B50008133C /* libThree20UICommon.a */, - 6EDAEA0B118CA5B50008133C /* UnitTests.octest */, + 6EDAEA0B118CA5B50008133C /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -1612,7 +1679,7 @@ isa = PBXGroup; children = ( 6EDAEA12118CA5BE0008133C /* libThree20UINavigator.a */, - 6EDAEA14118CA5BE0008133C /* UnitTests.octest */, + 6EDAEA14118CA5BE0008133C /* UINavigatorUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -1666,7 +1733,7 @@ isa = PBXGroup; children = ( 6EE738A31184ADB400A35176 /* libThree20Network.a */, - 6EE738A51184ADB400A35176 /* UnitTests.octest */, + 6EE738A51184ADB400A35176 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -1816,6 +1883,15 @@ 6E86A8DB118CBF7500662DA5 /* TTNavigatorWindow.h in Headers */, 6E60820311B0C32600C93CD4 /* TTNavigationController.h in Headers */, 6ECCA60011C0C105002296C7 /* TTLauncherHighlightView.h in Headers */, + 66ADC8CF1290AC1200855386 /* TTExtensionsController.h in Headers */, + 66ADCDA31291AA7E00855386 /* TTExtensionInfoController.h in Headers */, + 666E18F51294543F001C1D97 /* TTSplitViewController.h in Headers */, + 66F2E85412D426A5006FB485 /* TTTableFooterInfiniteScrollView.h in Headers */, + 66F2E85F12D426DA006FB485 /* TTTableViewNetworkEnabledDelegate.h in Headers */, + 6DB1E37D13CA885B00A72466 /* TTLauncherPersistenceMode.h in Headers */, + 6DD20D35141D0C1B00916A4A /* TTTableSettingsItem.h in Headers */, + 6DD20D3B141D0C4800916A4A /* TTTableSettingsItemCell.h in Headers */, + 6D31FEDB14312683006C6B7F /* TTTableSection.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1829,6 +1905,7 @@ BEF31F360F352DF5000DE5D2 /* Headers */, 6E645F461187B01F00F08CB1 /* Protect Copied Headers */, BEF31F370F352DF5000DE5D2 /* Sources */, + 668E65E7131ADFCA00ACE4AB /* Lint */, BEF31F380F352DF5000DE5D2 /* Frameworks */, ); buildRules = ( @@ -1845,9 +1922,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libThree20UI.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTests */ = { + EB9E6C6110B6A8F800DE563C /* Three20UIUnitTests */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20UIUnitTests" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -1864,9 +1941,9 @@ 6EDAEA1A118CA5D30008133C /* PBXTargetDependency */, 6EDAEA1C118CA5D30008133C /* PBXTargetDependency */, ); - name = UnitTests; + name = Three20UIUnitTests; productName = CoreUnitTests; - productReference = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + productReference = EB9E6C6210B6A8F800DE563C /* UIUnitTests.octest */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -1874,9 +1951,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0430; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Three20UI" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -1904,7 +1992,7 @@ projectRoot = ""; targets = ( BEF31F390F352DF5000DE5D2 /* Three20UI */, - EB9E6C6110B6A8F800DE563C /* UnitTests */, + EB9E6C6110B6A8F800DE563C /* Three20UIUnitTests */, ); }; /* End PBXProject section */ @@ -1917,10 +2005,10 @@ remoteRef = 6E6454A61184D42800F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E6454A91184D42800F08CB1 /* UnitTests.octest */ = { + 6E6454A91184D42800F08CB1 /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E6454A81184D42800F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1931,10 +2019,10 @@ remoteRef = 6EDAEA08118CA5B50008133C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6EDAEA0B118CA5B50008133C /* UnitTests.octest */ = { + 6EDAEA0B118CA5B50008133C /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6EDAEA0A118CA5B50008133C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1945,10 +2033,10 @@ remoteRef = 6EDAEA11118CA5BE0008133C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6EDAEA14118CA5BE0008133C /* UnitTests.octest */ = { + 6EDAEA14118CA5BE0008133C /* UINavigatorUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UINavigatorUnitTests.octest; remoteRef = 6EDAEA13118CA5BE0008133C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1973,10 +2061,10 @@ remoteRef = 6EE738A21184ADB400A35176 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6EE738A51184ADB400A35176 /* UnitTests.octest */ = { + 6EE738A51184ADB400A35176 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6EE738A41184ADB400A35176 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1993,6 +2081,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 668E65E7131ADFCA00ACE4AB /* Lint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = Lint; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/usr/bin/env python ../scripts/lint"; + shellScript = ""; + showEnvVarsInLog = 0; + }; 6E645F461187B01F00F08CB1 /* Protect Copied Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -2145,6 +2248,14 @@ 6E86A8EC118CBF8E00662DA5 /* TTNavigatorWindow.m in Sources */, 6E60820111B0C31400C93CD4 /* TTNavigationController.m in Sources */, 6ECCA5FE11C0C0F6002296C7 /* TTLauncherHighlightView.m in Sources */, + 66ADC8C91290AC0200855386 /* TTExtensionsController.m in Sources */, + 66ADCD9D1291AA7100855386 /* TTExtensionInfoController.m in Sources */, + 666E18E912945430001C1D97 /* TTSplitViewController.m in Sources */, + 66F2E85712D426AF006FB485 /* TTTableFooterInfiniteScrollView.m in Sources */, + 66F2E86512D426EF006FB485 /* TTTableViewNetworkEnabledDelegate.m in Sources */, + 6DD20D37141D0C2800916A4A /* TTTableSettingsItem.m in Sources */, + 6DD20D39141D0C3A00916A4A /* TTTableSettingsItemCell.m in Sources */, + 6D31FEDD1431268C006C6B7F /* TTTableSection.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2221,14 +2332,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; @@ -2240,9 +2348,10 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; @@ -2250,20 +2359,14 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; - SDKROOT = iphonesimulator4.0; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Internal; @@ -2276,7 +2379,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -2286,8 +2389,7 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -2296,14 +2398,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -2311,13 +2410,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -2325,19 +2422,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Debug; @@ -2346,18 +2437,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - HEADER_SEARCH_PATHS = .; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; ZERO_LINK = NO; }; @@ -2386,7 +2470,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20UIUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/Three20UI/UnitTests/UIGlobalTests.m b/src/Three20UI/UnitTests/UIGlobalTests.m index faea8b68c3..7489c92897 100644 --- a/src/Three20UI/UnitTests/UIGlobalTests.m +++ b/src/Three20UI/UnitTests/UIGlobalTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,8 +14,7 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. +// See: http://bit.ly/hS5nNh for unit test macros. #import #import diff --git a/src/Three20UICommon/Configurations/Library.xcconfig b/src/Three20UICommon/Configurations/Library.xcconfig index 5b3d248c39..ee37b32916 100644 --- a/src/Three20UICommon/Configurations/Library.xcconfig +++ b/src/Three20UICommon/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,5 +17,6 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = Three20UICommon +BASE_PRODUCT_NAME = Three20UICommon +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/src/Three20UICommon/Configurations/Project.xcconfig b/src/Three20UICommon/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/Three20UICommon/Configurations/Project.xcconfig +++ b/src/Three20UICommon/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UICommon/Configurations/UnitTests.xcconfig b/src/Three20UICommon/Configurations/UnitTests.xcconfig index afbd13f072..2ee43463dd 100644 --- a/src/Three20UICommon/Configurations/UnitTests.xcconfig +++ b/src/Three20UICommon/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = UICommonUnitTests -BUILD_BUNDLE_VERSION = 1.0 +BASE_PRODUCT_NAME = UICommonUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME) +BUILD_BUNDLE_VERSION = 1.0 -OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) $(COREGRAPHICS_FX) +OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) $(COREGRAPHICS_FX) diff --git a/src/Three20UICommon/Headers/TTBaseViewController.h b/src/Three20UICommon/Headers/TTBaseViewController.h index 9b5b2c623c..f47136c326 100644 --- a/src/Three20UICommon/Headers/TTBaseViewController.h +++ b/src/Three20UICommon/Headers/TTBaseViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -51,7 +51,8 @@ /** * The style of the status bar when this view controller is appearing. * - * @default UIStatusBarStyleDefault + * @default [[UIApplication sharedApplication] statusBarStyle] via app's info.plist + * */ @property (nonatomic) UIStatusBarStyle statusBarStyle; diff --git a/src/Three20UICommon/Headers/TTGlobalUICommon.h b/src/Three20UICommon/Headers/TTGlobalUICommon.h index 673234a457..a996e0a061 100644 --- a/src/Three20UICommon/Headers/TTGlobalUICommon.h +++ b/src/Three20UICommon/Headers/TTGlobalUICommon.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,6 +22,11 @@ */ float TTOSVersion(); +/** + * Checks if the run-time version of the OS is at least a certain version. + */ +BOOL TTRuntimeOSVersionIsAtLeast(float version); + /** * Checks if the link-time version of the OS is at least a certain version. */ @@ -37,6 +42,11 @@ BOOL TTIsKeyboardVisible(); */ BOOL TTIsPhoneSupported(); +/** + * @return TRUE if the device supports backgrounding + */ +BOOL TTIsMultiTaskingSupported(); + /** * @return TRUE if the device is iPad. */ @@ -47,11 +57,26 @@ BOOL TTIsPad(); */ UIDeviceOrientation TTDeviceOrientation(); +/** + * @return TRUE if the current device orientation is portrait or portrait upside down. + */ +BOOL TTDeviceOrientationIsPortrait(); + +/** + * @return TRUE if the current device orientation is landscape left, or landscape right. + */ +BOOL TTDeviceOrientationIsLandscape(); + +/** + * @return device full model name in human readable strings + */ +NSString* TTDeviceModelName(); + /** * On iPhone/iPod touch * Checks if the orientation is portrait, landscape left, or landscape right. * This helps to ignore upside down and flat orientations. - * + * * On iPad: * Always returns Yes. */ @@ -82,11 +107,21 @@ CGFloat TTToolbarHeightForOrientation(UIInterfaceOrientation orientation); */ CGFloat TTKeyboardHeightForOrientation(UIInterfaceOrientation orientation); +/** + * @return the space between the edge of the screen and a grouped table cell. Larger on iPad. + */ +CGFloat TTGroupedTableCellInset(); + /** * A convenient way to show a UIAlertView with a message. */ void TTAlert(NSString* message); +/** + * Same as TTAlert but the alert view has no title. + */ +void TTAlertNoTitle(NSString* message); + /////////////////////////////////////////////////////////////////////////////////////////////////// // Debug logging helpers @@ -158,8 +193,10 @@ extern const CGFloat ttkGroupedTableCellInset; #define TT_TOOLBAR_HEIGHT ttkDefaultPortraitToolbarHeight #define TT_LANDSCAPE_TOOLBAR_HEIGHT ttkDefaultLandscapeToolbarHeight -#define TT_KEYBOARD_HEIGHT ttkDefaultPortraitKeyboardHeight -#define TT_LANDSCAPE_KEYBOARD_HEIGHT ttkDefaultLandscapeKeyboardHeight +#define TT_KEYBOARD_HEIGHT ttkDefaultPortraitKeyboardHeight +#define TT_LANDSCAPE_KEYBOARD_HEIGHT ttkDefaultLandscapeKeyboardHeight +#define TT_IPAD_KEYBOARD_HEIGHT ttkDefaultPadPortraitKeyboardHeight +#define TT_IPAD_LANDSCAPE_KEYBOARD_HEIGHT ttkDefaultPadLandscapeKeyboardHeight /////////////////////////////////////////////////////////////////////////////////////////////////// // Animation diff --git a/src/Three20UICommon/Headers/Three20UICommon+Additions.h b/src/Three20UICommon/Headers/Three20UICommon+Additions.h index ed72bb4406..94e6b2288c 100644 --- a/src/Three20UICommon/Headers/Three20UICommon+Additions.h +++ b/src/Three20UICommon/Headers/Three20UICommon+Additions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,5 +17,7 @@ #import "Three20UICommon/Three20UICommon.h" // Additions +#import "Three20UICommon/UIView+TTUICommon.h" #import "Three20UICommon/UIViewControllerAdditions.h" +#import "Three20UICommon/UISplitViewController+TTNavigator.h" #import "Three20UICommon/UIWindowAdditions.h" diff --git a/src/Three20UICommon/Headers/Three20UICommon.h b/src/Three20UICommon/Headers/Three20UICommon.h index 081e08bfdd..92e1da5e86 100644 --- a/src/Three20UICommon/Headers/Three20UICommon.h +++ b/src/Three20UICommon/Headers/Three20UICommon.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UICommon/Headers/UISplitViewController+TTNavigator.h b/src/Three20UICommon/Headers/UISplitViewController+TTNavigator.h new file mode 100644 index 0000000000..1a00c57b98 --- /dev/null +++ b/src/Three20UICommon/Headers/UISplitViewController+TTNavigator.h @@ -0,0 +1,22 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@interface UISplitViewController (TTNavigator) + +@end diff --git a/src/Three20UICommon/Headers/UIView+TTUICommon.h b/src/Three20UICommon/Headers/UIView+TTUICommon.h new file mode 100644 index 0000000000..09774d5d38 --- /dev/null +++ b/src/Three20UICommon/Headers/UIView+TTUICommon.h @@ -0,0 +1,27 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@interface UIView (TTUICommon) + +/** + * The view controller whose view contains this view. + */ +- (UIViewController*)viewController; + +@end diff --git a/src/Three20UICommon/Headers/UIViewControllerAdditions.h b/src/Three20UICommon/Headers/UIViewControllerAdditions.h index baf3b71c8e..22e311b083 100644 --- a/src/Three20UICommon/Headers/UIViewControllerAdditions.h +++ b/src/Three20UICommon/Headers/UIViewControllerAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UICommon/Headers/UIViewControllerGarbageCollection.h b/src/Three20UICommon/Headers/UIViewControllerGarbageCollection.h index 611205db6f..48314cf173 100644 --- a/src/Three20UICommon/Headers/UIViewControllerGarbageCollection.h +++ b/src/Three20UICommon/Headers/UIViewControllerGarbageCollection.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UICommon/Headers/UIWindowAdditions.h b/src/Three20UICommon/Headers/UIWindowAdditions.h index cca9bc55f1..0e3a00eb7b 100644 --- a/src/Three20UICommon/Headers/UIWindowAdditions.h +++ b/src/Three20UICommon/Headers/UIWindowAdditions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UICommon/Sources/TTBaseViewController.m b/src/Three20UICommon/Sources/TTBaseViewController.m index 38b5cc8f76..a19e69eedb 100644 --- a/src/Three20UICommon/Sources/TTBaseViewController.m +++ b/src/Three20UICommon/Sources/TTBaseViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -44,9 +44,10 @@ @implementation TTBaseViewController /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { _navigationBarStyle = UIBarStyleDefault; - _statusBarStyle = UIStatusBarStyleDefault; + _statusBarStyle = [[UIApplication sharedApplication] statusBarStyle]; } return self; @@ -55,7 +56,8 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { } return self; @@ -108,6 +110,7 @@ - (void)resizeForKeyboard:(NSNotification*)notification appearing:(BOOL)appearin if (appearing) { [self keyboardWillAppear:animated withBounds:keyboardBounds]; + } else { [self keyboardDidDisappear:animated withBounds:keyboardBounds]; } @@ -154,7 +157,10 @@ - (void)viewWillAppear:(BOOL)animated { UINavigationBar* bar = self.navigationController.navigationBar; bar.tintColor = _navigationBarTintColor; bar.barStyle = _navigationBarStyle; - [[UIApplication sharedApplication] setStatusBarStyle:_statusBarStyle animated:YES]; + + if (!TTIsPad()) { + [[UIApplication sharedApplication] setStatusBarStyle:_statusBarStyle animated:YES]; + } } } @@ -192,6 +198,7 @@ - (void)didReceiveMemoryWarning { - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { if (TTIsPad()) { return YES; + } else { UIViewController* popup = [self popupViewController]; if (popup) { diff --git a/src/Three20UICommon/Sources/TTGlobalUICommon.m b/src/Three20UICommon/Sources/TTGlobalUICommon.m index bab153ffd3..a59efaf11f 100644 --- a/src/Three20UICommon/Sources/TTGlobalUICommon.m +++ b/src/Three20UICommon/Sources/TTGlobalUICommon.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,19 +22,25 @@ // Core #import "Three20Core/TTGlobalCoreLocale.h" -const CGFloat ttkDefaultRowHeight = 44; +#include +#include -const CGFloat ttkDefaultPortraitToolbarHeight = 44; -const CGFloat ttkDefaultLandscapeToolbarHeight = 33; +const CGFloat ttkDefaultRowHeight = 44.0f; -const CGFloat ttkDefaultPortraitKeyboardHeight = 216; -const CGFloat ttkDefaultLandscapeKeyboardHeight = 160; +const CGFloat ttkDefaultPortraitToolbarHeight = 44.0f; +const CGFloat ttkDefaultLandscapeToolbarHeight = 33.0f; -const CGFloat ttkGroupedTableCellInset = 10.0; +const CGFloat ttkDefaultPortraitKeyboardHeight = 216.0f; +const CGFloat ttkDefaultLandscapeKeyboardHeight = 160.0f; +const CGFloat ttkDefaultPadPortraitKeyboardHeight = 264.0f; +const CGFloat ttkDefaultPadLandscapeKeyboardHeight = 352.0f; -const CGFloat ttkDefaultTransitionDuration = 0.3; -const CGFloat ttkDefaultFastTransitionDuration = 0.2; -const CGFloat ttkDefaultFlipTransitionDuration = 0.7; +const CGFloat ttkGroupedTableCellInset = 9.0f; +const CGFloat ttkGroupedPadTableCellInset = 42.0f; + +const CGFloat ttkDefaultTransitionDuration = 0.3f; +const CGFloat ttkDefaultFastTransitionDuration = 0.2f; +const CGFloat ttkDefaultFlipTransitionDuration = 0.7f; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -42,33 +48,52 @@ float TTOSVersion() { return [[[UIDevice currentDevice] systemVersion] floatValue]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL TTRuntimeOSVersionIsAtLeast(float version) { + + static const CGFloat kEpsilon = 0.0000001f; + return TTOSVersion() - version > -kEpsilon; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// BOOL TTOSVersionIsAtLeast(float version) { // Floating-point comparison is pretty bad, so let's cut it some slack with an epsilon. - static const CGFloat kEpsilon = 0.0000001; - - #ifdef __IPHONE_4_0 - return 4.0 - version >= -kEpsilon; - #endif - #ifdef __IPHONE_3_2 - return 3.2 - version >= -kEpsilon; - #endif - #ifdef __IPHONE_3_1 - return 3.1 - version >= -kEpsilon; - #endif - #ifdef __IPHONE_3_0 - return 3.0 - version >= -kEpsilon; - #endif - #ifdef __IPHONE_2_2 - return 2.2 - version >= -kEpsilon; - #endif - #ifdef __IPHONE_2_1 - return 2.1 - version >= -kEpsilon; - #endif - #ifdef __IPHONE_2_0 - return 2.0 - version >= -kEpsilon; - #endif + static const CGFloat kEpsilon = 0.0000001f; + +#ifdef __IPHONE_5_0 + return 5.0 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_4_3 + return 4.3 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_4_2 + return 4.2 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_4_1 + return 4.1 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_4_0 + return 4.0 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_3_2 + return 3.2 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_3_1 + return 3.1 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_3_0 + return 3.0 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_2_2 + return 2.2 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_2_1 + return 2.1 - version >= -kEpsilon; +#endif +#ifdef __IPHONE_2_0 + return 2.0 - version >= -kEpsilon; +#endif return NO; } @@ -88,6 +113,15 @@ BOOL TTIsPhoneSupported() { return [deviceType isEqualToString:@"iPhone"]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL TTIsMultiTaskingSupported() { + UIDevice* device = [UIDevice currentDevice]; + BOOL backgroundSupported = NO; + if ([device respondsToSelector:@selector(isMultitaskingSupported)]){ + backgroundSupported = device.multitaskingSupported; + } + return backgroundSupported; +} /////////////////////////////////////////////////////////////////////////////////////////////////// BOOL TTIsPad() { @@ -101,19 +135,77 @@ BOOL TTIsPad() { /////////////////////////////////////////////////////////////////////////////////////////////////// UIDeviceOrientation TTDeviceOrientation() { - UIDeviceOrientation orient = [UIDevice currentDevice].orientation; + UIDeviceOrientation orient = [[UIDevice currentDevice] orientation]; if (UIDeviceOrientationUnknown == orient) { return UIDeviceOrientationPortrait; + } else { return orient; } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL TTDeviceOrientationIsPortrait() { + UIDeviceOrientation orient = TTDeviceOrientation(); + + switch (orient) { + case UIInterfaceOrientationPortrait: + case UIInterfaceOrientationPortraitUpsideDown: + return YES; + default: + return NO; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL TTDeviceOrientationIsLandscape() { + UIDeviceOrientation orient = TTDeviceOrientation(); + + switch (orient) { + case UIInterfaceOrientationLandscapeLeft: + case UIInterfaceOrientationLandscapeRight: + return YES; + default: + return NO; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +NSString* TTDeviceModelName() { + size_t size; + sysctlbyname("hw.machine", NULL, &size, NULL, 0); + char *machine = malloc(size); + sysctlbyname("hw.machine", machine, &size, NULL, 0); + NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding]; + free(machine); + + if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 1G"; + if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G"; + if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS"; + if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4 (GSM)"; + if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4 (CDMA)"; + if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G"; + if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G"; + if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G"; + if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G"; + if ([platform isEqualToString:@"iPad1,1"]) return @"iPad"; + if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)"; + if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2 (GSM)"; + if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)"; + if ([platform isEqualToString:@"i386"]) return @"Simulator"; + + return platform; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// BOOL TTIsSupportedOrientation(UIInterfaceOrientation orientation) { if (TTIsPad()) { return YES; + } else { switch (orientation) { case UIInterfaceOrientationPortrait: @@ -131,10 +223,13 @@ BOOL TTIsSupportedOrientation(UIInterfaceOrientation orientation) { CGAffineTransform TTRotateTransformForOrientation(UIInterfaceOrientation orientation) { if (orientation == UIInterfaceOrientationLandscapeLeft) { return CGAffineTransformMakeRotation(M_PI*1.5); + } else if (orientation == UIInterfaceOrientationLandscapeRight) { return CGAffineTransformMakeRotation(M_PI/2); + } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { return CGAffineTransformMakeRotation(-M_PI); + } else { return CGAffineTransformIdentity; } @@ -150,8 +245,9 @@ CGRect TTApplicationFrame() { /////////////////////////////////////////////////////////////////////////////////////////////////// CGFloat TTToolbarHeightForOrientation(UIInterfaceOrientation orientation) { - if (UIInterfaceOrientationIsPortrait(orientation)) { + if (UIInterfaceOrientationIsPortrait(orientation) || TTIsPad()) { return TT_ROW_HEIGHT; + } else { return TT_LANDSCAPE_TOOLBAR_HEIGHT; } @@ -160,14 +256,22 @@ CGFloat TTToolbarHeightForOrientation(UIInterfaceOrientation orientation) { /////////////////////////////////////////////////////////////////////////////////////////////////// CGFloat TTKeyboardHeightForOrientation(UIInterfaceOrientation orientation) { - if (UIInterfaceOrientationIsPortrait(orientation)) { - return TT_KEYBOARD_HEIGHT; + if (TTIsPad()) { + return UIInterfaceOrientationIsPortrait(orientation) ? TT_IPAD_KEYBOARD_HEIGHT + : TT_IPAD_LANDSCAPE_KEYBOARD_HEIGHT; + } else { - return TT_LANDSCAPE_KEYBOARD_HEIGHT; + return UIInterfaceOrientationIsPortrait(orientation) ? TT_KEYBOARD_HEIGHT + : TT_LANDSCAPE_KEYBOARD_HEIGHT; } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +CGFloat TTGroupedTableCellInset() { + return TTIsPad() ? ttkGroupedPadTableCellInset : ttkGroupedTableCellInset; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// void TTAlert(NSString* message) { UIAlertView* alert = [[[UIAlertView alloc] initWithTitle:TTLocalizedString(@"Alert", @"") @@ -176,3 +280,14 @@ void TTAlert(NSString* message) { otherButtonTitles:nil] autorelease]; [alert show]; } + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +void TTAlertNoTitle(NSString* message) { + UIAlertView* alert = [[[UIAlertView alloc] initWithTitle:nil + message:message + delegate:nil + cancelButtonTitle:TTLocalizedString(@"OK", @"") + otherButtonTitles:nil] autorelease]; + [alert show]; +} diff --git a/src/Three20UICommon/Sources/UISplitViewController+TTNavigator.m b/src/Three20UICommon/Sources/UISplitViewController+TTNavigator.m new file mode 100644 index 0000000000..29bcc2fd9f --- /dev/null +++ b/src/Three20UICommon/Sources/UISplitViewController+TTNavigator.m @@ -0,0 +1,49 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "UISplitViewController+TTNavigator.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +TT_FIX_CATEGORY_BUG(UISplitViewController_TTNavigator) + +@implementation UISplitViewController (TTNavigator) + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)canContainControllers { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)canBeTopViewController { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UIViewController*)superController { + return nil; +} + + +@end diff --git a/src/Three20UICommon/Sources/UIView+TTUICommon.m b/src/Three20UICommon/Sources/UIView+TTUICommon.m new file mode 100644 index 0000000000..d1a360314a --- /dev/null +++ b/src/Three20UICommon/Sources/UIView+TTUICommon.m @@ -0,0 +1,47 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "UIView+TTUICommon.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Additions. + */ +TT_FIX_CATEGORY_BUG(UIView_TTUICommon) + +@implementation UIView (TTUICommon) + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UIViewController*)viewController { + for (UIView* next = [self superview]; next; next = next.superview) { + UIResponder* nextResponder = [next nextResponder]; + if ([nextResponder isKindOfClass:[UIViewController class]]) { + return (UIViewController*)nextResponder; + } + } + return nil; +} + + +@end + diff --git a/src/Three20UICommon/Sources/UIViewControllerAdditions.m b/src/Three20UICommon/Sources/UIViewControllerAdditions.m index 283033d764..dbc7fbb6f4 100644 --- a/src/Three20UICommon/Sources/UIViewControllerAdditions.m +++ b/src/Three20UICommon/Sources/UIViewControllerAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -42,6 +42,11 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Additions. + */ +TT_FIX_CATEGORY_BUG(UIViewControllerAdditions) + @implementation UIViewController (TTCategory) @@ -116,6 +121,7 @@ + (void)ttAddCommonController:(UIViewController*)controller { repeats: YES] retain]; } #if TTDFLAG_CONTROLLERGARBAGECOLLECTION + } else { TTDCONDITIONLOG(TTDFLAG_CONTROLLERGARBAGECOLLECTION, @"Not adding a common controller."); @@ -293,12 +299,22 @@ - (void)delayDidEnd { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)showBars:(BOOL)show animated:(BOOL)animated { -#ifdef __IPHONE_3_2 - if ([[UIApplication sharedApplication] respondsToSelector:@selector(setStatusBarHidden:withAnimation:)]) - [[UIApplication sharedApplication] setStatusBarHidden:!show withAnimation:animated ? UIStatusBarAnimationFade : UIStatusBarAnimationNone]; - else -#endif - [[UIApplication sharedApplication] setStatusBarHidden:!show animated:animated]; + + BOOL statusBarHidden = [[[[NSBundle mainBundle] infoDictionary] + objectForKey:@"UIStatusBarHidden"] boolValue]; + + if (!statusBarHidden) { + #ifdef __IPHONE_3_2 + if ([[UIApplication sharedApplication] + respondsToSelector:@selector(setStatusBarHidden:withAnimation:)]) + [[UIApplication sharedApplication] setStatusBarHidden:!show + withAnimation:(animated + ? UIStatusBarAnimationFade + :UIStatusBarAnimationNone)]; + else + #endif + [[UIApplication sharedApplication] setStatusBarHidden:!show animated:animated]; + } if (animated) { [UIView beginAnimations:nil context:NULL]; @@ -346,7 +362,7 @@ + (void)doGarbageCollectionWithSelector:(SEL)selector controllerSet:(NSMutableSe NSInteger retainCount = [controller retainCount] - 1; TTDCONDITIONLOG(TTDFLAG_CONTROLLERGARBAGECOLLECTION, - @"Retain count for %X is %d", controller, retainCount); + @"Retain count for %X is %d", (unsigned int)controller, retainCount); if (retainCount == 1) { // If this fails, you've somehow added a controller that doesn't use @@ -370,7 +386,7 @@ + (void)doGarbageCollectionWithSelector:(SEL)selector controllerSet:(NSMutableSe /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)unsetCommonProperties { TTDCONDITIONLOG(TTDFLAG_CONTROLLERGARBAGECOLLECTION, - @"Unsetting this controller's properties: %X", self); + @"Unsetting this controller's properties: %X", (unsigned int)self); self.superController = nil; self.popupViewController = nil; diff --git a/src/Three20UICommon/Sources/UIWindowAdditions.m b/src/Three20UICommon/Sources/UIWindowAdditions.m index ccc64c3d13..0cd0c406b4 100644 --- a/src/Three20UICommon/Sources/UIWindowAdditions.m +++ b/src/Three20UICommon/Sources/UIWindowAdditions.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #import "Three20UICommon/UIWindowAdditions.h" +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -23,6 +26,8 @@ /** * Additions. */ +TT_FIX_CATEGORY_BUG(UIWindowAdditions) + @implementation UIWindow (TTCategory) diff --git a/src/Three20UICommon/Three20UICommon.xcodeproj/project.pbxproj b/src/Three20UICommon/Three20UICommon.xcodeproj/project.pbxproj index 4aed3e6f11..70dbeee246 100755 --- a/src/Three20UICommon/Three20UICommon.xcodeproj/project.pbxproj +++ b/src/Three20UICommon/Three20UICommon.xcodeproj/project.pbxproj @@ -3,10 +3,14 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 666E16BF12944956001C1D97 /* UISplitViewController+TTNavigator.h in Headers */ = {isa = PBXBuildFile; fileRef = 666E16BB12944956001C1D97 /* UISplitViewController+TTNavigator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 666E16C012944956001C1D97 /* UIView+TTUICommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 666E16BC12944956001C1D97 /* UIView+TTUICommon.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 666E16C512944961001C1D97 /* UISplitViewController+TTNavigator.m in Sources */ = {isa = PBXBuildFile; fileRef = 666E16C112944961001C1D97 /* UISplitViewController+TTNavigator.m */; }; + 666E16C612944961001C1D97 /* UIView+TTUICommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 666E16C212944961001C1D97 /* UIView+TTUICommon.m */; }; 6E3C377F118C94E50079637E /* TTGlobalUICommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E3C377E118C94E50079637E /* TTGlobalUICommon.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E3C3781118C94FC0079637E /* TTGlobalUICommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E3C3780118C94FC0079637E /* TTGlobalUICommon.m */; }; 6E3C37A9118C96670079637E /* UIWindowAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E3C37A8118C96670079637E /* UIWindowAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -63,6 +67,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 666E16BB12944956001C1D97 /* UISplitViewController+TTNavigator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UISplitViewController+TTNavigator.h"; path = "Headers/UISplitViewController+TTNavigator.h"; sourceTree = ""; }; + 666E16BC12944956001C1D97 /* UIView+TTUICommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView+TTUICommon.h"; path = "Headers/UIView+TTUICommon.h"; sourceTree = ""; }; + 666E16C112944961001C1D97 /* UISplitViewController+TTNavigator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UISplitViewController+TTNavigator.m"; path = "Sources/UISplitViewController+TTNavigator.m"; sourceTree = ""; }; + 666E16C212944961001C1D97 /* UIView+TTUICommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+TTUICommon.m"; path = "Sources/UIView+TTUICommon.m"; sourceTree = ""; }; 6E3C377E118C94E50079637E /* TTGlobalUICommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTGlobalUICommon.h; path = Headers/TTGlobalUICommon.h; sourceTree = ""; }; 6E3C3780118C94FC0079637E /* TTGlobalUICommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTGlobalUICommon.m; path = Sources/TTGlobalUICommon.m; sourceTree = ""; }; 6E3C37A8118C96670079637E /* UIWindowAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UIWindowAdditions.h; path = Headers/UIWindowAdditions.h; sourceTree = ""; }; @@ -84,7 +92,7 @@ 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = UnitTests.xcconfig; path = Configurations/UnitTests.xcconfig; sourceTree = ""; }; 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; BEF31F3A0F352DF5000DE5D2 /* libThree20UICommon.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libThree20UICommon.a; sourceTree = BUILT_PRODUCTS_DIR; }; - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB9E6C6210B6A8F800DE563C /* UICommonUnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UICommonUnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -111,7 +119,7 @@ isa = PBXGroup; children = ( BEF31F3A0F352DF5000DE5D2 /* libThree20UICommon.a */, - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */, + EB9E6C6210B6A8F800DE563C /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -153,6 +161,10 @@ 6E3C37AF118C967B0079637E /* Additions */ = { isa = PBXGroup; children = ( + 666E16BB12944956001C1D97 /* UISplitViewController+TTNavigator.h */, + 666E16C112944961001C1D97 /* UISplitViewController+TTNavigator.m */, + 666E16BC12944956001C1D97 /* UIView+TTUICommon.h */, + 666E16C212944961001C1D97 /* UIView+TTUICommon.m */, 6E3C37D5118C97040079637E /* UIViewControllerAdditions.h */, 6E3C37D0118C96FA0079637E /* UIViewControllerAdditions.m */, 6E7B116A11924443001359FE /* Private */, @@ -231,6 +243,8 @@ 6EDAE96A118C99580008133C /* Three20UICommon+Additions.h in Headers */, 6E7B103B119235CF001359FE /* TTBaseViewController.h in Headers */, 6E7B116911924440001359FE /* UIViewControllerGarbageCollection.h in Headers */, + 666E16BF12944956001C1D97 /* UISplitViewController+TTNavigator.h in Headers */, + 666E16C012944956001C1D97 /* UIView+TTUICommon.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -244,6 +258,7 @@ BEF31F360F352DF5000DE5D2 /* Headers */, 6E645F461187B01F00F08CB1 /* Protect Copied Headers */, BEF31F370F352DF5000DE5D2 /* Sources */, + 668E6601131ADFDB00ACE4AB /* Lint */, BEF31F380F352DF5000DE5D2 /* Frameworks */, ); buildRules = ( @@ -256,9 +271,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libThree20UICommon.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTests */ = { + EB9E6C6110B6A8F800DE563C /* Three20UICommonUnitTests */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20UICommonUnitTests" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -271,9 +286,9 @@ 6EE736C511849F9D00A35176 /* PBXTargetDependency */, 6EE736C711849FA000A35176 /* PBXTargetDependency */, ); - name = UnitTests; + name = Three20UICommonUnitTests; productName = CoreUnitTests; - productReference = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + productReference = EB9E6C6210B6A8F800DE563C /* UICommonUnitTests.octest */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -281,9 +296,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Three20UICommon" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -295,7 +321,7 @@ projectRoot = ""; targets = ( BEF31F390F352DF5000DE5D2 /* Three20UICommon */, - EB9E6C6110B6A8F800DE563C /* UnitTests */, + EB9E6C6110B6A8F800DE563C /* Three20UICommonUnitTests */, ); }; /* End PBXProject section */ @@ -328,6 +354,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 668E6601131ADFDB00ACE4AB /* Lint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = Lint; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/usr/bin/env python ../scripts/lint"; + shellScript = ""; + showEnvVarsInLog = 0; + }; 6E645F461187B01F00F08CB1 /* Protect Copied Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -366,6 +407,8 @@ 6E3C37AD118C96700079637E /* UIWindowAdditions.m in Sources */, 6E3C37D1118C96FA0079637E /* UIViewControllerAdditions.m in Sources */, 6E7B1039119235BF001359FE /* TTBaseViewController.m in Sources */, + 666E16C512944961001C1D97 /* UISplitViewController+TTNavigator.m in Sources */, + 666E16C612944961001C1D97 /* UIView+TTUICommon.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -403,14 +446,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; @@ -422,9 +462,10 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; @@ -432,20 +473,14 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; - SDKROOT = iphonesimulator4.0; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Internal; @@ -458,7 +493,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -468,8 +503,7 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -478,14 +512,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -493,13 +524,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -507,19 +536,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Debug; @@ -528,18 +551,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - HEADER_SEARCH_PATHS = .; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; ZERO_LINK = NO; }; @@ -568,7 +584,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20UICommonUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/Three20UICommon/UnitTests/UICommonTests.m b/src/Three20UICommon/UnitTests/UICommonTests.m index 9919ec2243..fc4e2f58fb 100644 --- a/src/Three20UICommon/UnitTests/UICommonTests.m +++ b/src/Three20UICommon/UnitTests/UICommonTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,8 +14,7 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. +// See: http://bit.ly/hS5nNh for unit test macros. #import @@ -42,6 +41,24 @@ - (void)testTTOSVersion { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)testTTOSVersionIsAtLeast { +#ifdef __IPHONE_4_2 + STAssertTrue(TTOSVersionIsAtLeast(4.2), @"Should be at least 4.2."); +#else + STAssertTrue(!TTOSVersionIsAtLeast(4.2), @"Should be lower than 4.2."); +#endif + +#ifdef __IPHONE_4_1 + STAssertTrue(TTOSVersionIsAtLeast(4.1), @"Should be at least 4.1."); +#else + STAssertTrue(!TTOSVersionIsAtLeast(4.1), @"Should be lower than 4.1."); +#endif + +#ifdef __IPHONE_4_0 + STAssertTrue(TTOSVersionIsAtLeast(4.0), @"Should be at least 4.0."); +#else + STAssertTrue(!TTOSVersionIsAtLeast(4.0), @"Should be lower than 4.0."); +#endif + #ifdef __IPHONE_3_2 STAssertTrue(TTOSVersionIsAtLeast(3.2), @"Should be at least 3.2."); #else diff --git a/src/Three20UICommon/UnitTests/UIViewControllerAdditionTests.m b/src/Three20UICommon/UnitTests/UIViewControllerAdditionTests.m index 580bc44e9e..691bbfa942 100644 --- a/src/Three20UICommon/UnitTests/UIViewControllerAdditionTests.m +++ b/src/Three20UICommon/UnitTests/UIViewControllerAdditionTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,8 +14,8 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. + +// See: http://bit.ly/hS5nNh for unit test macros. #import diff --git a/src/Three20UINavigator/Configurations/Library.xcconfig b/src/Three20UINavigator/Configurations/Library.xcconfig index b3a818bf81..9e9db5b427 100644 --- a/src/Three20UINavigator/Configurations/Library.xcconfig +++ b/src/Three20UINavigator/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,5 +17,6 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = Three20UINavigator +BASE_PRODUCT_NAME = Three20UINavigator +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 diff --git a/src/Three20UINavigator/Configurations/Project.xcconfig b/src/Three20UINavigator/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/Three20UINavigator/Configurations/Project.xcconfig +++ b/src/Three20UINavigator/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Configurations/UnitTests.xcconfig b/src/Three20UINavigator/Configurations/UnitTests.xcconfig index e1941498c2..06c175fff4 100644 --- a/src/Three20UINavigator/Configurations/UnitTests.xcconfig +++ b/src/Three20UINavigator/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = UINavigatorUnitTests -BUILD_BUNDLE_VERSION = 1.0 +BASE_PRODUCT_NAME = UINavigatorUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME) +BUILD_BUNDLE_VERSION = 1.0 -OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) $(COREGRAPHICS_FX) +OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) diff --git a/src/Three20UINavigator/Headers/TTBaseNavigationController.h b/src/Three20UINavigator/Headers/TTBaseNavigationController.h index a22102b69b..5c56d08ca0 100644 --- a/src/Three20UINavigator/Headers/TTBaseNavigationController.h +++ b/src/Three20UINavigator/Headers/TTBaseNavigationController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTBaseNavigator.h b/src/Three20UINavigator/Headers/TTBaseNavigator.h index bf0b0a4674..94ba535adb 100644 --- a/src/Three20UINavigator/Headers/TTBaseNavigator.h +++ b/src/Three20UINavigator/Headers/TTBaseNavigator.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ #import "Three20UINavigator/TTNavigatorPersistenceMode.h" @protocol TTNavigatorDelegate; +@protocol TTNavigatorRootContainer; @class TTURLAction; @class TTURLMap; @class TTURLPattern; @@ -27,14 +28,18 @@ /** * A URL-based navigation system with built-in persistence. */ -@interface TTBaseNavigator : NSObject { +@interface TTBaseNavigator : NSObject < + UIPopoverControllerDelegate +> { TTURLMap* _URLMap; UIWindow* _window; UIViewController* _rootViewController; NSMutableArray* _delayedControllers; + id _popoverController; + NSString* _persistenceKey; TTNavigatorPersistenceMode _persistenceMode; NSTimeInterval _persistenceExpirationAge; @@ -43,7 +48,8 @@ BOOL _supportsShakeToReload; BOOL _opensExternalURLs; - id _delegate; + id _delegate; + id _rootContainer; } /** @@ -61,6 +67,15 @@ */ @property (nonatomic, retain) UIWindow* window; +/** + * A container that holds the root view controller. + * + * If nil, the window is treated as the root container. + * + * @default nil + */ +@property (nonatomic, assign) id rootContainer; + /** * The controller that is at the root of the view controller hierarchy. */ @@ -86,6 +101,18 @@ */ @property (nonatomic, copy) NSString* URL; +/** + * The key to use for storing persistence information. + * + * Three bits of information are stored for persistence. + * If a key name is given, these values will first be stored within a dictionary and + * then persisted with the given key name. + * If a key name is not given, the values are stored individually. + * + * @default nil + */ +@property (nonatomic, copy) NSString* persistenceKey; + /** * How view controllers are automatically persisted on termination and restored on launch. * @@ -129,6 +156,22 @@ @property (nonatomic, assign) id delegate; +/** + * Determines the navigator that contains this view. + * + * Traverse the view hierarchy until the root view container is reached. If this root container + * conforms to the TTNavigatorRootContainer protocol, we call getNavigatorForController: + * with the top-most controller that contains this view that /isn't/ the container. + * If getNavigatorForController: returns a navigator, this navigator is returned. + * Otherwise, the global navigator is returned. + * + * If the given view is not, in fact, a view, which is the case if a UIBarButtonItem is passed, + * returns the global navigator via [TTBaseNavigator globalNavigator]. + * + * If you need to use a specific navigator for UIBarButtonItem, handle the button tap + * yourself and use navigatorForView: on an actual view in the controller. + */ ++ (TTBaseNavigator*)navigatorForView:(UIView*)view; + (TTBaseNavigator*)globalNavigator; + (void)setGlobalNavigator:(TTBaseNavigator*)navigator; diff --git a/src/Three20UINavigator/Headers/TTBaseNavigatorInternal.h b/src/Three20UINavigator/Headers/TTBaseNavigatorInternal.h index ad6a7d151e..f2e2b7ff6b 100644 --- a/src/Three20UINavigator/Headers/TTBaseNavigatorInternal.h +++ b/src/Three20UINavigator/Headers/TTBaseNavigatorInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,8 +21,7 @@ - (void)presentDependantController: (UIViewController*)controller parentController: (UIViewController*)parentController mode: (TTNavigationMode)mode - animated: (BOOL)animated - transition: (NSInteger)transition; + action: (TTURLAction*)action; - (UIViewController*)getVisibleChildController:(UIViewController*)controller; diff --git a/src/Three20UINavigator/Headers/TTGlobalNavigatorMetrics.h b/src/Three20UINavigator/Headers/TTGlobalNavigatorMetrics.h index 011ae2f5f7..26ac0b09af 100644 --- a/src/Three20UINavigator/Headers/TTGlobalNavigatorMetrics.h +++ b/src/Three20UINavigator/Headers/TTGlobalNavigatorMetrics.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTNavigationMode.h b/src/Three20UINavigator/Headers/TTNavigationMode.h index 8168990c70..9d6f9dda6b 100644 --- a/src/Three20UINavigator/Headers/TTNavigationMode.h +++ b/src/Three20UINavigator/Headers/TTNavigationMode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,5 +19,6 @@ typedef enum { TTNavigationModeCreate, // a new view controller is created each time TTNavigationModeShare, // a new view controller is created, cached and re-used TTNavigationModeModal, // a new view controller is created and presented modally + TTNavigationModePopover, // a new view controller is created and presented in a popover TTNavigationModeExternal, // an external app will be opened } TTNavigationMode; diff --git a/src/Three20UINavigator/Headers/TTNavigatorDelegate.h b/src/Three20UINavigator/Headers/TTNavigatorDelegate.h index 3dfdf00bdc..604f6866ef 100644 --- a/src/Three20UINavigator/Headers/TTNavigatorDelegate.h +++ b/src/Three20UINavigator/Headers/TTNavigatorDelegate.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTNavigatorPersistenceMode.h b/src/Three20UINavigator/Headers/TTNavigatorPersistenceMode.h index 023255df22..6d68e2cb68 100644 --- a/src/Three20UINavigator/Headers/TTNavigatorPersistenceMode.h +++ b/src/Three20UINavigator/Headers/TTNavigatorPersistenceMode.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTNavigatorRootContainer.h b/src/Three20UINavigator/Headers/TTNavigatorRootContainer.h new file mode 100644 index 0000000000..5752fe1408 --- /dev/null +++ b/src/Three20UINavigator/Headers/TTNavigatorRootContainer.h @@ -0,0 +1,30 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@class TTBaseNavigator; + +@protocol TTNavigatorRootContainer + +@required + +- (void)navigator:(TTBaseNavigator*)navigator setRootViewController:(UIViewController*)controller; + +- (TTBaseNavigator*)getNavigatorForController:(UIViewController*)controller; + +@end + diff --git a/src/Three20UINavigator/Headers/TTNavigatorViewController.h b/src/Three20UINavigator/Headers/TTNavigatorViewController.h index e5ea0eef53..077c006946 100644 --- a/src/Three20UINavigator/Headers/TTNavigatorViewController.h +++ b/src/Three20UINavigator/Headers/TTNavigatorViewController.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTURLAction.h b/src/Three20UINavigator/Headers/TTURLAction.h index 770da05217..cc4741a291 100644 --- a/src/Three20UINavigator/Headers/TTURLAction.h +++ b/src/Three20UINavigator/Headers/TTURLAction.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -37,29 +37,43 @@ BOOL _animated; BOOL _withDelay; + CGRect _sourceRect; + UIView* _sourceView; + UIBarButtonItem* _sourceButton; + UIViewAnimationTransition _transition; } @property (nonatomic, copy) NSString* urlPath; @property (nonatomic, copy) NSString* parentURLPath; -@property (nonatomic, retain) NSDictionary* query; -@property (nonatomic, retain) NSDictionary* state; +@property (nonatomic, copy) NSDictionary* query; +@property (nonatomic, copy) NSDictionary* state; @property (nonatomic, assign) BOOL animated; @property (nonatomic, assign) BOOL withDelay; +@property (nonatomic, assign) CGRect sourceRect; +@property (nonatomic, retain) UIView* sourceView; +@property (nonatomic, retain) UIBarButtonItem* sourceButton; @property (nonatomic, assign) UIViewAnimationTransition transition; /** - * Create an autoreleased TTURLAction object with a URL path. The path is required. + * Create an autoreleased TTURLAction object. + */ ++ (id)action; + +/** + * Create an autoreleased TTURLAction object with a URL path. */ + (id)actionWithURLPath:(NSString*)urlPath; /** - * Initialize a TTURLAction object with a URL path. The path is required. + * Initialize a TTURLAction object with a URL path. * * Designated initializer. */ - (id)initWithURLPath:(NSString*)urlPath; +- (id)init; + /** * @default nil */ @@ -85,6 +99,21 @@ */ - (TTURLAction*)applyWithDelay:(BOOL)withDelay; +/** + * @default CGRectZero + */ +- (TTURLAction*)applySourceRect:(CGRect)sourceRect; + +/** + * @default nil + */ +- (TTURLAction*)applySourceView:(UIView*)sourceView; + +/** + * @default nil + */ +- (TTURLAction*)applySourceButton:(UIBarButtonItem*)sourceButton; + /** * @default UIViewAnimationTransitionNone */ diff --git a/src/Three20UINavigator/Headers/TTURLArgumentType.h b/src/Three20UINavigator/Headers/TTURLArgumentType.h index 612b9483fa..926e370a22 100644 --- a/src/Three20UINavigator/Headers/TTURLArgumentType.h +++ b/src/Three20UINavigator/Headers/TTURLArgumentType.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTURLArguments.h b/src/Three20UINavigator/Headers/TTURLArguments.h index 5704e7c380..5938233aed 100644 --- a/src/Three20UINavigator/Headers/TTURLArguments.h +++ b/src/Three20UINavigator/Headers/TTURLArguments.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTURLGeneratorPattern.h b/src/Three20UINavigator/Headers/TTURLGeneratorPattern.h index 85681c68b2..f542cb0abc 100644 --- a/src/Three20UINavigator/Headers/TTURLGeneratorPattern.h +++ b/src/Three20UINavigator/Headers/TTURLGeneratorPattern.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ Class _targetClass; } -@property (nonatomic) Class targetClass; +@property (nonatomic, assign) Class targetClass; - (id)initWithTargetClass:(Class)targetClass; diff --git a/src/Three20UINavigator/Headers/TTURLLiteral.h b/src/Three20UINavigator/Headers/TTURLLiteral.h index 0097072944..5825d39f54 100644 --- a/src/Three20UINavigator/Headers/TTURLLiteral.h +++ b/src/Three20UINavigator/Headers/TTURLLiteral.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTURLMap.h b/src/Three20UINavigator/Headers/TTURLMap.h index d8fe42df58..915d0e3aa5 100644 --- a/src/Three20UINavigator/Headers/TTURLMap.h +++ b/src/Three20UINavigator/Headers/TTURLMap.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -42,6 +42,13 @@ */ - (void)from:(NSString*)URL toObject:(id)object; - (void)from:(NSString*)URL toObject:(id)object selector:(SEL)selector; +/** + * Specifies the navigation mode to use. If TTNavigationModeCreate, TTNavigationModeShared + * are used, then if this URL is referenced from a table - ie TTTableLinkedItem or + * one of it's subclasses - a disclosure button will be added. + */ +- (void)from:(NSString*)URL toObject:(id)target selector:(SEL)selector + mode:(TTNavigationMode)mode; /** * Adds a URL pattern which will create and present a view controller when loaded. @@ -82,6 +89,9 @@ - (void)from:(NSString*)URL parent:(NSString*)parentURL toModalViewController:(id)target selector:(SEL)selector transition:(NSInteger)transition; +- (void)from:(NSString*)URL toPopoverViewController:(id)target; +- (void)from:(NSString*)URL toPopoverViewController:(id)target selector:(SEL)selector; + /** * Adds a mapping from a class to a generated URL. */ diff --git a/src/Three20UINavigator/Headers/TTURLNavigatorPattern.h b/src/Three20UINavigator/Headers/TTURLNavigatorPattern.h index d73a01e65e..bcb351142e 100644 --- a/src/Three20UINavigator/Headers/TTURLNavigatorPattern.h +++ b/src/Three20UINavigator/Headers/TTURLNavigatorPattern.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,12 +27,12 @@ NSInteger _argumentCount; } -@property (nonatomic) Class targetClass; +@property (nonatomic, assign) Class targetClass; @property (nonatomic, assign) id targetObject; @property (nonatomic, readonly) TTNavigationMode navigationMode; @property (nonatomic, copy) NSString* parentURL; -@property (nonatomic) NSInteger transition; -@property (nonatomic) NSInteger argumentCount; +@property (nonatomic, assign) NSInteger transition; +@property (nonatomic, assign) NSInteger argumentCount; @property (nonatomic, readonly) BOOL isUniversal; @property (nonatomic, readonly) BOOL isFragment; @@ -44,6 +44,12 @@ - (BOOL)matchURL:(NSURL*)URL; - (id)invoke:(id)target withURL:(NSURL*)URL query:(NSDictionary*)query; + +/** + * either instantiates an object or delegates object creation + * depending on current configuration + * @return the newly created object or nil if something went wrong + */ - (id)createObjectFromURL:(NSURL*)URL query:(NSDictionary*)query; @end diff --git a/src/Three20UINavigator/Headers/TTURLObject.h b/src/Three20UINavigator/Headers/TTURLObject.h index 29575fc8e6..71791bde76 100644 --- a/src/Three20UINavigator/Headers/TTURLObject.h +++ b/src/Three20UINavigator/Headers/TTURLObject.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTURLPattern.h b/src/Three20UINavigator/Headers/TTURLPattern.h index 5e7bf2d9aa..859e422eb7 100644 --- a/src/Three20UINavigator/Headers/TTURLPattern.h +++ b/src/Three20UINavigator/Headers/TTURLPattern.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTURLPatternInternal.h b/src/Three20UINavigator/Headers/TTURLPatternInternal.h index 3bd67a3079..53e19ceba1 100644 --- a/src/Three20UINavigator/Headers/TTURLPatternInternal.h +++ b/src/Three20UINavigator/Headers/TTURLPatternInternal.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTURLPatternText.h b/src/Three20UINavigator/Headers/TTURLPatternText.h index 998a72446e..7142d36af3 100644 --- a/src/Three20UINavigator/Headers/TTURLPatternText.h +++ b/src/Three20UINavigator/Headers/TTURLPatternText.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTURLSelector.h b/src/Three20UINavigator/Headers/TTURLSelector.h index d49fe73085..563e34ba34 100644 --- a/src/Three20UINavigator/Headers/TTURLSelector.h +++ b/src/Three20UINavigator/Headers/TTURLSelector.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/TTURLWildcard.h b/src/Three20UINavigator/Headers/TTURLWildcard.h index 0a2ab59898..2eb5e78a09 100644 --- a/src/Three20UINavigator/Headers/TTURLWildcard.h +++ b/src/Three20UINavigator/Headers/TTURLWildcard.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/Three20UINavigator+Additions.h b/src/Three20UINavigator/Headers/Three20UINavigator+Additions.h index a7651e36d9..e202f78771 100644 --- a/src/Three20UINavigator/Headers/Three20UINavigator+Additions.h +++ b/src/Three20UINavigator/Headers/Three20UINavigator+Additions.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Headers/Three20UINavigator.h b/src/Three20UINavigator/Headers/Three20UINavigator.h index 897a094a24..0bf7d9563c 100644 --- a/src/Three20UINavigator/Headers/Three20UINavigator.h +++ b/src/Three20UINavigator/Headers/Three20UINavigator.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ #import "Three20UINavigator/TTNavigatorPersistenceMode.h" #import "Three20UINavigator/TTBaseNavigator.h" #import "Three20UINavigator/TTNavigatorDelegate.h" +#import "Three20UINavigator/TTNavigatorRootContainer.h" // -- URL Action #import "Three20UINavigator/TTURLAction.h" diff --git a/src/Three20UINavigator/Headers/UIViewController+TTNavigator.h b/src/Three20UINavigator/Headers/UIViewController+TTNavigator.h index 6bbdabafdc..cf419af952 100644 --- a/src/Three20UINavigator/Headers/UIViewController+TTNavigator.h +++ b/src/Three20UINavigator/Headers/UIViewController+TTNavigator.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -48,7 +48,7 @@ * * After you've restored the state, you should set frozenState to nil. */ -@property (nonatomic, retain) NSDictionary* frozenState; +@property (nonatomic, copy) NSDictionary* frozenState; /** * Forcefully initiates garbage collection. You may call this in your didReceiveMemoryWarning diff --git a/src/Three20UINavigator/Headers/UIViewController+TTNavigatorGarbageCollection.h b/src/Three20UINavigator/Headers/UIViewController+TTNavigatorGarbageCollection.h index 1dc55b8173..3a8700be04 100644 --- a/src/Three20UINavigator/Headers/UIViewController+TTNavigatorGarbageCollection.h +++ b/src/Three20UINavigator/Headers/UIViewController+TTNavigatorGarbageCollection.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Sources/TTBaseNavigationController.m b/src/Three20UINavigator/Sources/TTBaseNavigationController.m index 418f2ce4a1..41263fb57b 100644 --- a/src/Three20UINavigator/Sources/TTBaseNavigationController.m +++ b/src/Three20UINavigator/Sources/TTBaseNavigationController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Sources/TTBaseNavigator.m b/src/Three20UINavigator/Sources/TTBaseNavigator.m index 1e56d1551c..d754a37153 100644 --- a/src/Three20UINavigator/Sources/TTBaseNavigator.m +++ b/src/Three20UINavigator/Sources/TTBaseNavigator.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ // UINavigator #import "Three20UINavigator/TTGlobalNavigatorMetrics.h" #import "Three20UINavigator/TTNavigatorDelegate.h" +#import "Three20UINavigator/TTNavigatorRootContainer.h" #import "Three20UINavigator/TTBaseNavigationController.h" #import "Three20UINavigator/TTURLAction.h" #import "Three20UINavigator/TTURLMap.h" @@ -29,6 +30,7 @@ #import "Three20UINavigator/private/TTBaseNavigatorInternal.h" // UICommon +#import "Three20UICommon/UIView+TTUICommon.h" #import "Three20UICommon/UIViewControllerAdditions.h" // Core @@ -37,6 +39,7 @@ #import "Three20Core/TTDebug.h" #import "Three20Core/TTDebugFlags.h" #import "Three20Core/NSDateAdditions.h" +#import "Three20Core/TTAvailability.h" static TTBaseNavigator* gNavigator = nil; @@ -44,8 +47,12 @@ static NSString* kNavigatorHistoryTimeKey = @"TTNavigatorHistoryTime"; static NSString* kNavigatorHistoryImportantKey = @"TTNavigatorHistoryImportant"; -UIKIT_EXTERN NSString *const UIApplicationDidEnterBackgroundNotification __attribute__((weak_import)); -UIKIT_EXTERN NSString *const UIApplicationWillEnterForegroundNotification __attribute__((weak_import)); +#ifdef __IPHONE_4_0 +UIKIT_EXTERN NSString *const UIApplicationDidEnterBackgroundNotification +__attribute__((weak_import)); +UIKIT_EXTERN NSString *const UIApplicationWillEnterForegroundNotification +__attribute__((weak_import)); +#endif /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -57,15 +64,18 @@ @implementation TTBaseNavigator @synthesize URLMap = _URLMap; @synthesize window = _window; @synthesize rootViewController = _rootViewController; +@synthesize persistenceKey = _persistenceKey; @synthesize persistenceExpirationAge = _persistenceExpirationAge; @synthesize persistenceMode = _persistenceMode; @synthesize supportsShakeToReload = _supportsShakeToReload; @synthesize opensExternalURLs = _opensExternalURLs; +@synthesize rootContainer = _rootContainer; /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { _URLMap = [[TTURLMap alloc] init]; _persistenceMode = TTNavigatorPersistenceModeNone; @@ -74,12 +84,14 @@ - (id)init { selector:@selector(applicationWillLeaveForeground:) name:UIApplicationWillTerminateNotification object:nil]; +#ifdef __IPHONE_4_0 if (nil != &UIApplicationDidEnterBackgroundNotification) { [center addObserver:self selector:@selector(applicationWillLeaveForeground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; } +#endif } return self; } @@ -91,8 +103,10 @@ - (void)dealloc { _delegate = nil; TT_RELEASE_SAFELY(_window); TT_RELEASE_SAFELY(_rootViewController); + TT_RELEASE_SAFELY(_popoverController); TT_RELEASE_SAFELY(_delayedControllers); TT_RELEASE_SAFELY(_URLMap); + TT_RELEASE_SAFELY(_persistenceKey); [super dealloc]; } @@ -113,6 +127,38 @@ + (void)setGlobalNavigator:(TTBaseNavigator*)navigator { } +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (TTBaseNavigator*)navigatorForView:(UIView*)view { + // If this is called with a UIBarButtonItem, we can't traverse a view hierarchy to find the + // navigator, return the global navigator as a fallback. + if (![view isKindOfClass:[UIView class]]) { + return [TTBaseNavigator globalNavigator]; + } + + id container = nil; + UIViewController* controller = nil; // The iterator. + UIViewController* childController = nil; // The last iterated controller. + + for (controller = view.viewController; + nil != controller; + controller = controller.parentViewController) { + if ([controller conformsToProtocol:@protocol(TTNavigatorRootContainer)]) { + container = (id)controller; + break; + } + + childController = controller; + } + + TTBaseNavigator* navigator = [container getNavigatorForController:childController]; + if (nil == navigator) { + navigator = [TTBaseNavigator globalNavigator]; + } + + return navigator; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - @@ -199,7 +245,13 @@ - (void)setRootViewController:(UIViewController*)controller { if (controller != _rootViewController) { [_rootViewController release]; _rootViewController = [controller retain]; - [self.window addSubview:_rootViewController.view]; + + if (nil != _rootContainer) { + [_rootContainer navigator:self setRootViewController:_rootViewController]; + + } else { + [self.window addSubview:_rootViewController.view]; + } } } @@ -264,7 +316,10 @@ - (void)presentModalController: (UIViewController*)controller animated: animated]; } else { - UINavigationController* navController = [[[[self navigationControllerClass] alloc] init] autorelease]; + UINavigationController* navController = [[[[self navigationControllerClass] alloc] init] + autorelease]; + navController.modalTransitionStyle = transition; + navController.modalPresentationStyle = controller.modalPresentationStyle; [navController pushViewController: controller animated: NO]; [parentController presentModalViewController: navController @@ -273,6 +328,43 @@ - (void)presentModalController: (UIViewController*)controller } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)presentPopoverController: (UIViewController*)controller + sourceButton: (UIBarButtonItem*)sourceButton + sourceView: (UIView*)sourceView + sourceRect: (CGRect)sourceRect + animated: (BOOL)animated { + TTDASSERT(nil != sourceButton || nil != sourceView); + + if (nil == sourceButton && nil == sourceView) { + return; + } + + if (nil != _popoverController) { + [_popoverController dismissPopoverAnimated:animated]; + TT_RELEASE_SAFELY(_popoverController); + } + + _popoverController = [[TTUIPopoverControllerClass() alloc] init]; + if (_popoverController != nil) { + [_popoverController setContentViewController:controller]; + [_popoverController setDelegate:self]; + } + + if (nil != sourceButton) { + [_popoverController presentPopoverFromBarButtonItem: sourceButton + permittedArrowDirections: UIPopoverArrowDirectionAny + animated: animated]; + + } else { + [_popoverController presentPopoverFromRect: sourceRect + inView: sourceView + permittedArrowDirections: UIPopoverArrowDirectionAny + animated: animated]; + } +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /** * @return NO if the controller already has a super controller and is simply made visible. @@ -283,8 +375,7 @@ - (void)presentModalController: (UIViewController*)controller - (BOOL)presentController: (UIViewController*)controller parentController: (UIViewController*)parentController mode: (TTNavigationMode)mode - animated: (BOOL)animated - transition: (NSInteger)transition { + action: (TTURLAction*)action { BOOL didPresentNewController = YES; if (nil == _rootViewController) { @@ -309,8 +400,7 @@ - (BOOL)presentController: (UIViewController*)controller [self presentDependantController: controller parentController: parentController mode: mode - animated: animated - transition: transition]; + action: action]; } } @@ -322,8 +412,7 @@ - (BOOL)presentController: (UIViewController*)controller - (BOOL)presentController: (UIViewController*)controller parentURLPath: (NSString*)parentURLPath withPattern: (TTURLNavigatorPattern*)pattern - animated: (BOOL)animated - transition: (NSInteger)transition { + action: (TTURLAction*)action { BOOL didPresentNewController = NO; if (nil != controller) { @@ -341,16 +430,14 @@ - (BOOL)presentController: (UIViewController*)controller [self presentController: parentController parentController: nil mode: TTNavigationModeNone - animated: NO - transition: 0]; + action: [TTURLAction actionWithURLPath:nil]]; } didPresentNewController = [self presentController: controller parentController: parentController mode: pattern.navigationMode - animated: animated - transition: transition]; + action: action]; } } return didPresentNewController; @@ -384,6 +471,7 @@ - (UIViewController*)openURLAction:(TTURLAction*)action { if (nil == theURL.scheme) { if (nil != theURL.fragment) { urlPath = [self.URL stringByAppendingString:urlPath]; + } else { urlPath = [@"http://" stringByAppendingString:urlPath]; } @@ -403,6 +491,7 @@ - (UIViewController*)openURLAction:(TTURLAction*)action { NSURL *newURL = [_delegate navigator:self URLToOpen:theURL]; if (!newURL) { return nil; + } else { theURL = newURL; urlPath = newURL.absoluteString; @@ -433,12 +522,12 @@ - (UIViewController*)openURLAction:(TTURLAction*)action { inViewController: controller]; } + action.transition = action.transition ? action.transition : pattern.transition; + BOOL wasNew = [self presentController: controller parentURLPath: action.parentURLPath withPattern: pattern - animated: action.animated - transition: action.transition ? - action.transition : pattern.transition]; + action: action]; if (action.withDelay && !wasNew) { [self cancelDelay]; @@ -538,9 +627,11 @@ - (UIViewController*)topViewController { if (child) { if (child == _rootViewController) { return child; + } else { controller = child; } + } else { return controller; } @@ -592,7 +683,7 @@ - (UIViewController*)viewControllerForURL:(NSString*)URL query:(NSDictionary*)qu /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIViewController*)viewControllerForURL: (NSString*)URL query: (NSDictionary*)query - pattern: (TTURLNavigatorPattern**)pattern { + pattern: (TTURLPattern**)pattern { NSRange fragmentRange = [URL rangeOfString:@"#" options:NSBackwardsSearch]; if (fragmentRange.location != NSNotFound) { NSString* baseURL = [URL substringToIndex:fragmentRange.location]; @@ -601,25 +692,29 @@ - (UIViewController*)viewControllerForURL: (NSString*)URL id result = [_URLMap dispatchURL:URL toTarget:controller query:query]; if ([result isKindOfClass:[UIViewController class]]) { return result; + } else { return controller; } + } else { - id object = [_URLMap objectForURL:baseURL query:nil pattern:pattern]; + id object = [_URLMap objectForURL:baseURL query:nil pattern:(TTURLNavigatorPattern**)pattern]; if (object) { id result = [_URLMap dispatchURL:URL toTarget:object query:query]; if ([result isKindOfClass:[UIViewController class]]) { return result; + } else { return object; } + } else { return nil; } } } - id object = [_URLMap objectForURL:URL query:query pattern:pattern]; + id object = [_URLMap objectForURL:URL query:query pattern:(TTURLNavigatorPattern**)pattern]; if (object) { UIViewController* controller = object; controller.originalNavigatorURL = URL; @@ -627,12 +722,14 @@ - (UIViewController*)viewControllerForURL: (NSString*)URL if (_delayCount) { if (!_delayedControllers) { _delayedControllers = [[NSMutableArray alloc] initWithObjects:controller,nil]; + } else { [_delayedControllers addObject:controller]; } } return controller; + } else { return nil; } @@ -688,24 +785,50 @@ - (void)persistViewControllers { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; if (path.count) { - [defaults setObject:path forKey:kNavigatorHistoryKey]; - [defaults setObject:[NSDate date] forKey:kNavigatorHistoryTimeKey]; - [defaults setObject:[NSNumber numberWithInt:important] forKey:kNavigatorHistoryImportantKey]; + NSDate* historyTime = [NSDate date]; + NSNumber* historyImportant = [NSNumber numberWithInt:important]; + + if (TTIsStringWithAnyText(_persistenceKey)) { + NSDictionary* persistedValues = [NSDictionary dictionaryWithObjectsAndKeys: + path, kNavigatorHistoryKey, + historyTime, kNavigatorHistoryTimeKey, + historyImportant, kNavigatorHistoryImportantKey, + nil]; + [defaults setObject:persistedValues forKey:_persistenceKey]; + + } else { + [defaults setObject:path forKey:kNavigatorHistoryKey]; + [defaults setObject:historyTime forKey:kNavigatorHistoryTimeKey]; + [defaults setObject:historyImportant forKey:kNavigatorHistoryImportantKey]; + } + + [defaults synchronize]; + } else { - [defaults removeObjectForKey:kNavigatorHistoryKey]; - [defaults removeObjectForKey:kNavigatorHistoryTimeKey]; - [defaults removeObjectForKey:kNavigatorHistoryImportantKey]; + [self resetDefaults]; } - [defaults synchronize]; } /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIViewController*)restoreViewControllers { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - NSDate* timestamp = [defaults objectForKey:kNavigatorHistoryTimeKey]; - NSArray* path = [defaults objectForKey:kNavigatorHistoryKey]; - BOOL important = [[defaults objectForKey:kNavigatorHistoryImportantKey] boolValue]; + NSDate* timestamp = nil; + NSArray* path = nil; + BOOL important = NO; + + if (TTIsStringWithAnyText(_persistenceKey)) { + NSDictionary* persistedValues = [defaults objectForKey:_persistenceKey]; + + timestamp = [persistedValues objectForKey:kNavigatorHistoryTimeKey]; + path = [persistedValues objectForKey:kNavigatorHistoryKey]; + important = [[persistedValues objectForKey:kNavigatorHistoryImportantKey] boolValue]; + + } else { + timestamp = [defaults objectForKey:kNavigatorHistoryTimeKey]; + path = [defaults objectForKey:kNavigatorHistoryKey]; + important = [[defaults objectForKey:kNavigatorHistoryImportantKey] boolValue]; + } TTDCONDITIONLOG(TTDFLAG_NAVIGATOR, @"DEBUG RESTORE %@ FROM %@", path, [timestamp formatRelativeTime]); @@ -762,6 +885,7 @@ - (void)persistController:(UIViewController*)controller path:(NSMutableArray*)pa if (controller.modalViewController && controller.modalViewController.parentViewController == controller) { [self persistController:controller.modalViewController path:path]; + } else if (controller.popupViewController && controller.popupViewController.superController == controller) { [self persistController:controller.popupViewController path:path]; @@ -791,6 +915,7 @@ - (NSString*)pathForObject:(id)object { } return [paths componentsJoinedByString:@"/"]; + } else { return nil; } @@ -811,13 +936,35 @@ - (id)objectForPath:(NSString*)path { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)resetDefaults { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - [defaults removeObjectForKey:kNavigatorHistoryKey]; - [defaults removeObjectForKey:kNavigatorHistoryTimeKey]; - [defaults removeObjectForKey:kNavigatorHistoryImportantKey]; + + if (TTIsStringWithAnyText(_persistenceKey)) { + [defaults removeObjectForKey:_persistenceKey]; + + } else { + [defaults removeObjectForKey:kNavigatorHistoryKey]; + [defaults removeObjectForKey:kNavigatorHistoryTimeKey]; + [defaults removeObjectForKey:kNavigatorHistoryImportantKey]; + } + [defaults synchronize]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark UIPopoverControllerDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { + if (popoverController == _popoverController) { + TT_RELEASE_SAFELY(_popoverController); + } +} + + + @end @@ -834,19 +981,25 @@ @implementation TTBaseNavigator (TTInternal) - (void)presentDependantController: (UIViewController*)controller parentController: (UIViewController*)parentController mode: (TTNavigationMode)mode - animated: (BOOL)animated - transition: (NSInteger)transition { + action: (TTURLAction*)action { if (mode == TTNavigationModeModal) { [self presentModalController: controller parentController: parentController - animated: animated - transition: transition]; + animated: action.animated + transition: action.transition]; + + } else if (mode == TTNavigationModePopover) { + [self presentPopoverController: controller + sourceButton: action.sourceButton + sourceView: action.sourceView + sourceRect: action.sourceRect + animated: action.animated]; } else { [parentController addSubcontroller: controller - animated: animated - transition: transition]; + animated: action.animated + transition: action.transition]; } } diff --git a/src/Three20UINavigator/Sources/TTGlobalNavigatorMetrics.m b/src/Three20UINavigator/Sources/TTGlobalNavigatorMetrics.m index dd81efb898..87eb393440 100644 --- a/src/Three20UINavigator/Sources/TTGlobalNavigatorMetrics.m +++ b/src/Three20UINavigator/Sources/TTGlobalNavigatorMetrics.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ UIInterfaceOrientation TTInterfaceOrientation() { UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation; if (UIDeviceOrientationUnknown == orient) { return [TTBaseNavigator globalNavigator].visibleViewController.interfaceOrientation; + } else { return orient; } @@ -74,8 +75,10 @@ CGFloat TTStatusHeight() { UIInterfaceOrientation orientation = TTInterfaceOrientation(); if (orientation == UIInterfaceOrientationLandscapeLeft) { return [UIScreen mainScreen].applicationFrame.origin.x; + } else if (orientation == UIInterfaceOrientationLandscapeRight) { return -[UIScreen mainScreen].applicationFrame.origin.x; + } else { return [UIScreen mainScreen].applicationFrame.origin.y; } @@ -87,8 +90,9 @@ CGFloat TTBarsHeight() { CGRect frame = [UIApplication sharedApplication].statusBarFrame; if (UIInterfaceOrientationIsPortrait(TTInterfaceOrientation())) { return frame.size.height + TT_ROW_HEIGHT; + } else { - return frame.size.width + TT_LANDSCAPE_TOOLBAR_HEIGHT; + return frame.size.width + (TTIsPad() ? TT_ROW_HEIGHT : TT_LANDSCAPE_TOOLBAR_HEIGHT); } } diff --git a/src/Three20UINavigator/Sources/TTNavigatorViewController.m b/src/Three20UINavigator/Sources/TTNavigatorViewController.m index f66713c78c..5cbc549e13 100644 --- a/src/Three20UINavigator/Sources/TTNavigatorViewController.m +++ b/src/Three20UINavigator/Sources/TTNavigatorViewController.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/Three20UINavigator/Sources/TTURLAction.m b/src/Three20UINavigator/Sources/TTURLAction.m index 320fffdb90..e7e1bb5540 100644 --- a/src/Three20UINavigator/Sources/TTURLAction.m +++ b/src/Three20UINavigator/Sources/TTURLAction.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,9 +32,18 @@ @implementation TTURLAction @synthesize state = _state; @synthesize animated = _animated; @synthesize withDelay = _withDelay; +@synthesize sourceRect = _sourceRect; +@synthesize sourceView = _sourceView; +@synthesize sourceButton = _sourceButton; @synthesize transition = _transition; +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (id)action { + return [[[self alloc] init] autorelease]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// + (id)actionWithURLPath:(NSString*)urlPath { return [[[self alloc] initWithURLPath:urlPath] autorelease]; @@ -43,8 +52,8 @@ + (id)actionWithURLPath:(NSString*)urlPath { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithURLPath:(NSString*)urlPath { - if (self = [super init]) { - TTDASSERT(nil != urlPath); + self = [super init]; + if (self) { self.urlPath = urlPath; self.animated = NO; self.withDelay = NO; @@ -57,7 +66,8 @@ - (id)initWithURLPath:(NSString*)urlPath { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithURLPath:nil]) { + self = [self initWithURLPath:nil]; + if (self) { } return self; @@ -66,10 +76,12 @@ - (id)init { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)dealloc { - self.urlPath = nil; - self.parentURLPath = nil; - self.query = nil; - self.state = nil; + TT_RELEASE_SAFELY(_urlPath); + TT_RELEASE_SAFELY(_parentURLPath); + TT_RELEASE_SAFELY(_query); + TT_RELEASE_SAFELY(_state); + TT_RELEASE_SAFELY(_sourceView); + TT_RELEASE_SAFELY(_sourceButton); [super dealloc]; } @@ -110,6 +122,27 @@ - (TTURLAction*)applyWithDelay:(BOOL)withDelay { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTURLAction*)applySourceRect:(CGRect)sourceRect { + self.sourceRect = sourceRect; + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTURLAction*)applySourceView:(UIView*)sourceView { + self.sourceView = sourceView; + return self; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTURLAction*)applySourceButton:(UIBarButtonItem*)sourceButton { + self.sourceButton = sourceButton; + return self; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (TTURLAction*)applyTransition:(UIViewAnimationTransition)transition { self.transition = transition; diff --git a/src/Three20UINavigator/Sources/TTURLArguments.m b/src/Three20UINavigator/Sources/TTURLArguments.m index 60c41c5446..0c744768ca 100644 --- a/src/Three20UINavigator/Sources/TTURLArguments.m +++ b/src/Three20UINavigator/Sources/TTURLArguments.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // -#import "Three20UINavigator/TTURLArguments.h" +#import "Three20UINavigator/private/TTURLArguments.h" #import @@ -30,14 +30,19 @@ TTURLArgumentType TTConvertArgumentType(char argType) { || argType == 'S' || argType == 'L') { return TTURLArgumentTypeInteger; + } else if (argType == 'q' || argType == 'Q') { return TTURLArgumentTypeLongLong; + } else if (argType == 'f') { return TTURLArgumentTypeFloat; + } else if (argType == 'd') { return TTURLArgumentTypeDouble; + } else if (argType == 'B') { return TTURLArgumentTypeBool; + } else { return TTURLArgumentTypePointer; } @@ -50,6 +55,7 @@ TTURLArgumentType TTURLArgumentTypeForProperty(Class cls, NSString* propertyName if (prop) { const char* type = property_getAttributes(prop); return TTConvertArgumentType(type[1]); + } else { return TTURLArgumentTypeNone; } diff --git a/src/Three20UINavigator/Sources/TTURLGeneratorPattern.m b/src/Three20UINavigator/Sources/TTURLGeneratorPattern.m index 532356d192..abdd2a0d89 100644 --- a/src/Three20UINavigator/Sources/TTURLGeneratorPattern.m +++ b/src/Three20UINavigator/Sources/TTURLGeneratorPattern.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,7 +36,8 @@ @implementation TTURLGeneratorPattern /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTargetClass:(id)targetClass { - if (self = [super init]) { + self = [super init]; + if (self) { _targetClass = targetClass; } return self; @@ -45,7 +46,8 @@ - (id)initWithTargetClass:(id)targetClass { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithTargetClass:nil]) { + self = [self initWithTargetClass:nil]; + if (self) { } return self; @@ -115,6 +117,7 @@ - (NSString*)generateURLFromObject:(id)object { if (queries) { NSString* query = [queries componentsJoinedByString:@"&"]; return [path stringByAppendingFormat:@"?%@", query]; + } else { return path; } diff --git a/src/Three20UINavigator/Sources/TTURLLiteral.m b/src/Three20UINavigator/Sources/TTURLLiteral.m index 5a7b0c7d5b..3e593169c0 100644 --- a/src/Three20UINavigator/Sources/TTURLLiteral.m +++ b/src/Three20UINavigator/Sources/TTURLLiteral.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // -#import "Three20UINavigator/TTURLLiteral.h" +#import "Three20UINavigator/private/TTURLLiteral.h" // Core #import "Three20Core/TTCorePreprocessorMacros.h" diff --git a/src/Three20UINavigator/Sources/TTURLMap.m b/src/Three20UINavigator/Sources/TTURLMap.m index 2e9fb8bc56..743a22cae6 100644 --- a/src/Three20UINavigator/Sources/TTURLMap.m +++ b/src/Three20UINavigator/Sources/TTURLMap.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -156,7 +156,8 @@ - (BOOL)isWebURL:(NSURL*)URL { || [URL.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame || [URL.scheme caseInsensitiveCompare:@"ftp"] == NSOrderedSame || [URL.scheme caseInsensitiveCompare:@"ftps"] == NSOrderedSame - || [URL.scheme caseInsensitiveCompare:@"data"] == NSOrderedSame; + || [URL.scheme caseInsensitiveCompare:@"data"] == NSOrderedSame + || [URL.scheme caseInsensitiveCompare:@"file"] == NSOrderedSame; } @@ -166,6 +167,7 @@ - (BOOL)isExternalURL:(NSURL*)URL { || [URL.host isEqualToString:@"itunes.apple.com"] || [URL.host isEqualToString:@"phobos.apple.com"]) { return YES; + } else { return NO; } @@ -194,6 +196,15 @@ - (void)from:(NSString*)URL toObject:(id)target selector:(SEL)selector { [pattern release]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)from:(NSString*)URL toObject:(id)target selector:(SEL)selector mode: +(TTNavigationMode) mode {TTURLNavigatorPattern* pattern = + [[TTURLNavigatorPattern alloc] initWithTarget:target mode: mode]; + pattern.selector = selector; + [self addObjectPattern:pattern forURL:URL]; + [pattern release]; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)from:(NSString*)URL toViewController:(id)target { @@ -321,6 +332,27 @@ - (void)from:(NSString*)URL parent:(NSString*)parentURL } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)from:(NSString*)URL toPopoverViewController:(id)target { + TTURLNavigatorPattern* pattern = + [[TTURLNavigatorPattern alloc] initWithTarget: target + mode: TTNavigationModePopover]; + [self addObjectPattern:pattern forURL:URL]; + [pattern release]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)from:(NSString*)URL toPopoverViewController:(id)target selector:(SEL)selector { + TTURLNavigatorPattern* pattern = + [[TTURLNavigatorPattern alloc] initWithTarget:target + mode:TTNavigationModePopover]; + pattern.selector = selector; + [self addObjectPattern:pattern forURL:URL]; + [pattern release]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)from:(Class)cls toURL:(NSString*)URL { TTURLGeneratorPattern* pattern = [[TTURLGeneratorPattern alloc] initWithTargetClass:cls]; @@ -425,6 +457,7 @@ - (id)objectForURL: (NSString*)URL *outPattern = pattern; } return object; + } else { return nil; } @@ -501,6 +534,7 @@ - (NSString*)URLForObject:(id)object withName:(NSString*)name { TTURLGeneratorPattern* pattern = [_stringPatterns objectForKey:key]; if (pattern) { return [pattern generateURLFromObject:object]; + } else { cls = class_getSuperclass(cls); } diff --git a/src/Three20UINavigator/Sources/TTURLNavigatorPattern.m b/src/Three20UINavigator/Sources/TTURLNavigatorPattern.m index bacfa8aecf..e102ce0a77 100644 --- a/src/Three20UINavigator/Sources/TTURLNavigatorPattern.m +++ b/src/Three20UINavigator/Sources/TTURLNavigatorPattern.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -47,11 +47,13 @@ @implementation TTURLNavigatorPattern /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTarget: (id)target mode: (TTNavigationMode)navigationMode { - if (self = [super init]) { + self = [super init]; + if (self) { _navigationMode = navigationMode; if ([target class] == target && navigationMode) { _targetClass = target; + } else { _targetObject = target; } @@ -63,7 +65,8 @@ - (id)initWithTarget: (id)target /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithTarget:(id)target { - if (self = [self initWithTarget:target mode:TTNavigationModeNone]) { + self = [self initWithTarget:target mode:TTNavigationModeNone]; + if (self) { } return self; @@ -72,7 +75,8 @@ - (id)initWithTarget:(id)target { /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [self initWithTarget:nil]) { + self = [self initWithTarget:nil]; + if (self) { } return self; @@ -87,6 +91,17 @@ - (void)dealloc { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString *)description { + if (nil != _targetClass) { + return [NSString stringWithFormat:@"%@ => %@", _URL, _targetClass]; + + } else { + return [NSString stringWithFormat:@"%@ => %@", _URL, _targetObject]; + } +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - @@ -110,8 +125,10 @@ - (BOOL)callsInstanceMethod { - (NSComparisonResult)compareSpecificity:(TTURLPattern*)pattern2 { if (_specificity > pattern2.specificity) { return NSOrderedAscending; + } else if (_specificity < pattern2.specificity) { return NSOrderedDescending; + } else { return NSOrderedSame; } @@ -153,6 +170,7 @@ - (void)deduceSelector { [parts addObject:@"query"]; [self setSelectorWithNames:parts]; } + } else { [self setSelectorIfPossible:@selector(initWithNavigatorURL:query:)]; } @@ -297,15 +315,16 @@ - (void)setArgumentsFromURL: (NSURL*)URL } } - NSDictionary* URLQuery = [URL.query queryDictionaryUsingEncoding:NSUTF8StringEncoding]; + NSDictionary* URLQuery = [URL.query queryContentsUsingEncoding:NSUTF8StringEncoding]; if (URLQuery.count) { for (NSString* name in [URLQuery keyEnumerator]) { id patternText = [_query objectForKey:name]; - NSString* text = [URLQuery objectForKey:name]; + NSString* text = [[URLQuery objectForKey:name] objectAtIndex:0]; if (patternText) { if ([self setArgument:text pattern:patternText forInvocation:invocation]) { --remainingArgs; } + } else { if (!unmatchedArgs) { unmatchedArgs = [NSMutableDictionary dictionary]; @@ -357,6 +376,7 @@ - (void)compile { if (!_selector) { [self deduceSelector]; } + } else { [self compileURL]; @@ -400,6 +420,7 @@ - (BOOL)matchURL:(NSURL*)URL { if ((URL.fragment && !_fragment) || (_fragment && !URL.fragment)) { return NO; + } else if (URL.fragment && _fragment && ![_fragment match:URL.fragment]) { return NO; } @@ -424,6 +445,7 @@ - (id)invoke: (id)target if (query) { [invocation setArgument:&query atIndex:3]; } + } else { [self setArgumentsFromURL:URL forInvocation:invocation query:query]; } @@ -441,21 +463,34 @@ - (id)invoke: (id)target /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)createObjectFromURL: (NSURL*)URL query: (NSDictionary*)query { - id target = nil; + id returnValue = nil; + if (self.instantiatesClass) { - target = [_targetClass alloc]; + //suppress static analyzer warning for this part + // - invoke:withURL:query actually calls an - init method + // which returns either a new object with retain count of +1 + // or returnValue (which already has +1 retain count) +#ifndef __clang_analyzer__ + returnValue = [_targetClass alloc]; + if (_selector) { + returnValue = [self invoke:returnValue withURL:URL query:query]; + + } else { + returnValue = [returnValue init]; + } + [returnValue autorelease]; +#endif + } else { - target = [_targetObject retain]; - } + id target = [_targetObject retain]; + if (_selector) { + returnValue = [self invoke:target withURL:URL query:query]; - id returnValue = nil; - if (_selector) { - returnValue = [self invoke:target withURL:URL query:query]; - } else if (self.instantiatesClass) { - returnValue = [target init]; + } else { + TTDWARNING(@"No object created from URL:'%@'", URL); + } + [target release]; } - - [target autorelease]; return returnValue; } diff --git a/src/Three20UINavigator/Sources/TTURLPattern.m b/src/Three20UINavigator/Sources/TTURLPattern.m index 0dd592c13b..8747b38c88 100644 --- a/src/Three20UINavigator/Sources/TTURLPattern.m +++ b/src/Three20UINavigator/Sources/TTURLPattern.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,8 +17,8 @@ #import "Three20UINavigator/TTURLPattern.h" // UINavigator (Private) -#import "Three20UINavigator/TTURLWildcard.h" -#import "Three20UINavigator/TTURLLiteral.h" +#import "Three20UINavigator/private/TTURLWildcard.h" +#import "Three20UINavigator/private/TTURLLiteral.h" // Core #import "Three20Core/TTCorePreprocessorMacros.h" @@ -39,7 +39,8 @@ @implementation TTURLPattern /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { _path = [[NSMutableArray alloc] init]; } return self; @@ -150,9 +151,9 @@ - (void)compileURL { } if (URL.query) { - NSDictionary* query = [URL.query queryDictionaryUsingEncoding:NSUTF8StringEncoding]; + NSDictionary* query = [URL.query queryContentsUsingEncoding:NSUTF8StringEncoding]; for (NSString* name in [query keyEnumerator]) { - NSString* value = [query objectForKey:name]; + NSString* value = [[query objectForKey:name] objectAtIndex:0]; [self parseParameter:name value:value]; } } diff --git a/src/Three20UINavigator/Sources/TTURLPatternInternal.m b/src/Three20UINavigator/Sources/TTURLPatternInternal.m index 184ee4d60b..d83bc0787f 100644 --- a/src/Three20UINavigator/Sources/TTURLPatternInternal.m +++ b/src/Three20UINavigator/Sources/TTURLPatternInternal.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,12 +14,17 @@ // limitations under the License. // -#import "Three20UINavigator/TTURLPatternInternal.h" +#import "Three20UINavigator/private/TTURLPatternInternal.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +TT_FIX_CATEGORY_BUG(TTURLPatternInternal) + @implementation TTURLPattern (TTInternal) @@ -32,4 +37,3 @@ - (void)setSelectorWithNames:(NSArray*)names { @end - diff --git a/src/Three20UINavigator/Sources/TTURLSelector.m b/src/Three20UINavigator/Sources/TTURLSelector.m index f9dd9e7bd8..f12ce25c8f 100644 --- a/src/Three20UINavigator/Sources/TTURLSelector.m +++ b/src/Three20UINavigator/Sources/TTURLSelector.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // -#import "Three20UINavigator/TTURLSelector.h" +#import "Three20UINavigator/private/TTURLSelector.h" // UINavigator (private) #import "Three20UINavigator/private/TTURLArguments.h" @@ -34,7 +34,8 @@ @implementation TTURLSelector /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithName:(NSString*)name { - if (self = [super init]) { + self = [super init]; + if (self) { _name = [name copy]; _selector = NSSelectorFromString(_name); } @@ -57,6 +58,7 @@ - (NSString*)perform:(id)object returnType:(TTURLArgumentType)returnType { if (_next) { id value = [object performSelector:_selector]; return [_next perform:value returnType:returnType]; + } else { NSMethodSignature *sig = [object methodSignatureForSelector:_selector]; NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:sig]; diff --git a/src/Three20UINavigator/Sources/TTURLWildcard.m b/src/Three20UINavigator/Sources/TTURLWildcard.m index c5c6ecbbf0..389a1afe7e 100644 --- a/src/Three20UINavigator/Sources/TTURLWildcard.m +++ b/src/Three20UINavigator/Sources/TTURLWildcard.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // -#import "Three20UINavigator/TTURLWildcard.h" +#import "Three20UINavigator/private/TTURLWildcard.h" // UINavigator (private) #import "Three20UINavigator/private/TTURLArguments.h" @@ -37,7 +37,8 @@ @implementation TTURLWildcard /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { _argIndex = NSNotFound; _argType = TTURLArgumentTypeNone; } @@ -64,6 +65,7 @@ - (BOOL)match:(NSString*)text { - (NSString*)convertPropertyOfObject:(id)object { if (_selector) { return [_selector perform:object returnType:_argType]; + } else { return @""; } @@ -79,11 +81,13 @@ - (void)deduceSelectorForClass:(Class)cls { TTURLSelector* newSelector = [[[TTURLSelector alloc] initWithName:name] autorelease]; if (selector) { selector.next = newSelector; + } else { self.selector = newSelector; } selector = newSelector; } + } else { self.argType = TTURLArgumentTypeForProperty(cls, _name); self.selector = [[[TTURLSelector alloc] initWithName:_name] autorelease]; diff --git a/src/Three20UINavigator/Sources/UIViewController+TTNavigator.m b/src/Three20UINavigator/Sources/UIViewController+TTNavigator.m index 011579d782..a45924814e 100644 --- a/src/Three20UINavigator/Sources/UIViewController+TTNavigator.m +++ b/src/Three20UINavigator/Sources/UIViewController+TTNavigator.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -43,12 +43,18 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Additions. + */ +TT_FIX_CATEGORY_BUG(UIViewController_TTNavigator) + @implementation UIViewController (TTNavigator) /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query { - if (self = [self initWithNibName:nil bundle:nil]) { + self = [self initWithNibName:nil bundle:nil]; + if (self) { } return self; @@ -108,6 +114,7 @@ + (void)ttAddNavigatorController:(UIViewController*)controller { repeats: YES] retain]; } #if TTDFLAG_CONTROLLERGARBAGECOLLECTION + } else { TTDCONDITIONLOG(TTDFLAG_CONTROLLERGARBAGECOLLECTION, @"Not adding a navigator controller."); @@ -175,7 +182,7 @@ @implementation UIViewController (TTNavigatorGarbageCollection) /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)unsetNavigatorProperties { TTDCONDITIONLOG(TTDFLAG_CONTROLLERGARBAGECOLLECTION, - @"Unsetting this controller's properties: %X", self); + @"Unsetting this controller's properties: %X", (unsigned int)self); NSString* urlPath = self.originalNavigatorURL; if (nil != urlPath) { diff --git a/src/Three20UINavigator/Three20UINavigator.xcodeproj/project.pbxproj b/src/Three20UINavigator/Three20UINavigator.xcodeproj/project.pbxproj index 9e68b46fbb..82ec729cf6 100755 --- a/src/Three20UINavigator/Three20UINavigator.xcodeproj/project.pbxproj +++ b/src/Three20UINavigator/Three20UINavigator.xcodeproj/project.pbxproj @@ -3,10 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 666E16DD12944999001C1D97 /* TTNavigatorRootContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 666E16DC12944999001C1D97 /* TTNavigatorRootContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E3C35ED118B75800079637E /* TTNavigatorDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E3C35EA118B75800079637E /* TTNavigatorDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E3C3611118B77F70079637E /* TTURLAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E3C3610118B77F70079637E /* TTURLAction.m */; }; 6E3C3614118B77FE0079637E /* TTURLAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E3C3613118B77FE0079637E /* TTURLAction.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -121,6 +122,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 666E16DC12944999001C1D97 /* TTNavigatorRootContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTNavigatorRootContainer.h; path = Headers/TTNavigatorRootContainer.h; sourceTree = ""; }; 6E3C35EA118B75800079637E /* TTNavigatorDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTNavigatorDelegate.h; path = Headers/TTNavigatorDelegate.h; sourceTree = ""; }; 6E3C3610118B77F70079637E /* TTURLAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTURLAction.m; path = Sources/TTURLAction.m; sourceTree = ""; }; 6E3C3613118B77FE0079637E /* TTURLAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTURLAction.h; path = Headers/TTURLAction.h; sourceTree = ""; }; @@ -172,7 +174,7 @@ 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = UnitTests.xcconfig; path = Configurations/UnitTests.xcconfig; sourceTree = ""; }; 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; BEF31F3A0F352DF5000DE5D2 /* libThree20UINavigator.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libThree20UINavigator.a; sourceTree = BUILT_PRODUCTS_DIR; }; - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB9E6C6210B6A8F800DE563C /* UINavigatorUnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UINavigatorUnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -200,7 +202,7 @@ isa = PBXGroup; children = ( BEF31F3A0F352DF5000DE5D2 /* libThree20UINavigator.a */, - EB9E6C6210B6A8F800DE563C /* UnitTests.octest */, + EB9E6C6210B6A8F800DE563C /* UINavigatorUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -320,7 +322,7 @@ isa = PBXGroup; children = ( 6E3C37BA118C96A60079637E /* libThree20UICommon.a */, - 6E3C37BC118C96A60079637E /* UnitTests.octest */, + 6E3C37BC118C96A60079637E /* UICommonUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -366,6 +368,7 @@ isa = PBXGroup; children = ( 6E3C3758118C8E490079637E /* TTNavigatorPersistenceMode.h */, + 666E16DC12944999001C1D97 /* TTNavigatorRootContainer.h */, 6E3C3753118C8E180079637E /* TTBaseNavigator.h */, 6E3C3755118C8E210079637E /* TTBaseNavigator.m */, 6E3C35EA118B75800079637E /* TTNavigatorDelegate.h */, @@ -449,6 +452,7 @@ 6E7B106E11923A92001359FE /* TTNavigatorViewController.h in Headers */, 6E7B107011923AC1001359FE /* UIViewController+TTNavigatorGarbageCollection.h in Headers */, 6E6081C011B0C08600C93CD4 /* TTBaseNavigationController.h in Headers */, + 666E16DD12944999001C1D97 /* TTNavigatorRootContainer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -462,6 +466,7 @@ BEF31F360F352DF5000DE5D2 /* Headers */, 6E645F461187B01F00F08CB1 /* Protect Copied Headers */, BEF31F370F352DF5000DE5D2 /* Sources */, + 668E661D131ADFEA00ACE4AB /* Lint */, BEF31F380F352DF5000DE5D2 /* Frameworks */, ); buildRules = ( @@ -475,9 +480,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libThree20UINavigator.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTests */ = { + EB9E6C6110B6A8F800DE563C /* Three20UINavigatorUnitTests */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20UINavigatorUnitTests" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -491,9 +496,9 @@ 6E3C37C1118C96CB0079637E /* PBXTargetDependency */, 6EE736C711849FA000A35176 /* PBXTargetDependency */, ); - name = UnitTests; + name = Three20UINavigatorUnitTests; productName = CoreUnitTests; - productReference = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + productReference = EB9E6C6210B6A8F800DE563C /* UINavigatorUnitTests.octest */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -501,9 +506,20 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Three20UINavigator" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -519,7 +535,7 @@ projectRoot = ""; targets = ( BEF31F390F352DF5000DE5D2 /* Three20UINavigator */, - EB9E6C6110B6A8F800DE563C /* UnitTests */, + EB9E6C6110B6A8F800DE563C /* Three20UINavigatorUnitTests */, ); }; /* End PBXProject section */ @@ -532,10 +548,10 @@ remoteRef = 6E3C37B9118C96A60079637E /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E3C37BC118C96A60079637E /* UnitTests.octest */ = { + 6E3C37BC118C96A60079637E /* UICommonUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = UICommonUnitTests.octest; remoteRef = 6E3C37BB118C96A60079637E /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -566,6 +582,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 668E661D131ADFEA00ACE4AB /* Lint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = Lint; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/usr/bin/env python ../scripts/lint"; + shellScript = ""; + showEnvVarsInLog = 0; + }; 6E645F461187B01F00F08CB1 /* Protect Copied Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -662,14 +693,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; @@ -681,9 +709,10 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; @@ -691,20 +720,14 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; - SDKROOT = iphonesimulator4.0; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Internal; @@ -717,7 +740,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -727,8 +750,7 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -737,14 +759,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -752,13 +771,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E64543D1184BE1B00F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -766,19 +783,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; }; name = Debug; @@ -787,18 +798,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6EE7364C11849B3D00A35176 /* UnitTests.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - HEADER_SEARCH_PATHS = .; - PREBINDING = NO; - PRODUCT_NAME = UnitTests; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + SDKROOT = iphoneos; WRAPPER_EXTENSION = octest; ZERO_LINK = NO; }; @@ -827,7 +831,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "Three20UINavigatorUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/Three20UINavigator/UnitTests/TTURLActionTests.m b/src/Three20UINavigator/UnitTests/TTURLActionTests.m index 8bfa856a78..0f0927c894 100644 --- a/src/Three20UINavigator/UnitTests/TTURLActionTests.m +++ b/src/Three20UINavigator/UnitTests/TTURLActionTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,8 +14,7 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. +// See: http://bit.ly/hS5nNh for unit test macros. #import diff --git a/src/Three20UINavigator/UnitTests/UIViewControllerAdditionTests.m b/src/Three20UINavigator/UnitTests/UIViewControllerAdditionTests.m index 81c90af222..064baf948b 100644 --- a/src/Three20UINavigator/UnitTests/UIViewControllerAdditionTests.m +++ b/src/Three20UINavigator/UnitTests/UIViewControllerAdditionTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,8 +14,7 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. +// See: http://bit.ly/hS5nNh for unit test macros. #import diff --git a/src/common/Configurations/Libraries.xcconfig b/src/common/Configurations/Libraries.xcconfig index cd16c82936..c767151acc 100644 --- a/src/common/Configurations/Libraries.xcconfig +++ b/src/common/Configurations/Libraries.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ #include "Paths.xcconfig" OBJC_LIBRARY = -ObjC -OBJC_ALLLOAD = -all_load // stdlib / libSystem diff --git a/src/common/Configurations/Library.xcconfig b/src/common/Configurations/Library.xcconfig index cf41f36687..d4416ec7a3 100644 --- a/src/common/Configurations/Library.xcconfig +++ b/src/common/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,13 +15,31 @@ // HEADERS_FOLDER_PATH = /../three20/ -PRIVATE_HEADERS_FOLDER_PATH = $(HEADERS_FOLDER_PATH)$(PRODUCT_NAME)/private -PUBLIC_HEADERS_FOLDER_PATH = $(HEADERS_FOLDER_PATH)$(PRODUCT_NAME) +PRIVATE_HEADERS_FOLDER_PATH = $(HEADERS_FOLDER_PATH)$(BASE_PRODUCT_NAME)/private +PUBLIC_HEADERS_FOLDER_PATH = $(HEADERS_FOLDER_PATH)$(BASE_PRODUCT_NAME) GCC_PRECOMPILE_PREFIX_HEADER = YES -GCC_PREFIX_HEADER = $(SRCROOT)/Headers/$(PRODUCT_NAME)_Prefix.pch +GCC_PREFIX_HEADER = $(SRCROOT)/Headers/$(BASE_PRODUCT_NAME)_Prefix.pch RUN_CLANG_STATIC_ANALYZER = NO +// Don't include the Three20 libraries in the archive. This makes it possible to build IPAs +// in Xcode 4. +SKIP_INSTALL = YES + +// Uncomment this flags to build the modules with LLVM compiler 1.5 +//GCC_VERSION = com.apple.compilers.llvm.clang.1_0 + +// We frequently use self.view; in Three20UI and LLVM compiler 1.5 raises warnings. +// This flag turns them off. +//WARNING_CFLAGS = -Wno-unused-value + +FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)/Developer/Library/Frameworks" +IPHONEOS_DEPLOYMENT_TARGET = 3.0 +SDKROOT = iphoneos +// Required for older iOS devices (iPhone 3G) +ARCHS = $(ARCHS_STANDARD_32_BIT) +ARCHS[sdk=iphoneos*] = armv6 armv7 + // Linker Flags OTHER_LDFLAGS = $(OBJC_LIBRARY) @@ -35,3 +53,6 @@ GCC_WARN_ABOUT_MISSING_NEWLINE = YES GCC_WARN_UNUSED_FUNCTION = YES GCC_WARN_UNUSED_LABEL = YES +// THIS APPARENTLY FIXES HORRIBLE PROBLEMS WITH THE OPTIMIZER +// ACCESSING BASIC PROPS IN UI +OTHER_CFLAGS[arch=armv6] = -mno-thumb diff --git a/src/common/Configurations/Paths.xcconfig b/src/common/Configurations/Paths.xcconfig index 675665863d..2523f012a5 100644 --- a/src/common/Configurations/Paths.xcconfig +++ b/src/common/Configurations/Paths.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,5 +23,19 @@ SYMROOT = $(OBJROOT)/Products // Search Paths LIBRARY_SEARCH_PATHS = $(STDLIB_LIBRARY) -HEADER_SEARCH_PATHS = $(STDLIB_HEADERS) "$(CONFIGURATION_BUILD_DIR)/../three20" +// Header search paths: why we have three +// +// CONFIGURATION_BUILD_DIR is for when the headers are copied to Three20's Build folder. +// Applies to: +// - Xcode 3.2.# +// - Xcode 4 with the Build Location preference set to "Place build products in locations +// specified by targets" +// +// BUILT_PRODUCTS_DIR is for Xcode 4 support only. We need two copies of a BUILT_PRODUCTS_DIR path +// because on Archive builds, there is one extra folder placed between the +// product and the public header path. +// Applies to: +// - Xcode 4 only + +HEADER_SEARCH_PATHS = $(STDLIB_HEADERS) "$(BUILT_PRODUCTS_DIR)/../three20" "$(BUILT_PRODUCTS_DIR)/../../three20" "$(CONFIGURATION_BUILD_DIR)/../../three20" diff --git a/src/common/Configurations/Project.xcconfig b/src/common/Configurations/Project.xcconfig index fd78d50ebd..2cef1da7a4 100644 --- a/src/common/Configurations/Project.xcconfig +++ b/src/common/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,3 +15,10 @@ // #include "Paths.xcconfig" + +FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)/Developer/Library/Frameworks" +IPHONEOS_DEPLOYMENT_TARGET = 3.0 +SDKROOT = iphoneos +// Required for older iOS devices (iPhone 3G) +ARCHS = $(ARCHS_STANDARD_32_BIT) +ARCHS[sdk=iphoneos*] = armv6 armv7 \ No newline at end of file diff --git a/src/common/Configurations/UnitTests.xcconfig b/src/common/Configurations/UnitTests.xcconfig index a10e846295..374818fe23 100644 --- a/src/common/Configurations/UnitTests.xcconfig +++ b/src/common/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,8 +26,14 @@ FRAMEWORK_SEARCH_PATHS = $(SDKROOT)$(DEVELOPER_FRAMEWORKS_DIR) CURRENT_PROJECT_VERSION = $(BUILD_BUNDLE_VERSION) +FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)/Developer/Library/Frameworks" +IPHONEOS_DEPLOYMENT_TARGET = 3.0 +SDKROOT = iphoneos +// Required for older iOS devices (iPhone 3G) +ARCHS = $(ARCHS_STANDARD_32_BIT) + // Linker Flags -COMMON_LDFLAGS = $(OBJC_LIBRARY) $(OBJC_ALLLOAD) $(UIKIT_FX) $(COREGRAPHICS_FX) $(FOUNDATION_FX) $(SENTESTINGKIT_FX) +COMMON_LDFLAGS = $(OBJC_LIBRARY) $(UIKIT_FX) $(COREGRAPHICS_FX) $(FOUNDATION_FX) $(SENTESTINGKIT_FX) OTHER_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/src/extThree20CSSStyle/Configurations/Library.xcconfig b/src/extThree20CSSStyle/Configurations/Library.xcconfig index 955f723e9b..da2819ecb0 100644 --- a/src/extThree20CSSStyle/Configurations/Library.xcconfig +++ b/src/extThree20CSSStyle/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,9 +17,9 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -EXTENSION_NAME = extThree20CSSStyle -PRODUCT_NAME = $(EXTENSION_NAME) +BASE_PRODUCT_NAME = extThree20CSSStyle +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 -PRIVATE_HEADERS_FOLDER_PATH = /../three20/$(EXTENSION_NAME)/private -PUBLIC_HEADERS_FOLDER_PATH = /../three20/$(EXTENSION_NAME) +PRIVATE_HEADERS_FOLDER_PATH = /../three20/$(BASE_PRODUCT_NAME)/private +PUBLIC_HEADERS_FOLDER_PATH = /../three20/$(BASE_PRODUCT_NAME) diff --git a/src/extThree20CSSStyle/Configurations/Project.xcconfig b/src/extThree20CSSStyle/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/extThree20CSSStyle/Configurations/Project.xcconfig +++ b/src/extThree20CSSStyle/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/extThree20CSSStyle/Configurations/UnitTests.xcconfig b/src/extThree20CSSStyle/Configurations/UnitTests.xcconfig index bab11d54fe..3e1c11d5a0 100644 --- a/src/extThree20CSSStyle/Configurations/UnitTests.xcconfig +++ b/src/extThree20CSSStyle/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = extCSSStyleUnitTests +BASE_PRODUCT_NAME = extCSSStyleUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_BUNDLE_VERSION = 1.0 OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) diff --git a/src/extThree20CSSStyle/Headers/TTCSSApplyProtocol.h b/src/extThree20CSSStyle/Headers/TTCSSApplyProtocol.h new file mode 100644 index 0000000000..e1fffd89d7 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTCSSApplyProtocol.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org ) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "extThree20CSSStyle/TTCSSRuleSet.h" + +/** + * TTCSSApplyProtocol defines an common interface to classes that style itself + * using CSS readed properties. This classes should implement this protocol + * and his appropriate methods. + */ +@protocol TTCSSApplyProtocol +@required + +/** + * Receive an Set of Rules from some CSS selector to apply. This method + * receive an TTCSSRuleSet with all properties ready to be set. + */ +-(void)applyCssRules:(TTCSSRuleSet*)anRuleSet; + +/** + * Set a CSS stylesheet selector. + */ +- (void)applyCssSelector:(NSString *)selector; + +@end diff --git a/src/extThree20CSSStyle/Headers/TTCSSFunctions.h b/src/extThree20CSSStyle/Headers/TTCSSFunctions.h new file mode 100644 index 0000000000..de67f6c334 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTCSSFunctions.h @@ -0,0 +1,28 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +/** + * Helper function to convert an CSS readed colors to UIColor. + */ +UIColor* TTColorFromCssValues( NSArray* cssValues ); + +/** + * Helper function to convert an CSS readed size to CGFloat. + */ +CGFloat TTValueFromCssValues( NSString* value ); diff --git a/src/extThree20CSSStyle/Headers/TTCSSGlobalStyle.h b/src/extThree20CSSStyle/Headers/TTCSSGlobalStyle.h new file mode 100644 index 0000000000..1f5ea2a483 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTCSSGlobalStyle.h @@ -0,0 +1,64 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// CSS Style helpers + +#define TTCSSSTYLESHEET ([[TTDefaultCSSStyleSheet globalCSSStyleSheet] styleSheet]) + +#define TTCSS_color(_SELECTOR, _STATE) \ + ([TTCSSSTYLESHEET colorWithCssSelector:_SELECTOR forState:_STATE]) + +#define TTCSS_backgroundColor(_SELECTOR, _STATE) \ + ([TTCSSSTYLESHEET backgroundColorWithCssSelector:_SELECTOR forState:_STATE]) + +#define TTCSS_font(_SELECTOR, _STATE) \ + ([TTCSSSTYLESHEET fontWithCssSelector:_SELECTOR forState:_STATE]) + +#define TTCSS_shadowColor(_SELECTOR, _STATE) \ + ([TTCSSSTYLESHEET textShadowColorWithCssSelector:_SELECTOR forState:_STATE]) + +#define TTCSS_shadowOffset(_SELECTOR, _STATE) \ + ([TTCSSSTYLESHEET textShadowOffsetWithCssSelector:_SELECTOR forState:_STATE]) + +#define TTCSS_shadowRadius(_SELECTOR, _STATE) \ + ([TTCSSSTYLESHEET textShadowRadiusWithCssSelector:_SELECTOR forState:_STATE]) + +// _VARNAME must be one of: color, backgroundColor, font, shadowColor, shadowOffset, shadowRadius +#define TTCSSSTATE(_SELECTOR, _VARNAME, _STATE) \ + TTCSS_##_VARNAME(_SELECTOR, _STATE) + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Retrieve a Full CSS Rule (TTCSSRuleSet) for specified selector. + */ +#define TTCSSRule(selector) (TTCSSRuleSet*)[[TTDefaultCSSStyleSheet\ + globalCSSStyleSheet] css:selector] + +/** + * Retrieve an value for a property of an Rule Set (TTCSSRuleSet) for specified selector. + */ +#define TTCSS(selector,property) [TTCSSRule(selector) property] + +/** + * Apply an CSS style to specified object. + * The object must conform with the TTCSSApplyProtocol. + */ +#define TTApplyCSS(selector,object) [[TTDefaultCSSStyleSheet globalCSSStyleSheet]\ + applyCssFromSelector:selector\ + toObject:object] diff --git a/src/extThree20CSSStyle/Headers/TTCSSParser.h b/src/extThree20CSSStyle/Headers/TTCSSParser.h index fbcc58aa04..c9da7b70b5 100644 --- a/src/extThree20CSSStyle/Headers/TTCSSParser.h +++ b/src/extThree20CSSStyle/Headers/TTCSSParser.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/extThree20CSSStyle/Headers/TTCSSRuleSet.h b/src/extThree20CSSStyle/Headers/TTCSSRuleSet.h new file mode 100644 index 0000000000..048c71685e --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTCSSRuleSet.h @@ -0,0 +1,264 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +#import "TTCSSTextShadowModel.h" + +@interface TTCSSRuleSet : NSObject { + NSString *selector; + + // Colors. + UIColor *color; + UIColor *background_color; + + // Font properties. + NSString *font_family; + NSString *font_weight; + NSNumber *font_size; + + // Alignment and Justification. + NSString *text_align; + + // Text Shadow. + TTCSSTextShadowModel* text_shadow; + NSNumber* text_shadow_opacity; + + // Background properties. + NSString *background_image; + + // Visibility. + NSString *visibility; + + // Positioning and size. + NSString *width; + NSString *height; + NSString *top; + NSString *left; + NSString *right; + NSString *bottom; + + // Object alignment. + NSString *vertical_align; + + // Margins. + NSString *margin_right; + NSString *margin_left; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Properties. + +/** + * The identifier for this rule set. Also knowed as selector + */ +@property (copy) NSString *selector; + +/** + * A font family name only specifies a name given to a set of font faces, + * it does not specify an individual face. + * You can call [UIFont familyNames] to retrieve a list of + * available fonts on your system. Font family name is case-sensitive, + * make sure to inform correctly. + * See CSS3 Font Family + * for more information.
+ * Default value is the first Default Font Family. + */ +@property (copy) NSString *font_family; + +/** + * The ‘font-weight’ property specifies weight of glyphs in the font. + * In iOS each font has different font weight descriptions (such as Medium, Light, Oblique, etc.). + * You can call [UIFont familyNames] to retrieve a list of available fonts on your system. + * Default value is nil.
+ *
+ * Example:
+ * To use the font Helvetica-BoldOblique you should + * inform BoldOblique as font-weight and Helvetica as font_family. + *
+ * Font weight name is case-sensitive, make sure to inform correctly. + */ +@property (copy) NSString *font_weight; + +/** + * This property indicates the desired height of glyphs from the font. + * This value is always interpreted in points, regardless of what you specify. + * This is due to the tricky nature of varying DPI on the various iPhone OS devices. + * Default value is the Default System Font Size ([UIFont systemFontSize]). + */ +@property (copy) NSNumber *font_size; + +/** + * This property describes how inline contents of a block are horizontally + * aligned. Values have the following meanings:
+ * - left: Align text along the left edge.
+ * - center: Align text equally along both sides of the center line.
+ * - right: Align text along the right edge.
+ *
+ * Use the textAlign method to retrieve an iOS formatted UITextAlignment + * based on this values. + */ +@property (copy) NSString* text_align; + +/** + * This property specifies the size of an element’s rendering box. + * Possible Values:
+ * - auto: The width is determinant on the values of other properties. + * - length: Refers to an absolute measurement for the computed + * element box width. Negative values are not allowed. + * - percentage: Refers to a percentage of the width of the containing + * element block.
+ * Examples:
+ * "75px", "50%" + */ +@property (copy) NSString* width; + +/** + * /copydef width + */ +@property (copy) NSString* height; + +@property (copy) NSString* top; +@property (copy) NSString* left; +@property (copy) NSString* right; +@property (copy) NSString* bottom; + +/** + * The visibility property specifies whether or not an element is visible. + * Possible Values:
+ * - visible: The element is visible. This is default. + * - hidden: The element is invisible. + */ +@property (copy) NSString* visibility; + +/** + * An TTCSSTextShadowModel object that define a text shadow properties. + */ +@property (retain) TTCSSTextShadowModel* text_shadow; + +/** + * Specifies the opacity of the receiver’s text shadow. + * The default value is 0. + */ +@property (copy) NSNumber* text_shadow_opacity; + +/** + * This property describes the foreground color of an element. + * Default value is a transparent color. + */ +@property (retain) id color; + +/** + * This property describes the background color of an element. + * Default value is a transparent color. + */ +@property (retain) id background_color; + +/** + * This property sets the background image(s) of an element. + * Default value is nil. + */ +@property (copy) NSString *background_image; + +/** + * This property sets the vertical alignment of an element. + * Values have the following meanings:
+ * - top: The top of the element is aligned with the top of the + * tallest element on the line.
+ * - middle: The element is placed in the middle of the parent element.
+ * - bottom: The bottom of the element is aligned with the lowest element on the line.
+ *
+ * Use the contentVerticalAlignment method to retrieve an iOS formatted + * UIControlContentVerticalAlignment based on this values. + */ +@property (copy) NSString* vertical_align; + +/** + * This property specifies the left margin of an element. + * Possible Values:
+ * - auto: The left margin is calculated automatically. + * - length: Specifies a fixed left margin in px. + * - percentage: Specifies a left margin in percent. + * Examples:
+ * "75px", "50%" + */ +@property (copy) NSString* margin_left; + +/** + * This property specifies the right margin of an element. + * Possible Values:
+ * - auto: The right margin is calculated automatically. + * - length: Specifies a fixed right margin in px. + * - percentage: Specifies a left margin in percent. + * Examples:
+ * "75px", "50%" + */ +@property (copy) NSString* margin_right; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Init Methods. ++(id)initWithSelectorName:(NSString*)anRuleSetName; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Data Methods. + +/** + * Return an formatted UIFont object based on the defined properties. + * Will return nil if can't format. + */ +-(UIFont*)font; + +/** + * Return an formatted UITextAlignment based on the defined 'text_align' property. + * If isn't setted return default left alignment. + */ +-(UITextAlignment)textAlign; + +/** + * Return an formatted CGSize based on the defined 'width' + * and 'height' properties. + */ +-(CGSize)size; + +/** + * Return an formatted CGPoint based on the defined 'top' + * and 'left' properties. + */ +-(CGPoint)origin; + +/** + * Return an Boolean value that determines whether the receiver is hidden based + * on the 'visibility' property. + */ +-(BOOL)hidden; + +/** + * Return an formatted UIControlContentVerticalAlignment based on the defined + * 'vertical_align' property. If isn't setted return default top alignment. + */ +-(UIControlContentVerticalAlignment)contentVerticalAlignment; + +/** + * Return an formatted UIControlContentHorizontalAlignment based on the defined + * 'margin-left' and margin-right properties. + * If isn't setted return default left alignment. + */ +-(UIControlContentHorizontalAlignment)contentHorizontalAlignment; +@end diff --git a/src/extThree20CSSStyle/Headers/TTCSSStyleSheet.h b/src/extThree20CSSStyle/Headers/TTCSSStyleSheet.h index 2cb451ab9e..efcf8aac6b 100644 --- a/src/extThree20CSSStyle/Headers/TTCSSStyleSheet.h +++ b/src/extThree20CSSStyle/Headers/TTCSSStyleSheet.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ #import #import +#import "extThree20CSSStyle/TTDataPopulatorDelegate.h" /** * A general purpose CSS style sheet object for accessing a CSS style sheet's properties. @@ -25,17 +26,26 @@ * * Example apps: three20/samples/Style/TTCSSStyleSheets */ -@interface TTCSSStyleSheet : NSObject { +@class TTCSSRuleSet; +@interface TTCSSStyleSheet : NSObject { @private + + // The "crude" Styles readed from CSS file. NSDictionary* _cssStyles; - NSMutableDictionary* _cachedCssStyles; + // An collection of loaded TTCSSRuleSet. + NSDictionary* _cssRulesSet; - NSDictionary* _colorLookupTable; + // CSS mapped properties. + NSDictionary* _propertiesMap; } @property (nonatomic, readonly) NSDictionary* cssStyles; +/** + * An collection of loaded TTCSSRuleSet. + */ +@property (readonly) NSDictionary* cssRulesSet; /** * Load the style sheet into memory from disk. @@ -51,30 +61,74 @@ /** - * Get (text) color from a specific rule set. + * Get (text) color from a specific rule set, also accept an specific state. */ - (UIColor*)colorWithCssSelector:(NSString*)selector forState:(UIControlState)state; /** - * Get background-color from a specific rule set. + * Get (text) color from a specific rule set. + */ +- (UIColor*)colorWithCssSelector:(NSString*)selector; + +/** + * Get background-color from a specific rule set, also accept an specific state. */ - (UIColor*)backgroundColorWithCssSelector:(NSString*)selector forState:(UIControlState)state; /** - * Get font from a specific rule set. + * Get background-color from a specific rule set. + */ +- (UIColor*)backgroundColorWithCssSelector:(NSString*)selector; + +/** + * Get font from a specific rule set, also accept an specific state. */ - (UIFont*)fontWithCssSelector:(NSString*)selector forState:(UIControlState)state; /** - * Get text shadow color from a specific rule set. + * Get font from a specific rule set and 'normal' state. + */ +- (UIFont*)fontWithCssSelector:(NSString*)selector; + +/** + * Get text shadow color from a specific rule set, also accept an specific state. */ - (UIColor*)textShadowColorWithCssSelector:(NSString*)selector forState:(UIControlState)state; /** - * Get text shadow offset from a specific rule set. + * Get text shadow color from a specific rule set. + */ +- (UIColor*)textShadowColorWithCssSelector:(NSString*)selector; + +/** + * Get text shadow offset from a specific rule set, also accept an specific state. */ - (CGSize)textShadowOffsetWithCssSelector:(NSString*)selector forState:(UIControlState)state; +/** + * Get text shadow offset from a specific rule set. + */ +- (CGSize)textShadowOffsetWithCssSelector:(NSString*)selector; + +/** + * Get text shadow radius from a specific rule set. + */ +- (CGFloat)textShadowRadiusWithCssSelector:(NSString*)selector; + +/** + * Get text shadow radius from a specific rule set, also accept an specific state. + */ +- (CGFloat)textShadowRadiusWithCssSelector:(NSString*)selector forState:(UIControlState)state; + +/** + * CSS Rule Set. + */ +-(TTCSSRuleSet*)css:(NSString*)selectorName; + +/** + * CSS Rule Set, also accept an specific state. + */ +-(TTCSSRuleSet*)css:(NSString*)selectorName forState:(UIControlState)state; /** * Release all cached data. diff --git a/src/extThree20CSSStyle/Headers/TTCSSTextShadowModel.h b/src/extThree20CSSStyle/Headers/TTCSSTextShadowModel.h new file mode 100644 index 0000000000..08be8367d8 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTCSSTextShadowModel.h @@ -0,0 +1,55 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#import + +@interface TTCSSTextShadowModel : NSObject { + + UIColor* shadowColor; + NSNumber* shadowBlur; + CGSize shadowOffset; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Properties. + +/** + * This is given as a pair of length values indicating x- and y- distances to use as offset. + * The default offset size is (0, -1), which indicates a shadow one point above the text. + */ +@property (assign) CGSize shadowOffset; + +/** + * The shadowBlur specifies the blur radius used to render the receiver’s shadow. + * This value coud not be rendered on iOS older than 3.2. + * The default value is 3.0. + */ +@property (copy) NSNumber* shadowBlur; + +/* + * Define the color to create the shadow effect. + * The default value for this property is transparent, + * which indicates that no shadow is drawn. + */ +@property (retain) id shadowColor; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Init Methods. ++(id)initWithShadowColor:(id)anColor andShadowOffset:(CGSize)anOffset; ++(id)initWithShadowColor:(id)anColor andShadowOffset:(CGSize)anOffset andShadowBlur:(NSNumber*)blur; + +@end diff --git a/src/extThree20CSSStyle/Headers/TTDataConverter.h b/src/extThree20CSSStyle/Headers/TTDataConverter.h new file mode 100644 index 0000000000..afbc867c9f --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTDataConverter.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org ) + * JUMP GIT Repository: https://github.com/seqoy/jump + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#import + +/** + * \nosubgrouping + * This class contains an collection of methods to convert different Objective C objects. + * This is a little versio of this class with a small subset of useful methods to + * use with 'TTCSS' Classes. See JUMP Framework to retrieve the full version. + */ +@interface TTDataConverter : NSObject {} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Convert Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// +/** @name Convert Methods + */ +///@{ + +/** + * Take an NSString Object and try to convert to NSNumber. + * @param anObject An NSString to try to convert. + * @return Converted object or if an conversion isn't possible will return nil. + */ ++(NSNumber*)convertToNSNumberThisObject:(id)anObject; + +///@} +@end + diff --git a/src/extThree20CSSStyle/Headers/TTDataPopulator.h b/src/extThree20CSSStyle/Headers/TTDataPopulator.h new file mode 100644 index 0000000000..fe2f0a8ef8 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTDataPopulator.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org ) + * JUMP GIT Repository: https://github.com/seqoy/jump + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#import +#import +#import "extThree20CSSStyle/TTDataConverter.h" +#import "extThree20CSSStyle/TTDataPopulatorDelegate.h" + +/** + * \nosubgrouping + * TTDataPopulator is used to populate Model Objects with Data contained in dictionaries. + * This is a little versio of this class with a small subset of useful methods to + * use with 'TTCSS' Classes. See JUMP Framework to retrieve the full version. + */ +@interface TTDataPopulator : NSObject { + id delegate; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Properties. +@property (assign) id delegate; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma mark - +#pragma mark Populate Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// + +//// //// //// //// //// //// //// //// //// //// //// //// //// //// //// +/** @name Populate Methods + */ +///@{ + +/** + * Populate the informed object with data. + * @param anObject The object to populate. + * @param withData An NSDictionary with data. + * @param usingMap An NSDictionary that represent an map that describe + * how to populate the object. + */ ++(id)populateObject:(id)anObject withData:(NSDictionary*)anDictionary usingMap:(NSDictionary*)anMap; + +/** + * Populate the informed object with data. + * @param anObject The object to populate. + * @param withData An NSDictionary with data. + * @param usingMap An NSDictionary that represent an map that describe + * how to populate the object. + * @param anDelegate to extend the TTDataPopulator class. See TTDataPopulatorDelegate + * documentation for more information. + */ ++(id)populateObject:(id)anObject withData:(NSDictionary*)anDictionary usingMap:(NSDictionary*)anMap + withDelegate:(id)anDelegate; + +///@} +@end + diff --git a/src/extThree20CSSStyle/Headers/TTDataPopulatorDelegate.h b/src/extThree20CSSStyle/Headers/TTDataPopulatorDelegate.h new file mode 100644 index 0000000000..8a2fc3a7b6 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTDataPopulatorDelegate.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org ) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@protocol TTDataPopulatorDelegate +@optional + +/** + * When the Data Populator can't automatically convert some specific type. He will call this method + * and let you extend the class converting you specific type. + * @param firstObject is original object that we need to convert. + * @param firstObjectClass is the class of the original object. + * @param convertToClass is the class that we need to receive whe converted. + * @return Should return converted object or nil if can't convert. + */ +-(id)tryToConvert:(id)object ofClass:(Class)objectClass toClass:(Class)convertToClass; + +@end diff --git a/src/extThree20CSSStyle/Headers/TTDefaultCSSStyleSheet.h b/src/extThree20CSSStyle/Headers/TTDefaultCSSStyleSheet.h new file mode 100644 index 0000000000..ac72f698cb --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTDefaultCSSStyleSheet.h @@ -0,0 +1,68 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Style/TTDefaultStyleSheet.h" + +@class TTCSSStyleSheet; +@class TTCSSRuleSet; +@protocol TTCSSApplyProtocol; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface TTDefaultCSSStyleSheet : TTDefaultStyleSheet { +@private + TTCSSStyleSheet* _styleSheet; + + // Maintain an control of CSS Files already loaded and cached. + NSMutableSet* _cachedCssFiles; + +} + +@property (nonatomic, readonly) TTCSSStyleSheet* styleSheet; + +/** + * Load an CSS Style Sheet from disk and cache his data. + * If the file is already cached no data will be loaded again, + * if you need to reload the file use addStyleSheetFromDisk:ignoreCache: + */ +- (BOOL)addStyleSheetFromDisk:(NSString*)filename; + +/** + * Load an CSS Style Sheet from disk and cache his data. + * @param cache YES will ignore if is already cached and reload the data if needed. + */ +- (BOOL)addStyleSheetFromDisk:(NSString*)filename ignoreCache:(BOOL)cache; + ++ (TTDefaultCSSStyleSheet*)globalCSSStyleSheet; + +/** + * CSS Rule Set. + */ +-(TTCSSRuleSet*)css:(NSString*)selectorName; + +/** + * CSS Rule Set, also accept an specific state. + */ +-(TTCSSRuleSet*)css:(NSString*)selectorName forState:(UIControlState)state; + +/** + * Apply the rules for the specified selector to the informed object. This object + * must conform with the TTCSSApplyProtocol to read and properly apply the CSS rules. + */ +-(void)applyCssFromSelector:(NSString*)selectorName toObject:(id)anObject; + +@end diff --git a/src/extThree20CSSStyle/Headers/TTExtensionLoader.h b/src/extThree20CSSStyle/Headers/TTExtensionLoader.h new file mode 100644 index 0000000000..8e0f4bbfd7 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTExtensionLoader.h @@ -0,0 +1,21 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/TTExtensionLoader.h" + +@interface TTExtensionLoader (TTCSSStyleExtension) + +@end diff --git a/src/extThree20CSSStyle/Headers/TTShadowStyleAdditions.h b/src/extThree20CSSStyle/Headers/TTShadowStyleAdditions.h new file mode 100644 index 0000000000..336ab5ba28 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTShadowStyleAdditions.h @@ -0,0 +1,28 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Style/TTShadowStyle.h" + +@interface TTShadowStyle (TTCSSCategory) + ++ (TTShadowStyle*)styleWithCssSelector:(NSString*)selector + forState:(UIControlState)state + next:(TTStyle*)next; + ++ (TTShadowStyle*)styleWithCssSelector:(NSString*)selector + next:(TTStyle*)next; + +@end diff --git a/src/extThree20CSSStyle/Headers/TTTextStyleAdditions.h b/src/extThree20CSSStyle/Headers/TTTextStyleAdditions.h new file mode 100644 index 0000000000..8742f90ad1 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/TTTextStyleAdditions.h @@ -0,0 +1,55 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Style/TTTextStyle.h" + +@interface TTTextStyle (TTCSSCategory) + ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + next:(TTStyle*)next; + ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + minimumFontSize:(CGFloat)minimumFontSize + next:(TTStyle*)next; + ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + minimumFontSize:(CGFloat)minimumFontSize + textAlignment:(UITextAlignment)textAlignment + verticalAlignment:(UIControlContentVerticalAlignment)verticalAlignment + lineBreakMode:(UILineBreakMode)lineBreakMode + numberOfLines:(NSInteger)numberOfLines + next:(TTStyle*)next; + + ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + forState:(UIControlState)state + next:(TTStyle*)next; + ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + forState:(UIControlState)state + minimumFontSize:(CGFloat)minimumFontSize + next:(TTStyle*)next; + ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + forState:(UIControlState)state + minimumFontSize:(CGFloat)minimumFontSize + textAlignment:(UITextAlignment)textAlignment + verticalAlignment:(UIControlContentVerticalAlignment)verticalAlignment + lineBreakMode:(UILineBreakMode)lineBreakMode + numberOfLines:(NSInteger)numberOfLines + next:(TTStyle*)next; + +@end diff --git a/src/extThree20CSSStyle/Headers/UILabel+CSSAdditions.h b/src/extThree20CSSStyle/Headers/UILabel+CSSAdditions.h new file mode 100644 index 0000000000..c06415bd39 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/UILabel+CSSAdditions.h @@ -0,0 +1,21 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#import + +#import "extThree20CSSStyle/UIView+CSSAdditions.h" + +@interface UILabel(TTCSSAdditions) +@end diff --git a/src/extThree20CSSStyle/Headers/UILabelAdditions.h b/src/extThree20CSSStyle/Headers/UILabelAdditions.h new file mode 100644 index 0000000000..fc6956dbf0 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/UILabelAdditions.h @@ -0,0 +1,18 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// For compatibility issues we import the UILabel additions. +#import "extThree20CSSStyle/UILabel+CSSAdditions.h" diff --git a/src/extThree20CSSStyle/Headers/UIView+CSSAdditions.h b/src/extThree20CSSStyle/Headers/UIView+CSSAdditions.h new file mode 100644 index 0000000000..15d775d62c --- /dev/null +++ b/src/extThree20CSSStyle/Headers/UIView+CSSAdditions.h @@ -0,0 +1,30 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#import + +#import "extThree20CSSStyle/TTCSSRuleSet.h" +#import "extThree20CSSStyle/TTCSSApplyProtocol.h" + +@interface UIView(TTCSSAdditions) + +/** + * Convenient Init method to create an UIView and apply + * an CSS Rule Set on one pass. + */ +-(id)initWithFrame:(CGRect)anFrame andApplyCssFromSelector:(NSString*)anSelector; + + +@end diff --git a/src/extThree20CSSStyle/Headers/extThree20CSSStyle+Additions.h b/src/extThree20CSSStyle/Headers/extThree20CSSStyle+Additions.h new file mode 100644 index 0000000000..87fd4b0163 --- /dev/null +++ b/src/extThree20CSSStyle/Headers/extThree20CSSStyle+Additions.h @@ -0,0 +1,24 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// CSS Style +#import "extThree20CSSStyle/extThree20CSSStyle.h" + +// Additions +#import "extThree20CSSStyle/UIView+CSSAdditions.h" +#import "extThree20CSSStyle/UILabel+CSSAdditions.h" +#import "extThree20CSSStyle/TTTextStyleAdditions.h" +#import "extThree20CSSStyle/TTShadowStyleAdditions.h" diff --git a/src/extThree20CSSStyle/Headers/extThree20CSSStyle.h b/src/extThree20CSSStyle/Headers/extThree20CSSStyle.h index 4b0b387af6..bcacb3de3b 100644 --- a/src/extThree20CSSStyle/Headers/extThree20CSSStyle.h +++ b/src/extThree20CSSStyle/Headers/extThree20CSSStyle.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,5 +18,15 @@ #import "extThree20CSSStyle/TTCSSParser.h" // CSS Stylesheet +#import "extThree20CSSStyle/TTCSSGlobalStyle.h" #import "extThree20CSSStyle/TTCSSStyleSheet.h" #import "extThree20CSSStyle/TTDefaultCSSStyleSheet.h" + +// CSS Models +#import "extThree20CSSStyle/TTCSSTextShadowModel.h" +#import "extThree20CSSStyle/TTCSSRuleSet.h" + +// Data Processing +#import "extThree20CSSStyle/TTDataConverter.h" +#import "extThree20CSSStyle/TTDataPopulator.h" +#import "extThree20CSSStyle/TTDataPopulatorDelegate.h" diff --git a/src/extThree20CSSStyle/README.mdown b/src/extThree20CSSStyle/README.mdown index e379c72ea0..1be8d4c90e 100644 --- a/src/extThree20CSSStyle/README.mdown +++ b/src/extThree20CSSStyle/README.mdown @@ -83,10 +83,27 @@ style sheet with all of the default TTDefaultStyleSheet values. You can then com style sheet upon this one using addStyleSheetFromDisk:. For an example of this in action, see TTFacebook in the `three20/samples` directory. +### The Rule Set Object + +The Rule Set Object is an model that store data for each CSS Selector parsed. This object +contains the CSS properties as Objective-C objects ready to use on your application. +See the documentation for TTCSSRuleSet and TTCSSTextShadowModel for more information. + Known Limitations ----------------- +### Font families and font weights. +You need to always use iOS font family names and iOS font weights. For example, to use Helvetica +Bold on iOS you should create your CSS like this: + + .font { + font-family: Helvetica; + font-weight: Bold; + } + +This names are case-sensitive, you must make sure to respect the iOS font names. + ### Font Sizes Font-size is always interpreted in points, regardless of what you specify. This is due to @@ -94,7 +111,7 @@ the tricky nature of varying DPI on the various iPhone OS devices. ### Text Shadows -The "blur" property is always interpreted as "0". This is due to the technical limitations +In iOS older the 3.2 the "blur" property always interpreted as "0". This is due to the technical limitations of specifying blur for text shadows for UILabels. @@ -108,8 +125,8 @@ Supported CSS Properties and Values #FFF or #FF00FF or rgb(255, 0, 255) or rgba(0, 255, 255, 0.5) or - Any of the standard names found in the W3C for css3. - http://www.w3.org/TR/css3-color/ + Any of the Extended color keywords found in the W3C for css3. + http://www.w3.org/TR/css3-color/#svg-color Also, iPhone OS standard colors: lightTextColor darkTextColor @@ -139,14 +156,33 @@ Fonts are defined with a set of properties that collectively create the final UI ### Text Shadow + text-shadow-opacity: text-shadow: px px textShadowColorWithCssSelector textShadowOffsetWithCssSelector The `text-shadow` property is defined in one chunk, but read using two distinct methods. -The third parameter is ignored. See "Text Shadows" in the `Known Limitations` section for -the technical reasons. +The third parameter could be ignored on older iOS versions, see "Text Shadows" in the +`Known Limitations` section for the technical reasons. + + +### Alignment and Justification + + text-align: (left|center|right) + +This property describes how inline contents of a block are horizontally aligned. + +### Positioning and Size + + top: px + left: px + width: px + height: px + +### Visibilty + + visibilty: (visible|hidden) Examples @@ -173,7 +209,25 @@ Add the following code in your app delegate's `applicationDidFinishLaunching`. TT_RELEASE_SAFELY(styleSheet); -Now you can freely customize the styles of your app using `stylesheet.css`. You can freely -add new styles to the CSS, but with the current design you will also need to add an accessor -to a custom object that inherits from `TTDefaultCSSStyleSheet`. See the source for -`TTDefaultCSSStyleSheet` for examples of how to interact with the style sheet object. +Now you can freely customize the styles of your app using `stylesheet.css`. You can access +the CSS rules and his properties using two convenient functions: + +### TTCSS function + +Allows you to retrieve the selector and some specific property. + + // Read the color from the CSS 'headerFont'. + UIColor *headerFontColor = TTCSS( @"headerFont", color ); + +### TTCSSRule function + +Retrieve an TTCSSRuleSet object for specified property. So you can access every property directly. + + // Read the color rule set 'headerFont'. + TTCSSRuleSet *headerFont = TTCSSRuleSet( @"headerFont" ); + + UIColor *headerFontColor = headerFont.color; + + +You also could add an accessor to a custom object that inherits from `TTDefaultCSSStyleSheet`. See the source for +`TTDefaultCSSStyleSheet` for an example. diff --git a/src/extThree20CSSStyle/Sources/CssTokenizer.m b/src/extThree20CSSStyle/Sources/CssTokenizer.m index 9353e91a7e..2689e482e9 100644 --- a/src/extThree20CSSStyle/Sources/CssTokenizer.m +++ b/src/extThree20CSSStyle/Sources/CssTokenizer.m @@ -53,7 +53,7 @@ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. + * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 @@ -70,7 +70,7 @@ typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; +typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ @@ -186,7 +186,7 @@ #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) - + /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ @@ -243,7 +243,7 @@ int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ @@ -1605,7 +1605,7 @@ errno=0; \ while ( (result = fread(buf, 1, max_size, cssin))==0 && ferror(cssin)) \ { \ - if( errno != EINTR) \ + if ( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ @@ -1671,7 +1671,7 @@ register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; - + #line 21 "css.grammar" @@ -2230,7 +2230,9 @@ static int yy_get_next_buffer (void) if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cssrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cssrealloc((void *) + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, + new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } @@ -2250,7 +2252,7 @@ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; - + yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) @@ -2310,7 +2312,7 @@ static int input (void) { int c; - + *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) @@ -2377,12 +2379,12 @@ static int input (void) /** Immediately switch to a different input stream. * @param input_file A readable stream. - * + * * @note This function does not reset the start condition to @c INITIAL . */ void cssrestart (FILE * input_file ) { - + if ( ! YY_CURRENT_BUFFER ){ cssensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = @@ -2395,11 +2397,11 @@ void cssrestart (FILE * input_file ) /** Switch to a different input buffer. * @param new_buffer The new input buffer. - * + * */ void css_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { - + /* TODO. We should be able to replace this entire function body * with * csspop_buffer_state(); @@ -2439,13 +2441,13 @@ static void css_load_buffer_state (void) /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * + * * @return the allocated buffer state. */ YY_BUFFER_STATE css_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; - + b = (YY_BUFFER_STATE) cssalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in css_create_buffer()" ); @@ -2468,11 +2470,11 @@ YY_BUFFER_STATE css_create_buffer (FILE * file, int size ) /** Destroy the buffer. * @param b a buffer created with css_create_buffer() - * + * */ void css_delete_buffer (YY_BUFFER_STATE b ) { - + if ( ! b ) return; @@ -2488,7 +2490,7 @@ void css_delete_buffer (YY_BUFFER_STATE b ) #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ - + /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a cssrestart() or at EOF. @@ -2497,7 +2499,7 @@ static void css_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; - + css_flush_buffer(b ); b->yy_input_file = file; @@ -2513,13 +2515,13 @@ static void css_init_buffer (YY_BUFFER_STATE b, FILE * file ) } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - + errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * + * */ void css_flush_buffer (YY_BUFFER_STATE b ) { @@ -2548,7 +2550,7 @@ void css_flush_buffer (YY_BUFFER_STATE b ) * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. - * + * */ void csspush_buffer_state (YY_BUFFER_STATE new_buffer ) { @@ -2578,7 +2580,7 @@ void csspush_buffer_state (YY_BUFFER_STATE new_buffer ) /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. - * + * */ void csspop_buffer_state (void) { @@ -2602,7 +2604,7 @@ void csspop_buffer_state (void) static void cssensure_buffer_stack (void) { yy_size_t num_to_alloc; - + if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this @@ -2615,9 +2617,9 @@ static void cssensure_buffer_stack (void) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in cssensure_buffer_stack()" ); - + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - + (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; @@ -2645,13 +2647,13 @@ static void cssensure_buffer_stack (void) /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. + * + * @return the newly allocated buffer state object. */ YY_BUFFER_STATE css_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; - + if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) @@ -2680,14 +2682,14 @@ YY_BUFFER_STATE css_scan_buffer (char * base, yy_size_t size ) /** Setup the input buffer state to scan a string. The next call to csslex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan - * + * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * css_scan_bytes() instead. */ YY_BUFFER_STATE css_scan_string (yyconst char * yystr ) { - + return css_scan_bytes(yystr,strlen(yystr) ); } @@ -2695,7 +2697,7 @@ YY_BUFFER_STATE css_scan_string (yyconst char * yystr ) * scan from a @e copy of @a bytes. * @param bytes the byte buffer to scan * @param len the number of bytes in the buffer pointed to by @a bytes. - * + * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE css_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) @@ -2703,7 +2705,7 @@ YY_BUFFER_STATE css_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len YY_BUFFER_STATE b; char *buf; yy_size_t n, i; - + /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) cssalloc(n ); @@ -2757,16 +2759,16 @@ static void yy_fatal_error (yyconst char* msg ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. - * + * */ int cssget_lineno (void) { - + return csslineno; } /** Get the input stream. - * + * */ FILE *cssget_in (void) { @@ -2774,7 +2776,7 @@ int cssget_lineno (void) } /** Get the output stream. - * + * */ FILE *cssget_out (void) { @@ -2782,7 +2784,7 @@ int cssget_lineno (void) } /** Get the length of the current token. - * + * */ yy_size_t cssget_leng (void) { @@ -2790,7 +2792,7 @@ yy_size_t cssget_leng (void) } /** Get the current token. - * + * */ char *cssget_text (void) @@ -2800,18 +2802,18 @@ yy_size_t cssget_leng (void) /** Set the current line number. * @param line_number - * + * */ void cssset_lineno (int line_number ) { - + csslineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. - * + * * @see css_switch_to_buffer */ void cssset_in (FILE * in_str ) @@ -2865,9 +2867,9 @@ static int yy_init_globals (void) /* csslex_destroy is for both reentrant and non-reentrant scanners. */ int csslex_destroy (void) { - + /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ + while (YY_CURRENT_BUFFER){ css_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; csspop_buffer_state(); diff --git a/src/extThree20CSSStyle/Sources/TTCSSFunctions.m b/src/extThree20CSSStyle/Sources/TTCSSFunctions.m new file mode 100644 index 0000000000..7eab3fc49d --- /dev/null +++ b/src/extThree20CSSStyle/Sources/TTCSSFunctions.m @@ -0,0 +1,268 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "extThree20CSSStyle/TTCSSFunctions.h" +#import "extThree20CSSStyle/TTDataConverter.h" +#import "Three20Style/TTGlobalStyle.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/TTDebug.h" +#import "Three20Core/TTGlobalCorePaths.h" + + +// CSS3 Color Lookuptable (4.3. Extended color keywords): http://www.w3.org/TR/css3-color/#svg-color +#define __colorLookupTable [NSDictionary dictionaryWithObjectsAndKeys:\ + RGBCOLOR(0xFF, 0x00, 0xFF), @"fuschia",\ + RGBCOLOR(240,248,255), @"aliceblue",\ + RGBCOLOR(250,235,215), @"antiquewhite",\ + RGBCOLOR(0,255,255), @"aqua",\ + RGBCOLOR(127,255,212), @"aquamarine",\ + RGBCOLOR(240,255,255), @"azure",\ + RGBCOLOR(245,245,220), @"beige",\ + RGBCOLOR(255,228,196), @"bisque",\ + RGBCOLOR(0,0,0), @"black",\ + RGBCOLOR(255,235,205), @"blanchedalmond",\ + RGBCOLOR(0,0,255), @"blue",\ + RGBCOLOR(138,43,226), @"blueviolet",\ + RGBCOLOR(165,42,42), @"brown",\ + RGBCOLOR(222,184,135), @"burlywood",\ + RGBCOLOR(95,158,160), @"cadetblue",\ + RGBCOLOR(127,255,0), @"chartreuse",\ + RGBCOLOR(210,105,30), @"chocolate",\ + RGBCOLOR(255,127,80), @"coral",\ + RGBCOLOR(100,149,237), @"cornflowerblue",\ + RGBCOLOR(255,248,220), @"cornsilk",\ + RGBCOLOR(220,20,60), @"crimson",\ + RGBCOLOR(0,255,255), @"cyan",\ + RGBCOLOR(0,0,139), @"darkblue",\ + RGBCOLOR(0,139,139), @"darkcyan",\ + RGBCOLOR(184,134,11), @"darkgoldenrod",\ + RGBCOLOR(169,169,169), @"darkgray",\ + RGBCOLOR(0,100,0), @"darkgreen",\ + RGBCOLOR(169,169,169), @"darkgrey",\ + RGBCOLOR(189,183,107), @"darkkhaki",\ + RGBCOLOR(139,0,139), @"darkmagenta",\ + RGBCOLOR(85,107,47), @"darkolivegreen",\ + RGBCOLOR(255,140,0), @"darkorange",\ + RGBCOLOR(153,50,204), @"darkorchid",\ + RGBCOLOR(139,0,0), @"darkred",\ + RGBCOLOR(233,150,122), @"darksalmon",\ + RGBCOLOR(143,188,143), @"darkseagreen",\ + RGBCOLOR(72,61,139), @"darkslateblue",\ + RGBCOLOR(47,79,79), @"darkslategray",\ + RGBCOLOR(47,79,79), @"darkslategrey",\ + RGBCOLOR(0,206,209), @"darkturquoise",\ + RGBCOLOR(148,0,211), @"darkviolet",\ + RGBCOLOR(255,20,147), @"deeppink",\ + RGBCOLOR(0,191,255), @"deepskyblue",\ + RGBCOLOR(105,105,105), @"dimgray",\ + RGBCOLOR(105,105,105), @"dimgrey",\ + RGBCOLOR(30,144,255), @"dodgerblue",\ + RGBCOLOR(178,34,34), @"firebrick",\ + RGBCOLOR(255,250,240), @"floralwhite",\ + RGBCOLOR(34,139,34), @"forestgreen",\ + RGBCOLOR(255,0,255), @"fuchsia",\ + RGBCOLOR(220,220,220), @"gainsboro",\ + RGBCOLOR(248,248,255), @"ghostwhite",\ + RGBCOLOR(255,215,0), @"gold",\ + RGBCOLOR(218,165,32), @"goldenrod",\ + RGBCOLOR(128,128,128), @"gray",\ + RGBCOLOR(0,128,0), @"green",\ + RGBCOLOR(173,255,47), @"greenyellow",\ + RGBCOLOR(128,128,128), @"grey",\ + RGBCOLOR(240,255,240), @"honeydew",\ + RGBCOLOR(255,105,180), @"hotpink",\ + RGBCOLOR(205,92,92), @"indianred",\ + RGBCOLOR(75,0,130), @"indigo",\ + RGBCOLOR(255,255,240), @"ivory",\ + RGBCOLOR(240,230,140), @"khaki",\ + RGBCOLOR(230,230,250), @"lavender",\ + RGBCOLOR(255,240,245), @"lavenderblush",\ + RGBCOLOR(124,252,0), @"lawngreen",\ + RGBCOLOR(255,250,205), @"lemonchiffon",\ + RGBCOLOR(173,216,230), @"lightblue",\ + RGBCOLOR(240,128,128), @"lightcoral",\ + RGBCOLOR(224,255,255), @"lightcyan",\ + RGBCOLOR(250,250,210), @"lightgoldenrodyellow",\ + RGBCOLOR(211,211,211), @"lightgray",\ + RGBCOLOR(144,238,144), @"lightgreen",\ + RGBCOLOR(211,211,211), @"lightgrey",\ + RGBCOLOR(255,182,193), @"lightpink",\ + RGBCOLOR(255,160,122), @"lightsalmon",\ + RGBCOLOR(32,178,170), @"lightseagreen",\ + RGBCOLOR(135,206,250), @"lightskyblue",\ + RGBCOLOR(119,136,153), @"lightslategray",\ + RGBCOLOR(119,136,153), @"lightslategrey",\ + RGBCOLOR(176,196,222), @"lightsteelblue",\ + RGBCOLOR(255,255,224), @"lightyellow",\ + RGBCOLOR(0,255,0), @"lime",\ + RGBCOLOR(50,205,50), @"limegreen",\ + RGBCOLOR(250,240,230), @"linen",\ + RGBCOLOR(255,0,255), @"magenta",\ + RGBCOLOR(128,0,0), @"maroon",\ + RGBCOLOR(102,205,170), @"mediumaquamarine",\ + RGBCOLOR(0,0,205), @"mediumblue",\ + RGBCOLOR(186,85,211), @"mediumorchid",\ + RGBCOLOR(147,112,219), @"mediumpurple",\ + RGBCOLOR(60,179,113), @"mediumseagreen",\ + RGBCOLOR(123,104,238), @"mediumslateblue",\ + RGBCOLOR(0,250,154), @"mediumspringgreen",\ + RGBCOLOR(72,209,204), @"mediumturquoise",\ + RGBCOLOR(199,21,133), @"mediumvioletred",\ + RGBCOLOR(25,25,112), @"midnightblue",\ + RGBCOLOR(245,255,250), @"mintcream",\ + RGBCOLOR(255,228,225), @"mistyrose",\ + RGBCOLOR(255,228,181), @"moccasin",\ + RGBCOLOR(255,222,173), @"navajowhite",\ + RGBCOLOR(0,0,128), @"navy",\ + RGBCOLOR(253,245,230), @"oldlace",\ + RGBCOLOR(128,128,0), @"olive",\ + RGBCOLOR(107,142,35), @"olivedrab",\ + RGBCOLOR(255,165,0), @"orange",\ + RGBCOLOR(255,69,0), @"orangered",\ + RGBCOLOR(218,112,214), @"orchid",\ + RGBCOLOR(238,232,170), @"palegoldenrod",\ + RGBCOLOR(152,251,152), @"palegreen",\ + RGBCOLOR(175,238,238), @"paleturquoise",\ + RGBCOLOR(219,112,147), @"palevioletred",\ + RGBCOLOR(255,239,213), @"papayawhip",\ + RGBCOLOR(255,218,185), @"peachpuff",\ + RGBCOLOR(205,133,63), @"peru",\ + RGBCOLOR(255,192,203), @"pink",\ + RGBCOLOR(221,160,221), @"plum",\ + RGBCOLOR(176,224,230), @"powderblue",\ + RGBCOLOR(128,0,128), @"purple",\ + RGBCOLOR(255,0,0), @"red",\ + RGBCOLOR(188,143,143), @"rosybrown",\ + RGBCOLOR(65,105,225), @"royalblue",\ + RGBCOLOR(139,69,19), @"saddlebrown",\ + RGBCOLOR(250,128,114), @"salmon",\ + RGBCOLOR(244,164,96), @"sandybrown",\ + RGBCOLOR(46,139,87), @"seagreen",\ + RGBCOLOR(255,245,238), @"seashell",\ + RGBCOLOR(160,82,45), @"sienna",\ + RGBCOLOR(192,192,192), @"silver",\ + RGBCOLOR(135,206,235), @"skyblue",\ + RGBCOLOR(106,90,205), @"slateblue",\ + RGBCOLOR(112,128,144), @"slategray",\ + RGBCOLOR(112,128,144), @"slategrey",\ + RGBCOLOR(255,250,250), @"snow",\ + RGBCOLOR(0,255,127), @"springgreen",\ + RGBCOLOR(70,130,180), @"steelblue",\ + RGBCOLOR(210,180,140), @"tan",\ + RGBCOLOR(0,128,128), @"teal",\ + RGBCOLOR(216,191,216), @"thistle",\ + RGBCOLOR(255,99,71), @"tomato",\ + RGBCOLOR(64,224,208), @"turquoise",\ + RGBCOLOR(238,130,238), @"violet",\ + RGBCOLOR(245,222,179), @"wheat",\ + RGBCOLOR(245,245,245), @"whitesmoke",\ + RGBCOLOR(255,255,0), @"yellow",\ + RGBCOLOR(154,205,50), @"yellowgreen",\ + RGBACOLOR(0xFF, 0xFF, 0xFF, 0x00), @"transparent",\ + [UIColor whiteColor], @"white",\ + [UIColor lightTextColor], @"lightTextColor",\ + [UIColor darkTextColor], @"darkTextColor",\ + [UIColor groupTableViewBackgroundColor], @"groupTableViewBackgroundColor",\ + [UIColor viewFlipsideBackgroundColor], @"viewFlipsideBackgroundColor",\ + nil] + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Colors +/////////////////////////////////////////////////////////////////////////////////////////////////// +UIColor* TTColorFromCssValues( NSArray* cssValues ) { + UIColor* anColor = nil; + + // Validate CSS Color. Anything more or less is unsupported, and therefore this + // property is ignored according to the W3C guidelines. + BOOL validCss = [cssValues count] == 1 + || [cssValues count] == 5 // rgb( x x x ) + || [cssValues count] == 6; // rgba( x x x x ) + if ( !validCss ) + [NSException raise:@"TTCSSColorFormatter" format:@"Invalid CSS color values: '%@'", cssValues]; + + if ([cssValues count] == 1) { + NSString* cssString = [cssValues objectAtIndex:0]; + + if ([cssString characterAtIndex:0] == '#') { + unsigned long colorValue = 0; + + // #FFF + if ([cssString length] == 4) { + colorValue = strtol([cssString UTF8String] + 1, nil, 16); + colorValue = ((colorValue & 0xF00) << 12) | ((colorValue & 0xF00) << 8) + | ((colorValue & 0xF0) << 8) | ((colorValue & 0xF0) << 4) + | ((colorValue & 0xF) << 4) | (colorValue & 0xF); + + // #FFFFFF + } else if ([cssString length] == 7) { + colorValue = strtol([cssString UTF8String] + 1, nil, 16); + } + + anColor = RGBCOLOR(((colorValue & 0xFF0000) >> 16), + ((colorValue & 0xFF00) >> 8), + (colorValue & 0xFF)); + + } else if ([cssString isEqualToString:@"none"]) { + anColor = nil; + + } else { + UIColor *color = [__colorLookupTable objectForKey:cssString]; + // If not found, raise error. + if ( !color ) + [NSException raise:@"TTCSSColorFormatter" + format:@"'%@' isn't a valid W3C CSS Extended color keywords.", cssString]; + // Return correct. + return color; + } + + } else if ([cssValues count] == 5 && [[cssValues objectAtIndex:0] isEqualToString:@"rgb("]) { + // rgb( x x x ) + anColor = RGBCOLOR([[cssValues objectAtIndex:1] floatValue], + [[cssValues objectAtIndex:2] floatValue], + [[cssValues objectAtIndex:3] floatValue]); + + } else if ([cssValues count] == 6 && [[cssValues objectAtIndex:0] isEqualToString:@"rgba("]) { + // rgba( x x x x ) + anColor = RGBACOLOR([[cssValues objectAtIndex:1] floatValue], + [[cssValues objectAtIndex:2] floatValue], + [[cssValues objectAtIndex:3] floatValue], + [[cssValues objectAtIndex:4] floatValue]); + } + + return anColor; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Sizes. +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Helper function to convert an CSS readed size to CGFloat. + */ +CGFloat TTValueFromCssValues( NSString* value ) { + // Pixel measure. + if ( ! NSEqualRanges( [value rangeOfString:@"px"], (NSRange){NSNotFound,0} )) { + value = [value stringByReplacingOccurrencesOfString:@"px" withString:@""]; + return [[TTDataConverter convertToNSNumberThisObject:value] floatValue]; + } + return 0; +} + diff --git a/src/extThree20CSSStyle/Sources/TTCSSParser.m b/src/extThree20CSSStyle/Sources/TTCSSParser.m index 888ad396d8..0e128f0761 100644 --- a/src/extThree20CSSStyle/Sources/TTCSSParser.m +++ b/src/extThree20CSSStyle/Sources/TTCSSParser.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -39,6 +39,9 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// @interface TTCSSParser() +/** + * + */ - (void)consumeToken:(int)token text:(char*)text; @end @@ -61,7 +64,8 @@ @implementation TTCSSParser /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { _ruleSets = [[NSMutableDictionary alloc] init]; _activeCssSelectors = [[NSMutableArray alloc] init]; } @@ -84,8 +88,8 @@ - (void)dealloc { /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)consumeToken:(int)token text:(char*)text { - NSString* string = [[NSString stringWithCString: text - encoding: NSUTF8StringEncoding] lowercaseString]; + NSString* string = [NSString stringWithCString: text + encoding: NSUTF8StringEncoding]; switch (token) { case CSSHASH: case CSSIDENT: { diff --git a/src/extThree20CSSStyle/Sources/TTCSSRuleSet.m b/src/extThree20CSSStyle/Sources/TTCSSRuleSet.m new file mode 100644 index 0000000000..60f0692112 --- /dev/null +++ b/src/extThree20CSSStyle/Sources/TTCSSRuleSet.m @@ -0,0 +1,341 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "extThree20CSSStyle/TTCSSRuleSet.h" +#import "extThree20CSSStyle/TTCSSFunctions.h" + +// Style +#import "Three20Style/TTGlobalStyle.h" +#import "Three20Style/TTStyle.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/TTGlobalCore.h" +#import "Three20Core/TTDebug.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTCSSRuleSet +@synthesize selector, font_size, font_family, font_weight; +@synthesize color, background_color, background_image; +@synthesize text_shadow, text_shadow_opacity, text_align; +@synthesize width, height, visibility; +@synthesize top, left, right, bottom; +@synthesize vertical_align, margin_right, margin_left; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Init Methods. + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++(id)initWithSelectorName:(NSString*)anRuleSetName { + TTCSSRuleSet *instance = [[TTCSSRuleSet new] autorelease]; + instance.selector = anRuleSetName; + return instance; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(id)init { + self = [super init]; + if (self != nil) { + + // Default values. + self.background_color = [UIColor clearColor]; + self.color = [UIColor clearColor]; + + // Font size is the Default Sytem Font Size. + self.font_size = [NSNumber numberWithFloat:[UIFont systemFontSize]]; + + // Default Font Family. + self.font_family = [[UIFont systemFontOfSize:[UIFont systemFontSize]] familyName]; + + // Default alignment is left. + self.text_align = @"left"; + + // Default visiblity is visible. + self.visibility = @"visible"; + + // Default vertical aligment is top. + self.vertical_align = @"top"; + } + return self; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(void)dealloc { + TT_RELEASE_SAFELY( font_family ); + TT_RELEASE_SAFELY( selector ); + TT_RELEASE_SAFELY( font_size ); + TT_RELEASE_SAFELY( font_weight ); + TT_RELEASE_SAFELY( text_shadow ); + TT_RELEASE_SAFELY( color ); + TT_RELEASE_SAFELY( width ); + TT_RELEASE_SAFELY( height ); + TT_RELEASE_SAFELY( top ); + TT_RELEASE_SAFELY( left ); + TT_RELEASE_SAFELY( right ); + TT_RELEASE_SAFELY( bottom ); + TT_RELEASE_SAFELY( background_color ); + TT_RELEASE_SAFELY( background_image ); + TT_RELEASE_SAFELY( text_shadow_opacity ); + TT_RELEASE_SAFELY( visibility ); + TT_RELEASE_SAFELY( vertical_align ); + TT_RELEASE_SAFELY( margin_right ); + TT_RELEASE_SAFELY( margin_left ); + [super dealloc]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Private Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(NSError*)formatError:(NSString*)description { + return [NSError errorWithDomain:NSStringFromClass([self class]) code:1 + userInfo:[NSDictionary dictionaryWithObject:description + forKey:NSLocalizedDescriptionKey]]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Validate Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(BOOL)validateVertical_align:(id *)ioValue error:(NSError **)outError { + // Validate correct values. + if ( ![[NSArray arrayWithObjects:@"top", @"middle", @"bottom", nil] + containsObject:(NSString*)*ioValue] ) { + *outError = [self formatError:@"'vertical_align' must be 'top', 'middle' or 'bottom'!"]; + return NO; + } + return YES; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(BOOL)validateText_align:(id *)ioValue error:(NSError **)outError { + // Validate correct values. + if ( ![[NSArray arrayWithObjects:@"left", @"center", @"right", nil] + containsObject:(NSString*)*ioValue] ) { + *outError = [self formatError:@"'text_align' must be 'left', 'center' or 'right'!"]; + return NO; + } + return YES; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(BOOL)validateVisibility:(id *)ioValue error:(NSError **)outError { + // Validate correct values. + if ( ![[NSArray arrayWithObjects:@"visible", @"hidden", nil] + containsObject:(NSString*)*ioValue] ) { + *outError = [self formatError:@"'visibility' must be 'visible' or 'hidden'!"]; + return NO; + } + return YES; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(BOOL)validateFont_family:(id *)ioValue error:(NSError **)outError { + // Validate correct system fonts. + if ( ![[UIFont familyNames] containsObject:(NSString*)*ioValue] ) { + NSString *error = [NSString stringWithFormat:@"iOS don't support the '%@' font family.", + (NSString*)*ioValue]; + *outError = [self formatError:error]; + + return NO; + } + return YES; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Validate colors. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(BOOL)validateValue:(id *)ioValue forKey:(NSString *)inKey error:(NSError **)outError { + // Colors validation. + if ( [inKey isEqualToString:@"color"] || [inKey isEqualToString:@"background_color"] ) { + + // nil is Ok. + if ( ioValue == nil ) + return YES; + + /////////////////////////////////// + // Validate correct types. + if ( ( [*ioValue isKindOfClass:[NSArray class]] || + [*ioValue isKindOfClass:[NSString class]] || + [*ioValue isKindOfClass:[UIColor class]] )) { + return YES; + } + + /////////////////////////////////// + // Else Error. + NSString *e; + e = [NSString stringWithFormat:@"'%@' must be of class 'NSArray', 'NSString' or 'UIColor'", + inKey ]; + *outError = [self formatError:e]; + return NO; + } + + // Other validations. + return [super validateValue:ioValue forKey:inKey error:outError]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Set Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(void)setUIColorProperty:(UIColor**)anColor withValue:(id)anValue { + + ///////////////////////////////// + // Release. + if ( *anColor ) + TT_RELEASE_SAFELY( *anColor ); + + /////////////////////////////////////// + // Array of color? + if ( [anValue isKindOfClass:[NSArray class]] ) { + + // Set. + *anColor = [TTColorFromCssValues(anValue) retain]; + + } + + /////////////////////////////////////// + // String color? + else if ( [anValue isKindOfClass:[NSString class]] ) { + + // Set. + *anColor = [TTColorFromCssValues([NSArray arrayWithObject:anValue]) retain]; + } + + /////////////////////////////////////// + // UIColor? + else if ( [anValue isKindOfClass:[UIColor class]] ) { + + // Set. + *anColor = [anValue retain]; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(void)setColor:(id)anColor { + [self setUIColorProperty:&color withValue:anColor]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(void)setBackground_color:(id)anColor { + [self setUIColorProperty:&background_color withValue:anColor]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Data Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Return an formatted UIFont object based on the defined properties. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(UIFont*)font { + // If not enough properties return nil. + if ( !font_family && !font_size ) { + TTDWARNING ( @"Can't format UIFont, 'font_family' or 'font_size' isn't defined." ); + return nil; + } + + ////////////////////////////////// + // Font weight. + NSString *fullFontWeight = ( font_weight == nil + ? @"" + : [NSString stringWithFormat:@"-%@", [font_weight capitalizedString]] ); + + ////////////////////////////////// + // Font Name. + NSString *fullFontName = [NSString stringWithFormat:@"%@%@", [font_family capitalizedString], + fullFontWeight]; + + ////////////////////////////////// + // Create and return UIFont. + return [UIFont fontWithName:fullFontName size:[font_size floatValue]]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Return an formatted UITextAlignment based on the defined 'text_align' property. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(UITextAlignment)textAlign { + if ([text_align isEqualToString:@"left"]) { + return UITextAlignmentLeft; + } + else if ([text_align isEqualToString:@"center"]) { + return UITextAlignmentCenter; + } + else if ([text_align isEqualToString:@"right"]) { + return UITextAlignmentRight; + } + return UITextAlignmentLeft; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Return an formatted CGSize based on the defined width and height properties. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(CGSize)size { + return CGSizeMake(TTValueFromCssValues(self.width), TTValueFromCssValues(self.height)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Return an formatted CGPoint based on the defined top and left properties. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(CGPoint)origin { + return CGPointMake(TTValueFromCssValues(self.left), TTValueFromCssValues(self.top)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Return an Boolean value that determines whether the receiver is hidden +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(BOOL)hidden { + return [self.visibility isEqualToString:@"hidden"]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Return an formatted UIControlContentVerticalAlignment based on the defined +// 'vertical_align' property. If isn't setted return default top alignment. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(UIControlContentVerticalAlignment)contentVerticalAlignment { + if ([vertical_align isEqualToString:@"top"]) { + return UIControlContentVerticalAlignmentTop; + } + else if ([vertical_align isEqualToString:@"middle"]) { + return UIControlContentVerticalAlignmentCenter; + } + else if ([vertical_align isEqualToString:@"bottom"]) { + return UIControlContentVerticalAlignmentBottom; + } + return UIControlContentVerticalAlignmentTop; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Return an formatted UIControlContentHorizontalAlignment based on the defined +// 'margin-left' and margin-right properties. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(UIControlContentHorizontalAlignment)contentHorizontalAlignment { + if ([margin_right isEqualToString:@"auto"] && ![margin_left isEqualToString:@"auto"]) { + return UIControlContentHorizontalAlignmentLeft; + } + else if ([margin_right isEqualToString:@"auto"] && [margin_left isEqualToString:@"auto"]) { + return UIControlContentHorizontalAlignmentCenter; + } + else if (![margin_right isEqualToString:@"auto"] && [margin_left isEqualToString:@"auto"]) { + return UIControlContentHorizontalAlignmentRight; + } + return UIControlContentHorizontalAlignmentLeft; +} +@end diff --git a/src/extThree20CSSStyle/Sources/TTCSSStyleSheet.m b/src/extThree20CSSStyle/Sources/TTCSSStyleSheet.m index 4084851922..a3a2fde629 100644 --- a/src/extThree20CSSStyle/Sources/TTCSSStyleSheet.m +++ b/src/extThree20CSSStyle/Sources/TTCSSStyleSheet.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,9 +15,13 @@ // #import "extThree20CSSStyle/TTCSSStyleSheet.h" +#import "extThree20CSSStyle/TTCSSRuleSet.h" +#import "extThree20CSSStyle/TTDataPopulator.h" +#import "extThree20CSSStyle/TTDataConverter.h" #import "extThree20CSSStyle/TTCSSParser.h" + // Style #import "Three20Style/TTGlobalStyle.h" #import "Three20Style/TTStyle.h" @@ -48,11 +52,13 @@ @implementation TTCSSStyleSheet @synthesize cssStyles = _cssStyles; +@synthesize cssRulesSet = _cssRulesSet; /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(didReceiveMemoryWarning:) @@ -71,9 +77,9 @@ - (void)dealloc { name: UIApplicationDidReceiveMemoryWarningNotification object: nil]; + TT_RELEASE_SAFELY(_cssRulesSet); TT_RELEASE_SAFELY(_cssStyles); - TT_RELEASE_SAFELY(_cachedCssStyles); - TT_RELEASE_SAFELY(_colorLookupTable); + TT_RELEASE_SAFELY(_propertiesMap); [super dealloc]; } @@ -99,7 +105,7 @@ - (void)didReceiveMemoryWarning:(void*)object { /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)loadFromFilename:(NSString*)filename { TT_RELEASE_SAFELY(_cssStyles); - TT_RELEASE_SAFELY(_cachedCssStyles); + TT_RELEASE_SAFELY(_cssRulesSet); BOOL didLoadSuccessfully = NO; @@ -109,8 +115,8 @@ - (BOOL)loadFromFilename:(NSString*)filename { NSDictionary* results = [parser parseFilename:filename]; TT_RELEASE_SAFELY(parser); - _cssStyles = [results retain]; - _cachedCssStyles = [[NSMutableDictionary alloc] initWithCapacity:[_cssStyles count]]; + _cssStyles = [results retain]; + _cssRulesSet = [[NSMutableDictionary alloc] initWithCapacity:[_cssStyles count]]; didLoadSuccessfully = YES; } @@ -127,10 +133,14 @@ - (void)addStyleSheet:(TTCSSStyleSheet*)styleSheet { } // Clear the cache first. - TT_RELEASE_SAFELY(_cachedCssStyles); - _cachedCssStyles = [[NSMutableDictionary alloc] initWithCapacity:[_cssStyles count]]; + TT_RELEASE_SAFELY(_cssRulesSet); + _cssRulesSet = [[NSMutableDictionary alloc] initWithCapacity:[_cssStyles count]]; + + // Should init the styles? + if ( !_cssStyles ) + _cssStyles = [NSDictionary new]; - NSMutableDictionary* newStyles = [_cssStyles mutableCopy]; + NSMutableDictionary* newStyles = [_cssStyles mutableCopy]; for (NSString* selector in styleSheet.cssStyles) { NSDictionary* addingRuleSet = [styleSheet.cssStyles objectForKey:selector]; @@ -159,337 +169,296 @@ - (void)addStyleSheet:(TTCSSStyleSheet*)styleSheet { /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - -#pragma mark Object Cache - +#pragma mark Populate Methods. + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(NSDictionary*)propertiesMap { + if ( !_propertiesMap ) { + _propertiesMap = [[NSDictionary dictionaryWithObjectsAndKeys: + @"color", @"color", + @"font_family", @"font", + @"font_family", @"font-family", + @"font_weight", @"font-weight", + @"font_size", @"font-size", + @"background_color", @"background-color", + @"background_image", @"background-image", + @"text_shadow", @"text-shadow", + @"text_align", @"text-align", + @"width", @"width", + @"visibility", @"visibility", + @"height", @"height", + @"top", @"top", + @"left", @"left", + @"right", @"right", + @"bottom", @"bottom", + @"text_shadow_opacity", @"text-shadow-opacity", + @"margin_left", @"margin-left", + @"margin_right", @"margin-right", + @"vertical_align", @"vertical-align", + + nil] retain]; + } + return _propertiesMap; +} /////////////////////////////////////////////////////////////////////////////////////////////////// -- (id)objectForCssSelector:(NSString*)selector propertyName:(NSString*)propertyName { - NSDictionary* ruleSet = [_cachedCssStyles objectForKey:selector]; - if (nil != ruleSet) { - return [ruleSet objectForKey:propertyName]; - } - - return nil; -} +// When the Data Populator can't automatically convert some specific type. He will call +// this method and let you extend the class converting you specific type. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(id)tryToConvert:(id)object ofClass:(Class)objectClass toClass:(Class)convertToClass { + + ///////// /////// /////// /////// /////// /////// /////// /////// /////// /////// + // Text Shadow Model. + if ( convertToClass == [TTCSSTextShadowModel class] ) { + + // Anything more or less is unsupported, and therefore this property is ignored + // according to the W3C guidelines. + NSArray* values = object; + TTDASSERT([values count] >= 4); + if ([values count] >= 4) { + TTCSSTextShadowModel *shadowModel; + // Create an Shadow Model from data and return. + shadowModel = [TTCSSTextShadowModel initWithShadowColor:[values subarrayWithRange: + NSMakeRange(3,[values count] - 3)] + andShadowOffset:CGSizeMake([[values objectAtIndex:0] floatValue], + [[values objectAtIndex:1] floatValue]) + andShadowBlur:[values objectAtIndex:3]]; + // Return. + return shadowModel; + } + } + + ///////// /////// /////// /////// /////// /////// /////// /////// /////// /////// + // Strings. + if ( convertToClass == [NSString class] ) { + if ( [object isKindOfClass:[NSArray class]] ) { + NSMutableString *merged = [NSMutableString string]; + for ( NSString* part in object ) { + [merged appendString:part]; + } + // Return merged. + return merged; + } + else if ( [object isKindOfClass:[NSString class]] ) { + return object; + } + else { + return nil; + } + } + ///////// /////// /////// /////// /////// /////// /////// /////// /////// /////// + // Some crude data is returned as an NSArray... + if ( [object isKindOfClass:[NSArray class]] ) { -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)setObjectForCssSelector: (NSString*)selector - propertyName: (NSString*)propertyName - object: (id)object { - TTDASSERT(TTIsStringWithAnyText(selector)); - NSMutableDictionary* ruleSet = [_cachedCssStyles objectForKey:selector]; - if (nil == ruleSet) { - ruleSet = [[NSMutableDictionary alloc] init]; - [_cachedCssStyles setObject:ruleSet forKey:selector]; + // If have more than one element, return the full array. + if ( [object count] > 1 ) + return object; - // Can release here because it's now being retained by _processedCssStyles - [ruleSet release]; - } + // If not, we just need the first element. + id element = [object objectAtIndex:0]; - [ruleSet setObject:object forKey:propertyName]; -} + // Only one parameter is NSNumber, is the size of the font. Sometimes + // this value come with a 'pt' on it. + // We don't need it right? So we clean the string and convert to NSNumber. + if ( convertToClass == [NSNumber class] ) { + // Clean it. + element = [(NSString*)element stringByReplacingOccurrencesOfString:@"pt" + withString:@""]; + // Convert to number. + return [TTDataConverter convertToNSNumberThisObject:element]; + } -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (NSString*)selector:(NSString*)selector forState:(UIControlState)state { - selector = [selector lowercaseString]; - switch (state) { - default: - case UIControlStateNormal: - break; - - case UIControlStateHighlighted: { - selector = [selector stringByAppendingString:@":hover"]; - break; - } - } + // Return the element. + return element; + } - return selector; + // If can't convert. Return nil. + return nil; } - +/////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - -#pragma mark Colors - - /////////////////////////////////////////////////////////////////////////////////////////////////// -- (NSDictionary*)colorLookupTable { - if (nil == _colorLookupTable) { - // From the W3C HTML4 spec for colors: - // http://www.w3.org/TR/css3-color/ - _colorLookupTable = [[NSDictionary alloc] initWithObjectsAndKeys: - RGBCOLOR(0x00, 0xFF, 0xFF), @"aqua", - [UIColor blackColor], @"black", - RGBCOLOR(0x00, 0x00, 0xFF), @"blue", - RGBCOLOR(0xFF, 0x00, 0xFF), @"fuschia", - RGBCOLOR(0x80, 0x80, 0x80), @"gray", - RGBCOLOR(0x00, 0x80, 0x00), @"green", - RGBCOLOR(0x00, 0xFF, 0x00), @"lime", - RGBCOLOR(0x80, 0x00, 0x00), @"maroon", - RGBCOLOR(0x00, 0x00, 0x80), @"navy", - RGBCOLOR(0x80, 0x80, 0x00), @"olive", - RGBCOLOR(0xFF, 0x00, 0x00), @"red", - RGBCOLOR(0x80, 0x00, 0x80), @"purple", - RGBCOLOR(0xC0, 0xC0, 0xC0), @"silver", - RGBCOLOR(0x00, 0x80, 0x80), @"teal", - RGBACOLOR(0xFF, 0xFF, 0xFF, 0x00), @"transparent", - [UIColor whiteColor], @"white", - RGBCOLOR(0xFF, 0xFF, 0x00), @"yellow", - - // System colors - [UIColor lightTextColor], @"lightTextColor", - [UIColor darkTextColor], @"darkTextColor", - [UIColor groupTableViewBackgroundColor], @"groupTableViewBackgroundColor", - [UIColor viewFlipsideBackgroundColor], @"viewFlipsideBackgroundColor", - nil]; - } - - return _colorLookupTable; +- (NSString*)selector:(NSString*)selector forState:(UIControlState)state { + switch (state) { + default: + case UIControlStateNormal: + break; + + case UIControlStateHighlighted: { + selector = [selector stringByAppendingString:@":hover"]; + break; + } + } + + return selector; } - /////////////////////////////////////////////////////////////////////////////////////////////////// -- (UIColor*)colorFromCssValues:(NSArray*)cssValues { - UIColor* color = nil; - - // Anything more or less is unsupported, and therefore this property is ignored - // according to the W3C guidelines. - TTDASSERT([cssValues count] == 1 - || [cssValues count] == 5 // rgb( x x x ) - || [cssValues count] == 6); // rgba( x x x x ) - - if ([cssValues count] == 1) { - NSString* cssString = [cssValues objectAtIndex:0]; +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Object Cache - if ([cssString characterAtIndex:0] == '#') { - unsigned long colorValue = 0; +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(TTCSSRuleSet*)css:(NSString*)selector { + TTCSSRuleSet *ruleSet = [_cssRulesSet objectForKey:selector]; - // #FFF - if ([cssString length] == 4) { - colorValue = strtol([cssString UTF8String] + 1, nil, 16); - colorValue = ((colorValue & 0xF00) << 12) | ((colorValue & 0xF00) << 8) - | ((colorValue & 0xF0) << 8) | ((colorValue & 0xF0) << 4) - | ((colorValue & 0xF) << 4) | (colorValue & 0xF); + //////////////////////////////////////////////////// + // Can't find? Try to create it. + if ( ruleSet == nil ) { - // #FFFFFF - } else if ([cssString length] == 7) { - colorValue = strtol([cssString UTF8String] + 1, nil, 16); - } + //////////////////////////////////////////////////// + // Retrieve from "crude" repository? + NSDictionary *crudeData = [_cssStyles objectForKey:selector]; - color = RGBCOLOR(((colorValue & 0xFF0000) >> 16), - ((colorValue & 0xFF00) >> 8), - (colorValue & 0xFF)); + // Don't exist? Warn and return nil. + if ( !crudeData ) { + TTDWARNING( @"The CSS selector '%@' don't exist.", selector ); + return nil; + } - } else if ([cssString isEqualToString:@"none"]) { - color = nil; + // Create it. + ruleSet = [TTCSSRuleSet initWithSelectorName:selector]; - } else { - color = [[self colorLookupTable] objectForKey:cssString]; - } + // Populate + ruleSet = [TTDataPopulator populateObject:ruleSet + withData:crudeData + usingMap:[self propertiesMap] + withDelegate:self]; - } else if ([cssValues count] == 5 && [[cssValues objectAtIndex:0] isEqualToString:@"rgb("]) { - // rgb( x x x ) - color = RGBCOLOR([[cssValues objectAtIndex:1] floatValue], - [[cssValues objectAtIndex:2] floatValue], - [[cssValues objectAtIndex:3] floatValue]); - - } else if ([cssValues count] == 6 && [[cssValues objectAtIndex:0] isEqualToString:@"rgba("]) { - // rgba( x x x x ) - color = RGBACOLOR([[cssValues objectAtIndex:1] floatValue], - [[cssValues objectAtIndex:2] floatValue], - [[cssValues objectAtIndex:3] floatValue], - [[cssValues objectAtIndex:4] floatValue]); - } + // Cache it. + [_cssRulesSet setValue:ruleSet forKey:selector]; + } - return color; + // Return it. + return ruleSet; } - /////////////////////////////////////////////////////////////////////////////////////////////////// -- (UIColor*)colorWithCssSelector: (NSString*)selector - propertyName: (NSString*)propertyName { - UIColor* color = [self objectForCssSelector:selector propertyName:propertyName]; - - // No cached value. - if (nil == color) { - NSDictionary* ruleSet = [_cssStyles objectForKey:selector]; - - // The given selector actually exists in the CSS. - if (nil != ruleSet) { - NSArray* values = [ruleSet objectForKey:propertyName]; - - if (nil != values) { - color = [self colorFromCssValues:values]; - - // And we can actually parse it. - if (nil != color) { - [self setObjectForCssSelector:selector propertyName:propertyName object:color]; - } - } - } - } - - return color; +-(TTCSSRuleSet*)css:(NSString*)selectorName forState:(UIControlState)state { + return [self css:[self selector:selectorName forState:state]]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Colors /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIColor*)colorWithCssSelector:(NSString*)selector forState:(UIControlState)state { - selector = [self selector:selector forState:state]; + // Try Retrieve Rule Set from Cache. + TTCSSRuleSet *ruleSet = [self css:selector forState:state]; + + // If don't have an CSS Rule Set, return nil. + if ( !ruleSet ) return nil; - return [self colorWithCssSelector:selector propertyName:kCssPropertyColor]; + // Return color from rule set. + return ruleSet.color; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UIColor*)colorWithCssSelector:(NSString*)selector { + return [self colorWithCssSelector:selector forState:UIControlStateNormal]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIColor*)backgroundColorWithCssSelector:(NSString*)selector forState:(UIControlState)state { - selector = [self selector:selector forState:state]; + // Try Retrieve Rule Set from Cache. + TTCSSRuleSet *ruleSet = [self css:selector forState:state]; + + // If don't have an CSS Rule Set, return nil. + if ( !ruleSet ) return nil; - return [self colorWithCssSelector: selector - propertyName: kCssPropertyBackgroundColor]; + // Return background color from rule set. + return ruleSet.background_color; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UIColor*)backgroundColorWithCssSelector:(NSString*)selector { + return [self backgroundColorWithCssSelector:selector forState:UIControlStateNormal]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - #pragma mark Fonts - /////////////////////////////////////////////////////////////////////////////////////////////////// - (UIFont*)fontWithCssSelector:(NSString*)selector forState:(UIControlState)state { - selector = [self selector:selector forState:state]; - UIFont* font = [self objectForCssSelector:selector propertyName:kCssPropertyFont]; + // Try Retrieve Rule Set from Cache. + TTCSSRuleSet *ruleSet = [self css:selector forState:state]; - // No cached value. - if (nil == font) { - NSDictionary* ruleSet = [_cssStyles objectForKey:selector]; + // If don't have an CSS Rule Set, return nil. + if ( !ruleSet ) return nil; - // The given selector actually exists in the CSS. - if (nil != ruleSet) { - CGFloat fontSize = [UIFont systemFontSize]; - BOOL isBold = NO; + // Return decoded font from rule set. + return ruleSet.font; - NSArray* fontSizeValues = [ruleSet objectForKey:kCssPropertyFontSize]; - - if (nil != fontSizeValues) { - // Anything more or less is unsupported, and therefore this property is ignored - // according to the W3C guidelines. - TTDASSERT([fontSizeValues count] == 1); - if ([fontSizeValues count] == 1) { - fontSize = [[fontSizeValues objectAtIndex:0] floatValue]; - } - - NSArray* fontWeightValues = [ruleSet objectForKey:kCssPropertyFontWeight]; - // Anything more or less is unsupported, and therefore this property is ignored - // according to the W3C guidelines. - if ([fontWeightValues count] == 1) { - if ([[fontWeightValues objectAtIndex:0] isEqualToString:@"bold"]) { - isBold = YES; - } - } - - NSArray* fontFamilyValues = [ruleSet objectForKey:kCssPropertyFontFamily]; - if ([fontFamilyValues count] > 0) { - NSArray* systemFontFamilyNames = [UIFont familyNames]; - NSLog(@"Font families: %@", systemFontFamilyNames); - for (NSString* fontName in fontFamilyValues) { - } - if ([[fontFamilyValues objectAtIndex:0] isEqualToString:@"bold"]) { - isBold = YES; - } - } - - if (isBold) { - font = [UIFont boldSystemFontOfSize:fontSize]; - - } else { - font = [UIFont systemFontOfSize:fontSize]; - } - - if (nil != font) { - [self setObjectForCssSelector:selector propertyName:kCssPropertyFont object:font]; - } - } - } - } - - return font; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UIFont*)fontWithCssSelector:(NSString*)selector { + return [self fontWithCssSelector:selector forState:UIControlStateNormal]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - #pragma mark Text Shadows - /////////////////////////////////////////////////////////////////////////////////////////////////// -- (NSDictionary*)textShadowWithCssSelector:(NSString*)selector forState:(UIControlState)state { - NSDictionary* textShadow = [self objectForCssSelector: selector - propertyName: kCssPropertyTextShadow]; - - // No cached value. - if (nil == textShadow) { - NSDictionary* ruleSet = [_cssStyles objectForKey:selector]; - - // The given selector actually exists in the CSS. - if (nil != ruleSet) { - NSArray* values = [ruleSet objectForKey:kCssPropertyTextShadow]; - // Anything more or less is unsupported, and therefore this property is ignored - // according to the W3C guidelines. - TTDASSERT([values count] >= 4); - if ([values count] >= 4) { - NSNumber* horizOffset = [NSNumber numberWithFloat:[[values objectAtIndex:0] floatValue]]; - NSNumber* vertOffset = [NSNumber numberWithFloat:[[values objectAtIndex:1] floatValue]]; - NSNumber* blurAmount = [NSNumber numberWithFloat:[[values objectAtIndex:2] floatValue]]; - UIColor* color = [self colorFromCssValues: - [values subarrayWithRange: - NSMakeRange(3, [values count] - 3)]]; - - textShadow = [[NSDictionary alloc] initWithObjectsAndKeys: - horizOffset, kKeyTextShadowHOffset, - vertOffset, kKeyTextShadowVOffset, - blurAmount, kKeyTextShadowBlur, - color, kKeyTextShadowColor, - nil]; - } - - if (nil != textShadow) { - [self setObjectForCssSelector: selector - propertyName: kCssPropertyTextShadow - object: textShadow]; - } - } - } +- (UIColor*)textShadowColorWithCssSelector:(NSString*)selector forState:(UIControlState)state { + // Try Retrieve Rule Set from Cache. + TTCSSRuleSet *ruleSet = [self css:selector forState:state]; - return textShadow; + // If don't have an CSS Rule Set, return nil. + if ( !ruleSet ) return nil; + + // Return Text Shadow Color. + return ruleSet.text_shadow.shadowColor; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (UIColor*)textShadowColorWithCssSelector:(NSString*)selector { + return [self textShadowColorWithCssSelector:selector forState:UIControlStateNormal]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// -- (UIColor*)textShadowColorWithCssSelector:(NSString*)selector forState:(UIControlState)state { - selector = [self selector:selector forState:state]; +- (CGSize)textShadowOffsetWithCssSelector:(NSString*)selector forState:(UIControlState)state { + // Try Retrieve Rule Set from Cache. + TTCSSRuleSet *ruleSet = [self css:selector forState:state]; - NSDictionary* textShadow = [self textShadowWithCssSelector: selector - forState: state]; - return [textShadow objectForKey:kKeyTextShadowColor]; + // If don't have an CSS Rule Set, return zero. + if ( !ruleSet ) return CGSizeZero; + + // Return Text Shadow Color. + return ruleSet.text_shadow.shadowOffset; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (CGSize)textShadowOffsetWithCssSelector:(NSString*)selector { + return [self textShadowOffsetWithCssSelector:selector forState:UIControlStateNormal]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// -- (CGSize)textShadowOffsetWithCssSelector:(NSString*)selector forState:(UIControlState)state { - selector = [self selector:selector forState:state]; +- (CGFloat)textShadowRadiusWithCssSelector:(NSString*)selector forState:(UIControlState)state { + // Try Retrieve Rule Set from Cache. + TTCSSRuleSet *ruleSet = [self css:selector forState:state]; + + // If don't have an CSS Rule Set, return zero. + if ( !ruleSet ) return 0.0; - NSDictionary* textShadow = [self textShadowWithCssSelector: selector - forState: state]; - return CGSizeMake([[textShadow objectForKey:kKeyTextShadowHOffset] floatValue], - [[textShadow objectForKey:kKeyTextShadowVOffset] floatValue]); + // Return Shadow Blur. + return [[ruleSet.text_shadow shadowBlur] floatValue]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (CGFloat)textShadowRadiusWithCssSelector:(NSString*)selector { + return [self textShadowRadiusWithCssSelector:selector forState:UIControlStateNormal]; +} /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -499,9 +468,8 @@ - (CGSize)textShadowOffsetWithCssSelector:(NSString*)selector forState:(UIContro /////////////////////////////////////////////////////////////////////////////////////////////////// - (void)freeMemory { - TT_RELEASE_SAFELY(_cachedCssStyles); - TT_RELEASE_SAFELY(_colorLookupTable); - _cachedCssStyles = [[NSMutableDictionary alloc] initWithCapacity:[_cssStyles count]]; + TT_RELEASE_SAFELY(_cssRulesSet); + _cssRulesSet = [[NSMutableDictionary alloc] initWithCapacity:[_cssStyles count]]; } diff --git a/src/extThree20CSSStyle/Sources/TTCSSTextShadowModel.m b/src/extThree20CSSStyle/Sources/TTCSSTextShadowModel.m new file mode 100644 index 0000000000..8e9350800a --- /dev/null +++ b/src/extThree20CSSStyle/Sources/TTCSSTextShadowModel.m @@ -0,0 +1,108 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "extThree20CSSStyle/TTCSSTextShadowModel.h" +#import "extThree20CSSStyle/TTCSSFunctions.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/TTGlobalCore.h" +#import "Three20Core/TTDebug.h" + +@implementation TTCSSTextShadowModel +@synthesize shadowOffset, shadowColor, shadowBlur; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Init Methods. + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++(id)initWithShadowColor:(id)anColor andShadowOffset:(CGSize)anOffset { + TTCSSTextShadowModel *instance = [[TTCSSTextShadowModel new] autorelease]; + instance.shadowColor = anColor; + instance.shadowOffset = anOffset; + return instance; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++(id)initWithShadowColor:(id)anColor andShadowOffset:(CGSize)anOffset + andShadowBlur:(NSNumber*)blur { + TTCSSTextShadowModel *instance = [TTCSSTextShadowModel initWithShadowColor:anColor + andShadowOffset:anOffset]; + instance.shadowBlur = blur; + return instance; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(id)init { + self = [super init]; + if (self != nil) { + + // Default values. + self.shadowOffset = CGSizeMake(0, -1); + self.shadowColor = [UIColor clearColor]; + self.shadowBlur = [[NSNumber numberWithInt:3] retain]; + + } + return self; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(void)dealloc { + TT_RELEASE_SAFELY( shadowColor ); + TT_RELEASE_SAFELY( shadowBlur ); + [super dealloc]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Set Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(void)setShadowColor:(id)anValue { + + ///////////////////////////////// + // Release. + if ( shadowColor ) + TT_RELEASE_SAFELY( shadowColor ); + + /////////////////////////////////////// + // Array of color? + if ( [anValue isKindOfClass:[NSArray class]] ) { + + // Set. + shadowColor = [TTColorFromCssValues(anValue) retain]; + + } + + /////////////////////////////////////// + // String color? + else if ( [anValue isKindOfClass:[NSString class]] ) { + + // Set. + shadowColor = [TTColorFromCssValues([NSArray arrayWithObject:anValue]) retain]; + } + + /////////////////////////////////////// + // UIColor? + else if ( [anValue isKindOfClass:[UIColor class]] ) { + + // Set. + shadowColor = [anValue retain]; + } +} + +@end diff --git a/src/extThree20CSSStyle/Sources/TTDefaultCSSStyleSheet.m b/src/extThree20CSSStyle/Sources/TTDefaultCSSStyleSheet.m index a301da2a8c..0658c0b17c 100644 --- a/src/extThree20CSSStyle/Sources/TTDefaultCSSStyleSheet.m +++ b/src/extThree20CSSStyle/Sources/TTDefaultCSSStyleSheet.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,9 +15,11 @@ // #import "extThree20CSSStyle/TTDefaultCSSStyleSheet.h" +#import "extThree20CSSStyle/TTCSSRuleSet.h" // extThree20CSSStyle #import "extThree20CSSStyle/TTCSSStyleSheet.h" +#import "extThree20CSSStyle/TTCSSApplyProtocol.h" // Core #import "Three20Core/TTCorePreprocessorMacros.h" @@ -37,7 +39,8 @@ @implementation TTDefaultCSSStyleSheet /////////////////////////////////////////////////////////////////////////////////////////////////// - (id)init { - if (self = [super init]) { + self = [super init]; + if (self) { [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(didReceiveMemoryWarning:) @@ -49,12 +52,14 @@ - (id)init { BOOL loadedSuccessfully = [_styleSheet loadFromFilename:TTPathForBundleResource(kDefaultCSSPath)]; - // If this fails, it's very likely that you forgot to add the extThree20CSSStyle.bundle file - // to your project. If you didn't, ensure that it's being copied in the "Copy Bundle Resources" - // phase. - TTDASSERT(loadedSuccessfully); + // Test if load succesfully. if (!loadedSuccessfully) { - // Bail out. + [NSException raise:NSInternalInconsistencyException + format:@"%@ fail to load the Default CSS file. " + @"It's very likely that you forgot to add the extThree20CSSStyle.bundle " + @"to your project. If you didn't, ensure that it's being copied in " + @"the 'Copy Bundle Resources' phase.", NSStringFromClass([self class])]; + return nil; } } @@ -70,6 +75,7 @@ - (void)dealloc { object: nil]; TT_RELEASE_SAFELY(_styleSheet); + TT_RELEASE_SAFELY(_cachedCssFiles); [super dealloc]; } @@ -96,13 +102,20 @@ - (void)freeMemory { /////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - #pragma mark Public /////////////////////////////////////////////////////////////////////////////////////////////////// -- (BOOL)addStyleSheetFromDisk:(NSString*)filename { +- (BOOL)addStyleSheetFromDisk:(NSString*)filename ignoreCache:(BOOL)cache { + + // Check if this file is already cached, also respect if should ignore the cache. + if (!cache && [_cachedCssFiles containsObject:filename]) { + TTDWARNING( @"'%@' is already loaded and cached. Ignoring...", filename ); + return NO; + } + TTCSSStyleSheet* styleSheet = [[TTCSSStyleSheet alloc] init]; BOOL loadedSuccessfully = [styleSheet loadFromFilename:filename]; @@ -111,17 +124,23 @@ - (BOOL)addStyleSheetFromDisk:(NSString*)filename { TT_RELEASE_SAFELY(styleSheet); + ///////////// //////// //////// //////// //////// + // Init cache, if needed. + if ( !_cachedCssFiles ) + _cachedCssFiles = [NSMutableSet new]; + + // Cache if Loaded Successfully. + if ( loadedSuccessfully ) + [_cachedCssFiles addObject:filename]; + return loadedSuccessfully; } - /////////////////////////////////////////////////////////////////////////////////////////////////// -- (UIColor*)backgroundColorForCSSSelector:(NSString*)cssSelector { - return [_styleSheet backgroundColorWithCssSelector: cssSelector - forState: UIControlStateNormal]; +- (BOOL)addStyleSheetFromDisk:(NSString*)filename { + return [self addStyleSheetFromDisk:filename ignoreCache:NO]; } - /////////////////////////////////////////////////////////////////////////////////////////////////// + (TTDefaultCSSStyleSheet*)globalCSSStyleSheet { TTDASSERT([[TTStyleSheet globalStyleSheet] isKindOfClass:[TTDefaultStyleSheet class]]); @@ -129,6 +148,18 @@ + (TTDefaultCSSStyleSheet*)globalCSSStyleSheet { } +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(void)applyCssFromSelector:(NSString*)selectorName toObject:(id)anObject { + // Assert that the conforms with the protocol. + if ( ![(id)anObject conformsToProtocol:@protocol(TTCSSApplyProtocol)] ) + [NSException raise:NSInternalInconsistencyException + format:@"'%@' must conform with the 'TTCSSApplyProtocol' protocol", + NSStringFromClass([(id)anObject class]) ]; + + // Apply retrieved rules to the object. + [anObject applyCssRules:[self css:selectorName]]; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - @@ -353,6 +384,16 @@ - (CGSize)tableRefreshHeaderTextShadowOffset { forState: UIControlStateNormal]; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(TTCSSRuleSet*)css:(NSString*)selector { + return [_styleSheet css:selector]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(TTCSSRuleSet*)css:(NSString*)selectorName forState:(UIControlState)state { + return [_styleSheet css:selectorName forState:state]; +} + @end diff --git a/src/extThree20CSSStyle/Sources/TTExtensionLoader.m b/src/extThree20CSSStyle/Sources/TTExtensionLoader.m new file mode 100644 index 0000000000..8cdc99c857 --- /dev/null +++ b/src/extThree20CSSStyle/Sources/TTExtensionLoader.m @@ -0,0 +1,56 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "extThree20CSSStyle/TTExtensionLoader.h" + +// Core +#import "Three20Core/TTExtensionAuthor.h" +#import "Three20Core/TTExtensionInfo.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTExtensionLoader (TTCSSStyleExtension) + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)loadExtensionNamedThree20CSSStyle { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTExtensionInfo*)extensionInfoNamedThree20CSSStyle { + TTExtensionInfo* extension = [[TTExtensionInfo alloc] init]; + + extension.name = @"Three20 CSS Styling"; + extension.description = + @"The CSS Styling extension provides support for customizing the style of an app using" + @" standard CSS."; + extension.version = @"1.0"; + extension.copyright = @"Copyright 2009-2010 Facebook"; + extension.license = @"Apache 2.0"; + extension.authors = [NSArray arrayWithObjects: + [TTExtensionAuthor authorWithName:@"Jeff Verkoeyen"], + nil]; + + return [extension autorelease]; +} + + +@end + diff --git a/src/extThree20CSSStyle/Sources/TTShadowStyleAdditions.m b/src/extThree20CSSStyle/Sources/TTShadowStyleAdditions.m new file mode 100644 index 0000000000..83d27d2121 --- /dev/null +++ b/src/extThree20CSSStyle/Sources/TTShadowStyleAdditions.m @@ -0,0 +1,63 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "extThree20CSSStyle/TTShadowStyleAdditions.h" + +#import "extThree20CSSStyle/TTCSSGlobalStyle.h" +#import "extThree20CSSStyle/TTCSSStyleSheet.h" +#import "extThree20CSSStyle/TTDefaultCSSStyleSheet.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Additions. + */ +TT_FIX_CATEGORY_BUG(TTCSSShadowStyleAdditions) + +@implementation TTShadowStyle (TTCSSCategory) + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Class public + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (TTShadowStyle*)styleWithCssSelector:(NSString*)selector + forState:(UIControlState)state + next:(TTStyle*)next { + TTShadowStyle* style = [[[self alloc] initWithNext:next] autorelease]; + style.color = TTCSSSTATE(selector, shadowColor, state); + style.blur = TTCSSSTATE(selector, shadowRadius, state); + style.offset = TTCSSSTATE(selector, shadowOffset, state); + return style; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (TTShadowStyle*)styleWithCssSelector:(NSString*)selector + next:(TTStyle*)next { + return [self styleWithCssSelector:selector + forState:UIControlStateNormal next:next]; +} + + +@end diff --git a/src/extThree20CSSStyle/Sources/TTTextStyleAdditions.m b/src/extThree20CSSStyle/Sources/TTTextStyleAdditions.m new file mode 100644 index 0000000000..792669a6e1 --- /dev/null +++ b/src/extThree20CSSStyle/Sources/TTTextStyleAdditions.m @@ -0,0 +1,130 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "extThree20CSSStyle/TTTextStyleAdditions.h" + +#import "extThree20CSSStyle/TTCSSGlobalStyle.h" +#import "extThree20CSSStyle/TTCSSStyleSheet.h" +#import "extThree20CSSStyle/TTDefaultCSSStyleSheet.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Additions. + */ +TT_FIX_CATEGORY_BUG(TTCSSTextStyleAdditions) + +@implementation TTTextStyle (TTCSSCategory) + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Class public + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + forState:(UIControlState)state + next:(TTStyle*)next { + TTTextStyle* style = [[[self alloc] initWithNext:next] autorelease]; + UIFont *font = TTCSSSTATE(selector, font, state); + UIColor *color = TTCSSSTATE(selector, color, state); + UIColor *shadowColor = TTCSSSTATE(selector, shadowColor, state); + CGSize shadowOffset = TTCSSSTATE(selector, shadowOffset, state); + + if (font) style.font = font; + if (color) style.color = color; + if (shadowColor) { + style.shadowColor = shadowColor; + style.shadowOffset = shadowOffset; + } + return style; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + forState:(UIControlState)state + minimumFontSize:(CGFloat)minimumFontSize + next:(TTStyle*)next { + TTTextStyle* style = [self styleWithCssSelector:selector forState:state next:next]; + style.minimumFontSize = minimumFontSize; + return style; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + forState:(UIControlState)state + minimumFontSize:(CGFloat)minimumFontSize + textAlignment:(UITextAlignment)textAlignment + verticalAlignment:(UIControlContentVerticalAlignment)verticalAlignment + lineBreakMode:(UILineBreakMode)lineBreakMode + numberOfLines:(NSInteger)numberOfLines + next:(TTStyle*)next { + TTTextStyle* style = [self styleWithCssSelector:selector forState:state next:next]; + style.minimumFontSize = minimumFontSize; + style.textAlignment = textAlignment; + style.verticalAlignment = verticalAlignment; + style.lineBreakMode = lineBreakMode; + style.numberOfLines = numberOfLines; + return style; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector next:(TTStyle*)next { + return [self styleWithCssSelector:selector + forState:UIControlStateNormal + next:next]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + minimumFontSize:(CGFloat)minimumFontSize + next:(TTStyle*)next { + return [self styleWithCssSelector:selector + forState:UIControlStateNormal + minimumFontSize:minimumFontSize + next:next]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (TTTextStyle*)styleWithCssSelector:(NSString*)selector + minimumFontSize:(CGFloat)minimumFontSize + textAlignment:(UITextAlignment)textAlignment + verticalAlignment:(UIControlContentVerticalAlignment)verticalAlignment + lineBreakMode:(UILineBreakMode)lineBreakMode + numberOfLines:(NSInteger)numberOfLines + next:(TTStyle*)next { + return [self styleWithCssSelector:selector + forState:UIControlStateNormal + minimumFontSize:minimumFontSize + textAlignment:textAlignment + verticalAlignment:verticalAlignment + lineBreakMode:lineBreakMode + numberOfLines:numberOfLines + next:next]; +} + +@end diff --git a/src/extThree20CSSStyle/Sources/UILabel+CSSAdditions.m b/src/extThree20CSSStyle/Sources/UILabel+CSSAdditions.m new file mode 100644 index 0000000000..c964517957 --- /dev/null +++ b/src/extThree20CSSStyle/Sources/UILabel+CSSAdditions.m @@ -0,0 +1,83 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#import "extThree20CSSStyle/UILabel+CSSAdditions.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + +#ifdef __IPHONE_3_2 +#import +#endif + +/** + * Additions. + */ +TT_FIX_CATEGORY_BUG(TTCSSLabelAdditions) + +@implementation UILabel (TTCSSAdditions) + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Receive an Set of Rules from some CSS selector to apply. This method +// receive an TTCSSRuleSet with all properties ready to be set. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(void)applyCssRules:(TTCSSRuleSet*)anRuleSet { + // Super. + [super applyCssRules:anRuleSet]; + + // Set properties from CSS, if defined. + if (anRuleSet.font) self.font = anRuleSet.font; + if (anRuleSet.color) self.textColor = anRuleSet.color; + + // Alignment. + if (anRuleSet.text_align) self.textAlignment = [anRuleSet textAlign]; + + // Set Shadow, if needed. + if (anRuleSet.text_shadow.shadowColor) { + + // iPhone 3.2 accept blur on shadows, so do it. + #ifdef __IPHONE_3_2 + // If blur defined. + if (anRuleSet.text_shadow.shadowBlur) { + self.layer.shadowOpacity = [anRuleSet.text_shadow_opacity floatValue]; + self.layer.shadowColor = [anRuleSet.text_shadow.shadowColor CGColor]; + self.layer.shadowOffset = anRuleSet.text_shadow.shadowOffset; + self.layer.shadowRadius = [anRuleSet.text_shadow.shadowBlur floatValue]; + self.layer.masksToBounds = NO; + } + //////////// ///// ///// ///// ///// ///// ///// ///// ///// + // If not. + else { + self.shadowColor = anRuleSet.text_shadow.shadowColor; + self.shadowOffset = anRuleSet.text_shadow.shadowOffset; + } + //////////// ///// ///// ///// ///// ///// ///// ///// ///// + // If not, just color and offset. + #else + self.shadowColor = anRuleSet.text_shadow.shadowColor; + self.shadowOffset = anRuleSet.text_shadow.shadowOffset; + #endif + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Receive an Set of Rules from some CSS selector to apply. This method +// receive an TTCSSRuleSet with all properties ready to be set. +/////////////////////////////////////////////////////////////////////////////////////////////////// + + +@end + + diff --git a/src/extThree20CSSStyle/Sources/UIView+CSSAdditions.m b/src/extThree20CSSStyle/Sources/UIView+CSSAdditions.m new file mode 100644 index 0000000000..1a3f9e669b --- /dev/null +++ b/src/extThree20CSSStyle/Sources/UIView+CSSAdditions.m @@ -0,0 +1,103 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "extThree20CSSStyle/UIView+CSSAdditions.h" +#import "extThree20CSSStyle/TTDefaultCSSStyleSheet.h" +#import "extThree20CSSStyle/TTCSSGlobalStyle.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" +#import "Three20Core/TTGlobalCorePaths.h" + +/** + * Additions. + */ +TT_FIX_CATEGORY_BUG(TTCSSViewAdditions) + +@implementation UIView (TTCSSAdditions) + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Convenient Init method to create an UIView and apply an CSS Rule Set on one pass. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(id)initWithFrame:(CGRect)anFrame andApplyCssFromSelector:(NSString*)anSelector { + self = [self initWithFrame:anFrame]; + if (self != nil) { + // Apply CSS. + TTApplyCSS( anSelector, self ); + } + return self; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Receive an Set of Rules from some CSS selector to apply. This method +// receive an TTCSSRuleSet with all properties ready to be set. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(void)applyCssRules:(TTCSSRuleSet*)anRuleSet { + // Set properties from CSS. + self.backgroundColor = anRuleSet.background_color; + + ////////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// //// + // Set image background. + if ( anRuleSet.background_image ) { + + ////////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// //// + // Assert that this file exist on the bundle + BOOL exist = [[NSFileManager defaultManager] fileExistsAtPath: + TTPathForBundleResource( anRuleSet.background_image )]; + if ( !exist ) { + NSString *m = [NSString stringWithFormat:@"The file '%@' on the property %@", + anRuleSet.background_image, + @"'background_image' don't exist on your application bundle."]; + [NSException raise:@"NSFileNotFoundException" format:@"%@", m]; + } + + ////////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// //// + // If ok add as subview. + [self addSubview:[[UIImageView alloc] initWithImage: + [UIImage imageNamed:anRuleSet.background_image]]]; + } + + ////////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// //// + // Hidden? + self.hidden = anRuleSet.hidden; + + ////////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// //// + // Original frame. + CGRect newFrame = self.frame; + + ////////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// //// + // Change Frame from CSS values if needed. + newFrame.origin.x = ( anRuleSet.left ? anRuleSet.origin.x : newFrame.origin.x ); + newFrame.origin.y = ( anRuleSet.top ? anRuleSet.origin.y : newFrame.origin.y ); + /// + newFrame.size.width = ( anRuleSet.width ? anRuleSet.size.width : newFrame.size.width ); + newFrame.size.height = ( anRuleSet.height ? anRuleSet.size.height : newFrame.size.height ); + + // Apply. + self.frame = newFrame; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Set a CSS stylesheet selector. +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)applyCssSelector:(NSString *)anSelector { + // Apply CSS. + TTApplyCSS( anSelector, self ); +} + +@end diff --git a/src/extThree20CSSStyle/ThirdPart/TTDataConverter.m b/src/extThree20CSSStyle/ThirdPart/TTDataConverter.m new file mode 100644 index 0000000000..04c6ad2a39 --- /dev/null +++ b/src/extThree20CSSStyle/ThirdPart/TTDataConverter.m @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org ) + * JUMP GIT Repository: https://github.com/seqoy/jump + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#import "extThree20CSSStyle/TTDataConverter.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTDataConverter + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Convert Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Take an NSString Object and try to convert to NSNumber. +/////////////////////////////////////////////////////////////////////////////////////////////////// ++(NSNumber*)convertToNSNumberThisObject:(id)anObject { + + // Convert from NSString to NSNumber. + if ( [anObject isKindOfClass:[NSString class]] ) { + + // Create an Scanner, the scaner will scan the string looking for specific type number. + NSScanner *stringScanner = [NSScanner scannerWithString:anObject]; + + // NOTE: The order is very important ->-- 'float' after 'double' and then 'int'. + + // Scan string looking for FLOAT. + float aFloat; + if ( [stringScanner scanFloat:&aFloat] ) + return [NSNumber numberWithFloat:[anObject floatValue]]; + + // Scan string looking for DOUBLE. + double aDouble; + if ( [stringScanner scanDouble:&aDouble] ) + return [NSNumber numberWithDouble:[anObject doubleValue]]; + + // Scan string looking for INT. + int aInt; + if ( [stringScanner scanInt:&aInt] ) + return [NSNumber numberWithInt:[anObject intValue]]; + } + + // Can't convert, return NIL. + return nil; +} +@end diff --git a/src/extThree20CSSStyle/ThirdPart/TTDataPopulator.m b/src/extThree20CSSStyle/ThirdPart/TTDataPopulator.m new file mode 100644 index 0000000000..15359dacd8 --- /dev/null +++ b/src/extThree20CSSStyle/ThirdPart/TTDataPopulator.m @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org ) + * JUMP GIT Repository: https://github.com/seqoy/jump + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#import "extThree20CSSStyle/TTDataPopulator.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTDataPopulator +@synthesize delegate; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Private Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(NSString*)capitalizeFirstLetter:(NSString*)anString { + + NSString *firstLetter = [ [anString substringWithRange:NSMakeRange(0, 1)] uppercaseString]; + NSString *rest = [anString substringFromIndex:1]; + + // Return formatted String. + return [NSString stringWithFormat:@"%@%@", firstLetter, rest]; + +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(id)tryToGrabDataKey:(NSString*)anKey fromMap:(NSDictionary*)anMap { + + // Try To Grab a Data Key + return [anMap objectForKey:anKey]; + +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(Class)grabTheClassOfProperty:(NSString*)firstKey onObject:(id)firstObject { + + // ///////////// ///////////// ///////////// ///////////// ///////////// + /* + * To correct compile, you need to ADD the libobjc.A.dylib framework to + * your target. And also #import the + */ + + // Get the property (Method) attributes. + objc_property_t property = class_getProperty([firstObject class], [firstKey UTF8String]); + + // Test if some data was returned, first. + if ( property != NULL ) { + + // Attribute description: + NSString *attributeDescripion = [NSString stringWithCString:property_getAttributes(property) + encoding:[NSString defaultCStringEncoding]]; + + // Isolate the Class of this property. + NSArray *elements = [attributeDescripion componentsSeparatedByString:@"\""]; + + // Should have 3 elements, if don't we can't process. + if ( [elements count] != 3 ) return nil; + + // The second element is what we want... So transform him on a class. + Class firstKeyClass = NSClassFromString([elements objectAtIndex:1]); + + // And return. + return firstKeyClass; + } + + ///////////// ///////////// /////// + // If can't decode, return nil. + return nil; + +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Check if the *firstKey* (Method) type of the Object **anObject** (Class) +// is the same that the secondKey (Method) secondObject (Class). +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(BOOL)checkIfObject:(id)firstObject ofKey:(NSString*)firstKey + hasSameTypeOf:(id)secondObject ofKey:(NSString*)secondKey { + + // Class of the First Key. + Class firstKeyClass = [self grabTheClassOfProperty:firstKey onObject:firstObject]; + + // Return if matches. + return [secondObject isKindOfClass:firstKeyClass]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Try to convert the **fistObject** to the same type of the **secondObject**. +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(id)tryToConvert:(id)firstObject ofKey:(NSString*)firstKey + toTheSameClassOf:(id)secondObject ofKey:(NSString*)secondKey { + + // Class of the Second Key. + Class secondKeyClass = [self grabTheClassOfProperty:secondKey onObject:secondObject]; + + // Converted value. + id converted = nil; + + ///////////// ///////////// //////// + // If desired value are an NSNumber. + if ( secondKeyClass == [NSNumber class] ) + converted = [TTDataConverter convertToNSNumberThisObject:firstObject]; + + // Maybe the delegate can convert it... + if ( delegate ) + if ( [(id)delegate respondsToSelector:@selector(tryToConvert:ofClass:toClass:) ] ) + converted = [delegate tryToConvert:firstObject ofClass:[firstObject class] + toClass:secondKeyClass]; + + // Return converted. + return converted; + +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +-(id)populateObject:(id)anObject withData:(NSDictionary*)anDictionary + usingMap:(NSDictionary*)anMap { + + //// //// //// //// //// //// //// //// //// //// //// //// + // Loop every property. + for ( id property in anDictionary ) { + + // Try to find corresponding data key. + NSString *dataKey = [self tryToGrabDataKey:property fromMap:anMap]; + + // Only process if found. + if ( dataKey ) { + + // Method Name for corresponding server key. + NSString *convertedMethodName = [NSString stringWithFormat:@"set%@:", + [self capitalizeFirstLetter:dataKey]]; + + // Selector for this element. + SEL anSelector = NSSelectorFromString( convertedMethodName ); + + ///////////////////////////////////////////////////////////////////// + // Check if object responds to this SET selector. + if ( [anObject respondsToSelector:anSelector] + && + ! [[anDictionary objectForKey:property] isKindOfClass:[NSNull class]] ) + { + // Retrieve the data. + id serverData = [anDictionary objectForKey:property]; + + //// //// //// //// //// //// //// //// //// //// //// //// //// + // Check if Server Data has the same type of Core Data Object. + //// //// //// //// //// //// ///// //// // //// //// //// ///// + if ( ! [self checkIfObject:anObject ofKey:dataKey + hasSameTypeOf:serverData ofKey:property] ) + { + // if DONT → Try to convert. ➘ (Oh yeah!) + serverData = [self tryToConvert:serverData ofKey:property + toTheSameClassOf:anObject ofKey:dataKey]; + } + //// //// //// //// //// //// //// //// //// //////// //// //////// //// ///// + // Set Value if isn't NIL. + if ( serverData != nil ) { + + // Validate first. + NSError *anError; + if ( ![anObject validateValue:&serverData forKey:dataKey error:&anError] ) { + [NSException raise:anError.domain format:@"%@", [anError localizedDescription]]; + return nil; + } + + // Set the value. + [anObject setValue:serverData forKey:dataKey]; + } + } + } + } + + // Return populated object. + return anObject; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Populate Methods. +/////////////////////////////////////////////////////////////////////////////////////////////////// ++(id)populateObject:(id)anObject withData:(NSDictionary*)anDictionary + usingMap:(NSDictionary*)anMap withDelegate:(id)anDelegate { + // Create an instance. + TTDataPopulator *anInstance = [[[self alloc] init] autorelease]; + // Set delegate. + anInstance.delegate = anDelegate; + + ///////////// + return [anInstance populateObject:anObject + withData:anDictionary + usingMap:anMap]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Populate the informed object with data. +/////////////////////////////////////////////////////////////////////////////////////////////////// ++(id)populateObject:(id)anObject withData:(NSDictionary*)anDictionary + usingMap:(NSDictionary*)anMap { + return [self populateObject:anObject withData:anDictionary usingMap:anMap withDelegate:nil]; +} +///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// //// +@end diff --git a/src/extThree20CSSStyle/UnitTests/CssParserTests.m b/src/extThree20CSSStyle/UnitTests/CssParserTests.m index 3b41a8aa3e..05dc7d65e2 100644 --- a/src/extThree20CSSStyle/UnitTests/CssParserTests.m +++ b/src/extThree20CSSStyle/UnitTests/CssParserTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,10 +14,8 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. - -// See Also: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html +// See: http://bit.ly/hS5nNh for unit test macros. +// See Also: http://bit.ly/hgpqd2 #import diff --git a/src/extThree20CSSStyle/UnitTests/CssRuleSetTests.m b/src/extThree20CSSStyle/UnitTests/CssRuleSetTests.m new file mode 100644 index 0000000000..1f2cbc4971 --- /dev/null +++ b/src/extThree20CSSStyle/UnitTests/CssRuleSetTests.m @@ -0,0 +1,100 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// See: http://bit.ly/hS5nNh for unit test macros. +// See Also: http://bit.ly/hgpqd2 + +#import + +#import "TTCSSRuleSet.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + +@interface CssRuleSetTests : SenTestCase { + TTCSSRuleSet *_ruleSet; +} + +@end + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation CssRuleSetTests + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)setUp { + _ruleSet = [[TTCSSRuleSet initWithSelectorName:@"testSelector"] retain]; + STAssertNotNil( _ruleSet, @"CSS Rule Set Object wasn't initiated correctly"); + STAssertTrue( [_ruleSet.selector isEqualToString:@"testSelector"], + @"Selector name wasn't setted correctly." ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)tearDown { + TT_RELEASE_SAFELY(_ruleSet); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +//- (void)testLoadColorData { +// // Test UI Color. +// UIColor *anColor = [UIColor redColor]; +// _ruleSet.color = anColor; +// _ruleSet.background_color = anColor; +// /////////////////////// //////////////// /////////////////////// //////////////// +// STAssertTrue( anColor == _ruleSet.color, +// @"'color' property with UIColor value wasn't setted correctly" ); +// /////////////////////// //////////////// /////////////////////// //////////////// +// STAssertTrue( anColor == _ruleSet.background_color, +// @"'background_color' property with UIColor value wasn't setted correctly" ); +// +// /////////////////////// //////////////// /////////////////////// //////////////// +// // Test String Color. +// _ruleSet.color = @"red"; +// _ruleSet.background_color = @"red"; +// /////////////////////// //////////////// /////////////////////// //////////////// +// STAssertTrue( anColor == _ruleSet.color, +// @"'color' property with String value wasn't setted correctly" ); +// /////////////////////// //////////////// /////////////////////// //////////////// +// STAssertTrue( anColor == _ruleSet.background_color, +// @"'background_color' property with String value wasn't setted correctly" ); +//} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)testFont { + // Set font values. + _ruleSet.font_family = @"Helvetica"; + _ruleSet.font_weight = @"BoldOblique"; + _ruleSet.font_size = [NSNumber numberWithInt:10]; + /////////////////////// //////////////// /////////////////////// //////////////// + STAssertTrue( [_ruleSet.font_family isEqualToString:@"Helvetica"], + @"'font_family' property wasn't setted correctly" ); + /////////////////////// //////////////// /////////////////////// //////////////// + STAssertTrue( [_ruleSet.font_weight isEqualToString:@"BoldOblique"], + @"'font_weight' property wasn't setted correctly" ); + /////////////////////// //////////////// /////////////////////// //////////////// + STAssertTrue( [_ruleSet.font_size intValue] == 10, + @"'font_size' property wasn't setted correctly" ); + /////////////////////// //////////////// /////////////////////// //////////////// + //UIFont *createdFont = _ruleSet.font; + //STAssertNotNil( createdFont, @"Font must be created at this time"); +} + + +@end diff --git a/src/extThree20CSSStyle/UnitTests/CssStyleSheetTests.m b/src/extThree20CSSStyle/UnitTests/CssStyleSheetTests.m index 2c6cac7420..d1f55c24a8 100644 --- a/src/extThree20CSSStyle/UnitTests/CssStyleSheetTests.m +++ b/src/extThree20CSSStyle/UnitTests/CssStyleSheetTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,10 +14,8 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. - -// See Also: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html +// See: http://bit.ly/hS5nNh for unit test macros. +// See Also: http://bit.ly/hgpqd2 #import diff --git a/src/extThree20CSSStyle/extThree20CSSStyle.xcodeproj/project.pbxproj b/src/extThree20CSSStyle/extThree20CSSStyle.xcodeproj/project.pbxproj index f29460c791..d5933ad102 100755 --- a/src/extThree20CSSStyle/extThree20CSSStyle.xcodeproj/project.pbxproj +++ b/src/extThree20CSSStyle/extThree20CSSStyle.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXAggregateTarget section */ @@ -21,13 +21,39 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 1831D1AF13AA9FAC00AB4D55 /* TTDataConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1831D1AD13AA9FAC00AB4D55 /* TTDataConverter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1831D1B013AA9FAC00AB4D55 /* TTDataPopulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1831D1AE13AA9FAC00AB4D55 /* TTDataPopulator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1831D1B313AA9FB500AB4D55 /* TTDataConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1831D1B113AA9FB500AB4D55 /* TTDataConverter.m */; }; + 1831D1B413AA9FB500AB4D55 /* TTDataPopulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 1831D1B213AA9FB500AB4D55 /* TTDataPopulator.m */; }; + 1831D1DA13AAA24400AB4D55 /* TTDataPopulatorDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1831D1D913AAA24400AB4D55 /* TTDataPopulatorDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1832BD9713B243FD00C50CFE /* TTDefaultCSSStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1832BD9613B243FD00C50CFE /* TTDefaultCSSStyleSheet.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 183F67B313B0F5BE0032CFF5 /* TTCSSFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 183F67B213B0F5BE0032CFF5 /* TTCSSFunctions.m */; }; + 183F67EA13B0F8B40032CFF5 /* TTCSSFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 183F67AD13B0F5AE0032CFF5 /* TTCSSFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 186AE75913AA4C35004D43FA /* TTCSSRuleSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 186AE6F213AA3FF1004D43FA /* TTCSSRuleSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 186AE75A13AA4C3A004D43FA /* TTCSSRuleSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 186AE75613AA4C1C004D43FA /* TTCSSRuleSet.m */; }; + 186AE80913AA512C004D43FA /* TTCSSTextShadowModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 186AE80813AA512C004D43FA /* TTCSSTextShadowModel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 186AE80B13AA5379004D43FA /* TTCSSTextShadowModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 186AE80A13AA5379004D43FA /* TTCSSTextShadowModel.m */; }; + 186AE92013AA7C7E004D43FA /* CssRuleSetTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 186AE91F13AA7C7E004D43FA /* CssRuleSetTests.m */; }; + 1892DC1C13D61D5B008DFAC5 /* UILabelAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1892DC1B13D61D5B008DFAC5 /* UILabelAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1892DC1F13D61D6A008DFAC5 /* TTShadowStyleAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1892DC1D13D61D6A008DFAC5 /* TTShadowStyleAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1892DC2013D61D6A008DFAC5 /* TTTextStyleAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1892DC1E13D61D6A008DFAC5 /* TTTextStyleAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1892DC2213D61D77008DFAC5 /* TTCSSGlobalStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 1892DC2113D61D77008DFAC5 /* TTCSSGlobalStyle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1892DC2513D61D81008DFAC5 /* TTShadowStyleAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1892DC2313D61D81008DFAC5 /* TTShadowStyleAdditions.m */; }; + 1892DC2613D61D81008DFAC5 /* TTTextStyleAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1892DC2413D61D81008DFAC5 /* TTTextStyleAdditions.m */; }; + 1892DC2E13D61D90008DFAC5 /* extThree20CSSStyle+Additions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1892DC2D13D61D90008DFAC5 /* extThree20CSSStyle+Additions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 18F5A81713B2927500B3EF43 /* TTCSSApplyProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 18F5A81613B2927500B3EF43 /* TTCSSApplyProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 18F5A86F13B2973F00B3EF43 /* UIView+CSSAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 18F5A86E13B2973F00B3EF43 /* UIView+CSSAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 18F5A87813B2979E00B3EF43 /* UIView+CSSAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 18F5A87713B2979E00B3EF43 /* UIView+CSSAdditions.m */; }; + 18F5A88813B298BE00B3EF43 /* UILabel+CSSAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 18F5A88713B298BE00B3EF43 /* UILabel+CSSAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 18F5A88A13B298D100B3EF43 /* UILabel+CSSAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 18F5A88913B298D100B3EF43 /* UILabel+CSSAdditions.m */; }; + 66E722D0129392DD007134B0 /* TTExtensionLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 66E722CC129392DD007134B0 /* TTExtensionLoader.m */; }; + 66E722D3129392EB007134B0 /* TTExtensionLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E722D1129392EB007134B0 /* TTExtensionLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E036A2011B364670025E8EE /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E036A1411B364530025E8EE /* libThree20Network.a */; }; 6E036A2111B364670025E8EE /* libThree20Style.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E036A1D11B3645C0025E8EE /* libThree20Style.a */; }; 6E036A3011B364CC0025E8EE /* TTCSSStyleSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E036A2E11B364CC0025E8EE /* TTCSSStyleSheet.m */; }; 6E036A3211B364DF0025E8EE /* TTCSSStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E036A3111B364DF0025E8EE /* TTCSSStyleSheet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E036A7D11B371790025E8EE /* CssStyleSheetTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E036A7711B371150025E8EE /* CssStyleSheetTests.m */; }; 6E036B6911B38DA30025E8EE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E85155511B2E94E0071A4FD /* CoreGraphics.framework */; }; - 6E036D1911B487CF0025E8EE /* TTDefaultCSSStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E036D1711B487CF0025E8EE /* TTDefaultCSSStyleSheet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E036D1A11B487CF0025E8EE /* TTDefaultCSSStyleSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E036D1811B487CF0025E8EE /* TTDefaultCSSStyleSheet.m */; }; 6E3C3470118806590079637E /* extThree20CSSStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E646518118805EB00F08CB1 /* extThree20CSSStyle.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645AA111876E2B00F08CB1 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E645A7011876D3F00F08CB1 /* libThree20Core.a */; }; @@ -122,6 +148,34 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 1831D1AD13AA9FAC00AB4D55 /* TTDataConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTDataConverter.h; path = Headers/TTDataConverter.h; sourceTree = ""; }; + 1831D1AE13AA9FAC00AB4D55 /* TTDataPopulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTDataPopulator.h; path = Headers/TTDataPopulator.h; sourceTree = ""; }; + 1831D1B113AA9FB500AB4D55 /* TTDataConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTDataConverter.m; path = ThirdPart/TTDataConverter.m; sourceTree = ""; }; + 1831D1B213AA9FB500AB4D55 /* TTDataPopulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTDataPopulator.m; path = ThirdPart/TTDataPopulator.m; sourceTree = ""; }; + 1831D1D913AAA24400AB4D55 /* TTDataPopulatorDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTDataPopulatorDelegate.h; path = Headers/TTDataPopulatorDelegate.h; sourceTree = ""; }; + 1832BD9613B243FD00C50CFE /* TTDefaultCSSStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTDefaultCSSStyleSheet.h; path = Headers/TTDefaultCSSStyleSheet.h; sourceTree = ""; }; + 183F67AD13B0F5AE0032CFF5 /* TTCSSFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTCSSFunctions.h; path = Headers/TTCSSFunctions.h; sourceTree = ""; }; + 183F67B213B0F5BE0032CFF5 /* TTCSSFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTCSSFunctions.m; path = Sources/TTCSSFunctions.m; sourceTree = ""; }; + 186AE6F213AA3FF1004D43FA /* TTCSSRuleSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTCSSRuleSet.h; path = Headers/TTCSSRuleSet.h; sourceTree = ""; }; + 186AE75613AA4C1C004D43FA /* TTCSSRuleSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTCSSRuleSet.m; path = Sources/TTCSSRuleSet.m; sourceTree = ""; }; + 186AE80813AA512C004D43FA /* TTCSSTextShadowModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTCSSTextShadowModel.h; path = Headers/TTCSSTextShadowModel.h; sourceTree = ""; }; + 186AE80A13AA5379004D43FA /* TTCSSTextShadowModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTCSSTextShadowModel.m; path = Sources/TTCSSTextShadowModel.m; sourceTree = ""; }; + 186AE91F13AA7C7E004D43FA /* CssRuleSetTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CssRuleSetTests.m; path = UnitTests/CssRuleSetTests.m; sourceTree = ""; }; + 1892DC1B13D61D5B008DFAC5 /* UILabelAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UILabelAdditions.h; path = Headers/UILabelAdditions.h; sourceTree = ""; }; + 1892DC1D13D61D6A008DFAC5 /* TTShadowStyleAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTShadowStyleAdditions.h; path = Headers/TTShadowStyleAdditions.h; sourceTree = ""; }; + 1892DC1E13D61D6A008DFAC5 /* TTTextStyleAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTTextStyleAdditions.h; path = Headers/TTTextStyleAdditions.h; sourceTree = ""; }; + 1892DC2113D61D77008DFAC5 /* TTCSSGlobalStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTCSSGlobalStyle.h; path = Headers/TTCSSGlobalStyle.h; sourceTree = ""; }; + 1892DC2313D61D81008DFAC5 /* TTShadowStyleAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTShadowStyleAdditions.m; path = Sources/TTShadowStyleAdditions.m; sourceTree = ""; }; + 1892DC2413D61D81008DFAC5 /* TTTextStyleAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTTextStyleAdditions.m; path = Sources/TTTextStyleAdditions.m; sourceTree = ""; }; + 1892DC2D13D61D90008DFAC5 /* extThree20CSSStyle+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "extThree20CSSStyle+Additions.h"; path = "Headers/extThree20CSSStyle+Additions.h"; sourceTree = ""; }; + 18F5A81613B2927500B3EF43 /* TTCSSApplyProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTCSSApplyProtocol.h; path = Headers/TTCSSApplyProtocol.h; sourceTree = ""; }; + 18F5A86E13B2973F00B3EF43 /* UIView+CSSAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView+CSSAdditions.h"; path = "Headers/UIView+CSSAdditions.h"; sourceTree = ""; }; + 18F5A87713B2979E00B3EF43 /* UIView+CSSAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+CSSAdditions.m"; path = "Sources/UIView+CSSAdditions.m"; sourceTree = ""; }; + 18F5A88713B298BE00B3EF43 /* UILabel+CSSAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UILabel+CSSAdditions.h"; path = "Headers/UILabel+CSSAdditions.h"; sourceTree = ""; }; + 18F5A88913B298D100B3EF43 /* UILabel+CSSAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UILabel+CSSAdditions.m"; path = "Sources/UILabel+CSSAdditions.m"; sourceTree = ""; }; + 66313D671267BFCF00C09C9F /* extThree20CSSStyle_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = extThree20CSSStyle_Prefix.pch; path = Headers/extThree20CSSStyle_Prefix.pch; sourceTree = ""; }; + 66E722CC129392DD007134B0 /* TTExtensionLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTExtensionLoader.m; path = Sources/TTExtensionLoader.m; sourceTree = ""; }; + 66E722D1129392EB007134B0 /* TTExtensionLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTExtensionLoader.h; path = Headers/TTExtensionLoader.h; sourceTree = ""; }; 6E036A0E11B364530025E8EE /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; 6E036A1711B3645C0025E8EE /* Three20Style.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Style.xcodeproj; path = ../Three20Style/Three20Style.xcodeproj; sourceTree = SOURCE_ROOT; }; 6E036A2E11B364CC0025E8EE /* TTCSSStyleSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTCSSStyleSheet.m; path = Sources/TTCSSStyleSheet.m; sourceTree = ""; }; @@ -129,7 +183,6 @@ 6E036A7711B371150025E8EE /* CssStyleSheetTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CssStyleSheetTests.m; path = UnitTests/CssStyleSheetTests.m; sourceTree = ""; }; 6E036B3611B38A420025E8EE /* README.mdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.mdown; sourceTree = ""; }; 6E036B6111B38D1B0025E8EE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 6E036D1711B487CF0025E8EE /* TTDefaultCSSStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTDefaultCSSStyleSheet.h; path = Sources/TTDefaultCSSStyleSheet.h; sourceTree = ""; }; 6E036D1811B487CF0025E8EE /* TTDefaultCSSStyleSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTDefaultCSSStyleSheet.m; path = Sources/TTDefaultCSSStyleSheet.m; sourceTree = ""; }; 6E0835AB11B4C3A200B99C32 /* extThree20CSSStyle.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = extThree20CSSStyle.bundle; path = Resources/extThree20CSSStyle.bundle; sourceTree = ""; }; 6E083B5311B6122800B99C32 /* Build.Command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Build.Command; path = Grammars/Build.Command; sourceTree = ""; }; @@ -176,6 +229,56 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1831D1A913AA9F4800AB4D55 /* Data Processing */ = { + isa = PBXGroup; + children = ( + 1831D1AD13AA9FAC00AB4D55 /* TTDataConverter.h */, + 1831D1B113AA9FB500AB4D55 /* TTDataConverter.m */, + 1831D1D913AAA24400AB4D55 /* TTDataPopulatorDelegate.h */, + 1831D1AE13AA9FAC00AB4D55 /* TTDataPopulator.h */, + 1831D1B213AA9FB500AB4D55 /* TTDataPopulator.m */, + ); + name = "Data Processing"; + sourceTree = ""; + }; + 183F67AF13B0F5B10032CFF5 /* Common */ = { + isa = PBXGroup; + children = ( + 18F5A81613B2927500B3EF43 /* TTCSSApplyProtocol.h */, + 183F67AD13B0F5AE0032CFF5 /* TTCSSFunctions.h */, + 183F67B213B0F5BE0032CFF5 /* TTCSSFunctions.m */, + ); + name = Common; + sourceTree = ""; + }; + 186AE6E013AA3F97004D43FA /* CSS Model Objects */ = { + isa = PBXGroup; + children = ( + 1831D1A913AA9F4800AB4D55 /* Data Processing */, + 186AE80813AA512C004D43FA /* TTCSSTextShadowModel.h */, + 186AE80A13AA5379004D43FA /* TTCSSTextShadowModel.m */, + 186AE6F213AA3FF1004D43FA /* TTCSSRuleSet.h */, + 186AE75613AA4C1C004D43FA /* TTCSSRuleSet.m */, + 1892DC1D13D61D6A008DFAC5 /* TTShadowStyleAdditions.h */, + 1892DC2313D61D81008DFAC5 /* TTShadowStyleAdditions.m */, + 1892DC1E13D61D6A008DFAC5 /* TTTextStyleAdditions.h */, + 1892DC2413D61D81008DFAC5 /* TTTextStyleAdditions.m */, + ); + name = "CSS Model Objects"; + sourceTree = ""; + }; + 18F5A86613B2971900B3EF43 /* UIKit Additions */ = { + isa = PBXGroup; + children = ( + 18F5A86E13B2973F00B3EF43 /* UIView+CSSAdditions.h */, + 18F5A87713B2979E00B3EF43 /* UIView+CSSAdditions.m */, + 1892DC1B13D61D5B008DFAC5 /* UILabelAdditions.h */, + 18F5A88713B298BE00B3EF43 /* UILabel+CSSAdditions.h */, + 18F5A88913B298D100B3EF43 /* UILabel+CSSAdditions.m */, + ); + name = "UIKit Additions"; + sourceTree = ""; + }; 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( @@ -190,6 +293,10 @@ children = ( 6E036B3611B38A420025E8EE /* README.mdown */, 6E646518118805EB00F08CB1 /* extThree20CSSStyle.h */, + 1892DC2D13D61D90008DFAC5 /* extThree20CSSStyle+Additions.h */, + 66313D671267BFCF00C09C9F /* extThree20CSSStyle_Prefix.pch */, + 66E722D1129392EB007134B0 /* TTExtensionLoader.h */, + 66E722CC129392DD007134B0 /* TTExtensionLoader.m */, 6EB4609C1183D1E000685649 /* Source */, 6ED118E41183C38A0096AEBF /* Configurations */, 6E645A4311876CFE00F08CB1 /* Dependencies */, @@ -205,7 +312,7 @@ isa = PBXGroup; children = ( 6E036A1411B364530025E8EE /* libThree20Network.a */, - 6E036A1611B364530025E8EE /* UnitTests.octest */, + 6E036A1611B364530025E8EE /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -214,7 +321,7 @@ isa = PBXGroup; children = ( 6E036A1D11B3645C0025E8EE /* libThree20Style.a */, - 6E036A1F11B3645C0025E8EE /* UnitTests.octest */, + 6E036A1F11B3645C0025E8EE /* StyleUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -232,9 +339,10 @@ 6E036A2B11B364B60025E8EE /* CSS Stylesheet */ = { isa = PBXGroup; children = ( + 1892DC2113D61D77008DFAC5 /* TTCSSGlobalStyle.h */, 6E036A3111B364DF0025E8EE /* TTCSSStyleSheet.h */, 6E036A2E11B364CC0025E8EE /* TTCSSStyleSheet.m */, - 6E036D1711B487CF0025E8EE /* TTDefaultCSSStyleSheet.h */, + 1832BD9613B243FD00C50CFE /* TTDefaultCSSStyleSheet.h */, 6E036D1811B487CF0025E8EE /* TTDefaultCSSStyleSheet.m */, ); name = "CSS Stylesheet"; @@ -300,6 +408,9 @@ 6EB4609C1183D1E000685649 /* Source */ = { isa = PBXGroup; children = ( + 18F5A86613B2971900B3EF43 /* UIKit Additions */, + 183F67AF13B0F5B10032CFF5 /* Common */, + 186AE6E013AA3F97004D43FA /* CSS Model Objects */, 6E036A2A11B364AF0025E8EE /* CSS Parser */, 6E036A2B11B364B60025E8EE /* CSS Stylesheet */, ); @@ -321,6 +432,7 @@ 6ED117E51183BE2A0096AEBF /* Resources */, 6E85152511B2E7B80071A4FD /* CssParserTests.m */, 6E036A7711B371150025E8EE /* CssStyleSheetTests.m */, + 186AE91F13AA7C7E004D43FA /* CssRuleSetTests.m */, ); name = Tests; sourceTree = ""; @@ -342,11 +454,26 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1892DC2213D61D77008DFAC5 /* TTCSSGlobalStyle.h in Headers */, + 18F5A88813B298BE00B3EF43 /* UILabel+CSSAdditions.h in Headers */, + 18F5A86F13B2973F00B3EF43 /* UIView+CSSAdditions.h in Headers */, + 18F5A81713B2927500B3EF43 /* TTCSSApplyProtocol.h in Headers */, + 183F67EA13B0F8B40032CFF5 /* TTCSSFunctions.h in Headers */, + 1831D1AF13AA9FAC00AB4D55 /* TTDataConverter.h in Headers */, + 1831D1DA13AAA24400AB4D55 /* TTDataPopulatorDelegate.h in Headers */, + 1831D1B013AA9FAC00AB4D55 /* TTDataPopulator.h in Headers */, + 186AE80913AA512C004D43FA /* TTCSSTextShadowModel.h in Headers */, + 186AE75913AA4C35004D43FA /* TTCSSRuleSet.h in Headers */, + 6E036A3211B364DF0025E8EE /* TTCSSStyleSheet.h in Headers */, 6E3C3470118806590079637E /* extThree20CSSStyle.h in Headers */, 6E85145411B1B5390071A4FD /* TTCSSParser.h in Headers */, 6E8514ED11B2E3F30071A4FD /* CssTokens.h in Headers */, - 6E036A3211B364DF0025E8EE /* TTCSSStyleSheet.h in Headers */, - 6E036D1911B487CF0025E8EE /* TTDefaultCSSStyleSheet.h in Headers */, + 66E722D3129392EB007134B0 /* TTExtensionLoader.h in Headers */, + 1832BD9713B243FD00C50CFE /* TTDefaultCSSStyleSheet.h in Headers */, + 1892DC1C13D61D5B008DFAC5 /* UILabelAdditions.h in Headers */, + 1892DC1F13D61D6A008DFAC5 /* TTShadowStyleAdditions.h in Headers */, + 1892DC2013D61D6A008DFAC5 /* TTTextStyleAdditions.h in Headers */, + 1892DC2E13D61D90008DFAC5 /* extThree20CSSStyle+Additions.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -360,6 +487,7 @@ BEF31F360F352DF5000DE5D2 /* Headers */, 6E3C34AD118807DC0079637E /* Protect Copied Headers */, BEF31F370F352DF5000DE5D2 /* Sources */, + 668E667E131AE00F00ACE4AB /* Lint */, BEF31F380F352DF5000DE5D2 /* Frameworks */, ); buildRules = ( @@ -374,9 +502,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libextThree20CSSStyle.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTests */ = { + EB9E6C6110B6A8F800DE563C /* extThree20CSSStyleUnitTests */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "extThree20CSSStyleUnitTests" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -389,7 +517,7 @@ 6E645AA611876E3500F08CB1 /* PBXTargetDependency */, 6EB460DE1183D8D400685649 /* PBXTargetDependency */, ); - name = UnitTests; + name = extThree20CSSStyleUnitTests; productName = CoreUnitTests; productReference = EB9E6C6210B6A8F800DE563C /* extCSSStyleUnitTests.octest */; productType = "com.apple.product-type.bundle"; @@ -400,11 +528,19 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = NO; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "extThree20CSSStyle" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -424,7 +560,7 @@ projectRoot = ""; targets = ( BEF31F390F352DF5000DE5D2 /* extThree20CSSStyle */, - EB9E6C6110B6A8F800DE563C /* UnitTests */, + EB9E6C6110B6A8F800DE563C /* extThree20CSSStyleUnitTests */, 6E083B2C11B6113900B99C32 /* Grammar */, ); }; @@ -438,10 +574,10 @@ remoteRef = 6E036A1311B364530025E8EE /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E036A1611B364530025E8EE /* UnitTests.octest */ = { + 6E036A1611B364530025E8EE /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E036A1511B364530025E8EE /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -452,10 +588,10 @@ remoteRef = 6E036A1C11B3645C0025E8EE /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E036A1F11B3645C0025E8EE /* UnitTests.octest */ = { + 6E036A1F11B3645C0025E8EE /* StyleUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = StyleUnitTests.octest; remoteRef = 6E036A1E11B3645C0025E8EE /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -487,6 +623,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 668E667E131AE00F00ACE4AB /* Lint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = Lint; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/usr/bin/env python ../scripts/lint"; + shellScript = ""; + showEnvVarsInLog = 0; + }; 6E083B2B11B6113900B99C32 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -534,11 +685,21 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 186AE75A13AA4C3A004D43FA /* TTCSSRuleSet.m in Sources */, 6E85154011B2E8660071A4FD /* TTCSSParser.m in Sources */, 6E8514DA11B2E31E0071A4FD /* CssTokenizer.m in Sources */, 6E8514DB11B2E31E0071A4FD /* CssTokens.m in Sources */, 6E036A3011B364CC0025E8EE /* TTCSSStyleSheet.m in Sources */, 6E036D1A11B487CF0025E8EE /* TTDefaultCSSStyleSheet.m in Sources */, + 66E722D0129392DD007134B0 /* TTExtensionLoader.m in Sources */, + 186AE80B13AA5379004D43FA /* TTCSSTextShadowModel.m in Sources */, + 1831D1B313AA9FB500AB4D55 /* TTDataConverter.m in Sources */, + 1831D1B413AA9FB500AB4D55 /* TTDataPopulator.m in Sources */, + 183F67B313B0F5BE0032CFF5 /* TTCSSFunctions.m in Sources */, + 18F5A87813B2979E00B3EF43 /* UIView+CSSAdditions.m in Sources */, + 18F5A88A13B298D100B3EF43 /* UILabel+CSSAdditions.m in Sources */, + 1892DC2513D61D81008DFAC5 /* TTShadowStyleAdditions.m in Sources */, + 1892DC2613D61D81008DFAC5 /* TTTextStyleAdditions.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -548,6 +709,7 @@ files = ( 6E036A7D11B371790025E8EE /* CssStyleSheetTests.m in Sources */, 6E85152611B2E7B80071A4FD /* CssParserTests.m in Sources */, + 186AE92013AA7C7E004D43FA /* CssRuleSetTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -604,7 +766,6 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; PRODUCT_NAME = Grammar; ZERO_LINK = NO; }; @@ -614,14 +775,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; @@ -637,8 +795,8 @@ EXTJSON_SBJSON, DEBUG, ); - PREBINDING = NO; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; @@ -648,10 +806,9 @@ buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Internal; }; @@ -666,7 +823,7 @@ EXTJSON_SBJSON, DEBUG, ); - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -676,9 +833,8 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREPROCESSOR_DEFINITIONS = EXTJSON_SBJSON; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -687,14 +843,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -702,14 +855,12 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -719,10 +870,9 @@ buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -732,8 +882,7 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -771,7 +920,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "extThree20CSSStyleUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/extThree20JSON/Configurations/Library+SBJSON.xcconfig b/src/extThree20JSON/Configurations/Library+SBJSON.xcconfig new file mode 100644 index 0000000000..946e2fe963 --- /dev/null +++ b/src/extThree20JSON/Configurations/Library+SBJSON.xcconfig @@ -0,0 +1,29 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "../common/Configurations/Library.xcconfig" +#include "../common/Configurations/Libraries.xcconfig" + +BASE_PRODUCT_NAME = extThree20JSON +PRODUCT_NAME = $(BASE_PRODUCT_NAME)+SBJSON +BUILD_LIBRARY_VERSION = 1.0 + +// We override these paths in order to copy the headers to the same directory, +// regardless of target. +PRIVATE_HEADERS_FOLDER_PATH = /../three20/$(BASE_PRODUCT_NAME)/private +PUBLIC_HEADERS_FOLDER_PATH = /../three20/$(BASE_PRODUCT_NAME) + +GCC_PREFIX_HEADER = $(SRCROOT)/Headers/$(BASE_PRODUCT_NAME)+SBJSON_Prefix.pch diff --git a/src/extThree20JSON/Configurations/Library.xcconfig b/src/extThree20JSON/Configurations/Library+YAJL.xcconfig similarity index 69% rename from src/extThree20JSON/Configurations/Library.xcconfig rename to src/extThree20JSON/Configurations/Library+YAJL.xcconfig index d2699ff0a0..7300451e71 100644 --- a/src/extThree20JSON/Configurations/Library.xcconfig +++ b/src/extThree20JSON/Configurations/Library+YAJL.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,11 +17,13 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -EXTENSION_NAME = extThree20JSON -PRODUCT_NAME = $(EXTENSION_NAME) +BASE_PRODUCT_NAME = extThree20JSON +PRODUCT_NAME = $(BASE_PRODUCT_NAME)+YAJL BUILD_LIBRARY_VERSION = 1.0 // We override these paths in order to copy the headers to the same directory, // regardless of target. -PRIVATE_HEADERS_FOLDER_PATH = /../three20/$(EXTENSION_NAME)/private -PUBLIC_HEADERS_FOLDER_PATH = /../three20/$(EXTENSION_NAME) +PRIVATE_HEADERS_FOLDER_PATH = /../three20/$(BASE_PRODUCT_NAME)/private +PUBLIC_HEADERS_FOLDER_PATH = /../three20/$(BASE_PRODUCT_NAME) + +GCC_PREFIX_HEADER = $(SRCROOT)/Headers/$(BASE_PRODUCT_NAME)+YAJL_Prefix.pch diff --git a/src/extThree20JSON/Configurations/Project.xcconfig b/src/extThree20JSON/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/extThree20JSON/Configurations/Project.xcconfig +++ b/src/extThree20JSON/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/extThree20JSON/Configurations/UnitTests.xcconfig b/src/extThree20JSON/Configurations/UnitTests+SBJSON.xcconfig similarity index 85% rename from src/extThree20JSON/Configurations/UnitTests.xcconfig rename to src/extThree20JSON/Configurations/UnitTests+SBJSON.xcconfig index c0cbac3b81..16b1b4383d 100644 --- a/src/extThree20JSON/Configurations/UnitTests.xcconfig +++ b/src/extThree20JSON/Configurations/UnitTests+SBJSON.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = extJSONUnitTests +BASE_PRODUCT_NAME = extJSONUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME)+SBJSON BUILD_BUNDLE_VERSION = 1.0 OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) diff --git a/src/extThree20JSON/Headers/TTErrorCodes.h b/src/extThree20JSON/Headers/TTErrorCodes.h new file mode 100644 index 0000000000..b25f0f97c1 --- /dev/null +++ b/src/extThree20JSON/Headers/TTErrorCodes.h @@ -0,0 +1,19 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +extern NSString* const kTTExtJSONErrorDomain; +extern NSInteger const kTTExtJSONErrorCodeInvalidJSON; + diff --git a/src/extThree20JSON/Headers/TTExtensionLoader.h b/src/extThree20JSON/Headers/TTExtensionLoader.h new file mode 100644 index 0000000000..350754d3bd --- /dev/null +++ b/src/extThree20JSON/Headers/TTExtensionLoader.h @@ -0,0 +1,21 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/TTExtensionLoader.h" + +@interface TTExtensionLoader (TTJSONExtension) + +@end diff --git a/src/extThree20JSON/Headers/TTURLJSONResponse.h b/src/extThree20JSON/Headers/TTURLJSONResponse.h index 6f17dc54db..925c4d8cb5 100644 --- a/src/extThree20JSON/Headers/TTURLJSONResponse.h +++ b/src/extThree20JSON/Headers/TTURLJSONResponse.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/extThree20JSON/Headers/extThree20JSON+SBJSON_Prefix.pch b/src/extThree20JSON/Headers/extThree20JSON+SBJSON_Prefix.pch index 28f5d8f8f2..f2195d7988 100644 --- a/src/extThree20JSON/Headers/extThree20JSON+SBJSON_Prefix.pch +++ b/src/extThree20JSON/Headers/extThree20JSON+SBJSON_Prefix.pch @@ -1,5 +1,5 @@ // -// Prefix header for all source files of the 'Three20Core' target in the 'Three20Core' project +// Prefix header for all source files of the 'extThree20JSON+SBJSON' target in the 'extThree20JSON' project // #ifdef __OBJC__ diff --git a/src/extThree20JSON/Headers/extThree20JSON+YAJL_Prefix.pch b/src/extThree20JSON/Headers/extThree20JSON+YAJL_Prefix.pch index 28f5d8f8f2..d0d3ec1a1a 100644 --- a/src/extThree20JSON/Headers/extThree20JSON+YAJL_Prefix.pch +++ b/src/extThree20JSON/Headers/extThree20JSON+YAJL_Prefix.pch @@ -1,5 +1,5 @@ // -// Prefix header for all source files of the 'Three20Core' target in the 'Three20Core' project +// Prefix header for all source files of the 'extThree20JSON+YAJL' target in the 'extThree20JSON' project // #ifdef __OBJC__ diff --git a/src/extThree20JSON/Headers/extThree20JSON.h b/src/extThree20JSON/Headers/extThree20JSON.h index c2ea8925fa..48058e62b5 100644 --- a/src/extThree20JSON/Headers/extThree20JSON.h +++ b/src/extThree20JSON/Headers/extThree20JSON.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,4 +14,5 @@ // limitations under the License. // +#import "extThree20JSON/TTErrorCodes.h" #import "extThree20JSON/TTURLJSONResponse.h" diff --git a/src/extThree20JSON/Source/TTErrorCodes.m b/src/extThree20JSON/Source/TTErrorCodes.m new file mode 100644 index 0000000000..1ff2474cd6 --- /dev/null +++ b/src/extThree20JSON/Source/TTErrorCodes.m @@ -0,0 +1,19 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +NSString* const kTTExtJSONErrorDomain = @"three20.ext.json"; +NSInteger const kTTExtJSONErrorCodeInvalidJSON = 100; + diff --git a/src/extThree20JSON/Source/TTExtensionLoader.m b/src/extThree20JSON/Source/TTExtensionLoader.m new file mode 100644 index 0000000000..a7d3e69ffc --- /dev/null +++ b/src/extThree20JSON/Source/TTExtensionLoader.m @@ -0,0 +1,62 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "extThree20JSON/TTExtensionLoader.h" + +// Core +#import "Three20Core/TTExtensionAuthor.h" +#import "Three20Core/TTExtensionInfo.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTExtensionLoader (TTJSONExtension) + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)loadExtensionNamedThree20JSON { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTExtensionInfo*)extensionInfoNamedThree20JSON { + TTExtensionInfo* extension = [[TTExtensionInfo alloc] init]; + + extension.name = @"Three20 JSON"; + extension.description = @"The JSON extension provides support for parsing json files and receiving JSON responses."; + extension.version = @"2.0"; + extension.copyright = @"Copyright 2009-2011 Facebook."; + extension.license = @"Apache 2.0"; + extension.authors = [NSArray arrayWithObjects: + [TTExtensionAuthor authorWithName:@"Jeff Verkoeyen"], + nil]; + +#ifdef EXTJSON_SBJSON + extension.version = [extension.version stringByAppendingString:@" SBJSON 3.0.2"]; + extension.copyright = [extension.copyright stringByAppendingString:@" 2009-2011 Stig Brautaset."]; +#elif defined(EXTJSON_YAJL) + extension.version = [extension.version stringByAppendingString:@" YAJL 1.0.11"]; + extension.copyright = [extension.copyright stringByAppendingString:@" 2009 Gabriel Handford. 2010 Lloyd Hilaiel."]; +#endif + + return [extension autorelease]; +} + + +@end + diff --git a/src/extThree20JSON/Source/TTURLJSONResponse.m b/src/extThree20JSON/Source/TTURLJSONResponse.m index bf384467e4..9a021ee921 100644 --- a/src/extThree20JSON/Source/TTURLJSONResponse.m +++ b/src/extThree20JSON/Source/TTURLJSONResponse.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,8 +17,10 @@ #import "extThree20JSON/TTURLJSONResponse.h" // extJSON +#import "extThree20JSON/TTErrorCodes.h" #ifdef EXTJSON_SBJSON -#import "extThree20JSON/JSON.h" +#import "extThree20JSON/SBJson.h" +#import "extThree20JSON/NSString+SBJSON.h" #elif defined(EXTJSON_YAJL) #import "extThree20JSON/NSObject+YAJL.h" #endif @@ -56,19 +58,33 @@ - (NSError*)request:(TTURLRequest*)request processResponse:(NSHTTPURLResponse*)r // This response is designed for NSData objects, so if we get anything else it's probably a // mistake. TTDASSERT([data isKindOfClass:[NSData class]]); - TTDASSERT(nil == _rootObject); - + TT_RELEASE_SAFELY(_rootObject); + NSError* err = nil; if ([data isKindOfClass:[NSData class]]) { #ifdef EXTJSON_SBJSON - NSString* json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSString* json = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + // When there are newline characters in the JSON string, + // the error "Unescaped control character '0x9'" will be thrown. This removes those characters. + json = [json stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]]; _rootObject = [[json JSONValue] retain]; - TT_RELEASE_SAFELY(json); + if (!_rootObject) { + err = [NSError errorWithDomain:kTTExtJSONErrorDomain + code:kTTExtJSONErrorCodeInvalidJSON + userInfo:nil]; + } #elif defined(EXTJSON_YAJL) - _rootObject = [[data yajl_JSON] retain]; + @try { + _rootObject = [[data yajl_JSON] retain]; + } + @catch (NSException* exception) { + err = [NSError errorWithDomain:kTTExtJSONErrorDomain + code:kTTExtJSONErrorCodeInvalidJSON + userInfo:[exception userInfo]]; + } #endif } - return nil; + return err; } diff --git a/src/extThree20JSON/UnitTests/extJSONTests+SBJSON.m b/src/extThree20JSON/UnitTests/extJSONTests+SBJSON.m index 248d810aae..a319ddcc1c 100644 --- a/src/extThree20JSON/UnitTests/extJSONTests+SBJSON.m +++ b/src/extThree20JSON/UnitTests/extJSONTests+SBJSON.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ #import -#import "extThree20JSON/JSON.h" +#import "extThree20JSON/SBJson.h" /** * Unit tests for the Core JSON parser. These tests are a part of the comprehensive test suite diff --git a/src/extThree20JSON/Vendors/JSON/Changes.md b/src/extThree20JSON/Vendors/JSON/Changes.md new file mode 100755 index 0000000000..bd0a9bc6a8 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/Changes.md @@ -0,0 +1,337 @@ +# JSON Framework Changes + +## Version 3.0.2 (July 27th, 2011) + +* [Issue 88][#88]: Fix parsing of -0 into the integer 0. +* [Issue 86][#86]: Make framework compile on Leopard. + +## Version 3.0.1 (July 1st, 2011) + +* [Issue 80][#80]: Kill memory leak reported by DinosaurDad. +* Fix typo in Readme + +## Version 3.0 (June 18th, 2011) + +* Bump version number + +## Version 3.0beta3 (June 11th, 2011) + +### Changes + +* Fleshed out the [API documentation][api]. +* Remove the (admittedly rather cool) JavaScript hack from the Contrib directory, as I don't want to get stuck maintaining JavaScript I don't understand after 3.0. +* Moved content of Installation file to Readme. +* [Issue 73][#73]: Project rename, to avoid clashing with Apple's internal JSON.framework + * Renamed Mac framework to SBJson.framework + * Renamed iOS static lib to sbjson-ios. + * Changed name of main header to be SBJson.h rather than JSON.h. A backward compatibility header is included, but this will be removed in the future. +* Expanded the Mac example app to be a fully functional application +that reformats JSON you put into a text field. +* Removed the header indirection hack by making more headers public. +* Detect if NSCache is available and only use it if it is. This lets us support iOS versions prior to 4.0. + +### Bug Fixes + +* [Issue 43][#43]: Don't crash on parsing broken UTF8. +* [Issue 70][#70]: SBStateStack breaks when running with GC. This was +fixed by removing it and just using an NSMutableArray. This turns out +to have very little measurable effect on performance. + + +## Version 3.0beta2 (May 24th, 2011) + +### Changes + +* The parser used to always return NSMutableStrings, but may now return NSString instead, for strings with no escapes in them. This change speeded up the parser by about 30% on samsoffes' benchmark. +* Recent refactoring to clean up the code had negative impact on the performance in samsoffes' comparative benchmark. Most of this was reclaimed, but we are still a bit slower than beta1 in his test. Particularly for writing. (We are, however, not slowest.) + +### Enhancements + +* [Issue 40][#40]: Remove unnecessary script phase build +* [Issue 55][#55]: SBJsonStreamWriter stringCache is now using NSCache instead of NSMutableDictionary. This firstly means it is now thread-safe, and secondly that it will free up memory automatically if the OS requests it. + +[#40]: http://github.com/stig/json-framework/issues/40 + +### Bug Fixes +* [Issue 64][#64]: Handle really long integers better. +* [Issue 66][#66]: Parser fails to ignore trailing garbage +* [Issue 42][#42]: Fix bug in handling of Unicode Surrogate Pairs. +* [Issue 48][#48]: Increase precision when writing floating-point numbers so NSTimeInterval instances since epoch can be represented fully. + +## Version 3.0beta1 (January 30th, 2011) + +### Bug Fixes +* [Issue 36][#36]: Fix bug in build script that caused it to break if $SRCROOT has spaces. + +### Changes + +* Remove the hacky dataToHere method in favour of just exposing the internal NSMutableData buffer. +* Added a minimal Mac example project showing how to link to an external JSON framework rather than copying the sources into your project. + +## Version 3.0alpha3 (January 2nd, 2011) + +* Added documentation to the TwitterStream sample project. +* Fixed a few warnings, bugs & a memory leak reported by Andy Warwick. + +## Version 3.0alpha2 (December 28th, 2010) + +### Changes + +* Minor changes to formatting when the HumanReadable flag is set. Empty arrays and objects are no longer special-cased to appear on a single line. The separator between key and value in an object has changed to ': ' rather than ' : '. +* [Issue 25][#25]: Simplified error handling. + +### New Features + +* [Issue 16][#16]: Added support for parsing a UTF8 data stream. This means you can start parsing huge documents before it's all downloaded. Supports skipping the outer-most layer of huge arrays/objects or parsing multiple whitespace-separated completed documents. +* [Issue 12][#12]: Added support for writing JSON to a data stream. This means you can write huge JSON documents to disk, or an HTTP destination, without having to hold the entire structure in memory. You can even generate it as you go, and just stream snapshots to an external process. +* [Issue 18][#18] & [27][#27]: Re-orient API to be NSData-based. The NSString-oriented API methods now delegates to this. + +### Enhancements + +* [Issue 9][#9]: Improve performance of the SBJsonWriter. This implementation is nearly twice as fast as 2.3.x on Sam Soffes' [benchmarks][bench]. +* [Issue 30][#30]: Added *TwitterStream* example project showing how to interact with Twitter's multi-document stream. (See `Examples/TwitterStream` in the distribution.) + + +## Version 2.3.1 (September 25th, 2010) + +### Changes + +* Move to host releases on Github rather than Google code. +* Renamed .md files to .markdown. +* Removed bench target--use [Sam Soffes's benchmarks][bench] instead. +* Releases are no longer a munged form of the source tree, but identical to the tagged source. + +### Bug fixes + +* [Issue 2][#2]: Linkage not supported by default distribution. +* [Issue 4][#4]: Writer reported to occasionally fail infinity check. +* [Issue 8][#8]: Installation.markdown refers to missing JSON folder. + +[#2]: http://github.com/stig/json-framework/issues/2 +[#4]: http://github.com/stig/json-framework/issues/4 +[#8]: http://github.com/stig/json-framework/issues/8 + +## Version 2.3 (August 7, 2010) + +* Renamed README.md to Readme.md +* Updated version number + +## Version 2.3beta1 (July 31, 2010) + +### Changes + +* **Parsing performance improvements.** +[Issue 56][issue-56]: Dewvinci & Tobias Höhmann came up with a patch to improve parsing of short JSON texts with lots of numbers by over 60%. +* **Refactored tests to be more data-driven.** +This should make the source leaner and easier to maintain. +* **Removed problematic SDK** +[Issue 33][issue-33], [58][issue-58], [63][issue-63], and [64][issue-64]: The vast majority of the issues people are having with this framework were related to the somewhat mystical Custom SDK. This has been removed in this version. +* **Removed the deprecated SBJSON facade** +[Issue 71][issue-71]: You should use the SBJsonParser or SBJsonWriter classes, or the category methods, instead. This also let us remove the SBJsonParser and SBJsonWriter categories; these were only there to support the facade, but made the code less transparent. +* **Removed the deprecated fragment support** +[Issue 70][issue-70]: Fragments were a bad idea from the start, but deceptively useful while writing the framework's test suite. This has now been rectified. + +[issue-56]: http://code.google.com/p/json-framework/issues/detail?id=56 +[issue-33]: http://code.google.com/p/json-framework/issues/detail?id=33 +[issue-58]: http://code.google.com/p/json-framework/issues/detail?id=58 +[issue-63]: http://code.google.com/p/json-framework/issues/detail?id=63 +[issue-64]: http://code.google.com/p/json-framework/issues/detail?id=64 +[issue-70]: http://code.google.com/p/json-framework/issues/detail?id=70 +[issue-71]: http://code.google.com/p/json-framework/issues/detail?id=71 + + +### Bug Fixes + +* [Issue 38][issue-38]: Fixed header-inclusion issue. +* [Issue 74][issue-74]: Fix bug in handling of Infinity, -Infinity & NaN. +* [Issue 68][issue-68]: Fixed documentation bug + +[issue-38]: http://code.google.com/p/json-framework/issues/detail?id=39 +[issue-74]: http://code.google.com/p/json-framework/issues/detail?id=74 +[issue-68]: http://code.google.com/p/json-framework/issues/detail?id=68 + + +## Version 2.2.3 (March 7, 2010) + +* **Added -all_load to libjsontests linker flags.** +This allows the tests to run with more recent versions of GCC. +* **Unable to do a JSONRepresentation for a first-level proxy object.** +[Issue 54][issue-54] & [60][issue-60]: Allow the -proxyForJson method to be called for first-level proxy objects, in addition to objects that are embedded in other objects. + +[issue-54]: http://code.google.com/p/json-framework/issues/detail?id=54 +[issue-60]: http://code.google.com/p/json-framework/issues/detail?id=60 + +## Version 2.2.2 (September 12, 2009) + +* **Fixed error-reporting logic in category methods.** +Reported by Mike Monaco. +* **iPhone SDK built against iPhoneOS 3.0.** +This has been updated from 2.2.1. + +## Version 2.2.1 (August 1st, 2009) + +* **Added svn:ignore property to build directory.** +Requested by Rony Kubat. +* **Fixed potential corruption in category methods.** +If category methods were used in multiple threads they could potentially cause a crash. Reported by dprotaso / Relium. + +## Version 2.2 (June 6th, 2009) + +No changes since 2.2beta1. + +## Version 2.2beta1 (May 30th, 2009) + +* **Renamed method for custom object support** +Renamed the -jsonRepresentationProxy method to -proxyForJson. + +## Version 2.2alpha5 (May 25th, 2009) + +* **Added support for custom objects (generation only)** +Added an optional -jsonRepresentationProxy method that you can implement (either directly or as category) to enable JSON.framework to create a JSON representation of any object type. See the Tests/ProxyTest.m file for more information on how this works. +* **Moved maxDepth to SBJsonBase** +Throw errors when the input is nested too deep for writing json as well as parsing. This allows us to exit cleanly rather than break the stack if someone accidentally creates a recursive structure. + +## Version 2.2alpha4 (May 21st, 2009) + +* **Renamed protocols and moved method declarations** +Renamed SBJsonWriterOptions and SBJsonParserOptions protocols to be the same as their primary implementations and moved their one public method there. +* **Implemented proxy methods in SBJSON** +This facade now implements the same methods as the SBJsonWriter and SBJsonParser objects, and simply forwards to them. +* **Extracted private methods to private protocol** +Don't use these please. +* **Improved documentation generation** +Classes now inherit documentation from their superclasses and protocols they implement. + +## Version 2.2alpha3 (May 16th, 2009) + +* **Reintroduced the iPhone Custom SDK** +For the benefit of users who prefer not to copy the JSON source files into their project. Also updated it to be based on iPhoneOS v2.2.1. +* **Deprecated methods for dealing with fragments** +Tweaked the new interface classes to support the old fragment-methods one more version. + +## Version 2.2alpha2 (May 11th, 2009) + +* **Added a Changes file.** +So people can see what the changes are for each version without having to go to the project home page. +* **Updated Credits.** +Some people that have provided patches (or other valuable contributions) had been left out. I've done my best to add those in. (If you feel that you or someone else are still missing, please let me know.) +* **Removed .svn folders from distribution.** +The JSON source folder had a .svn folder in it, which could have caused problems when dragging it into your project. + +## Version 2.2alpha1 (May 10th, 2009) + +* **Improved installation instructions, particularly for the iPhone.** +Getting the SDK to work properly in all configurations has proved to be a headache. Therefore the SDK has been removed in favour of instructions for simply copying the source files into your project. +* **Split the SBJSON class into a writer and parser class.** +SBJSON remains as a facade for backwards compatibility. This refactoring also quashed warnings reported by the Clang static analyser. +* **Improved interface for dealing with errors.** +Rather than having to pass in a pointer to an NSError object, you can now simply call a method to get the error stack back if there was an error. (The NSError-based API remains in the SBJSON facade, but is not present in the new classes.) +* **Documentation updates.** +Minor updates to the documentation. + +Release notes for earlier releases can be found here: +http://code.google.com/p/json-framework/wiki/ReleaseNotes + +[#100]: http://github.com/stig/json-framework/issues/100 +[#99]: http://github.com/stig/json-framework/issues/99 +[#98]: http://github.com/stig/json-framework/issues/98 +[#97]: http://github.com/stig/json-framework/issues/97 +[#96]: http://github.com/stig/json-framework/issues/96 +[#95]: http://github.com/stig/json-framework/issues/95 +[#94]: http://github.com/stig/json-framework/issues/94 +[#93]: http://github.com/stig/json-framework/issues/93 +[#92]: http://github.com/stig/json-framework/issues/92 +[#91]: http://github.com/stig/json-framework/issues/91 +[#90]: http://github.com/stig/json-framework/issues/90 +[#89]: http://github.com/stig/json-framework/issues/89 +[#88]: http://github.com/stig/json-framework/issues/88 +[#87]: http://github.com/stig/json-framework/issues/87 +[#86]: http://github.com/stig/json-framework/issues/86 +[#85]: http://github.com/stig/json-framework/issues/85 +[#84]: http://github.com/stig/json-framework/issues/84 +[#83]: http://github.com/stig/json-framework/issues/83 +[#82]: http://github.com/stig/json-framework/issues/82 +[#81]: http://github.com/stig/json-framework/issues/81 +[#80]: http://github.com/stig/json-framework/issues/80 +[#79]: http://github.com/stig/json-framework/issues/79 +[#78]: http://github.com/stig/json-framework/issues/78 +[#77]: http://github.com/stig/json-framework/issues/77 +[#76]: http://github.com/stig/json-framework/issues/76 +[#75]: http://github.com/stig/json-framework/issues/75 +[#74]: http://github.com/stig/json-framework/issues/74 +[#73]: http://github.com/stig/json-framework/issues/73 +[#72]: http://github.com/stig/json-framework/issues/72 +[#71]: http://github.com/stig/json-framework/issues/71 +[#70]: http://github.com/stig/json-framework/issues/70 +[#69]: http://github.com/stig/json-framework/issues/69 +[#68]: http://github.com/stig/json-framework/issues/68 +[#67]: http://github.com/stig/json-framework/issues/67 +[#66]: http://github.com/stig/json-framework/issues/66 +[#65]: http://github.com/stig/json-framework/issues/65 +[#64]: http://github.com/stig/json-framework/issues/64 +[#63]: http://github.com/stig/json-framework/issues/63 +[#62]: http://github.com/stig/json-framework/issues/62 +[#61]: http://github.com/stig/json-framework/issues/61 +[#60]: http://github.com/stig/json-framework/issues/60 +[#59]: http://github.com/stig/json-framework/issues/59 +[#58]: http://github.com/stig/json-framework/issues/58 +[#57]: http://github.com/stig/json-framework/issues/57 +[#56]: http://github.com/stig/json-framework/issues/56 +[#55]: http://github.com/stig/json-framework/issues/55 +[#54]: http://github.com/stig/json-framework/issues/54 +[#53]: http://github.com/stig/json-framework/issues/53 +[#52]: http://github.com/stig/json-framework/issues/52 +[#51]: http://github.com/stig/json-framework/issues/51 +[#50]: http://github.com/stig/json-framework/issues/50 +[#49]: http://github.com/stig/json-framework/issues/49 +[#48]: http://github.com/stig/json-framework/issues/48 +[#47]: http://github.com/stig/json-framework/issues/47 +[#46]: http://github.com/stig/json-framework/issues/46 +[#45]: http://github.com/stig/json-framework/issues/45 +[#44]: http://github.com/stig/json-framework/issues/44 +[#43]: http://github.com/stig/json-framework/issues/43 +[#42]: http://github.com/stig/json-framework/issues/42 +[#41]: http://github.com/stig/json-framework/issues/41 +[#40]: http://github.com/stig/json-framework/issues/40 +[#39]: http://github.com/stig/json-framework/issues/39 +[#38]: http://github.com/stig/json-framework/issues/38 +[#37]: http://github.com/stig/json-framework/issues/37 +[#36]: http://github.com/stig/json-framework/issues/36 +[#35]: http://github.com/stig/json-framework/issues/35 +[#34]: http://github.com/stig/json-framework/issues/34 +[#33]: http://github.com/stig/json-framework/issues/33 +[#32]: http://github.com/stig/json-framework/issues/32 +[#31]: http://github.com/stig/json-framework/issues/31 +[#30]: http://github.com/stig/json-framework/issues/30 +[#29]: http://github.com/stig/json-framework/issues/29 +[#28]: http://github.com/stig/json-framework/issues/28 +[#27]: http://github.com/stig/json-framework/issues/27 +[#26]: http://github.com/stig/json-framework/issues/26 +[#25]: http://github.com/stig/json-framework/issues/25 +[#24]: http://github.com/stig/json-framework/issues/24 +[#23]: http://github.com/stig/json-framework/issues/23 +[#22]: http://github.com/stig/json-framework/issues/22 +[#21]: http://github.com/stig/json-framework/issues/21 +[#20]: http://github.com/stig/json-framework/issues/20 +[#19]: http://github.com/stig/json-framework/issues/19 +[#18]: http://github.com/stig/json-framework/issues/18 +[#17]: http://github.com/stig/json-framework/issues/17 +[#16]: http://github.com/stig/json-framework/issues/16 +[#15]: http://github.com/stig/json-framework/issues/15 +[#14]: http://github.com/stig/json-framework/issues/14 +[#13]: http://github.com/stig/json-framework/issues/13 +[#12]: http://github.com/stig/json-framework/issues/12 +[#11]: http://github.com/stig/json-framework/issues/11 +[#10]: http://github.com/stig/json-framework/issues/10 +[#9]: http://github.com/stig/json-framework/issues/9 +[#8]: http://github.com/stig/json-framework/issues/8 +[#7]: http://github.com/stig/json-framework/issues/7 +[#6]: http://github.com/stig/json-framework/issues/6 +[#5]: http://github.com/stig/json-framework/issues/5 +[#4]: http://github.com/stig/json-framework/issues/4 +[#3]: http://github.com/stig/json-framework/issues/3 +[#2]: http://github.com/stig/json-framework/issues/2 +[#1]: http://github.com/stig/json-framework/issues/1 + +[bench]: http://github.com/samsoffes/json-benchmarks +[api]: http://stig.github.com/json-framework/api/3.0 diff --git a/src/extThree20JSON/Vendors/JSON/Credits.md b/src/extThree20JSON/Vendors/JSON/Credits.md new file mode 100755 index 0000000000..79a59480e1 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/Credits.md @@ -0,0 +1,40 @@ +# Credits + +My thanks to the following people and organisations, without whom this +library wouldn't be what it is today: + +* Andrew Hannon +* Andrew W. Donoho +* Andy Warwick +* Ben Rimmington +* Blake Seely +* Gabriel Handford +* George MacKerron +* Greg Bolsinga +* Hager Hu +* Hiroshi Saito +* Jens Alfke +* Joerg Schwieder +* John Engelhart +* Konstantin Welke +* Lloyd Hilaiel +* Marc Lehmann +* Michael Papp +* Mike Monaco +* Robin Lu +* Sam Soffes +* Sean Scanlon +* The Adium Crew +* Tobias Höhmann +* Tod Karpinski +* Ullrich Schäfer +* Wolfgang Sourdeau +* aethereal +* boredzo +* dewvinci +* dmaclach +* jinksys +* lukef +* renerattur + +(Please let me know if I've mistakenly omitted anyone.) diff --git a/src/extThree20JSON/Vendors/JSON/Credits.rtf b/src/extThree20JSON/Vendors/JSON/Credits.rtf deleted file mode 100644 index 3961375251..0000000000 --- a/src/extThree20JSON/Vendors/JSON/Credits.rtf +++ /dev/null @@ -1,74 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf540 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 ArialMT;} -{\colortbl;\red255\green255\blue255;} -{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid1} -{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid2}} -{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural - -\f0\b\fs24 \cf0 Blake Seely -\b0 \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural -\cf0 Inspiration for early versions of this framwork came from early versions of Blake's {\field{\*\fldinst{HYPERLINK "http://github.com/blakeseely/bsjsonadditions/tree/master"}}{\fldrslt BSJSONAdditions}} project.\ -\ - -\b Marc Lehmann -\b0 \ -Marc is the author of the excellent {\field{\*\fldinst{HYPERLINK "http://search.cpan.org/dist/JSON-XS/"}}{\fldrslt JSON::XS}} Perl module. The number validation routine in my framework is re-licensed from his module, with his permission.\ -\ - -\b Jens Alfke, jens@mooseyard.com, {\field{\*\fldinst{HYPERLINK "http://mooseyard.com/Jens/"}}{\fldrslt http://mooseyard.com/Jens/}} -\b0 \ -Patches that gave a speedup of 11 times for generation and 5 times for parsing of the long (about 12k) JSON string I was using for testing.\ -\ - -\b Greg Bolsinga -\b0 \ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\ql\qnatural\pardirnatural -\ls1\ilvl0\cf0 {\listtext \'95 }Patch for dropping the dependency on AppKit, making this a Foundation framework.\ -{\listtext \'95 }Patch for building a static library, and instructions for creating a custom SDK suitable for the iPhone.\ -\pard\tx560\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural -\cf0 \ -\pard\pardeftab720\ql\qnatural - -\b \cf0 Ben Rimmington -\b0 \ -Patch speeding writing up by about 100% and parsing by 10% for certain inputs.\ -\ -\pard\pardeftab720\ql\qnatural - -\f1\b\fs26 \cf0 renerattur -\b0 \ -Patch to remove memory leak.\ -\ - -\b dmaclach -\b0 \ -\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural -\ls2\ilvl0\cf0 {\listtext \'95 }Patch to be warning-free with -Wparanthesis.\ -{\listtext \'95 }Prompted me to fix some Clang static analysis errors.\ -\pard\tx560\pardeftab720\ql\qnatural -\cf0 \ - -\b boredzo -\b0 \ -Patch to stop memory leak in -JSONValue and friends.\ -\ - -\b Adium, {\field{\*\fldinst{HYPERLINK "http://adiumx.com"}}{\fldrslt http://adiumx.com}} -\b0 \ -Provided patch to fix crash when parsing facebook chat responses.\ -\ - -\b Joerg Schwieder\ - -\b0 Patch to install instructions for use of static library.\ -\pard\pardeftab720\ql\qnatural - -\f0\fs24 \cf0 \ - -\b Mike Monaco\ - -\b0 Pointed out embarrasing mistake in logic to report errors in the category methods of 2.2.1.\ -\ -} \ No newline at end of file diff --git a/src/extThree20JSON/Vendors/JSON/LICENSE b/src/extThree20JSON/Vendors/JSON/LICENSE new file mode 100755 index 0000000000..2e3ec2035f --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/LICENSE @@ -0,0 +1,24 @@ +Copyright (C) 2007-2011 Stig Brautaset. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/extThree20JSON/Vendors/JSON/NSObject+SBJSON.h b/src/extThree20JSON/Vendors/JSON/NSObject+SBJSON.h old mode 100644 new mode 100755 index ecf0ee407e..4c9245404c --- a/src/extThree20JSON/Vendors/JSON/NSObject+SBJSON.h +++ b/src/extThree20JSON/Vendors/JSON/NSObject+SBJSON.h @@ -29,40 +29,39 @@ #import +#pragma mark JSON Writing -/** - @brief Adds JSON generation to Foundation classes - - This is a category on NSObject that adds methods for returning JSON representations - of standard objects to the objects themselves. This means you can call the - -JSONRepresentation method on an NSArray object and it'll do what you want. - */ -@interface NSObject (NSObject_SBJSON) +/// Adds JSON generation to NSObject +@interface NSObject (NSObject_SBJsonWriting) /** - @brief Returns a string containing the receiver encoded as a JSON fragment. + @brief Encodes the receiver into a JSON string + + Although defined as a category on NSObject it is only defined for NSArray and NSDictionary. - This method is added as a category on NSObject but is only actually - supported for the following objects: - @li NSDictionary - @li NSArray - @li NSString - @li NSNumber (also used for booleans) - @li NSNull + @return the receiver encoded in JSON, or nil on error. - @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed. + @see @ref objc2json */ -- (NSString *)JSONFragment; +- (NSString *)JSONRepresentation; + +@end -/** - @brief Returns a string containing the receiver encoded in JSON. - This method is added as a category on NSObject but is only actually - supported for the following objects: - @li NSDictionary - @li NSArray +#pragma mark JSON Parsing + +/// Adds JSON parsing methods to NSString +@interface NSString (NSString_SBJsonParsing) + +/** + @brief Decodes the receiver's JSON text + + @return the NSDictionary or NSArray represented by the receiver, or nil on error. + + @see @ref json2objc */ -- (NSString *)JSONRepresentation; +- (id)JSONValue; @end + diff --git a/src/extThree20JSON/Vendors/JSON/NSObject+SBJSON.m b/src/extThree20JSON/Vendors/JSON/NSObject+SBJSON.m old mode 100644 new mode 100755 index 20b084b646..9d6396d4b2 --- a/src/extThree20JSON/Vendors/JSON/NSObject+SBJSON.m +++ b/src/extThree20JSON/Vendors/JSON/NSObject+SBJSON.m @@ -27,27 +27,32 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "NSObject+SBJSON.h" +#import "NSObject+SBJson.h" #import "SBJsonWriter.h" +#import "SBJsonParser.h" -@implementation NSObject (NSObject_SBJSON) +@implementation NSObject (NSObject_SBJsonWriting) -- (NSString *)JSONFragment { - SBJsonWriter *jsonWriter = [SBJsonWriter new]; - NSString *json = [jsonWriter stringWithFragment:self]; +- (NSString *)JSONRepresentation { + SBJsonWriter *writer = [[[SBJsonWriter alloc] init] autorelease]; + NSString *json = [writer stringWithObject:self]; if (!json) - NSLog(@"-JSONFragment failed. Error trace is: %@", [jsonWriter errorTrace]); - [jsonWriter release]; + NSLog(@"-JSONRepresentation failed. Error is: %@", writer.error); return json; } -- (NSString *)JSONRepresentation { - SBJsonWriter *jsonWriter = [SBJsonWriter new]; - NSString *json = [jsonWriter stringWithObject:self]; - if (!json) - NSLog(@"-JSONRepresentation failed. Error trace is: %@", [jsonWriter errorTrace]); - [jsonWriter release]; - return json; +@end + + + +@implementation NSString (NSString_SBJsonParsing) + +- (id)JSONValue { + SBJsonParser *parser = [[[SBJsonParser alloc] init] autorelease]; + id repr = [parser objectWithString:self]; + if (!repr) + NSLog(@"-JSONValue failed. Error is: %@", parser.error); + return repr; } @end diff --git a/src/extThree20JSON/Vendors/JSON/NSString+SBJSON.h b/src/extThree20JSON/Vendors/JSON/NSString+SBJSON.h old mode 100644 new mode 100755 index fad7179cb3..029aa309d3 --- a/src/extThree20JSON/Vendors/JSON/NSString+SBJSON.h +++ b/src/extThree20JSON/Vendors/JSON/NSString+SBJSON.h @@ -36,16 +36,6 @@ This is a category on NSString that adds methods for parsing the target string. */ @interface NSString (NSString_SBJSON) - -/** - @brief Returns the object represented in the receiver, or nil on error. - - Returns a a scalar object represented by the string's JSON fragment representation. - - @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed. - */ -- (id)JSONFragmentValue; - /** @brief Returns the NSDictionary or NSArray represented by the current string's JSON representation. diff --git a/src/extThree20JSON/Vendors/JSON/NSString+SBJSON.m b/src/extThree20JSON/Vendors/JSON/NSString+SBJSON.m old mode 100644 new mode 100755 index 41a5a85bb7..fb8df0c3aa --- a/src/extThree20JSON/Vendors/JSON/NSString+SBJSON.m +++ b/src/extThree20JSON/Vendors/JSON/NSString+SBJSON.m @@ -1,20 +1,20 @@ /* Copyright (C) 2007-2009 Stig Brautaset. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -27,29 +27,23 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "NSString+SBJSON.h" -#import "SBJsonParser.h" +#import "extThree20JSON/NSString+SBJSON.h" +#import "extThree20JSON/SBJsonParser.h" -@implementation NSString (NSString_SBJSON) +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" -- (id)JSONFragmentValue -{ - SBJsonParser *jsonParser = [SBJsonParser new]; - id repr = [jsonParser fragmentWithString:self]; - if (!repr) - NSLog(@"-JSONFragmentValue failed. Error trace is: %@", [jsonParser errorTrace]); - [jsonParser release]; - return repr; -} -- (id)JSONValue -{ - SBJsonParser *jsonParser = [SBJsonParser new]; - id repr = [jsonParser objectWithString:self]; - if (!repr) - NSLog(@"-JSONValue failed. Error trace is: %@", [jsonParser errorTrace]); - [jsonParser release]; - return repr; +TT_FIX_CATEGORY_BUG(NSString_SBJSON) + +@implementation NSString (NSString_SBJSON) + +- (id)JSONValue { + SBJsonParser *parser = [[[SBJsonParser alloc] init] autorelease]; + id repr = [parser objectWithString:self]; + if (!repr) + NSLog(@"-JSONValue failed. Error is: %@", parser.error); + return repr; } @end diff --git a/src/extThree20JSON/Vendors/JSON/README b/src/extThree20JSON/Vendors/JSON/README deleted file mode 100644 index fdf982ae87..0000000000 --- a/src/extThree20JSON/Vendors/JSON/README +++ /dev/null @@ -1,9 +0,0 @@ -JSON is a light-weight data interchange format that's easy to read and -write for humans and computers alike. This framework implements a strict -JSON parser and generator in Objective-C. - -Please see the project site for more information: -http://code.google.com/p/json-framework/ - -There is an "Official Fork" of JSON.framework on github.com: -http://github.com/stig/json-framework/tree/master \ No newline at end of file diff --git a/src/extThree20JSON/Vendors/JSON/Readme.md b/src/extThree20JSON/Vendors/JSON/Readme.md new file mode 100755 index 0000000000..712c10aaf0 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/Readme.md @@ -0,0 +1,85 @@ +SBJson (aka json-framework) +=========================== + +JSON (JavaScript Object Notation) is a light-weight data interchange format that's easy to read and write for humans and computers alike. This library implements strict JSON parsing and generation in Objective-C. + +New Features, Changes, and Notable Enhancements in 3.0 +------------------------------------------------------ + +### JSON Stream Support + +We now support parsing of documents split into several NSData chunks, like those returned by *NSURLConnection*. This means you can start parsing a JSON document before it is fully downloaded. Depending how you configure the delegates you can chose to have the entire document delivered to your process when it's finished parsing, or delivered bit-by-bit as records on a particular level finishes downloading. For more details see *SBJsonStreamParser* and *SBJsonStreamParserAdapter* in the [API docs][api]. + +There is also support for *writing to* JSON streams. This means you can write huge JSON documents to disk, or an HTTP destination, without having to hold the entire structure in memory. You can use this to generate a stream of tick data for a stock trading simulation, for example. For more information see *SBJsonStreamWriter* in the [API docs][api]. + +### Parse and write UTF8-encoded NSData + +The internals of *SBJsonParser* and *SBJsonWriter* have been rewritten to be NSData based. It is no longer necessary to convert data returned by NSURLConnection into an NSString before feeding it to the parser. The old NSString-oriented API methods still exists, but now converts their inputs to NSData objects and delegates to the new methods. + +### Project renamed to SBJson + +The project was renamed to avoid clashing with Apple's private JSON.framework. (And to make it easier to Google for.) + +* If you copy the classes into your project then all you need to update is to change the header inclusion from `#import "JSON.h"` to `#import "SBJson.h"`. +* If you link to the library rather than copy the classes you have to change the library you link to. On the Mac `JSON.framework` became `SBJson.framework`. On iOS `libjson.a` became `libsbjson-ios.a`. In both cases you now have to `#import ` in your code. + +### API documentation integrated with Xcode + +The *InstallDocumentation.sh* script allows you to generate [API documentation][api] from the source and install it into Xcode, so it's always at your fingertips. (This script requires [Doxygen][] to be installed.) After running the script from the top-level directory, open Xcode's documentation window and search for SBJson. (You might have to close and re-open Xcode for the changes to take effect.) + +### TweetStream Example Project + +An example project showing how to use the new streaming functionality to interact with Twitter's multi-document streams. This also shows how to link to the iOS static lib rather than having to copy the classes into your project. + +### DisplayPretty Example Project + +A small Mac example project showing how to link to an external JSON framework rather than copying the sources into your project. This is a fully functional (though simplistic) application that takes JSON input from a text field and presents it nicely formatted into another text field. + +Features also present in previous versions +------------------------------------------ + +* BSD license. +* Super-simple high-level API: Calling `-JSONValue` on any NSString instance parses the JSON text in that string, and calling `-JSONRepresentation` on any NSArray or NSDictionary returns an NSString with the JSON representation of the object. +* The *SBJsonParser* and *SBJsonWriter* classes provides an object-oriented API providing a good balance between simplicity and flexibility. +* Configurable recursion depth limit for added security. +* Supports (but does not require) garbage collection. +* Sorted dictionary keys in JSON output. +* Pretty-printing of JSON output. + +Installation +============ + +The simplest way to start using JSON in your application is to copy all the source files (the contents of the `Classes` folder) into your own Xcode project. + +1. In the Finder, navigate to the `$PATH_TO_SBJSON/Classes` folder and select all the files. +1. Drag-and-drop them into your Xcode project. +1. Tick the **Copy items into destination group's folder** option. +1. Use `#import "SBJson.h"` in your source files. + +That should be it. Now create that Twitter client! + +Upgrading +--------- + +If you're upgrading from a previous version, make sure you're deleting the old SBJson classes first, moving all the files to Trash. + + +Linking rather than copying +--------------------------- + +Copying the SBJson classes into your project isn't the only way to use this framework. (Though it is the simplest.) With Xcode 4's workspaces it has become much simpler to link to dependant projects. The examples in the distribution link to the iOS library and Mac framework, respectively. + +* [Linking to JSON Framework on iOS](http://github.com/stig/JsonSampleIPhone) +* [Linking to JSON Framework on the Mac](http://github.com/stig/JsonSampleMac) + + +Links +===== + +* [GitHub project page](http://github.com/stig/json-framework). +* [Example Projects](http://github.com/stig/json-framework/Examples). +* [Online API docs](http://stig.github.com/json-framework/api). +* [Frequently Asked Questions](http://github.com/stig/json-framework/wiki/FrequentlyAskedQuestions) + +[api]: http://stig.github.com/json-framework/api/3.0/ +[Doxygen]: http://doxygen.org diff --git a/src/extThree20JSON/Vendors/JSON/ReleaseChecklist.md b/src/extThree20JSON/Vendors/JSON/ReleaseChecklist.md new file mode 100755 index 0000000000..0bab0ec066 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/ReleaseChecklist.md @@ -0,0 +1,6 @@ +* Update Changes.md +* % agvtool new-marketing-version XXX +* % agvtool bump +* Update website +* Refresh API documentation +* Close fixed tickets diff --git a/src/extThree20JSON/Vendors/JSON/SBJSON.m b/src/extThree20JSON/Vendors/JSON/SBJSON.m deleted file mode 100644 index 2a30f1a7dd..0000000000 --- a/src/extThree20JSON/Vendors/JSON/SBJSON.m +++ /dev/null @@ -1,212 +0,0 @@ -/* - Copyright (C) 2007-2009 Stig Brautaset. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the author nor the names of its contributors may be used - to endorse or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "SBJSON.h" - -@implementation SBJSON - -- (id)init { - self = [super init]; - if (self) { - jsonWriter = [SBJsonWriter new]; - jsonParser = [SBJsonParser new]; - [self setMaxDepth:512]; - - } - return self; -} - -- (void)dealloc { - [jsonWriter release]; - [jsonParser release]; - [super dealloc]; -} - -#pragma mark Writer - - -- (NSString *)stringWithObject:(id)obj { - NSString *repr = [jsonWriter stringWithObject:obj]; - if (repr) - return repr; - - [errorTrace release]; - errorTrace = [[jsonWriter errorTrace] mutableCopy]; - return nil; -} - -/** - Returns a string containing JSON representation of the passed in value, or nil on error. - If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error. - - @param value any instance that can be represented as a JSON fragment - @param allowScalar wether to return json fragments for scalar objects - @param error used to return an error by reference (pass NULL if this is not desired) - -@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed. - */ -- (NSString*)stringWithObject:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error { - - NSString *json = allowScalar ? [jsonWriter stringWithFragment:value] : [jsonWriter stringWithObject:value]; - if (json) - return json; - - [errorTrace release]; - errorTrace = [[jsonWriter errorTrace] mutableCopy]; - - if (error) - *error = [errorTrace lastObject]; - return nil; -} - -/** - Returns a string containing JSON representation of the passed in value, or nil on error. - If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error. - - @param value any instance that can be represented as a JSON fragment - @param error used to return an error by reference (pass NULL if this is not desired) - - @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed. - */ -- (NSString*)stringWithFragment:(id)value error:(NSError**)error { - return [self stringWithObject:value - allowScalar:YES - error:error]; -} - -/** - Returns a string containing JSON representation of the passed in value, or nil on error. - If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error. - - @param value a NSDictionary or NSArray instance - @param error used to return an error by reference (pass NULL if this is not desired) - */ -- (NSString*)stringWithObject:(id)value error:(NSError**)error { - return [self stringWithObject:value - allowScalar:NO - error:error]; -} - -#pragma mark Parsing - -- (id)objectWithString:(NSString *)repr { - id obj = [jsonParser objectWithString:repr]; - if (obj) - return obj; - - [errorTrace release]; - errorTrace = [[jsonParser errorTrace] mutableCopy]; - - return nil; -} - -/** - Returns the object represented by the passed-in string or nil on error. The returned object can be - a string, number, boolean, null, array or dictionary. - - @param value the json string to parse - @param allowScalar whether to return objects for JSON fragments - @param error used to return an error by reference (pass NULL if this is not desired) - - @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed. - */ -- (id)objectWithString:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error { - - id obj = allowScalar ? [jsonParser fragmentWithString:value] : [jsonParser objectWithString:value]; - if (obj) - return obj; - - [errorTrace release]; - errorTrace = [[jsonParser errorTrace] mutableCopy]; - - if (error) - *error = [errorTrace lastObject]; - return nil; -} - -/** - Returns the object represented by the passed-in string or nil on error. The returned object can be - a string, number, boolean, null, array or dictionary. - - @param repr the json string to parse - @param error used to return an error by reference (pass NULL if this is not desired) - - @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed. - */ -- (id)fragmentWithString:(NSString*)repr error:(NSError**)error { - return [self objectWithString:repr - allowScalar:YES - error:error]; -} - -/** - Returns the object represented by the passed-in string or nil on error. The returned object - will be either a dictionary or an array. - - @param repr the json string to parse - @param error used to return an error by reference (pass NULL if this is not desired) - */ -- (id)objectWithString:(NSString*)repr error:(NSError**)error { - return [self objectWithString:repr - allowScalar:NO - error:error]; -} - - - -#pragma mark Properties - parsing - -- (NSUInteger)maxDepth { - return jsonParser.maxDepth; -} - -- (void)setMaxDepth:(NSUInteger)d { - jsonWriter.maxDepth = jsonParser.maxDepth = d; -} - - -#pragma mark Properties - writing - -- (BOOL)humanReadable { - return jsonWriter.humanReadable; -} - -- (void)setHumanReadable:(BOOL)x { - jsonWriter.humanReadable = x; -} - -- (BOOL)sortKeys { - return jsonWriter.sortKeys; -} - -- (void)setSortKeys:(BOOL)x { - jsonWriter.sortKeys = x; -} - -@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJson.h b/src/extThree20JSON/Vendors/JSON/SBJson.h new file mode 100755 index 0000000000..e28fba73d5 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJson.h @@ -0,0 +1,84 @@ +/* + Copyright (C) 2009-2011 Stig Brautaset. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @page json2objc JSON to Objective-C + + JSON is mapped to Objective-C types in the following way: + + @li null -> NSNull + @li string -> NSString + @li array -> NSMutableArray + @li object -> NSMutableDictionary + @li true -> NSNumber's -numberWithBool:YES + @li false -> NSNumber's -numberWithBool:NO + @li integer up to 19 digits -> NSNumber's -numberWithLongLong: + @li all other numbers -> NSDecimalNumber + + Since Objective-C doesn't have a dedicated class for boolean values, + these turns into NSNumber instances. However, since these are + initialised with the -initWithBool: method they round-trip back to JSON + properly. In other words, they won't silently suddenly become 0 or 1; + they'll be represented as 'true' and 'false' again. + + As an optimisation integers up to 19 digits in length (the max length + for signed long long integers) turn into NSNumber instances, while + complex ones turn into NSDecimalNumber instances. We can thus avoid any + loss of precision as JSON allows ridiculously large numbers. + + @page objc2json Objective-C to JSON + + Objective-C types are mapped to JSON types in the following way: + + @li NSNull -> null + @li NSString -> string + @li NSArray -> array + @li NSDictionary -> object + @li NSNumber's -initWithBool:YES -> true + @li NSNumber's -initWithBool:NO -> false + @li NSNumber -> number + + @note In JSON the keys of an object must be strings. NSDictionary + keys need not be, but attempting to convert an NSDictionary with + non-string keys into JSON will throw an exception. + + NSNumber instances created with the -numberWithBool: method are + converted into the JSON boolean "true" and "false" values, and vice + versa. Any other NSNumber instances are converted to a JSON number the + way you would expect. + + */ + +#import "extThree20JSON/SBJsonParser.h" +#import "extThree20JSON/SBJsonWriter.h" +#import "extThree20JSON/SBJsonStreamParser.h" +#import "extThree20JSON/SBJsonStreamParserAdapter.h" +#import "extThree20JSON/SBJsonStreamWriter.h" +#import "extThree20JSON/NSObject+SBJson.h" + diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonBase.h b/src/extThree20JSON/Vendors/JSON/SBJsonBase.h deleted file mode 100644 index 7b108440f0..0000000000 --- a/src/extThree20JSON/Vendors/JSON/SBJsonBase.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (C) 2009 Stig Brautaset. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the author nor the names of its contributors may be used - to endorse or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import - -extern NSString * SBJSONErrorDomain; - - -enum { - EUNSUPPORTED = 1, - EPARSENUM, - EPARSE, - EFRAGMENT, - ECTRL, - EUNICODE, - EDEPTH, - EESCAPE, - ETRAILCOMMA, - ETRAILGARBAGE, - EEOF, - EINPUT -}; - -/** - @brief Common base class for parsing & writing. - - This class contains the common error-handling code and option between the parser/writer. - */ -@interface SBJsonBase : NSObject { - NSMutableArray *errorTrace; - -@protected - NSUInteger depth, maxDepth; -} - -/** - @brief The maximum recursing depth. - - Defaults to 512. If the input is nested deeper than this the input will be deemed to be - malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can - turn off this security feature by setting the maxDepth value to 0. - */ -@property NSUInteger maxDepth; - -/** - @brief Return an error trace, or nil if there was no errors. - - Note that this method returns the trace of the last method that failed. - You need to check the return value of the call you're making to figure out - if the call actually failed, before you know call this method. - */ - @property(copy,readonly) NSArray* errorTrace; - -/// @internal for use in subclasses to add errors to the stack trace -- (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str; - -/// @internal for use in subclasess to clear the error before a new parsing attempt -- (void)clearErrorTrace; - -@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonParser.h b/src/extThree20JSON/Vendors/JSON/SBJsonParser.h old mode 100644 new mode 100755 index e95304d9b1..bf728c7a80 --- a/src/extThree20JSON/Vendors/JSON/SBJsonParser.h +++ b/src/extThree20JSON/Vendors/JSON/SBJsonParser.h @@ -1,20 +1,20 @@ /* Copyright (C) 2009 Stig Brautaset. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,60 +28,80 @@ */ #import -#import "SBJsonBase.h" /** - @brief Options for the parser class. - - This exists so the SBJSON facade can implement the options in the parser without having to re-declare them. + @brief Parse JSON Strings and NSData objects + + This uses SBJsonStreamParser internally. + + @see @ref objc2json + */ -@protocol SBJsonParser + +@interface SBJsonParser : NSObject { + +@private + NSString *error; + NSUInteger depth, maxDepth; + +} /** - @brief Return the object represented by the given string. - - Returns the object represented by the passed-in string or nil on error. The returned object can be - a string, number, boolean, null, array or dictionary. - - @param repr the json string to parse + @brief The maximum recursing depth. + + Defaults to 32. If the input is nested deeper than this the input will be deemed to be + malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can + turn off this security feature by setting the maxDepth value to 0. */ -- (id)objectWithString:(NSString *)repr; +@property NSUInteger maxDepth; -@end +/** + @brief Description of parse error + This method returns the trace of the last method that failed. + You need to check the return value of the call you're making to figure out + if the call actually failed, before you know call this method. + + @return A string describing the error encountered, or nil if no error occured. + + */ +@property(copy) NSString *error; /** - @brief The JSON parser class. - - JSON is mapped to Objective-C types in the following way: - - @li Null -> NSNull - @li String -> NSMutableString - @li Array -> NSMutableArray - @li Object -> NSMutableDictionary - @li Boolean -> NSNumber (initialised with -initWithBool:) - @li Number -> NSDecimalNumber - - Since Objective-C doesn't have a dedicated class for boolean values, these turns into NSNumber - instances. These are initialised with the -initWithBool: method, and - round-trip back to JSON properly. (They won't silently suddenly become 0 or 1; they'll be - represented as 'true' and 'false' again.) - - JSON numbers turn into NSDecimalNumber instances, - as we can thus avoid any loss of precision. (JSON allows ridiculously large numbers.) + @brief Return the object represented by the given NSData object. + + The data *must* be UTF8 encoded. + @param data An NSData containing UTF8 encoded data to parse. + @return The NSArray or NSDictionary represented by the object, or nil if an error occured. + */ -@interface SBJsonParser : SBJsonBase { - -@private - const char *c; -} +- (id)objectWithData:(NSData*)data; -@end +/** + @brief Return the object represented by the given string + + This method converts its input to an NSData object containing UTF8 and calls -objectWithData: with it. + + @return The NSArray or NSDictionary represented by the object, or nil if an error occured. + */ +- (id)objectWithString:(NSString *)repr; + +/** + @brief Return the object represented by the given string + + This method calls objectWithString: internally. If an error occurs, and if @p error + is not nil, it creates an NSError object and returns this through its second argument. + + @param jsonText the json string to parse + @param error pointer to an NSError object to populate on error + + @return The NSArray or NSDictionary represented by the object, or nil if an error occured. + */ + +- (id)objectWithString:(NSString*)jsonText + error:(NSError**)error; -// don't use - exists for backwards compatibility with 2.1.x only. Will be removed in 2.3. -@interface SBJsonParser (Private) -- (id)fragmentWithString:(id)repr; @end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonParser.m b/src/extThree20JSON/Vendors/JSON/SBJsonParser.m old mode 100644 new mode 100755 index eda051a835..6f2e26b845 --- a/src/extThree20JSON/Vendors/JSON/SBJsonParser.m +++ b/src/extThree20JSON/Vendors/JSON/SBJsonParser.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2009 Stig Brautaset. All rights reserved. + Copyright (C) 2009,2010 Stig Brautaset. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -28,448 +28,77 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ #import "SBJsonParser.h" - -@interface SBJsonParser () - -- (BOOL)scanValue:(NSObject **)o; - -- (BOOL)scanRestOfArray:(NSMutableArray **)o; -- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o; -- (BOOL)scanRestOfNull:(NSNull **)o; -- (BOOL)scanRestOfFalse:(NSNumber **)o; -- (BOOL)scanRestOfTrue:(NSNumber **)o; -- (BOOL)scanRestOfString:(NSMutableString **)o; - -// Cannot manage without looking at the first digit -- (BOOL)scanNumber:(NSNumber **)o; - -- (BOOL)scanHexQuad:(unichar *)x; -- (BOOL)scanUnicodeChar:(unichar *)x; - -- (BOOL)scanIsAtEnd; - -@end - -#define skipWhitespace(c) while (isspace(*c)) c++ -#define skipDigits(c) while (isdigit(*c)) c++ - +#import "SBJsonStreamParser.h" +#import "SBJsonStreamParserAdapter.h" +#import "SBJsonStreamParserAccumulator.h" @implementation SBJsonParser -static char ctrl[0x22]; - +@synthesize maxDepth; +@synthesize error; -+ (void)initialize { - ctrl[0] = '\"'; - ctrl[1] = '\\'; - for (int i = 1; i < 0x20; i++) - ctrl[i+1] = i; - ctrl[0x21] = 0; +- (id)init { + self = [super init]; + if (self) + self.maxDepth = 32u; + return self; } -/** - @deprecated This exists in order to provide fragment support in older APIs in one more version. - It should be removed in the next major version. - */ -- (id)fragmentWithString:(id)repr { - [self clearErrorTrace]; - - if (!repr) { - [self addErrorWithCode:EINPUT description:@"Input was 'nil'"]; - return nil; - } - - depth = 0; - c = [repr UTF8String]; - - id o; - if (![self scanValue:&o]) { - return nil; - } - - // We found some valid JSON. But did it also contain something else? - if (![self scanIsAtEnd]) { - [self addErrorWithCode:ETRAILGARBAGE description:@"Garbage after JSON"]; - return nil; - } - - NSAssert1(o, @"Should have a valid object from %@", repr); - return o; -} - -- (id)objectWithString:(NSString *)repr { - - id o = [self fragmentWithString:repr]; - if (!o) - return nil; - - // Check that the object we've found is a valid JSON container. - if (![o isKindOfClass:[NSDictionary class]] && ![o isKindOfClass:[NSArray class]]) { - [self addErrorWithCode:EFRAGMENT description:@"Valid fragment, but not JSON"]; - return nil; - } - - return o; +- (void)dealloc { + [error release]; + [super dealloc]; } -/* - In contrast to the public methods, it is an error to omit the error parameter here. - */ -- (BOOL)scanValue:(NSObject **)o -{ - skipWhitespace(c); - - switch (*c++) { - case '{': - return [self scanRestOfDictionary:(NSMutableDictionary **)o]; - break; - case '[': - return [self scanRestOfArray:(NSMutableArray **)o]; - break; - case '"': - return [self scanRestOfString:(NSMutableString **)o]; - break; - case 'f': - return [self scanRestOfFalse:(NSNumber **)o]; - break; - case 't': - return [self scanRestOfTrue:(NSNumber **)o]; - break; - case 'n': - return [self scanRestOfNull:(NSNull **)o]; - break; - case '-': - case '0'...'9': - c--; // cannot verify number correctly without the first character - return [self scanNumber:(NSNumber **)o]; - break; - case '+': - [self addErrorWithCode:EPARSENUM description: @"Leading + disallowed in number"]; - return NO; - break; - case 0x0: - [self addErrorWithCode:EEOF description:@"Unexpected end of string"]; - return NO; - break; - default: - [self addErrorWithCode:EPARSE description: @"Unrecognised leading character"]; - return NO; - break; - } - - NSAssert(0, @"Should never get here"); - return NO; -} +#pragma mark Methods -- (BOOL)scanRestOfTrue:(NSNumber **)o -{ - if (!strncmp(c, "rue", 3)) { - c += 3; - *o = [NSNumber numberWithBool:YES]; - return YES; - } - [self addErrorWithCode:EPARSE description:@"Expected 'true'"]; - return NO; -} +- (id)objectWithData:(NSData *)data { -- (BOOL)scanRestOfFalse:(NSNumber **)o -{ - if (!strncmp(c, "alse", 4)) { - c += 4; - *o = [NSNumber numberWithBool:NO]; - return YES; - } - [self addErrorWithCode:EPARSE description: @"Expected 'false'"]; - return NO; -} - -- (BOOL)scanRestOfNull:(NSNull **)o { - if (!strncmp(c, "ull", 3)) { - c += 3; - *o = [NSNull null]; - return YES; - } - [self addErrorWithCode:EPARSE description: @"Expected 'null'"]; - return NO; -} - -- (BOOL)scanRestOfArray:(NSMutableArray **)o { - if (maxDepth && ++depth > maxDepth) { - [self addErrorWithCode:EDEPTH description: @"Nested too deep"]; - return NO; - } - - *o = [NSMutableArray arrayWithCapacity:8]; - - for (; *c ;) { - id v; - - skipWhitespace(c); - if (*c == ']' && c++) { - depth--; - return YES; - } - - if (![self scanValue:&v]) { - [self addErrorWithCode:EPARSE description:@"Expected value while parsing array"]; - return NO; - } - - [*o addObject:v]; - - skipWhitespace(c); - if (*c == ',' && c++) { - skipWhitespace(c); - if (*c == ']') { - [self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in array"]; - return NO; - } - } - } - - [self addErrorWithCode:EEOF description: @"End of input while parsing array"]; - return NO; -} - -- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o -{ - if (maxDepth && ++depth > maxDepth) { - [self addErrorWithCode:EDEPTH description: @"Nested too deep"]; - return NO; - } - - *o = [NSMutableDictionary dictionaryWithCapacity:7]; - - for (; *c ;) { - id k, v; - - skipWhitespace(c); - if (*c == '}' && c++) { - depth--; - return YES; - } - - if (!(*c == '\"' && c++ && [self scanRestOfString:&k])) { - [self addErrorWithCode:EPARSE description: @"Object key string expected"]; - return NO; - } - - skipWhitespace(c); - if (*c != ':') { - [self addErrorWithCode:EPARSE description: @"Expected ':' separating key and value"]; - return NO; - } - - c++; - if (![self scanValue:&v]) { - NSString *string = [NSString stringWithFormat:@"Object value expected for key: %@", k]; - [self addErrorWithCode:EPARSE description: string]; - return NO; - } - - [*o setObject:v forKey:k]; - - skipWhitespace(c); - if (*c == ',' && c++) { - skipWhitespace(c); - if (*c == '}') { - [self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in object"]; - return NO; - } - } - } - - [self addErrorWithCode:EEOF description: @"End of input while parsing object"]; - return NO; -} - -- (BOOL)scanRestOfString:(NSMutableString **)o -{ - *o = [NSMutableString stringWithCapacity:16]; - do { - // First see if there's a portion we can grab in one go. - // Doing this caused a massive speedup on the long string. - size_t len = strcspn(c, ctrl); - if (len) { - // check for - id t = [[NSString alloc] initWithBytesNoCopy:(char*)c - length:len - encoding:NSUTF8StringEncoding - freeWhenDone:NO]; - if (t) { - [*o appendString:t]; - [t release]; - c += len; - } - } - - if (*c == '"') { - c++; - return YES; - - } else if (*c == '\\') { - unichar uc = *++c; - switch (uc) { - case '\\': - case '/': - case '"': - break; - - case 'b': uc = '\b'; break; - case 'n': uc = '\n'; break; - case 'r': uc = '\r'; break; - case 't': uc = '\t'; break; - case 'f': uc = '\f'; break; - - case 'u': - c++; - if (![self scanUnicodeChar:&uc]) { - [self addErrorWithCode:EUNICODE description: @"Broken unicode character"]; - return NO; - } - c--; // hack. - break; - default: - [self addErrorWithCode:EESCAPE description: [NSString stringWithFormat:@"Illegal escape sequence '0x%x'", uc]]; - return NO; - break; - } - CFStringAppendCharacters((CFMutableStringRef)*o, &uc, 1); - c++; - - } else if (*c < 0x20) { - [self addErrorWithCode:ECTRL description: [NSString stringWithFormat:@"Unescaped control character '0x%x'", *c]]; - return NO; - - } else { - NSLog(@"should not be able to get here"); - } - } while (*c); - - [self addErrorWithCode:EEOF description:@"Unexpected EOF while parsing string"]; - return NO; -} - -- (BOOL)scanUnicodeChar:(unichar *)x -{ - unichar hi, lo; - - if (![self scanHexQuad:&hi]) { - [self addErrorWithCode:EUNICODE description: @"Missing hex quad"]; - return NO; - } - - if (hi >= 0xd800) { // high surrogate char? - if (hi < 0xdc00) { // yes - expect a low char - - if (!(*c == '\\' && ++c && *c == 'u' && ++c && [self scanHexQuad:&lo])) { - [self addErrorWithCode:EUNICODE description: @"Missing low character in surrogate pair"]; - return NO; - } - - if (lo < 0xdc00 || lo >= 0xdfff) { - [self addErrorWithCode:EUNICODE description:@"Invalid low surrogate char"]; - return NO; - } - - hi = (hi - 0xd800) * 0x400 + (lo - 0xdc00) + 0x10000; - - } else if (hi < 0xe000) { - [self addErrorWithCode:EUNICODE description:@"Invalid high character in surrogate pair"]; - return NO; - } + if (!data) { + self.error = @"Input was 'nil'"; + return nil; } - - *x = hi; - return YES; -} -- (BOOL)scanHexQuad:(unichar *)x -{ - *x = 0; - for (int i = 0; i < 4; i++) { - unichar uc = *c; - c++; - int d = (uc >= '0' && uc <= '9') - ? uc - '0' : (uc >= 'a' && uc <= 'f') - ? (uc - 'a' + 10) : (uc >= 'A' && uc <= 'F') - ? (uc - 'A' + 10) : -1; - if (d == -1) { - [self addErrorWithCode:EUNICODE description:@"Missing hex digit in quad"]; - return NO; - } - *x *= 16; - *x += d; - } - return YES; + SBJsonStreamParserAccumulator *accumulator = [[[SBJsonStreamParserAccumulator alloc] init] autorelease]; + + SBJsonStreamParserAdapter *adapter = [[[SBJsonStreamParserAdapter alloc] init] autorelease]; + adapter.delegate = accumulator; + + SBJsonStreamParser *parser = [[[SBJsonStreamParser alloc] init] autorelease]; + parser.maxDepth = self.maxDepth; + parser.delegate = adapter; + + switch ([parser parse:data]) { + case SBJsonStreamParserComplete: + return accumulator.value; + break; + + case SBJsonStreamParserWaitingForData: + self.error = @"Unexpected end of input"; + break; + + case SBJsonStreamParserError: + self.error = parser.error; + break; + } + + return nil; } -- (BOOL)scanNumber:(NSNumber **)o -{ - const char *ns = c; - - // The logic to test for validity of the number formatting is relicensed - // from JSON::XS with permission from its author Marc Lehmann. - // (Available at the CPAN: http://search.cpan.org/dist/JSON-XS/ .) - - if ('-' == *c) - c++; - - if ('0' == *c && c++) { - if (isdigit(*c)) { - [self addErrorWithCode:EPARSENUM description: @"Leading 0 disallowed in number"]; - return NO; - } - - } else if (!isdigit(*c) && c != ns) { - [self addErrorWithCode:EPARSENUM description: @"No digits after initial minus"]; - return NO; - - } else { - skipDigits(c); - } - - // Fractional part - if ('.' == *c && c++) { - - if (!isdigit(*c)) { - [self addErrorWithCode:EPARSENUM description: @"No digits after decimal point"]; - return NO; - } - skipDigits(c); - } - - // Exponential part - if ('e' == *c || 'E' == *c) { - c++; - - if ('-' == *c || '+' == *c) - c++; - - if (!isdigit(*c)) { - [self addErrorWithCode:EPARSENUM description: @"No digits after exponent"]; - return NO; - } - skipDigits(c); - } - - id str = [[NSString alloc] initWithBytesNoCopy:(char*)ns - length:c - ns - encoding:NSUTF8StringEncoding - freeWhenDone:NO]; - [str autorelease]; - if (str && (*o = [NSDecimalNumber decimalNumberWithString:str])) - return YES; - - [self addErrorWithCode:EPARSENUM description: @"Failed creating decimal instance"]; - return NO; +- (id)objectWithString:(NSString *)repr { + return [self objectWithData:[repr dataUsingEncoding:NSUTF8StringEncoding]]; } -- (BOOL)scanIsAtEnd -{ - skipWhitespace(c); - return !*c; +- (id)objectWithString:(NSString*)repr error:(NSError**)error_ { + id tmp = [self objectWithString:repr]; + if (tmp) + return tmp; + + if (error_) { + NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error, NSLocalizedDescriptionKey, nil]; + *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonParser.ErrorDomain" code:0 userInfo:ui]; + } + + return nil; } - @end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamParser.h b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParser.h new file mode 100755 index 0000000000..4d6667b341 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParser.h @@ -0,0 +1,167 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +@class SBJsonTokeniser; +@class SBJsonStreamParser; +@class SBJsonStreamParserState; + +typedef enum { + SBJsonStreamParserComplete, + SBJsonStreamParserWaitingForData, + SBJsonStreamParserError, +} SBJsonStreamParserStatus; + + +/** + @brief Delegate for interacting directly with the stream parser + + You will most likely find it much more convenient to implement the + SBJsonStreamParserAdapterDelegate protocol instead. + */ +@protocol SBJsonStreamParserDelegate + +/// Called when object start is found +- (void)parserFoundObjectStart:(SBJsonStreamParser*)parser; + +/// Called when object key is found +- (void)parser:(SBJsonStreamParser*)parser foundObjectKey:(NSString*)key; + +/// Called when object end is found +- (void)parserFoundObjectEnd:(SBJsonStreamParser*)parser; + +/// Called when array start is found +- (void)parserFoundArrayStart:(SBJsonStreamParser*)parser; + +/// Called when array end is found +- (void)parserFoundArrayEnd:(SBJsonStreamParser*)parser; + +/// Called when a boolean value is found +- (void)parser:(SBJsonStreamParser*)parser foundBoolean:(BOOL)x; + +/// Called when a null value is found +- (void)parserFoundNull:(SBJsonStreamParser*)parser; + +/// Called when a number is found +- (void)parser:(SBJsonStreamParser*)parser foundNumber:(NSNumber*)num; + +/// Called when a string is found +- (void)parser:(SBJsonStreamParser*)parser foundString:(NSString*)string; + +@end + + +/** + @brief Parse a stream of JSON data. + + Using this class directly you can reduce the apparent latency for each + download/parse cycle of documents over a slow connection. You can start + parsing *and return chunks of the parsed document* before the entire + document is downloaded. + + Using this class is also useful to parse huge documents on disk + bit by bit so you don't have to keep them all in memory. + + @see SBJsonStreamParserAdapter for more information. + + @see @ref objc2json + + */ +@interface SBJsonStreamParser : NSObject { +@private + BOOL supportMultipleDocuments; + id delegate; + SBJsonTokeniser *tokeniser; + NSMutableArray *stateStack; + __weak SBJsonStreamParserState *state; + NSUInteger maxDepth; + NSString *error; +} + +@property (nonatomic, assign) __weak SBJsonStreamParserState *state; // Private +@property (nonatomic, readonly, retain) NSMutableArray *stateStack; // Private + +/** + @brief Expect multiple documents separated by whitespace + + Normally the @p -parse: method returns SBJsonStreamParserComplete when it's found a complete JSON document. + Attempting to parse any more data at that point is considered an error. ("Garbage after JSON".) + + If you set this property to true the parser will never return SBJsonStreamParserComplete. Rather, + once an object is completed it will expect another object to immediately follow, separated + only by (optional) whitespace. + + @see The TweetStream app in the Examples + */ +@property BOOL supportMultipleDocuments; + +/** + @brief Delegate to receive messages + + The object set here receives a series of messages as the parser breaks down the JSON stream + into valid tokens. + + @note + Usually this should be an instance of SBJsonStreamParserAdapter, but you can + substitute your own implementation of the SBJsonStreamParserDelegate protocol if you need to. + */ +@property (assign) id delegate; + +/** + @brief The max parse depth + + If the input is nested deeper than this the parser will halt parsing and return an error. + + Defaults to 32. + */ +@property NSUInteger maxDepth; + +/// Holds the error after SBJsonStreamParserError was returned +@property (copy) NSString *error; + +/** + @brief Parse some JSON + + The JSON is assumed to be UTF8 encoded. This can be a full JSON document, or a part of one. + + @param data An NSData object containing the next chunk of JSON + + @return + @li SBJsonStreamParserComplete if a full document was found + @li SBJsonStreamParserWaitingForData if a partial document was found and more data is required to complete it + @li SBJsonStreamParserError if an error occured. (See the error property for details in this case.) + + */ +- (SBJsonStreamParserStatus)parse:(NSData*)data; + +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamParser.m b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParser.m new file mode 100755 index 0000000000..8fb32b8cdc --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParser.m @@ -0,0 +1,246 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "SBJsonStreamParser.h" +#import "SBJsonTokeniser.h" +#import "SBJsonStreamParserState.h" +#import + +@implementation SBJsonStreamParser + +@synthesize supportMultipleDocuments; +@synthesize error; +@synthesize delegate; +@synthesize maxDepth; +@synthesize state; +@synthesize stateStack; + +#pragma mark Housekeeping + +- (id)init { + self = [super init]; + if (self) { + maxDepth = 32u; + stateStack = [[NSMutableArray alloc] initWithCapacity:maxDepth]; + state = [SBJsonStreamParserStateStart sharedInstance]; + tokeniser = [[SBJsonTokeniser alloc] init]; + } + return self; +} + +- (void)dealloc { + self.error = nil; + self.state = nil; + [stateStack release]; + [tokeniser release]; + [super dealloc]; +} + +#pragma mark Methods + +- (NSString*)tokenName:(sbjson_token_t)token { + switch (token) { + case sbjson_token_array_start: + return @"start of array"; + break; + + case sbjson_token_array_end: + return @"end of array"; + break; + + case sbjson_token_number: + return @"number"; + break; + + case sbjson_token_string: + return @"string"; + break; + + case sbjson_token_true: + case sbjson_token_false: + return @"boolean"; + break; + + case sbjson_token_null: + return @"null"; + break; + + case sbjson_token_keyval_separator: + return @"key-value separator"; + break; + + case sbjson_token_separator: + return @"value separator"; + break; + + case sbjson_token_object_start: + return @"start of object"; + break; + + case sbjson_token_object_end: + return @"end of object"; + break; + + case sbjson_token_eof: + case sbjson_token_error: + break; + } + NSAssert(NO, @"Should not get here"); + return @""; +} + +- (void)maxDepthError { + self.error = [NSString stringWithFormat:@"Input depth exceeds max depth of %lu", maxDepth]; + self.state = [SBJsonStreamParserStateError sharedInstance]; +} + +- (void)handleObjectStart { + if (stateStack.count >= maxDepth) { + [self maxDepthError]; + return; + } + + [delegate parserFoundObjectStart:self]; + [stateStack addObject:state]; + self.state = [SBJsonStreamParserStateObjectStart sharedInstance]; +} + +- (void)handleArrayStart { + if (stateStack.count >= maxDepth) { + [self maxDepthError]; + return; + } + + [delegate parserFoundArrayStart:self]; + [stateStack addObject:state]; + self.state = [SBJsonStreamParserStateArrayStart sharedInstance]; +} + +- (SBJsonStreamParserStatus)parse:(NSData *)data_ { + [tokeniser appendData:data_]; + + + for (;;) { + + if ([state isKindOfClass:[SBJsonStreamParserStateError class]]) + return SBJsonStreamParserError; + + NSObject *token; + sbjson_token_t tok = [tokeniser getToken:&token]; + switch (tok) { + case sbjson_token_eof: + return [state parserShouldReturn:self]; + break; + + case sbjson_token_error: + self.state = [SBJsonStreamParserStateError sharedInstance]; + self.error = tokeniser.error; + return SBJsonStreamParserError; + break; + + default: + + if (![state parser:self shouldAcceptToken:tok]) { + NSString *tokenName = [self tokenName:tok]; + NSString *stateName = [state name]; + + self.error = [NSString stringWithFormat:@"Token '%@' not expected %@", tokenName, stateName]; + self.state = [SBJsonStreamParserStateError sharedInstance]; + return SBJsonStreamParserError; + } + + switch (tok) { + case sbjson_token_object_start: + [self handleObjectStart]; + break; + + case sbjson_token_object_end: + self.state = [stateStack lastObject]; + [stateStack removeLastObject]; + [state parser:self shouldTransitionTo:tok]; + [delegate parserFoundObjectEnd:self]; + break; + + case sbjson_token_array_start: + [self handleArrayStart]; + break; + + case sbjson_token_array_end: + self.state = [stateStack lastObject]; + [stateStack removeLastObject]; + [state parser:self shouldTransitionTo:tok]; + [delegate parserFoundArrayEnd:self]; + break; + + case sbjson_token_separator: + case sbjson_token_keyval_separator: + [state parser:self shouldTransitionTo:tok]; + break; + + case sbjson_token_true: + [delegate parser:self foundBoolean:YES]; + [state parser:self shouldTransitionTo:tok]; + break; + + case sbjson_token_false: + [delegate parser:self foundBoolean:NO]; + [state parser:self shouldTransitionTo:tok]; + break; + + case sbjson_token_null: + [delegate parserFoundNull:self]; + [state parser:self shouldTransitionTo:tok]; + break; + + case sbjson_token_number: + [delegate parser:self foundNumber:(NSNumber*)token]; + [state parser:self shouldTransitionTo:tok]; + break; + + case sbjson_token_string: + if ([state needKey]) + [delegate parser:self foundObjectKey:(NSString*)token]; + else + [delegate parser:self foundString:(NSString*)token]; + [state parser:self shouldTransitionTo:tok]; + break; + + default: + break; + } + break; + } + } + return SBJsonStreamParserComplete; +} + +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJSON.h b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAccumulator.h old mode 100644 new mode 100755 similarity index 52% rename from src/extThree20JSON/Vendors/JSON/SBJSON.h rename to src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAccumulator.h index 701c84c8e5..ede76c6521 --- a/src/extThree20JSON/Vendors/JSON/SBJSON.h +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAccumulator.h @@ -1,20 +1,20 @@ /* - Copyright (C) 2007-2009 Stig Brautaset. All rights reserved. - + Copyright (C) 2011 Stig Brautaset. All rights reserved. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,48 +28,13 @@ */ #import -#import "extThree20JSON/private/SBJsonParser.h" -#import "extThree20JSON/private/SBJsonWriter.h" - -/** - @brief Facade for SBJsonWriter/SBJsonParser. - - Requests are forwarded to instances of SBJsonWriter and SBJsonParser. - */ -@interface SBJSON : SBJsonBase { +#import "SBJsonStreamParserAdapter.h" +@interface SBJsonStreamParserAccumulator : NSObject { @private - SBJsonParser *jsonParser; - SBJsonWriter *jsonWriter; + id value; } - -/// Return the fragment represented by the given string -- (id)fragmentWithString:(NSString*)jsonrep - error:(NSError**)error; - -/// Return the object represented by the given string -- (id)objectWithString:(NSString*)jsonrep - error:(NSError**)error; - -/// Parse the string and return the represented object (or scalar) -- (id)objectWithString:(id)value - allowScalar:(BOOL)x - error:(NSError**)error; - - -/// Return JSON representation of an array or dictionary -- (NSString*)stringWithObject:(id)value - error:(NSError**)error; - -/// Return JSON representation of any legal JSON value -- (NSString*)stringWithFragment:(id)value - error:(NSError**)error; - -/// Return JSON representation (or fragment) for the given object -- (NSString*)stringWithObject:(id)value - allowScalar:(BOOL)x - error:(NSError**)error; - +@property (readonly, copy) id value; @end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonBase.m b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAccumulator.m old mode 100644 new mode 100755 similarity index 56% rename from src/extThree20JSON/Vendors/JSON/SBJsonBase.m rename to src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAccumulator.m index 6684325d13..72716daf27 --- a/src/extThree20JSON/Vendors/JSON/SBJsonBase.m +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAccumulator.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2009 Stig Brautaset. All rights reserved. + Copyright (C) 2011 Stig Brautaset. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -27,52 +27,25 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "SBJsonBase.h" -NSString * SBJSONErrorDomain = @"org.brautaset.JSON.ErrorDomain"; +#import "SBJsonStreamParserAccumulator.h" +@implementation SBJsonStreamParserAccumulator -@implementation SBJsonBase - -@synthesize errorTrace; -@synthesize maxDepth; - -- (id)init { - self = [super init]; - if (self) - self.maxDepth = 512; - return self; -} +@synthesize value; - (void)dealloc { - [errorTrace release]; + [value release]; [super dealloc]; } -- (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str { - NSDictionary *userInfo; - if (!errorTrace) { - errorTrace = [NSMutableArray new]; - userInfo = [NSDictionary dictionaryWithObject:str forKey:NSLocalizedDescriptionKey]; - - } else { - userInfo = [NSDictionary dictionaryWithObjectsAndKeys: - str, NSLocalizedDescriptionKey, - [errorTrace lastObject], NSUnderlyingErrorKey, - nil]; - } - - NSError *error = [NSError errorWithDomain:SBJSONErrorDomain code:code userInfo:userInfo]; +#pragma mark SBJsonStreamParserAdapterDelegate - [self willChangeValueForKey:@"errorTrace"]; - [errorTrace addObject:error]; - [self didChangeValueForKey:@"errorTrace"]; +- (void)parser:(SBJsonStreamParser*)parser foundArray:(NSArray *)array { + value = [array retain]; } -- (void)clearErrorTrace { - [self willChangeValueForKey:@"errorTrace"]; - [errorTrace release]; - errorTrace = nil; - [self didChangeValueForKey:@"errorTrace"]; +- (void)parser:(SBJsonStreamParser*)parser foundObject:(NSDictionary *)dict { + value = [dict retain]; } @end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAdapter.h b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAdapter.h new file mode 100755 index 0000000000..4cc4b3dbc2 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAdapter.h @@ -0,0 +1,148 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import +#import "SBJsonStreamParser.h" + +typedef enum { + SBJsonStreamParserAdapterNone, + SBJsonStreamParserAdapterArray, + SBJsonStreamParserAdapterObject, +} SBJsonStreamParserAdapterType; + +/** + @brief Delegate for getting objects & arrays from the stream parser adapter + + @see The TweetStream example project. + */ +@protocol SBJsonStreamParserAdapterDelegate + +/** + @brief Called if a JSON array is found + + This method is called if a JSON array is found. + + */ +- (void)parser:(SBJsonStreamParser*)parser foundArray:(NSArray*)array; + +/** + @brief Called when a JSON object is found + + This method is called if a JSON object is found. + */ +- (void)parser:(SBJsonStreamParser*)parser foundObject:(NSDictionary*)dict; + +@end + +/** + @brief SBJsonStreamParserDelegate protocol adapter + + Rather than implementing the SBJsonStreamParserDelegate protocol yourself you will + most likely find it much more convenient to use an instance of this class and + implement the SBJsonStreamParserAdapterDelegate protocol instead. + + Normally you would only get one call from either the -parser:foundArray: or + -parser:foundObject: method. However, if your inputs contains multiple JSON + documents and you set the parser's -supportMultipleDocuments property to YES + you will get one call for each full method. + + @code + SBJsonStreamParserAdapter *adapter = [[[SBJsonStreamParserAdapter alloc] init] autorelease]; + adapter.delegate = self; + + SBJsonStreamParser *parser = [[[SBJsonStreamParser alloc] init] autorelease]; + parser.delegate = adapter; + parser.supportMultipleDocuments = YES; + + // Note that this input contains multiple top-level JSON documents + NSData *json = [@"[]{}[]{}" dataWithEncoding:NSUTF8StringEncoding]; + [parser parse:data]; + @endcode + + In the above example @p self will have the following sequence of methods called on it: + + @li -parser:foundArray: + @li -parser:foundObject: + @li -parser:foundArray: + @li -parser:foundObject: + + Often you won't have control over the input you're parsing, so can't make use of + this feature. But, all is not lost: this class will let you get the same effect by + allowing you to skip one or more of the outer enclosing objects. Thus, the next + example results in the same sequence of -parser:foundArray: / -parser:foundObject: + being called on your delegate. + + @code + SBJsonStreamParserAdapter *adapter = [[[SBJsonStreamParserAdapter alloc] init] autorelease]; + adapter.delegate = self; + adapter.levelsToSkip = 1; + + SBJsonStreamParser *parser = [[[SBJsonStreamParser alloc] init] autorelease]; + parser.delegate = adapter; + + // Note that this input contains A SINGLE top-level document + NSData *json = [@"[[],{},[],{}]" dataWithEncoding:NSUTF8StringEncoding]; + [parser parse:data]; + @endcode + +*/ +@interface SBJsonStreamParserAdapter : NSObject { +@private + id delegate; + NSUInteger levelsToSkip, depth; + __weak NSMutableArray *array; + __weak NSMutableDictionary *dict; + NSMutableArray *keyStack; + NSMutableArray *stack; + + SBJsonStreamParserAdapterType currentType; +} + +/** + @brief How many levels to skip + + This is useful for parsing huge JSON documents, or documents coming in over a very slow link. + + If you set this to N it will skip the outer N levels and call the -parser:foundArray: + or -parser:foundObject: methods for each of the inner objects, as appropriate. + + @see The StreamParserIntegrationTest.m file for examples +*/ +@property NSUInteger levelsToSkip; + +/** + @brief Your delegate object + Set this to the object you want to receive the SBJsonStreamParserAdapterDelegate messages. + */ +@property (assign) id delegate; + +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAdapter.m b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAdapter.m new file mode 100755 index 0000000000..8493e24ab8 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserAdapter.m @@ -0,0 +1,171 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "SBJsonStreamParserAdapter.h" + +@interface SBJsonStreamParserAdapter () + +- (void)pop; +- (void)parser:(SBJsonStreamParser*)parser found:(id)obj; + +@end + + + +@implementation SBJsonStreamParserAdapter + +@synthesize delegate; +@synthesize levelsToSkip; + +#pragma mark Housekeeping + +- (id)init { + self = [super init]; + if (self) { + keyStack = [[NSMutableArray alloc] initWithCapacity:32]; + stack = [[NSMutableArray alloc] initWithCapacity:32]; + + currentType = SBJsonStreamParserAdapterNone; + } + return self; +} + +- (void)dealloc { + [keyStack release]; + [stack release]; + [super dealloc]; +} + +#pragma mark Private methods + +- (void)pop { + [stack removeLastObject]; + array = nil; + dict = nil; + currentType = SBJsonStreamParserAdapterNone; + + id value = [stack lastObject]; + + if ([value isKindOfClass:[NSArray class]]) { + array = value; + currentType = SBJsonStreamParserAdapterArray; + } else if ([value isKindOfClass:[NSDictionary class]]) { + dict = value; + currentType = SBJsonStreamParserAdapterObject; + } +} + +- (void)parser:(SBJsonStreamParser*)parser found:(id)obj { + NSParameterAssert(obj); + + switch (currentType) { + case SBJsonStreamParserAdapterArray: + [array addObject:obj]; + break; + + case SBJsonStreamParserAdapterObject: + NSParameterAssert(keyStack.count); + [dict setObject:obj forKey:[keyStack lastObject]]; + [keyStack removeLastObject]; + break; + + case SBJsonStreamParserAdapterNone: + if ([obj isKindOfClass:[NSArray class]]) { + [delegate parser:parser foundArray:obj]; + } else { + [delegate parser:parser foundObject:obj]; + } + break; + + default: + break; + } +} + + +#pragma mark Delegate methods + +- (void)parserFoundObjectStart:(SBJsonStreamParser*)parser { + if (++depth > levelsToSkip) { + dict = [[NSMutableDictionary new] autorelease]; + [stack addObject:dict]; + currentType = SBJsonStreamParserAdapterObject; + } +} + +- (void)parser:(SBJsonStreamParser*)parser foundObjectKey:(NSString*)key_ { + [keyStack addObject:key_]; +} + +- (void)parserFoundObjectEnd:(SBJsonStreamParser*)parser { + if (depth-- > levelsToSkip) { + id value = [dict retain]; + [self pop]; + [self parser:parser found:value]; + [value release]; + } +} + +- (void)parserFoundArrayStart:(SBJsonStreamParser*)parser { + if (++depth > levelsToSkip) { + array = [[NSMutableArray new] autorelease]; + [stack addObject:array]; + currentType = SBJsonStreamParserAdapterArray; + } +} + +- (void)parserFoundArrayEnd:(SBJsonStreamParser*)parser { + if (depth-- > levelsToSkip) { + id value = [array retain]; + [self pop]; + [self parser:parser found:value]; + [value release]; + } +} + +- (void)parser:(SBJsonStreamParser*)parser foundBoolean:(BOOL)x { + [self parser:parser found:[NSNumber numberWithBool:x]]; +} + +- (void)parserFoundNull:(SBJsonStreamParser*)parser { + [self parser:parser found:[NSNull null]]; +} + +- (void)parser:(SBJsonStreamParser*)parser foundNumber:(NSNumber*)num { + [self parser:parser found:num]; +} + +- (void)parser:(SBJsonStreamParser*)parser foundString:(NSString*)string { + [self parser:parser found:string]; +} + +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserState.h b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserState.h new file mode 100755 index 0000000000..accee2da3f --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserState.h @@ -0,0 +1,81 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +#import "SBJsonTokeniser.h" +#import "SBJsonStreamParser.h" + +@interface SBJsonStreamParserState : NSObject ++ (id)sharedInstance; +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token; +- (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser; +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok; +- (BOOL)needKey; + +- (NSString*)name; + +@end + +@interface SBJsonStreamParserStateStart : SBJsonStreamParserState +@end + +@interface SBJsonStreamParserStateComplete : SBJsonStreamParserState +@end + +@interface SBJsonStreamParserStateError : SBJsonStreamParserState +@end + + +@interface SBJsonStreamParserStateObjectStart : SBJsonStreamParserState +@end + +@interface SBJsonStreamParserStateObjectGotKey : SBJsonStreamParserState +@end + +@interface SBJsonStreamParserStateObjectSeparator : SBJsonStreamParserState +@end + +@interface SBJsonStreamParserStateObjectGotValue : SBJsonStreamParserState +@end + +@interface SBJsonStreamParserStateObjectNeedKey : SBJsonStreamParserState +@end + +@interface SBJsonStreamParserStateArrayStart : SBJsonStreamParserState +@end + +@interface SBJsonStreamParserStateArrayGotValue : SBJsonStreamParserState +@end + +@interface SBJsonStreamParserStateArrayNeedValue : SBJsonStreamParserState +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserState.m b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserState.m new file mode 100755 index 0000000000..a6dfddaabf --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamParserState.m @@ -0,0 +1,347 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "SBJsonStreamParserState.h" +#import "SBJsonStreamParser.h" + +#define SINGLETON \ ++ (id)sharedInstance { \ + static id state; \ + if (!state) state = [[self alloc] init]; \ + return state; \ +} + +@implementation SBJsonStreamParserState + ++ (id)sharedInstance { return nil; } + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + return NO; +} + +- (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser { + return SBJsonStreamParserWaitingForData; +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {} + +- (BOOL)needKey { + return NO; +} + +- (NSString*)name { + return @""; +} + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateStart + +SINGLETON + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + return token == sbjson_token_array_start || token == sbjson_token_object_start; +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok { + + SBJsonStreamParserState *state = nil; + switch (tok) { + case sbjson_token_array_start: + state = [SBJsonStreamParserStateArrayStart sharedInstance]; + break; + + case sbjson_token_object_start: + state = [SBJsonStreamParserStateObjectStart sharedInstance]; + break; + + case sbjson_token_array_end: + case sbjson_token_object_end: + if (parser.supportMultipleDocuments) + state = parser.state; + else + state = [SBJsonStreamParserStateComplete sharedInstance]; + break; + + case sbjson_token_eof: + return; + + default: + state = [SBJsonStreamParserStateError sharedInstance]; + break; + } + + + parser.state = state; +} + +- (NSString*)name { return @"before outer-most array or object"; } + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateComplete + +SINGLETON + +- (NSString*)name { return @"after outer-most array or object"; } + +- (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser { + return SBJsonStreamParserComplete; +} + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateError + +SINGLETON + +- (NSString*)name { return @"in error"; } + +- (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser { + return SBJsonStreamParserError; +} + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateObjectStart + +SINGLETON + +- (NSString*)name { return @"at beginning of object"; } + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + switch (token) { + case sbjson_token_object_end: + case sbjson_token_string: + return YES; + break; + default: + return NO; + break; + } +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok { + parser.state = [SBJsonStreamParserStateObjectGotKey sharedInstance]; +} + +- (BOOL)needKey { + return YES; +} + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateObjectGotKey + +SINGLETON + +- (NSString*)name { return @"after object key"; } + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + return token == sbjson_token_keyval_separator; +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok { + parser.state = [SBJsonStreamParserStateObjectSeparator sharedInstance]; +} + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateObjectSeparator + +SINGLETON + +- (NSString*)name { return @"as object value"; } + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + switch (token) { + case sbjson_token_object_start: + case sbjson_token_array_start: + case sbjson_token_true: + case sbjson_token_false: + case sbjson_token_null: + case sbjson_token_number: + case sbjson_token_string: + return YES; + break; + + default: + return NO; + break; + } +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok { + parser.state = [SBJsonStreamParserStateObjectGotValue sharedInstance]; +} + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateObjectGotValue + +SINGLETON + +- (NSString*)name { return @"after object value"; } + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + switch (token) { + case sbjson_token_object_end: + case sbjson_token_separator: + return YES; + break; + default: + return NO; + break; + } +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok { + parser.state = [SBJsonStreamParserStateObjectNeedKey sharedInstance]; +} + + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateObjectNeedKey + +SINGLETON + +- (NSString*)name { return @"in place of object key"; } + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + return sbjson_token_string == token; +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok { + parser.state = [SBJsonStreamParserStateObjectGotKey sharedInstance]; +} + +- (BOOL)needKey { + return YES; +} + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateArrayStart + +SINGLETON + +- (NSString*)name { return @"at array start"; } + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + switch (token) { + case sbjson_token_object_end: + case sbjson_token_keyval_separator: + case sbjson_token_separator: + return NO; + break; + + default: + return YES; + break; + } +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok { + parser.state = [SBJsonStreamParserStateArrayGotValue sharedInstance]; +} + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateArrayGotValue + +SINGLETON + +- (NSString*)name { return @"after array value"; } + + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + return token == sbjson_token_array_end || token == sbjson_token_separator; +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok { + if (tok == sbjson_token_separator) + parser.state = [SBJsonStreamParserStateArrayNeedValue sharedInstance]; +} + +@end + +#pragma mark - + +@implementation SBJsonStreamParserStateArrayNeedValue + +SINGLETON + +- (NSString*)name { return @"as array value"; } + + +- (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token { + switch (token) { + case sbjson_token_array_end: + case sbjson_token_keyval_separator: + case sbjson_token_object_end: + case sbjson_token_separator: + return NO; + break; + + default: + return YES; + break; + } +} + +- (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok { + parser.state = [SBJsonStreamParserStateArrayGotValue sharedInstance]; +} + +@end + diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriter.h b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriter.h new file mode 100755 index 0000000000..5c263375cc --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriter.h @@ -0,0 +1,194 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +/// Enable JSON writing for non-native objects +@interface NSObject (SBProxyForJson) + +/** + @brief Allows generation of JSON for otherwise unsupported classes. + + If you have a custom class that you want to create a JSON representation + for you can implement this method in your class. It should return a + representation of your object defined in terms of objects that can be + translated into JSON. For example, a Person object might implement it like this: + + @code + - (id)proxyForJson { + return [NSDictionary dictionaryWithObjectsAndKeys: + name, @"name", + phone, @"phone", + email, @"email", + nil]; + } + @endcode + + */ +- (id)proxyForJson; + +@end + +@class SBJsonStreamWriter; + +@protocol SBJsonStreamWriterDelegate + +- (void)writer:(SBJsonStreamWriter*)writer appendBytes:(const void *)bytes length:(NSUInteger)length; + +@end + +@class SBJsonStreamWriterState; + +/** + @brief The Stream Writer class. + + Accepts a stream of messages and writes JSON of these to its delegate object. + + This class provides a range of high-, mid- and low-level methods. You can mix + and match calls to these. For example, you may want to call -writeArrayOpen + to start an array and then repeatedly call -writeObject: with various objects + before finishing off with a -writeArrayClose call. + + @see @ref json2objc + + */ + +@interface SBJsonStreamWriter : NSObject { +@private + NSString *error; + NSMutableArray *stateStack; + __weak SBJsonStreamWriterState *state; + id delegate; + NSUInteger maxDepth; + BOOL sortKeys, humanReadable; +} + +@property (nonatomic, assign) __weak SBJsonStreamWriterState *state; // Internal +@property (nonatomic, readonly, retain) NSMutableArray *stateStack; // Internal + +/** + @brief delegate to receive JSON output + Delegate that will receive messages with output. + */ +@property (assign) id delegate; + +/** + @brief The maximum recursing depth. + + Defaults to 512. If the input is nested deeper than this the input will be deemed to be + malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can + turn off this security feature by setting the maxDepth value to 0. + */ +@property NSUInteger maxDepth; + +/** + @brief Whether we are generating human-readable (multiline) JSON. + + Set whether or not to generate human-readable JSON. The default is NO, which produces + JSON without any whitespace between tokens. If set to YES, generates human-readable + JSON with linebreaks after each array value and dictionary key/value pair, indented two + spaces per nesting level. + */ +@property BOOL humanReadable; + +/** + @brief Whether or not to sort the dictionary keys in the output. + + If this is set to YES, the dictionary keys in the JSON output will be in sorted order. + (This is useful if you need to compare two structures, for example.) The default is NO. + */ +@property BOOL sortKeys; + +/// Contains the error description after an error has occured. +@property (copy) NSString *error; + +/** + Write an NSDictionary to the JSON stream. + @return YES if successful, or NO on failure + */ +- (BOOL)writeObject:(NSDictionary*)dict; + +/** + Write an NSArray to the JSON stream. + @return YES if successful, or NO on failure + */ +- (BOOL)writeArray:(NSArray *)array; + +/** + Start writing an Object to the stream + @return YES if successful, or NO on failure +*/ +- (BOOL)writeObjectOpen; + +/** + Close the current object being written + @return YES if successful, or NO on failure +*/ +- (BOOL)writeObjectClose; + +/** Start writing an Array to the stream + @return YES if successful, or NO on failure +*/ +- (BOOL)writeArrayOpen; + +/** Close the current Array being written + @return YES if successful, or NO on failure +*/ +- (BOOL)writeArrayClose; + +/** Write a null to the stream + @return YES if successful, or NO on failure +*/ +- (BOOL)writeNull; + +/** Write a boolean to the stream + @return YES if successful, or NO on failure +*/ +- (BOOL)writeBool:(BOOL)x; + +/** Write a Number to the stream + @return YES if successful, or NO on failure +*/ +- (BOOL)writeNumber:(NSNumber*)n; + +/** Write a String to the stream + @return YES if successful, or NO on failure +*/ +- (BOOL)writeString:(NSString*)s; + +@end + +@interface SBJsonStreamWriter (Private) +- (BOOL)writeValue:(id)v; +- (void)appendBytes:(const void *)bytes length:(NSUInteger)length; +@end + diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriter.m b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriter.m new file mode 100755 index 0000000000..597ef74612 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriter.m @@ -0,0 +1,375 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "SBJsonStreamWriter.h" +#import "SBJsonStreamWriterState.h" + +static NSDecimalNumber *kNotANumber; +static id kStaticStringCache; + + +@implementation SBJsonStreamWriter + +@synthesize error; +@synthesize maxDepth; +@synthesize state; +@synthesize stateStack; +@synthesize humanReadable; +@synthesize sortKeys; + ++ (void)initialize { + kNotANumber = [NSDecimalNumber notANumber]; + + Class cacheClass = NSClassFromString(@"NSCache"); + if (cacheClass) { + NSLog(@"%s NSCache supported", __FUNCTION__); + kStaticStringCache = [[cacheClass alloc] init]; + }else { + NSLog(@"%s NSCache not supported", __FUNCTION__); + } + + +} + +#pragma mark Housekeeping + +@synthesize delegate; + +- (id)init { + self = [super init]; + if (self) { + maxDepth = 32u; + stateStack = [[NSMutableArray alloc] initWithCapacity:maxDepth]; + state = [SBJsonStreamWriterStateStart sharedInstance]; + } + return self; +} + +- (void)dealloc { + self.error = nil; + self.state = nil; + [stateStack release]; + [super dealloc]; +} + +#pragma mark Methods + +- (void)appendBytes:(const void *)bytes length:(NSUInteger)length { + [delegate writer:self appendBytes:bytes length:length]; +} + +- (BOOL)writeObject:(NSDictionary *)dict { + if (![self writeObjectOpen]) + return NO; + + NSArray *keys = [dict allKeys]; + if (sortKeys) + keys = [keys sortedArrayUsingSelector:@selector(compare:)]; + + for (id k in keys) { + if (![k isKindOfClass:[NSString class]]) { + self.error = [NSString stringWithFormat:@"JSON object key must be string: %@", k]; + return NO; + } + + if (![self writeString:k]) + return NO; + if (![self writeValue:[dict objectForKey:k]]) + return NO; + } + + return [self writeObjectClose]; +} + +- (BOOL)writeArray:(NSArray*)array { + if (![self writeArrayOpen]) + return NO; + for (id v in array) + if (![self writeValue:v]) + return NO; + return [self writeArrayClose]; +} + + +- (BOOL)writeObjectOpen { + if ([state isInvalidState:self]) return NO; + if ([state expectingKey:self]) return NO; + [state appendSeparator:self]; + if (humanReadable && stateStack.count) [state appendWhitespace:self]; + + [stateStack addObject:state]; + self.state = [SBJsonStreamWriterStateObjectStart sharedInstance]; + + if (maxDepth && stateStack.count > maxDepth) { + self.error = @"Nested too deep"; + return NO; + } + + [delegate writer:self appendBytes:"{" length:1]; + return YES; +} + +- (BOOL)writeObjectClose { + if ([state isInvalidState:self]) return NO; + + SBJsonStreamWriterState *prev = state; + + self.state = [stateStack lastObject]; + [stateStack removeLastObject]; + + if (humanReadable) [prev appendWhitespace:self]; + [delegate writer:self appendBytes:"}" length:1]; + + [state transitionState:self]; + return YES; +} + +- (BOOL)writeArrayOpen { + if ([state isInvalidState:self]) return NO; + if ([state expectingKey:self]) return NO; + [state appendSeparator:self]; + if (humanReadable && stateStack.count) [state appendWhitespace:self]; + + [stateStack addObject:state]; + self.state = [SBJsonStreamWriterStateArrayStart sharedInstance]; + + if (maxDepth && stateStack.count > maxDepth) { + self.error = @"Nested too deep"; + return NO; + } + + [delegate writer:self appendBytes:"[" length:1]; + return YES; +} + +- (BOOL)writeArrayClose { + if ([state isInvalidState:self]) return NO; + if ([state expectingKey:self]) return NO; + + SBJsonStreamWriterState *prev = state; + + self.state = [stateStack lastObject]; + [stateStack removeLastObject]; + + if (humanReadable) [prev appendWhitespace:self]; + [delegate writer:self appendBytes:"]" length:1]; + + [state transitionState:self]; + return YES; +} + +- (BOOL)writeNull { + if ([state isInvalidState:self]) return NO; + if ([state expectingKey:self]) return NO; + [state appendSeparator:self]; + if (humanReadable) [state appendWhitespace:self]; + + [delegate writer:self appendBytes:"null" length:4]; + [state transitionState:self]; + return YES; +} + +- (BOOL)writeBool:(BOOL)x { + if ([state isInvalidState:self]) return NO; + if ([state expectingKey:self]) return NO; + [state appendSeparator:self]; + if (humanReadable) [state appendWhitespace:self]; + + if (x) + [delegate writer:self appendBytes:"true" length:4]; + else + [delegate writer:self appendBytes:"false" length:5]; + [state transitionState:self]; + return YES; +} + + +- (BOOL)writeValue:(id)o { + if ([o isKindOfClass:[NSDictionary class]]) { + return [self writeObject:o]; + + } else if ([o isKindOfClass:[NSArray class]]) { + return [self writeArray:o]; + + } else if ([o isKindOfClass:[NSString class]]) { + [self writeString:o]; + return YES; + + } else if ([o isKindOfClass:[NSNumber class]]) { + return [self writeNumber:o]; + + } else if ([o isKindOfClass:[NSNull class]]) { + return [self writeNull]; + + } else if ([o respondsToSelector:@selector(proxyForJson)]) { + return [self writeValue:[o proxyForJson]]; + + } + + self.error = [NSString stringWithFormat:@"JSON serialisation not supported for %@", [o class]]; + return NO; +} + +static const char *strForChar(int c) { + switch (c) { + case 0: return "\\u0000"; break; + case 1: return "\\u0001"; break; + case 2: return "\\u0002"; break; + case 3: return "\\u0003"; break; + case 4: return "\\u0004"; break; + case 5: return "\\u0005"; break; + case 6: return "\\u0006"; break; + case 7: return "\\u0007"; break; + case 8: return "\\b"; break; + case 9: return "\\t"; break; + case 10: return "\\n"; break; + case 11: return "\\u000b"; break; + case 12: return "\\f"; break; + case 13: return "\\r"; break; + case 14: return "\\u000e"; break; + case 15: return "\\u000f"; break; + case 16: return "\\u0010"; break; + case 17: return "\\u0011"; break; + case 18: return "\\u0012"; break; + case 19: return "\\u0013"; break; + case 20: return "\\u0014"; break; + case 21: return "\\u0015"; break; + case 22: return "\\u0016"; break; + case 23: return "\\u0017"; break; + case 24: return "\\u0018"; break; + case 25: return "\\u0019"; break; + case 26: return "\\u001a"; break; + case 27: return "\\u001b"; break; + case 28: return "\\u001c"; break; + case 29: return "\\u001d"; break; + case 30: return "\\u001e"; break; + case 31: return "\\u001f"; break; + case 34: return "\\\""; break; + case 92: return "\\\\"; break; + } + NSLog(@"FUTFUTFUT: -->'%c'<---", c); + return "FUTFUTFUT"; +} + +- (BOOL)writeString:(NSString*)string { + if ([state isInvalidState:self]) return NO; + [state appendSeparator:self]; + if (humanReadable) [state appendWhitespace:self]; + + NSMutableData *buf = [kStaticStringCache objectForKey:string]; + if (!buf) { + + NSUInteger len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + const char *utf8 = [string UTF8String]; + NSUInteger written = 0, i = 0; + + buf = [NSMutableData dataWithCapacity:(NSUInteger)(len * 1.1f)]; + [buf appendBytes:"\"" length:1]; + + for (i = 0; i < len; i++) { + int c = utf8[i]; + BOOL isControlChar = c >= 0 && c < 32; + if (isControlChar || c == '"' || c == '\\') { + if (i - written) + [buf appendBytes:utf8 + written length:i - written]; + written = i + 1; + + const char *t = strForChar(c); + [buf appendBytes:t length:strlen(t)]; + } + } + + if (i - written) + [buf appendBytes:utf8 + written length:i - written]; + + [buf appendBytes:"\"" length:1]; + [kStaticStringCache setObject:buf forKey:string]; + } + + [delegate writer:self appendBytes:[buf bytes] length:[buf length]]; + [state transitionState:self]; + return YES; +} + +- (BOOL)writeNumber:(NSNumber*)number { + if ((CFBooleanRef)number == kCFBooleanTrue || (CFBooleanRef)number == kCFBooleanFalse) + return [self writeBool:[number boolValue]]; + + if ([state isInvalidState:self]) return NO; + if ([state expectingKey:self]) return NO; + [state appendSeparator:self]; + if (humanReadable) [state appendWhitespace:self]; + + if ((CFNumberRef)number == kCFNumberPositiveInfinity) { + self.error = @"+Infinity is not a valid number in JSON"; + return NO; + + } else if ((CFNumberRef)number == kCFNumberNegativeInfinity) { + self.error = @"-Infinity is not a valid number in JSON"; + return NO; + + } else if ((CFNumberRef)number == kCFNumberNaN) { + self.error = @"NaN is not a valid number in JSON"; + return NO; + + } else if (number == kNotANumber) { + self.error = @"NaN is not a valid number in JSON"; + return NO; + } + + const char *objcType = [number objCType]; + char num[128]; + size_t len; + + switch (objcType[0]) { + case 'c': case 'i': case 's': case 'l': case 'q': + len = snprintf(num, sizeof num, "%lld", [number longLongValue]); + break; + case 'C': case 'I': case 'S': case 'L': case 'Q': + len = snprintf(num, sizeof num, "%llu", [number unsignedLongLongValue]); + break; + case 'f': case 'd': default: + if ([number isKindOfClass:[NSDecimalNumber class]]) { + char const *utf8 = [[number stringValue] UTF8String]; + [delegate writer:self appendBytes:utf8 length: strlen(utf8)]; + [state transitionState:self]; + return YES; + } + len = snprintf(num, sizeof num, "%.17g", [number doubleValue]); + break; + } + [delegate writer:self appendBytes:num length: len]; + [state transitionState:self]; + return YES; +} + +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterAccumulator.h b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterAccumulator.h new file mode 100755 index 0000000000..6a23b15586 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterAccumulator.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2011 Stig Brautaset. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the author nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "SBJsonStreamWriter.h" + +@interface SBJsonStreamWriterAccumulator : NSObject { +@private + NSMutableData *data; +} + +@property (readonly, copy) NSData* data; + +@end diff --git a/src/extThree20JSON/Vendors/JSON/JSON.h b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterAccumulator.m old mode 100644 new mode 100755 similarity index 62% rename from src/extThree20JSON/Vendors/JSON/JSON.h rename to src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterAccumulator.m index 753d9f4df0..c82a1d2faf --- a/src/extThree20JSON/Vendors/JSON/JSON.h +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterAccumulator.m @@ -1,20 +1,20 @@ /* - Copyright (C) 2009 Stig Brautaset. All rights reserved. - + Copyright (C) 2011 Stig Brautaset. All rights reserved. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -27,24 +27,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** - A strict JSON parser and generator for Objective-C +#import "SBJsonStreamWriterAccumulator.h" + + +@implementation SBJsonStreamWriterAccumulator - JSON (JavaScript Object Notation) is a lightweight data-interchange - format. This framework provides two apis for parsing and generating - JSON. One standard object-based and a higher level api consisting of - categories added to existing Objective-C classes. +@synthesize data; - Learn more on the http://code.google.com/p/json-framework project site. +- (id)init { + self = [super init]; + if (self) { + data = [[NSMutableData alloc] initWithCapacity:8096u]; + } + return self; +} - This framework does its best to be as strict as possible, both in what it - accepts and what it generates. For example, it does not support trailing commas - in arrays or objects. Nor does it support embedded comments, or - anything else not in the JSON specification. This is considered a feature. +- (void)dealloc { + [data release]; + [super dealloc]; +} -*/ +#pragma mark SBJsonStreamWriterDelegate -#import "extThree20JSON/SBJSON.h" -#import "extThree20JSON/NSObject+SBJSON.h" -#import "extThree20JSON/NSString+SBJSON.h" +- (void)writer:(SBJsonStreamWriter *)writer appendBytes:(const void *)bytes length:(NSUInteger)length { + [data appendBytes:bytes length:length]; +} +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterState.h b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterState.h new file mode 100755 index 0000000000..90d442a088 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterState.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +@class SBJsonStreamWriter; + +@interface SBJsonStreamWriterState : NSObject ++ (id)sharedInstance; +- (BOOL)isInvalidState:(SBJsonStreamWriter*)writer; +- (void)appendSeparator:(SBJsonStreamWriter*)writer; +- (BOOL)expectingKey:(SBJsonStreamWriter*)writer; +- (void)transitionState:(SBJsonStreamWriter*)writer; +- (void)appendWhitespace:(SBJsonStreamWriter*)writer; +@end + +@interface SBJsonStreamWriterStateObjectStart : SBJsonStreamWriterState +@end + +@interface SBJsonStreamWriterStateObjectKey : SBJsonStreamWriterStateObjectStart +@end + +@interface SBJsonStreamWriterStateObjectValue : SBJsonStreamWriterState +@end + +@interface SBJsonStreamWriterStateArrayStart : SBJsonStreamWriterState +@end + +@interface SBJsonStreamWriterStateArrayValue : SBJsonStreamWriterState +@end + +@interface SBJsonStreamWriterStateStart : SBJsonStreamWriterState +@end + +@interface SBJsonStreamWriterStateComplete : SBJsonStreamWriterState +@end + +@interface SBJsonStreamWriterStateError : SBJsonStreamWriterState +@end + diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterState.m b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterState.m new file mode 100755 index 0000000000..9f04cac4ba --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonStreamWriterState.m @@ -0,0 +1,139 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "SBJsonStreamWriterState.h" +#import "SBJsonStreamWriter.h" + +#define SINGLETON \ ++ (id)sharedInstance { \ + static id state; \ + if (!state) state = [[self alloc] init]; \ + return state; \ +} + + +@implementation SBJsonStreamWriterState ++ (id)sharedInstance { return nil; } +- (BOOL)isInvalidState:(SBJsonStreamWriter*)writer { return NO; } +- (void)appendSeparator:(SBJsonStreamWriter*)writer {} +- (BOOL)expectingKey:(SBJsonStreamWriter*)writer { return NO; } +- (void)transitionState:(SBJsonStreamWriter *)writer {} +- (void)appendWhitespace:(SBJsonStreamWriter*)writer { + [writer appendBytes:"\n" length:1]; + for (NSUInteger i = 0; i < writer.stateStack.count; i++) + [writer appendBytes:" " length:2]; +} +@end + +@implementation SBJsonStreamWriterStateObjectStart + +SINGLETON + +- (void)transitionState:(SBJsonStreamWriter *)writer { + writer.state = [SBJsonStreamWriterStateObjectValue sharedInstance]; +} +- (BOOL)expectingKey:(SBJsonStreamWriter *)writer { + writer.error = @"JSON object key must be string"; + return YES; +} +@end + +@implementation SBJsonStreamWriterStateObjectKey + +SINGLETON + +- (void)appendSeparator:(SBJsonStreamWriter *)writer { + [writer appendBytes:"," length:1]; +} +@end + +@implementation SBJsonStreamWriterStateObjectValue + +SINGLETON + +- (void)appendSeparator:(SBJsonStreamWriter *)writer { + [writer appendBytes:":" length:1]; +} +- (void)transitionState:(SBJsonStreamWriter *)writer { + writer.state = [SBJsonStreamWriterStateObjectKey sharedInstance]; +} +- (void)appendWhitespace:(SBJsonStreamWriter *)writer { + [writer appendBytes:" " length:1]; +} +@end + +@implementation SBJsonStreamWriterStateArrayStart + +SINGLETON + +- (void)transitionState:(SBJsonStreamWriter *)writer { + writer.state = [SBJsonStreamWriterStateArrayValue sharedInstance]; +} +@end + +@implementation SBJsonStreamWriterStateArrayValue + +SINGLETON + +- (void)appendSeparator:(SBJsonStreamWriter *)writer { + [writer appendBytes:"," length:1]; +} +@end + +@implementation SBJsonStreamWriterStateStart + +SINGLETON + + +- (void)transitionState:(SBJsonStreamWriter *)writer { + writer.state = [SBJsonStreamWriterStateComplete sharedInstance]; +} +- (void)appendSeparator:(SBJsonStreamWriter *)writer { +} +@end + +@implementation SBJsonStreamWriterStateComplete + +SINGLETON + +- (BOOL)isInvalidState:(SBJsonStreamWriter*)writer { + writer.error = @"Stream is closed"; + return YES; +} +@end + +@implementation SBJsonStreamWriterStateError + +SINGLETON + +@end + diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonTokeniser.h b/src/extThree20JSON/Vendors/JSON/SBJsonTokeniser.h new file mode 100755 index 0000000000..bd5eb71272 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonTokeniser.h @@ -0,0 +1,70 @@ +/* + Copyright (c) 2010, Stig Brautaset. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +typedef enum { + sbjson_token_error = -1, + sbjson_token_eof, + + sbjson_token_array_start, + sbjson_token_array_end, + + sbjson_token_object_start, + sbjson_token_object_end, + + sbjson_token_separator, + sbjson_token_keyval_separator, + + sbjson_token_number, + sbjson_token_string, + sbjson_token_true, + sbjson_token_false, + sbjson_token_null, + +} sbjson_token_t; + +@class SBJsonUTF8Stream; + +@interface SBJsonTokeniser : NSObject { +@private + SBJsonUTF8Stream *_stream; + NSString *_error; +} + +@property (copy) NSString *error; + +- (void)appendData:(NSData*)data_; + +- (sbjson_token_t)getToken:(NSObject**)token; + +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonTokeniser.m b/src/extThree20JSON/Vendors/JSON/SBJsonTokeniser.m new file mode 100755 index 0000000000..b6039629c9 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonTokeniser.m @@ -0,0 +1,456 @@ +/* + Copyright (c) 2010-2011, Stig Brautaset. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "SBJsonTokeniser.h" +#import "SBJsonUTF8Stream.h" + +#define SBStringIsIllegalSurrogateHighCharacter(character) (((character) >= 0xD800UL) && ((character) <= 0xDFFFUL)) +#define SBStringIsSurrogateLowCharacter(character) ((character >= 0xDC00UL) && (character <= 0xDFFFUL)) +#define SBStringIsSurrogateHighCharacter(character) ((character >= 0xD800UL) && (character <= 0xDBFFUL)) + +@implementation SBJsonTokeniser + +@synthesize error = _error; + +- (id)init { + self = [super init]; + if (self) { + _stream = [[SBJsonUTF8Stream alloc] init]; + + } + + return self; +} + +- (void)dealloc { + [_stream release]; + [super dealloc]; +} + +- (void)appendData:(NSData *)data_ { + [_stream appendData:data_]; +} + + +- (sbjson_token_t)match:(const char *)pattern length:(NSUInteger)len retval:(sbjson_token_t)token { + if (![_stream haveRemainingCharacters:len]) + return sbjson_token_eof; + + if ([_stream skipCharacters:pattern length:len]) + return token; + + self.error = [NSString stringWithFormat:@"Expected '%s' after initial '%.1s'", pattern, pattern]; + return sbjson_token_error; +} + +- (BOOL)decodeEscape:(unichar)ch into:(unichar*)decoded { + switch (ch) { + case '\\': + case '/': + case '"': + *decoded = ch; + break; + + case 'b': + *decoded = '\b'; + break; + + case 'n': + *decoded = '\n'; + break; + + case 'r': + *decoded = '\r'; + break; + + case 't': + *decoded = '\t'; + break; + + case 'f': + *decoded = '\f'; + break; + + default: + self.error = @"Illegal escape character"; + return NO; + break; + } + return YES; +} + +- (BOOL)decodeHexQuad:(unichar*)quad { + unichar c, tmp = 0; + + for (int i = 0; i < 4; i++) { + (void)[_stream getNextUnichar:&c]; + tmp *= 16; + switch (c) { + case '0' ... '9': + tmp += c - '0'; + break; + + case 'a' ... 'f': + tmp += 10 + c - 'a'; + break; + + case 'A' ... 'F': + tmp += 10 + c - 'A'; + break; + + default: + return NO; + } + } + *quad = tmp; + return YES; +} + +- (sbjson_token_t)getStringToken:(NSObject**)token { + NSMutableString *acc = nil; + + for (;;) { + [_stream skip]; + + unichar ch; + { + NSMutableString *string = nil; + if (![_stream getSimpleString:&string]) + return sbjson_token_eof; + + if (!string) { + self.error = @"Broken Unicode encoding"; + return sbjson_token_error; + } + + + if (![_stream getUnichar:&ch]) + return sbjson_token_eof; + + if (acc) { + [acc appendString:string]; + + } else if (ch == '"') { + *token = string; + [_stream skip]; + return sbjson_token_string; + + } else { + acc = [[string mutableCopy] autorelease]; + } + } + + switch (ch) { + case 0 ... 0x1F: + self.error = [NSString stringWithFormat:@"Unescaped control character [0x%0.2X]", (int)ch]; + return sbjson_token_error; + break; + + case '"': + *token = acc; + [_stream skip]; + return sbjson_token_string; + break; + + case '\\': + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + + if (ch == 'u') { + if (![_stream haveRemainingCharacters:5]) + return sbjson_token_eof; + + unichar hi; + if (![self decodeHexQuad:&hi]) { + self.error = @"Invalid hex quad"; + return sbjson_token_error; + } + + if (SBStringIsSurrogateHighCharacter(hi)) { + unichar lo; + + if (![_stream haveRemainingCharacters:6]) + return sbjson_token_eof; + + (void)[_stream getNextUnichar:&ch]; + (void)[_stream getNextUnichar:&lo]; + if (ch != '\\' || lo != 'u' || ![self decodeHexQuad:&lo]) { + self.error = @"Missing low character in surrogate pair"; + return sbjson_token_error; + } + + if (!SBStringIsSurrogateLowCharacter(lo)) { + self.error = @"Invalid low character in surrogate pair"; + return sbjson_token_error; + } + + unichar pair[2] = {hi, lo}; + CFStringAppendCharacters((CFMutableStringRef)acc, pair, 2); + } else if (SBStringIsIllegalSurrogateHighCharacter(hi)) { + self.error = @"Invalid high character in surrogate pair"; + return sbjson_token_error; + } else { + CFStringAppendCharacters((CFMutableStringRef)acc, &hi, 1); + } + + + } else { + unichar decoded; + if (![self decodeEscape:ch into:&decoded]) + return sbjson_token_error; + CFStringAppendCharacters((CFMutableStringRef)acc, &decoded, 1); + } + + break; + + default: { + self.error = [NSString stringWithFormat:@"Invalid UTF-8: '%x'", (int)ch]; + return sbjson_token_error; + break; + } + } + } + return sbjson_token_eof; +} + +- (sbjson_token_t)getNumberToken:(NSObject**)token { + + NSUInteger numberStart = _stream.index; + NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet]; + + unichar ch; + if (![_stream getUnichar:&ch]) + return sbjson_token_eof; + + BOOL isNegative = NO; + if (ch == '-') { + isNegative = YES; + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + } + + unsigned long long mantissa = 0; + int mantissa_length = 0; + + if (ch == '0') { + mantissa_length++; + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + + if ([digits characterIsMember:ch]) { + self.error = @"Leading zero is illegal in number"; + return sbjson_token_error; + } + } + + while ([digits characterIsMember:ch]) { + mantissa *= 10; + mantissa += (ch - '0'); + mantissa_length++; + + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + } + + short exponent = 0; + BOOL isFloat = NO; + + if (ch == '.') { + isFloat = YES; + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + + while ([digits characterIsMember:ch]) { + mantissa *= 10; + mantissa += (ch - '0'); + mantissa_length++; + exponent--; + + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + } + + if (!exponent) { + self.error = @"No digits after decimal point"; + return sbjson_token_error; + } + } + + BOOL hasExponent = NO; + if (ch == 'e' || ch == 'E') { + hasExponent = YES; + + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + + BOOL expIsNegative = NO; + if (ch == '-') { + expIsNegative = YES; + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + + } else if (ch == '+') { + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + } + + short exp = 0; + short exp_length = 0; + while ([digits characterIsMember:ch]) { + exp *= 10; + exp += (ch - '0'); + exp_length++; + + if (![_stream getNextUnichar:&ch]) + return sbjson_token_eof; + } + + if (exp_length == 0) { + self.error = @"No digits in exponent"; + return sbjson_token_error; + } + + if (expIsNegative) + exponent -= exp; + else + exponent += exp; + } + + if (!mantissa_length && isNegative) { + self.error = @"No digits after initial minus"; + return sbjson_token_error; + + } else if (mantissa_length >= 19) { + + NSString *number = [_stream stringWithRange:NSMakeRange(numberStart, _stream.index - numberStart)]; + *token = [NSDecimalNumber decimalNumberWithString:number]; + + } else if (!isFloat && !hasExponent) { + if (!isNegative) + *token = [NSNumber numberWithUnsignedLongLong:mantissa]; + else + *token = [NSNumber numberWithLongLong:-mantissa]; + } else { + *token = [NSDecimalNumber decimalNumberWithMantissa:mantissa + exponent:exponent + isNegative:isNegative]; + } + + return sbjson_token_number; +} + +- (sbjson_token_t)getToken:(NSObject **)token { + + [_stream skipWhitespace]; + + unichar ch; + if (![_stream getUnichar:&ch]) + return sbjson_token_eof; + + NSUInteger oldIndexLocation = _stream.index; + sbjson_token_t tok; + + switch (ch) { + case '[': + tok = sbjson_token_array_start; + [_stream skip]; + break; + + case ']': + tok = sbjson_token_array_end; + [_stream skip]; + break; + + case '{': + tok = sbjson_token_object_start; + [_stream skip]; + break; + + case ':': + tok = sbjson_token_keyval_separator; + [_stream skip]; + break; + + case '}': + tok = sbjson_token_object_end; + [_stream skip]; + break; + + case ',': + tok = sbjson_token_separator; + [_stream skip]; + break; + + case 'n': + tok = [self match:"null" length:4 retval:sbjson_token_null]; + break; + + case 't': + tok = [self match:"true" length:4 retval:sbjson_token_true]; + break; + + case 'f': + tok = [self match:"false" length:5 retval:sbjson_token_false]; + break; + + case '"': + tok = [self getStringToken:token]; + break; + + case '0' ... '9': + case '-': + tok = [self getNumberToken:token]; + break; + + case '+': + self.error = @"Leading + is illegal in number"; + tok = sbjson_token_error; + break; + + default: + self.error = [NSString stringWithFormat:@"Illegal start of token [%c]", ch]; + tok = sbjson_token_error; + break; + } + + if (tok == sbjson_token_eof) { + // We ran out of bytes in the middle of a token. + // We don't know how to restart in mid-flight, so + // rewind to the start of the token for next attempt. + // Hopefully we'll have more data then. + _stream.index = oldIndexLocation; + } + + return tok; +} + + +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonUTF8Stream.h b/src/extThree20JSON/Vendors/JSON/SBJsonUTF8Stream.h new file mode 100755 index 0000000000..7a60cca3e9 --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonUTF8Stream.h @@ -0,0 +1,59 @@ +/* + Copyright (c) 2011, Stig Brautaset. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import + + +@interface SBJsonUTF8Stream : NSObject { +@private + const char *_bytes; + NSMutableData *_data; + NSUInteger _length; + NSUInteger _index; +} + +@property (assign) NSUInteger index; + +- (void)appendData:(NSData*)data_; + +- (BOOL)haveRemainingCharacters:(NSUInteger)chars; + +- (void)skip; +- (void)skipWhitespace; +- (BOOL)skipCharacters:(const char *)chars length:(NSUInteger)len; + +- (BOOL)getUnichar:(unichar*)ch; +- (BOOL)getNextUnichar:(unichar*)ch; +- (BOOL)getSimpleString:(NSString**)string; + +- (NSString*)stringWithRange:(NSRange)range; + +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonUTF8Stream.m b/src/extThree20JSON/Vendors/JSON/SBJsonUTF8Stream.m new file mode 100755 index 0000000000..ad7ccf78bf --- /dev/null +++ b/src/extThree20JSON/Vendors/JSON/SBJsonUTF8Stream.m @@ -0,0 +1,143 @@ +/* + Copyright (c) 2011, Stig Brautaset. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "SBJsonUTF8Stream.h" + + +@implementation SBJsonUTF8Stream + +@synthesize index = _index; + +- (id)init { + self = [super init]; + if (self) { + _data = [[NSMutableData alloc] initWithCapacity:4096u]; + } + return self; +} + +- (void)dealloc { + [_data release]; + [super dealloc]; +} + +- (void)appendData:(NSData *)data_ { + + if (_index) { + // Discard data we've already parsed + [_data replaceBytesInRange:NSMakeRange(0, _index) withBytes:"" length:0]; + + // Reset index to point to current position + _index = 0; + } + + [_data appendData:data_]; + + // This is an optimisation. + _bytes = [_data bytes]; + _length = [_data length]; +} + + +- (BOOL)getUnichar:(unichar*)ch { + if (_index < _length) { + *ch = (unichar)_bytes[_index]; + return YES; + } + return NO; +} + +- (BOOL)getNextUnichar:(unichar*)ch { + if (++_index < _length) { + *ch = (unichar)_bytes[_index]; + return YES; + } + return NO; +} + +- (BOOL)getSimpleString:(NSString **)string { + NSUInteger start = _index; + while (_index < _length) { + switch (_bytes[_index]) { + case '"': + case '\\': + case 0 ... 0x1f: + *string = [[[NSString alloc] initWithBytes:(_bytes + start) length:(_index - start) encoding:NSUTF8StringEncoding] autorelease]; + return YES; + break; + default: + _index++; + break; + } + } + return NO; +} + +- (void)skip { + _index++; +} + +- (void)skipWhitespace { + while (_index < _length) { + switch (_bytes[_index]) { + case ' ': + case '\t': + case '\r': + case '\n': + _index++; + break; + default: + return; + break; + } + } +} + +- (BOOL)haveRemainingCharacters:(NSUInteger)chars { + return [_data length] - _index >= chars; +} + +- (BOOL)skipCharacters:(const char *)chars length:(NSUInteger)len { + const void *bytes = [_data bytes] + _index; + if (!memcmp(bytes, chars, len)) { + _index += len; + return YES; + } + return NO; +} + +- (NSString*)stringWithRange:(NSRange)range { + return [[[NSString alloc] initWithBytes:_bytes + range.location length:range.length encoding:NSUTF8StringEncoding] autorelease]; + +} + + +@end diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonWriter.h b/src/extThree20JSON/Vendors/JSON/SBJsonWriter.h old mode 100644 new mode 100755 index f6f5e17bf3..8c167e0793 --- a/src/extThree20JSON/Vendors/JSON/SBJsonWriter.h +++ b/src/extThree20JSON/Vendors/JSON/SBJsonWriter.h @@ -28,14 +28,39 @@ */ #import -#import "SBJsonBase.h" /** - @brief Options for the writer class. + @brief The JSON writer class. + + This uses SBJsonStreamWriter internally. + + @see @ref json2objc + */ + +@interface SBJsonWriter : NSObject { +@private + NSString *error; + NSUInteger maxDepth; + BOOL sortKeys, humanReadable; +} + +/** + @brief The maximum recursing depth. - This exists so the SBJSON facade can implement the options in the writer without having to re-declare them. + Defaults to 32. If the input is nested deeper than this the input will be deemed to be + malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can + turn off this security feature by setting the maxDepth value to 0. */ -@protocol SBJsonWriter +@property NSUInteger maxDepth; + +/** + @brief Return an error trace, or nil if there was no errors. + + Note that this method returns the trace of the last method that failed. + You need to check the return value of the call you're making to figure out + if the call actually failed, before you know call this method. + */ +@property (readonly, copy) NSString *error; /** @brief Whether we are generating human-readable (multiline) JSON. @@ -56,74 +81,35 @@ @property BOOL sortKeys; /** - @brief Return JSON representation (or fragment) for the given object. + @brief Return JSON representation for the given object. Returns a string containing JSON representation of the passed in value, or nil on error. If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error. - @param value any instance that can be represented as a JSON fragment - + @param value any instance that can be represented as JSON text. */ - (NSString*)stringWithObject:(id)value; -@end - - /** - @brief The JSON writer class. + @brief Return JSON representation for the given object. - Objective-C types are mapped to JSON types in the following way: + Returns an NSData object containing JSON represented as UTF8 text, or nil on error. - @li NSNull -> Null - @li NSString -> String - @li NSArray -> Array - @li NSDictionary -> Object - @li NSNumber (-initWithBool:) -> Boolean - @li NSNumber -> Number + @param value any instance that can be represented as JSON text. + */ +- (NSData*)dataWithObject:(id)value; + +/** + @brief Return JSON representation (or fragment) for the given object. - In JSON the keys of an object must be strings. NSDictionary keys need - not be, but attempting to convert an NSDictionary with non-string keys - into JSON will throw an exception. + Returns a string containing JSON representation of the passed in value, or nil on error. + If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error. - NSNumber instances created with the +initWithBool: method are - converted into the JSON boolean "true" and "false" values, and vice - versa. Any other NSNumber instances are converted to a JSON number the - way you would expect. + @param value any instance that can be represented as a JSON fragment + @param error pointer to object to be populated with NSError on failure - */ -@interface SBJsonWriter : SBJsonBase { - -@private - BOOL sortKeys, humanReadable; -} - -@end + */- (NSString*)stringWithObject:(id)value + error:(NSError**)error; -// don't use - exists for backwards compatibility. Will be removed in 2.3. -@interface SBJsonWriter (Private) -- (NSString*)stringWithFragment:(id)value; -@end -/** - @brief Allows generation of JSON for otherwise unsupported classes. - - If you have a custom class that you want to create a JSON representation for you can implement - this method in your class. It should return a representation of your object defined - in terms of objects that can be translated into JSON. For example, a Person - object might implement it like this: - - @code - - (id)jsonProxyObject { - return [NSDictionary dictionaryWithObjectsAndKeys: - name, @"name", - phone, @"phone", - email, @"email", - nil]; - } - @endcode - - */ -@interface NSObject (SBProxyForJson) -- (id)proxyForJson; @end - diff --git a/src/extThree20JSON/Vendors/JSON/SBJsonWriter.m b/src/extThree20JSON/Vendors/JSON/SBJsonWriter.m old mode 100644 new mode 100755 index 0f32904109..15d14141d0 --- a/src/extThree20JSON/Vendors/JSON/SBJsonWriter.m +++ b/src/extThree20JSON/Vendors/JSON/SBJsonWriter.m @@ -28,210 +28,86 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ #import "SBJsonWriter.h" +#import "SBJsonStreamWriter.h" +#import "SBJsonStreamWriterAccumulator.h" -@interface SBJsonWriter () - -- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json; -- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json; -- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json; -- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json; - -- (NSString*)indent; +@interface SBJsonWriter () +@property (copy) NSString *error; @end @implementation SBJsonWriter -static NSMutableCharacterSet *kEscapeChars; - -+ (void)initialize { - kEscapeChars = [[NSMutableCharacterSet characterSetWithRange: NSMakeRange(0,32)] retain]; - [kEscapeChars addCharactersInString: @"\"\\"]; -} - - @synthesize sortKeys; @synthesize humanReadable; -/** - @deprecated This exists in order to provide fragment support in older APIs in one more version. - It should be removed in the next major version. - */ -- (NSString*)stringWithFragment:(id)value { - [self clearErrorTrace]; - depth = 0; - NSMutableString *json = [NSMutableString stringWithCapacity:128]; - - if ([self appendValue:value into:json]) - return json; - - return nil; -} - +@synthesize error; +@synthesize maxDepth; -- (NSString*)stringWithObject:(id)value { - - if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) { - return [self stringWithFragment:value]; - } - - if ([value respondsToSelector:@selector(proxyForJson)]) { - NSString *tmp = [self stringWithObject:[value proxyForJson]]; - if (tmp) - return tmp; +- (id)init { + self = [super init]; + if (self) { + self.maxDepth = 32u; } - - - [self clearErrorTrace]; - [self addErrorWithCode:EFRAGMENT description:@"Not valid type for JSON"]; - return nil; + return self; } - -- (NSString*)indent { - return [@"\n" stringByPaddingToLength:1 + 2 * depth withString:@" " startingAtIndex:0]; +- (void)dealloc { + [error release]; + [super dealloc]; } -- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json { - if ([fragment isKindOfClass:[NSDictionary class]]) { - if (![self appendDictionary:fragment into:json]) - return NO; - - } else if ([fragment isKindOfClass:[NSArray class]]) { - if (![self appendArray:fragment into:json]) - return NO; - - } else if ([fragment isKindOfClass:[NSString class]]) { - if (![self appendString:fragment into:json]) - return NO; - - } else if ([fragment isKindOfClass:[NSNumber class]]) { - if ('c' == *[fragment objCType]) - [json appendString:[fragment boolValue] ? @"true" : @"false"]; - else - [json appendString:[fragment stringValue]]; - - } else if ([fragment isKindOfClass:[NSNull class]]) { - [json appendString:@"null"]; - } else if ([fragment respondsToSelector:@selector(proxyForJson)]) { - [self appendValue:[fragment proxyForJson] into:json]; - - } else { - [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"JSON serialisation not supported for %@", [fragment class]]]; - return NO; - } - return YES; -} - -- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json { - if (maxDepth && ++depth > maxDepth) { - [self addErrorWithCode:EDEPTH description: @"Nested too deep"]; - return NO; - } - [json appendString:@"["]; - - BOOL addComma = NO; - for (id value in fragment) { - if (addComma) - [json appendString:@","]; - else - addComma = YES; - - if ([self humanReadable]) - [json appendString:[self indent]]; - - if (![self appendValue:value into:json]) { - return NO; - } - } +- (NSString*)stringWithObject:(id)value { + NSData *data = [self dataWithObject:value]; + if (data) + return [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + return nil; +} + +- (NSString*)stringWithObject:(id)value error:(NSError**)error_ { + NSString *tmp = [self stringWithObject:value]; + if (tmp) + return tmp; - depth--; - if ([self humanReadable] && [fragment count]) - [json appendString:[self indent]]; - [json appendString:@"]"]; - return YES; + if (error_) { + NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error, NSLocalizedDescriptionKey, nil]; + *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonWriter.ErrorDomain" code:0 userInfo:ui]; + } + + return nil; } -- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json { - if (maxDepth && ++depth > maxDepth) { - [self addErrorWithCode:EDEPTH description: @"Nested too deep"]; - return NO; - } - [json appendString:@"{"]; - - NSString *colon = [self humanReadable] ? @" : " : @":"; - BOOL addComma = NO; - NSArray *keys = [fragment allKeys]; - if (self.sortKeys) - keys = [keys sortedArrayUsingSelector:@selector(compare:)]; - - for (id value in keys) { - if (addComma) - [json appendString:@","]; - else - addComma = YES; - - if ([self humanReadable]) - [json appendString:[self indent]]; - - if (![value isKindOfClass:[NSString class]]) { - [self addErrorWithCode:EUNSUPPORTED description: @"JSON object key must be string"]; - return NO; - } - - if (![self appendString:value into:json]) - return NO; - - [json appendString:colon]; - if (![self appendValue:[fragment objectForKey:value] into:json]) { - [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"Unsupported value for key %@ in object", value]]; - return NO; - } - } - - depth--; - if ([self humanReadable] && [fragment count]) - [json appendString:[self indent]]; - [json appendString:@"}"]; - return YES; -} +- (NSData*)dataWithObject:(id)object { + self.error = nil; -- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json { + SBJsonStreamWriterAccumulator *accumulator = [[[SBJsonStreamWriterAccumulator alloc] init] autorelease]; - [json appendString:@"\""]; - - NSRange esc = [fragment rangeOfCharacterFromSet:kEscapeChars]; - if ( !esc.length ) { - // No special chars -- can just add the raw string: - [json appendString:fragment]; - - } else { - NSUInteger length = [fragment length]; - for (NSUInteger i = 0; i < length; i++) { - unichar uc = [fragment characterAtIndex:i]; - switch (uc) { - case '"': [json appendString:@"\\\""]; break; - case '\\': [json appendString:@"\\\\"]; break; - case '\t': [json appendString:@"\\t"]; break; - case '\n': [json appendString:@"\\n"]; break; - case '\r': [json appendString:@"\\r"]; break; - case '\b': [json appendString:@"\\b"]; break; - case '\f': [json appendString:@"\\f"]; break; - default: - if (uc < 0x20) { - [json appendFormat:@"\\u%04x", uc]; - } else { - CFStringAppendCharacters((CFMutableStringRef)json, &uc, 1); - } - break; - - } - } - } - - [json appendString:@"\""]; - return YES; + SBJsonStreamWriter *streamWriter = [[[SBJsonStreamWriter alloc] init] autorelease]; + streamWriter.sortKeys = self.sortKeys; + streamWriter.maxDepth = self.maxDepth; + streamWriter.humanReadable = self.humanReadable; + streamWriter.delegate = accumulator; + + BOOL ok = NO; + if ([object isKindOfClass:[NSDictionary class]]) + ok = [streamWriter writeObject:object]; + + else if ([object isKindOfClass:[NSArray class]]) + ok = [streamWriter writeArray:object]; + + else if ([object respondsToSelector:@selector(proxyForJson)]) + return [self dataWithObject:[object proxyForJson]]; + else { + self.error = @"Not valid type for JSON"; + return nil; + } + + if (ok) + return accumulator.data; + + self.error = streamWriter.error; + return nil; } - - + + @end diff --git a/src/extThree20JSON/Vendors/YAJL/GHKit/GHNSBundle+Utils.h b/src/extThree20JSON/Vendors/YAJL/GHKit/GHNSBundle+Utils.h new file mode 100644 index 0000000000..6178c13d21 --- /dev/null +++ b/src/extThree20JSON/Vendors/YAJL/GHKit/GHNSBundle+Utils.h @@ -0,0 +1,32 @@ +// +// GHNSBundle+Utils.h +// GHKit +// +// Created by Gabriel Handford on 4/27/09. +// Copyright 2009. All rights reserved. +// + +@interface NSBundle (YAJL_GHUtils) + +/*! + Load data from resource. + @param resource Name of resource + @result NSData + */ +- (NSData *)yajl_gh_loadDataFromResource:(NSString *)resource; + +/*! + Load string data from resource. + @param resource Name of resource + @result NSString + */ +- (NSString *)yajl_gh_loadStringDataFromResource:(NSString *)resource; + +/*! + Get URL for resource. + @param resource Name of resource + @result URL to resource + */ +- (NSURL *)yajl_gh_URLForResource:(NSString *)resource; + +@end diff --git a/src/extThree20JSON/Vendors/YAJL/GHKit/GHNSBundle+Utils.m b/src/extThree20JSON/Vendors/YAJL/GHKit/GHNSBundle+Utils.m new file mode 100644 index 0000000000..cb79da4b9d --- /dev/null +++ b/src/extThree20JSON/Vendors/YAJL/GHKit/GHNSBundle+Utils.m @@ -0,0 +1,33 @@ +// +// GHNSBundle+Utils.m +// GHKit +// +// Created by Gabriel Handford on 4/27/09. +// Copyright 2009. All rights reserved. +// + +#import "extThree20JSON/private/GHNSBundle+Utils.h" + +@implementation NSBundle (YAJL_GHUtils) + +- (NSData *)yajl_gh_loadDataFromResource:(NSString *)resource { + NSParameterAssert(resource); + NSString *resourcePath = [self pathForResource:[resource stringByDeletingPathExtension] ofType:[resource pathExtension]]; + if (!resourcePath) [NSException raise:NSInvalidArgumentException format:@"Resource not found: %@", resource]; + NSError *error = nil; + NSData *data = [NSData dataWithContentsOfFile:resourcePath options:0 error:&error]; + if (error) [NSException raise:NSInvalidArgumentException format:@"Error loading resource at path (%@): %@", resourcePath, error]; + return data; +} + +- (NSString *)yajl_gh_loadStringDataFromResource:(NSString *)resource { + return [[[NSString alloc] initWithData:[self yajl_gh_loadDataFromResource:resource] encoding:NSUTF8StringEncoding] autorelease]; +} + +- (NSURL *)yajl_gh_URLForResource:(NSString *)resource { + NSParameterAssert(resource); + NSString *resourcePath = [self pathForResource:[resource stringByDeletingPathExtension] ofType:[resource pathExtension]]; + return resourcePath ? [NSURL fileURLWithPath:resourcePath] : nil; +} + +@end diff --git a/src/extThree20JSON/Vendors/YAJL/GTM/YAJL_GTMBase64.h b/src/extThree20JSON/Vendors/YAJL/GTM/GTMBase64.h similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/GTM/YAJL_GTMBase64.h rename to src/extThree20JSON/Vendors/YAJL/GTM/GTMBase64.h diff --git a/src/extThree20JSON/Vendors/YAJL/GTM/YAJL_GTMBase64.m b/src/extThree20JSON/Vendors/YAJL/GTM/GTMBase64.m similarity index 99% rename from src/extThree20JSON/Vendors/YAJL/GTM/YAJL_GTMBase64.m rename to src/extThree20JSON/Vendors/YAJL/GTM/GTMBase64.m index ef2bb2ae96..5b6db2187e 100644 --- a/src/extThree20JSON/Vendors/YAJL/GTM/YAJL_GTMBase64.m +++ b/src/extThree20JSON/Vendors/YAJL/GTM/GTMBase64.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -16,7 +16,7 @@ // the License. // -#import "YAJL_GTMBase64.h" +#import "extThree20JSON/private/GTMBase64.h" static const char *kBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char *kWebSafeBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; @@ -493,10 +493,10 @@ +(NSUInteger)baseEncode:(const char *)srcBytes if (!srcLen || !destLen || !srcBytes || !destBytes) { return 0; } - + char *curDest = destBytes; const unsigned char *curSrc = (const unsigned char *)(srcBytes); - + // Three bytes of data encodes to four characters of cyphertext. // So we can pump through three-byte chunks atomically. while (srcLen > 2) { @@ -506,13 +506,13 @@ +(NSUInteger)baseEncode:(const char *)srcBytes curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)]; curDest[2] = charset[((curSrc[1] & 0x0f) << 2) + (curSrc[2] >> 6)]; curDest[3] = charset[curSrc[2] & 0x3f]; - + curDest += 4; curSrc += 3; srcLen -= 3; destLen -= 4; } - + // now deal with the tail (<=2 bytes) switch (srcLen) { case 0: @@ -572,7 +572,7 @@ +(NSUInteger)baseDecode:(const char *)srcBytes if (!srcLen || !destLen || !srcBytes || !destBytes) { return 0; } - + int decode; NSUInteger destIndex = 0; int state = 0; @@ -580,14 +580,14 @@ +(NSUInteger)baseDecode:(const char *)srcBytes while (srcLen-- && (ch = *srcBytes++) != 0) { if (IsSpace(ch)) // Skip whitespace continue; - + if (ch == kBase64PaddingChar) break; - + decode = charset[(unsigned int)ch]; if (decode == kBase64InvalidChar) return 0; - + // Four cyphertext characters decode to three bytes. // Therefore we can be in one of four states. switch (state) { @@ -633,7 +633,7 @@ +(NSUInteger)baseDecode:(const char *)srcBytes break; } } - + // We are done decoding Base-64 chars. Let's see if we ended // on a byte boundary, and/or with erroneous trailing characters. if (ch == kBase64PaddingChar) { // We got a pad char @@ -664,7 +664,7 @@ +(NSUInteger)baseDecode:(const char *)srcBytes } } else { // We ended by seeing the end of the string. - + if (requirePadding) { // If we require padding, then anything but state 0 is an error. if (state != 0) { @@ -678,7 +678,7 @@ +(NSUInteger)baseDecode:(const char *)srcBytes } } } - + // If then next piece of output was valid and got written to it means we got a // very carefully crafted input that appeared valid but contains some trailing // bits past the real length, so just toss the thing. @@ -686,7 +686,7 @@ +(NSUInteger)baseDecode:(const char *)srcBytes (destBytes[destIndex] != 0)) { return 0; } - + return destIndex; } diff --git a/src/extThree20JSON/Vendors/YAJL/NSBundle+YAJL.h b/src/extThree20JSON/Vendors/YAJL/NSBundle+YAJL.h new file mode 100644 index 0000000000..43a42393ce --- /dev/null +++ b/src/extThree20JSON/Vendors/YAJL/NSBundle+YAJL.h @@ -0,0 +1,62 @@ +// +// NSBundle+YAJL.h +// YAJL +// +// Created by Gabriel Handford on 7/23/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "extThree20JSON/YAJLParser.h" + +/*! + Utilities for loading JSON from resource bundles. + + @code + id JSONValue = [[NSBundle mainBundle] yajl_JSONFromResource:@"kegs.json"]; + @endcode + */ +@interface NSBundle(YAJL) + +/*! + Load JSON from bundle. + @param resource Resource name with extension, for example, file.json + @throws YAJLParserException On parse error + */ +- (id)yajl_JSONFromResource:(NSString *)resource; + +/*! + Load JSON from bundle. + @param resource Resource name with extension, for example, file.json + @param options Parser options + - YAJLParserOptionsNone: No options + - YAJLParserOptionsAllowComments: Javascript style comments will be allowed in the input (both /&asterisk; &asterisk;/ and //) + - YAJLParserOptionsCheckUTF8: Invalid UTF8 strings will cause a parse error + - YAJLParserOptionsStrictPrecision: If YES will force strict precision and return integer overflow error + + @param error Out error + @result JSON value (NSArray, NSDictionary) or nil if errored + */ +- (id)yajl_JSONFromResource:(NSString *)resource options:(YAJLParserOptions)options error:(NSError **)error; + +@end diff --git a/src/extThree20JSON/Vendors/YAJL/NSBundle+YAJL.m b/src/extThree20JSON/Vendors/YAJL/NSBundle+YAJL.m new file mode 100644 index 0000000000..b1284d25f3 --- /dev/null +++ b/src/extThree20JSON/Vendors/YAJL/NSBundle+YAJL.m @@ -0,0 +1,52 @@ +// +// NSBundle+YAJL.m +// YAJL +// +// Created by Gabriel Handford on 7/23/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "extThree20JSON/NSBundle+YAJL.h" +#import "extThree20JSON/NSObject+YAJL.h" +#import "extThree20JSON/private/GHNSBundle+Utils.h" + +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + +TT_FIX_CATEGORY_BUG(NSBundle_YAJL) + +@implementation NSBundle(YAJL) + +- (id)yajl_JSONFromResource:(NSString *)resource { + NSError *error = nil; + id JSONValue = [self yajl_JSONFromResource:resource options:YAJLParserOptionsNone error:&error]; + if (error) [NSException raise:YAJLParserException format:[error localizedDescription], nil]; + return JSONValue; +} + +- (id)yajl_JSONFromResource:(NSString *)resource options:(YAJLParserOptions)options error:(NSError **)error { + return [[self yajl_gh_loadStringDataFromResource:resource] yajl_JSONWithOptions:YAJLParserOptionsAllowComments error:error]; +} + +@end diff --git a/src/extThree20JSON/Vendors/YAJL/NSObject+YAJL.h b/src/extThree20JSON/Vendors/YAJL/NSObject+YAJL.h index 9e29136a68..8e58c8653e 100644 --- a/src/extThree20JSON/Vendors/YAJL/NSObject+YAJL.h +++ b/src/extThree20JSON/Vendors/YAJL/NSObject+YAJL.h @@ -27,10 +27,36 @@ // OTHER DEALINGS IN THE SOFTWARE. // -#import "YAJLGen.h" -#import "YAJLParser.h" +#import "extThree20JSON/YAJLGen.h" +#import "extThree20JSON/YAJLParser.h" -@interface NSObject (YAJL) +/*! + Generate JSON string from NSArray, NSDictionary or custom object or parse JSON from NSString or custom object. + + Parse JSON: + @code + NSData *JSONData = [NSData dataWithContentsOfFile:@"example.json"]; + NSArray *arrayFromData = [JSONData yajl_JSON]; + + NSString *JSONString = @"[\"Test\"]"; + NSArray *arrayFromString = [JSONString yajl_JSON]; + + // With options and out error + NSError *error = nil; + NSArray *arrayFromString = [JSONString yajl_JSONWithOptions:YAJLParserOptionsAllowComments error:&error]; + @endcode + + Generate JSON: + @code + NSDictionary *dict = [NSDictionary dictionaryWithObject:@"value" forKey:@"key"]; + NSString *JSONString = [dict yajl_JSONString]; + + // Beautified with custon indent string + NSArray *array = [NSArray arrayWithObjects:@"value1", @"value2", nil]; + NSString *JSONString = [dict yajl_JSONStringWithOptions:YAJLGenOptionsBeautify indentString:@" "]; + @endcode + */ +@interface NSObject(YAJL) #pragma mark Gen @@ -38,7 +64,7 @@ Create JSON string from object. Supported objects include: NSArray, NSDictionary, NSNumber, NSString, NSNull To override JSON value to encode (or support custom objects), implement (id)JSON; See YAJLCoding in YAJLGen.h - Otherwise throws YAJLGenInvalidObjectException. + @throws YAJLGenInvalidObjectException If object is invalid @result JSON String */ - (NSString *)yajl_JSONString; @@ -47,8 +73,13 @@ Create JSON string from object. Supported objects include: NSArray, NSDictionary, NSNumber, NSString, NSNull To override JSON value to encode (or support custom objects), implement (id)JSON; See YAJLCoding in YAJLGen.h - Otherwise throws YAJLGenInvalidObjectException. + @throws YAJLGenInvalidObjectException If object is invalid @param options + - YAJLGenOptionsNone: No options + - YAJLGenOptionsBeautify: Beautifiy JSON output + - YAJLGenOptionsIgnoreUnknownTypes: Ignore unknown types (will use null value) + - YAJLGenOptionsIncludeUnsupportedTypes: Handle non-JSON types (including NSDate, NSData, NSURL) + @param indentString @result JSON String */ @@ -62,11 +93,11 @@ @result JSON object @throws YAJLParserException If a parse error occured @throws YAJLParsingUnsupportedException If not NSData or doesn't respond to dataUsingEncoding: - + @code NSString *JSONString = @"{'foo':['bar', true]}"; id JSONValue = [JSONString yajl_JSON]; - + NSData *JSONData = ...; id JSONValue = [JSONData yajl_JSON]; @endcode @@ -75,7 +106,7 @@ /*! Parse JSON (NSString or NSData or dataUsingEncoding:) with out error. - + If an error occurs, the returned object will be the current state of the object when the error occurred. @@ -83,7 +114,7 @@ @result JSON object @throws YAJLParserException If a parse error occured @throws YAJLParsingUnsupportedException If not NSData or doesn't respond to dataUsingEncoding: - + @code NSString *JSONString = @"{'foo':['bar', true]}"; NSError *error = nil; @@ -95,16 +126,21 @@ /*! Parse JSON (NSString or NSData or dataUsingEncoding:) with options and out error. - + If an error occurs, the returned object will be the current state of the object when the error occurred. - - @param options Options (see YAJLParserOptions) + + @param options Parse options + - YAJLParserOptionsNone: No options + - YAJLParserOptionsAllowComments: Javascript style comments will be allowed in the input (both /&asterisk; &asterisk;/ and //) + - YAJLParserOptionsCheckUTF8: Invalid UTF8 strings will cause a parse error + - YAJLParserOptionsStrictPrecision: If YES will force strict precision and return integer overflow error + @param error Error to set if we failed to parse @result JSON object @throws YAJLParserException If a parse error occured @throws YAJLParsingUnsupportedException If not NSData or doesn't respond to dataUsingEncoding: - + @code NSString *JSONString = @"{'foo':['bar', true]} // comment"; NSError *error = nil; diff --git a/src/extThree20JSON/Vendors/YAJL/NSObject+YAJL.m b/src/extThree20JSON/Vendors/YAJL/NSObject+YAJL.m index e003bf305b..8a02faab95 100644 --- a/src/extThree20JSON/Vendors/YAJL/NSObject+YAJL.m +++ b/src/extThree20JSON/Vendors/YAJL/NSObject+YAJL.m @@ -27,11 +27,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // -#import "NSObject+YAJL.h" -#import "YAJLGen.h" -#import "YAJLDocument.h" +#import "extThree20JSON/NSObject+YAJL.h" +#import "extThree20JSON/YAJLGen.h" +#import "extThree20JSON/YAJLDocument.h" -@implementation NSObject (YAJL) +// Core +#import "Three20Core/TTCorePreprocessorMacros.h" + +TT_FIX_CATEGORY_BUG(NSObject_YAJL) + +@implementation NSObject(YAJL) #pragma mark Gen @@ -52,7 +57,7 @@ - (NSString *)yajl_JSONStringWithOptions:(YAJLGenOptions)options indentString:(N - (id)yajl_JSON { NSError *error = nil; id JSON = [self yajl_JSON:&error]; - if (error) [NSException raise:YAJLParserException format:[error localizedDescription]]; + if (error) [NSException raise:YAJLParserException format:[error localizedDescription], nil]; return JSON; } @@ -61,7 +66,7 @@ - (id)yajl_JSON:(NSError **)error { } - (id)yajl_JSONWithOptions:(YAJLParserOptions)options error:(NSError **)error { - NSData *data = nil; + NSData *data = nil; if ([self isKindOfClass:[NSData class]]) { data = (NSData *)self; } else if ([self respondsToSelector:@selector(dataUsingEncoding:)]) { @@ -69,12 +74,11 @@ - (id)yajl_JSONWithOptions:(YAJLParserOptions)options error:(NSError **)error { } else { [NSException raise:YAJLParsingUnsupportedException format:@"Object of type (%@) must implement dataUsingEncoding: to be parsed", [self class]]; } - + YAJLDocument *document = [[YAJLDocument alloc] initWithData:data parserOptions:options error:error]; id root = [document.root retain]; [document release]; return [root autorelease]; } - @end diff --git a/src/extThree20JSON/Vendors/YAJL/README.md b/src/extThree20JSON/Vendors/YAJL/README.md index 75490041e6..8b6af7e147 100644 --- a/src/extThree20JSON/Vendors/YAJL/README.md +++ b/src/extThree20JSON/Vendors/YAJL/README.md @@ -1,28 +1,23 @@ -# YAJL (Objective-C Wrapper) +# YAJL Framework -YAJL.framework is an Objective-C wrapper around the [YAJL](http://lloyd.github.com/yajl/) SAX-style JSON parser. +The YAJL framework is an Objective-C framework for the [YAJL](http://lloyd.github.com/yajl/) SAX-style JSON parser. -## Download +## Features -### Mac OS X +- Stream parsing, comments in JSON, better error messages. +- Parse directly from NSString or NSData. +- Generate JSON from default or custom types. +- Properly handles large numeric types. +- Document style parser. +- Error by exception or out error. -[YAJL-0.2.16.zip](http://rel.me.s3.amazonaws.com/yajl/YAJL-0.2.16.zip) *YAJL.framework* (2010/03/01) +## Links -### iPhone - -[libYAJLIPhone-0.2.17.zip](http://rel.me.s3.amazonaws.com/yajl/libYAJLIPhone-0.2.17.zip) *Static Library for iPhone OS 3.0 Simulator & Device* (2010/04/15) +- The online [API documentation](http://gabriel.github.com/yajl-objc/). ## Install (Mac OS X) -There are two options. You can install it globally in /Library/Frameworks or with a little extra effort embed it with your project. - -### Installing in /Library/Frameworks - -- Copy `YAJL.framework` to `/Library/Frameworks/` -- In the target Info window, General tab: - - Add a linked library, under `Mac OS X 10.5 SDK` section, select `YAJL.framework` - -### Installing in your project +### Installing in your project (Recommended) - Copy `YAJL.framework` to your project directory (maybe in MyProject/Frameworks/.) - Add the `YAJL.framekwork` files (from MyProject/Frameworks/) to your target. It should be visible as a `Linked Framework` in the target. @@ -32,138 +27,39 @@ There are two options. You can install it globally in /Library/Frameworks or wit - Drag `YAJL.framework` into the the build phase - Make sure the copy phase appears before any `Run Script` phases -## Install (iPhone) - -- Add files (from static library build) to project. -- Under 'Other Linker Flags' in the Test target, add `-ObjC` and `-all_load` (So NSObject+YAJL category is loaded). - -## Usage - -To parse JSON from an NSData (or NSString): - - #import "NSObject+YAJL.h" - - NSData *JSONData = [NSData dataWithContentsOfFile:@"example.json"]; - NSArray *arrayFromData = [JSONData yajl_JSON]; - - NSString *JSONString = @"[\"Test\"]"; - NSArray *arrayFromString = [JSONString yajl_JSON]; - - // With options and out error - NSError *error = nil; - NSArray *arrayFromString = [JSONString yajl_JSONWithOptions:YAJLParserOptionsAllowComments error:&error]; - -To generate JSON from an object: - - #import "NSObject+YAJL.h" - - NSDictionary *dict = [NSDictionary dictionaryWithObject:@"value" forKey:@"key"]; - NSString *JSONString = [dict yajl_JSONString]; - - // Beautified with custon indent string - NSArray *array = [NSArray arrayWithObjects:@"value1", @"value2", nil]; - NSString *JSONString = [dict yajl_JSONStringWithOptions:YAJLGenOptionsBeautify indentString:@" "]; - -To use the streaming (or SAX style) parser, use `YAJLParser`. For higher level (document) streaming, see below. - - NSData *data = [NSData dataWithContentsOfFile:@"example.json"]; - - YAJLParser *parser = [[YAJLParser alloc] initWithParserOptions:YAJLParserOptionsAllowComments]; - parser.delegate = self; - [parser parse:data]; - if (parser.parserError) { - NSLog(@"Error:\n%@", parser.parserError); - } - - parser.delegate = nil; - [parser release]; - - // Include delegate methods from YAJLParserDelegate - /* - - (void)parserDidStartDictionary:(YAJLParser *)parser; - - (void)parserDidEndDictionary:(YAJLParser *)parser; - - - (void)parserDidStartArray:(YAJLParser *)parser; - - (void)parserDidEndArray:(YAJLParser *)parser; - - - (void)parser:(YAJLParser *)parser didMapKey:(NSString *)key; - - (void)parser:(YAJLParser *)parser didAdd:(id)value; - */ - -### Parser Options - -There are options when parsing that can be specified with `YAJLParser#initWithParserOptions:`. - -- `YAJLParserOptionsAllowComments`: Allows comments in JSON -- `YAJLParserOptionsCheckUTF8`: Will verify UTF-8 -- `YAJLParserOptionsStrictPrecision`: Will force strict precision and return integer overflow error, if number is greater than long long. - -### Streaming Example (Parser) - - YAJLParser *parser = [[[YAJLParser alloc] init] autorelease]; - parser.delegate = self; - - // A chunk of data comes... - YAJLParserStatus status = [parser parse:chunk1]; - // 'status' should be YAJLParserStatusInsufficientData, if its not finished - if (parser.parserError) ...; - - // Another chunk of data comes... - YAJLParserStatus status = [parser parse:chunk2]; - // 'status' should be YAJLParserStatusOK if its finished - if (parser.parserError) ...; - -## Usage (Document-style) - -To use the document style, use `YAJLDocument`. Usage should be very similar to `NSXMLDocument`. - - NSData *data = [NSData dataWithContentsOfFile:@"example.json"]; - NSError *error = nil; - YAJLDocument *document = [[YAJLDocument alloc] initWithData:data parserOptions:0 error:&error]; - // Access root element at document.root - NSLog(@"Root: %@", document.root); - [document release]; - -### Streaming Example (Document) - - YAJLDocument *document = [[YAJLDocument alloc] init]; - document.delegate = self; - - NSError *error = nil; - [document parse:chunk1 error:error]; - [document parse:chunk2 error:error]; - - // You can access root element at document.root - NSLog(@"Root: %@", document.root); - [document release]; - - // Or via the YAJLDocumentDelegate delegate methods - - - (void)document:(YAJLDocument *)document didAddDictionary:(NSDictionary *)dict { } - - (void)document:(YAJLDocument *)document didAddArray:(NSArray *)array { } - - (void)document:(YAJLDocument *)document didAddObject:(id)object toArray:(NSArray *)array { } - - (void)document:(YAJLDocument *)document didSetObject:(id)object forKey:(id)key inDictionary:(NSDictionary *)dict { } - -## Customized Encoding - -To implement JSON encodable value for custom objects or override for existing objects, implement `- (id)JSON;` - -For example: - - @interface CustomObject : NSObject - @end - - @implementation CustomObject - - - (id)JSON { - return [NSArray arrayWithObject:[NSNumber numberWithInteger:1]]; - } - - @end - -Then: - - CustomObject *customObject = [[CustomObject alloc] init]; - NSString *JSONString = [customObject yajl_JSON]; - // JSONString == "[1]"; +### Installing in /Library/Frameworks + +- Copy `YAJL.framework` to `/Library/Frameworks/` +- In the target Info window, General tab: + - Add a linked library, under `Mac OS X 10.5 SDK` section, select `YAJL.framework` + +## Install (iOS) + +- Add `YAJLiOS.framework` to your project. +- Add the frameworks to `Linked Libraries`: + - `YAJLiOS.framework` + - `CoreGraphics.framework` + - `Foundation.framework` + - `UIKit.framework` +- Under `Framework Search Paths` make sure the (parent) directory to `YAJLiOS.framework` is listed. +- Under `Other Linker Flags` in your target, add `-ObjC` and `-all_load` + +## Apps + +YAJL framework is used by: + +- [Yelp for iPhone/iPad](http://itunes.apple.com/us/app/yelp/id284910350?mt=8) +- Add your app here! + +## Docset + +Download and copy the YAJL.docset to `~/Library/Developer/Shared/Documentation/DocSets/YAJL.docset` + +(You may need to restart XCode after copying the file.) + +The documentation will appear within XCode: + +![YAJL-Docset](http://rel.me.s3.amazonaws.com/yajl/images/docset.png) + + diff --git a/src/extThree20JSON/Vendors/YAJL/YAJL.h b/src/extThree20JSON/Vendors/YAJL/YAJL.h index 42a7bfad59..a4a8301940 100644 --- a/src/extThree20JSON/Vendors/YAJL/YAJL.h +++ b/src/extThree20JSON/Vendors/YAJL/YAJL.h @@ -27,7 +27,187 @@ // OTHER DEALINGS IN THE SOFTWARE. // -#import "YAJLParser.h" -#import "YAJLDocument.h" -#import "YAJLGen.h" -#import "NSObject+YAJL.h" +#import "extThree20JSON/YAJLParser.h" +#import "extThree20JSON/YAJLDocument.h" +#import "extThree20JSON/YAJLGen.h" +#import "extThree20JSON/NSObject+YAJL.h" +#import "extThree20JSON/NSBundle+YAJL.h" + +/*! + YAJL + + The YAJL framework is an Objective-C wrapper around the http://lloyd.github.com/yajl/ SAX-style JSON parser. + + @section Links + + Source: http://github.com/gabriel/yajl-objc + + View docs online: http://gabriel.github.com/yajl-objc/ + + YAJL C docs: http://lloyd.github.com/yajl/ + + @section Usage Usage + + To use the framework (for Mac OS X or iOS): + + @code + // For Mac OS X + #import + // For iOS + #import + @endcode + + @section Examples Examples + + @subsection Example1 To parse JSON from NSData + + @code + NSData *JSONData = [NSData dataWithContentsOfFile:@"example.json"]; + NSArray *arrayFromData = [JSONData yajl_JSON]; + @endcode + + @subsection Example2 To parse JSON from NSString + + @code + NSString *JSONString = @"[1, 2, 3]"; + NSArray *arrayFromString = [JSONString yajl_JSON]; + @endcode + + @subsection Example2_1 To parse JSON from NSString with error and comments + + @code + // With options and out error + NSString *JSONString = @"[1, 2, 3] // Allow comments"; + NSError *error = nil; + NSArray *arrayFromString = [JSONString yajl_JSONWithOptions:YAJLParserOptionsAllowComments error:&error]; + @endcode + + @subsection Example3 To generate JSON from an object, NSArray, NSDictionary, etc. + + @code + NSDictionary *dict = [NSDictionary dictionaryWithObject:@"value" forKey:@"key"]; + NSString *JSONString = [dict yajl_JSONString]; + // ==> {"key":"value"} + @endcode + + @subsection Example4 To generate JSON from an object, beautified with custom indent + + @code + // Beautified with custon indent string + NSArray *array = [NSArray arrayWithObjects:@"value1", @"value2", nil]; + NSString *JSONString = [dict yajl_JSONStringWithOptions:YAJLGenOptionsBeautify indentString:@" "]; + @endcode + + @subsection Example5 To use the streaming (or SAX style) parser, use YAJLParser + + @code + NSData *data = [NSData dataWithContentsOfFile:@"example.json"]; + + YAJLParser *parser = [[YAJLParser alloc] initWithParserOptions:YAJLParserOptionsAllowComments]; + parser.delegate = self; + [parser parse:data]; + if (parser.parserError) + NSLog(@"Error:\n%@", parser.parserError); + + parser.delegate = nil; + [parser release]; + + // Include delegate methods from YAJLParserDelegate + - (void)parserDidStartDictionary:(YAJLParser *)parser { } + - (void)parserDidEndDictionary:(YAJLParser *)parser { } + + - (void)parserDidStartArray:(YAJLParser *)parser { } + - (void)parserDidEndArray:(YAJLParser *)parser { } + + - (void)parser:(YAJLParser *)parser didMapKey:(NSString *)key { } + - (void)parser:(YAJLParser *)parser didAdd:(id)value { } + @endcode + + @subsection ParserOptions Parser Options + + There are options when parsing that can be specified with YAJLParser#initWithParserOptions:. + + - YAJLParserOptionsAllowComments: Allows comments in JSON + - YAJLParserOptionsCheckUTF8: Will verify UTF-8 + - YAJLParserOptionsStrictPrecision: Will force strict precision and return integer overflow error, if number is greater than long long. + + @subsection Example6 Parsing as data becomes available + + @code + YAJLParser *parser = [[[YAJLParser alloc] init] autorelease]; + parser.delegate = self; + + // A chunk of data comes... + YAJLParserStatus status = [parser parse:chunk1]; + // 'status' should be YAJLParserStatusInsufficientData, if its not finished + if (parser.parserError) + NSLog(@"Error:\n%@", parser.parserError); + + // Another chunk of data comes... + YAJLParserStatus status = [parser parse:chunk2]; + // 'status' should be YAJLParserStatusOK if its finished + if (parser.parserError) + NSLog(@"Error:\n%@", parser.parserError); + @endcode + + @subsection Example7 Document style parsing + + To use the document style, use YAJLDocument. Usage should be very similar to NSXMLDocument. + + @code + NSData *data = [NSData dataWithContentsOfFile:@"example.json"]; + NSError *error = nil; + YAJLDocument *document = [[YAJLDocument alloc] initWithData:data parserOptions:YAJLParserOptionsNone error:&error]; + // Access root element at document.root + NSLog(@"Root: %@", document.root); + [document release]; + @endcode + + @subsection Example8 Document style parsing as data becomes available + + @code + YAJLDocument *document = [[YAJLDocument alloc] init]; + document.delegate = self; + + NSError *error = nil; + [document parse:chunk1 error:error]; + [document parse:chunk2 error:error]; + + // You can access root element at document.root + NSLog(@"Root: %@", document.root); + [document release]; + + // Or via the YAJLDocumentDelegate delegate methods + + - (void)document:(YAJLDocument *)document didAddDictionary:(NSDictionary *)dict { } + - (void)document:(YAJLDocument *)document didAddArray:(NSArray *)array { } + - (void)document:(YAJLDocument *)document didAddObject:(id)object toArray:(NSArray *)array { } + - (void)document:(YAJLDocument *)document didSetObject:(id)object forKey:(id)key inDictionary:(NSDictionary *)dict { } + @endcode + + @subsection Example9 Load JSON from Bundle + + @code + id JSONValue = [[NSBundle mainBundle] yajl_JSONFromResource:@"kegs.json"]; + @endcode + + @section CustomizedEncoding Customized Encoding + + To implement JSON encodable value for custom objects or override for existing objects, implement - (id)JSON; + + For example: + + @code + @interface CustomObject : NSObject + @end + + @implementation CustomObject + + - (id)JSON { + return [NSArray arrayWithObject:[NSNumber numberWithInteger:1]]; + } + + @end + @endcode + + */ diff --git a/src/extThree20JSON/Vendors/YAJL/YAJLDocument.h b/src/extThree20JSON/Vendors/YAJL/YAJLDocument.h index 475b6d6499..8eee07c7c7 100644 --- a/src/extThree20JSON/Vendors/YAJL/YAJLDocument.h +++ b/src/extThree20JSON/Vendors/YAJL/YAJLDocument.h @@ -28,7 +28,7 @@ // -#include "YAJLParser.h" +#include "extThree20JSON/YAJLParser.h" typedef enum { YAJLDecoderCurrentTypeNone, @@ -40,57 +40,156 @@ extern NSInteger YAJLDocumentStackCapacity; @class YAJLDocument; +/*! + YAJLDocument delegate notified when objects are added. + */ @protocol YAJLDocumentDelegate @optional +/*! + Did add dictionary. + @param document Sender + @param dict Dictionary that was added + */ - (void)document:(YAJLDocument *)document didAddDictionary:(NSDictionary *)dict; + +/*! + Did add array. + @param document Sender + @param array Array that was added + */ - (void)document:(YAJLDocument *)document didAddArray:(NSArray *)array; + +/*! + Did add object to array. + @param document Sender + @param object Object added + @param array Array objct was added to + */ - (void)document:(YAJLDocument *)document didAddObject:(id)object toArray:(NSArray *)array; + +/*! + Did set object for key on dictionary. + @param document Sender + @param object Object that was set + @param key Key + @param dict Dictionary object was set for key on + */ - (void)document:(YAJLDocument *)document didSetObject:(id)object forKey:(id)key inDictionary:(NSDictionary *)dict; @end +/*! + JSON document interface. + + @code + NSData *data = [NSData dataWithContentsOfFile:@"example.json"]; + NSError *error = nil; + YAJLDocument *document = [[YAJLDocument alloc] initWithData:data parserOptions:YAJLParserOptionsNone error:&error]; + // Access root element at document.root + NSLog(@"Root: %@", document.root); + [document release]; + @endcode + + Example for streaming: + @code + YAJLDocument *document = [[YAJLDocument alloc] init]; + document.delegate = self; + + NSError *error = nil; + [document parse:chunk1 error:error]; + [document parse:chunk2 error:error]; + + // You can access root element at document.root + NSLog(@"Root: %@", document.root); + [document release]; + + // Or via the YAJLDocumentDelegate delegate methods + + - (void)document:(YAJLDocument *)document didAddDictionary:(NSDictionary *)dict { } + - (void)document:(YAJLDocument *)document didAddArray:(NSArray *)array { } + - (void)document:(YAJLDocument *)document didAddObject:(id)object toArray:(NSArray *)array { } + - (void)document:(YAJLDocument *)document didSetObject:(id)object forKey:(id)key inDictionary:(NSDictionary *)dict { } + @endcode + */ @interface YAJLDocument : NSObject { - + id root_; // NSArray or NSDictionary YAJLParser *parser_; - - __weak id delegate_; - - __weak NSMutableDictionary *dict_; // weak; if map in progress, points to the current map + + // TODO(gabe): This should be __weak + id delegate_; + + __weak NSMutableDictionary *dict_; // weak; if map in progress, points to the current map __weak NSMutableArray *array_; // weak; If array in progress, points the current array __weak NSString *key_; // weak; If map in progress, points to current key - + NSMutableArray *stack_; NSMutableArray *keyStack_; - + YAJLDecoderCurrentType currentType_; - + YAJLParserStatus parserStatus_; - + } -@property (readonly, nonatomic) id root; //! Root element -@property (readonly, nonatomic) YAJLParserStatus parserStatus; -@property (assign, nonatomic) id delegate; +@property (readonly, nonatomic) id root; //! The root element of the document, either NSArray or NSDictionary +@property (readonly, nonatomic) YAJLParserStatus parserStatus; //! The current status of parsing +@property (assign, nonatomic) id delegate; //! Delegate /*! Create document from data. @param data Data to parse @param parserOptions Parse options + - YAJLParserOptionsNone: No options + - YAJLParserOptionsAllowComments: Javascript style comments will be allowed in the input (both /&asterisk; &asterisk;/ and //) + - YAJLParserOptionsCheckUTF8: Invalid UTF8 strings will cause a parse error + - YAJLParserOptionsStrictPrecision: If YES will force strict precision and return integer overflow error @param error Error to set on failure */ - (id)initWithData:(NSData *)data parserOptions:(YAJLParserOptions)parserOptions error:(NSError **)error; +/*! + Create document from data. + @param data Data to parse + @param parserOptions Parse options + - YAJLParserOptionsNone: No options + - YAJLParserOptionsAllowComments: Javascript style comments will be allowed in the input (both /&asterisk; &asterisk;/ and //) + - YAJLParserOptionsCheckUTF8: Invalid UTF8 strings will cause a parse error + - YAJLParserOptionsStrictPrecision: If YES will force strict precision and return integer overflow error + @param capacity Initial capacity for NSArray and NSDictionary objects (Defaults to 20) + @param error Error to set on failure + */ +- (id)initWithData:(NSData *)data parserOptions:(YAJLParserOptions)parserOptions capacity:(NSInteger)capacity error:(NSError **)error; + /*! Create empty document with parser options. @param parserOptions Parse options + - YAJLParserOptionsNone: No options + - YAJLParserOptionsAllowComments: Javascript style comments will be allowed in the input (both /&asterisk; &asterisk;/ and //) + - YAJLParserOptionsCheckUTF8: Invalid UTF8 strings will cause a parse error + - YAJLParserOptionsStrictPrecision: If YES will force strict precision and return integer overflow error */ - (id)initWithParserOptions:(YAJLParserOptions)parserOptions; +/*! + Create empty document with parser options. + @param parserOptions Parse options + - YAJLParserOptionsNone: No options + - YAJLParserOptionsAllowComments: Javascript style comments will be allowed in the input (both /&asterisk; &asterisk;/ and //) + - YAJLParserOptionsCheckUTF8: Invalid UTF8 strings will cause a parse error + - YAJLParserOptionsStrictPrecision: If YES will force strict precision and return integer overflow error + @param capacity Initial capacity for NSArray and NSDictionary objects (Defaults to 20) + */ +- (id)initWithParserOptions:(YAJLParserOptions)parserOptions capacity:(NSInteger)capacity; + /*! Parse data. @param data Data to parse - @param error Error to set on failure + @param error Out error to set on failure @result Parser status + - YAJLParserStatusNone: No status + - YAJLParserStatusOK: Parsed OK + - YAJLParserStatusInsufficientData: There was insufficient data + - YAJLParserStatusError: Parser errored */ - (YAJLParserStatus)parse:(NSData *)data error:(NSError **)error; diff --git a/src/extThree20JSON/Vendors/YAJL/YAJLDocument.m b/src/extThree20JSON/Vendors/YAJL/YAJLDocument.m index 3a4fefe1e1..0b07feb8e7 100644 --- a/src/extThree20JSON/Vendors/YAJL/YAJLDocument.m +++ b/src/extThree20JSON/Vendors/YAJL/YAJLDocument.m @@ -28,7 +28,7 @@ // -#import "YAJLDocument.h" +#import "extThree20JSON/YAJLDocument.h" @interface YAJLDocument () - (void)_pop; @@ -46,9 +46,13 @@ - (id)init { } - (id)initWithParserOptions:(YAJLParserOptions)parserOptions { + return [self initWithParserOptions:parserOptions capacity:YAJLDocumentStackCapacity]; +} + +- (id)initWithParserOptions:(YAJLParserOptions)parserOptions capacity:(NSInteger)capacity { if ((self = [super init])) { stack_ = [[NSMutableArray alloc] initWithCapacity:YAJLDocumentStackCapacity]; - keyStack_ = [[NSMutableArray alloc] initWithCapacity:YAJLDocumentStackCapacity]; + keyStack_ = [[NSMutableArray alloc] initWithCapacity:YAJLDocumentStackCapacity]; parserStatus_ = YAJLParserStatusNone; parser_ = [[YAJLParser alloc] initWithParserOptions:parserOptions]; parser_.delegate = self; @@ -57,7 +61,11 @@ - (id)initWithParserOptions:(YAJLParserOptions)parserOptions { } - (id)initWithData:(NSData *)data parserOptions:(YAJLParserOptions)parserOptions error:(NSError **)error { - if ((self = [self initWithParserOptions:parserOptions])) { + return [self initWithData:data parserOptions:parserOptions capacity:YAJLDocumentStackCapacity error:error]; +} + +- (id)initWithData:(NSData *)data parserOptions:(YAJLParserOptions)parserOptions capacity:(NSInteger)capacity error:(NSError **)error { + if ((self = [self initWithParserOptions:parserOptions capacity:capacity])) { [self parse:data error:error]; } return self; @@ -67,7 +75,7 @@ - (void)dealloc { [stack_ release]; [keyStack_ release]; parser_.delegate = nil; - [parser_ release]; + [parser_ release]; [root_ release]; [super dealloc]; } @@ -94,7 +102,7 @@ - (void)parser:(YAJLParser *)parser didAdd:(id)value { [delegate_ document:self didSetObject:value forKey:key_ inDictionary:dict_]; [self _popKey]; break; - } + } } - (void)parser:(YAJLParser *)parser didMapKey:(NSString *)key { @@ -104,9 +112,9 @@ - (void)parser:(YAJLParser *)parser didMapKey:(NSString *)key { - (void)_popKey { key_ = nil; - [keyStack_ removeLastObject]; // Pop - if ([keyStack_ count] > 0) - key_ = [keyStack_ objectAtIndex:[keyStack_ count]-1]; + [keyStack_ removeLastObject]; // Pop + if ([keyStack_ count] > 0) + key_ = [keyStack_ objectAtIndex:[keyStack_ count]-1]; } - (void)parserDidStartDictionary:(YAJLParser *)parser { @@ -115,7 +123,7 @@ - (void)parserDidStartDictionary:(YAJLParser *)parser { [stack_ addObject:dict]; // Push [dict release]; dict_ = dict; - currentType_ = YAJLDecoderCurrentTypeDict; + currentType_ = YAJLDecoderCurrentTypeDict; } - (void)parserDidEndDictionary:(YAJLParser *)parser { @@ -140,7 +148,7 @@ - (void)parserDidStartArray:(YAJLParser *)parser { - (void)parserDidEndArray:(YAJLParser *)parser { id value = [[stack_ objectAtIndex:[stack_ count]-1] retain]; NSArray *array = array_; - [self _pop]; + [self _pop]; [self parser:parser didAdd:value]; [value release]; if ([delegate_ respondsToSelector:@selector(document:didAddArray:)]) @@ -155,10 +163,10 @@ - (void)_pop { id value = nil; if ([stack_ count] > 0) value = [stack_ objectAtIndex:[stack_ count]-1]; - if ([value isKindOfClass:[NSArray class]]) { + if ([value isKindOfClass:[NSArray class]]) { array_ = (NSMutableArray *)value; currentType_ = YAJLDecoderCurrentTypeArray; - } else if ([value isKindOfClass:[NSDictionary class]]) { + } else if ([value isKindOfClass:[NSDictionary class]]) { dict_ = (NSMutableDictionary *)value; currentType_ = YAJLDecoderCurrentTypeDict; } diff --git a/src/extThree20JSON/Vendors/YAJL/YAJLGen.h b/src/extThree20JSON/Vendors/YAJL/YAJLGen.h index d862d41414..1fa5ec1e50 100644 --- a/src/extThree20JSON/Vendors/YAJL/YAJLGen.h +++ b/src/extThree20JSON/Vendors/YAJL/YAJLGen.h @@ -27,19 +27,17 @@ // OTHER DEALINGS IN THE SOFTWARE. // -#include "yajl_gen.h" +#include "extThree20JSON/yajl_gen.h" -extern NSString *const YAJLGenInvalidObjectException; -/*! - @enum Generate options - @constant YAJLGenOptionsBeautify - */ -enum { - YAJLGenOptionsNone = 0, - YAJLGenOptionsBeautify = 1 << 0, - YAJLGenOptionsIgnoreUnknownTypes = 1 << 1, // Ignore unknown types (will use null value) - YAJLGenOptionsIncludeUnsupportedTypes = 1 << 2, // Handle non-JSON types (including NSDate, NSData, NSURL) +extern NSString *const YAJLGenInvalidObjectException; //! Exception type if we encounter invalid object + +//! JSON generate options +enum YAJLGenOptions { + YAJLGenOptionsNone = 0, //!< No options + YAJLGenOptionsBeautify = 1 << 0, //!< Beautifiy JSON output + YAJLGenOptionsIgnoreUnknownTypes = 1 << 1, //!< Ignore unknown types (will use null value) + YAJLGenOptionsIncludeUnsupportedTypes = 1 << 2, //!< Handle non-JSON types (including NSDate, NSData, NSURL) }; typedef NSUInteger YAJLGenOptions; @@ -51,40 +49,88 @@ typedef NSUInteger YAJLGenOptions; - NSString - NSNumber - NSNull - + We also support the following types (if using YAJLGenOptionsIncludeUnsupportedTypes option), by converting to JSON supported types: - - NSDate -> number representing number of milliseconds since (1970) epoch - - NSData -> Base64 encoded string - - NSURL -> URL (absolute) string + - NSDate: number representing number of milliseconds since (1970) epoch + - NSData: Base64 encoded string + - NSURL: URL (absolute) string */ @interface YAJLGen : NSObject { yajl_gen gen_; - + YAJLGenOptions genOptions_; } +/*! + JSON generator with options. + @param genOptions Generate options + - YAJLGenOptionsNone: No options + - YAJLGenOptionsBeautify: Beautifiy JSON output + - YAJLGenOptionsIgnoreUnknownTypes: Ignore unknown types (will use null value) + - YAJLGenOptionsIncludeUnsupportedTypes: Handle non-JSON types (including NSDate, NSData, NSURL) + + @param indentString String for indentation + */ - (id)initWithGenOptions:(YAJLGenOptions)genOptions indentString:(NSString *)indentString; +/*! + Write JSON for object to buffer. + @param obj Supported or custom object + */ - (void)object:(id)obj; +/*! + Write null value to buffer. + */ - (void)null; +/*! + Write bool value to buffer. + @param b Output true or false + */ - (void)bool:(BOOL)b; +/*! + Write numeric value to buffer. + @param number Numeric value + */ - (void)number:(NSNumber *)number; +/*! + Write string value to buffer. + @param s String value + */ - (void)string:(NSString *)s; +/*! + Write dictionary start ('{') to buffer. + */ - (void)startDictionary; + +/*! + Write dictionary end ('}') to buffer. + */ - (void)endDictionary; +/*! + Write array start ('[') to buffer. + */ - (void)startArray; +/*! + Write array end (']') to buffer. + */ - (void)endArray; +/*! + Clear JSON buffer. + */ - (void)clear; +/*! + Get current JSON buffer. + */ - (NSString *)buffer; @end @@ -92,6 +138,27 @@ typedef NSUInteger YAJLGenOptions; /*! Custom objects can support manual JSON encoding. + + @code + @interface CustomObject : NSObject + @end + + @implementation CustomObject + + - (id)JSON { + return [NSArray arrayWithObject:[NSNumber numberWithInteger:1]]; + } + + @end + @endcode + + And then: + + @code + CustomObject *customObject = [[CustomObject alloc] init]; + NSString *JSONString = [customObject yajl_JSON]; + // JSONString == "[1]"; + @endcode */ @protocol YAJLCoding diff --git a/src/extThree20JSON/Vendors/YAJL/YAJLGen.m b/src/extThree20JSON/Vendors/YAJL/YAJLGen.m index ae2080d43b..ac23d61061 100644 --- a/src/extThree20JSON/Vendors/YAJL/YAJLGen.m +++ b/src/extThree20JSON/Vendors/YAJL/YAJLGen.m @@ -27,8 +27,8 @@ // OTHER DEALINGS IN THE SOFTWARE. // -#import "YAJLGen.h" -#import "YAJL_GTMBase64.h" +#import "extThree20JSON/YAJLGen.h" +#import "extThree20JSON/private/GTMBase64.h" NSString *const YAJLGenInvalidObjectException = @"YAJLGenInvalidObjectException"; @@ -41,21 +41,21 @@ - (id)init { - (id)initWithGenOptions:(YAJLGenOptions)genOptions indentString:(NSString *)indentString { if ((self = [super init])) { genOptions_ = genOptions; - yajl_gen_config cfg = { + yajl_gen_config cfg = { ((genOptions & YAJLGenOptionsBeautify) ? 1 : 0), [indentString UTF8String] - }; - gen_ = yajl_gen_alloc(&cfg, NULL); + }; + gen_ = yajl_gen_alloc(&cfg, NULL); } return self; } -- (void)dealloc { +- (void)dealloc { if (gen_ != NULL) yajl_gen_free(gen_); [super dealloc]; } -- (void)object:(id)obj { +- (void)object:(id)obj { if ([obj respondsToSelector:@selector(JSON)]) { return [self object:[obj JSON]]; } else if ([obj isKindOfClass:[NSArray class]]) { @@ -80,12 +80,12 @@ - (void)object:(id)obj { [self string:obj]; } else if ([obj isKindOfClass:[NSNull class]]) { [self null]; - } else { - + } else { + BOOL unknownType = NO; if (genOptions_ & YAJLGenOptionsIncludeUnsupportedTypes) { // Begin with support for non-JSON representable (PList) types - if ([obj isKindOfClass:[NSDate class]]) { + if ([obj isKindOfClass:[NSDate class]]) { [self number:[NSNumber numberWithLongLong:round([obj timeIntervalSince1970] * 1000)]]; } else if ([obj isKindOfClass:[NSData class]]) { [self string:[YAJL_GTMBase64 stringByEncodingData:obj]]; @@ -97,7 +97,7 @@ - (void)object:(id)obj { } else { unknownType = YES; } - + // If we didn't handle special PList types if (unknownType) { if (!(genOptions_ & YAJLGenOptionsIgnoreUnknownTypes)) { @@ -126,7 +126,7 @@ - (void)number:(NSNumber *)number { - (void)string:(NSString *)s { unsigned int length = [s lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - const unsigned char *c = (const unsigned char *)[s UTF8String]; + const unsigned char *c = (const unsigned char *)[s UTF8String]; yajl_gen_string(gen_, c, length); } @@ -151,12 +151,12 @@ - (void)clear { } - (NSString *)buffer { - const unsigned char *buf; + const unsigned char *buf; unsigned int len; - yajl_gen_get_buf(gen_, &buf, &len); - NSString *s = [NSString stringWithUTF8String:(const char*)buf]; + yajl_gen_get_buf(gen_, &buf, &len); + NSString *s = [NSString stringWithUTF8String:(const char*)buf]; return s; -} +} @end diff --git a/src/extThree20JSON/Vendors/YAJL/YAJLParser.h b/src/extThree20JSON/Vendors/YAJL/YAJLParser.h index 69d2644d16..735107bd04 100644 --- a/src/extThree20JSON/Vendors/YAJL/YAJLParser.h +++ b/src/extThree20JSON/Vendors/YAJL/YAJLParser.h @@ -28,60 +28,78 @@ // -#include "yajl_parse.h" +#include "extThree20JSON/yajl_parse.h" -extern NSString *const YAJLErrorDomain; -extern NSString *const YAJLParserException; -extern NSString *const YAJLParsingUnsupportedException; +extern NSString *const YAJLErrorDomain; //! Error domain for YAJL +extern NSString *const YAJLParserException; //! Generic parse exception +extern NSString *const YAJLParsingUnsupportedException; //! Parsing unsupported exception -extern NSString *const YAJLParserValueKey; // Key in NSError userInfo for value we errored on +extern NSString *const YAJLParserValueKey; //! Key in NSError userInfo for value we errored on -#ifdef DEBUG -#define YAJLDebug(...) NSLog(__VA_ARGS__) -#else -#define YAJLDebug(...) do {} while(0) -#endif - -typedef enum { - YAJLParserErrorCodeAllocError = -1000, - YAJLParserErrorCodeDoubleOverflow = -1001, - YAJLParserErrorCodeIntegerOverflow = -1002 -} YAJLParserErrorCode; - -/*! - @enum Parser options - @constant YAJLParserOptionsAllowComments Javascript style comments will be allowed in the input (both /&asterisk; &asterisk;/ and //) - @constant YAJLParserOptionsCheckUTF8 Invalid UTF8 strings will cause a parse error - */ -enum { - YAJLParserOptionsNone = 0, - YAJLParserOptionsAllowComments = 1 << 0, // Allows comments in JSON - YAJLParserOptionsCheckUTF8 = 1 << 1, // If YES will verify UTF-8 - YAJLParserOptionsStrictPrecision = 1 << 2, // If YES will force strict precision and return integer overflow error +//! Parser error codes +enum YAJLParserErrorCode { + YAJLParserErrorCodeAllocError = -1000, //!< Alloc error + YAJLParserErrorCodeDoubleOverflow = -1001, //!< Double overflow + YAJLParserErrorCodeIntegerOverflow = -1002 //!< Integer overflow }; -typedef NSUInteger YAJLParserOptions; +typedef NSInteger YAJLParserErrorCode; //! Parser error codes + +//! Parser options +enum YAJLParserOptions { + YAJLParserOptionsNone = 0, //!< No options + YAJLParserOptionsAllowComments = 1 << 0, //!< Javascript style comments will be allowed in the input (both /&asterisk; &asterisk;/ and //) + YAJLParserOptionsCheckUTF8 = 1 << 1, //!< Invalid UTF8 strings will cause a parse error + YAJLParserOptionsStrictPrecision = 1 << 2, //!< If YES will force strict precision and return integer overflow error +}; +typedef NSUInteger YAJLParserOptions; //! Parser options +//! Parser status enum { - YAJLParserStatusNone = 0, - YAJLParserStatusOK = 1, - YAJLParserStatusInsufficientData = 2, - YAJLParserStatusError = 3 + YAJLParserStatusNone = 0, //!< No status + YAJLParserStatusOK = 1, //!< Parsed OK + YAJLParserStatusInsufficientData = 2, //!< There was insufficient data + YAJLParserStatusError = 3 //!< Parser errored }; -typedef NSUInteger YAJLParserStatus; +typedef NSUInteger YAJLParserStatus; //!< Status of the last parse event @class YAJLParser; - +/*! + Delegate for YAJL JSON parser. + */ @protocol YAJLParserDelegate +/*! + Parser did start dictionary. + @param parser Sender + */ - (void)parserDidStartDictionary:(YAJLParser *)parser; + +/*! + Parser did end dictionary. + @param parser Sender + */ - (void)parserDidEndDictionary:(YAJLParser *)parser; +/*! + Parser did start array. + @param parser Sender + */ - (void)parserDidStartArray:(YAJLParser *)parser; + +/*! + Parser did end array. + @param parser Sender + */ - (void)parserDidEndArray:(YAJLParser *)parser; +/*! + Parser did map key. + @param parser Sender + @param key Key that was mapped + */ - (void)parser:(YAJLParser *)parser didMapKey:(NSString *)key; /*! @@ -93,36 +111,70 @@ typedef NSUInteger YAJLParserStatus; @end +/*! + JSON parser. + + @code + NSData *data = [NSData dataWithContentsOfFile:@"example.json"]; + + YAJLParser *parser = [[YAJLParser alloc] initWithParserOptions:YAJLParserOptionsAllowComments]; + parser.delegate = self; + [parser parse:data]; + if (parser.parserError) { + NSLog(@"Error:\n%@", parser.parserError); + } + parser.delegate = nil; + [parser release]; + + // Include delegate methods from YAJLParserDelegate + - (void)parserDidStartDictionary:(YAJLParser *)parser { } + - (void)parserDidEndDictionary:(YAJLParser *)parser { } + + - (void)parserDidStartArray:(YAJLParser *)parser { } + - (void)parserDidEndArray:(YAJLParser *)parser { } + + - (void)parser:(YAJLParser *)parser didMapKey:(NSString *)key { } + - (void)parser:(YAJLParser *)parser didAdd:(id)value { } + @endcode + */ @interface YAJLParser : NSObject { - + yajl_handle handle_; - - id delegate_; // weak - + + __weak id delegate_; // weak + YAJLParserOptions parserOptions_; NSError *parserError_; } -@property (assign, nonatomic) id delegate; +@property (assign, nonatomic) __weak id delegate; @property (readonly, retain, nonatomic) NSError *parserError; @property (readonly, nonatomic) YAJLParserOptions parserOptions; /*! Create parser with data and options. - @param parserOptions + @param parserOptions Parser options + - YAJLParserOptionsNone: No options + - YAJLParserOptionsAllowComments: Javascript style comments will be allowed in the input (both /&asterisk; &asterisk;/ and //) + - YAJLParserOptionsCheckUTF8: Invalid UTF8 strings will cause a parse error + - YAJLParserOptionsStrictPrecision: If YES will force strict precision and return integer overflow error */ - (id)initWithParserOptions:(YAJLParserOptions)parserOptions; /*! Parse data. - - If streaming, you can call parse multiple times as long as + + If streaming, you can call parse multiple times as long as previous calls return YAJLParserStatusInsufficientData. - + @param data - @result See YAJLParserStatus + @result Parser status + - YAJLParserStatusNone: No status + - YAJLParserStatusOK: Parsed OK + - YAJLParserStatusInsufficientData: There was insufficient data + - YAJLParserStatusError: Parser errored */ - (YAJLParserStatus)parse:(NSData *)data; diff --git a/src/extThree20JSON/Vendors/YAJL/YAJLParser.m b/src/extThree20JSON/Vendors/YAJL/YAJLParser.m index 8ccb9b784b..a7f1ab5c3a 100644 --- a/src/extThree20JSON/Vendors/YAJL/YAJLParser.m +++ b/src/extThree20JSON/Vendors/YAJL/YAJLParser.m @@ -28,7 +28,7 @@ // -#import "YAJLParser.h" +#import "extThree20JSON/YAJLParser.h" NSString *const YAJLErrorDomain = @"YAJLErrorDomain"; NSString *const YAJLParserException = @"YAJLParserException"; @@ -40,8 +40,9 @@ @interface YAJLParser () @property (retain, nonatomic) NSError *parserError; @end +//! @internal -@interface YAJLParser (Private) +@interface YAJLParser () - (void)_add:(id)value; - (void)_mapKey:(NSString *)key; @@ -55,6 +56,8 @@ - (NSError *)_errorForStatus:(NSInteger)code message:(NSString *)message value:( - (void)_cancelWithErrorForStatus:(NSInteger)code message:(NSString *)message value:(NSString *)value; @end +//! @endinternal + @implementation YAJLParser @@ -66,7 +69,7 @@ - (id)init { - (id)initWithParserOptions:(YAJLParserOptions)parserOptions { if ((self = [super init])) { - parserOptions_ = parserOptions; + parserOptions_ = parserOptions; } return self; } @@ -75,8 +78,8 @@ - (void)dealloc { if (handle_ != NULL) { yajl_free(handle_); handle_ = NULL; - } - + } + [parserError_ release]; [super dealloc]; } @@ -109,7 +112,7 @@ int yajl_boolean(void *ctx, int boolVal) { // Instead of using yajl_integer, and yajl_double we use yajl_number and parse // as double (or long long); This is to be more compliant since Javascript numbers are represented -// as double precision floating point, though JSON spec doesn't define a max value +// as double precision floating point, though JSON spec doesn't define a max value // and is up to the parser? //int yajl_integer(void *ctx, long integerVal) { @@ -140,7 +143,7 @@ int yajl_number(void *ctx, const char *numberVal, unsigned int numberLen) { char buf[numberLen+1]; memcpy(buf, numberVal, numberLen); buf[numberLen] = 0; - + if (memchr(numberVal, '.', numberLen) || memchr(numberVal, 'e', numberLen) || memchr(numberVal, 'E', numberLen)) { return ParseDouble(ctx, buf, numberVal, numberLen); } else { @@ -152,7 +155,7 @@ int yajl_number(void *ctx, const char *numberVal, unsigned int numberLen) { [s release]; return 0; } else { - // If we integer overflow lets try double precision for HUGE_VAL > double > LLONG_MAX + // If we integer overflow lets try double precision for HUGE_VAL > double > LLONG_MAX return ParseDouble(ctx, buf, numberVal, numberLen); } } @@ -160,7 +163,7 @@ int yajl_number(void *ctx, const char *numberVal, unsigned int numberLen) { [(id)ctx _add:number]; [number release]; } - + return 1; } @@ -214,6 +217,8 @@ int yajl_end_array(void *ctx) { #pragma mark - +//! @internal + - (void)_add:(id)value { [delegate_ parser:self didAdd:value]; } @@ -230,7 +235,7 @@ - (void)_endDictionary { [delegate_ parserDidEndDictionary:self]; } -- (void)_startArray { +- (void)_startArray { [delegate_ parserDidStartArray:self]; } @@ -238,20 +243,22 @@ - (void)_endArray { [delegate_ parserDidEndArray:self]; } +//! @endinternal + - (YAJLParserStatus)parse:(NSData *)data { if (!handle_) { yajl_parser_config cfg = { ((parserOptions_ & YAJLParserOptionsAllowComments) ? 1 : 0), // allowComments: if nonzero, javascript style comments will be allowed in the input (both /* */ and //) ((parserOptions_ & YAJLParserOptionsCheckUTF8) ? 1 : 0) // checkUTF8: if nonzero, invalid UTF8 strings will cause a parse error }; - + handle_ = yajl_alloc(&callbacks, &cfg, NULL, self); - if (!handle_) { + if (!handle_) { self.parserError = [self _errorForStatus:YAJLParserErrorCodeAllocError message:@"Unable to allocate YAJL handle" value:nil]; return YAJLParserStatusError; - } + } } - + yajl_status status = yajl_parse(handle_, [data bytes], [data length]); if (status == yajl_status_client_canceled) { // We cancelled because we encountered an error here in the client; diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/BUILDING b/src/extThree20JSON/Vendors/YAJL/yajl/BUILDING old mode 100644 new mode 100755 similarity index 66% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/BUILDING rename to src/extThree20JSON/Vendors/YAJL/yajl/BUILDING index 74589e1127..8460ed4b40 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/BUILDING +++ b/src/extThree20JSON/Vendors/YAJL/yajl/BUILDING @@ -15,5 +15,9 @@ OR, attain CMake and build by hand: 4. make 5. build output left in yajl-X.Y.Z +NOTE: for 64-bit systems where lib64 is used you can pass the cmake + variable LIB_SUFFIX to cause installation into the system's 'lib64' + directory. + best, lloyd diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/BUILDING.win32 b/src/extThree20JSON/Vendors/YAJL/yajl/BUILDING.win32 old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/BUILDING.win32 rename to src/extThree20JSON/Vendors/YAJL/yajl/BUILDING.win32 diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/CMakeLists.txt b/src/extThree20JSON/Vendors/YAJL/yajl/CMakeLists.txt old mode 100644 new mode 100755 similarity index 86% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/CMakeLists.txt rename to src/extThree20JSON/Vendors/YAJL/yajl/CMakeLists.txt index fded92802b..5fa3ec4124 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/CMakeLists.txt +++ b/src/extThree20JSON/Vendors/YAJL/yajl/CMakeLists.txt @@ -34,15 +34,20 @@ PROJECT(YetAnotherJSONParser C) SET (YAJL_MAJOR 1) SET (YAJL_MINOR 0) -SET (YAJL_MICRO 10) +SET (YAJL_MICRO 11) SET (YAJL_DIST_NAME "yajl-${YAJL_MAJOR}.${YAJL_MINOR}.${YAJL_MICRO}") +# RPATH handling -- given we statically link, we'll turn off +# unnec. rpath embedding +SET(CMAKE_SKIP_RPATH TRUE) + IF (NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE "Release") ENDIF (NOT CMAKE_BUILD_TYPE) -SET(CMAKE_C_FLAGS "-Wall") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") + IF (WIN32) ADD_DEFINITIONS(-DWIN32) SET(linkFlags "/PDB:NONE /INCREMENTAL:NO /OPT:NOREF /OPT:NOICF") @@ -62,7 +67,7 @@ IF (WIN32) SET(CMAKE_C_FLAGS_RELEASE "/D NDEBUG /O2") ELSE (WIN32) SET(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} -fPIC -ansi -pedantic -Wpointer-arith -Wno-format-y2k -Wstrict-prototypes -Wmissing-declarations -Wnested-externs -Wextra -Wundef -Wwrite-strings -Wold-style-definition -Wno-missing-field-initializers -Wredundant-decls -Wno-unused-parameter -Wno-sign-compare -Wmissing-prototypes") + "${CMAKE_C_FLAGS} -fPIC -std=c99 -pedantic -Wpointer-arith -Wno-format-y2k -Wstrict-prototypes -Wmissing-declarations -Wnested-externs -Wextra -Wundef -Wwrite-strings -Wold-style-definition -Wredundant-decls -Wno-unused-parameter -Wno-sign-compare -Wmissing-prototypes") SET(CMAKE_C_FLAGS_DEBUG "-DDEBUG -g") SET(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2 -Wuninitialized") diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/COPYING b/src/extThree20JSON/Vendors/YAJL/yajl/COPYING old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/COPYING rename to src/extThree20JSON/Vendors/YAJL/yajl/COPYING diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/ChangeLog b/src/extThree20JSON/Vendors/YAJL/yajl/ChangeLog old mode 100644 new mode 100755 similarity index 87% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/ChangeLog rename to src/extThree20JSON/Vendors/YAJL/yajl/ChangeLog index 788837b660..1b4343c049 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/ChangeLog +++ b/src/extThree20JSON/Vendors/YAJL/yajl/ChangeLog @@ -1,3 +1,15 @@ +1.0.11 + * lth remove -Wno-missing-field-initializers for greater gcc compat (3.4.6) + +1.0.10 + * Brian Maher - yajl is now buildable without a c++ compiler present + * Brian Maher - fix header installation on OSX with cmake 2.8.0 installed + * lth & vitali - allow builder to specify alternate lib directory + for installation (i.e. lib64) + * Vitali Lovich - yajl version number now programatically accessible + * lth - prevent cmake from embedding rpaths in binaries. Static linking + makes this unneccesary. + 1.0.9 * lth - fix inverted logic causing yajl_gen_double() to always fail on win32 (thanks to Fredrik Kihlander for the report) diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/README b/src/extThree20JSON/Vendors/YAJL/yajl/README old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/README rename to src/extThree20JSON/Vendors/YAJL/yajl/README diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/TODO b/src/extThree20JSON/Vendors/YAJL/yajl/TODO old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/TODO rename to src/extThree20JSON/Vendors/YAJL/yajl/TODO diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/YAJLDoc.cmake b/src/extThree20JSON/Vendors/YAJL/yajl/YAJLDoc.cmake old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/YAJLDoc.cmake rename to src/extThree20JSON/Vendors/YAJL/yajl/YAJLDoc.cmake diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/configure b/src/extThree20JSON/Vendors/YAJL/yajl/configure similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/configure rename to src/extThree20JSON/Vendors/YAJL/yajl/configure diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/reformatter/CMakeLists.txt b/src/extThree20JSON/Vendors/YAJL/yajl/reformatter/CMakeLists.txt old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/reformatter/CMakeLists.txt rename to src/extThree20JSON/Vendors/YAJL/yajl/reformatter/CMakeLists.txt diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/reformatter/json_reformat.c b/src/extThree20JSON/Vendors/YAJL/yajl/reformatter/json_reformat.c old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/reformatter/json_reformat.c rename to src/extThree20JSON/Vendors/YAJL/yajl/reformatter/json_reformat.c diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/CMakeLists.txt b/src/extThree20JSON/Vendors/YAJL/yajl/src/CMakeLists.txt old mode 100644 new mode 100755 similarity index 88% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/CMakeLists.txt rename to src/extThree20JSON/Vendors/YAJL/yajl/src/CMakeLists.txt index 2d9a6cbd08..4472157ecc --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/CMakeLists.txt +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/CMakeLists.txt @@ -29,7 +29,9 @@ # POSSIBILITY OF SUCH DAMAGE. SET (SRCS yajl.c yajl_lex.c yajl_parser.c yajl_buf.c - yajl_encode.c yajl_gen.c yajl_alloc.c) + yajl_encode.c yajl_gen.c yajl_alloc.c + yajl_version.c +) SET (HDRS yajl_parser.h yajl_lex.h yajl_buf.h yajl_encode.h yajl_alloc.h) SET (PUB_HDRS api/yajl_parse.h api/yajl_gen.h api/yajl_common.h) @@ -64,6 +66,9 @@ SET_TARGET_PROPERTIES(yajl PROPERTIES FILE(MAKE_DIRECTORY ${libDir}) FILE(MAKE_DIRECTORY ${incDir}) +# generate build-time source +CONFIGURE_FILE(api/yajl_version.h.cmake ${incDir}/yajl_version.h) + # copy public headers to output directory FOREACH (header ${PUB_HDRS}) SET (header ${CMAKE_CURRENT_SOURCE_DIR}/${header}) @@ -77,7 +82,9 @@ ENDFOREACH (header ${PUB_HDRS}) INCLUDE_DIRECTORIES(${incDir}/..) IF(NOT WIN32) - INSTALL(TARGETS yajl LIBRARY DESTINATION lib) - INSTALL(TARGETS yajl_s ARCHIVE DESTINATION lib) + # at build time you may specify the cmake variable LIB_SUFFIX to handle + # 64-bit systems which use 'lib64' + INSTALL(TARGETS yajl LIBRARY DESTINATION lib${LIB_SUFFIX}) + INSTALL(TARGETS yajl_s ARCHIVE DESTINATION lib${LIB_SUFFIX}) INSTALL(DIRECTORY api/ DESTINATION include/yajl) ENDIF() diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/YAJL.dxy b/src/extThree20JSON/Vendors/YAJL/yajl/src/YAJL.dxy old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/YAJL.dxy rename to src/extThree20JSON/Vendors/YAJL/yajl/src/YAJL.dxy diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/api/yajl_common.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_common.h old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/api/yajl_common.h rename to src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_common.h diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/api/yajl_gen.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_gen.h old mode 100644 new mode 100755 similarity index 97% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/api/yajl_gen.h rename to src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_gen.h index 97c20426cb..15504ca056 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/api/yajl_gen.h +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_gen.h @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,21 +28,21 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ /** * \file yajl_gen.h * Interface to YAJL's JSON generation facilities. */ -#include "yajl_common.h" +#include #ifndef __YAJL_GEN_H__ #define __YAJL_GEN_H__ #ifdef __cplusplus extern "C" { -#endif +#endif /** generator status codes */ typedef enum { /** no error */ @@ -57,7 +57,7 @@ extern "C" { * state */ yajl_gen_in_error_state, /** A complete JSON document has been generated */ - yajl_gen_generation_complete, + yajl_gen_generation_complete, /** yajl_gen_double was passed an invalid floating point value * (infinity or NaN). */ yajl_gen_invalid_number, @@ -119,7 +119,7 @@ extern "C" { const yajl_alloc_funcs * allocFuncs, void * ctx); - /** free a generator handle */ + /** free a generator handle */ YAJL_API void yajl_gen_free(yajl_gen handle); YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long int number); @@ -134,7 +134,7 @@ extern "C" { const unsigned char * str, unsigned int len); YAJL_API yajl_gen_status yajl_gen_null(yajl_gen hand); - YAJL_API yajl_gen_status yajl_gen_bool(yajl_gen hand, int boolean); + YAJL_API yajl_gen_status yajl_gen_bool(yajl_gen hand, int boolean); YAJL_API yajl_gen_status yajl_gen_map_open(yajl_gen hand); YAJL_API yajl_gen_status yajl_gen_map_close(yajl_gen hand); YAJL_API yajl_gen_status yajl_gen_array_open(yajl_gen hand); @@ -154,6 +154,6 @@ extern "C" { #ifdef __cplusplus } -#endif +#endif #endif diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/api/yajl_parse.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_parse.h old mode 100644 new mode 100755 similarity index 96% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/api/yajl_parse.h rename to src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_parse.h index a3dcffcef0..13920e38af --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/api/yajl_parse.h +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_parse.h @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,21 +28,21 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ /** * \file yajl_parse.h * Interface to YAJL's JSON parsing facilities. */ -#include "yajl_common.h" +#include #ifndef __YAJL_PARSE_H__ #define __YAJL_PARSE_H__ #ifdef __cplusplus extern "C" { -#endif +#endif /** error codes returned from this interface */ typedef enum { /** no error was encountered */ @@ -103,12 +103,12 @@ extern "C" { int (* yajl_start_map)(void * ctx); int (* yajl_map_key)(void * ctx, const unsigned char * key, unsigned int stringLen); - int (* yajl_end_map)(void * ctx); + int (* yajl_end_map)(void * ctx); int (* yajl_start_array)(void * ctx); - int (* yajl_end_array)(void * ctx); + int (* yajl_end_array)(void * ctx); } yajl_callbacks; - + /** configuration structure for the generator */ typedef struct { /** if nonzero, javascript style comments will be allowed in @@ -132,7 +132,7 @@ extern "C" { const yajl_alloc_funcs * allocFuncs, void * ctx); - /** free a parser handle */ + /** free a parser handle */ YAJL_API void yajl_free(yajl_handle handle); /** Parse some json! @@ -154,7 +154,7 @@ extern "C" { * \param hand - a handle to the json parser allocated with yajl_alloc */ YAJL_API yajl_status yajl_parse_complete(yajl_handle hand); - + /** get an error string describing the state of the * parse. * @@ -163,7 +163,7 @@ extern "C" { * the specific char. * * \returns A dynamically allocated string will be returned which should - * be freed with yajl_free_error + * be freed with yajl_free_error */ YAJL_API unsigned char * yajl_get_error(yajl_handle hand, int verbose, const unsigned char * jsonText, @@ -174,8 +174,8 @@ extern "C" { * * In the case of a successful parse this can help you understand if * the entire buffer was consumed (which will allow you to handle - * "junk at end of input". - * + * "junk at end of input". + * * In the event an error is encountered during parsing, this function * affords the client a way to get the offset into the most recent * chunk where the error occured. 0 will be returned if no error @@ -188,6 +188,6 @@ extern "C" { #ifdef __cplusplus } -#endif +#endif #endif diff --git a/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_version.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_version.h new file mode 100755 index 0000000000..0bae087b68 --- /dev/null +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_version.h @@ -0,0 +1,23 @@ +#ifndef YAJL_VERSION_H_ +#define YAJL_VERSION_H_ + +#include + +#define YAJL_MAJOR 1 +#define YAJL_MINOR 0 +#define YAJL_MICRO 11 + +#define YAJL_VERSION ((YAJL_MAJOR * 10000) + (YAJL_MINOR * 100) + YAJL_MICRO) + +#ifdef __cplusplus +extern "C" { +#endif + +extern int YAJL_API yajl_version(void); + +#ifdef __cplusplus +} +#endif + +#endif /* YAJL_VERSION_H_ */ + diff --git a/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_version.h.cmake b/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_version.h.cmake new file mode 100755 index 0000000000..4262ff71f9 --- /dev/null +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/api/yajl_version.h.cmake @@ -0,0 +1,23 @@ +#ifndef YAJL_VERSION_H_ +#define YAJL_VERSION_H_ + +#include + +#define YAJL_MAJOR ${YAJL_MAJOR} +#define YAJL_MINOR ${YAJL_MINOR} +#define YAJL_MICRO ${YAJL_MICRO} + +#define YAJL_VERSION ((YAJL_MAJOR * 10000) + (YAJL_MINOR * 100) + YAJL_MICRO) + +#ifdef __cplusplus +extern "C" { +#endif + +extern int YAJL_API yajl_version(void); + +#ifdef __cplusplus +} +#endif + +#endif /* YAJL_VERSION_H_ */ + diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl.c b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl.c old mode 100644 new mode 100755 similarity index 94% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl.c rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl.c index 03458140e3..9cabbd5bdc --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl.c +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl.c @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,12 +28,12 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ -#include "api/yajl_parse.h" -#include "yajl_lex.h" -#include "yajl_parser.h" -#include "yajl_alloc.h" +#include "extThree20JSON/yajl_parse.h" +#include "extThree20JSON/private/yajl_lex.h" +#include "extThree20JSON/private/yajl_parser.h" +#include "extThree20JSON/private/yajl_alloc.h" #include #include @@ -70,7 +70,7 @@ yajl_alloc(const yajl_callbacks * callbacks, unsigned int validateUTF8 = 0; yajl_handle hand = NULL; yajl_alloc_funcs afsBuffer; - + /* first order of business is to set up memory allocation routines */ if (afs != NULL) { if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL) @@ -99,7 +99,7 @@ yajl_alloc(const yajl_callbacks * callbacks, hand->decodeBuf = yajl_buf_alloc(&(hand->alloc)); yajl_bs_init(hand->stateStack, &(hand->alloc)); - yajl_bs_push(hand->stateStack, yajl_state_start); + yajl_bs_push(hand->stateStack, yajl_state_start); return hand; } diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_alloc.c b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_alloc.c old mode 100644 new mode 100755 similarity index 97% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_alloc.c rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_alloc.c index ccfb7c3dde..b8d10bc066 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_alloc.c +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_alloc.c @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,7 +28,7 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ /** * \file yajl_alloc.h @@ -36,7 +36,7 @@ * free */ -#include "yajl_alloc.h" +#include "extThree20JSON/private/yajl_alloc.h" #include static void * yajl_internal_malloc(void *ctx, unsigned int sz) diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_alloc.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_alloc.h old mode 100644 new mode 100755 similarity index 97% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_alloc.h rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_alloc.h index 94e7de5f4a..a98f8abcea --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_alloc.h +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_alloc.h @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,7 +28,7 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ /** * \file yajl_alloc.h @@ -39,7 +39,7 @@ #ifndef __YAJL_ALLOC_H__ #define __YAJL_ALLOC_H__ -#include "api/yajl_common.h" +#include "extThree20JSON/yajl_common.h" #define YA_MALLOC(afs, sz) (afs)->malloc((afs)->ctx, (sz)) #define YA_FREE(afs, ptr) (afs)->free((afs)->ctx, (ptr)) diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_buf.c b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_buf.c old mode 100644 new mode 100755 similarity index 98% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_buf.c rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_buf.c index 04e608a3e8..151f348274 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_buf.c +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_buf.c @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,9 +28,9 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ -#include "yajl_buf.h" +#include "extThree20JSON/private/yajl_buf.h" #include #include @@ -49,7 +49,7 @@ static void yajl_buf_ensure_available(yajl_buf buf, unsigned int want) { unsigned int need; - + assert(buf != NULL); /* first call */ diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_buf.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_buf.h old mode 100644 new mode 100755 similarity index 95% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_buf.h rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_buf.h index e330f33ae0..4ded84e775 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_buf.h +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_buf.h @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,17 +28,17 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ #ifndef __YAJL_BUF_H__ #define __YAJL_BUF_H__ -#include "api/yajl_common.h" -#include "yajl_alloc.h" +#include "extThree20JSON/yajl_common.h" +#include "extThree20JSON/private/yajl_alloc.h" /* * Implementation/performance notes. If this were moved to a header - * only implementation using #define's where possible we might be + * only implementation using #define's where possible we might be * able to sqeeze a little performance out of the guy by killing function * call overhead. YMMV. */ diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_bytestack.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_bytestack.h old mode 100644 new mode 100755 similarity index 95% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_bytestack.h rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_bytestack.h index 872ede1162..82b1a88e96 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_bytestack.h +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_bytestack.h @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,7 +28,7 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ /* * A header only implementation of a simple stack of bytes, used in YAJL @@ -38,7 +38,7 @@ #ifndef __YAJL_BYTESTACK_H__ #define __YAJL_BYTESTACK_H__ -#include "api/yajl_common.h" +#include "extThree20JSON/yajl_common.h" #define YAJL_BS_INC 128 @@ -61,7 +61,7 @@ typedef struct yajl_bytestack_t /* initialize a bytestack */ #define yajl_bs_free(obs) \ - if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack); + if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack); #define yajl_bs_current(obs) \ (assert((obs).used > 0), (obs).stack[(obs).used - 1]) @@ -74,12 +74,12 @@ typedef struct yajl_bytestack_t } \ (obs).stack[((obs).used)++] = (byte); \ } - + /* removes the top item of the stack, returns nothing */ #define yajl_bs_pop(obs) { ((obs).used)--; } #define yajl_bs_set(obs, byte) \ - (obs).stack[((obs).used) - 1] = (byte); - + (obs).stack[((obs).used) - 1] = (byte); + #endif diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_encode.c b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_encode.c old mode 100644 new mode 100755 similarity index 95% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_encode.c rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_encode.c index ad5b1c591d..c36404b954 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_encode.c +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_encode.c @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,9 +28,9 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ -#include "yajl_encode.h" +#include "extThree20JSON/private/yajl_encode.h" #include #include @@ -58,7 +58,7 @@ yajl_string_encode2(const yajl_print_t print, unsigned int len) { unsigned int beg = 0; - unsigned int end = 0; + unsigned int end = 0; char hexBuf[7]; hexBuf[0] = '\\'; hexBuf[1] = 'u'; hexBuf[2] = '0'; hexBuf[3] = '0'; hexBuf[6] = 0; @@ -104,7 +104,7 @@ static void hexToDigit(unsigned int * val, const unsigned char * hex) } } -static void Utf32toUtf8(unsigned int codepoint, char * utf8Buf) +static void Utf32toUtf8(unsigned int codepoint, char * utf8Buf) { if (codepoint < 0x80) { utf8Buf[0] = (char) codepoint; @@ -134,7 +134,7 @@ void yajl_string_decode(yajl_buf buf, const unsigned char * str, unsigned int len) { unsigned int beg = 0; - unsigned int end = 0; + unsigned int end = 0; while (end < len) { if (str[end] == '\\') { @@ -161,8 +161,8 @@ void yajl_string_decode(yajl_buf buf, const unsigned char * str, unsigned int surrogate = 0; hexToDigit(&surrogate, str + end + 2); codepoint = - (((codepoint & 0x3F) << 10) | - ((((codepoint >> 6) & 0xF) + 1) << 16) | + (((codepoint & 0x3F) << 10) | + ((((codepoint >> 6) & 0xF) + 1) << 16) | (surrogate & 0x3FF)); end += 5; } else { @@ -170,7 +170,7 @@ void yajl_string_decode(yajl_buf buf, const unsigned char * str, break; } } - + Utf32toUtf8(codepoint, utf8Buf); unescaped = utf8Buf; break; diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_encode.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_encode.h old mode 100644 new mode 100755 similarity index 95% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_encode.h rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_encode.h index f24277908c..d59c782268 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_encode.h +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_encode.h @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,13 +28,13 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ #ifndef __YAJL_ENCODE_H__ #define __YAJL_ENCODE_H__ -#include "yajl_buf.h" -#include "api/yajl_gen.h" +#include "extThree20JSON/private/yajl_buf.h" +#include "extThree20JSON/yajl_gen.h" void yajl_string_encode2(const yajl_print_t printer, void * ctx, diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_gen.c b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_gen.c old mode 100644 new mode 100755 similarity index 96% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_gen.c rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_gen.c index 6ad9c0b442..400ce99ab5 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_gen.c +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_gen.c @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,11 +28,11 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ -#include "api/yajl_gen.h" -#include "yajl_buf.h" -#include "yajl_encode.h" +#include "extThree20JSON/yajl_gen.h" +#include "extThree20JSON/private/yajl_buf.h" +#include "extThree20JSON/private/yajl_encode.h" #include #include @@ -50,7 +50,7 @@ typedef enum { yajl_gen_error } yajl_gen_state; -struct yajl_gen_t +struct yajl_gen_t { unsigned int depth; unsigned int pretty; @@ -125,7 +125,7 @@ yajl_gen_free(yajl_gen g) } else if (g->state[g->depth] == yajl_gen_map_val) { \ g->print(g->ctx, ":", 1); \ if (g->pretty) g->print(g->ctx, " ", 1); \ - } + } #define INSERT_WHITESPACE \ if (g->pretty) { \ @@ -175,8 +175,8 @@ yajl_gen_free(yajl_gen g) #define FINAL_NEWLINE \ if (g->pretty && g->state[g->depth] == yajl_gen_complete) \ - g->print(g->ctx, "\n", 1); - + g->print(g->ctx, "\n", 1); + yajl_gen_status yajl_gen_integer(yajl_gen g, long int number) { @@ -199,7 +199,7 @@ yajl_gen_status yajl_gen_double(yajl_gen g, double number) { char i[32]; - ENSURE_VALID_STATE; ENSURE_NOT_KEY; + ENSURE_VALID_STATE; ENSURE_NOT_KEY; if (isnan(number) || isinf(number)) return yajl_gen_invalid_number; INSERT_SEP; INSERT_WHITESPACE; sprintf(i, "%g", number); @@ -258,8 +258,8 @@ yajl_gen_status yajl_gen_map_open(yajl_gen g) { ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - INCREMENT_DEPTH; - + INCREMENT_DEPTH; + g->state[g->depth] = yajl_gen_map_start; g->print(g->ctx, "{", 1); if (g->pretty) g->print(g->ctx, "\n", 1); @@ -270,7 +270,7 @@ yajl_gen_map_open(yajl_gen g) yajl_gen_status yajl_gen_map_close(yajl_gen g) { - ENSURE_VALID_STATE; + ENSURE_VALID_STATE; (g->depth)--; if (g->pretty) g->print(g->ctx, "\n", 1); APPENDED_ATOM; @@ -284,7 +284,7 @@ yajl_gen_status yajl_gen_array_open(yajl_gen g) { ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - INCREMENT_DEPTH; + INCREMENT_DEPTH; g->state[g->depth] = yajl_gen_array_start; g->print(g->ctx, "[", 1); if (g->pretty) g->print(g->ctx, "\n", 1); diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_lex.c b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_lex.c old mode 100644 new mode 100755 similarity index 93% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_lex.c rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_lex.c index 11e5f7bca9..62d4eb70d5 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_lex.c +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_lex.c @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,10 +28,10 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ -#include "yajl_lex.h" -#include "yajl_buf.h" +#include "extThree20JSON/private/yajl_lex.h" +#include "extThree20JSON/private/yajl_buf.h" #include #include @@ -40,7 +40,7 @@ #ifdef YAJL_LEXER_DEBUG static const char * -tokToStr(yajl_tok tok) +tokToStr(yajl_tok tok) { switch (tok) { case yajl_tok_bool: return "bool"; @@ -69,13 +69,13 @@ tokToStr(yajl_tok tok) * the network or disk). This makes the lexer more complex. The * responsibility of the lexer is to handle transparently the case where * a chunk boundary falls in the middle of a token. This is - * accomplished is via a buffer and a character reading abstraction. + * accomplished is via a buffer and a character reading abstraction. * * Overview of implementation * * When we lex to end of input string before end of token is hit, we * copy all of the input text composing the token into our lexBuf. - * + * * Every time we read a character, we do so through the readChar function. * readChar's responsibility is to handle pulling all chars from the buffer * before pulling chars from input text @@ -90,7 +90,7 @@ struct yajl_lexer_t { yajl_lex_error error; /* a input buffer to handle the case where a token is spread over - * multiple chunks */ + * multiple chunks */ yajl_buf buf; /* in the case where we have data in the lexBuf, bufOff holds @@ -170,24 +170,24 @@ static const char charLookupTable[256] = /*78*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* include these so we don't have to always check the range of the char */ - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; @@ -199,7 +199,7 @@ static const char charLookupTable[256] = * yajl_tok_eof - if end of input was hit before validation could * complete * yajl_tok_error - if invalid utf8 was encountered - * + * * NOTE: on error the offset will point to the first char of the * invalid utf8 */ #define UTF8_CHECK_EOF if (*offset >= jsonTextLen) { return yajl_tok_eof; } @@ -213,7 +213,7 @@ yajl_lex_utf8_char(yajl_lexer lexer, const unsigned char * jsonText, /* single byte */ return yajl_tok_string; } else if ((curChar >> 5) == 0x6) { - /* two byte */ + /* two byte */ UTF8_CHECK_EOF; curChar = readChar(lexer, jsonText, offset); if ((curChar >> 6) == 0x2) return yajl_tok_string; @@ -239,7 +239,7 @@ yajl_lex_utf8_char(yajl_lexer lexer, const unsigned char * jsonText, if ((curChar >> 6) == 0x2) return yajl_tok_string; } } - } + } return yajl_tok_error; } @@ -290,8 +290,8 @@ yajl_lex_string(yajl_lexer lexer, const unsigned char * jsonText, unsigned int i = 0; for (i=0;i<4;i++) { - STR_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); + STR_CHECK_EOF; + curChar = readChar(lexer, jsonText, offset); if (!(charLookupTable[curChar] & VHC)) { /* back up to offending char */ unreadChar(lexer, offset); @@ -303,8 +303,8 @@ yajl_lex_string(yajl_lexer lexer, const unsigned char * jsonText, /* back up to offending char */ unreadChar(lexer, offset); lexer->error = yajl_lex_string_invalid_escaped_char; - goto finish_string_lex; - } + goto finish_string_lex; + } } /* when not validating UTF8 it's a simple table lookup to determine * if the present character is invalid */ @@ -312,29 +312,29 @@ yajl_lex_string(yajl_lexer lexer, const unsigned char * jsonText, /* back up to offending char */ unreadChar(lexer, offset); lexer->error = yajl_lex_string_invalid_json_char; - goto finish_string_lex; + goto finish_string_lex; } /* when in validate UTF8 mode we need to do some extra work */ else if (lexer->validateUTF8) { yajl_tok t = yajl_lex_utf8_char(lexer, jsonText, jsonTextLen, offset, curChar); - + if (t == yajl_tok_eof) { tok = yajl_tok_eof; goto finish_string_lex; } else if (t == yajl_tok_error) { lexer->error = yajl_lex_string_invalid_utf8; goto finish_string_lex; - } + } } - /* accept it, and move on */ + /* accept it, and move on */ } finish_string_lex: /* tell our buddy, the parser, wether he needs to process this string * again */ if (hasEscapes && tok == yajl_tok_string) { tok = yajl_tok_string_with_escapes; - } + } return tok; } @@ -353,23 +353,23 @@ yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText, yajl_tok tok = yajl_tok_integer; - RETURN_IF_EOF; + RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); /* optional leading minus */ if (c == '-') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + RETURN_IF_EOF; + c = readChar(lexer, jsonText, offset); } /* a single zero, or a series of integers */ if (c == '0') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + RETURN_IF_EOF; + c = readChar(lexer, jsonText, offset); } else if (c >= '1' && c <= '9') { do { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + RETURN_IF_EOF; + c = readChar(lexer, jsonText, offset); } while (c >= '0' && c <= '9'); } else { unreadChar(lexer, offset); @@ -380,15 +380,15 @@ yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText, /* optional fraction (indicates this is floating point) */ if (c == '.') { int numRd = 0; - + RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + c = readChar(lexer, jsonText, offset); while (c >= '0' && c <= '9') { numRd++; RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } + c = readChar(lexer, jsonText, offset); + } if (!numRd) { unreadChar(lexer, offset); @@ -401,18 +401,18 @@ yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText, /* optional exponent (indicates this is floating point) */ if (c == 'e' || c == 'E') { RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + c = readChar(lexer, jsonText, offset); /* optional sign */ if (c == '+' || c == '-') { RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + c = readChar(lexer, jsonText, offset); } if (c >= '0' && c <= '9') { do { RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + c = readChar(lexer, jsonText, offset); } while (c >= '0' && c <= '9'); } else { unreadChar(lexer, offset); @@ -421,10 +421,10 @@ yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText, } tok = yajl_tok_double; } - + /* we always go "one too far" */ unreadChar(lexer, offset); - + return tok; } @@ -436,24 +436,24 @@ yajl_lex_comment(yajl_lexer lexer, const unsigned char * jsonText, yajl_tok tok = yajl_tok_comment; - RETURN_IF_EOF; + RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); /* either slash or star expected */ if (c == '/') { /* now we throw away until end of line */ do { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + RETURN_IF_EOF; + c = readChar(lexer, jsonText, offset); } while (c != '\n'); } else if (c == '*') { - /* now we throw away until end of comment */ + /* now we throw away until end of comment */ for (;;) { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + RETURN_IF_EOF; + c = readChar(lexer, jsonText, offset); if (c == '*') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); + RETURN_IF_EOF; + c = readChar(lexer, jsonText, offset); if (c == '/') { break; } else { @@ -465,7 +465,7 @@ yajl_lex_comment(yajl_lexer lexer, const unsigned char * jsonText, lexer->error = yajl_lex_invalid_char; tok = yajl_tok_error; } - + return tok; } @@ -573,7 +573,7 @@ yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, goto lexed; } case '-': - case '0': case '1': case '2': case '3': case '4': + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { /* integer parsing wants to start from the beginning */ unreadChar(lexer, offset); @@ -600,11 +600,11 @@ yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, jsonTextLen, offset); if (tok == yajl_tok_comment) { /* "error" is silly, but that's the initial - * state of tok. guilty until proven innocent. */ + * state of tok. guilty until proven innocent. */ tok = yajl_tok_error; yajl_buf_clear(lexer->buf); lexer->bufInUse = 0; - startOffset = *offset; + startOffset = *offset; break; } /* hit error or eof, bail */ @@ -625,7 +625,7 @@ yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, lexer->bufInUse = 1; yajl_buf_append(lexer->buf, jsonText + startOffset, *offset - startOffset); lexer->bufOff = 0; - + if (tok != yajl_tok_eof) { *outBuf = yajl_buf_data(lexer->buf); *outLen = yajl_buf_len(lexer->buf); @@ -641,7 +641,7 @@ yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, { assert(*outLen >= 2); (*outBuf)++; - *outLen -= 2; + *outLen -= 2; } @@ -672,7 +672,7 @@ yajl_lex_error_to_string(yajl_lex_error error) case yajl_lex_string_invalid_escaped_char: return "inside a string, '\\' occurs before a character " "which it may not."; - case yajl_lex_string_invalid_json_char: + case yajl_lex_string_invalid_json_char: return "invalid character inside string."; case yajl_lex_string_invalid_hex_char: return "invalid (non-hex) character occurs after '\\u' inside " @@ -725,13 +725,13 @@ yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText, unsigned int bufOff = lexer->bufOff; unsigned int bufInUse = lexer->bufInUse; yajl_tok tok; - + tok = yajl_lex_lex(lexer, jsonText, jsonTextLen, &offset, &outBuf, &outLen); lexer->bufOff = bufOff; lexer->bufInUse = bufInUse; yajl_buf_truncate(lexer->buf, bufLen); - + return tok; } diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_lex.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_lex.h old mode 100644 new mode 100755 similarity index 95% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_lex.h rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_lex.h index 6791a2958c..06475a29d1 --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_lex.h +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_lex.h @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,29 +28,29 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ #ifndef __YAJL_LEX_H__ #define __YAJL_LEX_H__ -#include "api/yajl_common.h" +#include "extThree20JSON/yajl_common.h" typedef enum { - yajl_tok_bool, + yajl_tok_bool, yajl_tok_colon, - yajl_tok_comma, + yajl_tok_comma, yajl_tok_eof, yajl_tok_error, - yajl_tok_left_brace, + yajl_tok_left_brace, yajl_tok_left_bracket, - yajl_tok_null, - yajl_tok_right_brace, + yajl_tok_null, + yajl_tok_right_brace, yajl_tok_right_bracket, /* we differentiate between integers and doubles to allow the * parser to interpret the number without re-scanning */ - yajl_tok_integer, - yajl_tok_double, + yajl_tok_integer, + yajl_tok_double, /* we differentiate between strings which require further processing, * and strings that do not */ @@ -81,7 +81,7 @@ n * error messages. * * When you pass the next chunk of data, context should be reinitialized * to zero. - * + * * Finally, the output buffer is usually just a pointer into the jsonText, * however in cases where the entity being lexed spans multiple chunks, * the lexer will buffer the entity and the data returned will be diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_parser.c b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_parser.c old mode 100644 new mode 100755 similarity index 93% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_parser.c rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_parser.c index 7fae6c6e1d..8c77d4a68c --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_parser.c +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_parser.c @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,12 +28,12 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ -#include "yajl_lex.h" -#include "yajl_parser.h" -#include "yajl_encode.h" -#include "yajl_bytestack.h" +#include "extThree20JSON/private/yajl_lex.h" +#include "extThree20JSON/private/yajl_parser.h" +#include "extThree20JSON/private/yajl_encode.h" +#include "extThree20JSON/private/yajl_bytestack.h" #include #include @@ -53,7 +53,7 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, const char * errorType = NULL; const char * errorText = NULL; char text[72]; - const char * arrow = " (right here) ------^\n"; + const char * arrow = " (right here) ------^\n"; if (yajl_bs_current(hand->stateStack) == yajl_state_parse_error) { errorType = "parse"; @@ -70,18 +70,18 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, memneeded += strlen(errorType); memneeded += strlen(" error"); if (errorText != NULL) { - memneeded += strlen(": "); - memneeded += strlen(errorText); + memneeded += strlen(": "); + memneeded += strlen(errorText); } str = (unsigned char *) YA_MALLOC(&(hand->alloc), memneeded + 2); str[0] = 0; strcat((char *) str, errorType); - strcat((char *) str, " error"); + strcat((char *) str, " error"); if (errorText != NULL) { - strcat((char *) str, ": "); - strcat((char *) str, errorText); + strcat((char *) str, ": "); + strcat((char *) str, errorText); } - strcat((char *) str, "\n"); + strcat((char *) str, "\n"); } /* now we append as many spaces as needed to make sure the error @@ -93,7 +93,7 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, spacesNeeded = (offset < 30 ? 40 - offset : 10); start = (offset >= 30 ? offset - 30 : 0); end = (offset + 30 > jsonTextLen ? jsonTextLen : offset + 30); - + for (i=0;ialloc), str); str = (unsigned char *) newStr; } @@ -145,14 +145,14 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, unsigned int * offset = &(hand->bytesConsumed); *offset = 0; - + around_again: switch (yajl_bs_current(hand->stateStack)) { case yajl_state_parse_complete: return yajl_status_ok; case yajl_state_lexical_error: - case yajl_state_parse_error: + case yajl_state_parse_error: return yajl_status_error; case yajl_state_start: case yajl_state_map_need_val: @@ -190,13 +190,13 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, yajl_buf_len(hand->decodeBuf))); } break; - case yajl_tok_bool: + case yajl_tok_bool: if (hand->callbacks && hand->callbacks->yajl_boolean) { _CC_CHK(hand->callbacks->yajl_boolean(hand->ctx, *buf == 't')); } break; - case yajl_tok_null: + case yajl_tok_null: if (hand->callbacks && hand->callbacks->yajl_null) { _CC_CHK(hand->callbacks->yajl_null(hand->ctx)); } @@ -290,13 +290,13 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, _CC_CHK(hand->callbacks->yajl_end_array(hand->ctx)); } yajl_bs_pop(hand->stateStack); - goto around_again; + goto around_again; } /* intentional fall-through */ } - case yajl_tok_colon: - case yajl_tok_comma: - case yajl_tok_right_bracket: + case yajl_tok_colon: + case yajl_tok_comma: + case yajl_tok_right_bracket: yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "unallowed token at this point in JSON text"; @@ -313,7 +313,7 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, yajl_bs_set(hand->stateStack, yajl_state_parse_complete); } else if (s == yajl_state_map_need_val) { yajl_bs_set(hand->stateStack, yajl_state_map_got_val); - } else { + } else { yajl_bs_set(hand->stateStack, yajl_state_array_got_val); } } @@ -323,7 +323,7 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, goto around_again; } - case yajl_state_map_start: + case yajl_state_map_start: case yajl_state_map_need_key: { /* only difference between these two states is that in * start '}' is valid, whereas in need_key, we've parsed @@ -359,12 +359,12 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, _CC_CHK(hand->callbacks->yajl_end_map(hand->ctx)); } yajl_bs_pop(hand->stateStack); - goto around_again; + goto around_again; } default: yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = - "invalid object key (must be a string)"; + "invalid object key (must be a string)"; goto around_again; } } @@ -374,7 +374,7 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, switch (tok) { case yajl_tok_colon: yajl_bs_set(hand->stateStack, yajl_state_map_need_val); - goto around_again; + goto around_again; case yajl_tok_eof: return yajl_status_insufficient_data; case yajl_tok_error: @@ -396,10 +396,10 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, _CC_CHK(hand->callbacks->yajl_end_map(hand->ctx)); } yajl_bs_pop(hand->stateStack); - goto around_again; + goto around_again; case yajl_tok_comma: yajl_bs_set(hand->stateStack, yajl_state_map_need_key); - goto around_again; + goto around_again; case yajl_tok_eof: return yajl_status_insufficient_data; case yajl_tok_error: @@ -407,8 +407,8 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, goto around_again; default: yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = "after key and value, inside map, " - "I expect ',' or '}'"; + hand->parseError = "after key and value, inside map, " + "I expect ',' or '}'"; /* try to restore error offset */ if (*offset >= bufLen) *offset -= bufLen; else *offset = 0; @@ -424,10 +424,10 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, _CC_CHK(hand->callbacks->yajl_end_array(hand->ctx)); } yajl_bs_pop(hand->stateStack); - goto around_again; + goto around_again; case yajl_tok_comma: yajl_bs_set(hand->stateStack, yajl_state_array_need_val); - goto around_again; + goto around_again; case yajl_tok_eof: return yajl_status_insufficient_data; case yajl_tok_error: @@ -441,7 +441,7 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, } } } - + abort(); return yajl_status_error; } diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_parser.h b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_parser.h old mode 100644 new mode 100755 similarity index 93% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_parser.h rename to src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_parser.h index f72f3de6ed..a30a19c85c --- a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/src/yajl_parser.h +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_parser.h @@ -1,22 +1,22 @@ /* * Copyright 2010, Lloyd Hilaiel. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * 3. Neither the name of Lloyd Hilaiel nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,14 +28,14 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ + */ #ifndef __YAJL_PARSER_H__ #define __YAJL_PARSER_H__ -#include "api/yajl_parse.h" -#include "yajl_bytestack.h" -#include "yajl_buf.h" +#include "extThree20JSON/yajl_parse.h" +#include "extThree20JSON/private/yajl_bytestack.h" +#include "extThree20JSON/private/yajl_buf.h" typedef enum { @@ -44,7 +44,7 @@ typedef enum { yajl_state_parse_error, yajl_state_lexical_error, yajl_state_map_start, - yajl_state_map_sep, + yajl_state_map_sep, yajl_state_map_need_val, yajl_state_map_got_val, yajl_state_map_need_key, diff --git a/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_version.c b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_version.c new file mode 100755 index 0000000000..d57433af72 --- /dev/null +++ b/src/extThree20JSON/Vendors/YAJL/yajl/src/yajl_version.c @@ -0,0 +1,7 @@ +#include + +int yajl_version(void) +{ + return YAJL_VERSION; +} + diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/CMakeLists.txt b/src/extThree20JSON/Vendors/YAJL/yajl/test/CMakeLists.txt old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/CMakeLists.txt rename to src/extThree20JSON/Vendors/YAJL/yajl/test/CMakeLists.txt diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array_close.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array_close.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array_close.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array_close.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array_close.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array_close.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array_close.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array_close.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array_open.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array_open.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array_open.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array_open.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array_open.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array_open.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/array_open.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/array_open.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/bogus_char.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/bogus_char.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/bogus_char.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/bogus_char.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/bogus_char.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/bogus_char.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/bogus_char.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/bogus_char.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/codepoints_from_unicode_org.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/codepoints_from_unicode_org.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/codepoints_from_unicode_org.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/codepoints_from_unicode_org.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/codepoints_from_unicode_org.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/codepoints_from_unicode_org.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/codepoints_from_unicode_org.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/codepoints_from_unicode_org.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/dc_simple_with_comments.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/dc_simple_with_comments.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/dc_simple_with_comments.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/dc_simple_with_comments.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/dc_simple_with_comments.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/dc_simple_with_comments.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/dc_simple_with_comments.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/dc_simple_with_comments.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/deep_arrays.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/deep_arrays.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/deep_arrays.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/deep_arrays.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/deep_arrays.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/deep_arrays.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/deep_arrays.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/deep_arrays.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/difficult_json_c_test_case.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/difficult_json_c_test_case.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/difficult_json_c_test_case.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/difficult_json_c_test_case.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/difficult_json_c_test_case.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/difficult_json_c_test_case.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/difficult_json_c_test_case.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/difficult_json_c_test_case.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/difficult_json_c_test_case_with_comments.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/difficult_json_c_test_case_with_comments.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/difficult_json_c_test_case_with_comments.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/difficult_json_c_test_case_with_comments.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/difficult_json_c_test_case_with_comments.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/difficult_json_c_test_case_with_comments.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/difficult_json_c_test_case_with_comments.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/difficult_json_c_test_case_with_comments.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/doubles.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/doubles.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/doubles.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/doubles.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/doubles.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/doubles.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/doubles.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/doubles.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/empty_array.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/empty_array.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/empty_array.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/empty_array.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/empty_array.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/empty_array.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/empty_array.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/empty_array.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/empty_string.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/empty_string.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/empty_string.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/empty_string.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/empty_string.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/empty_string.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/empty_string.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/empty_string.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/escaped_bulgarian.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/escaped_bulgarian.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/escaped_bulgarian.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/escaped_bulgarian.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/escaped_bulgarian.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/escaped_bulgarian.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/escaped_bulgarian.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/escaped_bulgarian.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/escaped_foobar.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/escaped_foobar.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/escaped_foobar.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/escaped_foobar.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/escaped_foobar.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/escaped_foobar.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/escaped_foobar.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/escaped_foobar.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/false.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/false.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/false.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/false.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/false.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/false.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/false.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/false.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/false_then_garbage.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/false_then_garbage.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/false_then_garbage.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/false_then_garbage.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/false_then_garbage.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/false_then_garbage.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/false_then_garbage.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/false_then_garbage.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/four_byte_utf8.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/four_byte_utf8.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/four_byte_utf8.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/four_byte_utf8.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/four_byte_utf8.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/four_byte_utf8.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/four_byte_utf8.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/four_byte_utf8.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/integers.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/integers.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/integers.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/integers.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/integers.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/integers.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/integers.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/integers.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/invalid_utf8.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/invalid_utf8.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/invalid_utf8.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/invalid_utf8.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/invalid_utf8.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/invalid_utf8.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/invalid_utf8.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/invalid_utf8.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/isolated_surrogate_marker.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/isolated_surrogate_marker.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/isolated_surrogate_marker.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/isolated_surrogate_marker.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/isolated_surrogate_marker.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/isolated_surrogate_marker.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/isolated_surrogate_marker.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/isolated_surrogate_marker.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/leading_zero_in_number.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/leading_zero_in_number.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/leading_zero_in_number.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/leading_zero_in_number.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/leading_zero_in_number.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/leading_zero_in_number.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/leading_zero_in_number.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/leading_zero_in_number.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/lonely_minus_sign.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/lonely_minus_sign.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/lonely_minus_sign.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/lonely_minus_sign.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/lonely_minus_sign.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/lonely_minus_sign.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/lonely_minus_sign.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/lonely_minus_sign.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/lonely_number.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/lonely_number.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/lonely_number.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/lonely_number.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/lonely_number.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/lonely_number.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/lonely_number.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/lonely_number.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/map_close.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/map_close.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/map_close.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/map_close.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/map_close.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/map_close.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/map_close.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/map_close.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/map_open.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/map_open.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/map_open.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/map_open.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/map_open.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/map_open.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/map_open.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/map_open.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/missing_integer_after_decimal_point.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/missing_integer_after_decimal_point.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/missing_integer_after_decimal_point.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/missing_integer_after_decimal_point.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/missing_integer_after_decimal_point.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/missing_integer_after_decimal_point.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/missing_integer_after_decimal_point.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/missing_integer_after_decimal_point.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/missing_integer_after_exponent.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/missing_integer_after_exponent.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/missing_integer_after_exponent.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/missing_integer_after_exponent.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/missing_integer_after_exponent.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/missing_integer_after_exponent.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/missing_integer_after_exponent.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/missing_integer_after_exponent.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/non_utf8_char_in_string.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/non_utf8_char_in_string.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/non_utf8_char_in_string.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/non_utf8_char_in_string.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/non_utf8_char_in_string.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/non_utf8_char_in_string.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/non_utf8_char_in_string.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/non_utf8_char_in_string.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/null.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/null.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/null.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/null.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/null.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/null.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/null.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/null.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/null_then_garbage.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/null_then_garbage.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/null_then_garbage.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/null_then_garbage.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/null_then_garbage.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/null_then_garbage.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/null_then_garbage.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/null_then_garbage.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/nulls_and_bools.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/nulls_and_bools.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/nulls_and_bools.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/nulls_and_bools.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/nulls_and_bools.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/nulls_and_bools.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/nulls_and_bools.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/nulls_and_bools.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/simple.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/simple.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/simple.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/simple.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/simple.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/simple.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/simple.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/simple.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/simple_with_comments.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/simple_with_comments.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/simple_with_comments.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/simple_with_comments.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/simple_with_comments.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/simple_with_comments.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/simple_with_comments.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/simple_with_comments.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_invalid_escape.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_invalid_escape.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_invalid_escape.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_invalid_escape.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_invalid_escape.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_invalid_escape.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_invalid_escape.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_invalid_escape.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_invalid_hex_char.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_invalid_hex_char.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_invalid_hex_char.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_invalid_hex_char.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_invalid_hex_char.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_invalid_hex_char.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_invalid_hex_char.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_invalid_hex_char.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_with_escapes.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_with_escapes.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_with_escapes.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_with_escapes.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_with_escapes.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_with_escapes.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_with_escapes.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_with_escapes.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_with_invalid_newline.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_with_invalid_newline.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_with_invalid_newline.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_with_invalid_newline.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_with_invalid_newline.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_with_invalid_newline.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/string_with_invalid_newline.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/string_with_invalid_newline.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/three_byte_utf8.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/three_byte_utf8.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/three_byte_utf8.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/three_byte_utf8.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/three_byte_utf8.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/three_byte_utf8.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/three_byte_utf8.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/three_byte_utf8.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/true.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/true.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/true.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/true.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/true.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/true.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/true.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/true.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/true_then_garbage.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/true_then_garbage.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/true_then_garbage.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/true_then_garbage.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/true_then_garbage.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/true_then_garbage.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/true_then_garbage.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/true_then_garbage.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/unescaped_bulgarian.json b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/unescaped_bulgarian.json old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/unescaped_bulgarian.json rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/unescaped_bulgarian.json diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/unescaped_bulgarian.json.gold b/src/extThree20JSON/Vendors/YAJL/yajl/test/cases/unescaped_bulgarian.json.gold old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/cases/unescaped_bulgarian.json.gold rename to src/extThree20JSON/Vendors/YAJL/yajl/test/cases/unescaped_bulgarian.json.gold diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/run_tests.sh b/src/extThree20JSON/Vendors/YAJL/yajl/test/run_tests.sh similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/run_tests.sh rename to src/extThree20JSON/Vendors/YAJL/yajl/test/run_tests.sh diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/yajl_test.c b/src/extThree20JSON/Vendors/YAJL/yajl/test/yajl_test.c old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/test/yajl_test.c rename to src/extThree20JSON/Vendors/YAJL/yajl/test/yajl_test.c diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/verify/CMakeLists.txt b/src/extThree20JSON/Vendors/YAJL/yajl/verify/CMakeLists.txt old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/verify/CMakeLists.txt rename to src/extThree20JSON/Vendors/YAJL/yajl/verify/CMakeLists.txt diff --git a/src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/verify/json_verify.c b/src/extThree20JSON/Vendors/YAJL/yajl/verify/json_verify.c old mode 100644 new mode 100755 similarity index 100% rename from src/extThree20JSON/Vendors/YAJL/yajl-1.0.9/verify/json_verify.c rename to src/extThree20JSON/Vendors/YAJL/yajl/verify/json_verify.c diff --git a/src/extThree20JSON/extThree20JSON.xcodeproj/project.pbxproj b/src/extThree20JSON/extThree20JSON.xcodeproj/project.pbxproj index 3e1a12b66e..64483992ac 100755 --- a/src/extThree20JSON/extThree20JSON.xcodeproj/project.pbxproj +++ b/src/extThree20JSON/extThree20JSON.xcodeproj/project.pbxproj @@ -3,54 +3,81 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 6609981B129397F5007B1E07 /* TTExtensionLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 66099817129397F5007B1E07 /* TTExtensionLoader.m */; }; + 6609981F129397F5007B1E07 /* TTExtensionLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 66099817129397F5007B1E07 /* TTExtensionLoader.m */; }; + 6609982212939800007B1E07 /* TTExtensionLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 6609982012939800007B1E07 /* TTExtensionLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6609982412939800007B1E07 /* TTExtensionLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 6609982012939800007B1E07 /* TTExtensionLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6609987112939B06007B1E07 /* GTMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6609986D12939B06007B1E07 /* GTMBase64.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6609987212939B06007B1E07 /* GTMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 6609986E12939B06007B1E07 /* GTMBase64.m */; }; + 664B29E912848B1A0008D569 /* TTErrorCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 664B29E812848B1A0008D569 /* TTErrorCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 664B29EC12848B1A0008D569 /* TTErrorCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 664B29E812848B1A0008D569 /* TTErrorCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 664B29F012848B270008D569 /* TTErrorCodes.m in Sources */ = {isa = PBXBuildFile; fileRef = 664B29EF12848B270008D569 /* TTErrorCodes.m */; }; + 664B29F312848B270008D569 /* TTErrorCodes.m in Sources */ = {isa = PBXBuildFile; fileRef = 664B29EF12848B270008D569 /* TTErrorCodes.m */; }; + 66A16605134266380052CA46 /* NSBundle+YAJL.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A16603134266380052CA46 /* NSBundle+YAJL.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66A16606134266380052CA46 /* NSBundle+YAJL.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A16604134266380052CA46 /* NSBundle+YAJL.m */; }; + 66A1663513427CD10052CA46 /* GHNSBundle+Utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A1663313427CD10052CA46 /* GHNSBundle+Utils.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 66A1663613427CD10052CA46 /* GHNSBundle+Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A1663413427CD10052CA46 /* GHNSBundle+Utils.m */; }; + 66E71B9112938CE3007134B0 /* yajl_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71B5A12938CE3007134B0 /* yajl_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66E71B9212938CE3007134B0 /* yajl_gen.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71B5B12938CE3007134B0 /* yajl_gen.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66E71B9312938CE3007134B0 /* yajl_parse.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71B5C12938CE3007134B0 /* yajl_parse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66E71B9412938CE3007134B0 /* yajl.c in Sources */ = {isa = PBXBuildFile; fileRef = 66E71B6012938CE3007134B0 /* yajl.c */; }; + 66E71B9512938CE3007134B0 /* yajl_alloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 66E71B6212938CE3007134B0 /* yajl_alloc.c */; }; + 66E71B9612938CE3007134B0 /* yajl_alloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71B6312938CE3007134B0 /* yajl_alloc.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 66E71B9712938CE3007134B0 /* yajl_buf.c in Sources */ = {isa = PBXBuildFile; fileRef = 66E71B6412938CE3007134B0 /* yajl_buf.c */; }; + 66E71B9812938CE3007134B0 /* yajl_buf.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71B6512938CE3007134B0 /* yajl_buf.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 66E71B9912938CE3007134B0 /* yajl_bytestack.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71B6612938CE3007134B0 /* yajl_bytestack.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 66E71B9A12938CE3007134B0 /* yajl_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 66E71B6712938CE3007134B0 /* yajl_encode.c */; }; + 66E71B9B12938CE3007134B0 /* yajl_encode.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71B6812938CE3007134B0 /* yajl_encode.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 66E71B9C12938CE3007134B0 /* yajl_gen.c in Sources */ = {isa = PBXBuildFile; fileRef = 66E71B6912938CE3007134B0 /* yajl_gen.c */; }; + 66E71B9D12938CE3007134B0 /* yajl_lex.c in Sources */ = {isa = PBXBuildFile; fileRef = 66E71B6A12938CE3007134B0 /* yajl_lex.c */; }; + 66E71B9E12938CE3007134B0 /* yajl_lex.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71B6B12938CE3007134B0 /* yajl_lex.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 66E71B9F12938CE3007134B0 /* yajl_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 66E71B6C12938CE3007134B0 /* yajl_parser.c */; }; + 66E71BA012938CE3007134B0 /* yajl_parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71B6D12938CE3007134B0 /* yajl_parser.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 66E71BA112938CE3007134B0 /* yajl_version.c in Sources */ = {isa = PBXBuildFile; fileRef = 66E71B6E12938CE3007134B0 /* yajl_version.c */; }; + 66E71BA812938CF8007134B0 /* yajl_version.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E71BA512938CF8007134B0 /* yajl_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D269ECE13CB5BC80006FE1F /* SBJsonTokeniser.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D269EC013CB5BC80006FE1F /* SBJsonTokeniser.m */; }; + 6D269ECF13CB5BC80006FE1F /* SBJsonTokeniser.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D269EC113CB5BC80006FE1F /* SBJsonTokeniser.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D269ED013CB5BC80006FE1F /* SBJsonStreamWriterState.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D269EC213CB5BC80006FE1F /* SBJsonStreamWriterState.m */; }; + 6D269ED113CB5BC80006FE1F /* SBJsonStreamWriterState.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D269EC313CB5BC80006FE1F /* SBJsonStreamWriterState.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D269ED213CB5BC80006FE1F /* SBJsonStreamWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D269EC413CB5BC80006FE1F /* SBJsonStreamWriter.m */; }; + 6D269ED313CB5BC80006FE1F /* SBJsonStreamWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D269EC513CB5BC80006FE1F /* SBJsonStreamWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D269ED413CB5BC80006FE1F /* SBJsonStreamParserState.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D269EC613CB5BC80006FE1F /* SBJsonStreamParserState.m */; }; + 6D269ED513CB5BC80006FE1F /* SBJsonStreamParserState.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D269EC713CB5BC80006FE1F /* SBJsonStreamParserState.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D269ED613CB5BC80006FE1F /* SBJsonStreamParserAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D269EC813CB5BC80006FE1F /* SBJsonStreamParserAdapter.m */; }; + 6D269ED713CB5BC80006FE1F /* SBJsonStreamParserAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D269EC913CB5BC80006FE1F /* SBJsonStreamParserAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D269ED813CB5BC80006FE1F /* SBJsonStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D269ECA13CB5BC80006FE1F /* SBJsonStreamParser.m */; }; + 6D269ED913CB5BC80006FE1F /* SBJsonStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D269ECB13CB5BC80006FE1F /* SBJsonStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D58F0B413E8ECC700E9CE78 /* NSString+SBJSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D58F0B213E8ECC500E9CE78 /* NSString+SBJSON.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D58F0B513E8ECC700E9CE78 /* NSString+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D58F0B313E8ECC600E9CE78 /* NSString+SBJSON.m */; }; + 6D58F0BE13E8ED1B00E9CE78 /* SBJson.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D58F0B713E8ED1900E9CE78 /* SBJson.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D58F0BF13E8ED1C00E9CE78 /* SBJsonStreamParserAccumulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D58F0B813E8ED1900E9CE78 /* SBJsonStreamParserAccumulator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D58F0C013E8ED1C00E9CE78 /* SBJsonStreamParserAccumulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D58F0B913E8ED1A00E9CE78 /* SBJsonStreamParserAccumulator.m */; }; + 6D58F0C113E8ED1C00E9CE78 /* SBJsonStreamWriterAccumulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D58F0BA13E8ED1A00E9CE78 /* SBJsonStreamWriterAccumulator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D58F0C213E8ED1C00E9CE78 /* SBJsonStreamWriterAccumulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D58F0BB13E8ED1A00E9CE78 /* SBJsonStreamWriterAccumulator.m */; }; + 6D58F0C313E8ED1C00E9CE78 /* SBJsonUTF8Stream.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D58F0BC13E8ED1B00E9CE78 /* SBJsonUTF8Stream.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D58F0C413E8ED1C00E9CE78 /* SBJsonUTF8Stream.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D58F0BD13E8ED1B00E9CE78 /* SBJsonUTF8Stream.m */; }; 6E645A1D11876C9800F08CB1 /* TTURLJSONResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A1A11876C9800F08CB1 /* TTURLJSONResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645A1E11876C9800F08CB1 /* TTURLJSONResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645A1C11876C9800F08CB1 /* TTURLJSONResponse.m */; }; - 6E645A3011876CA800F08CB1 /* JSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A2211876CA800F08CB1 /* JSON.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645A3111876CA800F08CB1 /* NSObject+SBJSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A2311876CA800F08CB1 /* NSObject+SBJSON.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645A3211876CA800F08CB1 /* NSObject+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645A2411876CA800F08CB1 /* NSObject+SBJSON.m */; }; - 6E645A3311876CA800F08CB1 /* NSString+SBJSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A2511876CA800F08CB1 /* NSString+SBJSON.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6E645A3411876CA800F08CB1 /* NSString+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645A2611876CA800F08CB1 /* NSString+SBJSON.m */; }; - 6E645A3511876CA800F08CB1 /* SBJSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A2811876CA800F08CB1 /* SBJSON.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6E645A3611876CA800F08CB1 /* SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645A2911876CA800F08CB1 /* SBJSON.m */; }; - 6E645A3711876CA800F08CB1 /* SBJsonBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A2A11876CA800F08CB1 /* SBJsonBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6E645A3811876CA800F08CB1 /* SBJsonBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645A2B11876CA800F08CB1 /* SBJsonBase.m */; }; - 6E645A3911876CA800F08CB1 /* SBJsonParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A2C11876CA800F08CB1 /* SBJsonParser.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6E645A3911876CA800F08CB1 /* SBJsonParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A2C11876CA800F08CB1 /* SBJsonParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645A3A11876CA800F08CB1 /* SBJsonParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645A2D11876CA800F08CB1 /* SBJsonParser.m */; }; - 6E645A3B11876CA800F08CB1 /* SBJsonWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A2E11876CA800F08CB1 /* SBJsonWriter.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6E645A3B11876CA800F08CB1 /* SBJsonWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A2E11876CA800F08CB1 /* SBJsonWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645A3C11876CA800F08CB1 /* SBJsonWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645A2F11876CA800F08CB1 /* SBJsonWriter.m */; }; 6E645A9A11876E0400F08CB1 /* extJSONTests+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645A6511876D2900F08CB1 /* extJSONTests+SBJSON.m */; }; 6E645AA111876E2B00F08CB1 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E645A7011876D3F00F08CB1 /* libThree20Core.a */; }; - 6E645AA211876E2D00F08CB1 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E645A7911876D4600F08CB1 /* libThree20Network.a */; }; 6E645BA91187751200F08CB1 /* TTURLJSONResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645A1A11876C9800F08CB1 /* TTURLJSONResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6E645BB11187751200F08CB1 /* YAJL_GTMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645AFA1187744C00F08CB1 /* YAJL_GTMBase64.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645BB21187751200F08CB1 /* NSObject+YAJL.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645AFD1187744C00F08CB1 /* NSObject+YAJL.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6E645BB31187751200F08CB1 /* yajl_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B0D1187744C00F08CB1 /* yajl_common.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6E645BB41187751200F08CB1 /* yajl_gen.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B0E1187744C00F08CB1 /* yajl_gen.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6E645BB51187751200F08CB1 /* yajl_parse.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B0F1187744C00F08CB1 /* yajl_parse.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6E645BB61187751200F08CB1 /* yajl_alloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B151187744C00F08CB1 /* yajl_alloc.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6E645BB71187751200F08CB1 /* yajl_buf.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B171187744C00F08CB1 /* yajl_buf.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6E645BB81187751200F08CB1 /* yajl_bytestack.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B181187744C00F08CB1 /* yajl_bytestack.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6E645BB91187751200F08CB1 /* yajl_encode.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B1A1187744C00F08CB1 /* yajl_encode.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6E645BBA1187751200F08CB1 /* yajl_lex.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B1D1187744C00F08CB1 /* yajl_lex.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6E645BBB1187751200F08CB1 /* yajl_parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B1F1187744C00F08CB1 /* yajl_parser.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6E645BBC1187751200F08CB1 /* YAJL.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B7C1187744D00F08CB1 /* YAJL.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645BBD1187751200F08CB1 /* YAJLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B7D1187744D00F08CB1 /* YAJLDocument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645BBE1187751200F08CB1 /* YAJLGen.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B7F1187744D00F08CB1 /* YAJLGen.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645BBF1187751200F08CB1 /* YAJLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E645B811187744D00F08CB1 /* YAJLParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E645BC11187751200F08CB1 /* TTURLJSONResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645A1C11876C9800F08CB1 /* TTURLJSONResponse.m */; }; - 6E645BC81187751200F08CB1 /* YAJL_GTMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645AFB1187744C00F08CB1 /* YAJL_GTMBase64.m */; }; 6E645BC91187751200F08CB1 /* NSObject+YAJL.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645AFE1187744C00F08CB1 /* NSObject+YAJL.m */; }; - 6E645BCA1187751200F08CB1 /* yajl.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B121187744C00F08CB1 /* yajl.c */; }; - 6E645BCB1187751200F08CB1 /* yajl_alloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B141187744C00F08CB1 /* yajl_alloc.c */; }; - 6E645BCC1187751200F08CB1 /* yajl_buf.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B161187744C00F08CB1 /* yajl_buf.c */; }; - 6E645BCD1187751200F08CB1 /* yajl_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B191187744C00F08CB1 /* yajl_encode.c */; }; - 6E645BCE1187751200F08CB1 /* yajl_gen.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B1B1187744C00F08CB1 /* yajl_gen.c */; }; - 6E645BCF1187751200F08CB1 /* yajl_lex.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B1C1187744C00F08CB1 /* yajl_lex.c */; }; - 6E645BD01187751200F08CB1 /* yajl_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B1E1187744C00F08CB1 /* yajl_parser.c */; }; 6E645BD11187751200F08CB1 /* YAJLDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B7E1187744D00F08CB1 /* YAJLDocument.m */; }; 6E645BD21187751200F08CB1 /* YAJLGen.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B801187744D00F08CB1 /* YAJLGen.m */; }; 6E645BD31187751200F08CB1 /* YAJLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E645B821187744D00F08CB1 /* YAJLParser.m */; }; @@ -60,30 +87,30 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 6E645A6F11876D3F00F08CB1 /* PBXContainerItemProxy */ = { + 2DA08A0714B796A100E7E492 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 6E645A6A11876D3F00F08CB1 /* Three20Core.xcodeproj */; + containerPortal = 6E645A7311876D4600F08CB1 /* Three20Network.xcodeproj */; proxyType = 2; remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; - remoteInfo = Three20Core; + remoteInfo = Three20Network; }; - 6E645A7111876D3F00F08CB1 /* PBXContainerItemProxy */ = { + 2DA08A0914B796A100E7E492 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 6E645A6A11876D3F00F08CB1 /* Three20Core.xcodeproj */; + containerPortal = 6E645A7311876D4600F08CB1 /* Three20Network.xcodeproj */; proxyType = 2; remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; - remoteInfo = UnitTests; + remoteInfo = Three20NetworkUnitTests; }; - 6E645A7811876D4600F08CB1 /* PBXContainerItemProxy */ = { + 6E645A6F11876D3F00F08CB1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 6E645A7311876D4600F08CB1 /* Three20Network.xcodeproj */; + containerPortal = 6E645A6A11876D3F00F08CB1 /* Three20Core.xcodeproj */; proxyType = 2; remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; - remoteInfo = Three20Network; + remoteInfo = Three20Core; }; - 6E645A7A11876D4600F08CB1 /* PBXContainerItemProxy */ = { + 6E645A7111876D3F00F08CB1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 6E645A7311876D4600F08CB1 /* Three20Network.xcodeproj */; + containerPortal = 6E645A6A11876D3F00F08CB1 /* Three20Core.xcodeproj */; proxyType = 2; remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; @@ -140,20 +167,71 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 6E55A4B31183CA80002768DE /* Library.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Library.xcconfig; path = Configurations/Library.xcconfig; sourceTree = ""; }; + 66099817129397F5007B1E07 /* TTExtensionLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTExtensionLoader.m; path = Source/TTExtensionLoader.m; sourceTree = ""; }; + 6609982012939800007B1E07 /* TTExtensionLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTExtensionLoader.h; path = Headers/TTExtensionLoader.h; sourceTree = ""; }; + 6609986D12939B06007B1E07 /* GTMBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMBase64.h; sourceTree = ""; }; + 6609986E12939B06007B1E07 /* GTMBase64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMBase64.m; sourceTree = ""; }; + 663DB06D12661EE900CF8CEA /* Library+YAJL.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = "Library+YAJL.xcconfig"; path = "Configurations/Library+YAJL.xcconfig"; sourceTree = ""; }; + 664B29E812848B1A0008D569 /* TTErrorCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTErrorCodes.h; path = Headers/TTErrorCodes.h; sourceTree = ""; }; + 664B29EF12848B270008D569 /* TTErrorCodes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTErrorCodes.m; path = Source/TTErrorCodes.m; sourceTree = ""; }; + 66A16603134266380052CA46 /* NSBundle+YAJL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+YAJL.h"; sourceTree = ""; }; + 66A16604134266380052CA46 /* NSBundle+YAJL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+YAJL.m"; sourceTree = ""; }; + 66A1663313427CD10052CA46 /* GHNSBundle+Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GHNSBundle+Utils.h"; sourceTree = ""; }; + 66A1663413427CD10052CA46 /* GHNSBundle+Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GHNSBundle+Utils.m"; sourceTree = ""; }; + 66E71B5A12938CE3007134B0 /* yajl_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_common.h; sourceTree = ""; }; + 66E71B5B12938CE3007134B0 /* yajl_gen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_gen.h; sourceTree = ""; }; + 66E71B5C12938CE3007134B0 /* yajl_parse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_parse.h; sourceTree = ""; }; + 66E71B5D12938CE3007134B0 /* yajl_version.h.cmake */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yajl_version.h.cmake; sourceTree = ""; }; + 66E71B5E12938CE3007134B0 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; + 66E71B5F12938CE3007134B0 /* yajl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yajl; sourceTree = ""; }; + 66E71B6012938CE3007134B0 /* yajl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yajl.c; sourceTree = ""; }; + 66E71B6112938CE3007134B0 /* YAJL.dxy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = YAJL.dxy; sourceTree = ""; }; + 66E71B6212938CE3007134B0 /* yajl_alloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yajl_alloc.c; sourceTree = ""; }; + 66E71B6312938CE3007134B0 /* yajl_alloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_alloc.h; sourceTree = ""; }; + 66E71B6412938CE3007134B0 /* yajl_buf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yajl_buf.c; sourceTree = ""; }; + 66E71B6512938CE3007134B0 /* yajl_buf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_buf.h; sourceTree = ""; }; + 66E71B6612938CE3007134B0 /* yajl_bytestack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_bytestack.h; sourceTree = ""; }; + 66E71B6712938CE3007134B0 /* yajl_encode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yajl_encode.c; sourceTree = ""; }; + 66E71B6812938CE3007134B0 /* yajl_encode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_encode.h; sourceTree = ""; }; + 66E71B6912938CE3007134B0 /* yajl_gen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yajl_gen.c; sourceTree = ""; }; + 66E71B6A12938CE3007134B0 /* yajl_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yajl_lex.c; sourceTree = ""; }; + 66E71B6B12938CE3007134B0 /* yajl_lex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_lex.h; sourceTree = ""; }; + 66E71B6C12938CE3007134B0 /* yajl_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yajl_parser.c; sourceTree = ""; }; + 66E71B6D12938CE3007134B0 /* yajl_parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_parser.h; sourceTree = ""; }; + 66E71B6E12938CE3007134B0 /* yajl_version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yajl_version.c; sourceTree = ""; }; + 66E71BA512938CF8007134B0 /* yajl_version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_version.h; sourceTree = ""; }; + 6D269EC013CB5BC80006FE1F /* SBJsonTokeniser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonTokeniser.m; sourceTree = ""; }; + 6D269EC113CB5BC80006FE1F /* SBJsonTokeniser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonTokeniser.h; sourceTree = ""; }; + 6D269EC213CB5BC80006FE1F /* SBJsonStreamWriterState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamWriterState.m; sourceTree = ""; }; + 6D269EC313CB5BC80006FE1F /* SBJsonStreamWriterState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamWriterState.h; sourceTree = ""; }; + 6D269EC413CB5BC80006FE1F /* SBJsonStreamWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamWriter.m; sourceTree = ""; }; + 6D269EC513CB5BC80006FE1F /* SBJsonStreamWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamWriter.h; sourceTree = ""; }; + 6D269EC613CB5BC80006FE1F /* SBJsonStreamParserState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamParserState.m; sourceTree = ""; }; + 6D269EC713CB5BC80006FE1F /* SBJsonStreamParserState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamParserState.h; sourceTree = ""; }; + 6D269EC813CB5BC80006FE1F /* SBJsonStreamParserAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamParserAdapter.m; sourceTree = ""; }; + 6D269EC913CB5BC80006FE1F /* SBJsonStreamParserAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamParserAdapter.h; sourceTree = ""; }; + 6D269ECA13CB5BC80006FE1F /* SBJsonStreamParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamParser.m; sourceTree = ""; }; + 6D269ECB13CB5BC80006FE1F /* SBJsonStreamParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamParser.h; sourceTree = ""; }; + 6D58F0AE13E8EBA400E9CE78 /* Changes.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Changes.md; sourceTree = ""; }; + 6D58F0AF13E8EBA400E9CE78 /* Credits.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Credits.md; sourceTree = ""; }; + 6D58F0B013E8EBA500E9CE78 /* Readme.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Readme.md; sourceTree = ""; }; + 6D58F0B113E8EBA500E9CE78 /* ReleaseChecklist.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReleaseChecklist.md; sourceTree = ""; }; + 6D58F0B213E8ECC500E9CE78 /* NSString+SBJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+SBJSON.h"; sourceTree = ""; }; + 6D58F0B313E8ECC600E9CE78 /* NSString+SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+SBJSON.m"; sourceTree = ""; }; + 6D58F0B613E8ED1800E9CE78 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + 6D58F0B713E8ED1900E9CE78 /* SBJson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJson.h; sourceTree = ""; }; + 6D58F0B813E8ED1900E9CE78 /* SBJsonStreamParserAccumulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamParserAccumulator.h; sourceTree = ""; }; + 6D58F0B913E8ED1A00E9CE78 /* SBJsonStreamParserAccumulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamParserAccumulator.m; sourceTree = ""; }; + 6D58F0BA13E8ED1A00E9CE78 /* SBJsonStreamWriterAccumulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamWriterAccumulator.h; sourceTree = ""; }; + 6D58F0BB13E8ED1A00E9CE78 /* SBJsonStreamWriterAccumulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamWriterAccumulator.m; sourceTree = ""; }; + 6D58F0BC13E8ED1B00E9CE78 /* SBJsonUTF8Stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonUTF8Stream.h; sourceTree = ""; }; + 6D58F0BD13E8ED1B00E9CE78 /* SBJsonUTF8Stream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonUTF8Stream.m; sourceTree = ""; }; + 6E55A4B31183CA80002768DE /* Library+SBJSON.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = "Library+SBJSON.xcconfig"; path = "Configurations/Library+SBJSON.xcconfig"; sourceTree = ""; }; 6E6454021184BDD500F08CB1 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Project.xcconfig; path = Configurations/Project.xcconfig; sourceTree = ""; }; 6E645A1A11876C9800F08CB1 /* TTURLJSONResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTURLJSONResponse.h; path = Headers/TTURLJSONResponse.h; sourceTree = ""; }; 6E645A1C11876C9800F08CB1 /* TTURLJSONResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTURLJSONResponse.m; path = Source/TTURLJSONResponse.m; sourceTree = ""; }; - 6E645A2211876CA800F08CB1 /* JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSON.h; sourceTree = ""; }; 6E645A2311876CA800F08CB1 /* NSObject+SBJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+SBJSON.h"; sourceTree = ""; }; 6E645A2411876CA800F08CB1 /* NSObject+SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+SBJSON.m"; sourceTree = ""; }; - 6E645A2511876CA800F08CB1 /* NSString+SBJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+SBJSON.h"; sourceTree = ""; }; - 6E645A2611876CA800F08CB1 /* NSString+SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+SBJSON.m"; sourceTree = ""; }; - 6E645A2711876CA800F08CB1 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; - 6E645A2811876CA800F08CB1 /* SBJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJSON.h; sourceTree = ""; }; - 6E645A2911876CA800F08CB1 /* SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJSON.m; sourceTree = ""; }; - 6E645A2A11876CA800F08CB1 /* SBJsonBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonBase.h; sourceTree = ""; }; - 6E645A2B11876CA800F08CB1 /* SBJsonBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonBase.m; sourceTree = ""; }; 6E645A2C11876CA800F08CB1 /* SBJsonParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonParser.h; sourceTree = ""; }; 6E645A2D11876CA800F08CB1 /* SBJsonParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonParser.m; sourceTree = ""; }; 6E645A2E11876CA800F08CB1 /* SBJsonWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonWriter.h; sourceTree = ""; }; @@ -161,31 +239,10 @@ 6E645A6511876D2900F08CB1 /* extJSONTests+SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "extJSONTests+SBJSON.m"; path = "UnitTests/extJSONTests+SBJSON.m"; sourceTree = ""; }; 6E645A6A11876D3F00F08CB1 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; 6E645A7311876D4600F08CB1 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; - 6E645AFA1187744C00F08CB1 /* YAJL_GTMBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YAJL_GTMBase64.h; sourceTree = ""; }; - 6E645AFB1187744C00F08CB1 /* YAJL_GTMBase64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YAJL_GTMBase64.m; sourceTree = ""; }; 6E645AFC1187744C00F08CB1 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 6E645AFD1187744C00F08CB1 /* NSObject+YAJL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+YAJL.h"; sourceTree = ""; }; 6E645AFE1187744C00F08CB1 /* NSObject+YAJL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+YAJL.m"; sourceTree = ""; }; 6E645AFF1187744C00F08CB1 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; - 6E645B0D1187744C00F08CB1 /* yajl_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_common.h; sourceTree = ""; }; - 6E645B0E1187744C00F08CB1 /* yajl_gen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_gen.h; sourceTree = ""; }; - 6E645B0F1187744C00F08CB1 /* yajl_parse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yajl_parse.h; sourceTree = ""; }; - 6E645B101187744C00F08CB1 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CMakeLists.txt; path = src/CMakeLists.txt; sourceTree = ""; }; - 6E645B111187744C00F08CB1 /* yajl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = yajl; path = src/yajl; sourceTree = ""; }; - 6E645B121187744C00F08CB1 /* yajl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yajl.c; path = src/yajl.c; sourceTree = ""; }; - 6E645B131187744C00F08CB1 /* YAJL.dxy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = YAJL.dxy; path = src/YAJL.dxy; sourceTree = ""; }; - 6E645B141187744C00F08CB1 /* yajl_alloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yajl_alloc.c; path = src/yajl_alloc.c; sourceTree = ""; }; - 6E645B151187744C00F08CB1 /* yajl_alloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yajl_alloc.h; path = src/yajl_alloc.h; sourceTree = ""; }; - 6E645B161187744C00F08CB1 /* yajl_buf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yajl_buf.c; path = src/yajl_buf.c; sourceTree = ""; }; - 6E645B171187744C00F08CB1 /* yajl_buf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yajl_buf.h; path = src/yajl_buf.h; sourceTree = ""; }; - 6E645B181187744C00F08CB1 /* yajl_bytestack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yajl_bytestack.h; path = src/yajl_bytestack.h; sourceTree = ""; }; - 6E645B191187744C00F08CB1 /* yajl_encode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yajl_encode.c; path = src/yajl_encode.c; sourceTree = ""; }; - 6E645B1A1187744C00F08CB1 /* yajl_encode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yajl_encode.h; path = src/yajl_encode.h; sourceTree = ""; }; - 6E645B1B1187744C00F08CB1 /* yajl_gen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yajl_gen.c; path = src/yajl_gen.c; sourceTree = ""; }; - 6E645B1C1187744C00F08CB1 /* yajl_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yajl_lex.c; path = src/yajl_lex.c; sourceTree = ""; }; - 6E645B1D1187744C00F08CB1 /* yajl_lex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yajl_lex.h; path = src/yajl_lex.h; sourceTree = ""; }; - 6E645B1E1187744C00F08CB1 /* yajl_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yajl_parser.c; path = src/yajl_parser.c; sourceTree = ""; }; - 6E645B1F1187744C00F08CB1 /* yajl_parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yajl_parser.h; path = src/yajl_parser.h; sourceTree = ""; }; 6E645B7C1187744D00F08CB1 /* YAJL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YAJL.h; sourceTree = ""; }; 6E645B7D1187744D00F08CB1 /* YAJLDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YAJLDocument.h; sourceTree = ""; }; 6E645B7E1187744D00F08CB1 /* YAJLDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YAJLDocument.m; sourceTree = ""; }; @@ -198,9 +255,9 @@ 6E645BF81187771D00F08CB1 /* extThree20JSON+YAJL_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "extThree20JSON+YAJL_Prefix.pch"; path = "Headers/extThree20JSON+YAJL_Prefix.pch"; sourceTree = ""; }; 6E6462111187DD2A00F08CB1 /* extThree20JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = extThree20JSON.h; path = Headers/extThree20JSON.h; sourceTree = ""; }; 6EB460921183D16000685649 /* UnitTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "UnitTests-Info.plist"; path = "UnitTests/Resources/PropertyLists/UnitTests-Info.plist"; sourceTree = ""; }; - 6EB460A61183D2AC00685649 /* UnitTests.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = UnitTests.xcconfig; path = Configurations/UnitTests.xcconfig; sourceTree = ""; }; + 6EB460A61183D2AC00685649 /* UnitTests+SBJSON.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = "UnitTests+SBJSON.xcconfig"; path = "Configurations/UnitTests+SBJSON.xcconfig"; sourceTree = ""; }; BEF31F3A0F352DF5000DE5D2 /* libextThree20JSON+SBJSON.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libextThree20JSON+SBJSON.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - EB9E6C6210B6A8F800DE563C /* extJSONUnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = extJSONUnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB9E6C6210B6A8F800DE563C /* extJSONUnitTests+SBJSON.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "extJSONUnitTests+SBJSON.octest"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -224,7 +281,6 @@ files = ( 6EB460DA1183D8CB00685649 /* libextThree20JSON+SBJSON.a in Frameworks */, 6E645AA111876E2B00F08CB1 /* libThree20Core.a in Frameworks */, - 6E645AA211876E2D00F08CB1 /* libThree20Network.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -235,8 +291,8 @@ isa = PBXGroup; children = ( BEF31F3A0F352DF5000DE5D2 /* libextThree20JSON+SBJSON.a */, - EB9E6C6210B6A8F800DE563C /* extJSONUnitTests.octest */, 6E645BD91187751200F08CB1 /* libextThree20JSON+YAJL.a */, + EB9E6C6210B6A8F800DE563C /* extJSONUnitTests+SBJSON.octest */, ); name = Products; sourceTree = ""; @@ -247,6 +303,8 @@ 6E6462111187DD2A00F08CB1 /* extThree20JSON.h */, 6E645BF71187771D00F08CB1 /* extThree20JSON+SBJSON_Prefix.pch */, 6E645BF81187771D00F08CB1 /* extThree20JSON+YAJL_Prefix.pch */, + 6609982012939800007B1E07 /* TTExtensionLoader.h */, + 66099817129397F5007B1E07 /* TTExtensionLoader.m */, 6EB4609C1183D1E000685649 /* Source */, 6E645A4311876CFE00F08CB1 /* Dependencies */, 6ED118E41183C38A0096AEBF /* Configurations */, @@ -256,6 +314,62 @@ name = CustomTemplate; sourceTree = ""; }; + 2DA089D314B7968700E7E492 /* Products */ = { + isa = PBXGroup; + children = ( + 2DA08A0814B796A100E7E492 /* libThree20Network.a */, + 2DA08A0A14B796A100E7E492 /* NetworkUnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 66A1663213427CD10052CA46 /* GHKit */ = { + isa = PBXGroup; + children = ( + 66A1663313427CD10052CA46 /* GHNSBundle+Utils.h */, + 66A1663413427CD10052CA46 /* GHNSBundle+Utils.m */, + ); + path = GHKit; + sourceTree = ""; + }; + 66E71B5812938CE3007134B0 /* src */ = { + isa = PBXGroup; + children = ( + 66E71B5912938CE3007134B0 /* api */, + 66E71B5E12938CE3007134B0 /* CMakeLists.txt */, + 66E71B5F12938CE3007134B0 /* yajl */, + 66E71B6012938CE3007134B0 /* yajl.c */, + 66E71B6112938CE3007134B0 /* YAJL.dxy */, + 66E71B6212938CE3007134B0 /* yajl_alloc.c */, + 66E71B6312938CE3007134B0 /* yajl_alloc.h */, + 66E71B6412938CE3007134B0 /* yajl_buf.c */, + 66E71B6512938CE3007134B0 /* yajl_buf.h */, + 66E71B6612938CE3007134B0 /* yajl_bytestack.h */, + 66E71B6712938CE3007134B0 /* yajl_encode.c */, + 66E71B6812938CE3007134B0 /* yajl_encode.h */, + 66E71B6912938CE3007134B0 /* yajl_gen.c */, + 66E71B6A12938CE3007134B0 /* yajl_lex.c */, + 66E71B6B12938CE3007134B0 /* yajl_lex.h */, + 66E71B6C12938CE3007134B0 /* yajl_parser.c */, + 66E71B6D12938CE3007134B0 /* yajl_parser.h */, + 66E71B6E12938CE3007134B0 /* yajl_version.c */, + ); + name = src; + path = yajl/src; + sourceTree = ""; + }; + 66E71B5912938CE3007134B0 /* api */ = { + isa = PBXGroup; + children = ( + 66E71B5A12938CE3007134B0 /* yajl_common.h */, + 66E71B5B12938CE3007134B0 /* yajl_gen.h */, + 66E71B5C12938CE3007134B0 /* yajl_parse.h */, + 66E71BA512938CF8007134B0 /* yajl_version.h */, + 66E71B5D12938CE3007134B0 /* yajl_version.h.cmake */, + ); + path = api; + sourceTree = ""; + }; 6E645A1F11876CA800F08CB1 /* Vendors */ = { isa = PBXGroup; children = ( @@ -268,16 +382,34 @@ 6E645A2011876CA800F08CB1 /* SBJSON */ = { isa = PBXGroup; children = ( - 6E645A2711876CA800F08CB1 /* README */, - 6E645A2211876CA800F08CB1 /* JSON.h */, + 6D58F0B613E8ED1800E9CE78 /* LICENSE */, + 6D58F0B713E8ED1900E9CE78 /* SBJson.h */, + 6D58F0B813E8ED1900E9CE78 /* SBJsonStreamParserAccumulator.h */, + 6D58F0B913E8ED1A00E9CE78 /* SBJsonStreamParserAccumulator.m */, + 6D58F0BA13E8ED1A00E9CE78 /* SBJsonStreamWriterAccumulator.h */, + 6D58F0BB13E8ED1A00E9CE78 /* SBJsonStreamWriterAccumulator.m */, + 6D58F0BC13E8ED1B00E9CE78 /* SBJsonUTF8Stream.h */, + 6D58F0BD13E8ED1B00E9CE78 /* SBJsonUTF8Stream.m */, + 6D58F0B213E8ECC500E9CE78 /* NSString+SBJSON.h */, + 6D58F0B313E8ECC600E9CE78 /* NSString+SBJSON.m */, + 6D58F0AE13E8EBA400E9CE78 /* Changes.md */, + 6D58F0AF13E8EBA400E9CE78 /* Credits.md */, + 6D58F0B013E8EBA500E9CE78 /* Readme.md */, + 6D58F0B113E8EBA500E9CE78 /* ReleaseChecklist.md */, + 6D269EC013CB5BC80006FE1F /* SBJsonTokeniser.m */, + 6D269EC113CB5BC80006FE1F /* SBJsonTokeniser.h */, + 6D269EC213CB5BC80006FE1F /* SBJsonStreamWriterState.m */, + 6D269EC313CB5BC80006FE1F /* SBJsonStreamWriterState.h */, + 6D269EC413CB5BC80006FE1F /* SBJsonStreamWriter.m */, + 6D269EC513CB5BC80006FE1F /* SBJsonStreamWriter.h */, + 6D269EC613CB5BC80006FE1F /* SBJsonStreamParserState.m */, + 6D269EC713CB5BC80006FE1F /* SBJsonStreamParserState.h */, + 6D269EC813CB5BC80006FE1F /* SBJsonStreamParserAdapter.m */, + 6D269EC913CB5BC80006FE1F /* SBJsonStreamParserAdapter.h */, + 6D269ECA13CB5BC80006FE1F /* SBJsonStreamParser.m */, + 6D269ECB13CB5BC80006FE1F /* SBJsonStreamParser.h */, 6E645A2311876CA800F08CB1 /* NSObject+SBJSON.h */, 6E645A2411876CA800F08CB1 /* NSObject+SBJSON.m */, - 6E645A2511876CA800F08CB1 /* NSString+SBJSON.h */, - 6E645A2611876CA800F08CB1 /* NSString+SBJSON.m */, - 6E645A2811876CA800F08CB1 /* SBJSON.h */, - 6E645A2911876CA800F08CB1 /* SBJSON.m */, - 6E645A2A11876CA800F08CB1 /* SBJsonBase.h */, - 6E645A2B11876CA800F08CB1 /* SBJsonBase.m */, 6E645A2C11876CA800F08CB1 /* SBJsonParser.h */, 6E645A2D11876CA800F08CB1 /* SBJsonParser.m */, 6E645A2E11876CA800F08CB1 /* SBJsonWriter.h */, @@ -305,22 +437,16 @@ name = Products; sourceTree = ""; }; - 6E645A7411876D4600F08CB1 /* Products */ = { - isa = PBXGroup; - children = ( - 6E645A7911876D4600F08CB1 /* libThree20Network.a */, - 6E645A7B11876D4600F08CB1 /* UnitTests.octest */, - ); - name = Products; - sourceTree = ""; - }; 6E645AF71187744C00F08CB1 /* YAJL */ = { isa = PBXGroup; children = ( 6E645AFF1187744C00F08CB1 /* README.md */, 6E645AFC1187744C00F08CB1 /* LICENSE */, + 66A1663213427CD10052CA46 /* GHKit */, 6E645AF91187744C00F08CB1 /* GTM */, - 6E645B001187744C00F08CB1 /* yajl-1.0.9 */, + 66E71B5812938CE3007134B0 /* src */, + 66A16603134266380052CA46 /* NSBundle+YAJL.h */, + 66A16604134266380052CA46 /* NSBundle+YAJL.m */, 6E645AFD1187744C00F08CB1 /* NSObject+YAJL.h */, 6E645AFE1187744C00F08CB1 /* NSObject+YAJL.m */, 6E645B7C1187744D00F08CB1 /* YAJL.h */, @@ -337,52 +463,19 @@ 6E645AF91187744C00F08CB1 /* GTM */ = { isa = PBXGroup; children = ( - 6E645AFA1187744C00F08CB1 /* YAJL_GTMBase64.h */, - 6E645AFB1187744C00F08CB1 /* YAJL_GTMBase64.m */, + 6609986D12939B06007B1E07 /* GTMBase64.h */, + 6609986E12939B06007B1E07 /* GTMBase64.m */, ); path = GTM; sourceTree = ""; }; - 6E645B001187744C00F08CB1 /* yajl-1.0.9 */ = { - isa = PBXGroup; - children = ( - 6E645B0C1187744C00F08CB1 /* api */, - 6E645B101187744C00F08CB1 /* CMakeLists.txt */, - 6E645B111187744C00F08CB1 /* yajl */, - 6E645B121187744C00F08CB1 /* yajl.c */, - 6E645B131187744C00F08CB1 /* YAJL.dxy */, - 6E645B141187744C00F08CB1 /* yajl_alloc.c */, - 6E645B151187744C00F08CB1 /* yajl_alloc.h */, - 6E645B161187744C00F08CB1 /* yajl_buf.c */, - 6E645B171187744C00F08CB1 /* yajl_buf.h */, - 6E645B181187744C00F08CB1 /* yajl_bytestack.h */, - 6E645B191187744C00F08CB1 /* yajl_encode.c */, - 6E645B1A1187744C00F08CB1 /* yajl_encode.h */, - 6E645B1B1187744C00F08CB1 /* yajl_gen.c */, - 6E645B1C1187744C00F08CB1 /* yajl_lex.c */, - 6E645B1D1187744C00F08CB1 /* yajl_lex.h */, - 6E645B1E1187744C00F08CB1 /* yajl_parser.c */, - 6E645B1F1187744C00F08CB1 /* yajl_parser.h */, - ); - path = "yajl-1.0.9"; - sourceTree = ""; - }; - 6E645B0C1187744C00F08CB1 /* api */ = { - isa = PBXGroup; - children = ( - 6E645B0D1187744C00F08CB1 /* yajl_common.h */, - 6E645B0E1187744C00F08CB1 /* yajl_gen.h */, - 6E645B0F1187744C00F08CB1 /* yajl_parse.h */, - ); - name = api; - path = src/api; - sourceTree = ""; - }; 6EB4609C1183D1E000685649 /* Source */ = { isa = PBXGroup; children = ( 6E645A1A11876C9800F08CB1 /* TTURLJSONResponse.h */, 6E645A1C11876C9800F08CB1 /* TTURLJSONResponse.m */, + 664B29E812848B1A0008D569 /* TTErrorCodes.h */, + 664B29EF12848B270008D569 /* TTErrorCodes.m */, 6E645A1F11876CA800F08CB1 /* Vendors */, ); name = Source; @@ -408,9 +501,10 @@ 6ED118E41183C38A0096AEBF /* Configurations */ = { isa = PBXGroup; children = ( - 6E55A4B31183CA80002768DE /* Library.xcconfig */, + 6E55A4B31183CA80002768DE /* Library+SBJSON.xcconfig */, + 663DB06D12661EE900CF8CEA /* Library+YAJL.xcconfig */, 6E6454021184BDD500F08CB1 /* Project.xcconfig */, - 6EB460A61183D2AC00685649 /* UnitTests.xcconfig */, + 6EB460A61183D2AC00685649 /* UnitTests+SBJSON.xcconfig */, ); name = Configurations; sourceTree = ""; @@ -423,22 +517,27 @@ buildActionMask = 2147483647; files = ( 6E645BA91187751200F08CB1 /* TTURLJSONResponse.h in Headers */, - 6E645BB11187751200F08CB1 /* YAJL_GTMBase64.h in Headers */, 6E645BB21187751200F08CB1 /* NSObject+YAJL.h in Headers */, - 6E645BB31187751200F08CB1 /* yajl_common.h in Headers */, - 6E645BB41187751200F08CB1 /* yajl_gen.h in Headers */, - 6E645BB51187751200F08CB1 /* yajl_parse.h in Headers */, - 6E645BB61187751200F08CB1 /* yajl_alloc.h in Headers */, - 6E645BB71187751200F08CB1 /* yajl_buf.h in Headers */, - 6E645BB81187751200F08CB1 /* yajl_bytestack.h in Headers */, - 6E645BB91187751200F08CB1 /* yajl_encode.h in Headers */, - 6E645BBA1187751200F08CB1 /* yajl_lex.h in Headers */, - 6E645BBB1187751200F08CB1 /* yajl_parser.h in Headers */, 6E645BBC1187751200F08CB1 /* YAJL.h in Headers */, 6E645BBD1187751200F08CB1 /* YAJLDocument.h in Headers */, 6E645BBE1187751200F08CB1 /* YAJLGen.h in Headers */, 6E645BBF1187751200F08CB1 /* YAJLParser.h in Headers */, 6E6462131187DD3300F08CB1 /* extThree20JSON.h in Headers */, + 664B29EC12848B1A0008D569 /* TTErrorCodes.h in Headers */, + 66E71B9112938CE3007134B0 /* yajl_common.h in Headers */, + 66E71B9212938CE3007134B0 /* yajl_gen.h in Headers */, + 66E71B9312938CE3007134B0 /* yajl_parse.h in Headers */, + 66E71B9612938CE3007134B0 /* yajl_alloc.h in Headers */, + 66E71B9812938CE3007134B0 /* yajl_buf.h in Headers */, + 66E71B9912938CE3007134B0 /* yajl_bytestack.h in Headers */, + 66E71B9B12938CE3007134B0 /* yajl_encode.h in Headers */, + 66E71B9E12938CE3007134B0 /* yajl_lex.h in Headers */, + 66E71BA012938CE3007134B0 /* yajl_parser.h in Headers */, + 66E71BA812938CF8007134B0 /* yajl_version.h in Headers */, + 6609982212939800007B1E07 /* TTExtensionLoader.h in Headers */, + 6609987112939B06007B1E07 /* GTMBase64.h in Headers */, + 66A16605134266380052CA46 /* NSBundle+YAJL.h in Headers */, + 66A1663513427CD10052CA46 /* GHNSBundle+Utils.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -447,14 +546,23 @@ buildActionMask = 2147483647; files = ( 6E645A1D11876C9800F08CB1 /* TTURLJSONResponse.h in Headers */, - 6E645A3011876CA800F08CB1 /* JSON.h in Headers */, 6E645A3111876CA800F08CB1 /* NSObject+SBJSON.h in Headers */, - 6E645A3311876CA800F08CB1 /* NSString+SBJSON.h in Headers */, - 6E645A3511876CA800F08CB1 /* SBJSON.h in Headers */, - 6E645A3711876CA800F08CB1 /* SBJsonBase.h in Headers */, 6E645A3911876CA800F08CB1 /* SBJsonParser.h in Headers */, 6E645A3B11876CA800F08CB1 /* SBJsonWriter.h in Headers */, 6E6462121187DD2F00F08CB1 /* extThree20JSON.h in Headers */, + 664B29E912848B1A0008D569 /* TTErrorCodes.h in Headers */, + 6609982412939800007B1E07 /* TTExtensionLoader.h in Headers */, + 6D269ECF13CB5BC80006FE1F /* SBJsonTokeniser.h in Headers */, + 6D269ED113CB5BC80006FE1F /* SBJsonStreamWriterState.h in Headers */, + 6D269ED313CB5BC80006FE1F /* SBJsonStreamWriter.h in Headers */, + 6D269ED513CB5BC80006FE1F /* SBJsonStreamParserState.h in Headers */, + 6D269ED713CB5BC80006FE1F /* SBJsonStreamParserAdapter.h in Headers */, + 6D269ED913CB5BC80006FE1F /* SBJsonStreamParser.h in Headers */, + 6D58F0B413E8ECC700E9CE78 /* NSString+SBJSON.h in Headers */, + 6D58F0BE13E8ED1B00E9CE78 /* SBJson.h in Headers */, + 6D58F0BF13E8ED1C00E9CE78 /* SBJsonStreamParserAccumulator.h in Headers */, + 6D58F0C113E8ED1C00E9CE78 /* SBJsonStreamWriterAccumulator.h in Headers */, + 6D58F0C313E8ED1C00E9CE78 /* SBJsonUTF8Stream.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -501,9 +609,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libextThree20JSON+SBJSON.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTestsSBJSON */ = { + EB9E6C6110B6A8F800DE563C /* extThree20JSONUnitTests+SBJSON */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTestsSBJSON" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "extThree20JSONUnitTests+SBJSON" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -517,9 +625,9 @@ 6E645AA811876E3500F08CB1 /* PBXTargetDependency */, 6EB460DE1183D8D400685649 /* PBXTargetDependency */, ); - name = UnitTestsSBJSON; + name = "extThree20JSONUnitTests+SBJSON"; productName = CoreUnitTests; - productReference = EB9E6C6210B6A8F800DE563C /* extJSONUnitTests.octest */; + productReference = EB9E6C6210B6A8F800DE563C /* extJSONUnitTests+SBJSON.octest */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -528,11 +636,19 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = NO; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "extThree20JSON" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -541,7 +657,7 @@ ProjectRef = 6E645A6A11876D3F00F08CB1 /* Three20Core.xcodeproj */; }, { - ProductGroup = 6E645A7411876D4600F08CB1 /* Products */; + ProductGroup = 2DA089D314B7968700E7E492 /* Products */; ProjectRef = 6E645A7311876D4600F08CB1 /* Three20Network.xcodeproj */; }, ); @@ -549,38 +665,38 @@ targets = ( BEF31F390F352DF5000DE5D2 /* extThree20JSON+SBJSON */, 6E645BA31187751200F08CB1 /* extThree20JSON+YAJL */, - EB9E6C6110B6A8F800DE563C /* UnitTestsSBJSON */, + EB9E6C6110B6A8F800DE563C /* extThree20JSONUnitTests+SBJSON */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - 6E645A7011876D3F00F08CB1 /* libThree20Core.a */ = { + 2DA08A0814B796A100E7E492 /* libThree20Network.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; - path = libThree20Core.a; - remoteRef = 6E645A6F11876D3F00F08CB1 /* PBXContainerItemProxy */; + path = libThree20Network.a; + remoteRef = 2DA08A0714B796A100E7E492 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E645A7211876D3F00F08CB1 /* CoreUnitTests.octest */ = { + 2DA08A0A14B796A100E7E492 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = CoreUnitTests.octest; - remoteRef = 6E645A7111876D3F00F08CB1 /* PBXContainerItemProxy */; + path = NetworkUnitTests.octest; + remoteRef = 2DA08A0914B796A100E7E492 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E645A7911876D4600F08CB1 /* libThree20Network.a */ = { + 6E645A7011876D3F00F08CB1 /* libThree20Core.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; - path = libThree20Network.a; - remoteRef = 6E645A7811876D4600F08CB1 /* PBXContainerItemProxy */; + path = libThree20Core.a; + remoteRef = 6E645A6F11876D3F00F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E645A7B11876D4600F08CB1 /* UnitTests.octest */ = { + 6E645A7211876D3F00F08CB1 /* CoreUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; - remoteRef = 6E645A7A11876D4600F08CB1 /* PBXContainerItemProxy */; + path = CoreUnitTests.octest; + remoteRef = 6E645A7111876D3F00F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ @@ -645,18 +761,23 @@ buildActionMask = 2147483647; files = ( 6E645BC11187751200F08CB1 /* TTURLJSONResponse.m in Sources */, - 6E645BC81187751200F08CB1 /* YAJL_GTMBase64.m in Sources */, 6E645BC91187751200F08CB1 /* NSObject+YAJL.m in Sources */, - 6E645BCA1187751200F08CB1 /* yajl.c in Sources */, - 6E645BCB1187751200F08CB1 /* yajl_alloc.c in Sources */, - 6E645BCC1187751200F08CB1 /* yajl_buf.c in Sources */, - 6E645BCD1187751200F08CB1 /* yajl_encode.c in Sources */, - 6E645BCE1187751200F08CB1 /* yajl_gen.c in Sources */, - 6E645BCF1187751200F08CB1 /* yajl_lex.c in Sources */, - 6E645BD01187751200F08CB1 /* yajl_parser.c in Sources */, 6E645BD11187751200F08CB1 /* YAJLDocument.m in Sources */, 6E645BD21187751200F08CB1 /* YAJLGen.m in Sources */, 6E645BD31187751200F08CB1 /* YAJLParser.m in Sources */, + 664B29F312848B270008D569 /* TTErrorCodes.m in Sources */, + 66E71B9412938CE3007134B0 /* yajl.c in Sources */, + 66E71B9512938CE3007134B0 /* yajl_alloc.c in Sources */, + 66E71B9712938CE3007134B0 /* yajl_buf.c in Sources */, + 66E71B9A12938CE3007134B0 /* yajl_encode.c in Sources */, + 66E71B9C12938CE3007134B0 /* yajl_gen.c in Sources */, + 66E71B9D12938CE3007134B0 /* yajl_lex.c in Sources */, + 66E71B9F12938CE3007134B0 /* yajl_parser.c in Sources */, + 66E71BA112938CE3007134B0 /* yajl_version.c in Sources */, + 6609981B129397F5007B1E07 /* TTExtensionLoader.m in Sources */, + 6609987212939B06007B1E07 /* GTMBase64.m in Sources */, + 66A16606134266380052CA46 /* NSBundle+YAJL.m in Sources */, + 66A1663613427CD10052CA46 /* GHNSBundle+Utils.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -666,11 +787,20 @@ files = ( 6E645A1E11876C9800F08CB1 /* TTURLJSONResponse.m in Sources */, 6E645A3211876CA800F08CB1 /* NSObject+SBJSON.m in Sources */, - 6E645A3411876CA800F08CB1 /* NSString+SBJSON.m in Sources */, - 6E645A3611876CA800F08CB1 /* SBJSON.m in Sources */, - 6E645A3811876CA800F08CB1 /* SBJsonBase.m in Sources */, 6E645A3A11876CA800F08CB1 /* SBJsonParser.m in Sources */, 6E645A3C11876CA800F08CB1 /* SBJsonWriter.m in Sources */, + 664B29F012848B270008D569 /* TTErrorCodes.m in Sources */, + 6609981F129397F5007B1E07 /* TTExtensionLoader.m in Sources */, + 6D269ECE13CB5BC80006FE1F /* SBJsonTokeniser.m in Sources */, + 6D269ED013CB5BC80006FE1F /* SBJsonStreamWriterState.m in Sources */, + 6D269ED213CB5BC80006FE1F /* SBJsonStreamWriter.m in Sources */, + 6D269ED413CB5BC80006FE1F /* SBJsonStreamParserState.m in Sources */, + 6D269ED613CB5BC80006FE1F /* SBJsonStreamParserAdapter.m in Sources */, + 6D269ED813CB5BC80006FE1F /* SBJsonStreamParser.m in Sources */, + 6D58F0B513E8ECC700E9CE78 /* NSString+SBJSON.m in Sources */, + 6D58F0C013E8ED1C00E9CE78 /* SBJsonStreamParserAccumulator.m in Sources */, + 6D58F0C213E8ED1C00E9CE78 /* SBJsonStreamWriterAccumulator.m in Sources */, + 6D58F0C413E8ED1C00E9CE78 /* SBJsonUTF8Stream.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -725,7 +855,7 @@ /* Begin XCBuildConfiguration section */ 6E645BD61187751200F08CB1 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6E55A4B31183CA80002768DE /* Library.xcconfig */; + baseConfigurationReference = 663DB06D12661EE900CF8CEA /* Library+YAJL.xcconfig */; buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; @@ -734,14 +864,13 @@ DEBUG, EXTJSON_YAJL, ); - PREBINDING = NO; - PRODUCT_NAME = "$(EXTENSION_NAME)+YAJL"; + SDKROOT = iphoneos; }; name = Debug; }; 6E645BD71187751200F08CB1 /* Internal */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6E55A4B31183CA80002768DE /* Library.xcconfig */; + baseConfigurationReference = 663DB06D12661EE900CF8CEA /* Library+YAJL.xcconfig */; buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; @@ -751,22 +880,19 @@ EXTJSON_YAJL, DEBUG, ); - PREBINDING = NO; - PRODUCT_NAME = "$(EXTENSION_NAME)+YAJL"; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; 6E645BD81187751200F08CB1 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6E55A4B31183CA80002768DE /* Library.xcconfig */; + baseConfigurationReference = 663DB06D12661EE900CF8CEA /* Library+YAJL.xcconfig */; buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREPROCESSOR_DEFINITIONS = EXTJSON_YAJL; - PREBINDING = NO; - PRODUCT_NAME = "$(EXTENSION_NAME)+YAJL"; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -775,20 +901,17 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; 6E924940112C6F4000531F03 /* Internal */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6E55A4B31183CA80002768DE /* Library.xcconfig */; + baseConfigurationReference = 6E55A4B31183CA80002768DE /* Library+SBJSON.xcconfig */; buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; @@ -798,29 +921,29 @@ EXTJSON_SBJSON, DEBUG, ); - PREBINDING = NO; - PRODUCT_NAME = "$(EXTENSION_NAME)+SBJSON"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; 6E924941112C6F4000531F03 /* Internal */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6EB460A61183D2AC00685649 /* UnitTests.xcconfig */; + baseConfigurationReference = 6EB460A61183D2AC00685649 /* UnitTests+SBJSON.xcconfig */; buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Internal; }; BEF31F3B0F352DF6000DE5D2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6E55A4B31183CA80002768DE /* Library.xcconfig */; + baseConfigurationReference = 6E55A4B31183CA80002768DE /* Library+SBJSON.xcconfig */; buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; @@ -829,21 +952,20 @@ EXTJSON_SBJSON, DEBUG, ); - PREBINDING = NO; - PRODUCT_NAME = "$(EXTENSION_NAME)+SBJSON"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + SDKROOT = iphoneos; }; name = Debug; }; BEF31F3C0F352DF6000DE5D2 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6E55A4B31183CA80002768DE /* Library.xcconfig */; + baseConfigurationReference = 6E55A4B31183CA80002768DE /* Library+SBJSON.xcconfig */; buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREPROCESSOR_DEFINITIONS = EXTJSON_SBJSON; - PREBINDING = NO; - PRODUCT_NAME = "$(EXTENSION_NAME)+SBJSON"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -852,14 +974,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -867,40 +986,38 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; EB9E6C6510B6A8F900DE563C /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6EB460A61183D2AC00685649 /* UnitTests.xcconfig */; + baseConfigurationReference = 6EB460A61183D2AC00685649 /* UnitTests+SBJSON.xcconfig */; buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; EB9E6C6610B6A8F900DE563C /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6EB460A61183D2AC00685649 /* UnitTests.xcconfig */; + baseConfigurationReference = 6EB460A61183D2AC00685649 /* UnitTests+SBJSON.xcconfig */; buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - PREBINDING = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -938,7 +1055,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTestsSBJSON" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "extThree20JSONUnitTests+SBJSON" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/extThree20XML/Configurations/Library.xcconfig b/src/extThree20XML/Configurations/Library.xcconfig index 102f845815..908d91d6f3 100644 --- a/src/extThree20XML/Configurations/Library.xcconfig +++ b/src/extThree20XML/Configurations/Library.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,9 +17,9 @@ #include "../common/Configurations/Library.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -EXTENSION_NAME = extThree20XML -PRODUCT_NAME = $(EXTENSION_NAME) +BASE_PRODUCT_NAME = extThree20XML +PRODUCT_NAME = $(BASE_PRODUCT_NAME) BUILD_LIBRARY_VERSION = 1.0 -PRIVATE_HEADERS_FOLDER_PATH = /../three20/$(EXTENSION_NAME)/private -PUBLIC_HEADERS_FOLDER_PATH = /../three20/$(EXTENSION_NAME) +PRIVATE_HEADERS_FOLDER_PATH = /../three20/$(BASE_PRODUCT_NAME)/private +PUBLIC_HEADERS_FOLDER_PATH = /../three20/$(BASE_PRODUCT_NAME) diff --git a/src/extThree20XML/Configurations/Project.xcconfig b/src/extThree20XML/Configurations/Project.xcconfig index 709061a56f..12ab00bb9b 100644 --- a/src/extThree20XML/Configurations/Project.xcconfig +++ b/src/extThree20XML/Configurations/Project.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/extThree20XML/Configurations/UnitTests.xcconfig b/src/extThree20XML/Configurations/UnitTests.xcconfig index c0cbac3b81..83135a8fae 100644 --- a/src/extThree20XML/Configurations/UnitTests.xcconfig +++ b/src/extThree20XML/Configurations/UnitTests.xcconfig @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #include "../common/Configurations/UnitTests.xcconfig" #include "../common/Configurations/Libraries.xcconfig" -PRODUCT_NAME = extJSONUnitTests -BUILD_BUNDLE_VERSION = 1.0 +BASE_PRODUCT_NAME = extXMLUnitTests +PRODUCT_NAME = $(BASE_PRODUCT_NAME) +BUILD_BUNDLE_VERSION = 1.0 -OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) +OTHER_LDFLAGS = $(COMMON_LDFLAGS) $(UIKIT_FX) diff --git a/src/extThree20XML/Headers/TTExtensionLoader.h b/src/extThree20XML/Headers/TTExtensionLoader.h new file mode 100644 index 0000000000..b47caa1716 --- /dev/null +++ b/src/extThree20XML/Headers/TTExtensionLoader.h @@ -0,0 +1,21 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Three20Core/TTExtensionLoader.h" + +@interface TTExtensionLoader (TTXMLExtension) + +@end diff --git a/src/extThree20XML/Headers/TTURLXMLResponse.h b/src/extThree20XML/Headers/TTURLXMLResponse.h index 738cb92b75..58eaa0deb9 100644 --- a/src/extThree20XML/Headers/TTURLXMLResponse.h +++ b/src/extThree20XML/Headers/TTURLXMLResponse.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/extThree20XML/Headers/TTXMLParser.h b/src/extThree20XML/Headers/TTXMLParser.h index d957e7ea69..521e4e2bce 100644 --- a/src/extThree20XML/Headers/TTXMLParser.h +++ b/src/extThree20XML/Headers/TTXMLParser.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/extThree20XML/Headers/extThree20XML.h b/src/extThree20XML/Headers/extThree20XML.h index cac70fd4fd..3e112f1627 100644 --- a/src/extThree20XML/Headers/extThree20XML.h +++ b/src/extThree20XML/Headers/extThree20XML.h @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/extThree20XML/Source/TTExtensionLoader.m b/src/extThree20XML/Source/TTExtensionLoader.m new file mode 100644 index 0000000000..d234f0479d --- /dev/null +++ b/src/extThree20XML/Source/TTExtensionLoader.m @@ -0,0 +1,54 @@ +// +// Copyright 2009-2011 Facebook +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "extThree20XML/TTExtensionLoader.h" + +// Core +#import "Three20Core/TTExtensionAuthor.h" +#import "Three20Core/TTExtensionInfo.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation TTExtensionLoader (TTXMLExtension) + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)loadExtensionNamedThree20XML { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (TTExtensionInfo*)extensionInfoNamedThree20XML { + TTExtensionInfo* extension = [[TTExtensionInfo alloc] init]; + + extension.name = @"Three20 XML"; + extension.description = + @"The XML extension provides support for parsing XML data and receiving XML responses."; + extension.version = @"1.0"; + extension.copyright = @"Copyright 2009-2010 Facebook"; + extension.license = @"Apache 2.0"; + extension.authors = [NSArray arrayWithObjects: + [TTExtensionAuthor authorWithName:@"Jeff Verkoeyen"], + nil]; + + return [extension autorelease]; +} + +@end + diff --git a/src/extThree20XML/Source/TTURLXMLResponse.m b/src/extThree20XML/Source/TTURLXMLResponse.m index 9f819c379c..67b069c152 100644 --- a/src/extThree20XML/Source/TTURLXMLResponse.m +++ b/src/extThree20XML/Source/TTURLXMLResponse.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/extThree20XML/Source/TTXMLParser.m b/src/extThree20XML/Source/TTXMLParser.m index 2b0d8a6728..1292d66704 100644 --- a/src/extThree20XML/Source/TTXMLParser.m +++ b/src/extThree20XML/Source/TTXMLParser.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -46,6 +46,14 @@ @implementation TTXMLParser @synthesize treatDuplicateKeysAsArrayItems = _treatDuplicateKeysAsArrayItems; +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)dealloc { + TT_RELEASE_SAFELY(_rootObject); + + [super dealloc]; +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// - (BOOL)parse { _objectStack = [[NSMutableArray alloc] init]; @@ -127,6 +135,7 @@ - (void)addChildObject:(id)childObject toObject:(id)object { // Collision, check if it's already an array. if (TTIsArrayWithItems(entityObject)) { [entityObject addObject:childObject]; + } else { NSMutableArray* array = [[NSMutableArray alloc] init]; [array addObject:entityObject]; @@ -294,6 +303,7 @@ - (NSString*)typeForXMLNode { - (id)objectForXMLNode { if ([[self typeForXMLNode] isEqualToString:kCommonXMLType_Array]) { return [self objectForKey:kInternalKey_Array]; + } else { return [self objectForKey:kInternalKey_EntityValue]; } diff --git a/src/extThree20XML/UnitTests/extXMLTests.m b/src/extThree20XML/UnitTests/extXMLTests.m index 3d9422c616..59650d0431 100644 --- a/src/extThree20XML/UnitTests/extXMLTests.m +++ b/src/extThree20XML/UnitTests/extXMLTests.m @@ -1,5 +1,5 @@ // -// Copyright 2009-2010 Facebook +// Copyright 2009-2011 Facebook // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,10 +14,8 @@ // limitations under the License. // -// See: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/905-A-Unit-Test_Result_Macro_Reference/unit-test_results.html#//apple_ref/doc/uid/TP40007959-CH21-SW2 -// for unit test macros. - -// See Also: http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html +// See: http://bit.ly/hS5nNh for unit test macros. +// See Also: http://bit.ly/hgpqd2 #import diff --git a/src/extThree20XML/extThree20XML.xcodeproj/project.pbxproj b/src/extThree20XML/extThree20XML.xcodeproj/project.pbxproj index 578b20295d..6c6a64849b 100755 --- a/src/extThree20XML/extThree20XML.xcodeproj/project.pbxproj +++ b/src/extThree20XML/extThree20XML.xcodeproj/project.pbxproj @@ -3,10 +3,12 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 660997C6129396F0007B1E07 /* TTExtensionLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 660997C2129396F0007B1E07 /* TTExtensionLoader.m */; }; + 660997C912939700007B1E07 /* TTExtensionLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 660997C712939700007B1E07 /* TTExtensionLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E3C3468118806430079637E /* TTURLXMLResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E3C3466118806430079637E /* TTURLXMLResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E3C3469118806430079637E /* TTXMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E3C3467118806430079637E /* TTXMLParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6E3C346C1188064F0079637E /* TTURLXMLResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E3C346A1188064F0079637E /* TTURLXMLResponse.m */; }; @@ -86,6 +88,9 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 660997C2129396F0007B1E07 /* TTExtensionLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTExtensionLoader.m; path = Source/TTExtensionLoader.m; sourceTree = ""; }; + 660997C712939700007B1E07 /* TTExtensionLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTExtensionLoader.h; path = Headers/TTExtensionLoader.h; sourceTree = ""; }; + 66313DC61267C0CB00C09C9F /* extThree20XML_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = extThree20XML_Prefix.pch; path = Headers/extThree20XML_Prefix.pch; sourceTree = ""; }; 6E3C3466118806430079637E /* TTURLXMLResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTURLXMLResponse.h; path = Headers/TTURLXMLResponse.h; sourceTree = ""; }; 6E3C3467118806430079637E /* TTXMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTXMLParser.h; path = Headers/TTXMLParser.h; sourceTree = ""; }; 6E3C346A1188064F0079637E /* TTURLXMLResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTURLXMLResponse.m; path = Source/TTURLXMLResponse.m; sourceTree = ""; }; @@ -100,7 +105,7 @@ 6EB460921183D16000685649 /* UnitTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "UnitTests-Info.plist"; path = "UnitTests/Resources/PropertyLists/UnitTests-Info.plist"; sourceTree = ""; }; 6EB460A61183D2AC00685649 /* UnitTests.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = UnitTests.xcconfig; path = Configurations/UnitTests.xcconfig; sourceTree = ""; }; BEF31F3A0F352DF5000DE5D2 /* libextThree20XML.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libextThree20XML.a; sourceTree = BUILT_PRODUCTS_DIR; }; - EB9E6C6210B6A8F800DE563C /* extJSONUnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = extJSONUnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB9E6C6210B6A8F800DE563C /* extXMLUnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = extXMLUnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -128,7 +133,7 @@ isa = PBXGroup; children = ( BEF31F3A0F352DF5000DE5D2 /* libextThree20XML.a */, - EB9E6C6210B6A8F800DE563C /* extJSONUnitTests.octest */, + EB9E6C6210B6A8F800DE563C /* extXMLUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -137,6 +142,9 @@ isa = PBXGroup; children = ( 6E646518118805EB00F08CB1 /* extThree20XML.h */, + 66313DC61267C0CB00C09C9F /* extThree20XML_Prefix.pch */, + 660997C712939700007B1E07 /* TTExtensionLoader.h */, + 660997C2129396F0007B1E07 /* TTExtensionLoader.m */, 6EB4609C1183D1E000685649 /* Source */, 6E645A4311876CFE00F08CB1 /* Dependencies */, 6ED118E41183C38A0096AEBF /* Configurations */, @@ -185,7 +193,7 @@ isa = PBXGroup; children = ( 6E645A7911876D4600F08CB1 /* libThree20Network.a */, - 6E645A7B11876D4600F08CB1 /* UnitTests.octest */, + 6E645A7B11876D4600F08CB1 /* NetworkUnitTests.octest */, ); name = Products; sourceTree = ""; @@ -238,6 +246,7 @@ 6E3C3468118806430079637E /* TTURLXMLResponse.h in Headers */, 6E3C3469118806430079637E /* TTXMLParser.h in Headers */, 6E3C3470118806590079637E /* extThree20XML.h in Headers */, + 660997C912939700007B1E07 /* TTExtensionLoader.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -251,6 +260,7 @@ BEF31F360F352DF5000DE5D2 /* Headers */, 6E3C34AD118807DC0079637E /* Protect Copied Headers */, BEF31F370F352DF5000DE5D2 /* Sources */, + 668E66BF131AE03600ACE4AB /* Lint */, BEF31F380F352DF5000DE5D2 /* Frameworks */, ); buildRules = ( @@ -264,9 +274,9 @@ productReference = BEF31F3A0F352DF5000DE5D2 /* libextThree20XML.a */; productType = "com.apple.product-type.library.static"; }; - EB9E6C6110B6A8F800DE563C /* UnitTests */ = { + EB9E6C6110B6A8F800DE563C /* extThree20XMLUnitTests */ = { isa = PBXNativeTarget; - buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildConfigurationList = EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "extThree20XMLUnitTests" */; buildPhases = ( EB9E6C5D10B6A8F800DE563C /* Resources */, EB9E6C5E10B6A8F800DE563C /* Sources */, @@ -280,9 +290,9 @@ 6E645AA811876E3500F08CB1 /* PBXTargetDependency */, 6EB460DE1183D8D400685649 /* PBXTargetDependency */, ); - name = UnitTests; + name = extThree20XMLUnitTests; productName = CoreUnitTests; - productReference = EB9E6C6210B6A8F800DE563C /* extJSONUnitTests.octest */; + productReference = EB9E6C6210B6A8F800DE563C /* extXMLUnitTests.octest */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -291,11 +301,19 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = NO; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0420; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "extThree20XML" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -311,7 +329,7 @@ projectRoot = ""; targets = ( BEF31F390F352DF5000DE5D2 /* extThree20XML */, - EB9E6C6110B6A8F800DE563C /* UnitTests */, + EB9E6C6110B6A8F800DE563C /* extThree20XMLUnitTests */, ); }; /* End PBXProject section */ @@ -338,10 +356,10 @@ remoteRef = 6E645A7811876D4600F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E645A7B11876D4600F08CB1 /* UnitTests.octest */ = { + 6E645A7B11876D4600F08CB1 /* NetworkUnitTests.octest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = UnitTests.octest; + path = NetworkUnitTests.octest; remoteRef = 6E645A7A11876D4600F08CB1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -359,6 +377,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 668E66BF131AE03600ACE4AB /* Lint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = Lint; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/usr/bin/env python ../scripts/lint"; + shellScript = ""; + showEnvVarsInLog = 0; + }; 6E3C34AD118807DC0079637E /* Protect Copied Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -395,6 +428,7 @@ files = ( 6E3C346C1188064F0079637E /* TTURLXMLResponse.m in Sources */, 6E3C346D1188064F0079637E /* TTXMLParser.m in Sources */, + 660997C6129396F0007B1E07 /* TTExtensionLoader.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -441,14 +475,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Internal; }; @@ -464,8 +495,8 @@ EXTJSON_SBJSON, DEBUG, ); - PREBINDING = NO; RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = iphoneos; }; name = Internal; }; @@ -475,11 +506,10 @@ buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Internal; }; @@ -494,7 +524,7 @@ EXTJSON_SBJSON, DEBUG, ); - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -504,9 +534,8 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREPROCESSOR_DEFINITIONS = EXTJSON_SBJSON; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -515,14 +544,11 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Debug; }; @@ -530,14 +556,12 @@ isa = XCBuildConfiguration; baseConfigurationReference = 6E6454021184BDD500F08CB1 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = "-ObjC"; - PREBINDING = NO; - SDKROOT = iphonesimulator3.2; + SDKROOT = iphoneos; }; name = Release; }; @@ -547,11 +571,10 @@ buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - PREBINDING = NO; + SDKROOT = iphoneos; }; name = Debug; }; @@ -561,9 +584,8 @@ buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - PREBINDING = NO; + SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; @@ -591,7 +613,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + EB9E6C6710B6A8F900DE563C /* Build configuration list for PBXNativeTarget "extThree20XMLUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( EB9E6C6510B6A8F900DE563C /* Debug */, diff --git a/src/scripts/Paths.py b/src/scripts/Paths.py new file mode 100644 index 0000000000..5308c052e5 --- /dev/null +++ b/src/scripts/Paths.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# encoding: utf-8 +""" +Paths.py + +Created by Jeff Verkoeyen on 2010-10-18. +Copyright 2009-2010 Facebook + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import os + +script_dir = os.path.dirname(os.path.realpath(__file__)) +src_dir = os.path.dirname(script_dir) diff --git a/src/scripts/Pbxproj.html b/src/scripts/Pbxproj.html new file mode 100644 index 0000000000..6df0fb4287 --- /dev/null +++ b/src/scripts/Pbxproj.html @@ -0,0 +1,161 @@ + + +Python: module Pbxproj + + + + +
 
+ 
Pbxproj
index
/Users/featherless/workbench/ios/three20/src/scripts/Pbxproj.py
+

Pbxproj.py

+Working with the pbxproj file format is a pain in the ass.

+This object provides a couple basic features for parsing pbxproj files:

+* Getting a dependency list
+* Adding one pbxproj to another pbxproj as a dependency

+Version 1.0.

+History:
+1.0 - October 20, 2010: Initial hacked-together version finished. It is alive!

+Created by Jeff Verkoeyen on 2010-10-18.
+Copyright 2009-2010 Facebook

+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at

+   http://www.apache.org/licenses/LICENSE-2.0

+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.

+

+ + + + + +
 
+Modules
       
Paths
+hashlib
+
logging
+os
+
re
+sys
+

+ + + + + +
 
+Classes
       
+
__builtin__.object +
+
+
Pbxproj +
+
+
+

+ + + + + +
 
+class Pbxproj(__builtin__.object)
    Methods defined here:
+
__init__(self, name)
# Valid names
+# Three20
+# Three20:Three20-Xcode3.2.5
+# /path/to/project.xcodeproj/project.pbxproj
+ +
__str__(self)
+ +
add_build_setting(self, configuration, setting_name, value)
+ +
add_buildfile(self, name, file_ref_hash, default_guid)
# Add a line to the PBXBuildFile section.
+#
+# <default_guid> /* <name> in Frameworks */ = {isa = PBXBuildFile; fileRef = <file_ref_hash> /* <name> */; };
+#
+# Returns: <default_guid> if a line was added.
+#          Otherwise, the existing guid is returned.
+ +
add_dependency(self, dep)
+ +
add_file_to_frameworks(self, name, guid)
# Add a file to the Frameworks PBXGroup.
+#
+# <guid> /* <name> */,
+ +
add_file_to_frameworks_phase(self, name, guid)
+ +
add_filereference(self, name, file_type, default_guid, rel_path, source_tree)
# Add a line to the PBXFileReference section.
+#
+# <default_guid> /* <name> */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.<file_type>"; name = <name>; path = <rel_path>; sourceTree = <source_tree>; };
+#
+# Returns: <default_guid> if a line was added.
+#          Otherwise, the existing guid is returned.
+ +
add_framework(self, framework)
+ +
add_header_search_path(self, configuration)
+ +
dependencies(self)
# Get and cache the dependencies for this project.
+ +
get_hash_base(self, uniquename)
+ +
get_project_data(self)
# Load the project data from disk.
+ +
guid(self)
+ +
path(self)
+ +
set_project_data(self, project_data)
# Write the project data to disk.
+ +
uniqueid(self)
+ +
xcodeprojpath(self)
# A pbxproj file is contained within an xcodeproj file.
+# This method simply strips off the project.pbxproj part of the path.
+ +
+Static methods defined here:
+
get_pbxproj_by_name(name)
+ +
+Data descriptors defined here:
+
__dict__
+
dictionary for instance variables (if defined)
+
+
__weakref__
+
list of weak references to the object (if defined)
+
+

+ + + + + +
 
+Functions
       
commonpath(l1, l2, common=[])
+
pathsplit(p, rest=[])
# The following relative path methods recyled from:
+# http://code.activestate.com/recipes/208993-compute-relative-path-from-one-directory-to-anothe/
+# Author: Cimarron Taylor
+# Date: July 6, 2003
+
relpath(p1, p2)
+

+ + + + + +
 
+Data
       pbxproj_cache = {}
+ \ No newline at end of file diff --git a/src/scripts/Pbxproj.py b/src/scripts/Pbxproj.py new file mode 100644 index 0000000000..639f724c8c --- /dev/null +++ b/src/scripts/Pbxproj.py @@ -0,0 +1,956 @@ +#!/usr/bin/env python +# encoding: utf-8 +""" +Pbxproj.py + +Working with the pbxproj file format is a pain in the ass. + +This object provides a couple basic features for parsing pbxproj files: + +* Getting a dependency list +* Adding one pbxproj to another pbxproj as a dependency + +Version 1.1. + +History: +1.0 - October 20, 2010: Initial hacked-together version finished. It is alive! +1.1 - January 11, 2011: Add configuration settings to all configurations by default. + +Created by Jeff Verkoeyen on 2010-10-18. +Copyright 2009-2011 Facebook + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import hashlib +import logging +import os +import re +import sys +import Paths + +pbxproj_cache = {} + +# The following relative path methods recyled from: +# http://code.activestate.com/recipes/208993-compute-relative-path-from-one-directory-to-anothe/ +# Author: Cimarron Taylor +# Date: July 6, 2003 +def pathsplit(p, rest=[]): + (h,t) = os.path.split(p) + if len(h) < 1: return [t]+rest + if len(t) < 1: return [h]+rest + return pathsplit(h,[t]+rest) + +def commonpath(l1, l2, common=[]): + if len(l1) < 1: return (common, l1, l2) + if len(l2) < 1: return (common, l1, l2) + if l1[0] != l2[0]: return (common, l1, l2) + return commonpath(l1[1:], l2[1:], common+[l1[0]]) + +def relpath(p1, p2): + (common,l1,l2) = commonpath(pathsplit(p1), pathsplit(p2)) + p = [] + if len(l1) > 0: + p = [ '../' * len(l1) ] + p = p + l2 + return os.path.join( *p ) + +class Pbxproj(object): + + @staticmethod + def get_pbxproj_by_name(name, xcode_version = None): + if name not in pbxproj_cache: + pbxproj_cache[name] = Pbxproj(name, xcode_version = xcode_version) + + return pbxproj_cache[name] + + # Valid names + # Three20 + # Three20:Three20-Xcode3.2.5 + # /path/to/project.xcodeproj/project.pbxproj + def __init__(self, name, xcode_version = None): + self._project_data = None + + parts = name.split(':') + self.name = parts[0] + + if len(parts) > 1: + self.target = parts[1] + else: + valid_file_chars = '[a-zA-Z0-9\.\-:+ "\'!@#$%^&*\(\)]'; + if re.match('^'+valid_file_chars+'+$', self.name): + self.target = self.name + else: + result = re.search('('+valid_file_chars+'+)\.xcodeproj', self.name) + if not result: + self.target = self.name + else: + (self.target, ) = result.groups() + + match = re.search('([^/\\\\]+)\.xcodeproj', self.name) + if not match: + self._project_name = self.name + else: + (self._project_name, ) = match.groups() + + self._guid = None + self._deps = None + self._xcode_version = xcode_version + self._projectVersion = None + self.guid() + + def __str__(self): + return str(self.name)+" target:"+str(self.target)+" guid:"+str(self._guid)+" prodguid: "+self._product_guid+" prodname: "+self._product_name + + def uniqueid(self): + return self.name + ':' + self.target + + def path(self): + # TODO: No sense calculating this every time, just store it when we get the name. + if re.match('^[a-zA-Z0-9\.\-:+"]+$', self.name): + return os.path.join(Paths.src_dir, self.name.strip('"'), self.name.strip('"')+'.xcodeproj', 'project.pbxproj') + elif not re.match('project.pbxproj$', self.name): + return os.path.join(self.name, 'project.pbxproj') + else: + return self.name + + # A pbxproj file is contained within an xcodeproj file. + # This method simply strips off the project.pbxproj part of the path. + def xcodeprojpath(self): + return os.path.dirname(self.path()) + + def guid(self): + if not self._guid: + self.dependencies() + + return self._guid + + def version(self): + if not self._projectVersion: + self.dependencies() + + return self._projectVersion + + # Load the project data from disk. + def get_project_data(self): + if self._project_data is None: + if not os.path.exists(self.path()): + logging.info("Couldn't find the project at this path:") + logging.info(self.path()) + return None + + project_file = open(self.path(), 'r') + self._project_data = project_file.read() + + return self._project_data + + # Write the project data to disk. + def set_project_data(self, project_data): + if self._project_data != project_data: + self._project_data = project_data + project_file = open(self.path(), 'w') + project_file.write(self._project_data) + + # Get and cache the dependencies for this project. + def dependencies(self): + if self._deps is not None: + return self._deps + + project_data = self.get_project_data() + + if project_data is None: + logging.error("Unable to open the project file at this path (is it readable?): "+self.path()) + return None + + # Get project file format version + + result = re.search('\tobjectVersion = ([0-9]+);', project_data) + + if not result: + logging.error("Can't recover: unable to find the project version for your target at: "+self.path()) + return None + + (self._projectVersion,) = result.groups() + self._projectVersion = int(self._projectVersion) + + # Get configuration list guid + + result = re.search('[A-Z0-9]+ \/\* '+re.escape(self.target)+' \*\/ = {\n[ \t]+isa = PBXNativeTarget;(?:.|\n)+?buildConfigurationList = ([A-Z0-9]+) \/\* Build configuration list for PBXNativeTarget "'+re.escape(self.target)+'" \*\/;', + project_data) + + if result: + (self.configurationListGuid, ) = result.groups() + else: + self.configurationListGuid = None + + + # Get configuration list + + if self.configurationListGuid: + match = re.search(re.escape(self.configurationListGuid)+' \/\* Build configuration list for PBXNativeTarget "'+re.escape(self.target)+'" \*\/ = \{\n[ \t]+isa = XCConfigurationList;\n[ \t]+buildConfigurations = \(\n((?:.|\n)+?)\);', project_data) + if not match: + logging.error("Couldn't find the configuration list.") + return False + + (configurationList,) = match.groups() + self.configurations = re.findall('[ \t]+([A-Z0-9]+) \/\* (.+) \*\/,\n', configurationList) + + # Get build phases + + result = re.search('([A-Z0-9]+) \/\* '+re.escape(self.target)+' \*\/ = {\n[ \t]+isa = PBXNativeTarget;(?:.|\n)+?buildPhases = \(\n((?:.|\n)+?)\);', + project_data) + + if not result: + logging.error("Can't recover: Unable to find the build phases from your target at: "+self.path()) + return None + + (self._guid, buildPhases, ) = result.groups() + + # Get the build phases we care about. + + match = re.search('([A-Z0-9]+) \/\* Resources \*\/', buildPhases) + if match: + (self._resources_guid, ) = match.groups() + else: + self._resources_guid = None + + match = re.search('([A-Z0-9]+) \/\* Frameworks \*\/', buildPhases) + if not match: + logging.error("Couldn't find the Frameworks phase from: "+self.path()) + logging.error("Please add a New Link Binary With Libraries Build Phase to your target") + logging.error("Right click your target in the project, Add, New Build Phase,") + logging.error(" \"New Link Binary With Libraries Build Phase\"") + return None + + (self._frameworks_guid, ) = match.groups() + + # Get the dependencies + + result = re.search(re.escape(self._guid)+' \/\* '+re.escape(self.target)+' \*\/ = {\n[ \t]+isa = PBXNativeTarget;(?:.|\n)+?dependencies = \(\n((?:[ \t]+[A-Z0-9]+ \/\* PBXTargetDependency \*\/,\n)*)[ \t]*\);\n', + project_data) + + if not result: + logging.error("Unable to get dependencies from: "+self.path()) + return None + + (dependency_set, ) = result.groups() + dependency_guids = re.findall('[ \t]+([A-Z0-9]+) \/\* PBXTargetDependency \*\/,\n', dependency_set) + + # Parse the dependencies + + dependency_names = [] + + for guid in dependency_guids: + result = re.search(guid+' \/\* PBXTargetDependency \*\/ = \{\n[ \t]+isa = PBXTargetDependency;\n[ \t]*name = (["a-zA-Z0-9\.\-]+);', + project_data) + + if result: + (dependency_name, ) = result.groups() + dependency_names.append(dependency_name) + + self._deps = dependency_names + + + # Get the product guid and name. + + result = re.search(re.escape(self._guid)+' \/\* '+re.escape(self.target)+' \*\/ = {\n[ \t]+isa = PBXNativeTarget;(?:.|\n)+?productReference = ([A-Z0-9]+) \/\* (.+?) \*\/;', + project_data) + + if not result: + logging.error("Unable to get product guid from: "+self.path()) + return None + + (self._product_guid, self._product_name, ) = result.groups() + + return self._deps + + # Add a line to the PBXBuildFile section. + # + # /* in Frameworks */ = {isa = PBXBuildFile; fileRef = /* */; }; + # + # Returns: if a line was added. + # Otherwise, the existing guid is returned. + def add_buildfile(self, name, file_ref_hash, default_guid): + project_data = self.get_project_data() + + match = re.search('\/\* Begin PBXBuildFile section \*\/\n((?:.|\n)+?)\/\* End PBXBuildFile section \*\/', project_data) + + if not match: + logging.error("Couldn't find PBXBuildFile section.") + return None + + (subtext, ) = match.groups() + + buildfile_hash = None + + match = re.search('([A-Z0-9]+).+?fileRef = '+re.escape(file_ref_hash), subtext) + if match: + (buildfile_hash, ) = match.groups() + logging.info("This build file already exists: "+buildfile_hash) + + if buildfile_hash is None: + match = re.search('\/\* Begin PBXBuildFile section \*\/\n', project_data) + + buildfile_hash = default_guid + + libfiletext = "\t\t"+buildfile_hash+" /* "+name+" in Frameworks */ = {isa = PBXBuildFile; fileRef = "+file_ref_hash+" /* "+name+" */; };\n" + project_data = project_data[:match.end()] + libfiletext + project_data[match.end():] + + self.set_project_data(project_data) + + return buildfile_hash + + # Add a line to the PBXFileReference section. + # + # /* */ = {isa = PBXFileReference; lastKnownFileType = "wrapper."; name = ; path = ; sourceTree = ; }; + # + # Returns: if a line was added. + # Otherwise, the existing guid is returned. + def add_filereference(self, name, file_type, default_guid, rel_path, source_tree): + project_data = self.get_project_data() + + quoted_rel_path = '"'+rel_path.strip('"')+'"' + + fileref_hash = None + + match = re.search('([A-Z0-9]+) \/\* '+re.escape(name)+' \*\/ = \{isa = PBXFileReference; lastKnownFileType = "wrapper.'+file_type+'"; name = '+re.escape(name)+'; path = '+re.escape(rel_path)+';', project_data) + + if not match: + # Check again for quoted versions, just to be sure. + match = re.search('([A-Z0-9]+) \/\* '+re.escape(name)+' \*\/ = \{isa = PBXFileReference; lastKnownFileType = "wrapper.'+file_type+'"; name = '+re.escape(name)+'; path = '+re.escape(quoted_rel_path)+';', project_data) + + if match: + logging.info("This file has already been added.") + (fileref_hash, ) = match.groups() + + else: + match = re.search('\/\* Begin PBXFileReference section \*\/\n', project_data) + + if not match: + logging.error("Couldn't find the PBXFileReference section.") + return False + + fileref_hash = default_guid + + pbxfileref = "\t\t"+fileref_hash+" /* "+name+" */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper."+file_type+"\"; name = "+name+"; path = "+quoted_rel_path+"; sourceTree = "+source_tree+"; };\n" + + project_data = project_data[:match.end()] + pbxfileref + project_data[match.end():] + + self.set_project_data(project_data) + + return fileref_hash + + # Add a file to the given PBXGroup. + # + # /* */, + def add_file_to_group(self, name, guid, group): + project_data = self.get_project_data() + + match = re.search('\/\* '+re.escape(group)+' \*\/ = \{\n[ \t]+isa = PBXGroup;\n[ \t]+children = \(\n((?:.|\n)+?)\);', project_data) + if not match: + logging.error("Couldn't find the "+group+" children.") + return False + + (children,) = match.groups() + match = re.search(re.escape(guid), children) + if match: + logging.info("This file is already a member of the "+name+" group.") + else: + match = re.search('\/\* '+re.escape(group)+' \*\/ = \{\n[ \t]+isa = PBXGroup;\n[ \t]+children = \(\n', project_data) + + if not match: + logging.error("Couldn't find the "+group+" group.") + return False + + pbxgroup = "\t\t\t\t"+guid+" /* "+name+" */,\n" + project_data = project_data[:match.end()] + pbxgroup + project_data[match.end():] + + self.set_project_data(project_data) + + return True + + # Add a file to the Frameworks PBXGroup. + # + # /* */, + def add_file_to_frameworks(self, name, guid): + return self.add_file_to_group(name, guid, 'Frameworks') + + # Add a file to the Resources PBXGroup. + # + # /* */, + def add_file_to_resources(self, name, guid): + match = re.search('\/\* '+re.escape('Resources')+' \*\/ = \{\n[ \t]+isa = PBXGroup;\n[ \t]+children = \(\n((?:.|\n)+?)\);', self.get_project_data()) + if not match: + return self.add_file_to_group(name, guid, 'Supporting Files') + + return self.add_file_to_group(name, guid, 'Resources') + + def add_file_to_phase(self, name, guid, phase_guid, phase): + project_data = self.get_project_data() + + match = re.search(re.escape(phase_guid)+" \/\* "+re.escape(phase)+" \*\/ = {(?:.|\n)+?files = \(((?:.|\n)+?)\);", project_data) + + if not match: + logging.error("Couldn't find the "+phase+" phase.") + return False + + (files, ) = match.groups() + + match = re.search(re.escape(guid), files) + if match: + logging.info("The file has already been added.") + else: + match = re.search(re.escape(phase_guid)+" \/\* "+phase+" \*\/ = {(?:.|\n)+?files = \(\n", project_data) + if not match: + logging.error("Couldn't find the "+phase+" files") + return False + + frameworktext = "\t\t\t\t"+guid+" /* "+name+" in "+phase+" */,\n" + project_data = project_data[:match.end()] + frameworktext + project_data[match.end():] + + self.set_project_data(project_data) + + return True + + def get_rel_path_to_products_dir(self): + project_path = os.path.dirname(os.path.abspath(self.xcodeprojpath())) + build_path = os.path.join(os.path.join(os.path.dirname(Paths.src_dir), 'Build'), 'Products') + return relpath(project_path, build_path) + + def add_file_to_frameworks_phase(self, name, guid): + return self.add_file_to_phase(name, guid, self._frameworks_guid, 'Frameworks') + + def add_file_to_resources_phase(self, name, guid): + if self._resources_guid is None: + logging.error("No resources build phase found in the destination project") + logging.error("Please add a New Copy Bundle Resources Build Phase to your target") + logging.error("Right click your target in the project, Add, New Build Phase,") + logging.error(" \"New Copy Bundle Resources Build Phase\"") + return False + + return self.add_file_to_phase(name, guid, self._resources_guid, 'Resources') + + def add_header_search_path(self, configuration): + project_path = os.path.dirname(os.path.abspath(self.xcodeprojpath())) + build_path = os.path.join(os.path.join(os.path.join(os.path.dirname(Paths.src_dir), 'Build'), 'Products'), 'three20') + rel_path = relpath(project_path, build_path) + + did_add_build_setting = self.add_build_setting(configuration, 'HEADER_SEARCH_PATHS', '"'+rel_path+'"') + if not did_add_build_setting: + return did_add_build_setting + + # Version 46 is Xcode 4's file format. + try: + primary_version = int(self._xcode_version.split('.')[0]) + except ValueError, e: + primary_version = 0 + if self._projectVersion >= 46 or primary_version >= 4: + did_add_build_setting = self.add_build_setting(configuration, 'HEADER_SEARCH_PATHS', '"$(BUILT_PRODUCTS_DIR)/../../three20"') + if not did_add_build_setting: + return did_add_build_setting + + did_add_build_setting = self.add_build_setting(configuration, 'HEADER_SEARCH_PATHS', '"$(BUILT_PRODUCTS_DIR)/../three20"') + if not did_add_build_setting: + return did_add_build_setting + + return did_add_build_setting + + def add_build_setting(self, configuration, setting_name, value): + project_data = self.get_project_data() + + match = re.search('\/\* '+configuration+' \*\/ = {\n[ \t]+isa = XCBuildConfiguration;\n(?:.|\n)+?[ \t]+buildSettings = \{\n((?:.|\n)+?)\};', project_data) + if not match: + print "Couldn't find the "+configuration+" configuration in "+self.path() + return False + + settings_start = match.start(1) + settings_end = match.end(1) + + (build_settings, ) = match.groups() + + match = re.search(re.escape(setting_name)+' = ((?:.|\n)+?);', build_settings) + + if not match: + # Add a brand new build setting. No checking for existing settings necessary. + settingtext = '\t\t\t\t'+setting_name+' = '+value+';\n' + + project_data = project_data[:settings_start] + settingtext + project_data[settings_start:] + else: + # Build settings already exist. Is there one or many? + (search_paths,) = match.groups() + if re.search('\(\n', search_paths): + # Many + match = re.search(re.escape(value), search_paths) + if not match: + # If value has any spaces in it, Xcode will split it up into + # multiple entries. + escaped_value = re.escape(value).replace(' ', '",\n[ \t]+"') + match = re.search(escaped_value, search_paths) + if not match and not re.search(re.escape(value.strip('"')), search_paths): + match = re.search(re.escape(setting_name)+' = \(\n', build_settings) + + build_settings = build_settings[:match.end()] + '\t\t\t\t\t'+value+',\n' + build_settings[match.end():] + project_data = project_data[:settings_start] + build_settings + project_data[settings_end:] + else: + # One + if search_paths.strip('"') != value.strip('"'): + existing_path = search_paths + path_set = '(\n\t\t\t\t\t'+value+',\n\t\t\t\t\t'+existing_path+'\n\t\t\t\t)' + build_settings = build_settings[:match.start(1)] + path_set + build_settings[match.end(1):] + project_data = project_data[:settings_start] + build_settings + project_data[settings_end:] + + self.set_project_data(project_data) + + return True + + def get_hash_base(self, uniquename): + examplehash = '320FFFEEEDDDCCCBBBAAA000' + uniquehash = hashlib.sha224(uniquename).hexdigest().upper() + uniquehash = uniquehash[:len(examplehash) - 4] + return '320'+uniquehash + + def add_framework(self, framework): + tthash_base = self.get_hash_base(framework) + + fileref_hash = self.add_filereference(framework, 'frameworks', tthash_base+'0', 'System/Library/Frameworks/'+framework, 'SDKROOT') + libfile_hash = self.add_buildfile(framework, fileref_hash, tthash_base+'1') + if not self.add_file_to_frameworks(framework, fileref_hash): + return False + + if not self.add_file_to_frameworks_phase(framework, libfile_hash): + return False + + return True + + def add_bundle(self): + tthash_base = self.get_hash_base('Three20.bundle') + + project_path = os.path.dirname(os.path.abspath(self.xcodeprojpath())) + build_path = os.path.join(Paths.src_dir, 'Three20.bundle') + rel_path = relpath(project_path, build_path) + + fileref_hash = self.add_filereference('Three20.bundle', 'plug-in', tthash_base+'0', rel_path, 'SOURCE_ROOT') + + libfile_hash = self.add_buildfile('Three20.bundle', fileref_hash, tthash_base+'1') + + if not self.add_file_to_resources('Three20.bundle', fileref_hash): + return False + + if not self.add_file_to_resources_phase('Three20.bundle', libfile_hash): + return False + + return True + + # Get the PBXFileReference from the given PBXBuildFile guid. + def get_filerefguid_from_buildfileguid(self, buildfileguid): + project_data = self.get_project_data() + match = re.search(buildfileguid+' \/\* .+ \*\/ = {isa = PBXBuildFile; fileRef = ([A-Z0-9]+) \/\* .+ \*\/;', project_data) + + if not match: + logging.error("Couldn't find PBXBuildFile row.") + return None + + (filerefguid, ) = match.groups() + + return filerefguid + + def get_filepath_from_filerefguid(self, filerefguid): + project_data = self.get_project_data() + match = re.search(filerefguid+' \/\* .+ \*\/ = {isa = PBXFileReference; .+ path = (.+); .+ };', project_data) + + if not match: + logging.error("Couldn't find PBXFileReference row.") + return None + + (path, ) = match.groups() + + return path + + + # Get all source files that are "built" in this project. This includes files built for + # libraries, executables, and unit testing. + def get_built_sources(self): + project_data = self.get_project_data() + match = re.search('\/\* Begin PBXSourcesBuildPhase section \*\/\n((?:.|\n)+?)\/\* End PBXSourcesBuildPhase section \*\/', project_data) + + if not match: + logging.error("Couldn't find PBXSourcesBuildPhase section.") + return None + + (buildphasedata, ) = match.groups() + + buildfileguids = re.findall('[ \t]+([A-Z0-9]+) \/\* .+ \*\/,\n', buildphasedata) + + project_path = os.path.dirname(os.path.abspath(self.xcodeprojpath())) + + filenames = [] + + for buildfileguid in buildfileguids: + filerefguid = self.get_filerefguid_from_buildfileguid(buildfileguid) + filepath = self.get_filepath_from_filerefguid(filerefguid) + + filenames.append(os.path.join(project_path, filepath.strip('"'))) + + return filenames + + + # Get all header files that are "built" in this project. This includes files built for + # libraries, executables, and unit testing. + def get_built_headers(self): + project_data = self.get_project_data() + match = re.search('\/\* Begin PBXHeadersBuildPhase section \*\/\n((?:.|\n)+?)\/\* End PBXHeadersBuildPhase section \*\/', project_data) + + if not match: + logging.error("Couldn't find PBXHeadersBuildPhase section.") + return None + + (buildphasedata, ) = match.groups() + + buildfileguids = re.findall('[ \t]+([A-Z0-9]+) \/\* .+ \*\/,\n', buildphasedata) + + project_path = os.path.dirname(os.path.abspath(self.xcodeprojpath())) + + filenames = [] + + for buildfileguid in buildfileguids: + filerefguid = self.get_filerefguid_from_buildfileguid(buildfileguid) + filepath = self.get_filepath_from_filerefguid(filerefguid) + + filenames.append(os.path.join(project_path, filepath.strip('"'))) + + return filenames + + + def add_dependency(self, dep): + project_data = self.get_project_data() + dep_data = dep.get_project_data() + + if project_data is None or dep_data is None: + return False + + logging.info("\nAdding "+str(dep)+" to "+str(self)) + + project_path = os.path.dirname(os.path.abspath(self.xcodeprojpath())) + dep_path = os.path.abspath(dep.xcodeprojpath()) + rel_path = relpath(project_path, dep_path) + + logging.info("") + logging.info("Project path: "+project_path) + logging.info("Dependency path: "+dep_path) + logging.info("Relative path: "+rel_path) + + tthash_base = self.get_hash_base(dep.uniqueid()) + + ############################################### + logging.info("") + logging.info("Step 1: Add file reference to the dependency...") + + self.set_project_data(project_data) + pbxfileref_hash = self.add_filereference(dep._project_name+'.xcodeproj', 'pb-project', tthash_base+'0', rel_path, 'SOURCE_ROOT') + project_data = self.get_project_data() + + logging.info("Done: Added file reference: "+pbxfileref_hash) + + ############################################### + logging.info("") + logging.info("Step 2: Add file to Frameworks group...") + + self.set_project_data(project_data) + if not self.add_file_to_frameworks(dep._project_name+".xcodeproj", pbxfileref_hash): + return False + project_data = self.get_project_data() + + logging.info("Done: Added file to Frameworks group.") + + ############################################### + logging.info("") + logging.info("Step 3: Add dependencies...") + + pbxtargetdependency_hash = None + pbxcontaineritemproxy_hash = None + + match = re.search('\/\* Begin PBXTargetDependency section \*\/\n((?:.|\n)+?)\/\* End PBXTargetDependency section \*\/', project_data) + if not match: + logging.info("\tAdding a PBXTargetDependency section...") + match = re.search('\/\* End PBXSourcesBuildPhase section \*\/\n', project_data) + + if not match: + logging.error("Couldn't find the PBXSourcesBuildPhase section.") + return False + + project_data = project_data[:match.end()] + "\n/* Begin PBXTargetDependency section */\n\n/* End PBXTargetDependency section */\n" + project_data[match.end():] + else: + (subtext, ) = match.groups() + match = re.search('([A-Z0-9]+) \/\* PBXTargetDependency \*\/ = {\n[ \t]+isa = PBXTargetDependency;\n[ \t]+name = '+re.escape(dep._project_name)+';\n[ \t]+targetProxy = ([A-Z0-9]+) \/\* PBXContainerItemProxy \*\/;', project_data) + if match: + (pbxtargetdependency_hash, pbxcontaineritemproxy_hash,) = match.groups() + logging.info("This dependency already exists.") + + if pbxtargetdependency_hash is None or pbxcontaineritemproxy_hash is None: + match = re.search('\/\* Begin PBXTargetDependency section \*\/\n', project_data) + + pbxtargetdependency_hash = tthash_base+'1' + pbxcontaineritemproxy_hash = tthash_base+'2' + + pbxtargetdependency = "\t\t"+pbxtargetdependency_hash+" /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = "+dep._project_name+";\n\t\t\ttargetProxy = "+pbxcontaineritemproxy_hash+" /* PBXContainerItemProxy */;\n\t\t};\n" + project_data = project_data[:match.end()] + pbxtargetdependency + project_data[match.end():] + + logging.info("Done: Added dependency.") + + + ############################################### + logging.info("") + logging.info("Step 3.1: Add container proxy for dependencies...") + + containerExists = False + + match = re.search('\/\* Begin PBXContainerItemProxy section \*\/\n((?:.|\n)+?)\/\* End PBXContainerItemProxy section \*\/', project_data) + if not match: + logging.info("\tAdding a PBXContainerItemProxy section...") + match = re.search('\/\* End PBXBuildFile section \*\/\n', project_data) + + if not match: + logging.error("Couldn't find the PBXBuildFile section.") + return False + + project_data = project_data[:match.end()] + "\n/* Begin PBXContainerItemProxy section */\n\n/* End PBXContainerItemProxy section */\n" + project_data[match.end():] + else: + (subtext, ) = match.groups() + match = re.search(re.escape(pbxcontaineritemproxy_hash), subtext) + if match: + logging.info("This container proxy already exists.") + containerExists = True + + if not containerExists: + match = re.search('\/\* Begin PBXContainerItemProxy section \*\/\n', project_data) + + pbxcontaineritemproxy = "\t\t"+pbxcontaineritemproxy_hash+" /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = "+pbxfileref_hash+" /* "+dep._project_name+".xcodeproj */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = "+dep.guid()+";\n\t\t\tremoteInfo = "+dep._project_name+";\n\t\t};\n" + project_data = project_data[:match.end()] + pbxcontaineritemproxy + project_data[match.end():] + + logging.info("Done: Added container proxy.") + + + ############################################### + logging.info("") + logging.info("Step 3.2: Add module to the dependency list...") + + match = re.search(self.guid()+' \/\* .+? \*\/ = {\n[ \t]+(?:.|\n)+?[ \t]+dependencies = \(\n((?:.|\n)+?)\);', project_data) + + dependency_exists = False + + if not match: + logging.error("Couldn't find the dependency list.") + return False + else: + (dependencylist, ) = match.groups() + match = re.search(re.escape(pbxtargetdependency_hash), dependencylist) + if match: + logging.info("This dependency has already been added.") + dependency_exists = True + + if not dependency_exists: + match = re.search(self.guid()+' \/\* .+? \*\/ = {\n[ \t]+(?:.|\n)+?[ \t]+dependencies = \(\n', project_data) + + if not match: + logging.error("Couldn't find the dependency list.") + return False + + dependency_item = '\t\t\t\t'+pbxtargetdependency_hash+' /* PBXTargetDependency */,\n' + project_data = project_data[:match.end()] + dependency_item + project_data[match.end():] + + logging.info("Done: Added module to the dependency list.") + + + ############################################### + logging.info("") + logging.info("Step 4: Create project references...") + + match = re.search('\/\* Begin PBXProject section \*\/\n((?:.|\n)+?)\/\* End PBXProject section \*\/', project_data) + if not match: + logging.error("Couldn't find the project section.") + return False + + project_start = match.start(1) + project_end = match.end(1) + + (project_section, ) = match.groups() + + reference_exists = False + did_change = False + + productgroup_hash = None + + match = re.search('projectReferences = \(\n((?:.|\n)+?)\n[ \t]+\);', project_section) + if not match: + logging.info("Creating project references...") + match = re.search('projectDirPath = ".*?";\n', project_section) + if not match: + logging.error("Couldn't find project references anchor.") + return False + + did_change = True + project_section = project_section[:match.end()] + '\t\t\tprojectReferences = (\n\t\t\t);\n' + project_section[match.end():] + + else: + (refs, ) = match.groups() + + match = re.search('\{\n[ \t]+ProductGroup = ([A-Z0-9]+) \/\* Products \*\/;\n[ \t]+ProjectRef = '+re.escape(pbxfileref_hash), refs) + if match: + (productgroup_hash, ) = match.groups() + logging.info("This product group already exists: "+productgroup_hash) + reference_exists = True + + + if not reference_exists: + match = re.search('projectReferences = \(\n', project_section) + + if not match: + logging.error("Missing the project references item.") + return False + + productgroup_hash = tthash_base+'3' + + reference_text = '\t\t\t\t{\n\t\t\t\t\tProductGroup = '+productgroup_hash+' /* Products */;\n\t\t\t\t\tProjectRef = '+pbxfileref_hash+' /* '+dep._project_name+'.xcodeproj */;\n\t\t\t\t},\n' + project_section = project_section[:match.end()] + reference_text + project_section[match.end():] + did_change = True + + if did_change: + project_data = project_data[:project_start] + project_section + project_data[project_end:] + + logging.info("Done: Created project reference.") + + ############################################### + logging.info("") + logging.info("Step 4.1: Create product group...") + + match = re.search('\/\* Begin PBXGroup section \*\/\n', project_data) + if not match: + logging.error("Couldn't find the group section.") + return False + + group_start = match.end() + + lib_hash = None + + match = re.search(re.escape(productgroup_hash)+" \/\* Products \*\/ = \{\n[ \t]+isa = PBXGroup;\n[ \t]+children = \(\n((?:.|\n)+?)\);", project_data) + if match: + logging.info("This product group already exists.") + (children, ) = match.groups() + match = re.search('([A-Z0-9]+) \/\* '+re.escape(dep._product_name)+' \*\/', children) + if not match: + logging.error("No product found") + return False + # TODO: Add this product. + else: + (lib_hash, ) = match.groups() + + else: + lib_hash = tthash_base+'4' + + productgrouptext = "\t\t"+productgroup_hash+" /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t"+lib_hash+" /* "+dep._product_name+" */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"\";\n\t\t};\n" + project_data = project_data[:group_start] + productgrouptext + project_data[group_start:] + + logging.info("Done: Created product group: "+lib_hash) + + + + ############################################### + logging.info("") + logging.info("Step 4.2: Add container proxy for target product...") + + containerExists = False + + targetproduct_hash = tthash_base+'6' + + match = re.search('\/\* Begin PBXContainerItemProxy section \*\/\n((?:.|\n)+?)\/\* End PBXContainerItemProxy section \*\/', project_data) + if not match: + logging.info("\tAdding a PBXContainerItemProxy section...") + match = re.search('\/\* End PBXBuildFile section \*\/\n', project_data) + + if not match: + logging.error("Couldn't find the PBXBuildFile section.") + return False + + project_data = project_data[:match.end()] + "\n/* Begin PBXContainerItemProxy section */\n\n/* End PBXContainerItemProxy section */\n" + project_data[match.end():] + else: + (subtext, ) = match.groups() + match = re.search(re.escape(targetproduct_hash), subtext) + if match: + logging.info("This container proxy already exists.") + containerExists = True + + if not containerExists: + match = re.search('\/\* Begin PBXContainerItemProxy section \*\/\n', project_data) + + pbxcontaineritemproxy = "\t\t"+targetproduct_hash+" /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = "+pbxfileref_hash+" /* "+dep._project_name+".xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = "+dep._product_guid+";\n\t\t\tremoteInfo = "+dep._project_name+";\n\t\t};\n" + project_data = project_data[:match.end()] + pbxcontaineritemproxy + project_data[match.end():] + + logging.info("Done: Added target container proxy.") + + + ############################################### + logging.info("") + logging.info("Step 4.3: Create reference proxy...") + + referenceExists = False + + match = re.search('\/\* Begin PBXReferenceProxy section \*\/\n((?:.|\n)+?)\/\* End PBXReferenceProxy section \*\/', project_data) + if not match: + logging.info("\tAdding a PBXReferenceProxy section...") + match = re.search('\/\* End PBXProject section \*\/\n', project_data) + + if not match: + logging.error("Couldn't find the PBXProject section.") + return False + + project_data = project_data[:match.end()] + "\n/* Begin PBXReferenceProxy section */\n\n/* End PBXReferenceProxy section */\n" + project_data[match.end():] + else: + (subtext, ) = match.groups() + match = re.search(re.escape(lib_hash), subtext) + if match: + logging.info("This reference proxy already exists.") + referenceExists = True + + if not referenceExists: + match = re.search('\/\* Begin PBXReferenceProxy section \*\/\n', project_data) + + referenceproxytext = "\t\t"+lib_hash+" /* "+dep._product_name+" */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \""+dep._product_name+"\";\n\t\t\tremoteRef = "+targetproduct_hash+" /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n" + project_data = project_data[:match.end()] + referenceproxytext + project_data[match.end():] + + logging.info("Done: Created reference proxy.") + + + ############################################### + logging.info("") + logging.info("Step 5: Add target file...") + + self.set_project_data(project_data) + libfile_hash = self.add_buildfile(dep._product_name, lib_hash, tthash_base+'5') + project_data = self.get_project_data() + + logging.info("Done: Added target file.") + + + ############################################### + logging.info("") + logging.info("Step 6: Add frameworks...") + + self.set_project_data(project_data) + self.add_file_to_frameworks_phase(dep._product_name, libfile_hash) + project_data = self.get_project_data() + + logging.info("Done: Adding module.") + + self.set_project_data(project_data) + + return True diff --git a/src/scripts/Protect.command b/src/scripts/Protect.command index bac8a998f5..e6d4ce25f5 100644 --- a/src/scripts/Protect.command +++ b/src/scripts/Protect.command @@ -20,7 +20,13 @@ # Ignore whitespace characters in paths IFS=$'\n' -cd ${CONFIGURATION_BUILD_DIR}${PUBLIC_HEADERS_FOLDER_PATH} +# In Xcode 4 Archive builds, there is one extra folder placed between the configuration build +# dir and the public headers path titled "ArchiveIntermediates". +if [[ "$DEPLOYMENT_LOCATION" == "YES" && "$XCODE_VERSION_MAJOR" -ge "0400" ]]; then + cd ${CONFIGURATION_BUILD_DIR}/..${PUBLIC_HEADERS_FOLDER_PATH} +else + cd ${CONFIGURATION_BUILD_DIR}${PUBLIC_HEADERS_FOLDER_PATH} +fi chmod a-w *.h 2>> /dev/null chmod a-w private/*.h 2>> /dev/null diff --git a/src/scripts/docs.py b/src/scripts/docs.py new file mode 100755 index 0000000000..e3ae0b2318 --- /dev/null +++ b/src/scripts/docs.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# encoding: utf-8 +""" +docs.py + +Created by Jeff Verkoeyen on 2010-10-18. +Copyright 2009-2010 Facebook + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import logging +import re +import os +import sys +import shutil +import errno +import git + +# Three20 Python Objects +import Paths + +from optparse import OptionParser + +def generate_appledoc(version): + logging.info("Generating appledoc") + + os.system("appledoc " + + "--project-name Three20 " + + "--project-company \"Facebook\" " + + "--company-id=com.facebook " + + "--output Docs/ " + + "--project-version " + version + " " + + "--ignore .m --ignore Vendors --ignore UnitTests " + + "--keep-undocumented-objects " + + "--keep-undocumented-members " + + "--warn-undocumented-object " + + "--warn-undocumented-member " + + "--warn-empty-description " + + "--warn-unknown-directive " + + "--warn-invalid-crossref " + + "--warn-missing-arg " + + "--keep-intermediate-files " + + "--docset-feed-name \"Three20 " + version + " Documentation\" " + + "--docset-feed-url http://facebook.github.com/three20/api/%DOCSETATOMFILENAME " + + "--docset-package-url http://facebook.github.com/three20/api/%DOCSETPACKAGEFILENAME " + + "--publish-docset " + + "--verbose 5 src/") + +def publish_ghpages(version): + + logging.info("Cloning and checking out gh-pages") + os.system("git clone git@github.com:facebook/three20.git Docs/gh-pages") + os.system("cd Docs/gh-pages && git pull") + os.system("cd Docs/gh-pages && git checkout gh-pages") + + logging.info("Copying docset into gh-pages folder") + + os.system("cp -r -f Docs/html/* Docs/gh-pages/api") + os.system("cp -r -f Docs/publish/ Docs/gh-pages/api") + + logging.info("Committing new docs") + os.system("cd Docs/gh-pages && git add -A .") + os.system("cd Docs/gh-pages && git commit -am \"Three20 " + version + " Documentation\"") + os.system("cd Docs/gh-pages && git push origin gh-pages") + + +def main(): + usage = '''%prog [options] + + +The Three20 Appledoc Generator Script. +Use this script to generate appledoc +--generate will generate the docs +--publish will publish the new docs into the three20's gh-pages branch + +EXAMPLES: + + Most common use case: + > %prog --version 1.0.10-dev --generate + +''' + parser = OptionParser(usage = usage) + + parser.add_option("-o", "--generate", dest="generate", + help="Generate appledoc", + action="store_true") + + parser.add_option("-p", "--publish", dest="publish", + help="publish gh-pages", + action="store_true") + + parser.add_option("-v", "--version", dest="version", + help="Project version") + + parser.add_option("", "--verbose", dest="verbose", + help="Display verbose output", + action="store_true") + + (options, args) = parser.parse_args() + + if options.verbose: + log_level = logging.INFO + else: + log_level = logging.WARNING + + logging.basicConfig(level=log_level) + + did_anything = False + + if options.generate: + did_anything = True + + generate_appledoc(options.version) + + if options.publish: + did_anything = True + publish_ghpages(options.version) + + if not did_anything: + parser.print_help() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/scripts/lint b/src/scripts/lint new file mode 100644 index 0000000000..345cbdbf19 --- /dev/null +++ b/src/scripts/lint @@ -0,0 +1,341 @@ +#!/usr/bin/env python +# encoding: utf-8 +""" +lint + +Validate style guidelines for a given source file. + +When run from Xcode, the linter will automatically lint all of the built source files +and headers. + +Version 1.0 + +History: +1.0 - February 27, 2011: Includes a set of simple linters and a delinter for most lints. + +Created by Jeff Verkoeyen on 2011-02-27. +Copyright 2009-2011 Facebook + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import ConfigParser +import logging +import os +import Paths +import pickle +import re +import string +import sys +from optparse import OptionParser + +from Pbxproj import Pbxproj +from Pbxproj import relpath + +gcopyrightyears = '2009-2011' +gdivider = '///////////////////////////////////////////////////////////////////////////////////////////////////' +maxlinelength = 100 + +# Program entry. The meat of this script happens in the lint() method below. +def main(): + usage = '''%prog filename + +The Three20 Linter. +Verify Three20 style guidelines for source code.''' + + parser = OptionParser(usage = usage) + parser.add_option("-d", "--delint", dest="delint", + help="Delint the source", + action="store_true") + parser.add_option("-l", "--maxline", dest="maxlinelength", + help="Maximum permissible length of a line",type="int", + action="store") + + (options, args) = parser.parse_args() + + global maxlinelength + if options.maxlinelength: + maxlinelength = options.maxlinelength + + if len(args) == 0: + parser.print_help() + + enabled_for_projects = True + + # Allow third-party developers to disable the linter entirely. See config.template for + # more information in the "lint" section. + configpath = os.path.join(os.path.dirname(Paths.src_dir), 'config') + if os.path.exists(configpath): + config = ConfigParser.ConfigParser() + config.read(configpath) + enabled_for_projects = config.getboolean('lint', 'enabled_for_projects') + + # If we're running the linter from Xcode, let's just process the project. + if 'PROJECT_FILE_PATH' in os.environ: + if enabled_for_projects: + lint_project(os.environ['PROJECT_FILE_PATH'], options) + else: + for filename in args: + lint(filename, options) + + +# This filter makes it possible to set the line number on logging.error calls. +class FilenameFilter(logging.Filter): + def __init__(self): + self.lineno = -1 + + def filter(self, record): + record.linenumber = self.lineno + return True + + +def lint_project(project_path, options): + project = Pbxproj.get_pbxproj_by_name(project_path) + + tempdir = None + if os.environ['TEMP_FILES_DIR']: + tempdir = os.environ['TEMP_FILES_DIR'] + + # We avoid relinting the same file over and over again by maintaining a mapping of filenames + # to modified times on disk. We store this information in the project's build directory and + # load it each time we run the linter for this project. + # Because we store the mtimes on a per project basis, we shouldn't run into any performance + # issues with a lint.dat file that's becoming completely massive. + mtimes = {} + + # Read the lint.dat file and unpickle it if we find it. + if tempdir: + lintdatpath = os.path.join(os.path.abspath(tempdir), 'lint.dat') + if os.path.exists(lintdatpath): + lintdatfile = open(lintdatpath, 'rb') + mtimes = pickle.load(lintdatfile) + + # The linter script may have changed since we last ran this project, so we might have to + # force lint every file to update them because there may be new linters. + + # Assume that the linter hasn't been run for this project. + forcelint = True + + # Get this script's path + lintfilename = os.path.realpath(__file__) + + # Check the mtime. + mtime = os.path.getmtime(lintfilename) + if lintfilename in mtimes: + if mtime <= mtimes[lintfilename]: + # The lint script hasn't changed since we last ran this, so we don't have to force + # lint. + forcelint = False + + # Store the linter's mtime for future runs. + mtimes[lintfilename] = mtime + + # + # Get all of the "built" filenames in this project. + + # The "Compile sources" phase files + filenames = project.get_built_sources() + + # The "Copy headers" phase files if they exist + if project.get_built_headers(): + filenames = filenames + project.get_built_headers() + + # Iterate through and lint each of the files that have been modified since we last ran + # the linter, unless we're forcelinting, in which case we lint everything. + for filename in filenames: + mtime = os.path.getmtime(filename) + + # If the filename isn't in the lint data, we have no idea when it was last modified so + # we'll run the linter anyway. + if not forcelint and filename in mtimes: + # Is it older or unchanged? + if mtime <= mtimes[filename]: + # Yeah, let's skip it then. + continue + + # The beef. + if lint(filename, options): + # Only update the last known modification time if there weren't any errors. + mtimes[filename] = mtime + else: + print "If you would like to disable the lint tool, please read the instructions in config.template in the root of the Three20 project" + if filename in mtimes: + del mtimes[filename] + + # Write out the lint data once we're done with this project. Thanks, pickle! + if tempdir: + lintdatfile = open(lintdatpath, 'wb') + pickle.dump(mtimes, lintdatfile) + + +# Lint the given filename. +def lint(filename, options): + logger = logging.getLogger() + + f = FilenameFilter() + logger.addFilter(f) + + # Set up the warning logger format. + ch = logging.StreamHandler() + if 'PROJECT_FILE_PATH' in os.environ: + formatter = logging.Formatter(filename+":%(linenumber)s: warning: "+relpath(os.getcwd(), filename)+":%(linenumber)s: %(message)s") + else: + formatter = logging.Formatter(filename+":%(linenumber)s: %(message)s") + ch.setFormatter(formatter) + logger.addHandler(ch) + + file = open(filename, 'r') + filedata = file.read() + + did_lint_cleanly = True + + # Everything is set up now, let's run through the linters! + if not lint_basics(filedata, filename, f, options.delint): + did_lint_cleanly = False + + logger.removeFilter(f) + logger.removeHandler(ch) + + return did_lint_cleanly + + +# Basic lint tests that only look at one line's information. +# If isdelinting is True, this method will try to fix as many lint issues as it can and then +# write the results out to disk. +def lint_basics(filedata, filename, linenofilter, isdelinting = False): + + logger = logging.getLogger() + + lines = string.split(filedata, "\n") + linenofilter.lineno = 1 + + prevline = None + + did_lint_cleanly = True + + nwarningsfixed = 0 + nwarnings = 0 + if isdelinting: + newfilelines = [] + + for line in lines: + # Check line lengths. + if len(line) > maxlinelength: + did_lint_cleanly = False + nwarnings = nwarnings + 1 + + # This is not something we can fix with the delinter. + if isdelinting: + logger.error('I don\'t know how to split this line up.') + else: + logger.error('Line length > %d'% maxlinelength) + + # Check method dividers. + if not re.search(r'.h$', filename) and re.search(r'^[-+][ ]*\([\w\s*]+\)', line): + if prevline != gdivider and prevline != ' */': + did_lint_cleanly = False + nwarnings = nwarnings + 1 + + # This is not something we can fix with the delinter. + if isdelinting: + if re.match(r'/+', prevline): + newfilelines.pop() + newfilelines.append(gdivider) + nwarningsfixed = nwarningsfixed + 1 + else: + logger.error('This method is missing a correct divider before it') + + # Properties + if re.search(r'^@property', line): + if re.search(r'(NSString|NSArray|NSDictionary|NSSet)[ ]*\*', line) and not re.search(r'copy|readonly', line): + nwarnings = nwarnings + 1 + if isdelinting: + line = re.sub(r'\bretain\b', r'copy', line) + nwarningsfixed = nwarningsfixed + 1 + else: + did_lint_cleanly = False + logger.error('Objects that have mutable subclasses, such as NSString, should be copied, not retained') + + if re.search(r'^@property\(', line): + nwarnings = nwarnings + 1 + if isdelinting: + line = line.rstrip(' \t') + nwarningsfixed = nwarningsfixed + 1 + else: + did_lint_cleanly = False + logger.error('Must be a space after the @property declarator') + + # Trailing whitespace + if re.search('[ \t]+$', line): + nwarnings = nwarnings + 1 + if isdelinting: + line = line.rstrip(' \t') + nwarningsfixed = nwarningsfixed + 1 + else: + did_lint_cleanly = False + logger.error('Trailing whitespace') + + # Spaces after logical constructs + if re.search('(if|while|for)\(', line, re.IGNORECASE): + nwarnings = nwarnings + 1 + if isdelinting: + line = re.sub(r'(if|while|for)\(', r'\1 (', line) + nwarningsfixed = nwarningsfixed + 1 + else: + did_lint_cleanly = False + logger.error('Missing space after logical construct') + + # Boolean checks against non-boolean objects + # This test is really hard to do without knowing the type of the object. + #if re.search('[^!]!(?!TTIs|[a-z0-9_.]*\.is|is|_is|has|_has|\[|self\.is|[a-z0-9_]+\.)[a-z0-9_]+', line, re.IGNORECASE): + # did_lint_cleanly = False + # logger.error('Use if (nil == value) instead of boolean checks for pointers') + + # Else statements must have one empty line before them + if re.search('}[ ]+else', line, re.IGNORECASE) and prevline != '' and not re.search(r'^[ ]*//', prevline): + nwarnings = nwarnings + 1 + if isdelinting: + newfilelines.append('') + nwarningsfixed = nwarningsfixed + 1 + else: + did_lint_cleanly = False + logger.error('There must be one empty line before an else statement') + + # Copyright statement for Facebook + match = re.match('\/\/ Copyright ([0-9]+-[0-9]+) Facebook', line, re.IGNORECASE) + if match: + (copyrightyears, ) = match.groups() + if copyrightyears != gcopyrightyears: + nwarnings = nwarnings + 1 + if isdelinting: + line = re.sub(r'([0-9]+-[0-9]+)', gcopyrightyears, line) + nwarningsfixed = nwarningsfixed + 1 + else: + did_lint_cleanly = False + logger.error('The copyright statement on this file is outdated. Should be 2009-2011') + + if isdelinting: + newfilelines.append(line) + + prevline = line + linenofilter.lineno = linenofilter.lineno + 1 + + if isdelinting and nwarnings > 0: + newfiledata = '\n'.join(newfilelines) + file = open(filename, 'w') + file.write(newfiledata) + + return did_lint_cleanly + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/scripts/ttmodule.py b/src/scripts/ttmodule.py new file mode 100755 index 0000000000..d99e8b2e4d --- /dev/null +++ b/src/scripts/ttmodule.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python +# encoding: utf-8 +""" +ttmodule.py + +Most of the documentation is found in Pbxproj.py. + +Created by Jeff Verkoeyen on 2010-10-18. +Copyright 2009-2010 Facebook + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import logging +import re +import os +import sys +from optparse import OptionParser + +# Three20 Python Objects +import Paths +from Pbxproj import Pbxproj + +# Print the given project's dependencies to stdout. +def print_dependencies(name): + pbxproj = Pbxproj.get_pbxproj_by_name(name) + print str(pbxproj)+"..." + if pbxproj.dependencies(): + [sys.stdout.write("\t"+x+"\n") for x in pbxproj.dependencies()] + +def get_dependency_modules(dependency_names): + dependency_modules = {} + if not dependency_names: + return dependency_modules + + for name in dependency_names: + project = Pbxproj.get_pbxproj_by_name(name) + dependency_modules[project.uniqueid()] = project + + dependencies = project.dependencies() + if dependencies is None: + print "Failed to get dependencies; it's possible that the given target doesn't exist." + sys.exit(0) + + submodules = get_dependency_modules(dependencies) + for guid, submodule in submodules.items(): + dependency_modules[guid] = submodule + + return dependency_modules + +def add_modules_to_project(module_names, project, configs): + logging.info(project) + logging.info("Checking dependencies...") + if project.dependencies() is None: + logging.error("Failed to get dependencies. Check the error logs for more details.") + sys.exit(0) + if len(project.dependencies()) == 0: + logging.info("\tNo dependencies.") + else: + logging.info("Existing dependencies:") + [logging.info("\t"+x) for x in project.dependencies()] + + modules = get_dependency_modules(module_names) + + logging.info("Requested dependency list:") + [logging.info("\t"+str(x)) for k,x in modules.items()] + + logging.info("Adding dependencies...") + failed = [] + for k,v in modules.items(): + if v.name == 'Three20UI': + project.add_framework('QuartzCore.framework') + if v.name == 'Three20Core': + project.add_bundle() + + if not project.add_dependency(v): + failed.append(k) + + if configs: + for config in configs: + project.add_header_search_path(config) + + project.add_build_setting(config, 'OTHER_LDFLAGS', '-ObjC') + else: + for configuration in project.configurations: + project.add_header_search_path(configuration[1]) + + for k,v in modules.items(): + project.add_build_setting(configuration[1], 'OTHER_LDFLAGS', '-ObjC') + + if len(failed) > 0: + logging.error("Some dependencies failed to be added:") + [logging.error("\t"+str(x)+"\n") for x in failed] + +def main(): + usage = '''%prog [options] module(s) + +The Three20 Module Script. +Easily add Three20 modules to your projects. + +MODULES: + + Modules may take the form (:) + defaults to if it is not specified + may be a path to a .pbxproj file. + +EXAMPLES: + + Most common use case: + > %prog -p path/to/myApp/myApp.xcodeproj Three20 + + For adding Xcode 4 support to an Xcode 3.2.# project: + > %prog -p path/to/myApp/myApp.xcodeproj Three20 --xcode-version=4 + + Print all dependencies for the Three20UI module + > %prog -d Three20UI + + Print all dependencies for the extThree20JSON module's extThree20JSON+SBJSON target. + > %prog -d extThree20JSON:extThree20JSON+SBJSON + + Add the Three20 project settings specifically to the Debug and Release configurations. + By default, all Three20 settings are added to all project configurations. + This includes adding the header search path and linker flags. + > %prog -p path/to/myApp.xcodeproj -c Debug -c Release + + Add the extThree20XML module and all of its dependencies to the myApp project. + > %prog -p path/to/myApp.xcodeproj extThree20XML + + Add a specific target of a module to a project. + > %prog -p path/to/myApp.xcodeproj extThree20JSON:extThree20JSON+SBJSON''' + parser = OptionParser(usage = usage) + + parser.add_option("-d", "--dependencies", dest="print_dependencies", + help="Print dependencies for the given modules", + action="store_true") + + parser.add_option("-v", "--verbose", dest="verbose", + help="Display verbose output", + action="store_true") + + parser.add_option("-p", "--project", dest="projects", + help="Add the given modules to this project", action="append") + + parser.add_option("--xcode-version", dest="xcode_version", + help="Set the xcode version you plan to open this project in. By default uses xcodebuild to determine your latest Xcode version.") + + parser.add_option("-c", "--config", dest="configs", + help="Explicit configurations to add Three20 settings to (example: Debug). By default, ttmodule will add configuration settings to every configuration for the given target", action="append") + + (options, args) = parser.parse_args() + + if options.verbose: + log_level = logging.INFO + else: + log_level = logging.WARNING + + logging.basicConfig(level=log_level) + + did_anything = False + + if options.print_dependencies: + [print_dependencies(x) for x in args] + did_anything = True + + if options.projects is not None: + did_anything = True + + if not options.xcode_version: + f=os.popen("xcodebuild -version") + xcodebuild_version = f.readlines()[0] + match = re.search('Xcode ([a-zA-Z0-9.]+)', xcodebuild_version) + if match: + (options.xcode_version, ) = match.groups() + + for name in options.projects: + project = Pbxproj.get_pbxproj_by_name(name, xcode_version = options.xcode_version) + add_modules_to_project(args, project, options.configs) + + if not did_anything: + parser.print_help() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/templates/InstallTemplates.Command b/templates/InstallTemplates3.2.2.Command similarity index 89% rename from templates/InstallTemplates.Command rename to templates/InstallTemplates3.2.2.Command index 73f6638c1f..7a6b372604 100644 --- a/templates/InstallTemplates.Command +++ b/templates/InstallTemplates3.2.2.Command @@ -17,7 +17,7 @@ # Installs the project and source file templates. Overwrites any existing files. mkdir -p ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Three20\ Application -cp -r projects/ ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Three20\ Application +cp -r projects3.2.2/ ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Three20\ Application mkdir -p ~/Library/Application\ Support/Developer/Shared/Xcode/File\ Templates cp -r source/ ~/Library/Application\ Support/Developer/Shared/Xcode/File\ Templates diff --git a/templates/InstallTemplates3.2.4.Command b/templates/InstallTemplates3.2.4.Command new file mode 100644 index 0000000000..ccebc3eae0 --- /dev/null +++ b/templates/InstallTemplates3.2.4.Command @@ -0,0 +1,24 @@ +# +# Copyright 2009-2010 Facebook +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Installs the project and source file templates. Overwrites any existing files. + +mkdir -p ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Three20\ Application +cp -r projects3.2.4/ ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Three20\ Application + +mkdir -p ~/Library/Application\ Support/Developer/Shared/Xcode/File\ Templates +cp -r source/ ~/Library/Application\ Support/Developer/Shared/Xcode/File\ Templates + diff --git a/templates/InstallTemplates3.2.5.Command b/templates/InstallTemplates3.2.5.Command new file mode 100644 index 0000000000..288e09ba68 --- /dev/null +++ b/templates/InstallTemplates3.2.5.Command @@ -0,0 +1,24 @@ +# +# Copyright 2009-2010 Facebook +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Installs the project and source file templates. Overwrites any existing files. + +mkdir -p ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Three20\ Application +cp -r projects3.2.5/ ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Three20\ Application + +mkdir -p ~/Library/Application\ Support/Developer/Shared/Xcode/File\ Templates +cp -r source/ ~/Library/Application\ Support/Developer/Shared/Xcode/File\ Templates + diff --git a/templates/projects/Simple Application/Simple Application/Classes/AppDelegate.h b/templates/projects3.2.2/Simple Application/Simple Application/Classes/AppDelegate.h similarity index 100% rename from templates/projects/Simple Application/Simple Application/Classes/AppDelegate.h rename to templates/projects3.2.2/Simple Application/Simple Application/Classes/AppDelegate.h diff --git a/templates/projects/Simple Application/Simple Application/Classes/AppDelegate.m b/templates/projects3.2.2/Simple Application/Simple Application/Classes/AppDelegate.m similarity index 100% rename from templates/projects/Simple Application/Simple Application/Classes/AppDelegate.m rename to templates/projects3.2.2/Simple Application/Simple Application/Classes/AppDelegate.m diff --git a/templates/projects/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist b/templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist similarity index 100% rename from templates/projects/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist rename to templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist diff --git a/templates/projects/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch b/templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch similarity index 100% rename from templates/projects/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch rename to templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch diff --git a/templates/projects/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns similarity index 100% rename from templates/projects/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns rename to templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns diff --git a/templates/projects/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist similarity index 100% rename from templates/projects/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist rename to templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist diff --git a/templates/projects/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj similarity index 94% rename from templates/projects/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj rename to templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj index 2a50561099..2a6567f15b 100755 --- a/templates/projects/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj +++ b/templates/projects3.2.2/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -28,126 +28,126 @@ isa = PBXContainerItemProxy; containerPortal = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20Core.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20Core; }; 6E3796B711B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* CoreUnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3796BB11B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20Network.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20Network; }; 6E3796BD11B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3796C111B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20Style.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20Style; }; 6E3796C311B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3796C711B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20UICommon.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20UICommon; }; 6E3796C911B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3796CD11B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20UINavigator.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20UINavigator; }; 6E3796CF11B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3796D311B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20UI.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20UI; }; 6E3796D511B9BD630011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3796E811B9BD800011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20Network */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Network; }; 6E3796EA11B9BD800011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20UINavigator */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UINavigator; }; 6E3796EC11B9BD800011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20Core */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Core; }; 6E3796EE11B9BD800011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20Style */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Style; }; 6E3796F011B9BD800011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20UICommon */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UICommon; }; 6E3796F211B9BD800011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20UI */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UI; }; 6EF962B6118E9553003902E7 /* PBXContainerItemProxy */ = { @@ -403,6 +403,12 @@ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; compatibilityVersion = "Xcode 3.1"; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -617,11 +623,13 @@ GCC_PREPROCESSOR_DEFINITIONS = DEBUG; HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; OTHER_LDFLAGS = ( "-all_load", "-ObjC", ); PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos3.1.3; }; name = Debug; }; @@ -634,37 +642,35 @@ GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; OTHER_LDFLAGS = ( "-all_load", "-ObjC", ); PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos3.1.3; }; name = Release; }; C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - SDKROOT = iphoneos3.1.2; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - SDKROOT = iphoneos3.1.2; }; name = Release; }; diff --git a/templates/projects/Simple Application/Simple Application/main.m b/templates/projects3.2.2/Simple Application/Simple Application/main.m similarity index 100% rename from templates/projects/Simple Application/Simple Application/main.m rename to templates/projects3.2.2/Simple Application/Simple Application/main.m diff --git a/templates/projects/Simple Application/Simple Core Data Application/Classes/AppDelegate.h b/templates/projects3.2.2/Simple Application/Simple Core Data Application/Classes/AppDelegate.h similarity index 100% rename from templates/projects/Simple Application/Simple Core Data Application/Classes/AppDelegate.h rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/Classes/AppDelegate.h diff --git a/templates/projects/Simple Application/Simple Core Data Application/Classes/AppDelegate.m b/templates/projects3.2.2/Simple Application/Simple Core Data Application/Classes/AppDelegate.m similarity index 100% rename from templates/projects/Simple Application/Simple Core Data Application/Classes/AppDelegate.m rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/Classes/AppDelegate.m diff --git a/templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist b/templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist similarity index 100% rename from templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist diff --git a/templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements b/templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements similarity index 100% rename from templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements diff --git a/templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout b/templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout similarity index 100% rename from templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout diff --git a/templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch b/templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch similarity index 100% rename from templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch diff --git a/templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns similarity index 100% rename from templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns diff --git a/templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist similarity index 100% rename from templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist diff --git a/templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj similarity index 95% rename from templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj index c8e4c051f7..94a7e3341a 100755 --- a/templates/projects/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj +++ b/templates/projects3.2.2/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -30,126 +30,126 @@ isa = PBXContainerItemProxy; containerPortal = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20Core.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20Core; }; 6E37972611B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* CoreUnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E37972A11B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20Network.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20Network; }; 6E37972C11B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E37973011B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20Style.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20Style; }; 6E37973211B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E37973611B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20UICommon.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20UICommon; }; 6E37973811B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E37973C11B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20UINavigator.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20UINavigator; }; 6E37973E11B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E37974211B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20UI.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20UI; }; 6E37974411B9BDB60011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E37974F11B9BDD70011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20Network */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Network; }; 6E37975111B9BDD70011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20UINavigator */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UINavigator; }; 6E37975311B9BDD70011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20UICommon */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UICommon; }; 6E37975511B9BDD70011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20Core */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Core; }; 6E37975711B9BDD70011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20Style */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Style; }; 6E37975911B9BDD70011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20UI */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UI; }; 6EF963E8118E96CA003902E7 /* PBXContainerItemProxy */ = { @@ -410,6 +410,12 @@ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; compatibilityVersion = "Xcode 3.1"; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( @@ -625,11 +631,13 @@ GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; OTHER_LDFLAGS = ( "-all_load", "-ObjC", ); PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos3.1.3; }; name = Debug; }; @@ -643,38 +651,36 @@ GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; OTHER_LDFLAGS = ( "-all_load", "-ObjC", ); PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos3.1.3; }; name = Release; }; C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - SDKROOT = iphoneos3.1.2; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - SDKROOT = iphoneos3.1.2; }; name = Release; }; diff --git a/templates/projects/Simple Application/Simple Core Data Application/main.m b/templates/projects3.2.2/Simple Application/Simple Core Data Application/main.m similarity index 100% rename from templates/projects/Simple Application/Simple Core Data Application/main.m rename to templates/projects3.2.2/Simple Application/Simple Core Data Application/main.m diff --git a/templates/projects/Simple Application/TemplateChooser.plist b/templates/projects3.2.2/Simple Application/TemplateChooser.plist similarity index 100% rename from templates/projects/Simple Application/TemplateChooser.plist rename to templates/projects3.2.2/Simple Application/TemplateChooser.plist diff --git a/templates/projects/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h b/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h similarity index 100% rename from templates/projects/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h rename to templates/projects3.2.2/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h diff --git a/templates/projects/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m b/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m similarity index 100% rename from templates/projects/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m rename to templates/projects3.2.2/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m diff --git a/templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist b/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist similarity index 100% rename from templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist rename to templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist diff --git a/templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch b/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch similarity index 100% rename from templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch rename to templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch diff --git a/templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns similarity index 100% rename from templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns rename to templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns diff --git a/templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist similarity index 100% rename from templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist rename to templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist diff --git a/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj new file mode 100755 index 0000000000..3834a4d71d --- /dev/null +++ b/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -0,0 +1,705 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 6E3175FB1126577100F4DDEC /* Three20.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 6E3175FA1126577100F4DDEC /* Three20.bundle */; }; + 6E3176191126579100F4DDEC /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3176181126579100F4DDEC /* QuartzCore.framework */; }; + 6E3797BA11B9BE030011C497 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37979911B9BE010011C497 /* libThree20Core.a */; }; + 6E3797BB11B9BE030011C497 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37979F11B9BE010011C497 /* libThree20Network.a */; }; + 6E3797BC11B9BE040011C497 /* libThree20Style.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3797A511B9BE010011C497 /* libThree20Style.a */; }; + 6E3797BD11B9BE040011C497 /* libThree20UI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3797B711B9BE010011C497 /* libThree20UI.a */; }; + 6E3797BE11B9BE050011C497 /* libThree20UICommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3797AB11B9BE010011C497 /* libThree20UICommon.a */; }; + 6E3797BF11B9BE050011C497 /* libThree20UINavigator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3797B111B9BE010011C497 /* libThree20UINavigator.a */; }; + 6EF96366118E9604003902E7 /* libThree20.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EF96363118E95FF003902E7 /* libThree20.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 6E37979811B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E37979A11B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37979E11B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E3797A011B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797A411B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E3797A611B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797AA11B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E3797AC11B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797B011B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E3797B211B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797B611B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6E3797B811B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797CB11B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E3797CD11B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E3797CF11B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E3797D111B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E3797D311B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E3797D511B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6EF96362118E95FF003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF96337118E95FE003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20; + }; + 6EF96364118E95FF003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF96337118E95FE003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6EF96367118E9608003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF96337118E95FE003902E7 /* Three20.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "___PROJECTNAME___.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6E3175FA1126577100F4DDEC /* Three20.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Three20.bundle; path = ../three20/src/Three20.bundle; sourceTree = SOURCE_ROOT; }; + 6E3176181126579100F4DDEC /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../three20/src/Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../three20/src/Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Style.xcodeproj; path = ../three20/src/Three20Style/Three20Style.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UICommon.xcodeproj; path = ../three20/src/Three20UICommon/Three20UICommon.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UINavigator.xcodeproj; path = ../three20/src/Three20UINavigator/Three20UINavigator.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UI.xcodeproj; path = ../three20/src/Three20UI/Three20UI.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6EF96337118E95FE003902E7 /* Three20.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20.xcodeproj; path = ../three20/src/Three20/Three20.xcodeproj; sourceTree = SOURCE_ROOT; }; + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + 6E3176191126579100F4DDEC /* QuartzCore.framework in Frameworks */, + 6EF96366118E9604003902E7 /* libThree20.a in Frameworks */, + 6E3797BA11B9BE030011C497 /* libThree20Core.a in Frameworks */, + 6E3797BB11B9BE030011C497 /* libThree20Network.a in Frameworks */, + 6E3797BC11B9BE040011C497 /* libThree20Style.a in Frameworks */, + 6E3797BD11B9BE040011C497 /* libThree20UI.a in Frameworks */, + 6E3797BE11B9BE050011C497 /* libThree20UICommon.a in Frameworks */, + 6E3797BF11B9BE050011C497 /* libThree20UINavigator.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources-iPad */, + 6EF9630E118E95E6003902E7 /* Dependencies */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + 6E3176181126579100F4DDEC /* QuartzCore.framework */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources-iPad */ = { + isa = PBXGroup; + children = ( + 6E3175FA1126577100F4DDEC /* Three20.bundle */, + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */, + ); + name = "Resources-iPad"; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 6E37978511B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37979911B9BE010011C497 /* libThree20Core.a */, + 6E37979B11B9BE010011C497 /* CoreUnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37978811B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37979F11B9BE010011C497 /* libThree20Network.a */, + 6E3797A111B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37978B11B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3797A511B9BE010011C497 /* libThree20Style.a */, + 6E3797A711B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37978E11B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3797AB11B9BE010011C497 /* libThree20UICommon.a */, + 6E3797AD11B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37979111B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3797B111B9BE010011C497 /* libThree20UINavigator.a */, + 6E3797B311B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37979411B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3797B711B9BE010011C497 /* libThree20UI.a */, + 6E3797B911B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3797C111B9BE070011C497 /* Three20 */ = { + isa = PBXGroup; + children = ( + 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */, + 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */, + 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */, + 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */, + 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */, + 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */, + 6EF96337118E95FE003902E7 /* Three20.xcodeproj */, + ); + name = Three20; + sourceTree = ""; + }; + 6E3797C211B9BE0D0011C497 /* Three20 Extensions */ = { + isa = PBXGroup; + children = ( + ); + name = "Three20 Extensions"; + sourceTree = ""; + }; + 6EF9630E118E95E6003902E7 /* Dependencies */ = { + isa = PBXGroup; + children = ( + 6E3797C111B9BE070011C497 /* Three20 */, + 6E3797C211B9BE0D0011C497 /* Three20 Extensions */, + ); + name = Dependencies; + sourceTree = ""; + }; + 6EF96338118E95FE003902E7 /* Products */ = { + isa = PBXGroup; + children = ( + 6EF96363118E95FF003902E7 /* libThree20.a */, + 6EF96365118E95FF003902E7 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6EF96368118E9608003902E7 /* PBXTargetDependency */, + 6E3797CC11B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797CE11B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797D011B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797D211B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797D411B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797D611B9BE1C0011C497 /* PBXTargetDependency */, + ); + name = "___PROJECTNAME___"; + productName = "___PROJECTNAME___"; + productReference = 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 6EF96338118E95FE003902E7 /* Products */; + ProjectRef = 6EF96337118E95FE003902E7 /* Three20.xcodeproj */; + }, + { + ProductGroup = 6E37978511B9BE010011C497 /* Products */; + ProjectRef = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; + }, + { + ProductGroup = 6E37978811B9BE010011C497 /* Products */; + ProjectRef = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; + }, + { + ProductGroup = 6E37978B11B9BE010011C497 /* Products */; + ProjectRef = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; + }, + { + ProductGroup = 6E37979411B9BE010011C497 /* Products */; + ProjectRef = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; + }, + { + ProductGroup = 6E37978E11B9BE010011C497 /* Products */; + ProjectRef = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; + }, + { + ProductGroup = 6E37979111B9BE010011C497 /* Products */; + ProjectRef = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 6E37979911B9BE010011C497 /* libThree20Core.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Core.a; + remoteRef = 6E37979811B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37979B11B9BE010011C497 /* CoreUnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CoreUnitTests.octest; + remoteRef = 6E37979A11B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37979F11B9BE010011C497 /* libThree20Network.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Network.a; + remoteRef = 6E37979E11B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797A111B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797A011B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797A511B9BE010011C497 /* libThree20Style.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Style.a; + remoteRef = 6E3797A411B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797A711B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797A611B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797AB11B9BE010011C497 /* libThree20UICommon.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UICommon.a; + remoteRef = 6E3797AA11B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797AD11B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797AC11B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797B111B9BE010011C497 /* libThree20UINavigator.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UINavigator.a; + remoteRef = 6E3797B011B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797B311B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797B211B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797B711B9BE010011C497 /* libThree20UI.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UI.a; + remoteRef = 6E3797B611B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797B911B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797B811B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF96363118E95FF003902E7 /* libThree20.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20.a; + remoteRef = 6EF96362118E95FF003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF96365118E95FF003902E7 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6EF96364118E95FF003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6E3175FB1126577100F4DDEC /* Three20.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 6E3797CC11B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UINavigator; + targetProxy = 6E3797CB11B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797CE11B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UICommon; + targetProxy = 6E3797CD11B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797D011B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Style; + targetProxy = 6E3797CF11B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797D211B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Network; + targetProxy = 6E3797D111B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797D411B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Core; + targetProxy = 6E3797D311B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797D611B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UI; + targetProxy = 6E3797D511B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6EF96368118E9608003902E7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20; + targetProxy = 6EF96367118E9608003902E7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos3.1.3; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos3.1.3; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/templates/projects/Simple iPad Application/Simple iPad Application/main.m b/templates/projects3.2.2/Simple iPad Application/Simple iPad Application/main.m similarity index 100% rename from templates/projects/Simple iPad Application/Simple iPad Application/main.m rename to templates/projects3.2.2/Simple iPad Application/Simple iPad Application/main.m diff --git a/templates/projects3.2.4/Simple Application/Simple Application/Classes/AppDelegate.h b/templates/projects3.2.4/Simple Application/Simple Application/Classes/AppDelegate.h new file mode 100644 index 0000000000..7cfb6b5468 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Application/Classes/AppDelegate.h @@ -0,0 +1,13 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.h +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +@interface AppDelegate : NSObject { +} + +@end + diff --git a/templates/projects3.2.4/Simple Application/Simple Application/Classes/AppDelegate.m b/templates/projects3.2.4/Simple Application/Simple Application/Classes/AppDelegate.m new file mode 100644 index 0000000000..7e3c63c5f5 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Application/Classes/AppDelegate.m @@ -0,0 +1,46 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "AppDelegate.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation AppDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)applicationDidFinishLaunching:(UIApplication *)application { + TTNavigator* navigator = [TTNavigator navigator]; + navigator.persistenceMode = TTNavigatorPersistenceModeAll; + + TTURLMap* map = navigator.URLMap; + + [map from:@"*" toViewController:[TTWebController class]]; + + if (![navigator restoreViewControllers]) { + [navigator openURLAction:[TTURLAction actionWithURLPath:@"http://three20.info"]]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)navigator:(TTNavigator*)navigator shouldOpenURL:(NSURL*)URL { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)URL { + [[TTNavigator navigator] openURLAction:[TTURLAction actionWithURLPath:URL.absoluteString]]; + return YES; +} + + +@end diff --git a/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist new file mode 100644 index 0000000000..15665856b0 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + + diff --git a/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch new file mode 100644 index 0000000000..b4a8da089d --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch @@ -0,0 +1,9 @@ +// +// Prefix header for all source files of the '___PROJECTNAME___' target in the '___PROJECTNAME___' project +// + +#ifdef __OBJC__ + #import + #import + #import "Three20/Three20.h" +#endif diff --git a/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000000..d80230f57f Binary files /dev/null and b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns differ diff --git a/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist new file mode 100644 index 0000000000..7110fc90d3 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist @@ -0,0 +1,8 @@ + + + + + Description + This template provides a starting point for any application using the three20 framework. It provides just an application delegate and a basic TTNavigator. + + diff --git a/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj new file mode 100755 index 0000000000..fb4c90a7e0 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -0,0 +1,702 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 6E3796DA11B9BD740011C497 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796B611B9BD630011C497 /* libThree20Core.a */; }; + 6E3796DB11B9BD750011C497 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796BC11B9BD630011C497 /* libThree20Network.a */; }; + 6E3796DC11B9BD750011C497 /* libThree20Style.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796C211B9BD630011C497 /* libThree20Style.a */; }; + 6E3796DD11B9BD750011C497 /* libThree20UI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796D411B9BD630011C497 /* libThree20UI.a */; }; + 6E3796DE11B9BD760011C497 /* libThree20UICommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796C811B9BD630011C497 /* libThree20UICommon.a */; }; + 6E3796DF11B9BD760011C497 /* libThree20UINavigator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796CE11B9BD630011C497 /* libThree20UINavigator.a */; }; + 6EF962BA118E955A003902E7 /* libThree20.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EF962B7118E9553003902E7 /* libThree20.a */; }; + EB383B6510BBF62B0000B2D2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB383B6410BBF62B0000B2D2 /* QuartzCore.framework */; }; + EB383B6D10BBF6360000B2D2 /* Three20.bundle in Resources */ = {isa = PBXBuildFile; fileRef = EB383B6C10BBF6360000B2D2 /* Three20.bundle */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 6E3796B511B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E3796B711B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796BB11B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E3796BD11B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796C111B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E3796C311B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796C711B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E3796C911B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796CD11B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E3796CF11B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796D311B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6E3796D511B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796E811B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E3796EA11B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E3796EC11B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E3796EE11B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E3796F011B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E3796F211B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6EF962B6118E9553003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF9628B118E9552003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20; + }; + 6EF962B8118E9553003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF9628B118E9552003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6EF962BB118E955F003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF9628B118E9552003902E7 /* Three20.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "___PROJECTNAME___.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; sourceTree = ""; }; + 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../three20/src/Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../three20/src/Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Style.xcodeproj; path = ../three20/src/Three20Style/Three20Style.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UICommon.xcodeproj; path = ../three20/src/Three20UICommon/Three20UICommon.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UINavigator.xcodeproj; path = ../three20/src/Three20UINavigator/Three20UINavigator.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UI.xcodeproj; path = ../three20/src/Three20UI/Three20UI.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6EF9628B118E9552003902E7 /* Three20.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20.xcodeproj; path = ../three20/src/Three20/Three20.xcodeproj; sourceTree = SOURCE_ROOT; }; + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + EB383B6410BBF62B0000B2D2 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + EB383B6C10BBF6360000B2D2 /* Three20.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Three20.bundle; path = ../three20/src/Three20.bundle; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + EB383B6510BBF62B0000B2D2 /* QuartzCore.framework in Frameworks */, + 6EF962BA118E955A003902E7 /* libThree20.a in Frameworks */, + 6E3796DA11B9BD740011C497 /* libThree20Core.a in Frameworks */, + 6E3796DB11B9BD750011C497 /* libThree20Network.a in Frameworks */, + 6E3796DC11B9BD750011C497 /* libThree20Style.a in Frameworks */, + 6E3796DD11B9BD750011C497 /* libThree20UI.a in Frameworks */, + 6E3796DE11B9BD760011C497 /* libThree20UICommon.a in Frameworks */, + 6E3796DF11B9BD760011C497 /* libThree20UINavigator.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 6EF96274118E9502003902E7 /* Dependencies */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + EB383B6C10BBF6360000B2D2 /* Three20.bundle */, + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + EB383B6410BBF62B0000B2D2 /* QuartzCore.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 6E3796A211B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796B611B9BD630011C497 /* libThree20Core.a */, + 6E3796B811B9BD630011C497 /* CoreUnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796A511B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796BC11B9BD630011C497 /* libThree20Network.a */, + 6E3796BE11B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796A811B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796C211B9BD630011C497 /* libThree20Style.a */, + 6E3796C411B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796AB11B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796C811B9BD630011C497 /* libThree20UICommon.a */, + 6E3796CA11B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796AE11B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796CE11B9BD630011C497 /* libThree20UINavigator.a */, + 6E3796D011B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796B111B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796D411B9BD630011C497 /* libThree20UI.a */, + 6E3796D611B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796D811B9BD650011C497 /* Three20 */ = { + isa = PBXGroup; + children = ( + 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */, + 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */, + 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */, + 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */, + 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */, + 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */, + 6EF9628B118E9552003902E7 /* Three20.xcodeproj */, + ); + name = Three20; + sourceTree = ""; + }; + 6E3796D911B9BD6C0011C497 /* Three20 Extensions */ = { + isa = PBXGroup; + children = ( + ); + name = "Three20 Extensions"; + sourceTree = ""; + }; + 6EF96274118E9502003902E7 /* Dependencies */ = { + isa = PBXGroup; + children = ( + 6E3796D811B9BD650011C497 /* Three20 */, + 6E3796D911B9BD6C0011C497 /* Three20 Extensions */, + ); + name = Dependencies; + sourceTree = ""; + }; + 6EF9628C118E9552003902E7 /* Products */ = { + isa = PBXGroup; + children = ( + 6EF962B7118E9553003902E7 /* libThree20.a */, + 6EF962B9118E9553003902E7 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6EF962BC118E955F003902E7 /* PBXTargetDependency */, + 6E3796E911B9BD800011C497 /* PBXTargetDependency */, + 6E3796EB11B9BD800011C497 /* PBXTargetDependency */, + 6E3796ED11B9BD800011C497 /* PBXTargetDependency */, + 6E3796EF11B9BD800011C497 /* PBXTargetDependency */, + 6E3796F111B9BD800011C497 /* PBXTargetDependency */, + 6E3796F311B9BD800011C497 /* PBXTargetDependency */, + ); + name = "___PROJECTNAME___"; + productName = "___PROJECTNAME___"; + productReference = 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 6EF9628C118E9552003902E7 /* Products */; + ProjectRef = 6EF9628B118E9552003902E7 /* Three20.xcodeproj */; + }, + { + ProductGroup = 6E3796A211B9BD630011C497 /* Products */; + ProjectRef = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; + }, + { + ProductGroup = 6E3796A511B9BD630011C497 /* Products */; + ProjectRef = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; + }, + { + ProductGroup = 6E3796A811B9BD630011C497 /* Products */; + ProjectRef = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; + }, + { + ProductGroup = 6E3796B111B9BD630011C497 /* Products */; + ProjectRef = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; + }, + { + ProductGroup = 6E3796AB11B9BD630011C497 /* Products */; + ProjectRef = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; + }, + { + ProductGroup = 6E3796AE11B9BD630011C497 /* Products */; + ProjectRef = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 6E3796B611B9BD630011C497 /* libThree20Core.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Core.a; + remoteRef = 6E3796B511B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796B811B9BD630011C497 /* CoreUnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CoreUnitTests.octest; + remoteRef = 6E3796B711B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796BC11B9BD630011C497 /* libThree20Network.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Network.a; + remoteRef = 6E3796BB11B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796BE11B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796BD11B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796C211B9BD630011C497 /* libThree20Style.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Style.a; + remoteRef = 6E3796C111B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796C411B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796C311B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796C811B9BD630011C497 /* libThree20UICommon.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UICommon.a; + remoteRef = 6E3796C711B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796CA11B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796C911B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796CE11B9BD630011C497 /* libThree20UINavigator.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UINavigator.a; + remoteRef = 6E3796CD11B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796D011B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796CF11B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796D411B9BD630011C497 /* libThree20UI.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UI.a; + remoteRef = 6E3796D311B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796D611B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796D511B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF962B7118E9553003902E7 /* libThree20.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20.a; + remoteRef = 6EF962B6118E9553003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF962B9118E9553003902E7 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6EF962B8118E9553003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EB383B6D10BBF6360000B2D2 /* Three20.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 6E3796E911B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Network; + targetProxy = 6E3796E811B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796EB11B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UINavigator; + targetProxy = 6E3796EA11B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796ED11B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Core; + targetProxy = 6E3796EC11B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796EF11B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Style; + targetProxy = 6E3796EE11B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796F111B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UICommon; + targetProxy = 6E3796F011B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796F311B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UI; + targetProxy = 6E3796F211B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6EF962BC118E955F003902E7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20; + targetProxy = 6EF962BB118E955F003902E7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos4.1; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos4.1; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/templates/projects3.2.4/Simple Application/Simple Application/main.m b/templates/projects3.2.4/Simple Application/Simple Application/main.m new file mode 100644 index 0000000000..8023e88258 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Application/main.m @@ -0,0 +1,14 @@ +// +// main.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +int main(int argc, char *argv[]) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate"); + [pool release]; + return retVal; +} diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/Classes/AppDelegate.h b/templates/projects3.2.4/Simple Application/Simple Core Data Application/Classes/AppDelegate.h new file mode 100644 index 0000000000..950ab6d71f --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Core Data Application/Classes/AppDelegate.h @@ -0,0 +1,28 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.h +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface AppDelegate : NSObject { + NSManagedObjectModel* _managedObjectModel; + NSManagedObjectContext* _managedObjectContext; + NSPersistentStoreCoordinator* _persistentStoreCoordinator; + + // App State + BOOL _modelCreated; + BOOL _resetModel; +} + +@property (nonatomic, retain, readonly) NSManagedObjectContext* managedObjectContext; +@property (nonatomic, readonly) NSString* applicationDocumentsDirectory; + + +@end + diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/Classes/AppDelegate.m b/templates/projects3.2.4/Simple Application/Simple Core Data Application/Classes/AppDelegate.m new file mode 100644 index 0000000000..e10428a214 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Core Data Application/Classes/AppDelegate.m @@ -0,0 +1,207 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "AppDelegate.h" + +#define kStoreType NSSQLiteStoreType +#define kStoreFilename @"db.sqlite" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface AppDelegate() +- (NSPersistentStoreCoordinator *)persistentStoreCoordinator; +- (NSString *)applicationDocumentsDirectory; + +@end + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation AppDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)applicationDidFinishLaunching:(UIApplication *)application { + // Forcefully removes the model db and recreates it. + //_resetModel = YES; + + TTNavigator* navigator = [TTNavigator navigator]; + navigator.persistenceMode = TTNavigatorPersistenceModeAll; + + TTURLMap* map = navigator.URLMap; + + [map from:@"*" toViewController:[TTWebController class]]; + + if (![navigator restoreViewControllers]) { + [navigator openURLAction:[TTURLAction actionWithURLPath:@"http://three20.info"]]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)dealloc { + TT_RELEASE_SAFELY(_managedObjectContext); + TT_RELEASE_SAFELY(_managedObjectModel); + TT_RELEASE_SAFELY(_persistentStoreCoordinator); + + [super dealloc]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)navigator:(TTNavigator*)navigator shouldOpenURL:(NSURL*)URL { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)URL { + [[TTNavigator navigator] openURLAction:[TTURLAction actionWithURLPath:URL.absoluteString]]; + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)applicationWillTerminate:(UIApplication *)application { + NSError* error = nil; + if (_managedObjectContext != nil) { + if ([_managedObjectContext hasChanges] && ![_managedObjectContext save:&error]) { + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + abort(); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Core Data stack + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSManagedObjectContext*)managedObjectContext { + if( _managedObjectContext != nil ) { + return _managedObjectContext; + } + + NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; + if (coordinator != nil) { + _managedObjectContext = [[NSManagedObjectContext alloc] init]; + [_managedObjectContext setPersistentStoreCoordinator: coordinator]; + [_managedObjectContext setUndoManager:nil]; + [_managedObjectContext setRetainsRegisteredObjects:YES]; + } + return _managedObjectContext; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSManagedObjectModel*)managedObjectModel { + if( _managedObjectModel != nil ) { + return _managedObjectModel; + } + _managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; + return _managedObjectModel; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString*)storePath { + return [[self applicationDocumentsDirectory] + stringByAppendingPathComponent: kStoreFilename]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSURL*)storeUrl { + return [NSURL fileURLWithPath:[self storePath]]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSDictionary*)migrationOptions { + return nil; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSPersistentStoreCoordinator*)persistentStoreCoordinator { + if( _persistentStoreCoordinator != nil ) { + return _persistentStoreCoordinator; + } + + NSString* storePath = [self storePath]; + NSURL *storeUrl = [self storeUrl]; + + NSError* error; + _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] + initWithManagedObjectModel: [self managedObjectModel]]; + + NSDictionary* options = [self migrationOptions]; + + // Check whether the store already exists or not. + NSFileManager* fileManager = [NSFileManager defaultManager]; + BOOL exists = [fileManager fileExistsAtPath:storePath]; + + TTDINFO(storePath); + if( !exists ) { + _modelCreated = YES; + } else { + if( _resetModel || + [[NSUserDefaults standardUserDefaults] boolForKey:@"erase_all_preference"] ) { + [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"erase_all_preference"]; + [fileManager removeItemAtPath:storePath error:nil]; + _modelCreated = YES; + } + } + + if (![_persistentStoreCoordinator + addPersistentStoreWithType: kStoreType + configuration: nil + URL: storeUrl + options: options + error: &error + ]) { + // We couldn't add the persistent store, so let's wipe it out and try again. + [fileManager removeItemAtPath:storePath error:nil]; + _modelCreated = YES; + + if (![_persistentStoreCoordinator + addPersistentStoreWithType: kStoreType + configuration: nil + URL: storeUrl + options: nil + error: &error + ]) { + // Something is terribly wrong here. + } + } + + return _persistentStoreCoordinator; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Application's documents directory + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString*)applicationDocumentsDirectory { + return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) + lastObject]; +} + + +@end + diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist new file mode 100644 index 0000000000..15665856b0 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + + diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements new file mode 100644 index 0000000000..788aaa2fe1 Binary files /dev/null and b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements differ diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout new file mode 100644 index 0000000000..ce1bc30d8c Binary files /dev/null and b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout differ diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch new file mode 100644 index 0000000000..ff72dc254c --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch @@ -0,0 +1,16 @@ +// +// Prefix header for all source files of the '___PROJECTNAME___' target in the '___PROJECTNAME___' project +// +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iPhone SDK 3.0 and later." +#endif + + +#ifdef __OBJC__ + #import + #import + #import + #import "Three20/Three20.h" +#endif diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000000..d80230f57f Binary files /dev/null and b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns differ diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist new file mode 100644 index 0000000000..7579261498 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist @@ -0,0 +1,8 @@ + + + + + Description + This template provides a starting point for an application that uses three20 with Core Data. It provides an application delegate that creates the Core Data stack and establishes the persistent store. + + diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj new file mode 100755 index 0000000000..8869c900f5 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -0,0 +1,712 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 28C3AD8A0F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 28C3AD890F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel */; }; + 28D801B40F44B63D00FB423F /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D801B30F44B63D00FB423F /* CoreData.framework */; }; + 6E37974911B9BDCB0011C497 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37972511B9BDB60011C497 /* libThree20Core.a */; }; + 6E37974A11B9BDCB0011C497 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37972B11B9BDB60011C497 /* libThree20Network.a */; }; + 6E37974B11B9BDCC0011C497 /* libThree20Style.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37973111B9BDB60011C497 /* libThree20Style.a */; }; + 6E37974C11B9BDCC0011C497 /* libThree20UI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37974311B9BDB60011C497 /* libThree20UI.a */; }; + 6E37974D11B9BDCC0011C497 /* libThree20UICommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37973711B9BDB60011C497 /* libThree20UICommon.a */; }; + 6E37974E11B9BDCD0011C497 /* libThree20UINavigator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37973D11B9BDB60011C497 /* libThree20UINavigator.a */; }; + 6EF963EC118E96CC003902E7 /* libThree20.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EF963E9118E96CA003902E7 /* libThree20.a */; }; + EB383C0610BBF8A40000B2D2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EB383C0510BBF8A40000B2D2 /* AppDelegate.m */; }; + EB383C1410BBF8C70000B2D2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB383C1310BBF8C70000B2D2 /* QuartzCore.framework */; }; + EB383D1110BBFC630000B2D2 /* Three20.bundle in Resources */ = {isa = PBXBuildFile; fileRef = EB383D1010BBFC630000B2D2 /* Three20.bundle */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 6E37972411B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E37972611B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37972A11B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E37972C11B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37973011B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E37973211B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37973611B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E37973811B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37973C11B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E37973E11B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37974211B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6E37974411B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37974F11B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E37975111B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E37975311B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E37975511B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E37975711B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E37975911B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6EF963E8118E96CA003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20; + }; + 6EF963EA118E96CA003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6EF963ED118E96CF003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "___PROJECTNAME___.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28C3AD890F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = "___PROJECTNAMEASIDENTIFIER___.xcdatamodel"; sourceTree = ""; }; + 28D801B30F44B63D00FB423F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; sourceTree = ""; }; + 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../three20/src/Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../three20/src/Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Style.xcodeproj; path = ../three20/src/Three20Style/Three20Style.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UICommon.xcodeproj; path = ../three20/src/Three20UICommon/Three20UICommon.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UINavigator.xcodeproj; path = ../three20/src/Three20UINavigator/Three20UINavigator.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UI.xcodeproj; path = ../three20/src/Three20UI/Three20UI.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20.xcodeproj; path = ../three20/src/Three20/Three20.xcodeproj; sourceTree = SOURCE_ROOT; }; + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; sourceTree = ""; }; + EB383C0410BBF8A40000B2D2 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Classes/AppDelegate.h; sourceTree = SOURCE_ROOT; }; + EB383C0510BBF8A40000B2D2 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Classes/AppDelegate.m; sourceTree = SOURCE_ROOT; }; + EB383C1310BBF8C70000B2D2 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + EB383D1010BBFC630000B2D2 /* Three20.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Three20.bundle; path = ../three20/src/Three20.bundle; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, + 28D801B40F44B63D00FB423F /* CoreData.framework in Frameworks */, + EB383C1410BBF8C70000B2D2 /* QuartzCore.framework in Frameworks */, + 6EF963EC118E96CC003902E7 /* libThree20.a in Frameworks */, + 6E37974911B9BDCB0011C497 /* libThree20Core.a in Frameworks */, + 6E37974A11B9BDCB0011C497 /* libThree20Network.a in Frameworks */, + 6E37974B11B9BDCC0011C497 /* libThree20Style.a in Frameworks */, + 6E37974C11B9BDCC0011C497 /* libThree20UI.a in Frameworks */, + 6E37974D11B9BDCC0011C497 /* libThree20UICommon.a in Frameworks */, + 6E37974E11B9BDCD0011C497 /* libThree20UINavigator.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + EB383C0410BBF8A40000B2D2 /* AppDelegate.h */, + EB383C0510BBF8A40000B2D2 /* AppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 6EF963BC118E96B7003902E7 /* Dependencies */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + EB383D1010BBFC630000B2D2 /* Three20.bundle */, + 28C3AD890F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel */, + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, + 28D801B30F44B63D00FB423F /* CoreData.framework */, + EB383C1310BBF8C70000B2D2 /* QuartzCore.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 6E37971111B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37972511B9BDB60011C497 /* libThree20Core.a */, + 6E37972711B9BDB60011C497 /* CoreUnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37971411B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37972B11B9BDB60011C497 /* libThree20Network.a */, + 6E37972D11B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37971711B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37973111B9BDB60011C497 /* libThree20Style.a */, + 6E37973311B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37971A11B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37973711B9BDB60011C497 /* libThree20UICommon.a */, + 6E37973911B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37971D11B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37973D11B9BDB60011C497 /* libThree20UINavigator.a */, + 6E37973F11B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37972011B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37974311B9BDB60011C497 /* libThree20UI.a */, + 6E37974511B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37974711B9BDB80011C497 /* Three20 */ = { + isa = PBXGroup; + children = ( + 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */, + 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */, + 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */, + 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */, + 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */, + 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */, + 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */, + ); + name = Three20; + sourceTree = ""; + }; + 6E37974811B9BDC10011C497 /* Three20 Extensions */ = { + isa = PBXGroup; + children = ( + ); + name = "Three20 Extensions"; + sourceTree = ""; + }; + 6EF963BC118E96B7003902E7 /* Dependencies */ = { + isa = PBXGroup; + children = ( + 6E37974711B9BDB80011C497 /* Three20 */, + 6E37974811B9BDC10011C497 /* Three20 Extensions */, + ); + name = Dependencies; + sourceTree = ""; + }; + 6EF963BE118E96C9003902E7 /* Products */ = { + isa = PBXGroup; + children = ( + 6EF963E9118E96CA003902E7 /* libThree20.a */, + 6EF963EB118E96CA003902E7 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6EF963EE118E96CF003902E7 /* PBXTargetDependency */, + 6E37975011B9BDD70011C497 /* PBXTargetDependency */, + 6E37975211B9BDD70011C497 /* PBXTargetDependency */, + 6E37975411B9BDD70011C497 /* PBXTargetDependency */, + 6E37975611B9BDD70011C497 /* PBXTargetDependency */, + 6E37975811B9BDD70011C497 /* PBXTargetDependency */, + 6E37975A11B9BDD70011C497 /* PBXTargetDependency */, + ); + name = "___PROJECTNAME___"; + productName = "___PROJECTNAME___"; + productReference = 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 6EF963BE118E96C9003902E7 /* Products */; + ProjectRef = 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */; + }, + { + ProductGroup = 6E37971111B9BDB60011C497 /* Products */; + ProjectRef = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; + }, + { + ProductGroup = 6E37971411B9BDB60011C497 /* Products */; + ProjectRef = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; + }, + { + ProductGroup = 6E37971711B9BDB60011C497 /* Products */; + ProjectRef = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; + }, + { + ProductGroup = 6E37972011B9BDB60011C497 /* Products */; + ProjectRef = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; + }, + { + ProductGroup = 6E37971A11B9BDB60011C497 /* Products */; + ProjectRef = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; + }, + { + ProductGroup = 6E37971D11B9BDB60011C497 /* Products */; + ProjectRef = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 6E37972511B9BDB60011C497 /* libThree20Core.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Core.a; + remoteRef = 6E37972411B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37972711B9BDB60011C497 /* CoreUnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CoreUnitTests.octest; + remoteRef = 6E37972611B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37972B11B9BDB60011C497 /* libThree20Network.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Network.a; + remoteRef = 6E37972A11B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37972D11B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37972C11B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973111B9BDB60011C497 /* libThree20Style.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Style.a; + remoteRef = 6E37973011B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973311B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37973211B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973711B9BDB60011C497 /* libThree20UICommon.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UICommon.a; + remoteRef = 6E37973611B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973911B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37973811B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973D11B9BDB60011C497 /* libThree20UINavigator.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UINavigator.a; + remoteRef = 6E37973C11B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973F11B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37973E11B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37974311B9BDB60011C497 /* libThree20UI.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UI.a; + remoteRef = 6E37974211B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37974511B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37974411B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF963E9118E96CA003902E7 /* libThree20.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20.a; + remoteRef = 6EF963E8118E96CA003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF963EB118E96CA003902E7 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6EF963EA118E96CA003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EB383D1110BBFC630000B2D2 /* Three20.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 28C3AD8A0F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel in Sources */, + EB383C0610BBF8A40000B2D2 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 6E37975011B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Network; + targetProxy = 6E37974F11B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975211B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UINavigator; + targetProxy = 6E37975111B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975411B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UICommon; + targetProxy = 6E37975311B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975611B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Core; + targetProxy = 6E37975511B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975811B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Style; + targetProxy = 6E37975711B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975A11B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UI; + targetProxy = 6E37975911B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6EF963EE118E96CF003902E7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20; + targetProxy = 6EF963ED118E96CF003902E7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos4.1; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos4.1; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/templates/projects3.2.4/Simple Application/Simple Core Data Application/main.m b/templates/projects3.2.4/Simple Application/Simple Core Data Application/main.m new file mode 100644 index 0000000000..9387467159 --- /dev/null +++ b/templates/projects3.2.4/Simple Application/Simple Core Data Application/main.m @@ -0,0 +1,14 @@ +// +// main.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +int main(int argc, char *argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate"); + [pool release]; + return retVal; +} diff --git a/templates/projects3.2.4/Simple Application/TemplateChooser.plist b/templates/projects3.2.4/Simple Application/TemplateChooser.plist new file mode 100644 index 0000000000..09bf9f451d --- /dev/null +++ b/templates/projects3.2.4/Simple Application/TemplateChooser.plist @@ -0,0 +1,12 @@ +{ + Checkboxes = ( + { + Key = CoreData; + Title = "Use Core Data for storage"; + }, + ); + TemplateSelection = { + "" = "Simple Application"; + CoreData = "Simple Core Data Application"; + }; +} diff --git a/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h new file mode 100644 index 0000000000..8694f8e28b --- /dev/null +++ b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h @@ -0,0 +1,17 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.h +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface AppDelegate : NSObject { +} + +@end + diff --git a/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m new file mode 100644 index 0000000000..7e3c63c5f5 --- /dev/null +++ b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m @@ -0,0 +1,46 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "AppDelegate.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation AppDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)applicationDidFinishLaunching:(UIApplication *)application { + TTNavigator* navigator = [TTNavigator navigator]; + navigator.persistenceMode = TTNavigatorPersistenceModeAll; + + TTURLMap* map = navigator.URLMap; + + [map from:@"*" toViewController:[TTWebController class]]; + + if (![navigator restoreViewControllers]) { + [navigator openURLAction:[TTURLAction actionWithURLPath:@"http://three20.info"]]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)navigator:(TTNavigator*)navigator shouldOpenURL:(NSURL*)URL { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)URL { + [[TTNavigator navigator] openURLAction:[TTURLAction actionWithURLPath:URL.absoluteString]]; + return YES; +} + + +@end diff --git a/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist new file mode 100644 index 0000000000..3d1e7e15e9 --- /dev/null +++ b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist @@ -0,0 +1,35 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch new file mode 100644 index 0000000000..9556e4be43 --- /dev/null +++ b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch @@ -0,0 +1,15 @@ +// +// Prefix header for all source files of the '___PROJECTNAME___' target in the '___PROJECTNAME___' project +// +#import + +#ifndef __IPHONE_3_2 +#warning "This project uses features only available in iPhone SDK 3.2 and later." +#endif + + +#ifdef __OBJC__ + #import + #import + #import "Three20/Three20.h" +#endif diff --git a/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000000..d80230f57f Binary files /dev/null and b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns differ diff --git a/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist new file mode 100644 index 0000000000..60b4ce1ffb --- /dev/null +++ b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist @@ -0,0 +1,8 @@ + + + + + Description + This template provides a starting point for an iPad application using the three20 framework. It provides an application delegate and a basic TTNavigator. + + diff --git a/templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj similarity index 95% rename from templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj rename to templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj index 85fd93fdb2..684cdc5ee3 100755 --- a/templates/projects/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj +++ b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -28,126 +28,126 @@ isa = PBXContainerItemProxy; containerPortal = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20Core.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20Core; }; 6E37979A11B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* CoreUnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E37979E11B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20Network.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20Network; }; 6E3797A011B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3797A411B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20Style.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20Style; }; 6E3797A611B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3797AA11B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20UICommon.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20UICommon; }; 6E3797AC11B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3797B011B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20UINavigator.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20UINavigator; }; 6E3797B211B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3797B611B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; proxyType = 2; - remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2 /* libThree20UI.a */; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; remoteInfo = Three20UI; }; 6E3797B811B9BE010011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; proxyType = 2; - remoteGlobalIDString = EB9E6C6210B6A8F800DE563C /* UnitTests.octest */; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; remoteInfo = UnitTests; }; 6E3797CB11B9BE1C0011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20UINavigator */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UINavigator; }; 6E3797CD11B9BE1C0011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20UICommon */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UICommon; }; 6E3797CF11B9BE1C0011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20Style */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Style; }; 6E3797D111B9BE1C0011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20Network */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Network; }; 6E3797D311B9BE1C0011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20Core */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20Core; }; 6E3797D511B9BE1C0011C497 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; proxyType = 1; - remoteGlobalIDString = BEF31F390F352DF5000DE5D2 /* Three20UI */; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; remoteInfo = Three20UI; }; 6EF96362118E95FF003902E7 /* PBXContainerItemProxy */ = { @@ -402,6 +402,7 @@ isa = PBXProject; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, @@ -623,11 +624,13 @@ GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; OTHER_LDFLAGS = ( "-all_load", "-ObjC", ); PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos3.2; }; name = Debug; }; @@ -640,11 +643,13 @@ GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; OTHER_LDFLAGS = ( "-all_load", "-ObjC", ); PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos3.2; VALIDATE_PRODUCT = YES; }; name = Release; @@ -652,13 +657,11 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - SDKROOT = iphoneos3.2; TARGETED_DEVICE_FAMILY = 2; }; name = Debug; @@ -666,14 +669,12 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; PREBINDING = NO; - SDKROOT = iphoneos3.2; TARGETED_DEVICE_FAMILY = 2; }; name = Release; diff --git a/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/main.m b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/main.m new file mode 100644 index 0000000000..8023e88258 --- /dev/null +++ b/templates/projects3.2.4/Simple iPad Application/Simple iPad Application/main.m @@ -0,0 +1,14 @@ +// +// main.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +int main(int argc, char *argv[]) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate"); + [pool release]; + return retVal; +} diff --git a/templates/projects3.2.5/Simple Application/Simple Application/Classes/AppDelegate.h b/templates/projects3.2.5/Simple Application/Simple Application/Classes/AppDelegate.h new file mode 100644 index 0000000000..7cfb6b5468 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Application/Classes/AppDelegate.h @@ -0,0 +1,13 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.h +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +@interface AppDelegate : NSObject { +} + +@end + diff --git a/templates/projects3.2.5/Simple Application/Simple Application/Classes/AppDelegate.m b/templates/projects3.2.5/Simple Application/Simple Application/Classes/AppDelegate.m new file mode 100644 index 0000000000..7e3c63c5f5 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Application/Classes/AppDelegate.m @@ -0,0 +1,46 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "AppDelegate.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation AppDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)applicationDidFinishLaunching:(UIApplication *)application { + TTNavigator* navigator = [TTNavigator navigator]; + navigator.persistenceMode = TTNavigatorPersistenceModeAll; + + TTURLMap* map = navigator.URLMap; + + [map from:@"*" toViewController:[TTWebController class]]; + + if (![navigator restoreViewControllers]) { + [navigator openURLAction:[TTURLAction actionWithURLPath:@"http://three20.info"]]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)navigator:(TTNavigator*)navigator shouldOpenURL:(NSURL*)URL { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)URL { + [[TTNavigator navigator] openURLAction:[TTURLAction actionWithURLPath:URL.absoluteString]]; + return YES; +} + + +@end diff --git a/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist new file mode 100644 index 0000000000..15665856b0 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER___-Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + + diff --git a/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch new file mode 100644 index 0000000000..b4a8da089d --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch @@ -0,0 +1,9 @@ +// +// Prefix header for all source files of the '___PROJECTNAME___' target in the '___PROJECTNAME___' project +// + +#ifdef __OBJC__ + #import + #import + #import "Three20/Three20.h" +#endif diff --git a/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000000..d80230f57f Binary files /dev/null and b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns differ diff --git a/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist new file mode 100644 index 0000000000..7110fc90d3 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist @@ -0,0 +1,8 @@ + + + + + Description + This template provides a starting point for any application using the three20 framework. It provides just an application delegate and a basic TTNavigator. + + diff --git a/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj new file mode 100755 index 0000000000..602fd21add --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -0,0 +1,702 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 6E3796DA11B9BD740011C497 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796B611B9BD630011C497 /* libThree20Core.a */; }; + 6E3796DB11B9BD750011C497 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796BC11B9BD630011C497 /* libThree20Network.a */; }; + 6E3796DC11B9BD750011C497 /* libThree20Style.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796C211B9BD630011C497 /* libThree20Style.a */; }; + 6E3796DD11B9BD750011C497 /* libThree20UI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796D411B9BD630011C497 /* libThree20UI.a */; }; + 6E3796DE11B9BD760011C497 /* libThree20UICommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796C811B9BD630011C497 /* libThree20UICommon.a */; }; + 6E3796DF11B9BD760011C497 /* libThree20UINavigator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3796CE11B9BD630011C497 /* libThree20UINavigator.a */; }; + 6EF962BA118E955A003902E7 /* libThree20.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EF962B7118E9553003902E7 /* libThree20.a */; }; + EB383B6510BBF62B0000B2D2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB383B6410BBF62B0000B2D2 /* QuartzCore.framework */; }; + EB383B6D10BBF6360000B2D2 /* Three20.bundle in Resources */ = {isa = PBXBuildFile; fileRef = EB383B6C10BBF6360000B2D2 /* Three20.bundle */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 6E3796B511B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E3796B711B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796BB11B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E3796BD11B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796C111B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E3796C311B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796C711B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E3796C911B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796CD11B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E3796CF11B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796D311B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6E3796D511B9BD630011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3796E811B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E3796EA11B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E3796EC11B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E3796EE11B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E3796F011B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E3796F211B9BD800011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6EF962B6118E9553003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF9628B118E9552003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20; + }; + 6EF962B8118E9553003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF9628B118E9552003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6EF962BB118E955F003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF9628B118E9552003902E7 /* Three20.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "___PROJECTNAME___.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; sourceTree = ""; }; + 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../three20/src/Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../three20/src/Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Style.xcodeproj; path = ../three20/src/Three20Style/Three20Style.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UICommon.xcodeproj; path = ../three20/src/Three20UICommon/Three20UICommon.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UINavigator.xcodeproj; path = ../three20/src/Three20UINavigator/Three20UINavigator.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UI.xcodeproj; path = ../three20/src/Three20UI/Three20UI.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6EF9628B118E9552003902E7 /* Three20.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20.xcodeproj; path = ../three20/src/Three20/Three20.xcodeproj; sourceTree = SOURCE_ROOT; }; + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + EB383B6410BBF62B0000B2D2 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + EB383B6C10BBF6360000B2D2 /* Three20.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Three20.bundle; path = ../three20/src/Three20.bundle; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + EB383B6510BBF62B0000B2D2 /* QuartzCore.framework in Frameworks */, + 6EF962BA118E955A003902E7 /* libThree20.a in Frameworks */, + 6E3796DA11B9BD740011C497 /* libThree20Core.a in Frameworks */, + 6E3796DB11B9BD750011C497 /* libThree20Network.a in Frameworks */, + 6E3796DC11B9BD750011C497 /* libThree20Style.a in Frameworks */, + 6E3796DD11B9BD750011C497 /* libThree20UI.a in Frameworks */, + 6E3796DE11B9BD760011C497 /* libThree20UICommon.a in Frameworks */, + 6E3796DF11B9BD760011C497 /* libThree20UINavigator.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 6EF96274118E9502003902E7 /* Dependencies */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + EB383B6C10BBF6360000B2D2 /* Three20.bundle */, + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + EB383B6410BBF62B0000B2D2 /* QuartzCore.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 6E3796A211B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796B611B9BD630011C497 /* libThree20Core.a */, + 6E3796B811B9BD630011C497 /* CoreUnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796A511B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796BC11B9BD630011C497 /* libThree20Network.a */, + 6E3796BE11B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796A811B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796C211B9BD630011C497 /* libThree20Style.a */, + 6E3796C411B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796AB11B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796C811B9BD630011C497 /* libThree20UICommon.a */, + 6E3796CA11B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796AE11B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796CE11B9BD630011C497 /* libThree20UINavigator.a */, + 6E3796D011B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796B111B9BD630011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3796D411B9BD630011C497 /* libThree20UI.a */, + 6E3796D611B9BD630011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3796D811B9BD650011C497 /* Three20 */ = { + isa = PBXGroup; + children = ( + 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */, + 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */, + 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */, + 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */, + 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */, + 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */, + 6EF9628B118E9552003902E7 /* Three20.xcodeproj */, + ); + name = Three20; + sourceTree = ""; + }; + 6E3796D911B9BD6C0011C497 /* Three20 Extensions */ = { + isa = PBXGroup; + children = ( + ); + name = "Three20 Extensions"; + sourceTree = ""; + }; + 6EF96274118E9502003902E7 /* Dependencies */ = { + isa = PBXGroup; + children = ( + 6E3796D811B9BD650011C497 /* Three20 */, + 6E3796D911B9BD6C0011C497 /* Three20 Extensions */, + ); + name = Dependencies; + sourceTree = ""; + }; + 6EF9628C118E9552003902E7 /* Products */ = { + isa = PBXGroup; + children = ( + 6EF962B7118E9553003902E7 /* libThree20.a */, + 6EF962B9118E9553003902E7 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6EF962BC118E955F003902E7 /* PBXTargetDependency */, + 6E3796E911B9BD800011C497 /* PBXTargetDependency */, + 6E3796EB11B9BD800011C497 /* PBXTargetDependency */, + 6E3796ED11B9BD800011C497 /* PBXTargetDependency */, + 6E3796EF11B9BD800011C497 /* PBXTargetDependency */, + 6E3796F111B9BD800011C497 /* PBXTargetDependency */, + 6E3796F311B9BD800011C497 /* PBXTargetDependency */, + ); + name = "___PROJECTNAME___"; + productName = "___PROJECTNAME___"; + productReference = 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 6EF9628C118E9552003902E7 /* Products */; + ProjectRef = 6EF9628B118E9552003902E7 /* Three20.xcodeproj */; + }, + { + ProductGroup = 6E3796A211B9BD630011C497 /* Products */; + ProjectRef = 6E3796A111B9BD630011C497 /* Three20Core.xcodeproj */; + }, + { + ProductGroup = 6E3796A511B9BD630011C497 /* Products */; + ProjectRef = 6E3796A411B9BD630011C497 /* Three20Network.xcodeproj */; + }, + { + ProductGroup = 6E3796A811B9BD630011C497 /* Products */; + ProjectRef = 6E3796A711B9BD630011C497 /* Three20Style.xcodeproj */; + }, + { + ProductGroup = 6E3796B111B9BD630011C497 /* Products */; + ProjectRef = 6E3796B011B9BD630011C497 /* Three20UI.xcodeproj */; + }, + { + ProductGroup = 6E3796AB11B9BD630011C497 /* Products */; + ProjectRef = 6E3796AA11B9BD630011C497 /* Three20UICommon.xcodeproj */; + }, + { + ProductGroup = 6E3796AE11B9BD630011C497 /* Products */; + ProjectRef = 6E3796AD11B9BD630011C497 /* Three20UINavigator.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 6E3796B611B9BD630011C497 /* libThree20Core.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Core.a; + remoteRef = 6E3796B511B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796B811B9BD630011C497 /* CoreUnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CoreUnitTests.octest; + remoteRef = 6E3796B711B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796BC11B9BD630011C497 /* libThree20Network.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Network.a; + remoteRef = 6E3796BB11B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796BE11B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796BD11B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796C211B9BD630011C497 /* libThree20Style.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Style.a; + remoteRef = 6E3796C111B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796C411B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796C311B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796C811B9BD630011C497 /* libThree20UICommon.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UICommon.a; + remoteRef = 6E3796C711B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796CA11B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796C911B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796CE11B9BD630011C497 /* libThree20UINavigator.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UINavigator.a; + remoteRef = 6E3796CD11B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796D011B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796CF11B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796D411B9BD630011C497 /* libThree20UI.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UI.a; + remoteRef = 6E3796D311B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3796D611B9BD630011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3796D511B9BD630011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF962B7118E9553003902E7 /* libThree20.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20.a; + remoteRef = 6EF962B6118E9553003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF962B9118E9553003902E7 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6EF962B8118E9553003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EB383B6D10BBF6360000B2D2 /* Three20.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 6E3796E911B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Network; + targetProxy = 6E3796E811B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796EB11B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UINavigator; + targetProxy = 6E3796EA11B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796ED11B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Core; + targetProxy = 6E3796EC11B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796EF11B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Style; + targetProxy = 6E3796EE11B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796F111B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UICommon; + targetProxy = 6E3796F011B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6E3796F311B9BD800011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UI; + targetProxy = 6E3796F211B9BD800011C497 /* PBXContainerItemProxy */; + }; + 6EF962BC118E955F003902E7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20; + targetProxy = 6EF962BB118E955F003902E7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/templates/projects3.2.5/Simple Application/Simple Application/main.m b/templates/projects3.2.5/Simple Application/Simple Application/main.m new file mode 100644 index 0000000000..8023e88258 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Application/main.m @@ -0,0 +1,14 @@ +// +// main.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +int main(int argc, char *argv[]) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate"); + [pool release]; + return retVal; +} diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/Classes/AppDelegate.h b/templates/projects3.2.5/Simple Application/Simple Core Data Application/Classes/AppDelegate.h new file mode 100644 index 0000000000..950ab6d71f --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Core Data Application/Classes/AppDelegate.h @@ -0,0 +1,28 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.h +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface AppDelegate : NSObject { + NSManagedObjectModel* _managedObjectModel; + NSManagedObjectContext* _managedObjectContext; + NSPersistentStoreCoordinator* _persistentStoreCoordinator; + + // App State + BOOL _modelCreated; + BOOL _resetModel; +} + +@property (nonatomic, retain, readonly) NSManagedObjectContext* managedObjectContext; +@property (nonatomic, readonly) NSString* applicationDocumentsDirectory; + + +@end + diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/Classes/AppDelegate.m b/templates/projects3.2.5/Simple Application/Simple Core Data Application/Classes/AppDelegate.m new file mode 100644 index 0000000000..e10428a214 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Core Data Application/Classes/AppDelegate.m @@ -0,0 +1,207 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "AppDelegate.h" + +#define kStoreType NSSQLiteStoreType +#define kStoreFilename @"db.sqlite" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface AppDelegate() +- (NSPersistentStoreCoordinator *)persistentStoreCoordinator; +- (NSString *)applicationDocumentsDirectory; + +@end + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation AppDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)applicationDidFinishLaunching:(UIApplication *)application { + // Forcefully removes the model db and recreates it. + //_resetModel = YES; + + TTNavigator* navigator = [TTNavigator navigator]; + navigator.persistenceMode = TTNavigatorPersistenceModeAll; + + TTURLMap* map = navigator.URLMap; + + [map from:@"*" toViewController:[TTWebController class]]; + + if (![navigator restoreViewControllers]) { + [navigator openURLAction:[TTURLAction actionWithURLPath:@"http://three20.info"]]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)dealloc { + TT_RELEASE_SAFELY(_managedObjectContext); + TT_RELEASE_SAFELY(_managedObjectModel); + TT_RELEASE_SAFELY(_persistentStoreCoordinator); + + [super dealloc]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)navigator:(TTNavigator*)navigator shouldOpenURL:(NSURL*)URL { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)URL { + [[TTNavigator navigator] openURLAction:[TTURLAction actionWithURLPath:URL.absoluteString]]; + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)applicationWillTerminate:(UIApplication *)application { + NSError* error = nil; + if (_managedObjectContext != nil) { + if ([_managedObjectContext hasChanges] && ![_managedObjectContext save:&error]) { + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + abort(); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Core Data stack + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSManagedObjectContext*)managedObjectContext { + if( _managedObjectContext != nil ) { + return _managedObjectContext; + } + + NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; + if (coordinator != nil) { + _managedObjectContext = [[NSManagedObjectContext alloc] init]; + [_managedObjectContext setPersistentStoreCoordinator: coordinator]; + [_managedObjectContext setUndoManager:nil]; + [_managedObjectContext setRetainsRegisteredObjects:YES]; + } + return _managedObjectContext; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSManagedObjectModel*)managedObjectModel { + if( _managedObjectModel != nil ) { + return _managedObjectModel; + } + _managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; + return _managedObjectModel; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString*)storePath { + return [[self applicationDocumentsDirectory] + stringByAppendingPathComponent: kStoreFilename]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSURL*)storeUrl { + return [NSURL fileURLWithPath:[self storePath]]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSDictionary*)migrationOptions { + return nil; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSPersistentStoreCoordinator*)persistentStoreCoordinator { + if( _persistentStoreCoordinator != nil ) { + return _persistentStoreCoordinator; + } + + NSString* storePath = [self storePath]; + NSURL *storeUrl = [self storeUrl]; + + NSError* error; + _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] + initWithManagedObjectModel: [self managedObjectModel]]; + + NSDictionary* options = [self migrationOptions]; + + // Check whether the store already exists or not. + NSFileManager* fileManager = [NSFileManager defaultManager]; + BOOL exists = [fileManager fileExistsAtPath:storePath]; + + TTDINFO(storePath); + if( !exists ) { + _modelCreated = YES; + } else { + if( _resetModel || + [[NSUserDefaults standardUserDefaults] boolForKey:@"erase_all_preference"] ) { + [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"erase_all_preference"]; + [fileManager removeItemAtPath:storePath error:nil]; + _modelCreated = YES; + } + } + + if (![_persistentStoreCoordinator + addPersistentStoreWithType: kStoreType + configuration: nil + URL: storeUrl + options: options + error: &error + ]) { + // We couldn't add the persistent store, so let's wipe it out and try again. + [fileManager removeItemAtPath:storePath error:nil]; + _modelCreated = YES; + + if (![_persistentStoreCoordinator + addPersistentStoreWithType: kStoreType + configuration: nil + URL: storeUrl + options: nil + error: &error + ]) { + // Something is terribly wrong here. + } + } + + return _persistentStoreCoordinator; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Application's documents directory + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString*)applicationDocumentsDirectory { + return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) + lastObject]; +} + + +@end + diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist new file mode 100644 index 0000000000..15665856b0 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___-Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + + diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements new file mode 100644 index 0000000000..788aaa2fe1 Binary files /dev/null and b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/elements differ diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout new file mode 100644 index 0000000000..ce1bc30d8c Binary files /dev/null and b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER___.xcdatamodel/layout differ diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch new file mode 100644 index 0000000000..ff72dc254c --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch @@ -0,0 +1,16 @@ +// +// Prefix header for all source files of the '___PROJECTNAME___' target in the '___PROJECTNAME___' project +// +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iPhone SDK 3.0 and later." +#endif + + +#ifdef __OBJC__ + #import + #import + #import + #import "Three20/Three20.h" +#endif diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000000..d80230f57f Binary files /dev/null and b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns differ diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist new file mode 100644 index 0000000000..7579261498 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist @@ -0,0 +1,8 @@ + + + + + Description + This template provides a starting point for an application that uses three20 with Core Data. It provides an application delegate that creates the Core Data stack and establishes the persistent store. + + diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj new file mode 100755 index 0000000000..321425a219 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Core Data Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -0,0 +1,712 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 28C3AD8A0F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 28C3AD890F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel */; }; + 28D801B40F44B63D00FB423F /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28D801B30F44B63D00FB423F /* CoreData.framework */; }; + 6E37974911B9BDCB0011C497 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37972511B9BDB60011C497 /* libThree20Core.a */; }; + 6E37974A11B9BDCB0011C497 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37972B11B9BDB60011C497 /* libThree20Network.a */; }; + 6E37974B11B9BDCC0011C497 /* libThree20Style.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37973111B9BDB60011C497 /* libThree20Style.a */; }; + 6E37974C11B9BDCC0011C497 /* libThree20UI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37974311B9BDB60011C497 /* libThree20UI.a */; }; + 6E37974D11B9BDCC0011C497 /* libThree20UICommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37973711B9BDB60011C497 /* libThree20UICommon.a */; }; + 6E37974E11B9BDCD0011C497 /* libThree20UINavigator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37973D11B9BDB60011C497 /* libThree20UINavigator.a */; }; + 6EF963EC118E96CC003902E7 /* libThree20.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EF963E9118E96CA003902E7 /* libThree20.a */; }; + EB383C0610BBF8A40000B2D2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EB383C0510BBF8A40000B2D2 /* AppDelegate.m */; }; + EB383C1410BBF8C70000B2D2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB383C1310BBF8C70000B2D2 /* QuartzCore.framework */; }; + EB383D1110BBFC630000B2D2 /* Three20.bundle in Resources */ = {isa = PBXBuildFile; fileRef = EB383D1010BBFC630000B2D2 /* Three20.bundle */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 6E37972411B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E37972611B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37972A11B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E37972C11B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37973011B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E37973211B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37973611B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E37973811B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37973C11B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E37973E11B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37974211B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6E37974411B9BDB60011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37974F11B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E37975111B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E37975311B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E37975511B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E37975711B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E37975911B9BDD70011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6EF963E8118E96CA003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20; + }; + 6EF963EA118E96CA003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6EF963ED118E96CF003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "___PROJECTNAME___.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28C3AD890F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = "___PROJECTNAMEASIDENTIFIER___.xcdatamodel"; sourceTree = ""; }; + 28D801B30F44B63D00FB423F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; sourceTree = ""; }; + 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../three20/src/Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../three20/src/Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Style.xcodeproj; path = ../three20/src/Three20Style/Three20Style.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UICommon.xcodeproj; path = ../three20/src/Three20UICommon/Three20UICommon.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UINavigator.xcodeproj; path = ../three20/src/Three20UINavigator/Three20UINavigator.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UI.xcodeproj; path = ../three20/src/Three20UI/Three20UI.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20.xcodeproj; path = ../three20/src/Three20/Three20.xcodeproj; sourceTree = SOURCE_ROOT; }; + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; sourceTree = ""; }; + EB383C0410BBF8A40000B2D2 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Classes/AppDelegate.h; sourceTree = SOURCE_ROOT; }; + EB383C0510BBF8A40000B2D2 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Classes/AppDelegate.m; sourceTree = SOURCE_ROOT; }; + EB383C1310BBF8C70000B2D2 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + EB383D1010BBFC630000B2D2 /* Three20.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Three20.bundle; path = ../three20/src/Three20.bundle; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, + 28D801B40F44B63D00FB423F /* CoreData.framework in Frameworks */, + EB383C1410BBF8C70000B2D2 /* QuartzCore.framework in Frameworks */, + 6EF963EC118E96CC003902E7 /* libThree20.a in Frameworks */, + 6E37974911B9BDCB0011C497 /* libThree20Core.a in Frameworks */, + 6E37974A11B9BDCB0011C497 /* libThree20Network.a in Frameworks */, + 6E37974B11B9BDCC0011C497 /* libThree20Style.a in Frameworks */, + 6E37974C11B9BDCC0011C497 /* libThree20UI.a in Frameworks */, + 6E37974D11B9BDCC0011C497 /* libThree20UICommon.a in Frameworks */, + 6E37974E11B9BDCD0011C497 /* libThree20UINavigator.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + EB383C0410BBF8A40000B2D2 /* AppDelegate.h */, + EB383C0510BBF8A40000B2D2 /* AppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 6EF963BC118E96B7003902E7 /* Dependencies */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + EB383D1010BBFC630000B2D2 /* Three20.bundle */, + 28C3AD890F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel */, + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, + 28D801B30F44B63D00FB423F /* CoreData.framework */, + EB383C1310BBF8C70000B2D2 /* QuartzCore.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 6E37971111B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37972511B9BDB60011C497 /* libThree20Core.a */, + 6E37972711B9BDB60011C497 /* CoreUnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37971411B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37972B11B9BDB60011C497 /* libThree20Network.a */, + 6E37972D11B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37971711B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37973111B9BDB60011C497 /* libThree20Style.a */, + 6E37973311B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37971A11B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37973711B9BDB60011C497 /* libThree20UICommon.a */, + 6E37973911B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37971D11B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37973D11B9BDB60011C497 /* libThree20UINavigator.a */, + 6E37973F11B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37972011B9BDB60011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37974311B9BDB60011C497 /* libThree20UI.a */, + 6E37974511B9BDB60011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37974711B9BDB80011C497 /* Three20 */ = { + isa = PBXGroup; + children = ( + 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */, + 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */, + 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */, + 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */, + 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */, + 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */, + 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */, + ); + name = Three20; + sourceTree = ""; + }; + 6E37974811B9BDC10011C497 /* Three20 Extensions */ = { + isa = PBXGroup; + children = ( + ); + name = "Three20 Extensions"; + sourceTree = ""; + }; + 6EF963BC118E96B7003902E7 /* Dependencies */ = { + isa = PBXGroup; + children = ( + 6E37974711B9BDB80011C497 /* Three20 */, + 6E37974811B9BDC10011C497 /* Three20 Extensions */, + ); + name = Dependencies; + sourceTree = ""; + }; + 6EF963BE118E96C9003902E7 /* Products */ = { + isa = PBXGroup; + children = ( + 6EF963E9118E96CA003902E7 /* libThree20.a */, + 6EF963EB118E96CA003902E7 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6EF963EE118E96CF003902E7 /* PBXTargetDependency */, + 6E37975011B9BDD70011C497 /* PBXTargetDependency */, + 6E37975211B9BDD70011C497 /* PBXTargetDependency */, + 6E37975411B9BDD70011C497 /* PBXTargetDependency */, + 6E37975611B9BDD70011C497 /* PBXTargetDependency */, + 6E37975811B9BDD70011C497 /* PBXTargetDependency */, + 6E37975A11B9BDD70011C497 /* PBXTargetDependency */, + ); + name = "___PROJECTNAME___"; + productName = "___PROJECTNAME___"; + productReference = 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 6EF963BE118E96C9003902E7 /* Products */; + ProjectRef = 6EF963BD118E96C9003902E7 /* Three20.xcodeproj */; + }, + { + ProductGroup = 6E37971111B9BDB60011C497 /* Products */; + ProjectRef = 6E37971011B9BDB60011C497 /* Three20Core.xcodeproj */; + }, + { + ProductGroup = 6E37971411B9BDB60011C497 /* Products */; + ProjectRef = 6E37971311B9BDB60011C497 /* Three20Network.xcodeproj */; + }, + { + ProductGroup = 6E37971711B9BDB60011C497 /* Products */; + ProjectRef = 6E37971611B9BDB60011C497 /* Three20Style.xcodeproj */; + }, + { + ProductGroup = 6E37972011B9BDB60011C497 /* Products */; + ProjectRef = 6E37971F11B9BDB60011C497 /* Three20UI.xcodeproj */; + }, + { + ProductGroup = 6E37971A11B9BDB60011C497 /* Products */; + ProjectRef = 6E37971911B9BDB60011C497 /* Three20UICommon.xcodeproj */; + }, + { + ProductGroup = 6E37971D11B9BDB60011C497 /* Products */; + ProjectRef = 6E37971C11B9BDB60011C497 /* Three20UINavigator.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 6E37972511B9BDB60011C497 /* libThree20Core.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Core.a; + remoteRef = 6E37972411B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37972711B9BDB60011C497 /* CoreUnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CoreUnitTests.octest; + remoteRef = 6E37972611B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37972B11B9BDB60011C497 /* libThree20Network.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Network.a; + remoteRef = 6E37972A11B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37972D11B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37972C11B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973111B9BDB60011C497 /* libThree20Style.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Style.a; + remoteRef = 6E37973011B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973311B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37973211B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973711B9BDB60011C497 /* libThree20UICommon.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UICommon.a; + remoteRef = 6E37973611B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973911B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37973811B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973D11B9BDB60011C497 /* libThree20UINavigator.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UINavigator.a; + remoteRef = 6E37973C11B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37973F11B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37973E11B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37974311B9BDB60011C497 /* libThree20UI.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UI.a; + remoteRef = 6E37974211B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37974511B9BDB60011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E37974411B9BDB60011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF963E9118E96CA003902E7 /* libThree20.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20.a; + remoteRef = 6EF963E8118E96CA003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF963EB118E96CA003902E7 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6EF963EA118E96CA003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EB383D1110BBFC630000B2D2 /* Three20.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 28C3AD8A0F43EF2300507BA6 /* ___PROJECTNAMEASIDENTIFIER___.xcdatamodel in Sources */, + EB383C0610BBF8A40000B2D2 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 6E37975011B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Network; + targetProxy = 6E37974F11B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975211B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UINavigator; + targetProxy = 6E37975111B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975411B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UICommon; + targetProxy = 6E37975311B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975611B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Core; + targetProxy = 6E37975511B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975811B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Style; + targetProxy = 6E37975711B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6E37975A11B9BDD70011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UI; + targetProxy = 6E37975911B9BDD70011C497 /* PBXContainerItemProxy */; + }; + 6EF963EE118E96CF003902E7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20; + targetProxy = 6EF963ED118E96CF003902E7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/templates/projects3.2.5/Simple Application/Simple Core Data Application/main.m b/templates/projects3.2.5/Simple Application/Simple Core Data Application/main.m new file mode 100644 index 0000000000..9387467159 --- /dev/null +++ b/templates/projects3.2.5/Simple Application/Simple Core Data Application/main.m @@ -0,0 +1,14 @@ +// +// main.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +int main(int argc, char *argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate"); + [pool release]; + return retVal; +} diff --git a/templates/projects3.2.5/Simple Application/TemplateChooser.plist b/templates/projects3.2.5/Simple Application/TemplateChooser.plist new file mode 100644 index 0000000000..09bf9f451d --- /dev/null +++ b/templates/projects3.2.5/Simple Application/TemplateChooser.plist @@ -0,0 +1,12 @@ +{ + Checkboxes = ( + { + Key = CoreData; + Title = "Use Core Data for storage"; + }, + ); + TemplateSelection = { + "" = "Simple Application"; + CoreData = "Simple Core Data Application"; + }; +} diff --git a/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h new file mode 100644 index 0000000000..8694f8e28b --- /dev/null +++ b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.h @@ -0,0 +1,17 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.h +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface AppDelegate : NSObject { +} + +@end + diff --git a/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m new file mode 100644 index 0000000000..7e3c63c5f5 --- /dev/null +++ b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/Classes/AppDelegate.m @@ -0,0 +1,46 @@ +// +// ___PROJECTNAMEASIDENTIFIER___AppDelegate.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "AppDelegate.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +@implementation AppDelegate + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)applicationDidFinishLaunching:(UIApplication *)application { + TTNavigator* navigator = [TTNavigator navigator]; + navigator.persistenceMode = TTNavigatorPersistenceModeAll; + + TTURLMap* map = navigator.URLMap; + + [map from:@"*" toViewController:[TTWebController class]]; + + if (![navigator restoreViewControllers]) { + [navigator openURLAction:[TTURLAction actionWithURLPath:@"http://three20.info"]]; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)navigator:(TTNavigator*)navigator shouldOpenURL:(NSURL*)URL { + return YES; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)URL { + [[TTNavigator navigator] openURLAction:[TTURLAction actionWithURLPath:URL.absoluteString]]; + return YES; +} + + +@end diff --git a/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist new file mode 100644 index 0000000000..3d1e7e15e9 --- /dev/null +++ b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER___-Info.plist @@ -0,0 +1,35 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch new file mode 100644 index 0000000000..9556e4be43 --- /dev/null +++ b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAMEASIDENTIFIER____Prefix.pch @@ -0,0 +1,15 @@ +// +// Prefix header for all source files of the '___PROJECTNAME___' target in the '___PROJECTNAME___' project +// +#import + +#ifndef __IPHONE_3_2 +#warning "This project uses features only available in iPhone SDK 3.2 and later." +#endif + + +#ifdef __OBJC__ + #import + #import + #import "Three20/Three20.h" +#endif diff --git a/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000000..d80230f57f Binary files /dev/null and b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns differ diff --git a/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist new file mode 100644 index 0000000000..60b4ce1ffb --- /dev/null +++ b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist @@ -0,0 +1,8 @@ + + + + + Description + This template provides a starting point for an iPad application using the three20 framework. It provides an application delegate and a basic TTNavigator. + + diff --git a/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj new file mode 100755 index 0000000000..4efaebb7ea --- /dev/null +++ b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -0,0 +1,706 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + 6E3175FB1126577100F4DDEC /* Three20.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 6E3175FA1126577100F4DDEC /* Three20.bundle */; }; + 6E3176191126579100F4DDEC /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3176181126579100F4DDEC /* QuartzCore.framework */; }; + 6E3797BA11B9BE030011C497 /* libThree20Core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37979911B9BE010011C497 /* libThree20Core.a */; }; + 6E3797BB11B9BE030011C497 /* libThree20Network.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E37979F11B9BE010011C497 /* libThree20Network.a */; }; + 6E3797BC11B9BE040011C497 /* libThree20Style.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3797A511B9BE010011C497 /* libThree20Style.a */; }; + 6E3797BD11B9BE040011C497 /* libThree20UI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3797B711B9BE010011C497 /* libThree20UI.a */; }; + 6E3797BE11B9BE050011C497 /* libThree20UICommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3797AB11B9BE010011C497 /* libThree20UICommon.a */; }; + 6E3797BF11B9BE050011C497 /* libThree20UINavigator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E3797B111B9BE010011C497 /* libThree20UINavigator.a */; }; + 6EF96366118E9604003902E7 /* libThree20.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EF96363118E95FF003902E7 /* libThree20.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 6E37979811B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E37979A11B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E37979E11B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E3797A011B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797A411B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E3797A611B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797AA11B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E3797AC11B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797B011B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E3797B211B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797B611B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6E3797B811B9BE010011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6E3797CB11B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UINavigator; + }; + 6E3797CD11B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UICommon; + }; + 6E3797CF11B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Style; + }; + 6E3797D111B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Network; + }; + 6E3797D311B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20Core; + }; + 6E3797D511B9BE1C0011C497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20UI; + }; + 6EF96362118E95FF003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF96337118E95FE003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BEF31F3A0F352DF5000DE5D2; + remoteInfo = Three20; + }; + 6EF96364118E95FF003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF96337118E95FE003902E7 /* Three20.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB9E6C6210B6A8F800DE563C; + remoteInfo = UnitTests; + }; + 6EF96367118E9608003902E7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6EF96337118E95FE003902E7 /* Three20.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BEF31F390F352DF5000DE5D2; + remoteInfo = Three20; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "___PROJECTNAME___.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6E3175FA1126577100F4DDEC /* Three20.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Three20.bundle; path = ../three20/src/Three20.bundle; sourceTree = SOURCE_ROOT; }; + 6E3176181126579100F4DDEC /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Core.xcodeproj; path = ../three20/src/Three20Core/Three20Core.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Network.xcodeproj; path = ../three20/src/Three20Network/Three20Network.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20Style.xcodeproj; path = ../three20/src/Three20Style/Three20Style.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UICommon.xcodeproj; path = ../three20/src/Three20UICommon/Three20UICommon.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UINavigator.xcodeproj; path = ../three20/src/Three20UINavigator/Three20UINavigator.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20UI.xcodeproj; path = ../three20/src/Three20UI/Three20UI.xcodeproj; sourceTree = SOURCE_ROOT; }; + 6EF96337118E95FE003902E7 /* Three20.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Three20.xcodeproj; path = ../three20/src/Three20/Three20.xcodeproj; sourceTree = SOURCE_ROOT; }; + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + 6E3176191126579100F4DDEC /* QuartzCore.framework in Frameworks */, + 6EF96366118E9604003902E7 /* libThree20.a in Frameworks */, + 6E3797BA11B9BE030011C497 /* libThree20Core.a in Frameworks */, + 6E3797BB11B9BE030011C497 /* libThree20Network.a in Frameworks */, + 6E3797BC11B9BE040011C497 /* libThree20Style.a in Frameworks */, + 6E3797BD11B9BE040011C497 /* libThree20UI.a in Frameworks */, + 6E3797BE11B9BE050011C497 /* libThree20UICommon.a in Frameworks */, + 6E3797BF11B9BE050011C497 /* libThree20UINavigator.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources-iPad */, + 6EF9630E118E95E6003902E7 /* Dependencies */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + 6E3176181126579100F4DDEC /* QuartzCore.framework */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 28A0AAE50D9B0CCF005BE974 /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources-iPad */ = { + isa = PBXGroup; + children = ( + 6E3175FA1126577100F4DDEC /* Three20.bundle */, + 8D1107310486CEB800E47090 /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */, + ); + name = "Resources-iPad"; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 6E37978511B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37979911B9BE010011C497 /* libThree20Core.a */, + 6E37979B11B9BE010011C497 /* CoreUnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37978811B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E37979F11B9BE010011C497 /* libThree20Network.a */, + 6E3797A111B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37978B11B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3797A511B9BE010011C497 /* libThree20Style.a */, + 6E3797A711B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37978E11B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3797AB11B9BE010011C497 /* libThree20UICommon.a */, + 6E3797AD11B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37979111B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3797B111B9BE010011C497 /* libThree20UINavigator.a */, + 6E3797B311B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E37979411B9BE010011C497 /* Products */ = { + isa = PBXGroup; + children = ( + 6E3797B711B9BE010011C497 /* libThree20UI.a */, + 6E3797B911B9BE010011C497 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 6E3797C111B9BE070011C497 /* Three20 */ = { + isa = PBXGroup; + children = ( + 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */, + 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */, + 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */, + 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */, + 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */, + 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */, + 6EF96337118E95FE003902E7 /* Three20.xcodeproj */, + ); + name = Three20; + sourceTree = ""; + }; + 6E3797C211B9BE0D0011C497 /* Three20 Extensions */ = { + isa = PBXGroup; + children = ( + ); + name = "Three20 Extensions"; + sourceTree = ""; + }; + 6EF9630E118E95E6003902E7 /* Dependencies */ = { + isa = PBXGroup; + children = ( + 6E3797C111B9BE070011C497 /* Three20 */, + 6E3797C211B9BE0D0011C497 /* Three20 Extensions */, + ); + name = Dependencies; + sourceTree = ""; + }; + 6EF96338118E95FE003902E7 /* Products */ = { + isa = PBXGroup; + children = ( + 6EF96363118E95FF003902E7 /* libThree20.a */, + 6EF96365118E95FF003902E7 /* UnitTests.octest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6EF96368118E9608003902E7 /* PBXTargetDependency */, + 6E3797CC11B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797CE11B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797D011B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797D211B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797D411B9BE1C0011C497 /* PBXTargetDependency */, + 6E3797D611B9BE1C0011C497 /* PBXTargetDependency */, + ); + name = "___PROJECTNAME___"; + productName = "___PROJECTNAME___"; + productReference = 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 6EF96338118E95FE003902E7 /* Products */; + ProjectRef = 6EF96337118E95FE003902E7 /* Three20.xcodeproj */; + }, + { + ProductGroup = 6E37978511B9BE010011C497 /* Products */; + ProjectRef = 6E37978411B9BE010011C497 /* Three20Core.xcodeproj */; + }, + { + ProductGroup = 6E37978811B9BE010011C497 /* Products */; + ProjectRef = 6E37978711B9BE010011C497 /* Three20Network.xcodeproj */; + }, + { + ProductGroup = 6E37978B11B9BE010011C497 /* Products */; + ProjectRef = 6E37978A11B9BE010011C497 /* Three20Style.xcodeproj */; + }, + { + ProductGroup = 6E37979411B9BE010011C497 /* Products */; + ProjectRef = 6E37979311B9BE010011C497 /* Three20UI.xcodeproj */; + }, + { + ProductGroup = 6E37978E11B9BE010011C497 /* Products */; + ProjectRef = 6E37978D11B9BE010011C497 /* Three20UICommon.xcodeproj */; + }, + { + ProductGroup = 6E37979111B9BE010011C497 /* Products */; + ProjectRef = 6E37979011B9BE010011C497 /* Three20UINavigator.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 6E37979911B9BE010011C497 /* libThree20Core.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Core.a; + remoteRef = 6E37979811B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37979B11B9BE010011C497 /* CoreUnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CoreUnitTests.octest; + remoteRef = 6E37979A11B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E37979F11B9BE010011C497 /* libThree20Network.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Network.a; + remoteRef = 6E37979E11B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797A111B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797A011B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797A511B9BE010011C497 /* libThree20Style.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20Style.a; + remoteRef = 6E3797A411B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797A711B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797A611B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797AB11B9BE010011C497 /* libThree20UICommon.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UICommon.a; + remoteRef = 6E3797AA11B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797AD11B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797AC11B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797B111B9BE010011C497 /* libThree20UINavigator.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UINavigator.a; + remoteRef = 6E3797B011B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797B311B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797B211B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797B711B9BE010011C497 /* libThree20UI.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20UI.a; + remoteRef = 6E3797B611B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6E3797B911B9BE010011C497 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6E3797B811B9BE010011C497 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF96363118E95FF003902E7 /* libThree20.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libThree20.a; + remoteRef = 6EF96362118E95FF003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6EF96365118E95FF003902E7 /* UnitTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.octest; + remoteRef = 6EF96364118E95FF003902E7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6E3175FB1126577100F4DDEC /* Three20.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 6E3797CC11B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UINavigator; + targetProxy = 6E3797CB11B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797CE11B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UICommon; + targetProxy = 6E3797CD11B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797D011B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Style; + targetProxy = 6E3797CF11B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797D211B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Network; + targetProxy = 6E3797D111B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797D411B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20Core; + targetProxy = 6E3797D311B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6E3797D611B9BE1C0011C497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20UI; + targetProxy = 6E3797D511B9BE1C0011C497 /* PBXContainerItemProxy */; + }; + 6EF96368118E9608003902E7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Three20; + targetProxy = 6EF96367118E9608003902E7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "___PROJECTNAMEASIDENTIFIER____Prefix.pch"; + HEADER_SEARCH_PATHS = ../three20/Build/Products/three20; + INFOPLIST_FILE = "___PROJECTNAMEASIDENTIFIER___-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "___PROJECTNAME___"; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "___PROJECTNAME___" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/main.m b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/main.m new file mode 100644 index 0000000000..8023e88258 --- /dev/null +++ b/templates/projects3.2.5/Simple iPad Application/Simple iPad Application/main.m @@ -0,0 +1,14 @@ +// +// main.m +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +int main(int argc, char *argv[]) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate"); + [pool release]; + return retVal; +} diff --git a/templates/source/Three20 Class/Three20 class/TTTableViewController subclass.pbfiletemplate/class.m b/templates/source/Three20 Class/Three20 class/TTTableViewController subclass.pbfiletemplate/class.m index b195d89fe1..45db9c20c7 100644 --- a/templates/source/Three20 Class/Three20 class/TTTableViewController subclass.pbfiletemplate/class.m +++ b/templates/source/Three20 Class/Three20 class/TTTableViewController subclass.pbfiletemplate/class.m @@ -15,13 +15,13 @@ @implementation «FILEBASENAMEASIDENTIFIER» /////////////////////////////////////////////////////////////////////////////////////////////////// -- (id) init { - if (self = [super init]) { +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { //self.variableHeightRows = YES; self.dataSource = [TTListDataSource dataSourceWithObjects: - [[TTTableTitleItem item] applyTitle:@"Table cell item"], + [TTTableTextItem itemWithText:@"Table cell item"], nil]; }