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::Feed feed
;
49 const QSize
& defaultSize
/*=(400,350)*/)
51 w
->resize (s
.value (QString ("%1/size").arg (g
), defaultSize
).toSize ());
59 const QPoint
& defaultPos
/*=(200,200)*/)
61 w
->move (s
.value (QString ("%1/pos").arg (g
), defaultPos
).toPoint ());
65 save_size (QSettings
& s
, QWidget
*w
, const QString
& g
)
67 s
.setValue (QString ("%1/size").arg (g
), w
->size ());
71 save_pos (QSettings
& s
, QWidget
*w
, const QString
& g
)
73 s
.setValue (QString ("%1/pos").arg (g
), w
->pos ());
77 info (QWidget
*p
, const QString
& m
)
79 p
->show (); // Make sure window is not hidden (e.g. minimized to tray).
81 QMessageBox::information (p
, QCoreApplication::applicationName(), m
);
85 crit (QWidget
*p
, const QString
& m
)
87 p
->show (); // See `info' function above.
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.
97 return QMessageBox::question(p
, QCoreApplication::applicationName(), m
, b
);
101 scan_dir (const QString path
, const bool show_paths
)
103 const QDir
dir (QDir::toNativeSeparators (path
));
106 qDebug () << dir
.absolutePath ();
108 return dir
.entryInfoList (QStringList( "*.qm"), QDir::Files
);
111 QMap
<QString
,QString
>
112 find_qm (QStringList
& langNames
)
116 bool show_paths
= false;
118 const QString qmShowPaths
= "qmShowPaths";
119 if (s
.contains (qmShowPaths
))
120 show_paths
= s
.value (qmShowPaths
).toBool ();
123 qDebug () << "qm search paths:";
127 const QString qmPath
= "qmPath";
128 if (s
.contains (qmPath
))
129 paths
<< s
.value (qmPath
).toString ();
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"
142 foreach (QString p
, paths
)
143 lst
<< scan_dir (p
, show_paths
);
145 QMap
<QString
,QString
> map
;
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 ())
161 map
[langName
] = fi
.filePath ();
163 langNames
<< langName
;
170 choose_lang (QWidget
*p
, QString
& langName
)
172 bool showPaths
= false;
173 QStringList langNamesWithPaths
;
175 const QString key
= "qmShowPaths";
178 if (s
.contains (key
))
181 showPaths
= s
.value (key
).toBool ();
186 langNamesWithPaths
<< "English [default, built-in]";
188 QMapIterator
<QString
,QString
> iter (qmFiles
);
190 while (iter
.hasNext ())
195 langNamesWithPaths
<< QString ("%1 [%2]")
197 .arg (iter
.value ());
205 langName
= QInputDialog::getItem (
207 QObject::tr ("Select language"),
208 QObject::tr ("Language:"),
209 showPaths
? langNamesWithPaths
: qmLangNames
,
215 langName
= langName
.split ("[")[0].simplified ();
226 if (s
.contains("language"))
228 const QString v
= s
.value("language").toString();
233 if (qmFiles
.contains(v
))
237 if (langName
.isEmpty())
239 if (!choose_lang(NULL
, langName
))
243 s
.setValue("language", langName
);
245 QTranslator
*t
= new QTranslator
;
246 t
->load(qmFiles
[langName
]);
252 parse_quvi_version (const QString
& path
, QString
& output
)
256 // Use command path (arg0) and "--version" only.
259 QStringList () << path
.split (" ").takeFirst () << "--version";
261 log
<< args
.join (" ");
263 const QString cmdPath
= args
.takeFirst ();
266 proc
.setProcessChannelMode (QProcess::MergedChannels
);
267 proc
.start (cmdPath
, args
);
269 if (!proc
.waitForFinished ())
273 QObject::tr ("error: %1: %2")
275 .arg (proc
.errorString ());
280 output
= QString::fromLocal8Bit (proc
.readAll ()).simplified ();
286 parse_quvi_support (const QString
& path
, QString
& errmsg
)
290 // Use command path (arg0) and "--support" only.
293 QStringList () << path
.split (" ").takeFirst () << "--support";
295 log
<< args
.join (" ");
297 const QString cmdPath
= args
.takeFirst ();
300 proc
.setProcessChannelMode(QProcess::MergedChannels
);
301 proc
.start(cmdPath
, args
);
303 if (!proc
.waitForFinished())
307 QObject::tr("error: %1: %2")
309 .arg(proc
.errorString ());
314 const QRegExp
re("(.*)\\s+(.*)$");
316 const QString output
=
317 QString::fromLocal8Bit(proc
.readAll());
319 foreach (QString ln
, output
.split("\n"))
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 ();
337 formats
.prepend (top
);
339 hosts
[host
] = formats
;
349 const QString
& user_regexp
,
350 const QString
& title
,
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");
369 QObject::tr ("Expected Perl-style regular expression, e.g. /pattern/flags"));
373 rx
.setPattern (pattern
);
375 rx
.setCaseSensitivity (
377 ? Qt::CaseInsensitive
383 while ( (pos
= rx
.indexIn (title
, pos
)) != -1)
386 pos
+= rx
.matchedLength ();
390 dst
= dst
.simplified ();
398 const QString
& user_regexp
,
399 const QString
& title
,
400 const QString
& suffix
,
405 // Assumes dst to contain the "filename format".
407 QString filtered_title
;
409 const bool ok
= filter_title (
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 ();
430 to_process_errmsg (QProcess::ProcessError n
)
437 case QProcess::FailedToStart
:
439 "The process failed to start. "
440 "Either the invoked program is missing, or you may have "
441 "insufficient permissions to invoke the program."
445 case QProcess::Crashed
:
447 "The process crashed some time after starting successfully."
451 case QProcess::Timedout
:
453 "The last waitFor...() function timed out. "
454 "The state of QProcess is unchanged, and you can try calling "
455 "waitFor...() again."
459 case QProcess::WriteError
:
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 "
467 case QProcess::ReadError
:
469 "An error occurred when attempting to read from the process. "
470 "For example, the process may not be running."
474 case QProcess::UnknownError
:
477 "An unknown error occurred. This is the default return value "
488 choose_from_feed (QWidget
*parent
, QString
& dst
)
493 FeedIterator
i(feed
);
497 items
<< i
.next().first
;
501 QString title
= QInputDialog::getItem (
503 QObject::tr ("Choose video"),
504 QObject::tr ("Video"),
513 i
= FeedIterator(feed
);
516 QPair
<QString
,QString
> p
= i
.next();
517 if (p
.first
== title
)
529 reverse_line_order(const QString
& s
, const QString
& sep
/*="\n"*/)
532 i(s
.split(sep
, QString::SkipEmptyParts
));
537 while(i
.hasPrevious())
538 r
+= i
.previous() + "\n";
543 } // End of namespace.
545 // vim: set ts=2 sw=2 tw=72 expandtab: