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/>.
20 #include <QApplication>
21 #include <QTranslator>
22 #include <QMessageBox>
35 extern QMap
<QString
,QStringList
> hosts
;
36 extern QMap
<QString
,QString
> qmFiles
;
37 extern QStringList qmLangNames
;
38 extern NomNom::FeedHash feed
;
48 const QSize
& defaultSize
/*=(400,350)*/)
50 w
->resize (s
.value (QString ("%1/size").arg (g
), defaultSize
).toSize ());
58 const QPoint
& defaultPos
/*=(200,200)*/)
60 w
->move (s
.value (QString ("%1/pos").arg (g
), defaultPos
).toPoint ());
64 save_size (QSettings
& s
, QWidget
*w
, const QString
& g
)
65 { s
.setValue (QString ("%1/size").arg (g
), w
->size ()); }
68 save_pos (QSettings
& s
, QWidget
*w
, const QString
& g
)
69 { s
.setValue (QString ("%1/pos").arg (g
), w
->pos ()); }
72 info (QWidget
*p
, const QString
& m
) {
73 p
->show (); // Make sure window is not hidden (e.g. minimized to tray).
75 QMessageBox::information (p
, QCoreApplication::applicationName(), m
);
79 crit (QWidget
*p
, const QString
& m
) {
80 p
->show (); // See `info' function above.
82 QMessageBox::critical (p
, QCoreApplication::applicationName (), m
);
85 QMessageBox::StandardButton
86 ask (QWidget
*p
, const QString
& m
, QMessageBox::StandardButtons b
/*=Yes|No*/) {
87 p
->show (); // See `info' function above.
89 return QMessageBox::question(p
, QCoreApplication::applicationName(), m
, b
);
93 scan_dir (const QString path
, const bool show_paths
) {
95 const QDir
dir (QDir::toNativeSeparators (path
));
98 qDebug () << dir
.absolutePath ();
100 return dir
.entryInfoList (QStringList( "*.qm"), QDir::Files
);
103 QMap
<QString
,QString
>
104 find_qm (QStringList
& langNames
) {
108 bool show_paths
= false;
110 const QString qmShowPaths
= "qmShowPaths";
111 if (s
.contains (qmShowPaths
))
112 show_paths
= s
.value (qmShowPaths
).toBool ();
115 qDebug () << "qm search paths:";
119 const QString qmPath
= "qmPath";
120 if (s
.contains (qmPath
))
121 paths
<< s
.value (qmPath
).toString ();
124 << QDir::currentPath () + "/tr"
125 << QDir::homePath () + "/.config/nomnom/tr"
126 << QDir::homePath () + "/.local/share/nomnom/tr"
127 #ifdef INSTALL_PREFIX
128 << QString (INSTALL_PREFIX
) + "/share/nomnom/tr"
134 foreach (QString p
, paths
)
135 lst
<< scan_dir (p
, show_paths
);
137 QMap
<QString
,QString
> map
;
140 foreach (QFileInfo fi
, lst
) {
142 t
.load (fi
.filePath ());
144 const QString langName
= t
.translate ("MainWindow", "English");
146 if (map
.contains (langName
)) { // Skip duplicates.
147 if (map
[langName
] == fi
.filePath ())
151 map
[langName
] = fi
.filePath ();
153 langNames
<< langName
;
160 choose_lang (QWidget
*p
, QString
& langName
) {
162 bool showPaths
= false;
163 QStringList langNamesWithPaths
;
165 const QString key
= "qmShowPaths";
168 if (s
.contains (key
)) {
170 showPaths
= s
.value (key
).toBool ();
174 langNamesWithPaths
<< "English [default, built-in]";
176 QMapIterator
<QString
,QString
> iter (qmFiles
);
178 while (iter
.hasNext ()) {
182 langNamesWithPaths
<< QString ("%1 [%2]")
184 .arg (iter
.value ());
192 langName
= QInputDialog::getItem (
194 QObject::tr ("Select language"),
195 QObject::tr ("Language:"),
196 showPaths
? langNamesWithPaths
: qmLangNames
,
202 langName
= langName
.split ("[")[0].simplified ();
213 if (s
.contains("language")) {
214 const QString v
= s
.value("language").toString();
219 if (qmFiles
.contains(v
))
223 if (langName
.isEmpty()) {
224 if (!choose_lang(NULL
, langName
))
228 s
.setValue("language", langName
);
230 QTranslator
*t
= new QTranslator
;
231 t
->load(qmFiles
[langName
]);
237 parse_quvi_version (const QString
& path
, QString
& output
) {
241 // Use command path (arg0) and "--version" only.
244 QStringList () << path
.split (" ").takeFirst () << "--version";
246 log
<< args
.join (" ");
248 const QString cmdPath
= args
.takeFirst ();
251 proc
.setProcessChannelMode (QProcess::MergedChannels
);
252 proc
.start (cmdPath
, args
);
254 if (!proc
.waitForFinished ()) {
257 QObject::tr ("error: %1: %2")
259 .arg (proc
.errorString ());
264 output
= QString::fromLocal8Bit (proc
.readAll ()).simplified ();
270 parse_quvi_support (const QString
& path
, QString
& errmsg
) {
274 // Use command path (arg0) and "--support" only.
277 QStringList () << path
.split (" ").takeFirst () << "--support";
279 log
<< args
.join (" ");
281 const QString cmdPath
= args
.takeFirst ();
284 proc
.setProcessChannelMode(QProcess::MergedChannels
);
285 proc
.start(cmdPath
, args
);
287 if (!proc
.waitForFinished()) {
290 QObject::tr("error: %1: %2")
292 .arg(proc
.errorString ());
297 const QRegExp
re("(.*)\\s+(.*)$");
299 const QString output
=
300 QString::fromLocal8Bit(proc
.readAll());
302 foreach (QString ln
, output
.split("\n")) {
309 if (re
.indexIn(ln
) != -1) {
311 const QString host
= re
.cap (1).simplified ();
312 QStringList formats
= re
.cap (2).simplified ().split ("|");
314 // Keep "default" at the beginning of the list.
316 const QString top
= formats
.takeFirst ();
318 formats
.prepend (top
);
320 hosts
[host
] = formats
;
330 const QString
& user_regexp
,
331 const QString
& title
,
339 QRegExp
rx("^\\/(.*)\\/(.*)$");
341 if (rx
.indexIn (user_regexp
) != -1) {
342 pattern
= rx
.cap (1);
343 g
= rx
.cap (2).contains ("g");
344 i
= rx
.cap (2).contains ("i");
348 QObject::tr ("Expected Perl-style regular expression, e.g. /pattern/flags"));
352 rx
.setPattern (pattern
);
354 rx
.setCaseSensitivity (
356 ? Qt::CaseInsensitive
362 while ( (pos
= rx
.indexIn (title
, pos
)) != -1) {
364 pos
+= rx
.matchedLength ();
368 dst
= dst
.simplified ();
376 const QString
& user_regexp
,
377 const QString
& title
,
378 const QString
& suffix
,
383 // Assumes dst to contain the "filename format".
385 QString filtered_title
;
387 const bool ok
= filter_title (
397 dst
.replace ("%t", filtered_title
);
398 dst
.replace ("%s", suffix
);
399 dst
.replace ("%h", host
);
400 dst
.replace ("%i", id
);
402 dst
= dst
.simplified ();
408 to_process_errmsg (QProcess::ProcessError n
) {
414 case QProcess::FailedToStart
:
416 "The process failed to start. "
417 "Either the invoked program is missing, or you may have "
418 "insufficient permissions to invoke the program."
422 case QProcess::Crashed
:
424 "The process crashed some time after starting successfully."
428 case QProcess::Timedout
:
430 "The last waitFor...() function timed out. "
431 "The state of QProcess is unchanged, and you can try calling "
432 "waitFor...() again."
436 case QProcess::WriteError
:
438 "An error occurred when attempting to write to the process. "
439 "For example, the process may not be running, or it may have closed "
444 case QProcess::ReadError
:
446 "An error occurred when attempting to read from the process. "
447 "For example, the process may not be running."
451 case QProcess::UnknownError
:
454 "An unknown error occurred. This is the default return value "
465 choose_from_feed (QWidget
*parent
, QString
& dst
) {
470 QHashIterator
<QString
,QString
> i (feed
);
473 while (i
.hasNext ()) {
480 QString title
= QInputDialog::getItem (
482 QObject::tr ("Choose video"),
483 QObject::tr ("Video"),
496 } // End of namespace.