comparison demos/browser/history.d @ 74:37caa90ce503

more porting
author mandel
date Fri, 22 May 2009 23:43:58 +0000
parents 7bfd46c330dc
children 0654fc9bac95
comparison
equal deleted inserted replaced
73:7bfd46c330dc 74:37caa90ce503
62 import qt.core.QObject; 62 import qt.core.QObject;
63 import qt.core.QTimer; 63 import qt.core.QTimer;
64 import qt.core.QUrl; 64 import qt.core.QUrl;
65 65
66 import qt.webkit.QWebHistoryInterface; 66 import qt.webkit.QWebHistoryInterface;
67 import qtWebkit.QWebSettings; 67 import qt.webkit.QWebSettings;
68 68
69 import QWebHistoryInterface; 69 import QWebHistoryInterface;
70 70
71 import autosaver 71 import autosaver;
72 import browserapplication; 72 import browserapplication;
73 import modelmenu; 73 import modelmenu;
74 74
75 75
76 static const unsigned int HISTORY_VERSION = 23; 76 static const uint HISTORY_VERSION = 23;
77 77
78 78
79 class HistoryItem 79 class HistoryItem
80 { 80 {
81 public: 81 public:
109 109
110 110
111 class HistoryManager : public QWebHistoryInterface 111 class HistoryManager : public QWebHistoryInterface
112 { 112 {
113 mixin Signal!("historyReset"); 113 mixin Signal!("historyReset");
114 mixin Signal!("entryAdded", HistoryItem item); 114 mixin Signal!("entryAdded", HistoryItem /*item*/);
115 mixin Signal!("entryRemoved", HistoryItem item); 115 mixin Signal!("entryRemoved", HistoryItem /*item*/);
116 mixin Signal!("entryUpdated", int offset); 116 mixin Signal!("entryUpdated", int /*offset*/);
117 117
118 public: 118 public:
119 119
120 this(QObject parent = null) 120 this(QObject parent = null)
121 { 121 {
145 ~this() 145 ~this()
146 { 146 {
147 m_saveTimer.saveIfNeccessary(); 147 m_saveTimer.saveIfNeccessary();
148 } 148 }
149 149
150 bool historyContains(QString &url) 150 bool historyContains(QString url)
151 { 151 {
152 return m_historyFilterModel.historyContains(url); 152 return m_historyFilterModel.historyContains(url);
153 } 153 }
154 154
155 void addHistoryEntry(QString &url) 155 void addHistoryEntry(QString url)
156 { 156 {
157 QUrl cleanUrl(url); 157 QUrl cleanUrl(url);
158 cleanUrl.setPassword(QString()); 158 cleanUrl.setPassword(QString());
159 cleanUrl.setHost(cleanUrl.host().toLower()); 159 cleanUrl.setHost(cleanUrl.host().toLower());
160 auto item = new HistoryItem(cleanUrl.toString(), QDateTime.currentDateTime()); 160 auto item = new HistoryItem(cleanUrl.toString(), QDateTime.currentDateTime());
161 addHistoryItem(item); 161 addHistoryItem(item);
162 } 162 }
163 163
164 void updateHistoryItem(QUrl &url, QString &title) 164 void updateHistoryItem(QUrl url, QString title)
165 { 165 {
166 for (int i = 0; i < m_history.count(); ++i) { 166 for (int i = 0; i < m_history.count(); ++i) {
167 if (url == m_history.at(i).url) { 167 if (url == m_history.at(i).url) {
168 m_history[i].title = title; 168 m_history[i].title = title;
169 m_saveTimer.changeOccurred(); 169 m_saveTimer.changeOccurred();
187 m_historyLimit = limit; 187 m_historyLimit = limit;
188 checkForExpired(); 188 checkForExpired();
189 m_saveTimer.changeOccurred(); 189 m_saveTimer.changeOccurred();
190 } 190 }
191 191
192 QList<HistoryItem> history() 192 HistoryItem[] history()
193 { 193 {
194 return m_history; 194 return m_history;
195 } 195 }
196 196
197 void setHistory(QList<HistoryItem> &history, bool loadedAndSorted = false); 197 void setHistory(HistoryItem[] history, bool loadedAndSorted = false)
198 { 198 {
199 m_history = history; 199 m_history = history;
200 200
201 // verify that it is sorted by date 201 // verify that it is sorted by date
202 if (!loadedAndSorted) 202 if (!loadedAndSorted)
212 } 212 }
213 emit historyReset(); 213 emit historyReset();
214 } 214 }
215 215
216 // History manager keeps around these models for use by the completer and other classes 216 // History manager keeps around these models for use by the completer and other classes
217 HistoryModel historyModel(); 217 HistoryModel historyModel()
218 { 218 {
219 return m_historyModel; 219 return m_historyModel;
220 } 220 }
221 221
222 HistoryFilterModel historyFilterModel() 222 HistoryFilterModel historyFilterModel()
277 if (!QFile.exists(directory)) { 277 if (!QFile.exists(directory)) {
278 QDir dir; 278 QDir dir;
279 dir.mkpath(directory); 279 dir.mkpath(directory);
280 } 280 }
281 281
282 QFile historyFile(directory + QLatin1String("/history")); 282 auto historyFile = new QFile(directory ~ QLatin1String("/history"));
283 // When saving everything use a temporary file to prevent possible data loss. 283 // When saving everything use a temporary file to prevent possible data loss.
284 QTemporaryFile tempFile; 284 auto tempFile = new QTemporaryFile;
285 tempFile.setAutoRemove(false); 285 tempFile.setAutoRemove(false);
286 bool open = false; 286 bool open = false;
287 if (saveAll) { 287 if (saveAll) {
288 open = tempFile.open(); 288 open = tempFile.open();
289 } else { 289 } else {
370 if (!historyFile.open(QFile.ReadOnly)) { 370 if (!historyFile.open(QFile.ReadOnly)) {
371 qWarning() << "Unable to open history file" << historyFile.fileName(); 371 qWarning() << "Unable to open history file" << historyFile.fileName();
372 return; 372 return;
373 } 373 }
374 374
375 QList<HistoryItem> list; 375 HistoryItem[] list;
376 auto in_ = new QDataStream(&historyFile); 376 auto in_ = new QDataStream(&historyFile);
377 // Double check that the history file is sorted as it is read in 377 // Double check that the history file is sorted as it is read in
378 bool needToSort = false; 378 bool needToSort = false;
379 HistoryItem lastInsertedItem; 379 HistoryItem lastInsertedItem;
380 QByteArray data; 380 QByteArray data;
424 } 424 }
425 425
426 AutoSaver m_saveTimer; 426 AutoSaver m_saveTimer;
427 int m_historyLimit; 427 int m_historyLimit;
428 QTimer m_expiredTimer; 428 QTimer m_expiredTimer;
429 QList<HistoryItem> m_history; 429 HistoryItem[] m_history;
430 QString m_lastSavedUrl; 430 QString m_lastSavedUrl;
431 431
432 HistoryModel m_historyModel; 432 HistoryModel m_historyModel;
433 HistoryFilterModel m_historyFilterModel; 433 HistoryFilterModel m_historyFilterModel;
434 HistoryTreeModel m_historyTreeModel; 434 HistoryTreeModel m_historyTreeModel;
488 return QAbstractTableModel.headerData(section, orientation, role); 488 return QAbstractTableModel.headerData(section, orientation, role);
489 } 489 }
490 490
491 QVariant data(QModelIndex index, int role = Qt.DisplayRole) 491 QVariant data(QModelIndex index, int role = Qt.DisplayRole)
492 { 492 {
493 QList<HistoryItem> lst = m_history.history(); 493 HistoryItem[] lst = m_history.history();
494 if (index.row() < 0 || index.row() >= lst.size()) 494 if (index.row() < 0 || index.row() >= lst.size())
495 return QVariant(); 495 return QVariant();
496 496
497 HistoryItem item = lst.at(index.row()); 497 HistoryItem item = lst.at(index.row());
498 switch (role) { 498 switch (role) {
542 { 542 {
543 if (parent.isValid()) 543 if (parent.isValid())
544 return false; 544 return false;
545 int lastRow = row + count - 1; 545 int lastRow = row + count - 1;
546 beginRemoveRows(parent, row, lastRow); 546 beginRemoveRows(parent, row, lastRow);
547 QList<HistoryItem> lst = m_history.history(); 547 HistoryItem[] lst = m_history.history();
548 for (int i = lastRow; i >= row; --i) 548 for (int i = lastRow; i >= row; --i)
549 lst.removeAt(i); 549 lst.removeAt(i);
550 m_history.historyReset.disconnect(&this.historyReset); 550 m_history.historyReset.disconnect(&this.historyReset);
551 m_history.setHistory(lst); 551 m_history.setHistory(lst);
552 m_history.historyReset.connect(&this.historyReset); 552 m_history.historyReset.connect(&this.historyReset);
583 { 583 {
584 load(); 584 load();
585 return m_historyHash.contains(url); 585 return m_historyHash.contains(url);
586 } 586 }
587 587
588 int historyLocation(QString url); 588 int historyLocation(QString url)
589 { 589 {
590 load(); 590 load();
591 if (!m_historyHash.contains(url)) 591 if (!m_historyHash.contains(url))
592 return 0; 592 return 0;
593 return sourceModel().rowCount() - m_historyHash.value(url); 593 return sourceModel().rowCount() - m_historyHash.value(url);
644 sourceModel.rowsInserted.connect(&this.sourceRowsInserted); 644 sourceModel.rowsInserted.connect(&this.sourceRowsInserted);
645 sourceModel.rowsRemoved.connect(&this.sourceRowsRemoved); 645 sourceModel.rowsRemoved.connect(&this.sourceRowsRemoved);
646 } 646 }
647 } 647 }
648 648
649 QVariant headerData(int section, Qt.Orientation orientation, int role = Qt.DisplayRole); 649 QVariant headerData(int section, Qt.Orientation orientation, int role = Qt.DisplayRole)
650 { 650 {
651 return sourceModel().headerData(section, orientation, role); 651 return sourceModel().headerData(section, orientation, role);
652 } 652 }
653 653
654 int rowCount(QModelIndex parent = QModelIndex()) 654 int rowCount(QModelIndex parent = QModelIndex())
657 if (parent.isValid()) 657 if (parent.isValid())
658 return 0; 658 return 0;
659 return m_historyHash.count(); 659 return m_historyHash.count();
660 } 660 }
661 661
662 int columnCount(QModelIndex parent = QModelIndex()); 662 int columnCount(QModelIndex parent = QModelIndex())
663 { 663 {
664 return (parent.isValid()) ? 0 : 2; 664 return (parent.isValid()) ? 0 : 2;
665 } 665 }
666 666
667 QModelIndex index(int, int, QModelIndex = QModelIndex()) 667 QModelIndex index(int, int, QModelIndex = QModelIndex())
680 680
681 /* 681 /*
682 Removing a continuous block of rows will remove filtered rows too as this is 682 Removing a continuous block of rows will remove filtered rows too as this is
683 the users intention. 683 the users intention.
684 */ 684 */
685 bool removeRows(int row, int count, QModelIndex parent = QModelIndex()); 685 bool removeRows(int row, int count, QModelIndex parent = QModelIndex())
686 { 686 {
687 if (row < 0 || count <= 0 || row + count > rowCount(parent) || parent.isValid()) 687 if (row < 0 || count <= 0 || row + count > rowCount(parent) || parent.isValid())
688 return false; 688 return false;
689 int lastRow = row + count - 1; 689 int lastRow = row + count - 1;
690 sourceModel.rowsRemoved,disconnect(&this.sourceRowsRemoved); 690 sourceModel.rowsRemoved,disconnect(&this.sourceRowsRemoved);
700 reset(); 700 reset();
701 return true; 701 return true;
702 } 702 }
703 703
704 704
705 QVariant data(QModelIndex index, int role = Qt.DisplayRole); 705 QVariant data(QModelIndex index, int role = Qt.DisplayRole)
706 { 706 {
707 return QAbstractProxyModel.data(index, role); 707 return QAbstractProxyModel.data(index, role);
708 } 708 }
709 709
710 private: 710 private:
715 reset(); 715 reset();
716 } 716 }
717 717
718 void sourceDataChanged(QModelIndex topLeft, QModelIndex bottomRight) 718 void sourceDataChanged(QModelIndex topLeft, QModelIndex bottomRight)
719 { 719 {
720 emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight)); 720 dataChanged.emit(mapFromSource(topLeft), mapFromSource(bottomRight));
721 } 721 }
722 722
723 void sourceRowsRemoved(QModelIndex , int start, int end) 723 void sourceRowsRemoved(QModelIndex , int start, int end)
724 { 724 {
725 //Q_UNUSED(start); 725 //Q_UNUSED(start);
766 } 766 }
767 } 767 }
768 m_loaded = true; 768 m_loaded = true;
769 } 769 }
770 770
771 771 int[] m_sourceRow;
772 QList<int> m_sourceRow; 772 int[QString] m_historyHash;
773 QHash<QString, int> m_historyHash;
774 bool m_loaded; 773 bool m_loaded;
775 } 774 }
776 775
777 776
778 /* 777 /*
788 public: 787 public:
789 788
790 /* 789 /*
791 Maps the first bunch of items of the source model to the root 790 Maps the first bunch of items of the source model to the root
792 */ 791 */
793 HistoryMenuModel(HistoryTreeModel sourceModel, QObject parent = null) 792 this(HistoryTreeModel sourceModel, QObject parent = null)
794 { 793 {
795 super(parent); 794 super(parent);
796 m_treeModel = sourceModel; 795 m_treeModel = sourceModel;
797 setSourceModel(sourceModel); 796 setSourceModel(sourceModel);
798 } 797 }
800 int columnCount(QModelIndex parent) 799 int columnCount(QModelIndex parent)
801 { 800 {
802 return m_treeModel.columnCount(mapToSource(parent)); 801 return m_treeModel.columnCount(mapToSource(parent));
803 } 802 }
804 803
805 int rowCount(QModelIndex parent = QModelIndex()); 804 int rowCount(QModelIndex parent = QModelIndex())
806 { 805 {
807 if (parent.column() > 0) 806 if (parent.column() > 0)
808 return 0; 807 return 0;
809 808
810 if (!parent.isValid()) { 809 if (!parent.isValid()) {
852 QModelIndex historyIndex = m_treeModel.sourceModel().index(proxyIndex.internalId(), proxyIndex.column()); 851 QModelIndex historyIndex = m_treeModel.sourceModel().index(proxyIndex.internalId(), proxyIndex.column());
853 QModelIndex treeIndex = m_treeModel.mapFromSource(historyIndex); 852 QModelIndex treeIndex = m_treeModel.mapFromSource(historyIndex);
854 return treeIndex; 853 return treeIndex;
855 } 854 }
856 855
857 856 QModelIndex index(int row, int column, QModelIndex parent = QModelIndex())
858 QModelIndex index(int, int, QModelIndex &parent = QModelIndex());
859 { 857 {
860 if (row < 0 || column < 0 || column >= columnCount(parent) || parent.column() > 0) 858 if (row < 0 || column < 0 || column >= columnCount(parent) || parent.column() > 0)
861 return QModelIndex(); 859 return QModelIndex();
862 860
863 if (!parent.isValid()) 861 if (!parent.isValid())
874 if (historyRow == -1) 872 if (historyRow == -1)
875 historyRow = treeIndex.row(); 873 historyRow = treeIndex.row();
876 return createIndex(row, column, historyRow); 874 return createIndex(row, column, historyRow);
877 } 875 }
878 876
879 QModelIndex parent(QModelIndex index = QModelIndex()); 877 QModelIndex parent(QModelIndex index = QModelIndex())
880 { 878 {
881 int offset = index.internalId(); 879 int offset = index.internalId();
882 if (offset == -1 || !index.isValid()) 880 if (offset == -1 || !index.isValid())
883 return QModelIndex(); 881 return QModelIndex();
884 882
908 906
909 907
910 // Menu that is dynamically populated from the history 908 // Menu that is dynamically populated from the history
911 class HistoryMenu : public ModelMenu 909 class HistoryMenu : public ModelMenu
912 { 910 {
913 mixin Signal!("openUrl", QUrl url); 911 mixin Signal!("openUrl", QUrl /*url*/);
914 912
915 public: 913 public:
916 914
917 this(QWidget parent = null) 915 this(QWidget parent = null)
918 { 916 {
920 m_history = 0; 918 m_history = 0;
921 activated.connect(&this.activated); 919 activated.connect(&this.activated);
922 setHoverRole(HistoryModel.UrlStringRole); 920 setHoverRole(HistoryModel.UrlStringRole);
923 } 921 }
924 922
925 void setInitialActions(QList<QAction> actions) 923 void setInitialActions(QAction[] actions)
926 { 924 {
927 m_initialActions = actions; 925 m_initialActions = actions;
928 for (int i = 0; i < m_initialActions.count(); ++i) 926 for (int i = 0; i < m_initialActions.count(); ++i)
929 addAction(m_initialActions.at(i)); 927 addAction(m_initialActions.at(i));
930 } 928 }
964 962
965 private: 963 private:
966 964
967 void activated(QModelIndex index) 965 void activated(QModelIndex index)
968 { 966 {
969 emit openUrl(index.data(HistoryModel.UrlRole).toUrl()); 967 openUrl.emit(index.data(HistoryModel.UrlRole).toUrl());
970 } 968 }
971 969
972 void showHistoryDialog() 970 void showHistoryDialog()
973 { 971 {
974 auto dialog = new HistoryDialog(this); 972 auto dialog = new HistoryDialog(this);
978 976
979 private: 977 private:
980 978
981 HistoryManager m_history; 979 HistoryManager m_history;
982 HistoryMenuModel m_historyMenuModel; 980 HistoryMenuModel m_historyMenuModel;
983 QList<QAction> m_initialActions; 981 QAction[] m_initialActions;
984 } 982 }
985 983
986 984
987 // proxy model for the history model that 985 // proxy model for the history model that
988 // exposes each url http://www.foo.com and it url starting at the host www.foo.com 986 // exposes each url http://www.foo.com and it url starting at the host www.foo.com
1025 { 1023 {
1026 int row = sourceIndex.row() * 2; 1024 int row = sourceIndex.row() * 2;
1027 return index(row, sourceIndex.column()); 1025 return index(row, sourceIndex.column());
1028 } 1026 }
1029 1027
1030
1031 QModelIndex mapToSource(QModelIndex proxyIndex) 1028 QModelIndex mapToSource(QModelIndex proxyIndex)
1032 { 1029 {
1033 if (!sourceModel()) 1030 if (!sourceModel())
1034 return QModelIndex(); 1031 return QModelIndex();
1035 int row = proxyIndex.row() / 2; 1032 int row = proxyIndex.row() / 2;
1041 if (row < 0 || row >= rowCount(parent) || column < 0 || column >= columnCount(parent)) 1038 if (row < 0 || row >= rowCount(parent) || column < 0 || column >= columnCount(parent))
1042 return QModelIndex(); 1039 return QModelIndex();
1043 return createIndex(row, column, 0); 1040 return createIndex(row, column, 0);
1044 } 1041 }
1045 1042
1046 QModelIndex parent(QModelIndex index= QModelIndex()); 1043 QModelIndex parent(QModelIndex index= QModelIndex())
1047 { 1044 {
1048 return QModelIndex(); 1045 return QModelIndex();
1049 } 1046 }
1050 1047
1051 void setSourceModel(QAbstractItemModel sourceModel); 1048 void setSourceModel(QAbstractItemModel sourceModel)
1052 { 1049 {
1053 if (sourceModel()) { 1050 if (sourceModel()) {
1054 sourceModel.modelReset.disconnect(&this.sourceReset); 1051 sourceModel.modelReset.disconnect(&this.sourceReset);
1055 sourceModel.rowsInserted.disconnect(&this.sourceReset); 1052 sourceModel.rowsInserted.disconnect(&this.sourceReset);
1056 sourceModel.rowsRemoved.disconnect(&this.sourceReset); 1053 sourceModel.rowsRemoved.disconnect(&this.sourceReset);
1087 { 1084 {
1088 super(parent); 1085 super(parent);
1089 setSourceModel(sourceModel); 1086 setSourceModel(sourceModel);
1090 } 1087 }
1091 1088
1092 QVariant data(QModelIndex index, int role = Qt.DisplayRole); 1089 QVariant data(QModelIndex index, int role = Qt.DisplayRole)
1093 { 1090 {
1094 if ((role == Qt.EditRole || role == Qt.DisplayRole)) { 1091 if ((role == Qt.EditRole || role == Qt.DisplayRole)) {
1095 int start = index.internalId(); 1092 int start = index.internalId();
1096 if (start == 0) { 1093 if (start == 0) {
1097 int offset = sourceDateRow(index.row()); 1094 int offset = sourceDateRow(index.row());
1116 } 1113 }
1117 1114
1118 return QAbstractProxyModel.data(index, role); 1115 return QAbstractProxyModel.data(index, role);
1119 } 1116 }
1120 1117
1121 1118 int columnCount(QModelIndex parent)
1122 int columnCount(QModelIndex parent);
1123 { 1119 {
1124 return sourceModel().columnCount(mapToSource(parent)); 1120 return sourceModel().columnCount(mapToSource(parent));
1125 } 1121 }
1126 1122
1127 int rowCount(QModelIndex parent = QModelIndex()) 1123 int rowCount(QModelIndex parent = QModelIndex())
1153 int start = sourceDateRow(parent.row()); 1149 int start = sourceDateRow(parent.row());
1154 int end = sourceDateRow(parent.row() + 1); 1150 int end = sourceDateRow(parent.row() + 1);
1155 return (end - start); 1151 return (end - start);
1156 } 1152 }
1157 1153
1158 1154 QModelIndex mapFromSource(QModelIndex sourceIndex)
1159 QModelIndex mapFromSource(QModelIndex sourceIndex);
1160 { 1155 {
1161 if (!sourceIndex.isValid()) 1156 if (!sourceIndex.isValid())
1162 return QModelIndex(); 1157 return QModelIndex();
1163 1158
1164 if (m_sourceRowCache.isEmpty()) 1159 if (m_sourceRowCache.isEmpty())
1165 rowCount(QModelIndex()); 1160 rowCount(QModelIndex());
1166 1161
1167 QList<int>.iterator it; 1162 int[].iterator it;
1168 it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), sourceIndex.row()); 1163 it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), sourceIndex.row());
1169 if (*it != sourceIndex.row()) 1164 if (*it != sourceIndex.row())
1170 --it; 1165 --it;
1171 int dateRow = qMax(0, it - m_sourceRowCache.begin()); 1166 int dateRow = qMax(0, it - m_sourceRowCache.begin());
1172 int row = sourceIndex.row() - m_sourceRowCache.at(dateRow); 1167 int row = sourceIndex.row() - m_sourceRowCache.at(dateRow);
1173 return createIndex(row, sourceIndex.column(), dateRow + 1); 1168 return createIndex(row, sourceIndex.column(), dateRow + 1);
1174 } 1169 }
1175 1170
1176
1177 QModelIndex mapToSource(QModelIndex proxyIndex) 1171 QModelIndex mapToSource(QModelIndex proxyIndex)
1178 { 1172 {
1179 int offset = proxyIndex.internalId(); 1173 int offset = proxyIndex.internalId();
1180 if (offset == 0) 1174 if (offset == 0)
1181 return QModelIndex(); 1175 return QModelIndex();
1182 int startDateRow = sourceDateRow(offset - 1); 1176 int startDateRow = sourceDateRow(offset - 1);
1183 return sourceModel().index(startDateRow + proxyIndex.row(), proxyIndex.column()); 1177 return sourceModel().index(startDateRow + proxyIndex.row(), proxyIndex.column());
1184 } 1178 }
1185 1179
1186
1187 QModelIndex index(int row, int column, QModelIndex parent = QModelIndex()) 1180 QModelIndex index(int row, int column, QModelIndex parent = QModelIndex())
1188 { 1181 {
1189 if (row < 0 || column < 0 || column >= columnCount(parent) || parent.column() > 0) 1182 if (row < 0 || column < 0 || column >= columnCount(parent) || parent.column() > 0)
1190 return QModelIndex(); 1183 return QModelIndex();
1191 1184
1192 if (!parent.isValid()) 1185 if (!parent.isValid())
1193 return createIndex(row, column, 0); 1186 return createIndex(row, column, 0);
1194 return createIndex(row, column, parent.row() + 1); 1187 return createIndex(row, column, parent.row() + 1);
1195 } 1188 }
1196
1197 1189
1198 QModelIndex parent(QModelIndex index = QModelIndex()) 1190 QModelIndex parent(QModelIndex index = QModelIndex())
1199 { 1191 {
1200 int offset = index.internalId(); 1192 int offset = index.internalId();
1201 if (offset == 0 || !index.isValid()) 1193 if (offset == 0 || !index.isValid())
1202 return QModelIndex(); 1194 return QModelIndex();
1203 return createIndex(offset - 1, 0, 0); 1195 return createIndex(offset - 1, 0, 0);
1204 } 1196 }
1205 1197
1206
1207 bool hasChildren(QModelIndex parent = QModelIndex()) 1198 bool hasChildren(QModelIndex parent = QModelIndex())
1208 { 1199 {
1209 QModelIndex grandparent = parent.parent(); 1200 QModelIndex grandparent = parent.parent();
1210 if (!grandparent.isValid()) 1201 if (!grandparent.isValid())
1211 return true; 1202 return true;
1212 return false; 1203 return false;
1213 } 1204 }
1214 1205
1215
1216 Qt.ItemFlags flags(QModelIndex index) 1206 Qt.ItemFlags flags(QModelIndex index)
1217 { 1207 {
1218 if (!index.isValid()) 1208 if (!index.isValid())
1219 return Qt.NoItemFlags; 1209 return Qt.NoItemFlags;
1220 return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled; 1210 return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled;
1221 } 1211 }
1222 1212
1223 bool removeRows(int row, int count, QModelIndex parent = QModelIndex()); 1213 bool removeRows(int row, int count, QModelIndex parent = QModelIndex())
1224 { 1214 {
1225 if (row < 0 || count <= 0 || row + count > rowCount(parent)) 1215 if (row < 0 || count <= 0 || row + count > rowCount(parent))
1226 return false; 1216 return false;
1227 1217
1228 if (parent.isValid()) { 1218 if (parent.isValid()) {
1273 { 1263 {
1274 m_sourceRowCache.clear(); 1264 m_sourceRowCache.clear();
1275 reset(); 1265 reset();
1276 } 1266 }
1277 1267
1278 void sourceRowsInserted(QModelIndex parent, int start, int end); 1268 void sourceRowsInserted(QModelIndex parent, int start, int end)
1279 { 1269 {
1280 //Q_UNUSED(parent); // Avoid warnings when compiling release 1270 //Q_UNUSED(parent); // Avoid warnings when compiling release
1281 assert(!parent.isValid()); 1271 assert(!parent.isValid());
1282 if (start != 0 || start != end) { 1272 if (start != 0 || start != end) {
1283 m_sourceRowCache.clear(); 1273 m_sourceRowCache.clear();
1302 //Q_UNUSED(parent); // Avoid warnings when compiling release 1292 //Q_UNUSED(parent); // Avoid warnings when compiling release
1303 assert(!parent.isValid()); 1293 assert(!parent.isValid());
1304 if (m_sourceRowCache.isEmpty()) 1294 if (m_sourceRowCache.isEmpty())
1305 return; 1295 return;
1306 for (int i = end; i >= start;) { 1296 for (int i = end; i >= start;) {
1307 QList<int>::iterator it; 1297 int[]::iterator it;
1308 it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), i); 1298 it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), i);
1309 // playing it safe 1299 // playing it safe
1310 if (it == m_sourceRowCache.end()) { 1300 if (it == m_sourceRowCache.end()) {
1311 m_sourceRowCache.clear(); 1301 m_sourceRowCache.clear();
1312 reset(); 1302 reset();
1352 return sourceModel().rowCount(); 1342 return sourceModel().rowCount();
1353 } 1343 }
1354 return m_sourceRowCache.at(row); 1344 return m_sourceRowCache.at(row);
1355 } 1345 }
1356 1346
1357 QList<int> m_sourceRowCache; 1347 int[] m_sourceRowCache;
1358 } 1348 }
1359 1349
1360 1350
1361 // A modified QSortFilterProxyModel that always accepts the root nodes in the tree 1351 // A modified QSortFilterProxyModel that always accepts the root nodes in the tree
1362 // so filtering is only done on the children. 1352 // so filtering is only done on the children.
1384 1374
1385 import ui_history; 1375 import ui_history;
1386 1376
1387 class HistoryDialog : public QDialog, public Ui_HistoryDialog 1377 class HistoryDialog : public QDialog, public Ui_HistoryDialog
1388 { 1378 {
1389 mixin Signal!("openUrl", QUrl url); 1379 mixin Signal!("openUrl", QUrl /*url*/);
1390 1380
1391 public: 1381 public:
1392 1382
1393 this(QWidget parent = null, HistoryManager history = null) : QDialog(parent) 1383 this(QWidget parent = null, HistoryManager history = null)
1384 //: QDialog(parent)
1394 { 1385 {
1395 HistoryManager history = setHistory; 1386 HistoryManager history = setHistory;
1396 if (!history) 1387 if (!history)
1397 history = BrowserApplication.historyManager(); 1388 history = BrowserApplication.historyManager();
1398 setupUi(this); 1389 setupUi(this);