source: smplayer/trunk/src/findsubtitles/findsubtitleswindow.cpp@ 178

Last change on this file since 178 was 176, checked in by Silvan Scherrer, 9 years ago

smplayer: update trunk to version 16.4

  • Property svn:eol-style set to LF
File size: 26.8 KB
Line 
1/* smplayer, GUI front-end for mplayer.
2 Copyright (C) 2006-2016 Ricardo Villalba <rvm@users.sourceforge.net>
3
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 2 of the License, or
7 (at your option) any later version.
8
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.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/
18
19#include "findsubtitleswindow.h"
20#include "findsubtitlesconfigdialog.h"
21
22#include "osclient.h"
23#include "filehash.h"
24#include "languages.h"
25#include <QStandardItemModel>
26#include <QSortFilterProxyModel>
27#include <QHeaderView>
28#include <QMessageBox>
29#include <QDesktopServices>
30#include <QUrl>
31#include <QMap>
32#include <QMenu>
33#include <QAction>
34#include <QClipboard>
35#include <QSettings>
36
37#ifdef DOWNLOAD_SUBS
38#include <QBuffer>
39#include "filedownloader.h"
40#include "subchooserdialog.h"
41#include "fixsubs.h"
42
43#ifdef USE_QUAZIP
44#include "quazip.h"
45#include "quazipfile.h"
46#include <QTemporaryFile>
47#else
48#include <zlib.h>
49#endif
50
51#endif
52
53//#define NO_SMPLAYER_SUPPORT
54
55#ifndef NO_SMPLAYER_SUPPORT
56#include "images.h"
57#endif
58
59#define COL_LANG 0
60#define COL_NAME 1
61#define COL_FORMAT 2
62#define COL_FILES 3
63#define COL_DATE 4
64#define COL_USER 5
65
66FindSubtitlesWindow::FindSubtitlesWindow( QWidget * parent, Qt::WindowFlags f )
67 : QDialog(parent,f)
68{
69 setupUi(this);
70
71 set = 0; // settings
72
73 subtitles_for_label->setBuddy(file_chooser);
74
75 progress->hide();
76
77 connect( file_chooser, SIGNAL(fileChanged(QString)),
78 this, SLOT(setMovie(QString)) );
79 connect( file_chooser, SIGNAL(textChanged(const QString &)),
80 this, SLOT(updateRefreshButton()) );
81
82 connect( refresh_button, SIGNAL(clicked()),
83 this, SLOT(refresh()) );
84
85 connect( download_button, SIGNAL(clicked()),
86 this, SLOT(download()) );
87
88 /*
89 connect( language_filter, SIGNAL(editTextChanged(const QString &)),
90 this, SLOT(applyFilter(const QString &)) );
91 */
92 connect( language_filter, SIGNAL(activated(int)),
93 this, SLOT(applyCurrentFilter()) );
94
95 table = new QStandardItemModel(this);
96 table->setColumnCount(COL_USER + 1);
97
98 proxy_model = new QSortFilterProxyModel(this);
99 proxy_model->setSourceModel(table);
100 proxy_model->setFilterKeyColumn(COL_LANG);
101 proxy_model->setFilterRole(Qt::UserRole);
102
103 view->setModel(proxy_model);
104 view->setRootIsDecorated(false);
105 view->setSortingEnabled(true);
106 view->setAlternatingRowColors(true);
107 view->header()->setSortIndicator(COL_LANG, Qt::AscendingOrder);
108 view->setEditTriggers(QAbstractItemView::NoEditTriggers);
109 view->setContextMenuPolicy( Qt::CustomContextMenu );
110
111 connect(view, SIGNAL(activated(const QModelIndex &)),
112 this, SLOT(itemActivated(const QModelIndex &)) );
113 connect(view->selectionModel(), SIGNAL(currentChanged(const QModelIndex &,const QModelIndex &)),
114 this, SLOT(currentItemChanged(const QModelIndex &,const QModelIndex &)) );
115
116 connect(view, SIGNAL(customContextMenuRequested(const QPoint &)),
117 this, SLOT(showContextMenu(const QPoint &)) );
118
119 /*
120 downloader = new SimpleHttp(this);
121
122 connect( downloader, SIGNAL(downloadFailed(QString)),
123 this, SLOT(showError(QString)) );
124 connect( downloader, SIGNAL(downloadFinished(QByteArray)),
125 this, SLOT(downloadFinished()) );
126 connect( downloader, SIGNAL(downloadFinished(QByteArray)),
127 this, SLOT(parseInfo(QByteArray)) );
128 connect( downloader, SIGNAL(stateChanged(int)),
129 this, SLOT(updateRefreshButton()) );
130
131 connect( downloader, SIGNAL(connecting(QString)),
132 this, SLOT(connecting(QString)) );
133 connect( downloader, SIGNAL(dataReadProgress(int, int)),
134 this, SLOT(updateDataReadProgress(int, int)) );
135 */
136
137 osclient = new OSClient();
138 connect( osclient, SIGNAL(searchFinished()), this, SLOT(downloadFinished()) );
139 connect( osclient, SIGNAL(searchFinished()), this, SLOT(parseInfo()) );
140 connect( osclient, SIGNAL(loginFailed()), this, SLOT(showLoginFailed()) );
141 connect( osclient, SIGNAL(searchFailed()), this, SLOT(showSearchFailed()) );
142 connect( osclient, SIGNAL(errorFound(int, const QString &)), this, SLOT(showErrorOS(int, const QString &)) );
143
144#ifdef DOWNLOAD_SUBS
145 include_lang_on_filename = true;
146
147 file_downloader = new FileDownloader(this);
148 file_downloader->setModal(false);
149 file_downloader->hide();
150
151 connect( file_downloader, SIGNAL(downloadFailed(QString)),
152 this, SLOT(showError(QString)), Qt::QueuedConnection );
153 connect( file_downloader, SIGNAL(downloadFinished(const QByteArray &)),
154 this, SLOT(archiveDownloaded(const QByteArray &)), Qt::QueuedConnection );
155 connect( this, SIGNAL(subtitleDownloaded(const QString &)),
156 this, SLOT(fixSubtitles(const QString &)) );
157#endif
158
159 // Actions
160 downloadAct = new QAction(this);
161 downloadAct->setEnabled(false);
162 connect( downloadAct, SIGNAL(triggered()), this, SLOT(download()) );
163
164 copyLinkAct = new QAction(this);
165 copyLinkAct->setEnabled(false);
166 connect( copyLinkAct, SIGNAL(triggered()), this, SLOT(copyLink()) );
167
168 context_menu = new QMenu(this);
169 context_menu->addAction(downloadAct);
170 context_menu->addAction(copyLinkAct);
171
172 retranslateStrings();
173
174 language_filter->setCurrentIndex(0);
175
176 // Opensubtitles server
177 /* os_server = "http://www.opensubtitles.org"; */
178 os_server = "http://api.opensubtitles.org/xml-rpc";
179 osclient->setServer(os_server);
180
181#ifdef FS_USE_PROXY
182 // Proxy
183 use_proxy = false;
184 proxy_type = QNetworkProxy::HttpProxy;
185 proxy_host = "";
186 proxy_port = 0;
187 proxy_username = "";
188 proxy_password = "";
189
190 setupProxy();
191#endif
192}
193
194FindSubtitlesWindow::~FindSubtitlesWindow() {
195 if (set) saveSettings();
196}
197
198void FindSubtitlesWindow::setSettings(QSettings * settings) {
199 set = settings;
200 loadSettings();
201#ifdef FS_USE_PROXY
202 setupProxy();
203#endif
204}
205
206#ifdef FS_USE_PROXY
207void FindSubtitlesWindow::setProxy(QNetworkProxy proxy) {
208 /*
209 downloader->abort();
210 downloader->setProxy(proxy);
211 */
212 osclient->setProxy(proxy);
213
214#ifdef DOWNLOAD_SUBS
215 file_downloader->setProxy(proxy);
216#endif
217
218 qDebug("FindSubtitlesWindow::setProxy: host: '%s' port: %d type: %d",
219 proxy.hostName().toUtf8().constData(), proxy.port(), proxy.type());
220}
221#endif
222
223void FindSubtitlesWindow::retranslateStrings() {
224 retranslateUi(this);
225
226 QStringList labels;
227 labels << tr("Language") << tr("Name") << tr("Format")
228 << tr("Files") << tr("Date") << tr("Uploaded by");
229
230 table->setHorizontalHeaderLabels( labels );
231
232 // Language combobox
233 //int language_index = language_filter->currentIndex();
234 QString current_language = language_filter->itemData(language_filter->currentIndex()).toString();
235 language_filter->clear();
236
237 QMap<QString,QString> l1 = Languages::most_used_list();
238 QMapIterator<QString, QString> i1(l1);
239 while (i1.hasNext()) {
240 i1.next();
241 language_filter->addItem( i1.value() + " (" + i1.key() + ")", i1.key() );
242 }
243 language_filter->addItem( tr("Portuguese - Brasil") + " (pb)", "pb");
244 language_filter->model()->sort(0);
245 #if QT_VERSION >= 0x040400
246 language_filter->insertSeparator(language_filter->count());
247 #endif
248
249 QMap<QString,QString> l2 = Languages::list();
250 QMapIterator<QString, QString> i2(l2);
251 while (i2.hasNext()) {
252 i2.next();
253 if (language_filter->findData(i2.key()) == -1) {
254 language_filter->addItem( i2.value() + " (" + i2.key() + ")", i2.key() );
255 }
256 }
257 //language_filter->model()->sort(0);
258 language_filter->insertItem( 0, tr("All"), "*" );
259 #if QT_VERSION >= 0x040400
260 language_filter->insertSeparator(1);
261 #endif
262 //language_filter->setCurrentIndex(language_index);
263 language_filter->setCurrentIndex(language_filter->findData(current_language));
264
265#if QT_VERSION < 0x040300
266 QPushButton * close_button = buttonBox->button(QDialogButtonBox::Close);
267 close_button->setText( tr("Close") );
268#endif
269
270 // Actions
271 downloadAct->setText( tr("&Download") );
272 copyLinkAct->setText( tr("&Copy link to clipboard") );
273
274 // Icons
275#ifndef NO_SMPLAYER_SUPPORT
276 download_button->setIcon( Images::icon("download") );
277 configure_button->setIcon( Images::icon("prefs") );
278 refresh_button->setIcon( Images::icon("refresh") );
279
280 downloadAct->setIcon( Images::icon("download") );
281 copyLinkAct->setIcon( Images::icon("copy") );
282#endif
283}
284
285void FindSubtitlesWindow::setMovie(QString filename) {
286 qDebug("FindSubtitlesWindow::setMovie: '%s'", filename.toLatin1().constData());
287
288 if (filename == last_file) {
289 return;
290 }
291
292 file_chooser->setText(filename);
293 table->setRowCount(0);
294
295 QString hash = FileHash::calculateHash(filename);
296 if (hash.isEmpty()) {
297 qWarning("FindSubtitlesWindow::setMovie: hash invalid. Doing nothing.");
298 } else {
299 qint64 file_size = QFileInfo(filename).size();
300 osclient->search(hash, file_size);
301 last_file = filename;
302 }
303}
304
305void FindSubtitlesWindow::refresh() {
306 last_file = "";
307 setMovie(file_chooser->text());
308}
309
310void FindSubtitlesWindow::updateRefreshButton() {
311 qDebug("FindSubtitlesWindow::updateRefreshButton:");
312 refresh_button->setEnabled(true);
313}
314
315void FindSubtitlesWindow::currentItemChanged(const QModelIndex & current, const QModelIndex & /*previous*/) {
316 qDebug("FindSubtitlesWindow::currentItemChanged: row: %d, col: %d", current.row(), current.column());
317 download_button->setEnabled(current.isValid());
318 downloadAct->setEnabled(current.isValid());
319 copyLinkAct->setEnabled(current.isValid());
320}
321
322void FindSubtitlesWindow::applyFilter(const QString & filter) {
323 proxy_model->setFilterWildcard(filter);
324}
325
326void FindSubtitlesWindow::applyCurrentFilter() {
327 //proxy_model->setFilterWildcard(language_filter->currentText());
328 QString filter = language_filter->itemData( language_filter->currentIndex() ).toString();
329 applyFilter(filter);
330}
331
332void FindSubtitlesWindow::setLanguage(const QString & lang) {
333 int idx = language_filter->findData(lang);
334 if (idx < 0) idx = 0;
335 language_filter->setCurrentIndex(idx);
336}
337
338QString FindSubtitlesWindow::language() {
339 int idx = language_filter->currentIndex();
340 return language_filter->itemData(idx).toString();
341}
342
343void FindSubtitlesWindow::showError(QString error) {
344 status->setText( tr("Download failed") );
345
346 QMessageBox::information(this, tr("Error"),
347 tr("Download failed: %1.")
348 .arg(error));
349}
350
351void FindSubtitlesWindow::connecting(QString host) {
352 status->setText( tr("Connecting to %1...").arg(host) );
353}
354
355void FindSubtitlesWindow::showLoginFailed() {
356 status->setText( tr("Login to opensubtitles.org has failed") );
357}
358
359void FindSubtitlesWindow::showSearchFailed() {
360 status->setText( tr("Search has failed") );
361}
362
363void FindSubtitlesWindow::showErrorOS(int, const QString & error) {
364 status->setText(error);
365}
366
367void FindSubtitlesWindow::updateDataReadProgress(int done, int total) {
368 qDebug("FindSubtitlesWindow::updateDataReadProgress: %d, %d", done, total);
369
370 status->setText( tr("Downloading...") );
371
372 if (!progress->isVisible()) progress->show();
373 progress->setMaximum(total);
374 progress->setValue(done);
375}
376
377void FindSubtitlesWindow::downloadFinished() {
378 status->setText( tr("Done.") );
379 progress->setMaximum(1);
380 progress->setValue(0);
381 progress->hide();
382}
383
384void FindSubtitlesWindow::parseInfo() {
385 bool ok = true;
386
387 table->setRowCount(0);
388
389 QMap <QString,QString> language_list = Languages::list();
390
391 if (ok) {
392 QList<OSSubtitle> l = osclient->subtitleList();
393 for (int n=0; n < l.count(); n++) {
394
395 QString title_name = l[n].movie;
396 if (!l[n].releasename.isEmpty()) {
397 title_name += " - " + l[n].releasename;
398 }
399
400 QStandardItem * i_name = new QStandardItem(title_name);
401 i_name->setData( l[n].link );
402 #if QT_VERSION < 0x040400
403 i_name->setToolTip( l[n].link );
404 #endif
405
406 QStandardItem * i_lang = new QStandardItem(l[n].language);
407 i_lang->setData(l[n].iso639, Qt::UserRole);
408 #if QT_VERSION < 0x040400
409 i_lang->setToolTip(l[n].iso639);
410 #endif
411 if (language_list.contains(l[n].iso639)) {
412 i_lang->setText( language_list[ l[n].iso639 ] );
413 }
414
415 table->setItem(n, COL_LANG, i_lang);
416 table->setItem(n, COL_NAME, i_name);
417 table->setItem(n, COL_FORMAT, new QStandardItem(l[n].format));
418 table->setItem(n, COL_FILES, new QStandardItem(l[n].files));
419 table->setItem(n, COL_DATE, new QStandardItem(l[n].date));
420 table->setItem(n, COL_USER, new QStandardItem(l[n].user));
421
422 }
423 status->setText( tr("%1 files available").arg(l.count()) );
424 applyCurrentFilter();
425
426 qDebug("FindSubtitlesWindow::parseInfo: sort column: %d", view->header()->sortIndicatorSection());
427 qDebug("FindSubtitlesWindow::parseInfo: sort indicator: %d", view->header()->sortIndicatorOrder());
428
429 table->sort( view->header()->sortIndicatorSection(),
430 view->header()->sortIndicatorOrder() );
431 } else {
432 status->setText( tr("Failed to parse the received data.") );
433 }
434
435 view->resizeColumnToContents(COL_NAME);
436}
437
438void FindSubtitlesWindow::itemActivated(const QModelIndex & index ) {
439 qDebug("FindSubtitlesWindow::itemActivated: row: %d, col %d", proxy_model->mapToSource(index).row(), proxy_model->mapToSource(index).column());
440
441 QString download_link = table->item(proxy_model->mapToSource(index).row(), COL_NAME)->data().toString();
442
443 qDebug("FindSubtitlesWindow::itemActivated: download link: '%s'", download_link.toLatin1().constData());
444
445#ifdef DOWNLOAD_SUBS
446 file_downloader->download( QUrl(download_link) );
447 file_downloader->show();
448#else
449 QDesktopServices::openUrl( QUrl(download_link) );
450#endif
451}
452
453void FindSubtitlesWindow::download() {
454 qDebug("FindSubtitlesWindow::download");
455 if (view->currentIndex().isValid()) {
456 itemActivated(view->currentIndex());
457 }
458}
459
460void FindSubtitlesWindow::copyLink() {
461 qDebug("FindSubtitlesWindow::copyLink");
462 if (view->currentIndex().isValid()) {
463 const QModelIndex & index = view->currentIndex();
464 QString download_link = table->item(proxy_model->mapToSource(index).row(), COL_NAME)->data().toString();
465 qDebug("FindSubtitlesWindow::copyLink: link: '%s'", download_link.toLatin1().constData());
466 qApp->clipboard()->setText(download_link);
467 }
468}
469
470void FindSubtitlesWindow::showContextMenu(const QPoint & pos) {
471 qDebug("FindSubtitlesWindow::showContextMenu");
472
473 context_menu->move( view->viewport()->mapToGlobal(pos) );
474 context_menu->show();
475}
476
477// Language change stuff
478void FindSubtitlesWindow::changeEvent(QEvent *e) {
479 if (e->type() == QEvent::LanguageChange) {
480 retranslateStrings();
481 } else {
482 QWidget::changeEvent(e);
483 }
484}
485
486#ifdef DOWNLOAD_SUBS
487
488#ifndef USE_QUAZIP
489void FindSubtitlesWindow::archiveDownloaded(const QByteArray & buffer) {
490 qDebug("FindSubtitlesWindow::archiveDownloaded");
491 QByteArray uncompress_data = gUncompress(buffer);
492 //qDebug("uncompress_data: %s", uncompress_data.constData());
493
494 if (uncompress_data.isEmpty()) {
495 status->setText(tr("Download failed"));
496 return;
497 }
498
499 QString lang = "unknown";
500 QString extension = "unknown";
501 if (view->currentIndex().isValid()) {
502 const QModelIndex & index = view->currentIndex();
503 lang = table->item(proxy_model->mapToSource(index).row(), COL_LANG)->data(Qt::UserRole).toString();
504 extension = table->item(proxy_model->mapToSource(index).row(), COL_FORMAT)->text();
505 }
506
507 QFileInfo fi(file_chooser->text());
508 QString output_name = fi.completeBaseName();
509 if (include_lang_on_filename) output_name += "_"+ lang;
510 output_name += "." + extension;
511
512 QString output_file = fi.absolutePath() + "/" + output_name;
513 qDebug("FindSubtitlesWindow::archiveDownloaded: save subtitle as '%s'", output_file.toUtf8().constData());
514
515 QFile file(output_file);
516 file.open(QIODevice::WriteOnly);
517 bool error = (file.write(uncompress_data) == -1);
518 file.close();
519
520 if (error) {
521 qWarning("FindSubtitlesWindow::archiveDownloaded: can't write subtitle file");
522 QMessageBox::warning(this, tr("Error saving file"),
523 tr("It wasn't possible to save the downloaded\n"
524 "file in folder %1\n"
525 "Please check the permissions of that folder.").arg(fi.absolutePath()));
526 } else {
527 status->setText(tr("Subtitle saved as %1").arg(output_file));
528 emit subtitleDownloaded( output_file );
529 }
530}
531
532QByteArray FindSubtitlesWindow::gUncompress(const QByteArray &data)
533{
534 if (data.size() <= 4) {
535 qWarning("gUncompress: Input data is truncated");
536 return QByteArray();
537 }
538
539 QByteArray result;
540
541 int ret;
542 z_stream strm;
543 static const int CHUNK_SIZE = 1024;
544 char out[CHUNK_SIZE];
545
546 /* allocate inflate state */
547 strm.zalloc = Z_NULL;
548 strm.zfree = Z_NULL;
549 strm.opaque = Z_NULL;
550 strm.avail_in = data.size();
551 strm.next_in = (Bytef*)(data.data());
552
553 ret = inflateInit2(&strm, 15 + 32); // gzip decoding
554 if (ret != Z_OK)
555 return QByteArray();
556
557 // run inflate()
558 do {
559 strm.avail_out = CHUNK_SIZE;
560 strm.next_out = (Bytef*)(out);
561
562 ret = inflate(&strm, Z_NO_FLUSH);
563 Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered
564
565 switch (ret) {
566 case Z_NEED_DICT:
567 ret = Z_DATA_ERROR; // and fall through
568 case Z_DATA_ERROR:
569 case Z_MEM_ERROR:
570 (void)inflateEnd(&strm);
571 return QByteArray();
572 }
573
574 result.append(out, CHUNK_SIZE - strm.avail_out);
575 } while (strm.avail_out == 0);
576
577 // clean up and return
578 inflateEnd(&strm);
579 return result;
580}
581
582#else
583
584void FindSubtitlesWindow::archiveDownloaded(const QByteArray & buffer) {
585 qDebug("FindSubtitlesWindow::archiveDownloaded");
586
587 QString temp_dir = QDir::tempPath();
588 if (!temp_dir.endsWith("/")) temp_dir += "/";
589
590 QTemporaryFile file(temp_dir + "archive_XXXXXX.zip");
591 file.setAutoRemove(false);
592
593 qDebug("FindSubtitlesWindow::archiveDownloaded: a temporary file will be saved in folder '%s'", temp_dir.toUtf8().constData());
594
595 if (file.open()) {
596 QString filename = file.fileName();
597 file.write( buffer );
598 file.close();
599
600 qDebug("FindSubtitlesWindow::archiveDownloaded: file saved as: %s", filename.toUtf8().constData());
601
602 /*
603 QMessageBox::information(this, tr("Downloaded"), tr("File saved as %1").arg(filename));
604 return;
605 */
606
607 status->setText(tr("Temporary file %1").arg(filename));
608
609 QString lang = "unknown";
610 QString extension = "unknown";
611 if (view->currentIndex().isValid()) {
612 const QModelIndex & index = view->currentIndex();
613 lang = table->item(proxy_model->mapToSource(index).row(), COL_LANG)->data(Qt::UserRole).toString();
614 extension = table->item(proxy_model->mapToSource(index).row(), COL_FORMAT)->text();
615 }
616
617 QFileInfo fi(file_chooser->text());
618 QString output_name = fi.completeBaseName();
619 if (include_lang_on_filename) output_name += "_"+ lang;
620 output_name += "." + extension;
621
622 if (!uncompressZip(filename, fi.absolutePath(), output_name)) {
623 status->setText(tr("Download failed"));
624 }
625 file.remove();
626 }
627 else {
628 qWarning("FindSubtitlesWindow::archiveDownloaded: can't write temporary file");
629 QMessageBox::warning(this, tr("Error saving file"),
630 tr("It wasn't possible to save the downloaded\n"
631 "file in folder %1\n"
632 "Please check the permissions of that folder.").arg(temp_dir));
633 }
634}
635
636
637bool FindSubtitlesWindow::uncompressZip(const QString & filename, const QString & output_path, const QString & preferred_output_name) {
638 qDebug("FindSubtitlesWindow::uncompressZip: zip file '%s', output_path '%s', save subtitle as '%s'",
639 filename.toUtf8().constData(), output_path.toUtf8().constData(),
640 preferred_output_name.toUtf8().constData());
641
642 QuaZip zip(filename);
643
644 if (!zip.open(QuaZip::mdUnzip)) {
645 qWarning("FindSubtitlesWindow::uncompressZip: open zip failed: %d", zip.getZipError());
646 return false;
647 }
648
649 zip.setFileNameCodec("IBM866");
650 qDebug("FindSubtitlesWindow::uncompressZip: %d entries", zip.getEntriesCount());
651 qDebug("FindSubtitlesWindow::uncompressZip: global comment: '%s'", zip.getComment().toUtf8().constData());
652
653 QStringList sub_files;
654 QuaZipFileInfo info;
655
656 for (bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
657 if (!zip.getCurrentFileInfo(&info)) {
658 qWarning("FindSubtitlesWindow::uncompressZip: getCurrentFileInfo(): %d\n", zip.getZipError());
659 return false;
660 }
661 qDebug("FindSubtitlesWindow::uncompressZip: file '%s'", info.name.toUtf8().constData());
662 if (QFileInfo(info.name).suffix() != "nfo") sub_files.append(info.name);
663 }
664
665 qDebug("FindSubtitlesWindow::uncompressZip: list of subtitle files:");
666 for (int n=0; n < sub_files.count(); n++) {
667 qDebug("FindSubtitlesWindow::uncompressZip: subtitle file %d '%s'", n, sub_files[n].toUtf8().constData());
668 }
669
670 if (sub_files.count() == 1) {
671 // If only one file, just extract it
672 QString output_name = output_path +"/"+ preferred_output_name;
673 if (extractFile(zip, sub_files[0], output_name )) {
674 status->setText(tr("Subtitle saved as %1").arg(preferred_output_name));
675 emit subtitleDownloaded(output_name);
676 } else {
677 return false;
678 }
679 } else {
680 // More than one file
681 SubChooserDialog d(this);
682
683 for (int n=0; n < sub_files.count(); n++) {
684 d.addFile(sub_files[n]);
685 }
686
687 if (d.exec() == QDialog::Rejected) return false;
688
689 QStringList files_to_extract = d.selectedFiles();
690 int extracted_count = 0;
691 for (int n=0; n < files_to_extract.count(); n++) {
692 QString file = files_to_extract[n];
693 bool ok = extractFile(zip, file, output_path +"/"+ file);
694 qDebug("FindSubtitlesWindow::uncompressZip: extracted %s ok: %d", file.toUtf8().constData(), ok);
695 if (ok) extracted_count++;
696 }
697 status->setText(tr("%n subtitle(s) extracted","", extracted_count));
698 if (extracted_count > 0) {
699 emit subtitleDownloaded( output_path +"/"+ files_to_extract[0] );
700 }
701 }
702
703 zip.close();
704 return true;
705}
706
707bool FindSubtitlesWindow::extractFile(QuaZip & zip, const QString & filename, const QString & output_name) {
708 qDebug("FindSubtitlesWindow::extractFile: '%s', save as '%s'", filename.toUtf8().constData(), output_name.toUtf8().constData());
709
710 if (QFile::exists(output_name)) {
711 if (QMessageBox::question(this, tr("Overwrite?"),
712 tr("The file %1 already exits, overwrite?").arg(output_name), QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
713 {
714 return false;
715 }
716 }
717
718 if (!zip.setCurrentFile(filename)) {
719 qDebug("FindSubtitlesWindow::extractFile: can't select file %s", filename.toUtf8().constData());
720 return false;
721 }
722
723 // Saving
724 char c;
725 QuaZipFile file(&zip);
726 QFile out(output_name);
727
728 if (!file.open(QIODevice::ReadOnly)) {
729 qWarning("FindSubtitlesWindow::extractFile: can't open file for reading: %d", file.getZipError());
730 return false;
731 }
732
733 if (out.open(QIODevice::WriteOnly)) {
734 // Slow like hell (on GNU/Linux at least), but it is not my fault.
735 // Not ZIP/UNZIP package's fault either.
736 // The slowest thing here is out.putChar(c).
737 while(file.getChar(&c)) out.putChar(c);
738 out.close();
739
740 file.close();
741 } else {
742 qWarning("FindSubtitlesWindow::extractFile: can't open %s for writing", output_name.toUtf8().constData());
743 return false;
744 }
745
746 return true;
747}
748#endif // USE_QUAZIP
749
750void FindSubtitlesWindow::fixSubtitles(const QString & filename) {
751 qDebug("FindSubtitlesWindow::fixSubtitles: %s", filename.toUtf8().constData());
752
753 QFileInfo fi(filename);
754 if (fi.suffix().toLower() == "sub") {
755 qDebug("FindSubtitlesWindow::fixSubtitles: fixing end of lines");
756 if (FixSubtitles::fix(filename) != FixSubtitles::NoError) {
757 status->setText( tr("Error fixing the subtitle lines") );
758 qDebug("FindSubtitlesWindow::fixSubtitles: error fixing the subtitles");
759 }
760 }
761}
762
763#endif // DOWNLOAD_SUBS
764
765void FindSubtitlesWindow::on_configure_button_clicked() {
766 qDebug("FindSubtitlesWindow::on_configure_button_clicked");
767
768 FindSubtitlesConfigDialog d(this);
769
770 d.setServer( os_server );
771 #ifdef OS_SEARCH_WORKAROUND
772 d.setRetries(osclient->retries());
773 #endif
774 #ifdef FS_USE_PROXY
775 d.setUseProxy( use_proxy );
776 d.setProxyHostname( proxy_host );
777 d.setProxyPort( proxy_port );
778 d.setProxyUsername( proxy_username );
779 d.setProxyPassword( proxy_password );
780 d.setProxyType( proxy_type );
781 #endif
782
783 #ifdef DOWNLOAD_SUBS
784 d.setAppendLang(include_lang_on_filename);
785 #endif
786
787 if (d.exec() == QDialog::Accepted) {
788 os_server = d.server();
789 #ifdef OS_SEARCH_WORKAROUND
790 osclient->setRetries( d.retries() );
791 #endif
792 #ifdef FS_USE_PROXY
793 use_proxy = d.useProxy();
794 proxy_host = d.proxyHostname();
795 proxy_port = d.proxyPort();
796 proxy_username = d.proxyUsername();
797 proxy_password = d.proxyPassword();
798 proxy_type = d.proxyType();
799 #endif
800
801 osclient->setServer(os_server);
802 #ifdef FS_USE_PROXY
803 setupProxy();
804 #endif
805
806 #ifdef DOWNLOAD_SUBS
807 include_lang_on_filename = d.appendLang();
808 #endif
809 }
810}
811
812#ifdef FS_USE_PROXY
813void FindSubtitlesWindow::setupProxy() {
814 QNetworkProxy proxy;
815
816 if ( (use_proxy) && (!proxy_host.isEmpty()) ) {
817 proxy.setType((QNetworkProxy::ProxyType) proxy_type);
818 proxy.setHostName(proxy_host);
819 proxy.setPort(proxy_port);
820 if ( (!proxy_username.isEmpty()) && (!proxy_password.isEmpty()) ) {
821 proxy.setUser(proxy_username);
822 proxy.setPassword(proxy_password);
823 }
824 qDebug("FindSubtitlesWindow::userProxy: using proxy: host: %s, port: %d, type: %d",
825 proxy_host.toUtf8().constData(), proxy_port, proxy_type);
826 } else {
827 // No proxy
828 proxy.setType(QNetworkProxy::NoProxy);
829 qDebug("FindSubtitlesDialog::userProxy: no proxy");
830 }
831
832 setProxy(proxy);
833}
834#endif
835
836void FindSubtitlesWindow::saveSettings() {
837 qDebug("FindSubtitlesWindow::saveSettings");
838
839 set->beginGroup("findsubtitles");
840
841 set->setValue("xmlrpc_server", os_server);
842#ifdef OS_SEARCH_WORKAROUND
843 set->setValue("retries", osclient->retries());
844#endif
845
846 set->setValue("language", language());
847#ifdef DOWNLOAD_SUBS
848 set->setValue("include_lang_on_filename", includeLangOnFilename());
849#endif
850
851#ifdef FS_USE_PROXY
852 set->setValue("proxy/use_proxy", use_proxy);
853 set->setValue("proxy/type", proxy_type);
854 set->setValue("proxy/host", proxy_host);
855 set->setValue("proxy/port", proxy_port);
856 set->setValue("proxy/username", proxy_username);
857 set->setValue("proxy/password", proxy_password);
858#endif
859
860 set->endGroup();
861}
862
863void FindSubtitlesWindow::loadSettings() {
864 qDebug("FindSubtitlesWindow::loadSettings");
865
866 set->beginGroup("findsubtitles");
867
868 os_server = set->value("xmlrpc_server", os_server).toString();
869#ifdef OS_SEARCH_WORKAROUND
870 osclient->setRetries( set->value("retries", osclient->retries()).toInt() );
871#endif
872
873 setLanguage( set->value("language", language()).toString() );
874#ifdef DOWNLOAD_SUBS
875 setIncludeLangOnFilename( set->value("include_lang_on_filename", includeLangOnFilename()).toBool() );
876#endif
877
878#ifdef FS_USE_PROXY
879 use_proxy = set->value("proxy/use_proxy", use_proxy).toBool();
880 proxy_type = set->value("proxy/type", proxy_type).toInt();
881 proxy_host = set->value("proxy/host", proxy_host).toString();
882 proxy_port = set->value("proxy/port", proxy_port).toInt();
883 proxy_username = set->value("proxy/username", proxy_username).toString();
884 proxy_password = set->value("proxy/password", proxy_password).toString();
885#endif
886
887 set->endGroup();
888}
889
890#include "moc_findsubtitleswindow.cpp"
891
Note: See TracBrowser for help on using the repository browser.