Skip to content

Commit

Permalink
Merge pull request #4 from oscardoudou/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
oscardoudou authored Mar 2, 2020
2 parents 1e80302 + 66b6ca0 commit e868eab
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 161 deletions.
8 changes: 6 additions & 2 deletions Quick Paste.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
3B80A20521D1C2EF003C0156 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80A20421D1C2EF003C0156 /* AppDelegate.swift */; };
3B80A20721D1C2EF003C0156 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80A20621D1C2EF003C0156 /* ViewController.swift */; };
3B80A20C21D1C2F0003C0156 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3B80A20A21D1C2F0003C0156 /* Main.storyboard */; };
3B88C3E6240A230700B68764 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B88C3E5240A230700B68764 /* Logger.swift */; };
3BD1CE48235EB5F700F4E18A /* GlobalEventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BD1CE47235EB5F700F4E18A /* GlobalEventMonitor.swift */; };
3BF303FA23B2BAC000657550 /* CopiedTableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF303F923B2BAC000657550 /* CopiedTableViewDelegate.swift */; };
/* End PBXBuildFile section */
Expand All @@ -36,6 +37,7 @@
3B80A20621D1C2EF003C0156 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
3B80A20B21D1C2F0003C0156 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
3B80A20D21D1C2F0003C0156 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3B88C3E5240A230700B68764 /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
3BC3C7E82340522900FE92E8 /* Quick Paste.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Quick Paste.entitlements"; sourceTree = "<group>"; };
3BD1CE47235EB5F700F4E18A /* GlobalEventMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalEventMonitor.swift; sourceTree = "<group>"; };
3BF303F923B2BAC000657550 /* CopiedTableViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopiedTableViewDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -74,17 +76,18 @@
3B10BACE23490CF50029AED3 /* Quick Paste.xcdatamodeld */,
3BC3C7E82340522900FE92E8 /* Quick Paste.entitlements */,
3B0F8CF721F68B0F001CF701 /* Assets.xcassets */,
3B510D3323BEEA9500A7F7F2 /* SplitViewController.swift */,
3B80A20421D1C2EF003C0156 /* AppDelegate.swift */,
3B80A20621D1C2EF003C0156 /* ViewController.swift */,
3B510D3123BEE99C00A7F7F2 /* DetailViewController.swift */,
3B510D3323BEEA9500A7F7F2 /* SplitViewController.swift */,
3B80A20A21D1C2F0003C0156 /* Main.storyboard */,
3BF303F923B2BAC000657550 /* CopiedTableViewDelegate.swift */,
3B56842223978AF700338B07 /* NSFRCChangeConsolidator.swift */,
3B10BAD123491C7F0029AED3 /* DataController.swift */,
3B88C3E5240A230700B68764 /* Logger.swift */,
3B3DE77C23B009AC00F248D3 /* CopiedDataSource.swift */,
3BD1CE47235EB5F700F4E18A /* GlobalEventMonitor.swift */,
3B014F5F235C057600838648 /* LocalEventMonitor.swift */,
3B3DE77C23B009AC00F248D3 /* CopiedDataSource.swift */,
3B80A20D21D1C2F0003C0156 /* Info.plist */,
);
path = "Quick Paste";
Expand Down Expand Up @@ -172,6 +175,7 @@
3B014F60235C057600838648 /* LocalEventMonitor.swift in Sources */,
3BD1CE48235EB5F700F4E18A /* GlobalEventMonitor.swift in Sources */,
3B10BAD223491C7F0029AED3 /* DataController.swift in Sources */,
3B88C3E6240A230700B68764 /* Logger.swift in Sources */,
3B80A20721D1C2EF003C0156 /* ViewController.swift in Sources */,
3B510D3223BEE99C00A7F7F2 /* DetailViewController.swift in Sources */,
3B56842323978AF700338B07 /* NSFRCChangeConsolidator.swift in Sources */,
Expand Down
159 changes: 102 additions & 57 deletions Quick Paste/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

import Cocoa
import CoreSpotlight
import Carbon

let logger: Logger = {
return Logger()
}()

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
Expand All @@ -31,62 +36,106 @@ class AppDelegate: NSObject, NSApplicationDelegate {
lazy var localEventMonitor : LocalEventMonitor = LocalEventMonitor(mask: .keyDown){[weak self]
event in
if let strongSelf = self {
print(strongSelf.localEventMonitor)
logger.log(category: .event, message: "localEvent")
strongSelf.viewController.keyDown(with: event!)
logger.log(category: .event, message: "localEvent")
}
return event!
}
lazy var globalEventMonitor: GlobalEventMonitor = GlobalEventMonitor(mask: [.leftMouseDown, .rightMouseDown]){ [weak self]
event in
if let strongSelf = self, strongSelf.popover.isShown {
print(strongSelf.globalEventMonitor)
logger.log(category: .event, message: "globalEvent")
strongSelf.closePopover(sender: event)
logger.log(category: .event, message: "globalEvent")
}
}
lazy var globalBringUpMonitor: GlobalEventMonitor = GlobalEventMonitor(mask: .keyDown){ [weak self]
event in
if let strongSelf = self {
print(strongSelf.globalBringUpMonitor)
// strongSelf.viewController.keyDown(with: event!)
strongSelf.keyDown(with: event!)
}

func getCarbonFlagsFromCocoaFlags(cocoaFlags: NSEvent.ModifierFlags) -> UInt32 {
let flags = cocoaFlags.rawValue
var newFlags: Int = 0
if ((flags & NSEvent.ModifierFlags.control.rawValue) > 0) {
newFlags |= controlKey
}
if ((flags & NSEvent.ModifierFlags.command.rawValue) > 0) {
newFlags |= cmdKey
}
if ((flags & NSEvent.ModifierFlags.shift.rawValue) > 0) {
newFlags |= shiftKey;
}
if ((flags & NSEvent.ModifierFlags.option.rawValue) > 0) {
newFlags |= optionKey
}
if ((flags & NSEvent.ModifierFlags.capsLock.rawValue) > 0) {
newFlags |= alphaLock
}
return UInt32(newFlags);
}
func keyDown(with event: NSEvent) {
if event.keyCode == 12{
print("q detected")
switch event.modifierFlags.intersection(.deviceIndependentFlagsMask){
case[.control, .shift]:
print("control+shift");
// if(appDelegate == nil){
// appDelegate = NSApplication.shared.delegate as! AppDelegate
// }
self.togglePopover(self.statusItem.button)
default:
break
}

func register() {
var hotKeyRef: EventHotKeyRef?
let modifierFlags: UInt32 = getCarbonFlagsFromCocoaFlags(cocoaFlags: NSEvent.ModifierFlags.init(rawValue: NSEvent.ModifierFlags.shift.rawValue + NSEvent.ModifierFlags.control.rawValue))
let keyCode = kVK_Space
var gMyHotKeyID = EventHotKeyID()

gMyHotKeyID.id = UInt32(keyCode)

// Not sure what "swat" vs "htk1" do.
gMyHotKeyID.signature = OSType("swat".fourCharCodeValue)
// gMyHotKeyID.signature = OSType("htk1".fourCharCodeValue)

var eventType = EventTypeSpec()
eventType.eventClass = OSType(kEventClassKeyboard)
eventType.eventKind = OSType(kEventHotKeyReleased)

let observer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
// Install handler.
InstallEventHandler(GetApplicationEventTarget(), {
(nextHanlder, theEvent, observer) -> OSStatus in
// var hkCom = EventHotKeyID()
let mySelf = Unmanaged<AppDelegate>.fromOpaque(observer!).takeUnretainedValue()
mySelf.togglePopover(mySelf.statusItem.button)
// GetEventParameter(theEvent,
// EventParamName(kEventParamDirectObject),
// EventParamType(typeEventHotKeyID),
// nil,
// MemoryLayout<EventHotKeyID>.size,
// nil,
// &hkCom)

// print("Shift + space Released!")
logger.log(category: .event, message: "Shift + Control + space Released!")
return noErr
/// Check that hkCom in indeed your hotkey ID and handle it.
}, 1, &eventType, observer, nil)

// Register hotkey.
let status = RegisterEventHotKey(UInt32(keyCode),
modifierFlags,
gMyHotKeyID,
GetApplicationEventTarget(),
0,
&hotKeyRef)
assert(status == noErr)
}
}

func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
// buildMenu()
print("applicationDidFinishLaunching start")
print("\(splitViewController.splitViewItems)")
viewController = splitViewController.viewItem.viewController as! ViewController
dataController = DataController()
print("appdelegate datacontroller:\(dataController)")
if let button = statusItem.button {
button.image = NSImage(named:"paste")
button.action = #selector(togglePopover)
}
logger.log(category: .app, message: "Appdelegate property has been initialized. SplitViewItems:\(splitViewController.splitViewItems)")
viewController = splitViewController.viewItem.viewController as? ViewController
logger.log(category: .app, message: "initializing app's datacontroller")
dataController = DataController()
logger.log(category: .app, message: "App's datacontroller: \(String(describing: dataController)) has been initialized")
//grab the view controller and pass a Persistent Container Reference to a View Controller
// if let viewController = ViewController.freshController() as? ViewController{
// viewController.container = dataController.persistentContainer
viewController.dataController = self.dataController
print("datacontroller of viewcontroller: \(viewController.dataController)")
//popover's contentViewController is not original ViewController any more, is splitViewController
viewController.dataController = self.dataController
logger.log(category: .app, message: "ViewController's datacontroller is setting to \(String(describing: viewController.dataController))")
//bind popover's contentViewController to splitViewController
popover.contentViewController = splitViewController
// }
//url scheme
NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(self.handleAppleEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
//add pasteboard observer/listener to notification center, center will post onPasteboardChanged when be notified
Expand All @@ -109,7 +158,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
let defaults = UserDefaults.standard
let defaultValue = ["maxId" : ""]
defaults.register(defaults: defaultValue)
globalBringUpMonitor.start()
register()
togglePopover(statusItem.button)
}

Expand All @@ -123,12 +172,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {

func showPopover(sender: Any?) {
if let button = statusItem.button {
print("inside showPopover")
print("to bring popover start loading popover contentviecontroller's view and its children views ")
logger.log(category: .app, message: "-------- initializing popover --------")
logger.log(category: .app, message: "preparing popover contentviecontroller's view and its children views")
//before actually execute popover.show, first need to make sure popover.contentViewController's view didLoad, which also involve child view's didLoad
popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
}
print("after popover.show")
logger.log(category: .app, message: "-------- popover is ready --------")
localEventMonitor.start()
globalEventMonitor.start()
}
Expand All @@ -155,12 +204,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
guard let items = pb.pasteboardItems else { return }
//only copy screenshot text and file, fix unsupport copy type unwrap nil crash
if let preferType = items.first?.availableType(from: preferTypes){
let currentDateTime = Date()
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .medium
let copyTimeStamp = "\(dateFormatter.string(from: currentDateTime))"
//for now we only log copy event, could be searchable, before introducing duplicate will leave this as unsearchable
print("\(copyTimeStamp) | '\(preferType)'")
logger.log(category: .app, message: "NSPasteBoardDidChange with incoming record type of '\(preferType)'")
//index copy event
bindIt()
}else{
Expand All @@ -171,11 +215,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {

//status bar menu
@objc func bindIt(){
logger.log(category: .app, message: "-------- start binding --------")
printPasteBoard()
print("---------bindIt--------------")
let items = NSPasteboard.general.pasteboardItems!
if items.count == 0{
print("items is: \(items)")
return
}
if(firstTime){
Expand All @@ -188,26 +231,26 @@ class AppDelegate: NSObject, NSApplicationDelegate {
//retrieve id from UserDefault which persistent after relaunch, avoid fetch multiple object associated with same id
let defaults = UserDefaults.standard
let id = defaults.string(forKey: "maxId") == "" ? 0 : Int(defaults.string(forKey: "maxId")!)!
print("id in appdelegate bindIt(): \(id)")
logger.log(category: .app, message: "try binding to id: \(id)")
let preferType = item.availableType(from: preferTypes)!
var isMobile = false
if let mobileType = item.availableType(from: mobileTypes){
isMobile = true
}
print("Prefer type is: \(preferType)")
print("isMobile: \(isMobile)")
logger.log(category: .app, message: "Prefer type is: \(preferType)")
logger.log(category: .app, message: "isMobile: \(isMobile)")
if preferType.rawValue == "public.utf8-plain-text"{
title = item.string(forType: preferType) ?? "NoText"
//NSPasteboard.general.clearContents()
print("plaintext is: \(title)")
logger.log(category: .app, message: "plaintext is: \(title)")
dataController.createCopied(id: id, title: title, type: preferType.rawValue, timestamp:Date(), device: isMobile == true ? "mobile" : "mac" )
}
else if preferType.rawValue == "public.file-url"{
path = item.string(forType: preferType) ?? "NoPath"
data = item.data(forType: NSPasteboard.PasteboardType.init("com.apple.icns")) ?? Data()
title = item.string(forType: NSPasteboard.PasteboardType.init("public.utf8-plain-text")) ?? "NoFileName"
//NSPasteboard.general.clearContents()
print("path is: \(path)")
logger.log(category: .app, message: "path is: \(path)")
dataController.createCopied(id: id, title: title, path: path, type: preferType.rawValue, data: data, timestamp:Date(), device: isMobile == true ? "mobile" : "mac")
}
else if preferType.rawValue == "public.png"{
Expand All @@ -221,23 +264,25 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
else{
// TODO
print(preferType.rawValue)
logger.log(category: .app, message: "Prefer type is: \(preferType)")
}
}
logger.log(category: .app, message: "-------- binding finished --------")
}


@objc func printPasteBoard(){
logger.log(category: .app, message: "-------- checking current pasteboard --------")
//it is possible no copy at all, so it need to be optional
print("---------inside printPasteBoard---------")
if let items = NSPasteboard.general.pasteboardItems{
for item in items{
for type in item.types{
print("Type: \(type)")
print("String: \(item.string(forType: type))")
logger.log(category: .app, message: "Type: \(type)")
logger.log(category: .app, message: "String: \(String(describing: item.string(forType: type)))")
}
}
}
logger.log(category: .app, message: "-------- checking finished --------")
}

//url scheme event handler
Expand All @@ -251,12 +296,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
let defaults = UserDefaults.standard
let id = defaults.string(forKey: "maxId") == "" ? 0 : Int(defaults.string(forKey: "maxId")!)!
print("id in appdelegate handleAppleEvent: \(id)")
logger.log(category: .app, message: "id in appdelegate handleAppleEvent: \(id)")
let start = text.index(indexOfSemiColon, offsetBy: 3)
let end = text.endIndex
let paramFromCommandLine = String(text[start..<end])
//NSPasteboard.general.clearContents()
print("url scheme message is: \(paramFromCommandLine)")
logger.log(category: .app, message: "url scheme message is: \(paramFromCommandLine)")
dataController.createCopied(id: id, title: paramFromCommandLine, type: "public.utf8-plain-text", timestamp:Date())
}
}
Expand Down
2 changes: 1 addition & 1 deletion Quick Paste/CopiedDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class CopiedDataSource: NSObject, NSTableViewDataSource {
// 1/2 have to implement function to show core data in table view
func numberOfRows(in tableView: NSTableView) -> Int {
let count = fetchedResultsController.fetchedObjects?.count
print("Number of Rows: \(count)")
logger.log(category: .data, message: "Number of Rows: \(String(describing: count))")
return count ?? 0
}
}
8 changes: 4 additions & 4 deletions Quick Paste/CopiedTableViewDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ class CopiedTableViewDelegate: NSObject, NSTableViewDelegate {
var tableView: NSTableView!
var detailViewController: DetailViewController!
func tableViewSelectionDidChange(_ notification: Notification) {
print("inside tableViewSelectionDidChange")
print("tableView.selectedRow: \(tableView.selectedRow)")
print("detailViewController: \(detailViewController)")
logger.log(category: .app, message: "inside tableViewSelectionDidChange")
logger.log(category: .ui, message: "tableView.selectedRow: \(tableView.selectedRow)")
logger.log(category: .app , message: "detailViewController: \(String(describing: detailViewController))")
detailViewController.getCopiedFromLeft()
print("before passing data to detailViewController")
logger.log(category: .app, message: "before passing data to detailViewController")
if(tableView.selectedRow == -1){return}
if let copied = fetchedResultsController.fetchedObjects![tableView.selectedRow] as? Copied{
detailViewController.copied = copied
Expand Down
Loading

0 comments on commit e868eab

Please sign in to comment.