e835a76ad045a2b516f64cdbde9d1d81cbbcfba5
[quassel.git] / icons / import / import_theme.pl
1 #!/usr/bin/perl
2
3 # This script scans the Quassel source for requested icons and imports the needed
4 # icons (and only them) from a KDE theme (by default Oxygen).
5 # This relies on all icons being requested using one of the convenience constructors in
6 # (K)IconLoader, like this:
7 #   widget->setIcon(SmallIcon("fubar"));
8 # Additional icons can be specified in whitelist-icons; you can also blacklist icons.
9 #
10 # NOTE: Unless you are a Quassel developer and need to bump the icons we ship, you shouldn't
11 #       need to use this script!
12
13 # USAGE: ./import/import_theme.pl $systhemefolder $themename
14 # Run from the icon/ directory.
15
16 use strict;
17 use Data::Dumper;
18 use File::Find;
19
20 my $themefolder = shift;
21
22 my $source = "../src";
23 my $themename = shift;
24 $themename = $themename ? $themename : "oxygen";
25 my $qrcfile_kde = $themename . ".qrc";
26
27 my $whitelistfile = "import/whitelist-icons";
28 my $blacklistfile = "import/blacklisted-icons";
29 my $extrafile = "import/extra-icons.qrc." . $themename;
30
31 my %req_icons;
32 my %found_icons;
33 my %blacklist;
34 my %themeblacklist;
35 my %whitelist;
36 my $extrafilecontent;
37
38 # First, load the icon blacklist
39 open BLACKLIST, "<$blacklistfile" or die "Could not open $blacklistfile\n";
40 while(<BLACKLIST>) {
41   s/#.*//;
42   next unless my ($name) = /([-\w]+)\s*/;
43   $blacklist{$name} = 1;
44 }
45 close BLACKLIST;
46
47 my $hasthemeblacklist = 1;
48 open BLACKLIST, "<$blacklistfile.$themename" or $hasthemeblacklist = 0;
49 if ($hasthemeblacklist) {
50   while(<BLACKLIST>) {
51     s/#.*//;
52     next unless my ($name) = /([-\w]+)\s*/;
53     $blacklist{$name} = 1;
54     $themeblacklist{$name} = 1;
55   }
56   close BLACKLIST;
57 } else {
58   print "Info: No theme specific blacklist found...\n";
59 }
60
61 # We now grep the source for things like SmallIcon("fubar") and generate size and name from that
62 print "Grepping $source for requested icons...\n";
63 my @results = `grep -r QIcon::fromTheme\\(\\" $source`;
64 foreach(@results) {
65   next unless my ($name) = /\W+QIcon::fromTheme\(\"([-\w]+)/;
66   $req_icons{$name} = 1
67     unless exists $blacklist{$name};
68 }
69
70 # Add whitelist icons
71 open WHITELIST, "<$whitelistfile" or die "Could not open $whitelistfile\n";
72 while(<WHITELIST>) {
73   s/#.*//;
74   next unless my ($name) = /([-\w]+)\s*/;
75   $req_icons{$name} = 1
76     unless exists $themeblacklist{$name};
77 }
78 close WHITELIST;
79
80 # Read in extra-icons
81 my $hasthemeextrafile = 1;
82 local $/;
83 open EXTRAFILE, "<$extrafile" or $hasthemeextrafile = 0;
84 if($hasthemeextrafile) {
85   binmode EXTRAFILE;
86   $extrafilecontent = <EXTRAFILE>;
87   close EXTRAFILE;
88 } else {
89   $extrafilecontent = "";
90 }
91
92 # Clean old output dir
93 print "Removing old $themename...\n";
94 system("rm -rf $themename");
95
96 # Now copy the icons
97 my %scalables;
98
99 print "Copying icons from $themefolder...\n";
100 opendir (BASEDIR, "$themefolder") or die "Could not open theme basedir\n";
101 my $scalableFound = 0;
102 foreach my $parent (readdir BASEDIR) {
103   next unless (-d "$themefolder/$parent");
104   $scalableFound = $scalableFound ? 1 : $parent eq 'scalable';
105   next if $parent eq '.' or $parent eq '..' or $parent eq 'scalable' or $parent =~ /\..*/;
106   my $ischildcat = $parent =~ /\d+x\d+/ ? 1 : 0;
107   opendir (SIZEDIR, "$themefolder/$parent") or die "Could not open dir $parent\n";
108   foreach my $child (readdir SIZEDIR) {
109     next if $child eq '.' or $child eq '..';
110     my $cat = $ischildcat ? $child : $parent;
111     opendir (CATDIR, "$themefolder/$parent/$child") or die "Could not open category dir\n";
112     foreach my $icon (readdir CATDIR) {
113       my $iconname = $icon;
114       $iconname =~ s/\.png$//;
115       $iconname =~ s/\.svg$//;
116       next unless exists $req_icons{$iconname};
117       $scalables{$cat}{$iconname} = 1;
118       system "mkdir -p $themename/$parent/$child" and die "Could not create category dir\n";
119       system "cp -aL $themefolder/$parent/$child/$icon $themename/$parent/$child"
120         and die "Error while copying file $parent/$child/$icon\n";
121       #print "Copy: $themefolder/$parent/$child/$icon\n";
122       $found_icons{$iconname} = 1;
123     }
124     closedir CATDIR;
125   }
126   closedir SIZEDIR;
127 }
128 closedir BASEDIR;
129
130 # Copy scalables
131 if ($scalableFound) {
132   foreach my $cat (keys %scalables) {
133     system "mkdir -p $themename/scalable/$cat" and die "Could not create category dir\n";
134     foreach my $scalable (keys $scalables{$cat}) {
135       system "cp -aL $themefolder/scalable/$cat/$scalable.svgz $themename/scalable/$cat/$scalable.svgz";
136     }
137   }
138 }
139
140 # Warn if we have still icons left
141 foreach my $icon (keys %req_icons) {
142   next if defined $found_icons{$icon};
143   print "Warning: Missing icon $icon\n";
144 }
145
146 # Copy license etc.
147 system "cp $themefolder/AUTHORS $themefolder/CONTRIBUTING $themefolder/COPYING $themefolder/index.theme $themename/";
148
149 # Generate .qrc
150 my @file_list;
151 generate_qrc($themename, $qrcfile_kde, $extrafilecontent);
152
153 print "Done.\n";
154
155 ########################################################################################
156 sub generate_qrc {
157   my $dir = shift;
158   my $qrcfile = shift;
159
160   @file_list = ();
161   find(\&push_icon_path, $dir);
162   @file_list = sort(@file_list );
163   my $files = join "\n", @file_list;
164
165   my $qrc = "<RCC>\n"
166            ."  <qresource prefix=\"/icons\">\n"
167            ."$files\n"
168            ."$extrafilecontent\n"
169            ."  </qresource>\n"
170            ."</RCC>\n";
171
172   open QRC, ">$qrcfile" or die "Could not open $qrcfile for writing!\n";
173   print QRC $qrc;
174   close QRC;
175 }
176
177 sub push_icon_path {
178   return unless /\.png$/ or /\.svg$/ or /^index.theme$/;
179
180   push @file_list, "    <file>$File::Find::name</file>";
181 }