Added PasteboardController to handle pasteboard cleanup on shutdown and timeout

This commit is contained in:
michael starke
2013-03-02 23:31:28 +01:00
parent b26434569c
commit b021aefd51
17 changed files with 504 additions and 156 deletions

View File

@@ -2,7 +2,7 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1080</int>
<string key="IBDocument.SystemVersion">12C60</string>
<string key="IBDocument.SystemVersion">12C3103</string>
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
<string key="IBDocument.AppKitVersion">1187.34</string>
<string key="IBDocument.HIToolboxVersion">625.00</string>
@@ -42,23 +42,13 @@
<reference key="NSNextResponder"/>
<int key="NSvFlags">268</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="NSCustomView" id="446204460">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{0, 56}, {291, 24}}</string>
<reference key="NSSuperview" ref="1005"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">MPPathBar</string>
</object>
<object class="NSPopUpButton" id="421904700">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{146, 91}, {127, 26}}</string>
<reference key="NSSuperview" ref="1005"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="446204460"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSAntiCompressionPriority">{750, 751}</string>
<bool key="NSEnabled">YES</bool>
@@ -196,14 +186,6 @@
</object>
<int key="connectionID">83</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">pathBar</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="446204460"/>
</object>
<int key="connectionID">372</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
@@ -317,54 +299,6 @@
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="679237613">
<reference key="firstItem" ref="1005"/>
<int key="firstAttribute">9</int>
<int key="relation">0</int>
<reference key="secondItem" ref="446204460"/>
<int key="secondAttribute">9</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="1005"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="804532430">
<reference key="firstItem" ref="446204460"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="1005"/>
<int key="secondAttribute">5</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="1005"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="537103058">
<reference key="firstItem" ref="446204460"/>
<int key="firstAttribute">10</int>
<int key="relation">0</int>
<reference key="secondItem" ref="1005"/>
<int key="secondAttribute">10</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="1005"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="689515169">
<reference key="firstItem" ref="637214120"/>
<int key="firstAttribute">7</int>
@@ -413,7 +347,6 @@
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<reference ref="446204460"/>
</array>
<reference key="parent" ref="0"/>
</object>
@@ -511,49 +444,6 @@
<reference key="object" ref="835508122"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">357</int>
<reference key="object" ref="446204460"/>
<array class="NSMutableArray" key="children">
<object class="IBNSLayoutConstraint" id="892605823">
<reference key="firstItem" ref="446204460"/>
<int key="firstAttribute">8</int>
<int key="relation">0</int>
<nil key="secondItem"/>
<int key="secondAttribute">0</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">24</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="446204460"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">1</int>
</object>
</array>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">366</int>
<reference key="object" ref="537103058"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">368</int>
<reference key="object" ref="804532430"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">370</int>
<reference key="object" ref="892605823"/>
<reference key="parent" ref="446204460"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">371</int>
<reference key="object" ref="679237613"/>
<reference key="parent" ref="1005"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -564,9 +454,6 @@
<reference ref="180695068"/>
<reference ref="989429017"/>
<reference ref="689515169"/>
<reference ref="537103058"/>
<reference ref="804532430"/>
<reference ref="679237613"/>
<reference ref="704304955"/>
<reference ref="106372279"/>
<reference ref="850330857"/>
@@ -585,15 +472,6 @@
<string key="17.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="18.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array key="357.IBNSViewMetadataConstraints">
<reference ref="892605823"/>
</array>
<boolean value="NO" key="357.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="357.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="366.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="368.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="370.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="59.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="62.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="66.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -606,7 +484,7 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">379</int>
<int key="maxID">407</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -632,22 +510,6 @@
<string key="minorKey">./Classes/MPGeneralSettingsController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPGradientView</string>
<string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPGradientView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPPathBar</string>
<string key="superclassName">MPGradientView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPPathBar.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPViewController</string>
<string key="superclassName">NSViewController</string>

52
MacPass/MPButtonBar.h Normal file
View File

@@ -0,0 +1,52 @@
//
// MPButtonBar.h
// MacPass
//
// Created by michael starke on 28.02.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPGradientView.h"
/*
Notifications and userInfo dictionary keys
*/
APPKIT_EXTERN NSString *const MPButtonBarSelectionChangedNotification;
/*
Key in for the Index of the new selection. NSNumber with NSUInteger
*/
APPKIT_EXTERN NSString *const MPButtonBarSelectionIndexKey;
/*
Exception thrown if an illegal delegate is used.
*/
APPKIT_EXTERN NSString *const MPButtonBarInvalidDelegateException;
@class MPButtonBar;
@protocol MPButtonBarDelegate <NSObject>
@required
- (NSUInteger)buttonsInButtonBar:(MPButtonBar *)buttonBar;
@optional
- (NSImage *)buttonBar:(MPButtonBar *)buttonBar imageAtIndex:(NSUInteger)index;
- (NSString *)buttonBar:(MPButtonBar *)buttonBar labelAtIndex:(NSUInteger)index;
/*
A delegate that implements this function automatically gets registred to recive MPButtonBarSelectionDidChangeNotification
The object in the notification is the buttonbar,
The userDictionary contrains the following keys:
MPButtonBarSelectionIndexKey;
*/
- (void)didChangeButtonSelection:(NSNotification *)notification;
@end
@interface MPButtonBar : MPGradientView
@property (nonatomic, assign) id<MPButtonBarDelegate> delegate;
@property (nonatomic, readonly) NSUInteger selectedIndex;
@property (nonatomic, readonly) BOOL hasSelection;
@end

131
MacPass/MPButtonBar.m Normal file
View File

@@ -0,0 +1,131 @@
//
// MPButtonBar.m
// MacPass
//
// Created by michael starke on 28.02.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPButtonBar.h"
#import "MPButtonBarButton.h"
#define MPBUTTONBAR_BUTTON_MARGIN 5.0;
NSString *const MPButtonBarSelectionChangedNotification = @"MPButtonBarSelectionChangedNotification";
NSString *const MPButtonBarSelectionIndexKey = @"MPButtonBarSelectionIndexKey";
NSString *const MPButtonBarInvalidDelegateException = @"MPButtonBarInvalidDelegateException";
@interface MPButtonBar ()
@property (retain) NSMutableArray *buttons;
@property (nonatomic, assign) NSUInteger selectedIndex;
@property (assign) BOOL delegateSupportsImage;
@property (assign) BOOL delegateSupportsLabel;
- (void)_updateButtons;
- (void)_didClickButton:(id)sender;
@end
@implementation MPButtonBar
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.selectedIndex = NSNotFound;
self.buttons = [NSMutableArray arrayWithCapacity:5];
self.delegateSupportsImage = NO;
self.delegateSupportsLabel = NO;
[self _updateButtons];
}
return self;
}
# pragma mark Layout
- (void)_updateButtons {
NSUInteger currentButtonCount = [self.buttons count];
NSUInteger newButtonCount = 5;//[self.delegate buttonsInButtonBar:self];
/*
remove unused buttons
*/
if(currentButtonCount > newButtonCount) {
NSRange removalRange = NSMakeRange(newButtonCount - 1, currentButtonCount - newButtonCount);
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:removalRange];
NSArray *obsolteButtons = [self.buttons objectsAtIndexes:indexSet];
for(NSButton *button in obsolteButtons) {
[button removeFromSuperviewWithoutNeedingDisplay];
}
[self.buttons removeObjectsInRange:NSMakeRange(newButtonCount - 1, currentButtonCount - newButtonCount)];
}
CGFloat startPosition = MPBUTTONBAR_BUTTON_MARGIN;
for(NSUInteger buttonIndex = 0; buttonIndex < newButtonCount ; buttonIndex++) {
BOOL needsDisplay = NO;
if(buttonIndex >= currentButtonCount) {
NSButton *newButton= [[MPButtonBarButton alloc] initWithFrame:NSMakeRect(0, 0, 30, 30)];
[self addSubview:newButton];
[self.buttons addObject:newButton];
[newButton release];
[newButton setTarget:self];
[newButton setImage:[NSImage imageNamed:NSImageNameActionTemplate]];
[newButton setAction:@selector(_didClickButton:)];
needsDisplay = YES;
}
NSButton *currentButton = self.buttons[buttonIndex];
if (self.delegateSupportsImage) {
[currentButton setImage:[self.delegate buttonBar:self imageAtIndex:buttonIndex]];
needsDisplay = YES;
}
if(self.delegateSupportsLabel) {
[currentButton setStringValue:[self.delegate buttonBar:self labelAtIndex:buttonIndex]];
needsDisplay = YES;
}
[currentButton sizeToFit];
NSRect frame = [currentButton frame];
frame.size.width += 20;
frame.origin.x = startPosition;
[currentButton setFrame:frame];
startPosition += frame.size.width + MPBUTTONBAR_BUTTON_MARGIN;
[self setNeedsDisplay:needsDisplay];
}
}
#pragma mark Button Events
- (void)_didClickButton:(id)sender {
NSUInteger index = [[self subviews] indexOfObject:sender];
if(index == NSNotFound) {
return; // Nothing we need to know about happened;
}
NSDictionary *userInfo = @{ MPButtonBarSelectionIndexKey: @(index) };
[[NSNotificationCenter defaultCenter] postNotificationName:MPButtonBarSelectionChangedNotification object:self userInfo:userInfo];
}
# pragma mark Properties
- (void)setDelegate:(id<MPButtonBarDelegate>)delegate {
if( ![delegate conformsToProtocol:@protocol(MPButtonBarDelegate)]) {
NSException *invalidDelegateException = [NSException exceptionWithName:MPButtonBarInvalidDelegateException reason:@"The Delegate does not conform to the MPButtonBarDelegate protocoll" userInfo:nil];
@throw invalidDelegateException;
}
if(_delegate != delegate) {
if([_delegate respondsToSelector:@selector(didChangeButtonSelection:)]) {
[[NSNotificationCenter defaultCenter] removeObserver:_delegate];
}
_delegate = delegate;
self.delegateSupportsLabel = [delegate respondsToSelector:@selector(buttonBar:labelAtIndex:)];
self.delegateSupportsImage = [delegate respondsToSelector:@selector(buttonBar:imageAtIndex:)];
if([delegate respondsToSelector:@selector(selectionDidChanged:)]) {
[[NSNotificationCenter defaultCenter] addObserver:self.delegate selector:@selector(didChangeButtonSelection:) name:MPButtonBarSelectionChangedNotification object:self];
}
[self _updateButtons];
}
}
- (BOOL)hasSelection {
return self.selectedIndex != NSNotFound;
}
@end

View File

@@ -0,0 +1,13 @@
//
// MPButtonBarButton.h
// MacPass
//
// Created by Michael Starke on 01.03.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface MPButtonBarButton : NSButton
@end

View File

@@ -0,0 +1,41 @@
//
// MPButtonBarButton.m
// MacPass
//
// Created by Michael Starke on 01.03.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPButtonBarButton.h"
@implementation MPButtonBarButton
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setButtonType:NSPushOnPushOffButton];
[self setBordered:NO];
[[self cell] setHighlightsBy:NSContentsCellMask];
[[self cell] setShowsStateBy:NSNoCellMask];
[[self cell] setBackgroundStyle:NSBackgroundStyleRaised];
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect {
if(self.state == NSOnState) {
NSRect drawingRect = [self bounds];
NSColor *edgeColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.2];
NSColor *middelColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0];
NSGradient *borderGradient = [[NSGradient alloc] initWithColors:@[edgeColor, middelColor]];
drawingRect.size.width = 5;
[borderGradient drawInRect:drawingRect relativeCenterPosition:NSMakePoint(-1.0, 0)];
drawingRect.origin.x = [self bounds].size.width - 5;
[borderGradient drawInRect:drawingRect relativeCenterPosition:NSMakePoint(1.0, 0)];
}
[super drawRect:dirtyRect];
}
@end

View File

@@ -12,6 +12,7 @@
#import "MPDatabaseDocument.h"
#import "MPIconHelper.h"
#import "MPMainWindowController.h"
#import "MPPasteBoardController.h"
#import "KdbGroup+MPAdditions.h"
#import <QuartzCore/QuartzCore.h>
@@ -25,6 +26,13 @@ typedef enum {
MPFilterTitles = 8,
} MPFilterModeType;
typedef enum {
MPCopyUsername,
MPCopyPassword,
MPCopyURL,
MPCopyWholeEntry,
} MPCopyContentTypeTag;
NSString *const MPEntryTableUserNameColumnIdentifier = @"MPUserNameColumnIdentifier";
NSString *const MPEntryTableTitleColumnIdentifier = @"MPTitleColumnIdentifier";
NSString *const MPEntryTablePasswordColumnIdentifier = @"MPPasswordColumnIdentifier";
@@ -69,10 +77,13 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
- (void)updateFilter;
- (void)setupFilterBar;
- (void)setupPathBar;
- (void)_setupEntryMenu;
- (void)_didChangeGroupSelectionInOutlineView:(NSNotification *)notification;
- (void)_showFilterBarAnimated:(BOOL)animate;
- (void)_hideStatusBarAnimated:(BOOL)animate;
- (void)_copyEntryData:(id)sender;
@end
@implementation MPEntryViewController
@@ -114,6 +125,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
[self _hideStatusBarAnimated:NO];
[self.entryTable setDelegate:self];
[self _setupEntryMenu];
NSTableColumn *parentColumn = [self.entryTable tableColumns][0];
NSTableColumn *titleColumn = [self.entryTable tableColumns][1];
@@ -340,8 +352,65 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
}
}
#pragma mark EntryMenu
- (void)_setupEntryMenu {
NSMenu *menu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
NSMenuItem *copyUserItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:@"Copy Username"
action:@selector(_copyEntryData:)
keyEquivalent:@"C"];
[copyUserItem setTag:MPCopyUsername];
[copyUserItem setTarget:self];
NSMenuItem *copyPasswordItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:@"Copy Password"
action:@selector(_copyEntryData:)
keyEquivalent:@"c"];
[copyPasswordItem setTag:MPCopyPassword];
[copyPasswordItem setTarget:self];
[menu addItem:copyUserItem];
[menu addItem:copyPasswordItem];
[copyUserItem release];
[copyPasswordItem release];
[self.entryTable setMenu:menu];
[menu release];
}
#pragma mark Actions
- (void)_copyEntryData:(id)sender {
NSInteger selectedRow = [self.entryTable selectedRow];
if(selectedRow > [[self.entryArrayController arrangedObjects] count]) {
return;
}
KdbEntry *selectedEntry = [self.entryArrayController arrangedObjects][selectedRow];
if([sender respondsToSelector:@selector(tag)]) {
MPCopyContentTypeTag contentTag = (MPCopyContentTypeTag)[sender tag];
SEL contentTypeSelector = @selector(description);
switch (contentTag) {
case MPCopyPassword:
contentTypeSelector = @selector(password);
break;
case MPCopyUsername:
contentTypeSelector = @selector(username);
break;
case MPCopyURL:
contentTypeSelector = @selector(URL);
break;
case MPCopyWholeEntry:
default:
break;
}
[[MPPasteBoardController defaultController] copyObjects:@[ [selectedEntry performSelector:contentTypeSelector] ]];
}
}
- (void)_toggleFilterSpace:(id)sender {
NSButton *button = sender;
NSNumber *value = self.filterButtonToMode[[button identifier]];

View File

@@ -51,7 +51,5 @@ NSString *const MPGeneralSetingsIdentifier = @"GeneralSettingsTab";
[_encodingPopup setMenu:encodingMenu];
[encodingMenu release];
}
@end

View File

@@ -57,7 +57,9 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
NSOutlineView *outlineView = [notification object];
KdbGroup *selectedGroup = [outlineView itemAtRow:[outlineView selectedRow]];
self.selectedGroup = selectedGroup;
#ifdef DEBUG
NSLog(@"Selected: %@", self.selectedGroup);
#endif
[[NSNotificationCenter defaultCenter] postNotificationName:MPOutlineViewDidChangeGroupSelection object:self userInfo:nil];
}

View File

@@ -50,6 +50,8 @@
}
- (void)_showError {
#ifdef DEBUG
NSLog(@"Something went wrong");
#endif
}
@end

View File

@@ -0,0 +1,23 @@
//
// MPPastBoardController.h
// MacPass
//
// Created by Michael Starke on 02.03.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface MPPasteBoardController : NSObject
/*
This time sets the time interval after which a copied entry shoudl be purged from the pasteboard
*/
@property (assign, nonatomic) NSTimeInterval clearTimeout;
@property (assign, nonatomic) BOOL clearPasteboardOnShutdown;
+ (MPPasteBoardController *)defaultController;
- (void)copyObjects:(NSArray *)objects;
@end

View File

@@ -0,0 +1,87 @@
//
// MPPastBoardController.m
// MacPass
//
// Created by Michael Starke on 02.03.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPPasteBoardController.h"
@interface MPPasteBoardController ()
@property (assign) BOOL isEmpty;
- (void)_clearPasteboardContents;
- (void)_updateNotifications;
@end
@implementation MPPasteBoardController
+ (MPPasteBoardController *)defaultController {
static MPPasteBoardController* sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[MPPasteBoardController alloc] init];
});
return sharedInstance;
}
- (id)init {
self = [super init];
if (self) {
_isEmpty = YES;
/* User preferences and bindings */
_clearTimeout = 30;
_clearPasteboardOnShutdown = YES;
[self _updateNotifications];
}
return self;
}
- (void)dealloc
{
if(_clearPasteboardOnShutdown) {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
[super dealloc];
}
- (void)_updateNotifications {
if(self.clearPasteboardOnShutdown) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearContents) name:NSApplicationWillTerminateNotification object:nil];
}
else {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
- (void)setClearTimeout:(NSTimeInterval)clearTimeout {
if(_clearTimeout != clearTimeout) {
_clearTimeout = clearTimeout;
}
}
- (void)setClearPasteboardOnShutdown:(BOOL)clearPasteboardOnShutdown {
if(_clearPasteboardOnShutdown != clearPasteboardOnShutdown ) {
_clearPasteboardOnShutdown = !_clearPasteboardOnShutdown;
[self _updateNotifications];
}
}
- (void)copyObjects:(NSArray *)objects {
[[NSPasteboard generalPasteboard] clearContents];
[[NSPasteboard generalPasteboard] writeObjects:objects];
self.isEmpty = NO;
[self performSelector:@selector(clearContents) withObject:nil afterDelay:self.clearTimeout];
}
- (void)_clearPasteboardContents {
/* Only clear stuff we might have put there */
if(!self.isEmpty) {
[[NSPasteboard generalPasteboard] clearContents];
}
self.isEmpty = YES;
}
@end

13
MacPass/MPPathControl.h Normal file
View File

@@ -0,0 +1,13 @@
//
// MPPathControl.h
// MacPass
//
// Created by Michael Starke on 02.03.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface MPPathControl : NSPathControl
@end

22
MacPass/MPPathControl.m Normal file
View File

@@ -0,0 +1,22 @@
//
// MPPathControl.m
// MacPass
//
// Created by Michael Starke on 02.03.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPPathControl.h"
@implementation MPPathControl
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[[self cell] setShowsStateBy:NSNoCellMask];
}
return self;
}
@end

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>34B</string>
<string>37D</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>

View File

@@ -70,6 +70,7 @@
<string key="NSFrame">{{257, 0}, {470, 449}}</string>
<reference key="NSSuperview" ref="947682332"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:13</string>
<string key="NSClassName">NSView</string>
</object>
@@ -88,7 +89,7 @@
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="947682332"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1058}}</string>
<string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
<string key="NSMinSize">{400, 422}</string>
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
<bool key="NSWindowIsRestorable">YES</bool>
@@ -211,7 +212,7 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">643</int>
<int key="maxID">674</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">