diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9ba158c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+## Build generated
+build/
+DerivedData/
+
+## Various settings
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata/
+
+## Other
+*.moved-aside
+*.xccheckout
+*.xcscmblueprint
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..42dbd14
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2019 Vishal Telangre
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..aca9e6e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+# bindPDF
+
+
+
+Quickly combine multiple PDF documents into a single PDF document.
+
+## Download
+
+Download the latest DMG archive file from from the [releases](https://github.com/vishaltelangre/bindPDF/releases) page.
+
+Extract it and move the compressed `bindPDF.app` from it into `Applications` folder displayed in the Finder app's sidebar.
+
+## Contribute
+
+If you want to contribute or hack the source, then you're more than welcome!
+
+Open `bindPDF.xcodeproj` with XCode.app, and hit `cmd (⌘)` and `R` keys together to build and run it locally.
+
+## Copyright and License
+
+Copyright (c) 2019, Vishal Telangre. All Rights Reserved.
+
+This project is licenced under the [MIT License](LICENSE).
diff --git a/bindPDF.xcodeproj/project.pbxproj b/bindPDF.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..1ab47ff
--- /dev/null
+++ b/bindPDF.xcodeproj/project.pbxproj
@@ -0,0 +1,344 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ C9851CAE235251030046BD84 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9851CAD235251030046BD84 /* AppDelegate.swift */; };
+ C9851CB0235251030046BD84 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9851CAF235251030046BD84 /* ViewController.swift */; };
+ C9851CB2235251030046BD84 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C9851CB1235251030046BD84 /* Assets.xcassets */; };
+ C9851CB5235251030046BD84 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9851CB3235251030046BD84 /* Main.storyboard */; };
+ C9851CBF23530AFB0046BD84 /* PDFKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9851CBE23530AFB0046BD84 /* PDFKit.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ C9851CAA235251030046BD84 /* bindPDF.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bindPDF.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ C9851CAD235251030046BD84 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ C9851CAF235251030046BD84 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ C9851CB1235251030046BD84 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ C9851CB4235251030046BD84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ C9851CB6235251030046BD84 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ C9851CB7235251030046BD84 /* bindPDF.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = bindPDF.entitlements; sourceTree = ""; };
+ C9851CBE23530AFB0046BD84 /* PDFKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PDFKit.framework; path = System/Library/Frameworks/PDFKit.framework; sourceTree = SDKROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ C9851CA7235251030046BD84 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C9851CBF23530AFB0046BD84 /* PDFKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ C9851CA1235251030046BD84 = {
+ isa = PBXGroup;
+ children = (
+ C9851CAC235251030046BD84 /* bindPDF */,
+ C9851CAB235251030046BD84 /* Products */,
+ C9851CBD23530AFB0046BD84 /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ C9851CAB235251030046BD84 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ C9851CAA235251030046BD84 /* bindPDF.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ C9851CAC235251030046BD84 /* bindPDF */ = {
+ isa = PBXGroup;
+ children = (
+ C9851CAD235251030046BD84 /* AppDelegate.swift */,
+ C9851CAF235251030046BD84 /* ViewController.swift */,
+ C9851CB1235251030046BD84 /* Assets.xcassets */,
+ C9851CB3235251030046BD84 /* Main.storyboard */,
+ C9851CB6235251030046BD84 /* Info.plist */,
+ C9851CB7235251030046BD84 /* bindPDF.entitlements */,
+ );
+ path = bindPDF;
+ sourceTree = "";
+ };
+ C9851CBD23530AFB0046BD84 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ C9851CBE23530AFB0046BD84 /* PDFKit.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ C9851CA9235251030046BD84 /* bindPDF */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C9851CBA235251030046BD84 /* Build configuration list for PBXNativeTarget "bindPDF" */;
+ buildPhases = (
+ C9851CA6235251030046BD84 /* Sources */,
+ C9851CA7235251030046BD84 /* Frameworks */,
+ C9851CA8235251030046BD84 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = bindPDF;
+ productName = bindPDF;
+ productReference = C9851CAA235251030046BD84 /* bindPDF.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ C9851CA2235251030046BD84 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 1110;
+ LastUpgradeCheck = 1110;
+ ORGANIZATIONNAME = "Vishal Telangre";
+ TargetAttributes = {
+ C9851CA9235251030046BD84 = {
+ CreatedOnToolsVersion = 11.1;
+ };
+ };
+ };
+ buildConfigurationList = C9851CA5235251030046BD84 /* Build configuration list for PBXProject "bindPDF" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = C9851CA1235251030046BD84;
+ productRefGroup = C9851CAB235251030046BD84 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ C9851CA9235251030046BD84 /* bindPDF */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ C9851CA8235251030046BD84 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C9851CB2235251030046BD84 /* Assets.xcassets in Resources */,
+ C9851CB5235251030046BD84 /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ C9851CA6235251030046BD84 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C9851CB0235251030046BD84 /* ViewController.swift in Sources */,
+ C9851CAE235251030046BD84 /* AppDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ C9851CB3235251030046BD84 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ C9851CB4235251030046BD84 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ C9851CB8235251030046BD84 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ C9851CB9235251030046BD84 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = macosx;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ };
+ name = Release;
+ };
+ C9851CBB235251030046BD84 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_ENTITLEMENTS = bindPDF/bindPDF.entitlements;
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEVELOPMENT_TEAM = KHGW69X6FJ;
+ INFOPLIST_FILE = bindPDF/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.vishaltelangre.bindPDF;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ C9851CBC235251030046BD84 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_ENTITLEMENTS = bindPDF/bindPDF.entitlements;
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEVELOPMENT_TEAM = KHGW69X6FJ;
+ INFOPLIST_FILE = bindPDF/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.vishaltelangre.bindPDF;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ C9851CA5235251030046BD84 /* Build configuration list for PBXProject "bindPDF" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C9851CB8235251030046BD84 /* Debug */,
+ C9851CB9235251030046BD84 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C9851CBA235251030046BD84 /* Build configuration list for PBXNativeTarget "bindPDF" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C9851CBB235251030046BD84 /* Debug */,
+ C9851CBC235251030046BD84 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = C9851CA2235251030046BD84 /* Project object */;
+}
diff --git a/bindPDF.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/bindPDF.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..cf72f56
--- /dev/null
+++ b/bindPDF.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/bindPDF.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/bindPDF.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/bindPDF.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/bindPDF/AppDelegate.swift b/bindPDF/AppDelegate.swift
new file mode 100644
index 0000000..bb58b54
--- /dev/null
+++ b/bindPDF/AppDelegate.swift
@@ -0,0 +1,26 @@
+//
+// AppDelegate.swift
+// bindPDF
+//
+// Created by Vishal M Telangre on 10/12/19.
+// Copyright © 2019 Vishal Telangre. All rights reserved.
+//
+
+import Cocoa
+
+@NSApplicationMain
+class AppDelegate: NSObject, NSApplicationDelegate {
+
+
+
+ func applicationDidFinishLaunching(_ aNotification: Notification) {
+ // Insert code here to initialize your application
+ }
+
+ func applicationWillTerminate(_ aNotification: Notification) {
+ // Insert code here to tear down your application
+ }
+
+
+}
+
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/1024x1024.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/1024x1024.png
new file mode 100644
index 0000000..a5414b2
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/1024x1024.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/128x128.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/128x128.png
new file mode 100644
index 0000000..4916098
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/128x128.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/16x16.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/16x16.png
new file mode 100644
index 0000000..37cd2ff
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/16x16.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/256x256-1.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/256x256-1.png
new file mode 100644
index 0000000..af56d49
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/256x256-1.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/256x256.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/256x256.png
new file mode 100644
index 0000000..af56d49
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/256x256.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/32x32-1.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/32x32-1.png
new file mode 100644
index 0000000..b150620
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/32x32-1.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/32x32.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/32x32.png
new file mode 100644
index 0000000..b150620
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/32x32.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/512x512-1.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/512x512-1.png
new file mode 100644
index 0000000..b761426
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/512x512-1.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/512x512.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/512x512.png
new file mode 100644
index 0000000..b761426
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/512x512.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/64x64.png b/bindPDF/Assets.xcassets/AppIcon.appiconset/64x64.png
new file mode 100644
index 0000000..b292fe7
Binary files /dev/null and b/bindPDF/Assets.xcassets/AppIcon.appiconset/64x64.png differ
diff --git a/bindPDF/Assets.xcassets/AppIcon.appiconset/Contents.json b/bindPDF/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..339d4f5
--- /dev/null
+++ b/bindPDF/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,68 @@
+{
+ "images" : [
+ {
+ "size" : "16x16",
+ "idiom" : "mac",
+ "filename" : "16x16.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "16x16",
+ "idiom" : "mac",
+ "filename" : "32x32.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "32x32",
+ "idiom" : "mac",
+ "filename" : "32x32-1.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "32x32",
+ "idiom" : "mac",
+ "filename" : "64x64.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "128x128",
+ "idiom" : "mac",
+ "filename" : "128x128.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "128x128",
+ "idiom" : "mac",
+ "filename" : "256x256.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "256x256",
+ "idiom" : "mac",
+ "filename" : "256x256-1.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "256x256",
+ "idiom" : "mac",
+ "filename" : "512x512-1.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "512x512",
+ "idiom" : "mac",
+ "filename" : "512x512.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "512x512",
+ "idiom" : "mac",
+ "filename" : "1024x1024.png",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/bindPDF/Assets.xcassets/Contents.json b/bindPDF/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/bindPDF/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/bindPDF/Base.lproj/Main.storyboard b/bindPDF/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..dc6888f
--- /dev/null
+++ b/bindPDF/Base.lproj/Main.storyboard
@@ -0,0 +1,934 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bindPDF/Info.plist b/bindPDF/Info.plist
new file mode 100644
index 0000000..2045110
--- /dev/null
+++ b/bindPDF/Info.plist
@@ -0,0 +1,38 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ $(PRODUCT_BUNDLE_PACKAGE_TYPE)
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSApplicationCategoryType
+ public.app-category.developer-tools
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ Copyright © 2019 Vishal Telangre. All rights reserved.
+ NSMainStoryboardFile
+ Main
+ NSPrincipalClass
+ NSApplication
+ NSSupportsAutomaticTermination
+
+ NSSupportsSuddenTermination
+
+
+
diff --git a/bindPDF/ViewController.swift b/bindPDF/ViewController.swift
new file mode 100644
index 0000000..bec7922
--- /dev/null
+++ b/bindPDF/ViewController.swift
@@ -0,0 +1,187 @@
+//
+// ViewController.swift
+// bindPDF
+//
+// Created by Vishal Telangre on 10/12/19.
+// Copyright © 2019 Vishal Telangre. All rights reserved.
+//
+
+import Cocoa
+import PDFKit
+
+class ViewController: NSViewController {
+ @IBOutlet weak var noPdfFilesContainerView: NSView!
+ @IBOutlet weak var pdfFilesContainerView: NSView!
+ @IBOutlet weak var pdfFileListTableView: NSTableView!
+ @IBOutlet weak var pdfPreviewView: PDFView!
+
+ @IBAction func addButton(_ sender: NSButton) {
+ let openPanel = NSOpenPanel()
+ openPanel.allowedFileTypes = ["pdf", "PDF"]
+ openPanel.allowsMultipleSelection = true
+ openPanel.canChooseDirectories = false
+ openPanel.canCreateDirectories = false
+ openPanel.canChooseFiles = true
+ openPanel.beginSheetModal(for: self.view.window!) { (response) in
+ if response == .OK {
+ for url in openPanel.urls {
+ self.urls.append(url)
+ }
+ }
+
+ self.pdfFileListTableView.reloadData()
+
+ openPanel.close()
+
+ self.reloadLivePreview()
+ }
+ }
+
+ @IBAction func export(_ sender: NSButton) {
+ let savePanel = NSSavePanel()
+ savePanel.allowedFileTypes = ["pdf", "PDF"]
+ savePanel.directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
+ savePanel.beginSheetModal(for: self.view.window!) { (response) in
+ if response == .OK {
+ self.pdfPreviewView.document?.write(to: savePanel.url!)
+ savePanel.close()
+
+ self.urls = []
+ self.pdfFileListTableView.reloadData()
+ self.reloadLivePreview()
+ }
+
+ }
+ }
+
+ let pasteboardType = NSPasteboard.PasteboardType(rawValue: "bindPDF.url")
+ var urls: [URL] = []
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ pdfFilesContainerView.isHidden = true
+ pdfFileListTableView.delegate = self
+ pdfFileListTableView.dataSource = self
+ pdfFileListTableView.registerForDraggedTypes([pasteboardType])
+ }
+
+ func reorderFile(at: Int, to: Int) {
+ pdfFileListTableView.delegate = nil
+ urls.insert(urls.remove(at: at), at: to)
+ pdfFileListTableView.delegate = self
+
+ reloadLivePreview()
+ }
+
+ func reloadLivePreview() {
+ pdfFilesContainerView.isHidden = urls.count == 0
+ noPdfFilesContainerView.isHidden = urls.count != 0
+
+ if urls.count == 0 {
+ return
+ }
+
+ var pageIndex = 0
+ let previewDocument = PDFDocument()
+
+ for url in urls {
+ if let document = PDFDocument(url: url) {
+ for pageNumber in 1...document.pageCount {
+ if let page = document.page(at: pageNumber - 1) {
+ previewDocument.insert(page, at: pageIndex)
+ pageIndex += 1
+ }
+ }
+ }
+ }
+
+ pdfPreviewView.document = previewDocument
+ }
+}
+
+extension ViewController: NSSplitViewDelegate {
+ func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
+ return 300
+ }
+
+ func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
+ return proposedMaximumPosition - 900
+ }
+}
+
+extension ViewController: NSTableViewDataSource {
+ func numberOfRows(in tableView: NSTableView) -> Int {
+ return urls.count
+ }
+
+ func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
+ let url = urls[row]
+ let pasteboardItem = NSPasteboardItem()
+ pasteboardItem.setString(url.path, forType: pasteboardType)
+ return pasteboardItem
+ }
+
+ func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
+ if dropOperation == .above {
+ return .move
+ } else {
+ return []
+ }
+ }
+
+ func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
+ guard
+ let item = info.draggingPasteboard.pasteboardItems?.first,
+ let theString = item.string(forType: pasteboardType),
+ let url = urls.first(where: { $0.path == theString }),
+ let originalRow = urls.firstIndex(of: url)
+ else {
+ return false
+ }
+
+ var newRow = row
+ if originalRow < newRow {
+ newRow = row - 1
+ }
+
+ // Animate the rows
+ pdfFileListTableView.beginUpdates()
+ pdfFileListTableView.moveRow(at: originalRow, to: newRow)
+ pdfFileListTableView.endUpdates()
+
+ // Update the data model
+ reorderFile(at: originalRow, to: newRow)
+
+ return true
+ }
+}
+
+extension ViewController: NSTableViewDelegate {
+ func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
+ let url = urls[row]
+ if let cell = pdfFileListTableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "defaultCell"), owner: nil) as? NSTableCellView {
+ cell.textField?.stringValue = url.lastPathComponent
+ cell.textField?.maximumNumberOfLines = 4
+
+ let pdfDocument = PDFDocument(url: url)
+ if let firstPage = pdfDocument?.page(at: 0) {
+ cell.imageView?.image = firstPage.thumbnail(of: NSSize(width: 256, height: 256), for: .artBox)
+ }
+
+ return cell
+ }
+
+ return nil
+ }
+
+ func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] {
+ let action = NSTableViewRowAction(style: .destructive, title: "Delete") { (action, row) in
+ self.urls.remove(at: row)
+ self.pdfFileListTableView.removeRows(at: IndexSet(integer: row), withAnimation: .effectFade)
+ self.reloadLivePreview()
+ }
+
+ return [action]
+ }
+}
diff --git a/bindPDF/bindPDF.entitlements b/bindPDF/bindPDF.entitlements
new file mode 100644
index 0000000..19afff1
--- /dev/null
+++ b/bindPDF/bindPDF.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-write
+
+
+