# -*- perl -*- package Pronto::CListView; use strict; use SelfLoader; 1; __DATA__ sub new { my $current_folder = &Pronto::FolderTree::get_folder_id(); return if (!$current_folder || $current_folder >= 1000); my $window = new Gtk::Window("toplevel"); my ($clist,$sw) = make_clist($window,$current_folder); $window->set_title("Pronto! CList View - $main::folderidtoname{$current_folder}"); my ($width,$height) = &main::get_win_size("CListView",580,200); $window->set_default_size($width,$height); make_clist_sigs($clist); $window->add($sw); $window->show_all(); $window->signal_connect("size-request" => \&main::save_win_size, "CListView", $window->window); refresh_messages($clist); return; } sub make_clist { my ($window,$folder) = @_; my ($clist,$sw,$resync); my @headers = (" "," "," ","Score", ,"From","Subject","Date", "Server", "Hidden Field"); if ($main::prefs{'messageview'} eq "clist") { $clist = new_with_titles Gtk::CList(@headers); } elsif ($main::prefs{'messageview'} eq "ctree") { $clist = new_with_titles Gtk::CTree(5,@headers); $clist->set_expander_style($main::prefs{'expander'}); $clist->set_line_style ( $main::prefs{'threadstyle'} ); } $clist->set_compare_func(\&Pronto::MessageList::my_sort_func); if($main::prefs{'prioritycolumn'} eq "n") { $clist->set_column_visibility(0,0); } if($main::prefs{'attachcolumn'} eq "n" ) { $clist->set_column_visibility(1,0); } if($main::prefs{'msgnewcolumn'} eq "n" ) { $clist->set_column_visibility(2,0); } if($main::prefs{'servercolumn'} eq "n") { $clist->set_column_visibility(7,0); } @{$clist->{'labels'}} = @headers; $clist->{'name'} = "view"; if (defined $main::prefs{'Scoring'} && $main::prefs{'Scoring'} ne "y") { $clist->set_column_visibility(3, 0); } $clist->set_column_justification(3, "center"); $clist->set_column_visibility(8, 0); $clist->column_titles_active; $clist->set_selection_mode('extended'); if (not defined $main::prefs{'MessageListColWidth4'}) { $clist->set_column_width(4,127); } if (not defined $main::prefs{'MessageListColWidth5'}) { $clist->set_column_width(5,175); } for (my $i = 0; $i < 7; $i++) { if (defined $main::prefs{'MessageListColWidth' . $i}) { $clist->set_column_width($i, $main::prefs{'MessageListColWidth' . $i}); } } $clist->set_row_height(17); if ($main::prefs{'messageview'} eq "clist") { $clist->signal_connect('click_column', \&Pronto::MessageList::click_column); } elsif ($main::prefs{'messageview'} eq "ctree") { $clist->signal_connect('click_column', \&Pronto::MessageList::ctree_click_column); $clist->signal_connect('tree_collapse', \&Pronto::MessageList::ctree_collapse); $clist->signal_connect('tree_expand',\&Pronto::MessageList::ctree_expand); } $clist->signal_connect('button_press_event',\&click_clist, 1); # $clist->signal_connect('key_press_event', \&key_pressed); $clist->{'sortcol'} = $main::prefs{'SortCol'}; $clist->{'sortdir'} = $main::prefs{'SortDir'}; $clist->signal_connect("resize-column" => sub {my ($d, $c, $w)=@_; $main::prefs{'MessageListColWidth'. $c}=$w;}); $sw = new Gtk::ScrolledWindow(undef,undef); $sw->set_policy('automatic','automatic'); $sw->add($clist); $clist->{'popup'} = new Gtk::Menu; my $mp_sep1 = new Gtk::MenuItem; $clist->{'popup'}->append($mp_sep1); $clist->{'window'} = $window; if ($main::prefs{'messageview'} eq "ctree") { my $collapse = new Gtk::MenuItem(_("Collapse Threads ..")); $collapse->signal_connect("activate", sub { $clist->collapse_recursive(undef) }); $clist->{'popup'}->append($collapse); my $expand = new Gtk::MenuItem(_("Expand Threads ..")); $expand->signal_connect("activate", sub { $clist->expand_recursive(undef)}); $clist->{'popup'}->append($expand); my $sep = new Gtk::MenuItem; $clist->{'popup'}->append($sep); } $clist->{'folder'} = $folder; $resync = new Gtk::MenuItem(_("Resync...")); $resync->signal_connect("activate", sub { &refresh_messages($clist); }); $clist->{'popup'}->append($resync); $clist->{'popup'}->show_all(); return $clist,$sw; } sub key_pressed { my ($clist, $event) = @_; &Pronto::MainWindow::handle_delete_msgs if ($event->{keyval} == 65535); return 1; } sub make_clist_sigs { my ($clist) = @_; my ($clipmask,$clip,$exclame_pix,$exclame_mask,$exclame,$newm,$new_pix,$newmp,$clippix); if ($main::prefs{'messageview'} eq "clist") { $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") { $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") { ($clippix,$clipmask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$clist->style->bg('normal'), "$main::prefs{'PixmapDir'}/paperclip.xpm"); } else { ($clippix,$clipmask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$clist->style->bg('normal'), @main::dummy_pixmap); } $clip = new Gtk::Pixmap($clippix,$clipmask); $clist->set_column_widget(1, $clip); if(-f "$main::prefs{'PixmapDir'}/exclamation.xpm") { ($exclame_pix,$exclame_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/exclamation.xpm"); } else { ($exclame_pix,$exclame_mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$clist->style->bg('normal'),@main::dummy_pixmap); } $exclame = new Gtk::Pixmap($exclame_pix,$exclame_mask); $clist->set_column_widget(0, $exclame); if(-f "$main::prefs{'PixmapDir'}/newm.xpm") { ($new_pix,$newm) = Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/newm.xpm"); } else { ($new_pix,$newm) = Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$clist->style->bg('normal'),@main::dummy_pixmap); } $newmp = new Gtk::Pixmap($new_pix,$newm); $clist->set_column_widget(2, $newmp); if ($main::prefs{'messageview'} eq "clist") { &Pronto::MessageList::click_column($clist, $clist->{'sortcol'}); } elsif ($main::prefs{'messageview'} eq "ctree") { $clist->set_sort_column ( $main::prefs{'SortCol'} ); &Pronto::MessageList::ctree_click_column($clist, $clist->{'sortcol'}); } return 1; } 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 refresh_messages { my ($clist) = @_; if ($main::prefs{'messageview'} eq "ctree") { &refresh_ctree($clist); 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 = $clist->{'folder'}; if (defined $box and $box == 0) { $clist->clear(); &main::set_win_title } if (!$box) {return 1;} if ($main::mark_timer) { Gtk->timeout_remove($main::mark_timer); } @msg_sel = $clist->selection(); my $vpos; if (@msg_sel) { if ($main::HTMLWIDGET ne "XmHTML") { $vpos = $main::root_window->{'sw'}->get_vadjustment; } foreach (@msg_sel) { $selected{${$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,""); } } $clist->freeze; $row=0; $clist->clear; if(-f "$main::prefs{'PixmapDir'}/paperclip.xpm") { ($paperclip,$paperclip_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$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,$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,$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,$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,$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,$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,$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,$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,$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,$clist->style->bg('normal'),@main::dummy_pixmap); } if ($box == 1000) { $main::root_window->{'button'}->show } if ($box != 1000) { if ($main::root_window->visible) {$main::root_window->{'button'}->hide} } if (($box != 3) and ($box != 2) and ($box != 5)) { ${$clist->{'labels'}}[4] = "From"; $sql = "select id,friendly,subject,date,newmsg,localdate,contenttype,priority,replyf,score,serverstat from messages where boxid=?"; } else { ${$clist->{'labels'}}[4] = "To"; $sql = "select id,friendly,subject,date,newmsg,localdate,contenttype,priority,replyf,score,serverstat from messages where boxid=?"; } $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. # } $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)) { $clist->set_pixmap($row, 1, $paperclip, $paperclip_mask); } if (($row[7]) and ($row[7] =~ /high/i)) { $clist->set_pixmap($row, 0, $exclamation, $exclamation_mask); } if ($row[8]) { if ($row[8] == 1) { $clist->set_pixtext($row, 4, $row[1],1,$replyf, $replyf_mask); } elsif ($row[8] == 2) { $clist->set_pixtext($row, 4, $row[1],1,$forwardf, $forwardf_mask); } } if (($row[4]) and ($row[4] eq "y")) { $clist->set_pixmap($row, 2, $newm, $newm_mask); if ($main::prefs{'BoldMsg'}) { $clist->set_row_style($row,$main::bold); } } else { if ($main::prefs{'BoldMsg'}) { $clist->set_row_style($row,$main::normal); } } if ($selected{$row[0]}) { $clist->select_row($row,1); $toselect = $row[0] if !$toselect; } $clist->set_row_data($row, \$row[0]); $row++; } if ($main::prefs{'SortCol'} != 5) { $clist->sort; } else { &Pronto::MessageList::subject_sort($clist); # my $select = get_row($toselect); # $clist->select_row($select,1) if (defined $select); } @msg_sel = $clist->selection; if (@msg_sel) { $clist->moveto($msg_sel[0],0,'0.5','0.5'); $clist->set_focus_row($msg_sel[0]); if ($vpos) { $main::root_window->{'sw'}->set_vadjustment($vpos); } } $clist->thaw; &main::set_win_title; return 1; } sub refresh_ctree { my ($clist,$switch)=@_; my ($newm,$newm_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/newm.xpm"); my ($replyf,$replyf_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$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,$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,$clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/paperclip.xpm"); my ($exclamation,$exclamation_mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$clist->style->bg('normal'),"$main::prefs{'PixmapDir'}/exclamation.xpm"); my ($selected,$vpos); if (not defined $switch or $switch ne "switch") { my @sel = $clist->selection; if (!@sel) { $selected = 0 } else { if ($main::HTMLWIDGET ne "XmHTML") { $vpos = $main::root_window->{'sw'}->get_vadjustment; } $selected = ${$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 = $clist->{'folder'}; if (defined $box and $box == 0) { $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->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 } $clist->freeze; $clist->clear; my($sql,$sth); if (($box != 3) and ($box != 2) and ($box != 5)) { ${$clist->{'labels'}}[4] = "From"; } else { ${$clist->{'labels'}}[4] = "To"; } $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 = $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 = $clist->insert_node(undef,undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1); } else { $node = $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 = $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 = $clist->insert_node($nodes{$inreplyto},undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1); } else { $node = $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 = $clist->insert_node($nodes{$sub},undef,$title,5,$replyf,$replyf_mask,$replyf,$replyf_mask,0,1); } elsif (defined $reply and $reply == 2) { $node = $clist->insert_node($nodes{$sub},undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1); } else { $node = $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 = $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 = $clist->insert_node(undef,undef,$title,5,$forwardf,$forwardf_mask,$forwardf,$forwardf_mask,0,1); } else { $node = $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; } } $clist->node_set_row_data($node,\$id); if ($contenttype && ($contenttype !~ /text/i && $contenttype !~ /alternative/i && $contenttype !~ /multipart\/report/i)) { $clist->node_set_pixmap($node, 1, $paperclip, $paperclip_mask); } if (($priority) and ($priority =~ /high/i)) { $clist->node_set_pixmap($node, 0, $exclamation, $exclamation_mask); } if (defined $newmsg and $newmsg eq "y") { $clist->node_set_pixmap($node,2,$newm,$newm_mask); if ($main::prefs{'BoldMsg'}) { $clist->node_set_row_style($node,$main::bold); } } else { if ($main::prefs{'BoldMsg'}) { $clist->node_set_row_style($node,$main::normal); } } } if ($main::prefs{'SortCol'} !=5) { $clist->sort_recursive( undef ); } else { &Pronto::MessageList::subject_sort($clist); } if (not defined $switch or $switch ne "switch") { if ($selected !=0) { # $clist->select($selected); for some reason does not work with remembing the $vpos $clist->node_moveto($selected,2,0.5,0.5); my $row = $clist->get_node_position($selected); if ($row != -1) { Gtk::CList::select_row($clist,$row,1); Gtk::CList::set_focus_row($clist,$row); if ($vpos) { $main::root_window->{'sw'}->set_vadjustment($vpos); } } } } if ($main::prefs{'threadpref'} eq "collapsed") { $clist->collapse_recursive(undef) } $clist->thaw; return 1; } sub get_selected_msgid { my ($clist)=@_; my (@msg_sel, $msgid); @msg_sel = $clist->selection; if (!@msg_sel) { return undef; }; if ($main::prefs{'messageview'} eq "clist") { $msgid = ${$clist->get_row_data($msg_sel[0])}; } else { $msgid = ${$clist->node_get_row_data($msg_sel[0])}; } return $msgid; } 1;