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