# $Id: MessageList.pm,v 1.6 2001/09/09 15:08:29 muhri Exp $
# -*- perl -*-
package Pronto::MessageList;
use strict;

sub refresh {
	if ($main::prefs{'messageview'} eq "ctree") {
		&refresh_ctree();
	} else {
		&refresh_messages();
	}	
}


sub get_position
{
	my $first = get_last_selected_node_or_row();
	if ($main::prefs{'messageview'} eq "ctree") {
		$first = get_node_row($first);
	}
	return $first;
}	

sub set_position
{
	my ($first) = @_;
	my @rows = $main::message_clist->rows();
	if (scalar(@rows) > 0) {
		while ($first >= $main::message_clist->rows) { $first --; }
		Gtk::CList::moveto($main::message_clist,$first,0,'0.5','0.5');
		Gtk::CList::select_row($main::message_clist,$first,0);
		if ($first !=0 && $first != -1) {
			Gtk::CList::set_focus_row($main::message_clist,$first);
		}
	}
}	


sub make_clist {
	my ($recreate)  = @_;
	my($mp_view_raw,@msg_headers,$mp_sep1,$mp_mar,$mp_sep2,
	$mp_plus,$mp_minus,$mp_sep3,$mp_view_header,$mp_nextunread,$mp_add2ab,
	$mp_sep4,$mp_delete,$mp_copy,$mp_move,$mp_view,$selectedmessage);
	
	if (defined $recreate and $recreate eq "y") {
		$Pronto::FolderMenus::pcp_menus{0}->detach;
		$Pronto::FolderMenus::pmv_menus{0}->detach;
		$main::message_clist->destroy;
		$main::root_window->{'search'}->destroy;
		$main::root_window->{'button'}->destroy;
		$main::root_window->{'scroll2'}->destroy;
		$Pronto::FolderMenus::pcp_items{0} = new Gtk::MenuItem("Copy");
        	$Pronto::FolderMenus::pcp_items{0}->set_submenu($Pronto::FolderMenus::pcp_menus{0});
 		$Pronto::FolderMenus::pmv_items{0} = new Gtk::MenuItem("Move");
 		$Pronto::FolderMenus::pmv_items{0}->set_submenu($Pronto::FolderMenus::pmv_menus{0});
	}

	@msg_headers = (" "," "," ",_("Score"), ,_("From"),_("Subject"),_("Date"), _("Server"), _("Hidden Field"));
	 if ($main::prefs{'messageview'} eq "clist") {
		 $main::message_clist = new_with_titles Gtk::CList(@msg_headers);		 
 	} elsif ($main::prefs{'messageview'} eq "ctree") {
 		$main::message_clist = new_with_titles Gtk::CTree(5,@msg_headers);
		$main::message_clist->set_expander_style($main::prefs{'expander'});
	}
	$main::message_clist->set_compare_func(\&my_sort_func);
 	if($main::prefs{'prioritycolumn'} eq "n") {
        	$main::message_clist->set_column_visibility(0,0);
 	}
 	if($main::prefs{'attachcolumn'} eq "n" ) {
		$main::message_clist->set_column_visibility(1,0);
 	}
 	if($main::prefs{'msgnewcolumn'} eq "n" ) {
        	$main::message_clist->set_column_visibility(2,0);
 	}
 	if($main::prefs{'servercolumn'} eq "n") {
		$main::message_clist->set_column_visibility(7,0);
	}	
 	@{$main::message_clist->{'labels'}} = @msg_headers;
 	$main::message_clist->{'name'} = "message";
 	if (defined $main::prefs{'Scoring'} && $main::prefs{'Scoring'} ne "y") { $main::message_clist->set_column_visibility(3, 0); }
 	$main::message_clist->set_column_justification(3, "center");
 	$main::message_clist->set_column_visibility(8, 0);
 	$main::message_clist->column_titles_active;
 	$main::message_clist->set_selection_mode('extended');
 	if (not defined $main::prefs{'MessageListColWidth4'}) { $main::message_clist->set_column_width(4,127); }
 	if (not defined $main::prefs{'MessageListColWidth5'}) { $main::message_clist->set_column_width(5,175); }
 	for (my $i = 0; $i < 7; $i++) {
 		if (defined $main::prefs{'MessageListColWidth' . $i}) {
			$main::message_clist->set_column_width($i, $main::prefs{'MessageListColWidth' . $i});
		}
	 }
 	$main::message_clist->set_row_height(17);
 	if ($main::prefs{'messageview'} eq "clist") {
 		$main::message_clist->signal_connect('click_column', \&click_column);
 	} elsif ($main::prefs{'messageview'} eq "ctree") {
 		$main::message_clist->signal_connect('click_column', \&ctree_click_column);
 		$main::message_clist->signal_connect('tree_collapse', \&ctree_collapse);
 		$main::message_clist->signal_connect('tree_expand',\&ctree_expand);
 	}
 	$main::message_clist->signal_connect('button_press_event',\&click_clist, 1);
 	$main::message_clist->signal_connect('key_press_event', \&key_pressed);
	$main::message_clist->{'sortcol'} = $main::prefs{'SortCol'};
 	$main::message_clist->{'sortdir'} = $main::prefs{'SortDir'};
 	$main::message_clist->signal_connect("resize-column" => sub {my ($d, $c, $w)=@_; $main::prefs{'MessageListColWidth'. $c}=$w;});
 	$main::root_window->{'scroll2'} = new Gtk::ScrolledWindow(undef,undef);
 	$main::root_window->{'scroll2'}->set_policy('automatic','automatic');
 	if ($main::prefs{'Layout'} == 2) {
   	     my ($swidth,$sheight) = &main::get_win_size("secondPane",225,125);
	     $main::root_window->{'scroll2'}->set_usize($swidth,$sheight);
             $main::root_window->{'scroll2'}->signal_connect("size-allocate" => \&main::save_sizepane2);
							        
	}								
	$main::root_window->{'scroll2'}->add($main::message_clist);
 	$main::root_window->{'search'} = new Gtk::Button(_("Search"));
 	$main::root_window->{'button'} = new Gtk::HBox(0,0);
 	$main::root_window->{'button'}->show;
 	$main::root_window->{'button'}->pack_start($main::root_window->{'search'},1,1,5);
 	$main::root_window->{'search'}->signal_connect("clicked" =>\&Pronto::Search::search_win);
 	$main::message_clist->{'popup'} = new Gtk::Menu;
 	$mp_sep1 = new Gtk::MenuItem;
 	$main::message_clist->{'popup'}->append($mp_sep1);
 	
 	if ($main::prefs{'messageview'} eq "ctree") {
 	
		my $collapse = new Gtk::MenuItem(_("Collapse Threads .."));
	 	$collapse->signal_connect("activate", sub { $main::message_clist->collapse_recursive(undef) });
	 	$main::message_clist->{'popup'}->append($collapse);
	 	my $expand = new Gtk::MenuItem(_("Expand Threads .."));
	 	$expand->signal_connect("activate", sub { $main::message_clist->expand_recursive(undef)});
	        $main::message_clist->{'popup'}->append($expand);
	 	my $sep = new Gtk::MenuItem;
		$main::message_clist->{'popup'}->append($sep);
	 }
 
	 $mp_mar = new Gtk::MenuItem(_("Mark as Read .."));
	 $mp_mar->signal_connect("activate", sub { &Pronto::Data::Message::mark_as_read("read") });
	 $main::message_clist->{'popup'}->append($mp_mar);
	 my $mp_mar_unread = new Gtk::MenuItem(_("Mark as Unread .."));
	 $mp_mar_unread->signal_connect("activate", sub { &Pronto::Data::Message::mark_as_read("unread") });
	 $main::message_clist->{'popup'}->append($mp_mar_unread);
	 $mp_sep2 = new Gtk::MenuItem();
	 $main::message_clist->{'popup'}->append($mp_sep2);
	 $mp_plus = new Gtk::MenuItem(_("Score +1"));
	 $main::message_clist->{'popup'}->append($mp_plus);
	 $mp_minus = new Gtk::MenuItem(_("Score -1"));
	 $main::message_clist->{'popup'}->append($mp_minus);
	 $mp_sep3 = new Gtk::MenuItem();
	 $main::message_clist->{'popup'}->append($mp_sep3);
	 $mp_view = new Gtk::MenuItem(_("Open in a view win"));
	 $main::message_clist->{'popup'}->append($mp_view);
	 $mp_view_header = new Gtk::MenuItem(_("View Header"));
	 $main::message_clist->{'popup'}->append($mp_view_header);
       	 $mp_view_raw = new Gtk::MenuItem(_("View Source"));
 	$main::message_clist->{'popup'}->append($mp_view_raw);
 	$mp_add2ab = new Gtk::MenuItem(_("Add to Addressbook"));
 	$main::message_clist->{'popup'}->append($mp_add2ab);
 	$mp_sep4 = new Gtk::MenuItem;
 	$main::message_clist->{'popup'}->append($mp_sep4);
 	my $refilter = new Gtk::MenuItem(_("Refilter"));
 	$refilter->signal_connect("activate" => \&Pronto::Data::Message::refilter);
 	$main::message_clist->{'popup'}->append($refilter);
 	$mp_delete = new Gtk::MenuItem(_("Delete"));
 	$mp_delete->signal_connect("activate" => \&Pronto::MainWindow::handle_delete_msgs);
 	$main::message_clist->{'popup'}->append($mp_delete);

 	my $serverstatmenu = new Gtk::Menu;
	$serverstatmenu->{'ServerLeave'} = new Gtk::MenuItem(_("Leave on server"));
 	$serverstatmenu->{'ServerLeave'}->signal_connect("activate", sub { &Pronto::MainWindow::handle_msgs_server_status(2) });
	$serverstatmenu->{'ServerFetch'} = new Gtk::MenuItem(_("Fetch from server"));
 	$serverstatmenu->{'ServerFetch'}->signal_connect("activate", sub { &Pronto::MainWindow::handle_msgs_server_status(4) });
	$serverstatmenu->{'ServerFetchDelete'} = new Gtk::MenuItem(_("Fetch & Delete"));
 	$serverstatmenu->{'ServerFetchDelete'}->signal_connect("activate", sub { &Pronto::MainWindow::handle_msgs_server_status(5) });
	$serverstatmenu->{'ServerDelete'} = new Gtk::MenuItem(_("Delete from server"));
 	$serverstatmenu->{'ServerDelete'}->signal_connect("activate", sub { &Pronto::MainWindow::handle_msgs_server_status(3) });
 	$serverstatmenu->append($serverstatmenu->{'ServerLeave'});
 	$serverstatmenu->append($serverstatmenu->{'ServerFetch'});
 	$serverstatmenu->append($serverstatmenu->{'ServerFetchDelete'});
 	$serverstatmenu->append($serverstatmenu->{'ServerDelete'});
	my $mp_servermenu = new Gtk::MenuItem(_("Server Status"));
 	$mp_servermenu->set_submenu($serverstatmenu);
 	$main::message_clist->{'popup'}->append($mp_servermenu);
	
	$main::message_clist->{'popup'}->append($Pronto::FolderMenus::pcp_items{0});
 	$main::message_clist->{'popup'}->append($Pronto::FolderMenus::pmv_items{0});
 	my $filtermenu = new Gtk::Menu;
 	$filtermenu->{'from'} = new Gtk::MenuItem(_("Based on From"));
 	$filtermenu->{'from'}->signal_connect("activate", sub { &Pronto::Filter::filter_editwin(undef,undef,"newfromlist",undef,"from") });
 	$filtermenu->{'to'} = new Gtk::MenuItem(_("Based on To"));
 	$filtermenu->{'to'}->signal_connect("activate", sub { &Pronto::Filter::filter_editwin(undef,undef,"newfromlist",undef,"to");});
 	$filtermenu->{'subject'}=new Gtk::MenuItem(_("Based on Subject"));
 	$filtermenu->{'subject'}->signal_connect("activate", sub { &Pronto::Filter::filter_editwin(undef,undef,"newfromlist",undef,"subject");});
 	$filtermenu->append($filtermenu->{'from'});
 	$filtermenu->append($filtermenu->{'to'});
 	$filtermenu->append($filtermenu->{'subject'});
 	my $mp_filter = new Gtk::MenuItem(_("Create Filter"));
 	$mp_filter->set_submenu($filtermenu);
 	$main::message_clist->{'popup'}->append($mp_filter);
 	$main::message_clist->{'popup'}->show_all;
 	$mp_view->signal_connect("activate", sub { &Pronto::Read::message_view_win(undef,1);});
 	$mp_view_header->signal_connect("activate" =>, sub {Pronto::Read::head_view(3)});
 	$mp_view_raw->signal_connect("activate" => \&Pronto::Read::view_raw);
 	$mp_plus->signal_connect("activate" => \&Pronto::Data::Message::scoring, $main::message_clist, "up");
 	$mp_minus->signal_connect("activate" => \&Pronto::Data::Message::scoring, $main::message_clist, "down");
 	$mp_add2ab->signal_connect("activate" => \&Pronto::Data::Message::clist2ab, $main::message_clist);
 	if (defined $recreate and $recreate eq "y") { 
 		$main::root_window->{'scroll2'}->show;
 		$main::root_window->{'search'}->show;
 		$main::root_window->{'message_vbox'}->pack_start($main::root_window->{'scroll2'},1,1,0);
 		$main::root_window->{'message_vbox'}->pack_start($main::root_window->{'button'},0,0,0);
 		$main::message_clist->show 
   	}
 return 1;
}

sub my_sort_func
{
	my ($clist, $first, $second) = @_;
	if ($first =~ /^\d+$/) {
		if ($first > $second) { return -1; }
		if ($first == $second) { return 0; }
		return 2;
	}
	my @stuff = ($first,$second);
	my @sorted = sort {uc($a) cmp uc($b)} @stuff;
	if ($sorted[0] eq $first) { return -1; }
	if ($first eq $second) { return 0; }
	return 2;		
}

sub key_pressed
{
	my ($clist, $event) = @_;
	&Pronto::MainWindow::handle_delete_msgs if ($event->{keyval} == 65535);
	return 1;
}

sub make_clist_sigs {
	
	my ($clipmask,$clip,$pixmap,$mask,$exclame,$newm,$newm_mask,$newmp,$clippixmap);
  	if ($main::prefs{'messageview'} eq "clist") {
		 $main::message_clist->signal_connect('select_row', \&main::selection_handler,
        	 	$main::root_window->{'html_view'}, $main::attach_menu, $main::view_attach_menu, $main::root_window->{'table1'});
	} elsif ($main::prefs{'messageview'} eq "ctree") {
	$main::message_clist->signal_connect('tree_select_row', \&main::selection_handler,
        	$main::root_window->{'html_view'}, $main::attach_menu, $main::view_attach_menu, $main::root_window->{'table1'});
	}
	
	if ($main::prefs{'Drag'}) {
		&main::set_clist_drag_signals();
	}	
	       
	
 	if(-f "$main::prefs{'PixmapDir'}/paperclip.xpm") {
 		($main::root_window->{'clippixmap'},$main::root_window->{'clipmask'})=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'), "$main::prefs{'PixmapDir'}/paperclip.xpm");
 	}
 	else {
		($main::root_window->{'clippixmap'},$main::root_window->{'clipmask'})=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$main::message_clist->style->bg('normal'), @main::dummy_pixmap);
 	}
 	$main::root_window->{'clip'} = new Gtk::Pixmap($main::root_window->{'clippixmap'}, $main::root_window->{'clipmask'});
 	$main::message_clist->set_column_widget(1, $main::root_window->{'clip'});
 	if(-f "$main::prefs{'PixmapDir'}/exclamation.xpm") {
		($main::root_window->{'pixmap'},$main::root_window->{'mask'})=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/exclamation.xpm");
	 }
	 else {
		($main::root_window->{'pixmap'},$main::root_window->{'mask'})=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),@main::dummy_pixmap);
 	}
 	$main::root_window->{'exclame'} = new Gtk::Pixmap($main::root_window->{'pixmap'}, $main::root_window->{'mask'});
 	$main::message_clist->set_column_widget(0, $main::root_window->{'exclame'});
 	if(-f "$main::prefs{'PixmapDir'}/newm.xpm") {
		($main::root_window->{'newm'},$main::root_window->{'newm_mask'}) = Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/newm.xpm");
	 }
	 else {
		($main::root_window->{'newm'},$main::root_window->{'newm_mask'}) = Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),@main::dummy_pixmap); }
	 $main::root_window->{'newmp'} = new Gtk::Pixmap($main::root_window->{'newm'},$main::root_window->{'newm_mask'});
	 $main::message_clist->set_column_widget(2, $main::root_window->{'newmp'});
	 if ($main::prefs{'messageview'} eq "clist") {
		 &click_column($main::message_clist, $main::message_clist->{'sortcol'});
	} elsif ($main::prefs{'messageview'} eq "ctree") {
		$main::message_clist->set_sort_column ( $main::prefs{'SortCol'} );
		&ctree_click_column($main::message_clist, $main::message_clist->{'sortcol'});
	}

	return 1;
}

sub click_column {
	my ($clist, $column) = @_;
	if ($column == $clist->{'sortcol'}) {
		$main::prefs{'SortDir'} = $clist->{'sortdir'};
		if ($clist->{'sortdir'} eq "descending") {
			$clist->{'sortdir'} = "ascending";
		} else {
			$clist->{'sortdir'} = "descending";
		}
	}
	$clist->{'sortcol'} = $column;
	$main::prefs{'SortCol'} = $column;
	if ($clist->{'sortcol'} == 6) {
		$clist->set_sort_column(8);
	} else {
		$clist->set_sort_column($clist->{'sortcol'});
	}
		
	$clist->set_sort_type($clist->{'sortdir'});
	if ($clist->{'sortcol'} == 5) {
		subject_sort($clist);
		return 1;
	}
	$clist->sort;
	&main::set_labels($clist);
	return 1;
}

sub subject_sort
{
	my ($clist) = @_;
	my (%messages);
	$clist->freeze();
	rw_select_all();
	my ($tmp,$id);
	my @msgs = $main::message_clist->selection();
	if (@msgs) {
       		foreach (@msgs) {
       			my $sub = $clist->get_text($_,5);
       			if ($sub) {  
       				$tmp = $sub;
       				$id = ${$clist->get_row_data($_)} if $main::prefs{'messageview'} eq "clist";
				$id = ${$clist->node_get_row_data($_)} if $main::prefs{'messageview'} eq "ctree";
				$messages{$id} = $sub;
       				$tmp =~ s!\bre(:|\b)\s+!!gi; 
       				$clist->set_text($_,5,$tmp);
       			}
       		}
       	}
       	$clist->set_sort_type($clist->{'sortdir'});
	$clist->sort if $main::prefs{'messageview'} eq "clist";
	$clist->sort_recursive(undef) if $main::prefs{'messageview'} eq "ctree";
       	if (@msgs) {
       		foreach (@msgs) {
			$id = ${$clist->get_row_data($_)} if $main::prefs{'messageview'} eq "clist";
			$id = ${$clist->node_get_row_data($_)} if $main::prefs{'messageview'} eq "ctree";
			if ($messages{$id}) {
				$clist->set_text($_,5,$messages{$id});
       			}
		}
       	}	
       	clear_selection();
       	$clist->thaw();
       	&main::set_labels($clist);
       	return 1;
}		


sub ctree_click_column {
	my ($ctree, $column, $data) = @_;
	if ( $column == $ctree->{'sortcol'} ) {      
		$main::prefs{'SortDir'} = $ctree->{'sortdir'};
		if ($ctree->{'sortdir'} eq "ascending") {
			$ctree->{'sortdir'} = "descending";
		} else {
			$ctree->{'sortdir'} = "ascending";
		}
	}
	
	$ctree->{'sortcol'} = $column;
	$main::prefs{'SortCol'} = $column; 
	
	if ($column == 6) { 
		$ctree->set_sort_column(8)
	} else {
		$ctree->set_sort_column($ctree->{'sortcol'});
	}
	
	$ctree->set_sort_type($ctree->{'sortdir'});
	if ($ctree->{'sortcol'} == 5) {
		subject_sort($ctree);
		return 1;
	}
	$ctree->sort_recursive(undef);
	&main::set_labels($ctree);
	return 1;
}

sub ctree_collapse {
        my($widget,$node) = @_;
	new_in_tree($node);
}

sub new_in_tree {
	my($nd,$mark,$check_children) = @_;
	my ($pixmap, $mask) = $main::message_clist->node_get_pixmap($nd,2);
        if(defined $pixmap) {
                return 1;
        }
	if($nd->row->expanded or (defined $check_children and $check_children)) {
        	if(defined $nd->row->children) {
			my $child = $nd->row->children;
       			if(new_in_tree($child,0) || (defined $child->row->sibling && new_in_tree($child->row->sibling,0))) {
   	        		if(not defined $mark or $mark) {
					my ($newm,$newm_mask);
                        		if(-f "$main::prefs{'PixmapDir'}/newm.xpm") {
                       				($newm,$newm_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/newm.xpm");
                       			}
                       			else {
                                		($newm,$newm_mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),@main::dummy_pixmap);
                       			}
                       			$main::message_clist->freeze;
                       			$main::message_clist->node_set_pixmap($nd,2,$newm,$newm_mask);
                       			$main::message_clist->thaw;
				}
                       		return 1;
        		}
		}
	}
	return 0;
}


sub ctree_expand {
        my ($tree,$node) = @_;
	my($pixmap,$bitmask) = $main::message_clist->node_get_pixmap($node,2);
	if(defined $pixmap) {
        	my($sql,$query,$msgid);
        	$msgid = ${$main::message_clist->node_get_row_data($node)};
        	$sql = "select newmsg from messages where id=$msgid";
        	$query = $main::conn->prepare($sql);
        	$query->execute();
        	my @newmsg;
        	while(@newmsg=$query->fetchrow_array()) {
                	if($newmsg[0] eq "n") {
                	        $main::message_clist->freeze;
                	        $main::message_clist->node_set_text($node,2,"");
                	        $main::message_clist->thaw;
                	}
        	}
	}
}


sub expand_threads {
	
	my ($widget) = @_;
	if ($widget->active) { 
		$main::prefs{'threadpref'} = "expanded";
		$main::message_clist->expand_recursive(undef);
	} else {
		$main::prefs{'threadpref'} = "collapsed";
		$main::message_clist->collapse_recursive(undef);
	}
     
return 1;

}

sub refresh_messages {
	if ($main::prefs{'messageview'} eq "ctree") { &refresh_ctree; return 1; }
	my ($sql, $query, @row, @selection, $box, $row, @msg_sel, %selected, $background, $style, $paperclip, $paperclip_mask, $exclamation, $exclamation_mask, $replyf, $replyf_mask, $forwardf, $forwardf_mask, $newm, $newm_mask,$toselect);
	$box = &Pronto::FolderTree::get_folder_id();
	if (defined $box and $box == 0) { $main::message_clist->clear(); &main::set_win_title }
	if (!$box) {return 1;}
	if ($main::mark_timer) { Gtk->timeout_remove($main::mark_timer); }
	@msg_sel = $main::message_clist->selection();
	my $vpos;
	if (@msg_sel) {
		if ($main::HTMLWIDGET ne "XmHTML") {
			$vpos = $main::root_window->{'sw'}->get_vadjustment;
		}	
		foreach (@msg_sel) {
			$selected{${$main::message_clist->get_row_data($_)}} = 1;
		}
	}
	
	
		foreach(keys(%main::folderidtoname)) {
	 		if ($_ >= 1000) {
	 			$main::folder_tree->node_set_text($main::ft_node[$_],1,"");
	 			$main::folder_tree->node_set_text($main::ft_node[$_],2,"");
	 		}
		}
	
	if ($box > 1000) { &Pronto::Search::view_virtual_folder($box); return 1; }
	$main::message_clist->freeze;
	$row=0;
	$main::message_clist->clear;
        if(-f "$main::prefs{'PixmapDir'}/paperclip.xpm") {
		($paperclip,$paperclip_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/paperclip.xpm");
	}
        else {
        	($paperclip,$paperclip_mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),@main::dummy_pixmap);
        }
        if(-f "$main::prefs{'PixmapDir'}/exclamation.xpm") {
		($exclamation,$exclamation_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/exclamation.xpm");
	}
	else {
		($exclamation,$exclamation_mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),@main::dummy_pixmap);
        }
	if(-f "$main::prefs{'PixmapDir'}/reply_flag.xpm") {
		($replyf,$replyf_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/reply_flag.xpm");
	}
	else {
		($replyf,$replyf_mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),@main::dummy_pixmap);
        }
	if(-f "$main::prefs{'PixmapDir'}/forward_flag.xpm") {
		($forwardf,$forwardf_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/forward_flag.xpm");
        }
	else {
		($forwardf,$forwardf_mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),@main::dummy_pixmap);
        }
	if(-f "$main::prefs{'PixmapDir'}/newm.xpm") {
		($newm,$newm_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/newm.xpm");
	}
	else {
		($newm,$newm_mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),@main::dummy_pixmap);
        }
	if ($box == 1000) {  $main::root_window->{'button'}->show } 
	if ($box != 1000) { if ($main::root_window->{'button'}->visible()) {$main::root_window->{'button'}->hide} }
	if (($box != 3) and ($box != 2) and ($box != 5)) {
		${$main::message_clist->{'labels'}}[4] = _("From");
		$sql = "select id,friendly,subject,date,newmsg,localdate,contenttype,priority,replyf,score,serverstat from messages where boxid=?";
	} else {
		${$main::message_clist->{'labels'}}[4] = _("To");
		$sql = "select id,friendly,subject,date,newmsg,localdate,contenttype,priority,replyf,score,serverstat from messages where boxid=?";
	}
	&main::set_labels($main::message_clist);
	$query = $main::conn->prepare($sql);
	$query->execute($box);
	while (@row=$query->fetchrow_array()) {
		if (not defined $row[9]) { $row[9] = 0; }
		if ($row[9] == 0) { $row[9] = " "; }
		if (defined $row[10] && $row[10] == 1) { 
			$row[10] = _("Not Fetched"); 	# Message is still on server and has NOT been fetched.
							#
		} elsif (defined $row[10] && ($row[10] == 2 || $row[10] == 6)) { 
			$row[10] = _("On Server"); # Message is still on server and has been fetched. 
						#
		} elsif (defined $row[10] && $row[10] == 3) { 
			$row[10] = _("To Be Deleted"); 	# Message is flagged for deletion. 
							#
		} elsif (defined $row[10] && $row[10] == 4) { 
			$row[10] = _("To Be Fetched"); 	# Message is flagged for fetching. 
								#
		} elsif (defined $row[10] && $row[10] == 5) { 
			$row[10] = _("To Be Fetched & Deleted"); 	# Message is flagged for fetch & delete. 
								#
		} else { 
			$row[10] = " "; # Message is not on server.
					#
		}

		$main::message_clist->insert($row,'','','',$row[9],$row[1],$row[2],&main::localdate_to_displaydate($row[5]),$row[10],$row[5]);
		if ($row[6] && ($row[6] !~ /text/i && $row[6] !~ /alternative/i && $row[6] !~ /multipart\/report/i)) {
			$main::message_clist->set_pixmap($row, 1, $paperclip, $paperclip_mask);
		}
		if (($row[7]) and ($row[7] =~ /high/i)) {
			$main::message_clist->set_pixmap($row, 0, $exclamation, $exclamation_mask);
		}
		if ($row[8]) {
			if ($row[8] == 1) {
				$main::message_clist->set_pixtext($row, 4, $row[1],1,$replyf, $replyf_mask);
			} elsif ($row[8] == 2) {
				$main::message_clist->set_pixtext($row, 4, $row[1],1,$forwardf, $forwardf_mask);
			}
		}
		if (($row[4]) and ($row[4] eq "y")) {
			$main::message_clist->set_pixmap($row, 2, $newm, $newm_mask);
			if ($main::prefs{'BoldMsg'}) {
				$main::message_clist->set_row_style($row,$main::bold);
			}
		} else {
			if ($main::prefs{'BoldMsg'}) {
				$main::message_clist->set_row_style($row,$main::normal);
		
			}	
		}
		if ($selected{$row[0]}) {
			$main::message_clist->select_row($row,1);
			$toselect = $row[0] if !$toselect;
		}
		$main::message_clist->set_row_data($row, \$row[0]);
		$row++;
	}
	if ($main::prefs{'SortCol'} != 5) {
		$main::message_clist->sort;
	} else {
		subject_sort($main::message_clist);
		my $select = get_row($toselect);
		$main::message_clist->select_row($select,1) if (defined $select);
	}	
	@msg_sel = $main::message_clist->selection;
	if (@msg_sel) {
		$main::message_clist->moveto($msg_sel[0],0,'0.5','0.5');
		$main::message_clist->set_focus_row($msg_sel[0]);
		if ($vpos) {
			$main::root_window->{'sw'}->set_vadjustment($vpos);
		}	
	}
	$main::message_clist->thaw;
	&main::set_win_title;
	return 1;
}

sub get_row
{
	my ($select) = @_;	
	if (!$select) { return undef }
	my (@selection);
	if ($main::message_clist->row_list) {
		rw_select_all();
		@selection = $main::message_clist->selection();
	}
	if (@selection) {
		my $i = -1;
		foreach(@selection){
			$i++;
			my $id=${$main::message_clist->get_row_data($_)};
			if ($id == $select) { 
				clear_selection(); 
				return $i;
		       	}
			
		}
	}
	return undef;
}	

sub refresh_ctree {
	
	my ($switch) = @_;
	if ($main::prefs{'threadbysubject'} && $main::prefs{'threadbysubject'} eq "y") {&subject_thread($switch); return 1;}
	my ($newm,$newm_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/newm.xpm");
	my ($replyf,$replyf_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/reply_flag.xpm");
	my ($forwardf,$forwardf_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/forward_flag.xpm");
	my ($paperclip,$paperclip_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/paperclip.xpm");
	my ($exclamation,$exclamation_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/exclamation.xpm");
	my ($selected,$vpos);
	if (not defined $switch or $switch ne "switch") {
		my @sel = $main::message_clist->selection;
		if (!@sel) { 
			$selected = 0 
	       	} else { 
			if ($main::HTMLWIDGET ne "XmHTML") {
				$vpos = $main::root_window->{'sw'}->get_vadjustment;
			}	
			$selected = ${$main::message_clist->node_get_row_data($sel[0])};
	       	}
    }
    foreach(keys(%main::folderidtoname)) {
		if ($_ >= 1000) {
			$main::folder_tree->node_set_text($main::ft_node[$_],1,"");
			$main::folder_tree->node_set_text($main::ft_node[$_],2,"");
		}
	}

	my $box = &Pronto::FolderTree::get_folder_id();
	if (defined $box and $box == 0) { $main::message_clist->clear(); &main::set_win_title }
	if (!$box) { return 1 }
	if ($main::mark_timer) { Gtk->timeout_remove($main::mark_timer); }	
	if ($box != 1000) { if ($main::root_window->{'button'}->visible()) {$main::root_window->{'button'}->hide} }
	if ($box > 1000) { &Pronto::Search::view_virtual_folder($box); return 1; } 
	if ($box == 1000) {  $main::root_window->{'button'}->show } 
	$main::message_clist->freeze;
	$main::message_clist->clear;	
	my($sql,$sth);
	if (($box != 3) and ($box != 2) and ($box != 5)) {
		${$main::message_clist->{'labels'}}[4] = _("From");
	} else { 
		${$main::message_clist->{'labels'}}[4] = _("To"); 
	}

	&main::set_labels($main::message_clist);

	$sql = "select msgid,inreplyto,subject,friendly,localdate,id,newmsg,replyf,priority,contenttype,score,ref,serverstat from messages where boxid = '$box' order by localdate";# order by inreplyto,ref"; 
	$sth = $main::conn->prepare($sql);
	$sth->execute();
	my ($node);
	my (%nodes, %not_found) = ((), ());
	while (my($msgid, $inreplyto, $subject, $sentfrom, $date,$id,$newmsg,$reply,$priority,$contenttype,$score,$ref,$serverstat) = $sth->fetchrow_array()) {
	my $sub = $subject;
	$sub =~ s!\bre(:|\b)\s+!!gi;		
	if (not defined $score) { $score = 0 }
	if ($score == 0) { $score = " "; }
	 #shut CSV up
        if ($main::prefs{'DatabaseDriver'} eq "CSV") {
		if (not defined $reply or $reply eq "") {
			$reply = 0;
		}
	}
	if (defined $serverstat && $serverstat == 1) {
		$serverstat = _("Not Fetched");	# Message is still on server and has NOT been fetched.
						# 
	} elsif (defined $serverstat && ($serverstat == 2 || $serverstat == 6)) {
		$serverstat = _("On Server"); 	# Message is still on server and has been fetched. 
						#
	} elsif (defined $serverstat && $serverstat == 3) { 
		$serverstat = _("To Be Deleted"); 	# Message is flagged for deletion. 
						#
	} elsif (defined $serverstat && $serverstat == 4) { 
		$serverstat = _("To Be Fetched");# Message is flagged for fetching. 
							#
	} elsif (defined $serverstat && $serverstat == 5) { 
		$serverstat = _("To Be Fetched & Deleted");# Message is flagged for fetch & delete. 
							#
	} else { 
		$serverstat = " "; 	# Message is not on server.
					#
	}
										 
	if (!$ref && !$inreplyto) { #toplevel mail
		my $title = ["",,"","",$score,$sentfrom,$subject,&main::localdate_to_displaydate($date),$serverstat, $date];
	if (defined $reply and $reply ne "" and $reply == 1) {
		$node = $main::message_clist->insert_node(undef,undef,$title,5,$replyf,$replyf_mask,$replyf,$replyf_mask,0,1);
	} elsif (defined $reply and $reply ne "" and $reply == 2) {
		$node = $main::message_clist->insert_node(undef,undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1);
	} else {
		$node = $main::message_clist->insert_node(undef,undef,$title,5,undef,undef,undef,undef,0,1);
	}
	$nodes{$msgid} = $node;
	$nodes{$sentfrom . $date} = $node;    
	$nodes{$sub} = $node;
	} else {
		if (!$ref && $inreplyto =~ /^(.+)\'s message of \"([^\"]+)\"/) {
			$inreplyto = "$1$2";
			$inreplyto =~ s/\"//g;
		} elsif ($ref =~ /(<[^>]+>)$/ || $inreplyto =~ /(<[^>]+>)/) {
			$inreplyto = $1;
		}
		

	if ($nodes{$inreplyto}) {
		if ($main::prefs{'arrowthreads'} eq "y") { $subject = $main::prefs{'threadarrow'}; }
		my $title = ["","","",$score,$sentfrom,$subject,&main::localdate_to_displaydate($date),$serverstat, $date];
		if (defined $reply and $reply ne "" and $reply == 1) {
			$node = $main::message_clist->insert_node($nodes{$inreplyto},undef,$title,5,$replyf,$replyf_mask,$replyf,$replyf_mask,0,1);
		} elsif (defined $reply and $reply ne "" and $reply == 2) {
			$node = $main::message_clist->insert_node($nodes{$inreplyto},undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1);
		} else {
			$node = $main::message_clist->insert_node($nodes{$inreplyto},undef,$title,5,undef,undef,undef,undef,0,1);
		}
		$nodes{$msgid} = $node;
		$nodes{$sentfrom . $date} = $node;     
		$nodes{$sub} = $node;
	} elsif ($nodes{$sub} && $main::prefs{'GuessRejectThreads'} eq "y") {
		if ($main::prefs{'arrowthreads'} eq "y") { $subject = $main::prefs{'threadarrow'}; }
	   
		my $title = ["","","",$score,$sentfrom,$subject,&main::localdate_to_displaydate($date),$serverstat, $date];
		if (defined $reply and $reply == 1) {
			$node = $main::message_clist->insert_node($nodes{$sub},undef,$title,5,$replyf,$replyf_mask,$replyf,$replyf_mask,0,1);
		} elsif (defined $reply and $reply == 2) {
			$node = $main::message_clist->insert_node($nodes{$sub},undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1);
      		} else {
			$node = $main::message_clist->insert_node($nodes{$sub},undef,$title,5,undef,undef,undef,undef,0,1);
      		}
		$nodes{$msgid} = $node;
		$nodes{$sentfrom . $date} = $node;     
		$nodes{$sub} = $node;
	} else {
		my $title = ["","","",$score,$sentfrom,$subject,&main::localdate_to_displaydate($date),$serverstat, $date];
		if (defined $reply and $reply ne "" and $reply == 1) {
			$node = $main::message_clist->insert_node(undef,undef,$title,5,$replyf,$replyf_mask,$replyf,$replyf_mask,0,1);
		} elsif (defined $reply and $reply ne "" and $reply == 2) {
			$node = $main::message_clist->insert_node(undef,undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1);
		} else {
			$node = $main::message_clist->insert_node(undef,undef,$title,5,undef,undef,undef,undef,0,1);
		}
		$nodes{$msgid} = $node;
		$nodes{$sentfrom . $date} = $node;     
		$nodes{$sub} = $node;
	}
	}		     
	if (not defined $switch or $switch ne "switch") {
		if ($id == $selected) { $selected = $node; }

	}

	$main::message_clist->node_set_row_data($node,\$id);

	if ($contenttype && ($contenttype !~ /text/i && $contenttype !~ /alternative/i && $contenttype !~ /multipart\/report/i)) { 
		$main::message_clist->node_set_pixmap($node, 1, $paperclip, $paperclip_mask);
	}
	if (($priority) and ($priority =~ /high/i)) {
		$main::message_clist->node_set_pixmap($node, 0, $exclamation, $exclamation_mask);
	}
	if (defined $newmsg and $newmsg eq "y") {
		$main::message_clist->node_set_pixmap($node,2,$newm,$newm_mask);
		if ($main::prefs{'BoldMsg'}) {
			$main::message_clist->node_set_row_style($node,$main::bold);
		}
	} else {
		if ($main::prefs{'BoldMsg'}) {
			$main::message_clist->node_set_row_style($node,$main::normal);
		}
	}	

}

	if ($main::prefs{'SortCol'} !=5) {
		$main::message_clist->sort_recursive( undef );
	} else {
		&subject_sort($main::message_clist);
	}	
	if (not defined $switch or $switch ne "switch") {
       		if ($selected !=0) {	 
#			$main::message_clist->select($selected); for some reason does not work with remembing the $vpos
			$main::message_clist->node_moveto($selected,2,0.5,0.5);
			my $row = $main::message_clist->get_node_position($selected);
			if ($row != -1) {
				Gtk::CList::select_row($main::message_clist,$row,1);
				Gtk::CList::set_focus_row($main::message_clist,$row);
				if ($vpos) {
					$main::root_window->{'sw'}->set_vadjustment($vpos);
				}	
	       
			}
		}
     	}
	if ($main::prefs{'threadpref'} eq "collapsed") { $main::message_clist->collapse_recursive(undef) }
	$main::message_clist->thaw;
	&main::set_win_title;

    return 1;
}

#experminal subject threading - not to be told to users yet.
sub subject_thread {
	
	my ($switch) = @_;
	my ($newm,$newm_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/newm.xpm");
	my ($replyf,$replyf_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/reply_flag.xpm");
	my ($forwardf,$forwardf_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/forward_flag.xpm");
	my ($paperclip,$paperclip_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/paperclip.xpm");
	my ($exclamation,$exclamation_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$main::message_clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/exclamation.xpm");
	my ($selected,$vpos);
	if (not defined $switch or $switch ne "switch") {
		my @sel = $main::message_clist->selection;
		if (!@sel) { 
			$selected = 0 
	       	} else { 
			if ($main::HTMLWIDGET ne "XmHTML") {
				$vpos = $main::root_window->{'sw'}->get_vadjustment;
			}	
			$selected = $main::message_clist->node_get_row_data($sel[0]);
			$selected = $$selected; 
	       	}
    	}
    	foreach(keys(%main::folderidtoname)) {
		if ($_ >= 1000) {
			$main::folder_tree->node_set_text($main::ft_node[$_],1,"");
			$main::folder_tree->node_set_text($main::ft_node[$_],2,"");
		}
	}

	my @selection = $main::folder_tree->selection();
	if (!@selection) { return 1 }
	if ($main::mark_timer) { Gtk->timeout_remove($main::mark_timer); }
	my $box = $main::ft_id{$selection[0]}; 
	if ($box != 1000) { if ($main::root_window->{'button'}->visible()) {$main::root_window->{'button'}->hide} }
	if ($box > 1000) { &Pronto::Search::view_virtual_folder($box); return 1; } 
	if ($box == 1000) {  $main::root_window->{'button'}->show } 
	$main::message_clist->freeze;
	$main::message_clist->clear;	
	my($sql,$sth);
	if (($box != 3) and ($box != 2) and ($box != 5)) {
		${$main::message_clist->{'labels'}}[4] = _("From");
	} else { 
		${$main::message_clist->{'labels'}}[4] = _("To"); 
	}

	&main::set_labels($main::message_clist);

	$sql = "select msgid,inreplyto,subject,friendly,localdate,id,newmsg,replyf,priority,contenttype,score,ref,serverstat from messages where boxid = '$box' order by localdate";# order by inreplyto,ref";
	$sth = $main::conn->prepare($sql);
	$sth->execute();
	my ($node);
	my (%nodes, %not_found) = ((), ());
	while (my($msgid, $inreplyto, $subject, $sentfrom, $date,$id,$newmsg,$reply,$priority,$contenttype,$score,$ref,$serverstat) = $sth->fetchrow_array()) {
       	my $sub = $subject;
	$sub =~ s!\bre(:|\b)\s+!!gi;
	if (not defined $score) { $score = 0 }
	if ($score == 0) { $score = " "; }
	if (defined $serverstat && $serverstat == 1) {
		$serverstat = _("Not Fetched");	# Message is still on server and has NOT been fetched.
						# 
	} elsif (defined $serverstat && ($serverstat == 2 || $serverstat == 6)) {
		$serverstat = _("On Server"); 	# Message is still on server and has been fetched. 
						#
	} elsif (defined $serverstat && $serverstat == 3) { 
		$serverstat = _("To Be Deleted"); 	# Message is flagged for deletion. 
						#
	} elsif (defined $serverstat && $serverstat == 4) { 
		$serverstat = _("To Be Fetched");# Message is flagged for fetching. 
							#
	} elsif (defined $serverstat && $serverstat == 5) { 
		$serverstat = _("To Be Fetched & Deleted");# Message is flagged for fetch and delete. 
							#
	} else { 
		$serverstat = " "; 	# Message is not on server.
					#
	}
	if (!$nodes{$sub}) { #toplevel mail
		my $title = ["",,"","",$score,$sentfrom,$subject,&main::localdate_to_displaydate($date),$serverstat,$date];
	if (defined $reply and $reply == 1) {
		$node = $main::message_clist->insert_node(undef,undef,$title,5,$replyf,$replyf_mask,$replyf,$replyf_mask,0,1);
	} elsif (defined $reply and $reply == 2) {
		$node = $main::message_clist->insert_node(undef,undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1);
	} else {
		$node = $main::message_clist->insert_node(undef,undef,$title,5,undef,undef,undef,undef,0,1);
	}
	$nodes{$msgid} = $node;
	$nodes{$sentfrom . $date} = $node;    
       	$nodes{$sub} = $node;
	} 

	 elsif ($nodes{$sub} and $subject =~ /\bre(:|\b)/ig) {
	 	if ($main::prefs{'arrowthreads'} eq "y") { $subject = $main::prefs{'threadarrow'}; }
		my $title = ["","","",$score,$sentfrom,$subject,&main::localdate_to_displaydate($date),$serverstat,$date];
		if (defined $reply and $reply == 1) {
			$node = $main::message_clist->insert_node($nodes{$sub},undef,$title,5,$replyf,$replyf_mask,$replyf,$replyf_mask,0,1);
		} elsif (defined $reply and $reply == 2) {
			$node = $main::message_clist->insert_node($nodes{$sub},undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1);
      		} else {
			$node = $main::message_clist->insert_node($nodes{$sub},undef,$title,5,undef,undef,undef,undef,0,1);
      		}
		$nodes{$msgid} = $node;
		$nodes{$sentfrom . $date} = $node;     
		$nodes{$sub} = $node;
	} else {
		my $title = ["","","",$score,$sentfrom,$subject,&main::localdate_to_displaydate($date),$serverstat,$date];
		if (defined $reply and $reply == 1) {
			$node = $main::message_clist->insert_node(undef,undef,$title,5,$replyf,$replyf_mask,$replyf,$replyf_mask,0,1);
		} elsif (defined $reply and $reply == 2) {
			$node = $main::message_clist->insert_node(undef,undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1);
		} else {
			$node = $main::message_clist->insert_node(undef,undef,$title,5,undef,undef,undef,undef,0,1);
		}
		$nodes{$msgid} = $node;
		$nodes{$sentfrom . $date} = $node;     
		$nodes{$sub} = $node;
	}
			     
	if (not defined $switch or $switch ne "switch") {
		if ($id == $selected) { $selected = $node }
	}

	$main::message_clist->node_set_row_data($node,\$id);

	if ($contenttype && ($contenttype !~ /text/i && $contenttype !~ /alternative/i && $contenttype !~ /multipart\/report/i)) { 
		$main::message_clist->node_set_pixmap($node, 1, $paperclip, $paperclip_mask);
	}
	if (($priority) and ($priority =~ /high/i)) {
		$main::message_clist->node_set_pixmap($node, 0, $exclamation, $exclamation_mask);
	}
	if (defined $newmsg and $newmsg eq "y") {
		$main::message_clist->node_set_pixmap($node,2,$newm,$newm_mask);
		if ($main::prefs{'BoldMsg'}) {
			$main::message_clist->node_set_row_style($node,$main::bold);
		}
	} else {
		if ($main::prefs{'BoldMsg'}) {
			$main::message_clist->node_set_row_style($node,$main::normal);
		}
	}	
}


	
	if ($main::prefs{'SortCol'} !=5) {
		$main::message_clist->sort_recursive( undef );
	} else {
		&subject_sort($main::message_clist);
	}	
	if (not defined $switch or $switch ne "switch") {
       		if ($selected !=0) {
			$main::message_clist->node_moveto($selected,2,0.5,0.5);
			#$main::message_clist->select($selected);
       			my $row = $main::message_clist->get_node_position($selected);
			if ($row != -1) {
				Gtk::CList::select_row($main::message_clist,$row,1);
				Gtk::CList::set_focus_row($main::message_clist,$row);
				if ($vpos) {					
					$main::root_window->{'sw'}->set_vadjustment($vpos);
				}	
			}
		}
     	}
	if ($main::prefs{'threadpref'} eq "collapsed") { $main::message_clist->collapse_recursive(undef) }
	$main::message_clist->thaw;
	&main::set_win_title;

    return 1;
}

#end expermintal subject threading

sub goto_next_unread_msg {
	return if $main::dragging;
	my ($last_selection, $current_selection, $current_node, $pixmap, $mask);
	$last_selection = -1;
        if(defined $main::message_clist->selection) {
		if ($main::prefs{'messageview'} eq "clist") {
			$last_selection = $main::message_clist->selection;
		}
		else {
			my @array = $main::message_clist->selection;
			$current_node = $array[0];
		}
	}
	$current_selection = $last_selection + 1;
        ($pixmap, $mask) = Gtk::CList::get_pixmap($main::message_clist,$current_selection,2); 
	while($last_selection != $current_selection and not defined $pixmap) {
		if($last_selection == -1) {
                	$last_selection = 0;
		}
		$current_selection++;
                if($current_selection >= $main::message_clist->rows) {
                	$current_selection = 0;
                } 
                ($pixmap, $mask) = Gtk::CList::get_pixmap($main::message_clist,$current_selection,2);     
        }
        $main::message_clist->unselect_all();
	if(defined $current_node) {
		if(not defined $pixmap) {
			$main::message_clist->select($current_node);
			$main::message_clist->node_moveto($current_node,2,0.5,0.5);
		}
		else {
			$main::message_clist->select_row($current_selection,2);
			$main::message_clist->moveto($current_selection,2,0.5,0.5);
		}
	}
	else {
		$main::message_clist->select_row($current_selection,2);
		$main::message_clist->moveto($current_selection,2,0.5,0.5);
	}
	if($main::prefs{'messageview'} eq "ctree") {
		my @select = $main::message_clist->selection;
		if(defined $select[0] and defined $pixmap) {
			my @children = $select[0]->row->children;
			if(defined $children[0]) {
				my $msgid = ${$main::message_clist->node_get_row_data($select[0])};
				my $sql = "select newmsg from messages where id=$msgid";
				my $query = $main::conn->prepare($sql);
				$query->execute();
				if(my $newmsg=$query->fetchrow_array()) {
					if($newmsg eq "n") {
						#actually expand the whole thread
						$main::message_clist->expand_recursive($select[0]);
						&goto_next_unread_msg;
					}
				}
			}
		}
	}
}

sub click_clist {
  	
	my ($widget, $data, $event) = @_;
      	if ($event->{type} eq "2button_press") {
		&dblclick_clist($widget, $event, $data);
   	} 

  	if (($event->{button} == 3) and ($widget->{'popup'})) {
   		$widget->{'popup'}->popup(undef,undef,$event->{button},1);
  	}
	return 1;
}

sub dblclick_clist {
  	my ($widget, $event, $data) = @_;
  	my ($x, $y, $flag);
  	$x = $event->{'x'};
  	$y = $event->{'y'};
  	my ($row, $col) = $widget->get_selection_info($x,$y);
  	if (not defined $row) { return 1; }
	my $msgid = ${$widget->get_row_data($row)};
	if (!$msgid) { return 1 }
	&Pronto::Read::message_view_win($msgid, 1);
  
  	return 1;
}

# returns the messageid for the first selected message
sub get_selected_msgid
{
	my (@msg_sel, $msgid);
	@msg_sel = $main::message_clist->selection;
	if (!@msg_sel) { return undef; };
	if ($main::prefs{'messageview'} eq "clist") {
		$msgid = ${$main::message_clist->get_row_data($msg_sel[0])};
    } else {
		$msgid = ${$main::message_clist->node_get_row_data($msg_sel[0])};
    };
    return $msgid;
}

sub get_selected_msgids 
{
	my (@msg_sel,@msgids);
	@msg_sel = $main::message_clist->selection();
	if (!@msg_sel) { return (); };
	if ($main::prefs{'messageview'} eq "clist") {
		foreach(@msg_sel) {
			my $msgid = ${$main::message_clist->get_row_data($_)};
			push(@msgids, $msgid);
			
		}
	} else {
		foreach (@msg_sel) {
			my $msgid = ${$main::message_clist->node_get_row_data($_)};
			push(@msgids, $msgid);
		}
	}
	return @msgids;
}



sub goto_top
{
	return if $main::dragging;
	$main::message_clist->select_row(0,0);
	$main::message_clist->moveto(0,0,0.5,0.5);
}


sub get_last_selected_node_or_row
{
	my (@selection) = $main::message_clist->selection();
        return $selection[0];
}	

sub rw_select_all {
	my ($i);
	for ($i = 0; $i < $main::message_clist->rows; $i++) {
		$main::message_clist->select_row($i, 0);
	}
	return 1;
}

sub clear_selection {
	my ($i);
	for ($i = 0; $i < $main::message_clist->rows; $i++) {
		$main::message_clist->unselect_row($i, 0);
	}
	return 1;
}



sub freeze { $main::message_clist->freeze() }
sub thaw { $main::message_clist->thaw() }
sub rows { return $main::message_clist->rows(); }
sub get_node_row 
{ 
	if (not defined $_[0]) { return undef }
	return $main::message_clist->get_node_position($_[0]);
}

sub messagelist_drag_data_get
{
	my ($widget, $context, $data, $info, $time) = @_;
#	print "drag data get\n";
	return if (!$main::current);
	$data->set($data->target, 8, $main::current);
	return;
}					

sub drag_begin
{
#	print "drag begin\n";
	@main::dragged = get_selected_msgids();
	$main::dragging = 1;
	return;
}

sub drag_end
{
#	print "drag end\n";
	undef @main::dragged;
	@main::dragged = ();
	$main::dragging = 0;
	return;
}	


1;


syntax highlighted by Code2HTML, v. 0.9.1