Using simpler aproach for modelChange proadcasting by using the document as broadcaster

This commit is contained in:
michael starke
2016-08-30 12:59:27 +02:00
parent da295b9acd
commit 8b60e9ec84
13 changed files with 74 additions and 269 deletions

View File

@@ -103,6 +103,7 @@
4C46B88517063A070046109A /* NSString+MPPasswordCreation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C46B88417063A070046109A /* NSString+MPPasswordCreation.m */; }; 4C46B88517063A070046109A /* NSString+MPPasswordCreation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C46B88417063A070046109A /* NSString+MPPasswordCreation.m */; };
4C473A8718AFD85B0073FD2E /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C473A8518AFD7250073FD2E /* XCTest.framework */; }; 4C473A8718AFD85B0073FD2E /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C473A8518AFD7250073FD2E /* XCTest.framework */; };
4C4A100F176286FD00BBF2CA /* MPTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4A100E176286FD00BBF2CA /* MPTableView.m */; }; 4C4A100F176286FD00BBF2CA /* MPTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4A100E176286FD00BBF2CA /* MPTableView.m */; };
4C4B5B3A1D759A4E005F329A /* MPDocument+ModelChange.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B5B391D759A4E005F329A /* MPDocument+ModelChange.m */; };
4C4B728518E4B9B400A1A5D5 /* MPDockTileHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B728418E4B9B400A1A5D5 /* MPDockTileHelper.m */; }; 4C4B728518E4B9B400A1A5D5 /* MPDockTileHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B728418E4B9B400A1A5D5 /* MPDockTileHelper.m */; };
4C4B7EE917A45EC6000234C7 /* MPDatePickingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EE717A45EC5000234C7 /* MPDatePickingViewController.m */; }; 4C4B7EE917A45EC6000234C7 /* MPDatePickingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EE717A45EC5000234C7 /* MPDatePickingViewController.m */; };
4C4B7EEE17A467E1000234C7 /* MPGroupInspectorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EEC17A467E1000234C7 /* MPGroupInspectorViewController.m */; }; 4C4B7EEE17A467E1000234C7 /* MPGroupInspectorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EEC17A467E1000234C7 /* MPGroupInspectorViewController.m */; };
@@ -140,7 +141,6 @@
4C6F228C19A4AA700012310C /* MPAutotypeDelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6F228B19A4AA700012310C /* MPAutotypeDelay.m */; }; 4C6F228C19A4AA700012310C /* MPAutotypeDelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6F228B19A4AA700012310C /* MPAutotypeDelay.m */; };
4C701CBC178618A000581B88 /* 12_RemoteTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C701CBB178618A000581B88 /* 12_RemoteTemplate.pdf */; }; 4C701CBC178618A000581B88 /* 12_RemoteTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C701CBB178618A000581B88 /* 12_RemoteTemplate.pdf */; };
4C7155D81A10DB6D00979307 /* IconSelection.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C7155DA1A10DB6D00979307 /* IconSelection.xib */; }; 4C7155D81A10DB6D00979307 /* IconSelection.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C7155DA1A10DB6D00979307 /* IconSelection.xib */; };
4C74DD07177BD1640034A9DB /* MPCustomFieldView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C74DD06177BD1640034A9DB /* MPCustomFieldView.m */; };
4C76155C1764C04C0015A1A6 /* GeneralSettings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C76155E1764C04C0015A1A6 /* GeneralSettings.xib */; }; 4C76155C1764C04C0015A1A6 /* GeneralSettings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C76155E1764C04C0015A1A6 /* GeneralSettings.xib */; };
4C7615681764C0C40015A1A6 /* PasswordInputView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C76156A1764C0C40015A1A6 /* PasswordInputView.xib */; }; 4C7615681764C0C40015A1A6 /* PasswordInputView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C76156A1764C0C40015A1A6 /* PasswordInputView.xib */; };
4C76156D1764C0E20015A1A6 /* InspectorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C76156F1764C0E20015A1A6 /* InspectorView.xib */; }; 4C76156D1764C0E20015A1A6 /* InspectorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C76156F1764C0E20015A1A6 /* InspectorView.xib */; };
@@ -195,8 +195,6 @@
4CAD748E15B88AC100104512 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CAD748D15B88AC100104512 /* libz.dylib */; }; 4CAD748E15B88AC100104512 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CAD748D15B88AC100104512 /* libz.dylib */; };
4CB915941A0159A20089CE5B /* DuplicateEntryOptionsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CB915931A0159A20089CE5B /* DuplicateEntryOptionsWindow.xib */; }; 4CB915941A0159A20089CE5B /* DuplicateEntryOptionsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CB915931A0159A20089CE5B /* DuplicateEntryOptionsWindow.xib */; };
4CB9339916D3A0DD00A13B5D /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4CB9339716D3A0DD00A13B5D /* Credits.rtf */; }; 4CB9339916D3A0DD00A13B5D /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4CB9339716D3A0DD00A13B5D /* Credits.rtf */; };
4CB9D77F1D70CE6B00F43F76 /* MPModelChangeObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D77E1D70CE6B00F43F76 /* MPModelChangeObserving.m */; };
4CB9D7821D71AFBE00F43F76 /* MPArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D7811D71AFBE00F43F76 /* MPArrayController.m */; };
4CBA2ABA17074C07006D8139 /* MPSettingsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CBA2AB917074C07006D8139 /* MPSettingsHelper.m */; }; 4CBA2ABA17074C07006D8139 /* MPSettingsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CBA2AB917074C07006D8139 /* MPSettingsHelper.m */; };
4CC0D2CE17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC0D2CD17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m */; }; 4CC0D2CE17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC0D2CD17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m */; };
4CC0D2D117974A5A000B4BDA /* MPAttachmentTableViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC0D2D017974A5A000B4BDA /* MPAttachmentTableViewDelegate.m */; }; 4CC0D2D117974A5A000B4BDA /* MPAttachmentTableViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC0D2D017974A5A000B4BDA /* MPAttachmentTableViewDelegate.m */; };
@@ -222,7 +220,6 @@
4CD78AC016D155FF00768A1D /* 11_CameraTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */; }; 4CD78AC016D155FF00768A1D /* 11_CameraTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */; };
4CD820211A32173100399DBB /* ReferenceBuilderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CD820231A32173100399DBB /* ReferenceBuilderView.xib */; }; 4CD820211A32173100399DBB /* ReferenceBuilderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CD820231A32173100399DBB /* ReferenceBuilderView.xib */; };
4CD884B715BD47080042BBF8 /* DocumentWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CD884B615BD47080042BBF8 /* DocumentWindow.xib */; }; 4CD884B715BD47080042BBF8 /* DocumentWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CD884B615BD47080042BBF8 /* DocumentWindow.xib */; };
4CDE7B161D660983008C4160 /* MPObjectController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDE7B151D660983008C4160 /* MPObjectController.m */; };
4CDF01A316D1B76700D0AC08 /* MPEntryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */; }; 4CDF01A316D1B76700D0AC08 /* MPEntryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */; };
4CE2961518429AA5005F01CE /* MPAutotypeKeyPress.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE2961418429AA5005F01CE /* MPAutotypeKeyPress.m */; }; 4CE2961518429AA5005F01CE /* MPAutotypeKeyPress.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE2961418429AA5005F01CE /* MPAutotypeKeyPress.m */; };
4CE296191842A166005F01CE /* MPAutotypePaste.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE296181842A166005F01CE /* MPAutotypePaste.m */; }; 4CE296191842A166005F01CE /* MPAutotypePaste.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE296181842A166005F01CE /* MPAutotypePaste.m */; };
@@ -233,7 +230,6 @@
4CE3E62617AB0D2D00D9E4B4 /* MPAttachmentTableDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3E62517AB0D2D00D9E4B4 /* MPAttachmentTableDataSource.m */; }; 4CE3E62617AB0D2D00D9E4B4 /* MPAttachmentTableDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3E62517AB0D2D00D9E4B4 /* MPAttachmentTableDataSource.m */; };
4CE501341BBC47F500FB819D /* MPTagsTokenFieldDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE501331BBC47F500FB819D /* MPTagsTokenFieldDelegate.m */; }; 4CE501341BBC47F500FB819D /* MPTagsTokenFieldDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE501331BBC47F500FB819D /* MPTagsTokenFieldDelegate.m */; };
4CE5B54B173AFBA700207B39 /* MPDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5B549173AFBA700207B39 /* MPDocument.m */; }; 4CE5B54B173AFBA700207B39 /* MPDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5B549173AFBA700207B39 /* MPDocument.m */; };
4CE7FAFB1D74813500E2C856 /* MPTestModelChangeObservingHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE7FAFA1D74813500E2C856 /* MPTestModelChangeObservingHelper.m */; };
4CE8246F16E2E93400573141 /* MPOverlayWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE8246E16E2E93400573141 /* MPOverlayWindowController.m */; }; 4CE8246F16E2E93400573141 /* MPOverlayWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE8246E16E2E93400573141 /* MPOverlayWindowController.m */; };
4CE8247516E2F2B900573141 /* MPOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE8247416E2F2B900573141 /* MPOverlayView.m */; }; 4CE8247516E2F2B900573141 /* MPOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE8247416E2F2B900573141 /* MPOverlayView.m */; };
4CE88B9717BA651C0042E078 /* contextTriangleTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CE88B9617BA651C0042E078 /* contextTriangleTemplate.pdf */; }; 4CE88B9717BA651C0042E078 /* contextTriangleTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CE88B9617BA651C0042E078 /* contextTriangleTemplate.pdf */; };
@@ -418,6 +414,7 @@
4C473A8518AFD7250073FD2E /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 4C473A8518AFD7250073FD2E /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
4C4A100D176286FD00BBF2CA /* MPTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTableView.h; sourceTree = "<group>"; }; 4C4A100D176286FD00BBF2CA /* MPTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTableView.h; sourceTree = "<group>"; };
4C4A100E176286FD00BBF2CA /* MPTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTableView.m; sourceTree = "<group>"; }; 4C4A100E176286FD00BBF2CA /* MPTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTableView.m; sourceTree = "<group>"; };
4C4B5B391D759A4E005F329A /* MPDocument+ModelChange.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPDocument+ModelChange.m"; sourceTree = "<group>"; };
4C4B728318E4B9B400A1A5D5 /* MPDockTileHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDockTileHelper.h; sourceTree = "<group>"; }; 4C4B728318E4B9B400A1A5D5 /* MPDockTileHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDockTileHelper.h; sourceTree = "<group>"; };
4C4B728418E4B9B400A1A5D5 /* MPDockTileHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDockTileHelper.m; sourceTree = "<group>"; }; 4C4B728418E4B9B400A1A5D5 /* MPDockTileHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDockTileHelper.m; sourceTree = "<group>"; };
4C4B7EE617A45EC5000234C7 /* MPDatePickingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDatePickingViewController.h; sourceTree = "<group>"; }; 4C4B7EE617A45EC5000234C7 /* MPDatePickingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDatePickingViewController.h; sourceTree = "<group>"; };
@@ -493,8 +490,6 @@
4C7155EA1A10DB7800979307 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/IconSelection.strings; sourceTree = "<group>"; }; 4C7155EA1A10DB7800979307 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/IconSelection.strings; sourceTree = "<group>"; };
4C7155EC1A10DB7900979307 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/IconSelection.strings; sourceTree = "<group>"; }; 4C7155EC1A10DB7900979307 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/IconSelection.strings; sourceTree = "<group>"; };
4C725F3F19EEF4FC00191B01 /* MJGAvailability.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MJGAvailability.h; sourceTree = "<group>"; }; 4C725F3F19EEF4FC00191B01 /* MJGAvailability.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MJGAvailability.h; sourceTree = "<group>"; };
4C74DD05177BD1640034A9DB /* MPCustomFieldView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCustomFieldView.h; sourceTree = "<group>"; };
4C74DD06177BD1640034A9DB /* MPCustomFieldView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCustomFieldView.m; sourceTree = "<group>"; };
4C76155F1764C0590015A1A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/GeneralSettings.xib; sourceTree = "<group>"; }; 4C76155F1764C0590015A1A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/GeneralSettings.xib; sourceTree = "<group>"; };
4C7615601764C05A0015A1A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; }; 4C7615601764C05A0015A1A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
4C76156B1764C0C80015A1A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PasswordInputView.xib; sourceTree = "<group>"; }; 4C76156B1764C0C80015A1A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PasswordInputView.xib; sourceTree = "<group>"; };
@@ -592,10 +587,6 @@
4CB63A6018986530002DEC4C /* MPFlagsHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPFlagsHelper.h; sourceTree = "<group>"; }; 4CB63A6018986530002DEC4C /* MPFlagsHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPFlagsHelper.h; sourceTree = "<group>"; };
4CB915931A0159A20089CE5B /* DuplicateEntryOptionsWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DuplicateEntryOptionsWindow.xib; sourceTree = "<group>"; }; 4CB915931A0159A20089CE5B /* DuplicateEntryOptionsWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DuplicateEntryOptionsWindow.xib; sourceTree = "<group>"; };
4CB9339816D3A0DD00A13B5D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; }; 4CB9339816D3A0DD00A13B5D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
4CB9D77C1D70CBCE00F43F76 /* MPModelChangeObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPModelChangeObserving.h; sourceTree = "<group>"; };
4CB9D77E1D70CE6B00F43F76 /* MPModelChangeObserving.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPModelChangeObserving.m; sourceTree = "<group>"; };
4CB9D7801D71AFBE00F43F76 /* MPArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPArrayController.h; sourceTree = "<group>"; };
4CB9D7811D71AFBE00F43F76 /* MPArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPArrayController.m; sourceTree = "<group>"; };
4CBA2AB617074B59006D8139 /* MPSettingsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSettingsHelper.h; sourceTree = "<group>"; }; 4CBA2AB617074B59006D8139 /* MPSettingsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSettingsHelper.h; sourceTree = "<group>"; };
4CBA2AB917074C07006D8139 /* MPSettingsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSettingsHelper.m; sourceTree = "<group>"; }; 4CBA2AB917074C07006D8139 /* MPSettingsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSettingsHelper.m; sourceTree = "<group>"; };
4CC0D2CC17974A47000B4BDA /* MPCustomFieldTableViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCustomFieldTableViewDelegate.h; sourceTree = "<group>"; }; 4CC0D2CC17974A47000B4BDA /* MPCustomFieldTableViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCustomFieldTableViewDelegate.h; sourceTree = "<group>"; };
@@ -635,8 +626,6 @@
4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 11_CameraTemplate.pdf; sourceTree = "<group>"; }; 4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 11_CameraTemplate.pdf; sourceTree = "<group>"; };
4CD820221A32173100399DBB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ReferenceBuilderView.xib; sourceTree = "<group>"; }; 4CD820221A32173100399DBB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ReferenceBuilderView.xib; sourceTree = "<group>"; };
4CD884B615BD47080042BBF8 /* DocumentWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DocumentWindow.xib; sourceTree = "<group>"; }; 4CD884B615BD47080042BBF8 /* DocumentWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DocumentWindow.xib; sourceTree = "<group>"; };
4CDE7B141D660983008C4160 /* MPObjectController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPObjectController.h; sourceTree = "<group>"; };
4CDE7B151D660983008C4160 /* MPObjectController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPObjectController.m; sourceTree = "<group>"; };
4CDF01A116D1B76700D0AC08 /* MPEntryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntryViewController.h; sourceTree = "<group>"; }; 4CDF01A116D1B76700D0AC08 /* MPEntryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntryViewController.h; sourceTree = "<group>"; };
4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntryViewController.m; sourceTree = "<group>"; }; 4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntryViewController.m; sourceTree = "<group>"; };
4CE2961318429AA5005F01CE /* MPAutotypeKeyPress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAutotypeKeyPress.h; sourceTree = "<group>"; }; 4CE2961318429AA5005F01CE /* MPAutotypeKeyPress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAutotypeKeyPress.h; sourceTree = "<group>"; };
@@ -657,7 +646,6 @@
4CE501331BBC47F500FB819D /* MPTagsTokenFieldDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTagsTokenFieldDelegate.m; sourceTree = "<group>"; }; 4CE501331BBC47F500FB819D /* MPTagsTokenFieldDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTagsTokenFieldDelegate.m; sourceTree = "<group>"; };
4CE5B548173AFBA700207B39 /* MPDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDocument.h; sourceTree = "<group>"; }; 4CE5B548173AFBA700207B39 /* MPDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDocument.h; sourceTree = "<group>"; };
4CE5B549173AFBA700207B39 /* MPDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = MPDocument.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 4CE5B549173AFBA700207B39 /* MPDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = MPDocument.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
4CE7FAFA1D74813500E2C856 /* MPTestModelChangeObservingHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTestModelChangeObservingHelper.m; sourceTree = "<group>"; };
4CE8246D16E2E93400573141 /* MPOverlayWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayWindowController.h; sourceTree = "<group>"; }; 4CE8246D16E2E93400573141 /* MPOverlayWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayWindowController.h; sourceTree = "<group>"; };
4CE8246E16E2E93400573141 /* MPOverlayWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOverlayWindowController.m; sourceTree = "<group>"; }; 4CE8246E16E2E93400573141 /* MPOverlayWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOverlayWindowController.m; sourceTree = "<group>"; };
4CE8247316E2F2B900573141 /* MPOverlayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayView.h; sourceTree = "<group>"; }; 4CE8247316E2F2B900573141 /* MPOverlayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayView.h; sourceTree = "<group>"; };
@@ -836,8 +824,6 @@
6021FE7918E15FF300C3BC51 /* DatePickingView.xib */, 6021FE7918E15FF300C3BC51 /* DatePickingView.xib */,
4C26C34A18D8D5A300CF1A1C /* PreviewView.xib */, 4C26C34A18D8D5A300CF1A1C /* PreviewView.xib */,
4CD820231A32173100399DBB /* ReferenceBuilderView.xib */, 4CD820231A32173100399DBB /* ReferenceBuilderView.xib */,
4C74DD05177BD1640034A9DB /* MPCustomFieldView.h */,
4C74DD06177BD1640034A9DB /* MPCustomFieldView.m */,
4CE8247316E2F2B900573141 /* MPOverlayView.h */, 4CE8247316E2F2B900573141 /* MPOverlayView.h */,
4CE8247416E2F2B900573141 /* MPOverlayView.m */, 4CE8247416E2F2B900573141 /* MPOverlayView.m */,
4CFC53BD16E94729007396BE /* MPShadowBox.h */, 4CFC53BD16E94729007396BE /* MPShadowBox.h */,
@@ -977,6 +963,7 @@
4C1FA07A18231900003A3F8C /* MPDocument+Autotype.m */, 4C1FA07A18231900003A3F8C /* MPDocument+Autotype.m */,
4C15B74518BCA3B1003F8008 /* MPDocument+Search.m */, 4C15B74518BCA3B1003F8008 /* MPDocument+Search.m */,
4C6B7C7C18BE7EB0001D5D77 /* MPDocument+HistoryBrowsing.m */, 4C6B7C7C18BE7EB0001D5D77 /* MPDocument+HistoryBrowsing.m */,
4C4B5B391D759A4E005F329A /* MPDocument+ModelChange.m */,
4C0AF62D195C1F2B009E658D /* MPEntrySearchContext.h */, 4C0AF62D195C1F2B009E658D /* MPEntrySearchContext.h */,
4C0AF62E195C1F2B009E658D /* MPEntrySearchContext.m */, 4C0AF62E195C1F2B009E658D /* MPEntrySearchContext.m */,
4CB44EEE1C972BFD00EE2D60 /* Proxies */, 4CB44EEE1C972BFD00EE2D60 /* Proxies */,
@@ -993,7 +980,6 @@
4C45FB2C178E0BCB0010007D /* MPDatabaseLoading.m */, 4C45FB2C178E0BCB0010007D /* MPDatabaseLoading.m */,
4C45FB2F178E0CE20010007D /* MPTestDocument.m */, 4C45FB2F178E0CE20010007D /* MPTestDocument.m */,
4C6BC65F1A36717E00BDDF3D /* MPDatabaseSearch.m */, 4C6BC65F1A36717E00BDDF3D /* MPDatabaseSearch.m */,
4CE7FAFA1D74813500E2C856 /* MPTestModelChangeObservingHelper.m */,
4C45FB1F178E09ED0010007D /* Supporting Files */, 4C45FB1F178E09ED0010007D /* Supporting Files */,
); );
path = MacPassTests; path = MacPassTests;
@@ -1308,8 +1294,6 @@
children = ( children = (
4CA0B30D15BCB6FD00654E32 /* MPSettingsTab.h */, 4CA0B30D15BCB6FD00654E32 /* MPSettingsTab.h */,
4C2B0B7419F66F6400E48913 /* MPTargetNodeResolving.h */, 4C2B0B7419F66F6400E48913 /* MPTargetNodeResolving.h */,
4CB9D77C1D70CBCE00F43F76 /* MPModelChangeObserving.h */,
4CB9D77E1D70CE6B00F43F76 /* MPModelChangeObserving.m */,
); );
name = Protocolls; name = Protocolls;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1373,10 +1357,6 @@
4C431BCC16E2A82700700A81 /* MPPasteBoardController.m */, 4C431BCC16E2A82700700A81 /* MPPasteBoardController.m */,
4C6AEEF71A043E2B00CA2420 /* MPDocumentController.h */, 4C6AEEF71A043E2B00CA2420 /* MPDocumentController.h */,
4C6AEEF81A043E2B00CA2420 /* MPDocumentController.m */, 4C6AEEF81A043E2B00CA2420 /* MPDocumentController.m */,
4CDE7B141D660983008C4160 /* MPObjectController.h */,
4CDE7B151D660983008C4160 /* MPObjectController.m */,
4CB9D7801D71AFBE00F43F76 /* MPArrayController.h */,
4CB9D7811D71AFBE00F43F76 /* MPArrayController.m */,
); );
name = "Data Controller"; name = "Data Controller";
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1682,7 +1662,6 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
4CE7FAFB1D74813500E2C856 /* MPTestModelChangeObservingHelper.m in Sources */,
4C45FB2D178E0BCB0010007D /* MPDatabaseLoading.m in Sources */, 4C45FB2D178E0BCB0010007D /* MPDatabaseLoading.m in Sources */,
4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */, 4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */,
4C45FB30178E0CE20010007D /* MPTestDocument.m in Sources */, 4C45FB30178E0CE20010007D /* MPTestDocument.m in Sources */,
@@ -1705,11 +1684,11 @@
4CA0B2FC15BCAF8600654E32 /* MPSettingsWindowController.m in Sources */, 4CA0B2FC15BCAF8600654E32 /* MPSettingsWindowController.m in Sources */,
4C4F72D118DF704400E8D378 /* DDHotKeyTextField.m in Sources */, 4C4F72D118DF704400E8D378 /* DDHotKeyTextField.m in Sources */,
4C83814215BF4677001AE468 /* MPDocumentWindowController.m in Sources */, 4C83814215BF4677001AE468 /* MPDocumentWindowController.m in Sources */,
4C4B5B3A1D759A4E005F329A /* MPDocument+ModelChange.m in Sources */,
4CD034AB1BFE113B003C002C /* MPPluginHost.m in Sources */, 4CD034AB1BFE113B003C002C /* MPPluginHost.m in Sources */,
4C2E382316D1421B00037A9D /* MPIconHelper.m in Sources */, 4C2E382316D1421B00037A9D /* MPIconHelper.m in Sources */,
4C2E382616D1470200037A9D /* MPViewController.m in Sources */, 4C2E382616D1470200037A9D /* MPViewController.m in Sources */,
4C65FAE916D16DDB006E0577 /* MPPasswordInputController.m in Sources */, 4C65FAE916D16DDB006E0577 /* MPPasswordInputController.m in Sources */,
4CB9D7821D71AFBE00F43F76 /* MPArrayController.m in Sources */,
4CDF01A316D1B76700D0AC08 /* MPEntryViewController.m in Sources */, 4CDF01A316D1B76700D0AC08 /* MPEntryViewController.m in Sources */,
4C3BD51516D276F800389F1F /* MPToolbarDelegate.m in Sources */, 4C3BD51516D276F800389F1F /* MPToolbarDelegate.m in Sources */,
4C7B63731C0CB51F00D7038C /* TTTDataTransformer.m in Sources */, 4C7B63731C0CB51F00D7038C /* TTTDataTransformer.m in Sources */,
@@ -1720,7 +1699,6 @@
4CE8246F16E2E93400573141 /* MPOverlayWindowController.m in Sources */, 4CE8246F16E2E93400573141 /* MPOverlayWindowController.m in Sources */,
4CE8247516E2F2B900573141 /* MPOverlayView.m in Sources */, 4CE8247516E2F2B900573141 /* MPOverlayView.m in Sources */,
4C7B63761C0CB51F00D7038C /* TTTJSONTransformer.m in Sources */, 4C7B63761C0CB51F00D7038C /* TTTJSONTransformer.m in Sources */,
4CB9D77F1D70CE6B00F43F76 /* MPModelChangeObserving.m in Sources */,
4C77547516E55FE800970E02 /* MPInspectorViewController.m in Sources */, 4C77547516E55FE800970E02 /* MPInspectorViewController.m in Sources */,
4C89F524182FB4740069C73C /* MPAutotypeCommand.m in Sources */, 4C89F524182FB4740069C73C /* MPAutotypeCommand.m in Sources */,
4CFC53BF16E94729007396BE /* MPShadowBox.m in Sources */, 4CFC53BF16E94729007396BE /* MPShadowBox.m in Sources */,
@@ -1740,7 +1718,6 @@
4CE296191842A166005F01CE /* MPAutotypePaste.m in Sources */, 4CE296191842A166005F01CE /* MPAutotypePaste.m in Sources */,
4C569D9E17652B0600595B62 /* MPConstants.m in Sources */, 4C569D9E17652B0600595B62 /* MPConstants.m in Sources */,
4C569DA117652BFE00595B62 /* MPEntryTableDataSource.m in Sources */, 4C569DA117652BFE00595B62 /* MPEntryTableDataSource.m in Sources */,
4CDE7B161D660983008C4160 /* MPObjectController.m in Sources */,
4C7B63711C0CB51F00D7038C /* NSValueTransformer+TransformerKit.m in Sources */, 4C7B63711C0CB51F00D7038C /* NSValueTransformer+TransformerKit.m in Sources */,
4CD034AA1BFE113B003C002C /* MPPlugin.m in Sources */, 4CD034AA1BFE113B003C002C /* MPPlugin.m in Sources */,
4CA2335A176DBFE100F0B6AC /* MPLockDaemon.m in Sources */, 4CA2335A176DBFE100F0B6AC /* MPLockDaemon.m in Sources */,
@@ -1761,7 +1738,6 @@
4C25703F1BF11C2300D39416 /* MPPluginSettingsController.m in Sources */, 4C25703F1BF11C2300D39416 /* MPPluginSettingsController.m in Sources */,
4CF6C711176F4533007A811D /* MPStringLengthValueTransformer.m in Sources */, 4CF6C711176F4533007A811D /* MPStringLengthValueTransformer.m in Sources */,
4CD5D705177A5F3300100649 /* MPDatabaseSettingsWindowController.m in Sources */, 4CD5D705177A5F3300100649 /* MPDatabaseSettingsWindowController.m in Sources */,
4C74DD07177BD1640034A9DB /* MPCustomFieldView.m in Sources */,
4C4FCE15177CFE6B00BBF7AE /* MPCustomFieldTableCellView.m in Sources */, 4C4FCE15177CFE6B00BBF7AE /* MPCustomFieldTableCellView.m in Sources */,
4C26C34B18D8D5A300CF1A1C /* MPPreviewViewController.m in Sources */, 4C26C34B18D8D5A300CF1A1C /* MPPreviewViewController.m in Sources */,
4C4B728518E4B9B400A1A5D5 /* MPDockTileHelper.m in Sources */, 4C4B728518E4B9B400A1A5D5 /* MPDockTileHelper.m in Sources */,

View File

@@ -7,16 +7,19 @@
// //
#import "MPCustomFieldTableCellView.h" #import "MPCustomFieldTableCellView.h"
#import "MPDocument.h"
@implementation MPCustomFieldTableCellView @implementation MPCustomFieldTableCellView
- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle { - (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle {
[super setBackgroundStyle:NSBackgroundStyleLight]; super.backgroundStyle = NSBackgroundStyleLight;
} }
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath { - (void)setValue:(id)value forKeyPath:(NSString *)keyPath {
NSLog(@"%@ setValue:forKeyPath:%@", NSStringFromClass([self class]), keyPath); if([keyPath hasPrefix:@"objectValue."]) {
[self.window.windowController.document willChangeModelProperty];
[super setValue:value forKeyPath:keyPath];
[self.window.windowController.document didChangeModelProperty];
}
[super setValue:value forKeyPath:keyPath]; [super setValue:value forKeyPath:keyPath];
} }
@end @end

View File

@@ -30,7 +30,7 @@
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
MPCustomFieldTableCellView *view = [tableView makeViewWithIdentifier:@"SelectedCell" owner:tableView]; MPCustomFieldTableCellView *view = [tableView makeViewWithIdentifier:@"SelectedCell" owner:tableView];
[view.labelTextField bind:NSValueBinding [view.labelTextField bind:NSValueBinding
toObject:view toObject:view
withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(objectValue)), NSStringFromSelector(@selector(key))] withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(objectValue)), NSStringFromSelector(@selector(key))]

View File

@@ -60,9 +60,9 @@ typedef NS_ENUM(NSUInteger, MPDatePreset) {
- (IBAction)useDate:(id)sender { - (IBAction)useDate:(id)sender {
KPKTimeInfo *timeInfo = [self.representedObject timeInfo]; KPKTimeInfo *timeInfo = [self.representedObject timeInfo];
[self willChangeValueForRepresentedObjectKeyPath:[NSString stringWithFormat:@"%@.%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(expirationDate))]]; [self.windowController.document willChangeModelProperty];
timeInfo.expirationDate = self.datePicker.dateValue; timeInfo.expirationDate = self.datePicker.dateValue;
[self didChangeValueForRepresentedObjectKeyPath:[NSString stringWithFormat:@"%@.%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(expirationDate))]]; [self.windowController.document didChangeModelProperty];
[self.view.window performClose:sender]; [self.view.window performClose:sender];
} }

View File

@@ -0,0 +1,24 @@
//
// MPDocument+ModelChange.m
// MacPass
//
// Created by Michael Starke on 30/08/16.
// Copyright © 2016 HicknHack Software GmbH. All rights reserved.
//
#import "MPDocument.h"
NSString *const MPDocumentWillChangeModelPropertyNotification = @"com.hicknhack.macpass.MPDocumentWillChangeModelPropertyNotification";
NSString *const MPDocumentDidChangeModelPropertyNotification = @"com.hicknhack.macpass.MPDocumentDidChangeModelPropertyNotification";
@implementation MPDocument (ModelChange)
- (void)willChangeModelProperty {
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentWillChangeModelPropertyNotification object:self];
}
- (void)didChangeModelProperty {
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidChangeModelPropertyNotification object:self];
}
@end

View File

@@ -224,6 +224,27 @@ FOUNDATION_EXPORT NSString *const MPDocumentDidExitHistoryNotification;
@end @end
#pragma mark -
#pragma mark ModelChanges
/**
* Notifications will be posted by the document to inform about changes to a model property being displayed
*/
FOUNDATION_EXPORT NSString *const MPDocumentWillChangeModelPropertyNotification;
FOUNDATION_EXPORT NSString *const MPDocumentDidChangeModelPropertyNotification;
@interface MPDocument (ModelChange)
/**
* Call this on the document ot inform it about changes about to happen. This is an entry point for views and controllers to notify others about changes done to the model.
* You coudl also observer modification times on objects but this way it's impossible to determine the source of the change. Undo/Redo or external plugins or merging can all introduce
* changes to a database that aren't relevant.
* The main use case for this is to update the history of entries on editing
*/
- (void)willChangeModelProperty;
- (void)didChangeModelProperty;
@end
#pragma mark - #pragma mark -
#pragma mark Search #pragma mark Search

View File

@@ -34,9 +34,9 @@
- (IBAction)useDefault:(id)sender { - (IBAction)useDefault:(id)sender {
KPKNode *node = self.representedObject; KPKNode *node = self.representedObject;
[self willChangeValueForRepresentedObjectKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(iconId))]]; [self.windowController.document willChangeModelProperty];
node.iconId = [[node class] defaultIcon]; node.iconId = [[node class] defaultIcon];
[self didChangeValueForRepresentedObjectKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(iconId))]]; [self.windowController.document didChangeModelProperty];
[self.view.window performClose:sender]; [self.view.window performClose:sender];
} }
@@ -50,9 +50,9 @@
NSUInteger buttonIndex = [self.iconCollectionView.content indexOfObject:image]; NSUInteger buttonIndex = [self.iconCollectionView.content indexOfObject:image];
NSInteger newIconId = ((NSNumber *)[MPIconHelper databaseIconTypes][buttonIndex]).integerValue; NSInteger newIconId = ((NSNumber *)[MPIconHelper databaseIconTypes][buttonIndex]).integerValue;
KPKNode *node = self.representedObject; KPKNode *node = self.representedObject;
[self willChangeValueForRepresentedObjectKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(iconId))]]; [self.windowController.document willChangeModelProperty];
node.iconId = newIconId; node.iconId = newIconId;
[self didChangeValueForRepresentedObjectKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(iconId))]]; [self.windowController.document didChangeModelProperty];
[self.view.window performClose:sender]; [self.view.window performClose:sender];
} }

View File

@@ -64,14 +64,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
self.groupViewController = [[MPGroupInspectorViewController alloc] init]; self.groupViewController = [[MPGroupInspectorViewController alloc] init];
self.didPushHistory = NO; self.didPushHistory = NO;
/* subviewcontrollers will notify us about a change so we can handle the history pushing */ /* subviewcontrollers will notify us about a change so we can handle the history pushing */
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_willChangeValueForRepresentedObjectNotification:)
name:MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification
object:self.entryViewController];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_willChangeValueForRepresentedObjectNotification:)
name:MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification
object:self.groupViewController];
} }
return self; return self;
} }
@@ -121,6 +113,12 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
selector:@selector(_didChangeCurrentItem:) selector:@selector(_didChangeCurrentItem:)
name:MPDocumentCurrentItemChangedNotification name:MPDocumentCurrentItemChangedNotification
object:document]; object:document];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_willChangeValueForRepresentedObjectNotification:)
name:MPDocumentWillChangeModelPropertyNotification
object:document];
[self.entryViewController registerNotificationsForDocument:document]; [self.entryViewController registerNotificationsForDocument:document];
} }
@@ -176,10 +174,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
self.popover.delegate = self; self.popover.delegate = self;
self.popover.behavior = NSPopoverBehaviorTransient; self.popover.behavior = NSPopoverBehaviorTransient;
MPIconSelectViewController *vc = [[MPIconSelectViewController alloc] init]; MPIconSelectViewController *vc = [[MPIconSelectViewController alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_willChangeValueForRepresentedObjectNotification:)
name:MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification
object:vc];
vc.representedObject = self.representedObject; vc.representedObject = self.representedObject;
vc.popover = self.popover; vc.popover = self.popover;
self.popover.contentViewController = vc; self.popover.contentViewController = vc;
@@ -195,10 +189,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
self.popover.delegate = self; self.popover.delegate = self;
self.popover.behavior = NSPopoverBehaviorTransient; self.popover.behavior = NSPopoverBehaviorTransient;
MPDatePickingViewController *vc = [[MPDatePickingViewController alloc] init]; MPDatePickingViewController *vc = [[MPDatePickingViewController alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_willChangeValueForRepresentedObjectNotification:)
name:MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification
object:vc];
vc.representedObject = self.representedObject; vc.representedObject = self.representedObject;
self.popover.contentViewController = vc; self.popover.contentViewController = vc;
[self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; [self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge];
@@ -210,26 +200,12 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
- (void)popoverDidClose:(NSNotification *)notification { - (void)popoverDidClose:(NSNotification *)notification {
/* clear out the popover */ /* clear out the popover */
NSPopover *po = notification.object;
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification object:po.contentViewController];
self.popover = nil; self.popover = nil;
} }
#pragma mark - #pragma mark -
#pragma mark Bindings #pragma mark MPDocument Notifications
- (void)_willChangeModelProperty:(NSNotification *)notification {
- (void)willChangeValueForRepresentedObjectKeyPath:(NSString *)keyPath {
[super willChangeValueForKey:keyPath];
[self _recordChangesForCurrentNode];
}
#pragma mark -
#pragma mark MPViewController Notifications
- (void)_willChangeValueForRepresentedObjectNotification:(NSNotification *)notification {
[self _recordChangesForCurrentNode];
}
- (void)_recordChangesForCurrentNode {
/* TODO use uuids for pushed item? */ /* TODO use uuids for pushed item? */
if(self.didPushHistory) { if(self.didPushHistory) {
return; return;
@@ -241,9 +217,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
} }
} }
#pragma mark -
#pragma mark MPDocument Notifications
- (void)_didChangeCurrentItem:(NSNotification *)notification { - (void)_didChangeCurrentItem:(NSNotification *)notification {
MPDocument *document = notification.object; MPDocument *document = notification.object;
KPKNode *node = document.selectedNodes.count == 1 ? document.selectedNodes.firstObject : nil; KPKNode *node = document.selectedNodes.count == 1 ? document.selectedNodes.firstObject : nil;

View File

@@ -1,41 +0,0 @@
//
// MPModelChangeObserving.h
// MacPass
//
// Created by Michael Starke on 26/08/16.
// Copyright © 2016 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol MPModelChangeObserving <NSObject>
/* A class conforming to the protocoll will shoudl always fire the appropriate notifications listes below
You need to overwrite setValue:forKeyPath in a conforming class. For convinience you can just call the helper and lett it do the job
*/
FOUNDATION_EXTERN NSString *const MPWillChangeModelNotification;
FOUNDATION_EXTERN NSString *const MPDidChangeModelNotification;
FOUNDATION_EXTERN NSString *const MPModelChangeObservingKeyPathKey;
@required
- (void)beginObservingModelChangesForKeyPath:(NSString *)keyPath;
- (void)endObservingModelChangesForKeyPath:(NSString *)keyPath;
@end
/* Use this helper to fire the right notifications. You can hold an instance to help in you implementation of setValue:forKeyPath and observerModelChangesForKeyPath: */
@interface MPModelChangeObservingHelper : NSObject
+ (void)willChangeModelKeyPath:(NSString *)keyPath observer:(id<MPModelChangeObserving>)observer;
+ (void)didChangeModelKeyPath:(NSString *)keyPath observer:(id<MPModelChangeObserving>)observer;
- (void)beginObservingModelChangesForKeyPath:(NSString *)keyPath;
- (void)endObservingModelChangesForKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath forTarget:(id)target;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,75 +0,0 @@
//
// MPModelChangeObserver.m
// MacPass
//
// Created by Michael Starke on 26/08/16.
// Copyright © 2016 HicknHack Software GmbH. All rights reserved.
//
#import "MPModelChangeObserving.h"
NSString *const MPWillChangeModelNotification = @"com.hicknhack.macpass.MPWillChangeModelNotification";
NSString *const MPDidChangeModelNotification = @"com.hicknhack.macpass.MPDidChangeModelNotification";
NSString *const MPModelChangeObservingKeyPathKey = @"MPModelChangeObservingKeyPathKey";
@interface MPModelChangeObservingHelper ()
@property (strong) NSMutableSet<NSString *> *observedPaths;
@property (strong) NSMutableSet<NSString *> *matchedPathsCache;
@end
@implementation MPModelChangeObservingHelper
+ (void)willChangeModelKeyPath:(NSString *)keyPath observer:(id<MPModelChangeObserving>)observer {
[[NSNotificationCenter defaultCenter] postNotificationName:MPWillChangeModelNotification object:observer userInfo:@{ MPModelChangeObservingKeyPathKey : keyPath }];
}
+ (void)didChangeModelKeyPath:(NSString *)keyPath observer:(id<MPModelChangeObserving>)observer {
[[NSNotificationCenter defaultCenter] postNotificationName:MPDidChangeModelNotification object:observer userInfo:@{ MPModelChangeObservingKeyPathKey : keyPath }];
}
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath forTarget:(id)target {
[MPModelChangeObservingHelper willChangeModelKeyPath:keyPath observer:target];
[target setValue:value forKeyPath:keyPath];
[MPModelChangeObservingHelper didChangeModelKeyPath:keyPath observer:target];
}
- (void)beginObservingModelChangesForKeyPath:(NSString *)keyPath {
if(!self.observedPaths) {
self.observedPaths = [[NSMutableSet alloc] initWithCapacity:3];
}
[self.observedPaths addObject:keyPath];
}
- (void)endObservingModelChangesForKeyPath:(NSString *)keyPath {
[self.observedPaths removeObject:keyPath];
/* if we have nothing to observer, just clear the cache and exit */
if(self.observedPaths.count == 0) {
self.matchedPathsCache = nil;
return;
}
NSPredicate *predicat = [NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
NSString *cachedPath = evaluatedObject;
return ![cachedPath hasPrefix:keyPath];
}];
[self.matchedPathsCache filterUsingPredicate:predicat];
}
- (BOOL)_isObservingKeyPath:(NSString *)keyPath {
if([self.matchedPathsCache containsObject:keyPath]) {
return YES;
}
for(NSString *observedKeyPath in self.observedPaths) {
if([keyPath hasPrefix:observedKeyPath]) {
if(!self.matchedPathsCache) {
self.matchedPathsCache = [[NSMutableSet alloc] initWithCapacity:3];
}
[self.matchedPathsCache addObject:keyPath];
return YES;
}
}
return NO;
}
@end

View File

@@ -10,33 +10,10 @@
@interface MPViewController : NSViewController @interface MPViewController : NSViewController
APPKIT_EXTERN NSString *const MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification;
APPKIT_EXTERN NSString *const MPViewControllerDidChangeValueForRepresentedObjectKeyPathNotification;
@property (nonatomic, readonly) NSWindowController *windowController; @property (nonatomic, readonly) NSWindowController *windowController;
- (void)didLoadView; - (void)didLoadView;
- (NSResponder *)reconmendedFirstResponder; - (NSResponder *)reconmendedFirstResponder;
- (void)updateResponderChain; - (void)updateResponderChain;
#pragma mark Binding Observation
/**
* Override this to get notificied when setValue:forKeyPath will be called with a keypath starting with representedObject.
* This is always called via the binding system, hence it's usefull to anticipate model changes via the ui
*
* The default implementation calls this just befor setValue:forKeyPath: and posts a MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification
* If you override this, you shoudl call super to ensure well defined behaviour
*
* @param keyPath the full key path about to be affected
*/
- (void)willChangeValueForRepresentedObjectKeyPath:(NSString *)keyPath;
/**
* Override this to get notified when setValue:forKeyPath was called with a keypath starting with representedObject.
* The default implementation calls this right after setValue:forKeyPath: and will post a MPViewControllerDidChangeValueForRepresentedObjectKeyPathNotification.
* If you override this, you should call super to ensure well defined behavoir
*
* @param keyPath the full key path affected
*/
- (void)didChangeValueForRepresentedObjectKeyPath:(NSString *)keyPath;
@end @end

View File

@@ -7,9 +7,7 @@
// //
#import "MPViewController.h" #import "MPViewController.h"
#import "MPDocument.h"
NSString *const MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification = @"com.hicknhack.macpass.MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification";
NSString *const MPViewControllerDidChangeValueForRepresentedObjectKeyPathNotification = @"comt.hicknhack.macpass.MPViewControllerDidChangeValueForRepresentedObjectKeyPathNotification";
@implementation MPViewController @implementation MPViewController
@@ -43,21 +41,13 @@ NSString *const MPViewControllerDidChangeValueForRepresentedObjectKeyPathNotific
#pragma mark Binding observation #pragma mark Binding observation
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath { - (void)setValue:(id)value forKeyPath:(NSString *)keyPath {
if([keyPath hasPrefix:@"representedObject."]) { if([keyPath hasPrefix:@"representedObject."]) {
[self willChangeValueForRepresentedObjectKeyPath:keyPath]; [((MPDocument *)self.windowController.document) willChangeModelProperty];
[super setValue:value forKeyPath:keyPath]; [super setValue:value forKeyPath:keyPath];
[self didChangeValueForRepresentedObjectKeyPath:keyPath]; [((MPDocument *)self.windowController.document) didChangeModelProperty];
} }
else { else {
[super setValue:value forKeyPath:keyPath]; [super setValue:value forKeyPath:keyPath];
} }
} }
- (void)willChangeValueForRepresentedObjectKeyPath:(NSString *)keyPath {
[[NSNotificationCenter defaultCenter] postNotificationName:MPViewControllerWillChangeValueForRepresentedObjectKeyPathNotification object:self];
}
- (void)didChangeValueForRepresentedObjectKeyPath:(NSString *)keyPath {
[[NSNotificationCenter defaultCenter] postNotificationName:MPViewControllerDidChangeValueForRepresentedObjectKeyPathNotification object:self];
}
@end @end

View File

@@ -1,43 +0,0 @@
//
// MPTestModelChangeObservingHelper.m
// MacPass
//
// Created by Michael Starke on 29/08/16.
// Copyright © 2016 HicknHack Software GmbH. All rights reserved.
//
#import <XCTest/XCTest.h>
#import "MPModelChangeObserving.h"
@interface MPTestModelChangeObservingHelper : XCTestCase
@property (strong) MPModelChangeObservingHelper *helper;
@end
@implementation MPTestModelChangeObservingHelper
- (void)setUp {
[super setUp];
self.helper = [[MPModelChangeObservingHelper alloc] init];
}
- (void)tearDown {
self.helper = nil;
[super tearDown];
}
- (void)testAddObserver {
[self.helper beginObservingModelChangesForKeyPath:@"testKey"];
NSMutableSet *set = [self.helper valueForKey:@"observedPaths"];
XCTAssertEqual(set.count, 1, @"Observed paths contains one element");
XCTAssertTrue([set containsObject:@"testKey"], @"Observed set contains testKey");
}
- (void)testRemoveObserver {
NSString *aKeyPath = @"testKeyPath";
[self.helper beginObservingModelChangesForKeyPath:aKeyPath];
[self.helper endObservingModelChangesForKeyPath:aKeyPath];
NSMutableSet *set = [self.helper valueForKey:@"observedPaths"];
XCTAssertFalse([set containsObject:aKeyPath], @"Observed path is removed after end of observation");
}
@end