|
@@ -0,0 +1,653 @@
|
|
|
+//
|
|
|
+// KMFreeTextStylesViewController.m
|
|
|
+// PDF Reader Pro Edition
|
|
|
+//
|
|
|
+// Created by KdanWJ on 2021/1/29.
|
|
|
+//
|
|
|
+
|
|
|
+#import "KMFreeTextStylesViewController.h"
|
|
|
+#import "PDF_Reader_Pro-Swift.h"
|
|
|
+//#import "NSMenu_SKExtensions.h"
|
|
|
+//#import <SkimNotes/SkimNotes.h>
|
|
|
+//#import "PDFAnnotation_SKExtensions.h"
|
|
|
+
|
|
|
+typedef NS_ENUM(NSUInteger, KMFreeTextMenuActionType) {
|
|
|
+ KMFreeTextMenuActionType_Redefine = 0,
|
|
|
+ KMFreeTextMenuActionType_Rename,
|
|
|
+ KMFreeTextMenuActionType_Delete,
|
|
|
+ KMFreeTextMenuActionType_Default
|
|
|
+};
|
|
|
+
|
|
|
+#pragma mark - KMScstyleTableRowView
|
|
|
+
|
|
|
+@interface KMScstyleTableRowView : NSTableRowView
|
|
|
+@end
|
|
|
+@implementation KMScstyleTableRowView
|
|
|
+
|
|
|
+- (instancetype)init {
|
|
|
+ self = [super init];
|
|
|
+ if (self) {
|
|
|
+ [self addTrackingArea];
|
|
|
+ }
|
|
|
+ return self;
|
|
|
+}
|
|
|
+
|
|
|
+- (void)addTrackingArea {
|
|
|
+ NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingActiveAlways |NSTrackingMouseMoved owner:self userInfo:nil];
|
|
|
+ [self addTrackingArea:trackingArea];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)drawSelectionInRect:(NSRect)dirtyRect {
|
|
|
+ NSRect selectionRect = self.bounds;
|
|
|
+ [[KMAppearance KMColor_Status_Sel] setFill];
|
|
|
+ NSBezierPath *selectionPath = [NSBezierPath bezierPathWithRoundedRect:selectionRect xRadius:0 yRadius:0];
|
|
|
+ [selectionPath fill];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)mouseEntered:(NSEvent *)event {
|
|
|
+ [super mouseEntered:event];
|
|
|
+}
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@interface KMFreeTextStyleTableViewCell:NSTableCellView <NSTextFieldDelegate>
|
|
|
+
|
|
|
+@property (nonatomic, retain) IBOutlet NSImageView *checkImageView;
|
|
|
+
|
|
|
+@property (nonatomic, retain) IBOutlet NSButton *updateButton;
|
|
|
+
|
|
|
+@property (nonatomic, retain) IBOutlet NSButton *moreButton;
|
|
|
+
|
|
|
+@property (nonatomic, retain) IBOutlet NSTextField *styleLabel;
|
|
|
+
|
|
|
+@property (assign) IBOutlet NSLayoutConstraint *styleLabelHeightConstant;
|
|
|
+
|
|
|
+@property (nonatomic, copy) void (^mouseMoveCallback) (BOOL mouseEntered);
|
|
|
+
|
|
|
+@property (nonatomic, copy) void (^menuActionCallback) (KMFreeTextMenuActionType memuType);
|
|
|
+
|
|
|
+@property (nonatomic, copy) void (^renameActionCallback) (NSString *count, KMFreeTextMenuActionType memuType);
|
|
|
+
|
|
|
+@property (nonatomic, retain) NSArray *annotations;
|
|
|
+
|
|
|
+@property (nonatomic, retain) NSArray *styleTitles;
|
|
|
+
|
|
|
+@property (nonatomic, assign) NSInteger *selectRow;
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@implementation KMFreeTextStyleTableViewCell
|
|
|
+
|
|
|
+- (void)dealloc {
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (void)awakeFromNib {
|
|
|
+ [super awakeFromNib];
|
|
|
+
|
|
|
+ self.checkImageView.hidden = YES;
|
|
|
+
|
|
|
+ self.updateButton.wantsLayer = YES;
|
|
|
+ self.updateButton.title = @"";
|
|
|
+ self.updateButton.layer.cornerRadius = CGRectGetWidth(_updateButton.bounds)/2;
|
|
|
+ self.updateButton.layer.backgroundColor = [KMAppearance KMColor_Layout_H2].CGColor;
|
|
|
+ self.updateButton.hidden = YES;
|
|
|
+
|
|
|
+ self.moreButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnArrowRight"];
|
|
|
+ _moreButton.hidden = YES;
|
|
|
+ _moreButton.enabled = NO;
|
|
|
+
|
|
|
+ self.styleLabel.editable = NO;
|
|
|
+
|
|
|
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidEndEdit:) name:NSControlTextDidEndEditingNotification object:_styleLabel];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)viewDidMoveToWindow {
|
|
|
+ [super viewDidMoveToWindow];
|
|
|
+ if ([self window] != nil) {
|
|
|
+ [self addTrackingRect:[self bounds]
|
|
|
+ owner:self
|
|
|
+ userData:NULL
|
|
|
+ assumeInside:NO];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)setFrameSize:(NSSize)newSize {
|
|
|
+ [super setFrameSize:newSize];
|
|
|
+ [self addTrackingRect:NSMakeRect(0, 0, newSize.width, newSize.height)
|
|
|
+ owner:self
|
|
|
+ userData:NULL
|
|
|
+ assumeInside:NO];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)mouseEntered:(NSEvent *)event {
|
|
|
+ if (self.mouseMoveCallback) {
|
|
|
+ self.mouseMoveCallback(YES);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)mouseExited:(NSEvent *)event {
|
|
|
+ if (self.mouseMoveCallback) {
|
|
|
+ self.mouseMoveCallback(NO);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (BOOL) isChange {
|
|
|
+ int selectInt = (int)self.selectRow;
|
|
|
+
|
|
|
+ NSAttributedString *string = self.styleLabel.attributedStringValue;
|
|
|
+ if(string.length < 1) {
|
|
|
+ return NO;
|
|
|
+ }
|
|
|
+ NSDictionary *dict = [string attributesAtIndex:0 effectiveRange:nil];
|
|
|
+ NSFont *font = dict[NSFontAttributeName];
|
|
|
+ NSColor *color = dict[NSForegroundColorAttributeName];
|
|
|
+ NSInteger alignment = self.styleLabel.alignment;
|
|
|
+
|
|
|
+ BOOL colorIsEqual = NO;
|
|
|
+ BOOL alignEqual = NO;
|
|
|
+ BOOL fontSizeEqual = NO;
|
|
|
+ BOOL fontWeightEqual = NO;
|
|
|
+ BOOL fontNameEqual = NO;
|
|
|
+ BOOL stringEqual = NO;
|
|
|
+
|
|
|
+ NSColor *color2 = nil;
|
|
|
+ if (_styleTitles[selectInt][@"Font Color"]) {
|
|
|
+ color2 = [NSUnarchiver unarchiveObjectWithData:_styleTitles[selectInt][@"Font Color"]];
|
|
|
+ }
|
|
|
+ if (CGColorEqualToColor(color.CGColor, color2.CGColor)){
|
|
|
+ colorIsEqual = YES;
|
|
|
+ }
|
|
|
+ NSString *alignString = @"NSTextAlignmentLeft";
|
|
|
+ if (_styleLabel.alignment == NSTextAlignmentLeft) {
|
|
|
+ alignment = @"NSTextAlignmentLeft";
|
|
|
+ } else if (_styleLabel.alignment == NSTextAlignmentCenter) {
|
|
|
+ alignment = @"NSTextAlignmentCenter";
|
|
|
+ } else if (_styleLabel.alignment == NSTextAlignmentRight) {
|
|
|
+ alignment = @"NSTextAlignmentRight";
|
|
|
+ } else if (_styleLabel.alignment == NSTextAlignmentJustified) {
|
|
|
+ alignment = @"NSTextAlignmentJustified";
|
|
|
+ }
|
|
|
+ if ([alignString isEqualToString:_styleTitles[selectInt][@"Font Alignment"]]) {
|
|
|
+ alignEqual = YES;
|
|
|
+ }
|
|
|
+ if ([_styleLabel.stringValue isEqualToString:_styleTitles[selectInt][@"StringValue"]]) {
|
|
|
+ stringEqual = YES;
|
|
|
+ }
|
|
|
+ NSString *fontSize = [NSString stringWithFormat:@"%.f",font.pointSize];
|
|
|
+ if ([fontSize isEqualToString:_styleTitles[selectInt][@"Font Size"]]) {
|
|
|
+ fontSizeEqual = YES;
|
|
|
+ }
|
|
|
+ if ([font.fontName isEqualToString:_styleTitles[selectInt][@"Font Name"]]) {
|
|
|
+ fontNameEqual = YES;
|
|
|
+ }
|
|
|
+ NSString *weight = [font.fontDescriptor objectForKey:NSFontFaceAttribute];
|
|
|
+ if ([weight isEqualToString:_styleTitles[selectInt][@"Font Weight"]]) {
|
|
|
+ fontWeightEqual = YES;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (colorIsEqual && alignEqual && fontSizeEqual && fontWeightEqual && stringEqual) {
|
|
|
+ return NO;
|
|
|
+ } else {
|
|
|
+ return YES;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - Action
|
|
|
+
|
|
|
+- (IBAction)updateButtonAction:(NSButton *)sender {
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)moreButtonAction:(NSButton *)sender {
|
|
|
+ NSMenu *menu = [[NSMenu alloc] init];
|
|
|
+ NSMenuItem *redefineItem = [menu addItemWithTitle:NSLocalizedString(@"Redefine from Selection", nil) action:@selector(redefineAction:) target:self];
|
|
|
+ [redefineItem setRepresentedObject:self];
|
|
|
+ [menu addItem:[NSMenuItem separatorItem]];
|
|
|
+ NSMenuItem *renameItem = [menu addItemWithTitle:NSLocalizedString(@"Rename Style", nil) action:@selector(renameAction:) target:self];
|
|
|
+ [renameItem setRepresentedObject:self];
|
|
|
+ [menu addItem:[NSMenuItem separatorItem]];
|
|
|
+ NSMenuItem *deleteItem = [menu addItemWithTitle:NSLocalizedString(@"Delete style", nil) action:@selector(deleteAction:) target:self];
|
|
|
+ [deleteItem setRepresentedObject:self];
|
|
|
+ NSMenuItem *defaultItem = [menu addItemWithTitle:NSLocalizedString(@"Restore Default Style", nil) action:@selector(defaultAction:) target:self];
|
|
|
+ [defaultItem setRepresentedObject:self];
|
|
|
+ [NSMenu popUpContextMenu:menu withEvent:[NSApp currentEvent] forView:(NSButton *)sender];
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)redefineAction:(id)sender {
|
|
|
+ if (self.menuActionCallback) {
|
|
|
+ self.menuActionCallback(KMFreeTextMenuActionType_Redefine);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)renameAction:(id)sender {
|
|
|
+ _styleLabel.editable = YES;
|
|
|
+ [_styleLabel becomeFirstResponder];
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)deleteAction:(id)sender {
|
|
|
+ if (self.menuActionCallback) {
|
|
|
+ self.menuActionCallback(KMFreeTextMenuActionType_Delete);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)defaultAction:(id)sender {
|
|
|
+ if (self.menuActionCallback) {
|
|
|
+ self.menuActionCallback(KMFreeTextMenuActionType_Default);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
|
|
|
+ SEL action = [menuItem action];
|
|
|
+ if (action == @selector(redefineAction:)) {
|
|
|
+ PDFAnnotation *annotation = _annotations.firstObject;
|
|
|
+// if (annotation.string != nil) {
|
|
|
+// return YES;
|
|
|
+// } else {
|
|
|
+ return NO;
|
|
|
+// }
|
|
|
+ } else if (action == @selector(deleteAction:)) {
|
|
|
+ if (_styleTitles.count > 1) {
|
|
|
+ return YES;
|
|
|
+ } else {
|
|
|
+ return NO;
|
|
|
+ }
|
|
|
+ } else if (action == @selector(defaultAction:)) {
|
|
|
+ if (_selectRow > 9) {
|
|
|
+ return NO;
|
|
|
+ } else {
|
|
|
+ if (_styleTitles.count > 1) {
|
|
|
+ if ([self isChange]) {
|
|
|
+ return YES;
|
|
|
+ } else {
|
|
|
+ return NO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return YES;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return YES;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - NSNotification
|
|
|
+
|
|
|
+- (void)contextDidEndEdit:(NSNotification *)notification {
|
|
|
+ NSTextField *textField = (NSTextField *)notification.object;
|
|
|
+
|
|
|
+ if (self.renameActionCallback) {
|
|
|
+ self.renameActionCallback(textField.stringValue, KMFreeTextMenuActionType_Rename);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@interface KMFreeTextStylesViewController () <NSTableViewDelegate, NSTableViewDataSource>
|
|
|
+
|
|
|
+@property (assign) IBOutlet NSTextField *defaultStylesLabel;
|
|
|
+@property (assign) IBOutlet NSButton *styleAddButton;
|
|
|
+@property (assign) IBOutlet NSButton *styleMoreButton;
|
|
|
+
|
|
|
+@property (assign) IBOutlet NSScrollView *styleScrollView;
|
|
|
+@property (assign) IBOutlet NSTableView *scstyleTableView;
|
|
|
+
|
|
|
+@property (nonatomic, retain) NSMutableArray <NSDictionary *>*freetextStyles;
|
|
|
+
|
|
|
+@property (nonatomic, assign) NSInteger lastSelectRow;
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@implementation KMFreeTextStylesViewController
|
|
|
+
|
|
|
+- (void)dealloc {
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (void)viewDidLoad {
|
|
|
+ [super viewDidLoad];
|
|
|
+ // Do view setup here.
|
|
|
+
|
|
|
+ self.defaultStylesLabel.stringValue = NSLocalizedString(@"Default Style", nil);
|
|
|
+
|
|
|
+ self.styleAddButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnAddNor"];
|
|
|
+ self.styleMoreButton.image = [NSImage imageNamed:@"KMImageNameUXIconBtnSidebarMoreSecondary"];
|
|
|
+
|
|
|
+ [[_defaultStylesLabel cell] setLineBreakMode:NSLineBreakByCharWrapping];
|
|
|
+ [[_defaultStylesLabel cell] setTruncatesLastVisibleLine:YES];
|
|
|
+
|
|
|
+ self.lastSelectRow = -1;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - View Methods
|
|
|
+
|
|
|
+#pragma mark - freetextStyles
|
|
|
+
|
|
|
+- (void)setFreetextStyles:(NSMutableArray<NSDictionary *> *)freetextStyles {
|
|
|
+ [[NSUserDefaults standardUserDefaults] setObject:freetextStyles forKey:@"KMFreetextAnnotationStylesKey"];
|
|
|
+ [[NSUserDefaults standardUserDefaults] synchronize];
|
|
|
+}
|
|
|
+
|
|
|
+- (NSMutableArray<NSDictionary *> *)freetextStyles {
|
|
|
+ if ([[NSUserDefaults standardUserDefaults] objectForKey:@"KMFreetextAnnotationStylesKey"]) {
|
|
|
+ return [[NSUserDefaults standardUserDefaults] objectForKey:@"KMFreetextAnnotationStylesKey"];
|
|
|
+ } else {
|
|
|
+ return [self defaultFreetextStyles];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (NSMutableArray <NSDictionary *>*)defaultFreetextStyles {
|
|
|
+ return @[@{@"Font Name" : @"PingFang HK", @"Font Size" : @"40", @"Font Weight" : @"Semibold", @"Font Color" : [self dataForColor:[NSColor colorWithRed:36/255.0 green:42/255.0 blue:51/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"The Headlines", nil)},
|
|
|
+ @{@"Font Name" : @"PingFang HK", @"Font Size" : @"32", @"Font Weight" : @"Semibold", @"Font Color" : [self dataForColor:[NSColor colorWithRed:36/255.0 green:42/255.0 blue:51/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"Title (small)", nil)},
|
|
|
+ @{@"Font Name" : @"PingFang HK", @"Font Size" : @"24", @"Font Weight" : @"Semibold", @"Font Color" : [self dataForColor:[NSColor colorWithRed:36/255.0 green:42/255.0 blue:51/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"Subtitle (Bold)", nil)},
|
|
|
+ @{@"Font Name" : @"PingFang HK", @"Font Size" : @"24", @"Font Weight" : @"Regular", @"Font Color" : [self dataForColor:[NSColor colorWithRed:36/255.0 green:42/255.0 blue:51/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"Subtitle", nil)},
|
|
|
+ @{@"Font Name" : @"PingFang HK", @"Font Size" : @"20", @"Font Weight" : @"Regular", @"Font Color" : [self dataForColor:[NSColor colorWithRed:36/255.0 green:42/255.0 blue:51/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"Text", nil)},
|
|
|
+ @{@"Font Name" : @"PingFang HK", @"Font Size" : @"16", @"Font Weight" : @"Regular", @"Font Color" : [self dataForColor:[NSColor colorWithRed:36/255.0 green:42/255.0 blue:51/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"Text (small)", nil)},
|
|
|
+ @{@"Font Name" : @"PingFang HK", @"Font Size" : @"16", @"Font Weight" : @"Regular", @"Font Color" : [self dataForColor:[NSColor colorWithRed:117/255.0 green:119/255.0 blue:128/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"Text (grey)", nil)},
|
|
|
+ @{@"Font Name" : @"PingFang HK", @"Font Size" : @"14", @"Font Weight" : @"Semibold", @"Font Color" : [self dataForColor:[NSColor colorWithRed:36/255.0 green:42/255.0 blue:51/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"Instructions", nil)},
|
|
|
+ @{@"Font Name" : @"PingFang HK", @"Font Size" : @"16", @"Font Weight" : @"Semibold", @"Font Color" : [self dataForColor:[NSColor colorWithRed:200/255.0 green:38/255.0 blue:6/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"Instructions (red)", nil)},
|
|
|
+ @{@"Font Name" : @"PingFang HK", @"Font Size" : @"12", @"Font Weight" : @"Regular", @"Font Color" : [self dataForColor:[NSColor colorWithRed:36/255.0 green:42/255.0 blue:51/255.0 alpha:1.0]], @"Font Alignment" : @"NSTextAlignmentLeft", @"StringValue" : NSLocalizedString(@"Annotations", nil)}];
|
|
|
+}
|
|
|
+
|
|
|
+- (NSColor *)colorForData:(NSData *)data {
|
|
|
+ NSColor *color = nil;
|
|
|
+ if (data) {
|
|
|
+ color = [NSUnarchiver unarchiveObjectWithData:data];
|
|
|
+ }
|
|
|
+ return color;
|
|
|
+}
|
|
|
+
|
|
|
+- (NSData *)dataForColor:(NSColor *)color {
|
|
|
+ NSData *data = color ? [NSArchiver archivedDataWithRootObject:color] : nil;
|
|
|
+ return data;
|
|
|
+}
|
|
|
+
|
|
|
+- (CGFloat)heightForNoteStringValue:(NSString *)text attrited:(NSDictionary *)attrited {
|
|
|
+ CGSize maxSize = CGSizeMake(MAXFLOAT, MAXFLOAT);
|
|
|
+ NSStringDrawingOptions opts = NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading;
|
|
|
+ CGRect rect = [text boundingRectWithSize:maxSize
|
|
|
+ options:opts
|
|
|
+ attributes:attrited
|
|
|
+ context:nil];
|
|
|
+ return rect.size.height;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - Action
|
|
|
+
|
|
|
+- (IBAction)styleAddButtonAction:(NSButton *)sender {
|
|
|
+ PDFAnnotationFreeText *annotation = (PDFAnnotationFreeText *)self.annotations.firstObject;
|
|
|
+ NSString *fontName = [annotation.font.fontDescriptor objectForKey:NSFontFamilyAttribute] ? : @"PingFang HK";
|
|
|
+ NSString *fontSize = [NSString stringWithFormat:@"%f", annotation.font.pointSize] ? : @"20";
|
|
|
+ NSString *fontWeight = [annotation.font.fontDescriptor objectForKey:NSFontFaceAttribute] ? : @"Regular";
|
|
|
+ NSColor *fontColor = annotation.fontColor ? : [NSColor colorWithRed:36/255.0 green:42/255.0 blue:51/255.0 alpha:1.0];
|
|
|
+ NSString *alignmentType = @"NSTextAlignmentLeft";
|
|
|
+ if (annotation.alignment == NSTextAlignmentLeft) {
|
|
|
+ alignmentType = @"NSTextAlignmentLeft";
|
|
|
+ } else if (annotation.alignment == NSTextAlignmentCenter) {
|
|
|
+ alignmentType = @"NSTextAlignmentCenter";
|
|
|
+ } else if (annotation.alignment == NSTextAlignmentRight) {
|
|
|
+ alignmentType = @"NSTextAlignmentRight";
|
|
|
+ } else if (annotation.alignment == NSTextAlignmentJustified) {
|
|
|
+ alignmentType = @"NSTextAlignmentJustified";
|
|
|
+ }
|
|
|
+ NSString *fontAlignment = alignmentType ? : @"NSTextAlignmentLeft";
|
|
|
+ NSString *noteString = /*annotation.string ? :*/ NSLocalizedString(@"Text", nil);
|
|
|
+ NSDictionary *dict = @{@"Font Name" : fontName, @"Font Size" : fontSize, @"Font Weight" : fontWeight, @"Font Color" : [self dataForColor:fontColor], @"Font Alignment" : fontAlignment, @"StringValue" : noteString};
|
|
|
+ NSMutableArray <NSDictionary *>*styleArr = [NSMutableArray arrayWithArray:[self freetextStyles]];
|
|
|
+ [styleArr addObject:dict];
|
|
|
+ [self setFreetextStyles:styleArr];
|
|
|
+
|
|
|
+ [_scstyleTableView reloadData];
|
|
|
+
|
|
|
+ NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:(styleArr.count - 1)];
|
|
|
+ [self.scstyleTableView selectRowIndexes:indexSet byExtendingSelection:NO];
|
|
|
+ [self.scstyleTableView.enclosingScrollView.contentView scrollToPoint:NSMakePoint(0, ((NSView*)self.scstyleTableView.enclosingScrollView.documentView).frame.size.height - self.scstyleTableView.enclosingScrollView.contentSize.height)];
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)styleMoreButtonAction:(NSButton *)sender {
|
|
|
+ NSMenu *menu = [[NSMenu alloc] init];
|
|
|
+ NSMenuItem *moreItem = [menu addItemWithTitle:NSLocalizedString(@"Restore Default Style", nil) action:@selector(freetextNote_moreAction:) target:self];
|
|
|
+ [moreItem setRepresentedObject:self];
|
|
|
+ [NSMenu popUpContextMenu:menu withEvent:[NSApp currentEvent] forView:(NSButton *)sender];
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)freetextNote_moreAction:(id)sender {
|
|
|
+ [self setFreetextStyles:[self defaultFreetextStyles]];
|
|
|
+
|
|
|
+ [_scstyleTableView reloadData];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)redefineAction:(NSInteger)count {
|
|
|
+ if (self.annotations.count > 0) {
|
|
|
+ PDFAnnotationFreeText *tAnnotation = (PDFAnnotationFreeText *)self.annotations.firstObject;
|
|
|
+ NSString * family = [tAnnotation.font.fontDescriptor objectForKey:NSFontFamilyAttribute];
|
|
|
+ NSString * style = [tAnnotation.font.fontDescriptor objectForKey:NSFontFaceAttribute];
|
|
|
+ NSString *fontSize = [NSString stringWithFormat:@"%f",tAnnotation.font.pointSize];
|
|
|
+ NSColor *color = tAnnotation.fontColor;
|
|
|
+ NSString *alignment = @"NSTextAlignmentLeft";
|
|
|
+ if (tAnnotation.alignment == NSTextAlignmentLeft) {
|
|
|
+ alignment = @"NSTextAlignmentLeft";
|
|
|
+ } else if (tAnnotation.alignment == NSTextAlignmentCenter) {
|
|
|
+ alignment = @"NSTextAlignmentCenter";
|
|
|
+ } else if (tAnnotation.alignment == NSTextAlignmentRight) {
|
|
|
+ alignment = @"NSTextAlignmentRight";
|
|
|
+ } else if (tAnnotation.alignment == NSTextAlignmentJustified) {
|
|
|
+ alignment = @"NSTextAlignmentJustified";
|
|
|
+ }
|
|
|
+ NSString *stringValue = @"";
|
|
|
+ /*if (tAnnotation.string && tAnnotation.string.length > 0) {
|
|
|
+ stringValue = tAnnotation.string;
|
|
|
+ } else */if (count < (NSInteger)self.defaultFreetextStyles.count) {
|
|
|
+ NSDictionary *dict = self.defaultFreetextStyles[count];
|
|
|
+ stringValue = dict[@"StringValue"] ? : @"";
|
|
|
+ }
|
|
|
+
|
|
|
+ NSMutableArray <NSDictionary *>*dictArr = [NSMutableArray arrayWithArray:[self freetextStyles]];
|
|
|
+ dictArr[count] = @{@"Font Name" : family, @"Font Size" : fontSize, @"Font Weight" : style, @"Font Color" : [self dataForColor:color], @"Font Alignment" : alignment, @"StringValue" : stringValue};
|
|
|
+ [self setFreetextStyles:dictArr];
|
|
|
+ [_scstyleTableView reloadData];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)renameAction:(NSString *)value
|
|
|
+ Count:(NSInteger)count {
|
|
|
+ if(count >= [self freetextStyles].count) return;
|
|
|
+ NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[self freetextStyles][count]];
|
|
|
+ [dict setObject:value forKey:@"StringValue"];
|
|
|
+ NSMutableArray *styleArr = [NSMutableArray arrayWithArray:[self freetextStyles]];
|
|
|
+ styleArr[count] = (NSDictionary *)dict;
|
|
|
+ [self setFreetextStyles:styleArr];
|
|
|
+
|
|
|
+ NSInteger selectRow = _scstyleTableView.selectedRow;
|
|
|
+ [_scstyleTableView reloadData];
|
|
|
+ NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:selectRow];
|
|
|
+ [self.scstyleTableView selectRowIndexes:indexSet byExtendingSelection:NO];
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)deleteAction:(NSInteger)count {
|
|
|
+ NSMutableArray *styleArr = [NSMutableArray arrayWithArray:[self freetextStyles]];
|
|
|
+ [styleArr removeObjectAtIndex:count];
|
|
|
+ [self setFreetextStyles:styleArr];
|
|
|
+
|
|
|
+ [self.scstyleTableView reloadData];
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)defaultAction:(NSInteger)count {
|
|
|
+ if (count < 10) {
|
|
|
+ NSDictionary *dict = [self defaultFreetextStyles][count];
|
|
|
+
|
|
|
+ NSMutableArray *styleArr = [NSMutableArray arrayWithArray:[self freetextStyles]];
|
|
|
+ styleArr[count] = dict;
|
|
|
+ [self setFreetextStyles:styleArr];
|
|
|
+
|
|
|
+ NSMutableIndexSet *rowIndexSet = [[NSMutableIndexSet alloc] init];
|
|
|
+ [rowIndexSet addIndex:count];
|
|
|
+ NSMutableIndexSet *columnIndexSet = [[NSMutableIndexSet alloc] init];
|
|
|
+ [columnIndexSet addIndex:0];
|
|
|
+ [self.scstyleTableView reloadDataForRowIndexes:rowIndexSet columnIndexes:columnIndexSet];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - NSTableViewDelegate, NSTableViewDataSource
|
|
|
+
|
|
|
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
|
|
|
+ return [self freetextStyles].count;
|
|
|
+}
|
|
|
+
|
|
|
+- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
|
|
|
+ NSDictionary *dict = [self freetextStyles][row];
|
|
|
+ NSString *fontName = dict[@"Font Name"];
|
|
|
+ CGFloat fontSize = [dict[@"Font Size"] floatValue];
|
|
|
+ NSString *fontWeight = dict[@"Font Weight"];
|
|
|
+ NSString *fontStringValue = dict[@"StringValue"];
|
|
|
+
|
|
|
+ NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
|
|
|
+ paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
|
|
|
+ paragraphStyle.alignment = NSTextAlignmentLeft;
|
|
|
+ paragraphStyle.lineSpacing = 1;
|
|
|
+
|
|
|
+ NSFontDescriptor *attributeFontDescriptor = [NSFontDescriptor fontDescriptorWithFontAttributes:@{NSFontFamilyAttribute:fontName,NSFontFaceAttribute:fontWeight}];
|
|
|
+ NSFont *font = [NSFont fontWithDescriptor:attributeFontDescriptor size:fontSize];
|
|
|
+ NSDictionary *attrited = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: paragraphStyle};
|
|
|
+
|
|
|
+ CGRect rect = [fontStringValue boundingRectWithSize:CGSizeMake(135.0, CGRectMaxYEdge)
|
|
|
+ options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
|
|
|
+ attributes:attrited
|
|
|
+ context:nil];
|
|
|
+ return CGRectGetHeight(rect);
|
|
|
+}
|
|
|
+
|
|
|
+- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
|
|
|
+ NSString *identifier = [tableColumn identifier];
|
|
|
+ KMFreeTextStyleTableViewCell *cellView = [tableView makeViewWithIdentifier:identifier owner:self];
|
|
|
+ NSDictionary *dict = [self freetextStyles][row];
|
|
|
+ NSString *fontName = dict[@"Font Name"];
|
|
|
+ CGFloat fontSize = [dict[@"Font Size"] floatValue];
|
|
|
+ NSString *fontWeight = dict[@"Font Weight"];
|
|
|
+ NSColor *fontColor = [self colorForData:dict[@"Font Color"]];
|
|
|
+ NSString *fontAlignment = dict[@"Font Alignment"];
|
|
|
+ NSString *fontStringValue = dict[@"StringValue"];
|
|
|
+
|
|
|
+ if (@available(macOS 10.14, *)) {
|
|
|
+ cellView.styleLabel.wantsLayer = YES;
|
|
|
+ NSAppearanceName appearanceName = [[NSApp effectiveAppearance] bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
|
|
|
+ if ([appearanceName isEqualToString:NSAppearanceNameDarkAqua]) {
|
|
|
+ if (row == 0 || row == 1 || row == 2 || row == 3 || row == 4 || row == 5 || row == 7 || row == 9) {
|
|
|
+ cellView.styleLabel.layer.backgroundColor = [KMAppearance KMColor_Layout_W30].CGColor;
|
|
|
+ } else {
|
|
|
+ cellView.styleLabel.layer.backgroundColor = [NSColor clearColor].CGColor;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ cellView.styleLabel.layer.backgroundColor = [NSColor clearColor].CGColor;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ NSFontDescriptor *attributeFontDescriptor = [NSFontDescriptor fontDescriptorWithFontAttributes:@{NSFontFamilyAttribute:fontName,NSFontFaceAttribute:fontWeight}];
|
|
|
+ NSFont *font = [NSFont fontWithDescriptor:attributeFontDescriptor size:fontSize];
|
|
|
+ NSDictionary *attrited = @{NSFontAttributeName:font, NSForegroundColorAttributeName:fontColor};
|
|
|
+ NSAttributedString *string = [[NSAttributedString alloc] initWithString:fontStringValue attributes:attrited];
|
|
|
+ cellView.styleLabel.attributedStringValue = string;
|
|
|
+ if ([fontAlignment isEqualToString:@"NSTextAlignmentLeft"]) {
|
|
|
+ cellView.styleLabel.alignment = NSTextAlignmentLeft;
|
|
|
+ } else if ([fontAlignment isEqualToString:@"NSTextAlignmentCenter"]) {
|
|
|
+ cellView.styleLabel.alignment = NSTextAlignmentCenter;
|
|
|
+ } else if ([fontAlignment isEqualToString:@"NSTextAlignmentRight"]) {
|
|
|
+ cellView.styleLabel.alignment = NSTextAlignmentRight;
|
|
|
+ } else if ([fontAlignment isEqualToString:@"NSTextAlignmentJustified"]) {
|
|
|
+ cellView.styleLabel.alignment = NSTextAlignmentJustified;
|
|
|
+ }
|
|
|
+ cellView.styleLabelHeightConstant.constant = [self heightForNoteStringValue:fontStringValue attrited:attrited];
|
|
|
+
|
|
|
+ cellView.annotations = _annotations;
|
|
|
+ cellView.styleTitles = [self freetextStyles];
|
|
|
+ cellView.selectRow = row;
|
|
|
+
|
|
|
+ if (row != tableView.selectedRow) {
|
|
|
+ cellView.moreButton.hidden = YES;
|
|
|
+ cellView.moreButton.enabled = NO;
|
|
|
+ }
|
|
|
+
|
|
|
+ cellView.mouseMoveCallback = ^(BOOL mouseEntered) {
|
|
|
+ if (mouseEntered) {
|
|
|
+ cellView.moreButton.hidden = NO;
|
|
|
+ cellView.moreButton.enabled = YES;
|
|
|
+ } else {
|
|
|
+ if (row != tableView.selectedRow) {
|
|
|
+ cellView.moreButton.hidden = YES;
|
|
|
+ cellView.moreButton.enabled = NO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ __block typeof(self) blockSelf = self;
|
|
|
+ cellView.menuActionCallback = ^(KMFreeTextMenuActionType memuType) {
|
|
|
+ switch (memuType) {
|
|
|
+ case KMFreeTextMenuActionType_Redefine:
|
|
|
+ [blockSelf redefineAction:row];
|
|
|
+ break;
|
|
|
+ case KMFreeTextMenuActionType_Delete:
|
|
|
+ [blockSelf deleteAction:row];
|
|
|
+ break;
|
|
|
+ case KMFreeTextMenuActionType_Default:
|
|
|
+ [blockSelf defaultAction:row];
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ cellView.renameActionCallback = ^(NSString *count, KMFreeTextMenuActionType memuType) {
|
|
|
+ if (memuType == KMFreeTextMenuActionType_Rename) {
|
|
|
+ [blockSelf renameAction:count Count:row];
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return cellView;
|
|
|
+}
|
|
|
+
|
|
|
+- (void)tableViewSelectionDidChange:(NSNotification *)notification {
|
|
|
+ NSTableView *tableView = (NSTableView *)notification.object;
|
|
|
+ NSInteger selectRow = tableView.selectedRow;
|
|
|
+ if(selectRow < 0) return;
|
|
|
+ if (_lastSelectRow != selectRow && _lastSelectRow != -1) {
|
|
|
+ NSMutableIndexSet *rowIndexSet = [[NSMutableIndexSet alloc] init];
|
|
|
+ [rowIndexSet addIndex:_lastSelectRow];
|
|
|
+ NSMutableIndexSet *columnIndexSet = [[NSMutableIndexSet alloc] init];
|
|
|
+ [columnIndexSet addIndex:0];
|
|
|
+ [tableView reloadDataForRowIndexes:rowIndexSet columnIndexes:columnIndexSet];
|
|
|
+ }
|
|
|
+ _lastSelectRow = selectRow;
|
|
|
+
|
|
|
+ NSDictionary *dict = [self freetextStyles][selectRow];
|
|
|
+ NSString *fontName = dict[@"Font Name"];
|
|
|
+ CGFloat fontSize = [dict[@"Font Size"] floatValue];
|
|
|
+ NSString *fontWeight = dict[@"Font Weight"];
|
|
|
+ NSColor *fontColor = [self colorForData:dict[@"Font Color"]];
|
|
|
+ NSString *fontAlignment = dict[@"Font Alignment"];
|
|
|
+
|
|
|
+ for (PDFAnnotation *tAnnotation in self.annotations) {
|
|
|
+ NSFontDescriptor *attributeFontDescriptor = [NSFontDescriptor fontDescriptorWithFontAttributes:@{NSFontFamilyAttribute:fontName,NSFontFaceAttribute:fontWeight}];
|
|
|
+ NSFont *font = [NSFont fontWithDescriptor:attributeFontDescriptor size:fontSize];
|
|
|
+ if (font) {
|
|
|
+ tAnnotation.font = font;
|
|
|
+ }
|
|
|
+ if (fontColor) {
|
|
|
+ tAnnotation.fontColor = fontColor;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ([fontAlignment isEqualToString:@"NSTextAlignmentLeft"]) {
|
|
|
+ tAnnotation.alignment = NSTextAlignmentLeft;
|
|
|
+ } else if ([fontAlignment isEqualToString:@"NSTextAlignmentCenter"]) {
|
|
|
+ tAnnotation.alignment = NSTextAlignmentCenter;
|
|
|
+ } else if ([fontAlignment isEqualToString:@"NSTextAlignmentRight"]) {
|
|
|
+ tAnnotation.alignment = NSTextAlignmentRight;
|
|
|
+ } else if ([fontAlignment isEqualToString:@"NSTextAlignmentJustified"]) {
|
|
|
+ tAnnotation.alignment = NSTextAlignmentJustified;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row {
|
|
|
+ KMScstyleTableRowView *rowView = [[KMScstyleTableRowView alloc] init];
|
|
|
+ return rowView;
|
|
|
+}
|
|
|
+
|
|
|
+@end
|