Add a feature saving text orientation state to file

This commit is contained in:
1024jp 2015-08-07 13:18:50 +09:00
parent 9f170fffc3
commit c832045183
7 changed files with 72 additions and 3 deletions

View File

@ -10,6 +10,8 @@ develop
- CotEditor is now __Sandboxed__.
- New setting option for the behavior on document modification by external process (in Genearal pane).
- Share button in toolbar (Customize toobar to use it).
- Save text orientation state to the file and restore it when the file is opened.
- __for advanced users__: In this feature, CotEditor saves an *extended attribute* which named `com.coteditor.VerticalText` to the file only when the editor's text orientation is vertical. You can even disable the feature running the command `defaults write com.coteditor.CotEditor savesTextOrientation -bool NO` in Terminal.
### Additions/Changes

View File

@ -221,6 +221,7 @@
CEDefaultLargeFileAlertThresholdKey: @(100 * pow(1024, 2)), // 100 MB
CEDefaultAutosavingDelayKey: @5.0,
CEDefaultEnablesAutosaveInPlaceKey: @NO,
CEDefaultSavesTextOrientationKey: @YES,
};
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];

View File

@ -65,6 +65,7 @@ NSString *const CEIncompatibleConvertedCharKey = @"convertedChar";
@property (nonatomic) BOOL didAlertNotWritable; //
@property (nonatomic, copy) NSString *fileMD5;
@property (nonatomic, copy) NSString *fileContentString; // string that is read from the document file
@property (nonatomic, getter=isVerticalText) BOOL verticalText;
@property (nonatomic) CEODBEventSender *ODBEventSender;
@property (nonatomic) BOOL shouldSaveXattr;
@property (nonatomic, copy) NSString *autosaveIdentifier;
@ -156,6 +157,11 @@ NSString *const CEIncompatibleConvertedCharKey = @"convertedChar";
NSNumber *isWritable = nil;
[url getResourceValue:&isWritable forKey:NSURLIsWritableKey error:nil];
_writable = [isWritable boolValue];
// check file meta data for text orientation
if ([[NSUserDefaults standardUserDefaults] boolForKey:CEDefaultSavesTextOrientationKey]) {
_verticalText = [url getXattrBoolForName:XATTR_VERTICAL_TEXT_NAME];
}
}
return self;
}
@ -318,8 +324,9 @@ NSString *const CEIncompatibleConvertedCharKey = @"convertedChar";
{
// [caution] This method may be called from a background thread due to async-saving.
// store current encoding here, since the main thread will already be unblocked after `dataOfType:error:`
// store current state here, since the main thread will already be unblocked after `dataOfType:error:`
NSStringEncoding encoding = [self encoding];
BOOL isVerticalText = [[self editor] isVerticalLayoutOrientation];
BOOL success = [super writeToURL:url ofType:typeName forSaveOperation:saveOperation originalContentsURL:absoluteOriginalContentsURL error:outError];
@ -329,6 +336,11 @@ NSString *const CEIncompatibleConvertedCharKey = @"convertedChar";
[url setXattrEncoding:encoding];
}
// save text orientation state
if ([[NSUserDefaults standardUserDefaults] boolForKey:CEDefaultSavesTextOrientationKey]) {
[url setXattrBool:isVerticalText forName:XATTR_VERTICAL_TEXT_NAME];
}
if (saveOperation != NSAutosaveElsewhereOperation) {
// store file hash (MD5) in order to check the file content identity in `presentedItemDidChange`
NSData *data = [NSData dataWithContentsOfURL:url];
@ -741,6 +753,9 @@ NSString *const CEIncompatibleConvertedCharKey = @"convertedChar";
// update line endings menu selection in toolbar
[self applyLineEndingToView];
// apply text orientation
[[self editor] setVerticalLayoutOrientation:[self isVerticalText]];
// update encoding menu selection in toolbar, status bar and document inspector
[self updateEncodingInToolbarAndInfo];

View File

@ -240,6 +240,7 @@ extern NSString *__nonnull const CEDefaultColoringRangeBufferLengthKey;
extern NSString *__nonnull const CEDefaultLargeFileAlertThresholdKey;
extern NSString *__nonnull const CEDefaultAutosavingDelayKey;
extern NSString *__nonnull const CEDefaultEnablesAutosaveInPlaceKey;
extern NSString *__nonnull const CEDefaultSavesTextOrientationKey;

View File

@ -239,6 +239,7 @@ NSString *__nonnull const CEDefaultColoringRangeBufferLengthKey = @"coloringRang
NSString *__nonnull const CEDefaultLargeFileAlertThresholdKey = @"largeFileAlertThreshold";
NSString *__nonnull const CEDefaultAutosavingDelayKey = @"autosavingDelay";
NSString *__nonnull const CEDefaultEnablesAutosaveInPlaceKey = @"enablesAutosaveInPlace";
NSString *__nonnull const CEDefaultSavesTextOrientationKey = @"savesTextOrientation";

View File

@ -28,9 +28,18 @@
@import Foundation;
// xattr names
extern char const XATTR_VERTICAL_TEXT_NAME[];
@interface NSURL (Xattr)
// for com.apple.TextEncoding
- (NSStringEncoding)getXattrEncoding;
- (BOOL)setXattrEncoding:(NSStringEncoding)encoding;
// for general bool values
- (BOOL)getXattrBoolForName:(const char *)name;
- (BOOL)setXattrBool:(BOOL)value forName:(const char *)name;
@end

View File

@ -30,6 +30,10 @@
// constants
// public
char const XATTR_VERTICAL_TEXT_NAME[] = "com.coteditor.VerticalText";
// private
static char const XATTR_ENCODING_NAME[] = "com.apple.TextEncoding";
@ -77,7 +81,34 @@ static char const XATTR_ENCODING_NAME[] = "com.apple.TextEncoding";
if (!data) { return NO; }
return [self setXattrData:data name:XATTR_ENCODING_NAME];
return [self setXattrData:data forName:XATTR_ENCODING_NAME];
}
// ------------------------------------------------------
/// get boolean value of extended attribute for given name from the file at URL
- (BOOL)getXattrBoolForName:(const char *)name
// ------------------------------------------------------
{
NSData *data = [self getXattrDataForName:name];
return data != nil; // just check the existance of the key
}
// ------------------------------------------------------
/// set boolean value as extended attribute for given name to the file at URL
- (BOOL)setXattrBool:(BOOL)value forName:(const char *)name
// ------------------------------------------------------
{
if (value) {
NSData *data = [NSData dataWithBytes:"1" length:1];
return [self setXattrData:data forName:name];
} else {
return [self removeXattrDataForName:name];
}
}
@ -105,7 +136,7 @@ static char const XATTR_ENCODING_NAME[] = "com.apple.TextEncoding";
// ------------------------------------------------------
/// set extended attribute for given name to the file at URL
- (BOOL)setXattrData:(nonnull NSData *)data name:(const char *)name
- (BOOL)setXattrData:(nonnull NSData *)data forName:(const char *)name
// ------------------------------------------------------
{
int result = setxattr([[self path] fileSystemRepresentation], name, [data bytes], [data length], 0, XATTR_NOFOLLOW);
@ -113,4 +144,13 @@ static char const XATTR_ENCODING_NAME[] = "com.apple.TextEncoding";
return result == 0;
}
// ------------------------------------------------------
/// remove extended attribute for given name from the file at URL
- (BOOL)removeXattrDataForName:(const char *)name
// ------------------------------------------------------
{
return removexattr([[self path] fileSystemRepresentation], name, XATTR_NOFOLLOW);
}
@end