nomnom_de.ts: Add missing translations
[nomnom.git] / src / util.cpp
blob89fecb157755aacae278f9e5ee9aa639bfd41acf
1 /*
2 * Copyright (C) 2010 Toni Gundogdu.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "config.h"
20 #include <QApplication>
21 #include <QTranslator>
22 #include <QMessageBox>
23 #include <QProcess>
24 #include <QWidget>
25 #include <QString>
26 #include <QPoint>
27 #include <QDebug>
28 #include <QSize>
29 #include <QDir>
31 #include "Log.h"
32 #include "util.h"
34 // main.cpp
35 extern QMap<QString,QStringList> hosts;
36 extern QMap<QString,QString> qmFiles;
37 extern QStringList qmLangNames;
38 extern NomNom::Feed feed;
39 extern Log log;
41 namespace NomNom
44 void
45 restore_size (
46 QSettings& s,
47 QWidget *w,
48 const QString& g,
49 const QSize& defaultSize/*=(400,350)*/)
51 w->resize (s.value (QString ("%1/size").arg (g), defaultSize).toSize ());
54 void
55 restore_pos (
56 QSettings& s,
57 QWidget *w,
58 const QString& g,
59 const QPoint& defaultPos/*=(200,200)*/)
61 w->move (s.value (QString ("%1/pos").arg (g), defaultPos).toPoint ());
64 void
65 save_size (QSettings& s, QWidget *w, const QString& g)
67 s.setValue (QString ("%1/size").arg (g), w->size ());
70 void
71 save_pos (QSettings& s, QWidget *w, const QString& g)
73 s.setValue (QString ("%1/pos").arg (g), w->pos ());
76 void
77 info (QWidget *p, const QString& m)
79 p->show (); // Make sure window is not hidden (e.g. minimized to tray).
80 p->showNormal ();
81 QMessageBox::information (p, QCoreApplication::applicationName(), m);
84 void
85 crit (QWidget *p, const QString& m)
87 p->show (); // See `info' function above.
88 p->showNormal ();
89 QMessageBox::critical (p, QCoreApplication::applicationName (), m);
92 QMessageBox::StandardButton
93 ask (QWidget *p, const QString& m, QMessageBox::StandardButtons b/*=Yes|No*/)
95 p->show (); // See `info' function above.
96 p->showNormal ();
97 return QMessageBox::question(p, QCoreApplication::applicationName(), m, b);
100 static QFileInfoList
101 scan_dir (const QString path, const bool show_paths)
103 const QDir dir (QDir::toNativeSeparators (path));
105 if (show_paths)
106 qDebug () << dir.absolutePath ();
108 return dir.entryInfoList (QStringList( "*.qm"), QDir::Files);
111 QMap<QString,QString>
112 find_qm (QStringList& langNames)
114 QSettings s;
116 bool show_paths = false;
118 const QString qmShowPaths = "qmShowPaths";
119 if (s.contains (qmShowPaths))
120 show_paths = s.value (qmShowPaths).toBool ();
122 if (show_paths)
123 qDebug () << "qm search paths:";
125 QStringList paths;
127 const QString qmPath = "qmPath";
128 if (s.contains (qmPath))
129 paths << s.value (qmPath).toString ();
131 paths
132 << QDir::currentPath () + "/tr"
133 << QDir::homePath () + "/.config/nomnom/tr"
134 << QDir::homePath () + "/.local/share/nomnom/tr"
135 #ifdef INSTALL_PREFIX
136 << QString (INSTALL_PREFIX) + "/share/nomnom/tr"
137 #endif
140 QFileInfoList lst;
142 foreach (QString p, paths)
143 lst << scan_dir (p, show_paths);
145 QMap<QString,QString> map;
146 QTranslator t;
148 foreach (QFileInfo fi, lst)
151 t.load (fi.filePath ());
153 const QString langName = t.translate ("MainWindow", "English");
155 if (map.contains (langName)) // Skip duplicates.
157 if (map[langName] == fi.filePath ())
158 continue;
161 map[langName] = fi.filePath ();
163 langNames << langName;
166 return map;
169 bool
170 choose_lang (QWidget *p, QString& langName)
172 bool showPaths = false;
173 QStringList langNamesWithPaths;
175 const QString key = "qmShowPaths";
176 QSettings s;
178 if (s.contains (key))
181 showPaths = s.value (key).toBool ();
183 if (showPaths)
186 langNamesWithPaths << "English [default, built-in]";
188 QMapIterator<QString,QString> iter (qmFiles);
190 while (iter.hasNext ())
193 iter.next ();
195 langNamesWithPaths << QString ("%1 [%2]")
196 .arg (iter.key ())
197 .arg (iter.value ());
203 bool ok = false;
205 langName = QInputDialog::getItem (
207 QObject::tr ("Select language"),
208 QObject::tr ("Language:"),
209 showPaths ? langNamesWithPaths : qmLangNames,
211 false,
215 langName = langName.split ("[")[0].simplified ();
217 return ok;
220 QTranslator*
221 load_qm ()
223 QString langName;
225 QSettings s;
226 if (s.contains("language"))
228 const QString v = s.value("language").toString();
230 if (v == "English")
231 return NULL;
233 if (qmFiles.contains(v))
234 langName = v;
237 if (langName.isEmpty())
239 if (!choose_lang(NULL, langName))
240 return NULL;
243 s.setValue("language", langName);
245 QTranslator *t = new QTranslator;
246 t->load(qmFiles[langName]);
248 return t;
251 bool
252 parse_quvi_version (const QString& path, QString& output)
254 output.clear ();
256 // Use command path (arg0) and "--version" only.
258 QStringList args =
259 QStringList () << path.split (" ").takeFirst () << "--version";
261 log << args.join (" ");
263 const QString cmdPath = args.takeFirst ();
265 QProcess proc;
266 proc.setProcessChannelMode (QProcess::MergedChannels);
267 proc.start (cmdPath, args);
269 if (!proc.waitForFinished ())
272 output =
273 QObject::tr ("error: %1: %2")
274 .arg (cmdPath)
275 .arg (proc.errorString ());
277 return false;
280 output = QString::fromLocal8Bit (proc.readAll ()).simplified ();
282 return true;
285 bool
286 parse_quvi_support (const QString& path, QString& errmsg)
288 errmsg.clear ();
290 // Use command path (arg0) and "--support" only.
292 QStringList args =
293 QStringList () << path.split (" ").takeFirst () << "--support";
295 log << args.join (" ");
297 const QString cmdPath = args.takeFirst ();
299 QProcess proc;
300 proc.setProcessChannelMode(QProcess::MergedChannels);
301 proc.start(cmdPath, args);
303 if (!proc.waitForFinished())
306 errmsg =
307 QObject::tr("error: %1: %2")
308 .arg(cmdPath)
309 .arg(proc.errorString ());
311 return false;
314 const QRegExp re("(.*)\\s+(.*)$");
316 const QString output =
317 QString::fromLocal8Bit(proc.readAll());
319 foreach (QString ln, output.split("\n"))
322 if (ln.isEmpty())
323 continue;
325 log << ln;
327 if (re.indexIn(ln) != -1)
330 const QString host = re.cap (1).simplified ();
331 QStringList formats = re.cap (2).simplified ().split ("|");
333 // Keep "default" at the beginning of the list.
335 const QString top = formats.takeFirst ();
336 formats.sort ();
337 formats.prepend (top);
339 hosts[host] = formats;
343 return true;
346 static bool
347 filter_title (
348 QWidget *p,
349 const QString& user_regexp,
350 const QString& title,
351 QString& dst)
353 QString pattern;
355 bool g = false;
356 bool i = false;
358 QRegExp rx("^\\/(.*)\\/(.*)$");
360 if (rx.indexIn (user_regexp) != -1)
362 pattern = rx.cap (1);
363 g = rx.cap (2).contains ("g");
364 i = rx.cap (2).contains ("i");
366 else
368 NomNom::crit (p,
369 QObject::tr ("Expected Perl-style regular expression, e.g. /pattern/flags"));
370 return false;
373 rx.setPattern (pattern);
375 rx.setCaseSensitivity (
377 ? Qt::CaseInsensitive
378 : Qt::CaseSensitive
381 int pos = 0;
383 while ( (pos = rx.indexIn (title, pos)) != -1)
385 dst += rx.cap (1);
386 pos += rx.matchedLength ();
387 if (!g) break;
390 dst = dst.simplified ();
392 return true;
395 bool
396 format_filename (
397 QWidget *p,
398 const QString& user_regexp,
399 const QString& title,
400 const QString& suffix,
401 const QString& host,
402 const QString& id,
403 QString& dst)
405 // Assumes dst to contain the "filename format".
407 QString filtered_title;
409 const bool ok = filter_title (
411 user_regexp,
412 title,
413 filtered_title
416 if (!ok)
417 return ok;
419 dst.replace ("%t", filtered_title);
420 dst.replace ("%s", suffix);
421 dst.replace ("%h", host);
422 dst.replace ("%i", id);
424 dst = dst.simplified ();
426 return true;
429 QString
430 to_process_errmsg (QProcess::ProcessError n)
432 QString e;
434 switch (n)
437 case QProcess::FailedToStart:
438 e = QObject::tr (
439 "The process failed to start. "
440 "Either the invoked program is missing, or you may have "
441 "insufficient permissions to invoke the program."
443 break;
445 case QProcess::Crashed:
446 e = QObject::tr (
447 "The process crashed some time after starting successfully."
449 break;
451 case QProcess::Timedout:
452 e = QObject::tr (
453 "The last waitFor...() function timed out. "
454 "The state of QProcess is unchanged, and you can try calling "
455 "waitFor...() again."
457 break;
459 case QProcess::WriteError:
460 e = QObject::tr (
461 "An error occurred when attempting to write to the process. "
462 "For example, the process may not be running, or it may have closed "
463 "its input channel."
465 break;
467 case QProcess::ReadError:
468 e = QObject::tr (
469 "An error occurred when attempting to read from the process. "
470 "For example, the process may not be running."
472 break;
474 case QProcess::UnknownError:
475 default:
476 e = QObject::tr (
477 "An unknown error occurred. This is the default return value "
478 "of error()."
480 break;
484 return e;
487 bool
488 choose_from_feed (QWidget *parent, QString& dst)
490 if (feed.isEmpty())
491 return false;
493 FeedIterator i(feed);
494 QStringList items;
496 while (i.hasNext())
497 items << i.next().first;
499 bool ok = false;
501 QString title = QInputDialog::getItem (
502 parent,
503 QObject::tr ("Choose video"),
504 QObject::tr ("Video"),
505 items,
507 false,
511 if (ok)
513 i = FeedIterator(feed);
514 while (i.hasNext())
516 QPair<QString,QString> p = i.next();
517 if (p.first == title)
519 dst = p.second;
520 break;
525 return ok;
528 QString
529 reverse_line_order(const QString& s, const QString& sep/*="\n"*/)
531 QStringListIterator
532 i(s.split(sep, QString::SkipEmptyParts));
534 i.toBack();
536 QString r;
537 while(i.hasPrevious())
538 r += i.previous() + "\n";
540 return r;
543 } // End of namespace.
545 // vim: set ts=2 sw=2 tw=72 expandtab: