2
0

iCloud sync of store.

[FIXED]     Guide toggle not working well.
[IMPROVED]  Core Data on a separate thread.
[IMPROVED]  Guide.
This commit is contained in:
Maarten Billemont 2012-02-05 00:36:19 +01:00
parent 960432577e
commit 7c36ff6acd
33 changed files with 169 additions and 92 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

View File

@ -203,6 +203,7 @@
DA84819414CB521E00A2FA22 /* tip_location_mercury.png in Resources */ = {isa = PBXBuildFile; fileRef = DA84817614CB521E00A2FA22 /* tip_location_mercury.png */; };
DA84819514CB521E00A2FA22 /* tip_location_teal.png in Resources */ = {isa = PBXBuildFile; fileRef = DA84817714CB521E00A2FA22 /* tip_location_teal.png */; };
DA84819614CB521E00A2FA22 /* tip_location_wood.png in Resources */ = {isa = PBXBuildFile; fileRef = DA84817814CB521E00A2FA22 /* tip_location_wood.png */; };
DA8E8E4614DD7C1D0044257E /* logo-bare.png in Resources */ = {isa = PBXBuildFile; fileRef = DA8E8E4514DD7C1D0044257E /* logo-bare.png */; };
DAA3B68E14CCCEE700F35AF6 /* icon_addressbook-person@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA3B53814CCCEE700F35AF6 /* icon_addressbook-person@2x.png */; };
DAA3B68F14CCCEE700F35AF6 /* icon_addressbook.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA3B53914CCCEE700F35AF6 /* icon_addressbook.png */; };
DAA3B69014CCCEE700F35AF6 /* icon_addressbook@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA3B53A14CCCEE700F35AF6 /* icon_addressbook@2x.png */; };
@ -904,6 +905,8 @@
DA84817614CB521E00A2FA22 /* tip_location_mercury.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tip_location_mercury.png; sourceTree = "<group>"; };
DA84817714CB521E00A2FA22 /* tip_location_teal.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tip_location_teal.png; sourceTree = "<group>"; };
DA84817814CB521E00A2FA22 /* tip_location_wood.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tip_location_wood.png; sourceTree = "<group>"; };
DA8E8E4514DD7C1D0044257E /* logo-bare.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "logo-bare.png"; path = "Resources/logo-bare.png"; sourceTree = "<group>"; };
DA8E8E4714DDA62D0044257E /* MasterPassword.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = MasterPassword.entitlements; sourceTree = "<group>"; };
DAA3B53814CCCEE700F35AF6 /* icon_addressbook-person@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_addressbook-person@2x.png"; sourceTree = "<group>"; };
DAA3B53914CCCEE700F35AF6 /* icon_addressbook.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_addressbook.png; sourceTree = "<group>"; };
DAA3B53A14CCCEE700F35AF6 /* icon_addressbook@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_addressbook@2x.png"; sourceTree = "<group>"; };
@ -1805,6 +1808,7 @@
DA5BFA50147E415C00F98B1E /* MasterPassword */ = {
isa = PBXGroup;
children = (
DA8E8E4714DDA62D0044257E /* MasterPassword.entitlements */,
DA7C28A214AF02A000491972 /* Models */,
DA7C28A314AF02B100491972 /* Data */,
DA5BFA59147E415C00F98B1E /* OPAppDelegate.h */,
@ -1834,6 +1838,7 @@
DA5BFA51147E415C00F98B1E /* Supporting Files */ = {
isa = PBXGroup;
children = (
DA8E8E4514DD7C1D0044257E /* logo-bare.png */,
DA6556F714D730B700841C99 /* Guide */,
DAA3B80414CDBBC600F35AF6 /* jquery-1.6.1.min.js */,
DA84811E14CB50C100A2FA22 /* Tooltips */,
@ -2992,6 +2997,7 @@
DA65571214D760BD00841C99 /* guide_page_6@2x.png in Resources */,
DA41A40B14DB3BF100638533 /* guide_page_0.png in Resources */,
DA41A40C14DB3BF100638533 /* guide_page_0@2x.png in Resources */,
DA8E8E4614DD7C1D0044257E /* logo-bare.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3182,6 +3188,7 @@
DA5BFA6E147E415C00F98B1E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MasterPassword/MasterPassword.entitlements;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "MasterPassword/MasterPassword-Prefix.pch";
INFOPLIST_FILE = "MasterPassword/MasterPassword-Info.plist";
@ -3194,6 +3201,7 @@
DA5BFA6F147E415C00F98B1E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MasterPassword/MasterPassword.entitlements;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "MasterPassword/MasterPassword-Prefix.pch";
INFOPLIST_FILE = "MasterPassword/MasterPassword-Info.plist";

View File

@ -349,7 +349,7 @@ The passwords aren't saved anywhere. This is a major advantage: if you loose yo
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<rect key="contentStretch" x="0.050000000000000003" y="0.10000000000000001" width="0.89999999999999991" height="0.79999999999999982"/>
</imageView>
<imageView userInteractionEnabled="NO" alpha="0.80000001192092896" contentMode="scaleToFill" image="ui_panel_display.png" id="cw7-HD-Wht">
<imageView userInteractionEnabled="NO" alpha="0.80000000000000004" contentMode="scaleToFill" image="ui_panel_display.png" id="cw7-HD-Wht">
<rect key="frame" x="11" y="20" width="298" height="86"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<rect key="contentStretch" x="0.050000000000000003" y="0.10000000000000001" width="0.89999999999999991" height="0.79999999999999982"/>

View File

@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<string>Passwords</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFiles</key>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>$(TeamIdentifierPrefix)com.lyndir.lhunath.MasterPassword</string>
</array>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>$(TeamIdentifierPrefix)com.lyndir.lhunath.MasterPassword</string>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.lyndir.lhunath.MasterPassword</string>
</array>
</dict>
</plist>

View File

@ -121,7 +121,7 @@
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if ([[OPConfig get].showQuickstart boolValue])
if ([[OPConfig get].showQuickStart boolValue])
[self showGuide];
else
[self loadKeyPhrase];
@ -244,13 +244,14 @@
- (void)applicationWillResignActive:(UIApplication *)application {
[self saveContext];
if (![[OPConfig get].rememberKeyPhrase boolValue])
self.keyPhrase = nil;
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Saves changes in the application's managed object context before the application terminates.
- (void)applicationWillTerminate:(UIApplication *)application {
[self saveContext];
}
@ -269,18 +270,13 @@
return [(OPAppDelegate *)[UIApplication sharedApplication].delegate managedObjectModel];
}
- (void)saveContext
{
NSError *error = nil;
if ([self.managedObjectContext hasChanges] && ![self.managedObjectContext save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
*/
err(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
- (void)saveContext {
[self.managedObjectContext performBlock:^{
NSError *error = nil;
if ([self.managedObjectContext hasChanges] && ![self.managedObjectContext save:&error])
err(@"Unresolved error %@", error);
}];
}
- (void)setKeyPhrase:(NSString *)keyPhrase {
@ -312,17 +308,30 @@
*/
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil)
{
if (__managedObjectContext)
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
if (coordinator) {
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
__managedObjectContext.persistentStoreCoordinator = coordinator;
[[NSNotificationCenter defaultCenter] addObserverForName:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:coordinator
queue:nil
usingBlock:^(NSNotification *note) {
dbg(@"Ubiquitous content change: %@", note);
[__managedObjectContext performBlock:^{
[__managedObjectContext mergeChangesFromContextDidSaveNotification:note];
[[NSNotificationCenter defaultCenter] postNotification:
[NSNotification notificationWithName:OPPersistentStoreDidChangeNotification
object:self userInfo:[note userInfo]]];
}];
}];
}
return __managedObjectContext;
}
@ -332,14 +341,11 @@
*/
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil)
{
if (__managedObjectModel)
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MasterPassword" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
return __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
}
/**
@ -348,19 +354,23 @@
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil)
{
if (__persistentStoreCoordinator)
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MasterPassword.sqlite"];
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
[__persistentStoreCoordinator lock];
NSError *error = nil;
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL
options:[NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, NSMigratePersistentStoresAutomaticallyOption,
(id)kCFBooleanTrue, NSInferMappingModelAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
@"MasterPassword.store", NSPersistentStoreUbiquitousContentNameKey,
[[[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil]
URLByAppendingPathComponent:@"store"
isDirectory:YES], NSPersistentStoreUbiquitousContentURLKey,
nil]
error:&error])
{
@ -395,7 +405,8 @@
@throw [NSException exceptionWithName:error.domain reason:error.localizedDescription
userInfo:[NSDictionary dictionaryWithObject:error forKey:@"cause"]];
}
[__persistentStoreCoordinator unlock];
return __persistentStoreCoordinator;
}

View File

@ -13,7 +13,7 @@
@property (nonatomic, retain) NSNumber *rememberKeyPhrase;
@property (nonatomic, retain) NSNumber *forgetKeyPhrase;
@property (nonatomic, retain) NSNumber *helpHidden;
@property (nonatomic, retain) NSNumber *showQuickstart;
@property (nonatomic, retain) NSNumber *showQuickStart;
+ (OPConfig *)get;

View File

@ -10,7 +10,7 @@
@implementation OPConfig
@dynamic dataStoreError, storeKeyPhrase, rememberKeyPhrase, forgetKeyPhrase, helpHidden, showQuickstart;
@dynamic dataStoreError, storeKeyPhrase, rememberKeyPhrase, forgetKeyPhrase, helpHidden, showQuickStart;
- (id)init {
@ -24,7 +24,7 @@
[NSNumber numberWithBool:YES], NSStringFromSelector(@selector(rememberKeyPhrase)),
[NSNumber numberWithBool:NO], NSStringFromSelector(@selector(forgetKeyPhrase)),
[NSNumber numberWithBool:NO], NSStringFromSelector(@selector(helpHidden)),
[NSNumber numberWithBool:YES], NSStringFromSelector(@selector(showQuickstart)),
[NSNumber numberWithBool:YES], NSStringFromSelector(@selector(showQuickStart)),
nil]];
return self;

View File

@ -17,8 +17,8 @@
@property (nonatomic) int16_t type;
@property (nonatomic) int16_t uses;
@property (nonatomic) NSTimeInterval lastUsed;
@property (nonatomic, readonly) id content;
- (void)use;
- (id)content;
@end

View File

@ -28,7 +28,7 @@
[super viewWillDisappear:animated];
[OPConfig get].showQuickstart = [NSNumber numberWithBool:NO];
[OPConfig get].showQuickStart = [NSNumber numberWithBool:NO];
[[OPAppDelegate get] loadKeyPhrase];
}

View File

@ -75,25 +75,29 @@
[self updateAnimated:NO];
}
- (void)viewWillDisappear:(BOOL)animated {
- (void)viewDidAppear:(BOOL)animated {
[super viewWillDisappear:animated];
[super viewDidAppear:animated];
self.searchTipContainer.hidden = YES;
// Put the search tip on the window so it's above the nav bar.
if (![self.searchTipContainer.superview isEqual:self.navigationController.navigationBar.superview]) {
CGRect frameInWindow = [self.searchTipContainer.window convertRect:self.searchTipContainer.frame
fromView:self.searchTipContainer.superview];
[self.searchTipContainer removeFromSuperview];
[self.navigationController.navigationBar.superview addSubview:self.searchTipContainer];
self.searchTipContainer.frame = [self.searchTipContainer.window convertRect:frameInWindow
toView:self.searchTipContainer.superview];
}
}
- (void)viewDidLoad {
// Put the search tip on the window so it's above the nav bar.
CGRect newFrame = [self.navigationController.navigationBar convertRect:self.searchTipContainer.frame
fromView:self.searchTipContainer.superview];
[self.searchTipContainer removeFromSuperview];
[self.navigationController.navigationBar addSubview:self.searchTipContainer];
self.searchTipContainer.frame = newFrame;
self.searchTipContainer.hidden = YES;
// Because IB's edit button doesn't auto-toggle self.editable like editButtonItem does.
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"ui_background"]];
//self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"logo-bare.png"]];
self.navigationItem.titleView.frame = CGRectMake(0, 0, 50, 50);
self.navigationItem.titleView.center = self.navigationController.navigationBar.center;
self.navigationItem.titleView.contentMode = UIViewContentModeScaleAspectFit;
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
if (![OPAppDelegate get].keyPhrase) {
@ -216,10 +220,12 @@
- (void)showAlertWithTitle:(NSString *)title message:(NSString *)message {
self.alertTitle.text = title;
NSRange scrollRange = NSMakeRange(self.alertBody.text.length, message.length);
if ([self.alertBody.text length])
self.alertBody.text = [NSString stringWithFormat:@"%@\n\n---\n\n%@", self.alertBody.text, message];
else
self.alertBody.text = message;
[self.alertBody scrollRangeToVisible:scrollRange];
[UIView animateWithDuration:0.2f animations:^{
self.alertContainer.alpha = 1;
@ -310,18 +316,19 @@
[self updateElement:^{
// Update password type.
if (ClassFromOPElementType(type) != ClassFromOPElementType(self.activeElement.type)) {
if (ClassFromOPElementType(type) != ClassFromOPElementType(self.activeElement.type))
// Type requires a different class of element. Recreate the element.
OPElementEntity *newElement = [NSEntityDescription insertNewObjectForEntityForName:ClassNameFromOPElementType(type)
inManagedObjectContext:[OPAppDelegate managedObjectContext]];
newElement.name = self.activeElement.name;
newElement.mpHashHex = self.activeElement.mpHashHex;
newElement.uses = self.activeElement.uses;
newElement.lastUsed = self.activeElement.lastUsed;
[[OPAppDelegate managedObjectContext] deleteObject:self.activeElement];
self.activeElement = newElement;
}
[[OPAppDelegate managedObjectContext] performBlockAndWait:^{
OPElementEntity *newElement = [NSEntityDescription insertNewObjectForEntityForName:ClassNameFromOPElementType(type)
inManagedObjectContext:[OPAppDelegate managedObjectContext]];
newElement.name = self.activeElement.name;
newElement.mpHashHex = self.activeElement.mpHashHex;
newElement.uses = self.activeElement.uses;
newElement.lastUsed = self.activeElement.lastUsed;
[[OPAppDelegate managedObjectContext] deleteObject:self.activeElement];
self.activeElement = newElement;
}];
self.activeElement.type = type;

View File

@ -42,16 +42,18 @@
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView {
[[NSNotificationCenter defaultCenter] addObserverForName:OPPersistentStoreDidChangeNotification
object:nil queue:nil usingBlock:^(NSNotification *note) {
NSError *error;
if (![self.fetchedResultsController performFetch:&error])
err(@"Couldn't fetch elements: %@", error);
}];
tableView.backgroundColor = [UIColor blackColor];
tableView.rowHeight = 34.0f;
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
- (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView {
[tableView setEditing:self.searchDisplayController.searchContentsController.editing animated:NO];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self update];
@ -89,7 +91,8 @@
[self.searchDisplayController.searchResultsTableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.searchDisplayController.searchResultsTableView;
switch(type) {
@ -118,7 +121,8 @@
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
UITableView *tableView = self.searchDisplayController.searchResultsTableView;
switch(type) {
@ -191,21 +195,33 @@
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
OPElementEntity *element;
if (indexPath.section < [[self.fetchedResultsController sections] count])
element = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.delegate didSelectElement:[self.fetchedResultsController objectAtIndexPath:indexPath]];
else {
// "New" section.
element = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([OPElementGeneratedEntity class])
inManagedObjectContext:[OPAppDelegate managedObjectContext]];
assert([element isKindOfClass:ClassFromOPElementType(element.type)]);
element.name = self.searchDisplayController.searchBar.text;
element.mpHashHex = [OPAppDelegate get].keyPhraseHashHex;
NSString *siteName = self.searchDisplayController.searchBar.text;
[AlertViewController showAlertWithTitle:@"New Site"
message:l(@"Do you want to create a new site named:\n%@", siteName)
viewStyle:UIAlertViewStyleDefault
tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
if (buttonIndex == [alert cancelButtonIndex])
return;
[self.fetchedResultsController.managedObjectContext performBlock:^{
OPElementEntity *element = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([OPElementGeneratedEntity class])
inManagedObjectContext:self.fetchedResultsController.managedObjectContext];
assert([element isKindOfClass:ClassFromOPElementType(element.type)]);
element.name = siteName;
element.mpHashHex = [OPAppDelegate get].keyPhraseHashHex;
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate didSelectElement:element];
});
}];
} cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonYes, nil];
}
[self.delegate didSelectElement:element];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
@ -232,11 +248,11 @@
// "New" section.
return;
if (editingStyle == UITableViewCellEditingStyleDelete) {
OPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath];
[[OPAppDelegate managedObjectContext] deleteObject:element];
}
if (editingStyle == UITableViewCellEditingStyleDelete)
[self.fetchedResultsController.managedObjectContext performBlock:^{
OPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.fetchedResultsController.managedObjectContext deleteObject:element];
}];
}

View File

@ -8,6 +8,8 @@
#import <Foundation/Foundation.h>
#define OPPersistentStoreDidChangeNotification @"OPPersistentStoreDidChange"
typedef enum {
OPElementContentTypePassword,
OPElementContentTypeNote,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 KiB

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 KiB

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 KiB

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 KiB

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 KiB

After

Width:  |  Height:  |  Size: 240 KiB

View File

@ -17,6 +17,9 @@
h2 {
font-size: inherit;
}
h3 {
font-size: 12px;
}
i {
font-weight: bold;
}
@ -33,6 +36,17 @@
color: inherit;
font-weight: bold;
}
header {
height: 8em;
padding: 3em 0 0;
}
header h1, header h2 {
margin: 0;
padding: 0.5ex;
}
header h3 {
padding-top: 2em;
}
</style>
<script src="jquery-1.6.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
@ -43,8 +57,11 @@
</script>
</head>
<body>
<h1 onclick="setClass('OPElementStoredEntity')">Master Password</h1>
<h2 onclick="setClass('OPElementGeneratedEntity')">by Lyndir</h2>
<header>
<h1>Master Password</h1>
<h2>by <a href="http://www.lyndir.com">Lyndir</a></h2>
<h3>&copy; 2011</h3>
</header>
<h2 id="1">&mdash; 1 &mdash;</h2>
<p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -106,9 +106,9 @@
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Show Quickstart</string>
<string>Show Quick Start</string>
<key>Key</key>
<string>showQuickstart</string>
<string>showQuickStart</string>
<key>DefaultValue</key>
<true/>
</dict>