mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-22 19:56:34 +01:00
9c7d6e9795
It now works correctly with Windows, Gtk+, Oxygen and Fusion theme with both Qt4 and Qt5. The only theme that doesn't work correctly is Bespin, because it draws icon size animation upon hover, but we are drawing the icon and text manually. I think there is not much to do with it actually...
337 lines
9.2 KiB
C++
337 lines
9.2 KiB
C++
/* ============================================================
|
|
* QupZilla - WebKit based browser
|
|
* Copyright (C) 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 "bookmarkstoolbarbutton.h"
|
|
#include "bookmarkstools.h"
|
|
#include "bookmarkitem.h"
|
|
#include "bookmarks.h"
|
|
#include "mainapplication.h"
|
|
#include "enhancedmenu.h"
|
|
|
|
#include <QStyle>
|
|
#include <QPainter>
|
|
#include <QMouseEvent>
|
|
#include <QStyleOptionButton>
|
|
|
|
#define MAX_WIDTH 150
|
|
#define SEPARATOR_WIDTH 8
|
|
#define PADDING 5
|
|
|
|
BookmarksToolbarButton::BookmarksToolbarButton(BookmarkItem* bookmark, QWidget* parent)
|
|
: QPushButton(parent)
|
|
, m_bookmark(bookmark)
|
|
, m_window(0)
|
|
, m_showOnlyIcon(false)
|
|
{
|
|
init();
|
|
}
|
|
|
|
BookmarkItem* BookmarksToolbarButton::bookmark() const
|
|
{
|
|
return m_bookmark;
|
|
}
|
|
|
|
void BookmarksToolbarButton::setMainWindow(BrowserWindow* window)
|
|
{
|
|
m_window = window;
|
|
}
|
|
|
|
bool BookmarksToolbarButton::showOnlyIcon() const
|
|
{
|
|
return m_showOnlyIcon;
|
|
}
|
|
|
|
void BookmarksToolbarButton::setShowOnlyIcon(bool show)
|
|
{
|
|
m_showOnlyIcon = show;
|
|
updateGeometry();
|
|
}
|
|
|
|
QSize BookmarksToolbarButton::sizeHint() const
|
|
{
|
|
int width = PADDING * 2 + 16;
|
|
|
|
if (m_bookmark->isSeparator()) {
|
|
width = SEPARATOR_WIDTH;
|
|
}
|
|
else if (!m_showOnlyIcon) {
|
|
width += PADDING * 2 + fontMetrics().width(m_bookmark->title());
|
|
|
|
if (menu()) {
|
|
width += PADDING + 8;
|
|
}
|
|
}
|
|
|
|
return QSize(qMin(width, MAX_WIDTH), preferredHeight());
|
|
}
|
|
|
|
QSize BookmarksToolbarButton::minimumSizeHint() const
|
|
{
|
|
int width = PADDING * 2 + 16;
|
|
|
|
if (m_bookmark->isSeparator()) {
|
|
width = SEPARATOR_WIDTH;
|
|
}
|
|
else if (!m_showOnlyIcon && menu()) {
|
|
width += PADDING + 8;
|
|
}
|
|
|
|
return QSize(width, preferredHeight());
|
|
}
|
|
|
|
int BookmarksToolbarButton::preferredHeight() const
|
|
{
|
|
return fontMetrics().height() + PADDING * 2;
|
|
}
|
|
|
|
void BookmarksToolbarButton::createMenu()
|
|
{
|
|
if (!menu()->isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
Menu* m = qobject_cast<Menu*>(menu());
|
|
Q_ASSERT(m);
|
|
|
|
foreach (BookmarkItem* child, m_bookmark->children()) {
|
|
BookmarksTools::addActionToMenu(this, m, child);
|
|
}
|
|
|
|
if (m->isEmpty()) {
|
|
m->addAction(Bookmarks::tr("Empty"))->setDisabled(true);
|
|
}
|
|
}
|
|
|
|
void BookmarksToolbarButton::menuMiddleClicked(Menu* menu)
|
|
{
|
|
BookmarkItem* item = static_cast<BookmarkItem*>(menu->menuAction()->data().value<void*>());
|
|
Q_ASSERT(item);
|
|
openFolder(item);
|
|
}
|
|
|
|
void BookmarksToolbarButton::bookmarkActivated(BookmarkItem* item)
|
|
{
|
|
if (QAction* action = qobject_cast<QAction*>(sender())) {
|
|
item = static_cast<BookmarkItem*>(action->data().value<void*>());
|
|
}
|
|
|
|
Q_ASSERT(item);
|
|
openBookmark(item);
|
|
}
|
|
|
|
void BookmarksToolbarButton::bookmarkCtrlActivated(BookmarkItem* item)
|
|
{
|
|
if (QAction* action = qobject_cast<QAction*>(sender())) {
|
|
item = static_cast<BookmarkItem*>(action->data().value<void*>());
|
|
}
|
|
|
|
Q_ASSERT(item);
|
|
openBookmarkInNewTab(item);
|
|
}
|
|
|
|
void BookmarksToolbarButton::bookmarkShiftActivated(BookmarkItem* item)
|
|
{
|
|
if (QAction* action = qobject_cast<QAction*>(sender())) {
|
|
item = static_cast<BookmarkItem*>(action->data().value<void*>());
|
|
}
|
|
|
|
Q_ASSERT(item);
|
|
openBookmarkInNewWindow(item);
|
|
}
|
|
|
|
void BookmarksToolbarButton::openFolder(BookmarkItem* item)
|
|
{
|
|
Q_ASSERT(item->isFolder());
|
|
|
|
if (m_window) {
|
|
BookmarksTools::openFolderInTabs(m_window, item);
|
|
}
|
|
}
|
|
|
|
void BookmarksToolbarButton::openBookmark(BookmarkItem* item)
|
|
{
|
|
Q_ASSERT(item->isUrl());
|
|
|
|
if (m_window) {
|
|
BookmarksTools::openBookmark(m_window, item);
|
|
}
|
|
}
|
|
|
|
void BookmarksToolbarButton::openBookmarkInNewTab(BookmarkItem* item)
|
|
{
|
|
Q_ASSERT(item->isUrl());
|
|
|
|
if (m_window) {
|
|
BookmarksTools::openBookmarkInNewTab(m_window, item);
|
|
}
|
|
}
|
|
|
|
void BookmarksToolbarButton::openBookmarkInNewWindow(BookmarkItem* item)
|
|
{
|
|
Q_ASSERT(item->isUrl());
|
|
|
|
BookmarksTools::openBookmarkInNewWindow(item);
|
|
}
|
|
|
|
void BookmarksToolbarButton::init()
|
|
{
|
|
Q_ASSERT(m_bookmark);
|
|
|
|
setFocusPolicy(Qt::NoFocus);
|
|
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
|
setToolTip(createTooltip());
|
|
|
|
if (m_bookmark->isFolder()) {
|
|
Menu* m = new Menu(this);
|
|
connect(m, SIGNAL(aboutToShow()), this, SLOT(createMenu()));
|
|
connect(m, SIGNAL(menuMiddleClicked(Menu*)), this, SLOT(menuMiddleClicked(Menu*)));
|
|
setMenu(m);
|
|
}
|
|
}
|
|
|
|
QString BookmarksToolbarButton::createTooltip() const
|
|
{
|
|
if (!m_bookmark->description().isEmpty()) {
|
|
if (!m_bookmark->urlString().isEmpty()) {
|
|
return QString("%1\n%2").arg(m_bookmark->description(), m_bookmark->urlString());
|
|
}
|
|
return m_bookmark->description();
|
|
}
|
|
|
|
if (!m_bookmark->url().isEmpty()) {
|
|
return QString("%1\n%2").arg(m_bookmark->title(), m_bookmark->urlString());
|
|
}
|
|
|
|
return m_bookmark->title();
|
|
}
|
|
|
|
void BookmarksToolbarButton::enterEvent(QEvent* event)
|
|
{
|
|
QPushButton::enterEvent(event);
|
|
|
|
update();
|
|
}
|
|
|
|
void BookmarksToolbarButton::leaveEvent(QEvent* event)
|
|
{
|
|
QPushButton::leaveEvent(event);
|
|
|
|
update();
|
|
}
|
|
|
|
void BookmarksToolbarButton::mousePressEvent(QMouseEvent* event)
|
|
{
|
|
if (m_bookmark && m_bookmark->isFolder()) {
|
|
if (event->buttons() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier) {
|
|
openFolder(m_bookmark);
|
|
return;
|
|
}
|
|
}
|
|
|
|
QPushButton::mousePressEvent(event);
|
|
}
|
|
|
|
void BookmarksToolbarButton::mouseReleaseEvent(QMouseEvent* event)
|
|
{
|
|
if (m_bookmark && rect().contains(event->pos())) {
|
|
Qt::MouseButton button = event->button();
|
|
Qt::KeyboardModifiers modifiers = event->modifiers();
|
|
|
|
if (m_bookmark->isUrl()) {
|
|
if (button == Qt::LeftButton && modifiers == Qt::NoModifier) {
|
|
bookmarkActivated(m_bookmark);
|
|
}
|
|
else if (button == Qt::LeftButton && modifiers == Qt::ShiftModifier) {
|
|
bookmarkShiftActivated(m_bookmark);
|
|
}
|
|
else if (button == Qt::MiddleButton || modifiers == Qt::ControlModifier) {
|
|
bookmarkCtrlActivated(m_bookmark);
|
|
}
|
|
}
|
|
else if (m_bookmark->isFolder() && button == Qt::MiddleButton) {
|
|
openFolder(m_bookmark);
|
|
}
|
|
}
|
|
|
|
QPushButton::mouseReleaseEvent(event);
|
|
}
|
|
|
|
void BookmarksToolbarButton::paintEvent(QPaintEvent* event)
|
|
{
|
|
Q_UNUSED(event)
|
|
|
|
QPainter p(this);
|
|
|
|
// Just draw separator
|
|
if (m_bookmark->isSeparator()) {
|
|
QStyleOption opt;
|
|
opt.initFrom(this);
|
|
opt.state |= QStyle::State_Horizontal;
|
|
style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, &p);
|
|
return;
|
|
}
|
|
|
|
QStyleOptionButton option;
|
|
initStyleOption(&option);
|
|
|
|
// We are manually drawing the arrow
|
|
option.features &= ~QStyleOptionButton::HasMenu;
|
|
|
|
// Draw button base (only under mouse, this is autoraise button)
|
|
if (isDown() || underMouse()) {
|
|
option.state |= QStyle::State_AutoRaise | QStyle::State_Raised;
|
|
style()->drawPrimitive(QStyle::PE_PanelButtonTool, &option, &p, this);
|
|
}
|
|
|
|
const int shiftX = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &option, this) : 0;
|
|
const int shiftY = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &option, this) : 0;
|
|
|
|
const int height = option.rect.height();
|
|
const int center = height / 2 + option.rect.top() + shiftY;
|
|
|
|
const int iconSize = 16;
|
|
const int iconYPos = center - iconSize / 2;
|
|
|
|
int leftPosition = PADDING + shiftX;
|
|
int rightPosition = option.rect.right() - PADDING;
|
|
|
|
// Draw icon
|
|
QRect iconRect(leftPosition, iconYPos, iconSize, iconSize);
|
|
p.drawPixmap(iconRect, m_bookmark->icon().pixmap(iconSize));
|
|
leftPosition = iconRect.right() + PADDING;
|
|
|
|
// Draw menu arrow
|
|
if (!m_showOnlyIcon && menu()) {
|
|
const int arrowSize = 8;
|
|
QStyleOption opt;
|
|
opt.initFrom(this);
|
|
opt.rect = QRect(rightPosition - 8, center - arrowSize / 2, arrowSize, arrowSize);
|
|
opt.state &= ~QStyle::State_MouseOver;
|
|
style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, &p, this);
|
|
rightPosition = opt.rect.left() - PADDING;
|
|
}
|
|
|
|
// Draw text
|
|
if (!m_showOnlyIcon) {
|
|
const int textWidth = rightPosition - leftPosition;
|
|
const int textYPos = center - fontMetrics().height() / 2;
|
|
const QString txt = fontMetrics().elidedText(m_bookmark->title(), Qt::ElideRight, textWidth);
|
|
QRect textRect(leftPosition, textYPos, textWidth, fontMetrics().height());
|
|
style()->drawItemText(&p, textRect, Qt::TextSingleLine | Qt::AlignCenter, option.palette, true, txt);
|
|
}
|
|
}
|