Skip to content
Browse files

hack in abstract preferences system by jamming the whole thing into p…

…references.rb
  • Loading branch information...
1 parent c808e0a commit a08fe37507dc9da033f6870bc1df2ab943edc3eb Greg Borenstein committed
Showing with 1,228 additions and 1,588 deletions.
  1. +2 −2 English.lproj/GEDocument.xib
  2. +1 −0 GEDocument.rb
  3. +4 −0 GEGistListDelegate.rb
  4. +292 −0 Preferences.rb
  5. +189 −0 Preferences.xib
  6. BIN build/Debug/gisteditor.app/Contents/MacOS/gisteditor
  7. BIN build/Debug/gisteditor.app/Contents/Resources/English.lproj/GEDocument.nib
  8. BIN build/Debug/gisteditor.app/Contents/Resources/English.lproj/MainMenu.nib
  9. +1 −0 build/Debug/gisteditor.app/Contents/Resources/GEDocument.rb
  10. +4 −0 build/Debug/gisteditor.app/Contents/Resources/GEGistListDelegate.rb
  11. BIN build/Debug/gisteditor.app/Contents/Resources/Preferences.nib
  12. +292 −0 build/Debug/gisteditor.app/Contents/Resources/Preferences.rb
  13. BIN build/gisteditor.build/Debug/gisteditor.build/Objects-normal/i386/main.o
  14. BIN build/gisteditor.build/gisteditor.pbxindex/categories.pbxbtree
  15. BIN build/gisteditor.build/gisteditor.pbxindex/cdecls.pbxbtree
  16. BIN build/gisteditor.build/gisteditor.pbxindex/decls.pbxbtree
  17. BIN build/gisteditor.build/gisteditor.pbxindex/files.pbxbtree
  18. BIN build/gisteditor.build/gisteditor.pbxindex/imports.pbxbtree
  19. BIN build/gisteditor.build/gisteditor.pbxindex/pbxindex.header
  20. BIN build/gisteditor.build/gisteditor.pbxindex/protocols.pbxbtree
  21. BIN build/gisteditor.build/gisteditor.pbxindex/refs.pbxbtree
  22. BIN build/gisteditor.build/gisteditor.pbxindex/strings.pbxstrings/control
  23. BIN build/gisteditor.build/gisteditor.pbxindex/strings.pbxstrings/strings
  24. BIN build/gisteditor.build/gisteditor.pbxindex/subclasses.pbxbtree
  25. BIN build/gisteditor.build/gisteditor.pbxindex/symbols0.pbxsymbols
  26. +25 −74 gisteditor.xcodeproj/greg.mode1v3
  27. +410 −1,512 gisteditor.xcodeproj/greg.pbxuser
  28. +8 −0 gisteditor.xcodeproj/project.pbxproj
View
4 English.lproj/GEDocument.xib
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="100026"/>
+ <integer value="6"/>
<integer value="100036"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
@@ -83,7 +83,7 @@
<string>WebURLsWithTitlesPboardType</string>
</object>
</object>
- <string key="NSFrameSize">{598, 77}</string>
+ <string key="NSFrameSize">{598, 14}</string>
<reference key="NSSuperview" ref="561630725"/>
<object class="NSTextContainer" key="NSTextContainer" id="1007486519">
<object class="NSLayoutManager" key="NSLayoutManager">
View
1 GEDocument.rb
@@ -15,6 +15,7 @@ class GEDocument < NSDocument
attr_accessor :associated_library
def applicationDidFinishLaunching(notification)
+
# pass
end
View
4 GEGistListDelegate.rb
@@ -9,6 +9,10 @@
class GEGistListDelegate
attr_accessor :associatedDocument
+ def awakeFromNib()
+ NSLog(preferences.user.login)
+ end
+
def numberOfRowsInTableView(aTableView)
@library = GEGistLibrary.new
@library.gists.length
View
292 Preferences.rb
@@ -0,0 +1,292 @@
+#
+# Preferences.rb
+# gisteditor
+#
+# Created by Greg Borenstein on 6/20/09.
+# Copyright (c) 2009 __MyCompanyName__. All rights reserved.
+#
+
+# require '/Users/greg/code/rubycocoa-prefs/lib/abstract_preferences.rb'
+
+require 'singleton'
+
+class NSUserDefaults
+ def [](str)
+ self.objectForKey(str)
+ end
+
+ def []=(str, obj)
+ self.setObject(obj, forKey:str)
+ end
+end
+
+class Preferences
+ include Singleton
+
+ # Save any unsaved changes to disk.
+ def save
+ Preferences.user_defaults.synchronize
+ end
+
+ class << self
+ # A shortcut method for access to <tt>NSUserDefaults.standardUserDefaults</tt>.
+ def user_defaults
+ NSUserDefaults.standardUserDefaults
+ end
+
+ # A hash of all default values for the user defaults
+ def default_values
+ @default_values ||= {}
+ end
+
+ # Registers the default values with NSUserDefaults.standardUserDefaults
+ # Call this after all your Preferences code has been loaded, for instance
+ # in <tt>awakeFromNib</tt> of your ApplicationController.
+ def register_default_values!
+ user_defaults.registerDefaults(default_values)
+ end
+ end
+
+ class Namespace
+ include Singleton
+
+ class << self
+ # Defines a reader method for the Namespace subclass on the Preferences instance.
+ #
+ # Defines a class <tt>Preferences::Keyword</tt> and <tt>preferences.keyword</tt>:
+ #
+ # class Preferences
+ # class Keyword < Namespace
+ # defaults_accessor :an_option, true
+ # end
+ # end
+ def inherited(klass)
+ super
+ method = klass.name.split('::').last.scan(/[A-Z][a-z]*/).map { |x| x.downcase }.join('_')
+ Preferences.class_eval "def #{method}; #{klass.name}.instance end", __FILE__, __LINE__
+ end
+
+ # The key in the preferences that represents the section class.
+ #
+ # Preferences::General.section_defaults_key # => "Preferences.General"
+ def section_defaults_key
+ @section_defaults_key ||= name.gsub('::', '.')
+ end
+
+ # Defines a reader and writer method for a user defaults key for this section.
+ #
+ # If the preference is a boolean value, inflected from the default value,
+ # a query method is also defined.
+ #
+ # # Defines #confirm_quit, #confirm_quit=, and #confirm_quit? It's default value is <tt>true</tt>.
+ # defaults_accessor :confirm_quit, true
+ def defaults_accessor(name, default_value)
+ key_path = "#{section_defaults_key}.#{name}"
+ Preferences.default_values[key_path] = default_value
+
+ class_eval do
+ define_method(name) do
+ Preferences.user_defaults[key_path]
+ end
+
+ define_method("#{name}=") do |value|
+ Preferences.user_defaults[key_path] = value
+ end
+
+ if default_value == true || default_value == false
+ alias_method "#{name}?", name
+ end
+ end
+
+ key_path
+ end
+
+ # Besides defining a reader and writer method via defaults_accessor,
+ # it also defines a reader method which returns an array of strings
+ # wrapped in KVO compatible string wrappers.
+ #
+ # The name of the wrapper class is defined by <tt>wrapper_class_name</tt>
+ # and can be used as the `Class Name' of a NSArrayController.
+ # The wrapper exposes `string' as a KVC accessor to which a NSTableColumn can be bound.
+ #
+ # # Defines #highlight_words, #highlight_words=, and #highlight_words_wrapped
+ # string_array_defaults_accessor :highlight_words, [], 'HighlightWordWrapper'
+ def string_array_defaults_accessor(name, default_value, wrapper_class_name)
+ wrapper = eval("class ::#{wrapper_class_name} < StringArrayWrapper; self end")
+ wrapper.key_path = defaults_accessor(name, default_value)
+
+ class_eval do
+ define_method("#{name}_wrapped") do
+ ary = []
+ send(name).each_with_index { |string, index| ary << wrapper.alloc.initWithString_index(string, index) }
+ ary
+ end
+ end
+ end
+ end
+
+ # Register an observer for a key.
+ #
+ # Include the <tt>Preferences::KVOCallbackHelper</tt> module in your class
+ # to get rubyish callback handling, instead of handling it yourself by defining
+ # the observeValueForKeyPath_ofObject_change_context method.
+ #
+ # class PreferencesController < OSX::NSWindowController
+ # include Preferences::KVOCallbackHelper
+ #
+ # def init
+ # if super_init
+ # preferences.keyword.observe(:highlight_words, self)
+ # self
+ # end
+ # end
+ #
+ # def highlight_words_changed(new_value)
+ # # Do stuff because a new value has been set.
+ # end
+ # end
+ def observe(name, observer)
+ key_path = "values.#{self.class.section_defaults_key}.#{name}"
+ NSUserDefaultsController.sharedUserDefaultsController.addObserver(observer,
+ forKeyPath:key_path, options:NSKeyValueObservingOptionNew, context:nil
+ )
+ end
+ end
+
+ class StringArrayWrapper < NSObject
+ class << self
+ attr_accessor :key_path
+
+ def array
+ Preferences.user_defaults[key_path]
+ end
+
+ def array=(array)
+ Preferences.user_defaults[key_path] = array
+ end
+
+ def destroy(klass, new_wrappers)
+ # Set the new correct indices on the remaining wrappers
+ new_wrappers.each_with_index do |wrapper, new_index|
+ wrapper.index = new_index
+ end
+
+ # Assign the new result array of strings
+ klass.array = new_wrappers.map { |wrapper| wrapper.string }
+ end
+ end
+
+ attr_accessor :string
+ attr_accessor :index
+
+ def initWithString(string, index:index)
+ if init
+ @string, @index = string, index
+ self
+ end
+ end
+
+ def array
+ self.class.array
+ end
+
+ def array=(array)
+ self.class.array = array
+ end
+
+ def string=(string)
+ @string = string
+ set_string!
+ end
+
+ def set_string!
+ if @index
+ ary = array
+ ary[@index] = string
+ self.array = ary
+ else
+ ary = array
+ ary << @string
+ self.array = ary
+ @index = ary.length - 1
+ end
+ end
+
+ def inspect
+ "#<#{self.class.name}:#{object_id} string=\"#{@string}\" key_path=\"#{self.class.key_path}\" index=\"#{@index}\">"
+ end
+ end
+
+ # Extend your class with this module to get access to a few KVC accessor helper methods.
+ module AccessorHelpers
+ # Defines a kvc_accessor which reads and writes
+ # to the specified preferences path (<tt>path_to_eval_to_object</tt>).
+ #
+ # This is useful for binding, for instance, UI elements
+ # to an array in the NSUserDefaults which is normally immutable.
+ #
+ # class PreferencesController < OSX::NSWindowController
+ # defaults_kvc_accessor :an_array_of_dictionaries, 'preferences.keyword.url_mappings'
+ # end
+ #
+ # Binding a NSArrayController to File's Owner with key path: <tt>an_array_of_dictionaries</tt>,
+ # will perform the following read/write actions on the NSUserDefaults:
+ #
+ # preferences_controller.valueForKey('an_array_of_dictionaries') # => [{'key' => 'value 1'}, {'key' => 'value 2'}]
+ # preferences_controller.setValueForKey([{'key' => 'value 1'}], 'an_array_of_dictionaries')
+ # preferences_controller.valueForKey('an_array_of_dictionaries') # => [{'key' => 'value 1'}]
+ def defaults_kvc_accessor(name, path_to_eval_to_object)
+ kvc_accessor(name)
+
+ class_eval %{
+ def #{name}
+ @#{name} ||= #{path_to_eval_to_object}
+ end
+
+ def #{name}=(new_defaults)
+ #{path_to_eval_to_object} = @#{name} = new_defaults
+ end
+ }, __FILE__, __LINE__
+ end
+
+ # Defines read and write KVC accessors like defaults_kvc_accessor does,
+ # but is used specifically for defaults defined with Namespace#string_array_defaults_accessor.
+ #
+ # class PreferencesController < OSX::NSWindowController
+ # defualts_string_array_kvc_accessor :an_array_of_strings, 'preferences.keyword.highlight_words'
+ # end
+ #
+ # See Namespace#string_array_defaults_accessor for more info.
+ def defualts_string_array_kvc_accessor(name, path_to_eval_to_object)
+ defaults_kvc_accessor(name, "#{path_to_eval_to_object}_wrapped")
+
+ class_eval %{
+ def #{name}=(new_wrappers)
+ if new_wrappers.length < #{name}.length
+ Preferences::StringArrayWrapper.destroy(#{name}.first.class, new_wrappers)
+ end
+ @#{name} = new_wrappers
+ end
+ }, __FILE__, __LINE__
+ end
+ end
+
+end
+
+module Kernel
+ # A shortcut method for easy access anywhere to the shared user defaults.
+ def preferences
+ Preferences.instance
+ end
+end
+
+class Preferences
+ class User < Namespace
+ defaults_accessor :login, "YOUR LOGIN HERE"
+ defaults_accessor :token, "YOUR TOKEN HERE"
+ end
+
+ # Register the default values with NSUserDefaults.standardUserDefaults.
+ register_default_values!
+end
+
View
189 Preferences.xib
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.01">
+ <data>
+ <string key="IBDocument.SystemVersion">9A369</string>
+ <string key="IBDocument.InterfaceBuilderVersion">592</string>
+ <string key="IBDocument.AppKitVersion">894</string>
+ <string key="IBDocument.HIToolboxVersion">298.00</string>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1" id="9"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilderKit</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSCustomObject" id="1001">
+ <string key="NSClassName">NSObject</string>
+ </object>
+ <object class="NSCustomObject" id="1003">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="1004">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSWindowTemplate" id="1005">
+ <int key="NSWindowStyleMask">15</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{196, 240}, {480, 270}}</string>
+ <int key="NSWTFlags">536870912</int>
+ <string key="NSWindowTitle">Window</string>
+ <string key="NSWindowClass">NSWindow</string>
+ <nil key="NSViewClass"/>
+ <object class="NSView" key="NSWindowView" id="1006">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{480, 270}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <object class="NSArray" key="object" id="1002">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="1001"/>
+ <reference key="parent" ref="1002"/>
+ <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="1003"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="1004"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="1005"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="1006"/>
+ </object>
+ <reference key="parent" ref="1002"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="1006"/>
+ <reference key="parent" ref="1005"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.IBPluginDependency</string>
+ <string>-2.IBPluginDependency</string>
+ <string>-3.IBPluginDependency</string>
+ <string>1.IBPluginDependency</string>
+ <string>1.IBWindowTemplateEditedContentRect</string>
+ <string>1.NSWindowTemplate.visibleAtLaunch</string>
+ <string>1.WindowOrigin</string>
+ <string>1.editorWindowContentRectSynchronizationRect</string>
+ <string>2.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilderKit</string>
+ <string>com.apple.InterfaceBuilderKit</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{202, 428}, {480, 270}}</string>
+ <reference ref="9"/>
+ <string>{196, 240}</string>
+ <string>{{202, 428}, {480, 270}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">2</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableDictionary" key="localDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <object class="NSMutableData" key="IBDocument.RunnableNib">
+ <bytes key="NS.bytes">YnBsaXN0MDDUAQIDBAUGCQpYJHZlcnNpb25UJHRvcFkkYXJjaGl2ZXJYJG9iamVjdHMSAAGGoNEHCF1J
+Qi5vYmplY3RkYXRhgAFfEA9OU0tleWVkQXJjaGl2ZXKvECwLDDE1Njs8QVVWV1gLYwtkaGlscHN3fYCB
+g4mQl5iZmpueoaivsLFSsrW4u1UkbnVsbN8QEg0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss
+LS4vMFZOU1Jvb3RWJGNsYXNzXU5TT2JqZWN0c0tleXNfEA9OU0NsYXNzZXNWYWx1ZXNfEBlOU0FjY2Vz
+c2liaWxpdHlPaWRzVmFsdWVzXU5TQ29ubmVjdGlvbnNbTlNOYW1lc0tleXNbTlNGcmFtZXdvcmtdTlND
+bGFzc2VzS2V5c1pOU09pZHNLZXlzXU5TTmFtZXNWYWx1ZXNfEBlOU0FjY2Vzc2liaWxpdHlDb25uZWN0
+b3JzXU5TRm9udE1hbmFnZXJfEBBOU1Zpc2libGVXaW5kb3dzXxAPTlNPYmplY3RzVmFsdWVzXxAXTlNB
+Y2Nlc3NpYmlsaXR5T2lkc0tleXNZTlNOZXh0T2lkXE5TT2lkc1ZhbHVlc4ACgCuAFYAhgCqAE4AagAWA
+IIAigBuAKIAAgAaAGYApEASAI9IOMjM0W05TQ2xhc3NOYW1lgASAA1hOU09iamVjdNI3ODk6WCRjbGFz
+c2VzWiRjbGFzc25hbWWiOjVeTlNDdXN0b21PYmplY3RfEBBJQkNvY29hRnJhbWV3b3Jr0g49Pj9aTlMu
+b2JqZWN0c4ASoUCAB9pCDkNERUZHSElKS0xNTk9QUVJTK1xOU1dpbmRvd1ZpZXdcTlNTY3JlZW5SZWN0
+XU5TV2luZG93VGl0bGVZTlNXVEZsYWdzXU5TV2luZG93Q2xhc3NcTlNXaW5kb3dSZWN0XxAPTlNXaW5k
+b3dCYWNraW5nXxARTlNXaW5kb3dTdHlsZU1hc2tbTlNWaWV3Q2xhc3OAC4ARgBCACRIgAAAAgAqACBAC
+EA+AAF8QGHt7MTk2LCAyNDB9LCB7NDgwLCAyNzB9fVZXaW5kb3dYTlNXaW5kb3fWWQ5aW1dcXV5fYF1i
+XxAPTlNOZXh0UmVzcG9uZGVyWE5TdkZsYWdzW05TRnJhbWVTaXplW05TU3VwZXJ2aWV3gAyADxEBAIAN
+gAyADlp7NDgwLCAyNzB90jc4ZWajZmc1Vk5TVmlld1tOU1Jlc3BvbmRlcl8QFnt7MCwgMH0sIHsxNjgw
+LCAxMDI4fX3SNzhqa6JrNV8QEE5TV2luZG93VGVtcGxhdGXSNzhtbqNubzVcTlNNdXRhYmxlU2V0VU5T
+U2V00g49cXKAFKDSNzh0daN1djVeTlNNdXRhYmxlQXJyYXlXTlNBcnJhedIOPXh5gBijektAgBaAC4AH
+0g4yM3+ABIAXXU5TQXBwbGljYXRpb27SNziCdqJ2NdIOPXiFgBijH0AfgAKAB4AC0g49eIuAGKQfQHpL
+gAKAB4AWgAvSDj14koAYpJOUlZaAHIAdgB6AH1xGaWxlJ3MgT3duZXJfEA9XaW5kb3cgKFdpbmRvdylb
+QXBwbGljYXRpb25cQ29udGVudCBWaWV30g49eJ2AGKDSDj14oIAYoNIOPXijgBikH0B6S4ACgAeAFoAL
+0g49eKqAGKSrrK2ugCSAJYAmgCcQAxABE//////////90g49cbSAFKDSDj14t4AYoNIOPXi6gBig0jc4
+vL2ivTVeTlNJQk9iamVjdERhdGEACAARABoAHwApADIANwA6AEgASgBcAIsAkQC4AL8AxgDUAOYBAgEQ
+ARwBKAE2AUEBTwFrAXkBjAGeAbgBwgHPAdEB0wHVAdcB2QHbAd0B3wHhAeMB5QHnAekB6wHtAe8B8QHz
+AfgCBAIGAggCEQIWAh8CKgItAjwCTwJUAl8CYQJjAmUCegKHApQCogKsAroCxwLZAu0C+QL7Av0C/wMB
+AwYDCAMKAwwDDgMQAysDMgM7A0gDWgNjA28DewN9A38DggOEA4YDiAOTA5gDnAOjA68DyAPNA9AD4wPo
+A+wD+QP/BAQEBgQHBAwEEAQfBCcELAQuBDIENAQ2BDgEPQQ/BEEETwRUBFcEXAReBGIEZARmBGgEbQRv
+BHQEdgR4BHoEfASBBIMEiASKBIwEjgSQBJ0ErwS7BMgEzQTPBNAE1QTXBNgE3QTfBOQE5gToBOoE7ATx
+BPME+AT6BPwE/gUABQIFBAUNBRIFFAUVBRoFHAUdBSIFJAUlBSoFLQAAAAAAAAIBAAAAAAAAAL4AAAAA
+AAAAAAAAAAAAAAU8A</bytes>
+ </object>
+ </data>
+</archive>
View
BIN build/Debug/gisteditor.app/Contents/MacOS/gisteditor
Binary file not shown.
View
BIN build/Debug/gisteditor.app/Contents/Resources/English.lproj/GEDocument.nib
Binary file not shown.
View
BIN build/Debug/gisteditor.app/Contents/Resources/English.lproj/MainMenu.nib
Binary file not shown.
View
1 build/Debug/gisteditor.app/Contents/Resources/GEDocument.rb
@@ -15,6 +15,7 @@ class GEDocument < NSDocument
attr_accessor :associated_library
def applicationDidFinishLaunching(notification)
+
# pass
end
View
4 build/Debug/gisteditor.app/Contents/Resources/GEGistListDelegate.rb
@@ -9,6 +9,10 @@
class GEGistListDelegate
attr_accessor :associatedDocument
+ def awakeFromNib()
+ NSLog(preferences.user.login)
+ end
+
def numberOfRowsInTableView(aTableView)
@library = GEGistLibrary.new
@library.gists.length
View
BIN build/Debug/gisteditor.app/Contents/Resources/Preferences.nib
Binary file not shown.
View
292 build/Debug/gisteditor.app/Contents/Resources/Preferences.rb
@@ -0,0 +1,292 @@
+#
+# Preferences.rb
+# gisteditor
+#
+# Created by Greg Borenstein on 6/20/09.
+# Copyright (c) 2009 __MyCompanyName__. All rights reserved.
+#
+
+# require '/Users/greg/code/rubycocoa-prefs/lib/abstract_preferences.rb'
+
+require 'singleton'
+
+class NSUserDefaults
+ def [](str)
+ self.objectForKey(str)
+ end
+
+ def []=(str, obj)
+ self.setObject(obj, forKey:str)
+ end
+end
+
+class Preferences
+ include Singleton
+
+ # Save any unsaved changes to disk.
+ def save
+ Preferences.user_defaults.synchronize
+ end
+
+ class << self
+ # A shortcut method for access to <tt>NSUserDefaults.standardUserDefaults</tt>.
+ def user_defaults
+ NSUserDefaults.standardUserDefaults
+ end
+
+ # A hash of all default values for the user defaults
+ def default_values
+ @default_values ||= {}
+ end
+
+ # Registers the default values with NSUserDefaults.standardUserDefaults
+ # Call this after all your Preferences code has been loaded, for instance
+ # in <tt>awakeFromNib</tt> of your ApplicationController.
+ def register_default_values!
+ user_defaults.registerDefaults(default_values)
+ end
+ end
+
+ class Namespace
+ include Singleton
+
+ class << self
+ # Defines a reader method for the Namespace subclass on the Preferences instance.
+ #
+ # Defines a class <tt>Preferences::Keyword</tt> and <tt>preferences.keyword</tt>:
+ #
+ # class Preferences
+ # class Keyword < Namespace
+ # defaults_accessor :an_option, true
+ # end
+ # end
+ def inherited(klass)
+ super
+ method = klass.name.split('::').last.scan(/[A-Z][a-z]*/).map { |x| x.downcase }.join('_')
+ Preferences.class_eval "def #{method}; #{klass.name}.instance end", __FILE__, __LINE__
+ end
+
+ # The key in the preferences that represents the section class.
+ #
+ # Preferences::General.section_defaults_key # => "Preferences.General"
+ def section_defaults_key
+ @section_defaults_key ||= name.gsub('::', '.')
+ end
+
+ # Defines a reader and writer method for a user defaults key for this section.
+ #
+ # If the preference is a boolean value, inflected from the default value,
+ # a query method is also defined.
+ #
+ # # Defines #confirm_quit, #confirm_quit=, and #confirm_quit? It's default value is <tt>true</tt>.
+ # defaults_accessor :confirm_quit, true
+ def defaults_accessor(name, default_value)
+ key_path = "#{section_defaults_key}.#{name}"
+ Preferences.default_values[key_path] = default_value
+
+ class_eval do
+ define_method(name) do
+ Preferences.user_defaults[key_path]
+ end
+
+ define_method("#{name}=") do |value|
+ Preferences.user_defaults[key_path] = value
+ end
+
+ if default_value == true || default_value == false
+ alias_method "#{name}?", name
+ end
+ end
+
+ key_path
+ end
+
+ # Besides defining a reader and writer method via defaults_accessor,
+ # it also defines a reader method which returns an array of strings
+ # wrapped in KVO compatible string wrappers.
+ #
+ # The name of the wrapper class is defined by <tt>wrapper_class_name</tt>
+ # and can be used as the `Class Name' of a NSArrayController.
+ # The wrapper exposes `string' as a KVC accessor to which a NSTableColumn can be bound.
+ #
+ # # Defines #highlight_words, #highlight_words=, and #highlight_words_wrapped
+ # string_array_defaults_accessor :highlight_words, [], 'HighlightWordWrapper'
+ def string_array_defaults_accessor(name, default_value, wrapper_class_name)
+ wrapper = eval("class ::#{wrapper_class_name} < StringArrayWrapper; self end")
+ wrapper.key_path = defaults_accessor(name, default_value)
+
+ class_eval do
+ define_method("#{name}_wrapped") do
+ ary = []
+ send(name).each_with_index { |string, index| ary << wrapper.alloc.initWithString_index(string, index) }
+ ary
+ end
+ end
+ end
+ end
+
+ # Register an observer for a key.
+ #
+ # Include the <tt>Preferences::KVOCallbackHelper</tt> module in your class
+ # to get rubyish callback handling, instead of handling it yourself by defining
+ # the observeValueForKeyPath_ofObject_change_context method.
+ #
+ # class PreferencesController < OSX::NSWindowController
+ # include Preferences::KVOCallbackHelper
+ #
+ # def init
+ # if super_init
+ # preferences.keyword.observe(:highlight_words, self)
+ # self
+ # end
+ # end
+ #
+ # def highlight_words_changed(new_value)
+ # # Do stuff because a new value has been set.
+ # end
+ # end
+ def observe(name, observer)
+ key_path = "values.#{self.class.section_defaults_key}.#{name}"
+ NSUserDefaultsController.sharedUserDefaultsController.addObserver(observer,
+ forKeyPath:key_path, options:NSKeyValueObservingOptionNew, context:nil
+ )
+ end
+ end
+
+ class StringArrayWrapper < NSObject
+ class << self
+ attr_accessor :key_path
+
+ def array
+ Preferences.user_defaults[key_path]
+ end
+
+ def array=(array)
+ Preferences.user_defaults[key_path] = array
+ end
+
+ def destroy(klass, new_wrappers)
+ # Set the new correct indices on the remaining wrappers
+ new_wrappers.each_with_index do |wrapper, new_index|
+ wrapper.index = new_index
+ end
+
+ # Assign the new result array of strings
+ klass.array = new_wrappers.map { |wrapper| wrapper.string }
+ end
+ end
+
+ attr_accessor :string
+ attr_accessor :index
+
+ def initWithString(string, index:index)
+ if init
+ @string, @index = string, index
+ self
+ end
+ end
+
+ def array
+ self.class.array
+ end
+
+ def array=(array)
+ self.class.array = array
+ end
+
+ def string=(string)
+ @string = string
+ set_string!
+ end
+
+ def set_string!
+ if @index
+ ary = array
+ ary[@index] = string
+ self.array = ary
+ else
+ ary = array
+ ary << @string
+ self.array = ary
+ @index = ary.length - 1
+ end
+ end
+
+ def inspect
+ "#<#{self.class.name}:#{object_id} string=\"#{@string}\" key_path=\"#{self.class.key_path}\" index=\"#{@index}\">"
+ end
+ end
+
+ # Extend your class with this module to get access to a few KVC accessor helper methods.
+ module AccessorHelpers
+ # Defines a kvc_accessor which reads and writes
+ # to the specified preferences path (<tt>path_to_eval_to_object</tt>).
+ #
+ # This is useful for binding, for instance, UI elements
+ # to an array in the NSUserDefaults which is normally immutable.
+ #
+ # class PreferencesController < OSX::NSWindowController
+ # defaults_kvc_accessor :an_array_of_dictionaries, 'preferences.keyword.url_mappings'
+ # end
+ #
+ # Binding a NSArrayController to File's Owner with key path: <tt>an_array_of_dictionaries</tt>,
+ # will perform the following read/write actions on the NSUserDefaults:
+ #
+ # preferences_controller.valueForKey('an_array_of_dictionaries') # => [{'key' => 'value 1'}, {'key' => 'value 2'}]
+ # preferences_controller.setValueForKey([{'key' => 'value 1'}], 'an_array_of_dictionaries')
+ # preferences_controller.valueForKey('an_array_of_dictionaries') # => [{'key' => 'value 1'}]
+ def defaults_kvc_accessor(name, path_to_eval_to_object)
+ kvc_accessor(name)
+
+ class_eval %{
+ def #{name}
+ @#{name} ||= #{path_to_eval_to_object}
+ end
+
+ def #{name}=(new_defaults)
+ #{path_to_eval_to_object} = @#{name} = new_defaults
+ end
+ }, __FILE__, __LINE__
+ end
+
+ # Defines read and write KVC accessors like defaults_kvc_accessor does,
+ # but is used specifically for defaults defined with Namespace#string_array_defaults_accessor.
+ #
+ # class PreferencesController < OSX::NSWindowController
+ # defualts_string_array_kvc_accessor :an_array_of_strings, 'preferences.keyword.highlight_words'
+ # end
+ #
+ # See Namespace#string_array_defaults_accessor for more info.
+ def defualts_string_array_kvc_accessor(name, path_to_eval_to_object)
+ defaults_kvc_accessor(name, "#{path_to_eval_to_object}_wrapped")
+
+ class_eval %{
+ def #{name}=(new_wrappers)
+ if new_wrappers.length < #{name}.length
+ Preferences::StringArrayWrapper.destroy(#{name}.first.class, new_wrappers)
+ end
+ @#{name} = new_wrappers
+ end
+ }, __FILE__, __LINE__
+ end
+ end
+
+end
+
+module Kernel
+ # A shortcut method for easy access anywhere to the shared user defaults.
+ def preferences
+ Preferences.instance
+ end
+end
+
+class Preferences
+ class User < Namespace
+ defaults_accessor :login, "YOUR LOGIN HERE"
+ defaults_accessor :token, "YOUR TOKEN HERE"
+ end
+
+ # Register the default values with NSUserDefaults.standardUserDefaults.
+ register_default_values!
+end
+
View
BIN build/gisteditor.build/Debug/gisteditor.build/Objects-normal/i386/main.o
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/categories.pbxbtree
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/cdecls.pbxbtree
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/decls.pbxbtree
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/files.pbxbtree
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/imports.pbxbtree
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/pbxindex.header
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/protocols.pbxbtree
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/refs.pbxbtree
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/strings.pbxstrings/control
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/strings.pbxstrings/strings
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/subclasses.pbxbtree
Binary file not shown.
View
BIN build/gisteditor.build/gisteditor.pbxindex/symbols0.pbxsymbols
Binary file not shown.
View
99 gisteditor.xcodeproj/greg.mode1v3
@@ -278,8 +278,8 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
- <integer>15</integer>
- <integer>11</integer>
+ <integer>4</integer>
+ <integer>1</integer>
<integer>0</integer>
</array>
</array>
@@ -321,7 +321,7 @@
<key>PBXProjectModuleGUID</key>
<string>1CE0B20306471E060097A5F4</string>
<key>PBXProjectModuleLabel</key>
- <string>GEDocument.rb</string>
+ <string>Preferences.rb</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@@ -329,22 +329,23 @@
<key>PBXProjectModuleGUID</key>
<string>1CE0B20406471E060097A5F4</string>
<key>PBXProjectModuleLabel</key>
- <string>GEDocument.rb</string>
+ <string>Preferences.rb</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>37895EC80FEB7FF2005EE5EE</string>
+ <string>374E6A860FEF64000062A2C9</string>
<key>history</key>
<array>
<string>37902CD30FD6F6F100DE3FDE</string>
<string>37902CD50FD6F6F100DE3FDE</string>
<string>37902CFD0FD6FBAD00DE3FDE</string>
<string>378DED7E0FDB008200F1958C</string>
- <string>37895EAD0FEB7C30005EE5EE</string>
- <string>37895EB60FEB7F15005EE5EE</string>
- <string>37895EB70FEB7F15005EE5EE</string>
- <string>37895EC30FEB7FC9005EE5EE</string>
- <string>37895EC40FEB7FC9005EE5EE</string>
+ <string>37895EED0FED96FC005EE5EE</string>
+ <string>37895EEE0FED96FC005EE5EE</string>
+ <string>37895EFF0FEDDC30005EE5EE</string>
+ <string>374E6A760FEF635F0062A2C9</string>
+ <string>374E6A780FEF635F0062A2C9</string>
+ <string>374E6A7F0FEF63E70062A2C9</string>
</array>
<key>prevStack</key>
<array>
@@ -357,59 +358,9 @@
<string>378DED8F0FDB20EC00F1958C</string>
<string>37A8359A0FEAD6980064AF4F</string>
<string>37A8359F0FEAD6980064AF4F</string>
- <string>37895DFD0FEB6BDC005EE5EE</string>
- <string>37895DFE0FEB6BDC005EE5EE</string>
- <string>37895DFF0FEB6BDC005EE5EE</string>
- <string>37895E000FEB6BDC005EE5EE</string>
- <string>37895E200FEB6F94005EE5EE</string>
- <string>37895E210FEB6F94005EE5EE</string>
- <string>37895E220FEB6F94005EE5EE</string>
- <string>37895E330FEB7045005EE5EE</string>
- <string>37895E340FEB7045005EE5EE</string>
- <string>37895E350FEB7045005EE5EE</string>
- <string>37895E360FEB7045005EE5EE</string>
- <string>37895E370FEB7045005EE5EE</string>
- <string>37895E380FEB7045005EE5EE</string>
- <string>37895E390FEB7045005EE5EE</string>
- <string>37895E3A0FEB7045005EE5EE</string>
- <string>37895E3B0FEB7045005EE5EE</string>
- <string>37895E3C0FEB7045005EE5EE</string>
- <string>37895E430FEB70F2005EE5EE</string>
- <string>37895E440FEB70F2005EE5EE</string>
- <string>37895E450FEB70F2005EE5EE</string>
- <string>37895E4B0FEB72A0005EE5EE</string>
- <string>37895E4C0FEB72A0005EE5EE</string>
- <string>37895E4D0FEB72A0005EE5EE</string>
- <string>37895E550FEB73D8005EE5EE</string>
- <string>37895E560FEB73D8005EE5EE</string>
- <string>37895E570FEB73D8005EE5EE</string>
- <string>37895E6E0FEB75A7005EE5EE</string>
- <string>37895E780FEB7612005EE5EE</string>
- <string>37895E7C0FEB7683005EE5EE</string>
- <string>37895E7D0FEB7683005EE5EE</string>
- <string>37895E880FEB7795005EE5EE</string>
- <string>37895E890FEB7795005EE5EE</string>
- <string>37895E8A0FEB7795005EE5EE</string>
- <string>37895E8B0FEB7795005EE5EE</string>
- <string>37895E8C0FEB7795005EE5EE</string>
- <string>37895E8D0FEB7795005EE5EE</string>
- <string>37895E8E0FEB7795005EE5EE</string>
- <string>37895E8F0FEB7795005EE5EE</string>
- <string>37895E900FEB7795005EE5EE</string>
- <string>37895E970FEB77ED005EE5EE</string>
- <string>37895E980FEB77ED005EE5EE</string>
- <string>37895E9E0FEB7846005EE5EE</string>
- <string>37895E9F0FEB7846005EE5EE</string>
- <string>37895EA00FEB7846005EE5EE</string>
- <string>37895EA50FEB7885005EE5EE</string>
- <string>37895EAE0FEB7C30005EE5EE</string>
- <string>37895EAF0FEB7C30005EE5EE</string>
- <string>37895EBA0FEB7F15005EE5EE</string>
- <string>37895EBB0FEB7F15005EE5EE</string>
- <string>37895EBC0FEB7F15005EE5EE</string>
- <string>37895EBD0FEB7F15005EE5EE</string>
- <string>37895EBE0FEB7F15005EE5EE</string>
- <string>37895EC50FEB7FC9005EE5EE</string>
+ <string>374E6A7A0FEF635F0062A2C9</string>
+ <string>374E6A7B0FEF635F0062A2C9</string>
+ <string>374E6A7D0FEF635F0062A2C9</string>
</array>
</dict>
<key>SplitCount</key>
@@ -467,9 +418,9 @@
</array>
<key>TableOfContents</key>
<array>
- <string>37895DF50FEB6B35005EE5EE</string>
+ <string>374E6A5B0FEF433B0062A2C9</string>
<string>1CE0B1FE06471DED0097A5F4</string>
- <string>37895DF60FEB6B35005EE5EE</string>
+ <string>374E6A5C0FEF433B0062A2C9</string>
<string>1CE0B20306471E060097A5F4</string>
<string>1CE0B20506471E060097A5F4</string>
</array>
@@ -603,8 +554,8 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
- <string>1CD10A99069EF8BA00B06720</string>
<string>37902BD30FD5F14500DE3FDE</string>
+ <string>1CD10A99069EF8BA00B06720</string>
<string>/Users/greg/code/gisteditor/gisteditor.xcodeproj</string>
<string>1C78EAAD065D492600B07095</string>
</array>
@@ -686,7 +637,7 @@
<key>TableOfContents</key>
<array>
<string>37902BD30FD5F14500DE3FDE</string>
- <string>37895E020FEB6BDC005EE5EE</string>
+ <string>374E6A660FEF62A50062A2C9</string>
<string>1CD0528F0623707200166675</string>
<string>XCMainBuildResultsModuleGUID</string>
</array>
@@ -806,13 +757,13 @@
<key>TableOfContents</key>
<array>
<string>1CD10A99069EF8BA00B06720</string>
- <string>37895E030FEB6BDC005EE5EE</string>
+ <string>374E6A670FEF62A50062A2C9</string>
<string>1C162984064C10D400B95A72</string>
- <string>37895E040FEB6BDC005EE5EE</string>
- <string>37895E050FEB6BDC005EE5EE</string>
- <string>37895E060FEB6BDC005EE5EE</string>
- <string>37895E070FEB6BDC005EE5EE</string>
- <string>37895E080FEB6BDC005EE5EE</string>
+ <string>374E6A680FEF62A50062A2C9</string>
+ <string>374E6A690FEF62A50062A2C9</string>
+ <string>374E6A6A0FEF62A50062A2C9</string>
+ <string>374E6A6B0FEF62A50062A2C9</string>
+ <string>374E6A6C0FEF62A50062A2C9</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugV3</string>
@@ -976,7 +927,7 @@
<key>TableOfContents</key>
<array>
<string>1C78EAAD065D492600B07095</string>
- <string>37895E090FEB6BDC005EE5EE</string>
+ <string>374E6A6D0FEF62A50062A2C9</string>
<string>1C78EAAC065D492600B07095</string>
</array>
<key>ToolbarConfiguration</key>
View
1,922 gisteditor.xcodeproj/greg.pbxuser
410 additions, 1,512 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
8 gisteditor.xcodeproj/project.pbxproj
@@ -9,6 +9,8 @@
/* Begin PBXBuildFile section */
1DDD582C0DA1D0D100B32029 /* GEDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58280DA1D0D100B32029 /* GEDocument.xib */; };
1DDD582D0DA1D0D100B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD582A0DA1D0D100B32029 /* MainMenu.xib */; };
+ 374E6A6F0FEF62D10062A2C9 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 374E6A6E0FEF62D10062A2C9 /* Preferences.xib */; };
+ 37895EFC0FEDDC08005EE5EE /* Preferences.rb in Resources */ = {isa = PBXBuildFile; fileRef = 37895EFB0FEDDC08005EE5EE /* Preferences.rb */; };
378DED890FDB0B3F00F1958C /* GEGist.rb in Resources */ = {isa = PBXBuildFile; fileRef = 378DED880FDB0B3F00F1958C /* GEGist.rb */; };
37902BCA0FD5F10500DE3FDE /* rb_main.rb in Resources */ = {isa = PBXBuildFile; fileRef = 37902BC90FD5F10500DE3FDE /* rb_main.rb */; };
37902BCC0FD5F11400DE3FDE /* GEDocument.rb in Resources */ = {isa = PBXBuildFile; fileRef = 37902BCB0FD5F11400DE3FDE /* GEDocument.rb */; };
@@ -33,6 +35,8 @@
2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
32DBCF750370BD2300C91783 /* gisteditor_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gisteditor_Prefix.pch; sourceTree = "<group>"; };
+ 374E6A6E0FEF62D10062A2C9 /* Preferences.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Preferences.xib; sourceTree = "<group>"; };
+ 37895EFB0FEDDC08005EE5EE /* Preferences.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = Preferences.rb; sourceTree = "<group>"; };
378DED880FDB0B3F00F1958C /* GEGist.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = GEGist.rb; sourceTree = "<group>"; };
37902BC90FD5F10500DE3FDE /* rb_main.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = rb_main.rb; sourceTree = "<group>"; };
37902BCB0FD5F11400DE3FDE /* GEDocument.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = GEDocument.rb; sourceTree = "<group>"; };
@@ -101,6 +105,7 @@
children = (
37902BCB0FD5F11400DE3FDE /* GEDocument.rb */,
378DED880FDB0B3F00F1958C /* GEGist.rb */,
+ 37895EFB0FEDDC08005EE5EE /* Preferences.rb */,
37A835730FEACC880064AF4F /* GEGistLibrary.rb */,
37A835660FEAC9A70064AF4F /* GEGistListDelegate.rb */,
37902D110FD7A3B300DE3FDE /* ConnectionDelegate.rb */,
@@ -126,6 +131,7 @@
089C165FFE840EACC02AAC07 /* InfoPlist.strings */,
1DDD58280DA1D0D100B32029 /* GEDocument.xib */,
1DDD582A0DA1D0D100B32029 /* MainMenu.xib */,
+ 374E6A6E0FEF62D10062A2C9 /* Preferences.xib */,
);
name = Resources;
sourceTree = "<group>";
@@ -192,6 +198,8 @@
378DED890FDB0B3F00F1958C /* GEGist.rb in Resources */,
37A835670FEAC9A80064AF4F /* GEGistListDelegate.rb in Resources */,
37A835740FEACC880064AF4F /* GEGistLibrary.rb in Resources */,
+ 37895EFC0FEDDC08005EE5EE /* Preferences.rb in Resources */,
+ 374E6A6F0FEF62D10062A2C9 /* Preferences.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

0 comments on commit a08fe37

Please sign in to comment.
Something went wrong with that request. Please try again.