/core/externals/update-engine/externals/google-toolbox-for-mac/XcodePlugin/GTMXcodePlugin.m

http://macfuse.googlecode.com/ · Objective C · 212 lines · 155 code · 27 blank · 30 comment · 22 complexity · ed49ee4d5036cf896ff69d688098fc40 MD5 · raw file

  1. //
  2. // GTMXcodePlugin.m
  3. //
  4. // Copyright 2007-2009 Google Inc.
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7. // use this file except in compliance with the License. You may obtain a copy
  8. // of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. // License for the specific language governing permissions and limitations under
  16. // the License.
  17. //
  18. #import "GTMXcodePlugin.h"
  19. #import "GTMXcodeMenuItem.h"
  20. #import "PBXPreferencesModule.h"
  21. #import "GTMXcodePreferences.h"
  22. #import "GTMDefines.h"
  23. @interface GTMXcodePlugin (PrivateMethods)
  24. // Called when the preference panel has been loaded so we can set up our
  25. // preference pane.
  26. - (void)preferencesPanelDidLoadNotification:(NSNotification *)notification;
  27. // Called when we start tracking the menu
  28. - (void)begunTracking:(NSNotification *)notification;
  29. // Called whenever the pref for showing the menuitem icon changes
  30. - (void)updateMenuIcons:(NSNotification *)notification;
  31. // the image to use for our menu items
  32. - (NSImage *)imageForMenuItems;
  33. @end
  34. // Our dictionary of menu items to add
  35. static NSMutableDictionary *gRegisteredMenuItems = nil;
  36. static NSMutableArray *gRegisteredClasses = nil;
  37. @implementation GTMXcodePlugin
  38. + (void)registerMenuItem:(id)item {
  39. @synchronized([self class]) {
  40. static int gTag = 0xDADE;
  41. if (!gRegisteredMenuItems) {
  42. gRegisteredMenuItems = [[NSMutableDictionary alloc] init];
  43. }
  44. if (item) {
  45. [gRegisteredMenuItems setObject:item
  46. forKey:[NSNumber numberWithInt:gTag++]];
  47. }
  48. }
  49. }
  50. + (void)registerSwizzleClass:(Class)cls {
  51. @synchronized([self class]) {
  52. if (!gRegisteredClasses) {
  53. gRegisteredClasses = [[NSMutableArray alloc] init];
  54. }
  55. if (cls) {
  56. [gRegisteredClasses addObject:cls];
  57. }
  58. }
  59. }
  60. - (id)init {
  61. self = [super init];
  62. if (!self) return nil;
  63. NSBundle *bundle = [NSBundle bundleForClass:[self class]];
  64. NSString *version = [bundle objectForInfoDictionaryKey:@"CFBundleVersion"];
  65. NSLog(@"GTMXcodePlugin loaded (%@)", version);
  66. NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  67. [nc addObserver:self
  68. selector:@selector(preferencesPanelDidLoadNotification:)
  69. name:PBXPreferencesPanelDidLoadNotification
  70. object:nil];
  71. [nc addObserver:self
  72. selector:@selector(begunTracking:)
  73. name:NSMenuDidBeginTrackingNotification
  74. object:[NSApp mainMenu]];
  75. [nc addObserver:self
  76. selector:@selector(updateMenuIcons:)
  77. name:GTMXcodePreferencesMenuItemPrefChanged
  78. object:nil];
  79. NSEnumerator *enumerator = [gRegisteredClasses objectEnumerator];
  80. Class cls;
  81. while ((cls = [enumerator nextObject])) {
  82. [[[cls alloc] init] autorelease];
  83. }
  84. return self;
  85. }
  86. - (void)dealloc {
  87. [[NSNotificationCenter defaultCenter] removeObserver:self];
  88. [gRegisteredMenuItems removeAllObjects];
  89. [gRegisteredMenuItems release];
  90. [super dealloc];
  91. }
  92. - (void)preferencesPanelDidLoadNotification:(NSNotification *)notification {
  93. GTMXcodePreferences *prefs = [[[GTMXcodePreferences alloc] init] autorelease];
  94. [[PBXPreferencesModule sharedPreferences] addPreferenceNamed:@"Google"
  95. owner:prefs];
  96. }
  97. - (NSImage *)imageForMenuItems {
  98. NSBundle *pluginBundle = [GTMXcodePlugin pluginBundle];
  99. NSString *path = [pluginBundle pathForResource:@"GTM"
  100. ofType:@"icns"];
  101. NSImage *image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
  102. [image setScalesWhenResized:YES];
  103. [image setSize:NSMakeSize(16, 16)];
  104. return image;
  105. }
  106. - (void)begunTracking:(NSNotification *)notification {
  107. NSImage *image = nil;
  108. if ([GTMXcodePreferences showImageOnMenuItems]) {
  109. image = [self imageForMenuItems];
  110. }
  111. NSArray *sortedKeys
  112. = [gRegisteredMenuItems keysSortedByValueUsingSelector:@selector(compareDepth:)];
  113. NSEnumerator *keyEnum = [sortedKeys objectEnumerator];
  114. NSNumber *key;
  115. while ((key = [keyEnum nextObject])) {
  116. id<GTMXcodeMenuItemProtocol> item = [gRegisteredMenuItems objectForKey:key];
  117. NSInteger insertionIndex = [item insertionIndex];
  118. NSMenu *insertionMenu = [item insertionMenu];
  119. NSInteger itemCount = [insertionMenu numberOfItems];
  120. if (insertionIndex > itemCount) {
  121. insertionIndex = itemCount;
  122. }
  123. NSString *itemTitle = [item title];
  124. if ([itemTitle isEqualToString:@"-"]) {
  125. [insertionMenu insertItem:[NSMenuItem separatorItem]
  126. atIndex:insertionIndex];
  127. } else {
  128. NSMenuItem *menuItem
  129. = [insertionMenu insertItemWithTitle:[item title]
  130. action:[item actionSelector]
  131. keyEquivalent:[item keyEquivalent]
  132. atIndex:insertionIndex];
  133. if (image && [item allowGDTMenuIcon]) {
  134. [menuItem setImage:image];
  135. }
  136. [menuItem setTarget:item];
  137. [menuItem setTag:[key intValue]];
  138. [item wasInserted:menuItem];
  139. }
  140. }
  141. // Now that we are installed, unregister us from the notification.
  142. NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  143. [center removeObserver:self
  144. name:NSMenuDidBeginTrackingNotification
  145. object:[NSApp mainMenu]];
  146. }
  147. - (void)updateMenuIcons:(NSNotification *)notification {
  148. // we use our own notification since the normal defaults one doesn't let you
  149. // tell which changed.
  150. NSImage *image = nil;
  151. if ([GTMXcodePreferences showImageOnMenuItems]) {
  152. image = [self imageForMenuItems];
  153. }
  154. NSEnumerator *keyEnum = [gRegisteredMenuItems keyEnumerator];
  155. NSNumber *key;
  156. while ((key = [keyEnum nextObject])) {
  157. id<GTMXcodeMenuItemProtocol> item = [gRegisteredMenuItems objectForKey:key];
  158. NSMenu *insertionMenu = [item insertionMenu];
  159. NSMenuItem *menuItem = [insertionMenu itemWithTag:[key intValue]];
  160. // play it safe, make sure it's the right target
  161. if (menuItem && (item == [menuItem target])) {
  162. // if the user wants images and this item should get it, then set the
  163. // image. if either wasn't true, just set it to nil to clear the
  164. // menu.
  165. if (image && [item allowGDTMenuIcon]) {
  166. [menuItem setImage:image];
  167. } else {
  168. [menuItem setImage:nil];
  169. }
  170. }
  171. }
  172. }
  173. + (NSBundle*)pluginBundle {
  174. return [NSBundle bundleForClass:self];
  175. }
  176. + (float)xCodeVersion {
  177. NSBundle *bundle = [NSBundle mainBundle];
  178. id object = [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
  179. float value = [object floatValue];
  180. if (!(value > 0.0)) {
  181. NSLog(@"Unable to get Xcode Version");
  182. }
  183. return value;
  184. }
  185. @end