Error when removing last row of liststore

I have a simple liststore and I have attached a sub to add/remove rows. Everything is fine unless it is the last row, when I get
variable not allowed to be undef where GtkTreeIter error.
Everything works but it throws the error.
Any idea how to remove the error, as it seems remove automatically sets iter to next iter, which obviously does not exit

Code

$dirview[0]->signal_connect('changed'=>sub{
	my ($cell,$row,$iter)= @_;
	my $iter1=$dirset{dir_model}->get_iter_from_string($row);
	#print $iter1,$row,$cell,$dirset{dir_model}->get($iter1,5),"\n";
	my $value=$cell->get('model')->get($iter,0);
	if ($value eq 'Delete'){
		my $sopts;
		print $iter1,$row,$cell,$dirset{dir_model}->get($iter1,5),"\n";
		$sopts->{model}=$dirset{dir_model};
		$dbh->do('DELETE from dirctl where rowid=$1',undef,$dirset{dir_model}->get($iter1,5));
		#$sopts->{model}->move_before($iter1);
		my $rem=$sopts->{iter}=$sopts->{model}->remove($iter1) unless $dirset{dir_model}->iter_n_children==1;
		my $metachk=($dbh->selectrow_array('SELECT  EXISTS(SELECT 1 FROM dirctl WHERE dirtype IN (\'meta\',\'playlist\'))'))[0];
		print '1244 ',$rem,"\n";
		if ($metachk==0){
			$dbh->do ('UPDATE configgen SET value1=\'no\' WHERE type1=\'dlna\'');
			$dirset{head_model}->set($dirset{head_model}->get_iter_from_string(0),0,0)
		}
		
		}

	return 1;
}
);

This looks like it could be an offset problem.

0 1 2 3 4 5 list
1 2 3 4 5 6 db rowid

Get list element at db rowid by moving the list iter at 6 back one but there isn’t a valid list iter at 6 so you get a warning. Moving the iter back one works for db rowid’s 1-5 though without a warning.

Go the other way and get an iter at list(db rowid-1) and then you don’t have to move it back one. Another problem will come up though if you are deleting rows from the database and there are gaps in your rowid. Best to have the list and rowid to match so that you have a one to one relationship and what is deleted from one is deleted from the other.

Eric

Just some clarification
The $row for the iter comes from the changed signal, not the database
The rowid is an identifier from the table which is put into column 5 and has no direct relationship to the $row.
ie:

my ($cell,$row,$iter)= @_;
	my $iter1=$dirset{dir_model}->get_iter_from_string($row);

Hmmm, I don’t have it figured out. If you have a one to one relationship and referential integrity enforced between the database and treeview list id’s it should work. I am missing something, I saw the move_before($iter1); and thought it might be an offset problem.

Eric

The move_before was something was something I tried to resolve the issue that didn’t work

I now have something that seems to work by wrapping the remove_row in an idle function if it is the last row, code

$dirview[0]->signal_connect('changed'=>sub{
		my ($cell,$row,$itercombo)= @_;
		my $itermodel=$dirset{dir_model}->get_iter_from_string($row);
		#print $iter1,$row,$cell,$dirset{dir_model}->get($iter1,5),"\n";
		my $value=$cell->get('model')->get($itercombo,0);

##using foreach sub to get the last row index counted from zero
		my $rowsel1 = -1;
			$dirset{dir_model}->foreach(sub{
				print '1224 ',$rowsel,"\n";
				$rowsel1++;
			return 0}
			);

if ($value eq 'Delete'){

		$sopts->{model}=$dirset{dir_model};
			
			if ($sopts->{model}->get($itermodel,0) !~/(?:dir|source|del)/){
##update database using db rowid stored in column 5
			$dbh->do('DELETE from dirctl where rowid=$1',undef,$dirset{dir_model}->get($itermodel,5));
			
		if ($row == $rowsel1){
			Glib::Idle->add(sub {
			$sopts->{model}->remove($itermodel); 
		      }
			);
			}
		else {
			$sopts->{model}->remove($itermodel); 
			}
});

Good deal! You got it to work.

A little while back there was a discussion here called

“Need help with a custom sort function Platform”

Near the end of the discussion there is some C code that pulls the database table data and copies it into a liststore. This way you can update and delete from the table and then get the contents without having to worry about updating and deleting both the liststore and the database. Leave the database to handle the transactions. Also maybe check the row count of the table and list to see if they are equal and if they aren’t just re-query the database for consistent data. The downside is that single records are not deleted from both the database and the liststore which could be a performance problem.

Just some thoughts about it. Probably depends on the app.

Eric

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.