aboutsummaryrefslogtreecommitdiff
path: root/QSThingsPlugin
diff options
context:
space:
mode:
Diffstat (limited to 'QSThingsPlugin')
-rw-r--r--QSThingsPlugin/Core Extensions/NSImage+Badge.h18
-rw-r--r--QSThingsPlugin/Core Extensions/NSImage+Badge.m64
-rw-r--r--QSThingsPlugin/Handlers/ThingsAppSectionHandler.h14
-rw-r--r--QSThingsPlugin/Handlers/ThingsAppSectionHandler.m190
-rw-r--r--QSThingsPlugin/Handlers/ThingsAreaHandler.h13
-rw-r--r--QSThingsPlugin/Handlers/ThingsAreaHandler.m124
-rw-r--r--QSThingsPlugin/Handlers/ThingsTagHandler.h14
-rw-r--r--QSThingsPlugin/Handlers/ThingsTagHandler.m134
-rw-r--r--QSThingsPlugin/Handlers/ThingsTaskHandler.h14
-rw-r--r--QSThingsPlugin/Handlers/ThingsTaskHandler.m165
-rw-r--r--QSThingsPlugin/Helpers/ObjectHelper.h18
-rw-r--r--QSThingsPlugin/Helpers/ObjectHelper.m58
-rw-r--r--QSThingsPlugin/Helpers/SQLHelper.m2
-rw-r--r--QSThingsPlugin/Helpers/ThingsHelper.h1
-rw-r--r--QSThingsPlugin/Helpers/ThingsHelper.m9
-rw-r--r--QSThingsPlugin/Parsers/QSThingsAppSectionsParser.m6
-rw-r--r--QSThingsPlugin/Parsers/QSThingsAreasParser.h4
-rw-r--r--QSThingsPlugin/Parsers/QSThingsAreasParser.m11
-rw-r--r--QSThingsPlugin/Parsers/QSThingsProjectsParser.h4
-rw-r--r--QSThingsPlugin/Parsers/QSThingsProjectsParser.m12
-rw-r--r--QSThingsPlugin/Parsers/QSThingsTagsParser.h4
-rw-r--r--QSThingsPlugin/Parsers/QSThingsTagsParser.m11
-rw-r--r--QSThingsPlugin/Parsers/QSThingsTasksParser.h3
-rw-r--r--QSThingsPlugin/Parsers/QSThingsTasksParser.m13
24 files changed, 852 insertions, 54 deletions
diff --git a/QSThingsPlugin/Core Extensions/NSImage+Badge.h b/QSThingsPlugin/Core Extensions/NSImage+Badge.h
new file mode 100644
index 0000000..0882620
--- /dev/null
+++ b/QSThingsPlugin/Core Extensions/NSImage+Badge.h
@@ -0,0 +1,18 @@
+//
+// NSImage+NSImage_Badges.h
+// Things Plugin
+//
+// Created by Ruben Beltran del Rio on 2025-09-12.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NSImage (Badge)
+
+- (NSImage *)imageOfSize:(NSSize)size withSystemBadge:(NSString *)symbolName ofColor:(NSColor *)color;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Core Extensions/NSImage+Badge.m b/QSThingsPlugin/Core Extensions/NSImage+Badge.m
new file mode 100644
index 0000000..e5a2bf1
--- /dev/null
+++ b/QSThingsPlugin/Core Extensions/NSImage+Badge.m
@@ -0,0 +1,64 @@
+//
+// NSImage+NSImage_Badges.h
+// Things Plugin
+//
+// Created by Ruben Beltran del Rio on 2025-09-12.
+//
+
+#import "NSImage+Badge.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation NSImage (Badge)
+
+- (NSImage *)imageOfSize:(NSSize)size withSystemBadge:(NSString *)symbolName ofColor:(NSColor *)color{
+ if (@available(macOS 12.0, *)) {
+ NSImageRep *baseRep = [self bestRepresentationForRect:NSMakeRect(0, 0, size.width, size.height)
+ context:nil
+ hints:nil];
+
+ NSImage *badgeImage = [NSImage imageWithSystemSymbolName:symbolName
+ accessibilityDescription:nil];
+ [badgeImage setTemplate:YES];
+ NSArray *colors = [NSArray arrayWithObjects:color, nil];
+ NSImageSymbolConfiguration *iconConfig = [NSImageSymbolConfiguration configurationWithPaletteColors:colors];
+
+ // Create composite image at the requested size
+ NSImage *compositImage = [[NSImage alloc] initWithSize:size];
+
+ [compositImage lockFocus];
+
+ // Draw the base image
+ [baseRep drawInRect:NSMakeRect(0, 0, size.width, size.height)];
+
+ // Calculate badge position (bottom right corner)
+ CGFloat badgeSize = size.width * 0.4;
+ CGFloat badgeX = size.width - badgeSize;
+ CGFloat badgeY = 0;
+ NSRect badgeRect = NSMakeRect(badgeX, badgeY, badgeSize, badgeSize);
+
+ // Draw white circle background
+ [[NSColor whiteColor] setFill];
+ NSBezierPath *circlePath = [NSBezierPath bezierPathWithOvalInRect:badgeRect];
+ [circlePath fill];
+
+ // Draw the SF Symbol in blue
+ [[NSColor blueColor] setFill];
+ [[badgeImage imageWithSymbolConfiguration:iconConfig] drawInRect:badgeRect];
+
+ [compositImage unlockFocus];
+
+ // Preserve template status if applicable
+ if ([self isTemplate]) {
+ [compositImage setTemplate:YES];
+ }
+
+ return compositImage;
+ } else {
+ return nil;
+ }
+
+}
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Handlers/ThingsAppSectionHandler.h b/QSThingsPlugin/Handlers/ThingsAppSectionHandler.h
new file mode 100644
index 0000000..6fc3f35
--- /dev/null
+++ b/QSThingsPlugin/Handlers/ThingsAppSectionHandler.h
@@ -0,0 +1,14 @@
+#import "Constants.h"
+#import "SQLHelper.h"
+#import "ObjectHelper.h"
+#import "NSImage+Badge.h"
+#import <Foundation/Foundation.h>
+#import <QSCore/QSCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface ThingsAppSectionHandler : NSObject <QSObjectHandler>
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Handlers/ThingsAppSectionHandler.m b/QSThingsPlugin/Handlers/ThingsAppSectionHandler.m
new file mode 100644
index 0000000..0f294fc
--- /dev/null
+++ b/QSThingsPlugin/Handlers/ThingsAppSectionHandler.m
@@ -0,0 +1,190 @@
+#import "ThingsAppSectionHandler.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation ThingsAppSectionHandler
+
+- (BOOL)objectHasChildren:(QSObject *)object {
+ return YES;
+}
+
+- (void)setQuickIconForObject:(QSObject *)object {
+ NSImage *baseImage = [QSResourceManager imageNamed:@"com.culturedcode.ThingsMac"];
+
+ ThingsAppSectionKey identifier = [object identifier];
+ NSImage *imageWithBadge = nil;
+ if (identifier == ThingsAppSectionKeyInbox) {
+ NSColor *color = [NSColor colorWithRed:0.318 green:0.667 blue:0.949 alpha:1.0];
+ imageWithBadge = [baseImage imageOfSize:NSMakeSize(512, 512) withSystemBadge:@"tray.circle" ofColor:color];
+ }
+ if (identifier == ThingsAppSectionKeyToday) {
+ NSColor *color = [NSColor colorWithRed:0.973 green:0.839 blue:0.282 alpha:1.0];
+ imageWithBadge = [baseImage imageOfSize:NSMakeSize(512, 512) withSystemBadge:@"star.circle" ofColor:color];
+ }
+ if (identifier == ThingsAppSectionKeyAnytime) {
+ NSColor *color = [NSColor colorWithRed:0.353 green:0.651 blue:0.616 alpha:1.0];
+ imageWithBadge = [baseImage imageOfSize:NSMakeSize(512, 512) withSystemBadge:@"diamond.circle" ofColor:color];
+ }
+ if (identifier == ThingsAppSectionKeySomeday) {
+ NSColor *color = [NSColor colorWithRed:0.792 green:0.749 blue:0.525 alpha:1.0];
+ imageWithBadge = [baseImage imageOfSize:NSMakeSize(512, 512) withSystemBadge:@"archivebox.circle" ofColor:color];
+ }
+ if (identifier == ThingsAppSectionKeyUpcoming) {
+ NSColor *color = [NSColor colorWithRed:0.902 green:0.224 blue:0.349 alpha:1.0];
+ imageWithBadge = [baseImage imageOfSize:NSMakeSize(512, 512) withSystemBadge:@"calendar.circle" ofColor:color];
+ }
+
+ if (imageWithBadge) {
+ [object setIcon:imageWithBadge];
+ } else {
+ [object setIcon:baseImage];
+ }
+}
+
+- (BOOL)loadChildrenForObject:(QSObject *)object {
+ NSDictionary *contents = [object objectForType:kAppSectionType];
+
+ if (!contents) {
+ NSLog(@"Malformed Things Task: No content.");
+ return NO;
+ }
+
+ NSString *path = [contents objectForKey:@"path"];
+ if (!path) {
+ NSLog(@"Malformed Things Task: No path.");
+ return NO;
+ }
+
+ ThingsAppSectionKey appSection = [object identifier];
+ if (!appSection) {
+ NSLog(@"Malformed Things App Section: No identifier.");
+ return NO;
+ }
+
+ NSMutableArray *children = [NSMutableArray array];
+ [children addObjectsFromArray:[self tasksForAppSection:appSection usingDatabaseAt:path ]];
+ [children addObjectsFromArray:[self projectsForAppSection:appSection usingDatabaseAt:path ]];
+
+ [object setChildren:children];
+ return YES;
+}
+
+- (NSArray *)projectsForAppSection:(ThingsAppSectionKey)appSection usingDatabaseAt:(NSString *)path {
+
+ NSString *conditions = [self conditionsFor:appSection];
+
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "task.uuid AS uuid, "
+ "task.creationDate AS creationDate, "
+ "task.status AS status, "
+ "task.title AS title, "
+ "task.notes AS notes, "
+ "task.area AS area "
+ "FROM TMTask as task "
+ "LEFT JOIN TMTask AS project "
+ "ON task.project = project.uuid "
+ "LEFT JOIN TMTask AS heading "
+ "ON task.heading = heading.uuid "
+ "LEFT JOIN TMTask AS headingProject "
+ "ON heading.project = headingProject.uuid "
+ "WHERE task.type = 1 "
+ "AND task.trashed = 0 "
+ "AND task.status = 0 "
+ "%@"
+ "GROUP BY task.uuid "
+ "ORDER BY title;", conditions];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ NSLog(@"WE PROJECTIN!");
+ [objects addObject:[ObjectHelper projectFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+- (NSArray *)tasksForAppSection:(ThingsAppSectionKey)appSection usingDatabaseAt:(NSString *)path {
+
+ NSString *conditions = [self conditionsFor:appSection];
+
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "task.uuid AS uuid, "
+ "task.creationDate AS creationDate, "
+ "task.status AS status, "
+ "task.title AS title, "
+ "task.notes AS notes, "
+ "task.area AS area "
+ "FROM TMTask as task "
+ "LEFT JOIN TMTask AS project "
+ "ON task.project = project.uuid "
+ "LEFT JOIN TMTask AS heading "
+ "ON task.heading = heading.uuid "
+ "LEFT JOIN TMTask AS headingProject "
+ "ON heading.project = headingProject.uuid "
+ "WHERE task.type = 0 "
+ "AND task.trashed = 0 "
+ "AND task.status = 0 "
+ "%@"
+ "GROUP BY task.uuid "
+ "ORDER BY title;", conditions];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper taskFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+- (NSString *)conditionsFor:(ThingsAppSectionKey)appSection {
+ if (appSection == ThingsAppSectionKeyInbox) {
+ return @"AND task.startDate IS NULL "
+ "AND task.area IS NULL "
+ "AND task.project IS NULL "
+ "AND task.heading IS NULL ";
+ }
+ if (appSection == ThingsAppSectionKeyToday) {
+ return @"AND task.todayIndexReferenceDate IS NOT NULL "
+ "AND task.todayIndex <= 0 ";
+ }
+ if (appSection == ThingsAppSectionKeyUpcoming) {
+ return @"AND task.todayIndexReferenceDate IS NOT NULL "
+ "AND task.todayIndex > 0 ";
+ }
+ if (appSection == ThingsAppSectionKeySomeday) {
+ return @"AND task.start=2 "
+ "AND task.startDate IS NULL "
+ "AND task.rt1_instanceCreationStartDate IS NULL ";
+ }
+ if (appSection == ThingsAppSectionKeyAnytime) {
+ return @"AND ( "
+ "( "
+ "task.todayIndexReferenceDate IS NOT NULL "
+ "AND task.todayIndex <= 0 "
+ ") "
+ "OR ( "
+ "task.startDate IS NULL AND "
+ "task.start=1 AND "
+ "task.rt1_instanceCreationStartDate IS NULL "
+ "AND ( "
+ "task.area IS NOT NULL "
+ "OR task.project IS NOT NULL "
+ "OR task.heading IS NOT NULL "
+ ") "
+ "AND project.todayIndexReferenceDate IS NULL "
+ "AND (project.start=1 OR headingProject.start IS NULL) "
+ "AND heading.todayIndexReferenceDate IS NULL "
+ "AND (heading.start=1 OR headingProject.start IS NULL) "
+ "AND headingProject.todayIndexReferenceDate IS NULL "
+ "AND (headingProject.start=1 OR headingProject.start IS NULL) "
+ ") "
+ ") ";
+ }
+}
+
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Handlers/ThingsAreaHandler.h b/QSThingsPlugin/Handlers/ThingsAreaHandler.h
new file mode 100644
index 0000000..14dd5ad
--- /dev/null
+++ b/QSThingsPlugin/Handlers/ThingsAreaHandler.h
@@ -0,0 +1,13 @@
+#import "Constants.h"
+#import "SQLHelper.h"
+#import "ObjectHelper.h"
+#import "NSImage+Badge.h"
+#import <Foundation/Foundation.h>
+#import <QSCore/QSCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface ThingsAreaHandler : NSObject <QSObjectHandler>
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Handlers/ThingsAreaHandler.m b/QSThingsPlugin/Handlers/ThingsAreaHandler.m
new file mode 100644
index 0000000..6619a0e
--- /dev/null
+++ b/QSThingsPlugin/Handlers/ThingsAreaHandler.m
@@ -0,0 +1,124 @@
+#import "ThingsAreaHandler.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation ThingsAreaHandler
+
+- (BOOL)objectHasChildren:(QSObject *)object {
+ return YES;
+}
+
+- (void)setQuickIconForObject:(QSObject *)object {
+ NSImage *baseImage = [QSResourceManager imageNamed:@"com.culturedcode.ThingsMac"];
+ NSColor *color = [NSColor colorWithRed:0.478 green:0.702 blue:0.584 alpha:1.0];
+ NSImage *imageWithBadge = [baseImage imageOfSize:NSMakeSize(512, 512) withSystemBadge:@"cube.circle" ofColor:color];
+
+ if (imageWithBadge) {
+ [object setIcon:imageWithBadge];
+ } else {
+ [object setIcon:baseImage];
+ }
+}
+
+- (BOOL)loadChildrenForObject:(QSObject *)object {
+ NSDictionary *contents = [object objectForType:kAreaType];
+
+ if (!contents) {
+ NSLog(@"Malformed Things Task: No content.");
+ return NO;
+ }
+
+ NSString *path = [contents objectForKey:@"path"];
+ if (!path) {
+ NSLog(@"Malformed Things Task: No path.");
+ return NO;
+ }
+
+ NSString *uuid = [contents objectForKey:@"uuid"];
+ if (!uuid) {
+ NSLog(@"Malformed Things Task: No uuid.");
+ return NO;
+ }
+
+ NSMutableArray *children = [NSMutableArray array];
+ [children addObjectsFromArray:[self tagsForAreaIdentifiedBy:uuid usingDatabaseAt:path ]];
+ [children addObjectsFromArray:[self tasksForAreaIdentifiedBy:uuid usingDatabaseAt:path ]];
+ [children addObjectsFromArray:[self projectsForAreaIdentifiedBy:uuid usingDatabaseAt:path ]];
+
+ [object setChildren:children];
+ return YES;
+}
+
+- (NSArray *)tagsForAreaIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "tag.uuid as uuid, "
+ "tag.title as title "
+ "FROM TMArea AS area "
+ "LEFT JOIN TMAreaTag as junction "
+ "ON junction.areas = area.uuid "
+ "LEFT JOIN TMTag as tag "
+ "ON junction.tags = tag.uuid "
+ "WHERE area.uuid = '%@' "
+ "AND tag.uuid IS NOT NULL "
+ "ORDER BY tag.title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper tagFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+- (NSArray *)projectsForAreaIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "uuid, "
+ "creationDate, "
+ "status, "
+ "title, "
+ "notes, "
+ "area "
+ "FROM TMTask "
+ "WHERE area = '%@' "
+ "AND type = 1 "
+ "AND trashed = 0 "
+ "AND status = 0 "
+ "ORDER BY title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper projectFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+- (NSArray *)tasksForAreaIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "uuid, "
+ "creationDate, "
+ "status, "
+ "title, "
+ "notes, "
+ "area "
+ "FROM TMTask "
+ "WHERE area = '%@' "
+ "AND type = 0 "
+ "AND trashed = 0 "
+ "AND status = 0 "
+ "ORDER BY title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper taskFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Handlers/ThingsTagHandler.h b/QSThingsPlugin/Handlers/ThingsTagHandler.h
new file mode 100644
index 0000000..6ecf432
--- /dev/null
+++ b/QSThingsPlugin/Handlers/ThingsTagHandler.h
@@ -0,0 +1,14 @@
+#import "Constants.h"
+#import "SQLHelper.h"
+#import "ObjectHelper.h"
+#import "NSImage+Badge.h"
+#import <Foundation/Foundation.h>
+#import <QSCore/QSCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface ThingsTagHandler : NSObject <QSObjectHandler>
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Handlers/ThingsTagHandler.m b/QSThingsPlugin/Handlers/ThingsTagHandler.m
new file mode 100644
index 0000000..27b93a2
--- /dev/null
+++ b/QSThingsPlugin/Handlers/ThingsTagHandler.m
@@ -0,0 +1,134 @@
+#import "ThingsTagHandler.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation ThingsTagHandler
+
+- (BOOL)objectHasChildren:(QSObject *)object {
+ return YES;
+}
+
+- (void)setQuickIconForObject:(QSObject *)object {
+ NSImage *baseImage = [QSResourceManager imageNamed:@"com.culturedcode.ThingsMac"];
+ NSColor *color = [NSColor colorWithRed:0.263 green:0.502 blue:0.376 alpha:1.0];
+ NSImage *imageWithBadge = [baseImage imageOfSize:NSMakeSize(512, 512) withSystemBadge:@"tag.circle" ofColor:color];
+
+ if (imageWithBadge) {
+ [object setIcon:imageWithBadge];
+ } else {
+ [object setIcon:baseImage];
+ }
+}
+
+- (BOOL)loadChildrenForObject:(QSObject *)object {
+ NSDictionary *contents = [object objectForType:kTagType];
+
+ if (!contents) {
+ NSLog(@"Malformed Things Task: No content.");
+ return NO;
+ }
+
+ NSString *path = [contents objectForKey:@"path"];
+ if (!path) {
+ NSLog(@"Malformed Things Task: No path.");
+ return NO;
+ }
+
+ NSString *uuid = [contents objectForKey:@"uuid"];
+ if (!uuid) {
+ NSLog(@"Malformed Things Task: No uuid.");
+ return NO;
+ }
+
+ NSMutableArray *children = [NSMutableArray array];
+ [children addObjectsFromArray:[self areasForTagIdentifiedBy:uuid usingDatabaseAt:path ]];
+ [children addObjectsFromArray:[self projectsForTagIdentifiedBy:uuid usingDatabaseAt:path ]];
+ [children addObjectsFromArray:[self tasksForTagIdentifiedBy:uuid usingDatabaseAt:path ]];
+
+ [object setChildren:children];
+ return YES;
+}
+
+- (NSArray *)projectsForTagIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "project.uuid as uuid, "
+ "project.creationDate as creationDate, "
+ "project.status as status, "
+ "project.title as title, "
+ "project.notes as notes, "
+ "project.area as area "
+ "FROM TMTag AS tag "
+ "LEFT JOIN TMTaskTag as junction "
+ "ON junction.tags = tag.uuid "
+ "LEFT JOIN TMTask as project "
+ "ON junction.tasks = project.uuid "
+ "WHERE tag.uuid = '%@' "
+ "AND project.uuid IS NOT NULL "
+ "AND project.type = 1 "
+ "AND project.status = 0 "
+ "AND project.trashed = 0 "
+ "ORDER BY project.title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper projectFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+- (NSArray *)tasksForTagIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "task.uuid as uuid, "
+ "task.creationDate as creationDate, "
+ "task.status as status, "
+ "task.title as title, "
+ "task.notes as notes, "
+ "task.area as area "
+ "FROM TMTag AS tag "
+ "LEFT JOIN TMTaskTag as junction "
+ "ON junction.tags = tag.uuid "
+ "LEFT JOIN TMTask as task "
+ "ON junction.tasks = task.uuid "
+ "WHERE tag.uuid = '%@' "
+ "AND task.uuid IS NOT NULL "
+ "AND task.type = 0 "
+ "AND task.status = 0 "
+ "AND task.trashed = 0 "
+ "ORDER BY task.title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper taskFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+- (NSArray *)areasForTagIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "area.uuid as uuid, "
+ "area.title as title "
+ "FROM TMTag AS tag "
+ "LEFT JOIN TMAreaTag as junction "
+ "ON junction.tags = tag.uuid "
+ "LEFT JOIN TMArea as area "
+ "ON junction.areas = area.uuid "
+ "WHERE tag.uuid = '%@' "
+ "AND area.uuid IS NOT NULL "
+ "ORDER BY area.title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper areaFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Handlers/ThingsTaskHandler.h b/QSThingsPlugin/Handlers/ThingsTaskHandler.h
new file mode 100644
index 0000000..b32e527
--- /dev/null
+++ b/QSThingsPlugin/Handlers/ThingsTaskHandler.h
@@ -0,0 +1,14 @@
+#import "Constants.h"
+#import "SQLHelper.h"
+#import "ObjectHelper.h"
+#import "NSImage+Badge.h"
+#import <Foundation/Foundation.h>
+#import <QSCore/QSCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface ThingsTaskHandler : NSObject <QSObjectHandler>
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Handlers/ThingsTaskHandler.m b/QSThingsPlugin/Handlers/ThingsTaskHandler.m
new file mode 100644
index 0000000..5875feb
--- /dev/null
+++ b/QSThingsPlugin/Handlers/ThingsTaskHandler.m
@@ -0,0 +1,165 @@
+#import "ThingsTaskHandler.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation ThingsTaskHandler
+
+- (BOOL)objectHasChildren:(QSObject *)object {
+ return YES;
+}
+
+- (void)setQuickIconForObject:(QSObject *)object {
+ NSImage *baseImage = [QSResourceManager imageNamed:@"com.culturedcode.ThingsMac"];
+ NSString *badge = @"checkmark.circle";
+ NSColor *color = [NSColor colorWithRed:0.310 green:0.616 blue:0.976 alpha:1.0];
+
+ if (object.primaryType == kProjectType) {
+ badge = @"circle";
+ color = [NSColor colorWithRed:0.157 green:0.376 blue:0.733 alpha:1.0];
+ }
+ NSImage *imageWithBadge = [baseImage imageOfSize:NSMakeSize(512, 512) withSystemBadge:badge ofColor:color];
+
+ if (imageWithBadge) {
+ [object setIcon:imageWithBadge];
+ } else {
+ [object setIcon:baseImage];
+ }
+}
+
+- (BOOL)loadChildrenForObject:(QSObject *)object {
+ NSDictionary *contents = [object objectForType:object.primaryType];
+
+ if (!contents) {
+ NSLog(@"Malformed Things Task: No content.");
+ return NO;
+ }
+
+ NSString *path = [contents objectForKey:@"path"];
+ if (!path) {
+ NSLog(@"Malformed Things Task: No path.");
+ return NO;
+ }
+
+ NSString *uuid = [contents objectForKey:@"uuid"];
+ if (!uuid) {
+ NSLog(@"Malformed Things Task: No uuid.");
+ return NO;
+ }
+
+ // Tasks and Projects are basically the same thing in the Things database. So we use the same handler.
+ // The big difference is that projects can't have projects, and tasks can't have tasks
+
+ NSMutableArray *children = [NSMutableArray array];
+ [children addObjectsFromArray:[self tagsForTaskIdentifiedBy:uuid usingDatabaseAt:path ]];
+ [children addObjectsFromArray:[self areasForTaskIdentifiedBy:uuid usingDatabaseAt:path ]];
+
+ if (object.primaryType == kProjectType) {
+ [children addObjectsFromArray:[self tasksForTaskIdentifiedBy:uuid usingDatabaseAt:path ]];
+ } else {
+ [children addObjectsFromArray:[self projectsForTaskIdentifiedBy:uuid usingDatabaseAt:path ]];
+ }
+
+ [object setChildren:children];
+ return YES;
+}
+
+- (NSArray *)tagsForTaskIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "tag.uuid as uuid, "
+ "tag.title as title "
+ "FROM TMTask AS task "
+ "LEFT JOIN TMTaskTag as junction "
+ "ON junction.tasks = task.uuid "
+ "LEFT JOIN TMTag as tag "
+ "ON junction.tags = tag.uuid "
+ "WHERE task.uuid = '%@' "
+ "AND tag.uuid IS NOT NULL "
+ "ORDER BY tag.title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper tagFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+- (NSArray *)projectsForTaskIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "project.uuid as uuid, "
+ "project.creationDate as creationDate, "
+ "project.status as status, "
+ "project.title as title, "
+ "project.notes as notes, "
+ "project.area as area "
+ "FROM TMTask AS task "
+ "LEFT JOIN TMTask as project "
+ "ON task.project = project.uuid "
+ "AND project.type = 1 "
+ "WHERE task.uuid = '%@' "
+ "AND project.uuid IS NOT NULL "
+ "AND project.trashed = 0 "
+ "AND project.status = 0 "
+ "ORDER BY project.title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper projectFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+- (NSArray *)areasForTaskIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "area.uuid as uuid, "
+ "area.title as title "
+ "FROM TMTask AS task "
+ "LEFT JOIN TMTask as project "
+ "ON task.project = project.uuid "
+ "LEFT JOIN TMArea as area "
+ "ON task.area = area.uuid OR project.area = area.uuid "
+ "WHERE task.uuid = '%@' "
+ "AND area.uuid IS NOT NULL "
+ "ORDER BY area.title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ if (results) {
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper areaFromSQLResult:dictionary usingPath:path ]];
+ }];
+ }
+
+ return objects;
+}
+
+- (NSArray *)tasksForTaskIdentifiedBy:(NSString *)uuid usingDatabaseAt:(NSString *)path {
+ NSString *query = [NSString stringWithFormat: @"SELECT "
+ "uuid, "
+ "creationDate, "
+ "status, "
+ "title, "
+ "notes, "
+ "area "
+ "FROM TMTask "
+ "WHERE project = '%@' "
+ "AND type = 0 "
+ "AND trashed = 0 "
+ "AND status = 0 "
+ "ORDER BY title;", uuid];
+
+ NSArray *results = [SQLHelper executeSql:query onFile:path];
+ NSMutableArray *objects = [NSMutableArray array];
+ [results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
+ [objects addObject:[ObjectHelper taskFromSQLResult:dictionary usingPath:path ]];
+ }];
+
+ return objects;
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Helpers/ObjectHelper.h b/QSThingsPlugin/Helpers/ObjectHelper.h
new file mode 100644
index 0000000..fdb0a48
--- /dev/null
+++ b/QSThingsPlugin/Helpers/ObjectHelper.h
@@ -0,0 +1,18 @@
+#import "Constants.h"
+#import <Foundation/Foundation.h>
+#import <QSCore/QSCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ Helper class to generate QSObjects
+ */
+@interface ObjectHelper : NSObject
+
++ (QSObject *) areaFromSQLResult:(NSDictionary *)result usingPath:(NSString *)path;
++ (QSObject *) projectFromSQLResult:(NSDictionary *)result usingPath:(NSString *)path;
++ (QSObject *) taskFromSQLResult:(NSDictionary *)result usingPath:(NSString *)path;
++ (QSObject *) tagFromSQLResult:(NSDictionary *)result usingPath:(NSString *)path;
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Helpers/ObjectHelper.m b/QSThingsPlugin/Helpers/ObjectHelper.m
new file mode 100644
index 0000000..cf26127
--- /dev/null
+++ b/QSThingsPlugin/Helpers/ObjectHelper.m
@@ -0,0 +1,58 @@
+#import "ObjectHelper.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation ObjectHelper
+
+#pragma mark - SQL Results to QSObjects
+
++ (QSObject *) areaFromSQLResult:(NSDictionary *)result usingPath:(NSString *)path {
+ NSMutableDictionary *configuration = [result mutableCopy];
+ [configuration setObject:path forKey:@"path"];
+ QSObject *area = [QSObject
+ makeObjectWithIdentifier:[result objectForKey:@"uuid"]];
+ [area setObject:configuration forType:kAreaType];
+ [area setName:[result objectForKey:@"title"]];
+ [area setPrimaryType:kAreaType];
+ return area;
+}
+
++ (QSObject *) projectFromSQLResult:(NSDictionary *)result usingPath:(NSString *)path {
+ NSMutableDictionary *configuration = [result mutableCopy];
+ [configuration setObject:path forKey:@"path"];
+ QSObject *project = [QSObject
+ makeObjectWithIdentifier:[result objectForKey:@"uuid"]];
+ [project setObject:configuration forType:kProjectType];
+ [project setName:[result objectForKey:@"title"]];
+ [project setDetails:[result objectForKey:@"notes"]];
+ [project setPrimaryType:kProjectType];
+
+ return project;
+}
++ (QSObject *) taskFromSQLResult:(NSDictionary *)result usingPath:(NSString *)path {
+ NSMutableDictionary *configuration = [result mutableCopy];
+ [configuration setObject:path forKey:@"path"];
+ QSObject *task = [QSObject
+ makeObjectWithIdentifier:[result objectForKey:@"uuid"]];
+ [task setObject:configuration forType:kTaskType];
+ [task setName:[result objectForKey:@"title"]];
+ [task setDetails:[result objectForKey:@"notes"]];
+ [task setPrimaryType:kTaskType];
+
+ return task;
+}
++ (QSObject *) tagFromSQLResult:(NSDictionary *)result usingPath:(NSString *)path {
+ NSMutableDictionary *configuration = [result mutableCopy];
+ [configuration setObject:path forKey:@"path"];
+ QSObject *tag = [QSObject
+ makeObjectWithIdentifier:[result objectForKey:@"uuid"]];
+ [tag setObject:configuration forType:kTagType];
+ [tag setName:[result objectForKey:@"title"]];
+ [tag setPrimaryType:kTagType];
+
+ return tag;
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Helpers/SQLHelper.m b/QSThingsPlugin/Helpers/SQLHelper.m
index c44ea22..c26dfc5 100644
--- a/QSThingsPlugin/Helpers/SQLHelper.m
+++ b/QSThingsPlugin/Helpers/SQLHelper.m
@@ -9,7 +9,7 @@
FMDatabase *database = [FMDatabase databaseWithPath:path];
if (![database openWithFlags:0x00000001]) { // 1 = SQLITE_OPEN_READONLY
- NSLog(@"Could not open Firefox's places.sqlite DB.");
+ NSLog(@"Could not open Things database.");
return @[];
}
[database goodConnection];
diff --git a/QSThingsPlugin/Helpers/ThingsHelper.h b/QSThingsPlugin/Helpers/ThingsHelper.h
index 29d3092..3f1ab6a 100644
--- a/QSThingsPlugin/Helpers/ThingsHelper.h
+++ b/QSThingsPlugin/Helpers/ThingsHelper.h
@@ -28,7 +28,6 @@ extern ThingsURLRoute const ThingsURLRouteAddProject;
@returns YES if the URL was successfully opened, NO if something went wrong.
*/
+ (BOOL)callRoute:(ThingsURLRoute)route withParameters:(NSDictionary *)parameters;
-
@end
NS_ASSUME_NONNULL_END
diff --git a/QSThingsPlugin/Helpers/ThingsHelper.m b/QSThingsPlugin/Helpers/ThingsHelper.m
index cc7267b..be54d8c 100644
--- a/QSThingsPlugin/Helpers/ThingsHelper.m
+++ b/QSThingsPlugin/Helpers/ThingsHelper.m
@@ -11,15 +11,6 @@ ThingsURLRoute const ThingsURLRouteAddProject = @"add-project";
@implementation ThingsHelper
-+ (instancetype)sharedInstance {
- static ThingsHelper *sharedInstance = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- sharedInstance = [[self alloc] init];
- });
- return sharedInstance;
-}
-
+ (BOOL)requiresAuthentication:(ThingsURLRoute)route {
if ([route isEqualToString:ThingsURLRouteSearch] || [route isEqualToString:ThingsURLRouteShow]) {
return NO;
diff --git a/QSThingsPlugin/Parsers/QSThingsAppSectionsParser.m b/QSThingsPlugin/Parsers/QSThingsAppSectionsParser.m
index 70a37ae..472a8fa 100644
--- a/QSThingsPlugin/Parsers/QSThingsAppSectionsParser.m
+++ b/QSThingsPlugin/Parsers/QSThingsAppSectionsParser.m
@@ -11,12 +11,14 @@
// confirm that this makes sense.
- (NSArray *)objectsFromPath:(NSString *)path withSettings:(NSDictionary *)settings {
NSMutableArray *objects = [NSMutableArray array];
+ NSDictionary *dictionary = @{@"path": path};
// Inbox
QSObject *inbox = [QSObject
makeObjectWithIdentifier: ThingsAppSectionKeyInbox];
[inbox setName:@"Inbox"];
[inbox setPrimaryType:kAppSectionType];
+ [inbox setObject:[dictionary copy] forType:kAppSectionType];
[objects addObject:inbox];
// Today
@@ -24,6 +26,7 @@
makeObjectWithIdentifier: ThingsAppSectionKeyToday];
[today setName:@"Today"];
[today setPrimaryType:kAppSectionType];
+ [today setObject:[dictionary copy] forType:kAppSectionType];
[objects addObject:today];
// Upcoming
@@ -31,6 +34,7 @@
makeObjectWithIdentifier: ThingsAppSectionKeyUpcoming];
[upcoming setName:@"Upcoming"];
[upcoming setPrimaryType:kAppSectionType];
+ [upcoming setObject:[dictionary copy] forType:kAppSectionType];
[objects addObject:upcoming];
// Anytime
@@ -38,6 +42,7 @@
makeObjectWithIdentifier: ThingsAppSectionKeyAnytime];
[anytime setName:@"Anytime"];
[anytime setPrimaryType:kAppSectionType];
+ [anytime setObject:[dictionary copy] forType:kAppSectionType];
[objects addObject:anytime];
// Anytime
@@ -45,6 +50,7 @@
makeObjectWithIdentifier: ThingsAppSectionKeySomeday];
[someday setName:@"Someday"];
[someday setPrimaryType:kAppSectionType];
+ [someday setObject:[dictionary copy] forType:kAppSectionType];
[objects addObject:someday];
return objects;
diff --git a/QSThingsPlugin/Parsers/QSThingsAreasParser.h b/QSThingsPlugin/Parsers/QSThingsAreasParser.h
index 74f829b..25601b7 100644
--- a/QSThingsPlugin/Parsers/QSThingsAreasParser.h
+++ b/QSThingsPlugin/Parsers/QSThingsAreasParser.h
@@ -1,3 +1,7 @@
+#import "Constants.h"
+#import "SQLHelper.h"
+#import "ObjectHelper.h"
+
@interface QSThingsAreasParser : QSParser
{
}
diff --git a/QSThingsPlugin/Parsers/QSThingsAreasParser.m b/QSThingsPlugin/Parsers/QSThingsAreasParser.m
index f147603..ca5e19f 100644
--- a/QSThingsPlugin/Parsers/QSThingsAreasParser.m
+++ b/QSThingsPlugin/Parsers/QSThingsAreasParser.m
@@ -1,6 +1,4 @@
-#import "Constants.h"
#import "QSThingsAreasParser.h"
-#import "SQLHelper.h"
@implementation QSThingsAreasParser
- (BOOL)validParserForPath:(NSString *)path {
@@ -18,14 +16,7 @@
NSMutableArray *objects = [NSMutableArray array];
[results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
-
- QSObject *newObject = [QSObject
- makeObjectWithIdentifier:[dictionary objectForKey:@"uuid"]];
- [newObject setObject:dictionary forType:kAreaType];
- [newObject setName:[dictionary objectForKey:@"title"]];
- [newObject setPrimaryType:kAreaType];
-
- [objects addObject:newObject];
+ [objects addObject:[ObjectHelper areaFromSQLResult:dictionary usingPath:path ]];
}];
return objects;
diff --git a/QSThingsPlugin/Parsers/QSThingsProjectsParser.h b/QSThingsPlugin/Parsers/QSThingsProjectsParser.h
index cee939d..0892fa1 100644
--- a/QSThingsPlugin/Parsers/QSThingsProjectsParser.h
+++ b/QSThingsPlugin/Parsers/QSThingsProjectsParser.h
@@ -1,3 +1,7 @@
+#import "Constants.h"
+#import "SQLHelper.h"
+#import "ObjectHelper.h"
+
@interface QSThingsProjectsParser : QSParser
{
}
diff --git a/QSThingsPlugin/Parsers/QSThingsProjectsParser.m b/QSThingsPlugin/Parsers/QSThingsProjectsParser.m
index 1a7956e..b59a420 100644
--- a/QSThingsPlugin/Parsers/QSThingsProjectsParser.m
+++ b/QSThingsPlugin/Parsers/QSThingsProjectsParser.m
@@ -1,6 +1,4 @@
-#import "Constants.h"
#import "QSThingsProjectsParser.h"
-#import "SQLHelper.h"
@implementation QSThingsProjectsParser
- (BOOL)validParserForPath:(NSString *)path {
@@ -26,15 +24,7 @@
NSMutableArray *objects = [NSMutableArray array];
[results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
-
- QSObject *newObject = [QSObject
- makeObjectWithIdentifier:[dictionary objectForKey:@"uuid"]];
- [newObject setObject:dictionary forType:kProjectType];
- [newObject setName:[dictionary objectForKey:@"title"]];
- [newObject setDetails:[dictionary objectForKey:@"notes"]];
- [newObject setPrimaryType:kProjectType];
-
- [objects addObject:newObject];
+ [objects addObject:[ObjectHelper projectFromSQLResult:dictionary usingPath:path ]];
}];
return objects;
diff --git a/QSThingsPlugin/Parsers/QSThingsTagsParser.h b/QSThingsPlugin/Parsers/QSThingsTagsParser.h
index d57aac1..ed78ec9 100644
--- a/QSThingsPlugin/Parsers/QSThingsTagsParser.h
+++ b/QSThingsPlugin/Parsers/QSThingsTagsParser.h
@@ -1,3 +1,7 @@
+#import "Constants.h"
+#import "SQLHelper.h"
+#import "ObjectHelper.h"
+
@interface QSThingsTagsParser : QSParser
{
}
diff --git a/QSThingsPlugin/Parsers/QSThingsTagsParser.m b/QSThingsPlugin/Parsers/QSThingsTagsParser.m
index 4a81de3..04202b0 100644
--- a/QSThingsPlugin/Parsers/QSThingsTagsParser.m
+++ b/QSThingsPlugin/Parsers/QSThingsTagsParser.m
@@ -1,6 +1,4 @@
-#import "Constants.h"
#import "QSThingsTagsParser.h"
-#import "SQLHelper.h"
@implementation QSThingsTagsParser
- (BOOL)validParserForPath:(NSString *)path {
@@ -18,14 +16,7 @@
NSMutableArray *objects = [NSMutableArray array];
[results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
-
- QSObject *newObject = [QSObject
- makeObjectWithIdentifier:[dictionary objectForKey:@"uuid"]];
- [newObject setObject:dictionary forType:kTagType];
- [newObject setName:[dictionary objectForKey:@"title"]];
- [newObject setPrimaryType:kTagType];
-
- [objects addObject:newObject];
+ [objects addObject:[ObjectHelper tagFromSQLResult:dictionary usingPath:path ]];
}];
return objects;
diff --git a/QSThingsPlugin/Parsers/QSThingsTasksParser.h b/QSThingsPlugin/Parsers/QSThingsTasksParser.h
index 7e3f1f2..50e8f05 100644
--- a/QSThingsPlugin/Parsers/QSThingsTasksParser.h
+++ b/QSThingsPlugin/Parsers/QSThingsTasksParser.h
@@ -1,3 +1,6 @@
+#import "Constants.h"
+#import "SQLHelper.h"
+#import "ObjectHelper.h"
@interface QSThingsTasksParser : QSParser
{
}
diff --git a/QSThingsPlugin/Parsers/QSThingsTasksParser.m b/QSThingsPlugin/Parsers/QSThingsTasksParser.m
index b29d011..8f4415b 100644
--- a/QSThingsPlugin/Parsers/QSThingsTasksParser.m
+++ b/QSThingsPlugin/Parsers/QSThingsTasksParser.m
@@ -1,7 +1,4 @@
-#import "Constants.h"
#import "QSThingsTasksParser.h"
-#import "SQLHelper.h"
-#import <os/log.h>
@implementation QSThingsTasksParser
- (BOOL)validParserForPath:(NSString *)path {
@@ -27,15 +24,7 @@
NSMutableArray *objects = [NSMutableArray array];
[results enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger i, BOOL *stop) {
-
- QSObject *newObject = [QSObject
- makeObjectWithIdentifier:[dictionary objectForKey:@"uuid"]];
- [newObject setObject:dictionary forType:kTaskType];
- [newObject setName:[dictionary objectForKey:@"title"]];
- [newObject setDetails:[dictionary objectForKey:@"notes"]];
- [newObject setPrimaryType:kTaskType];
-
- [objects addObject:newObject];
+ [objects addObject:[ObjectHelper taskFromSQLResult:dictionary usingPath:path ]];
}];
return objects;