Sophie

Sophie

distrib > Mandriva > 9.0 > i586 > by-pkgid > 738a681b5c2e2fed80f2ba9a5506a4b5 > files > 80

OpenOffice.org-1.0.1-9mdk.src.rpm

#!/usr/bin/perl
#*****************************************************************************
# 
#  ooffice - Wrapper script for OpenOffice.org
# 
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License version 2, as
#  published by the Free Software Foundation.
# 
#  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.
# 
#*****************************************************************************

use strict;
use XML::Twig;
use MDK::Common;

# Define OpenOffice.org version
my $Version = "<OOVERSION>";

# Define user OOo versions file
my $VersionFile = "$ENV{HOME}/.sversionrc";

# Define system installation directory
my $SystemInstallDir = "/usr/lib/openoffice";

# Define user installation directory
my $UserInstallDir = "$ENV{HOME}/.openoffice";

# Define user work directory ($HOME directory)
my $UserWorkDir = "$ENV{HOME}";

# Define chkfontpath program
my $ChkfontpathProgram = "/usr/sbin/chkfontpath";

# Define OOo setup program
my $SetupProgram = "$SystemInstallDir/program/setup";

# Define setup autoresponse file for user installation
my $SetupConfig = "/etc/openoffice/autoresponse.conf";

# Define user Setup.xml file
my $SetupXML = "$UserInstallDir/user/config/registry/instance/org/openoffice/Setup.xml";

# Define user Common.xml file
my $CommonXML = "$UserInstallDir/user/config/registry/instance/org/openoffice/Office/Common.xml";

# Define user Linguistic.xml file
my $LinguisticXML = "$UserInstallDir/user/config/registry/instance/org/openoffice/Office/Linguistic.xml";

# Define global Linguistic.xml file
my $SystemLinguisticXML = "$SystemInstallDir/share/config/registry/instance/org/openoffice/Office/Linguistic.xml";

# Define system ooffice script config
my $SystemOOfficeRC = "/etc/openoffice/openoffice.conf";

# Define user ooffice script config
my $OOfficeRC = "$ENV{HOME}/.oofficerc";

# Define system psprint.conf
my $SystemPsprintConf = "$SystemInstallDir/share/psprint/psprint.conf";

# Define user psprint.conf
my $PsprintConf = "$UserInstallDir/user/psprint/psprint.conf";

# Define if debug mode
my $Debug = 0;

#=============================================================================
# Print debug output
#=============================================================================

sub debug {
    print @_ if ($Debug);
}

#=============================================================================
# Read versions config file
#=============================================================================

sub ReadVersionFile($) {
    my ($file) = @_;
    my $e;
    my %entries;
    
    foreach (cat_("$file")) {
        chomp;
        if (/^\[(\w+)\]/) {
            $entries{$1} = $e = { };
        }
        elsif (/^([^=]+)=([^\r\n]+)/) {
            $e->{$1} = $2;
        }
    }
    %entries;
}

#=============================================================================
# Write versions config file
#=============================================================================

sub DoWriteVersionFile(%$) {
    my ($config, $file) = @_;
    local *F;
    
    if ($file) {
        open F, ">$file" or die "Cant write to $file\n";
        select F;
    }
    local $\ = "\n";
    while (my ($secname, $secvars) = each %$config) {
        print "[$secname]";
        while (my ($key, $value) = each %$secvars) {
            print "$key=$value";
        }
        print;
    }
    if ($file) {
        close F;
        select STDOUT;
    }
}

sub DumpVersionFile(%) {
    my (%config) = @_;
    DoWriteVersionFile \%config;
}

sub WriteVersionFile(%) {
    my (%config) = @_;
    DoWriteVersionFile \%config, "$VersionFile";
}

#=============================================================================
# Define default language -> country mappings
#=============================================================================

sub CountryOfLanguage($) {
    my ($lang) = @_;
    
    # Note if language is not in the table of exceptions below, it is
    # assumed that country is uc $lang
    my %countryOf = ("en" => "US",
                     "cs" => "CZ",
                     "ca" => "ES",
                     "da" => "DK",
                     "el" => "GR",
                     "ja" => "JP",
                     "ko" => "KR",
                     "sv" => "SE");

    $countryOf{$lang} || uc $lang;
}

#=============================================================================
# Main
#=============================================================================

# Get global and user configs (user config file has precedence over system config).
my %OOfficeConfig = (if_(-f "$SystemOOfficeRC", getVarsFromSh("$SystemOOfficeRC")),
                     if_(-f "$OOfficeRC", getVarsFromSh("$OOfficeRC")));

# Parse command line arguments
my @ooo_argv;
my $override_lang;
while ($ARGV[0]) {
    $_ = shift;
    if (m/^--lang(=(\S+))?/) {
        $override_lang = $2 || shift;
    }
    else {
        push @ooo_argv, $_;
    }
}
push @ooo_argv, "private:factory/s$1"
    if (!@ooo_argv && $0 =~ m/\/oo(calc|draw|impress|math|writer)$/);

# Get current language code
my $lang = $override_lang || $ENV{LC_MESSAGES} || $ENV{LANG} || "en_US";
$lang =~ tr/-/_/;
$lang .= "_" . CountryOfLanguage $lang if ($lang !~ /_/);
(my $isocode = $lang) =~ s/([a-z]+)_.*/\1/;
(my $oolang = $lang) =~ tr/_/-/;

# Remove any stale entry from versions file, if OOo was not already
# installed from an MDK package.
if ( -r "$VersionFile" ) {
    my %config = ReadVersionFile "$VersionFile";
    my $versions = $config{Versions};
    my $home = $versions->{"OpenOffice.org $Version"};
    if ($home && $home ne "file://$UserInstallDir") {
        foreach (keys %$versions) {
            delete $versions->{$_} if ($versions->{$_} eq $home);
        }
        WriteVersionFile %config;
    }
}

# Perform a user installation, if necessary.
if ( ! -d $UserInstallDir || ! -e "$UserInstallDir/soffice" || ! -e "$UserInstallDir/spadmin" ) {
    # First, make sure to remove any reference to $UserInstallDir, from older
    # (and broken) installation
    if ( -f $VersionFile ) {
        my %config = ReadVersionFile "$VersionFile";
        my $versions = $config{Versions};
        my $changed = 0;
        foreach (keys %$versions) {
            if ($versions->{$_} eq "file://$UserInstallDir") {
                delete $versions->{$_};
                $changed = 1;
            }
        }
        WriteVersionFile %config if ($changed);
    }
    # We can safely do the installation now
    die "Installation of OpenOffice.org $Version failed\n"
        if (system("$SetupProgram -R:$SetupConfig -LANG:$isocode"));
}

# Clean the installation version tags.
if ( -f "$VersionFile" ) {
    my %config = ReadVersionFile "$VersionFile";
    my $versions = $config{Versions};
    my $changed = 0;
    foreach (keys %$versions) {
        if ($_ =~ /^OpenOffice.org [.0-9]+/ && $_ ne "OpenOffice.org $Version") {
            delete $versions->{$_};
            $changed = 1;
        }
    }
    # Add current version tag if it does not exist already. This
    # occurs when you upgrade from 1.0 to 1.0.1 for example.
    $versions->{"OpenOffice.org $Version"} = "file://$UserInstallDir"
        if (!$versions->{"OpenOffice.org $Version"});
    WriteVersionFile %config if ($changed);
}
else {
    # The versions file is bound to exist unless we (or the user)
    # nuked it somehow. Regenerate it. We already have the
    # installation directory at this point.
    WriteVersionFile Versions => { "OpenOffice.org $Version" => "file://$UserInstallDir" };
}

# Remove broken links and previous dictionaries symlinks.
# As of 1.0.1-1mdk, dictionaries stuff is global in /usr/share/dict/ooo.
my @stale_dictentries;
foreach (glob_("$UserInstallDir/user/wordbook/*.aff")) {
    if ( -l $_ ) {
        (my $entry = $_) =~ s|.*/([^/]+)\.aff|\1|;
        push @stale_dictentries, $entry;
        unlink $_, ((dirname $_) . "/$entry.dic");
    }
}
my $dict_list = "$UserInstallDir/user/wordbook/dictionary.lst";
my $dict_pattern = join "|", @stale_dictentries;
substInFile { s|^(\s*DICT.*\s($dict_pattern))$|\# Removed: \1| } "$dict_list"
    if ( $dict_pattern && -f "$dict_list" );

# Remove dictionary.lst if it no longer contains any valid dictionary
# (DICT) or hyphenation (HYPH) entries.
unlink "$dict_list" if ( ! grep /^\s*(DICT|HYPH)/, cat_("$dict_list") );

# Expand TrueType and Type1 font paths
my @exclude_fontpaths = ( "/usr/share/fonts/ttf/japanese" );
my @fontpath;
if ( ! -x "$ChkfontpathProgram" ) {
    # OOo now correctly grabs chkfontpath output, so only add
    # "well-known" TrueType and Type1 font paths if that program is
    # not available
    push @fontpath, grep { -d $_ && (! member $_, @exclude_fontpaths ) }
    ( glob_("/usr/share/fonts/ttf/*"),
      "/usr/X11R6/lib/X11/fonts/TTF",
      "/usr/X11R6/lib/X11/fonts/drakfont/ttf",
      "/usr/X11R6/lib/X11/fonts/Type1",
      "/usr/share/fonts/default/Type1" );
}
$ENV{SAL_FONTPATH_USER} = join(";", @fontpath) . ";$ENV{SAL_FONTPATH_USER}"
    if (@fontpath);

# Create the user/work link for "Open..." menu command to work
# flawlessly
symlinkf $UserWorkDir, "$UserInstallDir/user/work"
    if ( ! -l "$UserInstallDir/user/work" && ! -d "$UserInstallDir/user/work" );

#=============================================================================
# Dump XML tree into file specified by name
#=============================================================================

sub OutputXML($$) {
    my ($file, $tree) = @_;
    local *F;
    open F, ">$file" or die "Cannot write to file $file\n";
    $tree->print(\*F);
    close F;
}

#=============================================================================
# Define language -> font mappings
#=============================================================================

sub FontOfLanguage($) {
    my ($lang) = @_;
    my %fontOf = ("el-GR" => "Kerkis",
                  "ja-JP" => "Kochi Gothic",
                  "ko-KR" => "Baekmuk Gulim",
                  "ru-RU" => "Nimbus Sans L",
                  "zh-CN" => "AR PL KaitiM GB",
                  "zh-TW" => "AR PL KaitiM Big5");
    $fontOf{$lang} || "Luxi Sans";
}

#=============================================================================
# Return the MTIME of a file, -1 if it does not exist
#=============================================================================

sub TimeStamp($) {
    my ($file) = @_;
    -f "$file" ? (stat "$file")[9] : -1;
}

#=============================================================================
# Misc configuration setup in user *.xml files
#=============================================================================

if ( $lang && ( -e "$SystemInstallDir/help/$lang"
             || -e "$SystemInstallDir/help/$isocode"
             || -e "$SystemInstallDir/help/$oolang" ) )
{
    # Initialize Twig XML parser
    my $p = XML::Twig->new(pretty_print => "indented", keep_encoding => 1);
    
    # Adjust user interface language, in Setup.xml
    my $setup_xml = $p->parsefile("$SetupXML");
    my $oolocale_node;
    if (! ($oolocale_node = ($setup_xml->get_xpath("/Setup/L10N/ooLocale"))[0]) ) {
        # Glue in new <L10N> section, "en-US" is the default locale
        my $new_l10n_node = << "EOF;";
<L10N>
 <ooLocale cfg:type="string">en-US</ooLocale>
</L10N>
EOF;
        $oolocale_node = XML::Twig->new()->parsestring($new_l10n_node)->root;
        $oolocale_node->paste($setup_xml->root);
        $oolocale_node = ($oolocale_node->descendants("ooLocale"))[0];
    }
    my $old_oolang = $oolocale_node->text();
    $oolocale_node->set_text("$oolang");
    OutputXML "$SetupXML", $setup_xml;

    # Update default language for documents, in Linguistic.xml
    # Create file if it does not exist yet.
    my $linguistic_file;
    if ( -f ( $linguistic_file = "$LinguisticXML" ) || -f ( $linguistic_file = "$SystemLinguisticXML" ) ) {
        my $linguistic_xml = $p->parsefile("$linguistic_file");
        $_->set_text("$oolang")
            foreach ( $linguistic_xml->get_xpath("/Linguistic/General/DefaultLocale") );
        OutputXML "$LinguisticXML", $linguistic_xml;
    }

    # Choose UI fonts according to the current UI language
    my $common_xml_changed = 0;
    my $common_xml = $p->parsefile("$CommonXML");
    my $font_node;
    if (! ($font_node = ($common_xml->get_xpath("/Common/Font/Substitution/FontPairs/FontReplacement/SubstituteFont"))[0]) ) {
        # Glue in new <Font> section
        my $new_font_node = << "EOF;";
<Font>
 <Substitution>
  <FontPairs cfg:element-type="FontReplacement">
   <FontReplacement state="replaced" cfg:name="_0">
    <Always cfg:type="boolean">true</Always>
    <OnScreenOnly cfg:type="boolean">true</OnScreenOnly>
    <ReplaceFont cfg:type="string">Andale Sans UI</ReplaceFont>
    <SubstituteFont cfg:type="string">Luxi Sans</SubstituteFont>
   </FontReplacement>
  </FontPairs>
  <Replacement cfg:type="boolean">true</Replacement>
 </Substitution>
</Font>
EOF;
        $font_node = XML::Twig->new()->parsestring($new_font_node)->root;
        $font_node->paste($common_xml->root);
        $font_node = ($font_node->descendants("SubstituteFont"))[0];
        $common_xml_changed = 1;
    }
    my $override_font = $OOfficeConfig{UI_FONT};
    if ($override_font eq "AUTO") {
        # Set new font UI, following the first switch to current language
        if ((my $font = FontOfLanguage $oolang) ne FontOfLanguage $old_oolang) {
            $font_node->set_text("$font");
            $common_xml_changed = 1;
        }
    }
    elsif ($override_font && $override_font ne $font_node->text) {
        $font_node->set_text("$override_font");
        $common_xml_changed = 1;
    }

    # Set UI font scaling based on current display resolution, or user defined value
    my $scale;
    my $override_fontscaling = $OOfficeConfig{FONT_SCALING} || "100";
    if ($override_fontscaling =~ /^([0-9]+)$/) {
        $scale = $1;
    }
    elsif ($override_fontscaling eq "AUTO") {
        # Get current resolution of screen #0
        my ($width, $height);
        foreach ( reverse cat_("LC_ALL=C xdpyinfo |") ) {
            ($width, $height) = ($1, $2) if m|^\s+dimensions:\s+([0-9]+)x([0-9]+) pixels|;
        }
        # Map to a scale value
        my %ScaleOfResolution = ("640" => "120", "800" => "120", "1024" => "110", "1152" => "110");
        $scale = $ScaleOfResolution{$width} || "100";
    }

    my $scale_node;
    if (! ($scale_node = ($common_xml->get_xpath("/Common/View/FontScaling"))[0]) ) {
        # Glue in new <View> section
        my $new_view_node = << "EOF;";
<View>
 <FontAntiAliasing>
  <MinPixelHeight cfg:type="short">8</MinPixelHeight>
 </FontAntiAliasing>
 <FontScaling cfg:type="short">100</FontScaling>
</View>
EOF;
        $scale_node = XML::Twig->new()->parsestring($new_view_node)->root;
        $scale_node->paste($common_xml->root);
        $scale_node = ($scale_node->descendants("FontScaling"))[0];
    }
    if ($scale ne $scale_node->text) {
        $scale_node->set_text("$scale");
        $common_xml_changed = 1;
    }
    
    OutputXML "$CommonXML", $common_xml if ($common_xml_changed);

    # Default to paper size from locale setting
    my $paper_size = $OOfficeConfig{PAPER_SIZE};
    
    # Get paper size dimension according to language set
    if ($paper_size eq "AUTO") {
        my ($width, $height);
        foreach (cat_("LC_ALL=$lang /usr/bin/locale -k LC_PAPER |")) {
            if (/^width=([0-9]+)/) {
                $width = $1;
            }
            elsif (/^height=([0-9]+)/) {
                $height = $1;
            }
        }
        
        my %PaperSizeOfDimensions = ("210x297" => "A4", "216x279" => "Letter");
        $paper_size = $PaperSizeOfDimensions{"${width}x${height}"} || "A4";
    }
    
    if ($paper_size) {
        # Always grab the newer system configuration as new printers
        # may have been configure in the meantime.
        output "$PsprintConf", ( cat_("$SystemPsprintConf"), "\n" )
            if ( TimeStamp "$SystemPsprintConf" > TimeStamp "$PsprintConf"
            || ! grep /PDF.+Converter (Screen|Press)/, cat_("$PsprintConf") );
        # Change "Generic Printer" section as this is the only valid
        # one provided that no other printer is configured and setup
        # as default, if any. Otherwise, printerdrake already
        # generates printer configuration with the right paper size.
        # NOTE: also change for PDF converters
        foreach my $category ( "Generic Printer",
                               "PDF 1.4 Converter Screen",
                               "PDF 1.4 Converter Press" )
        {
            # psprint.conf happens to be a "Windows"-style file
            update_gnomekderc $PsprintConf, $category, PPD_PageSize => $paper_size;
        }
    }
}

# And here we go. ;-)
exec "$UserInstallDir/soffice", @ooo_argv if (!$Debug);

# Local variables:
# tab-width: 4
# indent-tabs-mode: nil
# End: