Mercurial > projects > qtd
view demos/browser/cookiejar.d @ 288:f9559a957be9 signals
new signals and slots implementation
author | eldar |
---|---|
date | Sun, 08 Nov 2009 19:28:01 +0000 |
parents | a8d76a9a85aa |
children |
line wrap: on
line source
/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ module cookiejar; import qt.network.QNetworkCookieJar; //import qt.core.QDebug; import qt.core.QAbstractItemModel; import qt.core.QDateTime; import qt.core.QDir; import qt.core.QFile; //import qt.core.QMetaEnum; import qt.core.QSettings; import qt.core.QUrl; import qt.gui.QDialog; import qt.gui.QTableView; import qt.gui.QCompleter; import qt.gui.QDesktopServices; import qt.gui.QFont; import qt.gui.QFontMetrics; import qt.gui.QHeaderView; import qt.gui.QKeyEvent; import qt.gui.QSortFilterProxyModel; import qt.gui.QAbstractTableModel; import qt.webkit.QWebSettings; import cookiejar; import autosaver; static const uint JAR_VERSION = 23; QDataStream opShl(QDataStream stream, QNetworkCookie[] list) { stream << JAR_VERSION; stream << cast(uint) list.length; for (int i = 0; i < list.length; ++i) stream << list[i].toRawForm(); return stream; } QDataStream opShr(QDataStream stream, ref QNetworkCookie[] list) { list.clear(); uint version_; stream >> version_; if (version_ != JAR_VERSION) return stream; uint count; stream >> count; for(uint i = 0; i < count; ++i) { auto value = new QByteArray; stream >> value; QNetworkCookie[] newCookies = QNetworkCookie.parseCookies(value); if (newCookies.length == 0 && value.length() != 0) { qWarning("CookieJar: Unable to parse saved cookie:" ~ cast(string) value.data()); } for (int j = 0; j < newCookies.length; ++j) list ~= newCookies[j]; if (stream.atEnd()) break; } return stream; } class CookieJar : public QNetworkCookieJar { mixin Signal!("cookiesChanged"); public: enum AcceptPolicy { AcceptAlways, AcceptNever, AcceptOnlyFromSitesNavigatedTo } enum KeepPolicy { KeepUntilExpire, KeepUntilExit, KeepUntilTimeLimit } this(QObject parent = null) { super(parent); m_loaded = false; m_saveTimer = new AutoSaver(this); m_acceptCookies = AcceptOnlyFromSitesNavigatedTo; } ~this() { if (m_keepCookies == KeepUntilExit) clear(); m_saveTimer.saveIfNeccessary(); } QNetworkCookie[] cookiesForUrl(QUrl url) { CookieJar that = cast(CookieJar) this; if (!m_loaded) that.load(); QWebSettings globalSettings = QWebSettings.globalSettings(); if (globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled)) { QNetworkCookie[] noCookies; return noCookies; } return QNetworkCookieJar.cookiesForUrl(url); } bool setCookiesFromUrl(QNetworkCookie[] cookieList, QUrl url) { if (!m_loaded) load(); QWebSettings globalSettings = QWebSettings.globalSettings(); if (globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled)) return false; string host = url.host(); bool eBlock = qBinaryFind(m_exceptions_block.begin(), m_exceptions_block.end(), host) != m_exceptions_block.end(); bool eAllow = qBinaryFind(m_exceptions_allow.begin(), m_exceptions_allow.end(), host) != m_exceptions_allow.end(); bool eAllowSession = qBinaryFind(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end(), host) != m_exceptions_allowForSession.end(); bool addedCookies = false; // pass exceptions bool acceptInitially = (m_acceptCookies != AcceptNever); if ((acceptInitially && !eBlock) || (!acceptInitially && (eAllow || eAllowSession))) { // pass url domain == cookie domain QDateTime soon = QDateTime.currentDateTime(); soon = soon.addDays(90); foreach(QNetworkCookie cookie; cookieList) { QNetworkCookie[] lst; if (m_keepCookies == KeepUntilTimeLimit && !cookie.isSessionCookie() && cookie.expirationDate() > soon) { cookie.setExpirationDate(soon); } lst += cookie; if (QNetworkCookieJar.setCookiesFromUrl(lst, url)) { addedCookies = true; } else { // finally force it in if wanted if (m_acceptCookies == AcceptAlways) { QNetworkCookie[] cookies = allCookies(); cookies += cookie; setAllCookies(cookies); addedCookies = true; } /* else qWarning() << "setCookiesFromUrl failed" << url << cookieList.value(0).toRawForm(); */ } } } if (addedCookies) { m_saveTimer.changeOccurred(); cookiesChanged.emit(); } return addedCookies; } AcceptPolicy acceptPolicy() { if (!m_loaded) (cast(CookieJar) this).load(); return m_acceptCookies; } void setAcceptPolicy(AcceptPolicy policy) { if (!m_loaded) load(); if (policy == m_acceptCookies) return; m_acceptCookies = policy; m_saveTimer.changeOccurred(); } KeepPolicy keepPolicy() { if (!m_loaded) (cast(CookieJar) this).load(); return m_keepCookies; } void setKeepPolicy(KeepPolicy policy) { if (!m_loaded) load(); if (policy == m_keepCookies) return; m_keepCookies = policy; m_saveTimer.changeOccurred(); } string[] blockedCookies() { if (!m_loaded) (cast(CookieJar) this).load(); return m_exceptions_block; } string[] allowedCookies() { if (!m_loaded) (cast(CookieJar) this).load(); return m_exceptions_allow; } string[] allowForSessionCookies() { if (!m_loaded) (cast(CookieJar) this).load(); return m_exceptions_allowForSession; } void setBlockedCookies(string[] list) { if (!m_loaded) load(); m_exceptions_block = list; qSort(m_exceptions_block.begin(), m_exceptions_block.end()); m_saveTimer.changeOccurred(); } void setAllowedCookies(string[] list) { if (!m_loaded) load(); m_exceptions_allow = list; qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); m_saveTimer.changeOccurred(); } void setAllowForSessionCookies(string[] list) { if (!m_loaded) load(); m_exceptions_allowForSession = list; qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); m_saveTimer.changeOccurred(); } public: void clear() { setAllCookies(QNetworkCookie[]()); m_saveTimer.changeOccurred(); cookiesChanged.emit(); } void loadSettings() { QSettings settings; settings.beginGroup("cookies"); QByteArray value = settings.value("acceptCookies", "AcceptOnlyFromSitesNavigatedTo").toByteArray(); QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); m_acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ? AcceptOnlyFromSitesNavigatedTo : cast(AcceptPolicy) acceptPolicyEnum.keyToValue(value); value = settings.value("keepCookiesUntil", "KeepUntilExpire").toByteArray(); QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); m_keepCookies = keepPolicyEnum.keyToValue(value) == -1 ? KeepUntilExpire : cast(KeepPolicy) keepPolicyEnum.keyToValue(value); if (m_keepCookies == KeepUntilExit) setAllCookies(null); m_loaded = true; cookiesChanged.emit(); } private: void save() { if (!m_loaded) return; purgeOldCookies(); string directory = QDesktopServices.storageLocation(QDesktopServices.DataLocation); if (directory.isEmpty()) directory = QDir.homePath() ~ "/." ~ QCoreApplication.applicationName(); if (!QFile.exists(directory)) { QDir dir; dir.mkpath(directory); } auto cookieSettings = new QSettings(directory ~ "/cookies.ini", QSettings.IniFormat); QNetworkCookie[] cookies = allCookies(); for (int i = cookies.length - 1; i >= 0; --i) { if (cookies[i].isSessionCookie()) cookies.removeAt(i); } //cookieSettings.setValue("cookies", qVariantFromValue<QNetworkCookie[] >(cookies)); //TODO! cookieSettings.beginGroup("Exceptions"); cookieSettings.setValue("block", m_exceptions_block); cookieSettings.setValue("allow", m_exceptions_allow); cookieSettings.setValue("allowForSession", m_exceptions_allowForSession); // save cookie settings auto settings = new QSettings; settings.beginGroup("cookies"); QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); settings.setValue("acceptCookies", acceptPolicyEnum.valueToKey(m_acceptCookies)); QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); settings.setValue("keepCookiesUntil", keepPolicyEnum.valueToKey(m_keepCookies)); } private: void purgeOldCookies() { QNetworkCookie[] cookies = allCookies(); if (cookies.isEmpty()) return; int oldCount = cookies.count(); QDateTime now = QDateTime.currentDateTime(); for (int i = cookies.length - 1; i >= 0; --i) { if (!cookies[i].isSessionCookie() && cookies[i].expirationDate() < now) cookies.removeAt(i); } if (oldCount == cookies.length) return; setAllCookies(cookies); cookiesChanged.emit(); } void load() { if (m_loaded) return; // load cookies and exceptions qRegisterMetaTypeStreamOperators!(QNetworkCookie[])("QNetworkCookie[]"); auto cookieSettings = new QSettings(QDesktopServices.storageLocation(QDesktopServices.DataLocation) ~ "/cookies.ini", QSettings.IniFormat); setAllCookies(cast(QNetworkCookie[]) (cookieSettings.value("cookies"))); cookieSettings.beginGroup("Exceptions"); m_exceptions_block = cookieSettings.value("block").toStringList(); m_exceptions_allow = cookieSettings.value("allow").toStringList(); m_exceptions_allowForSession = cookieSettings.value("allowForSession").toStringList(); qSort(m_exceptions_block.begin(), m_exceptions_block.end()); qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); loadSettings(); } bool m_loaded; AutoSaver m_saveTimer; AcceptPolicy m_acceptCookies; KeepPolicy m_keepCookies; string[] m_exceptions_block; string[] m_exceptions_allow; string[] m_exceptions_allowForSession; } class CookieModel : public QAbstractTableModel { public: this(CookieJar jar, QObject parent = null) { super(parent); m_cookieJar = cookieJar; m_cookieJar.cookiesChanged.connect(&this.cookiesChanged); m_cookieJar.load(); } QVariant headerData(int section, Qt.Orientation orientation, int role) { if (role == Qt.SizeHintRole) { auto font = new QFont; font.setPointSize(10); auto fm = new QFontMetrics(font); int height = fm.height() + fm.height()/3; int width = fm.width(headerData(section, orientation, Qt.DisplayRole).toString()); return QSize(width, height); } if (orientation == Qt.Horizontal) { if (role != Qt.DisplayRole) return QVariant(); switch (section) { case 0: return tr("Website"); case 1: return tr("Name"); case 2: return tr("Path"); case 3: return tr("Secure"); case 4: return tr("Expires"); case 5: return tr("Contents"); default: return new QVariant(); } } return QAbstractTableModel.headerData(section, orientation, role); } QVariant data(QModelIndex index, int role = Qt.DisplayRole) { QNetworkCookie[] lst; if (m_cookieJar) lst = m_cookieJar.allCookies(); if (index.row() < 0 || index.row() >= lst.length) return new QVariant(); switch (role) { case Qt.DisplayRole: case Qt.EditRole: { QNetworkCookie cookie = lst[index.row]; switch (index.column()) { case 0: return cookie.domain(); case 1: return cookie.name(); case 2: return cookie.path(); case 3: return cookie.isSecure(); case 4: return cookie.expirationDate(); case 5: return cookie.value(); } } case Qt.FontRole:{ auto font = new QFont; font.setPointSize(10); return font; } } return QVariant(); } int columnCount(QModelIndex parent = QModelIndex()) { return (parent.isValid()) ? 0 : 6; } int rowCount(QModelIndex parent = QModelIndex()) { return (parent.isValid() || !m_cookieJar) ? 0 : m_cookieJar.allCookies().count(); } bool removeRows(int row, int count, QModelIndex parent = QModelIndex()) { if (parent.isValid() || !m_cookieJar) return false; int lastRow = row + count - 1; beginRemoveRows(parent, row, lastRow); QNetworkCookie[] lst = m_cookieJar.allCookies(); for (int i = lastRow; i >= row; --i) { lst.removeAt(i); } m_cookieJar.setAllCookies(lst); endRemoveRows(); return true; } private: void cookiesChanged() { reset(); } private: CookieJar m_cookieJar; } import ui_cookiesdialog; import ui_cookiesexceptionsdialog; class CookiesDialog : public QDialog //, public Ui_CookiesDialog { mixin Ui_CookiesDialog; public: this(CookieJar cookieJar, QWidget parent = null) { super(parent); setupUi(this); setWindowFlags(Qt.Sheet); CookieModel model = new CookieModel(cookieJar, this); m_proxyModel = new QSortFilterProxyModel(this); search.textChanged.connect(&m_proxyModel.setFilterFixedString); removeButton.clicked.connect(&cookiesTable.removeOne); removeAllButton.clicked.connect(&cookiesTable.removeAll); m_proxyModel.setSourceModel(model); cookiesTable.verticalHeader().hide(); cookiesTable.setSelectionBehavior(QAbstractItemView.SelectRows); cookiesTable.setModel(m_proxyModel); cookiesTable.setAlternatingRowColors(true); cookiesTable.setTextElideMode(Qt.ElideMiddle); cookiesTable.setShowGrid(false); cookiesTable.setSortingEnabled(true); QFont f = font(); f.setPointSize(10); QFontMetrics fm(f); int height = fm.height() + fm.height()/3; cookiesTable.verticalHeader().setDefaultSectionSize(height); cookiesTable.verticalHeader().setMinimumSectionSize(-1); for (int i = 0; i < model.columnCount(); ++i){ int header = cookiesTable.horizontalHeader().sectionSizeHint(i); switch (i) { case 0: header = fm.width("averagehost.domain.com"); break; case 1: header = fm.width("_session_id"); break; case 4: header = fm.width(QDateTime.currentDateTime().toString(Qt.LocalDate)); break; } int buffer = fm.width("xx"); header += buffer; cookiesTable.horizontalHeader().resizeSection(i, header); } cookiesTable.horizontalHeader().setStretchLastSection(true); } private: QSortFilterProxyModel m_proxyModel; } class CookieExceptionsModel : public QAbstractTableModel { public: this(CookieJar cookieJar, QObject parent = null) { super(parent); m_cookieJar = cookiejar; m_allowedCookies = m_cookieJar.allowedCookies(); m_blockedCookies = m_cookieJar.blockedCookies(); m_sessionCookies = m_cookieJar.allowForSessionCookies(); } QVariant headerData(int section, Qt.Orientation orientation, int role) { if (role == Qt.SizeHintRole) { auto font = new QFont; font.setPointSize(10); auto fm =new QFontMetrics(font); int height = fm.height() + fm.height()/3; int width = fm.width(headerData(section, orientation, Qt.DisplayRole).toString()); return QSize(width, height); } if (orientation == Qt.Horizontal && role == Qt.DisplayRole) { switch (section) { case 0: return tr("Website"); case 1: return tr("Status"); } } return QAbstractTableModel.headerData(section, orientation, role); } QVariant data(QModelIndex index, int role = Qt.DisplayRole) { if (index.row() < 0 || index.row() >= rowCount()) return QVariant(); switch (role) { case Qt.DisplayRole: case Qt.EditRole: { int row = index.row(); if (row < m_allowedCookies.length) { switch (index.column()) { case 0: return m_allowedCookies[row]; case 1: return tr("Allow"); } } row = row - m_allowedCookies.length; if (row < m_blockedCookies.length) { switch (index.column()) { case 0: return m_blockedCookies[row]; case 1: return tr("Block"); } } row = row - m_blockedCookies.length; if (row < m_sessionCookies.length) { switch (index.column()) { case 0: return m_sessionCookies[row]; case 1: return tr("Allow For Session"); } } } case Qt.FontRole:{ auto font = new QFont; font.setPointSize(10); return font; } } return QVariant(); } int columnCount(QModelIndex parent = QModelIndex()) { return (parent.isValid()) ? 0 : 2; } int rowCount(QModelIndex parent = QModelIndex()) { return (parent.isValid() || !m_cookieJar) ? 0 : m_allowedCookies.length + m_blockedCookies.length + m_sessionCookies.length; } bool removeRows(int row, int count, QModelIndex parent) { if (parent.isValid() || !m_cookieJar) return false; int lastRow = row + count - 1; beginRemoveRows(parent, row, lastRow); for (int i = lastRow; i >= row; --i) { if (i < m_allowedCookies.length) { m_allowedCookies.removeAt(row); continue; } i = i - m_allowedCookies.length; if (i < m_blockedCookies.length) { m_blockedCookies.removeAt(row); continue; } i = i - m_blockedCookies.length; if (i < m_sessionCookies.length) { m_sessionCookies.removeAt(row); continue; } } m_cookieJar.setAllowedCookies(m_allowedCookies); m_cookieJar.setBlockedCookies(m_blockedCookies); m_cookieJar.setAllowForSessionCookies(m_sessionCookies); endRemoveRows(); return true; } private: CookieJar m_cookieJar; // Domains we allow, Domains we block, Domains we allow for this session string[] m_allowedCookies; string[] m_blockedCookies; string[] m_sessionCookies; } class CookiesExceptionsDialog : public QDialog //, public Ui_CookiesExceptionsDialog { mixin Ui_CookiesExceptionsDialog; public: this(CookieJar cookieJar, QWidget parent = null) { super(parent); m_cookieJar = cookieJar; setupUi(this); setWindowFlags(Qt.Sheet); removeButton.clicked.connect(&exceptionTable.removeOne); removeAllButton.clicked.connect(&exceptionTable.removeAll); exceptionTable.verticalHeader().hide(); exceptionTable.setSelectionBehavior(QAbstractItemView.SelectRows); exceptionTable.setAlternatingRowColors(true); exceptionTable.setTextElideMode(Qt.ElideMiddle); exceptionTable.setShowGrid(false); exceptionTable.setSortingEnabled(true); m_exceptionsModel = new CookieExceptionsModel(cookieJar, this); m_proxyModel = new QSortFilterProxyModel(this); m_proxyModel.setSourceModel(m_exceptionsModel); search.textChanged.connect(&m_proxyModel.setFilterFixedString); exceptionTable.setModel(m_proxyModel); CookieModel cookieModel = new CookieModel(cookieJar, this); domainLineEdit.setCompleter(new QCompleter(cookieModel, domainLineEdit)); domainLineEdit.textChanged.connect(&this.textChanged); blockButton.clicked.connect(&this.block); allowButton.clicked.connect(&this.allow); allowForSessionButton.clicked.connect(&this.allowForSession); QFont f = font(); f.setPointSize(10); auto fm = new QFontMetrics(f); int height = fm.height() + fm.height()/3; exceptionTable.verticalHeader().setDefaultSectionSize(height); exceptionTable.verticalHeader().setMinimumSectionSize(-1); for (int i = 0; i < m_exceptionsModel.columnCount(); ++i) { int header = exceptionTable.horizontalHeader().sectionSizeHint(i); switch (i) { case 0: header = fm.width("averagebiglonghost.domain.com"); break; case 1: header = fm.width("Allow For Session"); break; } int buffer = fm.width("xx"); header += buffer; exceptionTable.horizontalHeader().resizeSection(i, header); } } private: void block() { if (domainLineEdit.text().isEmpty()) return; m_exceptionsModel.m_blockedCookies ~= domainLineEdit.text(); m_cookieJar.setBlockedCookies(m_exceptionsModel.m_blockedCookies); m_exceptionsModel.reset(); } void allow() { if (domainLineEdit.text().isEmpty()) return; m_exceptionsModel.m_allowedCookies ~= domainLineEdit.text(); m_cookieJar.setAllowedCookies(m_exceptionsModel.m_allowedCookies); m_exceptionsModel.reset(); } void allowForSession() { if (domainLineEdit.text().isEmpty()) return; m_exceptionsModel.m_sessionCookie ~= domainLineEdit.text(); m_cookieJar.setAllowForSessionCookies(m_exceptionsModel.m_sessionCookies); m_exceptionsModel.reset(); } void textChanged(string text) { bool enabled = !text.isEmpty(); blockButton.setEnabled(enabled); allowButton.setEnabled(enabled); allowForSessionButton.setEnabled(enabled); } private: CookieExceptionsModel m_exceptionsModel; QSortFilterProxyModel m_proxyModel; CookieJar m_cookieJar; }