0

What I want to do is building a TLV editor. The TLV-structur consists of constructed and normal items. When I add an item to a construction I need to update the length of the construction as well as the length in all above parent constructions.

I tried to do this by adding var parent: Construction? to the Construction model.

For adding it looks quite well, but when removing it gets out of sync. Anybody a good idea what is wrong? Or is there a better solution?

Here is a short demo: https://github.com/frcocoatst/test1

Model.swift:

class Item: Equatable, CustomStringConvertible {
    var id: Int?
    var tag: String = "TAG"
    var length: Int = 1
    var value: String = "VALUE"
...

class Construction: Equatable {
    var id: Int?
    var clength: Int = 0
    var parent: Construction?
    var items = [Any]()
...

ViewController.swift add an item:

 @IBAction func addItemAction(_ sender: Any) {
        print("addItemAction")
        // Make sure that there is a target construction to add a new item to.
        guard let construction = getConstructionForSelectedItem() else { return }
        
        // Create and get the instance of the new item.
        let newItem = viewModel.addItem(
            tag: itemTagOutlet.stringValue,
            length: itemValueOutlet.stringValue.count/2,
            value: itemValueOutlet.stringValue,
            comment: "ItemComment",
            construction: construction)
        
        print("update construction length")
        construction.clength += itemValueOutlet.stringValue.count/2
...
        // for all parents add length
        var parentConstruction = construction.parent
        while let pConstruction = parentConstruction
        {
            print(pConstruction)
            print(">>>update parent construction length")
            parentConstruction?.clength += itemValueOutlet.stringValue.count/2
            parentConstruction = pConstruction.parent
        }
        
        print("reload")
        // Reload the outline view and expand the construction.
        outlineView.reloadData()
        outlineView.expandItem(construction)

ViewController.swift remove an item:

    @IBAction func deleteItemAction(_ sender: Any) {
        print("deleteItemAction")
        let selectedRow = outlineView.selectedRow
        var result = false
        
        if let selectedItem = outlineView.item(atRow: selectedRow) as? Item {
            
            guard let construction = getConstructionForSelectedItem() else { return }
            
            let ctr = selectedItem.length
            construction.clength -= ctr
            
            viewModel.remove(item: selectedItem, from: construction)
            //
            print("remove item update construction length")
...
            // for all parents subtract length
            var parentConstruction = construction.parent
            while let pConstruction = parentConstruction
             {
                 print(pConstruction)
                 print(">>>update parent construction length")
                 parentConstruction?.clength -=  ctr 
                 parentConstruction = pConstruction.parent
             }
....
Fritz
  • 95
  • 7
  • Is the question about updating the data or about `NSOutlineView`? Post a [mre] in the question please. – Willeke Mar 12 '23 at 11:04
  • Is the data correct after `viewModel.remove(item: selectedItem, from: construction)`? – Willeke Mar 12 '23 at 20:43
  • Actually adding/removing is not working as I thought it could work. Adding works if you add items linearly. There are issues when you add/insert into constructions later. There is definitely an issue because I try to add instead of insert. Deleting works worse. It is quite easy to produce something that gets out of sync ... – Fritz Mar 24 '23 at 08:01

0 Answers0