demos/browser/history.h
changeset 0 1918ee327afb
child 4 3b1da2848fc7
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 #ifndef HISTORY_H
       
    43 #define HISTORY_H
       
    44 
       
    45 #include "modelmenu.h"
       
    46 
       
    47 #include <QtCore/QDateTime>
       
    48 #include <QtCore/QHash>
       
    49 #include <QtCore/QObject>
       
    50 #include <QtCore/QTimer>
       
    51 #include <QtCore/QUrl>
       
    52 
       
    53 #include <QtGui/QSortFilterProxyModel>
       
    54 
       
    55 #include <QWebHistoryInterface>
       
    56 
       
    57 class HistoryItem
       
    58 {
       
    59 public:
       
    60     HistoryItem() {}
       
    61     HistoryItem(const QString &u,
       
    62                 const QDateTime &d = QDateTime(), const QString &t = QString())
       
    63         : title(t), url(u), dateTime(d) {}
       
    64 
       
    65     inline bool operator==(const HistoryItem &other) const
       
    66         { return other.title == title
       
    67           && other.url == url && other.dateTime == dateTime; }
       
    68 
       
    69     // history is sorted in reverse
       
    70     inline bool operator <(const HistoryItem &other) const
       
    71         { return dateTime > other.dateTime; }
       
    72 
       
    73     QString title;
       
    74     QString url;
       
    75     QDateTime dateTime;
       
    76 };
       
    77 
       
    78 class AutoSaver;
       
    79 class HistoryModel;
       
    80 class HistoryFilterModel;
       
    81 class HistoryTreeModel;
       
    82 class HistoryManager : public QWebHistoryInterface
       
    83 {
       
    84     Q_OBJECT
       
    85     Q_PROPERTY(int historyLimit READ historyLimit WRITE setHistoryLimit)
       
    86 
       
    87 signals:
       
    88     void historyReset();
       
    89     void entryAdded(const HistoryItem &item);
       
    90     void entryRemoved(const HistoryItem &item);
       
    91     void entryUpdated(int offset);
       
    92 
       
    93 public:
       
    94     HistoryManager(QObject *parent = 0);
       
    95     ~HistoryManager();
       
    96 
       
    97     bool historyContains(const QString &url) const;
       
    98     void addHistoryEntry(const QString &url);
       
    99 
       
   100     void updateHistoryItem(const QUrl &url, const QString &title);
       
   101 
       
   102     int historyLimit() const;
       
   103     void setHistoryLimit(int limit);
       
   104 
       
   105     QList<HistoryItem> history() const;
       
   106     void setHistory(const QList<HistoryItem> &history, bool loadedAndSorted = false);
       
   107 
       
   108     // History manager keeps around these models for use by the completer and other classes
       
   109     HistoryModel *historyModel() const;
       
   110     HistoryFilterModel *historyFilterModel() const;
       
   111     HistoryTreeModel *historyTreeModel() const;
       
   112 
       
   113 public slots:
       
   114     void clear();
       
   115     void loadSettings();
       
   116 
       
   117 private slots:
       
   118     void save();
       
   119     void checkForExpired();
       
   120 
       
   121 protected:
       
   122     void addHistoryItem(const HistoryItem &item);
       
   123 
       
   124 private:
       
   125     void load();
       
   126 
       
   127     AutoSaver *m_saveTimer;
       
   128     int m_historyLimit;
       
   129     QTimer m_expiredTimer;
       
   130     QList<HistoryItem> m_history;
       
   131     QString m_lastSavedUrl;
       
   132 
       
   133     HistoryModel *m_historyModel;
       
   134     HistoryFilterModel *m_historyFilterModel;
       
   135     HistoryTreeModel *m_historyTreeModel;
       
   136 };
       
   137 
       
   138 class HistoryModel : public QAbstractTableModel
       
   139 {
       
   140     Q_OBJECT
       
   141 
       
   142 public slots:
       
   143     void historyReset();
       
   144     void entryAdded();
       
   145     void entryUpdated(int offset);
       
   146 
       
   147 public:
       
   148     enum Roles {
       
   149         DateRole = Qt::UserRole + 1,
       
   150         DateTimeRole = Qt::UserRole + 2,
       
   151         UrlRole = Qt::UserRole + 3,
       
   152         UrlStringRole = Qt::UserRole + 4
       
   153     };
       
   154 
       
   155     HistoryModel(HistoryManager *history, QObject *parent = 0);
       
   156     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
       
   157     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
       
   158     int columnCount(const QModelIndex &parent = QModelIndex()) const;
       
   159     int rowCount(const QModelIndex &parent = QModelIndex()) const;
       
   160     bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
       
   161 
       
   162 private:
       
   163     HistoryManager *m_history;
       
   164 };
       
   165 
       
   166 /*!
       
   167     Proxy model that will remove any duplicate entries.
       
   168     Both m_sourceRow and m_historyHash store their offsets not from
       
   169     the front of the list, but as offsets from the back.
       
   170   */
       
   171 class HistoryFilterModel : public QAbstractProxyModel
       
   172 {
       
   173     Q_OBJECT
       
   174 
       
   175 public:
       
   176     HistoryFilterModel(QAbstractItemModel *sourceModel, QObject *parent = 0);
       
   177 
       
   178     inline bool historyContains(const QString &url) const
       
   179         { load(); return m_historyHash.contains(url); }
       
   180     int historyLocation(const QString &url) const;
       
   181 
       
   182     QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
       
   183     QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
       
   184     void setSourceModel(QAbstractItemModel *sourceModel);
       
   185     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
       
   186     int rowCount(const QModelIndex &parent = QModelIndex()) const;
       
   187     int columnCount(const QModelIndex &parent = QModelIndex()) const;
       
   188     QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const;
       
   189     QModelIndex parent(const QModelIndex& index= QModelIndex()) const;
       
   190     bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
       
   191     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
       
   192 
       
   193 private slots:
       
   194     void sourceReset();
       
   195     void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
       
   196     void sourceRowsInserted(const QModelIndex &parent, int start, int end);
       
   197     void sourceRowsRemoved(const QModelIndex &, int, int);
       
   198 
       
   199 private:
       
   200     void load() const;
       
   201 
       
   202     mutable QList<int> m_sourceRow;
       
   203     mutable QHash<QString, int> m_historyHash;
       
   204     mutable bool m_loaded;
       
   205 };
       
   206 
       
   207 /*
       
   208     The history menu
       
   209     - Removes the first twenty entries and puts them as children of the top level.
       
   210     - If there are less then twenty entries then the first folder is also removed.
       
   211 
       
   212     The mapping is done by knowing that HistoryTreeModel is over a table
       
   213     We store that row offset in our index's private data.
       
   214 */
       
   215 class HistoryMenuModel : public QAbstractProxyModel
       
   216 {
       
   217     Q_OBJECT
       
   218 
       
   219 public:
       
   220     HistoryMenuModel(HistoryTreeModel *sourceModel, QObject *parent = 0);
       
   221     int columnCount(const QModelIndex &parent) const;
       
   222     int rowCount(const QModelIndex &parent = QModelIndex()) const;
       
   223     QModelIndex mapFromSource(const QModelIndex & sourceIndex) const;
       
   224     QModelIndex mapToSource(const QModelIndex & proxyIndex) const;
       
   225     QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const;
       
   226     QModelIndex parent(const QModelIndex &index = QModelIndex()) const;
       
   227 
       
   228     int bumpedRows() const;
       
   229 
       
   230 private:
       
   231     HistoryTreeModel *m_treeModel;
       
   232 };
       
   233 
       
   234 // Menu that is dynamically populated from the history
       
   235 class HistoryMenu : public ModelMenu
       
   236 {
       
   237     Q_OBJECT
       
   238 
       
   239 signals:
       
   240     void openUrl(const QUrl &url);
       
   241 
       
   242 public:
       
   243      HistoryMenu(QWidget *parent = 0);
       
   244      void setInitialActions(QList<QAction*> actions);
       
   245 
       
   246 protected:
       
   247     bool prePopulated();
       
   248     void postPopulated();
       
   249 
       
   250 private slots:
       
   251     void activated(const QModelIndex &index);
       
   252     void showHistoryDialog();
       
   253 
       
   254 private:
       
   255     HistoryManager *m_history;
       
   256     HistoryMenuModel *m_historyMenuModel;
       
   257     QList<QAction*> m_initialActions;
       
   258 };
       
   259 
       
   260 // proxy model for the history model that
       
   261 // exposes each url http://www.foo.com and it url starting at the host www.foo.com
       
   262 class HistoryCompletionModel : public QAbstractProxyModel
       
   263 {
       
   264     Q_OBJECT
       
   265 
       
   266 public:
       
   267     HistoryCompletionModel(QObject *parent = 0);
       
   268     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
       
   269     int rowCount(const QModelIndex &parent = QModelIndex()) const;
       
   270     int columnCount(const QModelIndex &parent = QModelIndex()) const;
       
   271     QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
       
   272     QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
       
   273     QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const;
       
   274     QModelIndex parent(const QModelIndex& index= QModelIndex()) const;
       
   275     void setSourceModel(QAbstractItemModel *sourceModel);
       
   276 
       
   277 private slots:
       
   278     void sourceReset();
       
   279 
       
   280 };
       
   281 
       
   282 // proxy model for the history model that converts the list
       
   283 // into a tree, one top level node per day.
       
   284 // Used in the HistoryDialog.
       
   285 class HistoryTreeModel : public QAbstractProxyModel
       
   286 {
       
   287     Q_OBJECT
       
   288 
       
   289 public:
       
   290     HistoryTreeModel(QAbstractItemModel *sourceModel, QObject *parent = 0);
       
   291     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
       
   292     int columnCount(const QModelIndex &parent) const;
       
   293     int rowCount(const QModelIndex &parent = QModelIndex()) const;
       
   294     QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
       
   295     QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
       
   296     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
       
   297     QModelIndex parent(const QModelIndex &index= QModelIndex()) const;
       
   298     bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
       
   299     Qt::ItemFlags flags(const QModelIndex &index) const;
       
   300     bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
       
   301     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
       
   302 
       
   303     void setSourceModel(QAbstractItemModel *sourceModel);
       
   304 
       
   305 private slots:
       
   306     void sourceReset();
       
   307     void sourceRowsInserted(const QModelIndex &parent, int start, int end);
       
   308     void sourceRowsRemoved(const QModelIndex &parent, int start, int end);
       
   309 
       
   310 private:
       
   311     int sourceDateRow(int row) const;
       
   312     mutable QList<int> m_sourceRowCache;
       
   313 
       
   314 };
       
   315 
       
   316 // A modified QSortFilterProxyModel that always accepts the root nodes in the tree
       
   317 // so filtering is only done on the children.
       
   318 // Used in the HistoryDialog
       
   319 class TreeProxyModel : public QSortFilterProxyModel
       
   320 {
       
   321     Q_OBJECT
       
   322 
       
   323 public:
       
   324     TreeProxyModel(QObject *parent = 0);
       
   325 
       
   326 protected:
       
   327     bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
       
   328 };
       
   329 
       
   330 #include "ui_history.h"
       
   331 
       
   332 class HistoryDialog : public QDialog, public Ui_HistoryDialog
       
   333 {
       
   334     Q_OBJECT
       
   335 
       
   336 signals:
       
   337     void openUrl(const QUrl &url);
       
   338 
       
   339 public:
       
   340     HistoryDialog(QWidget *parent = 0, HistoryManager *history = 0);
       
   341 
       
   342 private slots:
       
   343     void customContextMenuRequested(const QPoint &pos);
       
   344     void open();
       
   345     void copy();
       
   346 
       
   347 };
       
   348 
       
   349 #endif // HISTORY_H
       
   350