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