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