mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 10:46:35 +01:00
[HistoryTreeView] Rewrite HistoryView to use same logic as BookmarksTreeView
It also fixes issue that middle click on item opened the url in both current and new tab
This commit is contained in:
parent
0b6478d110
commit
ad5dbe459c
@ -35,17 +35,15 @@ BookmarksTreeView::BookmarksTreeView(QWidget* parent)
|
||||
setModel(m_filter);
|
||||
setDragEnabled(true);
|
||||
setAcceptDrops(true);
|
||||
setUniformRowHeights(true);
|
||||
setDropIndicatorShown(true);
|
||||
setAllColumnsShowFocus(true);
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
setItemDelegate(new BookmarksItemDelegate(this));
|
||||
header()->resizeSections(QHeaderView::ResizeToContents);
|
||||
|
||||
connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(indexExpanded(QModelIndex)));
|
||||
connect(this, SIGNAL(collapsed(QModelIndex)), this, SLOT(indexCollapsed(QModelIndex)));
|
||||
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged()));
|
||||
|
||||
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(createContextMenu(QPoint)));
|
||||
}
|
||||
|
||||
BookmarksTreeView::ViewType BookmarksTreeView::viewType() const
|
||||
@ -158,11 +156,6 @@ void BookmarksTreeView::selectionChanged()
|
||||
emit bookmarksSelected(selectedBookmarks());
|
||||
}
|
||||
|
||||
void BookmarksTreeView::createContextMenu(const QPoint &point)
|
||||
{
|
||||
emit contextMenuRequested(viewport()->mapToGlobal(point));
|
||||
}
|
||||
|
||||
void BookmarksTreeView::restoreExpandedState(const QModelIndex &parent)
|
||||
{
|
||||
for (int i = 0; i < m_filter->rowCount(parent); ++i) {
|
||||
@ -179,6 +172,11 @@ void BookmarksTreeView::rowsInserted(const QModelIndex &parent, int start, int e
|
||||
QTreeView::rowsInserted(parent, start, end);
|
||||
}
|
||||
|
||||
void BookmarksTreeView::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
emit contextMenuRequested(viewport()->mapToGlobal(event->pos()));
|
||||
}
|
||||
|
||||
void BookmarksTreeView::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
QTreeView::mouseMoveEvent(event);
|
||||
@ -193,7 +191,6 @@ void BookmarksTreeView::mouseMoveEvent(QMouseEvent* event)
|
||||
}
|
||||
setCursor(cursor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BookmarksTreeView::mousePressEvent(QMouseEvent* event)
|
||||
|
@ -71,12 +71,12 @@ private slots:
|
||||
void indexCollapsed(const QModelIndex &parent);
|
||||
|
||||
void selectionChanged();
|
||||
void createContextMenu(const QPoint &point);
|
||||
|
||||
private:
|
||||
void restoreExpandedState(const QModelIndex &parent);
|
||||
void rowsInserted(const QModelIndex &parent, int start, int end);
|
||||
|
||||
void contextMenuEvent(QContextMenuEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
@ -20,14 +20,14 @@
|
||||
#include "browserwindow.h"
|
||||
#include "mainapplication.h"
|
||||
#include "history.h"
|
||||
#include "browsinglibrary.h"
|
||||
#include "tabwidget.h"
|
||||
#include "tabbedwebview.h"
|
||||
#include "historymodel.h"
|
||||
#include "headerview.h"
|
||||
#include "qzsettings.h"
|
||||
#include "iconprovider.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QClipboard>
|
||||
|
||||
HistoryManager::HistoryManager(BrowserWindow* window, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
@ -35,20 +35,23 @@ HistoryManager::HistoryManager(BrowserWindow* window, QWidget* parent)
|
||||
, m_window(window)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->historyTree->setViewType(HistoryTreeView::HistoryManagerViewType);
|
||||
|
||||
connect(ui->historyTree, SIGNAL(openLink(QUrl,HistoryView::OpenBehavior)), this, SLOT(openLink(QUrl,HistoryView::OpenBehavior)));
|
||||
connect(ui->historyTree, SIGNAL(urlActivated(QUrl)), this, SLOT(urlActivated(QUrl)));
|
||||
connect(ui->historyTree, SIGNAL(urlCtrlActivated(QUrl)), this, SLOT(urlCtrlActivated(QUrl)));
|
||||
connect(ui->historyTree, SIGNAL(urlShiftActivated(QUrl)), this, SLOT(urlShiftActivated(QUrl)));
|
||||
connect(ui->historyTree, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(createContextMenu(QPoint)));
|
||||
|
||||
connect(ui->deleteB, SIGNAL(clicked()), ui->historyTree, SLOT(removeItems()));
|
||||
connect(ui->deleteB, SIGNAL(clicked()), ui->historyTree, SLOT(removeSelectedItems()));
|
||||
connect(ui->clearAll, SIGNAL(clicked()), this, SLOT(clearHistory()));
|
||||
|
||||
ui->historyTree->setFocus();
|
||||
}
|
||||
|
||||
BrowserWindow* HistoryManager::getQupZilla()
|
||||
BrowserWindow* HistoryManager::getWindow()
|
||||
{
|
||||
if (!m_window) {
|
||||
if (!m_window)
|
||||
m_window = mApp->getWindow();
|
||||
}
|
||||
return m_window.data();
|
||||
}
|
||||
|
||||
@ -83,17 +86,86 @@ void HistoryManager::clearHistory()
|
||||
|
||||
void HistoryManager::search(const QString &searchText)
|
||||
{
|
||||
ui->historyTree->filterModel()->setFilterFixedString(searchText);
|
||||
ui->historyTree->search(searchText);
|
||||
}
|
||||
|
||||
void HistoryManager::openLink(const QUrl &url, HistoryView::OpenBehavior openIn)
|
||||
void HistoryManager::urlActivated(const QUrl &url)
|
||||
{
|
||||
if (openIn == HistoryView::OpenInNewTab) {
|
||||
getQupZilla()->tabWidget()->addView(url, qzSettings->newTabPosition);
|
||||
}
|
||||
else {
|
||||
getQupZilla()->weView()->load(url);
|
||||
openUrl(url);
|
||||
}
|
||||
|
||||
void HistoryManager::urlCtrlActivated(const QUrl &url)
|
||||
{
|
||||
openUrlInNewTab(url);
|
||||
}
|
||||
|
||||
void HistoryManager::urlShiftActivated(const QUrl &url)
|
||||
{
|
||||
openUrlInNewWindow(url);
|
||||
}
|
||||
|
||||
void HistoryManager::openUrl(const QUrl &url)
|
||||
{
|
||||
const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl();
|
||||
m_window->weView()->load(u);
|
||||
}
|
||||
|
||||
void HistoryManager::openUrlInNewTab(const QUrl &url)
|
||||
{
|
||||
const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl();
|
||||
m_window->tabWidget()->addView(u, qzSettings->newTabPosition);
|
||||
}
|
||||
|
||||
void HistoryManager::openUrlInNewWindow(const QUrl &url)
|
||||
{
|
||||
const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl();
|
||||
mApp->createWindow(Qz::BW_NewWindow, u);
|
||||
}
|
||||
|
||||
void HistoryManager::openUrlInNewPrivateWindow(const QUrl &url)
|
||||
{
|
||||
const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl();
|
||||
mApp->startPrivateBrowsing(u);
|
||||
}
|
||||
|
||||
void HistoryManager::createContextMenu(const QPoint &pos)
|
||||
{
|
||||
QMenu menu;
|
||||
QAction* actNewTab = menu.addAction(IconProvider::newTabIcon(), tr("Open in new tab"));
|
||||
QAction* actNewWindow = menu.addAction(IconProvider::newWindowIcon(), tr("Open in new window"));
|
||||
QAction* actNewPrivateWindow = menu.addAction(IconProvider::privateBrowsingIcon(), tr("Open in new private window"));
|
||||
|
||||
menu.addSeparator();
|
||||
QAction* actCopyUrl = menu.addAction(tr("Copy url"), this, SLOT(copyUrl()));
|
||||
QAction* actCopyTitle = menu.addAction(tr("Copy title"), this, SLOT(copyTitle()));
|
||||
|
||||
menu.addSeparator();
|
||||
QAction* actDelete = menu.addAction(QIcon::fromTheme(QSL("edit-delete")), tr("Delete"));
|
||||
|
||||
connect(actNewTab, SIGNAL(triggered()), this, SLOT(openUrlInNewTab()));
|
||||
connect(actNewWindow, SIGNAL(triggered()), this, SLOT(openUrlInNewWindow()));
|
||||
connect(actNewPrivateWindow, SIGNAL(triggered()), this, SLOT(openUrlInNewPrivateWindow()));
|
||||
connect(actDelete, SIGNAL(triggered()), ui->historyTree, SLOT(removeSelectedItems()));
|
||||
|
||||
if (ui->historyTree->selectedUrl().isEmpty()) {
|
||||
actNewTab->setDisabled(true);
|
||||
actNewWindow->setDisabled(true);
|
||||
actNewPrivateWindow->setDisabled(true);
|
||||
actCopyTitle->setDisabled(true);
|
||||
actCopyUrl->setDisabled(true);
|
||||
}
|
||||
|
||||
menu.exec(pos);
|
||||
}
|
||||
|
||||
void HistoryManager::copyUrl()
|
||||
{
|
||||
QApplication::clipboard()->setText(ui->historyTree->selectedUrl().toString());
|
||||
}
|
||||
|
||||
void HistoryManager::copyTitle()
|
||||
{
|
||||
QApplication::clipboard()->setText(ui->historyTree->currentIndex().data().toString());
|
||||
}
|
||||
|
||||
HistoryManager::~HistoryManager()
|
||||
|
@ -20,9 +20,9 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
#include <QUrl>
|
||||
|
||||
#include "qzcommon.h"
|
||||
#include "historyview.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -50,11 +50,23 @@ public slots:
|
||||
void search(const QString &searchText);
|
||||
|
||||
private slots:
|
||||
void openLink(const QUrl &url, HistoryView::OpenBehavior openIn);
|
||||
void urlActivated(const QUrl &url);
|
||||
void urlCtrlActivated(const QUrl &url);
|
||||
void urlShiftActivated(const QUrl &url);
|
||||
|
||||
void openUrl(const QUrl &url = QUrl());
|
||||
void openUrlInNewTab(const QUrl &url = QUrl());
|
||||
void openUrlInNewWindow(const QUrl &url = QUrl());
|
||||
void openUrlInNewPrivateWindow(const QUrl &url = QUrl());
|
||||
|
||||
void createContextMenu(const QPoint &pos);
|
||||
|
||||
void copyUrl();
|
||||
void copyTitle();
|
||||
void clearHistory();
|
||||
|
||||
private:
|
||||
BrowserWindow* getQupZilla();
|
||||
BrowserWindow* getWindow();
|
||||
|
||||
Ui::HistoryManager* ui;
|
||||
QPointer<BrowserWindow> m_window;
|
||||
|
@ -42,7 +42,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="HistoryView" name="historyTree">
|
||||
<widget class="HistoryTreeView" name="historyTree">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -52,9 +52,9 @@
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>HistoryView</class>
|
||||
<class>HistoryTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>historyview.h</header>
|
||||
<header>historytreeview.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
|
266
src/lib/history/historytreeview.cpp
Normal file
266
src/lib/history/historytreeview.cpp
Normal file
@ -0,0 +1,266 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2014 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "historytreeview.h"
|
||||
#include "historymodel.h"
|
||||
#include "historyitem.h"
|
||||
#include "headerview.h"
|
||||
#include "mainapplication.h"
|
||||
#include "iconprovider.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QKeyEvent>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
|
||||
HistoryTreeView::HistoryTreeView(QWidget* parent)
|
||||
: QTreeView(parent)
|
||||
, m_history(mApp->history())
|
||||
, m_filter(new HistoryFilterModel(m_history->model()))
|
||||
, m_type(HistoryManagerViewType)
|
||||
{
|
||||
setModel(m_filter);
|
||||
setUniformRowHeights(true);
|
||||
setAllColumnsShowFocus(true);
|
||||
|
||||
m_header = new HeaderView(this);
|
||||
m_header->setDefaultSectionSizes(QList<double>() << 0.4 << 0.35 << 0.10 << 0.08);
|
||||
m_header->setSectionHidden(4, true);
|
||||
setHeader(m_header);
|
||||
|
||||
connect(m_filter, SIGNAL(expandAllItems()), this, SLOT(expandAll()));
|
||||
connect(m_filter, SIGNAL(collapseAllItems()), this, SLOT(collapseAll()));
|
||||
}
|
||||
|
||||
HistoryTreeView::ViewType HistoryTreeView::viewType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void HistoryTreeView::setViewType(HistoryTreeView::ViewType type)
|
||||
{
|
||||
m_type = type;
|
||||
|
||||
switch (m_type) {
|
||||
case HistoryManagerViewType:
|
||||
setColumnHidden(1, false);
|
||||
setColumnHidden(2, false);
|
||||
setColumnHidden(3, false);
|
||||
setHeaderHidden(false);
|
||||
setMouseTracking(false);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
break;
|
||||
case HistorySidebarViewType:
|
||||
setColumnHidden(1, true);
|
||||
setColumnHidden(2, true);
|
||||
setColumnHidden(3, true);
|
||||
setHeaderHidden(true);
|
||||
setMouseTracking(true);
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QUrl HistoryTreeView::selectedUrl() const
|
||||
{
|
||||
const QList<QModelIndex> indexes = selectionModel()->selectedRows();
|
||||
|
||||
if (indexes.count() != 1)
|
||||
return QUrl();
|
||||
|
||||
// TopLevelItems have invalid (empty) UrlRole data
|
||||
return indexes.first().data(HistoryModel::UrlRole).toUrl();
|
||||
}
|
||||
|
||||
HeaderView* HistoryTreeView::header() const
|
||||
{
|
||||
return m_header;
|
||||
}
|
||||
|
||||
void HistoryTreeView::search(const QString &string)
|
||||
{
|
||||
m_filter->setFilterFixedString(string);
|
||||
}
|
||||
|
||||
void HistoryTreeView::removeSelectedItems()
|
||||
{
|
||||
QList<int> list;
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
QList<QPersistentModelIndex> topLevelIndexes;
|
||||
|
||||
foreach (const QModelIndex &index, selectedIndexes()) {
|
||||
if (index.column() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (index.data(HistoryModel::IsTopLevelRole).toBool()) {
|
||||
qint64 start = index.data(HistoryModel::TimestampStartRole).toLongLong();
|
||||
qint64 end = index.data(HistoryModel::TimestampEndRole).toLongLong();
|
||||
|
||||
list.append(m_history->indexesFromTimeRange(start, end));
|
||||
|
||||
topLevelIndexes.append(index);
|
||||
}
|
||||
else {
|
||||
int id = index.data(HistoryModel::IdRole).toInt();
|
||||
if (!list.contains(id)) {
|
||||
list.append(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_history->deleteHistoryEntry(list);
|
||||
m_history->model()->removeTopLevelIndexes(topLevelIndexes);
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void HistoryTreeView::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
emit contextMenuRequested(viewport()->mapToGlobal(event->pos()));
|
||||
}
|
||||
|
||||
void HistoryTreeView::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
QTreeView::mouseMoveEvent(event);
|
||||
|
||||
if (m_type == HistorySidebarViewType) {
|
||||
QCursor cursor = Qt::ArrowCursor;
|
||||
if (event->buttons() == Qt::NoButton) {
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
if (index.isValid() && !index.data(HistoryModel::IsTopLevelRole).toBool()) {
|
||||
cursor = Qt::PointingHandCursor;
|
||||
}
|
||||
}
|
||||
setCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryTreeView::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
QTreeView::mousePressEvent(event);
|
||||
|
||||
if (selectionModel()->selectedRows().count() == 1) {
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
Qt::MouseButtons buttons = event->buttons();
|
||||
Qt::KeyboardModifiers modifiers = event->modifiers();
|
||||
|
||||
if (index.isValid() && !index.data(HistoryModel::IsTopLevelRole).toBool()) {
|
||||
const QUrl url = index.data(HistoryModel::UrlRole).toUrl();
|
||||
|
||||
if (buttons == Qt::LeftButton && modifiers == Qt::ShiftModifier) {
|
||||
emit urlShiftActivated(url);
|
||||
}
|
||||
else if (buttons == Qt::MiddleButton || (buttons == Qt::LeftButton && modifiers == Qt::ControlModifier)) {
|
||||
emit urlCtrlActivated(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryTreeView::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
QTreeView::mouseReleaseEvent(event);
|
||||
|
||||
if (selectionModel()->selectedRows().count() == 1) {
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
|
||||
if (index.isValid() && !index.data(HistoryModel::IsTopLevelRole).toBool()) {
|
||||
const QUrl url = index.data(HistoryModel::UrlRole).toUrl();
|
||||
|
||||
// Activate urls with single mouse click in Sidebar
|
||||
if (m_type == HistorySidebarViewType && event->button() == Qt::LeftButton && event->modifiers() == Qt::NoModifier) {
|
||||
emit urlActivated(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryTreeView::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
QTreeView::mouseDoubleClickEvent(event);
|
||||
|
||||
if (selectionModel()->selectedRows().count() == 1) {
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
|
||||
if (index.isValid() && !index.data(HistoryModel::IsTopLevelRole).toBool()) {
|
||||
const QUrl url = index.data(HistoryModel::UrlRole).toUrl();
|
||||
Qt::MouseButtons buttons = event->buttons();
|
||||
Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
|
||||
|
||||
if (buttons == Qt::LeftButton && modifiers == Qt::NoModifier) {
|
||||
emit urlActivated(url);
|
||||
}
|
||||
else if (buttons == Qt::LeftButton && modifiers == Qt::ShiftModifier) {
|
||||
emit urlShiftActivated(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryTreeView::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
QTreeView::keyPressEvent(event);
|
||||
|
||||
if (selectionModel()->selectedRows().count() == 1) {
|
||||
QModelIndex index = selectionModel()->selectedRows().first();
|
||||
const QUrl url = index.data(HistoryModel::UrlRole).toUrl();
|
||||
const bool isTopLevel = index.data(HistoryModel::IsTopLevelRole).toBool();
|
||||
|
||||
switch (event->key()) {
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
if (isTopLevel && event->modifiers() == Qt::NoModifier) {
|
||||
setExpanded(index, !isExpanded(index));
|
||||
}
|
||||
else {
|
||||
Qt::KeyboardModifiers modifiers = event->modifiers();
|
||||
|
||||
if (modifiers == Qt::NoModifier) {
|
||||
emit urlActivated(url);
|
||||
}
|
||||
else if (modifiers == Qt::ControlModifier) {
|
||||
emit urlCtrlActivated(url);
|
||||
}
|
||||
else if (modifiers == Qt::ShiftModifier) {
|
||||
emit urlShiftActivated(url);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Delete:
|
||||
removeSelectedItems();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryTreeView::drawRow(QPainter* painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
|
||||
{
|
||||
bool itemTopLevel = index.data(HistoryModel::IsTopLevelRole).toBool();
|
||||
bool iconLoaded = index.data(HistoryModel::IconLoadedRole).toBool();
|
||||
|
||||
if (index.isValid() && !itemTopLevel && !iconLoaded) {
|
||||
const QIcon icon = IconProvider::iconForUrl(index.data(HistoryModel::UrlRole).toUrl());
|
||||
model()->setData(index, icon, HistoryModel::IconRole);
|
||||
}
|
||||
|
||||
QTreeView::drawRow(painter, options, index);
|
||||
}
|
@ -15,8 +15,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef HISTORYVIEW_H
|
||||
#define HISTORYVIEW_H
|
||||
#ifndef HISTORYTREEVIEW_H
|
||||
#define HISTORYTREEVIEW_H
|
||||
|
||||
#include <QTreeView>
|
||||
|
||||
@ -24,43 +24,58 @@ class History;
|
||||
class HistoryFilterModel;
|
||||
class HeaderView;
|
||||
|
||||
class HistoryView : public QTreeView
|
||||
class HistoryTreeView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum OpenBehavior { OpenInCurrentTab, OpenInNewTab };
|
||||
enum ViewType {
|
||||
HistoryManagerViewType,
|
||||
HistorySidebarViewType
|
||||
};
|
||||
|
||||
explicit HistoryView(QWidget* parent = 0);
|
||||
explicit HistoryTreeView(QWidget* parent = 0);
|
||||
|
||||
ViewType viewType() const;
|
||||
void setViewType(ViewType type);
|
||||
|
||||
// Returns empty url if more than one (or zero) urls are selected
|
||||
QUrl selectedUrl() const;
|
||||
|
||||
HeaderView* header() const;
|
||||
HistoryFilterModel* filterModel() const;
|
||||
|
||||
signals:
|
||||
void openLink(const QUrl &, HistoryView::OpenBehavior);
|
||||
// Open url in current tab
|
||||
void urlActivated(const QUrl &url);
|
||||
// Open url in new tab
|
||||
void urlCtrlActivated(const QUrl &url);
|
||||
// Open url in new window
|
||||
void urlShiftActivated(const QUrl &url);
|
||||
// Context menu signal with point mapped to global
|
||||
void contextMenuRequested(const QPoint &point);
|
||||
|
||||
public slots:
|
||||
void removeItems();
|
||||
void search(const QString &string);
|
||||
void removeSelectedItems();
|
||||
|
||||
private slots:
|
||||
void itemActivated(const QModelIndex &index);
|
||||
void itemPressed(const QModelIndex &index);
|
||||
|
||||
void openLinkInCurrentTab();
|
||||
void openLinkInNewTab();
|
||||
void copyTitle();
|
||||
void copyAddress();
|
||||
|
||||
protected:
|
||||
void contextMenuEvent(QContextMenuEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
|
||||
void drawRow(QPainter* painter, const QStyleOptionViewItem &options, const QModelIndex &index) const;
|
||||
|
||||
private:
|
||||
History* m_history;
|
||||
HistoryFilterModel* m_filterModel;
|
||||
HistoryFilterModel* m_filter;
|
||||
HeaderView* m_header;
|
||||
|
||||
QModelIndex m_clickedIndex;
|
||||
ViewType m_type;
|
||||
};
|
||||
|
||||
#endif // HISTORYVIEW_H
|
||||
#endif // HISTORYTREEVIEW_H
|
@ -1,193 +0,0 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2014 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "historyview.h"
|
||||
#include "historymodel.h"
|
||||
#include "historyitem.h"
|
||||
#include "headerview.h"
|
||||
#include "mainapplication.h"
|
||||
#include "iconprovider.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QKeyEvent>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
|
||||
HistoryView::HistoryView(QWidget* parent)
|
||||
: QTreeView(parent)
|
||||
, m_history(mApp->history())
|
||||
, m_filterModel(new HistoryFilterModel(m_history->model()))
|
||||
{
|
||||
setModel(m_filterModel);
|
||||
|
||||
setAllColumnsShowFocus(true);
|
||||
setUniformRowHeights(true);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
m_header = new HeaderView(this);
|
||||
setHeader(m_header);
|
||||
|
||||
m_header->setDefaultSectionSizes(QList<double>() << 0.4 << 0.35 << 0.10 << 0.08);
|
||||
m_header->setSectionHidden(4, true);
|
||||
|
||||
connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(itemActivated(QModelIndex)));
|
||||
connect(this, SIGNAL(pressed(QModelIndex)), this, SLOT(itemPressed(QModelIndex)));
|
||||
|
||||
connect(m_filterModel, SIGNAL(expandAllItems()), this, SLOT(expandAll()));
|
||||
connect(m_filterModel, SIGNAL(collapseAllItems()), this, SLOT(collapseAll()));
|
||||
}
|
||||
|
||||
HeaderView* HistoryView::header() const
|
||||
{
|
||||
return m_header;
|
||||
}
|
||||
|
||||
HistoryFilterModel* HistoryView::filterModel() const
|
||||
{
|
||||
return m_filterModel;
|
||||
}
|
||||
|
||||
void HistoryView::removeItems()
|
||||
{
|
||||
QList<int> list;
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
QList<QPersistentModelIndex> topLevelIndexes;
|
||||
|
||||
foreach (const QModelIndex &index, selectedIndexes()) {
|
||||
if (index.column() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (index.data(HistoryModel::IsTopLevelRole).toBool()) {
|
||||
qint64 start = index.data(HistoryModel::TimestampStartRole).toLongLong();
|
||||
qint64 end = index.data(HistoryModel::TimestampEndRole).toLongLong();
|
||||
|
||||
list.append(m_history->indexesFromTimeRange(start, end));
|
||||
|
||||
topLevelIndexes.append(index);
|
||||
}
|
||||
else {
|
||||
int id = index.data(HistoryModel::IdRole).toInt();
|
||||
if (!list.contains(id)) {
|
||||
list.append(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_history->deleteHistoryEntry(list);
|
||||
m_history->model()->removeTopLevelIndexes(topLevelIndexes);
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void HistoryView::itemActivated(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid() || index.data(HistoryModel::IsTopLevelRole).toBool()) {
|
||||
return;
|
||||
}
|
||||
|
||||
emit openLink(index.data(HistoryModel::UrlRole).toUrl(), OpenInCurrentTab);
|
||||
}
|
||||
|
||||
void HistoryView::itemPressed(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid() || index.data(HistoryModel::IsTopLevelRole).toBool()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((selectionMode() == QAbstractItemView::SingleSelection && QApplication::keyboardModifiers() & Qt::ControlModifier) ||
|
||||
QApplication::mouseButtons() & Qt::MiddleButton
|
||||
) {
|
||||
emit openLink(index.data(HistoryModel::UrlRole).toUrl(), OpenInNewTab);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryView::openLinkInCurrentTab()
|
||||
{
|
||||
if (m_clickedIndex.isValid()) {
|
||||
emit openLink(m_clickedIndex.data(HistoryModel::UrlRole).toUrl(), OpenInCurrentTab);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryView::openLinkInNewTab()
|
||||
{
|
||||
if (m_clickedIndex.isValid()) {
|
||||
emit openLink(m_clickedIndex.data(HistoryModel::UrlRole).toUrl(), OpenInNewTab);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryView::copyTitle()
|
||||
{
|
||||
if (m_clickedIndex.isValid()) {
|
||||
QApplication::clipboard()->setText(m_clickedIndex.data(HistoryModel::TitleRole).toString());
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryView::copyAddress()
|
||||
{
|
||||
if (m_clickedIndex.isValid()) {
|
||||
QApplication::clipboard()->setText(m_clickedIndex.data(HistoryModel::UrlStringRole).toString());
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryView::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
const QModelIndex index = indexAt(event->pos());
|
||||
if (!index.isValid() || index.data(HistoryModel::IsTopLevelRole).toBool()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_clickedIndex = index;
|
||||
|
||||
QMenu menu;
|
||||
menu.addAction(tr("Open link in current tab"), this, SLOT(openLinkInCurrentTab()));
|
||||
menu.addAction(tr("Open link in new tab"), this, SLOT(openLinkInNewTab()));
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("Copy title"), this, SLOT(copyTitle()));
|
||||
menu.addAction(tr("Copy address"), this, SLOT(copyAddress()));
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("Remove"), this, SLOT(removeItems()));
|
||||
|
||||
// Prevent choosing first option with double rightclick
|
||||
QPoint pos = viewport()->mapToGlobal(event->pos());
|
||||
QPoint p(pos.x(), pos.y() + 1);
|
||||
menu.exec(p);
|
||||
}
|
||||
|
||||
void HistoryView::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Delete) {
|
||||
removeItems();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
QTreeView::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void HistoryView::drawRow(QPainter* painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
|
||||
{
|
||||
bool itemTopLevel = index.data(HistoryModel::IsTopLevelRole).toBool();
|
||||
bool iconLoaded = index.data(HistoryModel::IconLoadedRole).toBool();
|
||||
|
||||
if (index.isValid() && !itemTopLevel && !iconLoaded) {
|
||||
const QIcon icon = IconProvider::iconForUrl(index.data(HistoryModel::UrlRole).toUrl());
|
||||
model()->setData(index, icon, HistoryModel::IconRole);
|
||||
}
|
||||
|
||||
QTreeView::drawRow(painter, options, index);
|
||||
}
|
@ -115,7 +115,7 @@ SOURCES += \
|
||||
history/historymanager.cpp \
|
||||
history/historymenu.cpp \
|
||||
history/historymodel.cpp \
|
||||
history/historyview.cpp \
|
||||
history/historytreeview.cpp \
|
||||
history/webhistoryinterface.cpp \
|
||||
navigation/completer/locationcompleter.cpp \
|
||||
navigation/completer/locationcompleterdelegate.cpp \
|
||||
@ -314,7 +314,7 @@ HEADERS += \
|
||||
history/historymanager.h \
|
||||
history/historymenu.h \
|
||||
history/historymodel.h \
|
||||
history/historyview.h \
|
||||
history/historytreeview.h \
|
||||
history/webhistoryinterface.h \
|
||||
navigation/completer/locationcompleterdelegate.h \
|
||||
navigation/completer/locationcompleter.h \
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "tabwidget.h"
|
||||
#include "tabbedwebview.h"
|
||||
#include "mainapplication.h"
|
||||
#include "historymodel.h"
|
||||
#include "qzsettings.h"
|
||||
#include "iconprovider.h"
|
||||
|
||||
HistorySideBar::HistorySideBar(BrowserWindow* window, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
@ -30,24 +30,77 @@ HistorySideBar::HistorySideBar(BrowserWindow* window, QWidget* parent)
|
||||
, m_window(window)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->historyTree->setViewType(HistoryTreeView::HistorySidebarViewType);
|
||||
|
||||
ui->historyTree->setColumnHidden(1, true);
|
||||
ui->historyTree->setColumnHidden(2, true);
|
||||
ui->historyTree->setColumnHidden(3, true);
|
||||
ui->historyTree->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
connect(ui->historyTree, SIGNAL(urlActivated(QUrl)), this, SLOT(urlActivated(QUrl)));
|
||||
connect(ui->historyTree, SIGNAL(urlCtrlActivated(QUrl)), this, SLOT(urlCtrlActivated(QUrl)));
|
||||
connect(ui->historyTree, SIGNAL(urlShiftActivated(QUrl)), this, SLOT(urlShiftActivated(QUrl)));
|
||||
connect(ui->historyTree, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(createContextMenu(QPoint)));
|
||||
|
||||
connect(ui->historyTree, SIGNAL(openLink(QUrl,HistoryView::OpenBehavior)), this, SLOT(openLink(QUrl,HistoryView::OpenBehavior)));
|
||||
connect(ui->search, SIGNAL(textEdited(QString)), ui->historyTree->filterModel(), SLOT(setFilterFixedString(QString)));
|
||||
connect(ui->search, SIGNAL(textEdited(QString)), ui->historyTree, SLOT(search(QString)));
|
||||
}
|
||||
|
||||
void HistorySideBar::openLink(const QUrl &url, HistoryView::OpenBehavior openIn)
|
||||
void HistorySideBar::urlActivated(const QUrl &url)
|
||||
{
|
||||
if (openIn == HistoryView::OpenInNewTab) {
|
||||
m_window->tabWidget()->addView(url, qzSettings->newTabPosition);
|
||||
}
|
||||
else {
|
||||
m_window->weView()->load(url);
|
||||
openUrl(url);
|
||||
}
|
||||
|
||||
void HistorySideBar::urlCtrlActivated(const QUrl &url)
|
||||
{
|
||||
openUrlInNewTab(url);
|
||||
}
|
||||
|
||||
void HistorySideBar::urlShiftActivated(const QUrl &url)
|
||||
{
|
||||
openUrlInNewWindow(url);
|
||||
}
|
||||
|
||||
void HistorySideBar::openUrl(const QUrl &url)
|
||||
{
|
||||
const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl();
|
||||
m_window->weView()->load(u);
|
||||
}
|
||||
|
||||
void HistorySideBar::openUrlInNewTab(const QUrl &url)
|
||||
{
|
||||
const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl();
|
||||
m_window->tabWidget()->addView(u, qzSettings->newTabPosition);
|
||||
}
|
||||
|
||||
void HistorySideBar::openUrlInNewWindow(const QUrl &url)
|
||||
{
|
||||
const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl();
|
||||
mApp->createWindow(Qz::BW_NewWindow, u);
|
||||
}
|
||||
|
||||
void HistorySideBar::openUrlInNewPrivateWindow(const QUrl &url)
|
||||
{
|
||||
const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl();
|
||||
mApp->startPrivateBrowsing(u);
|
||||
}
|
||||
|
||||
void HistorySideBar::createContextMenu(const QPoint &pos)
|
||||
{
|
||||
QMenu menu;
|
||||
QAction* actNewTab = menu.addAction(IconProvider::newTabIcon(), tr("Open in new tab"));
|
||||
QAction* actNewWindow = menu.addAction(IconProvider::newWindowIcon(), tr("Open in new window"));
|
||||
QAction* actNewPrivateWindow = menu.addAction(IconProvider::privateBrowsingIcon(), tr("Open in new private window"));
|
||||
|
||||
menu.addSeparator();
|
||||
QAction* actDelete = menu.addAction(QIcon::fromTheme(QSL("edit-delete")), tr("Delete"));
|
||||
|
||||
connect(actNewTab, SIGNAL(triggered()), this, SLOT(openUrlInNewTab()));
|
||||
connect(actNewWindow, SIGNAL(triggered()), this, SLOT(openUrlInNewWindow()));
|
||||
connect(actNewPrivateWindow, SIGNAL(triggered()), this, SLOT(openUrlInNewPrivateWindow()));
|
||||
connect(actDelete, SIGNAL(triggered()), ui->historyTree, SLOT(removeSelectedItems()));
|
||||
|
||||
if (ui->historyTree->selectedUrl().isEmpty()) {
|
||||
actNewTab->setDisabled(true);
|
||||
actNewWindow->setDisabled(true);
|
||||
actNewPrivateWindow->setDisabled(true);
|
||||
}
|
||||
|
||||
menu.exec(pos);
|
||||
}
|
||||
|
||||
HistorySideBar::~HistorySideBar()
|
||||
|
@ -19,9 +19,9 @@
|
||||
#define HISTORYSIDEBAR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QUrl>
|
||||
|
||||
#include "qzcommon.h"
|
||||
#include "historyview.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -39,7 +39,16 @@ public:
|
||||
~HistorySideBar();
|
||||
|
||||
private slots:
|
||||
void openLink(const QUrl &url, HistoryView::OpenBehavior openIn);
|
||||
void urlActivated(const QUrl &url);
|
||||
void urlCtrlActivated(const QUrl &url);
|
||||
void urlShiftActivated(const QUrl &url);
|
||||
|
||||
void openUrl(const QUrl &url = QUrl());
|
||||
void openUrlInNewTab(const QUrl &url = QUrl());
|
||||
void openUrlInNewWindow(const QUrl &url = QUrl());
|
||||
void openUrlInNewPrivateWindow(const QUrl &url = QUrl());
|
||||
|
||||
void createContextMenu(const QPoint &pos);
|
||||
|
||||
private:
|
||||
Ui::HistorySideBar* ui;
|
||||
|
@ -34,7 +34,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="HistoryView" name="historyTree">
|
||||
<widget class="HistoryTreeView" name="historyTree">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -47,9 +47,9 @@
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>HistoryView</class>
|
||||
<class>HistoryTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>historyview.h</header>
|
||||
<header>historytreeview.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
|
Loading…
Reference in New Issue
Block a user