1
mirror of https://invent.kde.org/network/falkon.git synced 2024-11-11 01:22:10 +01:00

Added possibility to change icon of bookmarks

- created new IconChooser class with option to choose
  icon from file or icon from database

Closes #401
This commit is contained in:
nowrep 2012-05-22 11:46:22 +02:00
parent d6a859b367
commit cf5d399f00
11 changed files with 407 additions and 19 deletions

View File

@ -27,6 +27,7 @@
#include "browsinglibrary.h"
#include "globalfunctions.h"
#include "bookmarksimportdialog.h"
#include "iconchooser.h"
#include "webtab.h"
#include <QInputDialog>
@ -66,8 +67,6 @@ BookmarksManager::BookmarksManager(QupZilla* mainClass, QWidget* parent)
connect(deleteAction, SIGNAL(activated()), this, SLOT(deleteItem()));
ui->bookmarksTree->setDefaultItemShowMode(TreeWidget::ItemsExpanded);
//QTimer::singleShot(0, this, SLOT(refreshTable()));
}
void BookmarksManager::importBookmarks()
@ -151,6 +150,24 @@ void BookmarksManager::renameBookmark()
ui->bookmarksTree->editItem(item, 0);
}
void BookmarksManager::changeIcon()
{
QTreeWidgetItem* item = ui->bookmarksTree->currentItem();
if (!item) {
return;
}
int id = item->data(0, Qt::UserRole + 10).toInt();
QIcon icon;
IconChooser chooser(this);
icon = chooser.exec();
if (!icon.isNull()) {
m_bookmarksModel->changeIcon(id, icon);
}
}
void BookmarksManager::itemChanged(QTreeWidgetItem* item)
{
if (!item || m_isRefreshing || item->text(1).isEmpty()) {
@ -213,6 +230,7 @@ void BookmarksManager::moveBookmark()
if (!item) {
return;
}
if (QAction* action = qobject_cast<QAction*>(sender())) {
int id = item->data(0, Qt::UserRole + 10).toInt();
@ -225,7 +243,8 @@ void BookmarksManager::contextMenuRequested(const QPoint &position)
if (!ui->bookmarksTree->itemAt(position)) {
return;
}
QString link = ui->bookmarksTree->itemAt(position)->text(1);
QUrl link = ui->bookmarksTree->itemAt(position)->data(0, Qt::UserRole + 11).toUrl();
if (link.isEmpty()) {
QString folderName = ui->bookmarksTree->itemAt(position)->text(0);
QMenu menu;
@ -268,6 +287,7 @@ void BookmarksManager::contextMenuRequested(const QPoint &position)
menu.addMenu(&moveMenu);
menu.addSeparator();
menu.addAction(tr("Change icon"), this, SLOT(changeIcon()));
menu.addAction(tr("Rename bookmark"), this, SLOT(renameBookmark()));
menu.addAction(tr("Remove bookmark"), this, SLOT(deleteItem()));
@ -331,6 +351,7 @@ void BookmarksManager::refreshTable()
item->setToolTip(1, url.toEncoded());
item->setData(0, Qt::UserRole + 10, id);
item->setData(0, Qt::UserRole + 11, url);
item->setIcon(0, icon);
item->setFlags(item->flags() | Qt::ItemIsEditable);
ui->bookmarksTree->addTopLevelItem(item);
@ -359,6 +380,7 @@ void BookmarksManager::refreshTable()
item->setToolTip(1, url.toEncoded());
item->setData(0, Qt::UserRole + 10, id);
item->setData(0, Qt::UserRole + 11, url);
item->setIcon(0, icon);
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
@ -378,6 +400,7 @@ void BookmarksManager::addBookmark(const BookmarksModel::Bookmark &bookmark)
item->setText(0, bookmark.title);
item->setText(1, bookmark.url.toEncoded());
item->setData(0, Qt::UserRole + 10, bookmark.id);
item->setData(0, Qt::UserRole + 11, bookmark.url);
item->setIcon(0, qIconProvider->iconFromImage(bookmark.image));
item->setToolTip(0, bookmark.title);
item->setToolTip(1, bookmark.url.toEncoded());

View File

@ -63,6 +63,7 @@ private slots:
void itemControlClicked(QTreeWidgetItem* item);
void moveBookmark();
void renameBookmark();
void changeIcon();
void importBookmarks();
void addFolder(const QString &name);

View File

@ -280,13 +280,13 @@ bool BookmarksModel::editBookmark(int id, const QString &title, const QUrl &url,
if (title.isEmpty() && url.isEmpty() && folder.isEmpty()) {
return false;
}
QSqlQuery query;
if (!query.exec("SELECT title, url, folder, icon FROM bookmarks WHERE id = " + QString::number(id))) {
query.exec("SELECT title, url, folder, icon FROM bookmarks WHERE id = " + QString::number(id));
if (!query.next()) {
return false;
}
query.next();
Bookmark before;
before.id = id;
before.title = query.value(0).toString();
@ -318,6 +318,42 @@ bool BookmarksModel::editBookmark(int id, const QString &title, const QUrl &url,
return true;
}
bool BookmarksModel::changeIcon(int id, const QIcon &icon)
{
QSqlQuery query;
query.exec("SELECT title, url, folder, icon FROM bookmarks WHERE id = " + QString::number(id));
if (!query.next()) {
return false;
}
Bookmark before;
before.id = id;
before.title = query.value(0).toString();
before.url = query.value(1).toUrl();
before.folder = query.value(2).toString();
before.image = QImage::fromData(query.value(3).toByteArray());
before.inSubfolder = isSubfolder(before.folder);
Bookmark after = before;
after.image = icon.pixmap(16).toImage();
query.prepare("UPDATE bookmarks SET icon = ? WHERE id = ?");
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
after.image.save(&buffer, "PNG");
query.bindValue(0, buffer.data());
query.bindValue(1, id);
if (!query.exec()) {
return false;
}
emit bookmarkEdited(before, after);
mApp->sendMessages(Qz::AM_BookmarksChanged, true);
return true;
}
bool BookmarksModel::createFolder(const QString &name)
{
if (isFolder(name)) {

View File

@ -86,8 +86,7 @@ public:
void removeBookmark(const QList<int> list);
bool editBookmark(int id, const QString &title = "", const QUrl &url = QUrl(), const QString &folder = "");
// bool editBookmark(int id, const QString &title, const QString &folder);
// bool editBookmark(int id, const QUrl &url, const QString &title);
bool changeIcon(int id, const QIcon &icon);
bool createFolder(const QString &name);
void removeFolder(const QString &name);

View File

@ -177,7 +177,8 @@ SOURCES += \
history/historymodel.cpp \
history/historyview.cpp \
history/historyitem.cpp \
tools/headerview.cpp
tools/headerview.cpp \
other/iconchooser.cpp
HEADERS += \
webview/tabpreview.h \
@ -326,7 +327,8 @@ HEADERS += \
history/historymodel.h \
history/historyview.h \
history/historyitem.h \
tools/headerview.h
tools/headerview.h \
other/iconchooser.h
FORMS += \
preferences/autofillmanager.ui \
@ -367,7 +369,8 @@ FORMS += \
opensearch/searchenginesdialog.ui \
opensearch/editsearchengine.ui \
bookmarksimport/bookmarksimportdialog.ui \
other/checkboxdialog.ui
other/checkboxdialog.ui \
other/iconchooser.ui
RESOURCES += \
data/icons.qrc \

View File

@ -17,6 +17,7 @@
* ============================================================ */
#include "editsearchengine.h"
#include "ui_editsearchengine.h"
#include "iconchooser.h"
#include <QFileDialog>
@ -87,12 +88,10 @@ void EditSearchEngine::hideIconLabels()
void EditSearchEngine::chooseIcon()
{
const QString &fileTypes = QString("%3(*.png *.jpg *.jpeg *.bmp *.gif *.svg *.tiff)").arg(tr("Image files"));
IconChooser chooser(this);
QIcon icon = chooser.exec();
QString path = QFileDialog::getOpenFileName(this, tr("Choose icon..."), QDir::homePath(), fileTypes);
if (path.isEmpty()) {
return;
if (!icon.isNull()) {
setIcon(icon);
}
setIcon(QIcon(path));
}

View File

@ -94,7 +94,7 @@
<item>
<widget class="QPushButton" name="iconFromFile">
<property name="text">
<string>Add from file ...</string>
<string>Change...</string>
</property>
</widget>
</item>

View File

@ -0,0 +1,130 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2012 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 "iconchooser.h"
#include "ui_iconchooser.h"
#include <QFileDialog>
#include <QSqlQuery>
IconChooser::IconChooser(QWidget* parent)
: QDialog(parent),
ui(new Ui::IconChooser)
{
ui->setupUi(this);
ui->iconList->setItemDelegate(new IconChooserDelegate(ui->iconList));
connect(ui->chooseFile, SIGNAL(clicked()), this, SLOT(chooseFile()));
connect(ui->siteUrl, SIGNAL(textChanged(QString)), this, SLOT(searchIcon(QString)));
}
void IconChooser::chooseFile()
{
const QString &fileTypes = QString("%3(*.png *.jpg *.jpeg *.gif)").arg(tr("Image files"));
const QString &path = QFileDialog::getOpenFileName(this, tr("Choose icon..."), QDir::homePath(), fileTypes);
if (path.isEmpty()) {
return;
}
ui->iconList->clear();
QIcon icon(path);
if (!icon.isNull()) {
QListWidgetItem* item = new QListWidgetItem(ui->iconList);
item->setIcon(icon);
ui->iconList->setCurrentItem(item);
}
}
void IconChooser::searchIcon(const QString &string)
{
if (string.size() < 4) {
return;
}
ui->iconList->clear();
QSqlQuery query;
query.prepare("SELECT icon FROM icons WHERE url LIKE ? LIMIT 20");
query.bindValue(0, QString("%%1%").arg(string));
query.exec();
while (query.next()) {
QImage image = QImage::fromData(query.value(0).toByteArray());
if (!image.isNull()) {
QListWidgetItem* item = new QListWidgetItem(ui->iconList);
item->setIcon(QPixmap::fromImage(image));
}
}
}
QIcon IconChooser::exec()
{
QIcon icon;
int status = QDialog::exec();
if (status == QDialog::Accepted) {
QList<QListWidgetItem*> selectedItems = ui->iconList->selectedItems();
if (!selectedItems.isEmpty()) {
icon = selectedItems.at(0)->icon();
}
}
// Ensure we are returning 16×16px icon
if (!icon.isNull()) {
icon = icon.pixmap(16);
}
return icon;
}
IconChooser::~IconChooser()
{
delete ui;
}
IconChooserDelegate::IconChooserDelegate(QWidget* parent)
: QStyledItemDelegate(parent)
{
}
void IconChooserDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
const QWidget* w = opt.widget;
const QStyle* style = w ? w->style() : QApplication::style();
// Draw background
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w);
// Draw icon
QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
icon.paint(painter, opt.rect);
}
QSize IconChooserDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(option)
Q_UNUSED(index)
return QSize(48, 48);
}

View File

@ -0,0 +1,60 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2012 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/>.
* ============================================================ */
#ifndef ICONCHOOSER_H
#define ICONCHOOSER_H
#include <QDialog>
#include <QStyledItemDelegate>
#include "qz_namespace.h"
class QIcon;
namespace Ui
{
class IconChooser;
}
class QT_QUPZILLA_EXPORT IconChooser : public QDialog
{
Q_OBJECT
public:
explicit IconChooser(QWidget* parent = 0);
~IconChooser();
QIcon exec();
private slots:
void chooseFile();
void searchIcon(const QString &string);
private:
Ui::IconChooser* ui;
};
class QT_QUPZILLA_EXPORT IconChooserDelegate : public QStyledItemDelegate
{
public:
explicit IconChooserDelegate(QWidget* parent = 0);
void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#endif // ICONCHOOSER_H

View File

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IconChooser</class>
<widget class="QDialog" name="IconChooser">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>388</width>
<height>326</height>
</rect>
</property>
<property name="windowTitle">
<string>Choose icon...</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>From file</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Image (.png, .jpg, .jpeg, .gif)</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="chooseFile">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Choose file...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>From database</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Site Url:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="siteUrl"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="iconList">
<property name="movement">
<enum>QListView::Static</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>IconChooser</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>IconChooser</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -315,7 +315,6 @@ void TabWidget::closeTab(int index)
index = currentIndex();
}
WebTab* webTab = weTab(index);
if (!webTab) {
return;