#!/usr/bin/perl -w ## $Id: pronto-main,v 1.17 2002/05/25 00:37:37 muhri Exp $ # Pronto! version 2.4.0 # Distributed under the GNU public license # Development team members: # Muhri # Alex # Noidd # Flavio # Shank # and others... # some of the original code by Steven Kordik (countzero@cyberdeck.org) use strict; use vars qw( %prefs $libpath $HTMLWIDGET $message_clist $folder_tree %folderidtoname %foldernametoid $conn @ft_node %ft_id $ONETIME $attpixmap $parser $attach_menu $attach_menu2 $view_attach_menu $view_attach_menu2 %entity $root_window $view_window $version @dummy_pixmap @flttypes $acct_menu2 $acct_menu @attach_menu_items %acct_menu_items %acct_menu2_items $hashtml $bold $normal $head_style $hashtml_widget $current @dragged $dragging $locale $locale_installed); BEGIN { $libpath = $0; $libpath =~ s!/[^/]+$!!; $libpath =~ s!/bin$!/lib/pronto!; if (! -e $libpath) { die _("Can't find required files in ") . $libpath ."\n"; }; } use lib "$libpath"; require "prontolib.pl"; my ($sql, $query,@target_table, $view_timer, $mark_timer,$passphrase); use Gtk; use MIME::Parser; use MIME::Types; use Date::Manip; use URI::URL; use IO::File; # Pronto Specific. use Pronto::AddressBook; #Pronto's spanking new addybook use Pronto::Crypt; #GPG Module use Pronto::Crypt::GPG; #GPG Module use Pronto::Crypt::PGP; #PGP Module use Pronto::Crypt::GUI; #PGP Module use Pronto::Config; #Configuration use Pronto::Help; #Help system use Pronto::Search; #Search / Vfolders use Pronto::FirstRun; #First time setup stuff use Pronto::Compose; #Message composition / Spell check use Pronto::Read; #Decoding of messages and attachments, displaying messages use Pronto::FolderTree; #Folder tree widget use Pronto::Data::Message; #Message operations, delete, move, copy and refilter use Pronto::Data::MessageOp; #reply/forward/edit and reply_all use Pronto::Filter; #filter editing and reordering use Pronto::IPC; #IPC signals, USR1, USR2 & ALRM. use Pronto::MessageList; #Message list/tree widget use Pronto::FolderMenus; #Folder menus use Pronto::TableEdit; #Common accounts/mime types/filters editing code use Pronto::MainWindow; #main window initilization/toolbar creation/icon menus, etc.. use Pronto::Link; #Widget links and http/ftp link handler. use Pronto::Import; #import from mbox module use Pronto::Export; #export to mbox module use Pronto::Save; #Save message use Pronto::Print; #printing use Pronto::ViewAttachment; #View Attachment use Pronto::About; #About us :) use Pronto::Send; #send stuff. use Pronto::Get; #get stuff. use Pronto::Widget; #which html widget to use. use Pronto::KeyEdit; #short cuts. use Pronto::CListView; ## End Pronto Specific ... #warn da users ! if ($Gtk::VERSION < 0.7003) { print( _("WARNING: You are using Gtk::Perl version ") . $Gtk::VERSION . _(" - Pronto requires Gtk::Perl version 0.7003 at least\nPlease updat e your Gtk::Perl from http://www.muhri.net/pronto") . "\n"); } if ($MIME::Parser::VERSION < 5) { print( _("WARNING: You are using MIME::Parser version ") . $MIME::Parser::VERSION . _(" Pronto requires >= 5.xxx\nPlease update your MIME::Tools package from http://download.sourceforge.net/mirrors/CPAN/authors/id/ERYQ","\n")); } #runtime variable, are we running one time or not. $ONETIME = 0; $hashtml = 0; &Pronto::Widget::determine_widget(); #which html widget are we going to use Gtk->init(); init Gtk::Gdk::Rgb; if ($main::HTMLWIDGET ne "text") { #if there was an HTML widget found, init it. &Pronto::Widget::init_widget(); } if ($HTMLWIDGET ne "text") { $hashtml = 1; #for later purposes in config, does the use have an HTML widget installed $hashtml_widget = $HTMLWIDGET; } Gtk::Rc->parse("$libpath/pronto.gtkrc"); Gtk::Widget->set_default_colormap(Gtk::Gdk::Rgb->get_cmap()); Gtk::Widget->set_default_visual(Gtk::Gdk::Rgb->get_visual()); $parser = new MIME::Parser; $parser->output_dir("$prefs{'MailDir'}/tmp/"); opendir(DIR,"$prefs{'MailDir'}/tmp"); while (defined (my $nuke = readdir DIR)) { next if $nuke =~ /^\.\.?$/; unlink "$prefs{'MailDir'}/tmp/$nuke"; } closedir(DIR); $version = "v2.4.0"; use constant TARGET_STRING => 0; use constant TARGET_ROOTWIN => 1; @target_table = ( {'target' => "STRING", 'flags' => 0, 'info' => TARGET_STRING}, {'target' => "text/plain", 'flags' => 0, 'info' => TARGET_STRING}, {'target' => "application/x-rootwin-drop", 'flags' => 0, 'info' =>TARGET_ROOTWIN}, ); $SIG{CHLD} = \&Pronto::IPC::CHLD_handler; $SIG{USR1} = \&Pronto::IPC::USR1_handler; $SIG{USR2} = \&Pronto::IPC::USR2_handler; $SIG{ALRM} = \&Pronto::IPC::ALRM_handler; @flttypes = ( _("Inactive"), _("Account Based"), _("To/Cc Based"), _("Subject Based"), _("From Based"), _("Generic"), _("Scoring") ); @dummy_pixmap = ( "10 10 2 1", ". c None", "1 c #000000", "1........1", ".1......1.", "..1....1..", "...1..1...", "....11....", "....11....", "...1..1...", "..1....1..", ".1......1.", "1.........1" ); sub message_count { my($id,$msg_count,$new_count) = @_; my($sql,$query,@row); if(not defined $$msg_count[$id]) { $$msg_count[$id]=0; } if(not defined $$new_count[$id]) { $$new_count[$id]=0; } $sql = "select id from boxlist where parent=$id"; $query = $conn->prepare($sql); $query->execute(); while(@row=$query->fetchrow_array()) { &message_count($row[0],$msg_count,$new_count); $$new_count[$id]+=$$new_count[$row[0]]; $$msg_count[$id]+=$$msg_count[$row[0]]; } } sub set_default_box { if ($prefs{'startin'} eq "None") { return 1; } else { my $folder = $foldernametoid{$prefs{'startin'}}; $folder_tree->select($ft_node[$folder]); if ($folder < 1000) { &Pronto::MessageList::refresh_messages; } else { &Pronto::Search::view_virtual_folder($folder) } if($prefs{'onfolderchange'} eq 'top') { &Pronto::MessageList::goto_top; } elsif($prefs{'onfolderchange'} eq 'next unread') { &Pronto::MessageList::goto_next_unread_msg; } } return 1; } sub set_win_title { my ($box, $boxname); $box = &Pronto::FolderTree::get_folder_id(); if (!$box) { $box = 0 }; $boxname = $folderidtoname{$box}; if ($box >= 1000) { $root_window->set_title("Pronto! $version - $boxname") } else { $root_window->set_title("Pronto! $version - $boxname: $Pronto::FolderTree::msg_count[$box] ($Pronto::FolderTree::new_count[$box])"); } return 1; } sub set_labels { my ($clist) = @_; my($x, $lblbox, $lbl, $arrow, $pixmap, $mask); my @headers = @{$clist->{'labels'}}; if ($clist->{'name'} eq "message" || $clist->{'name'} eq "view") { for($x = 4; $x <= 7; $x++) { $clist->set_column_title($x, $headers[$x]); } } else { $x = 0; foreach (@headers) { $clist->set_column_title($x, $_); $x++; } } my $sortcolumn; if ($prefs{'messageview'} eq "clist") { $sortcolumn = $clist->{'sortcol'} } elsif ($prefs{'messageview'} eq "ctree") { $sortcolumn = $clist->sort_column() } if (($clist->{'name'} ne "message") or $sortcolumn > 3) { $lblbox = new Gtk::HBox(0,0); if ($prefs{'messageview'} eq "clist") { $lbl = new Gtk::Label($headers[$clist->{'sortcol'}]); } elsif ($prefs{'messageview'} eq "ctree") { $lbl = new Gtk::Label($headers[$clist->{'sortcol'}]); } my $sortdir; $sortdir = $clist->{'sortdir'}; if ($sortdir eq "ascending") { if(-f "$prefs{'PixmapDir'}/down.xpm") { ($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$clist->style->bg('normal'),"$prefs{'PixmapDir'}/down.xpm"); } else { ($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$clist->style->bg('normal'),@dummy_pixmap); } } else { if(-f "$prefs{'PixmapDir'}/up.xpm") { ($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm($main::message_clist->clist_window,$clist->style->bg('normal'),"$prefs{'PixmapDir'}/up.xpm"); } else { ($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::message_clist->clist_window,$clist->style->bg('normal'),@dummy_pixmap); } } $arrow = new Gtk::Pixmap($pixmap, $mask); $lblbox->pack_start($lbl,0,0,0); $lblbox->pack_end($arrow,0,0,5); $lblbox->show; $lbl->show; $arrow->show; $clist->set_column_widget($clist->{'sortcol'}, $lblbox); } return 1; } sub ctree_get_node_position { my ($ctree, $node) = @_; my ($row) = $node->row or return -1; my ($i) = 0; foreach ($ctree->row_list()) { return $i if ($_ eq $row); $i++; } return -1; } sub init_acct_menu { my ($sql, $query, @row); $sql = "select id, descr from accounts order by id"; $query = $conn->prepare($sql); $query->execute(); $acct_menu = new Gtk::Menu; $acct_menu2 = new Gtk::Menu; while (@row=$query->fetchrow_array()) { my $menuitem=new Gtk::MenuItem("$row[1]"); $menuitem->signal_connect("activate" => \&check_mail, $row[0], "1"); $menuitem->show; $acct_menu_items{$row[0]} = $menuitem; $acct_menu->append($menuitem); my $menuitem2=new Gtk::MenuItem("$row[1]"); $menuitem2->signal_connect("activate" => \&check_mail, $row[0], "1"); $menuitem2->show; $acct_menu2_items{$row[0]} = $menuitem2; $acct_menu2->append($menuitem2); } return 1; } sub new_pixmap { my ($filename, $window, $background) = @_; my ($pixmap,$mask); if(-f $filename) { ($pixmap, $mask) = create_from_xpm Gtk::Gdk::Pixmap($window, $background, $filename); } else { ($pixmap, $mask) = create_from_xpm_d Gtk::Gdk::Pixmap($window, $background, @dummy_pixmap); } return new Gtk::Pixmap($pixmap, $mask); } sub selection_handler { my ($widget,$html_view,$attach_menu,$view_attach_menu,$hdr_pane,$row,$col)=@_; if ($view_timer) { Gtk->timeout_remove($view_timer); } if ($prefs{'viewpane'} eq "y") { $view_timer=Gtk->timeout_add(100,\&view_msg,$widget,$row,$col,$html_view,$attach_menu,$view_attach_menu,$hdr_pane); } elsif ($prefs{'viewpane'} eq "n") { if (not defined $view_window) { return 1; } $view_timer=Gtk->timeout_add(100,\&view_msg,$widget,$row,$col,$view_window->{'html'},$attach_menu,$view_attach_menu,$view_window->{'hdr_pane'}); } return 1; } sub check_receipt { my ($msgid)=@_; my ($query,$receiptto,$subject); $sql = "select subject, rreceiptto from messages where id=$msgid"; $query=$conn->prepare($sql); $query->execute(); ($subject, $receiptto)=$query->fetchrow_array(); if (defined $receiptto && $receiptto ne "" && $receiptto ne "sent" && $receiptto ne "never"){ # check the prefs what to do with the receipt if (defined $prefs{'SendReceipt'} && $prefs{'SendReceipt'} eq "never"){ &Pronto::Data::Message::receipt_never(undef, undef, $msgid); } elsif (defined $prefs{'SendReceipt'} && $prefs{'SendReceipt'} eq "all") { &Pronto::Data::Message::receipt_now(undef, undef, $msgid); } else { &Pronto::Data::Message::receipt_dialog($msgid, $subject, $receiptto); } } } sub mark_read { if ($mark_timer) { Gtk->timeout_remove($mark_timer); } my ($widget, $row, $msgid) = @_; my ($query,$receiptto); if ($prefs{'messageview'} eq "clist") { $widget->set_text($row,2,""); if ($prefs{'BoldMsg'}) { $widget->set_row_style($row, $normal); } } else { my @selection = $widget->selection; if (!@selection) { return 1} $widget->set_text($selection[0],2,""); if ($prefs{'BoldMsg'}) { $widget->node_set_row_style($selection[0],$normal); } if($selection[0]->row->expanded != 1) { &Pronto::MessageList::new_in_tree($selection[0],1,1); } } $sql = "update messages set newmsg='n' where id = $msgid"; $conn->do($sql); &check_receipt($msgid); &Pronto::FolderTree::refresh_folder_tree; } sub view_msg { my ($widget, $row, $col, $html_view, $attach_menu, $view_attach_menu, $hdr_pane) = @_; my ($msgid, $sql, $query, $newmsg); if ($col == 1) { return 1; } $sql = "select newmsg from messages where id=?"; $query=$conn->prepare($sql); if ($view_timer) { Gtk->timeout_remove($view_timer); } undef $view_timer; $msgid = &Pronto::MessageList::get_selected_msgid() if ($widget->{'name'} eq "message"); $msgid = &Pronto::CListView::get_selected_msgid($widget) if ($widget->{'name'} eq "view"); if (! $msgid) { return 1; } &Pronto::Read::view_message($conn, $msgid, $html_view, 1, 0, $attach_menu, $view_attach_menu, $hdr_pane); $query->execute($msgid); ($newmsg) = $query->fetchrow_array(); ## mark as read if (($newmsg) and ($newmsg eq "y")) { if ($mark_timer) { Gtk->timeout_remove($mark_timer); } $mark_timer = Gtk->timeout_add($prefs{'MarkAsReadDelay'} * 1000, \&mark_read, $widget, $row, $msgid); } else { ## if already read check if return receipt has already been sent, if no, ask to &check_receipt($msgid); } return 1; } sub close_app { my ($widget, $window) = @_; if ($prefs{'empty_trash_on_exit'}) { &Pronto::FolderTree::empty_trash(undef,1); } $window->destroy; &save_prefs; foreach (keys(%entity)) { $entity{$_}->purge; } opendir(DIR,"$prefs{'MailDir'}/tmp"); while (defined (my $nuke = readdir DIR)) { next if $nuke =~ /^\.\.?$/; unlink "$prefs{'MailDir'}/tmp/$nuke"; } closedir(DIR); $query->finish; $conn->disconnect; unlink("$prefs{'MailDir'}/pronto.running"); Gtk->exit(0); } # Pass it a name, and a width & height to fall back on # if we aren't or can't saveSize sub get_win_size { my ($name,$dw,$dh) = @_; return ($dw,$dh) unless $prefs{'saveSize'} eq "y"; return ($dw,$dh) unless defined $prefs{$name.'Width'} and defined $prefs{$name.'Height'} >0; return ($prefs{$name.'Width'}, $prefs{$name.'Height'}); } sub save_win_size { my ($widget, $name, $window) = @_; my ($x, $y, $w, $h)=$window->get_geometry; if (defined $prefs{'saveSize'} && $prefs{'saveSize'} eq "y"){ $prefs{$name.'Width'}=$w; $prefs{$name.'Height'}=$h; } return Gtk::false; } sub save_sizepane { my ($widget, $window) = @_; if (defined $prefs{'saveSize'} && $prefs{'saveSize'} eq "y"){ $prefs{'startPaneWidth'}=@$window[2]; $prefs{'startPaneHeight'}=@$window[3]; } return Gtk::false; } sub save_sizepane2 { my ($widget, $window) = @_; if (defined $prefs{'saveSize'} && $prefs{'saveSize'} eq "y"){ $prefs{'secondPaneWidth'}=@$window[2]; $prefs{'secondPaneHeight'}=@$window[3]; } return Gtk::false; } sub debug { return 1; } sub destroy_entity { my ($widget, $msgid) = @_; $entity{$msgid}->{'usecount'}--; if ($entity{$msgid}->{'usecount'} >= 1) { return 1; } else { $entity{$msgid}->purge; delete $entity{$msgid}; return 1; } } sub destroy_window { my($widget, $windowref) = @_; $$windowref = undef; return 1; } sub send_out { if (open(TMP,"<$prefs{'MailDir'}/prontosend.running")) { my $proc = ; if(kill(0,$proc)) { &err_dialog( _("Prontosend is already running. if this is not true, please delete prontosend.running in ") . $prefs{'MailDir'}); return 1; } else { close(TMP); unlink "$prefs{'MailDir'}/prontosend.running"; } } if ($prefs{'forksend'} == 0) { $Pronto::Send::inter = 1; $Pronto::Send::called_from_send = 0; &Pronto::Send::send(); } else { my ($child); unless ($child = fork) { die "cannot fork: $~" unless defined $child; exec("prontosend 1"); } } return 1; } sub check_mail { if (open(TMP,"<$prefs{'MailDir'}/prontoget.running")) { my $proc = ; if(kill(0,$proc)) { &err_dialog( _("Prontoget is already running. if this is not true, please delete prontoget.running in ") . $prefs{'MailDir'}); return 1; } else { close(TMP); unlink "$prefs{'MailDir'}/prontoget.running"; } } if ($prefs{'forkget'} == 0) { $Pronto::Get::acct = $_[1]; $Pronto::Get::inter = $_[2]; $Pronto::Get::called_from_get = 0; &Pronto::Get::get(); } else { my ($child); unless ($child = fork) { die "cannot fork: $~" unless defined $child; exec("prontoget $_[1] $_[2]"); } } if ($prefs{'SendImmediately'} eq "n") { &send_out; } return 1; } sub init_timers { if ($prefs{'AutoCheckTime'} > 0) { my $seconds = 60*$prefs{'AutoCheckTime'}; alarm $seconds; } return 1; } sub appInit_NoSplash { &read_prefs; &save_prefs; $conn=&open_db_conn; $sql = "select * from accounts"; $query = $conn->prepare($sql); $query->execute() or &Pronto::FirstRun::create_database; if ($prefs{'NoHTML'} eq "y") { $HTMLWIDGET = "text" } &check_fonts(); my $fontnormal = Gtk::Gdk::Font->load($prefs{'FontMLNormal'}); my $fontbold = Gtk::Gdk::Font->load($prefs{'FontMLBold'}); my $fontui = Gtk::Gdk::Font->load($prefs{'FontUIBold'}); $head_style = new Gtk::Style; $head_style->font($fontui); &Pronto::FolderTree::init_folder_tree; $bold = $folder_tree->style->copy; $bold->font($fontbold); $normal = $folder_tree->style->copy; $normal->font($fontnormal); &Pronto::FolderMenus::init_folder_menu; &init_acct_menu; &Pronto::MainWindow::init_main_window; &Pronto::FolderTree::refresh_folder_tree; &init_timers; &set_default_box; &Pronto::FolderTree::set_folder_style; if ($prefs{'CheckMailOnStartup'} eq "y") { &check_mail("","all", 1); } } sub appInit { &read_prefs; if (!$prefs{'Splash'}) { appInit_NoSplash(); return; } my $splash = splash(); $splash->{'statusbar'}->push(1, _("Reading prefs ...")); while (Gtk->events_pending) { Gtk->main_iteration } &save_prefs; while (Gtk->events_pending) { Gtk->main_iteration } $splash->{'statusbar'}->push(1, _("Connecting to the db ...")); $conn=&open_db_conn; while (Gtk->events_pending) { Gtk->main_iteration } $sql = "select * from accounts"; $query = $conn->prepare($sql); $query->execute() or &Pronto::FirstRun::create_database; if ($prefs{'NoHTML'} eq "y") { $HTMLWIDGET = "text" } while (Gtk->events_pending) { Gtk->main_iteration } $splash->{'statusbar'}->push(1, _("Checking and loading fonts ...")); &check_fonts(); my $fontnormal = Gtk::Gdk::Font->load($prefs{'FontMLNormal'}); my $fontbold = Gtk::Gdk::Font->load($prefs{'FontMLBold'}); my $fontui = Gtk::Gdk::Font->load($prefs{'FontUIBold'}); $head_style = new Gtk::Style; $head_style->font($fontui); while (Gtk->events_pending) { Gtk->main_iteration } $splash->{'statusbar'}->push(1, _("Reading folders ...")); &Pronto::FolderTree::init_folder_tree; $bold = $folder_tree->style->copy; $bold->font($fontbold); $normal = $folder_tree->style->copy; $normal->font($fontnormal); while (Gtk->events_pending) { Gtk->main_iteration } $splash->{'statusbar'}->push(1, _("Building folder menus ...")); &Pronto::FolderMenus::init_folder_menu; while (Gtk->events_pending) { Gtk->main_iteration } $splash->{'statusbar'}->push(1, _("Reading accounts ...")); &init_acct_menu; while (Gtk->events_pending) { Gtk->main_iteration } $splash->{'statusbar'}->push(1, _("Creating main window ...")); &Pronto::MainWindow::init_main_window; $splash->window->raise(); while (Gtk->events_pending) { Gtk->main_iteration } $splash->{'statusbar'}->push(1, _("Preparing folder tree ...")); &Pronto::FolderTree::refresh_folder_tree; $splash->destroy(); &init_timers; &set_default_box; &Pronto::FolderTree::set_folder_style; if ($prefs{'CheckMailOnStartup'} eq "y") { &check_mail("","all", 1); } } ##### initial setup ## test for existing config file ## if not existing call setupdialog and setup tables (if they don't exist) if (!defined &Gtk::CTree::get_node_position) { *Gtk::CTree::get_node_position = \&ctree_get_node_position; } my $configfile=$ENV{'HOME'}."/.prontorc"; unless (-f $configfile) { &Pronto::FirstRun::firstSetup(); } else { if (defined $ARGV[0] and $ARGV[0] =~ /\-\-help/) { print("\nPronto $version\nUsage: pronto to-someone\@foo.com subject cc-someone\@bar.com bcc-someone\@foo.com\n"); exit; } if (defined $ARGV[0] and $ARGV[0] ne "") { if(open(TMP,"<$prefs{'MailDir'}/pronto.running")) { my $proc = ; close(TMP); if(kill(0,$proc)) { open(TMP,">$prefs{'MailDir'}/pronto.address"); foreach(@ARGV) { print TMP "$_\n"; } close(TMP); kill('USR1',$proc); exit; } else { unlink("$prefs{'MailDir'}/pronto.running"); } } &read_prefs(); $ONETIME = 1; $conn=&open_db_conn; my @fields; $ARGV[0] =~ s/mailto\://; #GNOME URL handler $fields[0] = $ARGV[0]; #to #subject if (defined $ARGV[1]) { $fields[2] = $ARGV[1]; } else { $fields[2] = ""; } #cc if (defined $ARGV[2]) { $ARGV[2] =~ s/mailto\://; #GNOME URL handler $fields[1] = $ARGV[2]; } else { $fields[1] = ""; } $fields[3] = $ARGV[3]; &Pronto::Compose::init_msg_window(0, undef, \@fields); } else { if(open(TMP,"<$prefs{'MailDir'}/pronto.running")) { my $proc = ; close(TMP); if(kill(0,$proc)) { kill('USR1',$proc); exit; } else { unlink("$prefs{'MailDir'}/pronto.running"); open(TMP,">$prefs{'MailDir'}/pronto.running"); print TMP "$$\n"; close(TMP); &appInit(); } } else { open(TMP,">$prefs{'MailDir'}/pronto.running"); print TMP "$$\n"; close(TMP); &appInit();} } } sub check_fonts { my @fonts = ( [$prefs{'FontUIBold'},"FontUIBold"], [$prefs{'FontMLBold'},"FontMLBold"], [$prefs{'FontMessages'},"FontMessages"], [$prefs{'FontMLNormal'},"FontMLNormal"], [$prefs{'FontComposer'},"FontComposer"] ); foreach my $font (@fonts) { Gtk::Gdk::Font->load(@{$font}[0]) or &change_font(@{$font}[1]); } } sub change_font { my ($pref) = @_; my $fallbackfont = "-misc-fixed-medium-r-semicondensed-*-*-120-*-*-c-*-koi8-r"; print "$prefs{$pref}: ", _("this font does not seem to be valid on your system, falling back to fixed"),"\n"; $prefs{$pref} = $fallbackfont; } sub splash { my ($splash); $splash = new Gtk::Window("toplevel"); $splash->realize(); $splash->set_title("Pronto - Splash!"); $splash->set_position('center'); $splash->window->set_decorations(0); $splash->{'vbox'} = new Gtk::VBox(0,0); $splash->{'statusbar'} = new Gtk::Statusbar(); my ($p,$m) = Gtk::Gdk::Pixmap->create_from_xpm($splash->window,$splash->style->bg('normal'),$libpath."/pixmaps/splash.xpm"); my $pixmap = new Gtk::Pixmap($p,$m); $pixmap->show(); $splash->add($splash->{'vbox'}); $splash->{'vbox'}->pack_start($pixmap,0,0,0); $splash->{'vbox'}->pack_start($splash->{'statusbar'},0,0,0); show_all $splash; while (Gtk->events_pending) { Gtk->main_iteration } return $splash; } sub set_folder_tree_drag_signals { $folder_tree->drag_dest_set('all', ['copy', 'move'], @target_table[0..1]); $folder_tree->signal_connect("drag_motion", \&Pronto::FolderTree::folderlist_drag_motion); $folder_tree->signal_connect("drag_data_received", \&Pronto::FolderTree::folderlist_drag_data_received); return; } sub set_clist_drag_signals { $message_clist->drag_source_set(['button1_mask', 'button3_mask'], ['copy', 'move'],@target_table); $message_clist->signal_connect("drag_begin", \&Pronto::MessageList::drag_begin); $message_clist->signal_connect("drag_data_get",\&Pronto::MessageList::messagelist_drag_data_get); $message_clist->signal_connect("drag_end", \&Pronto::MessageList::drag_end); return; } sub set_attachment_clist_drag_signals { my ($clist) = @_; $clist->drag_dest_set('all', ['copy', 'move'], @target_table[0..1]); $clist->signal_connect("drag_data_received", \&Pronto::Compose::Drag_Data_Received); return; } sub set_composer_entry_drag_signals { my ($entry) = @_; $entry->drag_dest_set('all',['copy', 'move'], @target_table[0..1]); $entry->signal_connect("drag_data_received", \&Pronto::Compose::Drag_Data_Entry); return; } main Gtk;