xref: /trunk/main/solenv/bin/modules/installer/windows/shortcut.pm (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1#*************************************************************************
2#
3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4#
5# Copyright 2000, 2010 Oracle and/or its affiliates.
6#
7# OpenOffice.org - a multi-platform office productivity suite
8#
9# This file is part of OpenOffice.org.
10#
11# OpenOffice.org is free software: you can redistribute it and/or modify
12# it under the terms of the GNU Lesser General Public License version 3
13# only, as published by the Free Software Foundation.
14#
15# OpenOffice.org is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU Lesser General Public License version 3 for more details
19# (a copy is included in the LICENSE file that accompanied this code).
20#
21# You should have received a copy of the GNU Lesser General Public License
22# version 3 along with OpenOffice.org.  If not, see
23# <http://www.openoffice.org/license.html>
24# for a copy of the LGPLv3 License.
25#
26#*************************************************************************
27
28package installer::windows::shortcut;
29
30use installer::existence;
31use installer::exiter;
32use installer::files;
33use installer::globals;
34use installer::windows::idtglobal;
35
36##############################################################
37# Returning the file object for the msiassembly table.
38##############################################################
39
40sub get_file_by_name
41{
42    my ( $filesref, $filename ) = @_;
43
44    my $foundfile = 0;
45    my $onefile;
46
47    for ( my $i = 0; $i <= $#{$filesref}; $i++ )
48    {
49        $onefile = ${$filesref}[$i];
50        my $name = $onefile->{'Name'};
51
52        if ( $name eq $filename )
53        {
54            $foundfile = 1;
55            last;
56        }
57    }
58
59    if (! $foundfile ) { $onefile  = ""; }
60
61    return $onefile;
62}
63
64##############################################################
65# Returning identifier for shortcut table.
66##############################################################
67
68sub get_shortcut_identifier
69{
70    my ($shortcut) = @_;
71
72    my $identifier = $shortcut->{'gid'};
73
74    return $identifier;
75}
76
77##############################################################
78# Returning directory for shortcut table.
79##############################################################
80
81sub get_shortcut_directory
82{
83    my ($shortcut, $dirref) = @_;
84
85    # For shortcuts it is easy to convert the gid_Dir_Abc into the unique name in
86    # the directory table, for instance help_en_simpressidx.
87    # For files (components) this is not so easy, because files can be included
88    # in zip files with subdirectories that are not defined in scp.
89
90    my $onedir;
91    my $shortcutdirectory = $shortcut->{'Dir'};
92    my $directory = "";
93    my $found = 0;
94
95    for ( my $i = 0; $i <= $#{$dirref}; $i++ )
96    {
97        $onedir = ${$dirref}[$i];
98        my $directorygid = $onedir->{'Dir'};
99
100        if ( $directorygid eq $shortcutdirectory )
101        {
102            $found = 1;
103            last;
104        }
105    }
106
107    if (!($found))
108    {
109        installer::exiter::exit_program("ERROR: Did not find DirectoryID $shortcutdirectory in directory collection for shortcut", "get_shortcut_directory");
110    }
111
112    $directory = $onedir->{'uniquename'};
113
114    if ($directory eq "") { $directory = "INSTALLLOCATION"; }       # Shortcuts in the root directory
115
116    return $directory;
117}
118
119##############################################################
120# Returning name for shortcut table.
121##############################################################
122
123sub get_shortcut_name
124{
125    my ($shortcut, $shortnamesref, $onelanguage) = @_;
126
127    my $returnstring;
128
129    my $name = $shortcut->{'Name'};
130
131    my $shortstring = installer::windows::idtglobal::make_eight_three_conform($name, "shortcut", $shortnamesref);
132    $shortstring =~ s/\s/\_/g;  # replacing white spaces with underline
133
134    if ( $shortstring eq $name ) { $returnstring = $name; } # nothing changed
135    else {$returnstring = $shortstring . "\|" . $name; }
136
137    return $returnstring;
138}
139
140##############################################################
141# Returning component for shortcut table.
142##############################################################
143
144sub get_shortcut_component
145{
146    my ($shortcut, $filesref) = @_;
147
148    my $onefile;
149    my $component = "";
150    my $found = 0;
151    my $shortcut_fileid = $shortcut->{'FileID'};
152
153    my $absolute_filename = 0;
154    if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
155    if ( $styles =~ /\bABSOLUTE_FILENAME\b/ ) { $absolute_filename = 1; }   # FileID contains an absolute filename
156    if ( $styles =~ /\bUSE_HELPER_FILENAME\b/ ) { $absolute_filename = 1; } # ComponentIDFile contains id of a helper file
157
158    # if the FileID contains an absolute filename, therefore the entry for "ComponentIDFile" has to be used.
159    if ( $absolute_filename ) { $shortcut_fileid = $shortcut->{'ComponentIDFile'}; }
160
161    for ( my $i = 0; $i <= $#{$filesref}; $i++ )
162    {
163        $onefile = ${$filesref}[$i];
164        my $filegid = $onefile->{'gid'};
165
166        if ( $filegid eq $shortcut_fileid )
167        {
168            $found = 1;
169            last;
170        }
171    }
172
173    if (!($found))
174    {
175        installer::exiter::exit_program("ERROR: Did not find FileID $shortcut_fileid in file collection for shortcut", "get_shortcut_component");
176    }
177
178    $component = $onefile->{'componentname'};
179
180    # finally saving the componentname in the folderitem collector
181
182    $shortcut->{'component'} = $component;
183
184    return $component;
185}
186
187##############################################################
188# Returning target for shortcut table.
189##############################################################
190
191sub get_shortcut_target
192{
193    my ($shortcut, $filesref) = @_;
194
195    my $target = "";
196    my $found = 0;
197    my $shortcut_fileid = $shortcut->{'FileID'};
198    my $onefile;
199
200    for ( my $i = 0; $i <= $#{$filesref}; $i++ )
201    {
202        $onefile = ${$filesref}[$i];
203        my $filegid = $onefile->{'gid'};
204
205        if ( $filegid eq $shortcut_fileid )
206        {
207            $found = 1;
208            last;
209        }
210    }
211
212    if (!($found))
213    {
214        installer::exiter::exit_program("ERROR: Did not find FileID $shortcut_fileid in file collection for shortcut", "get_shortcut_target");
215    }
216
217    if ( $onefile->{'Name'} )
218    {
219        $target = $onefile->{'Name'};
220    }
221
222    $target = "\[\#" . $target . "\]";  # format for Non-Advertised shortcuts
223
224    return $target;
225}
226
227##############################################################
228# Returning arguments for shortcut table.
229##############################################################
230
231sub get_shortcut_arguments
232{
233    my ($shortcut) = @_;
234
235    return "";
236}
237
238##############################################################
239# Returning the localized description for shortcut table.
240##############################################################
241
242sub get_shortcut_description
243{
244    my ($shortcut, $onelanguage) = @_;
245
246    my $description = "";
247    if ( $shortcut->{'Tooltip'} ) { $description = $shortcut->{'Tooltip'}; }
248
249    return $description;
250}
251
252##############################################################
253# Returning hotkey for shortcut table.
254##############################################################
255
256sub get_shortcut_hotkey
257{
258    my ($shortcut) = @_;
259
260    return "";
261}
262
263##############################################################
264# Returning icon for shortcut table.
265##############################################################
266
267sub get_shortcut_icon
268{
269    my ($shortcut) = @_;
270
271    return "";
272}
273
274##############################################################
275# Returning iconindex for shortcut table.
276##############################################################
277
278sub get_shortcut_iconindex
279{
280    my ($shortcut) = @_;
281
282    return "";
283}
284
285##############################################################
286# Returning show command for shortcut table.
287##############################################################
288
289sub get_shortcut_showcmd
290{
291    my ($shortcut) = @_;
292
293    return "";
294}
295
296##############################################################
297# Returning working directory for shortcut table.
298##############################################################
299
300sub get_shortcut_wkdir
301{
302    my ($shortcut) = @_;
303
304    return "";
305}
306
307####################################################################
308# Returning working directory for shortcut table for FolderItems.
309####################################################################
310
311sub get_folderitem_wkdir
312{
313    my ($onelink, $dirref) = @_;
314
315    # For shortcuts it is easy to convert the gid_Dir_Abc into the unique name in
316    # the directory table, for instance help_en_simpressidx.
317
318    my $onedir;
319    my $workingdirectory = "";
320    if ( $onelink->{'WkDir'} ) { $workingdirectory = $onelink->{'WkDir'}; }
321    my $directory = "";
322
323    if ( $workingdirectory )
324    {
325        my $found = 0;
326
327        for ( my $i = 0; $i <= $#{$dirref}; $i++ )
328        {
329            $onedir = ${$dirref}[$i];
330            my $directorygid = $onedir->{'Dir'};
331
332            if ( $directorygid eq $workingdirectory )
333            {
334                $found = 1;
335                last;
336            }
337        }
338
339        if (!($found))
340        {
341            installer::exiter::exit_program("ERROR: Did not find DirectoryID $workingdirectory in directory collection for FolderItem", "get_folderitem_wkdir");
342        }
343
344        $directory = $onedir->{'uniquename'};
345
346        if ($directory eq "") { $directory = "INSTALLLOCATION"; }
347    }
348
349    return $directory;
350}
351
352###################################################################
353# Returning the directory for a folderitem for shortcut table.
354###################################################################
355
356sub get_folderitem_directory
357{
358    my ($shortcut) = @_;
359
360    # my $directory = "$installer::globals::programmenufolder";  # default
361    my $directory = "$installer::globals::officemenufolder";     # default
362
363    # The value $installer::globals::programmenufolder is not correct for the
364    # PREDEFINED folders, like PREDEFINED_AUTOSTART
365
366    if ( $shortcut->{'FolderID'} eq "PREDEFINED_AUTOSTART" )
367    {
368        $directory = $installer::globals::startupfolder;
369    }
370
371    if ( $shortcut->{'FolderID'} eq "PREDEFINED_DESKTOP" )
372    {
373        $directory = $installer::globals::desktopfolder;
374        $installer::globals::desktoplinkexists = 1;
375    }
376
377    if ( $shortcut->{'FolderID'} eq "PREDEFINED_STARTMENU" )
378    {
379        $directory = $installer::globals::startmenufolder;
380    }
381
382    # saving the directory in the folderitems collector
383
384    $shortcut->{'directory'} = $directory;
385
386    return $directory;
387}
388
389########################################################################
390# Returning the target (feature) for a folderitem for shortcut table.
391# For non-advertised shortcuts this is a formatted string.
392########################################################################
393
394sub get_folderitem_target
395{
396    my ($shortcut, $filesref) = @_;
397
398    my $onefile;
399    my $target = "";
400    my $found = 0;
401    my $shortcut_fileid = $shortcut->{'FileID'};
402
403    my $styles = "";
404    my $nonadvertised = 0;
405    my $absolute_filename = 0;
406    if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
407    if ( $styles =~ /\bNON_ADVERTISED\b/ ) { $nonadvertised = 1; }  # this is a non-advertised shortcut
408    if ( $styles =~ /\bABSOLUTE_FILENAME\b/ ) { $absolute_filename = 1; }   # FileID contains an absolute filename
409
410    # if the FileID contains an absolute filename this can simply be returned as target for the shortcut table.
411    if ( $absolute_filename )
412    {
413        $shortcut->{'target'} = $shortcut_fileid;
414        return $shortcut_fileid;
415    }
416
417    for ( my $i = 0; $i <= $#{$filesref}; $i++ )
418    {
419        $onefile = ${$filesref}[$i];
420        my $filegid = $onefile->{'gid'};
421
422        if ( $filegid eq $shortcut_fileid )
423        {
424            $found = 1;
425            last;
426        }
427    }
428
429    if (!($found))
430    {
431        installer::exiter::exit_program("ERROR: Did not find FileID $shortcut_fileid in file collection for folderitem", "get_folderitem_target");
432    }
433
434    # Non advertised shortcuts do not return the feature, but the path to the file
435    if ( $nonadvertised )
436    {
437        $target = "\[" . $onefile->{'uniquedirname'} . "\]" . "\\" . $onefile->{'Name'};
438        $shortcut->{'target'} = $target;
439        return $target;
440    }
441
442    # the rest only for advertised shortcuts, which contain the feature in the shortcut table.
443
444    if ( $onefile->{'modules'} ) { $target = $onefile->{'modules'}; }
445
446    # If modules contains a list of modules, only taking the first one.
447    # But this should never be needed
448
449    if ( $target =~ /^\s*(.*?)\,/ ) { $target = $1; }
450
451    # Attention: Maximum feature length is 38!
452    installer::windows::idtglobal::shorten_feature_gid(\$target);
453
454    # and finally saving the target in the folderitems collector
455
456    $shortcut->{'target'} = $target;
457
458    return $target;
459}
460
461########################################################################
462# Returning the arguments for a folderitem for shortcut table.
463########################################################################
464
465sub get_folderitem_arguments
466{
467    my ($shortcut) = @_;
468
469    my $parameter = "";
470
471    if ( $shortcut->{'Parameter'} ) { $parameter = $shortcut->{'Parameter'}; }
472
473    return $parameter;
474}
475
476########################################################################
477# Returning the icon for a folderitem for shortcut table.
478# The returned value has to be defined in the icon table.
479########################################################################
480
481sub get_folderitem_icon
482{
483    my ($shortcut, $filesref, $iconfilecollector) = @_;
484
485    my $styles = "";
486    if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
487    if ( $styles =~ /\bNON_ADVERTISED\b/ ) { return ""; }   # no icon for non-advertised shortcuts
488
489    my $iconfilegid = "";
490
491    if ( $shortcut->{'IconFile'} ) { $iconfilegid = $shortcut->{'IconFile'}; }
492    else { $iconfilegid = $shortcut->{'FileID'}; }
493
494    my $onefile;
495    my $found = 0;
496
497    for ( my $i = 0; $i <= $#{$filesref}; $i++ )
498    {
499        $onefile = ${$filesref}[$i];
500        my $filegid = $onefile->{'gid'};
501
502        if ( $filegid eq $iconfilegid )
503        {
504            $found = 1;
505            last;
506        }
507    }
508
509    if (!($found))
510    {
511        installer::exiter::exit_program("ERROR: Did not find FileID $iconfilegid in file collection", "get_folderitem_icon");
512    }
513
514    $iconfile = $onefile->{'Name'};
515
516    # collecting all icon files to copy them into the icon directory
517
518    my $sourcepath = $onefile->{'sourcepath'};
519
520    if (! installer::existence::exists_in_array($sourcepath, $iconfilecollector))
521    {
522        push(@{$iconfilecollector}, $sourcepath);
523    }
524
525    return $iconfile;
526}
527
528########################################################################
529# Returning the iconindex for a folderitem for shortcut table.
530########################################################################
531
532sub get_folderitem_iconindex
533{
534    my ($shortcut) = @_;
535
536    my $styles = "";
537    if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
538    if ( $styles =~ /\bNON_ADVERTISED\b/ ) { return ""; }   # no iconindex for non-advertised shortcuts
539
540    my $iconid = 0;
541
542    if ( $shortcut->{'IconID'} ) { $iconid = $shortcut->{'IconID'}; }
543
544    return $iconid;
545}
546
547########################################################################
548# Returning the show command for a folderitem for shortcut table.
549########################################################################
550
551sub get_folderitem_showcmd
552{
553    my ($shortcut) = @_;
554
555    return "1";
556}
557
558###########################################################################################################
559# Creating the file Shortcut.idt dynamically
560# Content:
561# Shortcut Directory_ Name Component_ Target Arguments Description Hotkey Icon_ IconIndex ShowCmd WkDir
562###########################################################################################################
563
564sub create_shortcut_table
565{
566    my ($filesref, $linksref, $folderref, $folderitemsref, $dirref, $basedir, $languagesarrayref, $includepatharrayref, $iconfilecollector) = @_;
567
568    for ( my $m = 0; $m <= $#{$languagesarrayref}; $m++ )
569    {
570        my $onelanguage = ${$languagesarrayref}[$m];
571
572        my @shortcuttable = ();
573
574        my @shortnames = ();    # to collect all short names
575
576        installer::windows::idtglobal::write_idt_header(\@shortcuttable, "shortcut");
577
578        # First the links, defined in scp as ShortCut
579
580        for ( my $i = 0; $i <= $#{$linksref}; $i++ )
581        {
582            my $onelink = ${$linksref}[$i];
583
584            # Controlling the language!
585            # Only language independent folderitems or folderitems with the correct language
586            # will be included into the table
587
588            if (! (!(( $onelink->{'ismultilingual'} )) || ( $onelink->{'specificlanguage'} eq $onelanguage )) )  { next; }
589
590            my %shortcut = ();
591
592            $shortcut{'Shortcut'} = get_shortcut_identifier($onelink);
593            $shortcut{'Directory_'} = get_shortcut_directory($onelink, $dirref);
594            $shortcut{'Name'} = get_shortcut_name($onelink, \@shortnames, $onelanguage);    # localized name
595            $shortcut{'Component_'} = get_shortcut_component($onelink, $filesref);
596            $shortcut{'Target'} = get_shortcut_target($onelink, $filesref);
597            $shortcut{'Arguments'} = get_shortcut_arguments($onelink);
598            $shortcut{'Description'} = get_shortcut_description($onelink, $onelanguage);    # localized description
599            $shortcut{'Hotkey'} = get_shortcut_hotkey($onelink);
600            $shortcut{'Icon_'} = get_shortcut_icon($onelink);
601            $shortcut{'IconIndex'} = get_shortcut_iconindex($onelink);
602            $shortcut{'ShowCmd'} = get_shortcut_showcmd($onelink);
603            $shortcut{'WkDir'} = get_shortcut_wkdir($onelink);
604
605            my $oneline = $shortcut{'Shortcut'} . "\t" . $shortcut{'Directory_'} . "\t" . $shortcut{'Name'} . "\t"
606                        . $shortcut{'Component_'} . "\t" . $shortcut{'Target'} . "\t" . $shortcut{'Arguments'} . "\t"
607                        . $shortcut{'Description'} . "\t" . $shortcut{'Hotkey'} . "\t" . $shortcut{'Icon_'} . "\t"
608                        . $shortcut{'IconIndex'} . "\t" . $shortcut{'ShowCmd'} . "\t" . $shortcut{'WkDir'} . "\n";
609
610            push(@shortcuttable, $oneline);
611        }
612
613        # Second the entries into the start menu, defined in scp as Folder and Folderitem
614        # These shortcuts will fill the icons table.
615
616        for ( my $i = 0; $i <= $#{$folderref}; $i++ )
617        {
618            my $foldergid = ${$folderref}[$i]->{'gid'};
619
620            # iterating over all folderitems for this folder
621
622            for ( my $j = 0; $j <= $#{$folderitemsref}; $j++ )
623            {
624                my $onelink = ${$folderitemsref}[$j];
625
626                # Controlling the language!
627                # Only language independent folderitems or folderitems with the correct language
628                # will be included into the table
629
630                if (! (!(( $onelink->{'ismultilingual'} )) || ( $onelink->{'specificlanguage'} eq $onelanguage )) )  { next; }
631
632                # controlling the folder
633
634                my $localused = 0;
635
636                if ( $onelink->{'used'} ) { $localused = $onelink->{'used'}; }
637
638                if (!($localused == 1)) { $onelink->{'used'} = "0"; }       # no resetting
639
640                if (!( $onelink->{'FolderID'} eq $foldergid )) { next; }
641
642                $onelink->{'used'} = "1";
643
644                my %shortcut = ();
645
646                $shortcut{'Shortcut'} = get_shortcut_identifier($onelink);
647                $shortcut{'Directory_'} = get_folderitem_directory($onelink);
648                $shortcut{'Name'} = get_shortcut_name($onelink, \@shortnames, $onelanguage);    # localized name
649                $shortcut{'Component_'} = get_shortcut_component($onelink, $filesref);
650                $shortcut{'Target'} = get_folderitem_target($onelink, $filesref);
651                $shortcut{'Arguments'} = get_folderitem_arguments($onelink);
652                $shortcut{'Description'} = get_shortcut_description($onelink, $onelanguage);    # localized description
653                $shortcut{'Hotkey'} = get_shortcut_hotkey($onelink);
654                $shortcut{'Icon_'} = get_folderitem_icon($onelink, $filesref, $iconfilecollector);
655                $shortcut{'IconIndex'} = get_folderitem_iconindex($onelink);
656                $shortcut{'ShowCmd'} = get_folderitem_showcmd($onelink);
657                $shortcut{'WkDir'} = get_folderitem_wkdir($onelink, $dirref);
658
659                my $oneline = $shortcut{'Shortcut'} . "\t" . $shortcut{'Directory_'} . "\t" . $shortcut{'Name'} . "\t"
660                            . $shortcut{'Component_'} . "\t" . $shortcut{'Target'} . "\t" . $shortcut{'Arguments'} . "\t"
661                            . $shortcut{'Description'} . "\t" . $shortcut{'Hotkey'} . "\t" . $shortcut{'Icon_'} . "\t"
662                            . $shortcut{'IconIndex'} . "\t" . $shortcut{'ShowCmd'} . "\t" . $shortcut{'WkDir'} . "\n";
663
664                push(@shortcuttable, $oneline);
665            }
666        }
667
668        # The soffice.ico has to be included into the icon table
669        # as icon for the ARP applet
670
671        my $onefile = "";
672        my $sofficefile = "soffice.ico";
673
674        my $sourcepathref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$sofficefile, $includepatharrayref, 0);
675
676        if ($$sourcepathref eq "") { installer::exiter::exit_program("ERROR: Could not find $sofficefile as icon!", "create_shortcut_table"); }
677
678        if (! installer::existence::exists_in_array($$sourcepathref, $iconfilecollector))
679        {
680            unshift(@{$iconfilecollector}, $$sourcepathref);
681            $installer::globals::sofficeiconadded = 1;
682        }
683
684        my $localinfoline = "Added icon file $$sourcepathref for language pack into icon file collector.\n";
685        push(@installer::globals::logfileinfo, $localinfoline);
686
687        # Saving the file
688
689        my $shortcuttablename = $basedir . $installer::globals::separator . "Shortcut.idt" . "." . $onelanguage;
690        installer::files::save_file($shortcuttablename ,\@shortcuttable);
691        my $infoline = "Created idt file: $shortcuttablename\n";
692        push(@installer::globals::logfileinfo, $infoline);
693    }
694}
695
696
6971;