#!/usr/bin/perl # # Copyright (C) 2001-2004 by MandrakeSoft # DUPONT Sebastien # Damien Chaumette <dchaumette@mandrakesoft.com> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # drakfont Future Overview # - Fonts import: # pfb ( Adobe Type 1 binary ) # pfa ( Adobe Type 1 ASCII ) # ttf ( True-Type ) # pcf.gz # Speedo # and Bitmap (PCF, BDF, and SNF) # - Features # - Install fonts from any directory # - Get windows fonts on any vfat partitions # - Get fonts on any partitions. # - UN-installation of any fonts (even if not installed through drakfont) # - Support # - Xfs # - ghostscript & printer # - Staroffice & printer # - abiword # - netscape # - Koffice, Gnumeric, ... studying # - all fonts supported by printer # - anti-aliases by RENDER in Xfree86 .... # supported by KDE. # will be supported by gnome 1.2. # Visual Interface: # Window interface: # - Fontselectiondialog widget # - Command buttons under Fontselectiondialog (like the actual frontend). # Commands buttons: # - import from windows partition. # import from all fat32 partitions and look for winnt/windows/font # and import all (delete doubles) but don't import if they already exist. # - import from directory # look to see if each font exists and do not delete the original. # (replace all, no, none) # expert options: # specify the directory, and look to see if it exists before # if it exists ask: (replace all, no, none) # - uninstall with list per font type # Expert additional switch # - option support: ghostscript, Staroffice, etc... # check-button. (by default all check) # - Printer Application Fonts Support... # check-button. (by default all check) # # TODO: # - abiword, Koffice, Gnumeric, ... # - Speedo and Bitmap (PCF, BDF, and SNF) # # REQUIRE: # - font-tools.*.mdk.i586.rpm # # USING: # - pfm2afm: by Ken Borgendale: Convert a Windows .pfm file to a .afm (Adobe Font Metrics) # - type1inst: by James Macnicol: type1inst generates files fonts.dir fonts.scale & Fontmap. # - ttf2pt1: by Andrew Weeks, Frank Siegert, Thomas Henlich, Sergey Babkin convert ttf font files to afm and pfb fonts # # # directory to install fonts /usr/X11R6/lib/X11/fonts/ # -->> /usr/X11R6/lib/X11/fonts/drakfont use strict; use diagnostics; use lib qw(/usr/lib/libDrakX); use standalone; #- warning, standalone must be loaded very first, for 'explanations' use ugtk2 qw(:create :dialogs :helpers :wrappers); use common; require_root_capability(); # global variables needed by each functions my $xlsfonts = 0; my $windows = 0; my $replace; my $so = 1; my $gs = 1; my $abi = 1; my $printer = 1; my $mode = -1; my @application; my @install; my @uninstall; my $interactive; my $dialog; my $pbar; my $pbar1; my $pbar2; my $pbar3; my $window1; my $model; my $list; my $list_all_font_path; my $left_list; my $right_list; my $left_model; my $right_model; foreach (@ARGV) { /--list|-l/ and $list_all_font_path = 1, $mode = -1; /--xls_fonts/ and $xlsfonts = 1, $mode = -1; /--windows_import|-wi/ and $windows = 1, $mode = -1; /--replace|-r/ and $replace = 1, $mode = -1; /--application/ and $mode = 0, next; $mode == 0 and push @application, $_; /--install/ and $mode = 1, next; $mode == 1 and push @install, $_; /--uninstall/ and $mode = 2, next; $mode == 2 and push @uninstall, $_; } foreach my $i (@application) { if ($i =~ /so/i) { if ($gs != 2) { $gs = 0 } $so = 2; } if ($i =~ /gs/i) { if ($so != 2) { $so = 0 } $gs = 2; } } # PATH and binary full path #my $xfs_conffile = '/etc/fonts/fonts.conf'; my $drakfont_dir = '/usr/X11R6/lib/X11/fonts/drakfont'; my $ttf2pt1 = '/usr/sbin/ttf2pt1'; my $pfm2afm = '/usr/sbin/pfm2afm'; my $type1inst = '/usr/sbin/type1inst'; my $chkfontpath = '/usr/sbin/chkfontpath'; # mkttfdir only knows about iso-8859-1, using ttmkfdir -u instead -- pablo my $ttmkfdir = '/usr/sbin/ttmkfdir'; my $fccache = '/usr/bin/fc-cache'; my @font_list; # list of fonts to install my @installed_fonts; # list of installed fonts my @installed_fonts_path; # list of path included in xfs my @installed_fonts_full_path; # full path list of fonts to uninstall sub list_fontpath() { foreach (grep { /\d+:\s/ } `$chkfontpath -l`) { chomp; s/\d+:\s//gi; s/:\w*$//gi; push @installed_fonts_path, $_; } } sub chk_empty_xfs_path() { foreach my $tmp_path (@installed_fonts_path) { if (every { /^fonts/ || /^type/ } all($tmp_path)) { system("$chkfontpath -r $tmp_path ") or print "PERL::system command failed during chkfontpath\n"; } } } sub search_installed_fonts() { list_fontpath(); interactive_progress($pbar, 0.1, N("Search installed fonts")); push @installed_fonts, all($_) foreach @installed_fonts_path; interactive_progress($pbar, 0.1, N("Unselect fonts installed")); } sub search_installed_fonts_full_path() { list_fontpath(); foreach my $i (@installed_fonts_path) { foreach my $j (all($i)) { push @installed_fonts_full_path, "$i/$j"; } } } sub search_windows_font() { foreach my $fstab_line (grep { /vfat|smbfs|ntfs/ } cat_('/etc/mtab')) { my $win_dir = (split('\s', $fstab_line))[1]; my @list_fonts_win = all("$win_dir/windows/fonts"); my @list_fonts_winnt = all("$win_dir/winnt/fonts"); my $nb_dir = @list_fonts_win + @list_fonts_winnt; foreach ([ \@list_fonts_win, "windows" ], [ \@list_fonts_winnt, "winnt" ]) { foreach my $i (@{ $_->[0] }) { if ($interactive) { if ($nb_dir) { progress($pbar, 0.25 / $nb_dir, N("parse all fonts")); } else { err_dialog(N("Error"), N("No fonts found")); return 0; } } !$replace && any { /$i/ } @installed_fonts and next; any { /$i$/ } @font_list or push @font_list, "$win_dir/$_->[1]/fonts/$i"; } } $interactive && $nb_dir and progress($pbar, 1, N("done")); } if (!@font_list) { print "[35mdrakfont:: could not find any font in /win*/fonts [0m\n"; $interactive and err_dialog(N("Error"), N("Could not find any font in your mounted partitions")); return 0; } 1; } sub is_a_font($) { my ($file) = @_; any { $file =~ /\Q.$_\E$/i } qw(ttf pfa pfb pcf pcf.gz pfm gsf); } # Optimisation de cette etape indispensable sub search_dir_font() { foreach my $fn (@install) { my @font_list_tmp; if (!(-e $fn)) { print "$fn :: no such file or directory \n" } else { if (-d $fn) { foreach my $i (all($fn)) { if (is_a_font($i)) { push @font_list_tmp, $i; foreach my $i (@font_list_tmp) { !$replace && any { /$i/ } @installed_fonts and next; any { /$i/ } @font_list or push @font_list, "$fn/$i"; } } } } elsif (is_a_font($fn)) { !$replace && any { /$fn/ } @installed_fonts and next; !any { /$fn/ } @installed_fonts and push @font_list, $fn; } } interactive_progress($pbar, 0.50 / @install, N("Reselect correct fonts")); } interactive_progress($pbar, 1, N("done")); !@font_list && $interactive and err_dialog(N("Error"), N("Could not find any font.\n")); } sub search_dir_font_uninstall { my ($fn) = @_; print "Fonts to uninstal: " . $_ . "\n" foreach uniq(@font_list, -d $fn ? (grep { is_a_font($_) } all($fn)) : if_(is_a_font($fn), $fn)); } sub search_dir_font_uninstall_gi() { @font_list = @uninstall; interactive_progress($pbar, 1, N("Search for fonts in installed list")); } sub print_list() { print "Font(s) to Install:\n\n"; print "$_\n" foreach @font_list; } sub dir_created() { return if $::testing; -e $drakfont_dir or mkdir_p($drakfont_dir); -e $drakfont_dir . "/Type1" or mkdir_p($drakfont_dir . "/Type1"); -e $drakfont_dir . "/ttf" or mkdir_p($drakfont_dir . "/ttf"); -e $drakfont_dir . "/tmp" or mkdir_p($drakfont_dir . "/tmp"); -e $drakfont_dir . "/tmp/ttf" or mkdir_p($drakfont_dir . "/tmp/ttf"); -e $drakfont_dir . "/tmp/Type1" or mkdir_p($drakfont_dir . "/tmp/Type1"); -e $drakfont_dir . "/tmp/tmp" or mkdir_p($drakfont_dir . "/tmp/tmp"); } sub convert_fonts { my ($fonts, $converter, $font_type, $o_generate_pfb) = @_; $o_generate_pfb = $o_generate_pfb ? "-b" : ""; foreach my $fontname (@$fonts) { system("cd $drakfont_dir/tmp/tmp && $converter $o_generate_pfb $fontname"); interactive_progress($pbar2, 0.50 / @$fonts, N("%s fonts conversion", $font_type)); } } sub convert_ttf_fonts { my ($fonts, $o_generate_pfb) = @_; convert_fonts($fonts, $ttf2pt1, "TTF", $o_generate_pfb); } sub move_fonts { my ($src_dir, $dest_dir, @extensions) = @_; my @fonts = map { s!.*/!!; $_ } map { glob("$src_dir/*.$_") } @extensions; system("cd $src_dir && mv @fonts $dest_dir") if @fonts; } sub put_font_dir_real { my ($subdir, $command, $progress, $title) = @_; system("cd $drakfont_dir/$subdir && $fccache && $command"); interactive_progress($pbar2, $progress, $title); return "$chkfontpath -a $drakfont_dir/$subdir"; } sub put_font_dir() { -e "/usr/share/ghostscript" or do { $gs = 0; print "ghostscript is not installed on your system...\n" }; if (@font_list) { dir_created(); foreach my $i (@font_list) { cp_af($i, $drakfont_dir . "/tmp/tmp"); interactive_progress($pbar1, 1 / @font_list, N("Fonts copy")); } interactive_progress($pbar1, 0.01, N("done")); interactive_progress($pbar2, 0.10, N("True Type fonts installation")); foreach my $font (glob("$drakfont_dir/tmp/tmp/*.TTF")) { my $newfont = $font; $newfont =~ s/\.TTF$/.ttf/; rename($font, $newfont); } system('cd ' . $drakfont_dir . '/tmp/tmp && cp *.ttf ../../ttf; chmod 644 ../../ttf/*ttf'); interactive_progress($pbar2, 0.20, N("please wait during ttmkfdir...")); my $update_chkfontpath = put_font_dir_real("ttf", "$ttmkfdir -u > fonts.dir", 0.10, N("True Type install done")); if ($gs) { convert_ttf_fonts([ glob("$drakfont_dir/tmp/tmp/*.ttf") ], 1); move_fonts("$drakfont_dir/tmp/tmp", "../Type1", qw(afm gsf pfb pfm)); system("cd $drakfont_dir/tmp/Type1 && $type1inst"); interactive_progress($pbar2, 0.1, N("type1inst building")); if ($so) { -e "$drakfont_dir/tmp/Type1/Fontmap" and system("cd $drakfont_dir/tmp/Type1 && cat Fontmap >> `rpm -ql ghostscript | grep Fontmap.GS` "); move_fonts("$drakfont_dir/tmp/Type1", "../../Type1", qw(afm gsf pfb pfm)); } else { system("cd $drakfont_dir/tmp/Type1 && cat Fontmap >> `rpm -ql ghostscript | grep Fontmap.GS` "); move_fonts("$drakfont_dir/tmp/Type1", "../../Type1", qw(afm gsf pfb pfm)); } $update_chkfontpath .= "; " . put_font_dir_real("Type1", $type1inst, 0.05, N("Ghostscript referencing")); } elsif ($so) { convert_ttf_fonts([ glob("$drakfont_dir/tmp/tmp/*.ttf") ]); convert_fonts([ glob("$drakfont_dir/tmp/tmp/*.pfm") ], $pfm2afm, "PFM"); move_fonts("$drakfont_dir/tmp/tmp", "../Type1", qw(afm)); move_fonts("$drakfont_dir/tmp/Type1", "../../Type1", qw(afm)); $update_chkfontpath .= put_font_dir_real("Type1", $type1inst, 0.14, N("type1inst building")); } interactive_progress($pbar2, 1, N("done")); interactive_progress($pbar3, 0.25, N("Suppress Temporary Files")); rm_rf("$drakfont_dir/tmp/"); print "\n\nretarting xfs......\n"; interactive_progress($pbar3, 0.5, N("Restart XFS")); system($update_chkfontpath); system('/etc/rc.d/init.d/xfs restart'); system('xset fp rehash'); interactive_progress($pbar3, 0.30, N("done")); } } sub remove_gs_fonts() { my @Fontmap_new; if (all("$drakfont_dir/remove")) { system(" cd $drakfont_dir/remove && $type1inst"); my @Fontmap_out = cat_("$drakfont_dir/remove/Fontmap"); my $FontmapGS = `rpm -ql ghostscript | grep Fontmap.GS`; chomp($FontmapGS); my @FontmapGS_list = cat_($FontmapGS); foreach my $font_gs (@FontmapGS_list) { my @tmp_list = split(' ', $font_gs); any { /$tmp_list[0]/ } @Fontmap_out or push @Fontmap_new, $font_gs; } print $_ foreach @Fontmap_new; output($FontmapGS, @Fontmap_new); } } sub remove_fonts() { my @list_dir; -e $drakfont_dir . "/remove" or mkdir_p($drakfont_dir . "/remove") if !$::testing; interactive_progress($pbar, 1, N("done")); foreach my $i (@font_list) { local $_ = $i; if (/.pfb$/ || /.gsf$/ || /.pfm$/ || /.pfa$/) { system("mv $_ $drakfont_dir/remove "); } else { next if $::testing; if (/.ttf$/) { rm_rf($_); # rebuild of the fonts.dir and fc-cache files system("cd `dirname $_` && $fccache && $ttmkfdir -u > fonts.dir"); } else { rm_rf($i) } } $i =~ s!/\w*\.\w*!!gi; any { $i } @list_dir or push @list_dir, $i; interactive_progress($pbar1, 1 / @font_list, N("Suppress Fonts Files")); } interactive_progress($pbar1, 0.01, N("done")); -e "/usr/share/ghostscript" and remove_gs_fonts(); foreach my $i (@list_dir) { if (listlength all($i) < 3) { system("chkfontpath -r $i") or print "PERL::system command failed during chkfontpath\n"; } else { system("cd $i && type1inst") or print "PERL::system command failed during cd or type1inst\n"; } interactive_progress($pbar2, 1 / @list_dir, N("Suppress Fonts Files")); } interactive_progress($pbar2, 0.01, N("xfs restart")); system("/etc/rc.d/init.d/xfs restart"); system('xset fp rehash'); -e "/usr/share/ghostscript" and rm_rf("$drakfont_dir/remove") if !$::testing; interactive_progress($pbar2, 0.01, N("done")); } sub license_msg() { print N("Before installing any fonts, be sure that you have the right to use and install them on your system.\n\n-You can install the fonts the normal way. In rare cases, bogus fonts may hang up your X Server.") . "\n"; } sub backend_mod() { $xlsfonts and system("xlsfonts"); $list_all_font_path and system($chkfontpath); if ($windows) { license_msg(); print "\nWindows fonts Installation........\n"; search_installed_fonts(); if (search_windows_font()) { print_list(); put_font_dir(); } print "\nThe End...........................\n"; } if (@install) { license_msg(); print "\nInstall Specifics Fonts...........\n"; search_installed_fonts(); search_dir_font(); print "Font to install: " . $_ . "\n" foreach @font_list; put_font_dir(); print "\nThe End...........................\n"; } if (@uninstall) { print "\nUninstall Specifics Fonts.........\n"; search_installed_fonts_full_path(); if ($interactive) { search_dir_font_uninstall_gi() } else { search_dir_font_uninstall() foreach @uninstall } remove_fonts(); print "\nThe End............................\n"; } } sub create_fontsel() { Gtk2::FontSelection->new; } sub interactive_mode() { $interactive = 1; $window1 = ugtk2->new('drakfont'); $window1->{rwindow}->signal_connect(delete_event => sub { ugtk2->exit(0) }); unless ($::isEmbedded) { $window1->{rwindow}->set_position('center'); $window1->{rwindow}->set_title(N("DrakFont")); } my $button = {}; my $disable = sub { my ($b) = @_; $button->{$_}->set_sensitive($_ ne $b) foreach keys %$button }; local $::Wizard_no_previous = 1; gtkadd($window1->{window}, gtkpack_(Gtk2::VBox->new(0, 2), if_(!$::isEmbedded, 0, Gtk2::Banner->new("drakfont", N("DrakFont"))), 0, Gtk2::WrappedLabel->new(N("Font List")), 1, create_fontsel(), 0, create_okcancel(my $oc = { ok_clicked => sub { Gtk2->main_quit }, }, undef, undef, '', if_([ N("About"), \&help, 1 ]), [ N("Options"), \&appli_choice, 1 ], [ N("Uninstall"), \&uninstall, 1 ], [ N("Import"), \&advanced_install, 1 ], ), ), ); $oc->{ok}->set_label(N("Close")); $disable->('font_list'); $window1->{rwindow}->show_all; $window1->{rwindow}->realize; $window1->main; ugtk2->exit(0); } $list_all_font_path || $xlsfonts || $windows || @install || @uninstall ? backend_mod() : interactive_mode(); sub help() { ugtk2::create_dialog(N("Help"), formatAlaTeX(N("Copyright (C) 2001-2002 by MandrakeSoft DUPONT Sebastien (original version) CHAUMETTE Damien <dchaumette\@mandrakesoft.com> VIGNAUD Thierry <tvignaud\@mandrakesoft.com>") . "\n\n\n" . N("This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.") . "\n\n\n" . N("Thanks: - pfm2afm: by Ken Borgendale: Convert a Windows .pfm file to a .afm (Adobe Font Metrics) - type1inst: by James Macnicol: type1inst generates files fonts.dir fonts.scale & Fontmap. - ttf2pt1: by Andrew Weeks, Frank Siegert, Thomas Henlich, Sergey Babkin Convert ttf font files to afm and pfb fonts "))); } sub appli_choice() { dialog(N("Options"), [ 0, N("Choose the applications that will support the fonts:"), 0, Gtk2::WrappedLabel->new(N("Before installing any fonts, be sure that you have the right to use and install them on your system.\n\nYou can install the fonts the normal way. In rare cases, bogus fonts may hang up your X Server.")), (map { my ($label, $ref) = @$_; (0, gtkpack_(Gtk2::HBox->new, 0, $label, 1, Gtk2::HBox->new, # BUG: that code never had supported canceling 0, gtksignal_connect(gtkset_active(Gtk2::CheckButton->new, $$ref), toggled => sub { $$ref = $$ref ? 0 : 1 }), ), ); } ([ N("Ghostscript"), \$gs ], [ N("StarOffice"), \$so ], [ N("Abiword"), \$abi ], [ N("Generic Printers"), \$printer ], ), ), ], [ gtksignal_connect(Gtk2::Button->new(N("OK")), clicked => \&exitdialog, ), ], ); } my $select_font_msg; sub font_choice() { my $file_dialog; $select_font_msg = N("Select the font file or directory and click on 'Add'"); $file_dialog = Gtk2::FileSelection->new(N("File Selection")); $file_dialog->ok_button->signal_connect(clicked => \&file_ok_sel, $file_dialog); $file_dialog->ok_button->set_label(N("Add")); $file_dialog->cancel_button->signal_connect(clicked => sub { $file_dialog->destroy }); $file_dialog->cancel_button->set_label(N("Close")); $file_dialog->show; $file_dialog->run; } sub file_ok_sel { my ($_w, $file_selection) = @_; my $file_name = $file_selection->get_filename; if ($file_name =~ /\Q$select_font_msg/) { create_dialog(N("Error"), N("You've not selected any font")); } else { print "-- @install\n"; if (!member($file_name, @install)) { push @install, $file_name; $model->append_set(undef, [ 0 => $file_name ]); } } Gtk2->main; } sub list_remove() { #- TODO : multi-selection my ($treeStore, $iter) = $list->get_selection->get_selected; return unless $iter; my $to_remove = $treeStore->get($iter, 0); my ($index) = map_index { if_($_ eq $to_remove, $::i) } @install; splice @install, $index, 1; $treeStore->remove($iter); } sub exitdialog() { Gtk2->main_quit }; sub dialog { my ($title, $widgets, $buttons, $o_main_loop) = @_; $dialog = _create_dialog($title); $dialog->signal_connect(delete_event => \&exitdialog); gtkpack_($dialog->vbox, @$widgets); gtkpack($dialog->action_area, @$buttons) if $buttons; $dialog->show_all; $window1->{rwindow}->set_sensitive(0); if ($o_main_loop) { gtkflush(); $o_main_loop->(); } else { Gtk2->main; } $dialog->destroy if $dialog; undef $dialog; $window1->{rwindow}->set_sensitive(1); } sub advanced_install() { $model = Gtk2::TreeStore->new("Glib::String"); $list = Gtk2::TreeView->new_with_model($model); $list->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0)); $list->set_headers_visible(0); $list->get_selection->set_mode('browse'); $list->set_rules_hint(1); dialog(N("Import fonts"), [ 1, create_scrolled_window($list) ], [ gtksignal_connect(Gtk2::Button->new(N("Add")), clicked => \&font_choice), gtksignal_connect(Gtk2::Button->new(N("Remove Selected")), clicked => \&list_remove), gtksignal_connect(Gtk2::Button->new(N("Install fonts")), clicked => sub { $dialog->destroy; undef $dialog; import_status() if @install; }), gtksignal_connect(Gtk2::Button->new(N("Cancel")), clicked => \&exitdialog), ], ); } sub list_to_remove() { #my @files_path = grep(!/fonts/, all($current_path)); garbage ? gtkflush(); my (@tux) = $left_list->get_selection->get_selected_rows; #- get tree & paths push @uninstall, map { $left_model->get($left_model->get_iter($_), 0) } @tux; #push @uninstall, $current_path . "/" . $files_path[$_] foreach @number_to_remove; garbage ? show_list_to_remove(); } sub show_list_to_remove() { my $model = Gtk2::TreeStore->new("Glib::String"); my $list = Gtk2::TreeView->new_with_model($model); $list->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0)); $list->set_headers_visible(0); $list->get_selection->set_mode('browse'); $list->set_rules_hint(1); $model->append_set(undef, [ 0 => $_ ]) foreach @uninstall; dialog(N("Uninstall"), [ 1, gtkpack_(Gtk2::HBox->new(0, 4), 1, create_scrolled_window($list)), ], [ gtksignal_connect(Gtk2::Button->new(N("click here if you are sure.")), clicked => sub { import_status_uninstall(); exitdialog() }), gtksignal_connect(Gtk2::Button->new(N("here if no.")), clicked => \&exitdialog ), ], ); } sub uninstall() { #- TODO : add item to right list with gtksignal_connect @install = (); @installed_fonts_path = (); list_fontpath(); chk_empty_xfs_path(); #- left part $left_model = Gtk2::TreeStore->new("Glib::String"); $left_list = Gtk2::TreeView->new_with_model($left_model); $left_list->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0)); $left_list->set_headers_visible(0); $left_list->set_rules_hint(1); $left_list->get_selection->set_mode('multiple'); $left_model->append_set(undef, [ 0 => $_ ]) foreach @installed_fonts_path; #- right part $right_model = Gtk2::TreeStore->new("Glib::String");; $right_list = Gtk2::TreeView->new_with_model($right_model); $right_list->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0)); $right_list->set_headers_visible(0); $right_list->get_selection->set_mode('multiple'); $right_list->set_rules_hint(1); dialog(N("Uninstall"), [ 1, gtkpack_(Gtk2::HBox->new(0, 4), 1, create_scrolled_window($left_list), #1, create_scrolled_window($right_list) ), ], [ gtksignal_connect(Gtk2::Button->new(N("Unselected All")), clicked => sub { $left_list->get_selection->unselect_all } ), gtksignal_connect(Gtk2::Button->new(N("Selected All")), clicked => sub { $left_list->get_selection->select_all } ), gtksignal_connect(Gtk2::Button->new(N("Remove List")), clicked => sub { exitdialog(); list_to_remove() }), gtksignal_connect(Gtk2::Button->new(N("Cancel")), clicked => \&exitdialog), ], ); } sub import_status() { $pbar = Gtk2::ProgressBar->new; $pbar1 = Gtk2::ProgressBar->new; $pbar2 = Gtk2::ProgressBar->new; $pbar3 = Gtk2::ProgressBar->new; dialog(N("Importing fonts"), [ 0, create_packtable({ col_spacings => 10, row_spacings => 50 }, [ "", "" ], [ N("Initial tests"), $pbar, $pbar->set_text(' ') ], [ N("Copy fonts on your system"), $pbar1, $pbar1->set_text(' ') ], [ N("Install & convert Fonts"), $pbar2, $pbar2->set_text(' ') ], [ N("Post Install"), $pbar3, $pbar3->set_text(' ') ], ), ], [], \&backend_mod, ); } sub import_status_uninstall() { $pbar = Gtk2::ProgressBar->new; $pbar1 = Gtk2::ProgressBar->new; $pbar2 = Gtk2::ProgressBar->new; dialog(N("Importing fonts"), [ 0, create_packtable({ col_spacings => 10, row_spacings => 50 }, [ "", "" ], [ "", "" ], [ N("Initial tests"), $pbar, $pbar->set_text(' ') ], [ N("Remove fonts on your system"), $pbar1, $pbar1->set_text(' ') ], [ N("Post Uninstall"), $pbar2, $pbar2->set_text(' ') ], ), ], [], \&backend_mod, ); } sub progress { my ($progressbar, $incr, $label_text) = @_; $progressbar->set_fraction(min(1, $progressbar->get_fraction + $incr)); $progressbar->set_text($label_text); gtkflush(); } sub interactive_progress { $interactive and progress(@_); }