Skip to content

Commit

Permalink
Merge pull request #821 from Sequel-Ace/windowHierarchyFixes
Browse files Browse the repository at this point in the history
Windows hierarchy cleanup and typesafety, part 1 #infra
  • Loading branch information
Kaspik committed Jan 24, 2021
2 parents 85d0d6b + aa8f7ad commit e6ffd10
Show file tree
Hide file tree
Showing 28 changed files with 497 additions and 533 deletions.
15 changes: 15 additions & 0 deletions Frameworks/PSMTabBar/NSTabViewItemExtension.swift
@@ -0,0 +1,15 @@
//
// SPTabViewItem.swift
// Sequel Ace
//
// Created by Jakub Kašpar on 23.01.2021.
// Copyright © 2021 Sequel-Ace. All rights reserved.
//

import Cocoa

extension NSTabViewItem {
@objc var databaseDocument: SPDatabaseDocument? {
return identifier as? SPDatabaseDocument
}
}
10 changes: 5 additions & 5 deletions Frameworks/PSMTabBar/PSMTabBarControl.h
Expand Up @@ -54,11 +54,11 @@ enum {

@interface PSMTabBarControl : NSControl {
// control basics
NSMutableArray *_cells; // the cells that draw the tabs
IBOutlet NSTabView *tabView; // the tab view being navigated
PSMOverflowPopUpButton *_overflowPopUpButton; // for too many tabs
PSMRolloverButton *_addTabButton;
PSMTabBarController *_controller;
NSMutableArray *_cells; // the cells that draw the tabs
IBOutlet NSTabView *tabView; // the tab view being navigated
PSMOverflowPopUpButton *_overflowPopUpButton; // for too many tabs
PSMRolloverButton *_addTabButton;
PSMTabBarController *_controller;

// Spring-loading.
NSTabViewItem *_tabViewItemWithSpring;
Expand Down
104 changes: 47 additions & 57 deletions Frameworks/PSMTabBar/PSMTabBarControl.m
Expand Up @@ -18,6 +18,9 @@
#include <Carbon/Carbon.h> /* for GetKeys() and KeyMap */
#include <bitstring.h>

#import "SPDatabaseDocument.h"
#import "sequel-ace-Swift.h"

@interface PSMTabBarControl (Private)

// constructor/destructor
Expand Down Expand Up @@ -613,8 +616,7 @@ - (void)addTabViewItem:(NSTabViewItem *)item
}
}

- (void)removeTabForCell:(PSMTabBarCell *)cell
{
- (void)removeTabForCell:(PSMTabBarCell *)cell {
NSTabViewItem *item = [cell representedObject];

// unbind
Expand All @@ -627,39 +629,26 @@ - (void)removeTabForCell:(PSMTabBarCell *)cell
[cell unbind:@"countColor"];
[cell unbind:@"isEdited"];

if ([item identifier] != nil) {
if ([[item identifier] respondsToSelector:@selector(isProcessing)]) {
[[item identifier] removeObserver:cell forKeyPath:@"isProcessing"];
SPDatabaseDocument *databaseDocument = [item databaseDocument];

if (databaseDocument) {
if ([databaseDocument respondsToSelector:@selector(isProcessing)]) {
[databaseDocument removeObserver:cell forKeyPath:@"isProcessing"];
}
}

if ([item identifier] != nil) {
if ([[item identifier] respondsToSelector:@selector(icon)]) {
[[item identifier] removeObserver:cell forKeyPath:@"icon"];
if ([databaseDocument respondsToSelector:@selector(icon)]) {
[databaseDocument removeObserver:cell forKeyPath:@"icon"];
}
}

if ([item identifier] != nil) {
if ([[item identifier] respondsToSelector:@selector(count)]) {
[[item identifier] removeObserver:cell forKeyPath:@"objectCount"];
if ([databaseDocument respondsToSelector:@selector(count)]) {
[databaseDocument removeObserver:cell forKeyPath:@"objectCount"];
}
}

if ([item identifier] != nil) {
if ([[item identifier] respondsToSelector:@selector(countColor)]) {
[[item identifier] removeObserver:cell forKeyPath:@"countColor"];
if ([databaseDocument respondsToSelector:@selector(countColor)]) {
[databaseDocument removeObserver:cell forKeyPath:@"countColor"];
}
}

if ([item identifier] != nil) {
if ([[item identifier] respondsToSelector:@selector(largeImage)]) {
[[item identifier] removeObserver:cell forKeyPath:@"largeImage"];
if ([databaseDocument respondsToSelector:@selector(largeImage)]) {
[databaseDocument removeObserver:cell forKeyPath:@"largeImage"];
}
}

if ([item identifier] != nil) {
if ([[item identifier] respondsToSelector:@selector(isEdited)]) {
[[item identifier] removeObserver:cell forKeyPath:@"isEdited"];
if ([databaseDocument respondsToSelector:@selector(isEdited)]) {
[databaseDocument removeObserver:cell forKeyPath:@"isEdited"];
}
}

Expand Down Expand Up @@ -1587,65 +1576,66 @@ - (void)bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewIte
[item addObserver:self forKeyPath:@"identifier" options:0 context:nil];
}

- (void)_bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item
{
- (void)_bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item {

SPDatabaseDocument *databaseDocument = [item databaseDocument];
// bind the indicator to the represented object's status (if it exists)
[[cell indicator] setHidden:YES];
if ([item identifier] != nil) {
if ([[[cell representedObject] identifier] respondsToSelector:@selector(isProcessing)]) {
if (databaseDocument != nil) {
if ([databaseDocument respondsToSelector:@selector(isProcessing)]) {
NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
[bindingOptions setObject:NSNegateBooleanTransformerName forKey:@"NSValueTransformerName"];
[[cell indicator] bind:@"animate" toObject:[item identifier] withKeyPath:@"isProcessing" options:nil];
[[cell indicator] bind:@"hidden" toObject:[item identifier] withKeyPath:@"isProcessing" options:bindingOptions];
[[item identifier] addObserver:cell forKeyPath:@"isProcessing" options:0 context:nil];
[[cell indicator] bind:@"animate" toObject:databaseDocument withKeyPath:@"isProcessing" options:nil];
[[cell indicator] bind:@"hidden" toObject:databaseDocument withKeyPath:@"isProcessing" options:bindingOptions];
[databaseDocument addObserver:cell forKeyPath:@"isProcessing" options:0 context:nil];
}
}

// bind for the existence of an icon
[cell setHasIcon:NO];
if ([item identifier] != nil) {
if ([[[cell representedObject] identifier] respondsToSelector:@selector(icon)]) {
if (databaseDocument != nil) {
if ([databaseDocument respondsToSelector:@selector(icon)]) {
NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
[bindingOptions setObject:NSIsNotNilTransformerName forKey:@"NSValueTransformerName"];
[cell bind:@"hasIcon" toObject:[item identifier] withKeyPath:@"icon" options:bindingOptions];
[[item identifier] addObserver:cell forKeyPath:@"icon" options:0 context:nil];
[cell bind:@"hasIcon" toObject:databaseDocument withKeyPath:@"icon" options:bindingOptions];
[databaseDocument addObserver:cell forKeyPath:@"icon" options:0 context:nil];
}
}

// bind for the existence of a counter
[cell setCount:0];
if ([item identifier] != nil) {
if ([[[cell representedObject] identifier] respondsToSelector:@selector(count)]) {
[cell bind:@"count" toObject:[item identifier] withKeyPath:@"objectCount" options:nil];
[[item identifier] addObserver:cell forKeyPath:@"objectCount" options:0 context:nil];
if (databaseDocument != nil) {
if ([databaseDocument respondsToSelector:@selector(count)]) {
[cell bind:@"count" toObject:databaseDocument withKeyPath:@"objectCount" options:nil];
[databaseDocument addObserver:cell forKeyPath:@"objectCount" options:0 context:nil];
}
}

// bind for the color of a counter
[cell setCountColor:nil];
if ([item identifier] != nil) {
if ([[[cell representedObject] identifier] respondsToSelector:@selector(countColor)]) {
[cell bind:@"countColor" toObject:[item identifier] withKeyPath:@"countColor" options:nil];
[[item identifier] addObserver:cell forKeyPath:@"countColor" options:0 context:nil];
if (databaseDocument != nil) {
if ([databaseDocument respondsToSelector:@selector(countColor)]) {
[cell bind:@"countColor" toObject:databaseDocument withKeyPath:@"countColor" options:nil];
[databaseDocument addObserver:cell forKeyPath:@"countColor" options:0 context:nil];
}
}

// bind for a large image
[cell setHasLargeImage:NO];
if ([item identifier] != nil) {
if ([[[cell representedObject] identifier] respondsToSelector:@selector(largeImage)]) {
if (databaseDocument != nil) {
if ([databaseDocument respondsToSelector:@selector(largeImage)]) {
NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
[bindingOptions setObject:NSIsNotNilTransformerName forKey:@"NSValueTransformerName"];
[cell bind:@"hasLargeImage" toObject:[item identifier] withKeyPath:@"largeImage" options:bindingOptions];
[[item identifier] addObserver:cell forKeyPath:@"largeImage" options:0 context:nil];
[cell bind:@"hasLargeImage" toObject:databaseDocument withKeyPath:@"largeImage" options:bindingOptions];
[databaseDocument addObserver:cell forKeyPath:@"largeImage" options:0 context:nil];
}
}

[cell setIsEdited:NO];
if ([item identifier] != nil) {
if ([[[cell representedObject] identifier] respondsToSelector:@selector(isEdited)]) {
[cell bind:@"isEdited" toObject:[item identifier] withKeyPath:@"isEdited" options:nil];
[[item identifier] addObserver:cell forKeyPath:@"isEdited" options:0 context:nil];
if (databaseDocument != nil) {
if ([databaseDocument respondsToSelector:@selector(isEdited)]) {
[cell bind:@"isEdited" toObject:databaseDocument withKeyPath:@"isEdited" options:nil];
[databaseDocument addObserver:cell forKeyPath:@"isEdited" options:0 context:nil];
}
}

Expand Down
2 changes: 1 addition & 1 deletion Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m
Expand Up @@ -499,7 +499,7 @@ - (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlVie
// icon
if ([cell hasIcon]) {
NSRect iconRect = [self iconRectForTabCell:cell];
NSImage *icon = [(id)[[cell representedObject] identifier] icon];
NSImage *icon = [[[cell representedObject] identifier] icon];

// center in available space (in case icon image is smaller than kPSMTabBarIconWidth)
if ([icon size].width < kPSMTabBarIconWidth) {
Expand Down
64 changes: 32 additions & 32 deletions Source/Controllers/BundleSupport/SPBundleCommandRunner.m
Expand Up @@ -160,60 +160,60 @@ + (NSString *)runBashCommand:(NSString *)command withEnvironment:(NSDictionary*)
// Create and set an unique process ID for each SPDatabaseDocument which has to passed
// for each sequelace:// scheme command as user to be able to identify the url scheme command.
// Furthermore this id is used to communicate with the called command as file name.
id doc = nil;
if([[[NSApp mainWindow] delegate] respondsToSelector:@selector(selectedTableDocument)])
doc = [(SPWindowController *)[[NSApp mainWindow] delegate] selectedTableDocument];
SPDatabaseDocument *databaseDocument = nil;
if ([[[NSApp mainWindow] delegate] isKindOfClass:[SPWindowController class]]) {
databaseDocument = [(SPWindowController *)[[NSApp mainWindow] delegate] selectedTableDocument];
}
// Check if connected
if([doc getConnection] == nil)
doc = nil;
else {
for (NSWindow *aWindow in [NSApp orderedWindows])
{
if ([[[[aWindow windowController] class] description] isEqualToString:@"SPWindowController"]) {

SPWindowController *windowController = (SPWindowController *)[aWindow windowController];
NSArray *documents = [windowController documents];

if ([documents count] && [[[[documents objectAtIndex:0] class] description] isEqualToString:@"SPDatabaseDocument"]) {
// Check if connected
if ([[documents objectAtIndex:0] getConnection]) {
doc = [documents objectAtIndex:0];
}
else {
doc = nil;
}
}
if ([databaseDocument getConnection] == nil) {
databaseDocument = nil;
} else {
for (NSWindow *window in [NSApp orderedWindows]) {
if ([[[window windowController] class] isKindOfClass:[SPWindowController class]]) {
NSArray <SPDatabaseDocument *> *documents = [(SPWindowController *)[window windowController] documents];
for (SPDatabaseDocument *document in documents) {
// Check if connected
if ([document getConnection]) {
databaseDocument = document;
} else {
databaseDocument = nil;
}

if (databaseDocument) {
break;
}
}
}

if (doc) break;
}
}

if (doc != nil) {

[doc setProcessID:uuid];
if (databaseDocument != nil) {
[databaseDocument setProcessID:uuid];

[theEnv setObject:uuid forKey:SPBundleShellVariableProcessID];
[theEnv setObject:[NSString stringWithFormat:@"%@%@", [SPURLSchemeQueryInputPathHeader stringByExpandingTildeInPath], uuid] forKey:SPBundleShellVariableQueryFile];
[theEnv setObject:[NSString stringWithFormat:@"%@%@", [SPURLSchemeQueryResultPathHeader stringByExpandingTildeInPath], uuid] forKey:SPBundleShellVariableQueryResultFile];
[theEnv setObject:[NSString stringWithFormat:@"%@%@", [SPURLSchemeQueryResultStatusPathHeader stringByExpandingTildeInPath], uuid] forKey:SPBundleShellVariableQueryResultStatusFile];
[theEnv setObject:[NSString stringWithFormat:@"%@%@", [SPURLSchemeQueryResultMetaPathHeader stringByExpandingTildeInPath], uuid] forKey:SPBundleShellVariableQueryResultMetaFile];

if([doc shellVariables])
[theEnv addEntriesFromDictionary:[doc shellVariables]];
if ([databaseDocument shellVariables]) {
[theEnv addEntriesFromDictionary:[databaseDocument shellVariables]];
}

if([theEnv objectForKey:SPBundleShellVariableCurrentEditedColumnName] && [[theEnv objectForKey:SPBundleShellVariableDataTableSource] isEqualToString:@"content"])
[theEnv setObject:[theEnv objectForKey:SPBundleShellVariableSelectedTable] forKey:SPBundleShellVariableCurrentEditedTable];

}

if(theEnv != nil && [theEnv count])
if(theEnv != nil && [theEnv count]) {
[bashTask setEnvironment:theEnv];
}

if(path != nil)
if (path != nil) {
[bashTask setCurrentDirectoryPath:path];
else if([shellEnvironment objectForKey:SPBundleShellVariableBundlePath] && [fileManager fileExistsAtPath:[shellEnvironment objectForKey:SPBundleShellVariableBundlePath] isDirectory:&isDir] && isDir)
} else if ([shellEnvironment objectForKey:SPBundleShellVariableBundlePath] && [fileManager fileExistsAtPath:[shellEnvironment objectForKey:SPBundleShellVariableBundlePath] isDirectory:&isDir] && isDir) {
[bashTask setCurrentDirectoryPath:[shellEnvironment objectForKey:SPBundleShellVariableBundlePath]];
}

// logging below due to "Couldn't posix_spawn: error 7"
// FB: 5c541e5508e7cdd4a925295cabfbf398
Expand Down
4 changes: 3 additions & 1 deletion Source/Controllers/BundleSupport/SPBundleEditorController.m
Expand Up @@ -1460,7 +1460,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
(action == @selector(displayBundleMetaInfo:)))
{
// Allow to record short-cuts used by the Bundle Editor
if([[NSApp keyWindow] firstResponder] == keyEquivalentField) return NO;
if ([[NSApp keyWindow] firstResponder] == keyEquivalentField) {
return NO;
}

return ([[commandBundleTreeController selectedObjects] count] == 1 && ![[[commandBundleTreeController selectedObjects] objectAtIndex:0] objectForKey:kChildrenKey]);
}
Expand Down
12 changes: 6 additions & 6 deletions Source/Controllers/DataExport/SPExportController.m
Expand Up @@ -337,7 +337,7 @@ - (void)exportTables:(NSArray *)exportTables asFormat:(SPExportType)format using
[self _updateExportAdvancedOptionsLabel];
[self setExportInput:source];

[[tableDocumentInstance parentWindow] beginSheet:self.window completionHandler:^(NSModalResponse returnCode) {
[[tableDocumentInstance parentWindowControllerWindow] beginSheet:self.window completionHandler:^(NSModalResponse returnCode) {
// Perform the export
if (returnCode == NSModalResponseOK) {

Expand Down Expand Up @@ -369,7 +369,7 @@ - (void)openExportErrorsSheetWithString:(NSString *)errors
[errorsTextView setString:@""];
[errorsTextView setString:errors];

[[tableDocumentInstance parentWindow] beginSheet:errorsWindow completionHandler:nil];
[[tableDocumentInstance parentWindowControllerWindow] beginSheet:errorsWindow completionHandler:nil];
}

/**
Expand Down Expand Up @@ -446,7 +446,7 @@ - (IBAction)closeSheet:(id)sender
[alert setMessageText:NSLocalizedString(@"No directory selected.", @"No directory selected.")];
[alert setInformativeText:NSLocalizedString(@"Please select a new export location and try again.", @"Please select a new export location and try again")];

[alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] completionHandler:^(NSInteger returnCode) {
[alert beginSheetModalForWindow:[tableDocumentInstance parentWindowControllerWindow] completionHandler:^(NSInteger returnCode) {
[self performSelector:@selector(_reopenExportSheet) withObject:nil afterDelay:0.1];
}];

Expand Down Expand Up @@ -1272,7 +1272,7 @@ - (void)startExport

// If it's not already displayed, open the progress sheet
if (![exportProgressWindow isVisible]) {
[[tableDocumentInstance parentWindow] beginSheet:exportProgressWindow completionHandler:nil];
[[tableDocumentInstance parentWindowControllerWindow] beginSheet:exportProgressWindow completionHandler:nil];
}

// cache the current connection encoding so the exporter can do what it wants.
Expand Down Expand Up @@ -1447,7 +1447,7 @@ - (void)exportTables:(NSArray *)exportTables orDataArray:(NSArray *)dataArray
[exportProgressIndicator setUsesThreadedAnimation:YES];

// Open the progress sheet
[[tableDocumentInstance parentWindow] beginSheet:exportProgressWindow completionHandler:nil];
[[tableDocumentInstance parentWindowControllerWindow] beginSheet:exportProgressWindow completionHandler:nil];

// CSV export
if (exportType == SPCSVExport) {
Expand Down Expand Up @@ -2123,7 +2123,7 @@ - (void)errorCreatingExportFileHandles:(NSArray *)files
* Re-open the export sheet without resetting the interface - for use on error.
*/
- (void)_reopenExportSheet {
[[tableDocumentInstance parentWindow] beginSheet:self.window completionHandler:nil];
[[tableDocumentInstance parentWindowControllerWindow] beginSheet:self.window completionHandler:nil];
}

#pragma mark - SPExportFilenameUtilities
Expand Down

0 comments on commit e6ffd10

Please sign in to comment.