Merge pull request #96 from MarkJerde/ClippingSource_Fixes_Features_Versions

Display source App of clipping and time that it was copied.  Plus bug fixes and dev features.
This commit is contained in:
Gennadiy Potapov 2016-03-26 15:01:33 +03:00
commit a3dcfc4edf
14 changed files with 597 additions and 275 deletions

View file

@ -22,6 +22,7 @@
SGHotKey *mainHotKey;
IBOutlet SRRecorderControl *mainRecorder;
IBOutlet NSPanel *prefsPanel;
IBOutlet NSBox *appearancePanel;
int mainHotkeyModifiers;
SRKeyCodeTransformer *srTransformer;
BOOL isBezelDisplayed;
@ -30,6 +31,7 @@
int stackPosition;
int favoritesStackPosition;
int stashedStackPosition;
NSDateFormatter* dateFormat;
// The below were pulled in from JumpcutController
JumpcutStore *clippingStore;

View file

@ -71,16 +71,19 @@
@"saveForgottenClippings",
[NSNumber numberWithBool:YES],
@"saveForgottenFavorites",
[NSNumber numberWithBool:YES],
[NSNumber numberWithBool:(floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)],
@"popUpAnimation",
[NSNumber numberWithBool:NO],
@"pasteMovesToTop",
[NSNumber numberWithBool:YES],
@"displayClippingSource",
nil]];
return [super init];
}
- (void)awakeFromNib
{
[self buildAppearancesPreferencePanel];
// We no longer get autosave from ShortcutRecorder, so let's set the recorder by hand
if ( [[DBUserDefaults standardUserDefaults] dictionaryForKey:@"ShortcutRecorder mainHotkey"] ) {
@ -98,20 +101,13 @@
stashedStore = NULL;
[bezel setColor:NO];
NSRect screenFrame = [[NSScreen mainScreen] frame];
widthSlider.maxValue = screenFrame.size.width;
heightSlider.maxValue = screenFrame.size.height;
// Set up the bezel window
NSRect windowFrame = NSMakeRect(0, 0,
[[DBUserDefaults standardUserDefaults] floatForKey:@"bezelWidth"],
[[DBUserDefaults standardUserDefaults] floatForKey:@"bezelHeight"]);
bezel = [[BezelWindow alloc] initWithContentRect:windowFrame
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
[bezel trueCenter];
[bezel setDelegate:self];
[self setupBezel:nil];
// Set up the bezel date formatter
dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"EEEE, MMMM dd 'at' h:mm a"];
// Create our pasteboard interface
jcPasteboard = [NSPasteboard generalPasteboard];
@ -247,7 +243,7 @@
statusItemText = [statusItem title];
statusItemImage = [statusItem image];
[statusItem setTitle: @""];
[statusItem setImage: [NSImage imageNamed:@"com.generalarcade.flycut.disabled.16.png"]];
[statusItem setImage: [NSImage imageNamed:@"com.generalarcade.flycut.xout.16.png"]];
return true;
}
else
@ -306,6 +302,20 @@
[bezel trueCenter];
}
-(IBAction) setupBezel:(id)sender
{
NSRect windowFrame = NSMakeRect(0, 0,
[[DBUserDefaults standardUserDefaults] floatForKey:@"bezelWidth"],
[[DBUserDefaults standardUserDefaults] floatForKey:@"bezelHeight"]);
bezel = [[BezelWindow alloc] initWithContentRect:windowFrame
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO
showSource:[[DBUserDefaults standardUserDefaults] boolForKey:@"displayClippingSource"]];
[bezel trueCenter];
[bezel setDelegate:self];
}
-(IBAction) switchMenuIcon:(id)sender
{
@ -373,6 +383,182 @@
[self updateMenu];
}
-(NSTextField*) preferencePanelSliderLabelForText:(NSString*)text aligned:(NSTextAlignment)alignment andFrame:(NSRect)frame
{
NSTextField *newLabel = [[NSTextField alloc] initWithFrame:frame];
newLabel.editable = NO;
[newLabel setAlignment:alignment];
[newLabel setBordered:NO];
[newLabel setDrawsBackground:NO];
[newLabel setFont:[NSFont labelFontOfSize:10]];
[newLabel setStringValue:text];
return newLabel;
}
-(NSBox*) preferencePanelSliderRowForText:(NSString*)title withTicks:(int)ticks minText:(NSString*)minText maxText:(NSString*)maxText minValue:(double)min maxValue:(double)max frameMaxY:(int)frameMaxY binding:(NSString*)keyPath action:(SEL)action
{
NSRect panelFrame = [appearancePanel frame];
if ( frameMaxY < 0 )
frameMaxY = panelFrame.size.height-8;
int height = 63;
NSBox *newRow = [[NSBox alloc] initWithFrame:NSMakeRect(0, frameMaxY-height, panelFrame.size.width-10, height)];
[newRow setTitlePosition:NSNoTitle];
[newRow setBorderType:NSNoBorder];
[newRow addSubview:[self preferencePanelSliderLabelForText:title aligned:NSNaturalTextAlignment andFrame:NSMakeRect(8, 25, 100, 25)]];
[newRow addSubview:[self preferencePanelSliderLabelForText:minText aligned:NSLeftTextAlignment andFrame:NSMakeRect(113, 0, 151, 25)]];
[newRow addSubview:[self preferencePanelSliderLabelForText:maxText aligned:NSRightTextAlignment andFrame:NSMakeRect(109+310-151-4, 0, 151, 25)]];
NSSlider *newControl = [[NSSlider alloc] initWithFrame:NSMakeRect(109, 29, 310, 25)];
newControl.numberOfTickMarks=ticks;
[newControl setMinValue:min];
[newControl setMaxValue:max];
[self setBinding:@"value" forKey:keyPath andOrAction:action on:newControl];
[newRow addSubview:newControl];
return newRow;
}
-(NSBox*) preferencePanelPopUpRowForText:(NSString*)title items:(NSArray*)items frameMaxY:(int)frameMaxY binding:(NSString*)keyPath action:(SEL)action
{
NSRect panelFrame = [appearancePanel frame];
if ( frameMaxY < 0 )
frameMaxY = panelFrame.size.height-8;
int height = 40;
NSBox *newRow = [[NSBox alloc] initWithFrame:NSMakeRect(0, frameMaxY-height+5, panelFrame.size.width-10, height)];
[newRow setTitlePosition:NSNoTitle];
[newRow setBorderType:NSNoBorder];
[newRow addSubview:[self preferencePanelSliderLabelForText:title aligned:NSNaturalTextAlignment andFrame:NSMakeRect(8, -2, 100, 25)]];
NSPopUpButton *newControl = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(109, 4, 150, 25) pullsDown:NO];
[newControl addItemsWithTitles:items];
[self setBinding:@"selectedIndex" forKey:keyPath andOrAction:action on:newControl];
[newRow addSubview:newControl];
return newRow;
}
-(NSBox*) preferencePanelCheckboxRowForText:(NSString*)title frameMaxY:(int)frameMaxY binding:(NSString*)keyPath action:(SEL)action
{
NSRect panelFrame = [appearancePanel frame];
if ( frameMaxY < 0 )
frameMaxY = panelFrame.size.height-8;
int height = 40;
NSBox *newRow = [[NSBox alloc] initWithFrame:NSMakeRect(0, frameMaxY-height+5, panelFrame.size.width-10, height)];
[newRow setTitlePosition:NSNoTitle];
[newRow setBorderType:NSNoBorder];
NSButton *newControl = [[NSButton alloc] initWithFrame:NSMakeRect(8, 4, panelFrame.size.width-20, 25)];
[newControl setButtonType:NSSwitchButton];
[newControl setTitle:title];
[self setBinding:@"value" forKey:keyPath andOrAction:action on:newControl];
[newRow addSubview:newControl];
return newRow;
}
-(void)setBinding:(NSString*)binding forKey:(NSString*)keyPath andOrAction:(SEL)action on:(NSControl*)newControl
{
[newControl bind:binding
toObject:[DBUserDefaults standardUserDefaults]
withKeyPath:keyPath
options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
forKey:@"NSContinuouslyUpdatesValue"]];
if ( nil != action )
{
[newControl setTarget:self];
[newControl setAction:action];
}
}
-(void) buildAppearancesPreferencePanel
{
NSRect screenFrame = [[NSScreen mainScreen] frame];
int nextYMax = -1;
NSView *row = [self preferencePanelSliderRowForText:@"Bezel transparency"
withTicks:16
minText:@"Lighter"
maxText:@"Darker"
minValue:0.1
maxValue:0.9
frameMaxY:nextYMax
binding:@"bezelAlpha"
action:@selector(setBezelAlpha:)];
[appearancePanel addSubview:row];
nextYMax = row.frame.origin.y;
row = [self preferencePanelSliderRowForText:@"Bezel width"
withTicks:50
minText:@"Smaller"
maxText:@"Bigger"
minValue:200
maxValue:screenFrame.size.width
frameMaxY:nextYMax
binding:@"bezelWidth"
action:@selector(setBezelWidth:)];
[appearancePanel addSubview:row];
nextYMax = row.frame.origin.y;
row = [self preferencePanelSliderRowForText:@"Bezel height"
withTicks:50
minText:@"Smaller"
maxText:@"Bigger"
minValue:200
maxValue:screenFrame.size.height
frameMaxY:nextYMax
binding:@"bezelHeight"
action:@selector(setBezelHeight:)];
[appearancePanel addSubview:row];
nextYMax = row.frame.origin.y;
row = [self preferencePanelPopUpRowForText:@"Menu item icon"
items:[NSArray arrayWithObjects:
@"Flycut icon",
@"Black Flycut icon",
@"White scissors",
@"Black scissors",nil]
frameMaxY:nextYMax
binding:@"menuIcon"
action:@selector(switchMenuIcon:)];
[appearancePanel addSubview:row];
nextYMax = row.frame.origin.y;
row = [self preferencePanelCheckboxRowForText:@"Animate bezel appearance"
frameMaxY:nextYMax
binding:@"popUpAnimation"
action:nil];
[appearancePanel addSubview:row];
nextYMax = row.frame.origin.y;
row = [self preferencePanelCheckboxRowForText:@"Show clipping source app and time"
frameMaxY:nextYMax
binding:@"displayClippingSource"
action:@selector(setupBezel:)];
[appearancePanel addSubview:row];
nextYMax = row.frame.origin.y;
}
-(IBAction) showPreferencePanel:(id)sender
{
[currentRunningApplication release];
@ -481,8 +667,7 @@
[self restoreStashedStore];
}
// Get text from clipping store.
[favoritesStore addClipping:[clippingStore clippingContentsAtPosition:stackPosition]
ofType:[clippingStore clippingTypeAtPosition:stackPosition] ];
[favoritesStore addClipping:[clippingStore clippingAtPosition:stackPosition] ];
[clippingStore clearItem:stackPosition];
[self updateBezel];
[self updateMenu];
@ -598,7 +783,7 @@
{
// Check to see if they want a little help figuring out what types to enter.
if ( [[DBUserDefaults standardUserDefaults] boolForKey:@"revealPasteboardTypes"] )
[clippingStore addClipping:type ofType:type];
[clippingStore addClipping:type ofType:type fromAppLocalizedName:@"Flycut" fromAppBundleURL:nil atTimestamp:0];
__block bool skipClipping = NO;
@ -666,11 +851,11 @@
[pbCount release];
pbCount = [[NSNumber numberWithInt:[jcPasteboard changeCount]] retain];
if ( type != nil ) {
NSString *currRunningApp = @"";
NSRunningApplication *currRunningApp = nil;
for (NSRunningApplication *currApp in [[NSWorkspace sharedWorkspace] runningApplications])
if ([currApp isActive])
currRunningApp = [currApp localizedName];
bool largeCopyRisk = [currRunningApp rangeOfString:@"Remote Desktop Connection"].location != NSNotFound;
currRunningApp = currApp;
bool largeCopyRisk = nil != currRunningApp && [[currRunningApp localizedName] rangeOfString:@"Remote Desktop Connection"].location != NSNotFound;
// Microsoft's Remote Desktop Connection has an issue with large copy actions, which appears to be in the time it takes to transer them over the network. The copy starts being registered with OS X prior to completion of the transfer, and if the active application changes during the transfer the copy will be lost. Indicate this time period by toggling the menu icon at the beginning of all RDC trasfers and back at the end. Apple's Screen Sharing does not demonstrate this problem.
if (largeCopyRisk)
@ -705,7 +890,10 @@
}
[clippingStore addClipping:contents
ofType:type ];
ofType:type
fromAppLocalizedName:[currRunningApp localizedName]
fromAppBundleURL:currRunningApp.bundleURL.path
atTimestamp:[[NSDate date] timeIntervalSince1970]];
// The below tracks our position down down down... Maybe as an option?
// if ( [clippingStore jcListCount] > 1 ) stackPosition++;
stackPosition = 0;
@ -796,8 +984,7 @@
newStackPosition = pressed == 0x30 ? 9 : [[NSString stringWithCharacters:&pressed length:1] intValue] - 1;
if ( [clippingStore jcListCount] >= newStackPosition ) {
stackPosition = newStackPosition;
[bezel setCharString:[NSString stringWithFormat:@"%d of %d", stackPosition + 1, [clippingStore jcListCount]]];
[bezel setText:[clippingStore clippingContentsAtPosition:stackPosition]];
[self fillBezel];
}
break;
case 's': case 'S': // Save / Save-and-delete
@ -846,16 +1033,14 @@
[bezel setCharString:@"Empty"];
}
else { // normal
[bezel setText:[clippingStore clippingContentsAtPosition:stackPosition]];
[bezel setCharString:[NSString stringWithFormat:@"%d of %d", stackPosition + 1, [clippingStore jcListCount]]];
[self fillBezel];
}
}
- (void) showBezel
{
if ( [clippingStore jcListCount] > 0 && [clippingStore jcListCount] > stackPosition ) {
[bezel setCharString:[NSString stringWithFormat:@"%d of %d", stackPosition + 1, [clippingStore jcListCount]]];
[bezel setText:[clippingStore clippingContentsAtPosition:stackPosition]];
[self fillBezel];
}
NSRect mainScreenRect = [NSScreen mainScreen].visibleFrame;
[bezel setFrame:NSMakeRect(mainScreenRect.origin.x + mainScreenRect.size.width/2 - bezel.frame.size.width/2,
@ -1067,7 +1252,10 @@
NSArray *toBeRestoredClips = [[[savedJCList subarrayWithRange:loadRange] reverseObjectEnumerator] allObjects];
for( NSDictionary *aSavedClipping in toBeRestoredClips)
[clippingStore addClipping:[aSavedClipping objectForKey:@"Contents"]
ofType:[aSavedClipping objectForKey:@"Type"]];
ofType:[aSavedClipping objectForKey:@"Type"]
fromAppLocalizedName:[aSavedClipping objectForKey:@"AppLocalizedName"]
fromAppBundleURL:[aSavedClipping objectForKey:@"AppBundleURL"]
atTimestamp:[[aSavedClipping objectForKey:@"Timestamp"] integerValue]];
// Now for the favorites, same thing.
savedJCList =[loadDict objectForKey:@"favoritesList"];
@ -1079,7 +1267,10 @@
toBeRestoredClips = [[[savedJCList subarrayWithRange:loadRange] reverseObjectEnumerator] allObjects];
for( NSDictionary *aSavedClipping in toBeRestoredClips)
[favoritesStore addClipping:[aSavedClipping objectForKey:@"Contents"]
ofType:[aSavedClipping objectForKey:@"Type"]];
ofType:[aSavedClipping objectForKey:@"Type"]
fromAppLocalizedName:[aSavedClipping objectForKey:@"AppLocalizedName"]
fromAppBundleURL:[aSavedClipping objectForKey:@"AppBundleURL"]
atTimestamp:[[aSavedClipping objectForKey:@"Timestamp"] integerValue]];
}
} else NSLog(@"Not array");
[self updateMenu];
@ -1092,40 +1283,81 @@
{
stackPosition++;
if ( [clippingStore jcListCount] > stackPosition ) {
[bezel setCharString:[NSString stringWithFormat:@"%d of %d", stackPosition + 1, [clippingStore jcListCount]]];
[bezel setText:[clippingStore clippingContentsAtPosition:stackPosition]];
[self fillBezel];
} else {
if ( [[DBUserDefaults standardUserDefaults] boolForKey:@"wraparoundBezel"] ) {
stackPosition = 0;
[bezel setCharString:[NSString stringWithFormat:@"%d of %d", 1, [clippingStore jcListCount]]];
[bezel setText:[clippingStore clippingContentsAtPosition:stackPosition]];
[self fillBezel];
} else {
stackPosition--;
}
}
}
-(void) fillBezel
{
JumpcutClipping* clipping = [clippingStore clippingAtPosition:stackPosition];
[bezel setText:[NSString stringWithFormat:@"%@", [clipping contents]]];
[bezel setCharString:[NSString stringWithFormat:@"%d of %d", stackPosition + 1, [clippingStore jcListCount]]];
NSString *localizedName = [clipping appLocalizedName];
if ( nil == localizedName )
localizedName = @"";
NSString* dateString = @"";
if ( [clipping timestamp] > 0)
dateString = [dateFormat stringFromDate:[NSDate dateWithTimeIntervalSince1970: [clipping timestamp]]];
NSImage* icon = nil;
if (nil != [clipping appBundleURL])
icon = [[NSWorkspace sharedWorkspace] iconForFile:[clipping appBundleURL]];
[bezel setSource:localizedName];
[bezel setDate:dateString];
[bezel setSourceIcon:icon];
}
-(void) stackUp
{
stackPosition--;
if ( stackPosition < 0 ) {
if ( [[DBUserDefaults standardUserDefaults] boolForKey:@"wraparoundBezel"] ) {
stackPosition = [clippingStore jcListCount] - 1;
[bezel setCharString:[NSString stringWithFormat:@"%d of %d", stackPosition + 1, [clippingStore jcListCount]]];
[bezel setText:[clippingStore clippingContentsAtPosition:stackPosition]];
[self fillBezel];
} else {
stackPosition = 0;
}
}
if ( [clippingStore jcListCount] > stackPosition ) {
[bezel setCharString:[NSString stringWithFormat:@"%d of %d", stackPosition + 1, [clippingStore jcListCount]]];
[bezel setText:[clippingStore clippingContentsAtPosition:stackPosition]];
[self fillBezel];
}
}
- (void)saveStore:(JumpcutStore *)store toKey:(NSString *)key onDict:(NSMutableDictionary *)saveDict {
NSMutableArray *jcListArray = [NSMutableArray array];
for ( int i = 0 ; i < [store jcListCount] ; i++ )
{
JumpcutClipping *clipping = [store clippingAtPosition:i];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[clipping contents], @"Contents",
[clipping type], @"Type",
[NSNumber numberWithInt:i], @"Position",nil];
NSString *val = [clipping appLocalizedName];
if ( nil != val )
[dict setObject:val forKey:@"AppLocalizedName"];
val = [clipping appBundleURL];
if ( nil != val )
[dict setObject:val forKey:@"AppBundleURL"];
int timestamp = [clipping timestamp];
if ( timestamp > 0 )
[dict setObject:[NSNumber numberWithInt:timestamp] forKey:@"Timestamp"];
[jcListArray addObject:dict];
}
[saveDict setObject:jcListArray forKey:key];
}
-(void) saveEngine {
NSMutableDictionary *saveDict;
NSMutableArray *jcListArray = [NSMutableArray array];
saveDict = [NSMutableDictionary dictionaryWithCapacity:3];
[saveDict setObject:@"0.7" forKey:@"version"];
[saveDict setObject:[NSNumber numberWithInt:[[DBUserDefaults standardUserDefaults] integerForKey:@"rememberNum"]]
@ -1136,19 +1368,10 @@
forKey:@"displayLen"];
[saveDict setObject:[NSNumber numberWithInt:[[DBUserDefaults standardUserDefaults] integerForKey:@"displayNum"]]
forKey:@"displayNum"];
for (int i = 0 ; i < [clippingStore jcListCount]; i++)
[jcListArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[clippingStore clippingContentsAtPosition:i], @"Contents",
[clippingStore clippingTypeAtPosition:i], @"Type",
[NSNumber numberWithInt:i], @"Position",nil]];
[saveDict setObject:jcListArray forKey:@"jcList"];
jcListArray = [NSMutableArray array];
for (int i = 0 ; i < [favoritesStore jcListCount]; i++)
[jcListArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[favoritesStore clippingContentsAtPosition:i], @"Contents",
[favoritesStore clippingTypeAtPosition:i], @"Type",
[NSNumber numberWithInt:i], @"Position",nil]];
[saveDict setObject:jcListArray forKey:@"favoritesList"];
[self saveStore:clippingStore toKey:@"jcList" onDict:saveDict];
[self saveStore:favoritesStore toKey:@"favoritesList" onDict:saveDict];
[[DBUserDefaults standardUserDefaults] setObject:saveDict forKey:@"store"];
[[DBUserDefaults standardUserDefaults] synchronize];
}

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1050" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/>
@ -93,13 +93,12 @@
</menu>
<customObject id="213" userLabel="AppController" customClass="AppController">
<connections>
<outlet property="appearancePanel" destination="EFy-pc-aKl" id="NYD-Y7-bfQ"/>
<outlet property="dropboxCheckbox" destination="858" id="896"/>
<outlet property="heightSlider" destination="784" id="806"/>
<outlet property="jcMenu" destination="206" id="215"/>
<outlet property="mainRecorder" destination="555" id="556"/>
<outlet property="prefsPanel" destination="218" id="220"/>
<outlet property="searchBox" destination="BYk-Gn-IDB" id="MpX-C1-cdn"/>
<outlet property="widthSlider" destination="776" id="807"/>
</connections>
</customObject>
<userDefaultsController id="808" customClass="DBUserDefaultsController"/>
@ -472,7 +471,7 @@
<tabViewItem label="Hotkeys" identifier="net.sf.jumpcut.preferences.hotkey.tiff" id="346">
<view key="view" id="347">
<rect key="frame" x="0.0" y="0.0" width="507" height="471"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<box title="Box" boxType="oldStyle" borderType="none" titlePosition="noTitle" id="348">
<rect key="frame" x="0.0" y="227" width="555" height="125"/>
@ -517,186 +516,17 @@
</subviews>
</view>
</tabViewItem>
<tabViewItem label="Appearance" identifier="net.sf.jumpcut.preferences.appearance.tiff" id="498">
<view key="view" id="499">
<tabViewItem label="Appearance" identifier="net.sf.jumpcut.preferences.appearance.tiff" id="whe-Ak-H3h" userLabel="Appearance">
<view key="view" id="hA0-Jo-KpB">
<rect key="frame" x="0.0" y="0.0" width="507" height="471"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<box title="Box" boxType="oldStyle" borderType="none" titlePosition="noTitle" id="500" userLabel="Box - Box">
<rect key="frame" x="-3" y="173" width="555" height="316"/>
<box identifier="testbox" title="Box" boxType="oldStyle" borderType="none" titlePosition="noTitle" id="EFy-pc-aKl" userLabel="Box - Box">
<rect key="frame" x="0.0" y="155" width="502" height="316"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView">
<rect key="frame" x="0.0" y="0.0" width="555" height="316"/>
<rect key="frame" x="0.0" y="0.0" width="502" height="316"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<slider verticalHuggingPriority="750" id="505">
<rect key="frame" x="119" y="279" width="306" height="25"/>
<autoresizingMask key="autoresizingMask"/>
<sliderCell key="cell" alignment="left" minValue="0.10000000000000001" maxValue="0.90000000000000002" doubleValue="0.25" tickMarkPosition="below" numberOfTickMarks="16" sliderType="linear" id="764">
<font key="font" size="12" name="Helvetica"/>
</sliderCell>
<connections>
<action selector="setBezelAlpha:" target="213" id="528"/>
<binding destination="808" name="value" keyPath="values.bezelAlpha" id="847"/>
</connections>
</slider>
<textField verticalHuggingPriority="750" id="508">
<rect key="frame" x="121" y="262" width="80" height="13"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="765">
<font key="font" metaFont="label"/>
<string key="title">Lighter
</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="509">
<rect key="frame" x="381" y="262" width="42" height="13"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" id="766">
<font key="font" metaFont="label"/>
<string key="title">Darker
</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<slider verticalHuggingPriority="750" id="776">
<rect key="frame" x="119" y="216" width="306" height="25"/>
<autoresizingMask key="autoresizingMask"/>
<sliderCell key="cell" state="on" alignment="left" minValue="200" maxValue="2000" doubleValue="500" tickMarkPosition="below" numberOfTickMarks="50" sliderType="linear" id="781">
<font key="font" size="12" name="Helvetica"/>
</sliderCell>
<connections>
<action selector="setBezelWidth:" target="213" id="805"/>
<binding destination="808" name="value" keyPath="values.bezelWidth" id="838"/>
</connections>
</slider>
<textField verticalHuggingPriority="750" id="777">
<rect key="frame" x="121" y="199" width="80" height="13"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="780">
<font key="font" metaFont="label"/>
<string key="title">Smaller
</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="778">
<rect key="frame" x="381" y="199" width="42" height="13"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Bigger" id="779">
<font key="font" metaFont="label"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" id="513">
<rect key="frame" x="118" y="100" width="155" height="26"/>
<autoresizingMask key="autoresizingMask"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" id="767">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="514">
<items>
<menuItem title="Flycut icon" id="515"/>
<menuItem title="Black Flycut icon" id="bUV-Uc-NGM">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="White scissors" id="517"/>
<menuItem title="Black scissors" id="516"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="switchMenuIcon:" target="213" id="529"/>
<binding destination="808" name="selectedIndex" keyPath="values.menuIcon" id="844"/>
</connections>
</popUpButton>
<textField verticalHuggingPriority="750" id="521">
<rect key="frame" x="16" y="106" width="80" height="13"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="768">
<font key="font" metaFont="label"/>
<string key="title">Menu item icon
</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="774">
<rect key="frame" x="16" y="222" width="80" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Bezel width" id="775">
<font key="font" metaFont="label"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<slider verticalHuggingPriority="750" id="784">
<rect key="frame" x="119" y="159" width="306" height="25"/>
<autoresizingMask key="autoresizingMask"/>
<sliderCell key="cell" state="on" alignment="left" minValue="200" maxValue="2000" doubleValue="320" tickMarkPosition="below" numberOfTickMarks="50" sliderType="linear" id="791">
<font key="font" size="12" name="Helvetica"/>
</sliderCell>
<connections>
<action selector="setBezelHeight:" target="213" id="804"/>
<binding destination="808" name="value" keyPath="values.bezelHeight" id="841"/>
</connections>
</slider>
<textField verticalHuggingPriority="750" id="785">
<rect key="frame" x="121" y="142" width="80" height="13"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Smaller" id="790">
<font key="font" metaFont="label"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="786">
<rect key="frame" x="381" y="142" width="42" height="13"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Bigger" id="789">
<font key="font" metaFont="label"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="787">
<rect key="frame" x="16" y="165" width="80" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Bezel height" id="788">
<font key="font" metaFont="label"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="526">
<rect key="frame" x="16" y="287" width="97" height="13"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="769">
<font key="font" metaFont="label"/>
<string key="title">Bezel transparency
</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button id="910">
<rect key="frame" x="14" y="68" width="189" height="18"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="check" title="Animate bezel appearance" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="911">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="808" name="value" keyPath="values.popUpAnimation" id="913"/>
</connections>
</button>
</subviews>
</view>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
@ -707,7 +537,7 @@
<tabViewItem label="Acknowledgements" identifier="com.generalarcade.flycut.32.png" id="352">
<view key="view" id="353">
<rect key="frame" x="0.0" y="0.0" width="507" height="471"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<box title="Box" boxType="oldStyle" borderType="none" titlePosition="noTitle" id="354">
<rect key="frame" x="-3" y="109" width="555" height="376"/>

Binary file not shown.

View file

@ -61,8 +61,8 @@
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
8D2E28861B0669F500AE62C8 /* com.generalarcade.flycut.black.16.png in Resources */ = {isa = PBXBuildFile; fileRef = 8D2E28821B0669F500AE62C8 /* com.generalarcade.flycut.black.16.png */; };
8D2E28871B0669F500AE62C8 /* com.generalarcade.flycut.black.32.png in Resources */ = {isa = PBXBuildFile; fileRef = 8D2E28831B0669F500AE62C8 /* com.generalarcade.flycut.black.32.png */; };
8D2E28881B0669F500AE62C8 /* com.generalarcade.flycut.disabled.16.png in Resources */ = {isa = PBXBuildFile; fileRef = 8D2E28841B0669F500AE62C8 /* com.generalarcade.flycut.disabled.16.png */; };
8D2E28891B0669F500AE62C8 /* com.generalarcade.flycut.disabled.32.png in Resources */ = {isa = PBXBuildFile; fileRef = 8D2E28851B0669F500AE62C8 /* com.generalarcade.flycut.disabled.32.png */; };
8D2E28881B0669F500AE62C8 /* com.generalarcade.flycut.xout.16.png in Resources */ = {isa = PBXBuildFile; fileRef = 8D2E28841B0669F500AE62C8 /* com.generalarcade.flycut.xout.16.png */; };
8D2E28891B0669F500AE62C8 /* com.generalarcade.flycut.xout.32.png in Resources */ = {isa = PBXBuildFile; fileRef = 8D2E28851B0669F500AE62C8 /* com.generalarcade.flycut.xout.32.png */; };
AABE497C09FF9CD000A6A239 /* AppController.m in Sources */ = {isa = PBXBuildFile; fileRef = AABE497B09FF9CD000A6A239 /* AppController.m */; };
AAFAC85F0A1BD9DD00DC6025 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAFAC84A0A1BD9DD00DC6025 /* Carbon.framework */; };
DB46BEEB143466ED0025EA0E /* DBUserDefaults.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB46BEEA143466ED0025EA0E /* DBUserDefaults.framework */; };
@ -169,8 +169,8 @@
8D1107320486CEB800E47090 /* Flycut.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Flycut.app; sourceTree = BUILT_PRODUCTS_DIR; };
8D2E28821B0669F500AE62C8 /* com.generalarcade.flycut.black.16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = com.generalarcade.flycut.black.16.png; path = Resources/com.generalarcade.flycut.black.16.png; sourceTree = "<group>"; };
8D2E28831B0669F500AE62C8 /* com.generalarcade.flycut.black.32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = com.generalarcade.flycut.black.32.png; path = Resources/com.generalarcade.flycut.black.32.png; sourceTree = "<group>"; };
8D2E28841B0669F500AE62C8 /* com.generalarcade.flycut.disabled.16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = com.generalarcade.flycut.disabled.16.png; path = Resources/com.generalarcade.flycut.disabled.16.png; sourceTree = "<group>"; };
8D2E28851B0669F500AE62C8 /* com.generalarcade.flycut.disabled.32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = com.generalarcade.flycut.disabled.32.png; path = Resources/com.generalarcade.flycut.disabled.32.png; sourceTree = "<group>"; };
8D2E28841B0669F500AE62C8 /* com.generalarcade.flycut.xout.16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = com.generalarcade.flycut.xout.16.png; path = Resources/com.generalarcade.flycut.xout.16.png; sourceTree = "<group>"; };
8D2E28851B0669F500AE62C8 /* com.generalarcade.flycut.xout.32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = com.generalarcade.flycut.xout.32.png; path = Resources/com.generalarcade.flycut.xout.32.png; sourceTree = "<group>"; };
AABE497A09FF9CD000A6A239 /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = "<group>"; };
AABE497B09FF9CD000A6A239 /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AppController.m; sourceTree = "<group>"; };
AAFAC84A0A1BD9DD00DC6025 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
@ -272,8 +272,8 @@
7761C8CE139BE06B000FB3AB /* com.generalarcade.flycut.32.png */,
8D2E28821B0669F500AE62C8 /* com.generalarcade.flycut.black.16.png */,
8D2E28831B0669F500AE62C8 /* com.generalarcade.flycut.black.32.png */,
8D2E28841B0669F500AE62C8 /* com.generalarcade.flycut.disabled.16.png */,
8D2E28851B0669F500AE62C8 /* com.generalarcade.flycut.disabled.32.png */,
8D2E28841B0669F500AE62C8 /* com.generalarcade.flycut.xout.16.png */,
8D2E28851B0669F500AE62C8 /* com.generalarcade.flycut.xout.32.png */,
7761C8D1139BE06B000FB3AB /* jumpcut.icns */,
7761C8EB139BE09D000FB3AB /* Info.plist */,
7761C8D2139BE06B000FB3AB /* net.sf.jumpcut.ghost_scissors_small.png */,
@ -429,6 +429,7 @@
isa = PBXNativeTarget;
buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Flycut" */;
buildPhases = (
8D60A1BA1BC8399900A26CBF /* ShellScript */,
8D1107290486CEB800E47090 /* Resources */,
8D11072C0486CEB800E47090 /* Sources */,
AAECDE440A03E75C007D377A /* CopyFiles */,
@ -492,13 +493,13 @@
7761C8DB139BE06B000FB3AB /* com.generalarcade.flycut.16.png in Resources */,
7761C8DC139BE06B000FB3AB /* com.generalarcade.flycut.32.png in Resources */,
7761C8DF139BE06B000FB3AB /* jumpcut.icns in Resources */,
8D2E28891B0669F500AE62C8 /* com.generalarcade.flycut.disabled.32.png in Resources */,
8D2E28891B0669F500AE62C8 /* com.generalarcade.flycut.xout.32.png in Resources */,
7761C8E0139BE06B000FB3AB /* net.sf.jumpcut.ghost_scissors_small.png in Resources */,
7761C8E1139BE06B000FB3AB /* net.sf.jumpcut.preferences.acknowledgements.tiff in Resources */,
8D2E28871B0669F500AE62C8 /* com.generalarcade.flycut.black.32.png in Resources */,
7761C8E2139BE06B000FB3AB /* net.sf.jumpcut.preferences.appearance.tiff in Resources */,
7761C8E3139BE06B000FB3AB /* net.sf.jumpcut.preferences.general.tiff in Resources */,
8D2E28881B0669F500AE62C8 /* com.generalarcade.flycut.disabled.16.png in Resources */,
8D2E28881B0669F500AE62C8 /* com.generalarcade.flycut.xout.16.png in Resources */,
7761C8E4139BE06B000FB3AB /* net.sf.jumpcut.preferences.hotkey.tiff in Resources */,
7761C8E5139BE06B000FB3AB /* net.sf.jumpcut.scissors_bw16.png in Resources */,
8D2E28861B0669F500AE62C8 /* com.generalarcade.flycut.black.16.png in Resources */,
@ -511,6 +512,22 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
8D60A1BA1BC8399900A26CBF /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 12;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Sets the build number to identify, to some extent, the git version of the code.\n# Combines the hash of the origin commit, number of commits of divergence, local HEAD commit, local uncommitted lines of change, and year/month of build.\n# Eliminates all except for the origin commit if there are no local changes, since that can be easily tracked.\n# e.g. 1.b690b47.1.1.cb73ce6.35.1510 from origin b690b47, one and one different, locally at commit cb73ce6, with a further 35 lines of change, built in 2015 in the tenth month. Day numbers are excluded for brevity, as there is already much uncertainty in the local changes and this field is only to indicate a rough level of freshness. Build numer starts with \"1.\" to avoid strange compile errors.\ncd \"${SOURCE_ROOT}\"\nORIGIN=$(git rev-parse --short remotes/origin/master)\nOFFSET=\".$(git status|sed -n '1,/^# *$/ p'|grep \"[0-9]\"|head -1|sed 's/^[^0-9]*//;s/[^0-9]*$//'|sed 's/[^0-9][^0-9]*/./')\"\nLOCAL=\".$(git rev-parse --short HEAD)\"\nUNCOMMITTED=\".$(git diff -b -w HEAD|grep \"^[+\\-]\"|grep -v \"^[+\\-][+\\-][+\\-] [ab]\"|wc -l|sed 's/[^0-9]//g')\"\nBUILD_YEAR_MONTH=\".$(date +\"%y%m\")\"\nif [ \".$ORIGIN\" == \"$LOCAL\" ]\nthen\n OFFSET=\"\"\n LOCAL=\"\"\n if [ \".0\" == \"$UNCOMMITTED\" ]\n then\n UNCOMMITTED=\"\"\n BUILD_YEAR_MONTH=\"\"\n fi\nfi\nNEWVERSIONSTRING=\"1.$ORIGIN$OFFSET$LOCAL$UNCOMMITTED$BUILD_YEAR_MONTH\"\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $NEWVERSIONSTRING\" \"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D11072C0486CEB800E47090 /* Sources */ = {
isa = PBXSourcesBuildPhase;

View file

@ -4,8 +4,6 @@
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array/>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
@ -19,13 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>1.7</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array/>
<key>CFBundleVersion</key>
<string>1.0</string>
<string>1.3456789</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSUIElement</key>
@ -36,12 +32,6 @@
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSServices</key>
<array/>
<key>UTExportedTypeDeclarations</key>
<array/>
<key>UTImportedTypeDeclarations</key>
<array/>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>

View file

@ -38,9 +38,15 @@
NSString * clipDisplayString;
// Does it have a name?
BOOL clipHasName;
// The app name it came from
NSString * appLocalizedName;
// The the bunle URL of the app it came from
NSString * appBundleURL;
// The time
int clipTimestamp;
}
-(id) initWithContents:(NSString *)contents withType:(NSString *)type withDisplayLength:(int)displayLength;
-(id) initWithContents:(NSString *)contents withType:(NSString *)type withDisplayLength:(int)displayLength withAppLocalizedName:(NSString *)localizedName withAppBundleURL:(NSString *)bundleURL withTimestamp:(int)timestamp;
/* -(id) initWithCoder:(NSCoder *)coder;
-(void) decodeWithCoder:(NSCoder *)coder; */
-(NSString *) description;
@ -53,10 +59,14 @@
-(void) setHasName:(BOOL)newHasName;
// Retrieve values
-(JumpcutClipping *) clipping;
-(NSString *) contents;
-(int) displayLength;
-(NSString *) displayString;
-(NSString *) type;
-(NSString *) appLocalizedName;
-(NSString *) appBundleURL;
-(int) timestamp;
-(BOOL) hasName;
// Additional functions

View file

@ -31,12 +31,15 @@
-(id) init
{
[self initWithContents:@""
withType:@""
withDisplayLength:40];
withType:@""
withDisplayLength:40
withAppLocalizedName:@""
withAppBundleURL:nil
withTimestamp:0];
return self;
}
-(id) initWithContents:(NSString *)contents withType:(NSString *)type withDisplayLength:(int)displayLength
-(id) initWithContents:(NSString *)contents withType:(NSString *)type withDisplayLength:(int)displayLength withAppLocalizedName:(NSString *)localizedName withAppBundleURL:(NSString*)bundleURL withTimestamp:(int)timestamp
{
[super init];
clipContents = [[[NSString alloc] init] retain];
@ -45,6 +48,9 @@
[self setContents:contents setDisplayLength:displayLength];
[self setType:type];
[self setAppLocalizedName:localizedName];
[self setAppBundleURL:bundleURL];
[self setTimestamp:timestamp];
[self setHasName:false];
return self;
@ -93,17 +99,19 @@
-(void) setContents:(NSString *)newContents
{
id old = clipContents;
[newContents retain];
[clipContents release];
clipContents = newContents;
[old release];
[self resetDisplayString];
}
-(void) setType:(NSString *)newType
{
id old = clipType;
[newType retain];
[clipType release];
clipType = newType;
[old release];
}
-(void) setDisplayLength:(int)newDisplayLength
@ -114,6 +122,27 @@
}
}
-(void) setAppLocalizedName:(NSString *)new
{
id old = appLocalizedName;
[new retain];
appLocalizedName = new;
[old release];
}
-(void) setAppBundleURL:(NSString *)new
{
id old = appBundleURL;
[new retain];
appBundleURL = new;
[old release];
}
-(void) setTimestamp:(NSString *)newTimestamp
{
clipTimestamp = newTimestamp;
}
-(void) setHasName:(BOOL)newHasName
{
clipHasName = newHasName;
@ -148,6 +177,11 @@
return description;
}
-(JumpcutClipping *) clipping
{
return self;
}
-(NSString *) contents
{
// NSString *returnClipContents;
@ -156,6 +190,21 @@
return clipContents;
}
-(NSString *) appLocalizedName
{
return appLocalizedName;
}
-(NSString *) appBundleURL
{
return appBundleURL;
}
-(int) timestamp
{
return clipTimestamp;
}
-(int) displayLength
{
return clipDisplayLength;
@ -199,6 +248,8 @@
{
[clipContents release];
[clipType release];
[appLocalizedName release];
[appBundleURL release];
clipDisplayLength = 0;
[clipDisplayString release];
clipHasName = 0;

View file

@ -34,6 +34,7 @@
// In Jumpcut 0.5, I should go through and fiddle with the nomenclature.
#import <Foundation/Foundation.h>
#import "JumpcutClipping.h"
@interface JumpcutStore : NSObject {
@ -64,6 +65,7 @@
-(int) rememberNum;
-(int) displayLen;
-(int) jcListCount;
-(JumpcutClipping *) clippingAtPosition:(int)index;
-(NSString *) clippingContentsAtPosition:(int)index;
-(NSString *) clippingDisplayStringAtPosition:(int)index;
-(NSString *) clippingTypeAtPosition:(int)index;
@ -73,7 +75,8 @@
-(NSArray *) previousIndexes:(int)howMany containing:(NSString*)search; // This method is in newest-first order.
// Add a clipping
-(void) addClipping:(NSString *)clipping ofType:(NSString *)type;
-(void) addClipping:(NSString *)clipping ofType:(NSString *)type fromAppLocalizedName:(NSString *)appLocalizedName fromAppBundleURL:(NSString *)bundleURL atTimestamp:(int) timestamp;
-(void) addClipping:(JumpcutClipping*) clipping;
// Delete a clipping
-(void) clearItem:(int)index;

View file

@ -50,7 +50,7 @@
}
// Add a clipping
-(void) addClipping:(NSString *)clipping ofType:(NSString *)type{
-(void) addClipping:(NSString *)clipping ofType:(NSString *)type fromAppLocalizedName:(NSString *)appLocalizedName fromAppBundleURL:(NSString *)bundleURL atTimestamp:(int) timestamp{
if ([clipping length] == 0) {
return;
}
@ -59,24 +59,31 @@
// Create clipping
newClipping = [[JumpcutClipping alloc] initWithContents:clipping
withType:type
withDisplayLength:[self displayLen]];
withDisplayLength:[self displayLen]
withAppLocalizedName:appLocalizedName
withAppBundleURL:bundleURL
withTimestamp:timestamp];
[self addClipping:newClipping];
[newClipping release];
}
if ([jcList containsObject:newClipping] && [[[DBUserDefaults standardUserDefaults] valueForKey:@"removeDuplicates"] boolValue]) {
[jcList removeObject:newClipping];
-(void) addClipping:(JumpcutClipping*) clipping{
if ([jcList containsObject:clipping] && [[[DBUserDefaults standardUserDefaults] valueForKey:@"removeDuplicates"] boolValue]) {
[jcList removeObject:clipping];
}
// Push it onto our recent clippings stack
[jcList insertObject:newClipping atIndex:0];
[jcList insertObject:clipping atIndex:0];
// Delete clippings older than jcRememberNum
while ( [jcList count] > jcRememberNum ) {
[jcList removeObjectAtIndex:jcRememberNum];
}
[newClipping release];
}
-(void) addClipping:(NSString *)clipping ofType:(NSString *)type withPBCount:(int *)pbCount
{
[self addClipping:clipping ofType:type];
[self addClipping:clipping ofType:type fromAppLocalizedName:@"PBCount" fromAppBundleURL:nil atTimestamp:0];
}
// Clear remembered and listed
@ -89,7 +96,7 @@
-(void) mergeList {
NSString *merge = [[[[jcList reverseObjectEnumerator] allObjects] valueForKey:@"clipContents"] componentsJoinedByString:@"\n"];
[self addClipping:merge ofType:NSStringFromClass([merge class])];
[self addClipping:merge ofType:NSStringFromClass([merge class]) fromAppLocalizedName:@"Merge" fromAppBundleURL:nil atTimestamp:0];
}
-(void) clearItem:(int)index
@ -148,6 +155,15 @@
return [jcList count];
}
-(JumpcutClipping *) clippingAtPosition:(int)index
{
if ( index >= [jcList count] ) {
return nil;
} else {
return [[jcList objectAtIndex:index] clipping];
}
}
-(NSString *) clippingContentsAtPosition:(int)index
{
if ( index >= [jcList count] ) {

View file

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -14,10 +14,20 @@
@interface BezelWindow : NSWindow {
// "n of n" text in bezel
NSString *charString; // Slightly misleading, as this can be longer than one character
NSString *title;
// Clipping text shown in bezel
NSString *bezelText;
NSString *sourceText;
NSString *dateText;
NSImage *sourceIconImage;
NSImage *icon;
Boolean showSourceField;
NSImageView *sourceIcon;
RoundRecTextField *sourceFieldBackground;
RoundRecTextField *sourceFieldApp;
RoundRecTextField *sourceFieldDate;
RoundRecTextField *textField;
RoundRecTextField *charField;
NSImageView *iconView;
@ -25,6 +35,12 @@
Boolean color;
}
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)aStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag
showSource:(BOOL)showSource;
- (NSColor *)roundedBackgroundWithRect:(NSRect)bgRect withRadius:(float)radius withAlpha:(float)alpha;
- (NSColor *)sizedBezelBackgroundWithRadius:(float)radius withAlpha:(float)alpha;
@ -35,6 +51,9 @@
- (void)setColor:(BOOL)value;
- (void)setCharString:(NSString *)newChar;
- (void)setAlpha:(float)newValue;
- (void)setSource:(NSString *)newSource;
- (void)setDate:(NSString *)newDate;
- (void)setSourceIcon:(NSImage *)newSourceIcon;
- (id)delegate;
- (void)setDelegate:(id)newDelegate;

View file

@ -18,7 +18,8 @@ static const float lineHeight = 16;
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)aStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag {
defer:(BOOL)flag
showSource:(BOOL)showSource {
self = [super initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask
@ -32,8 +33,58 @@ static const float lineHeight = 16;
[self setHasShadow:NO];
[self setMovableByWindowBackground:NO];
[self setColor:NO];
[self setBackgroundColor:[self sizedBezelBackgroundWithRadius:25.0 withAlpha:[[DBUserDefaults standardUserDefaults] floatForKey:@"bezelAlpha"]]];
NSRect textFrame = NSMakeRect(12, 36, self.frame.size.width - 24, self.frame.size.height - 50);
[self setBackgroundColor:[self backgroundColor]];
showSourceField = showSource;
if (showSourceField)
{
sourceIcon = [[NSImageView alloc] initWithFrame: [self iconFrame]];
[[self contentView] addSubview:sourceIcon];
[sourceIcon setEditable:NO];
sourceFieldBackground = [[RoundRecTextField alloc] initWithFrame:[self sourceFrame]];
[[self contentView] addSubview:sourceFieldBackground];
[sourceFieldBackground setEditable:NO];
[sourceFieldBackground setTextColor:[NSColor whiteColor]];
[sourceFieldBackground setBackgroundColor:[NSColor colorWithCalibratedWhite:0.1 alpha:.45]];
[sourceFieldBackground setDrawsBackground:YES];
[sourceFieldBackground setBordered:NO];
sourceFieldApp = [[RoundRecTextField alloc] initWithFrame:[self sourceFrameLeft]];
[[self contentView] addSubview:sourceFieldApp];
[sourceFieldApp setEditable:NO];
[sourceFieldApp setTextColor:[NSColor whiteColor]];
[sourceFieldApp setBackgroundColor:[NSColor colorWithCalibratedWhite:0.1 alpha:0]];
[sourceFieldApp setDrawsBackground:YES];
[sourceFieldApp setBordered:NO];
[sourceFieldApp setAlignment:NSLeftTextAlignment];
NSMutableParagraphStyle *textParagraph = [[NSMutableParagraphStyle alloc] init];
[textParagraph setLineSpacing:100.0];
NSDictionary *attrDic = [NSDictionary dictionaryWithObjectsAndKeys:textParagraph, NSParagraphStyleAttributeName, nil];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"foo" attributes:attrDic];
[sourceFieldApp setAllowsEditingTextAttributes:YES];
[sourceFieldApp setAttributedStringValue:attrString];
NSFont *font = [sourceFieldApp font];
NSFont *newFont = [NSFont fontWithName:[font fontName] size:font.pointSize*3/2];
[sourceFieldApp setFont:newFont];
sourceFieldDate = [[RoundRecTextField alloc] initWithFrame:[self sourceFrameRight]];
[[self contentView] addSubview:sourceFieldDate];
[sourceFieldDate setEditable:NO];
[sourceFieldDate setTextColor:[NSColor whiteColor]];
[sourceFieldDate setBackgroundColor:[NSColor colorWithCalibratedWhite:0.1 alpha:0]];
[sourceFieldDate setDrawsBackground:YES];
[sourceFieldDate setBordered:NO];
[sourceFieldDate setAlignment:NSRightTextAlignment];
font = [sourceFieldDate font];
newFont = [NSFont fontWithName:[font fontName] size:font.pointSize*5/4];
[sourceFieldDate setFont:newFont];
}
NSRect textFrame = [self textFrame];
textField = [[RoundRecTextField alloc] initWithFrame:textFrame];
[[self contentView] addSubview:textField];
[textField setEditable:NO];
@ -44,7 +95,8 @@ static const float lineHeight = 16;
[textField setDrawsBackground:YES];
[textField setBordered:NO];
[textField setAlignment:NSLeftTextAlignment];
NSRect charFrame = NSMakeRect(([self frame].size.width - (3 * lineHeight)) / 2, 7, 4 * lineHeight, 1.2 * lineHeight);
NSRect charFrame = [self charFrame];
charField = [[RoundRecTextField alloc] initWithFrame:charFrame];
[[self contentView] addSubview:charField];
[charField setEditable:NO];
@ -53,6 +105,7 @@ static const float lineHeight = 16;
[charField setDrawsBackground:YES];
[charField setBordered:NO];
[charField setAlignment:NSCenterTextAlignment];
[self setInitialFirstResponder:textField];
return self;
}
@ -62,17 +115,81 @@ static const float lineHeight = 16;
- (void) update {
[super update];
[self setBackgroundColor:[self sizedBezelBackgroundWithRadius:25.0 withAlpha:[[DBUserDefaults standardUserDefaults] floatForKey:@"bezelAlpha"]]];
NSRect textFrame = NSMakeRect(12, 36, self.frame.size.width - 24, self.frame.size.height - 50);
[self setBackgroundColor:[self backgroundColor]];
Boolean savedShowSourceField = showSourceField;
if (nil == sourceText || 0 == sourceText.length)
showSourceField = false;
NSRect textFrame = [self textFrame];
[textField setFrame:textFrame];
NSRect charFrame = NSMakeRect(([self frame].size.width - (3 * lineHeight)) / 2, 7, 4 * lineHeight, 1.2 * lineHeight);
NSRect charFrame = [self charFrame];
[charField setFrame:charFrame];
if (showSourceField)
[sourceFieldBackground setBackgroundColor:[NSColor colorWithCalibratedWhite:0.1 alpha:.45]];
else if ( nil != sourceFieldApp )
[sourceFieldBackground setBackgroundColor:[NSColor colorWithCalibratedWhite:0.1 alpha:0]];
showSourceField = savedShowSourceField;
}
-(NSRect) iconFrame
{
NSRect frame = [self textFrame];
frame.origin.y += frame.size.height + 5;
frame.size.height = 1.8 * lineHeight;
frame.size.width = frame.size.height;
return frame;
}
-(NSRect) sourceFrame
{
NSRect frame = [self textFrame];
frame.origin.y += frame.size.height + 5;
frame.size.height = 1.8 * lineHeight;
frame.origin.x += frame.size.height + 5;
frame.size.width -= frame.size.height + 5;
return frame;
}
-(NSRect) sourceFrameLeft
{
NSRect frame = [self sourceFrame];
frame.size.width = frame.size.width * 1 / 3 - 5;
frame.origin.x += 5;
return frame;
}
-(NSRect) sourceFrameRight
{
NSRect frame = [self sourceFrame];
frame.size.height -= 0.3 * lineHeight;
frame.origin.x += frame.size.width * 1 / 3 + 10;
frame.size.width = frame.size.width * 2 / 3 - 10;
return frame;
}
-(NSRect) textFrame
{
int adjustHeight = 0;
if (showSourceField) adjustHeight = 1.8 * lineHeight;
return NSMakeRect(12, 36, self.frame.size.width - 24, self.frame.size.height - 50 - adjustHeight);
}
-(NSRect) charFrame
{
return NSMakeRect(([self frame].size.width - (3 * lineHeight)) / 2, 7, 4 * lineHeight, 1.2 * lineHeight);
}
-(NSColor*) backgroundColor
{
return [self sizedBezelBackgroundWithRadius:25.0 withAlpha:[[DBUserDefaults standardUserDefaults] floatForKey:@"bezelAlpha"]];
}
- (void) setAlpha:(float)newValue
{
[self setBackgroundColor:[self sizedBezelBackgroundWithRadius:25.0 withAlpha:[[DBUserDefaults standardUserDefaults] floatForKey:@"bezelAlpha"]]];
[self setBackgroundColor:[self backgroundColor]];
[[self contentView] setNeedsDisplay:YES];
}
@ -113,6 +230,50 @@ static const float lineHeight = 16;
[textField setStringValue:bezelText];
}
- (void)setSourceIcon:(NSImage *)newSourceIcon
{
if (!showSourceField)
return;
[newSourceIcon retain];
[sourceIconImage release];
sourceIconImage = newSourceIcon;
[sourceIcon setImage:sourceIconImage];
}
- (void)setSource:(NSString *)newSource
{
if (!showSourceField)
return;
// Ensure that the source will fit in the screen space available, and truncate nicely if need be.
NSDictionary *attributes = @{NSFontAttributeName: sourceFieldApp.font};
CGSize size = [newSource sizeWithAttributes:attributes]; // How big is this string when drawn in this font?
if (size.width >= sourceFieldApp.frame.size.width - 5)
{
newSource = [NSString stringWithFormat:@"%@...", newSource];
do
{
newSource = [NSString stringWithFormat:@"%@...", [newSource substringToIndex:[newSource length] - 4]];
size = [newSource sizeWithAttributes:attributes];
} while (size.width >= sourceFieldApp.frame.size.width - 5);
}
[newSource retain];
[sourceText release];
sourceText = newSource;
[sourceFieldApp setStringValue:sourceText];
}
- (void)setDate:(NSString *)newDate
{
if (!showSourceField)
return;
[newDate retain];
[dateText release];
dateText = newDate;
[sourceFieldDate setStringValue:dateText];
}
- (void)setColor:(BOOL)value
{
color=value;