Add startup dialog for when no file access has been granted.
authorRobert Sesek <rsesek@bluestatic.org>
Sun, 8 Dec 2019 18:40:54 +0000 (13:40 -0500)
committerRobert Sesek <rsesek@bluestatic.org>
Sun, 15 Dec 2019 17:08:04 +0000 (12:08 -0500)
MacGDBp.xcodeproj/project.pbxproj
Source/AppDelegate.h
Source/AppDelegate.m
Source/FileAccessController.h [new file with mode: 0644]
Source/FileAccessController.m [new file with mode: 0644]
en.lproj/FileAccess.xib [new file with mode: 0644]

index 8bf4c27f3da0b682c906442f9cb73d8e42f758fc..287e2bb5e4e2d288303743a017f6130fff6948ae 100644 (file)
@@ -41,6 +41,8 @@
                1E9582670E2524AD001A3D89 /* PreferencesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E9582660E2524AD001A3D89 /* PreferencesController.m */; };
                1E9583200E2531BD001A3D89 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E95831F0E2531BD001A3D89 /* Sparkle.framework */; };
                1E95834C0E2531D5001A3D89 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1E95831F0E2531BD001A3D89 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
+               1E9C305B239D6DC600EFE30E /* FileAccess.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E9C3059239D6DC600EFE30E /* FileAccess.xib */; };
+               1E9C305F239D6E4200EFE30E /* FileAccessController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E9C305E239D6E4200EFE30E /* FileAccessController.m */; };
                1EB7BED50ECF3CA90033283A /* StackFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EB7BED40ECF3CA90033283A /* StackFrame.m */; };
                1EC1337E127DBB00007946FC /* VariableNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EC1337D127DBB00007946FC /* VariableNode.m */; };
                1EDA9CF812DD13B300596211 /* BSLineNumberRulerView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1EDA9CF712DD13B300596211 /* BSLineNumberRulerView.mm */; };
                1E9C3056239C3BED00EFE30E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Log.xib; sourceTree = "<group>"; };
                1E9C3057239C3BED00EFE30E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
                1E9C3058239C3BEE00EFE30E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Preferences.xib; sourceTree = "<group>"; };
+               1E9C305A239D6DC600EFE30E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/FileAccess.xib; sourceTree = "<group>"; };
+               1E9C305D239D6E4200EFE30E /* FileAccessController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FileAccessController.h; path = Source/FileAccessController.h; sourceTree = "<group>"; };
+               1E9C305E239D6E4200EFE30E /* FileAccessController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FileAccessController.m; path = Source/FileAccessController.m; sourceTree = "<group>"; };
                1EB7BED30ECF3CA90033283A /* StackFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StackFrame.h; path = Source/StackFrame.h; sourceTree = "<group>"; };
                1EB7BED40ECF3CA90033283A /* StackFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StackFrame.m; path = Source/StackFrame.m; sourceTree = "<group>"; };
                1EC1337C127DBB00007946FC /* VariableNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VariableNode.h; path = Source/VariableNode.h; sourceTree = "<group>"; };
                                1E1E53010DF9B89800D334F9 /* Breakpoints.xib */,
                                1E9582600E252474001A3D89 /* Preferences.xib */,
                                1E6B594A11610993001189D2 /* Log.xib */,
+                               1E9C3059239D6DC600EFE30E /* FileAccess.xib */,
                        );
                        name = Interfaces;
                        sourceTree = "<group>";
                                1E9582660E2524AD001A3D89 /* PreferencesController.m */,
                                1E67E6FB0F3C052000E68F1B /* PreferencesPathsArrayController.h */,
                                1E67E6FC0F3C052000E68F1B /* PreferencesPathsArrayController.m */,
+                               1E9C305D239D6E4200EFE30E /* FileAccessController.h */,
+                               1E9C305E239D6E4200EFE30E /* FileAccessController.m */,
                        );
                        name = Preferences;
                        sourceTree = "<group>";
                        buildActionMask = 2147483647;
                        files = (
                                1E42F1D70F53317B008412DB /* dsa_pub.pem in Resources */,
+                               1E9C305B239D6DC600EFE30E /* FileAccess.xib in Resources */,
                                8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
                                1EEBFBE50D34C793008F835B /* Debugger.xib in Resources */,
                                1EEBFC2B0D358EBD008F835B /* StepIn.png in Resources */,
                                1EDA9CF812DD13B300596211 /* BSLineNumberRulerView.mm in Sources */,
                                1E11814A1319805E003BFEF1 /* BSSourceViewTextView.m in Sources */,
                                1EE97E55232B11CB000FA8E6 /* ValidatingNSToolbarItem.m in Sources */,
+                               1E9C305F239D6E4200EFE30E /* FileAccessController.m in Sources */,
                                1E108E40136CC8B9002E34E0 /* EvalController.m in Sources */,
                                1E109019136DD92D002E34E0 /* StripLineBreaksValueTransformer.m in Sources */,
                                1EEBE842176FEA80003622C3 /* MessageQueue.m in Sources */,
                        name = Preferences.xib;
                        sourceTree = "<group>";
                };
+               1E9C3059239D6DC600EFE30E /* FileAccess.xib */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               1E9C305A239D6DC600EFE30E /* en */,
+                       );
+                       name = FileAccess.xib;
+                       sourceTree = "<group>";
+               };
                1EEBFBE30D34C793008F835B /* Debugger.xib */ = {
                        isa = PBXVariantGroup;
                        children = (
index 1350a984062290f232df2c24980652f9ab529af3..990107badd826367a47dc78d97cc9191ef722c7d 100644 (file)
 {
   IBOutlet DebuggerController* debugger;
   IBOutlet LoggingController* loggingController_;
-  PreferencesController* prefs;
 }
 
 @property (readonly) DebuggerController* debugger;
 @property (readonly) BreakpointController* breakpoint;
 @property (readonly) LoggingController* loggingController;
+@property (readonly) PreferencesController* prefsController;
 
 // Returns the instance of this class that is acting as the application's
 // delegate.
index cab45e77842b5012dce26a2fe5ade9544ba5076f..0ce51bb7e43eb426ff30373236d87f7379705ca2 100644 (file)
 
 #import <Sparkle/Sparkle.h>
 
+#import "FileAccessController.h"
 #import "PreferenceNames.h"
 
-@implementation AppDelegate
+@implementation AppDelegate {
+  PreferencesController* _prefsController;
+}
 
 @synthesize debugger;
 @synthesize breakpoint;
   return (AppDelegate*)[NSApp delegate];
 }
 
+- (PreferencesController*)prefsController
+{
+  if (!_prefsController)
+    _prefsController = [[PreferencesController alloc] init];
+  return _prefsController;
+}
+
 - (void)applicationDidFinishLaunching:(NSNotification*)notification
 {
   // Record whether this user ever used the beta VersionCast feed. In the
@@ -64,6 +74,8 @@
       [[feedURL absoluteString] rangeOfString:@"?unstable"].location != NSNotFound;
   [defaults setBool:usesUnstable forKey:kPrefUnstableVersionCast];
 
+  [FileAccessController maybeShowFileAccessDialog];
+
   [self _activateSecureFileAccess];
 }
 
  */
 - (IBAction)showPreferences:(id)sender
 {
-  if (!prefs)
-    prefs = [[PreferencesController alloc] init];
-  
-  [prefs showPreferencesWindow];
+  [self.prefsController showPreferencesWindow];
 }
 
 /**
diff --git a/Source/FileAccessController.h b/Source/FileAccessController.h
new file mode 100644 (file)
index 0000000..67cceab
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+* MacGDBp
+* Copyright (c) 2019, Blue Static <https://www.bluestatic.org>
+*
+* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
+* General Public License as published by the Free Software Foundation; either version 2 of the
+* License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program; if not,
+* write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#import <Cocoa/Cocoa.h>
+
+@interface FileAccessController : NSWindowController <NSWindowDelegate>
++ (void)maybeShowFileAccessDialog;
+
+- (IBAction)openFileAccess:(id)sender;
+@end
diff --git a/Source/FileAccessController.m b/Source/FileAccessController.m
new file mode 100644 (file)
index 0000000..871cfdd
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+* MacGDBp
+* Copyright (c) 2019, Blue Static <https://www.bluestatic.org>
+*
+* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
+* General Public License as published by the Free Software Foundation; either version 2 of the
+* License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with this program; if not,
+* write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#import "FileAccessController.h"
+
+#import "AppDelegate.h"
+#import "PreferenceNames.h"
+#import "PreferencesController.h"
+
+@implementation FileAccessController {
+  // Self-owned window controller reference. Cleared when |-windowWillClose:|.
+  FileAccessController* __strong _selfRef;
+}
+
++ (void)maybeShowFileAccessDialog
+{
+  NSDictionary* fileAccesses = [[NSUserDefaults standardUserDefaults] objectForKey:kPrefFileAccessBookmarks];
+  if ([fileAccesses count] == 0) {
+    FileAccessController* controller = [[FileAccessController alloc] init];
+    [controller.window center];
+    [controller showWindow:self];
+  }
+}
+
+- (instancetype)init
+{
+  if ((self = [self initWithWindowNibName:@"FileAccess"])) {
+    _selfRef = self;
+  }
+  return self;
+}
+
+- (IBAction)openFileAccess:(id)sender
+{
+  [self close];
+  PreferencesController* prefs = [[AppDelegate instance] prefsController];
+  [prefs showPreferencesWindow];
+  [prefs showFileAccess:sender];
+}
+
+- (void)windowWillClose:(NSNotification*)notification
+{
+  _selfRef = nil;
+}
+
+@end
diff --git a/en.lproj/FileAccess.xib b/en.lproj/FileAccess.xib
new file mode 100644 (file)
index 0000000..c3e53e9
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="FileAccessController">
+            <connections>
+                <outlet property="window" destination="QvC-M9-y7g" id="5iT-IM-Ttg"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <window title="File Access Needed" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" animationBehavior="default" id="QvC-M9-y7g">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES"/>
+            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+            <rect key="contentRect" x="196" y="240" width="480" height="238"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
+            <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
+                <rect key="frame" x="0.0" y="0.0" width="480" height="238"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" id="lhg-S3-BdC">
+                        <rect key="frame" x="18" y="43" width="444" height="151"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                        <textFieldCell key="cell" selectable="YES" id="5Cu-Jk-ZZM">
+                            <font key="font" usesAppearanceFont="YES"/>
+                            <string key="title">In order to show the source code for file breakpoints, MacGDBp needs to be granted permission to read the files.
+
+This is necessary because MacGDBp is sandboxed.
+
+Granting access to the root of your PHP projects folder is the simplest approach. But you always have complete control in Preferences over the files MacGDBp can read.</string>
+                            <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                        </textFieldCell>
+                    </textField>
+                    <button verticalHuggingPriority="750" id="AIn-4e-AOZ">
+                        <rect key="frame" x="245" y="13" width="221" height="32"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                        <buttonCell key="cell" type="push" title="Open File Access Preferences" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Fhl-Yt-VMg">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                            <string key="keyEquivalent" base64-UTF8="YES">
+DQ
+</string>
+                        </buttonCell>
+                        <connections>
+                            <action selector="openFileAccess:" target="-2" id="wwW-ri-EOZ"/>
+                        </connections>
+                    </button>
+                    <button verticalHuggingPriority="750" id="myT-z7-C4A">
+                        <rect key="frame" x="152" y="13" width="93" height="32"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                        <buttonCell key="cell" type="push" title="Not Now" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="eVp-7F-z3y">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                        </buttonCell>
+                        <connections>
+                            <action selector="performClose:" target="QvC-M9-y7g" id="GsJ-qU-lEU"/>
+                        </connections>
+                    </button>
+                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="auQ-AN-1N8">
+                        <rect key="frame" x="18" y="202" width="248" height="16"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                        <textFieldCell key="cell" lineBreakMode="clipping" title="MacGDBp Needs Read Access to Files" id="8d8-mv-qOp">
+                            <font key="font" metaFont="systemBold"/>
+                            <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                        </textFieldCell>
+                    </textField>
+                </subviews>
+            </view>
+            <connections>
+                <outlet property="delegate" destination="-2" id="K0J-qB-xpq"/>
+            </connections>
+            <point key="canvasLocation" x="139" y="124"/>
+        </window>
+    </objects>
+</document>