├── .gitignore ├── .gitmodules ├── Developers.md ├── License ├── PTHotkey ├── PTHotKey.h ├── PTHotKeyCenter.h ├── PTHotKeyLib.h ├── PTKeyBroadcaster.h ├── PTKeyCodeTranslator.h ├── PTKeyCodes.plist ├── PTKeyCombo.h ├── PTKeyComboPanel.h ├── PTKeyComboPanel.xib └── libPTHotkey-OSX.a ├── QuickRadar.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── xcshareddata │ └── QuickRadar.xcscmblueprint ├── QuickRadar ├── ADNLogoTemplate.png ├── AppDelegate.h ├── AppDelegate.m ├── AppIconSmall.png ├── Appicon.icns ├── AppleLogoTemplate.png ├── Config.plist ├── Config │ └── Readme.md ├── DDOpenAtLoginController.h ├── DDOpenAtLoginController.m ├── MenubarTemplate.tif ├── MenubarTemplate@2x.tif ├── NSButton+QuickRadar.h ├── NSButton+QuickRadar.m ├── NSError+Additions.h ├── NSError+Additions.m ├── NSImage+ProportionalScaling.h ├── NSImage+ProportionalScaling.m ├── NSString+URLEncoding.h ├── NSString+URLEncoding.m ├── NSXMLNode+Additions.h ├── NSXMLNode+Additions.m ├── OpenRadarTemplate.tif ├── OrderedDictionary.h ├── OrderedDictionary.m ├── PasswordStoring.h ├── PasswordStoring.m ├── ProductCategories.plist ├── Products.json ├── QRAppDotNetSubmissionService.h ├── QRAppDotNetSubmissionService.m ├── QRAppDotNetSubmissionServicePreferencesViewController.h ├── QRAppDotNetSubmissionServicePreferencesViewController.m ├── QRAppDotNetSubmissionServicePreferencesViewController.xib ├── QRAppListManager.h ├── QRAppListManager.m ├── QRAppListOutlineView.h ├── QRAppListOutlineView.m ├── QRAppListPopover.h ├── QRAppListPopover.m ├── QRAppListTableCellView.h ├── QRAppListTableCellView.m ├── QRAppListViewController.h ├── QRAppListViewController.m ├── QRAppListViewController.xib ├── QRCachedRunningApplication.h ├── QRCachedRunningApplication.m ├── QRCopyToClipboardSubmissionService.h ├── QRCopyToClipboardSubmissionService.m ├── QRFileDuplicateWindow.xib ├── QRFileDuplicateWindowController.h ├── QRFileDuplicateWindowController.m ├── QRFileWell.h ├── QRFileWell.m ├── QRMainAppSettingsViewController.h ├── QRMainAppSettingsViewController.m ├── QRMainAppSettingsViewController.xib ├── QROpenRadarSubmissionService.h ├── QROpenRadarSubmissionService.m ├── QROpenRadarSubmissionServicePreferencesViewController.h ├── QROpenRadarSubmissionServicePreferencesViewController.m ├── QROpenRadarSubmissionServicePreferencesViewController.xib ├── QRPreferencesWindowController.h ├── QRPreferencesWindowController.m ├── QRPreferencesWindowController.xib ├── QRRadar.h ├── QRRadar.m ├── QRRadarSubmissionService.h ├── QRRadarSubmissionService.m ├── QRRadarSubmissionServicePreferencesViewController.h ├── QRRadarSubmissionServicePreferencesViewController.m ├── QRRadarSubmissionServicePreferencesViewController.xib ├── QRRadarWindow.h ├── QRRadarWindow.m ├── QRRadarWindowController.h ├── QRRadarWindowController.m ├── QRSubmissionController.h ├── QRSubmissionController.m ├── QRSubmissionService.h ├── QRSubmissionService.m ├── QRTwitterSubmissionService.h ├── QRTwitterSubmissionService.m ├── QRURLConnection.h ├── QRURLConnection.m ├── QRUserDefaultsKeys.h ├── QRWebScraper.h ├── QRWebScraper.m ├── QRWordpressSubmissionService.h ├── QRWordpressSubmissionService.m ├── QRWordpressSubmissionServicePreferencesViewController.h ├── QRWordpressSubmissionServicePreferencesViewController.m ├── QRWordpressSubmissionServicePreferencesViewController.xib ├── QuickRadar-Info.plist ├── QuickRadar-Prefix.pch ├── RadarWindow.xib ├── SGHotKeyCenter │ ├── SGHotKey.h │ ├── SGHotKey.m │ ├── SGHotKeyCenter.h │ ├── SGHotKeyCenter.m │ ├── SGKeyCodeTranslator.h │ ├── SGKeyCodeTranslator.m │ ├── SGKeyCodes.plist │ ├── SGKeyCombo.h │ └── SGKeyCombo.m ├── SRCommon.h ├── SRCommon.m ├── SRKeyCodeTransformer.h ├── SRKeyCodeTransformer.m ├── SRRecorderCell.h ├── SRRecorderCell.m ├── SRRecorderControl.h ├── SRRecorderControl.m ├── SRValidator.h ├── SRValidator.m ├── WarningIcon.png ├── WordpressLogoTemplate.png ├── dsa_pub.pem ├── en.lproj │ ├── Credits.rtf │ └── MainMenu.xib └── main.m ├── README.md └── Sparkle.framework ├── Headers ├── Modules ├── PrivateHeaders ├── Resources ├── Sparkle └── Versions ├── A ├── Headers │ ├── SUAppcast.h │ ├── SUAppcastItem.h │ ├── SUErrors.h │ ├── SUExport.h │ ├── SUStandardVersionComparator.h │ ├── SUUpdater.h │ ├── SUVersionComparisonProtocol.h │ ├── SUVersionDisplayProtocol.h │ └── Sparkle.h ├── Modules │ └── module.modulemap ├── PrivateHeaders │ └── SUUnarchiver.h ├── Resources │ ├── Autoupdate.app │ │ └── Contents │ │ │ ├── Info.plist │ │ │ ├── MacOS │ │ │ └── Autoupdate │ │ │ ├── PkgInfo │ │ │ └── Resources │ │ │ ├── AppIcon.icns │ │ │ ├── SUStatus.nib │ │ │ ├── ar.lproj │ │ │ └── Sparkle.strings │ │ │ ├── ca.lproj │ │ │ └── Sparkle.strings │ │ │ ├── cs.lproj │ │ │ └── Sparkle.strings │ │ │ ├── da.lproj │ │ │ └── Sparkle.strings │ │ │ ├── de.lproj │ │ │ └── Sparkle.strings │ │ │ ├── el.lproj │ │ │ └── Sparkle.strings │ │ │ ├── en.lproj │ │ │ └── Sparkle.strings │ │ │ ├── es.lproj │ │ │ └── Sparkle.strings │ │ │ ├── fi.lproj │ │ │ └── Sparkle.strings │ │ │ ├── fr.lproj │ │ │ └── Sparkle.strings │ │ │ ├── he.lproj │ │ │ └── Sparkle.strings │ │ │ ├── is.lproj │ │ │ └── Sparkle.strings │ │ │ ├── it.lproj │ │ │ └── Sparkle.strings │ │ │ ├── ja.lproj │ │ │ └── Sparkle.strings │ │ │ ├── ko.lproj │ │ │ └── Sparkle.strings │ │ │ ├── nb.lproj │ │ │ └── Sparkle.strings │ │ │ ├── nl.lproj │ │ │ └── Sparkle.strings │ │ │ ├── pl.lproj │ │ │ └── Sparkle.strings │ │ │ ├── pt_BR.lproj │ │ │ └── Sparkle.strings │ │ │ ├── pt_PT.lproj │ │ │ └── Sparkle.strings │ │ │ ├── ro.lproj │ │ │ └── Sparkle.strings │ │ │ ├── ru.lproj │ │ │ └── Sparkle.strings │ │ │ ├── sk.lproj │ │ │ └── Sparkle.strings │ │ │ ├── sl.lproj │ │ │ └── Sparkle.strings │ │ │ ├── sv.lproj │ │ │ └── Sparkle.strings │ │ │ ├── th.lproj │ │ │ └── Sparkle.strings │ │ │ ├── tr.lproj │ │ │ └── Sparkle.strings │ │ │ ├── uk.lproj │ │ │ └── Sparkle.strings │ │ │ ├── zh_CN.lproj │ │ │ └── Sparkle.strings │ │ │ └── zh_TW.lproj │ │ │ └── Sparkle.strings │ ├── Info.plist │ ├── SUModelTranslation.plist │ ├── SUStatus.nib │ ├── ar.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── ca.lproj │ │ └── Sparkle.strings │ ├── cs.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── da.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── de.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── el.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── en.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── es.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── fi.lproj │ │ └── Sparkle.strings │ ├── fr.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── fr_CA.lproj │ ├── he.lproj │ │ └── Sparkle.strings │ ├── is.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── it.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── ja.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── ko.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── nb.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── nl.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── pl.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── pt.lproj │ ├── pt_BR.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── pt_PT.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── ro.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── ru.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── sk.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── sl.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── sv.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── th.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── tr.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── uk.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ ├── zh_CN.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings │ └── zh_TW.lproj │ │ ├── SUAutomaticUpdateAlert.nib │ │ ├── SUUpdateAlert.nib │ │ ├── SUUpdatePermissionPrompt.nib │ │ └── Sparkle.strings └── Sparkle └── Current /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | QuickRadar.xcodeproj/project.xcworkspace/contents.xcworkspacedata 3 | xcuserdata 4 | .xcworkspace 5 | *.xccheckout 6 | *.xcscmblueprint 7 | xcuserdata 8 | /QuickRadar/AppDotNetConfig.plist 9 | /QuickRadar/Config/AppDotNetConfig.plist 10 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Externals/DTXMLRPC"] 2 | path = Externals/DTXMLRPC 3 | url = https://github.com/Cocoanetics/DTXMLRPC.git 4 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Amy Worrall 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the QuickRadar project nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL AMY WORRALL BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /PTHotkey/PTHotKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTHotKey.h 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "PTKeyCombo.h" 12 | 13 | @interface PTHotKey : NSObject { 14 | NSString* mName; 15 | PTKeyCombo* mKeyCombo; 16 | id mTarget; 17 | SEL mAction; 18 | EventHotKeyRef carbonHotKey; 19 | } 20 | 21 | - (id)init; 22 | 23 | - (void)setName: (NSString*)name; 24 | - (NSString*)name; 25 | 26 | - (EventHotKeyRef)carbonHotKey; 27 | - (void)setCarbonHotKey:(EventHotKeyRef)hotKey; 28 | 29 | - (void)setKeyCombo: (PTKeyCombo*)combo; 30 | - (PTKeyCombo*)keyCombo; 31 | 32 | - (void)setTarget: (id)target; 33 | - (id)target; 34 | - (void)setAction: (SEL)action; 35 | - (SEL)action; 36 | 37 | - (void)invoke; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /PTHotkey/PTHotKeyCenter.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTHotKeyCenter.h 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class PTHotKey; 12 | 13 | @interface PTHotKeyCenter : NSObject 14 | { 15 | NSMutableDictionary* mHotKeys; //Keys are NSValue of EventHotKeyRef 16 | NSMutableDictionary* mHotKeyMap; 17 | u_int32_t mNextKeyID; 18 | BOOL mEventHandlerInstalled; 19 | } 20 | 21 | + (id)sharedCenter; 22 | 23 | //- (void) enterHotKeyWithName:(NSString *)name enable:(BOOL)ena; 24 | - (BOOL)registerHotKey: (PTHotKey*)hotKey; 25 | - (void)unregisterHotKey: (PTHotKey*)hotKey; 26 | - (void) unregisterHotKeyForName:(NSString *)name; 27 | - (void) unregisterAllHotKeys; 28 | - (void) setHotKeyRegistrationForName:(NSString *)name enable:(BOOL)ena; 29 | - (PTHotKey *) hotKeyForName:(NSString *)name; 30 | - (void) updateHotKey:(PTHotKey *)hk; 31 | 32 | - (NSArray*)allHotKeys; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /PTHotkey/PTHotKeyLib.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTKeyCombo.h 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PTKeyCombo.h" 11 | #import "PTKeyBroadcaster.h" 12 | #import "PTKeyCodeTranslator.h" 13 | #import "PTHotKey.h" 14 | #import "PTHotKeyCenter.h" 15 | #import "PTKeyComboPanel.h" -------------------------------------------------------------------------------- /PTHotkey/PTKeyBroadcaster.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTKeyBroadcaster.h 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sun Aug 03 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface PTKeyBroadcaster : NSButton 13 | { 14 | } 15 | 16 | + (long)cocoaModifiersAsCarbonModifiers: (long)cocoaModifiers; 17 | 18 | @end 19 | 20 | __attribute__((visibility("hidden"))) NSString* PTKeyBroadcasterKeyEvent; //keys: keyCombo as PTKeyCombo 21 | -------------------------------------------------------------------------------- /PTHotkey/PTKeyCodeTranslator.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTKeyCodeTranslator.h 3 | // Chercher 4 | // 5 | // Created by Finlay Dobbie on Sat Oct 11 2003. 6 | // Copyright (c) 2003 Cliché Software. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PTKeyCodeTranslator : NSObject 12 | { 13 | TISInputSourceRef keyboardLayout; 14 | const UCKeyboardLayout *uchrData; 15 | UInt32 keyTranslateState; 16 | UInt32 deadKeyState; 17 | } 18 | 19 | + (id)currentTranslator; 20 | 21 | - (id)initWithKeyboardLayout:(TISInputSourceRef)aLayout; 22 | - (NSString *)translateKeyCode:(short)keyCode; 23 | 24 | - (TISInputSourceRef)keyboardLayout; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /PTHotkey/PTKeyCodes.plist: -------------------------------------------------------------------------------- 1 | { 2 | 0 = "A"; 3 | 1 = "S"; 4 | 2 = "D"; 5 | 3 = "F"; 6 | 4 = "H"; 7 | 5 = "G"; 8 | 6 = "Z"; 9 | 7 = "X"; 10 | 8 = "C"; 11 | 9 = "V"; 12 | 10 = "$"; 13 | 11 = "B"; 14 | 12 = "Q"; 15 | 13 = "W"; 16 | 14 = "E"; 17 | 15 = "R"; 18 | 16 = "Y"; 19 | 17 = "T"; 20 | 18 = "1"; 21 | 19 = "2"; 22 | 20 = "3"; 23 | 21 = "4"; 24 | 22 = "6"; 25 | 23 = "5"; 26 | 24 = "="; 27 | 25 = "9"; 28 | 26 = "7"; 29 | 27 = "-"; 30 | 28 = "8"; 31 | 29 = "0"; 32 | 30 = "\]"; 33 | 31 = "O"; 34 | 32 = "U"; 35 | 33 = "\["; 36 | 34 = "I"; 37 | 35 = "P"; 38 | 36 = "Return"; 39 | 37 = "L"; 40 | 38 = "J"; 41 | 39 = "\'"; 42 | 40 = "K"; 43 | 41 = ";"; 44 | 42 = "\\"; 45 | 43 = ","; 46 | 44 = "\/"; 47 | 45 = "N"; 48 | 46 = "M"; 49 | 47 = "."; 50 | 48 = "Tab"; 51 | 49 = "Space"; 52 | 50 = "\`"; 53 | 51 = "Delete"; 54 | 53 = "ESC"; 55 | 55 = "Command"; 56 | 56 = "Shift"; 57 | 57 = "Caps Lock"; 58 | 58 = "Option"; 59 | 59 = "Control"; 60 | 65 = "Pad ."; 61 | 67 = "Pad *"; 62 | 69 = "Pad +"; 63 | 71 = "Clear"; 64 | 75 = "Pad /"; 65 | 76 = "Pad Enter"; 66 | 78 = "Pad -"; 67 | 81 = "Pad ="; 68 | 82 = "Pad 0"; 69 | 83 = "Pad 1"; 70 | 84 = "Pad 2"; 71 | 85 = "Pad 3"; 72 | 86 = "Pad 4"; 73 | 87 = "Pad 5"; 74 | 88 = "Pad 6"; 75 | 89 = "Pad 7"; 76 | 91 = "Pad 8"; 77 | 92 = "Pad 9"; 78 | 96 = "F5"; 79 | 97 = "F6"; 80 | 98 = "F7"; 81 | 99 = "F3"; 82 | 100 = "F8"; 83 | 101 = "F9"; 84 | 103 = "F11"; 85 | 105 = "F13"; 86 | 107 = "F14"; 87 | 109 = "F10"; 88 | 111 = "F12"; 89 | 113 = "F15"; 90 | 114 = "Ins"; 91 | 115 = "Home"; 92 | 116 = "Page Up"; 93 | 117 = "Del"; 94 | 118 = "F4"; 95 | 119 = "End"; 96 | 120 = "F2"; 97 | 121 = "Page Down"; 98 | 122 = "F1"; 99 | 123 = "Left Arrow"; 100 | 124 = "Right Arrow"; 101 | 125 = "Down Arrow"; 102 | 126 = "Up Arrow"; 103 | } -------------------------------------------------------------------------------- /PTHotkey/PTKeyCombo.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTKeyCombo.h 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface PTKeyCombo : NSObject 13 | { 14 | int mKeyCode; 15 | int mModifiers; 16 | } 17 | 18 | + (id)clearKeyCombo; 19 | + (id)keyComboWithKeyCode: (int)keyCode modifiers: (int)modifiers; 20 | - (id)initWithKeyCode: (int)keyCode modifiers: (int)modifiers; 21 | 22 | - (id)initWithPlistRepresentation: (id)plist; 23 | - (id)plistRepresentation; 24 | 25 | - (BOOL)isEqual: (PTKeyCombo*)combo; 26 | 27 | - (int)keyCode; 28 | - (int)modifiers; 29 | 30 | - (BOOL)isClearCombo; 31 | - (BOOL)isValidHotKeyCombo; 32 | 33 | @end 34 | 35 | @interface PTKeyCombo (UserDisplayAdditions) 36 | 37 | - (NSString*)description; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /PTHotkey/PTKeyComboPanel.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTKeyComboPanel.h 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sun Aug 03 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class PTKeyBroadcaster; 12 | @class PTKeyCombo; 13 | @class PTHotKey; 14 | 15 | @class PTKeyComboPanel; 16 | 17 | @protocol PTKeyComboPanelDelegate 18 | - (void)keyComboPanelEnded:(PTKeyComboPanel*)panel; 19 | @end 20 | 21 | @interface PTKeyComboPanel : NSWindowController 22 | { 23 | IBOutlet NSTextField* mTitleField; 24 | IBOutlet NSTextField* mComboField; 25 | IBOutlet PTKeyBroadcaster* mKeyBcaster; 26 | 27 | id currentModalDelegate; 28 | 29 | NSString* mTitleFormat; 30 | NSString* mKeyName; 31 | PTKeyCombo* mKeyCombo; 32 | } 33 | 34 | + (id)sharedPanel; 35 | 36 | - (void)showSheetForHotkey:(PTHotKey*)hotKey forWindow:(NSWindow*)mainWindow modalDelegate:(id)target; 37 | 38 | - (void)runModalForHotKey: (PTHotKey*)hotKey; 39 | 40 | - (void)setKeyCombo: (PTKeyCombo*)combo; 41 | - (PTKeyCombo*)keyCombo; 42 | 43 | - (void)setKeyBindingName: (NSString*)name; 44 | - (NSString*)keyBindingName; 45 | 46 | - (IBAction)ok: (id)sender; 47 | - (IBAction)cancel: (id)sender; 48 | - (IBAction)clear: (id)sender; 49 | @end 50 | 51 | 52 | -------------------------------------------------------------------------------- /PTHotkey/libPTHotkey-OSX.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/PTHotkey/libPTHotkey-OSX.a -------------------------------------------------------------------------------- /QuickRadar.xcodeproj/project.xcworkspace/xcshareddata/QuickRadar.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "C7F0E23F728CABFEF59E7EB1D1EC9757E1DE9BAF", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "C7F0E23F728CABFEF59E7EB1D1EC9757E1DE9BAF" : 0, 8 | "422C0041F817004E349B37831E7CB20A8ACE8A07" : 0 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "1258499B-E9EB-4624-9ED3-52ED8A4EB7A5", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "C7F0E23F728CABFEF59E7EB1D1EC9757E1DE9BAF" : "QuickRadar", 13 | "422C0041F817004E349B37831E7CB20A8ACE8A07" : "QuickRadarExternals\/DTXMLRPC" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "QuickRadar", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "QuickRadar.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/Cocoanetics\/DTXMLRPC.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "422C0041F817004E349B37831E7CB20A8ACE8A07" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:chockenberry\/QuickRadar.git", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "C7F0E23F728CABFEF59E7EB1D1EC9757E1DE9BAF" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /QuickRadar/ADNLogoTemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/QuickRadar/ADNLogoTemplate.png -------------------------------------------------------------------------------- /QuickRadar/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 15/05/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | #define GlobalHotkeyName @"hotkey" 13 | 14 | @class QRRadar; 15 | 16 | @interface AppDelegate : NSObject 17 | 18 | @property (assign) IBOutlet NSMenu *menu; 19 | 20 | - (IBAction)showPreferencesWindow:(id)sender; 21 | - (IBAction)showDuplicateWindow:(id)sender; 22 | 23 | - (IBAction)newBug:(id)sender; 24 | - (IBAction)bugWindowControllerSubmissionComplete:(id)sender; 25 | - (IBAction)activateAndShowAbout:(id)sender; 26 | - (void)newBugWithRadar:(QRRadar*)radar; 27 | 28 | - (IBAction)goToAppleRadar:(id)sender; 29 | - (IBAction)goToOpenRadar:(id)sender; 30 | 31 | - (void)hitHotKey:(id)sender; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /QuickRadar/AppIconSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/QuickRadar/AppIconSmall.png -------------------------------------------------------------------------------- /QuickRadar/Appicon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/QuickRadar/Appicon.icns -------------------------------------------------------------------------------- /QuickRadar/AppleLogoTemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/QuickRadar/AppleLogoTemplate.png -------------------------------------------------------------------------------- /QuickRadar/Config.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | classifications 6 | 7 | 8 | code 9 | 1 10 | name 11 | Security 12 | 13 | 14 | code 15 | 2 16 | name 17 | Crash/Hang/Data Loss 18 | 19 | 20 | code 21 | 3 22 | name 23 | Power 24 | 25 | 26 | code 27 | 4 28 | name 29 | Performance 30 | 31 | 32 | code 33 | 5 34 | name 35 | UI/Usability 36 | 37 | 38 | code 39 | 7 40 | name 41 | Serious Bug 42 | 43 | 44 | code 45 | 8 46 | name 47 | Other Bug 48 | 49 | 50 | code 51 | 10 52 | name 53 | Feature (New) 54 | 55 | 56 | code 57 | 11 58 | name 59 | Enhancement 60 | 61 | 62 | reproducible 63 | 64 | 65 | code 66 | 1 67 | name 68 | Always 69 | 70 | 71 | code 72 | 2 73 | name 74 | Sometimes 75 | 76 | 77 | code 78 | 3 79 | name 80 | Rarely 81 | 82 | 83 | code 84 | 4 85 | name 86 | Unable 87 | 88 | 89 | code 90 | 5 91 | name 92 | I Didn't Try 93 | 94 | 95 | code 96 | 6 97 | name 98 | Not Applicable 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /QuickRadar/Config/Readme.md: -------------------------------------------------------------------------------- 1 | Config Folder 2 | ------------- 3 | 4 | Some services, such as app.net and Twitter, require an API key per app. These keys aren't meant to be distributed, so the open source version of QuickRadar doesn't include them. If you're compiling QuickRadar from source, you can of course register your own API keys with the appropriate services. The required files are listed below. 5 | 6 | 7 | app.net 8 | ------- 9 | 10 | A file called `AppDotNetConfig.plist`, containing two keys, `clientID` (which should be set to the client ID you register with app.net) and `redirectURI`. The latter should be: quickradar://appdotnetauth 11 | 12 | 13 | Twitter 14 | ------- -------------------------------------------------------------------------------- /QuickRadar/DDOpenAtLoginController.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created 2013 Dominik Pich 3 | // Some rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @interface DDOpenAtLoginController : NSObject 9 | 10 | @property (nonatomic, assign) NSNumber *appStartsAtLogin; //bool for binding 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /QuickRadar/DDOpenAtLoginController.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created 2013 Dominik Pich 3 | // Some rights reserved. 4 | // 5 | 6 | #import "DDOpenAtLoginController.h" 7 | #import 8 | 9 | @implementation DDOpenAtLoginController { 10 | LSSharedFileListRef _sharedFileList; 11 | } 12 | 13 | NSArray* SDSharedFileArray(LSSharedFileListRef list); 14 | void SDAppDelegateSharedFileListObservance(LSSharedFileListRef inList, void *context); 15 | 16 | - (void)setAppStartsAtLogin:(NSNumber *)numberForAppStartsAtLogin { 17 | [self willChangeValueForKey:@"appStartsAtLogin"]; 18 | BOOL appStartsAtLogin = numberForAppStartsAtLogin.boolValue; 19 | 20 | if (appStartsAtLogin) { 21 | NSString *appPath = [[NSBundle mainBundle] bundlePath]; 22 | CFURLRef appURL = (__bridge CFURLRef)[NSURL fileURLWithPath:appPath]; 23 | LSSharedFileListItemRef result = LSSharedFileListInsertItemURL(self.sharedFileList, kLSSharedFileListItemLast, NULL, NULL, appURL, NULL, NULL); 24 | CFRelease(result); 25 | } 26 | else { 27 | NSArray *array = SDSharedFileArray(self.sharedFileList); 28 | NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; 29 | for (id item in array) { 30 | LSSharedFileListItemRef fileItem = (__bridge LSSharedFileListItemRef)item; 31 | CFURLRef cfurl = NULL; 32 | 33 | if (LSSharedFileListItemResolve(fileItem, 0, &cfurl, NULL) == noErr) { 34 | NSURL *url = (__bridge_transfer NSURL*)cfurl; 35 | if ([url.path isEqualToString: bundlePath]) { 36 | LSSharedFileListItemRemove(self.sharedFileList, fileItem); 37 | } 38 | } 39 | } 40 | } 41 | [self didChangeValueForKey:@"appStartsAtLogin"]; 42 | } 43 | 44 | - (NSNumber*) appStartsAtLogin { 45 | BOOL appInLoginItems = NO; 46 | 47 | NSArray *array = SDSharedFileArray(self.sharedFileList); 48 | NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; 49 | for (id item in array) { 50 | LSSharedFileListItemRef listItem = (__bridge LSSharedFileListItemRef)item; 51 | CFURLRef cfurl = NULL; 52 | 53 | if (LSSharedFileListItemResolve(listItem, 0, &cfurl, NULL) == noErr) { 54 | NSURL *url = (__bridge_transfer NSURL*)cfurl; 55 | if ([url.path isEqualToString: bundlePath]) { 56 | appInLoginItems = YES; 57 | break; 58 | } 59 | } 60 | } 61 | 62 | return @(appInLoginItems); 63 | } 64 | 65 | - (LSSharedFileListRef) sharedFileList { 66 | if(!_sharedFileList) { 67 | _sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); 68 | LSSharedFileListAddObserver(_sharedFileList, CFRunLoopGetMain(), kCFRunLoopDefaultMode, SDAppDelegateSharedFileListObservance, (__bridge void*)self); 69 | } 70 | return _sharedFileList; 71 | } 72 | 73 | #pragma mark c 74 | 75 | NSArray* SDSharedFileArray(LSSharedFileListRef list) { 76 | UInt32 seed; 77 | return (__bridge_transfer NSArray*)LSSharedFileListCopySnapshot(list, &seed); 78 | } 79 | 80 | void SDAppDelegateSharedFileListObservance(LSSharedFileListRef inList, void *context) { 81 | DDOpenAtLoginController *controller = (__bridge DDOpenAtLoginController*)context; 82 | [controller willChangeValueForKey:@"appStartsAtLogin"]; 83 | [controller didChangeValueForKey:@"appStartsAtLogin"]; 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /QuickRadar/MenubarTemplate.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/QuickRadar/MenubarTemplate.tif -------------------------------------------------------------------------------- /QuickRadar/MenubarTemplate@2x.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/QuickRadar/MenubarTemplate@2x.tif -------------------------------------------------------------------------------- /QuickRadar/NSButton+QuickRadar.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSControl+QuickRadar.h 3 | // QuickRadar 4 | // 5 | // Created by Balázs Faludi on 18.08.12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface NSButton (QuickRadar) 12 | 13 | - (void)blink; 14 | - (void)blinkTwice; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /QuickRadar/NSButton+QuickRadar.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSControl+QuickRadar.m 3 | // QuickRadar 4 | // 5 | // Created by Balázs Faludi on 18.08.12. 6 | // 7 | // 8 | 9 | #import "NSButton+QuickRadar.h" 10 | 11 | @implementation NSButton (QuickRadar) 12 | 13 | - (void)turnOff { 14 | [self highlight:NO]; 15 | } 16 | 17 | - (void)turnOn { 18 | [self highlight:YES]; 19 | } 20 | 21 | - (void)blink { 22 | [self turnOn]; 23 | [self performSelector:@selector(turnOff) withObject:nil afterDelay:0.1]; 24 | } 25 | 26 | - (void)blinkTwice { 27 | [self turnOn]; 28 | [self performSelector:@selector(turnOff) withObject:nil afterDelay:0.1]; 29 | [self performSelector:@selector(turnOn) withObject:nil afterDelay:0.2]; 30 | [self performSelector:@selector(turnOff) withObject:nil afterDelay:0.3]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /QuickRadar/NSError+Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSError+Additions.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 03/07/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define QRErrorDomain @"QRErrorDomain" 12 | #define QRErrorCodeAuthenticationError 1 13 | 14 | @interface NSError (Additions) 15 | 16 | + (NSError*)authenticationErrorWithServiceIdentifier:(NSString*)serviceIdentifier underlyingError:(NSError*)error; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /QuickRadar/NSError+Additions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSError+Additions.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 03/07/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "NSError+Additions.h" 10 | #import "QRSubmissionService.h" 11 | 12 | @implementation NSError (Additions) 13 | 14 | + (NSError*)authenticationErrorWithServiceIdentifier:(NSString*)serviceIdentifier underlyingError:(NSError*)error; 15 | { 16 | 17 | NSDictionary *services = [QRSubmissionService services]; 18 | Class service = services[serviceIdentifier]; 19 | NSString *name = [service name]; 20 | 21 | NSString *message = [NSString stringWithFormat:@"The \"%@\" service reported an authentication failure. Are your credentials correct?", name]; 22 | NSString *title = @"Authentication failure"; 23 | 24 | if (!error) 25 | { 26 | error = [[NSError alloc] init]; 27 | } 28 | 29 | NSDictionary *userInfo = @{NSLocalizedRecoverySuggestionErrorKey: message, 30 | NSLocalizedDescriptionKey: title, 31 | NSUnderlyingErrorKey: error}; 32 | 33 | NSError *newError = [NSError errorWithDomain:QRErrorDomain code:QRErrorCodeAuthenticationError userInfo:userInfo]; 34 | return newError; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /QuickRadar/NSImage+ProportionalScaling.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSImage+ProportionalScaling.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 10/10/2014. 6 | // 7 | // 8 | 9 | // From http://theocacao.com/document.page/498 10 | 11 | #import 12 | 13 | @interface NSImage (ProportionalScaling) 14 | 15 | - (NSImage*)imageByScalingProportionallyToSize:(NSSize)targetSize; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /QuickRadar/NSImage+ProportionalScaling.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSImage+ProportionalScaling.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 10/10/2014. 6 | // 7 | // 8 | 9 | #import "NSImage+ProportionalScaling.h" 10 | 11 | @implementation NSImage (ProportionalScaling) 12 | 13 | - (NSImage*)imageByScalingProportionallyToSize:(NSSize)targetSize 14 | { 15 | NSImage* sourceImage = self; 16 | NSImage* newImage = nil; 17 | 18 | if ([sourceImage isValid]) 19 | { 20 | NSSize imageSize = [sourceImage size]; 21 | float width = imageSize.width; 22 | float height = imageSize.height; 23 | 24 | float targetWidth = targetSize.width; 25 | float targetHeight = targetSize.height; 26 | 27 | float scaleFactor = 0.0; 28 | float scaledWidth = targetWidth; 29 | float scaledHeight = targetHeight; 30 | 31 | NSPoint thumbnailPoint = NSZeroPoint; 32 | 33 | if ( NSEqualSizes( imageSize, targetSize ) == NO ) 34 | { 35 | 36 | float widthFactor = targetWidth / width; 37 | float heightFactor = targetHeight / height; 38 | 39 | if ( widthFactor < heightFactor ) 40 | scaleFactor = widthFactor; 41 | else 42 | scaleFactor = heightFactor; 43 | 44 | scaledWidth = width * scaleFactor; 45 | scaledHeight = height * scaleFactor; 46 | 47 | if ( widthFactor < heightFactor ) 48 | thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 49 | 50 | else if ( widthFactor > heightFactor ) 51 | thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; 52 | } 53 | 54 | newImage = [[NSImage alloc] initWithSize:targetSize]; 55 | 56 | [newImage lockFocus]; 57 | 58 | NSRect thumbnailRect; 59 | thumbnailRect.origin = thumbnailPoint; 60 | thumbnailRect.size.width = scaledWidth; 61 | thumbnailRect.size.height = scaledHeight; 62 | 63 | [sourceImage drawInRect: thumbnailRect 64 | fromRect: NSZeroRect 65 | operation: NSCompositeSourceOver 66 | fraction: 1.0]; 67 | 68 | [newImage unlockFocus]; 69 | 70 | } 71 | 72 | return newImage; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /QuickRadar/NSString+URLEncoding.h: -------------------------------------------------------------------------------- 1 | #import 2 | @interface NSString (URLEncoding) 3 | -(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding; 4 | -(NSString *)xmlEncode; 5 | -(NSString *)backslashQuotes; 6 | @end -------------------------------------------------------------------------------- /QuickRadar/NSString+URLEncoding.m: -------------------------------------------------------------------------------- 1 | #import "NSString+URLEncoding.h" 2 | @implementation NSString (URLEncoding) 3 | -(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding { 4 | return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, 5 | (CFStringRef)self, 6 | NULL, 7 | (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", 8 | CFStringConvertNSStringEncodingToEncoding(encoding))); 9 | } 10 | 11 | -(NSString *)xmlEncode; 12 | { 13 | return (NSString *)CFBridgingRelease(CFXMLCreateStringByEscapingEntities(NULL, (__bridge CFStringRef)self, NULL)); 14 | } 15 | 16 | -(NSString *)backslashQuotes; 17 | { 18 | NSString *ret = [self stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; 19 | ret = [self stringByReplacingOccurrencesOfString:@"\""withString:@"\\\""]; 20 | 21 | return ret; 22 | } 23 | 24 | @end -------------------------------------------------------------------------------- /QuickRadar/NSXMLNode+Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSXMLNode+Additions.h 3 | // Saisier 4 | // 5 | // Created by Amy Worrall on 09/05/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSXMLNode (Additions) 12 | 13 | - (NSXMLNode*)firstNodeForXPath:(NSString*)xpath; 14 | - (NSXMLElement*)firstElementForXPath:(NSString*)xpath; 15 | 16 | - (NSXMLNode*)firstNodeForXPath:(NSString*)xpath error:(NSError**)error; 17 | - (NSXMLElement*)firstElementForXPath:(NSString*)xpath error:(NSError**)error; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /QuickRadar/NSXMLNode+Additions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSXMLNode+Additions.m 3 | // Saisier 4 | // 5 | // Created by Amy Worrall on 09/05/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "NSXMLNode+Additions.h" 10 | 11 | @implementation NSXMLNode (Additions) 12 | 13 | - (NSXMLNode*)firstNodeForXPath:(NSString*)xpath; 14 | { 15 | NSError *error; 16 | 17 | NSArray *nodes = [self nodesForXPath:xpath error:&error]; 18 | 19 | if (!nodes || error) 20 | { 21 | return nil; 22 | } 23 | 24 | if (nodes.count == 0) 25 | { 26 | return nil; 27 | } 28 | 29 | return nodes[0]; 30 | } 31 | 32 | - (NSXMLElement*)firstElementForXPath:(NSString *)xpath 33 | { 34 | NSXMLNode *n = [self firstNodeForXPath:xpath]; 35 | 36 | if ([n isKindOfClass:[NSXMLElement class]]) 37 | { 38 | return (NSXMLElement*)n; 39 | } 40 | return nil; 41 | } 42 | 43 | 44 | - (NSXMLNode*)firstNodeForXPath:(NSString*)xpath error:(NSError **)retError; 45 | { 46 | NSError *error; 47 | 48 | NSArray *nodes = [self nodesForXPath:xpath error:&error]; 49 | 50 | if (!nodes || error) 51 | { 52 | *retError = error; 53 | return nil; 54 | } 55 | 56 | if (nodes.count == 0) 57 | { 58 | return nil; 59 | } 60 | 61 | return nodes[0]; 62 | } 63 | 64 | - (NSXMLElement*)firstElementForXPath:(NSString *)xpath error:(NSError **)retError 65 | { 66 | NSError *error = nil; 67 | NSXMLNode *n = [self firstNodeForXPath:xpath error:&error]; 68 | 69 | if (error) 70 | { 71 | *retError = error; 72 | return nil; 73 | } 74 | 75 | if ([n isKindOfClass:[NSXMLElement class]]) 76 | { 77 | return (NSXMLElement*)n; 78 | } 79 | NSLog(@"It's a %@", NSStringFromClass([n class])); 80 | return nil; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /QuickRadar/OpenRadarTemplate.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/QuickRadar/OpenRadarTemplate.tif -------------------------------------------------------------------------------- /QuickRadar/OrderedDictionary.h: -------------------------------------------------------------------------------- 1 | // 2 | // OrderedDictionary.h 3 | // OrderedDictionary 4 | // 5 | // Created by Matt Gallagher on 19/12/08. 6 | // Copyright 2008 Matt Gallagher. All rights reserved. 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. Permission is granted to anyone to 11 | // use this software for any purpose, including commercial applications, and to 12 | // alter it and redistribute it freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would be 17 | // appreciated but is not required. 18 | // 2. Altered source versions must be plainly marked as such, and must not be 19 | // misrepresented as being the original software. 20 | // 3. This notice may not be removed or altered from any source 21 | // distribution. 22 | // 23 | 24 | #import 25 | 26 | @interface OrderedDictionary : NSMutableDictionary 27 | { 28 | NSMutableDictionary *dictionary; 29 | NSMutableArray *array; 30 | } 31 | 32 | - (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex; 33 | - (id)keyAtIndex:(NSUInteger)anIndex; 34 | - (NSEnumerator *)reverseKeyEnumerator; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /QuickRadar/OrderedDictionary.m: -------------------------------------------------------------------------------- 1 | // 2 | // OrderedDictionary.m 3 | // OrderedDictionary 4 | // 5 | // Created by Matt Gallagher on 19/12/08. 6 | // Copyright 2008 Matt Gallagher. All rights reserved. 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. Permission is granted to anyone to 11 | // use this software for any purpose, including commercial applications, and to 12 | // alter it and redistribute it freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would be 17 | // appreciated but is not required. 18 | // 2. Altered source versions must be plainly marked as such, and must not be 19 | // misrepresented as being the original software. 20 | // 3. This notice may not be removed or altered from any source 21 | // distribution. 22 | // 23 | 24 | #import "OrderedDictionary.h" 25 | 26 | NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent) 27 | { 28 | NSString *objectString; 29 | if ([object isKindOfClass:[NSString class]]) 30 | { 31 | objectString = (NSString *)[[object retain] autorelease]; 32 | } 33 | else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)]) 34 | { 35 | objectString = [(NSDictionary *)object descriptionWithLocale:locale indent:indent]; 36 | } 37 | else if ([object respondsToSelector:@selector(descriptionWithLocale:)]) 38 | { 39 | objectString = [(NSSet *)object descriptionWithLocale:locale]; 40 | } 41 | else 42 | { 43 | objectString = [object description]; 44 | } 45 | return objectString; 46 | } 47 | 48 | @implementation OrderedDictionary 49 | 50 | - (id)init 51 | { 52 | return [self initWithCapacity:0]; 53 | } 54 | 55 | - (id)initWithCapacity:(NSUInteger)capacity 56 | { 57 | self = [super init]; 58 | if (self != nil) 59 | { 60 | dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity]; 61 | array = [[NSMutableArray alloc] initWithCapacity:capacity]; 62 | } 63 | return self; 64 | } 65 | 66 | - (void)dealloc 67 | { 68 | [dictionary release]; 69 | [array release]; 70 | [super dealloc]; 71 | } 72 | 73 | - (id)copy 74 | { 75 | return [self mutableCopy]; 76 | } 77 | 78 | - (void)setObject:(id)anObject forKey:(id)aKey 79 | { 80 | if (![dictionary objectForKey:aKey]) 81 | { 82 | [array addObject:aKey]; 83 | } 84 | [dictionary setObject:anObject forKey:aKey]; 85 | } 86 | 87 | - (void)removeObjectForKey:(id)aKey 88 | { 89 | [dictionary removeObjectForKey:aKey]; 90 | [array removeObject:aKey]; 91 | } 92 | 93 | - (NSUInteger)count 94 | { 95 | return [dictionary count]; 96 | } 97 | 98 | - (id)objectForKey:(id)aKey 99 | { 100 | return [dictionary objectForKey:aKey]; 101 | } 102 | 103 | - (NSEnumerator *)keyEnumerator 104 | { 105 | return [array objectEnumerator]; 106 | } 107 | 108 | - (NSEnumerator *)reverseKeyEnumerator 109 | { 110 | return [array reverseObjectEnumerator]; 111 | } 112 | 113 | - (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex 114 | { 115 | if ([dictionary objectForKey:aKey]) 116 | { 117 | [self removeObjectForKey:aKey]; 118 | } 119 | [array insertObject:aKey atIndex:anIndex]; 120 | [dictionary setObject:anObject forKey:aKey]; 121 | } 122 | 123 | - (id)keyAtIndex:(NSUInteger)anIndex 124 | { 125 | return [array objectAtIndex:anIndex]; 126 | } 127 | 128 | - (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level 129 | { 130 | NSMutableString *indentString = [NSMutableString string]; 131 | NSUInteger i, count = level; 132 | for (i = 0; i < count; i++) 133 | { 134 | [indentString appendFormat:@" "]; 135 | } 136 | 137 | NSMutableString *description = [NSMutableString string]; 138 | [description appendFormat:@"%@{\n", indentString]; 139 | for (NSObject *key in self) 140 | { 141 | [description appendFormat:@"%@ %@ = %@;\n", 142 | indentString, 143 | DescriptionForObject(key, locale, level), 144 | DescriptionForObject([self objectForKey:key], locale, level)]; 145 | } 146 | [description appendFormat:@"%@}\n", indentString]; 147 | return description; 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /QuickRadar/PasswordStoring.h: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordStoring.h 3 | // QuickRadar 4 | // 5 | // Created by Graham Lee on 14/06/2012. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface PasswordStoring : NSObject 12 | 13 | @property (weak, nonatomic) IBOutlet NSSecureTextField *radarPasswordField; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /QuickRadar/ProductCategories.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Accessibility 6 | 7 | com.apple.VoiceOverUtility 8 | 9 | Developer Tools 10 | 11 | com.apple.dt 12 | com.apple.iphonesimulator 13 | com.apple.itunes.connect 14 | com.apple.ScriptEditor 15 | com.apple.FileMerge 16 | com.apple.AccessibilityInspector 17 | com.apple.PrinterSimulator 18 | 19 | Documentation 20 | 21 | com.apple.helpviewer 22 | 23 | Hardware 24 | 25 | com.apple.SystemProfiler 26 | 27 | Java 28 | 29 | com.apple.Java 30 | com.apple.Jar 31 | 32 | OS X App Store 33 | 34 | com.apple.appstore 35 | 36 | OS X 37 | 38 | com.apple.finder 39 | com.apple.dock 40 | com.apple.Terminal 41 | com.apple.keychainaccess 42 | com.apple.RAIDUtility 43 | com.apple.NetworkUtility 44 | com.apple.MigrateAssistant 45 | com.apple.Console 46 | com.apple.DiskUtility 47 | com.apple.grapher 48 | com.apple.DigitalColorMeter 49 | com.apple.ColorSyncUtility 50 | com.apple.bootcampassistant 51 | com.apple.BluetoothFileExchange 52 | com.apple.Grab 53 | com.apple.audio.AudioMIDISetup 54 | com.apple.ActivityMonitor 55 | com.apple.airport.airportutility 56 | com.apple.Preview 57 | com.apple.TextEdit 58 | com.apple.systempreferences 59 | com.apple.FontBook 60 | com.apple.Chess 61 | com.apple.calculator 62 | com.apple.PhotoBooth 63 | com.apple.Stickies 64 | com.apple.Notes 65 | com.apple.iChat 66 | com.apple.Dictionary 67 | com.apple.AddressBook 68 | com.apple.iCal 69 | com.apple.gamecenter 70 | com.apple.FaceTime 71 | com.apple.reminders 72 | com.apple.DVDPlayer 73 | com.apple.Image_Capture 74 | com.apple.Automator 75 | com.apple.installer 76 | com.apple.PackageKit 77 | com.apple.NetworkSetupAssistant 78 | com.apple.NetworkDiagnostics 79 | com.apple.ProblemReporter 80 | com.apple.SoftwareUpdate 81 | com.apple.SetupAssistant 82 | 83 | Mail 84 | 85 | com.apple.mail 86 | 87 | QuickTime 88 | 89 | com.apple.QuickTime 90 | 91 | Safari 92 | 93 | com.apple.Safari 94 | 95 | iAd Producer 96 | 97 | com.apple.iAdProducer 98 | 99 | iLife 100 | 101 | com.apple.iLife 102 | com.apple.iPhoto 103 | com.apple.iMovie 104 | com.apple.garageband 105 | 106 | iTunes 107 | 108 | com.apple.iTunes 109 | 110 | iWork 111 | 112 | com.apple.iWork 113 | com.apple.Pages 114 | com.apple.Numbers 115 | com.apple.Keynote 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /QuickRadar/QRAppDotNetSubmissionService.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppDotNetSubmissionService.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 22/08/2012. 6 | // 7 | // 8 | 9 | #import "QRSubmissionService.h" 10 | 11 | @interface QRAppDotNetSubmissionService : QRSubmissionService 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /QuickRadar/QRAppDotNetSubmissionService.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppDotNetSubmissionService.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 22/08/2012. 6 | // 7 | // 8 | 9 | #import "QRAppDotNetSubmissionService.h" 10 | #import "QRURLConnection.h" 11 | #import "QRUserDefaultsKeys.h" 12 | 13 | @interface QRAppDotNetSubmissionService () 14 | 15 | @property (atomic, assign) CGFloat progressValue; 16 | @property (atomic, assign) SubmissionStatus submissionStatusValue; 17 | 18 | @end 19 | 20 | @implementation QRAppDotNetSubmissionService 21 | 22 | 23 | 24 | + (void)load 25 | { 26 | [QRSubmissionService registerService:self]; 27 | } 28 | 29 | + (NSString *)identifier 30 | { 31 | return @"QRAppDotNetSubmissionServiceIdentifier"; 32 | } 33 | 34 | + (NSString *)name 35 | { 36 | return @"AppDotNet"; 37 | } 38 | 39 | + (NSString*)checkBoxString 40 | { 41 | return @"Send to App.net"; 42 | } 43 | 44 | + (BOOL)isAvailable 45 | { 46 | NSString *apiKey = [[NSUserDefaults standardUserDefaults] stringForKey:@"appDotNetUserToken"]; 47 | 48 | if (apiKey.length > 0) 49 | { 50 | return YES; 51 | } 52 | return NO; 53 | } 54 | 55 | + (BOOL)supportedOnMac; 56 | { 57 | return YES; 58 | } 59 | 60 | + (BOOL)supportedOniOS; 61 | { 62 | return NO; 63 | } 64 | 65 | + (NSString*)macSettingsViewControllerClassName; 66 | { 67 | return @"QRAppDotNetSubmissionServicePreferencesViewController"; 68 | } 69 | 70 | + (NSString*)iosSettingsViewControllerClassName; 71 | { 72 | return nil; 73 | } 74 | 75 | + (id)settingsIconPlatformAppropriateImage; 76 | { 77 | if (NSClassFromString(@"NSImage")) 78 | { 79 | return [NSImage imageNamed:@"ADNLogoTemplate"]; 80 | } 81 | return nil; 82 | } 83 | 84 | - (CGFloat)progress 85 | { 86 | return self.progressValue; 87 | } 88 | 89 | - (SubmissionStatus)submissionStatus 90 | { 91 | return self.submissionStatusValue; 92 | } 93 | 94 | 95 | +(NSSet *)hardDependencies 96 | { 97 | return [NSSet setWithObject:QRRadarSubmissionServiceIdentifier]; 98 | } 99 | 100 | +(NSSet *)softDependencies 101 | { 102 | return [NSSet setWithObject:QROpenRadarSubmissionServiceIdentifier]; 103 | } 104 | 105 | - (void)submitAsyncWithProgressBlock:(void (^)())progressBlock completionBlock:(void (^)(BOOL, NSError *))completionBlock 106 | { 107 | BOOL postRdarURLs = [[NSUserDefaults standardUserDefaults] boolForKey:QRAppDotNetIncludeRdarLinksKey]; 108 | 109 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 110 | self.submissionStatusValue = submissionStatusInProgress; 111 | 112 | NSError *error = nil; 113 | 114 | NSString *apiKey = [[NSUserDefaults standardUserDefaults] stringForKey:@"appDotNetUserToken"]; 115 | 116 | if (apiKey.length == 0 || self.radar.radarNumber == 0) 117 | { 118 | dispatch_sync(dispatch_get_main_queue(), ^{ 119 | self.submissionStatusValue = submissionStatusFailed; 120 | completionBlock(NO, error); 121 | }); 122 | return; 123 | } 124 | 125 | 126 | NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://alpha-api.app.net/stream/0/posts"]]; 127 | [req addValue:[NSString stringWithFormat:@"Bearer %@", apiKey] forHTTPHeaderField:@"Authorization"]; 128 | req.HTTPMethod = @"POST"; 129 | 130 | NSString *radarLink; 131 | if (self.radar.submittedToOpenRadar) 132 | { 133 | radarLink = [NSString stringWithFormat:@"http://openradar.me/%ld", self.radar.radarNumber]; 134 | } 135 | else 136 | { 137 | radarLink = [NSString stringWithFormat:@"rdar://problem/%ld", self.radar.radarNumber]; 138 | } 139 | 140 | NSString *afterwards = @""; 141 | if (self.radar.submittedToOpenRadar && postRdarURLs) 142 | { 143 | afterwards = [NSString stringWithFormat:@" (rdar://problem/%ld)", self.radar.radarNumber]; 144 | } 145 | 146 | NSString *post = [NSString stringWithFormat:@"%@%@", self.radar.title, afterwards]; 147 | 148 | 149 | NSDictionary *entitiesDict = @{ 150 | @"links" : @[ 151 | @{ 152 | @"pos": @0, 153 | @"len": @(self.radar.title.length), 154 | @"url": radarLink 155 | } 156 | ], 157 | @"parse_links" : @(YES) 158 | }; 159 | 160 | NSDictionary *postParams = 161 | @{ @"text" : post, 162 | @"entities" : entitiesDict 163 | }; 164 | NSLog(@"Sending %@", postParams); 165 | 166 | QRURLConnection *conn = [[QRURLConnection alloc] init]; 167 | conn.request = req; 168 | conn.postParameters = postParams; 169 | conn.sendPostParamsAsJSON = YES; 170 | 171 | NSData *data = [conn fetchSyncWithError:&error]; 172 | 173 | NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 174 | NSLog(@"Result: %@ %@", result, error); 175 | 176 | self.progressValue = 1.0; 177 | self.submissionStatusValue = submissionStatusCompleted; 178 | 179 | dispatch_sync(dispatch_get_main_queue(), ^{ 180 | progressBlock(); 181 | completionBlock(YES, nil); 182 | }); 183 | 184 | 185 | }); 186 | } 187 | 188 | @end 189 | -------------------------------------------------------------------------------- /QuickRadar/QRAppDotNetSubmissionServicePreferencesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppDotNetSubmissionServicePreferencesViewController.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 22/08/2012. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface QRAppDotNetSubmissionServicePreferencesViewController : NSViewController 12 | 13 | - (IBAction)authorise:(id)sender; 14 | - (IBAction)obtainAccount:(id)sender; 15 | 16 | @property (strong) IBOutlet NSButton *authButton; 17 | @property (strong) IBOutlet NSTextField *statusLabel; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /QuickRadar/QRAppDotNetSubmissionServicePreferencesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppDotNetSubmissionServicePreferencesViewController.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 22/08/2012. 6 | // 7 | // 8 | 9 | #import "QRAppDotNetSubmissionServicePreferencesViewController.h" 10 | 11 | #define appDotNetUserTokenKey @"appDotNetUserToken" 12 | 13 | @interface QRAppDotNetSubmissionServicePreferencesViewController () 14 | 15 | @end 16 | 17 | @implementation QRAppDotNetSubmissionServicePreferencesViewController 18 | 19 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 20 | { 21 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 22 | if (self) { 23 | // Initialization code here. 24 | 25 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateStatusString) name:@"AppDotNetAuthChangedNotification" object:nil]; 26 | } 27 | 28 | return self; 29 | } 30 | 31 | - (void)loadView 32 | { 33 | [super loadView]; 34 | [self updateStatusString]; 35 | } 36 | 37 | - (void)authorise:(id)sender 38 | { 39 | NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; 40 | 41 | NSString *token = [prefs objectForKey:appDotNetUserTokenKey]; 42 | 43 | if (token.length==0) 44 | { 45 | // need to authorise 46 | NSDictionary *config = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"AppDotNetConfig" ofType:@"plist" inDirectory:@"Config"]]; 47 | 48 | if (!config) 49 | { 50 | NSRunAlertPanel(@"Config not available", @"App.net config file not found. If you compiled QuickRadar from source, see the file QuickRadar/Config/Readme.md for how to create this file.", @"OK", nil, nil); 51 | NSLog(@"App.net config file not found. If you compiled QuickRadar from source, see the file QuickRadar/Config/Readme.md for how to create this file."); 52 | return; 53 | } 54 | 55 | NSString *clientID = config[@"clientID"]; 56 | NSString *requestURI = [config[@"redirectURI"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 57 | 58 | NSString *stringURL = [NSString stringWithFormat:@"https://alpha.app.net/oauth/authenticate?client_id=%@&response_type=token&redirect_uri=%@&scope=write_post", clientID, requestURI]; 59 | 60 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:stringURL]]; 61 | } 62 | else 63 | { 64 | // need to deauthorise 65 | [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"appDotNetUserToken"]; 66 | } 67 | 68 | [self updateStatusString]; 69 | } 70 | 71 | - (void)updateStatusString 72 | { 73 | NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; 74 | NSString *token = [prefs objectForKey:appDotNetUserTokenKey]; 75 | 76 | if (token.length==0) 77 | { 78 | [self.statusLabel setStringValue:@"Not Connected"]; 79 | [self.authButton setTitle:@"Authorise with App.net"]; 80 | } 81 | else 82 | { 83 | [self.statusLabel setStringValue:@"Connected"]; 84 | [self.authButton setTitle:@"Disconnect"]; 85 | } 86 | 87 | } 88 | 89 | - (IBAction)obtainAccount:(id)sender 90 | { 91 | NSString *stringURL = @"http://join.app.net"; 92 | NSURL *url = [NSURL URLWithString:stringURL]; 93 | [[NSWorkspace sharedWorkspace] openURL:url]; 94 | 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /QuickRadar/QRAppListManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppListManager.h 3 | // RunningApps 4 | // 5 | // Created by Balázs Faludi on 16.08.12. 6 | // Copyright (c) 2012 Balázs Faludi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define kQRAppListUpdatesNotification @"QRAppListUpdatedFirstApp" 12 | #define kQRAppListNotificationAppKey @"QRAppListNotificationAppKey" 13 | #define kQRAppListNotificationOldIndexKey @"QRAppListNotificationOldIndexKey" 14 | 15 | @interface QRAppListManager : NSObject 16 | 17 | @property (nonatomic, readonly) NSArray *appList; 18 | @property (nonatomic, readonly) NSDictionary *categories; 19 | 20 | + (QRAppListManager *)sharedManager; 21 | 22 | - (NSString *)cacheFolder; 23 | - (void)saveList; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /QuickRadar/QRAppListOutlineView.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppListOutlineView.h 3 | // QuickRadar 4 | // 5 | // Created by Nicholas Riley on 3/31/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface QRAppListOutlineView : NSOutlineView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /QuickRadar/QRAppListOutlineView.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppListOutlineView.m 3 | // QuickRadar 4 | // 5 | // Created by Nicholas Riley on 3/31/13. 6 | // 7 | // 8 | 9 | #import "QRAppListOutlineView.h" 10 | 11 | @implementation QRAppListOutlineView 12 | 13 | - (BOOL)performKeyEquivalent:(NSEvent *)theEvent; 14 | { 15 | if ([[theEvent charactersIgnoringModifiers] isEqualToString:@"\r"]) { 16 | [NSApp sendAction:[self action] to:[self target] from:self]; 17 | return YES; 18 | } 19 | 20 | return [super performKeyEquivalent:theEvent]; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /QuickRadar/QRAppListPopover.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppListPopover.h 3 | // RunningApps 4 | // 5 | // Created by Balázs Faludi on 16.08.12. 6 | // Copyright (c) 2012 Balázs Faludi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class QRCachedRunningApplication; 12 | @protocol QRAppListPopoverDelegate; 13 | 14 | 15 | @interface QRAppListPopover : NSPopover 16 | 17 | @property (nonatomic, unsafe_unretained) IBOutlet NSObject *appListDelegate; 18 | 19 | @end 20 | 21 | 22 | @protocol QRAppListPopoverDelegate 23 | 24 | - (void)appListPopover:(QRAppListPopover *)popover selectedApp:(QRCachedRunningApplication *)app; 25 | 26 | @end -------------------------------------------------------------------------------- /QuickRadar/QRAppListPopover.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppListPopover.m 3 | // RunningApps 4 | // 5 | // Created by Balázs Faludi on 16.08.12. 6 | // Copyright (c) 2012 Balázs Faludi. All rights reserved. 7 | // 8 | 9 | #import "QRAppListPopover.h" 10 | #import "QRAppListViewController.h" 11 | #import "QRCachedRunningApplication.h" 12 | 13 | 14 | 15 | @implementation QRAppListPopover 16 | 17 | - (QRAppListViewController *) listViewController 18 | { 19 | return (QRAppListViewController *)self.contentViewController; 20 | } 21 | 22 | // When building with SDKs older than 10.10, we have to call viewWillAppear et. al. manually, 23 | // but on 10.10 and greater the view system will call it for us. Avoid calling it twice... 24 | #if MAC_OS_X_VERSION_10_9 <= MAC_OS_X_VERSION_MAX_ALLOWED 25 | - (void)popoverWillShow:(NSNotification *)notification { 26 | [[self listViewController] viewWillAppear]; 27 | } 28 | 29 | - (void)popoverDidShow:(NSNotification *)notification { 30 | [[self listViewController] viewDidAppear]; 31 | } 32 | 33 | - (void)popoverWillClose:(NSNotification *)notification { 34 | [[self listViewController] viewWillDisappear]; 35 | } 36 | 37 | - (void)popoverDidClose:(NSNotification *)notification { 38 | [[self listViewController] viewDidDisappear]; 39 | } 40 | #endif 41 | 42 | - (void)selectedApp:(QRCachedRunningApplication *)app { 43 | if ([self.appListDelegate respondsToSelector:@selector(appListPopover:selectedApp:)]) { 44 | [self.appListDelegate appListPopover:self selectedApp:app]; 45 | } 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /QuickRadar/QRAppListTableCellView.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppListTableCellView.h 3 | // RunningApps 4 | // 5 | // Created by Balázs Faludi on 18.08.12. 6 | // Copyright (c) 2012 Balázs Faludi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QRAppListTableCellView : NSTableCellView 12 | 13 | @property (nonatomic) NSString *appName; 14 | @property (nonatomic) NSString *appVersion; 15 | @property (nonatomic) NSImage *appIcon; 16 | @property (nonatomic) BOOL showsWarning; 17 | 18 | @end -------------------------------------------------------------------------------- /QuickRadar/QRAppListTableCellView.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppListTableCellView.m 3 | // RunningApps 4 | // 5 | // Created by Balázs Faludi on 18.08.12. 6 | // Copyright (c) 2012 Balázs Faludi. All rights reserved. 7 | // 8 | 9 | #import "QRAppListTableCellView.h" 10 | 11 | @interface QRAppListTableCellView () 12 | 13 | @property (nonatomic) IBOutlet NSTextField *appInfoField; 14 | @property (nonatomic) IBOutlet NSImageView *iconView; 15 | @property (nonatomic) IBOutlet NSImageView *warningView; 16 | 17 | @end 18 | 19 | @implementation QRAppListTableCellView 20 | 21 | - (void)updateText { 22 | // Put it in an attributed string. Version numbers will be gray (or light gray when selected) 23 | NSString *text = self.appName; 24 | if (!text) text = @"Unknown app"; 25 | if (self.appVersion) text = [text stringByAppendingFormat:@" %@", self.appVersion]; 26 | 27 | NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text]; 28 | 29 | NSRange nameRange = NSMakeRange(0, self.appName.length); 30 | NSRange versionRange = NSMakeRange(self.appName.length, text.length - self.appName.length); 31 | 32 | NSColor *nameColor = [NSColor blackColor]; 33 | NSColor *versionColor = [NSColor grayColor]; 34 | if (self.backgroundStyle == NSBackgroundStyleDark) { 35 | nameColor = [NSColor whiteColor]; 36 | versionColor = [NSColor colorWithCalibratedWhite:0.9f alpha:1.0f]; 37 | } 38 | 39 | [attributedString addAttribute:NSForegroundColorAttributeName value:nameColor range:nameRange]; 40 | [attributedString addAttribute:NSForegroundColorAttributeName value:versionColor range:versionRange]; 41 | self.appInfoField.attributedStringValue = attributedString; 42 | } 43 | 44 | - (void)setAppName:(NSString *)appName { 45 | _appName = appName; 46 | [self updateText]; 47 | } 48 | 49 | - (void)setAppVersion:(NSString *)appVersion { 50 | _appVersion = appVersion; 51 | [self updateText]; 52 | } 53 | 54 | - (void)setAppIcon:(NSImage *)appIcon { 55 | self.iconView.image = appIcon; 56 | } 57 | 58 | - (void)setShowsWarning:(BOOL)showsWarning { 59 | self.warningView.hidden = !showsWarning; 60 | } 61 | 62 | - (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle { 63 | [super setBackgroundStyle:backgroundStyle]; 64 | [self updateText]; 65 | } 66 | 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /QuickRadar/QRAppListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRAppListViewController.h 3 | // RunningApps 4 | // 5 | // Created by Balázs Faludi on 15.08.12. 6 | // Copyright (c) 2012 Balázs Faludi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class QRAppListPopover; 12 | 13 | @interface QRAppListViewController : NSViewController 14 | 15 | @property (nonatomic, weak) IBOutlet QRAppListPopover *popover; 16 | 17 | - (void)viewWillAppear; 18 | - (void)viewDidAppear; 19 | - (void)viewWillDisappear; 20 | - (void)viewDidDisappear; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /QuickRadar/QRCachedRunningApplication.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRCachedRunningApplication.h 3 | // RunningApps 4 | // 5 | // Created by Balázs Faludi on 16.08.12. 6 | // Copyright (c) 2012 Balázs Faludi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QRCachedRunningApplication : NSObject 12 | 13 | @property (nonatomic, readonly) NSString *unlocalizedName; 14 | @property (nonatomic, readonly) NSString *version; 15 | @property (nonatomic, readonly) NSString *build; 16 | @property (nonatomic, readonly) NSString *versionAndBuild; 17 | @property (nonatomic, readonly) NSImage *icon; 18 | 19 | - (id)initWithRunningApplication:(NSRunningApplication *)app; 20 | - (NSArray *)findCrashReports; 21 | - (BOOL)didCrashRecently; 22 | - (NSString *)guessCategory; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /QuickRadar/QRCopyToClipboardSubmissionService.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRCopyToClipboardSubmissionService.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 26/09/2012. 6 | // 7 | // 8 | 9 | #import "QRSubmissionService.h" 10 | 11 | @interface QRCopyToClipboardSubmissionService : QRSubmissionService 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /QuickRadar/QRCopyToClipboardSubmissionService.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRCopyToClipboardSubmissionService.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 26/09/2012. 6 | // 7 | // 8 | 9 | #import "QRCopyToClipboardSubmissionService.h" 10 | 11 | @interface QRCopyToClipboardSubmissionService () 12 | 13 | @property (assign) BOOL completed; 14 | 15 | @end 16 | 17 | @implementation QRCopyToClipboardSubmissionService 18 | 19 | + (void)load 20 | { 21 | [QRSubmissionService registerService:self]; 22 | } 23 | 24 | + (NSString *)identifier 25 | { 26 | return @"QRCopyToClipboardSubmissionService.h"; 27 | } 28 | 29 | + (NSString *)name 30 | { 31 | return @"Copy to Clipboard"; 32 | } 33 | 34 | + (NSString*)checkBoxString 35 | { 36 | return @"Copy radar number to clipboard"; 37 | } 38 | 39 | + (BOOL)isAvailable 40 | { 41 | return YES; 42 | } 43 | 44 | + (BOOL)supportedOnMac; 45 | { 46 | return YES; 47 | } 48 | 49 | + (BOOL)supportedOniOS; 50 | { 51 | return NO; 52 | } 53 | 54 | + (NSString*)macSettingsViewControllerClassName; 55 | { 56 | return nil; 57 | } 58 | 59 | + (NSString*)iosSettingsViewControllerClassName; 60 | { 61 | return nil; 62 | } 63 | 64 | +(NSSet *)hardDependencies 65 | { 66 | return [NSSet setWithObject:QRRadarSubmissionServiceIdentifier]; 67 | } 68 | 69 | +(NSSet *)softDependencies 70 | { 71 | return nil; 72 | } 73 | 74 | - (CGFloat)progress 75 | { 76 | return self.completed ? 1.0 : 0.0; 77 | } 78 | 79 | - (SubmissionStatus)submissionStatus 80 | { 81 | return (self.completed) ? submissionStatusCompleted : submissionStatusNotStarted; 82 | } 83 | 84 | - (void)submitAsyncWithProgressBlock:(void (^)())progressBlock completionBlock:(void (^)(BOOL, NSError *))completionBlock 85 | { 86 | NSString *radarNumString = [NSString stringWithFormat:@"%li", self.radar.radarNumber]; 87 | 88 | [[NSPasteboard generalPasteboard] clearContents]; 89 | [[NSPasteboard generalPasteboard] writeObjects:@[radarNumString]]; 90 | 91 | self.completed = YES; 92 | 93 | completionBlock(YES, nil); 94 | } 95 | 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /QuickRadar/QRFileDuplicateWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRFileDuplicateWindowController.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 19/02/2013. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface QRFileDuplicateWindowController : NSWindowController 12 | 13 | - (IBAction)OK:(id)sender; 14 | - (IBAction)cancel:(id)sender; 15 | 16 | @property (nonatomic, strong) IBOutlet NSTextField *textField; 17 | @property (nonatomic, strong) IBOutlet NSProgressIndicator *spinner; 18 | 19 | @property (nonatomic, strong) IBOutlet NSButton *cancelButton; 20 | @property (nonatomic, strong) IBOutlet NSButton *okButton; 21 | 22 | - (void)setRadarNumber:(NSString*)number; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /QuickRadar/QRFileDuplicateWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRFileDuplicateWindowController.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 19/02/2013. 6 | // 7 | // 8 | 9 | #import "QRFileDuplicateWindowController.h" 10 | #import "QRRadar.h" 11 | #import "QRUserDefaultsKeys.h" 12 | #import "AppDelegate.h" 13 | 14 | @interface QRFileDuplicateWindowController () 15 | 16 | @end 17 | 18 | @implementation QRFileDuplicateWindowController 19 | 20 | - (id)initWithWindow:(NSWindow *)window 21 | { 22 | self = [super initWithWindow:window]; 23 | if (self) { 24 | // Initialization code here. 25 | } 26 | 27 | return self; 28 | } 29 | 30 | - (void)windowDidLoad 31 | { 32 | [super windowDidLoad]; 33 | 34 | NSInteger windowLevel = [[NSUserDefaults standardUserDefaults] integerForKey:QRWindowLevelKey]; 35 | [self.window setLevel:windowLevel]; 36 | 37 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. 38 | } 39 | 40 | - (void)cancel:(id)sender 41 | { 42 | [self close]; 43 | } 44 | 45 | - (void)setRadarNumber:(NSString*)number; 46 | { 47 | self.textField.stringValue = number; 48 | } 49 | 50 | 51 | - (void)OK:(id)sender 52 | { 53 | if (self.textField.stringValue.length == 0) 54 | { 55 | return; 56 | } 57 | 58 | [self.spinner startAnimation:self]; 59 | [self.okButton setEnabled:NO]; 60 | 61 | NSString *radarNum = self.textField.stringValue; 62 | NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://openradar.appspot.com/api/radar?number=%@", radarNum]]]; 63 | NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 64 | 65 | [NSURLConnection sendAsynchronousRequest:req queue:queue completionHandler:^(NSURLResponse *r, NSData *d, NSError *e) { 66 | NSDictionary *mainDict = [NSJSONSerialization JSONObjectWithData:d options:0 error:nil]; 67 | NSDictionary *radarDict = mainDict[@"result"]; 68 | 69 | QRRadar *radar = [[QRRadar alloc] init]; 70 | radar.title = radarDict[@"title"]; 71 | radar.classification = radarDict[@"classification"]; 72 | radar.version = radarDict[@"product_version"]; 73 | radar.reproducible = radarDict[@"reproducible"]; 74 | radar.product = radarDict[@"product"]; 75 | radar.radarNumber = [radarNum integerValue]; 76 | 77 | NSString *body = radarDict[@"description"]; 78 | radar.body = [NSString stringWithFormat:@"This is a duplicate of rdar://%li\n\n%@", (long)radar.radarNumber, (body!=nil)?body:@""]; 79 | 80 | dispatch_async(dispatch_get_main_queue(), ^{ 81 | self.textField.stringValue = @""; 82 | [self.spinner stopAnimation:self]; 83 | [self.okButton setEnabled:YES]; 84 | [self close]; 85 | [(AppDelegate*)[NSApp delegate] newBugWithRadar:radar]; 86 | }); 87 | 88 | }]; 89 | 90 | } 91 | 92 | @end 93 | -------------------------------------------------------------------------------- /QuickRadar/QRFileWell.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRFileWell.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 10/10/2014. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface QRFileWell : NSControl 12 | 13 | @property (nonatomic, assign) NSCellImagePosition imagePosition; 14 | 15 | @property (nonatomic, copy) NSURL *URL; // The file currently represented by the control 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /QuickRadar/QRFileWell.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRFileWell.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 10/10/2014. 6 | // 7 | // 8 | 9 | #import "QRFileWell.h" 10 | #import "NSImage+ProportionalScaling.h" 11 | 12 | @interface QRFileWell () 13 | @property (nonatomic, assign) NSInteger cachedDragOperation; 14 | 15 | @property (nonatomic, assign) BOOL hovering; 16 | @end 17 | 18 | 19 | 20 | @implementation QRFileWell 21 | 22 | #pragma mark - Intitialisation 23 | 24 | - (id)initWithFrame:(NSRect)frameRect { 25 | if (self = [super initWithFrame:frameRect]) { 26 | [self setup]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)awakeFromNib { 32 | [self setup]; 33 | } 34 | 35 | - (void)setup { 36 | [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; 37 | } 38 | 39 | #pragma mark - Options 40 | 41 | - (void)setImagePosition:(NSCellImagePosition)imagePosition { 42 | _imagePosition = imagePosition; 43 | [self setNeedsDisplay:YES]; 44 | } 45 | 46 | #pragma mark - Drawing 47 | 48 | - (void)drawRect:(NSRect)dirtyRect { 49 | if (!self.URL) { 50 | [self drawEmptyState]; 51 | } else { 52 | [self drawFullState]; 53 | } 54 | } 55 | 56 | - (void)drawEmptyState 57 | { 58 | NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(self.bounds, 2, 2) xRadius:5 yRadius:5]; 59 | [path setLineWidth:3]; 60 | 61 | 62 | CGFloat array[2]; 63 | array[0] = 8.0; //segment painted with stroke color 64 | array[1] = 4.0; //segment not painted with a color 65 | 66 | [path setLineDash: array count: 2 phase: 1.0]; 67 | 68 | if (self.hovering) { 69 | [[NSColor lightGrayColor] set]; 70 | [path fill]; 71 | } 72 | 73 | [[NSColor grayColor] set]; 74 | [path stroke]; 75 | 76 | NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 77 | [style setAlignment:NSCenterTextAlignment]; 78 | NSDictionary *attributes = @{NSParagraphStyleAttributeName : style, 79 | NSForegroundColorAttributeName : [NSColor grayColor], 80 | NSFontAttributeName : [NSFont boldSystemFontOfSize:13.0]}; 81 | 82 | NSString *message = @"Choose a file to attach"; 83 | [self drawString:message verticallyCentredInRect:self.bounds withAttributes:attributes]; 84 | } 85 | 86 | - (void)drawFullState 87 | { 88 | NSImage *image = [[NSWorkspace sharedWorkspace] iconForFile:self.URL.path]; 89 | NSImage *scaledImage = [image imageByScalingProportionallyToSize:NSMakeSize(self.bounds.size.height, self.bounds.size.height)]; 90 | [scaledImage drawInRect:NSMakeRect(0, 0, self.bounds.size.height, self.bounds.size.height)]; 91 | 92 | NSString *filename = [self.URL lastPathComponent]; 93 | [self drawString:filename verticallyCentredInRect:NSMakeRect(self.bounds.size.height, 0, self.bounds.size.width - self.bounds.size.height, self.bounds.size.height) withAttributes:@{}]; 94 | } 95 | 96 | - (void)drawString:(NSString*)string verticallyCentredInRect:(NSRect)rect withAttributes:(NSDictionary*)attributes { 97 | NSSize size = [string sizeWithAttributes:attributes]; 98 | [string drawInRect:NSMakeRect(rect.origin.x, rect.origin.y + (rect.size.height - size.height) / 2.0, rect.size.width, size.height) withAttributes:attributes]; 99 | } 100 | 101 | #pragma mark - Dragging 102 | 103 | - (NSDragOperation) draggingEntered:sender { 104 | NSPasteboard *pboard; 105 | 106 | self.cachedDragOperation = NSDragOperationNone; 107 | pboard = [sender draggingPasteboard]; 108 | 109 | // we don't acept drags if we are the provider!! 110 | if ([sender draggingSource] == self) return NSDragOperationNone; 111 | 112 | if ([[pboard types] containsObject:NSFilenamesPboardType]) { 113 | self.hovering = YES; 114 | [self setNeedsDisplay:YES]; 115 | 116 | // we'll copy or link depending on the intent of the dragging source: 117 | self.cachedDragOperation = [sender draggingSourceOperationMask]; 118 | } 119 | return self.cachedDragOperation; 120 | } 121 | 122 | - (NSDragOperation) draggingUpdated:sender { 123 | return self.cachedDragOperation; 124 | } 125 | 126 | - (void) draggingExited:sender 127 | { 128 | // the user has exited -> clean up: 129 | if ([sender draggingSource] != self) { 130 | self.hovering = NO; 131 | [self setNeedsDisplay:YES]; 132 | 133 | self.cachedDragOperation = NSDragOperationNone; 134 | } 135 | } 136 | 137 | - (BOOL) performDragOperation:(id )sender { 138 | NSPasteboard *pboard = [sender draggingPasteboard]; 139 | NSString *path = [[pboard propertyListForType:NSFilenamesPboardType] objectAtIndex:0]; 140 | self.URL = [NSURL fileURLWithPath:path]; 141 | return YES; 142 | } 143 | 144 | - (void)setURL:(NSURL *)URL { 145 | _URL = URL; 146 | [self setNeedsDisplay:YES]; 147 | } 148 | 149 | 150 | 151 | 152 | 153 | @end 154 | -------------------------------------------------------------------------------- /QuickRadar/QRMainAppSettingsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRMainAppSettingsViewController.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 29/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SRRecorderControl.h" 12 | 13 | @interface QRMainAppSettingsViewController : NSViewController 14 | 15 | @property (assign) IBOutlet SRRecorderControl *hotkeyRecorderControl; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /QuickRadar/QRMainAppSettingsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRMainAppSettingsViewController.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 29/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "QRMainAppSettingsViewController.h" 10 | #import "AppDelegate.h" 11 | #import "SRCommon.h" 12 | #import "SGHotKeyCenter.h" 13 | #import "SGHotKey.h" 14 | 15 | @interface QRMainAppSettingsViewController () 16 | 17 | @end 18 | 19 | @implementation QRMainAppSettingsViewController 20 | 21 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 22 | { 23 | if (nibNameOrNil.length == 0) 24 | { 25 | nibNameOrNil = @"QRMainAppSettingsViewController"; 26 | } 27 | 28 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 29 | if (self) { 30 | // Initialization code here. 31 | } 32 | 33 | return self; 34 | } 35 | 36 | - (void)configureRecorderControl:(SRRecorderControl *)recorderControl withHotKeyIdentifier:(NSString *)identifier 37 | { 38 | SGHotKeyCenter *hotKeyCenter = [SGHotKeyCenter sharedCenter]; 39 | SGHotKey *hotKey = [hotKeyCenter hotKeyWithIdentifier:identifier]; 40 | if (hotKey) { 41 | KeyCombo keyCombo; 42 | keyCombo.code = hotKey.keyCombo.keyCode; 43 | keyCombo.flags = [recorderControl carbonToCocoaFlags:hotKey.keyCombo.modifiers]; 44 | [recorderControl setAllowsKeyOnly:YES escapeKeysRecord:NO]; 45 | [recorderControl setKeyCombo:keyCombo]; 46 | [recorderControl setNeedsDisplay:YES]; 47 | } 48 | [recorderControl setDelegate:self]; 49 | [recorderControl setCanCaptureGlobalHotKeys:YES]; 50 | } 51 | 52 | - (void)awakeFromNib 53 | { 54 | [self configureRecorderControl:self.hotkeyRecorderControl withHotKeyIdentifier:GlobalHotkeyName]; 55 | } 56 | 57 | 58 | #pragma mark SRRecorderControl delegate 59 | 60 | - (void)shortcutRecorder:(SRRecorderControl *)aRecorder keyComboDidChange:(KeyCombo)newKeyCombo 61 | { 62 | // NOTE: changes to the following actions must also be done in AppDelegate -applicationDidFinishLaunching: 63 | 64 | NSString *hotKeyIdentifier = nil; 65 | SEL action = NULL; 66 | if (aRecorder == self.hotkeyRecorderControl) { 67 | hotKeyIdentifier = GlobalHotkeyName; 68 | action = @selector(hitHotKey:); 69 | } 70 | 71 | if (hotKeyIdentifier) { 72 | SGHotKeyCenter *hotKeyCenter = [SGHotKeyCenter sharedCenter]; 73 | SGHotKey *hotKey = [hotKeyCenter hotKeyWithIdentifier:hotKeyIdentifier]; 74 | 75 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 76 | 77 | // remove any existing hot key 78 | if (hotKey) { 79 | [hotKeyCenter unregisterHotKey:hotKey]; 80 | [userDefaults removeObjectForKey:hotKeyIdentifier]; 81 | } 82 | 83 | SGKeyCombo *keyCombo = [SGKeyCombo keyComboWithKeyCode:newKeyCombo.code modifiers:[aRecorder cocoaToCarbonFlags:newKeyCombo.flags]]; 84 | if (newKeyCombo.code != ShortcutRecorderEmptyCode) { 85 | // create a new hot key 86 | hotKey = [[SGHotKey alloc] initWithIdentifier:hotKeyIdentifier keyCombo:keyCombo]; 87 | [hotKey setTarget:nil]; // send to first responder 88 | [hotKey setAction:action]; 89 | [[SGHotKeyCenter sharedCenter] registerHotKey:hotKey]; 90 | } 91 | [userDefaults setObject:[keyCombo plistRepresentation] forKey:hotKeyIdentifier]; 92 | 93 | [userDefaults synchronize]; 94 | } 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /QuickRadar/QROpenRadarSubmissionService.h: -------------------------------------------------------------------------------- 1 | // 2 | // QROpenRadarSubmissionService.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 21/08/2012. 6 | // 7 | // 8 | 9 | #import "QRSubmissionService.h" 10 | 11 | @interface QROpenRadarSubmissionService : QRSubmissionService 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /QuickRadar/QROpenRadarSubmissionService.m: -------------------------------------------------------------------------------- 1 | // 2 | // QROpenRadarSubmissionService.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 21/08/2012. 6 | // 7 | // 8 | 9 | #import "QROpenRadarSubmissionService.h" 10 | #import "QRURLConnection.h" 11 | 12 | 13 | @interface QROpenRadarSubmissionService () 14 | 15 | @property (atomic, assign) CGFloat progressValue; 16 | @property (atomic, assign) SubmissionStatus submissionStatusValue; 17 | 18 | @end 19 | 20 | 21 | @implementation QROpenRadarSubmissionService 22 | 23 | + (void)load 24 | { 25 | [QRSubmissionService registerService:self]; 26 | } 27 | 28 | + (NSString *)identifier 29 | { 30 | return QROpenRadarSubmissionServiceIdentifier; 31 | } 32 | 33 | + (NSString *)name 34 | { 35 | return @"Open Radar"; 36 | } 37 | 38 | + (NSString*)checkBoxString 39 | { 40 | return @"Send to Open Radar"; 41 | } 42 | 43 | + (BOOL)isAvailable 44 | { 45 | NSString *apiKey = [[NSUserDefaults standardUserDefaults] stringForKey:@"openRadarAPIKey"]; 46 | 47 | if (apiKey.length > 0) 48 | { 49 | return YES; 50 | } 51 | return NO; 52 | } 53 | 54 | + (BOOL)supportedOnMac; 55 | { 56 | return YES; 57 | } 58 | 59 | + (BOOL)supportedOniOS; 60 | { 61 | return NO; 62 | } 63 | 64 | + (NSString*)macSettingsViewControllerClassName; 65 | { 66 | return @"QROpenRadarSubmissionServicePreferencesViewController"; 67 | } 68 | 69 | + (NSString*)iosSettingsViewControllerClassName; 70 | { 71 | return nil; 72 | } 73 | 74 | + (id)settingsIconPlatformAppropriateImage; 75 | { 76 | if (NSClassFromString(@"NSImage")) 77 | { 78 | return [NSImage imageNamed:@"MenubarTemplate"]; 79 | } 80 | return nil; 81 | } 82 | 83 | - (CGFloat)progress 84 | { 85 | return self.progressValue; 86 | } 87 | 88 | - (SubmissionStatus)submissionStatus 89 | { 90 | return self.submissionStatusValue; 91 | } 92 | 93 | +(NSSet *)hardDependencies 94 | { 95 | return [NSSet setWithObject:QRRadarSubmissionServiceIdentifier]; 96 | } 97 | 98 | - (void)submitAsyncWithProgressBlock:(void (^)())progressBlock completionBlock:(void (^)(BOOL, NSError *))completionBlock 99 | { 100 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 101 | self.submissionStatusValue = submissionStatusInProgress; 102 | 103 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 104 | formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; 105 | formatter.dateFormat = @"dd-MMM-yyyy hh:mm a"; 106 | NSString *dateString = [formatter stringFromDate:self.radar.dateOriginated]; 107 | 108 | NSLog(@"Date originated: %@, formatted %@", self.radar.dateOriginated, dateString); 109 | 110 | NSError *error = nil; 111 | 112 | NSString *apiKey = [[NSUserDefaults standardUserDefaults] stringForKey:@"openRadarAPIKey"]; 113 | 114 | if (apiKey.length == 0 || self.radar.radarNumber == 0) 115 | { 116 | dispatch_sync(dispatch_get_main_queue(), ^{ 117 | self.submissionStatusValue = submissionStatusFailed; 118 | completionBlock(NO, error); 119 | }); 120 | return; 121 | } 122 | 123 | NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://openradar.appspot.com/api/radars/add"]]; 124 | [req addValue:apiKey forHTTPHeaderField:@"Authorization"]; 125 | req.HTTPMethod = @"POST"; 126 | 127 | NSDictionary *postParams = 128 | @{ 129 | @"number" : @(self.radar.radarNumber), 130 | @"classification" : self.radar.classification, 131 | @"description" : self.radar.body, 132 | @"product" : self.radar.product, 133 | @"product_version" : self.radar.version, 134 | @"reproducible" : self.radar.reproducible, 135 | @"title" : self.radar.title, 136 | @"originated" : dateString, 137 | @"status" : self.radar.status, 138 | }; 139 | 140 | QRURLConnection *conn = [[QRURLConnection alloc] init]; 141 | conn.request = req; 142 | conn.postParameters = postParams; 143 | 144 | NSData *data = [conn fetchSyncWithError:&error]; 145 | 146 | NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 147 | NSLog(@"OR: Result: %@ %@", result, error); 148 | 149 | self.progressValue = 1.0; 150 | self.submissionStatusValue = submissionStatusCompleted; 151 | self.radar.submittedToOpenRadar = YES; 152 | 153 | dispatch_sync(dispatch_get_main_queue(), ^{ 154 | progressBlock(); 155 | completionBlock(YES, nil); 156 | }); 157 | 158 | }); 159 | } 160 | 161 | 162 | 163 | @end 164 | -------------------------------------------------------------------------------- /QuickRadar/QROpenRadarSubmissionServicePreferencesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // QROpenRadarSubmissionServicePreferencesViewController.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 21/08/2012. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface QROpenRadarSubmissionServicePreferencesViewController : NSViewController 12 | 13 | - (IBAction)jumpToAPIKeyPage:(id)sender; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /QuickRadar/QROpenRadarSubmissionServicePreferencesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // QROpenRadarSubmissionServicePreferencesViewController.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 21/08/2012. 6 | // 7 | // 8 | 9 | #import "QROpenRadarSubmissionServicePreferencesViewController.h" 10 | 11 | @interface QROpenRadarSubmissionServicePreferencesViewController () 12 | 13 | @end 14 | 15 | @implementation QROpenRadarSubmissionServicePreferencesViewController 16 | 17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 18 | { 19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 20 | if (self) { 21 | // Initialization code here. 22 | } 23 | 24 | return self; 25 | } 26 | 27 | - (void)jumpToAPIKeyPage:(id)sender 28 | { 29 | NSLog(@"Opening"); 30 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://openradar.appspot.com/apikey"]]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /QuickRadar/QRPreferencesWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencesWindowController.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 29/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QRPreferencesWindowController : NSWindowController 12 | 13 | @property (strong, nonatomic, readonly) IBOutlet NSToolbar *toolbar; 14 | 15 | - (void)selectItemAtIndex:(NSUInteger)index; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /QuickRadar/QRPreferencesWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencesWindowController.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 29/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "QRPreferencesWindowController.h" 10 | #import "QRMainAppSettingsViewController.h" 11 | #import "QRSubmissionService.h" 12 | #import "QRUserDefaultsKeys.h" 13 | 14 | @interface QRPreferencesWindowController () 15 | @property (strong, nonatomic) IBOutlet NSToolbar *toolbar; 16 | @property (strong, nonatomic) NSMutableArray *panes; 17 | @property (assign, nonatomic) NSUInteger index; 18 | @end 19 | 20 | @implementation QRPreferencesWindowController 21 | @synthesize toolbar = _toolbar; 22 | @synthesize panes = _panes; 23 | @synthesize index = _index; 24 | 25 | - (instancetype)init 26 | { 27 | self = [super initWithWindowNibName:NSStringFromClass([self class])]; 28 | if (self) 29 | { 30 | _panes = [NSMutableArray new]; 31 | } 32 | return self; 33 | } 34 | 35 | - (void)awakeFromNib 36 | { 37 | [super awakeFromNib]; 38 | 39 | NSInteger windowLevel = [[NSUserDefaults standardUserDefaults] integerForKey:QRWindowLevelKey]; 40 | [self.window setLevel:windowLevel]; 41 | 42 | self.window.title = NSLocalizedString(@"Preferences", @"Preferences Window Title"); 43 | self.toolbar.delegate = self; 44 | self.toolbar.allowsUserCustomization = NO; 45 | 46 | QRMainAppSettingsViewController *mainPrefsVC = [[QRMainAppSettingsViewController alloc] init]; 47 | mainPrefsVC.title = @"Settings"; 48 | mainPrefsVC.representedObject = [NSImage imageNamed:NSImageNameActionTemplate]; 49 | [self qr_addViewController:mainPrefsVC]; 50 | 51 | // Start the toolbar with a flexible space 52 | [self.toolbar insertItemWithItemIdentifier:NSToolbarFlexibleSpaceItemIdentifier atIndex:0]; 53 | 54 | // Now add all the services 55 | NSDictionary *services = [QRSubmissionService services]; 56 | 57 | // Special case Apple Radar, so it comes first 58 | Class radarPrefsVC = services[QRRadarSubmissionServiceIdentifier]; 59 | [self addViewControllerForClass:radarPrefsVC]; 60 | 61 | // Now do the others 62 | NSMutableDictionary *nonRadarServices = [services mutableCopy]; 63 | [nonRadarServices removeObjectForKey:QRRadarSubmissionServiceIdentifier]; 64 | 65 | for (Class ServiceClass in [nonRadarServices allValues]) 66 | { 67 | [self addViewControllerForClass:ServiceClass]; 68 | } 69 | 70 | // And another flexible space at the end 71 | [self.toolbar insertItemWithItemIdentifier:NSToolbarFlexibleSpaceItemIdentifier atIndex:self.toolbar.items.count]; 72 | 73 | [self qr_updateUI]; 74 | } 75 | 76 | 77 | - (void)addViewControllerForClass:(Class)ServiceClass 78 | { 79 | NSString *viewControllerClassName = [ServiceClass macSettingsViewControllerClassName]; 80 | if (viewControllerClassName.length>0) 81 | { 82 | Class viewControllerClass = NSClassFromString(viewControllerClassName); 83 | NSViewController *viewController = [[viewControllerClass alloc] initWithNibName:viewControllerClassName bundle:nil]; 84 | 85 | viewController.title = [ServiceClass name]; 86 | viewController.representedObject = [ServiceClass settingsIconPlatformAppropriateImage]; 87 | 88 | [self qr_addViewController:viewController]; 89 | } 90 | } 91 | 92 | - (void)qr_addViewController:(NSViewController *)viewController 93 | { 94 | [self.panes addObject:viewController]; 95 | [self.toolbar insertItemWithItemIdentifier:viewController.title atIndex:[self.toolbar.items count]]; 96 | } 97 | 98 | - (void)selectItemAtIndex:(NSUInteger)index 99 | { 100 | self.index = index; 101 | NSString *selectedIdentifier = [self.toolbar.items[index] itemIdentifier]; 102 | [self.toolbar setSelectedItemIdentifier:selectedIdentifier]; 103 | [self qr_updateUI]; 104 | } 105 | 106 | - (void)selectItemWithIdentifier:(NSString *)identifier 107 | { 108 | NSUInteger index = [[self toolbarAllowedItemIdentifiers:self.toolbar] indexOfObject:identifier]; 109 | if (index == NSNotFound) 110 | { 111 | return; 112 | } 113 | [self selectItemAtIndex:index]; 114 | } 115 | 116 | - (void)qr_updateUI 117 | { 118 | NSViewController *controller = self.panes[self.index]; 119 | self.toolbar.selectedItemIdentifier = controller.title; 120 | self.window.contentView = controller.view; 121 | } 122 | 123 | - (NSViewController *)qr_preferenceViewControllerForIdentifier:(NSString *)identifier 124 | { 125 | NSViewController *preferenceViewController = nil; 126 | for (NSViewController *viewController in self.panes) 127 | { 128 | if ([viewController.title isEqualToString:identifier]) 129 | { 130 | preferenceViewController = viewController; 131 | break; 132 | } 133 | } 134 | return preferenceViewController; 135 | } 136 | 137 | #pragma mark - NSToolbarDelegate 138 | 139 | - (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag 140 | { 141 | NSToolbarItem *toolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier]; 142 | NSViewController *viewController = [self qr_preferenceViewControllerForIdentifier:itemIdentifier]; 143 | 144 | [toolbarItem setImage:[viewController representedObject]]; 145 | [toolbarItem setLabel:[viewController title]]; 146 | [toolbarItem setTarget:self]; 147 | [toolbarItem setAction:@selector(qr_toolbarItemSelected:)]; 148 | 149 | return toolbarItem; 150 | } 151 | 152 | - (NSArray *)qr_identifiers 153 | { 154 | return [self.panes valueForKey:@"title"]; 155 | } 156 | 157 | - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar 158 | { 159 | return [self qr_identifiers]; 160 | } 161 | 162 | - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar 163 | { 164 | return [self qr_identifiers]; 165 | } 166 | 167 | - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar 168 | { 169 | return [self qr_identifiers]; 170 | } 171 | 172 | #pragma mark - Toolbar Action 173 | 174 | - (void)qr_toolbarItemSelected:(NSToolbarItem *)toolbarItem 175 | { 176 | [self selectItemWithIdentifier:toolbarItem.itemIdentifier]; 177 | } 178 | 179 | @end 180 | -------------------------------------------------------------------------------- /QuickRadar/QRPreferencesWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /QuickRadar/QRRadar.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRRadar.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 26/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QRRadar : NSObject 12 | 13 | @property (nonatomic, copy) NSString *product; 14 | @property (nonatomic, assign) NSInteger productCode; 15 | 16 | @property (nonatomic, copy) NSString *version; 17 | 18 | @property (nonatomic, copy) NSString *classification; 19 | @property (nonatomic, assign) NSInteger classificationCode; 20 | 21 | @property (nonatomic, copy) NSString *reproducible; 22 | @property (nonatomic, assign) NSInteger reproducibleCode; 23 | 24 | @property (nonatomic, copy) NSString *title; 25 | @property (nonatomic, copy) NSString *body; 26 | 27 | @property (nonatomic, copy) NSString *status; 28 | @property (nonatomic, copy) NSDate *dateOriginated; 29 | 30 | @property (nonatomic, copy) NSString *configurationString; 31 | 32 | @property (nonatomic, copy) NSURL *attachmentURL; 33 | 34 | @property (nonatomic, assign) NSInteger radarNumber; 35 | @property (nonatomic, assign) NSInteger draftNumber; 36 | @property (nonatomic, assign) BOOL submittedToOpenRadar; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /QuickRadar/QRRadar.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRRadar.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 26/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "QRRadar.h" 10 | 11 | @interface QRRadar () 12 | 13 | @property (nonatomic, strong) NSMutableDictionary *serviceSpecificProperties; 14 | 15 | @end 16 | 17 | @implementation QRRadar 18 | 19 | @synthesize product = _product; 20 | @synthesize version = _version; 21 | @synthesize classification = _classification; 22 | @synthesize reproducible = _reproducible; 23 | @synthesize title = _title; 24 | @synthesize body = _body; 25 | @synthesize radarNumber = _radarNumber; 26 | @synthesize serviceSpecificProperties = _serviceSpecificProperties; 27 | 28 | 29 | - (void)setValue:(id)value forUndefinedKey:(NSString *)key 30 | { 31 | if (!self.serviceSpecificProperties) 32 | { 33 | self.serviceSpecificProperties = [NSMutableDictionary dictionary]; 34 | } 35 | 36 | (self.serviceSpecificProperties)[key] = value; 37 | } 38 | 39 | - (id)valueForUndefinedKey:(NSString *)key 40 | { 41 | return (self.serviceSpecificProperties)[key]; 42 | } 43 | 44 | 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /QuickRadar/QRRadarSubmissionService.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRRadarSubmissionService.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 26/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "QRSubmissionService.h" 10 | 11 | 12 | @interface QRRadarSubmissionService : QRSubmissionService 13 | 14 | @property (nonatomic, assign) BOOL submitDraft; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /QuickRadar/QRRadarSubmissionServicePreferencesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRRadarSubmissionServicePreferencesViewController.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 29/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QRRadarSubmissionServicePreferencesViewController : NSViewController 12 | 13 | - (IBAction)getAnAccount:(id)sender; 14 | @end 15 | -------------------------------------------------------------------------------- /QuickRadar/QRRadarSubmissionServicePreferencesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRRadarSubmissionServicePreferencesViewController.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 29/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "QRRadarSubmissionServicePreferencesViewController.h" 10 | 11 | @interface QRRadarSubmissionServicePreferencesViewController () 12 | 13 | @end 14 | 15 | @implementation QRRadarSubmissionServicePreferencesViewController 16 | 17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 18 | { 19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 20 | if (self) { 21 | // Initialization code here. 22 | } 23 | 24 | return self; 25 | } 26 | 27 | - (IBAction)getAnAccount:(id)sender 28 | { 29 | NSString *stringURL = @"https://developer.apple.com/programs/register/"; 30 | NSURL *url = [NSURL URLWithString:stringURL]; 31 | [[NSWorkspace sharedWorkspace] openURL:url]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /QuickRadar/QRRadarWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRRadarWindow.h 3 | // QuickRadar 4 | // 5 | // Created by Balázs Faludi on 14.08.12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface QRRadarWindow : NSWindow 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /QuickRadar/QRRadarWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRRadarWindow.m 3 | // QuickRadar 4 | // 5 | // Created by Balázs Faludi on 14.08.12. 6 | // 7 | // 8 | 9 | #import "QRRadarWindow.h" 10 | 11 | @implementation QRRadarWindow 12 | 13 | // Don't contrain window frame, so it can be moved off screen. 14 | - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { 15 | return frameRect; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /QuickRadar/QRRadarWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RadarWindowController.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 15/05/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "QRAppListPopover.h" 11 | #import "QRRadar.h" 12 | @class QRFileWell; 13 | 14 | @interface QRRadarWindowController : NSWindowController 15 | 16 | @property (nonatomic, strong) IBOutlet NSPopUpButton *productMenu; 17 | @property (nonatomic, strong) IBOutlet NSPopUpButton *classificationMenu; 18 | @property (nonatomic, strong) IBOutlet NSPopUpButton *reproducibleMenu; 19 | @property (nonatomic, strong) IBOutlet NSTextField *versionField; 20 | @property (nonatomic, strong) IBOutlet NSTextField *titleField; 21 | @property (nonatomic, strong) IBOutlet NSTextField *configurationField; 22 | @property (nonatomic, strong) IBOutlet NSTextView *bodyTextView; 23 | @property (nonatomic, strong) IBOutlet NSButton *openRadarCheckbox; 24 | @property (nonatomic, strong) IBOutlet NSButton *submitButton; 25 | @property (nonatomic, strong) IBOutlet NSProgressIndicator *spinner; 26 | @property (nonatomic, strong) IBOutlet NSProgressIndicator *progressBar; 27 | @property (nonatomic, strong) IBOutlet NSTextField *submitStatusField; 28 | @property (nonatomic, strong) IBOutlet NSButton *appListButton; 29 | @property (nonatomic, strong) IBOutlet QRAppListPopover *appListPopover; 30 | @property (nonatomic, strong) IBOutlet NSMatrix *checkboxMatrix; 31 | @property (nonatomic, strong) IBOutlet QRFileWell *attachmentFileWell; 32 | @property (nonatomic, strong) IBOutlet NSButton *draftButton; 33 | 34 | - (IBAction)showAppList:(id)sender; 35 | - (IBAction)submitRadar:(id)sender; 36 | - (IBAction)saveDraft:(id)sender; 37 | - (void)prepopulateWithApp:(QRCachedRunningApplication *)app; 38 | 39 | - (void)prepopulateWithRadar:(QRRadar *)radar; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /QuickRadar/QRSubmissionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RadarSubmission.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 15/05/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class QRRadar; 12 | 13 | @interface QRSubmissionController : NSObject 14 | 15 | 16 | 17 | @property (nonatomic, strong) QRRadar *radar; 18 | @property (nonatomic, strong) NSDictionary *requestedOptionalServices; // ignored if draft 19 | @property (nonatomic, assign) BOOL submitDraft; 20 | @property (readonly) CGFloat progress; 21 | @property (readonly) NSString *statusText; 22 | @property (nonatomic, strong) NSWindow *submissionWindow; 23 | 24 | 25 | - (void)startWithProgressBlock:(void (^)())progressBlock completionBlock:(void (^)(BOOL, NSError *))completionBlock; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /QuickRadar/QRSubmissionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RadarSubmission.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 15/05/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "QRSubmissionController.h" 10 | #import "QRSubmissionService.h" 11 | #import "QRRadarSubmissionService.h" 12 | 13 | @interface QRSubmissionController () 14 | 15 | @property (nonatomic, strong) NSMutableSet *completed; 16 | @property (nonatomic, strong) NSMutableSet *inProgress; 17 | @property (nonatomic, strong) NSMutableSet *waiting; 18 | 19 | @property (nonatomic, copy) void (^progressBlock)() ; 20 | @property (nonatomic, copy) void (^completionBlock)(BOOL, NSError *) ; 21 | @property (assign) BOOL hasFiredCompletionBlock; 22 | 23 | @end 24 | 25 | @implementation QRSubmissionController 26 | 27 | 28 | @synthesize radar = _radar; 29 | @synthesize completed = _completed, inProgress = _inProgress, waiting = _waiting; 30 | @synthesize progressBlock = _progressBlock, completionBlock = _completionBlock; 31 | @synthesize hasFiredCompletionBlock = _hasFiredCompletionBlock; 32 | 33 | 34 | - (void)startWithProgressBlock:(void (^)())progressBlock completionBlock:(void (^)(BOOL, NSError *))completionBlock 35 | { 36 | if (!self.radar) 37 | { 38 | completionBlock(NO, [NSError errorWithDomain:@"No radar object" code:0 userInfo:nil]); 39 | return; 40 | } 41 | 42 | self.progressBlock = progressBlock; 43 | self.completionBlock = completionBlock; 44 | 45 | self.completed = [NSMutableSet set]; 46 | self.inProgress = [NSMutableSet set]; 47 | self.waiting = [NSMutableSet set]; 48 | 49 | if (self.submitDraft) { 50 | // Special case drafts to just submit radar 51 | QRRadarSubmissionService *service = [[QRRadarSubmissionService alloc] init]; 52 | service.radar = self.radar; 53 | service.submissionWindow = self.submissionWindow; 54 | service.submitDraft = YES; 55 | [self.waiting addObject:service]; 56 | } else { 57 | NSDictionary *services = [QRSubmissionService services]; 58 | 59 | for (NSString *serviceID in services) 60 | { 61 | Class serviceClass = services[serviceID]; 62 | 63 | if (![serviceClass isAvailable]) 64 | { 65 | NSLog(@"%@ not available", serviceID); 66 | continue; 67 | } 68 | 69 | if ([serviceClass requireCheckBox]) 70 | { 71 | if ([(self.requestedOptionalServices)[serviceID] boolValue] == NO) 72 | { 73 | NSLog(@"%@ not requested", serviceID); 74 | continue; 75 | } 76 | } 77 | 78 | QRSubmissionService *service = [[serviceClass alloc] init]; 79 | service.radar = self.radar; 80 | service.submissionWindow = self.submissionWindow; 81 | 82 | [self.waiting addObject:service]; 83 | } 84 | } 85 | 86 | [self startNextAvailableServices]; 87 | } 88 | 89 | - (void)startNextAvailableServices; 90 | { 91 | for (QRSubmissionService *service in [self.waiting copy]) 92 | { 93 | NSSet *hardDeps = [[service class] hardDependencies]; 94 | NSSet *softDeps = [[service class] softDependencies]; 95 | 96 | BOOL hasFailedDeps = NO; 97 | 98 | /* Check hard deps */ 99 | // For a hard dep, if the service in question is NOT completed, it fails. 100 | for (NSString *serviceID in hardDeps) 101 | { 102 | BOOL metThisDep = NO; 103 | for (QRSubmissionService *testService in [self.completed copy]) 104 | { 105 | if ([[[testService class] identifier] isEqualToString:serviceID]) 106 | { 107 | metThisDep = YES; 108 | } 109 | } 110 | if (!metThisDep) 111 | { 112 | hasFailedDeps = YES; 113 | } 114 | } 115 | 116 | // TODO: decide what you're doing about serviceStatus -- either use it here, or remove it everywhere. 117 | 118 | /* Check soft deps */ 119 | // For a soft dep, if the service in question is present and not finished, it fails. 120 | for (NSString *serviceID in softDeps) 121 | { 122 | for (QRSubmissionService *testService in [self.waiting setByAddingObjectsFromSet:self.inProgress]) 123 | { 124 | if ([[[testService class] identifier] isEqualToString:serviceID]) 125 | { 126 | hasFailedDeps = YES; 127 | } 128 | } 129 | } 130 | 131 | if (hasFailedDeps) 132 | { 133 | continue; 134 | } 135 | 136 | // Hopefully fix the OpenRadar multiple submissions bug 137 | @synchronized(self) 138 | { 139 | if (![self.waiting containsObject:service]) 140 | { 141 | continue; 142 | } 143 | 144 | /* Get on with it */ 145 | 146 | [self.inProgress addObject:service]; 147 | [self.waiting removeObject:service]; 148 | 149 | [service submitAsyncWithProgressBlock:^{ 150 | self.progressBlock(); 151 | } completionBlock:^(BOOL success, NSError *error) { 152 | [self.inProgress removeObject:service]; 153 | [self.completed addObject:service]; 154 | 155 | if (!success) 156 | { 157 | NSLog(@"Failure by %@", [[service class] identifier]); 158 | self.hasFiredCompletionBlock = YES; 159 | self.completionBlock(NO, error); 160 | } 161 | else 162 | { 163 | [self startNextAvailableServices]; 164 | } 165 | 166 | }]; 167 | } 168 | 169 | 170 | 171 | } 172 | 173 | if (self.inProgress.count == 0 && self.waiting.count == 0 && !self.hasFiredCompletionBlock) 174 | { 175 | self.hasFiredCompletionBlock = YES; 176 | self.completionBlock(YES, nil); 177 | } 178 | } 179 | 180 | - (CGFloat)progress 181 | { 182 | CGFloat accumulator = 0; 183 | CGFloat number = 0; 184 | 185 | for (__unused QRSubmissionService *service in self.waiting) 186 | { 187 | number++; 188 | } 189 | for (QRSubmissionService *service in self.inProgress) 190 | { 191 | number++; 192 | accumulator += service.progress; 193 | } 194 | for (__unused QRSubmissionService *service in self.completed) 195 | { 196 | number++; 197 | accumulator += 1.0; 198 | } 199 | 200 | return accumulator/number; 201 | } 202 | 203 | - (NSString *)statusText 204 | { 205 | NSMutableString *overallStatus = nil; 206 | 207 | for (QRSubmissionService *service in self.inProgress) 208 | { 209 | NSString *serviceStatus = service.statusText; 210 | if (serviceStatus == nil) 211 | continue; 212 | if (overallStatus == nil) 213 | overallStatus = [serviceStatus mutableCopy]; 214 | else 215 | [overallStatus appendFormat:@"; %@", serviceStatus]; 216 | } 217 | 218 | return overallStatus; 219 | } 220 | 221 | @end 222 | -------------------------------------------------------------------------------- /QuickRadar/QRSubmissionService.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRSubmissionService.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 26/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "QRRadar.h" 12 | 13 | typedef enum { 14 | submissionStatusNotStarted, 15 | submissionStatusInProgress, 16 | submissionStatusCompleted, 17 | submissionStatusFailed 18 | } SubmissionStatus; 19 | 20 | NSString * const QRWordpressSubmissionServiceIdentifier; 21 | NSString * const QRRadarSubmissionServiceIdentifier; 22 | NSString * const QROpenRadarSubmissionServiceIdentifier; 23 | NSString * const QRTwitterSubmissionServiceIdentifier; 24 | 25 | 26 | @interface QRSubmissionService : NSObject 27 | 28 | // A dictionary of service classes, keyed by service identifier 29 | + (NSDictionary *)services; 30 | 31 | // A dictionary of service identifiers (keys) to check box strings (values) 32 | + (NSDictionary *)checkBoxNames; 33 | 34 | // Should be called by all subclasses in +initialize. 35 | + (void)registerService:(Class)service; 36 | 37 | 38 | 39 | /** The following are all things subclasses should override **/ 40 | 41 | + (NSString*)identifier; 42 | + (NSString*)name; 43 | 44 | // Set of service identifiers that MUST be completed before this one runs 45 | + (NSSet*)hardDependencies; 46 | 47 | // Set of service identifiers that, if they are present, should be run before this one. 48 | + (NSSet*)softDependencies; 49 | 50 | + (BOOL)supportedOnMac; 51 | + (BOOL)supportedOniOS; 52 | 53 | + (NSString*)macSettingsViewControllerClassName; 54 | + (NSString*)iosSettingsViewControllerClassName; 55 | + (id)settingsIconPlatformAppropriateImage; 56 | 57 | - (SubmissionStatus)submissionStatus; 58 | - (NSString *)statusText; 59 | 60 | // Return YES if the requirements for using this service are met (e.g. user has entered username and password in Settings). 61 | // Don't block this method, so don't go and check the username/pass are valid, just return YES if they're present. 62 | + (BOOL) isAvailable; 63 | 64 | // return YES to only activate this service if the user requests it. 65 | + (BOOL)requireCheckBox; 66 | // A string to display next to the check box in the user interface. 67 | + (NSString*)checkBoxString; 68 | 69 | 70 | // returns a float ranging 0-1 indicating progress. Should return 1 when status is complete. 71 | - (CGFloat)progress; 72 | 73 | @property (nonatomic, strong) QRRadar *radar; 74 | @property (nonatomic, strong) NSWindow *submissionWindow; 75 | 76 | // The method that does the work. Call progressBlock whenever progress has changed. Call completion block on success or failure. 77 | - (void)submitAsyncWithProgressBlock:(void(^)())progressBlock completionBlock:(void(^)(BOOL success, NSError *error))completionBlock; 78 | 79 | 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /QuickRadar/QRSubmissionService.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRSubmissionService.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 26/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "QRSubmissionService.h" 10 | 11 | NSString * const QRWordpressSubmissionServiceIdentifier = @"QRWordpressSubmissionServiceIdentifier"; 12 | NSString * const QRRadarSubmissionServiceIdentifier = @"QRRadarSubmissionServiceIdentifier"; 13 | NSString * const QROpenRadarSubmissionServiceIdentifier = @"QROpenRadarSubmissionServiceIdentifier"; 14 | NSString * const QRTwitterSubmissionServiceIdentifier = @"QRTwitterSubmissionServiceIdentifier"; 15 | 16 | static NSMutableDictionary *_services; 17 | 18 | @implementation QRSubmissionService 19 | 20 | @synthesize radar = _radar; 21 | 22 | + (NSDictionary *)services 23 | { 24 | return [NSDictionary dictionaryWithDictionary:_services]; 25 | } 26 | 27 | + (BOOL)requireCheckBox; 28 | { 29 | return YES; 30 | } 31 | 32 | + (NSDictionary *)checkBoxNames; 33 | { 34 | NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 35 | 36 | NSDictionary *services = [QRSubmissionService services]; 37 | 38 | for (NSString *serviceID in services) 39 | { 40 | Class serviceClass = services[serviceID]; 41 | 42 | if (![serviceClass isAvailable]) 43 | { 44 | continue; 45 | } 46 | 47 | if ([serviceClass checkBoxString].length == 0) 48 | { 49 | continue; 50 | } 51 | 52 | dict[serviceID] = [serviceClass checkBoxString]; 53 | } 54 | 55 | return [NSDictionary dictionaryWithDictionary:dict]; 56 | } 57 | 58 | + (void)registerService:(Class)service 59 | { 60 | @autoreleasepool 61 | { 62 | if (!_services) 63 | { 64 | _services = [NSMutableDictionary dictionary]; 65 | } 66 | 67 | NSString *identifier = [service identifier]; 68 | 69 | _services[identifier] = service; 70 | 71 | } 72 | } 73 | 74 | /** The following are all things subclasses should override **/ 75 | 76 | + (NSString*)identifier 77 | { 78 | return nil; 79 | } 80 | 81 | + (NSString*)name 82 | { 83 | return nil; 84 | } 85 | 86 | + (NSSet*)hardDependencies 87 | { 88 | return [NSSet set]; 89 | } 90 | 91 | + (NSSet*)softDependencies 92 | { 93 | return [NSSet set]; 94 | } 95 | 96 | + (BOOL)supportedOnMac 97 | { 98 | return NO; 99 | } 100 | 101 | + (BOOL)supportedOniOS 102 | { 103 | return NO; 104 | } 105 | 106 | + (NSString*)macSettingsViewControllerClassName 107 | { 108 | return nil; 109 | } 110 | 111 | + (NSString*)iosSettingsViewControllerClassName 112 | { 113 | return nil; 114 | } 115 | 116 | + (id)settingsIconPlatformAppropriateImage 117 | { 118 | return nil; 119 | } 120 | 121 | + (NSString *)checkBoxString 122 | { 123 | return nil; 124 | } 125 | 126 | + (BOOL)isAvailable 127 | { 128 | return YES; 129 | } 130 | 131 | - (SubmissionStatus)submissionStatus 132 | { 133 | return submissionStatusNotStarted; 134 | } 135 | 136 | - (CGFloat)progress 137 | { 138 | return 0.0f; 139 | } 140 | 141 | - (NSString *)statusText 142 | { 143 | return nil; 144 | } 145 | 146 | - (void)submitAsyncWithProgressBlock:(void(^)())progressBlock completionBlock:(void(^)(BOOL success, NSError *error))completionBlock 147 | { 148 | 149 | } 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /QuickRadar/QRTwitterSubmissionService.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRTwitterSubmissionService.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 19/02/2013. 6 | // 7 | // 8 | 9 | #import "QRSubmissionService.h" 10 | 11 | @interface QRTwitterSubmissionService : QRSubmissionService 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /QuickRadar/QRTwitterSubmissionService.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRTwitterSubmissionService.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 19/02/2013. 6 | // 7 | // 8 | 9 | #import "QRTwitterSubmissionService.h" 10 | 11 | @interface QRTwitterSubmissionService () 12 | 13 | @property (nonatomic, assign) BOOL hasTweeted; 14 | @property (nonatomic, copy) void(^completionBlock)(BOOL, NSError *); 15 | 16 | @end 17 | 18 | 19 | @implementation QRTwitterSubmissionService 20 | 21 | + (void)load 22 | { 23 | [QRSubmissionService registerService:self]; 24 | } 25 | 26 | + (NSString *)identifier 27 | { 28 | return QRTwitterSubmissionServiceIdentifier; 29 | } 30 | 31 | + (NSString *)name 32 | { 33 | return @"Twitter"; 34 | } 35 | 36 | + (NSString*)checkBoxString 37 | { 38 | return @"Post to Twitter"; 39 | } 40 | 41 | + (BOOL)isAvailable 42 | { 43 | if (!NSClassFromString(@"NSSharingService")) 44 | { 45 | return NO; 46 | } 47 | 48 | return [[NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnTwitter] canPerformWithItems:nil]; 49 | } 50 | 51 | + (BOOL)supportedOnMac; 52 | { 53 | return YES; 54 | } 55 | 56 | + (BOOL)supportedOniOS; 57 | { 58 | return NO; 59 | } 60 | 61 | + (NSString*)macSettingsViewControllerClassName; 62 | { 63 | return nil; 64 | } 65 | 66 | + (NSString*)iosSettingsViewControllerClassName; 67 | { 68 | return nil; 69 | } 70 | 71 | + (id)settingsIconPlatformAppropriateImage; 72 | { 73 | return nil; 74 | } 75 | 76 | - (CGFloat)progress 77 | { 78 | if (self.hasTweeted) { 79 | return 1.0; 80 | } 81 | return 0.0; 82 | } 83 | 84 | - (SubmissionStatus)submissionStatus 85 | { 86 | if (self.hasTweeted) { 87 | return submissionStatusNotStarted; 88 | } 89 | return submissionStatusCompleted; 90 | } 91 | 92 | +(NSSet *)hardDependencies 93 | { 94 | return [NSSet setWithObject:QRRadarSubmissionServiceIdentifier]; 95 | } 96 | 97 | +(NSSet *)softDependencies 98 | { 99 | return [NSSet setWithObject:QROpenRadarSubmissionServiceIdentifier]; 100 | } 101 | 102 | - (void)submitAsyncWithProgressBlock:(void (^)())progressBlock completionBlock:(void (^)(BOOL, NSError *))completionBlock 103 | { 104 | self.completionBlock = completionBlock; 105 | 106 | NSSharingService *s = [NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnTwitter]; 107 | s.delegate = self; 108 | 109 | NSString *radarLink; 110 | if (self.radar.submittedToOpenRadar) 111 | { 112 | radarLink = [NSString stringWithFormat:@"http://openradar.me/%ld", self.radar.radarNumber]; 113 | } 114 | else 115 | { 116 | radarLink = [NSString stringWithFormat:@"rdar://%ld", self.radar.radarNumber]; 117 | } 118 | 119 | NSString *post = [NSString stringWithFormat:@"Radar: %@", self.radar.title]; 120 | NSURL *link = [NSURL URLWithString:radarLink]; 121 | 122 | 123 | dispatch_async(dispatch_get_main_queue(), ^{ 124 | [s performWithItems:@[post, link]]; 125 | }); 126 | 127 | } 128 | 129 | 130 | - (void)sharingService:(NSSharingService *)sharingService didFailToShareItems:(NSArray *)items error:(NSError *)error; 131 | { 132 | self.completionBlock(NO, error); 133 | } 134 | 135 | - (void)sharingService:(NSSharingService *)sharingService didShareItems:(NSArray *)items; 136 | { 137 | self.completionBlock(YES, nil); 138 | } 139 | 140 | - (NSWindow *)sharingService:(NSSharingService *)sharingService sourceWindowForShareItems:(NSArray *)items sharingContentScope:(NSSharingContentScope *)sharingContentScope; 141 | { 142 | return self.submissionWindow; 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /QuickRadar/QRURLConnection.h: -------------------------------------------------------------------------------- 1 | // 2 | // BlockBasedURLConnection.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 16/05/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QRURLConnection : NSObject 12 | 13 | @property (strong) NSURLRequest *request; 14 | @property (strong) NSDictionary *postParameters; 15 | @property (strong) NSDictionary *postParametersFilenames; 16 | @property (strong) NSData *customBody; 17 | @property (strong) NSArray *fieldOrdering; 18 | @property (strong) NSString *HTTPUsername; 19 | @property (strong) NSString *HTTPPassword; 20 | @property (nonatomic, strong) NSArray *cookiesReturned; 21 | @property (nonatomic, assign) BOOL addRadarSpoofingHeaders; 22 | @property (nonatomic, assign) BOOL sendPostParamsAsJSON; 23 | 24 | @property (assign) BOOL useMultipartRatherThanURLEncoded; 25 | 26 | - (NSData*)fetchSyncWithError:(NSError**)error; 27 | 28 | //- (NSData*)requestAsyncWithBlock: 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /QuickRadar/QRUserDefaultsKeys.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRUserDefaultsKeys.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 03/07/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | 10 | #define QRShowInDockKey @"QRShowInDock" 11 | #define QRShowInStatusBarKey @"QRShowInStatusBar" 12 | #define QRHandleRdarURLsKey @"QRHandleRdarURLs" 13 | #define QRAppDotNetIncludeRdarLinksKey @"appDotNetIncludeRdarLinks" 14 | #define QRWindowLevelKey @"QRWindowLevel" 15 | #define QRFontSizeKey @"QRFontSize" 16 | 17 | typedef enum { 18 | rdarURLsMethodDoNothing = 1, 19 | rdarURLsMethodOpenRadar = 2, 20 | rdarURLsMethodFileDuplicate = 0, 21 | } rdarURLsMethod; -------------------------------------------------------------------------------- /QuickRadar/QRWebScraper.h: -------------------------------------------------------------------------------- 1 | // 2 | // WebScraper.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 21/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QRWebScraper : NSObject 12 | 13 | // param can be a string or NSData object. The order they're added is the order they'll be in the response. 14 | - (void)addPostParameter:(id)param forKey:(NSString*)key; 15 | - (void)addPostParameter:(id)param forKey:(NSString*)key filename:(NSString*)filename; 16 | 17 | @property (nonatomic, strong) NSURL *URL; 18 | @property (nonatomic, copy) NSString *HTTPMethod; 19 | @property (nonatomic, assign) BOOL sendMultipartFormData; 20 | @property (nonatomic, strong) QRWebScraper *cookiesSource; 21 | @property (nonatomic, strong) id referrer; // can be a QRWebScaper or a string 22 | @property (nonatomic, strong) NSData *returnedData; 23 | @property (nonatomic, strong) NSDictionary *customHeaders; 24 | @property (nonatomic, strong) NSData *customBody; 25 | @property (nonatomic, assign) BOOL shouldParseXML; // defaults to YES 26 | 27 | /* A synchronous method */ 28 | - (BOOL)fetch:(NSError**)error; 29 | 30 | /* Deletes any cookies currently present. Set the URL before invoking this method. */ 31 | - (BOOL)deleteCookies; 32 | 33 | - (NSDictionary*)stringValuesForXPathsDictionary:(NSDictionary*)dict error:(NSError**)error; 34 | 35 | @property (nonatomic, strong, readonly) NSString *pageContent; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /QuickRadar/QRWordpressSubmissionService.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRWordpressSubmissionService.h 3 | // QuickRadar 4 | // 5 | // Created by Oliver Drobnik on 22.03.13. 6 | // 7 | // 8 | 9 | #import "QRSubmissionService.h" 10 | 11 | @interface QRWordpressSubmissionService : QRSubmissionService 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /QuickRadar/QRWordpressSubmissionService.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRWordpressSubmissionService.m 3 | // QuickRadar 4 | // 5 | // Created by Oliver Drobnik on 22.03.13. 6 | // 7 | // 8 | 9 | #import "QRWordpressSubmissionService.h" 10 | #import "NSError+Additions.h" 11 | #import "DTWordpress.h" 12 | 13 | @implementation QRWordpressSubmissionService 14 | 15 | + (void)load 16 | { 17 | [QRSubmissionService registerService:self]; 18 | } 19 | 20 | + (NSString *)identifier 21 | { 22 | return QRWordpressSubmissionServiceIdentifier; 23 | } 24 | 25 | + (NSString *)name 26 | { 27 | return @"Wordpress"; 28 | } 29 | 30 | + (NSString*)checkBoxString 31 | { 32 | return @"Send to Wordpress Blog"; 33 | } 34 | 35 | + (BOOL)isAvailable 36 | { 37 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 38 | NSString *endpointURLString = [defaults stringForKey:@"WordpressURL"]; 39 | NSURL *endpointURL = [NSURL URLWithString:endpointURLString]; 40 | NSString *userName = [defaults stringForKey:@"WordpressUser"]; 41 | NSString *password = [defaults stringForKey:@"WordpressPassword"]; 42 | 43 | NSString *scheme = [endpointURL scheme]; 44 | 45 | if (!endpointURL || !([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"])) 46 | { 47 | return NO; 48 | } 49 | 50 | if (![userName length]) 51 | { 52 | return NO; 53 | } 54 | 55 | if (![password length]) 56 | { 57 | return NO; 58 | } 59 | 60 | return YES; 61 | } 62 | 63 | + (BOOL)supportedOnMac; 64 | { 65 | return YES; 66 | } 67 | 68 | + (BOOL)supportedOniOS; 69 | { 70 | return NO; 71 | } 72 | 73 | + (NSString*)macSettingsViewControllerClassName; 74 | { 75 | return @"QRWordpressSubmissionServicePreferencesViewController"; 76 | } 77 | 78 | + (NSString*)iosSettingsViewControllerClassName; 79 | { 80 | return nil; 81 | } 82 | 83 | + (id)settingsIconPlatformAppropriateImage; 84 | { 85 | if (NSClassFromString(@"NSImage")) 86 | { 87 | return [NSImage imageNamed:@"WordpressLogoTemplate"]; 88 | } 89 | return nil; 90 | } 91 | 92 | - (CGFloat)progress 93 | { 94 | return 0; 95 | } 96 | 97 | - (SubmissionStatus)submissionStatus 98 | { 99 | return submissionStatusCompleted; 100 | } 101 | 102 | +(NSSet *)hardDependencies 103 | { 104 | return [NSSet setWithObject:QRRadarSubmissionServiceIdentifier]; 105 | } 106 | 107 | +(NSSet *)softDependencies 108 | { 109 | return [NSSet setWithObject:QROpenRadarSubmissionServiceIdentifier]; 110 | } 111 | 112 | - (void)submitAsyncWithProgressBlock:(void (^)())progressBlock completionBlock:(void (^)(BOOL, NSError *))completionBlock 113 | { 114 | // TODO: implement wordpress submission here 115 | 116 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 117 | NSString *endpointURLString = [defaults stringForKey:@"WordpressURL"]; 118 | NSURL *endpointURL = [NSURL URLWithString:endpointURLString]; 119 | NSString *userName = [defaults stringForKey:@"WordpressUser"]; 120 | NSString *password = [defaults stringForKey:@"WordpressPassword"]; 121 | 122 | NSString *scheme = [endpointURL scheme]; 123 | 124 | if (!endpointURL || !([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"])) 125 | { 126 | return; 127 | } 128 | 129 | if (![userName length]) 130 | { 131 | return; 132 | } 133 | 134 | if (![password length]) 135 | { 136 | return; 137 | } 138 | 139 | DTWordpress *wordpress = [[DTWordpress alloc] initWithEndpointURL:endpointURL]; 140 | wordpress.userName = userName; 141 | wordpress.password = password; 142 | 143 | NSString *title = [NSString stringWithFormat:@"Radar: %@", self.radar.title]; 144 | NSMutableString *description = [NSMutableString string]; 145 | 146 | [description appendFormat:@"Submitted as rdar://%ld", self.radar.radarNumber]; 147 | 148 | if (self.radar.submittedToOpenRadar) 149 | { 150 | [description appendFormat:@" and to OpenRadar", self.radar.radarNumber]; 151 | } 152 | 153 | [description appendString:@".\n\n"]; 154 | 155 | [description appendString:self.radar.body]; 156 | 157 | NSDictionary *content = @{@"title":title, @"description":description, @"post_type":@"post"}; 158 | 159 | [wordpress newPostWithContent:content shouldPublish:NO completion:^(NSInteger postID, NSError *error) { 160 | if (error) 161 | { 162 | // wrap authentication error 163 | if (error.code == 403) 164 | { 165 | error = [NSError authenticationErrorWithServiceIdentifier:QRWordpressSubmissionServiceIdentifier underlyingError:error]; 166 | } 167 | 168 | progressBlock(); 169 | completionBlock(NO, error); 170 | } 171 | else 172 | { 173 | NSLog(@"new post id %ld", (long)postID); 174 | 175 | progressBlock(); 176 | completionBlock(YES, nil); 177 | } 178 | }]; 179 | } 180 | 181 | 182 | @end 183 | -------------------------------------------------------------------------------- /QuickRadar/QRWordpressSubmissionServicePreferencesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRWordpressSubmissionServicePreferencesViewController.h 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 29/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QRWordpressSubmissionServicePreferencesViewController : NSViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /QuickRadar/QRWordpressSubmissionServicePreferencesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRRadarSubmissionServicePreferencesViewController.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 29/06/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "QRWordpressSubmissionServicePreferencesViewController.h" 10 | 11 | @interface QRWordpressSubmissionServicePreferencesViewController () 12 | 13 | @end 14 | 15 | @implementation QRWordpressSubmissionServicePreferencesViewController 16 | 17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 18 | { 19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 20 | if (self) { 21 | // Initialization code here. 22 | } 23 | 24 | return self; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /QuickRadar/QuickRadar-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | Appicon.icns 11 | CFBundleIdentifier 12 | com.quickradar.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 beta 3 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleTypeRole 27 | Viewer 28 | CFBundleURLName 29 | rdar 30 | CFBundleURLSchemes 31 | 32 | rdar 33 | 34 | 35 | 36 | CFBundleVersion 37 | 18 38 | LSMinimumSystemVersion 39 | ${MACOSX_DEPLOYMENT_TARGET} 40 | LSUIElement 41 | 42 | NSAppTransportSecurity 43 | 44 | NSAllowsArbitraryLoads 45 | 46 | 47 | NSHumanReadableCopyright 48 | Copyright (c) 2012, Amy Worrall. All rights reserved. 49 | NSMainNibFile 50 | MainMenu 51 | NSPrincipalClass 52 | NSApplication 53 | SUFeedURL 54 | http://www.quickradar.com/appcast.xml 55 | SUPublicDSAKeyFile 56 | dsa_pub.pem 57 | 58 | 59 | -------------------------------------------------------------------------------- /QuickRadar/QuickRadar-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'QuickRadar' target in the 'QuickRadar' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /QuickRadar/SGHotKeyCenter/SGHotKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // SGHotKey.h 3 | // SGHotKeyCenter 4 | // 5 | // Created by Justin Williams on 7/26/09. 6 | // Copyright 2009 Second Gear. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "SGKeyCombo.h" 12 | 13 | @interface SGHotKey : NSObject { 14 | NSString *identifier; 15 | NSString *name; 16 | 17 | SGKeyCombo *keyCombo; 18 | id target; 19 | SEL action; 20 | 21 | EventHotKeyID hotKeyID; 22 | } 23 | 24 | @property (nonatomic, copy) NSString *identifier; 25 | @property (nonatomic, copy) NSString *name; 26 | @property (nonatomic, retain) SGKeyCombo *keyCombo; 27 | @property (nonatomic, assign) id target; 28 | @property (nonatomic, assign) SEL action; 29 | @property (nonatomic, assign) EventHotKeyID hotKeyID; 30 | 31 | - (id)initWithIdentifier:(id)theIdentifier keyCombo:(SGKeyCombo *)theCombo; 32 | - (id)initWithIdentifier:(id)theIdentifier keyCombo:(SGKeyCombo *)theCombo target:(id)theTarget action:(SEL)theAction; 33 | - (BOOL)matchesHotKeyID:(EventHotKeyID)theKeyID; 34 | - (void)invoke; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /QuickRadar/SGHotKeyCenter/SGHotKey.m: -------------------------------------------------------------------------------- 1 | // 2 | // SGHotKey.m 3 | // SGHotKeyCenter 4 | // 5 | // Created by Justin Williams on 7/26/09. 6 | // Copyright 2009 Second Gear. All rights reserved. 7 | // 8 | 9 | #import "SGHotKey.h" 10 | #import "SGKeyCombo.h" 11 | 12 | @implementation SGHotKey 13 | 14 | @synthesize identifier; 15 | @synthesize name; 16 | @synthesize keyCombo; 17 | @synthesize target; 18 | @synthesize action; 19 | @synthesize hotKeyID; 20 | 21 | - (void)dealloc { 22 | [identifier release]; 23 | [name release]; 24 | [keyCombo release]; 25 | [super dealloc]; 26 | } 27 | 28 | - (id)init { 29 | return [self initWithIdentifier:nil keyCombo:nil]; 30 | } 31 | 32 | - (id)initWithIdentifier:(id)theIdentifier keyCombo:(SGKeyCombo *)theCombo { 33 | if ((self = [super init])) { 34 | self.identifier = theIdentifier; 35 | self.keyCombo = theCombo; 36 | } 37 | 38 | return self; 39 | } 40 | - (id)initWithIdentifier:(id)theIdentifier keyCombo:(SGKeyCombo *)theCombo target:(id)theTarget action:(SEL)theAction { 41 | if ((self = [super init])) { 42 | self.identifier = theIdentifier; 43 | self.keyCombo = theCombo; 44 | self.target = theTarget; 45 | self.action = theAction; 46 | } 47 | 48 | return self; 49 | } 50 | 51 | - (BOOL)matchesHotKeyID:(EventHotKeyID)theKeyID { 52 | return (hotKeyID.id == theKeyID.id) && (hotKeyID.signature == theKeyID.signature); 53 | } 54 | 55 | - (void)invoke { 56 | // [self.target performSelector:self.action withObject:self]; 57 | [NSApp sendAction:self.action to:self.target from:self]; 58 | } 59 | 60 | - (void)setKeyCombo:(SGKeyCombo *)theKeyCombo { 61 | if (theKeyCombo == nil) 62 | theKeyCombo = [SGKeyCombo clearKeyCombo]; 63 | 64 | keyCombo = [theKeyCombo retain]; 65 | } 66 | 67 | - (NSString *)description { 68 | return [NSString stringWithFormat: @"<%@: %@, %@>", 69 | NSStringFromClass([self class]), 70 | self.identifier, 71 | self.keyCombo]; 72 | } 73 | 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /QuickRadar/SGHotKeyCenter/SGHotKeyCenter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SGHotKeyCenter.h 3 | // SGHotKeyCenter 4 | // 5 | // Created by Justin Williams on 7/26/09. 6 | // Copyright 2009 Second Gear. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SGHotKey; 12 | 13 | @interface SGHotKeyCenter : NSObject { 14 | NSMutableDictionary *hotKeys; // Keys are NSValue of EventHotKeyRef 15 | BOOL eventHandlerInstalled; 16 | BOOL hasInited; 17 | } 18 | 19 | + (SGHotKeyCenter *)sharedCenter; 20 | 21 | - (BOOL)registerHotKey:(SGHotKey *)theHotKey; 22 | - (void)unregisterHotKey:(SGHotKey *)theHotKey; 23 | 24 | - (NSArray *)allHotKeys; 25 | - (SGHotKey *)hotKeyWithIdentifier:(id)theIdentifier; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /QuickRadar/SGHotKeyCenter/SGKeyCodeTranslator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SGKeyCodeTranslator.h 3 | // SGHotKeyCenter 4 | // 5 | // Created by Justin Williams on 7/26/09. 6 | // Copyright 2009 Second Gear. All rights reserved. 7 | // 8 | 9 | #import 10 | #include 11 | #include 12 | 13 | 14 | @interface SGKeyCodeTranslator : NSObject { 15 | TISInputSourceRef keyboardLayout; 16 | const UCKeyboardLayout *keyboardLayoutData; 17 | NSUInteger keyTranslateState; 18 | UInt32 deadKeyState; 19 | } 20 | 21 | @property (nonatomic, assign) TISInputSourceRef keyboardLayout; 22 | 23 | + (id)currentTranslator; 24 | 25 | - (id)initWithKeyboardLayout:(TISInputSourceRef)theLayout; 26 | - (NSString *)translateKeyCode:(short)theKeyCode; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /QuickRadar/SGHotKeyCenter/SGKeyCodeTranslator.m: -------------------------------------------------------------------------------- 1 | // 2 | // SGKeyCodeTranslator.m 3 | // SGHotKeyCenter 4 | // 5 | // Created by Justin Williams on 7/26/09. 6 | // Copyright 2009 Second Gear. All rights reserved. 7 | // 8 | 9 | #import "SGKeyCodeTranslator.h" 10 | 11 | 12 | @implementation SGKeyCodeTranslator 13 | 14 | @synthesize keyboardLayout; 15 | 16 | + (id)currentTranslator { 17 | static SGKeyCodeTranslator *currentTranslator = nil; 18 | TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource(); 19 | 20 | if (currentTranslator == nil) { 21 | currentTranslator = [[SGKeyCodeTranslator alloc] initWithKeyboardLayout:currentKeyboardLayout]; 22 | } else if ([currentTranslator keyboardLayout] != currentKeyboardLayout) { 23 | [currentTranslator release]; 24 | currentTranslator = [[SGKeyCodeTranslator alloc] initWithKeyboardLayout:currentKeyboardLayout]; 25 | } 26 | 27 | return currentTranslator; 28 | } 29 | 30 | - (id)initWithKeyboardLayout:(TISInputSourceRef)theLayout { 31 | if ((self = [super init]) != nil) { 32 | keyboardLayout = theLayout; 33 | CFDataRef uchr = TISGetInputSourceProperty(keyboardLayout, kTISPropertyUnicodeKeyLayoutData); 34 | keyboardLayoutData = (const UCKeyboardLayout *)CFDataGetBytePtr(uchr); 35 | } 36 | 37 | return self; 38 | } 39 | 40 | 41 | - (NSString *)translateKeyCode:(short)keyCode { 42 | UniCharCount maxStringLength = 4, actualStringLength; 43 | UniChar unicodeString[4]; 44 | 45 | UCKeyTranslate(keyboardLayoutData, 46 | keyCode, 47 | kUCKeyActionDisplay, 48 | 0, 49 | LMGetKbdType(), 50 | kUCKeyTranslateNoDeadKeysBit, 51 | &deadKeyState, 52 | maxStringLength, 53 | &actualStringLength, 54 | unicodeString); 55 | 56 | return [NSString stringWithCharacters:unicodeString length:1]; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /QuickRadar/SGHotKeyCenter/SGKeyCodes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | padKeyString 6 | Pad 7 | padKeys 8 | 9 | 65 10 | 67 11 | 69 12 | 75 13 | 78 14 | 81 15 | 82 16 | 83 17 | 84 18 | 85 19 | 86 20 | 87 21 | 88 22 | 89 23 | 91 24 | 92 25 | 26 | unmappedKeys 27 | 28 | 100 29 | F8 30 | 101 31 | F9 32 | 103 33 | F11 34 | 105 35 | F13 36 | 107 37 | F14 38 | 109 39 | F10 40 | 111 41 | F12 42 | 113 43 | F15 44 | 114 45 | Ins 46 | 115 47 | Home 48 | 116 49 | Page Up 50 | 117 51 | Del 52 | 118 53 | F4 54 | 119 55 | End 56 | 120 57 | F2 58 | 121 59 | Page Down 60 | 122 61 | F1 62 | 123 63 | Left Arrow 64 | 124 65 | Right Arrow 66 | 125 67 | Down Arrow 68 | 126 69 | Up Arrow 70 | 36 71 | Return 72 | 48 73 | Tab 74 | 49 75 | Space 76 | 51 77 | Backspace 78 | 53 79 | ESC 80 | 71 81 | Clear 82 | 76 83 | Pad Enter 84 | 96 85 | F5 86 | 97 87 | F6 88 | 98 89 | F7 90 | 99 91 | F3 92 | 93 | version 94 | 1 95 | 96 | 97 | -------------------------------------------------------------------------------- /QuickRadar/SGHotKeyCenter/SGKeyCombo.h: -------------------------------------------------------------------------------- 1 | // 2 | // SGKeyCombo.h 3 | // SGHotKeyCenter 4 | // 5 | // Created by Justin Williams on 7/26/09. 6 | // Copyright 2009 Second Gear. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SGKeyCombo : NSObject { 12 | NSInteger keyCode; 13 | NSInteger modifiers; 14 | } 15 | 16 | @property (nonatomic, assign) NSInteger keyCode; 17 | @property (nonatomic, assign) NSInteger modifiers; 18 | 19 | + (id)clearKeyCombo; 20 | + (id)keyComboWithKeyCode:(NSInteger)theKeyCode modifiers:(NSInteger)theModifiers; 21 | - (id)initWithKeyCode:(NSInteger)theKeyCode modifiers:(NSInteger)theModifiers; 22 | 23 | - (id)initWithPlistRepresentation:(id)thePlist; 24 | - (id)plistRepresentation; 25 | 26 | - (BOOL)isEqual:(SGKeyCombo *)theCombo; 27 | 28 | - (BOOL)isClearCombo; 29 | - (BOOL)isValidHotKeyCombo; 30 | 31 | @end 32 | 33 | @interface SGKeyCombo (UserDisplayAdditions) 34 | - (NSString *)description; 35 | - (NSString *)keyCodeString; 36 | - (NSUInteger)modifierMask; 37 | @end 38 | 39 | -------------------------------------------------------------------------------- /QuickRadar/SRKeyCodeTransformer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRKeyCodeTransformer.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | 16 | @interface SRKeyCodeTransformer : NSValueTransformer {} @end 17 | -------------------------------------------------------------------------------- /QuickRadar/SRRecorderCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRRecorderCell.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | #import "SRCommon.h" 16 | 17 | #define SRMinWidth 50 18 | #define SRMaxHeight 22 19 | 20 | #define SRTransitionFPS 30.0f 21 | #define SRTransitionDuration 0.35f 22 | //#define SRTransitionDuration 2.35 23 | #define SRTransitionFrames (SRTransitionFPS*SRTransitionDuration) 24 | #define SRAnimationAxisIsY YES 25 | #define ShortcutRecorderNewStyleDrawing 26 | 27 | #define SRAnimationOffsetRect(X,Y) (SRAnimationAxisIsY ? NSOffsetRect(X,0.0f,-NSHeight(Y)) : NSOffsetRect(X,NSWidth(Y),0.0f)) 28 | 29 | @class SRRecorderControl, SRValidator; 30 | 31 | enum SRRecorderStyle { 32 | SRGradientBorderStyle = 0, 33 | SRGreyStyle = 1 34 | }; 35 | typedef enum SRRecorderStyle SRRecorderStyle; 36 | 37 | @interface SRRecorderCell : NSActionCell 38 | { 39 | NSGradient *recordingGradient; 40 | NSString *autosaveName; 41 | 42 | BOOL isRecording; 43 | BOOL mouseInsideTrackingArea; 44 | BOOL mouseDown; 45 | 46 | SRRecorderStyle style; 47 | 48 | BOOL isAnimating; 49 | CGFloat transitionProgress; 50 | BOOL isAnimatingNow; 51 | BOOL isAnimatingTowardsRecording; 52 | BOOL comboJustChanged; 53 | 54 | NSTrackingRectTag removeTrackingRectTag; 55 | NSTrackingRectTag snapbackTrackingRectTag; 56 | 57 | KeyCombo keyCombo; 58 | BOOL hasKeyChars; 59 | NSString *keyChars; 60 | NSString *keyCharsIgnoringModifiers; 61 | 62 | NSUInteger allowedFlags; 63 | NSUInteger requiredFlags; 64 | NSUInteger recordingFlags; 65 | 66 | BOOL allowsKeyOnly; 67 | BOOL escapeKeysRecord; 68 | 69 | NSSet *cancelCharacterSet; 70 | 71 | SRValidator *validator; 72 | 73 | IBOutlet id delegate; 74 | BOOL globalHotKeys; 75 | void *hotKeyModeToken; 76 | } 77 | 78 | - (void)resetTrackingRects; 79 | 80 | #pragma mark *** Aesthetics *** 81 | 82 | + (BOOL)styleSupportsAnimation:(SRRecorderStyle)style; 83 | 84 | - (BOOL)animates; 85 | - (void)setAnimates:(BOOL)an; 86 | - (SRRecorderStyle)style; 87 | - (void)setStyle:(SRRecorderStyle)nStyle; 88 | 89 | #pragma mark *** Delegate *** 90 | 91 | - (id)delegate; 92 | - (void)setDelegate:(id)aDelegate; 93 | 94 | #pragma mark *** Responder Control *** 95 | 96 | - (BOOL)becomeFirstResponder; 97 | - (BOOL)resignFirstResponder; 98 | 99 | #pragma mark *** Key Combination Control *** 100 | 101 | - (BOOL)performKeyEquivalent:(NSEvent *)theEvent; 102 | - (void)flagsChanged:(NSEvent *)theEvent; 103 | 104 | - (NSUInteger)allowedFlags; 105 | - (void)setAllowedFlags:(NSUInteger)flags; 106 | 107 | - (NSUInteger)requiredFlags; 108 | - (void)setRequiredFlags:(NSUInteger)flags; 109 | 110 | - (BOOL)allowsKeyOnly; 111 | - (void)setAllowsKeyOnly:(BOOL)nAllowsKeyOnly; 112 | - (void)setAllowsKeyOnly:(BOOL)nAllowsKeyOnly escapeKeysRecord:(BOOL)nEscapeKeysRecord; 113 | - (BOOL)escapeKeysRecord; 114 | - (void)setEscapeKeysRecord:(BOOL)nEscapeKeysRecord; 115 | 116 | - (BOOL)canCaptureGlobalHotKeys; 117 | - (void)setCanCaptureGlobalHotKeys:(BOOL)inState; 118 | 119 | - (KeyCombo)keyCombo; 120 | - (void)setKeyCombo:(KeyCombo)aKeyCombo; 121 | 122 | #pragma mark *** Autosave Control *** 123 | 124 | - (NSString *)autosaveName; 125 | - (void)setAutosaveName:(NSString *)aName; 126 | 127 | // Returns the displayed key combination if set 128 | - (NSString *)keyComboString; 129 | 130 | - (NSString *)keyChars; 131 | - (NSString *)keyCharsIgnoringModifiers; 132 | 133 | @end 134 | 135 | // Delegate Methods 136 | @interface NSObject (SRRecorderCellDelegate) 137 | - (BOOL)shortcutRecorderCell:(SRRecorderCell *)aRecorderCell isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason; 138 | - (void)shortcutRecorderCell:(SRRecorderCell *)aRecorderCell keyComboDidChange:(KeyCombo)newCombo; 139 | @end 140 | -------------------------------------------------------------------------------- /QuickRadar/SRRecorderControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRRecorderControl.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | #import "SRRecorderCell.h" 16 | 17 | @interface SRRecorderControl : NSControl 18 | { 19 | IBOutlet id delegate; 20 | } 21 | 22 | #pragma mark *** Aesthetics *** 23 | - (BOOL)animates; 24 | - (void)setAnimates:(BOOL)an; 25 | - (SRRecorderStyle)style; 26 | - (void)setStyle:(SRRecorderStyle)nStyle; 27 | 28 | #pragma mark *** Delegate *** 29 | - (id)delegate; 30 | - (void)setDelegate:(id)aDelegate; 31 | 32 | #pragma mark *** Key Combination Control *** 33 | 34 | - (NSUInteger)allowedFlags; 35 | - (void)setAllowedFlags:(NSUInteger)flags; 36 | 37 | - (BOOL)allowsKeyOnly; 38 | - (void)setAllowsKeyOnly:(BOOL)nAllowsKeyOnly escapeKeysRecord:(BOOL)nEscapeKeysRecord; 39 | - (BOOL)escapeKeysRecord; 40 | 41 | - (BOOL)canCaptureGlobalHotKeys; 42 | - (void)setCanCaptureGlobalHotKeys:(BOOL)inState; 43 | 44 | - (NSUInteger)requiredFlags; 45 | - (void)setRequiredFlags:(NSUInteger)flags; 46 | 47 | - (KeyCombo)keyCombo; 48 | - (void)setKeyCombo:(KeyCombo)aKeyCombo; 49 | 50 | - (NSString *)keyChars; 51 | - (NSString *)keyCharsIgnoringModifiers; 52 | 53 | #pragma mark *** Autosave Control *** 54 | 55 | - (NSString *)autosaveName; 56 | - (void)setAutosaveName:(NSString *)aName; 57 | 58 | #pragma mark - 59 | 60 | // Returns the displayed key combination if set 61 | - (NSString *)keyComboString; 62 | 63 | #pragma mark *** Conversion Methods *** 64 | 65 | - (NSUInteger)cocoaToCarbonFlags:(NSUInteger)cocoaFlags; 66 | - (NSUInteger)carbonToCocoaFlags:(NSUInteger)carbonFlags; 67 | 68 | #pragma mark *** Binding Methods *** 69 | 70 | - (NSDictionary *)objectValue; 71 | - (void)setObjectValue:(NSDictionary *)shortcut; 72 | 73 | @end 74 | 75 | // Delegate Methods 76 | @interface NSObject (SRRecorderDelegate) 77 | - (BOOL)shortcutRecorder:(SRRecorderControl *)aRecorder isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason; 78 | - (void)shortcutRecorder:(SRRecorderControl *)aRecorder keyComboDidChange:(KeyCombo)newKeyCombo; 79 | @end 80 | -------------------------------------------------------------------------------- /QuickRadar/SRValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRValidator.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | 16 | @interface SRValidator : NSObject { 17 | id delegate; 18 | } 19 | 20 | - (id) initWithDelegate:(id)theDelegate; 21 | 22 | - (BOOL) isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags error:(NSError **)error; 23 | - (BOOL) isKeyCode:(NSInteger)keyCode andFlags:(NSUInteger)flags takenInMenu:(NSMenu *)menu error:(NSError **)error; 24 | 25 | - (id) delegate; 26 | - (void) setDelegate: (id) theDelegate; 27 | 28 | @end 29 | 30 | #pragma mark - 31 | 32 | @interface NSObject( SRValidation ) 33 | - (BOOL) shortcutValidator:(SRValidator *)validator isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason; 34 | @end 35 | -------------------------------------------------------------------------------- /QuickRadar/WarningIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/QuickRadar/WarningIcon.png -------------------------------------------------------------------------------- /QuickRadar/WordpressLogoTemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/QuickRadar/WordpressLogoTemplate.png -------------------------------------------------------------------------------- /QuickRadar/dsa_pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIDPDCCAi4GByqGSM44BAEwggIhAoIBAQD1eR74QXlxsQ/wEmhRZnu7mKlEYH3x 3 | TG3SysvEDSE+D9tCoggVgo4P9V+pT+HkNItTG/xnIDrPr1cbrVRfnEayi8JQQPpb 4 | zUsqrwUvMAspYaGrO8YOlVG2fofuhCKC9U/rMzuGgc4ZaaLjo7fbtqdMYqLKl0VX 5 | UHT5NuFPH8A9BeBWoLldgQ0/e9jqqPDRi4BeJQLfZG0Cxz4lPOIMoMV9IEoXDzbc 6 | Zx/nGgVXdMkB22hOLGwAAactSPIxV7RcMUek74TlHMlnmxbSwQP6Ufvel0rejamR 7 | XLFLZUK/7OGNUUejriqh6lD+rXZpYe322ND8Qcv/SL6/bR/lOH23SF9BAhUAnbrh 8 | 6Yh8x5LAC6VCkz5UAI29VMUCggEBAJEjXjbtfY3Z0gVHLbrq1GAIpGxFVHuEVDeB 9 | rhmMY1EMBgXgSgqyO3uX5CA4udZPRixvSvxZYQNIUzF3ORH9oxmyVi7eXpcMhFwZ 10 | GrlVOvNNggiH+oIS6C/F4dkDuPtLB/bQevdTXYKw1KE+VLzHdIpMKoNB7IyDMTNi 11 | b9QcMg1Y98pr/vGfiQyll3G4oHTWYNZNM5jYx4Ffmr6tzbJcOaVxyR8Wu6DdS04M 12 | x8JKn0FqOJVRUqpU8QesetZ1/NDDYzMcmfMHfz5PQ4eYmhrksgTofXEOT6LhjKAb 13 | zoRXJd6e/J+cpUSI8BNc1wj8LSTmdkEZNxdbdr8MWavUquGx2l4DggEGAAKCAQEA 14 | 30Dhe8BRFyfJIDnNqj/yiqMlZHtEWPlbjX633d7KekIaLa8E+SBGcklZum3K0nyx 15 | IEz/K8lqccrC9vzTAMt5YvXL0YyIPr3UrFua9vTay89DGpAp6m3QsUl8plZe6rtC 16 | ZpsjIOL625zACQNkDxZzWxzksWUB114wlR3Q0jVqa73sjws2OiOM5NhDXRnUA8J5 17 | +66e6AB7+JL4r+09G6yzOBGLpaHhjLTiXZ6896jIztYS10uUY/P57idpWh7IV6FU 18 | y/MhUbgt2rLcOAVSi9ALn7qYbBT3m7Mua2nCpYlUwn/8AkFRQUcHmNaUvLH4+GGu 19 | cOaxSOwCww01bcEYbV3/Tg== 20 | -----END PUBLIC KEY----- 21 | -------------------------------------------------------------------------------- /QuickRadar/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw11900\paperh16840\vieww9600\viewh8400\viewkind0 5 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 6 | 7 | \f0\b\fs24 \cf0 QuickRadar contributors: 8 | \b0 \ 9 | \ 10 | Amy Worrall \'97 @amyruthworrall\ 11 | Graham Lee \'97 @secboffin\ 12 | \pard\pardeftab720 13 | \cf0 Doug Russell \'97\'a0@halfliterate\ 14 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 15 | \cf0 Dominik Pich \'97 @daijdjan\ 16 | \pard\pardeftab720 17 | \cf0 Michael Gorbach \'97\'a0@mgorbach\ 18 | Balazs Faludi \'97\'a0@drummerbf\ 19 | Ortwin Gentz \'97 \uc0\u8207 @ortwingentz\ 20 | Mike Abdullah \'97\'a0@mikeabdullah} -------------------------------------------------------------------------------- /QuickRadar/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // QuickRadar 4 | // 5 | // Created by Amy Worrall on 15/05/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QuickRadar 2 | ========== 3 | 4 | Mac app to simplify posting bug reports to Apple's Radar bug tracking system. It provides a global hotkey to open a window in which to enter a bug report, which can be easily submitted to Apple. 5 | 6 | More info at http://www.quickradar.com/ 7 | 8 | Status 9 | ====== 10 | 11 | The app is currently VERY rough-and-ready. It has very little error handling worth speaking of. It almost certainly can't deal with any Radar of the type where you have to upload a crash report. **Use at your own risk!** 12 | 13 | The code is in just as bad a state. The web scraping is done in one big method which chains xpaths together to plot a course through the web site, and currently it spits out all the logs I was using while trying to get something that could post to Radar. 14 | 15 | That said, I do plan to develop it a lot more. I'd also welcome any help and contributions. I'm sharing it now because I've reached the stage where it can post Radars. 16 | 17 | Using QuickRadar 18 | ================ 19 | 20 | Build and run the app. It is meant to run in the background, and does not open any windows at launch, it only displays a menubar icon. 21 | 22 | First, choose "Login Details…" from the QuickBug menu. In there, fill in your username and password for Apple's web-based bug reporter. Make sure you get them right! 23 | 24 | To invoke QuickRadar, press command-option-control-space (you can change the hotkey from the menu). A window will pop up for you to fill in the details of your radar. At the moment, don't choose any Classification that would make the bug reporter require a file upload (such as Crash/Hang/Data Loss), because QuickRadar doesn't support them yet, nor does it have any error handling worth speaking of. 25 | 26 | Once you've entered the details, hit Submit. Sadly this bit is anything but quick: in the background, QuickRadar has to log in to the bug reporter web page, fetch the New Problem page, fill it in, and submit the form. However, you can go and do something else while that's happening. Once it is done you'll get a notification. 27 | 28 | Roadmap 29 | ======= 30 | 31 | I hope to get it doing the following things: 32 | 33 | * Also posting to OpenRadar 34 | * Customise the lists of components etc to display your favourites at the top 35 | * Uploading config information for crash reports 36 | * Error handling, incorrect password dialog etc 37 | * And more! Maybe future versions will let you browse your submitted Radars too. 38 | 39 | Contributors 40 | ============ 41 | 42 | A list of contributors can be found in the QuickBug/en.lproj/Credits.rtf file. This file also displays in the About window when the app is running. If you contribute, feel free to add your name and Twitter handle there. -------------------------------------------------------------------------------- /Sparkle.framework/Headers: -------------------------------------------------------------------------------- 1 | Versions/Current/Headers -------------------------------------------------------------------------------- /Sparkle.framework/Modules: -------------------------------------------------------------------------------- 1 | Versions/Current/Modules -------------------------------------------------------------------------------- /Sparkle.framework/PrivateHeaders: -------------------------------------------------------------------------------- 1 | Versions/Current/PrivateHeaders -------------------------------------------------------------------------------- /Sparkle.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /Sparkle.framework/Sparkle: -------------------------------------------------------------------------------- 1 | Versions/Current/Sparkle -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUAppcast.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcast.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCAST_H 10 | #define SUAPPCAST_H 11 | 12 | #import 13 | #import "SUExport.h" 14 | 15 | @class SUAppcastItem; 16 | SU_EXPORT @interface SUAppcast : NSObject 17 | 18 | @property (copy) NSString *userAgentString; 19 | @property (copy) NSDictionary *httpHeaders; 20 | 21 | - (void)fetchAppcastFromURL:(NSURL *)url completionBlock:(void (^)(NSError *))err; 22 | - (SUAppcast *)copyWithoutDeltaUpdates; 23 | 24 | @property (readonly, copy) NSArray *items; 25 | @end 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUAppcastItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcastItem.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCASTITEM_H 10 | #define SUAPPCASTITEM_H 11 | 12 | #import 13 | #import "SUExport.h" 14 | 15 | SU_EXPORT @interface SUAppcastItem : NSObject 16 | @property (copy, readonly) NSString *title; 17 | @property (copy, readonly) NSDate *date; 18 | @property (copy, readonly) NSString *itemDescription; 19 | @property (strong, readonly) NSURL *releaseNotesURL; 20 | @property (copy, readonly) NSString *DSASignature; 21 | @property (copy, readonly) NSString *minimumSystemVersion; 22 | @property (copy, readonly) NSString *maximumSystemVersion; 23 | @property (strong, readonly) NSURL *fileURL; 24 | @property (copy, readonly) NSString *versionString; 25 | @property (copy, readonly) NSString *displayVersionString; 26 | @property (copy, readonly) NSDictionary *deltaUpdates; 27 | @property (strong, readonly) NSURL *infoURL; 28 | 29 | // Initializes with data from a dictionary provided by the RSS class. 30 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 31 | - (instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString **)error; 32 | 33 | @property (getter=isDeltaUpdate, readonly) BOOL deltaUpdate; 34 | @property (getter=isCriticalUpdate, readonly) BOOL criticalUpdate; 35 | @property (getter=isInformationOnlyUpdate, readonly) BOOL informationOnlyUpdate; 36 | 37 | // Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. 38 | @property (readonly, copy) NSDictionary *propertiesDictionary; 39 | 40 | - (NSURL *)infoURL; 41 | 42 | @end 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUErrors.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUErrors.h 3 | // Sparkle 4 | // 5 | // Created by C.W. Betts on 10/13/14. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUERRORS_H 10 | #define SUERRORS_H 11 | 12 | #import 13 | #import "SUExport.h" 14 | 15 | /** 16 | * Error domain used by Sparkle 17 | */ 18 | SU_EXPORT extern NSString *const SUSparkleErrorDomain; 19 | 20 | typedef NS_ENUM(OSStatus, SUError) { 21 | // Appcast phase errors. 22 | SUAppcastParseError = 1000, 23 | SUNoUpdateError = 1001, 24 | SUAppcastError = 1002, 25 | SURunningFromDiskImageError = 1003, 26 | 27 | // Downlaod phase errors. 28 | SUTemporaryDirectoryError = 2000, 29 | 30 | // Extraction phase errors. 31 | SUUnarchivingError = 3000, 32 | SUSignatureError = 3001, 33 | 34 | // Installation phase errors. 35 | SUFileCopyFailure = 4000, 36 | SUAuthenticationFailure = 4001, 37 | SUMissingUpdateError = 4002, 38 | SUMissingInstallerToolError = 4003, 39 | SURelaunchError = 4004, 40 | SUInstallationError = 4005, 41 | SUDowngradeError = 4006, 42 | 43 | // System phase errors 44 | SUSystemPowerOffError = 5000 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUExport.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUExport.h 3 | // Sparkle 4 | // 5 | // Created by Jake Petroules on 2014-08-23. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUEXPORT_H 10 | #define SUEXPORT_H 11 | 12 | #ifdef BUILDING_SPARKLE 13 | #define SU_EXPORT __attribute__((visibility("default"))) 14 | #else 15 | #define SU_EXPORT 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStandardVersionComparator.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUSTANDARDVERSIONCOMPARATOR_H 10 | #define SUSTANDARDVERSIONCOMPARATOR_H 11 | 12 | #import 13 | #import "SUExport.h" 14 | #import "SUVersionComparisonProtocol.h" 15 | 16 | /*! 17 | Sparkle's default version comparator. 18 | 19 | This comparator is adapted from MacPAD, by Kevin Ballard. 20 | It's "dumb" in that it does essentially string comparison, 21 | in components split by character type. 22 | */ 23 | SU_EXPORT @interface SUStandardVersionComparator : NSObject 24 | 25 | /*! 26 | Returns a singleton instance of the comparator. 27 | */ 28 | + (SUStandardVersionComparator *)defaultComparator; 29 | 30 | /*! 31 | Compares version strings through textual analysis. 32 | 33 | See the implementation for more details. 34 | */ 35 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; 36 | @end 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionComparisonProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUVERSIONCOMPARISONPROTOCOL_H 10 | #define SUVERSIONCOMPARISONPROTOCOL_H 11 | 12 | #import 13 | #import "SUExport.h" 14 | 15 | /*! 16 | Provides version comparison facilities for Sparkle. 17 | */ 18 | @protocol SUVersionComparison 19 | 20 | /*! 21 | An abstract method to compare two version strings. 22 | 23 | Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, 24 | and NSOrderedSame if they are equivalent. 25 | */ 26 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD! 27 | 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionDisplayProtocol.h 3 | // EyeTV 4 | // 5 | // Created by Uli Kusterer on 08.12.09. 6 | // Copyright 2009 Elgato Systems GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SUExport.h" 11 | 12 | /*! 13 | Applies special display formatting to version numbers. 14 | */ 15 | @protocol SUVersionDisplay 16 | 17 | /*! 18 | Formats two version strings. 19 | 20 | Both versions are provided so that important distinguishing information 21 | can be displayed while also leaving out unnecessary/confusing parts. 22 | */ 23 | - (void)formatVersion:(NSString **)inOutVersionA andVersion:(NSString **)inOutVersionB; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/Sparkle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sparkle.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SPARKLE_H 10 | #define SPARKLE_H 11 | 12 | #import 13 | 14 | // This list should include the shared headers. It doesn't matter if some of them aren't shared (unless 15 | // there are name-space collisions) so we can list all of them to start with: 16 | 17 | #import "SUAppcast.h" 18 | #import "SUAppcastItem.h" 19 | #import "SUStandardVersionComparator.h" 20 | #import "SUUpdater.h" 21 | #import "SUVersionComparisonProtocol.h" 22 | #import "SUVersionDisplayProtocol.h" 23 | #import "SUErrors.h" 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module Sparkle { 2 | umbrella header "Sparkle.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUnarchiver.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUUNARCHIVER_H 10 | #define SUUNARCHIVER_H 11 | 12 | #import 13 | 14 | @class SUHost; 15 | @protocol SUUnarchiverDelegate; 16 | 17 | @interface SUUnarchiver : NSObject 18 | 19 | @property (copy, readonly) NSString *archivePath; 20 | @property (copy, readonly) NSString *updateHostBundlePath; 21 | @property (copy, readonly) NSString *decryptionPassword; 22 | @property (weak) id delegate; 23 | 24 | + (SUUnarchiver *)unarchiverForPath:(NSString *)path updatingHostBundlePath:(NSString *)host withPassword:(NSString *)decryptionPassword; 25 | 26 | - (void)start; 27 | @end 28 | 29 | @protocol SUUnarchiverDelegate 30 | - (void)unarchiverDidFinish:(SUUnarchiver *)unarchiver; 31 | - (void)unarchiverDidFail:(SUUnarchiver *)unarchiver; 32 | @optional 33 | - (void)unarchiver:(SUUnarchiver *)unarchiver extractedProgress:(double)progress; 34 | @end 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 15E49a 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | Autoupdate 11 | CFBundleIconFile 12 | AppIcon 13 | CFBundleIdentifier 14 | org.sparkle-project.Sparkle.Autoupdate 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.14.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleSupportedPlatforms 24 | 25 | MacOSX 26 | 27 | CFBundleVersion 28 | 1.14.0 29 | DTCompiler 30 | com.apple.compilers.llvm.clang.1_0 31 | DTPlatformBuild 32 | 7C1002 33 | DTPlatformVersion 34 | GM 35 | DTSDKBuild 36 | 15C43 37 | DTSDKName 38 | macosx10.11 39 | DTXcode 40 | 0721 41 | DTXcodeBuild 42 | 7C1002 43 | LSBackgroundOnly 44 | 1 45 | LSMinimumSystemVersion 46 | 10.7 47 | LSUIElement 48 | 1 49 | NSMainNibFile 50 | MainMenu 51 | NSPrincipalClass 52 | NSApplication 53 | 54 | 55 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ca.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ca.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fi.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fi.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/he.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/he.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 15E49a 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | Sparkle 11 | CFBundleIdentifier 12 | org.sparkle-project.Sparkle 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Sparkle 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.14.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleSupportedPlatforms 24 | 25 | MacOSX 26 | 27 | CFBundleVersion 28 | 1.14.0 29 | DTCompiler 30 | com.apple.compilers.llvm.clang.1_0 31 | DTPlatformBuild 32 | 7C1002 33 | DTPlatformVersion 34 | GM 35 | DTSDKBuild 36 | 15C43 37 | DTSDKName 38 | macosx10.11 39 | DTXcode 40 | 0721 41 | DTXcodeBuild 42 | 7C1002 43 | 44 | 45 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/SUStatus.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/SUStatus.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ca.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ca.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fi.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/fi.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr_CA.lproj: -------------------------------------------------------------------------------- 1 | fr.lproj -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/he.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/he.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt.lproj: -------------------------------------------------------------------------------- 1 | pt_BR.lproj -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Sparkle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amyworrall/QuickRadar/8326a52ba49f47c1faad59117ead6935987f91e0/Sparkle.framework/Versions/A/Sparkle -------------------------------------------------------------------------------- /Sparkle.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | A --------------------------------------------------------------------------------