Skip to content

Commit

Permalink
Show alert when keynote is running in single window.
Browse files Browse the repository at this point in the history
  • Loading branch information
jkrumow committed Apr 18, 2023
1 parent 3c0e9a7 commit ae5f99b
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 40 deletions.
6 changes: 4 additions & 2 deletions ACShell.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@
3B1BB29529EDD80D00343D1F /* RsyncTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RsyncTask.h; sourceTree = "<group>"; };
3B1BB29729EDD80D00343D1F /* Keynote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Keynote.h; sourceTree = "<group>"; };
3B1BB29829EDD80D00343D1F /* KeynoteHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeynoteHandler.h; sourceTree = "<group>"; };
3B1BB29929EDD80D00343D1F /* KeynoteDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeynoteDelegate.h; sourceTree = "<group>"; };
3B1BB29929EDD80D00343D1F /* KeynotePlaybackDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeynotePlaybackDelegate.h; sourceTree = "<group>"; };
3B1BB29A29EDD80D00343D1F /* KeynoteHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeynoteHandler.m; sourceTree = "<group>"; };
3B49FD9929EDD5D100082582 /* ACShellAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACShellAppDelegate.h; sourceTree = "<group>"; };
3B49FDA829EDD5D100082582 /* ACShellAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ACShellAppDelegate.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -269,6 +269,7 @@
3B9FA6EC1C85C46A003D7EE0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3B9FA6FA1C85C62E003D7EE0 /* library.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = library.xml; path = Fixtures/library.xml; sourceTree = "<group>"; };
3BF60F1D29EE8D550084FFCC /* ACShell-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ACShell-Info.plist"; sourceTree = "<group>"; };
3BF7D4D029EEDEDE00DCE0D8 /* KeynoteLaunchDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeynoteLaunchDelegate.h; sourceTree = "<group>"; };
6379E763120C89B5006A6FEF /* acshell_add_ssh_host_key.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = acshell_add_ssh_host_key.m; sourceTree = "<group>"; };
6379E76C120C8B24006A6FEF /* acshell_addhostkey */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = acshell_addhostkey; sourceTree = BUILT_PRODUCTS_DIR; };
8D1107320486CEB800E47090 /* ACShell.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ACShell.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -556,9 +557,10 @@
isa = PBXGroup;
children = (
3B1BB29729EDD80D00343D1F /* Keynote.h */,
3B1BB29929EDD80D00343D1F /* KeynoteDelegate.h */,
3B1BB29929EDD80D00343D1F /* KeynotePlaybackDelegate.h */,
3B1BB29829EDD80D00343D1F /* KeynoteHandler.h */,
3B1BB29A29EDD80D00343D1F /* KeynoteHandler.m */,
3BF7D4D029EEDEDE00DCE0D8 /* KeynoteLaunchDelegate.h */,
);
path = Keynote;
sourceTree = "<group>";
Expand Down
4 changes: 2 additions & 2 deletions ACShell/Controllers/ACShellWindowController.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#import <Cocoa/Cocoa.h>
#import "RsyncController.h"
#import "KeynoteDelegate.h"
#import "KeynotePlaybackDelegate.h"
#import "EditWindowController.h"
#import "PresentationWindowController.h"
#import "PresentationLibrary.h"
Expand All @@ -18,7 +18,7 @@
NS_ASSUME_NONNULL_BEGIN

@interface ACShellWindowController : NSWindowController <NSToolbarItemValidation,
KeynoteDelegate, RsyncControllerDelegate, LibraryTableViewControllerDelegate>
KeynotePlaybackDelegate, RsyncControllerDelegate, LibraryTableViewControllerDelegate>

@property (strong) LibraryViewController *libraryViewController;
@property (strong) LibraryTableViewController *libraryTableViewController;
Expand Down
23 changes: 14 additions & 9 deletions ACShell/Controllers/ACShellWindowController.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ - (void)setupControllers
self.rsyncController.documentWindow = self.window;
self.rsyncController.delegate = self;

[[KeynoteHandler sharedHandler] launchWithDelegate:self];
KeynoteHandler.sharedHandler.launchDelegate = self;
[KeynoteHandler.sharedHandler launch];
[self loadLibrary];
}

Expand Down Expand Up @@ -206,7 +207,7 @@ - (BOOL)validateToolbarItem:(NSToolbarItem *)item


#pragma mark -
#pragma mark KeynoteDelegate Protocol Methods
#pragma mark KeynoteLaunchDelegate Protocol Methods

- (void) keynoteAppDidLaunch: (BOOL) success version:(NSString *)version {
if (success) {
Expand All @@ -218,12 +219,16 @@ - (void) keynoteAppDidLaunch: (BOOL) success version:(NSString *)version {
}
}

- (void)keynoteDidStartPresentation:(KeynoteHandler *)keynote {
// Do nothing
}

- (void)keynoteDidStopPresentation:(KeynoteHandler *)keynote {
// Do nothing
- (void)keynoteDidRunInWindow:(KeynoteHandler *)keynote {
NSAlert * alert = NSAlert.new;
alert.messageText = NSLocalizedString(ACSHELL_STR_PRESENTATION_IN_WINDOW, nil);
alert.informativeText = NSLocalizedString(ACSHELL_STR_PRESENTATION_IN_WINDOW_INFO, nil);
[alert addButtonWithTitle:NSLocalizedString(ACSHELL_STR_CANCEL, nil)];
alert.alertStyle = NSAlertStyleCritical;

[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
[KeynoteHandler.sharedHandler stop];
}];
}

#pragma mark -
Expand Down Expand Up @@ -251,7 +256,7 @@ - (void)libraryTableViewController:(LibraryTableViewController *)controller open
- (void)libraryTableViewController:(LibraryTableViewController *)controller playPresentation:(nonnull Presentation *)presentation
{
if (presentation.presentationFileExists) {
[[KeynoteHandler sharedHandler] play: presentation.absolutePresentationPath withDelegate: self];
[[KeynoteHandler sharedHandler] play: presentation.absolutePresentationPath];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#import "PresentationIntroViewDelegate.h"
#import "PresentationViewDataSource.h"
#import "PresentationViewDelegate.h"
#import "KeynoteDelegate.h"
#import "KeynotePlaybackDelegate.h"

@class KeynoteHandler;
@class PresentationIntroView;
Expand All @@ -23,7 +23,7 @@
@interface PresentationWindowController : NSWindowController
<PresentationViewDataSource, PresentationViewDelegate,
PresentationIntroViewDataSource, PresentationIntroViewDelegate,
KeynoteDelegate, NSWindowDelegate>
KeynotePlaybackDelegate, NSWindowDelegate>

@property (nonatomic, strong) KeynoteHandler *keynote;
@property (nonatomic, strong) NSArray *categories;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ - (id)init {
self = [super initWithWindowNibName:@"PresentationWindow"];
if (self != nil) {
self.keynote = [KeynoteHandler sharedHandler];
self.keynote.playbackDelegate = self;
self.window.delegate = self;
}
return self;
Expand Down Expand Up @@ -250,7 +251,7 @@ - (CALayer *)presentationView:(PresentationView *)aPresentationView hoverLayerFo
- (void)presentationView:(PresentationView *)aView didClickItemAtIndex:(NSInteger)index {
self.selectedPresentationIndex = index;
Presentation *presentation = [self.presentationsForSelectedCategory objectAtIndex:index];
[self.keynote play:presentation.absolutePresentationPath withDelegate: self];
[self.keynote play:presentation.absolutePresentationPath];
[self showActivityForItemAtIndex:index];
}

Expand Down Expand Up @@ -282,7 +283,6 @@ - (void)presentationViewDidClickBackButton:(PresentationView *)aView

#pragma mark - Keynote Handler Delegate


- (void)keynoteDidStartPresentation:(KeynoteHandler *)keynote {
[self highlightItemAtIndex:self.selectedPresentationIndex];
}
Expand All @@ -292,8 +292,4 @@ - (void)keynoteDidStopPresentation:(KeynoteHandler *)aKeynote {
[[self window] makeKeyAndOrderFront:nil];
}

- (void)keynoteAppDidLaunch:(BOOL)success version:(NSString *)version {
// Do nothing
}

@end
11 changes: 8 additions & 3 deletions ACShell/Keynote/KeynoteHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,23 @@

#import <Cocoa/Cocoa.h>
#import "Keynote.h"
#import "KeynoteDelegate.h"
#import "KeynoteLaunchDelegate.h"
#import "KeynotePlaybackDelegate.h"

@interface KeynoteHandler : NSObject

@property (atomic, strong, readonly) KeynoteApplication *application;
@property (atomic, assign, readonly) BOOL presenting;


@property (nonatomic, weak) id<KeynoteLaunchDelegate> launchDelegate;
@property (nonatomic, weak) id<KeynotePlaybackDelegate> playbackDelegate;

+ (KeynoteHandler *)sharedHandler;

- (void)launchWithDelegate: (id<KeynoteDelegate>) delegate;
- (void)launch;
- (void)open:(NSString *)file;

- (void)play:(NSString *)file withDelegate: (id<KeynoteDelegate>) delegate;
- (void)play:(NSString *)file;
- (void)stop;
@end
51 changes: 39 additions & 12 deletions ACShell/Keynote/KeynoteHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ @interface KeynoteHandler ()
@property (atomic, assign) int currentPresentationTicket;
@property (atomic, strong) NSTimer *timerObservePresentation;
@property (atomic, strong) KeynoteDocument *presentation;
@property (atomic, weak) id<KeynoteDelegate> delegate;
@end

@implementation KeynoteHandler
Expand All @@ -39,16 +38,16 @@ - (id)init {
return self;
}

- (void)launchWithDelegate:(id<KeynoteDelegate>) delegate {
- (void)launch {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
self.application = [SBApplication applicationWithBundleIdentifier:ACShellKeynoteDefaultDomain];

// To trigger startup of application we need to retrieve some values.
NSString *version = self.application.version;
BOOL isRunning = self.application.isRunning;
dispatch_async(dispatch_get_main_queue(), ^{
if ([delegate respondsToSelector:@selector(keynoteAppDidLaunch:version:)]) {
[delegate keynoteAppDidLaunch:isRunning version:version];
if ([self.launchDelegate respondsToSelector:@selector(keynoteAppDidLaunch:version:)]) {
[self.launchDelegate keynoteAppDidLaunch:isRunning version:version];
}
});

Expand All @@ -71,12 +70,11 @@ - (void)stop {
[self presentationDidStop];
}

- (void)play:(NSString *)file withDelegate:(id<KeynoteDelegate>)delegate {
- (void)play:(NSString *)file {

if (self.presenting) return;
self.presenting = YES;
self.presentation = nil;
self.delegate = delegate;
int ticket = [self nextPresentationTicket];
NSURL *url = [NSURL fileURLWithPath: file];

Expand All @@ -101,10 +99,17 @@ - (void)play:(NSString *)file withDelegate:(id<KeynoteDelegate>)delegate {
self.presentation = presentation;
[presentation startFrom:firstSlide];
NSLog(@" started to play..");
dispatch_async(dispatch_get_main_queue(), ^{
[self startObservingPresentation];
[delegate keynoteDidStartPresentation:self];
});

if ([self keynoteIsPlayingFullscreen]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self startObservingPresentation];
[self.playbackDelegate keynoteDidStartPresentation:self];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self.launchDelegate keynoteDidRunInWindow:self];
});
}
}
else {
NSLog(@" cancelled.");
Expand Down Expand Up @@ -146,7 +151,29 @@ - (void)presentationDidStop {
[self.presentation closeSaving:KeynoteSaveOptionsNo savingIn:nil];
self.presenting = NO;
self.presentation = nil;
[self.delegate keynoteDidStopPresentation:self];
[self.playbackDelegate keynoteDidStopPresentation:self];
}

- (BOOL)keynoteIsPlayingFullscreen
{
NSMutableArray *windows = NSMutableArray.new;
[self.application.windows enumerateObjectsUsingBlock:^(KeynoteWindow *_Nonnull window, NSUInteger index, BOOL *_Nonnull stop) {
NSRange range = [window.name rangeOfString:@".key"];
if (range.length > 0) {
[windows addObject:window];
}
}];

__block BOOL noncloseable = NO;
__block BOOL nonresizable = NO;
__block BOOL nonzoomable = NO;
[windows enumerateObjectsUsingBlock:^(KeynoteWindow * _Nonnull window, NSUInteger index, BOOL * _Nonnull stop) {
if(!window.closeable) noncloseable = YES;
if(!window.resizable) nonresizable = YES;
if(!window.zoomable) nonzoomable = YES;
}];

return (noncloseable && nonresizable && nonzoomable);
}

- (BOOL)keynoteIsPlaying {
Expand All @@ -165,7 +192,7 @@ - (BOOL)keynoteIsPlaying {
If there is more than one window for a given document, this means that this document is displayed in an edit window AND in a presentation window.
*/
NSMutableArray *documentIds = [NSMutableArray new];
NSArray *documents = [[self.application windows] arrayByApplyingSelector:@selector(document)];
NSArray *documents = [self.application.windows arrayByApplyingSelector:@selector(document)];
for (KeynoteDocument *document in documents) {
NSString *documentId = [document id];
if ([documentIds containsObject:documentId]) {
Expand Down
19 changes: 19 additions & 0 deletions ACShell/Keynote/KeynoteLaunchDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// KeynoteLaunchDelegate.h
// ACShell
//
// Created by Julian Krumow on 18.04.23.
// Copyright © 2023 ART+COM AG. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class KeynoteHandler;
@protocol KeynoteLaunchDelegate <NSObject>
- (void)keynoteAppDidLaunch:(BOOL)success version:(NSString *)version;
- (void)keynoteDidRunInWindow:(KeynoteHandler *)keynote;
@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
//

#import <Cocoa/Cocoa.h>
@class KeynoteHandler;

@protocol KeynoteDelegate <NSObject>
NS_ASSUME_NONNULL_BEGIN

@class KeynoteHandler;
@protocol KeynotePlaybackDelegate <NSObject>
- (void)keynoteDidStartPresentation:(KeynoteHandler *)keynote;
- (void)keynoteDidStopPresentation:(KeynoteHandler *)keynote;
- (void)keynoteAppDidLaunch:(BOOL)success version:(NSString *)version;

@end

NS_ASSUME_NONNULL_END
2 changes: 2 additions & 0 deletions ACShell/OtherSources/localized_text_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,5 @@
#define ACSHELL_STR_DELETING_PRESENTATION @"DeletingPresentation"
#define ACSHELL_STR_GENERAL @"General"
#define ACSHELL_STR_ADVANCED @"Advanced"
#define ACSHELL_STR_PRESENTATION_IN_WINDOW @"KeynoteRunningInWindow"
#define ACSHELL_STR_PRESENTATION_IN_WINDOW_INFO @"KeynoteRunningInWindowInfo"
2 changes: 2 additions & 0 deletions ACShell/Resources/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
"DeletePresentationWarning" = "Do you really want to delete the entire presentation?";
"DeletingPresentation" = "Moving presentation to trash...";
"FileOperationFailed" = "File Operation failed.";
"KeynoteRunningInWindow" = "Presentation is currently playing in a window.";
"KeynoteRunningInWindowInfo" = "Please switch to fullscreen.";

"General" = "General";
"Advanced" = "Advanced";
Expand Down
2 changes: 2 additions & 0 deletions ACShell/Resources/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
"DeletePresentationWarning" = "Willst Du die gesamte Präsentation wirklich löschen?";
"DeletingPresentation" = "Verschiebe Präsentation in den Papierkorb...";
"FileOperationFailed" = "Vorgang abgebrochen.";
"KeynoteRunningInWindow" = "Präsentation läuft im Fenster.";
"KeynoteRunningInWindowInfo" = "Bitte auf Vollbild umstellen.";

"General" = "Allgemein";
"Advanced" = "Erweitert";
Expand Down

0 comments on commit ae5f99b

Please sign in to comment.