comparison demos/browser/cookiejar.d @ 45:71b382c10ef6

add coarse and incomplete QT browser port
author mandel
date Sun, 17 May 2009 18:49:59 +0000
parents
children b5d10b2218da
comparison
equal deleted inserted replaced
44:3cb15c92ac28 45:71b382c10ef6
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Qt Software Information (qt-info@nokia.com)
5 **
6 ** This file is part of the demonstration applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial Usage
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Nokia.
14 **
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22 **
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** If you are unsure which license is appropriate for your use, please
37 ** contact the sales department at qt-sales@nokia.com.
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 module cookiejar;
42
43 import QtNetwork.QNetworkCookieJar;
44
45 import QtCore.QAbstractItemModel;
46 import QtCore.QStringList;
47
48 import QtGui.QDialog;
49 import QtGui.QTableView;
50
51
52 #include "cookiejar.h"
53
54 #include "autosaver.h"
55
56 import QtCore.QDateTime;
57 import QtCore.QDir;
58 import QtCore.QFile;
59 import QtCore.QMetaEnum;
60 import QtCore.QSettings;
61 import QtCore.QUrl;
62
63 import QtGui.QCompleter;
64 import QtGui.QDesktopServices;
65 import QtGui.QFont;
66 import QtGui.QFontMetrics;
67 import QtGui.QHeaderView;
68 import QtGui.QKeyEvent;
69 import QtGui.QSortFilterProxyModel;
70
71 import QtWebKit.QWebSettings;
72
73 import QtCore.QDebug;
74
75 /*
76 QT_BEGIN_NAMESPACE
77 class QSortFilterProxyModel;
78 class QKeyEvent;
79 QT_END_NAMESPACE
80
81 class AutoSaver;
82 */
83
84 static const unsigned int JAR_VERSION = 23;
85
86 QDataStream &operator<<(QDataStream &stream, const QList<QNetworkCookie> &list)
87 {
88 stream << JAR_VERSION;
89 stream << quint32(list.size());
90 for (int i = 0; i < list.size(); ++i)
91 stream << list.at(i).toRawForm();
92 return stream;
93 }
94
95 QDataStream &operator>>(QDataStream &stream, QList<QNetworkCookie> &list)
96 {
97 list.clear();
98
99 quint32 version;
100 stream >> version;
101
102 if (version != JAR_VERSION)
103 return stream;
104
105 quint32 count;
106 stream >> count;
107 for(quint32 i = 0; i < count; ++i)
108 {
109 QByteArray value;
110 stream >> value;
111 QList<QNetworkCookie> newCookies = QNetworkCookie::parseCookies(value);
112 if (newCookies.count() == 0 && value.length() != 0) {
113 qWarning() << "CookieJar: Unable to parse saved cookie:" << value;
114 }
115 for (int j = 0; j < newCookies.count(); ++j)
116 list.append(newCookies.at(j));
117 if (stream.atEnd())
118 break;
119 }
120 return stream;
121 }
122
123
124 class CookieJar : public QNetworkCookieJar
125 {
126 friend class CookieModel;
127 Q_OBJECT
128 Q_PROPERTY(AcceptPolicy acceptPolicy READ acceptPolicy WRITE setAcceptPolicy)
129 Q_PROPERTY(KeepPolicy keepPolicy READ keepPolicy WRITE setKeepPolicy)
130 Q_PROPERTY(QStringList blockedCookies READ blockedCookies WRITE setBlockedCookies)
131 Q_PROPERTY(QStringList allowedCookies READ allowedCookies WRITE setAllowedCookies)
132 Q_PROPERTY(QStringList allowForSessionCookies READ allowForSessionCookies WRITE setAllowForSessionCookies)
133 Q_ENUMS(KeepPolicy)
134 Q_ENUMS(AcceptPolicy)
135
136 signals:
137 void cookiesChanged();
138
139 public:
140 enum AcceptPolicy {
141 AcceptAlways,
142 AcceptNever,
143 AcceptOnlyFromSitesNavigatedTo
144 };
145
146 enum KeepPolicy {
147 KeepUntilExpire,
148 KeepUntilExit,
149 KeepUntilTimeLimit
150 };
151
152 this(QObject *parent = null)
153 {
154 super(parent);
155 m_loaded = false;
156 m_saveTimer = new AutoSaver(this);
157 m_acceptCookies = AcceptOnlyFromSitesNavigatedTo;
158 }
159
160 ~this()
161 {
162 if (m_keepCookies == KeepUntilExit)
163 clear();
164 m_saveTimer.saveIfNeccessary();
165 }
166
167 QList<QNetworkCookie> cookiesForUrl(const QUrl &url)
168 {
169 CookieJar *that = const_cast<CookieJar*>(this);
170 if (!m_loaded)
171 that.load();
172
173 QWebSettings *globalSettings = QWebSettings::globalSettings();
174 if (globalSettings.testAttribute(QWebSettings::PrivateBrowsingEnabled)) {
175 QList<QNetworkCookie> noCookies;
176 return noCookies;
177 }
178
179 return QNetworkCookieJar::cookiesForUrl(url);
180 }
181
182
183 bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
184 {
185 if (!m_loaded)
186 load();
187
188 QWebSettings *globalSettings = QWebSettings::globalSettings();
189 if (globalSettings.testAttribute(QWebSettings::PrivateBrowsingEnabled))
190 return false;
191
192 QString host = url.host();
193 bool eBlock = qBinaryFind(m_exceptions_block.begin(), m_exceptions_block.end(), host) != m_exceptions_block.end();
194 bool eAllow = qBinaryFind(m_exceptions_allow.begin(), m_exceptions_allow.end(), host) != m_exceptions_allow.end();
195 bool eAllowSession = qBinaryFind(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end(), host) != m_exceptions_allowForSession.end();
196
197 bool addedCookies = false;
198 // pass exceptions
199 bool acceptInitially = (m_acceptCookies != AcceptNever);
200 if ((acceptInitially && !eBlock)
201 || (!acceptInitially && (eAllow || eAllowSession))) {
202 // pass url domain == cookie domain
203 QDateTime soon = QDateTime::currentDateTime();
204 soon = soon.addDays(90);
205 foreach(QNetworkCookie cookie, cookieList) {
206 QList<QNetworkCookie> lst;
207 if (m_keepCookies == KeepUntilTimeLimit
208 && !cookie.isSessionCookie()
209 && cookie.expirationDate() > soon) {
210 cookie.setExpirationDate(soon);
211 }
212 lst += cookie;
213 if (QNetworkCookieJar::setCookiesFromUrl(lst, url)) {
214 addedCookies = true;
215 } else {
216 // finally force it in if wanted
217 if (m_acceptCookies == AcceptAlways) {
218 QList<QNetworkCookie> cookies = allCookies();
219 cookies += cookie;
220 setAllCookies(cookies);
221 addedCookies = true;
222 }
223 #if 0
224 else
225 qWarning() << "setCookiesFromUrl failed" << url << cookieList.value(0).toRawForm();
226 #endif
227 }
228 }
229 }
230
231 if (addedCookies) {
232 m_saveTimer.changeOccurred();
233 emit cookiesChanged();
234 }
235 return addedCookies;
236 }
237
238 AcceptPolicy acceptPolicy()
239 {
240 if (!m_loaded)
241 (const_cast<CookieJar*>(this)).load();
242 return m_acceptCookies;
243 }
244
245 void setAcceptPolicy(AcceptPolicy policy)
246 {
247 if (!m_loaded)
248 load();
249 if (policy == m_acceptCookies)
250 return;
251 m_acceptCookies = policy;
252 m_saveTimer.changeOccurred();
253 }
254
255 KeepPolicy keepPolicy()
256 {
257 if (!m_loaded)
258 (const_cast<CookieJar*>(this)).load();
259 return m_keepCookies;
260 }
261
262 void setKeepPolicy(KeepPolicy policy)
263 {
264 if (!m_loaded)
265 load();
266 if (policy == m_keepCookies)
267 return;
268 m_keepCookies = policy;
269 m_saveTimer.changeOccurred();
270 }
271
272
273 QStringList blockedCookies()
274 {
275 if (!m_loaded)
276 (const_cast<CookieJar*>(this)).load();
277 return m_exceptions_block;
278 }
279
280 QStringList allowedCookies()
281 {
282 if (!m_loaded)
283 (const_cast<CookieJar*>(this)).load();
284 return m_exceptions_allow;
285 }
286
287 QStringList allowForSessionCookies()
288 {
289 if (!m_loaded)
290 (const_cast<CookieJar*>(this)).load();
291 return m_exceptions_allowForSession;
292 }
293
294 void setBlockedCookies(const QStringList &list)
295 {
296 if (!m_loaded)
297 load();
298 m_exceptions_block = list;
299 qSort(m_exceptions_block.begin(), m_exceptions_block.end());
300 m_saveTimer.changeOccurred();
301 }
302
303 void setAllowedCookies(const QStringList &list)
304 {
305 if (!m_loaded)
306 load();
307 m_exceptions_allow = list;
308 qSort(m_exceptions_allow.begin(), m_exceptions_allow.end());
309 m_saveTimer.changeOccurred();
310 }
311
312 void setAllowForSessionCookies(const QStringList &list)
313 {
314 if (!m_loaded)
315 load();
316 m_exceptions_allowForSession = list;
317 qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end());
318 m_saveTimer.changeOccurred();
319 }
320
321 public slots:
322
323 void clear()
324 {
325 setAllCookies(QList<QNetworkCookie>());
326 m_saveTimer.changeOccurred();
327 emit cookiesChanged();
328 }
329
330 void loadSettings()
331 {
332 QSettings settings;
333 settings.beginGroup(QLatin1String("cookies"));
334 QByteArray value = settings.value(QLatin1String("acceptCookies"),
335 QLatin1String("AcceptOnlyFromSitesNavigatedTo")).toByteArray();
336 QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy"));
337 m_acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ?
338 AcceptOnlyFromSitesNavigatedTo :
339 static_cast<AcceptPolicy>(acceptPolicyEnum.keyToValue(value));
340
341 value = settings.value(QLatin1String("keepCookiesUntil"), QLatin1String("KeepUntilExpire")).toByteArray();
342 QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy"));
343 m_keepCookies = keepPolicyEnum.keyToValue(value) == -1 ?
344 KeepUntilExpire :
345 static_cast<KeepPolicy>(keepPolicyEnum.keyToValue(value));
346
347 if (m_keepCookies == KeepUntilExit)
348 setAllCookies(QList<QNetworkCookie>());
349
350 m_loaded = true;
351 emit cookiesChanged();
352 }
353
354 private slots:
355 void save()
356 {
357 if (!m_loaded)
358 return;
359 purgeOldCookies();
360 QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
361 if (directory.isEmpty())
362 directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName();
363 if (!QFile::exists(directory)) {
364 QDir dir;
365 dir.mkpath(directory);
366 }
367 QSettings cookieSettings(directory + QLatin1String("/cookies.ini"), QSettings::IniFormat);
368 QList<QNetworkCookie> cookies = allCookies();
369 for (int i = cookies.count() - 1; i >= 0; --i) {
370 if (cookies.at(i).isSessionCookie())
371 cookies.removeAt(i);
372 }
373 cookieSettings.setValue(QLatin1String("cookies"), qVariantFromValue<QList<QNetworkCookie> >(cookies));
374 cookieSettings.beginGroup(QLatin1String("Exceptions"));
375 cookieSettings.setValue(QLatin1String("block"), m_exceptions_block);
376 cookieSettings.setValue(QLatin1String("allow"), m_exceptions_allow);
377 cookieSettings.setValue(QLatin1String("allowForSession"), m_exceptions_allowForSession);
378
379 // save cookie settings
380 QSettings settings;
381 settings.beginGroup(QLatin1String("cookies"));
382 QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy"));
383 settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(m_acceptCookies)));
384
385 QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy"));
386 settings.setValue(QLatin1String("keepCookiesUntil"), QLatin1String(keepPolicyEnum.valueToKey(m_keepCookies)));
387 }
388
389 private:
390 void purgeOldCookies()
391 {
392 QList<QNetworkCookie> cookies = allCookies();
393 if (cookies.isEmpty())
394 return;
395 int oldCount = cookies.count();
396 QDateTime now = QDateTime::currentDateTime();
397 for (int i = cookies.count() - 1; i >= 0; --i) {
398 if (!cookies.at(i).isSessionCookie() && cookies.at(i).expirationDate() < now)
399 cookies.removeAt(i);
400 }
401 if (oldCount == cookies.count())
402 return;
403 setAllCookies(cookies);
404 emit cookiesChanged();
405 }
406
407 void load()
408 {
409 if (m_loaded)
410 return;
411 // load cookies and exceptions
412 qRegisterMetaTypeStreamOperators<QList<QNetworkCookie> >("QList<QNetworkCookie>");
413 QSettings cookieSettings(QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QLatin1String("/cookies.ini"), QSettings::IniFormat);
414 setAllCookies(qvariant_cast<QList<QNetworkCookie> >(cookieSettings.value(QLatin1String("cookies"))));
415 cookieSettings.beginGroup(QLatin1String("Exceptions"));
416 m_exceptions_block = cookieSettings.value(QLatin1String("block")).toStringList();
417 m_exceptions_allow = cookieSettings.value(QLatin1String("allow")).toStringList();
418 m_exceptions_allowForSession = cookieSettings.value(QLatin1String("allowForSession")).toStringList();
419 qSort(m_exceptions_block.begin(), m_exceptions_block.end());
420 qSort(m_exceptions_allow.begin(), m_exceptions_allow.end());
421 qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end());
422
423 loadSettings();
424 }
425
426 bool m_loaded;
427 AutoSaver *m_saveTimer;
428
429 AcceptPolicy m_acceptCookies;
430 KeepPolicy m_keepCookies;
431
432 QStringList m_exceptions_block;
433 QStringList m_exceptions_allow;
434 QStringList m_exceptions_allowForSession;
435 }
436
437 class CookieModel : public QAbstractTableModel
438 {
439 Q_OBJECT
440
441 public:
442 this(CookieJar *jar, QObject *parent = null )
443 {
444 super(parent);
445 m_cookieJar = cookieJar;
446 connect(m_cookieJar, SIGNAL(cookiesChanged()), this, SLOT(cookiesChanged()));
447 m_cookieJar.load();
448 }
449
450 QVariant headerData(int section, Qt.Orientation orientation, int role)
451 {
452 if (role == Qt.SizeHintRole) {
453 QFont font;
454 font.setPointSize(10);
455 QFontMetrics fm(font);
456 int height = fm.height() + fm.height()/3;
457 int width = fm.width(headerData(section, orientation, Qt.DisplayRole).toString());
458 return QSize(width, height);
459 }
460
461 if (orientation == Qt.Horizontal) {
462 if (role != Qt.DisplayRole)
463 return QVariant();
464
465 switch (section) {
466 case 0:
467 return tr("Website");
468 case 1:
469 return tr("Name");
470 case 2:
471 return tr("Path");
472 case 3:
473 return tr("Secure");
474 case 4:
475 return tr("Expires");
476 case 5:
477 return tr("Contents");
478 default:
479 return QVariant();
480 }
481 }
482 return QAbstractTableModel.headerData(section, orientation, role);
483 }
484
485
486 QVariant data(const QModelIndex &index, int role = Qt.DisplayRole)
487 {
488 QList<QNetworkCookie> lst;
489 if (m_cookieJar)
490 lst = m_cookieJar.allCookies();
491 if (index.row() < 0 || index.row() >= lst.size())
492 return QVariant();
493
494 switch (role) {
495 case Qt.DisplayRole:
496 case Qt.EditRole: {
497 QNetworkCookie cookie = lst.at(index.row());
498 switch (index.column()) {
499 case 0:
500 return cookie.domain();
501 case 1:
502 return cookie.name();
503 case 2:
504 return cookie.path();
505 case 3:
506 return cookie.isSecure();
507 case 4:
508 return cookie.expirationDate();
509 case 5:
510 return cookie.value();
511 }
512 }
513 case Qt.FontRole:{
514 QFont font;
515 font.setPointSize(10);
516 return font;
517 }
518 }
519
520 return QVariant();
521 }
522
523 int columnCount(const QModelIndex &parent = QModelIndex())
524 {
525 return (parent.isValid()) ? 0 : 6;
526 }
527
528
529 int rowCount(const QModelIndex &parent = QModelIndex())
530 {
531 return (parent.isValid() || !m_cookieJar) ? 0 : m_cookieJar.allCookies().count();
532 }
533
534
535 bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex())
536 {
537 if (parent.isValid() || !m_cookieJar)
538 return false;
539 int lastRow = row + count - 1;
540 beginRemoveRows(parent, row, lastRow);
541 QList<QNetworkCookie> lst = m_cookieJar.allCookies();
542 for (int i = lastRow; i >= row; --i) {
543 lst.removeAt(i);
544 }
545 m_cookieJar.setAllCookies(lst);
546 endRemoveRows();
547 return true;
548 }
549
550 private slots:
551
552 void cookiesChanged()
553 {
554 reset();
555 }
556
557 private:
558 CookieJar *m_cookieJar;
559 }
560
561 #include "ui_cookies.h"
562 #include "ui_cookiesexceptions.h"
563
564 class CookiesDialog : public QDialog, public Ui_CookiesDialog
565 {
566 Q_OBJECT
567
568 public:
569
570 this(CookieJar *cookieJar, QWidget *parent = this) : QDialog(parent)
571 {
572 setupUi(this);
573 setWindowFlags(Qt.Sheet);
574 CookieModel *model = new CookieModel(cookieJar, this);
575 m_proxyModel = new QSortFilterProxyModel(this);
576 connect(search, SIGNAL(textChanged(QString)),
577 m_proxyModel, SLOT(setFilterFixedString(QString)));
578 connect(removeButton, SIGNAL(clicked()), cookiesTable, SLOT(removeOne()));
579 connect(removeAllButton, SIGNAL(clicked()), cookiesTable, SLOT(removeAll()));
580 m_proxyModel.setSourceModel(model);
581 cookiesTable.verticalHeader().hide();
582 cookiesTable.setSelectionBehavior(QAbstractItemView::SelectRows);
583 cookiesTable.setModel(m_proxyModel);
584 cookiesTable.setAlternatingRowColors(true);
585 cookiesTable.setTextElideMode(Qt.ElideMiddle);
586 cookiesTable.setShowGrid(false);
587 cookiesTable.setSortingEnabled(true);
588 QFont f = font();
589 f.setPointSize(10);
590 QFontMetrics fm(f);
591 int height = fm.height() + fm.height()/3;
592 cookiesTable.verticalHeader().setDefaultSectionSize(height);
593 cookiesTable.verticalHeader().setMinimumSectionSize(-1);
594 for (int i = 0; i < model.columnCount(); ++i){
595 int header = cookiesTable.horizontalHeader().sectionSizeHint(i);
596 switch (i) {
597 case 0:
598 header = fm.width(QLatin1String("averagehost.domain.com"));
599 break;
600 case 1:
601 header = fm.width(QLatin1String("_session_id"));
602 break;
603 case 4:
604 header = fm.width(QDateTime::currentDateTime().toString(Qt.LocalDate));
605 break;
606 }
607 int buffer = fm.width(QLatin1String("xx"));
608 header += buffer;
609 cookiesTable.horizontalHeader().resizeSection(i, header);
610 }
611 cookiesTable.horizontalHeader().setStretchLastSection(true);
612 }
613
614 private:
615
616 QSortFilterProxyModel *m_proxyModel;
617 }
618
619 class CookieExceptionsModel : public QAbstractTableModel
620 {
621 Q_OBJECT
622 friend class CookiesExceptionsDialog;
623
624 public:
625 zhis(CookieJar *cookieJar, QObject *parent = null)
626 {
627 super(parent);
628 m_cookieJar = cookiejar;
629 m_allowedCookies = m_cookieJar.allowedCookies();
630 m_blockedCookies = m_cookieJar.blockedCookies();
631 m_sessionCookies = m_cookieJar.allowForSessionCookies();
632 }
633
634 QVariant headerData(int section, Qt.Orientation orientation, int role)
635 {
636 if (role == Qt.SizeHintRole) {
637 QFont font;
638 font.setPointSize(10);
639 QFontMetrics fm(font);
640 int height = fm.height() + fm.height()/3;
641 int width = fm.width(headerData(section, orientation, Qt.DisplayRole).toString());
642 return QSize(width, height);
643 }
644
645 if (orientation == Qt.Horizontal && role == Qt.DisplayRole) {
646 switch (section) {
647 case 0:
648 return tr("Website");
649 case 1:
650 return tr("Status");
651 }
652 }
653 return QAbstractTableModel::headerData(section, orientation, role);
654 }
655
656
657
658 QVariant data(const QModelIndex &index, int role = Qt.DisplayRole)
659 {
660 if (index.row() < 0 || index.row() >= rowCount())
661 return QVariant();
662
663 switch (role) {
664 case Qt.DisplayRole:
665 case Qt.EditRole: {
666 int row = index.row();
667 if (row < m_allowedCookies.count()) {
668 switch (index.column()) {
669 case 0:
670 return m_allowedCookies.at(row);
671 case 1:
672 return tr("Allow");
673 }
674 }
675 row = row - m_allowedCookies.count();
676 if (row < m_blockedCookies.count()) {
677 switch (index.column()) {
678 case 0:
679 return m_blockedCookies.at(row);
680 case 1:
681 return tr("Block");
682 }
683 }
684 row = row - m_blockedCookies.count();
685 if (row < m_sessionCookies.count()) {
686 switch (index.column()) {
687 case 0:
688 return m_sessionCookies.at(row);
689 case 1:
690 return tr("Allow For Session");
691 }
692 }
693 }
694 case Qt.FontRole:{
695 QFont font;
696 font.setPointSize(10);
697 return font;
698 }
699 }
700 return QVariant();
701 }
702
703 int columnCount(const QModelIndex &parent = QModelIndex());
704 {
705 return (parent.isValid()) ? 0 : 2;
706 }
707
708 int rowCount(const QModelIndex &parent = QModelIndex())
709 {
710 return (parent.isValid() || !m_cookieJar) ? 0 : m_allowedCookies.count() + m_blockedCookies.count() + m_sessionCookies.count();
711 }
712
713 bool removeRows(int row, int count, const QModelIndex &parent)
714 {
715 if (parent.isValid() || !m_cookieJar)
716 return false;
717
718 int lastRow = row + count - 1;
719 beginRemoveRows(parent, row, lastRow);
720 for (int i = lastRow; i >= row; --i) {
721 if (i < m_allowedCookies.count()) {
722 m_allowedCookies.removeAt(row);
723 continue;
724 }
725 i = i - m_allowedCookies.count();
726 if (i < m_blockedCookies.count()) {
727 m_blockedCookies.removeAt(row);
728 continue;
729 }
730 i = i - m_blockedCookies.count();
731 if (i < m_sessionCookies.count()) {
732 m_sessionCookies.removeAt(row);
733 continue;
734 }
735 }
736
737 m_cookieJar.setAllowedCookies(m_allowedCookies);
738 m_cookieJar.setBlockedCookies(m_blockedCookies);
739 m_cookieJar.setAllowForSessionCookies(m_sessionCookies);
740 endRemoveRows();
741 return true;
742 }
743 private:
744 CookieJar *m_cookieJar;
745
746 // Domains we allow, Domains we block, Domains we allow for this session
747 QStringList m_allowedCookies;
748 QStringList m_blockedCookies;
749 QStringList m_sessionCookies;
750 }
751
752 class CookiesExceptionsDialog : public QDialog, public Ui_CookiesExceptionsDialog
753 {
754 Q_OBJECT
755
756 public:
757 this(CookieJar *cookieJar, QWidget *parent = null)
758 : QDialog(parent)
759 {
760 m_cookieJar = cookieJar;
761 setupUi(this);
762 setWindowFlags(Qt.Sheet);
763 connect(removeButton, SIGNAL(clicked()), exceptionTable, SLOT(removeOne()));
764 connect(removeAllButton, SIGNAL(clicked()), exceptionTable, SLOT(removeAll()));
765 exceptionTable.verticalHeader().hide();
766 exceptionTable.setSelectionBehavior(QAbstractItemView::SelectRows);
767 exceptionTable.setAlternatingRowColors(true);
768 exceptionTable.setTextElideMode(Qt.ElideMiddle);
769 exceptionTable.setShowGrid(false);
770 exceptionTable.setSortingEnabled(true);
771 m_exceptionsModel = new CookieExceptionsModel(cookieJar, this);
772 m_proxyModel = new QSortFilterProxyModel(this);
773 m_proxyModel.setSourceModel(m_exceptionsModel);
774 connect(search, SIGNAL(textChanged(QString)),
775 m_proxyModel, SLOT(setFilterFixedString(QString)));
776 exceptionTable.setModel(m_proxyModel);
777
778 CookieModel *cookieModel = new CookieModel(cookieJar, this);
779 domainLineEdit.setCompleter(new QCompleter(cookieModel, domainLineEdit));
780
781 connect(domainLineEdit, SIGNAL(textChanged(const QString &)),
782 this, SLOT(textChanged(const QString &)));
783 connect(blockButton, SIGNAL(clicked()), this, SLOT(block()));
784 connect(allowButton, SIGNAL(clicked()), this, SLOT(allow()));
785 connect(allowForSessionButton, SIGNAL(clicked()), this, SLOT(allowForSession()));
786
787 QFont f = font();
788 f.setPointSize(10);
789 QFontMetrics fm(f);
790 int height = fm.height() + fm.height()/3;
791 exceptionTable.verticalHeader().setDefaultSectionSize(height);
792 exceptionTable.verticalHeader().setMinimumSectionSize(-1);
793 for (int i = 0; i < m_exceptionsModel.columnCount(); ++i){
794 int header = exceptionTable.horizontalHeader().sectionSizeHint(i);
795 switch (i) {
796 case 0:
797 header = fm.width(QLatin1String("averagebiglonghost.domain.com"));
798 break;
799 case 1:
800 header = fm.width(QLatin1String("Allow For Session"));
801 break;
802 }
803 int buffer = fm.width(QLatin1String("xx"));
804 header += buffer;
805 exceptionTable.horizontalHeader().resizeSection(i, header);
806 }
807 }
808
809 private slots:
810 void block()
811 {
812 if (domainLineEdit.text().isEmpty())
813 return;
814 m_exceptionsModel.m_blockedCookies.append(domainLineEdit.text());
815 m_cookieJar.setBlockedCookies(m_exceptionsModel.m_blockedCookies);
816 m_exceptionsModel.reset();
817 }
818
819 void allow()
820 {
821 if (domainLineEdit.text().isEmpty())
822 return;
823 m_exceptionsModel.m_allowedCookies.append(domainLineEdit.text());
824 m_cookieJar.setAllowedCookies(m_exceptionsModel.m_allowedCookies);
825 m_exceptionsModel.reset();
826 }
827 void allowForSession()
828 {
829 if (domainLineEdit.text().isEmpty())
830 return;
831 m_exceptionsModel.m_sessionCookies.append(domainLineEdit.text());
832 m_cookieJar.setAllowForSessionCookies(m_exceptionsModel.m_sessionCookies);
833 m_exceptionsModel.reset();
834 }
835
836 void textChanged(const QString &text)
837 {
838 bool enabled = !text.isEmpty();
839 blockButton.setEnabled(enabled);
840 allowButton.setEnabled(enabled);
841 allowForSessionButton.setEnabled(enabled);
842 }
843
844 private:
845
846 CookieExceptionsModel *m_exceptionsModel;
847 QSortFilterProxyModel *m_proxyModel;
848 CookieJar *m_cookieJar;
849 }