scan: add select/invert buttons.
[abby.git] / src / scandlg.cpp
blob2a9f522b8a135db05769098b3e9d051799538481
1 /*
2 * abby Copyright (C) 2009 Toni Gundogdu.
3 * This file is part of abby.
5 * abby 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 3 of the License, or
8 * (at your option) any later version.
10 * abby is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <QDialog>
19 #include <QSettings>
20 //#include <QDebug>
21 #include <QMessageBox>
22 #include <QRegExp>
24 #include "util.h"
25 #include "scandlg.h"
27 ScanDialog::ScanDialog(QWidget *parent)
28 : QDialog(parent), titleMode(false)
30 setupUi(this);
32 readSettings();
34 mgr = createManager();
36 itemsTree->setColumnHidden(1, true);
39 void
40 ScanDialog::onScan() {
41 QString lnk = linkEdit->text();
43 lnk = lnk.trimmed();
45 if (lnk.isEmpty())
46 return;
48 if (!lnk.startsWith("http://", Qt::CaseInsensitive))
49 lnk.insert(0,"http://");
51 itemsTree->clear();
53 titleMode = false;
55 linkEdit->setEnabled (false);
56 scanButton->setEnabled (false);
57 titlesBox->setEnabled (false);
58 buttonBox->setEnabled (false);
59 selectallButton->setEnabled(false);
60 invertButton->setEnabled(false);
62 mgr->get(QNetworkRequest(lnk));
65 void
66 ScanDialog::replyFinished(QNetworkReply* reply) {
68 bool state = false;
70 if (reply->error() == QNetworkReply::NoError) {
72 handleRedirect(reply);
74 if (!redirectedToURL.isEmpty())
75 mgr->get( QNetworkRequest(redirectedToURL) );
76 else {
77 if (!titleMode)
78 scanContent(reply);
79 else
80 parseHtmlTitle(reply);
81 redirectedToURL.clear();
82 state = true;
85 else {
86 QMessageBox::critical(this, QCoreApplication::applicationName(),
87 QString(tr("Network error: %1")).arg(reply->errorString()));
88 state = true;
91 if (state) {
92 linkEdit->setEnabled (state);
93 scanButton->setEnabled (state);
94 titlesBox->setEnabled (state);
95 buttonBox->setEnabled (state);
96 selectallButton->setEnabled(state);
97 invertButton->setEnabled(state);
100 reply->deleteLater();
103 static QStringList
104 matchScanContent (const QStringList& lst, QRegExp& re, const QString& content) {
106 re.setCaseSensitivity(Qt::CaseInsensitive);
107 re.setMinimal(true);
109 QStringList matches;
111 int pos = 0;
112 while ((pos = re.indexIn(content, pos)) != -1) {
113 if (!matches.contains(re.cap(1)) && !lst.contains(re.cap(1)))
114 matches << re.cap(1);
115 pos += re.matchedLength();
117 return matches;
120 typedef unsigned int _uint;
122 #ifdef _1_
123 static void
124 dumpScanMatches (const QStringList& lst) {
125 const register _uint size = lst.size();
126 for (register _uint i=0; i<size; ++i)
127 qDebug() << lst[i];
128 qDebug() << "total: " << lst.size();
130 #endif
132 static void
133 scanYoutubeEmbed(QStringList& lst, const QString& content) {
134 QRegExp re("\\/v\\/(.*)[\"&\n]");
135 QStringList matches = matchScanContent(lst, re, content);
136 //dumpScanMatches(matches);
137 lst << matches;
140 static void
141 scanYoutubeRegular(QStringList& lst, const QString& content) {
142 QRegExp re("\\/watch\\?v=(.*)[\"&\n]");
143 QStringList matches = matchScanContent(lst, re, content);
144 //dumpScanMatches(matches);
145 lst << matches;
148 void
149 ScanDialog::scanContent(QNetworkReply *reply) {
151 const QString content = QString::fromLocal8Bit(reply->readAll());
153 QStringList IDs, links;
155 scanYoutubeEmbed (IDs, content);
156 scanYoutubeRegular (IDs, content);
158 const register _uint ids_size = IDs.size();
159 register _uint i;
161 for (i=0; i<ids_size; ++i)
162 links << "http://www.youtube.com/watch?v="+IDs[i];
164 const register _uint links_size = links.size();
166 if (titlesBox->checkState()) {
167 titleMode = true;
168 for (i=0; i<links_size; ++i)
169 mgr->get( QNetworkRequest(links[i]) );
171 else {
172 for (i=0; i<links_size; ++i) {
173 QTreeWidgetItem *item = new QTreeWidgetItem;
174 item->setCheckState(0, Qt::Unchecked);
175 item->setText(0, links[i]);
176 item->setText(1, links[i]);
177 itemsTree->addTopLevelItem(item);
182 void
183 ScanDialog::parseHtmlTitle(QNetworkReply *reply) {
185 const QString content = QString::fromLocal8Bit(reply->readAll());
186 const QString link = reply->url().toString();
188 QRegExp re("<title>(.*)<\\/title>"); // TODO: improve.
189 re.setCaseSensitivity(Qt::CaseInsensitive);
190 re.setMinimal(true);
191 re.indexIn(content);
193 QTreeWidgetItem *item = new QTreeWidgetItem;
194 item->setCheckState(0, Qt::Unchecked);
195 item->setText(0, re.cap(1));
196 item->setText(1, link);
197 itemsTree->addTopLevelItem(item);
200 QNetworkAccessManager*
201 ScanDialog::createManager() {
202 QNetworkAccessManager *p = new QNetworkAccessManager(this);
204 connect(p, SIGNAL(finished(QNetworkReply*)),
205 this, SLOT(replyFinished(QNetworkReply*)));
207 return p;
210 void
211 ScanDialog::handleRedirect(const QNetworkReply *reply) {
213 // QUrl location =
214 // reply->header(QNetworkRequest::LocationHeader).toUrl();
216 QUrl location =
217 reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
219 if (!location.isEmpty() && location != redirectedToURL)
220 redirectedToURL = location;
221 else
222 redirectedToURL.clear();
225 void
226 ScanDialog::writeSettings() {
227 QSettings s;
228 s.beginGroup("ScanDialog");
229 s.setValue("size", size());
230 s.endGroup();
233 void
234 ScanDialog::readSettings() {
235 QSettings s;
236 s.beginGroup("ScanDialog");
237 resize( s.value("size", QSize(514,295)).toSize() );
238 s.endGroup();
241 void
242 ScanDialog::onSelectAll() {
243 Util::checkAllItems(itemsTree, Qt::Checked);
246 void
247 ScanDialog::onInvert() {
248 Util::invertAllCheckableItems(itemsTree);