Save sidebar expanded state.
This commit is contained in:
parent
94d04e3cc2
commit
ae8f36d300
|
@ -18,7 +18,7 @@ protocol SidebarDelegate: class {
|
||||||
func sidebarInvalidatedRestorationState(_: SidebarViewController)
|
func sidebarInvalidatedRestorationState(_: SidebarViewController)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc class SidebarViewController: NSViewController, NSOutlineViewDelegate, NSOutlineViewDataSource, NSMenuDelegate, UndoableCommandRunner {
|
@objc class SidebarViewController: NSViewController, NSOutlineViewDelegate, NSMenuDelegate, UndoableCommandRunner {
|
||||||
|
|
||||||
@IBOutlet var outlineView: SidebarOutlineView!
|
@IBOutlet var outlineView: SidebarOutlineView!
|
||||||
|
|
||||||
|
@ -39,9 +39,9 @@ protocol SidebarDelegate: class {
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
treeControllerDelegate.isReadFiltered = newValue
|
treeControllerDelegate.isReadFiltered = newValue
|
||||||
delegate?.sidebarInvalidatedRestorationState(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var expandedTable = Set<ContainerIdentifier>()
|
||||||
|
|
||||||
var undoableCommands = [UndoableCommand]()
|
var undoableCommands = [UndoableCommand]()
|
||||||
private var animatingChanges = false
|
private var animatingChanges = false
|
||||||
|
@ -77,28 +77,31 @@ protocol SidebarDelegate: class {
|
||||||
|
|
||||||
outlineView.reloadData()
|
outlineView.reloadData()
|
||||||
|
|
||||||
// Always expand all group items on initial display.
|
// Expand top level items by default. If there is state to restore, overlay this.
|
||||||
var row = 0
|
for topLevelNode in treeController.rootNode.childNodes {
|
||||||
while(true) {
|
if let containerID = (topLevelNode.representedObject as? ContainerIdentifiable)?.containerID {
|
||||||
guard let item = outlineView.item(atRow: row) else {
|
expandedTable.insert(containerID)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
let node = item as! Node
|
|
||||||
if node.isGroupItem {
|
|
||||||
outlineView.expandItem(item)
|
|
||||||
}
|
|
||||||
row += 1
|
|
||||||
}
|
}
|
||||||
|
expandNodes()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: State Restoration
|
// MARK: State Restoration
|
||||||
|
|
||||||
func saveState(to coder: NSCoder) {
|
func saveState(to coder: NSCoder) {
|
||||||
coder.encode(isReadFiltered, forKey: UserInfoKey.readFeedsFilterState)
|
coder.encode(isReadFiltered, forKey: UserInfoKey.readFeedsFilterState)
|
||||||
|
coder.encode(expandedTable.map( { $0.userInfo }), forKey: UserInfoKey.containerExpandedWindowState)
|
||||||
}
|
}
|
||||||
|
|
||||||
func restoreState(from coder: NSCoder) {
|
func restoreState(from coder: NSCoder) {
|
||||||
isReadFiltered = coder.decodeBool(forKey: UserInfoKey.readFeedsFilterState)
|
isReadFiltered = coder.decodeBool(forKey: UserInfoKey.readFeedsFilterState)
|
||||||
|
|
||||||
|
if let containerExpandedWindowState = try? coder.decodeTopLevelObject(forKey: UserInfoKey.containerExpandedWindowState) as? [[AnyHashable: AnyHashable]] {
|
||||||
|
let containerIdentifers = containerExpandedWindowState.compactMap( { ContainerIdentifier(userInfo: $0) })
|
||||||
|
expandedTable = Set(containerIdentifers)
|
||||||
|
}
|
||||||
|
|
||||||
rebuildTreeAndRestoreSelection()
|
rebuildTreeAndRestoreSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,6 +323,28 @@ protocol SidebarDelegate: class {
|
||||||
selectionDidChange(selectedObjects.isEmpty ? nil : selectedObjects)
|
selectionDidChange(selectedObjects.isEmpty ? nil : selectedObjects)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func outlineViewItemDidExpand(_ notification: Notification) {
|
||||||
|
guard let node = notification.userInfo?["NSObject"] as? Node,
|
||||||
|
let containerID = (node.representedObject as? ContainerIdentifiable)?.containerID else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !expandedTable.contains(containerID) {
|
||||||
|
expandedTable.insert(containerID)
|
||||||
|
delegate?.sidebarInvalidatedRestorationState(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func outlineViewItemDidCollapse(_ notification: Notification) {
|
||||||
|
guard let node = notification.userInfo?["NSObject"] as? Node,
|
||||||
|
let containerID = (node.representedObject as? ContainerIdentifiable)?.containerID else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if expandedTable.contains(containerID) {
|
||||||
|
expandedTable.remove(containerID)
|
||||||
|
delegate?.sidebarInvalidatedRestorationState(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//MARK: - Node Manipulation
|
//MARK: - Node Manipulation
|
||||||
|
|
||||||
func deleteNodes(_ nodes: [Node]) {
|
func deleteNodes(_ nodes: [Node]) {
|
||||||
|
@ -378,6 +403,7 @@ protocol SidebarDelegate: class {
|
||||||
} else {
|
} else {
|
||||||
isReadFiltered = true
|
isReadFiltered = true
|
||||||
}
|
}
|
||||||
|
delegate?.sidebarInvalidatedRestorationState(self)
|
||||||
rebuildTreeAndRestoreSelection()
|
rebuildTreeAndRestoreSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,6 +513,21 @@ private extension SidebarViewController {
|
||||||
treeController.rebuild()
|
treeController.rebuild()
|
||||||
treeControllerDelegate.resetFilterExceptions()
|
treeControllerDelegate.resetFilterExceptions()
|
||||||
outlineView.reloadData()
|
outlineView.reloadData()
|
||||||
|
expandNodes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandNodes() {
|
||||||
|
treeController.visitNodes(expandNodesVisitor(node:))
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandNodesVisitor(node: Node) {
|
||||||
|
if let containerID = (node.representedObject as? ContainerIdentifiable)?.containerID {
|
||||||
|
if expandedTable.contains(containerID) {
|
||||||
|
outlineView.expandItem(node)
|
||||||
|
} else {
|
||||||
|
outlineView.collapseItem(node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue