Mercurial > projects > qtd
comparison demos/browser/history.d @ 77:0654fc9bac95
more porting
author | mandel |
---|---|
date | Sun, 24 May 2009 13:46:32 +0000 |
parents | 37caa90ce503 |
children | 85c59c4e5f19 |
comparison
equal
deleted
inserted
replaced
76:454e4b4beb59 | 77:0654fc9bac95 |
---|---|
80 { | 80 { |
81 public: | 81 public: |
82 | 82 |
83 this() {} | 83 this() {} |
84 | 84 |
85 this(QString u, QDateTime d = QDateTime(), QString t = QString()) | 85 this(string u, QDateTime d = QDateTime(), string t = null) |
86 { | 86 { |
87 title = t; | 87 title = t; |
88 url = u; | 88 url = u; |
89 dateTime = d; | 89 dateTime = d; |
90 } | 90 } |
100 int opCmp(HistoryItem other) | 100 int opCmp(HistoryItem other) |
101 { | 101 { |
102 return cast(int) (dateTime > other.dateTime); | 102 return cast(int) (dateTime > other.dateTime); |
103 } | 103 } |
104 | 104 |
105 QString title; | 105 string title; |
106 QString url; | 106 string url; |
107 QDateTime dateTime; | 107 QDateTime dateTime; |
108 } | 108 } |
109 | 109 |
110 | 110 |
111 class HistoryManager : public QWebHistoryInterface | 111 class HistoryManager : public QWebHistoryInterface |
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(string 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(string url) |
156 { | 156 { |
157 QUrl cleanUrl(url); | 157 QUrl cleanUrl(url); |
158 cleanUrl.setPassword(QString()); | 158 cleanUrl.setPassword(null); |
159 cleanUrl.setHost(cleanUrl.host().toLower()); | 159 cleanUrl.setHost(toLower(cleanUrl.host())); |
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, string title) |
165 { | 165 { |
166 for (int i = 0; i < m_history.count(); ++i) { | 166 for (int i = 0; i < m_history.length; ++i) { |
167 if (url == m_history.at(i).url) { | 167 if (url == m_history[i].url) { |
168 m_history[i].title = title; | 168 m_history[i].title = title; |
169 m_saveTimer.changeOccurred(); | 169 m_saveTimer.changeOccurred(); |
170 if (m_lastSavedUrl.isEmpty()) | 170 if (m_lastSavedUrl.isEmpty()) |
171 m_lastSavedUrl = m_history.at(i).url; | 171 m_lastSavedUrl = m_history[i].url; |
172 emit entryUpdated(i); | 172 entryUpdated.emit(i); |
173 break; | 173 break; |
174 } | 174 } |
175 } | 175 } |
176 } | 176 } |
177 | 177 |
205 checkForExpired(); | 205 checkForExpired(); |
206 | 206 |
207 if (loadedAndSorted) { | 207 if (loadedAndSorted) { |
208 m_lastSavedUrl = m_history.value(0).url; | 208 m_lastSavedUrl = m_history.value(0).url; |
209 } else { | 209 } else { |
210 m_lastSavedUrl = QString(); | 210 m_lastSavedUrl = null; |
211 m_saveTimer.changeOccurred(); | 211 m_saveTimer.changeOccurred(); |
212 } | 212 } |
213 emit historyReset(); | 213 historyReset.emit(); |
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 { |
231 | 231 |
232 public: | 232 public: |
233 | 233 |
234 void clear() | 234 void clear() |
235 { | 235 { |
236 m_history.clear(); | 236 m_history = null; |
237 m_lastSavedUrl = QString(); | 237 m_lastSavedUrl = null; |
238 m_saveTimer.changeOccurred(); | 238 m_saveTimer.changeOccurred(); |
239 m_saveTimer.saveIfNeccessary(); | 239 m_saveTimer.saveIfNeccessary(); |
240 historyReset(); | 240 historyReset(); |
241 } | 241 } |
242 | 242 |
255 QSettings settings; | 255 QSettings settings; |
256 settings.beginGroup(QLatin1String("history")); | 256 settings.beginGroup(QLatin1String("history")); |
257 settings.setValue(QLatin1String("historyLimit"), m_historyLimit); | 257 settings.setValue(QLatin1String("historyLimit"), m_historyLimit); |
258 | 258 |
259 bool saveAll = m_lastSavedUrl.isEmpty(); | 259 bool saveAll = m_lastSavedUrl.isEmpty(); |
260 int first = m_history.count() - 1; | 260 int first = m_history.length - 1; |
261 if (!saveAll) { | 261 if (!saveAll) { |
262 // find the first one to save | 262 // find the first one to save |
263 for (int i = 0; i < m_history.count(); ++i) { | 263 for (int i = 0; i < m_history.length; ++i) { |
264 if (m_history.at(i).url == m_lastSavedUrl) { | 264 if (m_history[i].url == m_lastSavedUrl) { |
265 first = i - 1; | 265 first = i - 1; |
266 break; | 266 break; |
267 } | 267 } |
268 } | 268 } |
269 } | 269 } |
270 | 270 |
271 if (first == m_history.count() - 1) | 271 if (first == m_history.length - 1) |
272 saveAll = true; | 272 saveAll = true; |
273 | 273 |
274 QString directory = QDesktopServices.storageLocation(QDesktopServices.DataLocation); | 274 string directory = QDesktopServices.storageLocation(QDesktopServices.DataLocation); |
275 if (directory.isEmpty()) | 275 if (directory.isEmpty()) |
276 directory = QDir.homePath() + QLatin1String("/.") + QCoreApplication.applicationName(); | 276 directory = QDir.homePath() + QLatin1String("/.") + QCoreApplication.applicationName(); |
277 if (!QFile.exists(directory)) { | 277 if (!QFile.exists(directory)) { |
278 QDir dir; | 278 QDir dir; |
279 dir.mkpath(directory); | 279 dir.mkpath(directory); |
298 | 298 |
299 QDataStream out_ = (saveAll ? tempFile : historyFile); | 299 QDataStream out_ = (saveAll ? tempFile : historyFile); |
300 for (int i = first; i >= 0; --i) { | 300 for (int i = first; i >= 0; --i) { |
301 QByteArray data; | 301 QByteArray data; |
302 auto stream = new QDataStream(data, QIODevice.WriteOnly); | 302 auto stream = new QDataStream(data, QIODevice.WriteOnly); |
303 HistoryItem item = m_history.at(i); | 303 HistoryItem item = m_history[i]; |
304 stream << HISTORY_VERSION << item.url << item.dateTime << item.title; | 304 stream << HISTORY_VERSION << item.url << item.dateTime << item.title; |
305 out_ << data; | 305 out_ << data; |
306 } | 306 } |
307 tempFile.close(); | 307 tempFile.close(); |
308 | 308 |
315 m_lastSavedUrl = m_history.value(0).url; | 315 m_lastSavedUrl = m_history.value(0).url; |
316 } | 316 } |
317 | 317 |
318 void checkForExpired() | 318 void checkForExpired() |
319 { | 319 { |
320 if (m_historyLimit < 0 || m_history.isEmpty()) | 320 if (m_historyLimit < 0 || m_history.length == 0) |
321 return; | 321 return; |
322 | 322 |
323 QDateTime now = QDateTime.currentDateTime(); | 323 QDateTime now = QDateTime.currentDateTime(); |
324 int nextTimeout = 0; | 324 int nextTimeout = 0; |
325 | 325 |
326 while (!m_history.isEmpty()) { | 326 while (m_history.length) { |
327 QDateTime checkForExpired = m_history.last().dateTime; | 327 QDateTime checkForExpired = m_history.last().dateTime; |
328 checkForExpired.setDate(checkForExpired.date().addDays(m_historyLimit)); | 328 checkForExpired.setDate(checkForExpired.date().addDays(m_historyLimit)); |
329 if (now.daysTo(checkForExpired) > 7) { | 329 if (now.daysTo(checkForExpired) > 7) { |
330 // check at most in a week to prevent int overflows on the timer | 330 // check at most in a week to prevent int overflows on the timer |
331 nextTimeout = 7 * 86400; | 331 nextTimeout = 7 * 86400; |
334 } | 334 } |
335 if (nextTimeout > 0) | 335 if (nextTimeout > 0) |
336 break; | 336 break; |
337 HistoryItem item = m_history.takeLast(); | 337 HistoryItem item = m_history.takeLast(); |
338 // remove from saved file also | 338 // remove from saved file also |
339 m_lastSavedUrl = QString(); | 339 m_lastSavedUrl = null; |
340 emit entryRemoved(item); | 340 entryRemoved.emit(item); |
341 } | 341 } |
342 | 342 |
343 if (nextTimeout > 0) | 343 if (nextTimeout > 0) |
344 m_expiredTimer.start(nextTimeout * 1000); | 344 m_expiredTimer.start(nextTimeout * 1000); |
345 } | 345 } |
350 { | 350 { |
351 QWebSettings globalSettings = QWebSettings.globalSettings(); | 351 QWebSettings globalSettings = QWebSettings.globalSettings(); |
352 if (globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled)) | 352 if (globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled)) |
353 return; | 353 return; |
354 | 354 |
355 m_history.prepend(item); | 355 m_history = [item] ~ m_history; |
356 emit entryAdded(item); | 356 entryAdded.emit(item); |
357 if (m_history.count() == 1) | 357 if (m_history.length == 1) |
358 checkForExpired(); | 358 checkForExpired(); |
359 } | 359 } |
360 | 360 |
361 private: | 361 private: |
362 | 362 |
363 void load() | 363 void load() |
364 { | 364 { |
365 loadSettings(); | 365 loadSettings(); |
366 | 366 |
367 historyFile = new QFile(QDesktopServices.storageLocation(QDesktopServices.DataLocation) + QLatin1String("/history")); | 367 historyFile = new QFile(QDesktopServices.storageLocation(QDesktopServices.DataLocation) ~ QLatin1String("/history")); |
368 if (!historyFile.exists()) | 368 if (!historyFile.exists()) |
369 return; | 369 return; |
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; |
374 | 374 |
375 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 auto lastInsertedItem = new HistoryItem; |
380 QByteArray data; | 380 auto data = new QByteArray; |
381 QDataStream stream; | 381 auto stream = new QDataStream; |
382 QBuffer buffer; | 382 auto buffer = new QBuffer; |
383 stream.setDevice(buffer); | 383 stream.setDevice(buffer); |
384 while (!historyFile.atEnd()) { | 384 while (!historyFile.atEnd()) { |
385 in_ >> data; | 385 in_ >> data; |
386 buffer.close(); | 386 buffer.close(); |
387 buffer.setBuffer(data); | 387 buffer.setBuffer(data); |
388 buffer.open(QIODevice.ReadOnly); | 388 buffer.open(QIODevice.ReadOnly); |
389 quint32 ver; | 389 uint ver; |
390 stream >> ver; | 390 stream >> ver; |
391 if (ver != HISTORY_VERSION) | 391 if (ver != HISTORY_VERSION) |
392 continue; | 392 continue; |
393 HistoryItem item; | 393 auto item = new HistoryItem; |
394 stream >> item.url; | 394 stream >> item.url; |
395 stream >> item.dateTime; | 395 stream >> item.dateTime; |
396 stream >> item.title; | 396 stream >> item.title; |
397 | 397 |
398 if (!item.dateTime.isValid()) | 398 if (!item.dateTime.isValid()) |
416 | 416 |
417 setHistory(list, true); | 417 setHistory(list, true); |
418 | 418 |
419 // If we had to sort re-write the whole history sorted | 419 // If we had to sort re-write the whole history sorted |
420 if (needToSort) { | 420 if (needToSort) { |
421 m_lastSavedUrl = QString(); | 421 m_lastSavedUrl = null; |
422 m_saveTimer.changeOccurred(); | 422 m_saveTimer.changeOccurred(); |
423 } | 423 } |
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 HistoryItem[] m_history; | 429 HistoryItem[] m_history; |
430 QString m_lastSavedUrl; | 430 string 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; |
435 } | 435 } |
451 } | 451 } |
452 | 452 |
453 void entryUpdated(int offset) | 453 void entryUpdated(int offset) |
454 { | 454 { |
455 QModelIndex idx = index(offset, 0); | 455 QModelIndex idx = index(offset, 0); |
456 emit dataChanged(idx, idx); | 456 dataChanged.emit(idx, idx); |
457 } | 457 } |
458 | 458 |
459 public: | 459 public: |
460 | 460 |
461 enum Roles { | 461 enum Roles { |
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 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.length) |
495 return QVariant(); | 495 return QVariant(); |
496 | 496 |
497 HistoryItem item = lst.at(index.row()); | 497 HistoryItem item = lst[index.row()]; |
498 switch (role) { | 498 switch (role) { |
499 case DateTimeRole: | 499 case DateTimeRole: |
500 return item.dateTime; | 500 return item.dateTime; |
501 case DateRole: | 501 case DateRole: |
502 return item.dateTime.date(); | 502 return item.dateTime.date(); |
508 case Qt.EditRole: { | 508 case Qt.EditRole: { |
509 switch (index.column()) { | 509 switch (index.column()) { |
510 case 0: | 510 case 0: |
511 // when there is no title try to generate one from the url | 511 // when there is no title try to generate one from the url |
512 if (item.title.isEmpty()) { | 512 if (item.title.isEmpty()) { |
513 QString page = QFileInfo(QUrl(item.url).path()).fileName(); | 513 string page = QFileInfo(QUrl(item.url).path()).fileName(); |
514 if (!page.isEmpty()) | 514 if (!page.isEmpty()) |
515 return page; | 515 return page; |
516 return item.url; | 516 return item.url; |
517 } | 517 } |
518 return item.title; | 518 return item.title; |
552 m_history.historyReset.connect(&this.historyReset); | 552 m_history.historyReset.connect(&this.historyReset); |
553 endRemoveRows(); | 553 endRemoveRows(); |
554 return true; | 554 return true; |
555 } | 555 } |
556 | 556 |
557 | |
558 private: | 557 private: |
558 | |
559 HistoryManager m_history; | 559 HistoryManager m_history; |
560 } | 560 } |
561 | 561 |
562 | 562 |
563 const uint MOVEDROWS = 15; | 563 const uint MOVEDROWS = 15; |
577 super(parent); | 577 super(parent); |
578 m_loaded = false; | 578 m_loaded = false; |
579 setSourceModel(sourceModel); | 579 setSourceModel(sourceModel); |
580 } | 580 } |
581 | 581 |
582 bool historyContains(QString url) | 582 bool historyContains(string url) |
583 { | 583 { |
584 load(); | 584 load(); |
585 return m_historyHash.contains(url); | 585 return ((url in m_historyHash) != null); |
586 } | 586 } |
587 | 587 |
588 int historyLocation(QString url) | 588 int historyLocation(string url) |
589 { | 589 { |
590 load(); | 590 load(); |
591 if (!m_historyHash.contains(url)) | 591 if (!(url in m_historyHash)) |
592 return 0; | 592 return 0; |
593 return sourceModel().rowCount() - m_historyHash.value(url); | 593 return sourceModel().rowCount() - m_historyHash.value(url); |
594 } | 594 } |
595 | 595 |
596 QModelIndex mapFromSource(QModelIndex sourceIndex) | 596 QModelIndex mapFromSource(QModelIndex sourceIndex) |
597 { | 597 { |
598 load(); | 598 load(); |
599 QString url = sourceIndex.data(HistoryModel.UrlStringRole).toString(); | 599 string url = sourceIndex.data(HistoryModel.UrlStringRole).toString(); |
600 if (!m_historyHash.contains(url)) | 600 if (!(url in m_historyHash)) |
601 return QModelIndex(); | 601 return QModelIndex(); |
602 | 602 |
603 // This can be done in a binary search, but we can't use qBinary find | 603 // This can be done in a binary search, but we can't use qBinary find |
604 // because it can't take: qBinaryFind(m_sourceRow.end(), m_sourceRow.begin(), v); | 604 // because it can't take: qBinaryFind(m_sourceRow.end(), m_sourceRow.begin(), v); |
605 // so if this is a performance bottlneck then convert to binary search, until then | 605 // so if this is a performance bottlneck then convert to binary search, until then |
606 // the cleaner/easier to read code wins the day. | 606 // the cleaner/easier to read code wins the day. |
607 int realRow = -1; | 607 int realRow = -1; |
608 int sourceModelRow = sourceModel().rowCount() - sourceIndex.row(); | 608 int sourceModelRow = sourceModel().rowCount() - sourceIndex.row(); |
609 | 609 |
610 for (int i = 0; i < m_sourceRow.count(); ++i) { | 610 for (int i = 0; i < m_sourceRow.count(); ++i) { |
611 if (m_sourceRow.at(i) == sourceModelRow) { | 611 if (m_sourceRow[i] == sourceModelRow) { |
612 realRow = i; | 612 realRow = i; |
613 break; | 613 break; |
614 } | 614 } |
615 } | 615 } |
616 if (realRow == -1) | 616 if (realRow == -1) |
654 int rowCount(QModelIndex parent = QModelIndex()) | 654 int rowCount(QModelIndex parent = QModelIndex()) |
655 { | 655 { |
656 load(); | 656 load(); |
657 if (parent.isValid()) | 657 if (parent.isValid()) |
658 return 0; | 658 return 0; |
659 return m_historyHash.count(); | 659 return m_historyHash.length; |
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; |
699 if (oldCount - count != rowCount()) | 699 if (oldCount - count != rowCount()) |
700 reset(); | 700 reset(); |
701 return true; | 701 return true; |
702 } | 702 } |
703 | 703 |
704 | |
705 QVariant data(QModelIndex index, int role = Qt.DisplayRole) | 704 QVariant data(QModelIndex index, int role = Qt.DisplayRole) |
706 { | 705 { |
707 return QAbstractProxyModel.data(index, role); | 706 return QAbstractProxyModel.data(index, role); |
708 } | 707 } |
709 | 708 |
720 dataChanged.emit(mapFromSource(topLeft), mapFromSource(bottomRight)); | 719 dataChanged.emit(mapFromSource(topLeft), mapFromSource(bottomRight)); |
721 } | 720 } |
722 | 721 |
723 void sourceRowsRemoved(QModelIndex , int start, int end) | 722 void sourceRowsRemoved(QModelIndex , int start, int end) |
724 { | 723 { |
725 //Q_UNUSED(start); | |
726 //Q_UNUSED(end); | |
727 sourceReset(); | 724 sourceReset(); |
728 } | 725 } |
729 | 726 |
730 void sourceRowsInserted(QModelIndex parent, int start, int end) | 727 void sourceRowsInserted(QModelIndex parent, int start, int end) |
731 { | 728 { |
732 assert(start == end && start == 0); | 729 assert(start == end && start == 0); |
733 //Q_UNUSED(end); | 730 |
734 if (!m_loaded) | 731 if (!m_loaded) |
735 return; | 732 return; |
736 QModelIndex idx = sourceModel().index(start, 0, parent); | 733 QModelIndex idx = sourceModel().index(start, 0, parent); |
737 QString url = idx.data(HistoryModel.UrlStringRole).toString(); | 734 string url = idx.data(HistoryModel.UrlStringRole).toString(); |
738 if (m_historyHash.contains(url)) { | 735 if (url in m_historyHash) { |
739 int sourceRow = sourceModel().rowCount() - m_historyHash[url]; | 736 int sourceRow = sourceModel().rowCount() - m_historyHash[url]; |
740 int realRow = mapFromSource(sourceModel().index(sourceRow, 0)).row(); | 737 int realRow = mapFromSource(sourceModel().index(sourceRow, 0)).row(); |
741 beginRemoveRows(QModelIndex(), realRow, realRow); | 738 beginRemoveRows(QModelIndex(), realRow, realRow); |
742 m_sourceRow.removeAt(realRow); | 739 m_sourceRow.removeAt(realRow); |
743 m_historyHash.remove(url); | 740 m_historyHash.remove(url); |
744 endRemoveRows(); | 741 endRemoveRows(); |
745 } | 742 } |
746 beginInsertRows(QModelIndex(), 0, 0); | 743 beginInsertRows(QModelIndex(), 0, 0); |
747 m_historyHash.insert(url, sourceModel().rowCount() - start); | 744 m_historyHash[url] = (sourceModel().rowCount() - start); |
748 m_sourceRow.insert(0, sourceModel().rowCount()); | 745 m_sourceRow.insert(0, sourceModel().rowCount()); |
749 endInsertRows(); | 746 endInsertRows(); |
750 } | 747 } |
751 | 748 |
752 private: | 749 private: |
753 void load() | 750 void load() |
754 { | 751 { |
755 if (m_loaded) | 752 if (m_loaded) |
756 return; | 753 return; |
757 m_sourceRow.clear(); | 754 m_sourceRow.clear(); |
758 m_historyHash.clear(); | 755 m_historyHash = null; |
759 m_historyHash.reserve(sourceModel().rowCount()); | 756 m_historyHash.length = sourceModel().rowCount(); |
757 m_historyHash.length = 0; | |
760 for (int i = 0; i < sourceModel().rowCount(); ++i) { | 758 for (int i = 0; i < sourceModel().rowCount(); ++i) { |
761 QModelIndex idx = sourceModel().index(i, 0); | 759 QModelIndex idx = sourceModel().index(i, 0); |
762 QString url = idx.data(HistoryModel.UrlStringRole).toString(); | 760 string url = idx.data(HistoryModel.UrlStringRole).toString(); |
763 if (!m_historyHash.contains(url)) { | 761 if (!(url in m_historyHash)) { |
764 m_sourceRow.append(sourceModel().rowCount() - i); | 762 m_sourceRow.append(sourceModel().rowCount() - i); |
765 m_historyHash[url] = sourceModel().rowCount() - i; | 763 m_historyHash[url] = sourceModel().rowCount() - i; |
766 } | 764 } |
767 } | 765 } |
768 m_loaded = true; | 766 m_loaded = true; |
769 } | 767 } |
770 | 768 |
771 int[] m_sourceRow; | 769 int[] m_sourceRow; |
772 int[QString] m_historyHash; | 770 int[string] m_historyHash; |
773 bool m_loaded; | 771 bool m_loaded; |
774 } | 772 } |
775 | 773 |
776 | 774 |
777 /* | 775 /* |
921 } | 919 } |
922 | 920 |
923 void setInitialActions(QAction[] actions) | 921 void setInitialActions(QAction[] actions) |
924 { | 922 { |
925 m_initialActions = actions; | 923 m_initialActions = actions; |
926 for (int i = 0; i < m_initialActions.count(); ++i) | 924 for (int i = 0; i < m_initialActions.length; ++i) |
927 addAction(m_initialActions.at(i)); | 925 addAction(m_initialActions[i]); |
928 } | 926 } |
929 | 927 |
930 protected: | 928 protected: |
931 | 929 |
932 bool prePopulated() | 930 bool prePopulated() |
935 m_history = BrowserApplication.historyManager(); | 933 m_history = BrowserApplication.historyManager(); |
936 m_historyMenuModel = new HistoryMenuModel(m_history.historyTreeModel(), this); | 934 m_historyMenuModel = new HistoryMenuModel(m_history.historyTreeModel(), this); |
937 setModel(m_historyMenuModel); | 935 setModel(m_historyMenuModel); |
938 } | 936 } |
939 // initial actions | 937 // initial actions |
940 for (int i = 0; i < m_initialActions.count(); ++i) | 938 for (int i = 0; i < m_initialActions.length; ++i) |
941 addAction(m_initialActions.at(i)); | 939 addAction(m_initialActions[i]); |
942 if (!m_initialActions.isEmpty()) | 940 if (m_initialActions.length) |
943 addSeparator(); | 941 addSeparator(); |
944 setFirstSeparator(m_historyMenuModel.bumpedRows()); | 942 setFirstSeparator(m_historyMenuModel.bumpedRows()); |
945 | 943 |
946 return false; | 944 return false; |
947 } | 945 } |
996 QVariant data(QModelIndex index, int role) | 994 QVariant data(QModelIndex index, int role) |
997 { | 995 { |
998 if (sourceModel() && (role == Qt.EditRole || role == Qt.DisplayRole) && index.isValid()) { | 996 if (sourceModel() && (role == Qt.EditRole || role == Qt.DisplayRole) && index.isValid()) { |
999 QModelIndex idx = mapToSource(index); | 997 QModelIndex idx = mapToSource(index); |
1000 idx = idx.sibling(idx.row(), 1); | 998 idx = idx.sibling(idx.row(), 1); |
1001 QString urlString = idx.data(HistoryModel.UrlStringRole).toString(); | 999 string urlString = idx.data(HistoryModel.UrlStringRole).toString(); |
1002 if (index.row() % 2) { | 1000 if (index.row() % 2) { |
1003 QUrl url = urlString; | 1001 QUrl url = urlString; |
1004 QString s = url.toString(QUrl.RemoveScheme | QUrl.RemoveUserInfo | QUrl.StripTrailingSlash); | 1002 string s = url.toString(QUrl.RemoveScheme | QUrl.RemoveUserInfo | QUrl.StripTrailingSlash); |
1005 return s.mid(2); // strip // from the front | 1003 return s.mid(2); // strip // from the front |
1006 } | 1004 } |
1007 return urlString; | 1005 return urlString; |
1008 } | 1006 } |
1009 return QAbstractProxyModel.data(index, role); | 1007 return QAbstractProxyModel.data(index, role); |
1098 if (date == QDate.currentDate()) | 1096 if (date == QDate.currentDate()) |
1099 return tr("Earlier Today"); | 1097 return tr("Earlier Today"); |
1100 return date.toString(QLatin1String("dddd, MMMM d, yyyy")); | 1098 return date.toString(QLatin1String("dddd, MMMM d, yyyy")); |
1101 } | 1099 } |
1102 if (index.column() == 1) { | 1100 if (index.column() == 1) { |
1103 return tr("%1 items").arg(rowCount(index.sibling(index.row(), 0))); | 1101 return Format(tr("{} items"), rowCount(index.sibling(index.row(), 0))); |
1104 } | 1102 } |
1105 } | 1103 } |
1106 } | 1104 } |
1107 if (role == Qt.DecorationRole && index.column() == 0 && !index.parent().isValid()) | 1105 if (role == Qt.DecorationRole && index.column() == 0 && !index.parent().isValid()) |
1108 return QIcon(QLatin1String(":history.png")); | 1106 return QIcon(QLatin1String(":history.png")); |
1125 if ( parent.internalId() != 0 || parent.column() > 0 || !sourceModel()) | 1123 if ( parent.internalId() != 0 || parent.column() > 0 || !sourceModel()) |
1126 return 0; | 1124 return 0; |
1127 | 1125 |
1128 // row count OF dates | 1126 // row count OF dates |
1129 if (!parent.isValid()) { | 1127 if (!parent.isValid()) { |
1130 if (!m_sourceRowCache.isEmpty()) | 1128 if (m_sourceRowCache.length) |
1131 return m_sourceRowCache.count(); | 1129 return m_sourceRowCache.length; |
1132 QDate currentDate; | 1130 QDate currentDate; |
1133 int rows = 0; | 1131 int rows = 0; |
1134 int totalRows = sourceModel().rowCount(); | 1132 int totalRows = sourceModel().rowCount(); |
1135 | 1133 |
1136 for (int i = 0; i < totalRows; ++i) { | 1134 for (int i = 0; i < totalRows; ++i) { |
1137 QDate rowDate = sourceModel().index(i, 0).data(HistoryModel.DateRole).toDate(); | 1135 QDate rowDate = sourceModel().index(i, 0).data(HistoryModel.DateRole).toDate(); |
1138 if (rowDate != currentDate) { | 1136 if (rowDate != currentDate) { |
1139 m_sourceRowCache.append(i); | 1137 m_sourceRowCache ~= i; |
1140 currentDate = rowDate; | 1138 currentDate = rowDate; |
1141 ++rows; | 1139 ++rows; |
1142 } | 1140 } |
1143 } | 1141 } |
1144 assert(m_sourceRowCache.count() == rows); | 1142 assert(m_sourceRowCache.length == rows); |
1145 return rows; | 1143 return rows; |
1146 } | 1144 } |
1147 | 1145 |
1148 // row count FOR a date | 1146 // row count FOR a date |
1149 int start = sourceDateRow(parent.row()); | 1147 int start = sourceDateRow(parent.row()); |
1154 QModelIndex mapFromSource(QModelIndex sourceIndex) | 1152 QModelIndex mapFromSource(QModelIndex sourceIndex) |
1155 { | 1153 { |
1156 if (!sourceIndex.isValid()) | 1154 if (!sourceIndex.isValid()) |
1157 return QModelIndex(); | 1155 return QModelIndex(); |
1158 | 1156 |
1159 if (m_sourceRowCache.isEmpty()) | 1157 if (m_sourceRowCache.length == 0) |
1160 rowCount(QModelIndex()); | 1158 rowCount(QModelIndex()); |
1161 | 1159 |
1162 int[].iterator it; | 1160 int[].iterator it; |
1163 it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), sourceIndex.row()); | 1161 it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), sourceIndex.row()); |
1164 if (*it != sourceIndex.row()) | 1162 if (*it != sourceIndex.row()) |
1165 --it; | 1163 --it; |
1166 int dateRow = qMax(0, it - m_sourceRowCache.begin()); | 1164 int dateRow = qMax(0, it - m_sourceRowCache.begin()); |
1167 int row = sourceIndex.row() - m_sourceRowCache.at(dateRow); | 1165 int row = sourceIndex.row() - m_sourceRowCache[dateRow]; |
1168 return createIndex(row, sourceIndex.column(), dateRow + 1); | 1166 return createIndex(row, sourceIndex.column(), dateRow + 1); |
1169 } | 1167 } |
1170 | 1168 |
1171 QModelIndex mapToSource(QModelIndex proxyIndex) | 1169 QModelIndex mapToSource(QModelIndex proxyIndex) |
1172 { | 1170 { |
1259 | 1257 |
1260 private: | 1258 private: |
1261 | 1259 |
1262 void sourceReset() | 1260 void sourceReset() |
1263 { | 1261 { |
1264 m_sourceRowCache.clear(); | 1262 m_sourceRowCache.length = 0; |
1265 reset(); | 1263 reset(); |
1266 } | 1264 } |
1267 | 1265 |
1268 void sourceRowsInserted(QModelIndex parent, int start, int end) | 1266 void sourceRowsInserted(QModelIndex parent, int start, int end) |
1269 { | 1267 { |
1270 //Q_UNUSED(parent); // Avoid warnings when compiling release | |
1271 assert(!parent.isValid()); | 1268 assert(!parent.isValid()); |
1272 if (start != 0 || start != end) { | 1269 if (start != 0 || start != end) { |
1273 m_sourceRowCache.clear(); | 1270 m_sourceRowCache.length = 0; |
1274 reset(); | 1271 reset(); |
1275 return; | 1272 return; |
1276 } | 1273 } |
1277 | 1274 |
1278 m_sourceRowCache.clear(); | 1275 m_sourceRowCache.length = 0; |
1279 QModelIndex treeIndex = mapFromSource(sourceModel().index(start, 0)); | 1276 QModelIndex treeIndex = mapFromSource(sourceModel().index(start, 0)); |
1280 QModelIndex treeParent = treeIndex.parent(); | 1277 QModelIndex treeParent = treeIndex.parent(); |
1281 if (rowCount(treeParent) == 1) { | 1278 if (rowCount(treeParent) == 1) { |
1282 beginInsertRows(QModelIndex(), 0, 0); | 1279 beginInsertRows(QModelIndex(), 0, 0); |
1283 endInsertRows(); | 1280 endInsertRows(); |
1285 beginInsertRows(treeParent, treeIndex.row(), treeIndex.row()); | 1282 beginInsertRows(treeParent, treeIndex.row(), treeIndex.row()); |
1286 endInsertRows(); | 1283 endInsertRows(); |
1287 } | 1284 } |
1288 } | 1285 } |
1289 | 1286 |
1290 void sourceRowsRemoved(QModelIndex parent, int start, int end); | 1287 void sourceRowsRemoved(QModelIndex parent, int start, int end) |
1291 { | 1288 { |
1292 //Q_UNUSED(parent); // Avoid warnings when compiling release | |
1293 assert(!parent.isValid()); | 1289 assert(!parent.isValid()); |
1294 if (m_sourceRowCache.isEmpty()) | 1290 if (m_sourceRowCache.length == 0) |
1295 return; | 1291 return; |
1296 for (int i = end; i >= start;) { | 1292 for (int i = end; i >= start;) { |
1297 int[]::iterator it; | 1293 int[]::iterator it; |
1298 it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), i); | 1294 it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), i); |
1299 // playing it safe | 1295 // playing it safe |
1300 if (it == m_sourceRowCache.end()) { | 1296 if (it == m_sourceRowCache.end()) { |
1301 m_sourceRowCache.clear(); | 1297 m_sourceRowCache = null; |
1302 reset(); | 1298 reset(); |
1303 return; | 1299 return; |
1304 } | 1300 } |
1305 | 1301 |
1306 if (*it != i) | 1302 if (*it != i) |
1317 } else { | 1313 } else { |
1318 beginRemoveRows(dateParent, i - offset, i - offset); | 1314 beginRemoveRows(dateParent, i - offset, i - offset); |
1319 ++row; | 1315 ++row; |
1320 --i; | 1316 --i; |
1321 } | 1317 } |
1322 for (int j = row; j < m_sourceRowCache.count(); ++j) | 1318 for (int j = row; j < m_sourceRowCache.length; ++j) |
1323 --m_sourceRowCache[j]; | 1319 --m_sourceRowCache[j]; |
1324 endRemoveRows(); | 1320 endRemoveRows(); |
1325 } | 1321 } |
1326 } | 1322 } |
1327 | 1323 |
1331 int sourceDateRow(int row) | 1327 int sourceDateRow(int row) |
1332 { | 1328 { |
1333 if (row <= 0) | 1329 if (row <= 0) |
1334 return 0; | 1330 return 0; |
1335 | 1331 |
1336 if (m_sourceRowCache.isEmpty()) | 1332 if (m_sourceRowCache.length == 0) |
1337 rowCount(QModelIndex()); | 1333 rowCount(QModelIndex()); |
1338 | 1334 |
1339 if (row >= m_sourceRowCache.count()) { | 1335 if (row >= m_sourceRowCache.length) { |
1340 if (!sourceModel()) | 1336 if (!sourceModel()) |
1341 return 0; | 1337 return 0; |
1342 return sourceModel().rowCount(); | 1338 return sourceModel().rowCount(); |
1343 } | 1339 } |
1344 return m_sourceRowCache.at(row); | 1340 return m_sourceRowCache[row]; |
1345 } | 1341 } |
1346 | 1342 |
1347 int[] m_sourceRowCache; | 1343 int[] m_sourceRowCache; |
1348 } | 1344 } |
1349 | 1345 |
1360 super(parent); | 1356 super(parent); |
1361 setSortRole(HistoryModel.DateTimeRole); | 1357 setSortRole(HistoryModel.DateTimeRole); |
1362 setFilterCaseSensitivity(Qt.CaseInsensitive); | 1358 setFilterCaseSensitivity(Qt.CaseInsensitive); |
1363 } | 1359 } |
1364 | 1360 |
1365 protected: | 1361 protected: |
1362 | |
1366 bool filterAcceptsRow(int source_row, QModelIndex source_parent) | 1363 bool filterAcceptsRow(int source_row, QModelIndex source_parent) |
1367 { | 1364 { |
1368 if (!source_parent.isValid()) | 1365 if (!source_parent.isValid()) |
1369 return true; | 1366 return true; |
1370 return QSortFilterProxyModel.filterAcceptsRow(source_row, source_parent); | 1367 return QSortFilterProxyModel.filterAcceptsRow(source_row, source_parent); |
1390 tree.setUniformRowHeights(true); | 1387 tree.setUniformRowHeights(true); |
1391 tree.setSelectionBehavior(QAbstractItemView.SelectRows); | 1388 tree.setSelectionBehavior(QAbstractItemView.SelectRows); |
1392 tree.setTextElideMode(Qt.ElideMiddle); | 1389 tree.setTextElideMode(Qt.ElideMiddle); |
1393 auto model = history.historyTreeModel(); | 1390 auto model = history.historyTreeModel(); |
1394 auto proxyModel = new TreeProxyModel(this); | 1391 auto proxyModel = new TreeProxyModel(this); |
1395 search.textChanged(QString).connect(&proxyModel.setFilterFixedString(QString)); | 1392 search.textChanged.connect(&proxyModel.setFilterFixedString); |
1396 removeButton.clicked.connect(&tree.removeOne); | 1393 removeButton.clicked.connect(&tree.removeOne); |
1397 removeAllButton.clicked.connect(&history.clear); | 1394 removeAllButton.clicked.connect(&history.clear); |
1398 proxyModel.setSourceModel(model); | 1395 proxyModel.setSourceModel(model); |
1399 tree.setModel(proxyModel); | 1396 tree.setModel(proxyModel); |
1400 tree.setExpanded(proxyModel.index(0, 0), true); | 1397 tree.setExpanded(proxyModel.index(0, 0), true); |
1410 | 1407 |
1411 private: | 1408 private: |
1412 | 1409 |
1413 void customContextMenuRequested(QPoint pos) | 1410 void customContextMenuRequested(QPoint pos) |
1414 { | 1411 { |
1415 QMenu menu; | 1412 auto menu = new QMenu; |
1416 QModelIndex index = tree.indexAt(pos); | 1413 QModelIndex index = tree.indexAt(pos); |
1417 index = index.sibling(index.row(), 0); | 1414 index = index.sibling(index.row(), 0); |
1418 if (index.isValid() && !tree.model().hasChildren(index)) { | 1415 if (index.isValid() && !tree.model().hasChildren(index)) { |
1419 menu.addAction(tr("Open"), this, SLOT(open())); | 1416 menu.addAction(tr("Open"), this, SLOT(open())); |
1420 menu.addSeparator(); | 1417 menu.addSeparator(); |
1427 void open() | 1424 void open() |
1428 { | 1425 { |
1429 QModelIndex index = tree.currentIndex(); | 1426 QModelIndex index = tree.currentIndex(); |
1430 if (!index.parent().isValid()) | 1427 if (!index.parent().isValid()) |
1431 return; | 1428 return; |
1432 emit openUrl(index.data(HistoryModel.UrlRole).toUrl()); | 1429 openUrl.emit(index.data(HistoryModel.UrlRole).toUrl()); |
1433 } | 1430 } |
1434 | 1431 |
1435 void copy() | 1432 void copy() |
1436 { | 1433 { |
1437 QModelIndex index = tree.currentIndex(); | 1434 QModelIndex index = tree.currentIndex(); |
1438 if (!index.parent().isValid()) | 1435 if (!index.parent().isValid()) |
1439 return; | 1436 return; |
1440 QString url = index.data(HistoryModel.UrlStringRole).toString(); | 1437 string url = index.data(HistoryModel.UrlStringRole).toString(); |
1441 | 1438 |
1442 QClipboard clipboard = QApplication.clipboard(); | 1439 QClipboard clipboard = QApplication.clipboard(); |
1443 clipboard.setText(url); | 1440 clipboard.setText(url); |
1444 } | 1441 } |
1445 } | 1442 } |