Help for transforming from OC to ASOC

Hi,

I need help for transforming the following code into ASObjC:

I tried this:


on tableView_setObjectValue_forTableColumn_row_(theTableView, theValue, aColumn, aRow)
		if theDataSource's |count|() is equal to 0 then return end
		--try
		set columnIdent to aColumn's identifier
		--log theValue
		--log columnIdent
		set theRecord to theDataSource's objectAtIndex_(aRow)
		--log theRecord
		theRecord's setObject_forKey_(theValue, columnIdent) -- ?????
		return
		--end try
	end tableView_setObjectValue_forTableColumn_row_

and the call for this handler is:


tableView_setObjectValue_forTableColumn_row_(theTableView, "111", "column5", 0)

to set (for ex.) the value “111” into the cell of the 1. row and the 5. column.

I get no result.

Heiner

Model: iMac
Browser: Safari 525.13
Operating System: Mac OS X (10.6)

I presume you’ve logged theRecord after “theRecord’s setObject_forKey_(theValue, columnIdent)” and found that all’s well there. I’d also add a “log theDatasource” there, to see if it changes.

You could try forcing KVO by using willChangeValueForKey_(theDataSource) and didChangeValueForKey_(theDataSource) either side of your setObject_forValue_.

Shane, thanks again!

My transforming to tableView_setObjectValue_forTableColumn_row_ was obviously correct and “log theDataSource” shows it.

Because I think meanwhile this method is mainly provided to enable the user to edit table cells directly and not via text fields and bindings, I put the rest of the code into an own handler (as a first step). And here I got into next troubles.

You said:

  1. I havn’t found a setObject_forValue-method in the documentation.
  2. I did this but without success (again)

property theIdentifiers : {"column2", "column3", "column4"}
	
	on berechnen_(sender)
		repeat with i from 1 to 11 -- theDataSource's |count|()
			set sum to 0
			repeat with anIdentifier in theIdentifiers --
				set a to theDataSource's valueForKey_(anIdentifier) as list
				try
					set sum to sum + (item i of a)
				end try
			end repeat -- next column
			log sum -- OK!

			willChangeValueForKey_(theDataSource)
			theDataSource's setObject_forKey_(sum, "column5") -- ????
			-- should set sum into the cell of column 5 of row i , but it fails
			didChangeValueForKey_(theDataSource)

		end repeat -- next row
	end berechnen_

Please have a look at.

Heiner

Sorry, I typed forValue but I meant forKey. Try this:

on tableView_setObjectValue_forTableColumn_row_(theTableView, theValue, aColumn, aRow)
       if theDataSource's |count|() is equal to 0 then return end
       --try
       set columnIdent to aColumn's identifier
       --log theValue
       --log columnIdent
       set theRecord to theDataSource's objectAtIndex_(aRow)
       --log theRecord
              willChangeValueForKey_(theDataSource)
    theRecord's setObject_forKey_(theValue, columnIdent) -- ?????
            didChangeValueForKey_(theDataSource)
      return
       --end try
   end tableView_setObjectValue_forTableColumn_row_

That’s not going to work if theDatasource is a list of records

That’s right – datasources are an alternative to bindings.In fact, having both sounds potentially problematic to me.

tableView: setObjectValue: forTableColumn: row: is called by the table view as a delegate method after you changed the datasource and sent reloadData: to the tableView. Don’t evoke this method directly

Stefan wrote:

Thanks Stefan, I tried to set the code meanwhile into a button-handler.

Shane wrote:

This doesn’t work.

So I did this:


on setSum_(sender)
		set theCount to theDataSource's |count|()
		repeat with i from 1 to theCount
			set sum to 0

			set theItemList to (item i of theDataSource) -- !!!
			-- log (count items of theItemList) -- OK!
			-- log column1 of theItemList -- (for ex.) OK!

			repeat with anIdentifier in theIdentifiers
				set a to theDataSource's valueForKey_(anIdentifier) as list
				try
					set sum to sum + (item i of a)
					--log sum -- OK!
					
					--willChangeValueForKey_(theItemList) -- necessary ?
					theItemList's setObject_forKey_(sum, "column5") -- !!!
					--didChangeValueForKey_(theItemList)
					
				end try
			end repeat -- next column
			set theItemList to missing value -- set back
		end repeat -- next row
	end setSum_

This works, but because it’s set into a button handler it works bumpy.
Therefore I need a method which sends the message a cell value is changed; and there can I insert the code above (I think).

I’m a fool; a simple call of a handler will do it:



property theIdentifiers : {"column2", "column3", "column4"}

on setSum()
		--set theCount to theDataSource's |count|()  -- (**) if all rows should be target
		set myRow to ((theTableView's selectedRow()) + 1) -- (*) only the selected row is target
		--repeat with i from 1 to theCount -- (**)
		set sum to 0
		-- set theItemList to (item i of theDataSource) -- (**)
		set theItemList to (item myRow of theDataSource) -- (*)
		repeat with anIdentifier in theIdentifiers
			set a to theDataSource's valueForKey_(anIdentifier) as list
			try
				-- set sum to sum + (item i of a) -- (**)
				set sum to sum + (item myRow of a) -- (*)
				theItemList's setObject_forKey_(sum, "column5")
			end try
		end repeat -- next column
		set theItemList to missing value -- set back
		--end repeat -- next row -- (**)
	end setSum


-- Table View's Setter
	on tableView_setObjectValue_forTableColumn_row_(theTableView, theValue, aColumn, aRow)
		if theDataSource's |count|() is equal to 0 then return end
		set columnIdent to aColumn's identifier
		set theRecord to theDataSource's objectAtIndex_(aRow)
		theRecord's setObject_forKey_(theValue, columnIdent)
		
		setSum()
		return
	end tableView_setObjectValue_forTableColumn_row_