diff --git a/EC/EC.entitlements b/EC/EC.entitlements
index 60c1f0a..09da21d 100644
--- a/EC/EC.entitlements
+++ b/EC/EC.entitlements
@@ -6,7 +6,7 @@
com.apple.security.application-groups
- 2WQE6AU5PD.group.com.music4kid.easycode
+ $(TeamIdentifierPrefix)group.com.sito.easycode
diff --git a/EC/ECFileParser/ECFileParser.m b/EC/ECFileParser/ECFileParser.m
index 2745092..29b80ef 100644
--- a/EC/ECFileParser/ECFileParser.m
+++ b/EC/ECFileParser/ECFileParser.m
@@ -25,9 +25,7 @@ - (FSElementCache*)getImpElementByContent:(NSString*)content
}
- (FSElementCache*)getElementByContent:(NSString*)content selection:(NSRange)range {
-
FSElementCache* element = nil;
-
FSImpProcessor* p = [FSImpProcessor new];
NSArray* elementsInFile = [p createElements:content];
for (FSElementCache* e in elementsInFile) {
diff --git a/EC/ECFileParser/FSElementPool.h b/EC/ECFileParser/FSElementPool.h
index ab839d6..32916f9 100644
--- a/EC/ECFileParser/FSElementPool.h
+++ b/EC/ECFileParser/FSElementPool.h
@@ -18,7 +18,7 @@
@property (nonatomic, strong) NSMutableDictionary* elementMap;
-- (void)parseElementFromProjectFile:(NSString*)filePath complete:(dispatch_block_t)completeBlock;
+//- (void)parseElementFromProjectFile:(NSString*)filePath complete:(dispatch_block_t)completeBlock;
- (void)parseHeaderFile:(NSString*)filePath;
- (FSElementCache*)getElementFromCache:(NSString*)elementName;
diff --git a/EC/ECMapping.h b/EC/ECMapping.h
index 64b9099..755ffb1 100644
--- a/EC/ECMapping.h
+++ b/EC/ECMapping.h
@@ -7,8 +7,9 @@
//
#import
+#import "ECSnippetEntry.h"
@interface ECMapping : NSObject
-- (NSDictionary*)provideMapping;
++ (NSArray*)defaultEntries;
@end
diff --git a/EC/ECMapping.m b/EC/ECMapping.m
index b49a440..4835054 100644
--- a/EC/ECMapping.m
+++ b/EC/ECMapping.m
@@ -9,7 +9,7 @@
#import "ECMapping.h"
@implementation ECMapping
-- (NSDictionary*)provideMapping {
++ (NSArray*)defaultEntries {
return nil;
}
@end
diff --git a/EC/ECMappingForObjectiveC.h b/EC/ECMappingForObjectiveC.h
index 0f9ae55..cbcdbcb 100644
--- a/EC/ECMappingForObjectiveC.h
+++ b/EC/ECMappingForObjectiveC.h
@@ -10,7 +10,5 @@
#import "ECMapping.h"
@interface ECMappingForObjectiveC : ECMapping
-
-- (NSDictionary*)provideMapping;
-
++ (NSArray*)defaultEntries;
@end
diff --git a/EC/ECMappingForObjectiveC.m b/EC/ECMappingForObjectiveC.m
index 145b92c..1e1646f 100644
--- a/EC/ECMappingForObjectiveC.m
+++ b/EC/ECMappingForObjectiveC.m
@@ -8,10 +8,11 @@
#import "ECMappingForObjectiveC.h"
#import "OCMapping.h"
+#import "ECSnippetEntry.h"
@implementation ECMappingForObjectiveC
-- (NSDictionary*)provideMapping {
++ (NSArray*)defaultEntries {
NSDictionary* mapping = @{
//UIViewController
KeyOC_UIViewController_VDL:KeyOC_UIViewController_VDL_Value,
@@ -63,9 +64,14 @@ - (NSDictionary*)provideMapping {
KeyOC_Template_Label:KeyOC_Template_Label_Value,
KeyOC_Template_ImageView:KeyOC_Template_ImageView_Value,
- }.mutableCopy;
-
- return mapping;
+ };
+ NSMutableArray* snippetList = [NSMutableArray arrayWithCapacity:mapping.count];
+ [mapping enumerateKeysAndObjectsUsingBlock:^(NSString* _Nonnull key, NSString* _Nonnull code, BOOL * _Nonnull stop) {
+ ECSnippetEntry* snippet = [ECSnippetEntry snippetWithKey:key code:code];
+ [snippetList addObject:snippet];
+ }];
+ NSArray* snippets = [snippetList copy];
+ return snippets;
}
diff --git a/EC/ECMappingForSwift.h b/EC/ECMappingForSwift.h
index 388e4a8..87f450c 100644
--- a/EC/ECMappingForSwift.h
+++ b/EC/ECMappingForSwift.h
@@ -10,7 +10,5 @@
#import "ECMapping.h"
@interface ECMappingForSwift : ECMapping
-
-- (NSDictionary*)provideMapping;
-
++ (NSArray*)defaultEntries;
@end
diff --git a/EC/ECMappingForSwift.m b/EC/ECMappingForSwift.m
index bcb3a05..03e02c2 100644
--- a/EC/ECMappingForSwift.m
+++ b/EC/ECMappingForSwift.m
@@ -8,16 +8,70 @@
#import "ECMappingForSwift.h"
#import "SwiftMapping.h"
+#import "ECSnippetEntry.h"
@implementation ECMappingForSwift
-- (NSDictionary*)provideMapping {
++ (NSArray*)defaultEntries {
NSDictionary* mapping = @{
-
+ //UIViewController
+ KeySwift_UIViewController_VDL:KeySwift_UIViewController_VDL_Value,
+ KeySwift_UIViewController_VWA:KeySwift_UIViewController_VWA_Value,
+ KeySwift_UIViewController_VDA:KeySwift_UIViewController_VDA_Value,
+ KeySwift_UIViewController_VWD:KeySwift_UIViewController_VWD_Value,
+ KeySwift_UIViewController_VDD:KeySwift_UIViewController_VDD_Value,
+ KeySwift_UIViewController_DRM:KeySwift_UIViewController_DRM_Value,
+ KeySwift_UIViewController_SIO:KeySwift_UIViewController_SIO_Value,
+ KeySwift_UIViewController_PIO:KeySwift_UIViewController_PIO_Value,
- }.mutableCopy;
-
- return mapping;
+ //UIView
+ KeySwift_UIView_HTW:KeySwift_UIView_HTW_Value,
+ KeySwift_UIView_PIE:KeySwift_UIView_PIE_Value,
+ KeySwift_UIView_CPT:KeySwift_UIView_CPT_Value,
+ KeySwift_UIView_CPF:KeySwift_UIView_CPF_Value,
+ KeySwift_UIView_CRP:KeySwift_UIView_CRP_Value,
+ KeySwift_UIView_CRF:KeySwift_UIView_CRF_Value,
+ KeySwift_UIView_DR:KeySwift_UIView_DR_Value,
+
+ //UIApplication
+ KeySwift_UIApplication_DRU:KeySwift_UIApplication_DRU_Value,
+ KeySwift_UIApplication_DRF:KeySwift_UIApplication_DRF_Value,
+ KeySwift_UIApplication_DRT:KeySwift_UIApplication_DRT_Value,
+ KeySwift_UIApplication_DRR:KeySwift_UIApplication_DRR_Value,
+ KeySwift_UIApplication_DRL:KeySwift_UIApplication_DRL_Value,
+
+ //GCD
+ KeySwift_GCD_DAFM:KeySwift_GCD_DAFM_Value,
+ KeySwift_GCD_DASM:KeySwift_GCD_DASM_Value,
+ KeySwift_GCD_DAFG:KeySwift_GCD_DAFG_Value,
+ KeySwift_GCD_DASG:KeySwift_GCD_DASG_Value,
+
+ //MISC
+ KeySwift_MISC_DEL:KeySwift_MISC_DEL_Value,
+ KeySwift_MISC_V:KeySwift_MISC_V_Value,
+ KeySwift_MISC_C:KeySwift_MISC_C_Value,
+ KeySwift_MISC_P:KeySwift_MISC_P_Value,
+ KeySwift_MISC_W:KeySwift_MISC_W_Value,
+ KeySwift_MISC_N:KeySwift_MISC_N_Value,
+ KeySwift_MISC_U:KeySwift_MISC_U_Value,
+ KeySwift_MISC_F:KeySwift_MISC_F_Value,
+ KeySwift_MISC_M:KeySwift_MISC_M_Value,
+ KeySwift_MISC_IMG:KeySwift_MISC_IMG_Value,
+ KeySwift_MISC_BUN:KeySwift_MISC_BUN_Value,
+
+ //Template
+ KeySwift_Template_Button:KeySwift_Template_Button_Value,
+ KeySwift_Template_Label:KeySwift_Template_Label_Value,
+ KeySwift_Template_ImageView:KeySwift_Template_ImageView_Value,
+
+ };
+ NSMutableArray* snippetList = [NSMutableArray arrayWithCapacity:mapping.count];
+ [mapping enumerateKeysAndObjectsUsingBlock:^(NSString* _Nonnull key, NSString* _Nonnull code, BOOL * _Nonnull stop) {
+ ECSnippetEntry* snippet = [ECSnippetEntry snippetWithKey:key code:code];
+ [snippetList addObject:snippet];
+ }];
+ NSArray* snippets = [snippetList copy];
+ return snippets;
}
diff --git a/EC/ECMappingHelper.m b/EC/ECMappingHelper.m
index e2e203f..f9de85b 100644
--- a/EC/ECMappingHelper.m
+++ b/EC/ECMappingHelper.m
@@ -7,58 +7,41 @@
//
#import "ECMappingHelper.h"
-#import "ECMappingForObjectiveC.h"
-#import "ECMappingForSwift.h"
+#import "NSFileManager+Additions.h"
#import "ESharedUserDefault.h"
+#import "ECSnippet.h"
+#import "ECSnippetHelper.h"
@interface ECMappingHelper ()
-@property (nonatomic, strong) NSMutableDictionary* mappingOC;
-@property (nonatomic, strong) NSMutableDictionary* mappingSwift;
+@property (nonatomic, strong) ECSnippet* curSnippets;
@end
@implementation ECMappingHelper
-+ (instancetype)sharedInstance
-{
++ (instancetype)sharedInstance {
static ECMappingHelper* instance = nil;
-
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
- instance = [ECMappingHelper new];
+ instance = [[ECMappingHelper alloc] init];
});
return instance;
}
-- (instancetype)init
-{
- self = [super init];
- if (self) {
-
- }
- return self;
-}
-
-- (void)checkForDuplicatedKeys:(NSDictionary*)mapping
-{
- //check for duplicated keys
- NSArray* keys = mapping.allKeys;
- NSMutableDictionary* dic = @{}.mutableCopy;
- for (NSString* key in keys) {
- if ([dic objectForKey:keys]) {
- NSLog(@"detect duplicated keys!");
- }
- else
- {
- dic[key] = key;
- }
+- (void)reloadSnippetBySourceType:(ECSourceType)sourceType {
+ NSString* dirname = [ECSnippetHelper directoryForSourceType:sourceType];
+ NSString* versionKey = [NSString stringWithFormat:kVersionFormat,dirname];
+ NSNumber* latestVer = [ESharedUserDefault objectForKey:versionKey];
+
+ if ([_curSnippets.version isEqualToNumber:latestVer] == NO) { //if versions are not equal,reload from UserDefaults.
+ NSData* data = [ESharedUserDefault dataForKey:dirname];
+ _curSnippets = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
}
- (BOOL)handleInvocation:(XCSourceEditorCommandInvocation *)invocation {
-
- //read from NSUserDefault each time
- [self clearMapping];
+ ECSourceType sourceType = [ECSnippetHelper sourceTypeForContentUTI:invocation.buffer.contentUTI];
+ [self reloadSnippetBySourceType:sourceType];
XCSourceTextRange *selection = invocation.buffer.selections.firstObject;
NSMutableArray* lines = invocation.buffer.lines;
@@ -67,12 +50,11 @@ - (BOOL)handleInvocation:(XCSourceEditorCommandInvocation *)invocation {
int matchedCount = 0;
- if (index > lines.count-1) {
+ if (index > lines.count - 1) {
return false;
}
NSString* originalLine = lines[index];
-
int matchLength = 8;//max match length for shortcut
while (matchLength >= 1) {
@@ -81,19 +63,14 @@ - (BOOL)handleInvocation:(XCSourceEditorCommandInvocation *)invocation {
NSRange targetRange = NSMakeRange(column-matchLength, matchLength);
NSString* lastNStr = [originalLine substringWithRange:targetRange];
- BOOL isOC = true;
- if ([invocation.buffer.contentUTI isEqualToString:@"public.swift-source"]) {
- isOC = false;
- }
- NSString* matchedVal = [self getMatchedCode:lastNStr isOC:isOC];
+ NSString* matchedVal = [self matchedCode:lastNStr forSourceType:sourceType];
if (matchedVal.length > 0) {
-
int numberOfSpaceIndent = (int)[originalLine rangeOfString:lastNStr].location;
NSString* indentStr = @"";
while (numberOfSpaceIndent>0) {
indentStr = [indentStr stringByAppendingString:@" "];
- numberOfSpaceIndent --;
+ numberOfSpaceIndent--;
}
NSArray* linesToInsert = [self convertToLines:matchedVal];
@@ -105,7 +82,7 @@ - (BOOL)handleInvocation:(XCSourceEditorCommandInvocation *)invocation {
range:targetRange];
//insert the rest
- for (int i = 1; i < linesToInsert.count; i ++) {
+ for (int i = 1; i < linesToInsert.count; i++) {
NSString* lineToInsert = linesToInsert[i];
//indent
lineToInsert = [NSString stringWithFormat:@"%@%@", indentStr, lineToInsert];
@@ -118,11 +95,10 @@ - (BOOL)handleInvocation:(XCSourceEditorCommandInvocation *)invocation {
}
}
- matchLength --;
+ matchLength--;
}
-
//adjust selection
if (matchedCount > 0) {
selection.start = XCSourceTextPositionMake(selection.start.line, selection.start.column-matchedCount);
@@ -132,62 +108,28 @@ - (BOOL)handleInvocation:(XCSourceEditorCommandInvocation *)invocation {
}
-- (NSString*)getMatchedCode:(NSString*)abbr isOC:(BOOL)isOC
-{
+- (NSString*)matchedCode:(NSString*)abbr forSourceType:(ECSourceType)type {
//need to detect swift or oc
- NSDictionary* mappingDic = nil;
-
- if (isOC) {
- mappingDic = self.mappingOC;
- }
- else
- {
- mappingDic = self.mappingSwift;
- }
+ NSArray* entries = _curSnippets.entries;
+ __block NSInteger index = NSNotFound;
+ [_curSnippets.entries enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(ECSnippetEntry * _Nonnull entry, NSUInteger idx, BOOL * _Nonnull stop) {
+ if ([entry.key hasPrefix:abbr] || [entry.key isEqual:abbr]) {
+ index = idx;
+ *stop = YES;
+ }
+ }];
- if ([mappingDic objectForKey:abbr] != nil) {
- return [mappingDic objectForKey:abbr];
+ if (index != NSNotFound) {
+ NSString* matchedCode = [entries[index] code];
+ return matchedCode;
}
return nil;
}
-
-- (NSArray*)convertToLines:(NSString*)codeStr
-{
- NSMutableArray* lines = @[].mutableCopy;
-
+- (NSArray*)convertToLines:(NSString*)codeStr {
NSArray* arr = [codeStr componentsSeparatedByString:@"\n"];
-
- for (NSString* line in arr) {
- [lines addObject:line];
- }
-
- return lines;
-}
-
-- (NSMutableDictionary*)mappingOC
-{
- if (_mappingOC == nil) {
- _mappingOC = [_UD readMappingForOC].mutableCopy;
- }
- return _mappingOC;
-}
-
-- (NSMutableDictionary*)mappingSwift
-{
- if (_mappingSwift == nil) {
- _mappingSwift = [_UD readMappingForSwift].mutableCopy;
- }
- return _mappingSwift;
-}
-
-- (void)clearMapping
-{
- self.mappingOC = nil;
- self.mappingSwift = nil;
-
- [_UD clearMapping];
+ return arr;
}
@end
diff --git a/EC/EasyCodeManager.m b/EC/EasyCodeManager.m
index dc25c68..e4ac5c0 100644
--- a/EC/EasyCodeManager.m
+++ b/EC/EasyCodeManager.m
@@ -7,7 +7,6 @@
//
#import "EasyCodeManager.h"
-#import "ECMappingForObjectiveC.h"
#import "ECGenerateHelper.h"
#import "ECMappingHelper.h"
@@ -31,6 +30,7 @@ + (instancetype)sharedInstance
- (void)handleInvocation:(XCSourceEditorCommandInvocation *)invocation
{
+
//dynamic code generation based on class parsing like FastStub(https://github.com/music4kid/FastStub-Xcode)
if ([[ECGenerateHelper sharedInstance] handleInvocation:invocation]) {
return;
@@ -44,5 +44,4 @@ - (void)handleInvocation:(XCSourceEditorCommandInvocation *)invocation
}
-
@end
diff --git a/EC/SourceEditorExtension.m b/EC/SourceEditorExtension.m
index a612dc2..89306e5 100644
--- a/EC/SourceEditorExtension.m
+++ b/EC/SourceEditorExtension.m
@@ -10,11 +10,10 @@
@implementation SourceEditorExtension
-
- (void)extensionDidFinishLaunching
{
- NSLog(@"extensionDidFinishLaunching...");
// If your extension needs to do any work at launch, implement this optional method.
+// NSLog(@"extensionDidFinishLaunching...");
}
diff --git a/EC/SwiftMapping.h b/EC/SwiftMapping.h
index e7c7783..51bd3e6 100644
--- a/EC/SwiftMapping.h
+++ b/EC/SwiftMapping.h
@@ -9,5 +9,256 @@
#ifndef SwiftMapping_h
#define SwiftMapping_h
+#pragma mark- UIViewController
+
+#define KeySwift_UIViewController_VDL @"vdl"
+#define KeySwift_UIViewController_VDL_Value @"\
+override func viewDidLoad() {\n\
+super.viewDidLoad()\n\
+\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIViewController_VWA @"vwa"
+#define KeySwift_UIViewController_VWA_Value @"\
+override func viewWillAppear(_ animated: Bool) {\n\
+super.viewWillAppear(animated)\n\
+\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIViewController_VDA @"vda"
+#define KeySwift_UIViewController_VDA_Value @"\
+override func viewDidAppear(_ animated: Bool) {\n\
+super.viewDidAppear(animated)\n\
+\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIViewController_VWD @"vwd"
+#define KeySwift_UIViewController_VWD_Value @"\
+override func viewWillDisappear(_ animated: Bool) {\n\
+super.viewWillDisappear(animated)\n\
+\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIViewController_VDD @"vdd"
+#define KeySwift_UIViewController_VDD_Value @"\
+override func viewDidDisappear(_ animated: Bool) {\n\
+super.viewDidDisappear(animated)\n\
+\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIViewController_DRM @"drm"
+#define KeySwift_UIViewController_DRM_Value @"\
+override func didReceiveMemoryWarning() {\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIViewController_SIO @"sio"
+#define KeySwift_UIViewController_SIO_Value @"\
+override var supportedInterfaceOrientations: UIInterfaceOrientationMask{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIViewController_PIO @"pio"
+#define KeySwift_UIViewController_PIO_Value @"\
+override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{\n\
+<#code#>\n\
+}"
+
+#pragma mark- UIView
+
+#define KeySwift_UIView_HTW @"htw"
+#define KeySwift_UIView_HTW_Value @"\
+- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIView_PIE @"pie"
+#define KeySwift_UIView_PIE_Value @"\
+- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIView_CPT @"cpt"
+#define KeySwift_UIView_CPT_Value @"\
+- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIView_CPF @"cpf"
+#define KeySwift_UIView_CPF_Value @"\
+- (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIView_CRP @"crp"
+#define KeySwift_UIView_CRP_Value @"\
+- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIView_CRF @"crf"
+#define KeySwift_UIView_CRF_Value @"\
+- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIView_DR @"dr"
+#define KeySwift_UIView_DR_Value @"\
+- (void)drawRect:(CGRect)rect\n\
+{\n\
+<#code#>\n\
+}"
+
+#pragma mark- UIAppication
+#define KeySwift_UIApplication_DRU @"dru"
+#define KeySwift_UIApplication_DRU_Value @"\
+- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIApplication_DRF @"drf"
+#define KeySwift_UIApplication_DRF_Value @"\
+- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIApplication_DRT @"drt"
+#define KeySwift_UIApplication_DRT_Value @"\
+- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIApplication_DRR @"drr"
+#define KeySwift_UIApplication_DRR_Value @"\
+- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo\n\
+{\n\
+<#code#>\n\
+}"
+
+#define KeySwift_UIApplication_DRL @"drl"
+#define KeySwift_UIApplication_DRL_Value @"\
+- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification\n\
+{\n\
+<#code#>\n\
+}"
+
+#pragma mark- GCD
+#define KeySwift_GCD_DAFM @"dafm"
+#define KeySwift_GCD_DAFM_Value @"\
+dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{\n\
+<#code to be executed after a specified delay#>\n\
+});"
+
+#define KeySwift_GCD_DASM @"dasm"
+#define KeySwift_GCD_DASM_Value @"\
+dispatch_async(dispatch_get_main_queue(), ^{\n\
+<#code#>\n\
+});"
+
+#define KeySwift_GCD_DAFG @"dafg"
+#define KeySwift_GCD_DAFG_Value @"\
+dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n\
+<#code to be executed after a specified delay#>\n\
+});"
+
+#define KeySwift_GCD_DASG @"dasg"
+#define KeySwift_GCD_DASG_Value @"\
+dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n\
+<#code#>\n\
+});"
+
+
+#pragma mark- MISC
+#define KeySwift_MISC_DEL @"del"
+#define KeySwift_MISC_DEL_Value @"\
+([UIApplication sharedApplication].delegate)"
+
+#define KeySwift_MISC_V @"v"
+#define KeySwift_MISC_V_Value @"\
+- (void)<#method#>"
+
+#define KeySwift_MISC_C @"c"
+#define KeySwift_MISC_C_Value @"\
+[UIColor colorWith<#color#>]"
+
+#define KeySwift_MISC_P @"p"
+#define KeySwift_MISC_P_Value @"\
+@property (nonatomic, strong) <#type#> <#name#>"
+
+#define KeySwift_MISC_W @"w"
+#define KeySwift_MISC_W_Value @"\
+__weak __typeof(self) wself = self;"
+
+#define KeySwift_MISC_N @"n"
+#define KeySwift_MISC_N_Value @"\
+[[NSNotificationCenter defaultCenter] <#method#>];"
+
+#define KeySwift_MISC_U @"u"
+#define KeySwift_MISC_U_Value @"\
+[[NSUserDefaults standardUserDefaults] <#method#>];"
+
+#define KeySwift_MISC_F @"f"
+#define KeySwift_MISC_F_Value @"\
+[[NSFileManager defaultManager] <#method#>];"
+
+#define KeySwift_MISC_M @"m"
+#define KeySwift_MISC_M_Value @"\
+#pragma mark - <#text#>"
+
+#define KeySwift_MISC_URL @"url"
+#define KeySwift_MISC_URL_Value @"\
+[NSURL URLWithString:<#(nonnull NSString *)#>]"
+
+#define KeySwift_MISC_IMG @"img"
+#define KeySwift_MISC_IMG_Value @"\
+[UIImage imageNamed:<#(nonnull NSString *)#>];"
+
+#define KeySwift_MISC_BUN @"bun"
+#define KeySwift_MISC_BUN_Value @"\
+[[NSBundle mainBundle] pathForResource:<#(nullable NSString *)#> ofType:<#(nullable NSString *)#>];"
+
+
+
+#pragma mark- Template
+#define KeySwift_Template_Button @"btn"
+#define KeySwift_Template_Button_Value @"\
+UIButton *btn = [UIButton new];\n\
+[btn setBackgroundColor:<#(UIColor * _Nullable)#>];\n\
+[btn setTitle:<#(nullable NSString *)#> forState:UIControlStateNormal];\n\
+[btn addTarget:<#(nullable id)#> action:<#(nonnull SEL)#> forControlEvents:UIControlEventTouchUpInside];\n\
+[<#self#> addSubview:btn];\n\
+<#self.btn#> = btn;"
+
+#define KeySwift_Template_Label @"lb"
+#define KeySwift_Template_Label_Value @"\
+UILabel *lb = [UILabel new];\n\
+lb.text = <#text#>;\n\
+lb.textColor = <#(UIColor * _Nullable)#>;\n\
+lb.font = [UIFont systemFontOfSize:<#(CGFloat)#>];\n\
+lb.backgroundColor = [UIColor clearColor];\n\
+[<#self#> addSubview:lb];\n\
+<#self.lb#> = lb;"
+
+#define KeySwift_Template_ImageView @"iv"
+#define KeySwift_Template_ImageView_Value @"\
+UIImageView* imgV = [UIImageView new];\n\
+imgV.backgroundColor = [UIColor clearColor];\n\
+imgV.image = [UIImage imageNamed:<#(nonnull NSString *)#>];\n\
+[<#self#> addSubview:imgV];\n\
+<#self.imgV#> = imgV;"
#endif /* SwiftMapping_h */
diff --git a/EasyCode.xcodeproj/project.pbxproj b/EasyCode.xcodeproj/project.pbxproj
index 5f556a8..8387f90 100644
--- a/EasyCode.xcodeproj/project.pbxproj
+++ b/EasyCode.xcodeproj/project.pbxproj
@@ -7,9 +7,38 @@
objects = {
/* Begin PBXBuildFile section */
+ 0BEB36A81E671F760039FF67 /* EditorWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6741CE661DB884DD000408E7 /* EditorWindowController.m */; };
+ 2A1CD1E41E68179A007A2700 /* NSWindowController+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1CD1E31E68179A007A2700 /* NSWindowController+Additions.m */; };
+ 2A2DBB171E6566E4008C78AF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2A2DBB161E6566E4008C78AF /* Localizable.strings */; };
+ 2A2DBB2D1E66A0F6008C78AF /* NSString+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A2DBB2A1E66A0F6008C78AF /* NSString+Additions.m */; };
+ 2A2DBB2E1E66A0F6008C78AF /* NSWindow+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A2DBB2C1E66A0F6008C78AF /* NSWindow+Additions.m */; };
+ 2A2DBB311E66A133008C78AF /* NSFileManager+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A2DBB301E66A133008C78AF /* NSFileManager+Additions.m */; };
+ 2A68099F1E7FAB1700750C23 /* EEditorTableMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A68099E1E7FAB1700750C23 /* EEditorTableMenu.m */; };
+ 2A6809A21E7FC4DE00750C23 /* EEditorTableRowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A6809A11E7FC4DE00750C23 /* EEditorTableRowView.m */; };
+ 2A6809A51E7FCE1900750C23 /* NSAlert+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A6809A41E7FCE1900750C23 /* NSAlert+Additions.m */; };
+ 2AD25BC71E67F2FE007AE3B8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 670F2ED91DB2284400A1739F /* Assets.xcassets */; };
+ 2AD25BCD1E67F6E7007AE3B8 /* ECSnippetsDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD25BCC1E67F6E7007AE3B8 /* ECSnippetsDocument.m */; };
+ 2AD25BD31E6806AA007AE3B8 /* ECMainWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD25BD11E6806AA007AE3B8 /* ECMainWindowController.m */; };
+ 2AD25BD41E6806AA007AE3B8 /* ECMainWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2AD25BD21E6806AA007AE3B8 /* ECMainWindowController.xib */; };
+ 2AD4BADD1E6E5195007A443C /* ECMappingForObjectiveC.m in Sources */ = {isa = PBXBuildFile; fileRef = 67302B0F1DB23C010030C360 /* ECMappingForObjectiveC.m */; };
+ 2AD4BADF1E6E5205007A443C /* ECSnippetEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 6741CE6B1DB89894000408E7 /* ECSnippetEntry.m */; };
+ 2AD4BAE01E6E5210007A443C /* NSString+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A2DBB2A1E66A0F6008C78AF /* NSString+Additions.m */; };
+ 2AD4BAE31E6E5272007A443C /* ECSnippet.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BAE21E6E5272007A443C /* ECSnippet.m */; };
+ 2AD4BAE41E6E5272007A443C /* ECSnippet.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BAE21E6E5272007A443C /* ECSnippet.m */; };
+ 2AD4BAFC1E6E6183007A443C /* NSFileWrapper+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BAFB1E6E6183007A443C /* NSFileWrapper+Additions.m */; };
+ 2AD4BAFD1E6E6183007A443C /* NSFileWrapper+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BAFB1E6E6183007A443C /* NSFileWrapper+Additions.m */; };
+ 2AD4BB001E6E67E2007A443C /* ECSnippetHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BAFF1E6E67E2007A443C /* ECSnippetHelper.m */; };
+ 2AD4BB011E6E67E2007A443C /* ECSnippetHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BAFF1E6E67E2007A443C /* ECSnippetHelper.m */; };
+ 2AD4BB0A1E6EAD6F007A443C /* NSFileManager+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A2DBB301E66A133008C78AF /* NSFileManager+Additions.m */; };
+ 2AD4BB911E76310E007A443C /* DetailWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BB8F1E76310E007A443C /* DetailWindowController.m */; };
+ 2AD4BB921E76310E007A443C /* DetailWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2AD4BB901E76310E007A443C /* DetailWindowController.xib */; };
+ 2AD4BB9A1E763131007A443C /* ECustomButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BB951E763131007A443C /* ECustomButton.m */; };
+ 2AD4BB9B1E763131007A443C /* EEditorTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BB971E763131007A443C /* EEditorTableView.m */; };
+ 2AD4BB9C1E763131007A443C /* EVerticalScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BB991E763131007A443C /* EVerticalScrollView.m */; };
+ 2AD4BBA01E763238007A443C /* ECSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BB9F1E763238007A443C /* ECSafeCast.m */; };
+ 2AD4BBA11E7632DD007A443C /* ECSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD4BB9F1E763238007A443C /* ECSafeCast.m */; };
670F2ED51DB2284400A1739F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 670F2ED41DB2284400A1739F /* AppDelegate.m */; };
670F2ED81DB2284400A1739F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 670F2ED71DB2284400A1739F /* main.m */; };
- 670F2EDA1DB2284400A1739F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 670F2ED91DB2284400A1739F /* Assets.xcassets */; };
670F2EDD1DB2284400A1739F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 670F2EDB1DB2284400A1739F /* MainMenu.xib */; };
670F2EEB1DB228DD00A1739F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 670F2EEA1DB228DD00A1739F /* Cocoa.framework */; };
670F2EF11DB228DD00A1739F /* SourceEditorExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 670F2EF01DB228DD00A1739F /* SourceEditorExtension.m */; };
@@ -34,18 +63,9 @@
6741CE591DB87CE8000408E7 /* ECMappingForSwift.m in Sources */ = {isa = PBXBuildFile; fileRef = 67AFF68D1DB5B45400697135 /* ECMappingForSwift.m */; };
6741CE5A1DB87CE8000408E7 /* SwiftMapping.h in Sources */ = {isa = PBXBuildFile; fileRef = 67AFF68B1DB5B44000697135 /* SwiftMapping.h */; };
6741CE5B1DB87CE8000408E7 /* ECMappingForObjectiveC.h in Sources */ = {isa = PBXBuildFile; fileRef = 67302B0E1DB23C010030C360 /* ECMappingForObjectiveC.h */; };
- 6741CE5C1DB87CE8000408E7 /* ECMappingForObjectiveC.m in Sources */ = {isa = PBXBuildFile; fileRef = 67302B0F1DB23C010030C360 /* ECMappingForObjectiveC.m */; };
6741CE5D1DB87CE8000408E7 /* OCMapping.h in Sources */ = {isa = PBXBuildFile; fileRef = 6751C6251DB23D5500004735 /* OCMapping.h */; };
- 6741CE681DB884DD000408E7 /* EditorWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6741CE661DB884DD000408E7 /* EditorWindowController.m */; };
6741CE691DB884DD000408E7 /* EditorWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6741CE671DB884DD000408E7 /* EditorWindowController.xib */; };
- 6741CE6C1DB89894000408E7 /* EShortcutEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 6741CE6B1DB89894000408E7 /* EShortcutEntry.m */; };
- 6741CE711DB8A04A000408E7 /* edit.png in Resources */ = {isa = PBXBuildFile; fileRef = 6741CE6E1DB8A04A000408E7 /* edit.png */; };
- 6741CE721DB8A04A000408E7 /* remove.png in Resources */ = {isa = PBXBuildFile; fileRef = 6741CE6F1DB8A04A000408E7 /* remove.png */; };
- 6741CE731DB8A04A000408E7 /* add.png in Resources */ = {isa = PBXBuildFile; fileRef = 6741CE701DB8A04A000408E7 /* add.png */; };
- 6741CE761DB8A713000408E7 /* EVerticalScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6741CE751DB8A713000408E7 /* EVerticalScrollView.m */; };
- 6741CE791DB8B4DF000408E7 /* EEditorTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6741CE781DB8B4DF000408E7 /* EEditorTableView.m */; };
- 6741CE7E1DB8BA19000408E7 /* DetailWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6741CE7C1DB8BA19000408E7 /* DetailWindowController.m */; };
- 6741CE7F1DB8BA19000408E7 /* DetailWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6741CE7D1DB8BA19000408E7 /* DetailWindowController.xib */; };
+ 6741CE6C1DB89894000408E7 /* ECSnippetEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 6741CE6B1DB89894000408E7 /* ECSnippetEntry.m */; };
67AFF68E1DB5B45400697135 /* ECMappingForSwift.m in Sources */ = {isa = PBXBuildFile; fileRef = 67AFF68D1DB5B45400697135 /* ECMappingForSwift.m */; };
67AFF6931DB5B71200697135 /* ECMappingHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 67AFF6921DB5B71200697135 /* ECMappingHelper.m */; };
67AFF6A01DB5C8A100697135 /* ECGenerateHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 67AFF69F1DB5C8A100697135 /* ECGenerateHelper.m */; };
@@ -60,15 +80,6 @@
67AFF6EB1DB5CBF500697135 /* ECFileParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 67AFF6E91DB5CBF500697135 /* ECFileParser.m */; };
67AFF6F01DB5CC2E00697135 /* NSString+PDRegex.m in Sources */ = {isa = PBXBuildFile; fileRef = 67AFF6EF1DB5CC2E00697135 /* NSString+PDRegex.m */; };
67AFF6F31DB5CC5B00697135 /* FSElementProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 67AFF6F21DB5CC5B00697135 /* FSElementProperty.m */; };
- 67F73F9F1DCC8A70000780C3 /* mainbg.png in Resources */ = {isa = PBXBuildFile; fileRef = 67F73F9D1DCC8A70000780C3 /* mainbg.png */; };
- 67F73FA21DCC8ADF000780C3 /* mainbg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 67F73FA11DCC8ADF000780C3 /* mainbg@2x.png */; };
- 67F73FA51DCC8BF7000780C3 /* btnbg.png in Resources */ = {isa = PBXBuildFile; fileRef = 67F73FA31DCC8BF7000780C3 /* btnbg.png */; };
- 67F73FA61DCC8BF7000780C3 /* btnbg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 67F73FA41DCC8BF7000780C3 /* btnbg@2x.png */; };
- 67F73FA91DCC8E31000780C3 /* btnbg2.png in Resources */ = {isa = PBXBuildFile; fileRef = 67F73FA71DCC8E31000780C3 /* btnbg2.png */; };
- 67F73FAA1DCC8E31000780C3 /* btnbg2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 67F73FA81DCC8E31000780C3 /* btnbg2@2x.png */; };
- 67F73FAD1DCC9278000780C3 /* btnguide.png in Resources */ = {isa = PBXBuildFile; fileRef = 67F73FAB1DCC9278000780C3 /* btnguide.png */; };
- 67F73FAE1DCC9278000780C3 /* btnguide@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 67F73FAC1DCC9278000780C3 /* btnguide@2x.png */; };
- 67F73FB11DCC9625000780C3 /* CustomButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F73FB01DCC9625000780C3 /* CustomButton.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -96,6 +107,45 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 2A1CD1E21E68179A007A2700 /* NSWindowController+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSWindowController+Additions.h"; sourceTree = ""; };
+ 2A1CD1E31E68179A007A2700 /* NSWindowController+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSWindowController+Additions.m"; sourceTree = ""; };
+ 2A1CD20A1E697AAA007A2700 /* easycode.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = easycode.pch; sourceTree = ""; };
+ 2A2DBB161E6566E4008C78AF /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; };
+ 2A2DBB291E66A0F6008C78AF /* NSString+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Additions.h"; sourceTree = ""; };
+ 2A2DBB2A1E66A0F6008C78AF /* NSString+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Additions.m"; sourceTree = ""; };
+ 2A2DBB2B1E66A0F6008C78AF /* NSWindow+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSWindow+Additions.h"; sourceTree = ""; };
+ 2A2DBB2C1E66A0F6008C78AF /* NSWindow+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSWindow+Additions.m"; sourceTree = ""; };
+ 2A2DBB2F1E66A133008C78AF /* NSFileManager+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileManager+Additions.h"; sourceTree = ""; };
+ 2A2DBB301E66A133008C78AF /* NSFileManager+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileManager+Additions.m"; sourceTree = ""; };
+ 2A68099D1E7FAB1700750C23 /* EEditorTableMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EEditorTableMenu.h; sourceTree = ""; };
+ 2A68099E1E7FAB1700750C23 /* EEditorTableMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EEditorTableMenu.m; sourceTree = ""; };
+ 2A6809A01E7FC4DE00750C23 /* EEditorTableRowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EEditorTableRowView.h; sourceTree = ""; };
+ 2A6809A11E7FC4DE00750C23 /* EEditorTableRowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EEditorTableRowView.m; sourceTree = ""; };
+ 2A6809A31E7FCE1900750C23 /* NSAlert+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAlert+Additions.h"; sourceTree = ""; };
+ 2A6809A41E7FCE1900750C23 /* NSAlert+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAlert+Additions.m"; sourceTree = ""; };
+ 2AD25BCB1E67F6E7007AE3B8 /* ECSnippetsDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECSnippetsDocument.h; sourceTree = ""; };
+ 2AD25BCC1E67F6E7007AE3B8 /* ECSnippetsDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ECSnippetsDocument.m; sourceTree = ""; };
+ 2AD25BD01E6806AA007AE3B8 /* ECMainWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECMainWindowController.h; sourceTree = ""; };
+ 2AD25BD11E6806AA007AE3B8 /* ECMainWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ECMainWindowController.m; sourceTree = ""; };
+ 2AD25BD21E6806AA007AE3B8 /* ECMainWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ECMainWindowController.xib; sourceTree = ""; };
+ 2AD4BAE11E6E5272007A443C /* ECSnippet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECSnippet.h; sourceTree = ""; };
+ 2AD4BAE21E6E5272007A443C /* ECSnippet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ECSnippet.m; sourceTree = ""; };
+ 2AD4BAFA1E6E6183007A443C /* NSFileWrapper+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileWrapper+Additions.h"; sourceTree = ""; };
+ 2AD4BAFB1E6E6183007A443C /* NSFileWrapper+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileWrapper+Additions.m"; sourceTree = ""; };
+ 2AD4BAFE1E6E67E2007A443C /* ECSnippetHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECSnippetHelper.h; sourceTree = ""; };
+ 2AD4BAFF1E6E67E2007A443C /* ECSnippetHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ECSnippetHelper.m; sourceTree = ""; };
+ 2AD4BB021E6E85B4007A443C /* ECDefine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ECDefine.h; sourceTree = ""; };
+ 2AD4BB8E1E76310E007A443C /* DetailWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailWindowController.h; sourceTree = ""; };
+ 2AD4BB8F1E76310E007A443C /* DetailWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailWindowController.m; sourceTree = ""; };
+ 2AD4BB901E76310E007A443C /* DetailWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DetailWindowController.xib; sourceTree = ""; };
+ 2AD4BB941E763131007A443C /* ECustomButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECustomButton.h; sourceTree = ""; };
+ 2AD4BB951E763131007A443C /* ECustomButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ECustomButton.m; sourceTree = ""; };
+ 2AD4BB961E763131007A443C /* EEditorTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EEditorTableView.h; sourceTree = ""; };
+ 2AD4BB971E763131007A443C /* EEditorTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EEditorTableView.m; sourceTree = ""; };
+ 2AD4BB981E763131007A443C /* EVerticalScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EVerticalScrollView.h; sourceTree = ""; };
+ 2AD4BB991E763131007A443C /* EVerticalScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EVerticalScrollView.m; sourceTree = ""; };
+ 2AD4BB9E1E763238007A443C /* ECSafeCast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECSafeCast.h; sourceTree = ""; };
+ 2AD4BB9F1E763238007A443C /* ECSafeCast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ECSafeCast.m; sourceTree = ""; };
670F2ED01DB2284400A1739F /* EasyCode.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EasyCode.app; sourceTree = BUILT_PRODUCTS_DIR; };
670F2ED31DB2284400A1739F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
670F2ED41DB2284400A1739F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
@@ -129,18 +179,8 @@
6741CE651DB884DD000408E7 /* EditorWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditorWindowController.h; sourceTree = ""; };
6741CE661DB884DD000408E7 /* EditorWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditorWindowController.m; sourceTree = ""; };
6741CE671DB884DD000408E7 /* EditorWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EditorWindowController.xib; sourceTree = ""; };
- 6741CE6A1DB89894000408E7 /* EShortcutEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EShortcutEntry.h; sourceTree = ""; };
- 6741CE6B1DB89894000408E7 /* EShortcutEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EShortcutEntry.m; sourceTree = ""; };
- 6741CE6E1DB8A04A000408E7 /* edit.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = edit.png; sourceTree = ""; };
- 6741CE6F1DB8A04A000408E7 /* remove.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = remove.png; sourceTree = ""; };
- 6741CE701DB8A04A000408E7 /* add.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = add.png; sourceTree = ""; };
- 6741CE741DB8A713000408E7 /* EVerticalScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EVerticalScrollView.h; sourceTree = ""; };
- 6741CE751DB8A713000408E7 /* EVerticalScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EVerticalScrollView.m; sourceTree = ""; };
- 6741CE771DB8B4DF000408E7 /* EEditorTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EEditorTableView.h; sourceTree = ""; };
- 6741CE781DB8B4DF000408E7 /* EEditorTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EEditorTableView.m; sourceTree = ""; };
- 6741CE7B1DB8BA19000408E7 /* DetailWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailWindowController.h; sourceTree = ""; };
- 6741CE7C1DB8BA19000408E7 /* DetailWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailWindowController.m; sourceTree = ""; };
- 6741CE7D1DB8BA19000408E7 /* DetailWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DetailWindowController.xib; sourceTree = ""; };
+ 6741CE6A1DB89894000408E7 /* ECSnippetEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECSnippetEntry.h; sourceTree = ""; };
+ 6741CE6B1DB89894000408E7 /* ECSnippetEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ECSnippetEntry.m; sourceTree = ""; };
6751C6251DB23D5500004735 /* OCMapping.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OCMapping.h; sourceTree = ""; };
676E320D1DB70B2000C9DC9B /* EasyCode.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = EasyCode.entitlements; sourceTree = ""; };
67AFF68B1DB5B44000697135 /* SwiftMapping.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftMapping.h; sourceTree = ""; };
@@ -172,16 +212,6 @@
67AFF6EF1DB5CC2E00697135 /* NSString+PDRegex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+PDRegex.m"; sourceTree = ""; };
67AFF6F11DB5CC5B00697135 /* FSElementProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSElementProperty.h; sourceTree = ""; };
67AFF6F21DB5CC5B00697135 /* FSElementProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSElementProperty.m; sourceTree = ""; };
- 67F73F9D1DCC8A70000780C3 /* mainbg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mainbg.png; sourceTree = ""; };
- 67F73FA11DCC8ADF000780C3 /* mainbg@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mainbg@2x.png"; sourceTree = ""; };
- 67F73FA31DCC8BF7000780C3 /* btnbg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = btnbg.png; sourceTree = ""; };
- 67F73FA41DCC8BF7000780C3 /* btnbg@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btnbg@2x.png"; sourceTree = ""; };
- 67F73FA71DCC8E31000780C3 /* btnbg2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = btnbg2.png; sourceTree = ""; };
- 67F73FA81DCC8E31000780C3 /* btnbg2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btnbg2@2x.png"; sourceTree = ""; };
- 67F73FAB1DCC9278000780C3 /* btnguide.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = btnguide.png; sourceTree = ""; };
- 67F73FAC1DCC9278000780C3 /* btnguide@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btnguide@2x.png"; sourceTree = ""; };
- 67F73FAF1DCC9625000780C3 /* CustomButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomButton.h; sourceTree = ""; };
- 67F73FB01DCC9625000780C3 /* CustomButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomButton.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -203,6 +233,60 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 2A2DBB281E66A0F6008C78AF /* Additions */ = {
+ isa = PBXGroup;
+ children = (
+ 2A2DBB291E66A0F6008C78AF /* NSString+Additions.h */,
+ 2A2DBB2A1E66A0F6008C78AF /* NSString+Additions.m */,
+ 2A2DBB2B1E66A0F6008C78AF /* NSWindow+Additions.h */,
+ 2A2DBB2C1E66A0F6008C78AF /* NSWindow+Additions.m */,
+ 2A2DBB2F1E66A133008C78AF /* NSFileManager+Additions.h */,
+ 2A2DBB301E66A133008C78AF /* NSFileManager+Additions.m */,
+ 2A1CD1E21E68179A007A2700 /* NSWindowController+Additions.h */,
+ 2A1CD1E31E68179A007A2700 /* NSWindowController+Additions.m */,
+ 2AD4BAFA1E6E6183007A443C /* NSFileWrapper+Additions.h */,
+ 2AD4BAFB1E6E6183007A443C /* NSFileWrapper+Additions.m */,
+ 2A6809A31E7FCE1900750C23 /* NSAlert+Additions.h */,
+ 2A6809A41E7FCE1900750C23 /* NSAlert+Additions.m */,
+ );
+ path = Additions;
+ sourceTree = "";
+ };
+ 2AD25BCA1E67F6E7007AE3B8 /* Document */ = {
+ isa = PBXGroup;
+ children = (
+ 2AD25BCB1E67F6E7007AE3B8 /* ECSnippetsDocument.h */,
+ 2AD25BCC1E67F6E7007AE3B8 /* ECSnippetsDocument.m */,
+ );
+ path = Document;
+ sourceTree = "";
+ };
+ 2AD4BB931E763131007A443C /* UI */ = {
+ isa = PBXGroup;
+ children = (
+ 2AD4BB941E763131007A443C /* ECustomButton.h */,
+ 2AD4BB951E763131007A443C /* ECustomButton.m */,
+ 2AD4BB961E763131007A443C /* EEditorTableView.h */,
+ 2AD4BB971E763131007A443C /* EEditorTableView.m */,
+ 2AD4BB981E763131007A443C /* EVerticalScrollView.h */,
+ 2AD4BB991E763131007A443C /* EVerticalScrollView.m */,
+ 2A68099D1E7FAB1700750C23 /* EEditorTableMenu.h */,
+ 2A68099E1E7FAB1700750C23 /* EEditorTableMenu.m */,
+ 2A6809A01E7FC4DE00750C23 /* EEditorTableRowView.h */,
+ 2A6809A11E7FC4DE00750C23 /* EEditorTableRowView.m */,
+ );
+ path = UI;
+ sourceTree = "";
+ };
+ 2AD4BB9D1E763238007A443C /* Utility */ = {
+ isa = PBXGroup;
+ children = (
+ 2AD4BB9E1E763238007A443C /* ECSafeCast.h */,
+ 2AD4BB9F1E763238007A443C /* ECSafeCast.m */,
+ );
+ path = Utility;
+ sourceTree = "";
+ };
670F2EC71DB2284400A1739F = {
isa = PBXGroup;
children = (
@@ -225,11 +309,19 @@
670F2ED21DB2284400A1739F /* EasyCode */ = {
isa = PBXGroup;
children = (
+ 676E320D1DB70B2000C9DC9B /* EasyCode.entitlements */,
+ 2A2DBB281E66A0F6008C78AF /* Additions */,
+ 2AD4BB931E763131007A443C /* UI */,
+ 2AD4BB9D1E763238007A443C /* Utility */,
6741CE5E1DB87FEC000408E7 /* MappingEditor */,
6741CE4C1DB8732D000408E7 /* SharedLogic */,
- 676E320D1DB70B2000C9DC9B /* EasyCode.entitlements */,
+ 2AD25BCA1E67F6E7007AE3B8 /* Document */,
+ 2AD25BD01E6806AA007AE3B8 /* ECMainWindowController.h */,
+ 2AD25BD11E6806AA007AE3B8 /* ECMainWindowController.m */,
+ 2AD25BD21E6806AA007AE3B8 /* ECMainWindowController.xib */,
670F2ED31DB2284400A1739F /* AppDelegate.h */,
670F2ED41DB2284400A1739F /* AppDelegate.m */,
+ 2A1CD20A1E697AAA007A2700 /* easycode.pch */,
6741CE6D1DB89DFE000408E7 /* Resource */,
670F2ED91DB2284400A1739F /* Assets.xcassets */,
670F2EDB1DB2284400A1739F /* MainMenu.xib */,
@@ -298,12 +390,15 @@
6741CE4C1DB8732D000408E7 /* SharedLogic */ = {
isa = PBXGroup;
children = (
+ 2AD4BB021E6E85B4007A443C /* ECDefine.h */,
+ 2AD4BAFE1E6E67E2007A443C /* ECSnippetHelper.h */,
+ 2AD4BAFF1E6E67E2007A443C /* ECSnippetHelper.m */,
6741CE4D1DB87340000408E7 /* ESharedUserDefault.h */,
6741CE4E1DB87340000408E7 /* ESharedUserDefault.m */,
6741CE501DB87BC2000408E7 /* ECMapping.h */,
6741CE511DB87BC2000408E7 /* ECMapping.m */,
- 67AFF6901DB5B46000697135 /* Swift */,
67AFF68F1DB5B45A00697135 /* ObjectiveC */,
+ 67AFF6901DB5B46000697135 /* Swift */,
);
path = SharedLogic;
sourceTree = "";
@@ -311,18 +406,16 @@
6741CE5E1DB87FEC000408E7 /* MappingEditor */ = {
isa = PBXGroup;
children = (
- 6741CE7A1DB8B987000408E7 /* DetailEditorController */,
+ 2AD4BAE11E6E5272007A443C /* ECSnippet.h */,
+ 2AD4BAE21E6E5272007A443C /* ECSnippet.m */,
+ 6741CE6A1DB89894000408E7 /* ECSnippetEntry.h */,
+ 6741CE6B1DB89894000408E7 /* ECSnippetEntry.m */,
+ 2AD4BB8E1E76310E007A443C /* DetailWindowController.h */,
+ 2AD4BB8F1E76310E007A443C /* DetailWindowController.m */,
+ 2AD4BB901E76310E007A443C /* DetailWindowController.xib */,
6741CE651DB884DD000408E7 /* EditorWindowController.h */,
6741CE661DB884DD000408E7 /* EditorWindowController.m */,
6741CE671DB884DD000408E7 /* EditorWindowController.xib */,
- 6741CE6A1DB89894000408E7 /* EShortcutEntry.h */,
- 6741CE6B1DB89894000408E7 /* EShortcutEntry.m */,
- 6741CE741DB8A713000408E7 /* EVerticalScrollView.h */,
- 6741CE751DB8A713000408E7 /* EVerticalScrollView.m */,
- 6741CE771DB8B4DF000408E7 /* EEditorTableView.h */,
- 6741CE781DB8B4DF000408E7 /* EEditorTableView.m */,
- 67F73FAF1DCC9625000780C3 /* CustomButton.h */,
- 67F73FB01DCC9625000780C3 /* CustomButton.m */,
);
path = MappingEditor;
sourceTree = "";
@@ -330,31 +423,11 @@
6741CE6D1DB89DFE000408E7 /* Resource */ = {
isa = PBXGroup;
children = (
- 67F73FAB1DCC9278000780C3 /* btnguide.png */,
- 67F73FAC1DCC9278000780C3 /* btnguide@2x.png */,
- 67F73FA71DCC8E31000780C3 /* btnbg2.png */,
- 67F73FA81DCC8E31000780C3 /* btnbg2@2x.png */,
- 67F73FA31DCC8BF7000780C3 /* btnbg.png */,
- 67F73FA41DCC8BF7000780C3 /* btnbg@2x.png */,
- 67F73FA11DCC8ADF000780C3 /* mainbg@2x.png */,
- 67F73F9D1DCC8A70000780C3 /* mainbg.png */,
- 6741CE6E1DB8A04A000408E7 /* edit.png */,
- 6741CE6F1DB8A04A000408E7 /* remove.png */,
- 6741CE701DB8A04A000408E7 /* add.png */,
+ 2A2DBB161E6566E4008C78AF /* Localizable.strings */,
);
path = Resource;
sourceTree = "";
};
- 6741CE7A1DB8B987000408E7 /* DetailEditorController */ = {
- isa = PBXGroup;
- children = (
- 6741CE7B1DB8BA19000408E7 /* DetailWindowController.h */,
- 6741CE7C1DB8BA19000408E7 /* DetailWindowController.m */,
- 6741CE7D1DB8BA19000408E7 /* DetailWindowController.xib */,
- );
- path = DetailEditorController;
- sourceTree = "";
- };
67AFF68F1DB5B45A00697135 /* ObjectiveC */ = {
isa = PBXGroup;
children = (
@@ -460,6 +533,7 @@
670F2ECD1DB2284400A1739F /* Frameworks */,
670F2ECE1DB2284400A1739F /* Resources */,
670F2EFC1DB228DD00A1739F /* Embed App Extensions */,
+ 2AD4BB451E716B5B007A443C /* ShellScript */,
);
buildRules = (
);
@@ -494,25 +568,31 @@
670F2EC81DB2284400A1739F /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0800;
+ LastUpgradeCheck = 0820;
ORGANIZATIONNAME = music4kid;
TargetAttributes = {
670F2ECF1DB2284400A1739F = {
CreatedOnToolsVersion = 8.0;
- DevelopmentTeam = 2WQE6AU5PD;
+ DevelopmentTeam = JW95CV255J;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.ApplicationGroups.Mac = {
enabled = 1;
};
+ com.apple.Push = {
+ enabled = 1;
+ };
com.apple.Sandbox = {
enabled = 1;
};
+ com.apple.iCloud = {
+ enabled = 1;
+ };
};
};
670F2EE71DB228DC00A1739F = {
CreatedOnToolsVersion = 8.0;
- DevelopmentTeam = 2WQE6AU5PD;
+ DevelopmentTeam = JW95CV255J;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.ApplicationGroups.Mac = {
@@ -546,21 +626,12 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 670F2EDA1DB2284400A1739F /* Assets.xcassets in Resources */,
- 6741CE711DB8A04A000408E7 /* edit.png in Resources */,
- 6741CE7F1DB8BA19000408E7 /* DetailWindowController.xib in Resources */,
- 67F73F9F1DCC8A70000780C3 /* mainbg.png in Resources */,
- 67F73FA91DCC8E31000780C3 /* btnbg2.png in Resources */,
670F2EDD1DB2284400A1739F /* MainMenu.xib in Resources */,
- 67F73FAE1DCC9278000780C3 /* btnguide@2x.png in Resources */,
- 67F73FA21DCC8ADF000780C3 /* mainbg@2x.png in Resources */,
- 67F73FAD1DCC9278000780C3 /* btnguide.png in Resources */,
- 6741CE731DB8A04A000408E7 /* add.png in Resources */,
- 67F73FA51DCC8BF7000780C3 /* btnbg.png in Resources */,
- 67F73FAA1DCC8E31000780C3 /* btnbg2@2x.png in Resources */,
+ 2AD25BD41E6806AA007AE3B8 /* ECMainWindowController.xib in Resources */,
6741CE691DB884DD000408E7 /* EditorWindowController.xib in Resources */,
- 6741CE721DB8A04A000408E7 /* remove.png in Resources */,
- 67F73FA61DCC8BF7000780C3 /* btnbg@2x.png in Resources */,
+ 2A2DBB171E6566E4008C78AF /* Localizable.strings in Resources */,
+ 2AD4BB921E76310E007A443C /* DetailWindowController.xib in Resources */,
+ 2AD25BC71E67F2FE007AE3B8 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -580,27 +651,56 @@
};
/* End PBXResourcesBuildPhase section */
+/* Begin PBXShellScriptBuildPhase section */
+ 2AD4BB451E716B5B007A443C /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "TAGS=\"TODO:|FIXME:\"\necho \"searching ${SRCROOT} for ${TAGS}\"\nfind \"${SRCROOT}\" \\( -name \"*.m\" \\) -print0 | xargs -0 egrep --with-filename --line-number --only-matching \"($TAGS).*\\$\" | perl -p -e \"s/($TAGS)/ warning: \\$1/\"";
+ };
+/* End PBXShellScriptBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
670F2ECC1DB2284400A1739F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 2A2DBB2E1E66A0F6008C78AF /* NSWindow+Additions.m in Sources */,
+ 2AD4BB001E6E67E2007A443C /* ECSnippetHelper.m in Sources */,
+ 2A6809A21E7FC4DE00750C23 /* EEditorTableRowView.m in Sources */,
+ 2AD4BB911E76310E007A443C /* DetailWindowController.m in Sources */,
+ 2AD4BB9C1E763131007A443C /* EVerticalScrollView.m in Sources */,
6741CE561DB87CE8000408E7 /* ECMapping.h in Sources */,
6741CE571DB87CE8000408E7 /* ECMapping.m in Sources */,
- 6741CE7E1DB8BA19000408E7 /* DetailWindowController.m in Sources */,
- 6741CE681DB884DD000408E7 /* EditorWindowController.m in Sources */,
- 6741CE761DB8A713000408E7 /* EVerticalScrollView.m in Sources */,
+ 2A6809A51E7FCE1900750C23 /* NSAlert+Additions.m in Sources */,
+ 2AD25BCD1E67F6E7007AE3B8 /* ECSnippetsDocument.m in Sources */,
+ 2A2DBB311E66A133008C78AF /* NSFileManager+Additions.m in Sources */,
+ 0BEB36A81E671F760039FF67 /* EditorWindowController.m in Sources */,
6741CE581DB87CE8000408E7 /* ECMappingForSwift.h in Sources */,
+ 2AD4BAE31E6E5272007A443C /* ECSnippet.m in Sources */,
6741CE591DB87CE8000408E7 /* ECMappingForSwift.m in Sources */,
6741CE5A1DB87CE8000408E7 /* SwiftMapping.h in Sources */,
- 6741CE6C1DB89894000408E7 /* EShortcutEntry.m in Sources */,
+ 6741CE6C1DB89894000408E7 /* ECSnippetEntry.m in Sources */,
6741CE5B1DB87CE8000408E7 /* ECMappingForObjectiveC.h in Sources */,
- 6741CE791DB8B4DF000408E7 /* EEditorTableView.m in Sources */,
- 6741CE5C1DB87CE8000408E7 /* ECMappingForObjectiveC.m in Sources */,
+ 2AD4BB9B1E763131007A443C /* EEditorTableView.m in Sources */,
+ 2AD4BAFC1E6E6183007A443C /* NSFileWrapper+Additions.m in Sources */,
+ 2A68099F1E7FAB1700750C23 /* EEditorTableMenu.m in Sources */,
+ 2A1CD1E41E68179A007A2700 /* NSWindowController+Additions.m in Sources */,
+ 2AD4BADD1E6E5195007A443C /* ECMappingForObjectiveC.m in Sources */,
+ 2AD4BBA01E763238007A443C /* ECSafeCast.m in Sources */,
+ 2AD25BD31E6806AA007AE3B8 /* ECMainWindowController.m in Sources */,
+ 2A2DBB2D1E66A0F6008C78AF /* NSString+Additions.m in Sources */,
6741CE5D1DB87CE8000408E7 /* OCMapping.h in Sources */,
- 67F73FB11DCC9625000780C3 /* CustomButton.m in Sources */,
670F2ED81DB2284400A1739F /* main.m in Sources */,
6741CE4F1DB87340000408E7 /* ESharedUserDefault.m in Sources */,
+ 2AD4BB9A1E763131007A443C /* ECustomButton.m in Sources */,
670F2ED51DB2284400A1739F /* AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -610,6 +710,9 @@
buildActionMask = 2147483647;
files = (
6729B1BA1DB8CFA300885A9A /* ESharedUserDefault.h in Sources */,
+ 2AD4BBA11E7632DD007A443C /* ECSafeCast.m in Sources */,
+ 2AD4BB0A1E6EAD6F007A443C /* NSFileManager+Additions.m in Sources */,
+ 2AD4BB011E6E67E2007A443C /* ECSnippetHelper.m in Sources */,
6729B1BB1DB8CFA300885A9A /* ESharedUserDefault.m in Sources */,
67AFF6A01DB5C8A100697135 /* ECGenerateHelper.m in Sources */,
67AFF6931DB5B71200697135 /* ECMappingHelper.m in Sources */,
@@ -617,10 +720,13 @@
67AFF6F01DB5CC2E00697135 /* NSString+PDRegex.m in Sources */,
67AFF6E51DB5CBE000697135 /* FSExtensionProcessor.m in Sources */,
67AFF68E1DB5B45400697135 /* ECMappingForSwift.m in Sources */,
+ 2AD4BADF1E6E5205007A443C /* ECSnippetEntry.m in Sources */,
+ 2AD4BAE41E6E5272007A443C /* ECSnippet.m in Sources */,
670F2EF11DB228DD00A1739F /* SourceEditorExtension.m in Sources */,
67AFF6E31DB5CBE000697135 /* FSCategoryProcessor.m in Sources */,
67AFF6F31DB5CC5B00697135 /* FSElementProperty.m in Sources */,
67302B0D1DB23ACA0030C360 /* EasyCodeManager.m in Sources */,
+ 2AD4BAFD1E6E6183007A443C /* NSFileWrapper+Additions.m in Sources */,
6741CE521DB87BC2000408E7 /* ECMapping.m in Sources */,
670F2EF41DB228DD00A1739F /* SourceEditorCommand.m in Sources */,
67AFF6E41DB5CBE000697135 /* FSElementProcessor.m in Sources */,
@@ -628,6 +734,7 @@
67AFF6E71DB5CBE000697135 /* FSInterfaceProcessor.m in Sources */,
67AFF6E81DB5CBE000697135 /* FSProtocolProcessor.m in Sources */,
67AFF6E21DB5CBE000697135 /* FSElementCache.m in Sources */,
+ 2AD4BAE01E6E5210007A443C /* NSString+Additions.m in Sources */,
67AFF6EB1DB5CBF500697135 /* ECFileParser.m in Sources */,
67AFF6E61DB5CBE000697135 /* FSImpProcessor.m in Sources */,
);
@@ -673,6 +780,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -720,6 +828,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -749,11 +858,14 @@
CODE_SIGN_ENTITLEMENTS = EasyCode/EasyCode.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES;
- DEVELOPMENT_TEAM = 2WQE6AU5PD;
+ DEVELOPMENT_TEAM = JW95CV255J;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = EasyCode/easycode.pch;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/EasyCode/SharedLogic\"";
INFOPLIST_FILE = EasyCode/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
- PRODUCT_BUNDLE_IDENTIFIER = com.music4kid.ec;
+ PRODUCT_BUNDLE_IDENTIFIER = com.sito.easycode;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@@ -765,11 +877,14 @@
CODE_SIGN_ENTITLEMENTS = EasyCode/EasyCode.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES;
- DEVELOPMENT_TEAM = 2WQE6AU5PD;
+ DEVELOPMENT_TEAM = JW95CV255J;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = EasyCode/easycode.pch;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/EasyCode/SharedLogic\"";
INFOPLIST_FILE = EasyCode/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
- PRODUCT_BUNDLE_IDENTIFIER = com.music4kid.ec;
+ PRODUCT_BUNDLE_IDENTIFIER = com.sito.easycode;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@@ -780,11 +895,12 @@
CODE_SIGN_ENTITLEMENTS = EC/EC.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES;
- DEVELOPMENT_TEAM = 2WQE6AU5PD;
+ DEVELOPMENT_TEAM = JW95CV255J;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/EasyCode/SharedLogic\"";
INFOPLIST_FILE = EC/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
- PRODUCT_BUNDLE_IDENTIFIER = com.music4kid.ec.ec;
+ PRODUCT_BUNDLE_IDENTIFIER = com.sito.easycode;
PRODUCT_NAME = EC;
SKIP_INSTALL = YES;
};
@@ -796,11 +912,12 @@
CODE_SIGN_ENTITLEMENTS = EC/EC.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES;
- DEVELOPMENT_TEAM = 2WQE6AU5PD;
+ DEVELOPMENT_TEAM = JW95CV255J;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/EasyCode/SharedLogic\"";
INFOPLIST_FILE = EC/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
- PRODUCT_BUNDLE_IDENTIFIER = com.music4kid.ec.ec;
+ PRODUCT_BUNDLE_IDENTIFIER = com.sito.easycode;
PRODUCT_NAME = EC;
SKIP_INSTALL = YES;
};
diff --git a/EasyCode.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/EasyCode.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/EasyCode.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/EasyCode/Additions/NSAlert+Additions.h b/EasyCode/Additions/NSAlert+Additions.h
new file mode 100644
index 0000000..dd0c06d
--- /dev/null
+++ b/EasyCode/Additions/NSAlert+Additions.h
@@ -0,0 +1,16 @@
+//
+// NSAlert+Additions.h
+// EasyCode
+//
+// Created by lijia on 20/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+
+@interface NSAlert (Additions)
++(instancetype)ec_alertWithStyle:(NSAlertStyle)alertStyle
+ messageText:(NSString *)message
+ informativeText:(NSString *)informative
+ buttonTitle:(NSString *)firstTitle,...;
+@end
diff --git a/EasyCode/Additions/NSAlert+Additions.m b/EasyCode/Additions/NSAlert+Additions.m
new file mode 100644
index 0000000..135cbee
--- /dev/null
+++ b/EasyCode/Additions/NSAlert+Additions.m
@@ -0,0 +1,29 @@
+//
+// NSAlert+Additions.m
+// EasyCode
+//
+// Created by lijia on 20/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "NSAlert+Additions.h"
+
+@implementation NSAlert (Additions)
++(instancetype)ec_alertWithStyle:(NSAlertStyle)alertStyle
+ messageText:(NSString *)message
+ informativeText:(NSString *)informative
+ buttonTitle:(NSString *)firstTitle,... {
+ NSAlert *alert = [[NSAlert alloc] init];
+ alert.messageText = message;
+ alert.informativeText = informative;
+ alert.alertStyle = alertStyle;
+ va_list args;
+ va_start(args, firstTitle);
+ for (NSString *arg = firstTitle; arg != nil; arg = va_arg(args, NSString*))
+ {
+ [alert addButtonWithTitle:arg];
+ }
+ va_end(args);
+ return alert;
+}
+@end
diff --git a/EasyCode/Additions/NSFileManager+Additions.h b/EasyCode/Additions/NSFileManager+Additions.h
new file mode 100644
index 0000000..1419f12
--- /dev/null
+++ b/EasyCode/Additions/NSFileManager+Additions.h
@@ -0,0 +1,32 @@
+//
+// NSFileManager+Additions.h
+// EasyCode
+//
+// Created by lijia on 01/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+#import "ECDefine.h"
+
+extern NSString *const DirectoryLocationDomain;
+extern NSString *const DirectoryUbiquityDocuments;
+extern NSString *const DirectoryOCName;
+extern NSString *const DirectorySwiftName;
+extern NSString *const SnippetFileName;
+extern NSString *const VersionFileName;
+
+@interface NSFileManager (Additions)
+-(NSURL*)ec_localURL;
+-(NSURL*)ec_localSnippetsURLWithFilename:(NSString*)filename;
+-(NSURL*)ec_ubiquityURL;
+-(NSURL*)ec_ubiquitySnippetsURLWithFilename:(NSString*)filename;
+
+-(NSURL*)ec_detectURLForSourceType:(ECSourceType)sourceType;
+
+-(NSString *)ec_findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory
+ inDomain:(NSSearchPathDomainMask)domainMask
+ appendPathComponent:(NSString *)appendComponent
+ error:(NSError **)errorOut;
+-(NSString*)ec_supportDocumentDirectory;
+@end
diff --git a/EasyCode/Additions/NSFileManager+Additions.m b/EasyCode/Additions/NSFileManager+Additions.m
new file mode 100644
index 0000000..27bb3ac
--- /dev/null
+++ b/EasyCode/Additions/NSFileManager+Additions.m
@@ -0,0 +1,140 @@
+//
+// NSFileManager+Additions.m
+// EasyCode
+//
+// Created by lijia on 01/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "NSFileManager+Additions.h"
+#import "ESharedUserDefault.h"
+
+enum {
+ DirectoryLocationErrorNoPathFound,
+ DirectoryLocationErrorFileExistsAtLocation
+};
+NSString *const DirectoryLocationDomain = @"DirectoryLocationDomain";
+NSString *const DirectoryDocuments = @"Documents";
+NSString *const DirectoryOCName = @"objective-c";
+NSString *const DirectorySwiftName = @"swift";
+NSString *const SnippetFileName = @"snippets.dat";
+NSString *const VersionFileName = @"version.dat";
+
+@implementation NSFileManager (Additions)
+-(NSURL*)ec_localURL
+{
+ NSString* supportPath = [self ec_supportDocumentDirectory];
+ NSURL* url = [NSURL fileURLWithPath:supportPath];
+ return url;
+}
+
+-(NSURL*)ec_localSnippetsURLWithFilename:(NSString*)filename
+{
+ NSURL* ec_localURL = [self ec_localURL];
+ NSURL* url = [ec_localURL URLByAppendingPathComponent:filename];
+
+ NSError *error = nil;
+ BOOL success = [self createDirectoryAtURL:url withIntermediateDirectories:YES attributes:nil error:&error];
+ if (!success) {
+ NSLog(@"create local directory error :%@",[error localizedDescription]);
+ }
+
+ return url;
+}
+
+-(NSURL*)ec_ubiquityURL
+{
+ NSURL* ubiURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
+ ubiURL = [ubiURL URLByAppendingPathComponent:DirectoryDocuments];
+ return ubiURL;
+}
+
+-(NSURL*)ec_ubiquitySnippetsURLWithFilename:(NSString*)filename
+{
+ NSURL* ubiURL = [self ec_ubiquityURL];
+ NSURL* url = [ubiURL URLByAppendingPathComponent:filename];
+
+ NSError *error = nil;
+ BOOL success = [self createDirectoryAtURL:url withIntermediateDirectories:YES attributes:nil error:&error];
+ if (!success) {
+ NSLog(@"create ubiquity directory error :%@",[error localizedDescription]);
+ }
+
+ return url;
+}
+
+-(NSURL*)ec_detectURLForSourceType:(ECSourceType)sourceType
+{
+ NSString* dirname = DirectoryOCName;
+ if (sourceType == ECSourceTypeSwift) {
+ dirname = DirectorySwiftName;
+ }
+
+ NSURL* fileURL = [[NSFileManager defaultManager] ec_localSnippetsURLWithFilename:dirname];;
+ BOOL useiCloud = [ESharedUserDefault boolForKey:kUseiCloudSync];
+ if (useiCloud) {
+ id ubiq = [[NSFileManager defaultManager] ubiquityIdentityToken];
+ if (ubiq) {
+ fileURL = [[NSFileManager defaultManager] ec_ubiquitySnippetsURLWithFilename:dirname];
+ }
+ }
+
+ return fileURL;
+}
+
+- (NSString *)ec_findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory
+ inDomain:(NSSearchPathDomainMask)domainMask
+ appendPathComponent:(NSString *)appendComponent
+ error:(NSError **)errorOut {
+
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory, domainMask, YES);
+ if ([paths count] == 0) {
+ if (errorOut) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey : @"No path found for directory in domain.",
+ @"NSSearchPathDirectory" : @(searchPathDirectory),
+ @"NSSearchPathDomainMask" : @(domainMask) };
+
+ *errorOut = [NSError errorWithDomain:DirectoryLocationDomain
+ code:DirectoryLocationErrorNoPathFound
+ userInfo:userInfo];
+ }
+ return nil;
+ }
+
+ NSString *resolvedPath = [paths objectAtIndex:0];
+ if (appendComponent) {
+ resolvedPath = [resolvedPath stringByAppendingPathComponent:appendComponent];
+ }
+
+ NSError *error = nil;
+ BOOL success = [self createDirectoryAtPath:resolvedPath
+ withIntermediateDirectories:YES
+ attributes:nil
+ error:&error];
+ if (!success) {
+ if (errorOut) {
+ *errorOut = error;
+ }
+ return nil;
+ }
+
+ if (errorOut) {
+ *errorOut = nil;
+ }
+ return resolvedPath;
+}
+
+-(NSString*)ec_supportDocumentDirectory {
+ NSString* appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
+ NSString *documentPath = [appName stringByAppendingPathComponent:DirectoryDocuments];
+ NSError *error = nil;
+ NSString *result = [self ec_findOrCreateDirectory:NSApplicationSupportDirectory
+ inDomain:NSUserDomainMask
+ appendPathComponent:documentPath
+ error:&error];
+ if (!result) {
+ NSLog(@"Unable to find or create application support directory:\n%@", error);
+ }
+ return result;
+}
+@end
diff --git a/EasyCode/Additions/NSFileWrapper+Additions.h b/EasyCode/Additions/NSFileWrapper+Additions.h
new file mode 100644
index 0000000..5947f58
--- /dev/null
+++ b/EasyCode/Additions/NSFileWrapper+Additions.h
@@ -0,0 +1,13 @@
+//
+// NSFileWrapper+Additions.h
+// EasyCode
+//
+// Created by lijia on 07/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+
+@interface NSFileWrapper (Additions)
+-(void)ec_replaceFileWrapper:(NSFileWrapper*)child forKey:(NSString*)filename;
+@end
diff --git a/EasyCode/Additions/NSFileWrapper+Additions.m b/EasyCode/Additions/NSFileWrapper+Additions.m
new file mode 100644
index 0000000..3bb5a7d
--- /dev/null
+++ b/EasyCode/Additions/NSFileWrapper+Additions.m
@@ -0,0 +1,23 @@
+//
+// NSFileWrapper+Additions.m
+// EasyCode
+//
+// Created by lijia on 07/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "NSFileWrapper+Additions.h"
+#import "NSString+Additions.h"
+
+@implementation NSFileWrapper (Additions)
+-(void)ec_replaceFileWrapper:(NSFileWrapper*)child forKey:(NSString*)filename {
+ if ([filename ec_isNotEmpty] == NO) {
+ return;
+ }
+ NSFileWrapper* oldChild = [[self fileWrappers] objectForKey:filename];
+ if (oldChild) {
+ [self removeFileWrapper:oldChild];
+ }
+ [self addFileWrapper:child];
+}
+@end
diff --git a/EasyCode/Additions/NSString+Additions.h b/EasyCode/Additions/NSString+Additions.h
new file mode 100644
index 0000000..2764a0d
--- /dev/null
+++ b/EasyCode/Additions/NSString+Additions.h
@@ -0,0 +1,14 @@
+//
+// NSString+Additions.h
+// EasyCode
+//
+// Created by lijia on 09/02/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+
+@interface NSString (Additions)
+-(NSString*)ec_trimWhiteSpace;
+-(BOOL)ec_isNotEmpty;
+@end
diff --git a/EasyCode/Additions/NSString+Additions.m b/EasyCode/Additions/NSString+Additions.m
new file mode 100644
index 0000000..69a75c8
--- /dev/null
+++ b/EasyCode/Additions/NSString+Additions.m
@@ -0,0 +1,20 @@
+//
+// NSString+Additions.m
+// EasyCode
+//
+// Created by lijia on 09/02/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "NSString+Additions.h"
+
+@implementation NSString (Additions)
+-(NSString*)ec_trimWhiteSpace {
+ return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
+}
+
+-(BOOL)ec_isNotEmpty {
+ NSString* trimStr = [self ec_trimWhiteSpace];
+ return (trimStr != nil && trimStr.length > 0);
+}
+@end
diff --git a/EasyCode/Additions/NSWindow+Additions.h b/EasyCode/Additions/NSWindow+Additions.h
new file mode 100644
index 0000000..f76d526
--- /dev/null
+++ b/EasyCode/Additions/NSWindow+Additions.h
@@ -0,0 +1,15 @@
+//
+// NSWindow+Additions.h
+// EasyCode
+//
+// Created by lijia on 08/02/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+
+@interface NSWindow (Additions)
+- (void)ec_setCornRadius:(CGFloat)raduis;
+- (void)ec_fadeInAnimated:(BOOL)animated;
+- (void)ec_fadeOutAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay;
+@end
diff --git a/EasyCode/Additions/NSWindow+Additions.m b/EasyCode/Additions/NSWindow+Additions.m
new file mode 100644
index 0000000..534e88b
--- /dev/null
+++ b/EasyCode/Additions/NSWindow+Additions.m
@@ -0,0 +1,55 @@
+//
+// NSWindow+Additions.m
+// EasyCode
+//
+// Created by lijia on 08/02/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "NSWindow+Additions.h"
+
+@implementation NSWindow (Additions)
+- (void)ec_setCornRadius:(CGFloat)raduis {
+ self.contentView.wantsLayer = YES;
+ self.contentView.layer.cornerRadius = raduis;
+ self.contentView.layer.masksToBounds = YES;
+}
+
+- (void)ec_fadeInAnimated:(BOOL)animated {
+ [self makeKeyAndOrderFront:nil];
+ [self.contentView setNeedsDisplay:YES];
+ self.contentView.hidden = NO;
+ if (animated) {
+ [[NSAnimationContext currentContext] setDuration:0.3];
+ [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
+ [[self.contentView animator] setAlphaValue:1.0];
+ } completionHandler:nil];
+ } else {
+ self.contentView.alphaValue = 1.0;
+ }
+}
+
+- (void)hideDone {
+ self.contentView.alphaValue = 0.f;
+ self.contentView.hidden = YES;
+ [self orderOut:nil];
+}
+
+- (void)hideDelayed:(NSNumber*)animated {
+ if ([animated boolValue]) {
+ [[NSAnimationContext currentContext] setDuration:0.3];
+ [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
+ [[self.contentView animator] setAlphaValue:0.02];
+ } completionHandler:^{
+ [self hideDone];
+ }];
+ } else {
+ [self hideDone];
+ }
+}
+
+- (void)ec_fadeOutAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay {
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideDelayed:) object:@(animated)];
+ [self performSelector:@selector(hideDelayed:) withObject:@(animated) afterDelay:delay];
+}
+@end
diff --git a/EasyCode/Additions/NSWindowController+Additions.h b/EasyCode/Additions/NSWindowController+Additions.h
new file mode 100644
index 0000000..905d1e6
--- /dev/null
+++ b/EasyCode/Additions/NSWindowController+Additions.h
@@ -0,0 +1,13 @@
+//
+// NSWindowController+Additions.h
+// EasyCode
+//
+// Created by lijia on 02/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+
+@interface NSWindowController (Additions)
+-(void)ec_makeWindowFront;
+@end
diff --git a/EasyCode/Additions/NSWindowController+Additions.m b/EasyCode/Additions/NSWindowController+Additions.m
new file mode 100644
index 0000000..fb404bd
--- /dev/null
+++ b/EasyCode/Additions/NSWindowController+Additions.m
@@ -0,0 +1,15 @@
+//
+// NSWindowController+Additions.m
+// EasyCode
+//
+// Created by lijia on 02/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "NSWindowController+Additions.h"
+
+@implementation NSWindowController (Additions)
+-(void)ec_makeWindowFront {
+ [self.window makeKeyAndOrderFront:nil];
+}
+@end
diff --git a/EasyCode/AppDelegate.h b/EasyCode/AppDelegate.h
index 2bae03b..e94d446 100644
--- a/EasyCode/AppDelegate.h
+++ b/EasyCode/AppDelegate.h
@@ -7,12 +7,12 @@
//
#import
-
+@class ECMainWindowController;
@interface AppDelegate : NSObject
-
-- (IBAction)showEditorWindowForOC:(id)sender;
-- (IBAction)showEditorWindowForSwift:(id)sender;
-- (IBAction)showHowToUse:(id)sender;
-
+//icloud
+@property (nonatomic, strong) id ubiquityToken;
+@property (nonatomic, strong) NSURL *ubiquityURL;
+@property (nonatomic, strong) ECMainWindowController* mainController;
++(instancetype)sharedInstance;
@end
diff --git a/EasyCode/AppDelegate.m b/EasyCode/AppDelegate.m
index 6b4bf5c..031dcff 100644
--- a/EasyCode/AppDelegate.m
+++ b/EasyCode/AppDelegate.m
@@ -7,59 +7,93 @@
//
#import "AppDelegate.h"
-#import "EditorWindowController.h"
+#import "ECMainWindowController.h"
+#import "NSWindowController+Additions.h"
@interface AppDelegate ()
-
-@property (weak) IBOutlet NSWindow *window;
-@property (nonatomic, strong) EditorWindowController* editorOC;
-@property (nonatomic, strong) EditorWindowController* editorSwift;
-
+@property (nonatomic, strong) NSStatusItem *statusItem;
@end
@implementation AppDelegate
-- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
- // Insert code here to initialize your application
++(instancetype)sharedInstance {
+ AppDelegate* appDelegate = [NSApplication sharedApplication].delegate;
+ return appDelegate;
}
-
-- (void)applicationWillTerminate:(NSNotification *)aNotification {
- // Insert code here to tear down your application
+- (void)dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
}
-- (IBAction)showEditorWindowForOC:(id)sender
+- (void)ubiquityIdentityChanged:(NSNotification *)notification
{
- if (self.editorOC == nil) {
- self.editorOC = [[EditorWindowController alloc] initWithWindowNibName:@"EditorWindowController"];
- [_editorOC initEditorWindow:EditorTypeOC];
+ id token = [[NSFileManager defaultManager] ubiquityIdentityToken];
+ if (token == nil) {
+ NSAlert *warningAlert = [NSAlert ec_alertWithStyle:NSWarningAlertStyle
+ messageText:NSLocalizedString(@"Logged_Out_Message", nil)
+ informativeText:NSLocalizedString(@"Logged_Out_Message_Explain", nil)
+ buttonTitle:NSLocalizedString(@"Button_OK_Title", nil),
+ nil];
+ [warningAlert runModal];
+ } else {
+ if ([self.ubiquityToken isEqual:token]) {
+ NSLog(@"user has stayed logged in with same account");
+ } else {
+ NSLog(@"user logged in with a new account");
+ }
+ self.ubiquityToken = token;
}
- [_editorOC showWindow:self];
}
-- (void)showEditorWindowForSwift:(id)sender
+- (IBAction)clickStatusBarItem:(id)sender {
+ NSString* quoteText = @"Never put off until tomorrow what you can do the day after tomorrow.";
+ NSString* quoteAuthor = @"Mark Twain";
+ NSLog(@"%@ - %@",quoteText,quoteAuthor);
+}
+
+- (void)setupStatusItem {
+ _statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
+ _statusItem.image = [NSImage imageNamed:@"StatusBarImage"];
+ _statusItem.action = @selector(clickStatusBarItem:);
+}
+
+- (void)setupUbiquityURL {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ _ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
+ });
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(ubiquityIdentityChanged:)
+ name:NSUbiquityIdentityDidChangeNotification
+ object:nil];
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
- if (self.editorSwift == nil) {
- self.editorSwift = [[EditorWindowController alloc] initWithWindowNibName:@"EditorWindowController"];
- [_editorSwift initEditorWindow:EditorTypeSwift];
- }
- [_editorSwift showWindow:self];
+ [self setupUbiquityURL];
+ [self setupStatusItem];
+ _mainController = [[ECMainWindowController alloc] initWithWindowNibName:@"ECMainWindowController"];
+ [_mainController ec_makeWindowFront];
+}
+
+- (void)applicationDidBecomeActive:(NSNotification *)notification
+{
+ _ubiquityToken = [[NSFileManager defaultManager] ubiquityIdentityToken];
+
+}
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification
+{
+ // Insert code here to tear down your application
}
-- (IBAction)showHowToUse:(id)sender {
- [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: @"https://github.com/music4kid/EasyCode-Xcode"]];
+- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender {
+ return NO;
}
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
{
- if (flag) {
- return NO;
- }
- else
- {
- [self.window makeKeyAndOrderFront:self];
- return YES;
- }
+ return YES;
}
@end
diff --git a/EasyCode/Assets.xcassets/AppIcon.appiconset/Artboard-128.png b/EasyCode/Assets.xcassets/AppIcon.appiconset/Artboard-128.png
deleted file mode 100644
index 2dce2d7..0000000
Binary files a/EasyCode/Assets.xcassets/AppIcon.appiconset/Artboard-128.png and /dev/null differ
diff --git a/EasyCode/Assets.xcassets/AppIcon.appiconset/Artboard-257.png b/EasyCode/Assets.xcassets/AppIcon.appiconset/Artboard-257.png
new file mode 100644
index 0000000..7a40673
Binary files /dev/null and b/EasyCode/Assets.xcassets/AppIcon.appiconset/Artboard-257.png differ
diff --git a/EasyCode/Assets.xcassets/AppIcon.appiconset/Contents.json b/EasyCode/Assets.xcassets/AppIcon.appiconset/Contents.json
index 1713f77..c3d7de7 100644
--- a/EasyCode/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/EasyCode/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -39,7 +39,7 @@
{
"size" : "256x256",
"idiom" : "mac",
- "filename" : "Artboard-128.png",
+ "filename" : "Artboard-257.png",
"scale" : "1x"
},
{
diff --git a/EasyCode/Assets.xcassets/Contents.json b/EasyCode/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/EasyCode/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Assets.xcassets/EasyCode/Contents.json b/EasyCode/Assets.xcassets/EasyCode/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/EasyCode/Assets.xcassets/EasyCode/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Assets.xcassets/EasyCode/StatusBarImage.imageset/Contents.json b/EasyCode/Assets.xcassets/EasyCode/StatusBarImage.imageset/Contents.json
new file mode 100644
index 0000000..4cbb0d5
--- /dev/null
+++ b/EasyCode/Assets.xcassets/EasyCode/StatusBarImage.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "StatusBarImage@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Assets.xcassets/EasyCode/StatusBarImage.imageset/StatusBarImage@2x.png b/EasyCode/Assets.xcassets/EasyCode/StatusBarImage.imageset/StatusBarImage@2x.png
new file mode 100644
index 0000000..c385d2c
Binary files /dev/null and b/EasyCode/Assets.xcassets/EasyCode/StatusBarImage.imageset/StatusBarImage@2x.png differ
diff --git a/EasyCode/Assets.xcassets/EasyCode/add.imageset/Contents.json b/EasyCode/Assets.xcassets/EasyCode/add.imageset/Contents.json
new file mode 100644
index 0000000..a625689
--- /dev/null
+++ b/EasyCode/Assets.xcassets/EasyCode/add.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "add.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Resource/add.png b/EasyCode/Assets.xcassets/EasyCode/add.imageset/add.png
similarity index 100%
rename from EasyCode/Resource/add.png
rename to EasyCode/Assets.xcassets/EasyCode/add.imageset/add.png
diff --git a/EasyCode/Assets.xcassets/EasyCode/btnbg.imageset/Contents.json b/EasyCode/Assets.xcassets/EasyCode/btnbg.imageset/Contents.json
new file mode 100644
index 0000000..9c155c9
--- /dev/null
+++ b/EasyCode/Assets.xcassets/EasyCode/btnbg.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "btnbg.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "btnbg@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Resource/btnbg.png b/EasyCode/Assets.xcassets/EasyCode/btnbg.imageset/btnbg.png
similarity index 100%
rename from EasyCode/Resource/btnbg.png
rename to EasyCode/Assets.xcassets/EasyCode/btnbg.imageset/btnbg.png
diff --git a/EasyCode/Resource/btnbg@2x.png b/EasyCode/Assets.xcassets/EasyCode/btnbg.imageset/btnbg@2x.png
similarity index 100%
rename from EasyCode/Resource/btnbg@2x.png
rename to EasyCode/Assets.xcassets/EasyCode/btnbg.imageset/btnbg@2x.png
diff --git a/EasyCode/Assets.xcassets/EasyCode/btnbg2.imageset/Contents.json b/EasyCode/Assets.xcassets/EasyCode/btnbg2.imageset/Contents.json
new file mode 100644
index 0000000..dfa1ba5
--- /dev/null
+++ b/EasyCode/Assets.xcassets/EasyCode/btnbg2.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "btnbg2.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "btnbg2@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Resource/btnbg2.png b/EasyCode/Assets.xcassets/EasyCode/btnbg2.imageset/btnbg2.png
similarity index 100%
rename from EasyCode/Resource/btnbg2.png
rename to EasyCode/Assets.xcassets/EasyCode/btnbg2.imageset/btnbg2.png
diff --git a/EasyCode/Resource/btnbg2@2x.png b/EasyCode/Assets.xcassets/EasyCode/btnbg2.imageset/btnbg2@2x.png
similarity index 100%
rename from EasyCode/Resource/btnbg2@2x.png
rename to EasyCode/Assets.xcassets/EasyCode/btnbg2.imageset/btnbg2@2x.png
diff --git a/EasyCode/Assets.xcassets/EasyCode/btnguide.imageset/Contents.json b/EasyCode/Assets.xcassets/EasyCode/btnguide.imageset/Contents.json
new file mode 100644
index 0000000..feb9c6f
--- /dev/null
+++ b/EasyCode/Assets.xcassets/EasyCode/btnguide.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "btnguide.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "btnguide@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Resource/btnguide.png b/EasyCode/Assets.xcassets/EasyCode/btnguide.imageset/btnguide.png
similarity index 100%
rename from EasyCode/Resource/btnguide.png
rename to EasyCode/Assets.xcassets/EasyCode/btnguide.imageset/btnguide.png
diff --git a/EasyCode/Resource/btnguide@2x.png b/EasyCode/Assets.xcassets/EasyCode/btnguide.imageset/btnguide@2x.png
similarity index 100%
rename from EasyCode/Resource/btnguide@2x.png
rename to EasyCode/Assets.xcassets/EasyCode/btnguide.imageset/btnguide@2x.png
diff --git a/EasyCode/Assets.xcassets/EasyCode/edit.imageset/Contents.json b/EasyCode/Assets.xcassets/EasyCode/edit.imageset/Contents.json
new file mode 100644
index 0000000..3f753a7
--- /dev/null
+++ b/EasyCode/Assets.xcassets/EasyCode/edit.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "edit.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Resource/edit.png b/EasyCode/Assets.xcassets/EasyCode/edit.imageset/edit.png
similarity index 100%
rename from EasyCode/Resource/edit.png
rename to EasyCode/Assets.xcassets/EasyCode/edit.imageset/edit.png
diff --git a/EasyCode/Assets.xcassets/EasyCode/mainbg.imageset/Contents.json b/EasyCode/Assets.xcassets/EasyCode/mainbg.imageset/Contents.json
new file mode 100644
index 0000000..a0773f8
--- /dev/null
+++ b/EasyCode/Assets.xcassets/EasyCode/mainbg.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "mainbg.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "mainbg@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Resource/mainbg.png b/EasyCode/Assets.xcassets/EasyCode/mainbg.imageset/mainbg.png
similarity index 100%
rename from EasyCode/Resource/mainbg.png
rename to EasyCode/Assets.xcassets/EasyCode/mainbg.imageset/mainbg.png
diff --git a/EasyCode/Resource/mainbg@2x.png b/EasyCode/Assets.xcassets/EasyCode/mainbg.imageset/mainbg@2x.png
similarity index 100%
rename from EasyCode/Resource/mainbg@2x.png
rename to EasyCode/Assets.xcassets/EasyCode/mainbg.imageset/mainbg@2x.png
diff --git a/EasyCode/Assets.xcassets/EasyCode/remove.imageset/Contents.json b/EasyCode/Assets.xcassets/EasyCode/remove.imageset/Contents.json
new file mode 100644
index 0000000..d7238fe
--- /dev/null
+++ b/EasyCode/Assets.xcassets/EasyCode/remove.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "remove.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/EasyCode/Resource/remove.png b/EasyCode/Assets.xcassets/EasyCode/remove.imageset/remove.png
similarity index 100%
rename from EasyCode/Resource/remove.png
rename to EasyCode/Assets.xcassets/EasyCode/remove.imageset/remove.png
diff --git a/EasyCode/Base.lproj/Document.xib b/EasyCode/Base.lproj/Document.xib
new file mode 100644
index 0000000..94beef9
--- /dev/null
+++ b/EasyCode/Base.lproj/Document.xib
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/EasyCode/Base.lproj/MainMenu.xib b/EasyCode/Base.lproj/MainMenu.xib
index 1756928..ace583b 100644
--- a/EasyCode/Base.lproj/MainMenu.xib
+++ b/EasyCode/Base.lproj/MainMenu.xib
@@ -1,9 +1,8 @@
-
+
-
-
+
@@ -13,11 +12,7 @@
-
-
-
-
-
+
-
-
-
-
-
-
diff --git a/EasyCode/Document/ECSnippetsDocument.h b/EasyCode/Document/ECSnippetsDocument.h
new file mode 100644
index 0000000..e31ad04
--- /dev/null
+++ b/EasyCode/Document/ECSnippetsDocument.h
@@ -0,0 +1,48 @@
+//
+// ECSnippetDocument.h
+// AirCode
+//
+// Created by lijia on 2017/3/1.
+// Copyright © 2017年 music4kid. All rights reserved.
+//
+
+#import
+#import "EditorWindowController.h"
+#import "ECSnippet.h"
+@protocol ECSnippetEntrysDocumentDelegate;
+
+EC_EXTERN NSString *const ECDocumentLoadedNotificationOC;
+EC_EXTERN NSString *const ECDocumentLoadedNotificationSwift;
+
+typedef NS_ENUM(NSInteger,ECSnippetEntryActionType) {
+ ECSnippetEntryActionTypeCreate,
+ ECSnippetEntryActionTypeRetrieve,
+ ECSnippetEntryActionTypeUpdate,
+ ECSnippetEntryActionTypeDelete
+};
+
+@interface ECSnippetDocument : NSDocument
+@property (nonatomic, assign) ECSourceType sourceType;
+@property (nonatomic, copy,readonly) ECSnippet* snippet;
+@property (nonatomic, weak) id delegate;
+
+-(instancetype)initWithFileURL:(NSURL*)itemURL sourceType:(ECSourceType)type;
+//条目数量
+-(NSInteger)snippetEntryCount;
+//根据键查找片段
+-(ECSnippetEntry*)snippetEntryForKey:(NSString*)key;
+//插入片段
+-(void)addSnippetEntry:(ECSnippetEntry*)snippet;
+//根据键删除片段
+-(void)removeSnippetEntryForKey:(NSString*)key;
+//根据键更新片段
+-(void)updateSnippetEntry:(ECSnippetEntry*)snippet;
+//保存文档
+-(void)saveDocumentCompletionHandler:(void (^)(void))handler;
+@end
+
+@protocol ECSnippetEntrysDocumentDelegate
+-(void)snippetsDocument:(ECSnippetDocument*)document performActionWithType:(ECSnippetEntryActionType)actionType withEntry:(ECSnippetEntry*)snippet;
+@end
+
+
diff --git a/EasyCode/Document/ECSnippetsDocument.m b/EasyCode/Document/ECSnippetsDocument.m
new file mode 100644
index 0000000..5899ae8
--- /dev/null
+++ b/EasyCode/Document/ECSnippetsDocument.m
@@ -0,0 +1,165 @@
+//
+// ECSnippetDocument.m
+// AirCode
+//
+// Created by lijia on 2017/3/1.
+// Copyright © 2017年 music4kid. All rights reserved.
+//
+
+#import "ECSnippetsDocument.h"
+#import "NSWindowController+Additions.h"
+#import "ECSnippetEntry.h"
+#import "ECMappingForObjectiveC.h"
+#import "ECMappingForSwift.h"
+#import "NSFileWrapper+Additions.h"
+#import "ECSnippetHelper.h"
+
+NSString *const ECDocumentLoadedNotificationOC = @"ECDocumentLoadedNotificationOC";
+NSString *const ECDocumentLoadedNotificationSwift = @"ECDocumentLoadedNotificationSwift";
+
+@interface ECSnippetDocument ()
+@property (nonatomic, strong) NSFileWrapper *fileWrapper;
+@property (nonatomic, assign,getter=hasSavedAlready) BOOL savedAlready;
+@end
+
+@implementation ECSnippetDocument
+-(instancetype)initWithFileURL:(NSURL *)itemURL sourceType:(ECSourceType)type {
+ if (type == ECSourceTypeOC) {
+ self = [super initWithContentsOfURL:itemURL ofType:DirectoryOCName error:nil];
+ } else {
+ self = [super initWithContentsOfURL:itemURL ofType:DirectorySwiftName error:nil];;
+ }
+
+ if (self) {
+ _sourceType = type;
+ _savedAlready = NO;
+ }
+ return self;
+}
+
+-(void)sortedSnippets {
+ [_snippet sortedEntry];
+}
+
+-(NSInteger)snippetEntryCount {
+ return [_snippet entryCount];
+}
+
+-(ECSnippetEntry*)snippetEntryForKey:(NSString*)key {
+ return [_snippet entryForKey:key];
+}
+
+-(void)addSnippetEntry:(ECSnippetEntry*)entry {
+ if ([entry.key ec_isNotEmpty] == NO) {
+ return;
+ }
+ [_snippet addEntry:entry];
+ [self saveDocumentCompletionHandler:^{
+ if ([_delegate respondsToSelector:@selector(snippetsDocument:performActionWithType:withEntry:)]) {
+ [_delegate snippetsDocument:self performActionWithType:ECSnippetEntryActionTypeCreate withEntry:entry];
+ }
+ }];
+}
+
+-(void)removeSnippetEntryForKey:(NSString*)key {
+ ECSnippetEntry* hitEntry = [_snippet removeEntryForKey:key];
+ [self saveDocumentCompletionHandler:^{
+ if ([_delegate respondsToSelector:@selector(snippetsDocument:performActionWithType:withEntry:)]) {
+ [_delegate snippetsDocument:self performActionWithType:ECSnippetEntryActionTypeDelete withEntry:hitEntry];
+ }
+ }];
+}
+
+-(void)updateSnippetEntry:(ECSnippetEntry*)entry {
+ ECSnippetEntry* hitEntry = entry;
+ [_snippet updateEntry:hitEntry];
+ [self saveDocumentCompletionHandler:^{
+ if ([_delegate respondsToSelector:@selector(snippetsDocument:performActionWithType:withEntry:)]) {
+ [_delegate snippetsDocument:self performActionWithType:ECSnippetEntryActionTypeUpdate withEntry:hitEntry];
+ }
+ }];
+}
+
+-(void)saveDocumentCompletionHandler:(void (^)(void))handler {
+ NSInteger version = [ECSnippetHelper versionForSourceType:_sourceType];
+ if (version == _snippet.version.integerValue && [self hasSavedAlready]) {
+ if (handler) {
+ handler();
+ }
+ return;
+ }
+ [self sortedSnippets];
+
+ NSString *typeName = DirectoryOCName;
+ if (_sourceType == ECSourceTypeOC) {
+ typeName = DirectoryOCName;
+ } else {
+ typeName = DirectorySwiftName;
+ }
+
+ [self saveToURL:self.fileURL ofType:typeName forSaveOperation:NSSaveOperation completionHandler:^(NSError * _Nullable errorOrNil) {
+ if (errorOrNil) {
+ NSLog(@"Save Document Error :%@",[errorOrNil localizedDescription]);
+ } else {
+ _savedAlready = YES;
+
+ NSString* dirnameKey = [ECSnippetHelper directoryForSourceType:_sourceType];
+ NSData* snippetData = [_snippet snippetData];
+
+ NSNumber* versionNum = _snippet.version;
+ NSString* versionKey = [NSString stringWithFormat:kVersionFormat,dirnameKey];
+ [ESharedUserDefault setObjects:@[snippetData,versionNum] forKeys:@[dirnameKey,versionKey]];
+ }
+
+ if (handler) {
+ handler();
+ }
+ }];
+}
+
+#pragma mark - Override Documents
+-(NSString *)displayName {
+ return @"Code Snippet";
+}
+
++ (BOOL)autosavesInPlace {
+ return NO;
+}
+
+- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError {
+ //snippet data
+ NSData* snippetData = [NSKeyedArchiver archivedDataWithRootObject:_snippet];
+ NSFileWrapper* snippetWrapper = [[NSFileWrapper alloc] initRegularFileWithContents:snippetData];
+ snippetWrapper.preferredFilename = SnippetFileName;
+ //version data
+ NSData* verData = [_snippet.version.stringValue dataUsingEncoding:NSUTF8StringEncoding];
+ NSFileWrapper* verWrapper = [[NSFileWrapper alloc] initRegularFileWithContents:verData];
+ verWrapper.preferredFilename = VersionFileName;
+ if (_fileWrapper == nil) {
+ NSDictionary* fileWrappers = @{ SnippetFileName:snippetWrapper,
+ VersionFileName:verWrapper };
+ _fileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:fileWrappers];
+ } else {
+ [_fileWrapper ec_replaceFileWrapper:snippetWrapper forKey:SnippetFileName];
+ [_fileWrapper ec_replaceFileWrapper:verWrapper forKey:VersionFileName];
+ }
+
+ return _fileWrapper;
+}
+
+- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString *)typeName error:(NSError * _Nullable *)outError {
+ _snippet = [ECSnippetHelper snippetWithFileWrapper:fileWrapper];
+
+ if (typeName == DirectoryOCName) {
+ [[NSNotificationCenter defaultCenter] postNotificationName:ECDocumentLoadedNotificationOC
+ object:self];
+ } else {
+ [[NSNotificationCenter defaultCenter] postNotificationName:ECDocumentLoadedNotificationSwift
+ object:self];
+ }
+
+
+ return YES;
+}
+
+@end
diff --git a/EasyCode/ECMainWindowController.h b/EasyCode/ECMainWindowController.h
new file mode 100644
index 0000000..b5c4e36
--- /dev/null
+++ b/EasyCode/ECMainWindowController.h
@@ -0,0 +1,13 @@
+//
+// ECMainWindowController.h
+// EasyCode
+//
+// Created by lijia on 02/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+EC_EXTERN NSString* const ECiCloudSyncChangedNotification;
+@interface ECMainWindowController : NSWindowController
+
+@end
diff --git a/EasyCode/ECMainWindowController.m b/EasyCode/ECMainWindowController.m
new file mode 100644
index 0000000..051f909
--- /dev/null
+++ b/EasyCode/ECMainWindowController.m
@@ -0,0 +1,80 @@
+//
+// ECMainWindowController.m
+// EasyCode
+//
+// Created by lijia on 02/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "ECMainWindowController.h"
+#import "EditorWindowController.h"
+
+NSString *const ECiCloudSyncChangedNotification = @"ECiCloudSyncChangedNotification";
+
+@interface ECMainWindowController ()
+@property (nonatomic, weak) IBOutlet NSButton *useicloudBtn;
+@property (nonatomic, strong) EditorWindowController* editorOC;
+@property (nonatomic, strong) EditorWindowController* editorSwift;
+@end
+
+@implementation ECMainWindowController
+
+- (void)windowDidLoad {
+ [super windowDidLoad];
+ _useicloudBtn.state = [ESharedUserDefault boolForKey:kUseiCloudSync];
+}
+
+- (IBAction)showEditorWindowForOC:(id)sender {
+ if (self.editorOC == nil) {
+ self.editorOC = [[EditorWindowController alloc] initEditorWindowForType:ECSourceTypeOC];
+ }
+ [_editorOC showWindow:self];
+}
+
+- (IBAction)showEditorWindowForSwift:(id)sender {
+ if (self.editorSwift == nil) {
+ self.editorSwift = [[EditorWindowController alloc] initEditorWindowForType:ECSourceTypeSwift];
+ }
+ [_editorSwift showWindow:self];
+}
+
+- (IBAction)useiCloudCheck:(NSButton*)sender {
+ BOOL useiCloud = (sender.state == NSOnState);
+ if (useiCloud) {
+ id ubiq = [[NSFileManager defaultManager] ubiquityIdentityToken];
+ if (ubiq) {
+ [ESharedUserDefault setBool:YES forKey:kUseiCloudSync];
+ [[NSNotificationCenter defaultCenter] postNotificationName:ECiCloudSyncChangedNotification object:nil];
+ } else {
+ [ESharedUserDefault setBool:NO forKey:kUseiCloudSync];
+ sender.state = NSOffState;
+ //Alert Note
+ }
+ } else {
+ id ubiq = [[NSFileManager defaultManager] ubiquityIdentityToken];
+ if (ubiq) {
+ NSAlert *warningAlert = [NSAlert ec_alertWithStyle:NSWarningAlertStyle
+ messageText:NSLocalizedString(@"iCloud_Attention", nil)
+ informativeText:NSLocalizedString(@"iCloud_Attention_Message", nil)
+ buttonTitle:NSLocalizedString(@"Button_OK_Title",nil),
+ NSLocalizedString(@"Button_Cancel_Title", nil),
+ nil];
+
+ [warningAlert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
+ if (returnCode == NSAlertFirstButtonReturn) { //OK
+ [ESharedUserDefault setBool:NO forKey:kUseiCloudSync];
+ [[NSNotificationCenter defaultCenter] postNotificationName:ECiCloudSyncChangedNotification object:nil];
+ }
+ }];
+ } else {
+ [ESharedUserDefault setBool:NO forKey:kUseiCloudSync];
+ }
+ }
+}
+
+- (IBAction)showHowToUse:(id)sender {
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: @"https://github.com/music4kid/EasyCode-Xcode"]];
+}
+
+
+@end
diff --git a/EasyCode/ECMainWindowController.xib b/EasyCode/ECMainWindowController.xib
new file mode 100644
index 0000000..9b2cb9b
--- /dev/null
+++ b/EasyCode/ECMainWindowController.xib
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/EasyCode/EasyCode.entitlements b/EasyCode/EasyCode.entitlements
index 60c1f0a..34b7dfb 100644
--- a/EasyCode/EasyCode.entitlements
+++ b/EasyCode/EasyCode.entitlements
@@ -2,11 +2,27 @@
+ com.apple.developer.aps-environment
+ development
+ com.apple.developer.icloud-container-identifiers
+
+ iCloud.$(CFBundleIdentifier)
+
+ com.apple.developer.icloud-services
+
+ CloudDocuments
+
+ com.apple.developer.ubiquity-container-identifiers
+
+ iCloud.$(CFBundleIdentifier)
+
+ com.apple.developer.ubiquity-kvstore-identifier
+ $(TeamIdentifierPrefix)$(CFBundleIdentifier)
com.apple.security.app-sandbox
com.apple.security.application-groups
- 2WQE6AU5PD.group.com.music4kid.easycode
+ $(TeamIdentifierPrefix)group.com.sito.easycode
diff --git a/EasyCode/Info.plist b/EasyCode/Info.plist
index f19d1eb..a8f59f8 100644
--- a/EasyCode/Info.plist
+++ b/EasyCode/Info.plist
@@ -4,6 +4,35 @@
CFBundleDevelopmentRegion
en
+ CFBundleDisplayName
+
+ CFBundleDocumentTypes
+
+
+ CFBundleTypeExtensions
+
+ ec
+
+ CFBundleTypeIconFile
+
+ CFBundleTypeName
+ Snippets Document
+ CFBundleTypeOSTypes
+
+ ????
+
+ CFBundleTypeRole
+ Editor
+ LSItemContentTypes
+
+ com.yingxiang.easycode.ec
+
+ LSTypeIsPackage
+ 1
+ NSDocumentClass
+ ECSnippetDocument
+
+
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIconFile
@@ -24,11 +53,29 @@
public.app-category.developer-tools
LSMinimumSystemVersion
$(MACOSX_DEPLOYMENT_TARGET)
+ LSUIElement
+
NSHumanReadableCopyright
Copyright © 2016年 music4kid. All rights reserved.
NSMainNibFile
MainMenu
NSPrincipalClass
NSApplication
+ UTExportedTypeDeclarations
+
+
+ UTTypeDescription
+ Snippets Document package
+ UTTypeIdentifier
+ com.yingxiang.easycode.ec
+ UTTypeTagSpecification
+
+ public.filename-extension
+
+ ec
+
+
+
+
diff --git a/EasyCode/MappingEditor/DetailEditorController/DetailWindowController.h b/EasyCode/MappingEditor/DetailWindowController.h
similarity index 74%
rename from EasyCode/MappingEditor/DetailEditorController/DetailWindowController.h
rename to EasyCode/MappingEditor/DetailWindowController.h
index 7e54728..08088cf 100644
--- a/EasyCode/MappingEditor/DetailEditorController/DetailWindowController.h
+++ b/EasyCode/MappingEditor/DetailWindowController.h
@@ -7,7 +7,7 @@
//
#import
-#import "EShortcutEntry.h"
+#import "ECSnippetEntry.h"
typedef enum : NSUInteger {
DetailEditorModeUpdate,
@@ -15,21 +15,18 @@ typedef enum : NSUInteger {
} DetailEditorMode;
@protocol DetailWindowEditorDelegate
-
-- (void)onEntryUpdated:(EShortcutEntry*)entry;
-- (void)onEntryInserted:(EShortcutEntry*)entry;
-
+- (void)onSnippetUpdated:(ECSnippetEntry*)snippet;
+- (void)onSnippetInserted:(ECSnippetEntry*)snippet;
@end
@interface DetailWindowController : NSWindowController
+@property (nonatomic, readonly,getter=hasEdited) BOOL edited;
-- (void)initWithMappingEntry:(EShortcutEntry*)entry;
+- (void)initWithEntry:(ECSnippetEntry*)entry;
@property (nonatomic, weak) id delegate;
@property (nonatomic, assign) DetailEditorMode editMode;
-
-
@property (nonatomic, strong) IBOutlet NSTextField* txtKey;
@property (nonatomic, strong) IBOutlet NSTextField* txtCode;
diff --git a/EasyCode/MappingEditor/DetailEditorController/DetailWindowController.m b/EasyCode/MappingEditor/DetailWindowController.m
similarity index 71%
rename from EasyCode/MappingEditor/DetailEditorController/DetailWindowController.m
rename to EasyCode/MappingEditor/DetailWindowController.m
index d20d251..7167af6 100644
--- a/EasyCode/MappingEditor/DetailEditorController/DetailWindowController.m
+++ b/EasyCode/MappingEditor/DetailWindowController.m
@@ -9,38 +9,37 @@
#import "DetailWindowController.h"
@interface DetailWindowController ()
-@property (nonatomic, strong) EShortcutEntry* curEntry;
-
+@property (nonatomic, strong) ECSnippetEntry* curEntry;
@end
@implementation DetailWindowController
- (void)windowDidLoad {
[super windowDidLoad];
+ _edited = NO;
[self updateEntryDisplay];
-
self.window.delegate = self;
-
+ [self.window center];
}
- (void)windowWillClose:(NSNotification *)notification
{
if (_delegate) {
if (_editMode == DetailEditorModeUpdate) {
- [_delegate onEntryUpdated:_curEntry];
+ [_delegate onSnippetUpdated:_curEntry];
}
else if(_editMode == DetailEditorModeInsert)
{
- [_delegate onEntryInserted:_curEntry];
+ [_delegate onSnippetInserted:_curEntry];
}
}
+ _edited = NO;
}
-- (void)initWithMappingEntry:(EShortcutEntry*)entry
+- (void)initWithEntry:(ECSnippetEntry*)entry
{
self.curEntry = entry;
-
[self updateEntryDisplay];
}
@@ -71,10 +70,18 @@ - (void)controlTextDidChange:(NSNotification *)notification {
NSTextField *textField = [notification object];
if (textField == _txtKey) {
- _curEntry.key = [textField stringValue];
+ NSString* changedValue = [textField stringValue];
+ if ([_curEntry.key isEqualToString:changedValue] == NO) {
+ _edited = YES;
+ }
+ _curEntry.key = changedValue;
}
else if(textField == _txtCode)
{
+ NSString* changedValue = [textField stringValue];
+ if ([_curEntry.code isEqualToString:changedValue] == NO) {
+ _edited = YES;
+ }
_curEntry.code = [textField stringValue];
}
}
@@ -99,4 +106,12 @@ - (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySe
return result;
}
+- (void)setEditMode:(DetailEditorMode)editMode {
+ _editMode = editMode;
+ if (_editMode == DetailEditorModeUpdate) {
+ [_txtCode becomeFirstResponder];
+ } else {
+ [_txtKey becomeFirstResponder];
+ }
+}
@end
diff --git a/EasyCode/MappingEditor/DetailEditorController/DetailWindowController.xib b/EasyCode/MappingEditor/DetailWindowController.xib
similarity index 100%
rename from EasyCode/MappingEditor/DetailEditorController/DetailWindowController.xib
rename to EasyCode/MappingEditor/DetailWindowController.xib
diff --git a/EasyCode/MappingEditor/ECSnippet.h b/EasyCode/MappingEditor/ECSnippet.h
new file mode 100644
index 0000000..1f3d0fa
--- /dev/null
+++ b/EasyCode/MappingEditor/ECSnippet.h
@@ -0,0 +1,34 @@
+//
+// ECSnippet.h
+// EasyCode
+//
+// Created by lijia on 07/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+#import "ECSnippetEntry.h"
+#import "ECDefine.h"
+
+@interface ECSnippet : NSObject
+@property (nonatomic, copy) NSNumber* version;
+@property (nonatomic, copy) NSNumber* type;
+@property (nonatomic, copy) NSArray* entries;
+
+-(instancetype)initWithSourceType:(ECSourceType)sourceType entries:(NSArray*)entries;
+
+//sort entry
+-(void)sortedEntry;
+//count entry
+-(NSInteger)entryCount;
+//search entry
+-(ECSnippetEntry*)entryForKey:(NSString*)key;
+//insert entry
+-(void)addEntry:(ECSnippetEntry*)entry;
+//delete entry
+-(ECSnippetEntry*)removeEntryForKey:(NSString*)key;
+//update entry
+-(void)updateEntry:(ECSnippetEntry*)entry;
+//use for store
+-(NSData*)snippetData;
+@end
diff --git a/EasyCode/MappingEditor/ECSnippet.m b/EasyCode/MappingEditor/ECSnippet.m
new file mode 100644
index 0000000..bc0e80e
--- /dev/null
+++ b/EasyCode/MappingEditor/ECSnippet.m
@@ -0,0 +1,121 @@
+//
+// ECSnippet.m
+// EasyCode
+//
+// Created by lijia on 07/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "ECSnippet.h"
+#import "NSString+Additions.h"
+
+
+@interface ECSnippet () {
+ NSMutableArray* _entryList;
+}
+@end
+
+
+@implementation ECSnippet
+-(instancetype)initWithSourceType:(ECSourceType)sourceType entries:(NSArray*)entries {
+ self = [super init];
+ if (self) {
+ _type = @(sourceType);
+ _entryList = [entries mutableCopy];
+ _version = @(1);
+ }
+ return self;
+}
+
+- (instancetype)initWithCoder:(NSCoder *)decoder {
+ self.version = [decoder decodeObjectForKey:@"version"];
+ self.entries = [decoder decodeObjectForKey:@"entries"];
+ self.type = [decoder decodeObjectForKey:@"type"];
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)encoder {
+ [encoder encodeObject:_version forKey:@"version"];
+ [encoder encodeObject:[self entries] forKey:@"entries"];
+ [encoder encodeObject:_type forKey:@"type"];
+}
+
+- (id)copyWithZone:(NSZone *)zone {
+ ECSnippet* snippet = [[[self class] allocWithZone:zone] init];
+ snippet.version = _version;
+ snippet.entries = [_entryList copy];
+ snippet.type = _type;
+ return snippet;
+}
+
+-(NSArray *)entries {
+ return [_entryList copy];
+}
+
+-(void)setEntries:(NSArray *)entries {
+ _entryList = [entries mutableCopy];
+}
+
+//排序
+-(void)sortedEntry {
+ [_entryList sortUsingComparator:^NSComparisonResult(ECSnippetEntry* _Nonnull e1, ECSnippetEntry* _Nonnull e2) {
+ return [e1.key compare:e2.key];
+ }];
+}
+
+//条目数量
+-(NSInteger)entryCount {
+ return _entryList.count;
+}
+
+-(ECSnippetEntry*)entryForKey:(NSString*)key {
+ NSString* trimKey = [key ec_trimWhiteSpace];
+ NSArray* entryList = [self entries];
+ NSUInteger index = [entryList indexOfObjectWithOptions:NSEnumerationConcurrent passingTest:^BOOL(ECSnippetEntry* _Nonnull snippet, NSUInteger idx, BOOL * _Nonnull stop) {
+ BOOL result = [snippet.key isEqualToString:trimKey];
+ if (result) {
+ *stop = YES;
+ }
+ return result;
+ }];
+ if (index != NSNotFound) {
+ return entryList[index];
+ }
+ return nil;
+}
+
+-(void)addEntry:(ECSnippetEntry*)entry {
+ if ([entry.key ec_isNotEmpty] == NO) {
+ return;
+ }
+ ECSnippetEntry* hitEntry = [self entryForKey:entry.key];
+ if (hitEntry == nil) { //add
+ [_entryList addObject:entry];
+ } else {
+ [self updateEntry:entry];
+ }
+ _version = @([_NUMBER(_version) unsignedIntegerValue] + 1);
+}
+
+-(ECSnippetEntry*)removeEntryForKey:(NSString*)key {
+ ECSnippetEntry* hitEntry = [self entryForKey:key];
+ if (hitEntry) {
+ [_entryList removeObject:hitEntry];
+ _version = @([_NUMBER(_version) unsignedIntegerValue] + 1);
+ }
+ return hitEntry;
+}
+
+-(void)updateEntry:(ECSnippetEntry*)entry {
+ ECSnippetEntry* hitEntry = [self entryForKey:entry.key];
+ [hitEntry updateBySnippet:hitEntry];
+ _version = @([_NUMBER(_version) unsignedIntegerValue] + 1);
+}
+
+-(NSData*)snippetData {
+ NSData* data = [NSKeyedArchiver archivedDataWithRootObject:self];
+ return data;
+}
+
+
+@end
diff --git a/EasyCode/MappingEditor/ECSnippetEntry.h b/EasyCode/MappingEditor/ECSnippetEntry.h
new file mode 100644
index 0000000..8d1597b
--- /dev/null
+++ b/EasyCode/MappingEditor/ECSnippetEntry.h
@@ -0,0 +1,19 @@
+//
+// ECSnippetEntry.h
+// EasyCode
+//
+// Created by lijia on 07/03/2017.
+// Copyright © 2016年 music4kid. All rights reserved.
+//
+
+#import
+
+@interface ECSnippetEntry : NSObject
+@property (nonatomic, copy) NSString* key;
+@property (nonatomic, copy) NSString* code;
+@property (nonatomic, copy) NSString* createAt;
+
++(instancetype)snippetWithKey:(NSString*)key code:(NSString*)code;
+
+-(void)updateBySnippet:(ECSnippetEntry*)snippet;
+@end
diff --git a/EasyCode/MappingEditor/ECSnippetEntry.m b/EasyCode/MappingEditor/ECSnippetEntry.m
new file mode 100644
index 0000000..7ace6fa
--- /dev/null
+++ b/EasyCode/MappingEditor/ECSnippetEntry.m
@@ -0,0 +1,61 @@
+//
+// ECSnippetEntry.m
+// EasyCode
+//
+// Created by gao feng on 2016/10/20.
+// Copyright © 2016年 music4kid. All rights reserved.
+//
+
+#import "ECSnippetEntry.h"
+#import "NSString+Additions.h"
+
+static NSDateFormatter* formatter = nil;
+
+@implementation ECSnippetEntry
++ (void)initialize {
+ if (self == [ECSnippetEntry class]) {
+ formatter = [[NSDateFormatter alloc] init];
+ [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
+ }
+}
+
++(instancetype)snippetWithKey:(NSString*)key code:(NSString*)code {
+ ECSnippetEntry* snippet = [[[self class] alloc] init];
+ snippet.key = key;
+ snippet.code = code;
+ snippet.createAt = [formatter stringFromDate:[NSDate date]];
+ return snippet;
+}
+
+- (instancetype)initWithCoder:(NSCoder *)decoder {
+ self.key = [decoder decodeObjectForKey:@"key"];
+ self.code = [decoder decodeObjectForKey:@"code"];
+ self.createAt = [decoder decodeObjectForKey:@"createAt"];
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)encoder {
+ [encoder encodeObject:_key forKey:@"key"];
+ [encoder encodeObject:_code forKey:@"code"];
+ [encoder encodeObject:_createAt forKey:@"createAt"];
+}
+
+- (id)copyWithZone:(NSZone *)zone {
+ ECSnippetEntry* snippet = [[[self class] allocWithZone:zone] init];
+ snippet.key = _key;
+ snippet.code = _code;
+ snippet.createAt = _createAt;
+ return snippet;
+}
+
+- (void)setKey:(NSString *)key {
+ _key = [key ec_trimWhiteSpace];
+}
+
+-(void)updateBySnippet:(ECSnippetEntry*)snippet {
+ if ([self.key isEqualToString:snippet.key]) {
+ self.code = snippet.code;
+ }
+}
+
+@end
diff --git a/EasyCode/MappingEditor/EEditorTableView.m b/EasyCode/MappingEditor/EEditorTableView.m
deleted file mode 100644
index ca893f4..0000000
--- a/EasyCode/MappingEditor/EEditorTableView.m
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// EEditorTableView.m
-// EasyCode
-//
-// Created by gao feng on 2016/10/20.
-// Copyright © 2016年 music4kid. All rights reserved.
-//
-
-#import "EEditorTableView.h"
-
-@implementation EEditorTableView
-
-
-@end
diff --git a/EasyCode/MappingEditor/EShortcutEntry.h b/EasyCode/MappingEditor/EShortcutEntry.h
deleted file mode 100644
index b21f819..0000000
--- a/EasyCode/MappingEditor/EShortcutEntry.h
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// EShortcutEntry.h
-// EasyCode
-//
-// Created by gao feng on 2016/10/20.
-// Copyright © 2016年 music4kid. All rights reserved.
-//
-
-#import
-
-@interface EShortcutEntry : NSObject
-@property (nonatomic, strong) NSString* key;
-@property (nonatomic, strong) NSString* code;
-@end
diff --git a/EasyCode/MappingEditor/EShortcutEntry.m b/EasyCode/MappingEditor/EShortcutEntry.m
deleted file mode 100644
index caaa8ef..0000000
--- a/EasyCode/MappingEditor/EShortcutEntry.m
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// EShortcutEntry.m
-// EasyCode
-//
-// Created by gao feng on 2016/10/20.
-// Copyright © 2016年 music4kid. All rights reserved.
-//
-
-#import "EShortcutEntry.h"
-
-@implementation EShortcutEntry
-
-@end
diff --git a/EasyCode/MappingEditor/EditorWindowController.h b/EasyCode/MappingEditor/EditorWindowController.h
index 8e8b5c8..8332332 100644
--- a/EasyCode/MappingEditor/EditorWindowController.h
+++ b/EasyCode/MappingEditor/EditorWindowController.h
@@ -8,15 +8,6 @@
#import
-typedef enum : NSUInteger {
- EditorTypeOC,
- EditorTypeSwift,
-} EditorType;
-
@interface EditorWindowController : NSWindowController
-
-@property (nonatomic, strong) IBOutlet NSTableView* tableView;
-
-- (void)initEditorWindow:(EditorType)editorType;
-
+- (instancetype)initEditorWindowForType:(ECSourceType)sourceType;
@end
diff --git a/EasyCode/MappingEditor/EditorWindowController.m b/EasyCode/MappingEditor/EditorWindowController.m
index 46beeeb..ea8eac6 100644
--- a/EasyCode/MappingEditor/EditorWindowController.m
+++ b/EasyCode/MappingEditor/EditorWindowController.m
@@ -7,90 +7,288 @@
//
#import "EditorWindowController.h"
-#import "ESharedUserDefault.h"
-#import "EShortcutEntry.h"
+#import "ECMainWindowController.h"
#import "DetailWindowController.h"
+#import "ESharedUserDefault.h"
+#import "ECSnippetEntry.h"
+#import "ECSnippetsDocument.h"
+#import "NSWindow+Additions.h"
+#import "NSString+Additions.h"
+#import "NSFileManager+Additions.h"
+#import "ECSnippetHelper.h"
+#import "EEditorTableMenu.h"
+#import "EEditorTableRowView.h"
-@interface EditorWindowController ()
-@property (nonatomic, strong) NSMutableDictionary* mappingDic;
-@property (nonatomic, strong) NSMutableArray* mappingList;
-@property (nonatomic, assign) EditorType editorType;
-
-@property (nonatomic, strong) NSImage* imgEdit;
-@property (nonatomic, strong) NSImage* imgAdd;
-@property (nonatomic, strong) NSImage* imgRemove;
+@interface EditorWindowController ()
+@property (nonatomic, weak) IBOutlet NSWindow *toastPanel;
+@property (nonatomic, weak) IBOutlet NSTextField *toastText;
+@property (nonatomic, weak) IBOutlet NSScrollView *scrollView;
+@property (nonatomic, weak) IBOutlet NSTableView *tableView;
+@property (nonatomic, weak) IBOutlet NSTableColumn *filterColumn;
+@property (nonatomic, weak) IBOutlet NSSearchField *searchField;
+@property (nonatomic, strong) EEditorTableMenu *tableMenu;
+@property (nonatomic, strong) NSImage *imgEdit;
+@property (nonatomic, strong) NSImage *imgAdd;
+@property (nonatomic, strong) NSImage *imgRemove;
-@property (nonatomic, strong) DetailWindowController* detailEditor;
+@property (nonatomic, assign) ECSourceType sourceType;
+@property (nonatomic, strong) NSArray *filteringList;
+@property (nonatomic, strong) NSArray *matchingList;
+@property (nonatomic, strong) DetailWindowController *detailEditor;
+@property (nonatomic, strong) ECSnippetDocument *snippetDoc;
+@property (nonatomic, copy) NSString *searchKey;
+@property (nonatomic, copy) NSString *dirname;
+@property (nonatomic, strong) NSMetadataQuery *query;
+@property (nonatomic, strong) NSMetadataItem *dataItem;
@end
@implementation EditorWindowController
+- (void)dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (instancetype)initEditorWindowForType:(ECSourceType)sourceType {
+ self = [super initWithWindowNibName:@"EditorWindowController"];
+ if (self) {
+ _sourceType = sourceType;
+ }
+ return self;
+}
-- (void)initEditorWindow:(EditorType)editorType {
- self.editorType = editorType;
+- (void)setupData {
+ self.dirname = [ECSnippetHelper directoryForSourceType:_sourceType];
+ self.window.title = self.dirname;
self.imgEdit = [NSImage imageNamed:@"edit"];
self.imgAdd = [NSImage imageNamed:@"add"];
self.imgRemove = [NSImage imageNamed:@"remove"];
- self.mappingList = @[].mutableCopy;
- if (_editorType == EditorTypeOC) {
- self.mappingDic = [_UD readMappingForOC].mutableCopy;
- self.window.title = @"Objective-C";
+ if (_sourceType == ECSourceTypeOC) {
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(onDocumentLoaded:)
+ name:ECDocumentLoadedNotificationOC
+ object:nil];
}
- else if(_editorType == EditorTypeSwift)
- {
- self.mappingDic = [_UD readMappingForSwift].mutableCopy;
- self.window.title = @"Swift";
+ else{
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(onDocumentLoaded:)
+ name:ECDocumentLoadedNotificationSwift
+ object:nil];
}
- NSArray* keys = self.mappingDic.allKeys;
- keys = [keys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
- NSString* str1 = obj1;
- NSString* str2 = obj2;
- return [str1 compare:str2];
- }];
- for (NSString* key in keys) {
- EShortcutEntry* entry = [EShortcutEntry new];
- entry.key = key;
- entry.code = _mappingDic[key];
- [_mappingList addObject:entry];
- }
- [self sortMappingList];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(onUbiquityIdentityChanged:)
+ name:NSUbiquityIdentityDidChangeNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(oniCloudSyncChanged:)
+ name:ECiCloudSyncChangedNotification
+ object:nil];
+}
+
+- (void)setupView {
+ _tableMenu = [[EEditorTableMenu alloc] initWithTitle:@"Menu"];
+ _tableMenu.editorDelegate = self;
+ [_tableView setMenu:_tableMenu];
+ [_tableView setDoubleAction:@selector(onHandleDoubleClick:)];
+ [_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleRegular];
+
+ _searchField.delegate = self;
+ _toastPanel.backgroundColor = [NSColor colorWithWhite:0 alpha:0.5];
+ [_toastPanel ec_setCornRadius:12];
+ [_toastPanel orderOut:self];
+
+ self.window.delegate = self;
+ [self.window center];
}
+
- (void)windowDidLoad {
[super windowDidLoad];
-
- [_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
+ [self setupData];
+ [self setupView];
+ [self loadDocument];
+}
+
+- (void)reloadData {
dispatch_async(dispatch_get_main_queue(), ^{
[_tableView reloadData];
});
+}
+
+- (void)onDocumentLoaded:(NSNotification*)notification {
+ _snippetDoc = [notification object];
+ _snippetDoc.delegate = self;
+ [_snippetDoc saveDocumentCompletionHandler:^{
+ [self reloadData];
+ }];
+}
+
+- (void)onUbiquityIdentityChanged:(NSNotification*)notification {
+ [self loadDocument];
+}
+
+- (void)oniCloudSyncChanged:(NSNotification*)notification {
+ BOOL useiCloud = [ESharedUserDefault boolForKey:kUseiCloudSync];
+ NSURL* baseURL = [[NSFileManager defaultManager] ec_localURL];
+ if (useiCloud) {
+ baseURL = [[NSFileManager defaultManager] ec_ubiquityURL];
+ }
+ NSURL* destURL = [baseURL URLByAppendingPathComponent:_dirname];
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ NSError* error = nil;
+ BOOL success = [[NSFileManager defaultManager] setUbiquitous:useiCloud itemAtURL:_snippetDoc.fileURL destinationURL:destURL error:&error];
+ if (!success) {
+ NSLog(@"ubiquitous move error :%@",[error localizedDescription]);
+ }
+ [self loadDocument];
+ });
+}
+
+- (void)queryDidFinishGathering:(NSNotification *)notification {
+ NSMetadataQuery *query = [notification object];
+ [query disableUpdates];
+ [query stopQuery];
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:NSMetadataQueryDidFinishGatheringNotification
+ object:nil];
+ [self loadDataWithQuery:query];
+ _query = nil;
+}
+
+- (void)loadDocument {
+ id ubiq = [[NSFileManager defaultManager] ubiquityIdentityToken];
+ BOOL useiCloud = [ESharedUserDefault boolForKey:kUseiCloudSync];
+ if (ubiq && useiCloud) { //iCloud Enabled and Checked
+ _query = [[NSMetadataQuery alloc] init];
+ _query.searchScopes = @[NSMetadataQueryUbiquitousDocumentsScope];
+ NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K == %@", NSMetadataItemFSNameKey,_dirname];
+ [_query setPredicate:pred];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(queryDidFinishGathering:)
+ name:NSMetadataQueryDidFinishGatheringNotification
+ object:_query];
+ [_query startQuery];
+ } else { //iCloud Disabled
+ [self loadDataWithQuery:nil];
+ }
+}
+
+- (void)loadDataWithQuery:(NSMetadataQuery*)query {
+ NSURL* fileURL = [[NSFileManager defaultManager] ec_localSnippetsURLWithFilename:_dirname];
+ if (query) {
+ //load from remote
+ if ([query resultCount] >= 1) {
+ _dataItem = [query resultAtIndex:0];
+ fileURL = [_dataItem valueForAttribute:NSMetadataItemURLKey];
+ } else {
+ fileURL = [[NSFileManager defaultManager] ec_ubiquitySnippetsURLWithFilename:_dirname];
+ }
+ }
+ _snippetDoc = [[ECSnippetDocument alloc] initWithFileURL:fileURL sourceType:_sourceType];
+ _snippetDoc.delegate = self;
+}
+
+- (void)onFireSearchRequest {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ NSArray* cloneList = _snippetDoc.snippet.entries;
+ if (_searchKey.length > 0) {
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"key contains[cd] %@", _searchKey];
+ cloneList = [cloneList filteredArrayUsingPredicate:predicate];
+ }
+ _filteringList = cloneList;
+ [self reloadData];
+ });
+}
+
+- (void)onQueueSearchRequest {
+ _searchKey = [_searchField.stringValue ec_trimWhiteSpace];
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onFireSearchRequest) object:nil];
+ [self performSelector:@selector(onFireSearchRequest) withObject:nil afterDelay:0.2f];
+}
+
+- (void)controlTextDidChange:(NSNotification *)notification {
+ [self onQueueSearchRequest];
+}
+
+- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
+ if (commandSelector == @selector(insertNewline:)) { //pressed enter
+ [self onQueueSearchRequest];
+ }
+ return NO;
+}
+
+- (void)focusSearchField:(id)sender {
+ [_searchField selectText:self];
+ [[_searchField currentEditor] setSelectedRange:NSMakeRange(_searchField.stringValue.length, 0)];
+}
+
+- (void)keyDown:(NSEvent *)event {
+ if (([event modifierFlags] & NSCommandKeyMask) == NSCommandKeyMask){
+ if ([event keyCode] == 3) { //Command + F
+ [self focusSearchField:nil];
+ }
+ }
+}
+
+- (void)pasteShortcutWithEntry:(ECSnippetEntry*)snippet {
+ NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
+ [pasteboard clearContents];
+ BOOL success = [pasteboard writeObjects:@[snippet.key]];
+ if (success) {
+ _toastText.stringValue = snippet.key;
+ [_toastPanel ec_fadeInAnimated:NO];
+ [_toastPanel ec_fadeOutAnimated:YES afterDelay:3];
+ }
+}
+
+- (void)onHandleDoubleClick:(id)sender {
+ if (_tableView.clickedColumn > 1) {
+ return;
+ }
- self.window.delegate = self;
+ ECSnippetEntry* snippet = _matchingList[_tableView.clickedRow];
+ if (_tableView.clickedColumn == 0) { //clicked shortcut key
+ [self pasteShortcutWithEntry:snippet];
+ } else {
+ [self presentDetailEditorWithEntry:snippet];
+ }
}
+#pragma mark NSTableViewDelegate
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification {
- NSInteger selectedRow = [_tableView selectedRow];
- NSTableRowView *myRowView = [_tableView rowViewAtRow:selectedRow makeIfNecessary:NO];
- [myRowView setEmphasized:NO];
+// NSInteger selectedRow = [_tableView selectedRow];
+// NSTableRowView *myRowView = [_tableView rowViewAtRow:selectedRow makeIfNecessary:NO];
+// [myRowView setEmphasized:NO];
+}
+
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
+ if ([_searchKey ec_isNotEmpty]) {
+ _matchingList = _filteringList;
+ } else {
+ _matchingList = _snippetDoc.snippet.entries;
+ }
+ return [_matchingList count];
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
-
// Get a new ViewCell
NSTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
- EShortcutEntry* entry = _mappingList[row];
+ ECSnippetEntry* snippet = _matchingList[row];
if( [tableColumn.identifier isEqualToString:@"cShortcut"] )
{
- cellView.textField.stringValue = entry.key;
+ cellView.textField.stringValue = snippet.key;
return cellView;
}
if( [tableColumn.identifier isEqualToString:@"cCode"] )
{
- cellView.textField.stringValue = entry.code;
+ cellView.textField.stringValue = _STR(snippet.code);
cellView.textField.textColor = [NSColor colorWithWhite:0.5 alpha:1];
return cellView;
}
@@ -122,27 +320,45 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn
return cellView;
}
+- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row {
+ EEditorTableRowView* rowView = [[EEditorTableRowView alloc] initWithFrame:CGRectZero];
+ return rowView;
+}
-- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
- return [self.mappingList count];
+#pragma mark EEditorMenuDelegate
+-(void)menu:(EEditorTableMenu*)menu didSelectedItemWithTag:(NSInteger)tag {
+ if (_tableView.selectedRow == -1) {
+ return;
+ }
+
+ if (tag == 0) { //Edit
+ ECSnippetEntry* snippet = _matchingList[_tableView.selectedRow];
+ [self presentDetailEditorWithEntry:snippet];
+ }
+}
+
+- (void)presentDetailEditorWithEntry:(ECSnippetEntry*)snippet {
+ if (snippet == nil) {
+ return;
+ }
+
+ [self.detailEditor initWithEntry:snippet];
+ self.detailEditor.editMode = DetailEditorModeUpdate;
+ [self.detailEditor showWindow:self];
}
- (void)onEditCodeClick:(id)sender
{
NSButton* btn = sender;
NSInteger row = [_tableView rowForView:btn];
- EShortcutEntry* entry = _mappingList[row];
- if (entry) {
- [self.detailEditor initWithMappingEntry:entry];
- self.detailEditor.editMode = DetailEditorModeUpdate;
- [self.detailEditor showWindow:self];
- }
+ ECSnippetEntry* snippet = _matchingList[row];
+ [self presentDetailEditorWithEntry:snippet];
}
- (void)onAddEntryClick:(id)sender
{
- EShortcutEntry* entry = [EShortcutEntry new];
- [self.detailEditor initWithMappingEntry:entry];
+ ECSnippetEntry* entry = [ECSnippetEntry new];
+ [self.detailEditor initWithEntry:entry];
self.detailEditor.editMode = DetailEditorModeInsert;
[self.detailEditor showWindow:self];
}
@@ -151,79 +367,53 @@ - (void)onRemoveEntryClick:(id)sender
{
NSButton* btn = sender;
NSInteger row = [_tableView rowForView:btn];
- EShortcutEntry* entry = _mappingList[row];
- if (entry) {
- [_mappingList removeObject:entry];
- [self sortMappingList];
- [_tableView reloadData];
-
- [self saveMapping];
- }
+
+ NSAlert* alert = [NSAlert ec_alertWithStyle:NSAlertStyleWarning
+ messageText:NSLocalizedString(@"Entry_Delete_Message",nil)
+ informativeText:NSLocalizedString(@"Entry_Delete_Message_Explain",nil)
+ buttonTitle:NSLocalizedString(@"Button_OK_Title",nil),
+ NSLocalizedString(@"Button_Cancel_Title",nil),
+ nil];
+ [alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
+ if (returnCode == NSAlertFirstButtonReturn) { //OK
+ ECSnippetEntry* snippet = _matchingList[row];
+ [self onEntryRemoved:snippet];
+ }
+ }];
+
}
- (DetailWindowController*)detailEditor
{
if (_detailEditor == nil) {
- self.detailEditor = [[DetailWindowController alloc] initWithWindowNibName:@"DetailWindowController"];
+ _detailEditor = [[DetailWindowController alloc] initWithWindowNibName:@"DetailWindowController"];
_detailEditor.delegate = self;
}
return _detailEditor;
}
#pragma mark - DetailWindowEditorDelegate
-- (void)onEntryInserted:(EShortcutEntry*)entry {
- if (entry.key.length > 0 && entry.code.length > 0) {
- [_mappingList addObject:entry];
- [self sortMappingList];
- [_tableView reloadData];
-
- [self saveMapping];
- }
+- (void)snippetsDocument:(ECSnippetDocument*)document performActionWithType:(ECSnippetEntryActionType)actionType withEntry:(ECSnippetEntry*)entry {
+ [self reloadData];
}
-- (void)onEntryUpdated:(EShortcutEntry*)entry {
- [self sortMappingList];
- [_tableView reloadData];
-
- [self saveMapping];
+#pragma mark - DetailWindowEditorDelegate
+- (void)onSnippetInserted:(ECSnippetEntry*)entry {
+ [_snippetDoc addSnippetEntry:entry];
}
-- (void)windowWillClose:(NSNotification *)notification
-{
- [self saveMapping];
+- (void)onEntryRemoved:(ECSnippetEntry*)snippet {
+ [_snippetDoc removeSnippetEntryForKey:snippet.key];
}
-#pragma mark - Other
-- (void)saveMapping
-{
- NSMutableDictionary* newMapping = @{}.mutableCopy;
- for (EShortcutEntry* entry in _mappingList) {
- [newMapping setObject:entry.code forKey:entry.key];
- }
-
- if (_editorType == EditorTypeOC) {
- [_UD saveMappingForOC:newMapping];
- }
- else if(_editorType == EditorTypeSwift)
- {
- [_UD saveMappingForSwift:newMapping];
+- (void)onSnippetUpdated:(ECSnippetEntry*)snippet {
+ if ([_detailEditor hasEdited]) {
+ [_snippetDoc updateSnippetEntry:snippet];
}
}
-- (void)sortMappingList
-{
- if (_mappingList.count == 0) {
- EShortcutEntry* testEntry = [EShortcutEntry new];
- testEntry.key = @"key";
- testEntry.code = @"code";
- [_mappingList addObject:testEntry];
- }
-
- [_mappingList sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
- EShortcutEntry* entry1 = obj1;
- EShortcutEntry* entry2 = obj2;
- return [entry1.key compare:entry2.key];
- }];
+- (void)windowWillClose:(NSNotification *)notification {
+ [_snippetDoc saveDocumentCompletionHandler:NULL];
}
@end
diff --git a/EasyCode/MappingEditor/EditorWindowController.xib b/EasyCode/MappingEditor/EditorWindowController.xib
index e2c9945..958b6ef 100644
--- a/EasyCode/MappingEditor/EditorWindowController.xib
+++ b/EasyCode/MappingEditor/EditorWindowController.xib
@@ -1,14 +1,19 @@
-
+
-
+
+
+
+
+
+
@@ -17,33 +22,31 @@
-
-
+
+
-
+
-
-
-
+
+
-
-
-
+
+
-
+
-
-
+
+
-
-
+
+
@@ -56,13 +59,13 @@
-
+
-
-
+
+
-
+
@@ -75,8 +78,8 @@
-
-
+
+
@@ -89,13 +92,13 @@
-
+
-
-
+
+
-
+
@@ -108,8 +111,8 @@
-
-
+
+
@@ -122,7 +125,7 @@
-
-
+
+
@@ -145,7 +148,7 @@
-
-
+
+
@@ -168,7 +171,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -191,15 +207,66 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/EasyCode/Resource/Localizable.strings b/EasyCode/Resource/Localizable.strings
new file mode 100755
index 0000000..7913f5c
--- /dev/null
+++ b/EasyCode/Resource/Localizable.strings
@@ -0,0 +1,13 @@
+// errors
+"Search_Failed" = "Failed to start the search for documents in iCloud.";
+
+// log out alert
+"Logged_Out_Message" = "You have been using iCloud, but it has now become unavailable.";
+"Logged_Out_Message_Explain" = "Please check your network connection and make sure you are signed in.";
+"Button_OK_Title" = "OK";
+"Button_Cancel_Title" = "Cancel";
+"iCloud_Attention" = "Attention";
+"iCloud_Attention_Message" = "This will delete notes from your iCloud account. Are you sure?";
+
+"Entry_Delete_Message" = "Delete Entry";
+"Entry_Delete_Message_Explain" = "This will delete entry from your snippets lab. Are you sure?";
diff --git a/EasyCode/SharedLogic/ECDefine.h b/EasyCode/SharedLogic/ECDefine.h
new file mode 100644
index 0000000..3180228
--- /dev/null
+++ b/EasyCode/SharedLogic/ECDefine.h
@@ -0,0 +1,61 @@
+//
+// ECDefine.h
+// EasyCode
+//
+// Created by lijia on 07/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+#import "ECSafeCast.h"
+
+#ifndef ECDefine_H
+#define ECDefine_H
+
+#define kUseiCloudSync @"kUseiCloudSync"
+#define kVersionFormat @"%@-version"
+
+typedef NS_ENUM(NSInteger,ECSourceType) {
+ ECSourceTypeOC,
+ ECSourceTypeSwift
+};
+
+#define _STR(s) [ECSafeCast parseToString:s]
+#define _INT(s) [ECSafeCast parseToIntValue:s]
+#define _LONG(s) [ECSafeCast parseTolongValue:s]
+#define _BOOL(s) [ECSafeCast parseToBOOLValue:s]
+#define _FLOAT(s) [ECSafeCast parseToFloatValue:s]
+#define _NUMBER(s) [ECSafeCast parseToNumValue:s]
+#define _INTEGER(s) [ECSafeCast parseToIntegerValue:s]
+#define _LONGLONG(s) [ECSafeCast parseTolongLongValue:s]
+#define _DOUBLE(s) [ECSafeCast parseToDoubleValue:s]
+#define _ARRAY(s) [ECSafeCast parseToArray:s]
+#define _DIC(s) [ECSafeCast parseToDictionary:s]
+
+#define APP_OBJ [NSApplication sharedApplication]
+#define APP_DELEGATE ((AppDelegate *)[APP_OBJ delegate])
+
+#ifndef dispatch_main_sync_safe
+#define dispatch_main_sync_safe(block)\
+if ([NSThread isMainThread]) {\
+if(block){\
+block();\
+}\
+}\
+else {\
+if(block){\
+dispatch_sync(dispatch_get_main_queue(), block);\
+}\
+}
+#endif
+
+#ifndef dispatch_async_safe
+#define dispatch_async_safe(block) \
+dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block)
+#endif
+
+
+
+#endif /* ECDefine_H */
+
+
diff --git a/EasyCode/SharedLogic/ECSnippetHelper.h b/EasyCode/SharedLogic/ECSnippetHelper.h
new file mode 100644
index 0000000..14bb8a8
--- /dev/null
+++ b/EasyCode/SharedLogic/ECSnippetHelper.h
@@ -0,0 +1,20 @@
+//
+// ECSnippetHelper.h
+// EasyCode
+//
+// Created by lijia on 07/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+#import "ECSnippet.h"
+#import "ECDefine.h"
+
+@interface ECSnippetHelper : NSObject
++(ECSnippet*)snippetWithFileWrapper:(NSFileWrapper*)fileWrapper;
++(ECSnippet*)snippetWithSourceType:(ECSourceType)sourceType;
++(NSInteger)versionForSourceType:(ECSourceType)sourceType;
++(NSString*)directoryForSourceType:(ECSourceType)sourceType;
++(ECSourceType)sourceTypeForContentUTI:(NSString*)contentUTI;
++(ECSourceType)sourceTypeForDirectory:(NSString*)filename;
+@end
diff --git a/EasyCode/SharedLogic/ECSnippetHelper.m b/EasyCode/SharedLogic/ECSnippetHelper.m
new file mode 100644
index 0000000..f2f3b1d
--- /dev/null
+++ b/EasyCode/SharedLogic/ECSnippetHelper.m
@@ -0,0 +1,100 @@
+//
+// ECSnippetHelper.m
+// EasyCode
+//
+// Created by lijia on 07/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "ECSnippetHelper.h"
+#import "NSFileManager+Additions.h"
+#import "ECMappingForObjectiveC.h"
+#import "ECMappingForSwift.h"
+
+@implementation ECSnippetHelper
+
++(ECSourceType)sourceTypeForContentUTI:(NSString*)contentUTI {
+ if ([contentUTI isEqualToString:@"public.swift-source"]) {
+ return ECSourceTypeSwift;
+ } else {
+ return ECSourceTypeOC;
+ }
+}
+
++(NSString*)directoryForSourceType:(ECSourceType)sourceType {
+ if (sourceType == ECSourceTypeOC) {
+ return DirectoryOCName;
+ } else {
+ return DirectorySwiftName;
+ }
+}
+
++(ECSourceType)sourceTypeForDirectory:(NSString*)filename {
+ if ([filename isEqualToString:DirectoryOCName]) {
+ return ECSourceTypeOC;
+ } else {
+ return ECSourceTypeSwift;
+ }
+}
+
++(ECSnippet*)snippetWithFileWrapper:(NSFileWrapper*)fileWrapper {
+ NSString* filename = [fileWrapper filename];
+ NSDictionary *fileWrappers = [fileWrapper fileWrappers];
+ NSFileWrapper *snippetWrapper = [fileWrappers objectForKey:SnippetFileName];
+ if (snippetWrapper == nil) { //switch ubiquity to local
+ NSURL* fileURL = [[NSFileManager defaultManager] ec_localSnippetsURLWithFilename:filename];
+ fileWrapper = [[NSFileWrapper alloc] initWithURL:fileURL options:NSFileWrapperReadingWithoutMapping error:nil];
+ fileWrappers = [fileWrapper fileWrappers];
+ snippetWrapper = [fileWrappers objectForKey:SnippetFileName];
+ }
+ NSData* data = [snippetWrapper regularFileContents];
+ ECSnippet* snippet = nil;
+ if ([data length] > 0) {
+ snippet = [NSKeyedUnarchiver unarchiveObjectWithData:data];
+ if(snippet.entries.count==0){
+ NSArray* entries = nil;
+ if ([[fileWrapper filename] isEqualToString:DirectoryOCName]) {
+ entries = [ECMappingForObjectiveC defaultEntries];
+ } else {
+ entries = [ECMappingForSwift defaultEntries];
+ }
+ ECSourceType sourceType = [self sourceTypeForDirectory:filename];
+ snippet = [[ECSnippet alloc] initWithSourceType:sourceType entries:entries];
+ }
+
+ } else { //create from memory if local not exist
+ NSArray* entries = nil;
+ if ([[fileWrapper filename] isEqualToString:DirectoryOCName]) {
+ entries = [ECMappingForObjectiveC defaultEntries];
+ } else {
+ entries = [ECMappingForSwift defaultEntries];
+ }
+ ECSourceType sourceType = [self sourceTypeForDirectory:filename];
+ snippet = [[ECSnippet alloc] initWithSourceType:sourceType entries:entries];
+ }
+ return snippet;
+}
+
++(ECSnippet*)snippetWithSourceType:(ECSourceType)sourceType {
+ NSURL* fileURL = [[NSFileManager defaultManager] ec_detectURLForSourceType:sourceType];
+ NSFileWrapper* fileWrapper = [[NSFileWrapper alloc] initWithURL:fileURL
+ options:NSFileWrapperReadingWithoutMapping
+ error:nil];
+ ECSnippet* snippet = [self snippetWithFileWrapper:fileWrapper];
+ return snippet;
+}
+
++(NSInteger)versionForSourceType:(ECSourceType)sourceType {
+ NSURL* url = [[NSFileManager defaultManager] ec_detectURLForSourceType:sourceType];
+ NSFileWrapper* fileWrapper = [[NSFileWrapper alloc] initWithURL:url options:NSFileWrapperReadingWithoutMapping error:nil];
+ NSDictionary *fileWrappers = [fileWrapper fileWrappers];
+ NSFileWrapper *versionWrapper = [fileWrappers objectForKey:VersionFileName];
+ NSData* data = [versionWrapper regularFileContents];
+ NSInteger version = 0;
+ if ([data length] > 0) {
+ NSString* verStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ version = [verStr integerValue];
+ }
+ return version;
+}
+@end
diff --git a/EasyCode/SharedLogic/ESharedUserDefault.h b/EasyCode/SharedLogic/ESharedUserDefault.h
index 1a4e75b..2f0749f 100644
--- a/EasyCode/SharedLogic/ESharedUserDefault.h
+++ b/EasyCode/SharedLogic/ESharedUserDefault.h
@@ -8,18 +8,13 @@
#import
-#define _UD [ESharedUserDefault sharedInstance]
-
@interface ESharedUserDefault : NSObject
-
-+ (instancetype)sharedInstance;
-
-- (NSDictionary*)readMappingForOC;
-- (void)saveMappingForOC:(NSDictionary*)mapping;
-
-- (NSDictionary*)readMappingForSwift;
-- (void)saveMappingForSwift:(NSDictionary*)mapping;
-
-- (void)clearMapping;
-
++ (BOOL)boolForKey:(NSString*)key;
++ (id)objectForKey:(NSString*)key;
++ (id)dataForKey:(NSString*)key;
++ (id)stringForKey:(NSString*)key;
+
++ (void)setBool:(BOOL)value forKey:(NSString*)key;
++ (void)setObject:(NSObject*)value forKey:(NSString*)key;
++ (void)setObjects:(NSArray*)values forKeys:(NSArray*)keys;
@end
diff --git a/EasyCode/SharedLogic/ESharedUserDefault.m b/EasyCode/SharedLogic/ESharedUserDefault.m
index cc45970..a1b5126 100644
--- a/EasyCode/SharedLogic/ESharedUserDefault.m
+++ b/EasyCode/SharedLogic/ESharedUserDefault.m
@@ -10,23 +10,12 @@
#import "ECMappingForObjectiveC.h"
#import "ECMappingForSwift.h"
-#define KeySharedContainerGroup @"2WQE6AU5PD.group.com.music4kid.easycode"
-
-#define KeyCodeShortcutForObjectiveC @"KeyCodeShortcutForObjectiveC"
-#define KeyCodeShortcutForSwift @"KeyCodeShortcutForSwift"
-
-#define KeyCurrentUDVersion @"KeyCurrentUDVersion"
-#define ValueCurrentUDVersion @"1"
+#define KeySharedContainerGroup @"JW95CV255J.group.com.sito.easycode"
+#define KeyCurrentUDVersion @"KeyCurrentUDVersion"
+#define ValueCurrentUDVersion @"1"
@interface ESharedUserDefault ()
@property (nonatomic, strong) NSUserDefaults* sharedUD;
-
-@property (nonatomic, strong) NSDictionary* ocMappingDefault;
-@property (nonatomic, strong) NSDictionary* swiftMappingDefault;
-
-@property (nonatomic, strong) NSMutableDictionary* ocMapping;
-@property (nonatomic, strong) NSMutableDictionary* swiftMapping;
-
@end
@implementation ESharedUserDefault
@@ -37,7 +26,7 @@ + (instancetype)sharedInstance
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
- instance = [ESharedUserDefault new];
+ instance = [[ESharedUserDefault alloc] init];
});
return instance;
@@ -47,7 +36,6 @@ - (instancetype)init
{
self = [super init];
if (self) {
-
[self initSharedUD];
}
return self;
@@ -55,91 +43,62 @@ - (instancetype)init
- (void)initSharedUD
{
- self.sharedUD = [[NSUserDefaults alloc] initWithSuiteName:KeySharedContainerGroup];
- if ([_sharedUD objectForKey:KeyCurrentUDVersion] == nil) {
+ _sharedUD = [[NSUserDefaults alloc] initWithSuiteName:KeySharedContainerGroup];
+ NSString* UIVersion = [_sharedUD objectForKey:KeyCurrentUDVersion];
+ if (UIVersion == nil) {
[_sharedUD setObject:ValueCurrentUDVersion forKey:KeyCurrentUDVersion];
}
}
-- (void)clearMapping
++ (BOOL)boolForKey:(NSString*)key
{
- _ocMapping = nil;
- _swiftMapping = nil;
+ NSUserDefaults* shareUD = [[ESharedUserDefault sharedInstance] sharedUD];
+ return [shareUD boolForKey:key];
}
-#pragma mark - Objective-C
-
-- (NSDictionary*)readMappingForOC
++ (id)objectForKey:(NSString*)key
{
- if (_ocMapping == nil) {
- _ocMapping = [_sharedUD dictionaryForKey:KeyCodeShortcutForObjectiveC].mutableCopy;
-
- BOOL isMappingEmpty = false;
- if (_ocMapping == nil || (_ocMapping.allKeys.count == 1 && [_ocMapping[@"key"] isEqualToString:@"code"])) {
- isMappingEmpty = true;
- }
-
- if (isMappingEmpty == true) {
- _ocMapping = self.ocMappingDefault.mutableCopy;
- [self saveMappingForOC:self.ocMappingDefault];
- }
- }
-
- return _ocMapping;
+ NSUserDefaults* shareUD = [[ESharedUserDefault sharedInstance] sharedUD];
+ return [shareUD objectForKey:key];
}
-- (void)saveMappingForOC:(NSDictionary*)mapping
-{
- if (mapping.allKeys.count == 0 || mapping.allKeys.count == 1) {
- return;
- }
- self.ocMapping = mapping.mutableCopy;
- [_sharedUD setObject:mapping forKey:KeyCodeShortcutForObjectiveC];
- [_sharedUD synchronize];
++ (id)dataForKey:(NSString*)key {
+ NSUserDefaults* shareUD = [[ESharedUserDefault sharedInstance] sharedUD];
+ return [shareUD dataForKey:key];
}
-- (NSDictionary*)ocMappingDefault
-{
- if (_ocMappingDefault == nil) {
- _ocMappingDefault = [[ECMappingForObjectiveC new] provideMapping];
- }
- return _ocMappingDefault;
++ (id)stringForKey:(NSString*)key {
+ NSUserDefaults* shareUD = [[ESharedUserDefault sharedInstance] sharedUD];
+ return [shareUD stringForKey:key];
}
-#pragma mark - Swift
-
-- (NSDictionary*)readMappingForSwift
++ (void)setBool:(BOOL)value forKey:(NSString*)key
{
- if (_swiftMapping == nil) {
- _swiftMapping = [_sharedUD dictionaryForKey:KeyCodeShortcutForSwift].mutableCopy;
-
- BOOL isMappingEmpty = false;
- if (_ocMapping == nil || (_ocMapping.allKeys.count == 1 && [_ocMapping[@"key"] isEqualToString:@"code"])) {
- isMappingEmpty = true;
- }
-
- if (isMappingEmpty) {
- _swiftMapping = self.swiftMappingDefault.mutableCopy;
- [self saveMappingForOC:self.swiftMappingDefault];
- }
- }
-
- return _swiftMapping;
+ NSUserDefaults* shareUD = [[ESharedUserDefault sharedInstance] sharedUD];
+ [shareUD setBool:value forKey:key];
+ [shareUD synchronize];
}
-- (void)saveMappingForSwift:(NSDictionary*)mapping
++ (void)setObject:(NSObject*)value forKey:(NSString*)key
{
- self.swiftMapping = mapping.mutableCopy;
- [_sharedUD setObject:mapping forKey:KeyCodeShortcutForSwift];
- [_sharedUD synchronize];
+ NSUserDefaults* shareUD = [[ESharedUserDefault sharedInstance] sharedUD];
+ [shareUD setObject:value forKey:key];
+ [shareUD synchronize];
}
-- (NSDictionary*)swiftMappingDefault
++ (void)setObjects:(NSArray*)values forKeys:(NSArray*)keys
{
- if (_swiftMappingDefault == nil) {
- _swiftMappingDefault = [[ECMappingForSwift new] provideMapping];
+ if (keys.count != values.count) {
+ return;
}
- return _swiftMappingDefault;
-}
+ NSUserDefaults* shareUD = [[ESharedUserDefault sharedInstance] sharedUD];
+ [keys enumerateObjectsUsingBlock:^(NSString* _Nonnull key, NSUInteger idx, BOOL * _Nonnull stop) {
+ [shareUD setObject:values[idx] forKey:key];
+ }];
+ BOOL success = [shareUD synchronize];
+ if (!success) {
+ NSLog(@"synchronize error");
+ }
+}
@end
diff --git a/EasyCode/MappingEditor/CustomButton.h b/EasyCode/UI/ECustomButton.h
similarity index 72%
rename from EasyCode/MappingEditor/CustomButton.h
rename to EasyCode/UI/ECustomButton.h
index 09b7dc8..7ae26b5 100644
--- a/EasyCode/MappingEditor/CustomButton.h
+++ b/EasyCode/UI/ECustomButton.h
@@ -1,5 +1,5 @@
//
-// CustomButton.h
+// ECustomButton.h
// EasyCode
//
// Created by gao feng on 2016/11/4.
@@ -8,6 +8,6 @@
#import
-@interface CustomButton : NSButton
+@interface ECustomButton : NSButton
@end
diff --git a/EasyCode/MappingEditor/CustomButton.m b/EasyCode/UI/ECustomButton.m
similarity index 65%
rename from EasyCode/MappingEditor/CustomButton.m
rename to EasyCode/UI/ECustomButton.m
index c7cf9b6..19da4f8 100644
--- a/EasyCode/MappingEditor/CustomButton.m
+++ b/EasyCode/UI/ECustomButton.m
@@ -1,19 +1,17 @@
//
-// CustomButton.m
+// ECustomButton.m
// EasyCode
//
// Created by gao feng on 2016/11/4.
// Copyright © 2016年 music4kid. All rights reserved.
//
-#import "CustomButton.h"
+#import "ECustomButton.h"
-@implementation CustomButton
+@implementation ECustomButton
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
-
- // Drawing code here.
}
@end
diff --git a/EasyCode/UI/EEditorTableMenu.h b/EasyCode/UI/EEditorTableMenu.h
new file mode 100644
index 0000000..1b08755
--- /dev/null
+++ b/EasyCode/UI/EEditorTableMenu.h
@@ -0,0 +1,19 @@
+//
+// EEditorTableMenu.h
+// EasyCode
+//
+// Created by lijia on 20/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+@protocol EEditorMenuDelegate;
+
+@interface EEditorTableMenu : NSMenu
+@property (nonatomic, weak) id editorDelegate;
+@property (nonatomic, readonly,copy) NSArray* itemsTitle;
+@end
+
+@protocol EEditorMenuDelegate
+-(void)menu:(EEditorTableMenu*)menu didSelectedItemWithTag:(NSInteger)tag;
+@end
diff --git a/EasyCode/UI/EEditorTableMenu.m b/EasyCode/UI/EEditorTableMenu.m
new file mode 100644
index 0000000..c276fd7
--- /dev/null
+++ b/EasyCode/UI/EEditorTableMenu.m
@@ -0,0 +1,41 @@
+//
+// EEditorTableMenu.m
+// EasyCode
+//
+// Created by lijia on 20/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "EEditorTableMenu.h"
+@interface EEditorTableMenu ()
+
+@end
+
+
+@implementation EEditorTableMenu
+
+- (instancetype)initWithTitle:(NSString*)title
+{
+ self = [super initWithTitle:title];
+ if (self) {
+ _itemsTitle = @[@"Edit "];
+ NSInteger index = 0;
+ for (NSString* itemTitle in _itemsTitle) {
+ NSMenuItem* item = [self addItemWithTitle:itemTitle action:@selector(onMenuItemSelected:) keyEquivalent:@""];
+ item.target = self;
+ item.tag = index++;
+ }
+ [self addItem:[NSMenuItem separatorItem]];
+ }
+ return self;
+}
+
+- (void)onMenuItemSelected:(NSMenuItem*)item {
+ if (_editorDelegate) {
+ if ([_editorDelegate respondsToSelector:@selector(menu:didSelectedItemWithTag:)]) {
+ [_editorDelegate menu:self didSelectedItemWithTag:item.tag];
+ }
+ }
+}
+
+@end
diff --git a/EasyCode/UI/EEditorTableRowView.h b/EasyCode/UI/EEditorTableRowView.h
new file mode 100644
index 0000000..dec4511
--- /dev/null
+++ b/EasyCode/UI/EEditorTableRowView.h
@@ -0,0 +1,13 @@
+//
+// EEditorTableRowView.h
+// EasyCode
+//
+// Created by lijia on 20/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import
+
+@interface EEditorTableRowView : NSTableRowView
+
+@end
diff --git a/EasyCode/UI/EEditorTableRowView.m b/EasyCode/UI/EEditorTableRowView.m
new file mode 100644
index 0000000..5d1b151
--- /dev/null
+++ b/EasyCode/UI/EEditorTableRowView.m
@@ -0,0 +1,22 @@
+//
+// EEditorTableRowView.m
+// EasyCode
+//
+// Created by lijia on 20/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#import "EEditorTableRowView.h"
+
+@implementation EEditorTableRowView
+- (void)drawSelectionInRect:(NSRect)dirtyRect {
+ if (self.selectionHighlightStyle != NSTableViewSelectionHighlightStyleNone) {
+ NSRect selectionRect = NSInsetRect(self.bounds, 0, 0);
+// [[NSColor colorWithCalibratedWhite:.65 alpha:1.0] setStroke];
+ [[NSColor lightGrayColor] setFill];
+ NSBezierPath *selectionPath = [NSBezierPath bezierPathWithRoundedRect:selectionRect xRadius:0 yRadius:0];
+ [selectionPath fill];
+ [selectionPath stroke];
+ }
+}
+@end
diff --git a/EasyCode/MappingEditor/EEditorTableView.h b/EasyCode/UI/EEditorTableView.h
similarity index 100%
rename from EasyCode/MappingEditor/EEditorTableView.h
rename to EasyCode/UI/EEditorTableView.h
diff --git a/EasyCode/UI/EEditorTableView.m b/EasyCode/UI/EEditorTableView.m
new file mode 100644
index 0000000..e176c64
--- /dev/null
+++ b/EasyCode/UI/EEditorTableView.m
@@ -0,0 +1,27 @@
+//
+// EEditorTableView.m
+// EasyCode
+//
+// Created by gao feng on 2016/10/20.
+// Copyright © 2016年 music4kid. All rights reserved.
+//
+
+#import "EEditorTableView.h"
+#import "EEditorTableMenu.h"
+
+@implementation EEditorTableView
+-(NSMenu*)menuForEvent:(NSEvent*)event {
+ [[self window] makeFirstResponder:self];
+ NSPoint menuPoint = [self convertPoint:[event locationInWindow] fromView:nil];
+ NSInteger row = [self rowAtPoint:menuPoint];
+ if (row != -1) {
+ NSIndexSet* indexSet = [NSIndexSet indexSetWithIndex:row];
+ [self selectRowIndexes:indexSet byExtendingSelection:NO];
+ return [self menu];
+ } else {
+ return [super menu];
+ }
+}
+
+
+@end
diff --git a/EasyCode/MappingEditor/EVerticalScrollView.h b/EasyCode/UI/EVerticalScrollView.h
similarity index 100%
rename from EasyCode/MappingEditor/EVerticalScrollView.h
rename to EasyCode/UI/EVerticalScrollView.h
diff --git a/EasyCode/MappingEditor/EVerticalScrollView.m b/EasyCode/UI/EVerticalScrollView.m
similarity index 100%
rename from EasyCode/MappingEditor/EVerticalScrollView.m
rename to EasyCode/UI/EVerticalScrollView.m
diff --git a/EasyCode/Utility/ECSafeCast.h b/EasyCode/Utility/ECSafeCast.h
new file mode 100644
index 0000000..4fea369
--- /dev/null
+++ b/EasyCode/Utility/ECSafeCast.h
@@ -0,0 +1,28 @@
+//
+// ECSafeCast.h
+// EasyCode
+//
+// Created by li on 10/8/15.
+// Copyright © 2015 hh.changhong.com. All rights reserved.
+//
+
+#import
+
+@interface ECSafeCast : NSObject
+
++ (NSString *)parseToString:(id)parse;
++ (float)parseToFloatValue:(id)parse;
+
++ (int)parseToIntValue:(id)parse;
++ (long long)parseTolongLongValue:(id)parse;
++ (long)parseTolongValue:(id)parse;
++ (NSInteger)parseToIntegerValue:(id)parse;
+
++ (BOOL)parseToBOOLValue:(id)parse;
++ (double)parseToDoubleValue:(id)parse;
++ (NSNumber *)parseToNumValue:(id)parse;
++ (NSArray *)parseToArray:(id)parse;
++ (NSDictionary *)parseToDictionary:(id)parse;
+
+
+@end
diff --git a/EasyCode/Utility/ECSafeCast.m b/EasyCode/Utility/ECSafeCast.m
new file mode 100644
index 0000000..fb2cfa3
--- /dev/null
+++ b/EasyCode/Utility/ECSafeCast.m
@@ -0,0 +1,180 @@
+//
+// ECSafeCast.m
+// testImage
+//
+// Created by li on 10/8/15.
+// Copyright © 2015 hh.changhong.com. All rights reserved.
+//
+
+#import "ECSafeCast.h"
+
+@implementation ECSafeCast
+
++ (NSString *)parseToString:(id)parse
+{
+ if (!parse) {
+ return @"";
+ }
+ if ([parse isKindOfClass:[NSString class]]) {
+ return parse;
+ }
+ else if([parse isKindOfClass:[NSNumber class]])
+ {
+ return [NSString stringWithFormat:@"%@",parse];
+ }
+ else
+ return [NSString stringWithFormat:@"%@",parse];
+
+}
+
++ (NSNumber *)parseToNumValue:(id)parse
+{
+ if (!parse) {
+ return @(0);
+ }
+ if ([parse isKindOfClass:[NSString class]]) {
+ return [NSNumber numberWithDouble:[parse doubleValue]];
+ }
+ else if([parse isKindOfClass:[NSNumber class]])
+ {
+ return parse;
+ }
+ else
+ return @(0);
+}
+
+
++ (double)parseToDoubleValue:(id)parse
+{
+ if (!parse) {
+ return 0;
+ }
+ if ([parse isKindOfClass:[NSString class]]) {
+ return [(NSString*)parse doubleValue];
+ }
+ else if([parse isKindOfClass:[NSNumber class]])
+ {
+ return [(NSNumber*)parse doubleValue];
+ }
+ else
+ return 0;
+}
+
+
++ (BOOL)parseToBOOLValue:(id)parse
+{
+ if (!parse) {
+ return false;
+ }
+ if ([parse isKindOfClass:[NSString class]]) {
+ return [(NSString*)parse boolValue];
+ }
+ else if([parse isKindOfClass:[NSNumber class]])
+ {
+ return [(NSNumber*)parse boolValue];
+ }
+ else
+ return false;
+}
+
++ (NSInteger)parseToIntegerValue:(id)parse
+{
+ if (!parse) {
+ return 0;
+ }
+ if ([parse isKindOfClass:[NSString class]]) {
+ return [(NSString*)parse integerValue];
+ }
+ else if([parse isKindOfClass:[NSNumber class]])
+ {
+ return [(NSNumber*)parse integerValue];
+ }
+ else
+ return 0;
+}
+
++ (long long)parseTolongLongValue:(id)parse
+{
+ if (!parse) {
+ return 0;
+ }
+ if ([parse isKindOfClass:[NSString class]]) {
+ return [(NSString*)parse longLongValue];
+ }
+ else if([parse isKindOfClass:[NSNumber class]])
+ {
+ return [(NSNumber*)parse longLongValue];
+ }
+ else
+ return 0;
+}
+
++ (long)parseTolongValue:(id)parse
+{
+ if (!parse) {
+ return 0;
+ }
+ if ([parse isKindOfClass:[NSString class]]) {
+ return (long)[(NSString*)parse longLongValue];
+ }
+ else if([parse isKindOfClass:[NSNumber class]])
+ {
+ return [(NSNumber*)parse longValue];
+ }
+ else
+ return 0;
+}
+
++ (float)parseToFloatValue:(id)parse
+{
+ if (!parse) {
+ return 0;
+ }
+ if ([parse isKindOfClass:[NSString class]]) {
+ return [(NSString*)parse floatValue];
+ }
+ else if([parse isKindOfClass:[NSNumber class]])
+ {
+ return [(NSNumber*)parse floatValue];
+ }
+ else
+ return 0;
+}
+
++ (int)parseToIntValue:(id)parse
+{
+ if (!parse) {
+ return 0;
+ }
+ if ([parse isKindOfClass:[NSString class]]) {
+ return [(NSString*)parse intValue];
+ }
+ else if([parse isKindOfClass:[NSNumber class]])
+ {
+ return [(NSNumber*)parse intValue];
+ }
+ else
+ return 0;
+}
+
++ (NSArray *)parseToArray:(id)parse;
+{
+ if (!parse) {
+ return @[];
+ }
+ if ([parse isKindOfClass:[NSArray class]]) {
+ return parse;
+ }
+ else
+ return @[];
+}
+
++ (NSDictionary *)parseToDictionary:(id)parse
+{
+ if (parse && [parse isKindOfClass:[NSDictionary class]]) {
+ return parse;
+ }
+ return @{};
+}
+
+@end
diff --git a/EasyCode/easycode.pch b/EasyCode/easycode.pch
new file mode 100644
index 0000000..1eba6f4
--- /dev/null
+++ b/EasyCode/easycode.pch
@@ -0,0 +1,20 @@
+//
+// easycode.h
+// EasyCode
+//
+// Created by lijia on 03/03/2017.
+// Copyright © 2017 music4kid. All rights reserved.
+//
+
+#if defined(__cplusplus)
+#define EC_EXTERN extern "C"
+#else
+#define EC_EXTERN extern
+#endif
+
+#import "ECDefine.h"
+#import "AppDelegate.h"
+#import "NSString+Additions.h"
+#import "NSFileManager+Additions.h"
+#import "NSAlert+Additions.h"
+#import "ESharedUserDefault.h"