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