OSDN Git Service

Moved Natural String Sort functions into MUtils library + moved the "Prerequisites...
[lamexp/LameXP.git] / src / Global_Utils.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version, but always including the *additional*
9 // restrictions defined in the "License.txt" file.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
22
23 #include "Global.h"
24
25 //Qt includes
26 #include <QApplication>
27 #include <QDate>
28 #include <QDir>
29 #include <QFileInfo>
30 #include <QIcon>
31 #include <QMutex>
32 #include <QProcessEnvironment>
33 #include <QReadWriteLock>
34 #include <QTextCodec>
35 #include <QUuid>
36 #include <QWidget>
37
38 //MUtils
39 #include <MUtils/Global.h>
40
41 //CRT includes
42 #include <time.h>
43 #include <process.h>
44
45 ///////////////////////////////////////////////////////////////////////////////
46 // GLOBAL VARS
47 ///////////////////////////////////////////////////////////////////////////////
48
49 static struct
50 {
51         QIcon *appIcon;
52         QReadWriteLock lock;
53 }
54 g_lamexp_app_icon;
55
56 ///////////////////////////////////////////////////////////////////////////////
57 // GLOBAL FUNCTIONS
58 ///////////////////////////////////////////////////////////////////////////////
59
60 /*
61  * Remove forbidden characters from a filename
62  */
63 const QString lamexp_clean_filename(const QString &str)
64 {
65         QString newStr(str);
66         QRegExp rx("\"(.+)\"");
67         rx.setMinimal(true);
68
69         newStr.replace("\\", "-");
70         newStr.replace(" / ", ", ");
71         newStr.replace("/", ",");
72         newStr.replace(":", "-");
73         newStr.replace("*", "x");
74         newStr.replace("?", "");
75         newStr.replace("<", "[");
76         newStr.replace(">", "]");
77         newStr.replace("|", "!");
78         newStr.replace(rx, "`\\1ยด");
79         newStr.replace("\"", "'");
80         
81         return newStr.simplified();
82 }
83
84 /*
85  * Remove forbidden characters from a file path
86  */
87 const QString lamexp_clean_filepath(const QString &str)
88 {
89         QStringList parts = QString(str).replace("\\", "/").split("/");
90
91         for(int i = 0; i < parts.count(); i++)
92         {
93                 parts[i] = lamexp_clean_filename(parts[i]);
94         }
95
96         return parts.join("/");
97 }
98
99 /*
100  * Get a list of all available Qt Text Codecs
101  */
102 QStringList lamexp_available_codepages(bool noAliases)
103 {
104         QStringList codecList;
105         
106         QList<QByteArray> availableCodecs = QTextCodec::availableCodecs();
107         while(!availableCodecs.isEmpty())
108         {
109                 QByteArray current = availableCodecs.takeFirst();
110                 if(!(current.startsWith("system") || current.startsWith("System")))
111                 {
112                         codecList << QString::fromLatin1(current.constData(), current.size());
113                         if(noAliases)
114                         {
115                                 if(QTextCodec *currentCodec = QTextCodec::codecForName(current.constData()))
116                                 {
117                                         
118                                         QList<QByteArray> aliases = currentCodec->aliases();
119                                         while(!aliases.isEmpty()) availableCodecs.removeAll(aliases.takeFirst());
120                                 }
121                         }
122                 }
123         }
124
125         return codecList;
126 }
127
128 /*
129  * Make a window blink (to draw user's attention)
130  */
131 void lamexp_blink_window(QWidget *poWindow, unsigned int count, unsigned int delay)
132 {
133         static QMutex blinkMutex;
134
135         const double maxOpac = 1.0;
136         const double minOpac = 0.3;
137         const double delOpac = 0.1;
138
139         if(!blinkMutex.tryLock())
140         {
141                 qWarning("Blinking is already in progress, skipping!");
142                 return;
143         }
144         
145         try
146         {
147                 const int steps = static_cast<int>(ceil(maxOpac - minOpac) / delOpac);
148                 const int sleep = static_cast<int>(floor(static_cast<double>(delay) / static_cast<double>(steps)));
149                 const double opacity = poWindow->windowOpacity();
150         
151                 for(unsigned int i = 0; i < count; i++)
152                 {
153                         for(double x = maxOpac; x >= minOpac; x -= delOpac)
154                         {
155                                 poWindow->setWindowOpacity(x);
156                                 QApplication::processEvents();
157                                 lamexp_sleep(sleep);
158                         }
159
160                         for(double x = minOpac; x <= maxOpac; x += delOpac)
161                         {
162                                 poWindow->setWindowOpacity(x);
163                                 QApplication::processEvents();
164                                 lamexp_sleep(sleep);
165                         }
166                 }
167
168                 poWindow->setWindowOpacity(opacity);
169                 QApplication::processEvents();
170                 blinkMutex.unlock();
171         }
172         catch(...)
173         {
174                 blinkMutex.unlock();
175                 qWarning("Exception error while blinking!");
176         }
177 }
178
179 /*
180  * Computus according to H. Lichtenberg
181  */
182 static bool lamexp_computus(const QDate &date)
183 {
184         int X = date.year();
185         int A = X % 19;
186         int K = X / 100;
187         int M = 15 + (3*K + 3) / 4 - (8*K + 13) / 25;
188         int D = (19*A + M) % 30;
189         int S = 2 - (3*K + 3) / 4;
190         int R = D / 29 + (D / 28 - D / 29) * (A / 11);
191         int OG = 21 + D - R;
192         int SZ = 7 - (X + X / 4 + S) % 7;
193         int OE = 7 - (OG - SZ) % 7;
194         int OS = (OG + OE);
195
196         if(OS > 31)
197         {
198                 return (date.month() == 4) && (date.day() == (OS - 31));
199         }
200         else
201         {
202                 return (date.month() == 3) && (date.day() == OS);
203         }
204 }
205
206 /*
207  * Check for Thanksgiving
208  */
209 static bool lamexp_thanksgiving(const QDate &date)
210 {
211         int day = 0;
212
213         switch(QDate(date.year(), 11, 1).dayOfWeek())
214         {
215                 case 1: day = 25; break; 
216                 case 2: day = 24; break; 
217                 case 3: day = 23; break; 
218                 case 4: day = 22; break; 
219                 case 5: day = 28; break; 
220                 case 6: day = 27; break; 
221                 case 7: day = 26; break;
222         }
223
224         return (date.month() == 11) && (date.day() == day);
225 }
226
227 /*
228  * Initialize app icon
229  */
230 const QIcon &lamexp_app_icon(void)
231 {
232         QReadLocker readLock(&g_lamexp_app_icon.lock);
233
234         //Already initialized?
235         if(g_lamexp_app_icon.appIcon)
236         {
237                 return *g_lamexp_app_icon.appIcon;
238         }
239
240         readLock.unlock();
241         QWriteLocker writeLock(&g_lamexp_app_icon.lock);
242
243         while(!g_lamexp_app_icon.appIcon)
244         {
245                 QDate currentDate = QDate::currentDate();
246                 QTime currentTime = QTime::currentTime();
247         
248                 if(lamexp_thanksgiving(currentDate))
249                 {
250                         g_lamexp_app_icon.appIcon = new QIcon(":/MainIcon6.png");
251                 }
252                 else if(((currentDate.month() == 12) && (currentDate.day() == 31) && (currentTime.hour() >= 20)) || ((currentDate.month() == 1) && (currentDate.day() == 1)  && (currentTime.hour() <= 19)))
253                 {
254                         g_lamexp_app_icon.appIcon = new QIcon(":/MainIcon5.png");
255                 }
256                 else if(((currentDate.month() == 10) && (currentDate.day() == 31) && (currentTime.hour() >= 12)) || ((currentDate.month() == 11) && (currentDate.day() == 1)  && (currentTime.hour() <= 11)))
257                 {
258                         g_lamexp_app_icon.appIcon = new QIcon(":/MainIcon4.png");
259                 }
260                 else if((currentDate.month() == 12) && (currentDate.day() >= 24) && (currentDate.day() <= 26))
261                 {
262                         g_lamexp_app_icon.appIcon = new QIcon(":/MainIcon3.png");
263                 }
264                 else if(lamexp_computus(currentDate))
265                 {
266                         g_lamexp_app_icon.appIcon = new QIcon(":/MainIcon2.png");
267                 }
268                 else
269                 {
270                         g_lamexp_app_icon.appIcon = new QIcon(":/MainIcon1.png");
271                 }
272         }
273
274         return *g_lamexp_app_icon.appIcon;
275 }
276
277 ///////////////////////////////////////////////////////////////////////////////
278 // INITIALIZATION
279 ///////////////////////////////////////////////////////////////////////////////
280
281 extern "C" void _lamexp_global_init_utils(void)
282 {
283         LAMEXP_ZERO_MEMORY(g_lamexp_app_icon);
284 }
285
286 ///////////////////////////////////////////////////////////////////////////////
287 // FINALIZATION
288 ///////////////////////////////////////////////////////////////////////////////
289
290 extern "C" void _lamexp_global_free_utils(void)
291 {
292         //Free memory
293         MUTILS_DELETE(g_lamexp_app_icon.appIcon);
294 }