mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 18:56:34 +01:00
Add VerticalTabs plugin
This commit is contained in:
parent
af95dd14e2
commit
66023d2dba
@ -12,6 +12,7 @@ add_subdirectory(MouseGestures)
|
|||||||
add_subdirectory(PIM)
|
add_subdirectory(PIM)
|
||||||
add_subdirectory(StatusBarIcons)
|
add_subdirectory(StatusBarIcons)
|
||||||
add_subdirectory(TabManager)
|
add_subdirectory(TabManager)
|
||||||
|
add_subdirectory(VerticalTabs)
|
||||||
|
|
||||||
if (GNOME_KEYRING_FOUND)
|
if (GNOME_KEYRING_FOUND)
|
||||||
add_subdirectory(GnomeKeyringPasswords)
|
add_subdirectory(GnomeKeyringPasswords)
|
||||||
|
23
src/plugins/VerticalTabs/CMakeLists.txt
Normal file
23
src/plugins/VerticalTabs/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
set( VerticalTabs_SRCS
|
||||||
|
verticaltabsplugin.cpp
|
||||||
|
verticaltabscontroller.cpp
|
||||||
|
verticaltabswidget.cpp
|
||||||
|
verticaltabssettings.cpp
|
||||||
|
tabtreeview.cpp
|
||||||
|
tabtreedelegate.cpp
|
||||||
|
loadinganimator.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set( VerticalTabs_UIS
|
||||||
|
verticaltabssettings.ui
|
||||||
|
)
|
||||||
|
qt5_wrap_ui(UIS ${VerticalTabs_UIS})
|
||||||
|
|
||||||
|
set( VerticalTabs_RSCS
|
||||||
|
verticaltabs.qrc
|
||||||
|
)
|
||||||
|
qt5_add_resources(RSCS ${VerticalTabs_RSCS})
|
||||||
|
|
||||||
|
add_library(VerticalTabs MODULE ${VerticalTabs_SRCS} ${UIS} ${RSCS})
|
||||||
|
install(TARGETS VerticalTabs DESTINATION ${FALKON_INSTALL_PLUGINDIR})
|
||||||
|
target_link_libraries(VerticalTabs FalkonPrivate)
|
14
src/plugins/VerticalTabs/data/icon.svg
Normal file
14
src/plugins/VerticalTabs/data/icon.svg
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
|
||||||
|
<defs id="defs3051">
|
||||||
|
<style type="text/css" id="current-color-scheme">
|
||||||
|
.ColorScheme-Text {
|
||||||
|
color:#4d4d4d;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<path
|
||||||
|
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||||
|
d="M 4.5 3 C 3.671579 3 3.000008 3.67157 3 4.5 C 3.000008 5.32843 3.671579 6 4.5 6 C 5.328421 6 5.999992 5.32843 6 4.5 C 5.999992 3.67157 5.328421 3 4.5 3 z M 7 4 L 7 5 L 8 5 L 8 4 L 7 4 z M 9 4 L 9 5 L 19 5 L 19 4 L 9 4 z M 9 6 L 9 7 L 12 7 L 12 6 L 9 6 z M 4.5 9 C 3.671573 8.9999999 3 9.671572 3 10.5 C 3 11.328428 3.671573 12.000001 4.5 12 C 5.328427 12 6 11.328428 6 10.5 C 6 9.671572 5.328427 8.999999 4.5 9 z M 7 10 L 7 11 L 8 11 L 8 10 L 7 10 z M 9 10 L 9 11 L 19 11 L 19 10 L 9 10 z M 9 12 L 9 13 L 13 13 L 13 12 L 9 12 z M 4.5 15 C 3.671573 15 3 15.671572 3 16.5 C 3 17.328428 3.671573 18.000001 4.5 18 C 5.328427 18 6 17.328428 6 16.5 C 6 15.671572 5.328427 14.999999 4.5 15 z M 7 16 L 7 17 L 8 17 L 8 16 L 7 16 z M 9 16 L 9 17 L 19 17 L 19 16 L 9 16 z M 9 18 L 9 19 L 16 19 L 16 18 L 9 18 z "
|
||||||
|
class="ColorScheme-Text"
|
||||||
|
/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
80
src/plugins/VerticalTabs/loadinganimator.cpp
Normal file
80
src/plugins/VerticalTabs/loadinganimator.cpp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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 "loadinganimator.h"
|
||||||
|
|
||||||
|
#include "tabicon.h"
|
||||||
|
#include "tabmodel.h"
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
class LoadingAnimation : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit LoadingAnimation(LoadingAnimator *animator)
|
||||||
|
: QObject(animator)
|
||||||
|
, m_animator(animator)
|
||||||
|
{
|
||||||
|
QTimer *timer = new QTimer(this);
|
||||||
|
timer->setInterval(TabIcon::data()->animationInterval);
|
||||||
|
connect(timer, &QTimer::timeout, this, [this]() {
|
||||||
|
m_currentFrame = (m_currentFrame + 1) % TabIcon::data()->framesCount;
|
||||||
|
m_animator->updatePixmap(this);
|
||||||
|
});
|
||||||
|
timer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap pixmap() const
|
||||||
|
{
|
||||||
|
const QPixmap p = TabIcon::data()->animationPixmap;
|
||||||
|
const int size = 16;
|
||||||
|
const int pixmapSize = qRound(size * p.devicePixelRatioF());
|
||||||
|
return p.copy(m_currentFrame * pixmapSize, 0, pixmapSize, pixmapSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_currentFrame = 0;
|
||||||
|
LoadingAnimator *m_animator;
|
||||||
|
};
|
||||||
|
|
||||||
|
LoadingAnimator::LoadingAnimator(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap LoadingAnimator::pixmap(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
LoadingAnimation *animation = m_animations.value(index);
|
||||||
|
if (!animation) {
|
||||||
|
animation = new LoadingAnimation(this);
|
||||||
|
m_indexes[animation] = index;
|
||||||
|
m_animations[index] = animation;
|
||||||
|
}
|
||||||
|
return animation->pixmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadingAnimator::updatePixmap(LoadingAnimation *animation)
|
||||||
|
{
|
||||||
|
const QModelIndex index = m_indexes.value(animation);
|
||||||
|
if (!index.isValid() || !index.data(TabModel::LoadingRole).toBool()) {
|
||||||
|
animation->deleteLater();
|
||||||
|
m_indexes.remove(animation);
|
||||||
|
m_animations.remove(index);
|
||||||
|
} else {
|
||||||
|
emit updateIndex(index);
|
||||||
|
}
|
||||||
|
}
|
45
src/plugins/VerticalTabs/loadinganimator.h
Normal file
45
src/plugins/VerticalTabs/loadinganimator.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
* ============================================================ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPersistentModelIndex>
|
||||||
|
|
||||||
|
class LoadingAnimation;
|
||||||
|
|
||||||
|
class LoadingAnimator : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LoadingAnimator(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QPixmap pixmap(const QModelIndex &index);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void updateIndex(const QModelIndex &index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updatePixmap(LoadingAnimation *animation);
|
||||||
|
|
||||||
|
QHash<LoadingAnimation*, QPersistentModelIndex> m_indexes;
|
||||||
|
QHash<QPersistentModelIndex, LoadingAnimation*> m_animations;
|
||||||
|
|
||||||
|
friend class LoadingAnimation;
|
||||||
|
};
|
176
src/plugins/VerticalTabs/tabtreedelegate.cpp
Normal file
176
src/plugins/VerticalTabs/tabtreedelegate.cpp
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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 "tabtreedelegate.h"
|
||||||
|
#include "tabtreeview.h"
|
||||||
|
#include "loadinganimator.h"
|
||||||
|
|
||||||
|
#include "tabmodel.h"
|
||||||
|
#include "tabicon.h"
|
||||||
|
#include "iconprovider.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
TabTreeDelegate::TabTreeDelegate(TabTreeView *view)
|
||||||
|
: QStyledItemDelegate()
|
||||||
|
, m_view(view)
|
||||||
|
{
|
||||||
|
m_padding = qMax(5, m_view->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1);
|
||||||
|
m_indentation = 15;
|
||||||
|
|
||||||
|
m_loadingAnimator = new LoadingAnimator(this);
|
||||||
|
connect(m_loadingAnimator, &LoadingAnimator::updateIndex, this, [this](const QModelIndex &index) {
|
||||||
|
m_view->update(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static int indexDepth(QModelIndex index)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (index.parent().isValid()) {
|
||||||
|
index = index.parent();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect TabTreeDelegate::expandButtonRect(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
const QRect rect = m_view->visualRect(index);
|
||||||
|
const int depth = indexDepth(index);
|
||||||
|
return QRect(m_indentation * depth, rect.y(), m_indentation, rect.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect TabTreeDelegate::audioButtonRect(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.data(TabModel::AudioPlayingRole).toBool() && !index.data(TabModel::AudioMutedRole).toBool()) {
|
||||||
|
return QRect();
|
||||||
|
}
|
||||||
|
const QRect rect = m_view->visualRect(index);
|
||||||
|
const int center = rect.height() / 2 + rect.top();
|
||||||
|
const int rightPosition = rect.right() - m_padding * 2 - 16;
|
||||||
|
return QRect(rightPosition - 16, center - 16 / 2, 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect TabTreeDelegate::closeButtonRect(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
const QRect rect = m_view->visualRect(index);
|
||||||
|
const int center = rect.height() / 2 + rect.top();
|
||||||
|
return QRect(rect.right() - m_padding - 16, center - 16 / 2, 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabTreeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
const QWidget *w = option.widget;
|
||||||
|
const QStyle *style = w ? w->style() : m_view->style();
|
||||||
|
|
||||||
|
const bool reverse = m_view->isRightToLeft();
|
||||||
|
const bool expanded = m_view->isExpanded(index);
|
||||||
|
const bool children = m_view->model()->rowCount(index) > 0;
|
||||||
|
const int depth = indexDepth(index);
|
||||||
|
|
||||||
|
QStyleOptionViewItem opt = option;
|
||||||
|
opt.state.setFlag(QStyle::State_Active, true);
|
||||||
|
opt.state.setFlag(QStyle::State_HasFocus, false);
|
||||||
|
opt.state.setFlag(QStyle::State_Selected, index.data(TabModel::CurrentTabRole).toBool());
|
||||||
|
|
||||||
|
const int height = opt.rect.height();
|
||||||
|
const int center = height / 2 + opt.rect.top();
|
||||||
|
|
||||||
|
int leftPosition = opt.rect.left() + m_indentation + m_indentation * depth + m_padding;
|
||||||
|
int rightPosition = opt.rect.right() - m_padding * 2 - 16; // always reserve close button size
|
||||||
|
|
||||||
|
const QIcon::Mode iconMode = opt.state & QStyle::State_Selected ? QIcon::Selected : QIcon::Normal;
|
||||||
|
const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text;
|
||||||
|
|
||||||
|
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
||||||
|
if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) {
|
||||||
|
cg = QPalette::Inactive;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text));
|
||||||
|
opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QPalette textPalette = opt.palette;
|
||||||
|
textPalette.setCurrentColorGroup(cg);
|
||||||
|
|
||||||
|
// Draw background
|
||||||
|
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w);
|
||||||
|
|
||||||
|
// Draw expand button
|
||||||
|
if (children) {
|
||||||
|
QStyle::PrimitiveElement element;
|
||||||
|
if (expanded) {
|
||||||
|
element = QStyle::PE_IndicatorArrowDown;
|
||||||
|
} else {
|
||||||
|
element = reverse ? QStyle::PE_IndicatorArrowLeft : QStyle::PE_IndicatorArrowRight;
|
||||||
|
}
|
||||||
|
QStyleOptionViewItem o = opt;
|
||||||
|
o.state &= ~QStyle::State_MouseOver;
|
||||||
|
o.rect.moveLeft(m_indentation * depth);
|
||||||
|
o.rect.setWidth(m_indentation);
|
||||||
|
style->drawPrimitive(element, &o, painter, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw icon
|
||||||
|
const int iconSize = 16;
|
||||||
|
const int iconYPos = center - (iconSize / 2);
|
||||||
|
QRect iconRect(leftPosition, iconYPos, iconSize, iconSize);
|
||||||
|
QPixmap pixmap;
|
||||||
|
if (index.data(TabModel::LoadingRole).toBool()) {
|
||||||
|
pixmap = m_loadingAnimator->pixmap(index);
|
||||||
|
} else {
|
||||||
|
pixmap = index.data(Qt::DecorationRole).value<QIcon>().pixmap(iconSize, iconMode);
|
||||||
|
}
|
||||||
|
painter->drawPixmap(iconRect, pixmap);
|
||||||
|
leftPosition += iconRect.width() + m_padding;
|
||||||
|
|
||||||
|
// Draw close button
|
||||||
|
if (opt.state.testFlag(QStyle::State_MouseOver) || opt.state.testFlag(QStyle::State_Selected)) {
|
||||||
|
QSize closeSize(16, 16);
|
||||||
|
QPoint pos(opt.rect.right() - m_padding - closeSize.width(), center - closeSize.height() / 2);
|
||||||
|
QRect closeRect(pos, closeSize);
|
||||||
|
painter->drawPixmap(closeRect, IconProvider::standardIcon(QStyle::SP_DialogCloseButton).pixmap(closeSize, iconMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw audio icon
|
||||||
|
const bool audioMuted = index.data(TabModel::AudioMutedRole).toBool();
|
||||||
|
const bool audioPlaying = index.data(TabModel::AudioPlayingRole).toBool();
|
||||||
|
if (audioMuted || audioPlaying) {
|
||||||
|
QSize audioSize(16, 16);
|
||||||
|
QPoint pos(rightPosition - audioSize.width(), center - audioSize.height() / 2);
|
||||||
|
QRect audioRect(pos, audioSize);
|
||||||
|
painter->drawPixmap(audioRect, audioMuted ? TabIcon::data()->audioMutedPixmap : TabIcon::data()->audioPlayingPixmap);
|
||||||
|
rightPosition -= audioSize.width() + m_padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw title
|
||||||
|
QRect titleRect(leftPosition, center - opt.fontMetrics.height() / 2, opt.rect.width(), opt.fontMetrics.height());
|
||||||
|
titleRect.setRight(rightPosition - m_padding);
|
||||||
|
QString title = opt.fontMetrics.elidedText(index.data().toString(), Qt::ElideRight, titleRect.width());
|
||||||
|
style->drawItemText(painter, titleRect, Qt::AlignLeft, textPalette, true, title, colorRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize TabTreeDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QStyleOptionViewItem opt(option);
|
||||||
|
initStyleOption(&opt, index);
|
||||||
|
|
||||||
|
return QSize(200, m_padding * 2 + opt.fontMetrics.height());
|
||||||
|
}
|
42
src/plugins/VerticalTabs/tabtreedelegate.h
Normal file
42
src/plugins/VerticalTabs/tabtreedelegate.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
* ============================================================ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
class TabTreeView;
|
||||||
|
class LoadingAnimator;
|
||||||
|
|
||||||
|
class TabTreeDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit TabTreeDelegate(TabTreeView *view);
|
||||||
|
|
||||||
|
QRect expandButtonRect(const QModelIndex &index) const;
|
||||||
|
QRect audioButtonRect(const QModelIndex &index) const;
|
||||||
|
QRect closeButtonRect(const QModelIndex &index) const;
|
||||||
|
|
||||||
|
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TabTreeView *m_view;
|
||||||
|
LoadingAnimator *m_loadingAnimator;
|
||||||
|
int m_padding;
|
||||||
|
int m_indentation;
|
||||||
|
};
|
169
src/plugins/VerticalTabs/tabtreeview.cpp
Normal file
169
src/plugins/VerticalTabs/tabtreeview.cpp
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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 "tabtreeview.h"
|
||||||
|
#include "tabtreedelegate.h"
|
||||||
|
#include "loadinganimator.h"
|
||||||
|
|
||||||
|
#include "tabmodel.h"
|
||||||
|
#include "webtab.h"
|
||||||
|
#include "tabcontextmenu.h"
|
||||||
|
|
||||||
|
#include <QToolTip>
|
||||||
|
#include <QHoverEvent>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
TabTreeView::TabTreeView(QWidget* parent)
|
||||||
|
: QTreeView(parent)
|
||||||
|
{
|
||||||
|
setDragEnabled(true);
|
||||||
|
setAcceptDrops(true);
|
||||||
|
setHeaderHidden(true);
|
||||||
|
setUniformRowHeights(true);
|
||||||
|
setDropIndicatorShown(true);
|
||||||
|
setAllColumnsShowFocus(true);
|
||||||
|
setMouseTracking(true);
|
||||||
|
setIndentation(0);
|
||||||
|
|
||||||
|
m_delegate = new TabTreeDelegate(this);
|
||||||
|
setItemDelegate(m_delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TabTreeView::areTabsInOrder() const
|
||||||
|
{
|
||||||
|
return m_tabsInOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabTreeView::setTabsInOrder(bool enable)
|
||||||
|
{
|
||||||
|
m_tabsInOrder = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabTreeView::drawBranches(QPainter *, const QRect &, const QModelIndex &) const
|
||||||
|
{
|
||||||
|
// Disable drawing branches
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabTreeView::currentChanged(const QModelIndex &, const QModelIndex &)
|
||||||
|
{
|
||||||
|
// Disable current index
|
||||||
|
setCurrentIndex(QModelIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TabTreeView::viewportEvent(QEvent *event)
|
||||||
|
{
|
||||||
|
switch (event->type()) {
|
||||||
|
case QEvent::MouseButtonPress: {
|
||||||
|
QMouseEvent *me = static_cast<QMouseEvent*>(event);
|
||||||
|
const QModelIndex index = indexAt(me->pos());
|
||||||
|
WebTab *tab = index.data(TabModel::WebTabRole).value<WebTab*>();
|
||||||
|
if (me->buttons() == Qt::MiddleButton && tab) {
|
||||||
|
tab->closeTab();
|
||||||
|
}
|
||||||
|
if (me->buttons() != Qt::LeftButton) {
|
||||||
|
m_pressedIndex = QModelIndex();
|
||||||
|
m_pressedButton = NoButton;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_pressedIndex = index;
|
||||||
|
m_pressedButton = buttonAt(me->pos(), m_pressedIndex);
|
||||||
|
if (m_pressedIndex.isValid()) {
|
||||||
|
if (m_pressedButton == ExpandButton) {
|
||||||
|
if (isExpanded(m_pressedIndex)) {
|
||||||
|
collapse(m_pressedIndex);
|
||||||
|
} else {
|
||||||
|
expand(m_pressedIndex);
|
||||||
|
}
|
||||||
|
} else if (m_pressedButton == NoButton && tab) {
|
||||||
|
tab->makeCurrentTab();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QEvent::MouseButtonRelease: {
|
||||||
|
QMouseEvent *me = static_cast<QMouseEvent*>(event);
|
||||||
|
if (me->buttons() != Qt::NoButton) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const QModelIndex index = indexAt(me->pos());
|
||||||
|
if (m_pressedIndex != index) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DelegateButton button = buttonAt(me->pos(), index);
|
||||||
|
if (m_pressedButton == button) {
|
||||||
|
if (m_pressedButton == ExpandButton) {
|
||||||
|
me->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
WebTab *tab = index.data(TabModel::WebTabRole).value<WebTab*>();
|
||||||
|
if (tab) {
|
||||||
|
if (m_pressedButton == CloseButton) {
|
||||||
|
tab->closeTab();
|
||||||
|
} else if (m_pressedButton == AudioButton) {
|
||||||
|
tab->toggleMuted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QEvent::ToolTip: {
|
||||||
|
QHelpEvent *he = static_cast<QHelpEvent*>(event);
|
||||||
|
const QModelIndex index = indexAt(he->pos());
|
||||||
|
DelegateButton button = buttonAt(he->pos(), index);
|
||||||
|
if (button == AudioButton) {
|
||||||
|
const bool muted = index.data(TabModel::AudioMutedRole).toBool();
|
||||||
|
QToolTip::showText(he->globalPos(), muted ? tr("Unmute Tab") : tr("Mute Tab"), this, visualRect(index));
|
||||||
|
he->accept();
|
||||||
|
return true;
|
||||||
|
} else if (button == CloseButton) {
|
||||||
|
QToolTip::showText(he->globalPos(), tr("Close Tab"), this, visualRect(index));
|
||||||
|
he->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QEvent::ContextMenu: {
|
||||||
|
QContextMenuEvent *ce = static_cast<QContextMenuEvent*>(event);
|
||||||
|
const QModelIndex index = indexAt(ce->pos());
|
||||||
|
WebTab *tab = index.data(TabModel::WebTabRole).value<WebTab*>();
|
||||||
|
if (tab) {
|
||||||
|
TabContextMenu menu(tab, Qt::Vertical, m_tabsInOrder);
|
||||||
|
menu.exec(ce->globalPos());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QTreeView::viewportEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
TabTreeView::DelegateButton TabTreeView::buttonAt(const QPoint &pos, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (m_delegate->expandButtonRect(index).contains(pos)) {
|
||||||
|
return ExpandButton;
|
||||||
|
} else if (m_delegate->audioButtonRect(index).contains(pos)) {
|
||||||
|
return AudioButton;
|
||||||
|
} else if (m_delegate->closeButtonRect(index).contains(pos)) {
|
||||||
|
return CloseButton;
|
||||||
|
}
|
||||||
|
return NoButton;
|
||||||
|
}
|
53
src/plugins/VerticalTabs/tabtreeview.h
Normal file
53
src/plugins/VerticalTabs/tabtreeview.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
* ============================================================ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
|
class TabTreeDelegate;
|
||||||
|
|
||||||
|
class TabTreeView : public QTreeView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TabTreeView(QWidget *parent = 0);
|
||||||
|
|
||||||
|
// In TabBar order
|
||||||
|
bool areTabsInOrder() const;
|
||||||
|
void setTabsInOrder(bool enable);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const override;
|
||||||
|
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override;
|
||||||
|
bool viewportEvent(QEvent *event) override;
|
||||||
|
|
||||||
|
enum DelegateButton {
|
||||||
|
NoButton,
|
||||||
|
ExpandButton,
|
||||||
|
AudioButton,
|
||||||
|
CloseButton
|
||||||
|
};
|
||||||
|
|
||||||
|
DelegateButton buttonAt(const QPoint &pos, const QModelIndex &index) const;
|
||||||
|
|
||||||
|
TabTreeDelegate *m_delegate;
|
||||||
|
DelegateButton m_pressedButton = NoButton;
|
||||||
|
QModelIndex m_pressedIndex;
|
||||||
|
bool m_tabsInOrder = false;
|
||||||
|
};
|
5
src/plugins/VerticalTabs/verticaltabs.qrc
Normal file
5
src/plugins/VerticalTabs/verticaltabs.qrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/verticaltabs">
|
||||||
|
<file>data/icon.svg</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
49
src/plugins/VerticalTabs/verticaltabscontroller.cpp
Normal file
49
src/plugins/VerticalTabs/verticaltabscontroller.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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 "verticaltabscontroller.h"
|
||||||
|
#include "verticaltabsplugin.h"
|
||||||
|
#include "verticaltabswidget.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
|
VerticalTabsController::VerticalTabsController(VerticalTabsPlugin *plugin)
|
||||||
|
: SideBarInterface(plugin)
|
||||||
|
, m_plugin(plugin)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VerticalTabsController::title() const
|
||||||
|
{
|
||||||
|
return tr("Vertical Tabs");
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction *VerticalTabsController::createMenuAction()
|
||||||
|
{
|
||||||
|
QAction *act = new QAction(title(), this);
|
||||||
|
act->setCheckable(true);
|
||||||
|
return act;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *VerticalTabsController::createSideBarWidget(BrowserWindow *window)
|
||||||
|
{
|
||||||
|
VerticalTabsWidget *widget = new VerticalTabsWidget(window);
|
||||||
|
connect(m_plugin, &VerticalTabsPlugin::viewTypeChanged, widget, &VerticalTabsWidget::setViewType);
|
||||||
|
widget->setViewType(m_plugin->viewType());
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
36
src/plugins/VerticalTabs/verticaltabscontroller.h
Normal file
36
src/plugins/VerticalTabs/verticaltabscontroller.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
* ============================================================ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sidebarinterface.h"
|
||||||
|
|
||||||
|
class VerticalTabsPlugin;
|
||||||
|
|
||||||
|
class VerticalTabsController : public SideBarInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit VerticalTabsController(VerticalTabsPlugin *plugin);
|
||||||
|
|
||||||
|
QString title() const override;
|
||||||
|
QAction *createMenuAction() override;
|
||||||
|
QWidget *createSideBarWidget(BrowserWindow *window) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VerticalTabsPlugin *m_plugin;
|
||||||
|
};
|
152
src/plugins/VerticalTabs/verticaltabsplugin.cpp
Normal file
152
src/plugins/VerticalTabs/verticaltabsplugin.cpp
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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 "verticaltabsplugin.h"
|
||||||
|
#include "verticaltabssettings.h"
|
||||||
|
#include "verticaltabscontroller.h"
|
||||||
|
|
||||||
|
#include "browserwindow.h"
|
||||||
|
#include "pluginproxy.h"
|
||||||
|
#include "mainapplication.h"
|
||||||
|
#include "tabwidget.h"
|
||||||
|
#include "tabbar.h"
|
||||||
|
#include "sidebar.h"
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QTranslator>
|
||||||
|
|
||||||
|
VerticalTabsPlugin::VerticalTabsPlugin()
|
||||||
|
: QObject()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginSpec VerticalTabsPlugin::pluginSpec()
|
||||||
|
{
|
||||||
|
PluginSpec spec;
|
||||||
|
spec.name = QSL("Vertical Tabs");
|
||||||
|
spec.info = QSL("Vertical tabs for Falkon");
|
||||||
|
spec.description = QSL("Adds ability to show tabs in sidebar");
|
||||||
|
spec.version = QSL("0.1.0");
|
||||||
|
spec.author = QSL("David Rosca <nowrep@gmail.com>");
|
||||||
|
spec.icon = QIcon(QSL(":verticaltabs/data/icon.svg")).pixmap(32);
|
||||||
|
spec.hasSettings = true;
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerticalTabsPlugin::init(InitState state, const QString &settingsPath)
|
||||||
|
{
|
||||||
|
m_settingsPath = settingsPath + QL1S("/extensions.ini");
|
||||||
|
|
||||||
|
QSettings settings(m_settingsPath, QSettings::IniFormat);
|
||||||
|
settings.beginGroup(QSL("VerticalTabs"));
|
||||||
|
m_viewType = static_cast<ViewType>(settings.value(QSL("ViewType"), TabListView).toInt());
|
||||||
|
m_replaceTabBar = settings.value(QSL("ReplaceTabBar"), false).toBool();
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
m_controller = new VerticalTabsController(this);
|
||||||
|
SideBarManager::addSidebar(QSL("VerticalTabs"), m_controller);
|
||||||
|
|
||||||
|
connect(mApp->plugins(), &PluginProxy::mainWindowCreated, this, &VerticalTabsPlugin::mainWindowCreated);
|
||||||
|
|
||||||
|
if (state == LateInitState) {
|
||||||
|
const auto windows = mApp->windows();
|
||||||
|
for (BrowserWindow *window : windows) {
|
||||||
|
mainWindowCreated(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerticalTabsPlugin::unload()
|
||||||
|
{
|
||||||
|
setTabBarVisible(true);
|
||||||
|
|
||||||
|
SideBarManager::removeSidebar(QSL("VerticalTabs"));
|
||||||
|
delete m_controller;
|
||||||
|
m_controller = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VerticalTabsPlugin::testPlugin()
|
||||||
|
{
|
||||||
|
return (Qz::VERSION == QSL(FALKON_VERSION));
|
||||||
|
}
|
||||||
|
|
||||||
|
QTranslator *VerticalTabsPlugin::getTranslator(const QString &locale)
|
||||||
|
{
|
||||||
|
QTranslator *translator = new QTranslator(this);
|
||||||
|
translator->load(locale, QSL(":/verticaltabs/locale/"));
|
||||||
|
return translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerticalTabsPlugin::showSettings(QWidget *parent)
|
||||||
|
{
|
||||||
|
VerticalTabsSettings *settings = new VerticalTabsSettings(this, parent);
|
||||||
|
settings->exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalTabsPlugin::ViewType VerticalTabsPlugin::viewType() const
|
||||||
|
{
|
||||||
|
return m_viewType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerticalTabsPlugin::setViewType(ViewType type)
|
||||||
|
{
|
||||||
|
if (m_viewType == type) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_viewType = type;
|
||||||
|
|
||||||
|
QSettings settings(m_settingsPath, QSettings::IniFormat);
|
||||||
|
settings.setValue(QSL("VerticalTabs/ViewType"), m_viewType);
|
||||||
|
|
||||||
|
emit viewTypeChanged(m_viewType);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VerticalTabsPlugin::replaceTabBar() const
|
||||||
|
{
|
||||||
|
return m_replaceTabBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerticalTabsPlugin::setReplaceTabBar(bool replace)
|
||||||
|
{
|
||||||
|
if (m_replaceTabBar == replace) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_replaceTabBar = replace;
|
||||||
|
setTabBarVisible(!m_replaceTabBar);
|
||||||
|
|
||||||
|
QSettings settings(m_settingsPath, QSettings::IniFormat);
|
||||||
|
settings.setValue(QSL("VerticalTabs/ReplaceTabBar"), m_replaceTabBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerticalTabsPlugin::mainWindowCreated(BrowserWindow *window)
|
||||||
|
{
|
||||||
|
if (window->sideBarManager()->activeSideBar().isEmpty()) {
|
||||||
|
window->sideBarManager()->showSideBar(QSL("VerticalTabs"));
|
||||||
|
}
|
||||||
|
setTabBarVisible(!m_replaceTabBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerticalTabsPlugin::setTabBarVisible(bool visible)
|
||||||
|
{
|
||||||
|
const auto windows = mApp->windows();
|
||||||
|
for (BrowserWindow *window : windows) {
|
||||||
|
window->tabWidget()->tabBar()->setForceHidden(!visible);
|
||||||
|
}
|
||||||
|
}
|
64
src/plugins/VerticalTabs/verticaltabsplugin.h
Normal file
64
src/plugins/VerticalTabs/verticaltabsplugin.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
* ============================================================ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "plugininterface.h"
|
||||||
|
|
||||||
|
class BrowserWindow;
|
||||||
|
|
||||||
|
class VerticalTabsController;
|
||||||
|
|
||||||
|
class VerticalTabsPlugin : public QObject, public PluginInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(PluginInterface)
|
||||||
|
Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.VerticalTabs")
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit VerticalTabsPlugin();
|
||||||
|
|
||||||
|
PluginSpec pluginSpec() override;
|
||||||
|
void init(InitState state, const QString &settingsPath) override;
|
||||||
|
void unload() override;
|
||||||
|
bool testPlugin() override;
|
||||||
|
QTranslator* getTranslator(const QString &locale) override;
|
||||||
|
void showSettings(QWidget *parent = nullptr) override;
|
||||||
|
|
||||||
|
enum ViewType {
|
||||||
|
TabListView,
|
||||||
|
TabTreeView
|
||||||
|
};
|
||||||
|
|
||||||
|
ViewType viewType() const;
|
||||||
|
void setViewType(ViewType type);
|
||||||
|
|
||||||
|
bool replaceTabBar() const;
|
||||||
|
void setReplaceTabBar(bool replace);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void viewTypeChanged(ViewType type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void mainWindowCreated(BrowserWindow *window);
|
||||||
|
void setTabBarVisible(bool visible);
|
||||||
|
|
||||||
|
QString m_settingsPath;
|
||||||
|
VerticalTabsController *m_controller = nullptr;
|
||||||
|
ViewType m_viewType = TabListView;
|
||||||
|
bool m_replaceTabBar = false;
|
||||||
|
};
|
45
src/plugins/VerticalTabs/verticaltabssettings.cpp
Normal file
45
src/plugins/VerticalTabs/verticaltabssettings.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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 "verticaltabssettings.h"
|
||||||
|
#include "ui_verticaltabssettings.h"
|
||||||
|
#include "verticaltabsplugin.h"
|
||||||
|
|
||||||
|
VerticalTabsSettings::VerticalTabsSettings(VerticalTabsPlugin *plugin, QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, ui(new Ui::VerticalTabsSettings)
|
||||||
|
, m_plugin(plugin)
|
||||||
|
{
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->tabListView->setChecked(m_plugin->viewType() == VerticalTabsPlugin::TabListView);
|
||||||
|
ui->tabTreeView->setChecked(m_plugin->viewType() == VerticalTabsPlugin::TabTreeView);
|
||||||
|
ui->replaceTabBar->setChecked(m_plugin->replaceTabBar());
|
||||||
|
|
||||||
|
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, [this]() {
|
||||||
|
m_plugin->setViewType(ui->tabListView->isChecked() ? VerticalTabsPlugin::TabListView : VerticalTabsPlugin::TabTreeView);
|
||||||
|
m_plugin->setReplaceTabBar(ui->replaceTabBar->isChecked());
|
||||||
|
accept();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalTabsSettings::~VerticalTabsSettings()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
38
src/plugins/VerticalTabs/verticaltabssettings.h
Normal file
38
src/plugins/VerticalTabs/verticaltabssettings.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
* ============================================================ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class VerticalTabsSettings;
|
||||||
|
}
|
||||||
|
class VerticalTabsPlugin;
|
||||||
|
|
||||||
|
class VerticalTabsSettings : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit VerticalTabsSettings(VerticalTabsPlugin *plugin, QWidget *parent = nullptr);
|
||||||
|
~VerticalTabsSettings();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::VerticalTabsSettings *ui;
|
||||||
|
VerticalTabsPlugin *m_plugin;
|
||||||
|
};
|
81
src/plugins/VerticalTabs/verticaltabssettings.ui
Normal file
81
src/plugins/VerticalTabs/verticaltabssettings.ui
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>VerticalTabsSettings</class>
|
||||||
|
<widget class="QDialog" name="VerticalTabsSettings">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>415</width>
|
||||||
|
<height>231</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Vertical Tabs Settings</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>View</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Please select view type:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="tabListView">
|
||||||
|
<property name="text">
|
||||||
|
<string>Tab List</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="tabTreeView">
|
||||||
|
<property name="text">
|
||||||
|
<string>Tab Tree</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="replaceTabBar">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use as replacement for main TabBar.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</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/>
|
||||||
|
</ui>
|
58
src/plugins/VerticalTabs/verticaltabswidget.cpp
Normal file
58
src/plugins/VerticalTabs/verticaltabswidget.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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 "verticaltabswidget.h"
|
||||||
|
#include "tabtreeview.h"
|
||||||
|
|
||||||
|
#include "tabmodel.h"
|
||||||
|
#include "tabtreemodel.h"
|
||||||
|
#include "browserwindow.h"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
VerticalTabsWidget::VerticalTabsWidget(BrowserWindow *window)
|
||||||
|
: QWidget()
|
||||||
|
, m_window(window)
|
||||||
|
{
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
m_view = new TabTreeView(this);
|
||||||
|
layout->addWidget(m_view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerticalTabsWidget::setViewType(VerticalTabsPlugin::ViewType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case VerticalTabsPlugin::TabListView:
|
||||||
|
m_view->setModel(m_window->tabModel());
|
||||||
|
m_view->setTabsInOrder(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VerticalTabsPlugin::TabTreeView:
|
||||||
|
delete m_treeModel;
|
||||||
|
m_treeModel = new TabTreeModel(this);
|
||||||
|
m_treeModel->setSourceModel(m_window->tabModel());
|
||||||
|
m_view->setModel(m_treeModel);
|
||||||
|
m_view->setTabsInOrder(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
41
src/plugins/VerticalTabs/verticaltabswidget.h
Normal file
41
src/plugins/VerticalTabs/verticaltabswidget.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* VerticalTabs plugin for Falkon
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
* ============================================================ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "verticaltabsplugin.h"
|
||||||
|
|
||||||
|
class BrowserWindow;
|
||||||
|
class TabTreeModel;
|
||||||
|
|
||||||
|
class TabTreeView;
|
||||||
|
|
||||||
|
class VerticalTabsWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit VerticalTabsWidget(BrowserWindow *window);
|
||||||
|
|
||||||
|
void setViewType(VerticalTabsPlugin::ViewType type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BrowserWindow *m_window;
|
||||||
|
TabTreeView *m_view;
|
||||||
|
TabTreeModel *m_treeModel = nullptr;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user