1 /* ============================================================
2 * QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
3 * Copyright (C) 2011-2020 QuiteRSS Team <quiterssteam@gmail.com>
4 *
5 * This program 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.
9 *
10 * This program 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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 * ============================================================ */
18 #include "addfeedwizard.h"
19
20 #include "mainapplication.h"
21 #include "addfolderdialog.h"
22 #include "authenticationdialog.h"
23 #include "toolbutton.h"
24 #include "settings.h"
25
26 #include <QDomDocument>
27 #include <qzregexp.h>
28
29 extern QString kCreateNewsTableQuery;
30
AddFeedWizard(QWidget * parent,int curFolderId)31 AddFeedWizard::AddFeedWizard(QWidget *parent, int curFolderId)
32 : QWizard(parent),
33 curFolderId_(curFolderId)
34 {
35 setModal(true);
36 setWindowFlags (windowFlags() & ~Qt::WindowContextHelpButtonHint);
37 setWindowTitle(tr("Add Feed"));
38 setWizardStyle(QWizard::ModernStyle);
39 setOptions(QWizard::HaveFinishButtonOnEarlyPages |
40 QWizard::NoBackButtonOnStartPage);
41
42 addPage(createUrlFeedPage());
43 addPage(createNameFeedPage());
44
45 updateFeeds_ = new UpdateFeeds(this, true);
46
47 connect(button(QWizard::BackButton), SIGNAL(clicked()),
48 this, SLOT(backButtonClicked()));
49 connect(button(QWizard::NextButton), SIGNAL(clicked()),
50 this, SLOT(nextButtonClicked()));
51 connect(button(QWizard::FinishButton), SIGNAL(clicked()),
52 this, SLOT(finishButtonClicked()));
53 connect(this, SIGNAL(currentIdChanged(int)),
54 SLOT(slotCurrentIdChanged(int)),
55 Qt::QueuedConnection);
56 resize(400, 300);
57
58 Settings settings;
59 restoreGeometry(settings.value("addFeedWizard/geometry").toByteArray());
60 }
61
~AddFeedWizard()62 AddFeedWizard::~AddFeedWizard()
63 {
64 Settings settings;
65 settings.setValue("addFeedWizard/geometry", saveGeometry());
66
67 updateFeeds_->disconnectObjects();
68 delete updateFeeds_;
69 }
70
done(int result)71 /*virtual*/ void AddFeedWizard::done(int result)
72 {
73 if (result == QDialog::Rejected) {
74 if (progressBar_->isVisible() || (currentId() == 1))
75 deleteFeed();
76 }
77 QWizard::done(result);
78 }
79
changeEvent(QEvent * event)80 void AddFeedWizard::changeEvent(QEvent *event)
81 {
82 if ((event->type() == QEvent::ActivationChange) &&
83 isActiveWindow() && (currentId() == 0) && urlFeedEdit_->isEnabled()) {
84 QClipboard *clipboard_ = QApplication::clipboard();
85 QString clipboardStr = clipboard_->text().left(8);
86 if (clipboardStr.contains("http://", Qt::CaseInsensitive) ||
87 clipboardStr.contains("https://", Qt::CaseInsensitive) ||
88 clipboardStr.contains("www.", Qt::CaseInsensitive) ||
89 clipboardStr.contains("feed://", Qt::CaseInsensitive) ||
90 clipboardStr.contains("file://", Qt::CaseInsensitive)) {
91 urlFeedEdit_->setText(clipboard_->text());
92 urlFeedEdit_->selectAll();
93 urlFeedEdit_->setFocus();
94 }
95 }
96 }
97
createUrlFeedPage()98 QWizardPage *AddFeedWizard::createUrlFeedPage()
99 {
100 QWizardPage *page = new QWizardPage;
101 page->setTitle(tr("Create New Feed"));
102
103 selectedPage = false;
104 finishOn = false;
105
106 urlFeedEdit_ = new LineEdit(this);
107 urlFeedEdit_->setText("http://");
108
109 titleFeedAsName_ = new QCheckBox(
110 tr("Use title of the feed as displayed name"), this);
111 titleFeedAsName_->setChecked(true);
112
113 authentication_ = new QGroupBox(this);
114 authentication_->setTitle(tr("Server requires authentication:"));
115 authentication_->setCheckable(true);
116 authentication_->setChecked(false);
117
118 user_ = new LineEdit(this);
119 pass_ = new LineEdit(this);
120 pass_->setEchoMode(QLineEdit::Password);
121
122 QGridLayout *authenticationLayout = new QGridLayout();
123 authenticationLayout->addWidget(new QLabel(tr("Username:")), 0, 0);
124 authenticationLayout->addWidget(user_, 0, 1);
125 authenticationLayout->addWidget(new QLabel(tr("Password:")), 1, 0);
126 authenticationLayout->addWidget(pass_, 1, 1);
127
128 authentication_->setLayout(authenticationLayout);
129
130 QLabel *iconWarning = new QLabel(this);
131 iconWarning->setPixmap(QPixmap(":/images/warning"));
132 textWarning = new QLabel(this);
133 QFont font = textWarning->font();
134 font.setBold(true);
135 textWarning->setFont(font);
136
137 QHBoxLayout *warningLayout = new QHBoxLayout();
138 warningLayout->setMargin(0);
139 warningLayout->addWidget(iconWarning);
140 warningLayout->addWidget(textWarning, 1);
141
142 warningWidget_ = new QWidget(this);
143 warningWidget_->setLayout(warningLayout);
144
145 progressBar_ = new QProgressBar(this);
146 progressBar_->setObjectName("progressBar_");
147 progressBar_->setTextVisible(false);
148 progressBar_->setFixedHeight(15);
149 progressBar_->setMinimum(0);
150 progressBar_->setMaximum(0);
151 progressBar_->setVisible(false);
152
153 QVBoxLayout *layout = new QVBoxLayout;
154 layout->addWidget(new QLabel(tr("Feed URL or website address:")));
155 layout->addWidget(urlFeedEdit_);
156 layout->addWidget(titleFeedAsName_);
157 layout->addSpacing(10);
158 layout->addWidget(authentication_);
159 layout->addStretch(1);
160 layout->addWidget(warningWidget_);
161 layout->addWidget(progressBar_);
162 page->setLayout(layout);
163
164 connect(urlFeedEdit_, SIGNAL(textChanged(const QString&)),
165 this, SLOT(urlFeedEditChanged(const QString&)));
166 connect(titleFeedAsName_, SIGNAL(stateChanged(int)),
167 this, SLOT(titleFeedAsNameStateChanged(int)));
168
169 return page;
170 }
171
createNameFeedPage()172 QWizardPage *AddFeedWizard::createNameFeedPage()
173 {
174 QWizardPage *page = new QWizardPage;
175 page->setTitle(tr("Create New Feed"));
176 page->setFinalPage(false);
177
178 nameFeedEdit_ = new LineEdit(this);
179
180 foldersTree_ = new QTreeWidget(this);
181 foldersTree_->setObjectName("foldersTree_");
182 foldersTree_->setColumnCount(2);
183 foldersTree_->setColumnHidden(1, true);
184 foldersTree_->header()->hide();
185
186 QStringList treeItem;
187 treeItem << tr("Feeds") << "Id";
188 foldersTree_->setHeaderLabels(treeItem);
189
190 treeItem.clear();
191 treeItem << tr("All Feeds") << "0";
192 QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem(treeItem);
193 treeWidgetItem->setIcon(0, QIcon(":/images/folder"));
194 foldersTree_->addTopLevelItem(treeWidgetItem);
195 foldersTree_->setCurrentItem(treeWidgetItem);
196
197 QSqlQuery q;
198 QQueue<int> parentIds;
199 parentIds.enqueue(0);
200 while (!parentIds.empty()) {
201 int parentId = parentIds.dequeue();
202 QString qStr = QString("SELECT text, id FROM feeds WHERE parentId='%1' AND (xmlUrl='' OR xmlUrl IS NULL)").
203 arg(parentId);
204 q.exec(qStr);
205 while (q.next()) {
206 QString folderText = q.value(0).toString();
207 QString folderId = q.value(1).toString();
208
209 QStringList treeItem;
210 treeItem << folderText << folderId;
211 QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem(treeItem);
212
213 treeWidgetItem->setIcon(0, QIcon(":/images/folder"));
214
215 QList<QTreeWidgetItem *> treeItems =
216 foldersTree_->findItems(QString::number(parentId),
217 Qt::MatchFixedString | Qt::MatchRecursive,
218 1);
219 treeItems.at(0)->addChild(treeWidgetItem);
220 if (folderId.toInt() == curFolderId_)
221 foldersTree_->setCurrentItem(treeWidgetItem);
222 parentIds.enqueue(folderId.toInt());
223 }
224 }
225
226 foldersTree_->expandAll();
227 foldersTree_->sortByColumn(0, Qt::AscendingOrder);
228
229 ToolButton *newFolderButton = new ToolButton(this);
230 newFolderButton->setIcon(QIcon(":/images/addT"));
231 newFolderButton->setToolTip(tr("New Folder..."));
232 newFolderButton->setAutoRaise(true);
233
234 QHBoxLayout *newFolderLayout = new QHBoxLayout;
235 newFolderLayout->setMargin(0);
236 newFolderLayout->addWidget(newFolderButton);
237 newFolderLayout->addStretch();
238 QVBoxLayout *newFolderVLayout = new QVBoxLayout;
239 newFolderVLayout->setMargin(2);
240 newFolderVLayout->addStretch();
241 newFolderVLayout->addLayout(newFolderLayout);
242
243 foldersTree_->setLayout(newFolderVLayout);
244
245 QVBoxLayout *layout = new QVBoxLayout;
246 layout->addWidget(new QLabel(tr("Displayed name:")));
247 layout->addWidget(nameFeedEdit_);
248 layout->addWidget(new QLabel(tr("Location:")));
249 layout->addWidget(foldersTree_);
250 page->setLayout(layout);
251
252 connect(nameFeedEdit_, SIGNAL(textChanged(const QString&)),
253 this, SLOT(nameFeedEditChanged(const QString&)));
254 connect(newFolderButton, SIGNAL(clicked()),
255 this, SLOT(newFolder()));
256
257 return page;
258 }
259
setUrlFeed(const QString & feedUrl)260 void AddFeedWizard::setUrlFeed(const QString &feedUrl)
261 {
262 urlFeedEdit_->setText(feedUrl);
263 }
264
urlFeedEditChanged(const QString & text)265 void AddFeedWizard::urlFeedEditChanged(const QString& text)
266 {
267 button(QWizard::NextButton)->setEnabled(
268 !text.isEmpty() && (text != "http://"));
269
270 bool buttonEnable = false;
271 if (titleFeedAsName_->isChecked() && (text != "http://") &&
272 !text.isEmpty()) {
273 buttonEnable = true;
274 }
275 warningWidget_->setVisible(false);
276 button(QWizard::FinishButton)->setEnabled(buttonEnable);
277 }
278
titleFeedAsNameStateChanged(int state)279 void AddFeedWizard::titleFeedAsNameStateChanged(int state)
280 {
281 bool buttonEnable = false;
282 if ((state == Qt::Checked) && (urlFeedEdit_->text() != "http://") &&
283 !urlFeedEdit_->text().isEmpty()) {
284 buttonEnable = true;
285 }
286 button(QWizard::FinishButton)->setEnabled(buttonEnable);
287 }
288
nameFeedEditChanged(const QString & text)289 void AddFeedWizard::nameFeedEditChanged(const QString& text)
290 {
291 button(QWizard::FinishButton)->setEnabled(!text.isEmpty());
292 }
293
backButtonClicked()294 void AddFeedWizard::backButtonClicked()
295 {
296 deleteFeed();
297 nameFeedEdit_->clear();
298 page(0)->setEnabled(true);
299 selectedPage = false;
300 }
301
nextButtonClicked()302 void AddFeedWizard::nextButtonClicked()
303 {
304 if (currentId() == 0)
305 addFeed();
306 }
307
finishButtonClicked()308 void AddFeedWizard::finishButtonClicked()
309 {
310 if (currentId() == 0) {
311 finishOn = true;
312 addFeed();
313 } else if (currentId() == 1) {
314 finish();
315 }
316 }
317
addFeed()318 void AddFeedWizard::addFeed()
319 {
320 // Set URL-schema for URL-address "http://" or leave it "https://"
321 feedUrlString_ = urlFeedEdit_->text().simplified();
322 if (feedUrlString_.contains("feed:", Qt::CaseInsensitive)) {
323 if (feedUrlString_.contains("https://", Qt::CaseInsensitive)) {
324 feedUrlString_.remove(0, 5);
325 urlFeedEdit_->setText(feedUrlString_);
326 } else {
327 feedUrlString_.remove(0, 7);
328 urlFeedEdit_->setText("http://" + feedUrlString_);
329 }
330 }
331 QUrl feedUrl(urlFeedEdit_->text().simplified());
332 if (feedUrl.scheme().isEmpty()) {
333 feedUrl.setUrl("http://" % urlFeedEdit_->text().simplified());
334 }
335 feedUrlString_ = feedUrl.toString();
336 urlFeedEdit_->setText(feedUrlString_);
337
338 #if QT_VERSION >= 0x040800
339 if (feedUrl.host().isEmpty() && !feedUrl.isLocalFile()) {
340 #else
341 if (feedUrl.host().isEmpty() && (feedUrl.scheme() != "file")) {
342 #endif
343 textWarning->setText(tr("URL error!"));
344 warningWidget_->setVisible(true);
345 return;
346 }
347
348 QSqlQuery q;
349 int duplicateFoundId = -1;
350 q.prepare("SELECT id FROM feeds WHERE xmlUrl LIKE :xmlUrl");
351 q.bindValue(":xmlUrl", feedUrlString_);
352 q.exec();
353 if (q.first())
354 duplicateFoundId = q.value(0).toInt();
355
356 if (0 <= duplicateFoundId) {
357 textWarning->setText(tr("Duplicate feed!"));
358 warningWidget_->setVisible(true);
359 } else {
360 button(QWizard::NextButton)->setEnabled(false);
361 button(QWizard::CancelButton)->setEnabled(false);
362 button(QWizard::FinishButton)->setEnabled(false);
363 page(0)->setEnabled(false);
364 showProgressBar();
365
366 // Calculate row's number to insert new feed
367 int rowToParent = 0;
368 q.exec("SELECT count(id) FROM feeds WHERE parentId=0");
369 if (q.next()) rowToParent = q.value(0).toInt();
370
371 int auth = 0;
372 QString userInfo;
373 if (authentication_->isChecked()) {
374 auth = 1;
375 userInfo = QString("%1:%2").arg(user_->text()).arg(pass_->text());
376 }
377
378 // Insert feed
379 q.prepare("INSERT INTO feeds(xmlUrl, created, rowToParent, authentication) "
380 "VALUES (:feedUrl, :feedCreateTime, :rowToParent, :authentication)");
381 q.bindValue(":feedUrl", feedUrlString_);
382 q.bindValue(":feedCreateTime",
383 QLocale::c().toString(QDateTime::currentDateTimeUtc(), "yyyy-MM-ddTHH:mm:ss"));
384 q.bindValue(":rowToParent", rowToParent);
385 q.bindValue(":authentication", auth);
386 q.exec();
387
388 feedId_ = q.lastInsertId().toInt();
389 q.finish();
390
391 if (feedUrlString_.contains(":COOKIE:", Qt::CaseInsensitive)) {
392 int index = feedUrlString_.lastIndexOf(":COOKIE:", -1, Qt::CaseInsensitive);
393 QString cookieStr = feedUrlString_.right(feedUrlString_.length() - index - 8);
394 QStringList cookieStrList = cookieStr.split(";");
395
396 QList<QNetworkCookie> loadedCookies;
397 foreach (QString cookieStr, cookieStrList) {
398 const QList<QNetworkCookie> &cookieList = QNetworkCookie::parseCookies(cookieStr.toUtf8());
399 if (cookieList.isEmpty()) {
400 continue;
401 }
402 QNetworkCookie cookie = cookieList.at(0);
403 QDateTime date = QDateTime::currentDateTime();
404 date = date.addYears(35);
405 cookie.setExpirationDate(date);
406 loadedCookies.append(cookie);
407 }
408 mainApp->cookieJar()->setCookiesFromUrl(loadedCookies, feedUrlString_);
409 }
410
411 emit signalRequestUrl(feedId_, feedUrlString_, QDateTime(), userInfo);
412 }
413 }
414
415 void AddFeedWizard::deleteFeed()
416 {
417 QSqlQuery q;
418 q.exec(QString("DELETE FROM feeds WHERE id='%1'").arg(feedId_));
419 q.exec(QString("DELETE FROM news WHERE feedId='%1'").arg(feedId_));
420
421 // Correct rowToParent field
422 QList<int> idList;
423 q.exec("SELECT id FROM feeds WHERE parentId=0 ORDER BY rowToParent");
424 while (q.next()) {
425 idList << q.value(0).toInt();
426 }
427 for (int i = 0; i < idList.count(); i++) {
428 q.exec(QString("UPDATE feeds SET rowToParent='%1' WHERE id=='%2'").
429 arg(i).arg(idList.at(i)));
430 }
431 q.finish();
432 }
433
434 void AddFeedWizard::slotCurrentIdChanged(int idPage)
435 {
436 if (idPage == 0)
437 urlFeedEditChanged(urlFeedEdit_->text());
438 else if (idPage == 1)
439 nameFeedEditChanged(nameFeedEdit_->text());
440 }
441
442 /*virtual*/ bool AddFeedWizard::validateCurrentPage()
443 {
444 if (!selectedPage) {
445 return false;
446 }
447 return true;
448 }
449
450 void AddFeedWizard::showProgressBar()
451 {
452 progressBar_->show();
453 QTimer::singleShot(250, this, SLOT(slotProgressBarUpdate()));
454 }
455
456 void AddFeedWizard::slotProgressBarUpdate()
457 {
458 progressBar_->update();
459 if (progressBar_->isVisible())
460 QTimer::singleShot(250, this, SLOT(slotProgressBarUpdate()));
461 }
462
463 void AddFeedWizard::getUrlDone(int result, int feedId, QString feedUrlStr,
464 QString error, QByteArray data,
465 QDateTime dtReply, QString codecName)
466 {
467 if (!data.isEmpty()) {
468 bool isFeed = false;
469 QString errorStr;
470 int errorLine;
471 int errorColumn;
472 QDomDocument doc("parseDoc");
473 if (!doc.setContent(data, false, &errorStr, &errorLine, &errorColumn)) {
474 qWarning() << QString("Parse data error (1): url %1, id %2, line %3, column %4: %5").
475 arg(feedUrlStr).arg(feedId).
476 arg(errorLine).arg(errorColumn).arg(errorStr);
477 } else {
478 QDomElement docElem = doc.documentElement();
479 if ((docElem.tagName() == "rss") || (docElem.tagName() == "feed") ||
480 (docElem.tagName() == "rdf:RDF"))
481 isFeed = true;
482 }
483
484 if (!isFeed) {
485 QString str = QString::fromUtf8(data);
486
487 QzRegExp rx("<link[^>]+(atom|rss)\\+xml[^>]+>", Qt::CaseInsensitive);
488 int pos = rx.indexIn(str);
489 if (pos > -1) {
490 str = rx.cap(0);
491 rx.setPattern("href=\"([^\"]+)");
492 pos = rx.indexIn(str);
493 if (pos > -1) {
494 QString linkFeedString = rx.cap(1);
495 linkFeedString.replace("&", "&", Qt::CaseInsensitive);
496 QUrl url(linkFeedString);
497 QUrl feedUrl(feedUrlStr);
498 if (url.host().isEmpty()) {
499 url.setScheme(feedUrl.scheme());
500 url.setHost(feedUrl.host());
501 if (feedUrl.toString().indexOf('?') > -1) {
502 str = feedUrl.path();
503 str = str.left(str.lastIndexOf('/')+1);
504 url.setPath(str+url.path());
505 }
506 }
507 linkFeedString = url.toString();
508 qDebug() << "Parse feed URL, valid:" << linkFeedString;
509
510 QSqlQuery q;
511 int duplicateFoundId = -1;
512 q.prepare("SELECT id FROM feeds WHERE xmlUrl LIKE :xmlUrl");
513 q.bindValue(":xmlUrl", linkFeedString);
514 q.exec();
515 if (q.next()) duplicateFoundId = q.value(0).toInt();
516
517 if (0 <= duplicateFoundId) {
518 if (feedUrlString_ != linkFeedString)
519 textWarning->setText(tr("Duplicate feed!"));
520 else
521 textWarning->setText(tr("Can't find feed URL!"));
522 warningWidget_->setVisible(true);
523
524 deleteFeed();
525 progressBar_->hide();
526 page(0)->setEnabled(true);
527 selectedPage = false;
528 button(QWizard::CancelButton)->setEnabled(true);
529 } else {
530 feedUrlString_ = linkFeedString;
531 q.prepare("UPDATE feeds SET xmlUrl = :xmlUrl WHERE id == :id");
532 q.bindValue(":xmlUrl", linkFeedString);
533 q.bindValue(":id", feedId);
534 q.exec();
535
536 authentication_->setChecked(false);
537
538 emit signalRequestUrl(feedId, linkFeedString, QDateTime(), "");
539 }
540 }
541 }
542 if (pos < 0) {
543 textWarning->setText(tr("Can't find feed URL!"));
544 warningWidget_->setVisible(true);
545
546 deleteFeed();
547 progressBar_->hide();
548 page(0)->setEnabled(true);
549 selectedPage = false;
550 button(QWizard::CancelButton)->setEnabled(true);
551 }
552 return;
553 }
554
555 emit xmlReadyParse(data, feedId, dtReply, codecName);
556 }
557
558 if ((result < 0) || data.isEmpty()) {
559 if ((result >= -5) && (result <= -1))
560 textWarning->setText(error);
561 else
562 textWarning->setText(tr("Request failed!"));
563 warningWidget_->setVisible(true);
564 qWarning() << QString("Request failed: result = %1, error - %2, url - %3").
565 arg(result).arg(error).arg(feedUrlStr);
566
567 deleteFeed();
568 progressBar_->hide();
569 page(0)->setEnabled(true);
570 selectedPage = false;
571 button(QWizard::CancelButton)->setEnabled(true);
572 }
573 }
574
575 void AddFeedWizard::slotUpdateFeed(int feedId, bool, int newCount, QString)
576 {
577 qDebug() << "ParseDone: " << feedUrlString_;
578 selectedPage = true;
579 newCount_ = newCount;
580
581 if (titleFeedAsName_->isChecked()) {
582 QSqlQuery q;
583 q.exec(QString("SELECT title FROM feeds WHERE id=='%1'").arg(feedId));
584 if (q.first()) nameFeedEdit_->setText(q.value(0).toString());
585 nameFeedEdit_->selectAll();
586 nameFeedEdit_->setFocus();
587 }
588 if (!finishOn) {
589 button(QWizard::CancelButton)->setEnabled(true);
590 next();
591 } else {
592 finish();
593 }
594 progressBar_->hide();
595 }
596
597 void AddFeedWizard::finish()
598 {
599 QSqlQuery q;
600 q.exec(QString("SELECT htmlUrl FROM feeds WHERE id=='%1'").arg(feedId_));
601 if (q.first())
602 htmlUrlString_ = q.value(0).toString();
603
604 feedParentId_ = foldersTree_->currentItem()->text(1).toInt();
605
606 // Correct rowToParent field
607 QList<int> idList;
608 q.exec("SELECT id FROM feeds WHERE parentId=0 ORDER BY rowToParent");
609 while (q.next()) {
610 if (feedId_ != q.value(0).toInt())
611 idList << q.value(0).toInt();
612 }
613 for (int i = 0; i < idList.count(); i++) {
614 q.exec(QString("UPDATE feeds SET rowToParent='%1' WHERE id=='%2'").
615 arg(i).arg(idList.at(i)));
616 }
617
618 // Calculate row number to insert feed
619 int rowToParent = 0;
620 q.exec(QString("SELECT count(id) FROM feeds WHERE parentId='%1' AND id!='%2'").
621 arg(feedParentId_).arg(feedId_));
622 if (q.next()) rowToParent = q.value(0).toInt();
623
624 int auth = 0;
625 if (authentication_->isChecked()) auth = 1;
626
627 q.prepare("UPDATE feeds SET text = ?, parentId = ?, rowToParent = ?, authentication = ? WHERE id == ?");
628 q.addBindValue(nameFeedEdit_->text());
629 q.addBindValue(feedParentId_);
630 q.addBindValue(rowToParent);
631 q.addBindValue(auth);
632 q.addBindValue(feedId_);
633 q.exec();
634
635 if (auth) {
636 QUrl url(feedUrlString_);
637 QString server = url.host();
638
639 q.prepare("SELECT * FROM passwords WHERE server=?");
640 q.addBindValue(server);
641 q.exec();
642 if (!q.next()) {
643 q.prepare("INSERT INTO passwords (server, username, password) "
644 "VALUES (:server, :username, :password)");
645 q.bindValue(":server", server);
646 q.bindValue(":username", user_->text());
647 q.bindValue(":password", pass_->text().toUtf8().toBase64());
648 q.exec();
649 }
650 }
651
652 if (feedParentId_) {
653 q.prepare("SELECT columns, sort, sortType, "
654 "updateIntervalEnable, updateInterval, updateIntervalType, "
655 "displayEmbeddedImages, displayNews, layoutDirection, "
656 "javaScriptEnable "
657 "FROM feeds WHERE id=?");
658 q.addBindValue(feedParentId_);
659 q.exec();
660 if (q.next()) {
661 QSqlQuery q1;
662 q1.prepare("UPDATE feeds SET columns = ?, sort = ?, sortType = ?, "
663 "updateIntervalEnable = ?, updateInterval = ?, updateIntervalType = ?, "
664 "displayEmbeddedImages = ?, displayNews = ?, layoutDirection = ?, "
665 "javaScriptEnable = ? "
666 "WHERE id == ?");
667 q1.addBindValue(q.value(0));
668 q1.addBindValue(q.value(1));
669 q1.addBindValue(q.value(2));
670 q1.addBindValue(q.value(3));
671 q1.addBindValue(q.value(4));
672 q1.addBindValue(q.value(5));
673 q1.addBindValue(q.value(6));
674 q1.addBindValue(q.value(7));
675 q1.addBindValue(q.value(8));
676 q1.addBindValue(q.value(9));
677 q1.addBindValue(feedId_);
678 q1.exec();
679 }
680 }
681
682 accept();
683 }
684
685 /*! \brief Adding new folder **************************************************/
686 void AddFeedWizard::newFolder()
687 {
688 AddFolderDialog *addFolderDialog = new AddFolderDialog(this);
689 QList<QTreeWidgetItem *> treeItems =
690 addFolderDialog->foldersTree_->findItems(foldersTree_->currentItem()->text(1),
691 Qt::MatchFixedString | Qt::MatchRecursive,
692 1);
693 addFolderDialog->foldersTree_->setCurrentItem(treeItems.at(0));
694
695 if (addFolderDialog->exec() == QDialog::Rejected) {
696 delete addFolderDialog;
697 return;
698 }
699
700 int folderId = 0;
701 QString folderText = addFolderDialog->nameFeedEdit_->text();
702 int parentId = addFolderDialog->foldersTree_->currentItem()->text(1).toInt();
703
704 // Calculate row number to insert folder
705 int rowToParent = 0;
706 QSqlQuery q;
707 q.exec(QString("SELECT count(id) FROM feeds WHERE parentId='%1'").arg(parentId));
708 if (q.first())
709 rowToParent = q.value(0).toInt();
710
711 // Add folder
712 q.prepare("INSERT INTO feeds(text, created, parentId, rowToParent) "
713 "VALUES (:text, :feedCreateTime, :parentId, :rowToParent)");
714 q.bindValue(":text", folderText);
715 q.bindValue(":feedCreateTime",
716 QLocale::c().toString(QDateTime::currentDateTimeUtc(), "yyyy-MM-ddTHH:mm:ss"));
717 q.bindValue(":parentId", parentId);
718 q.bindValue(":rowToParent", rowToParent);
719 q.exec();
720
721 folderId = q.lastInsertId().toInt();
722 q.finish();
723
724 treeItems = foldersTree_->findItems(QString::number(parentId),
725 Qt::MatchFixedString | Qt::MatchRecursive,
726 1);
727 QStringList treeItem;
728 treeItem << folderText << QString::number(folderId);
729 QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem(treeItem);
730 treeItems.at(0)->addChild(treeWidgetItem);
731 foldersTree_->setCurrentItem(treeWidgetItem);
732
733 delete addFolderDialog;
734 }
735