You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

188 lines
5.3 KiB

/*
Copyright 2018 by Tomaz Canabrava <tcanabrava@kde.org>
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 2 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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
*/
#include "DetachableTabBar.h"
#include "KonsoleSettings.h"
#include "ViewContainer.h"
#include <QMouseEvent>
#include <QApplication>
#include <QMimeData>
#include <KAcceleratorManager>
#include <QPainter>
#include <QColor>
namespace Konsole {
DetachableTabBar::DetachableTabBar(QWidget *parent) :
QTabBar(parent),
dragType(DragType::NONE),
_originalCursor(cursor()),
tabId(-1)
{
setAcceptDrops(true);
setElideMode(Qt::TextElideMode::ElideMiddle);
KAcceleratorManager::setNoAccel(this);
}
void DetachableTabBar::setColor(int idx, const QColor &color)
{
setTabData(idx, color);
}
void DetachableTabBar::removeColor(int idx)
{
setTabData(idx, QVariant());
}
void DetachableTabBar::middleMouseButtonClickAt(const QPoint& pos)
{
tabId = tabAt(pos);
if (tabId != -1) {
emit closeTab(tabId);
}
}
void DetachableTabBar::mousePressEvent(QMouseEvent *event)
{
QTabBar::mousePressEvent(event);
_containers = window()->findChildren<Konsole::TabbedViewContainer*>();
}
void DetachableTabBar::mouseMoveEvent(QMouseEvent *event)
{
QTabBar::mouseMoveEvent(event);
auto widgetAtPos = qApp->topLevelAt(event->globalPos());
if (widgetAtPos != nullptr) {
if (window() == widgetAtPos->window()) {
if (dragType != DragType::NONE) {
dragType = DragType::NONE;
setCursor(_originalCursor);
}
} else {
if (dragType != DragType::WINDOW) {
dragType = DragType::WINDOW;
setCursor(QCursor(Qt::DragMoveCursor));
}
}
} else if (!contentsRect().adjusted(-30,-30,30,30).contains(event->pos())) {
// Don't let it detach the last tab.
if (count() == 1) {
return;
}
if (dragType != DragType::OUTSIDE) {
dragType = DragType::OUTSIDE;
setCursor(QCursor(Qt::DragCopyCursor));
}
}
}
void DetachableTabBar::mouseReleaseEvent(QMouseEvent *event)
{
QTabBar::mouseReleaseEvent(event);
switch(event->button()) {
case Qt::MiddleButton : if (KonsoleSettings::closeTabOnMiddleMouseButton()) {
middleMouseButtonClickAt(event->pos());
}
tabId = tabAt(event->pos());
if (tabId == -1) {
emit newTabRequest();
}
break;
case Qt::LeftButton: _containers = window()->findChildren<Konsole::TabbedViewContainer*>(); break;
default: break;
}
setCursor(_originalCursor);
if (contentsRect().adjusted(-30,-30,30,30).contains(event->pos())) {
return;
}
auto widgetAtPos = qApp->topLevelAt(event->globalPos());
if (widgetAtPos == nullptr) {
if (count() != 1) {
emit detachTab(currentIndex());
}
} else if (window() != widgetAtPos->window()) {
if (_containers.size() == 1 || count() > 1) {
emit moveTabToWindow(currentIndex(), widgetAtPos);
}
}
}
void DetachableTabBar::dragEnterEvent(QDragEnterEvent* event)
{
const auto dragId = QStringLiteral("konsole/terminal_display");
if (!event->mimeData()->hasFormat(dragId)) {
return;
}
auto other_pid = event->mimeData()->data(dragId).toInt();
// don't accept the drop if it's another instance of konsole
if (qApp->applicationPid() != other_pid) {
return;
}
event->accept();
}
void DetachableTabBar::dragMoveEvent(QDragMoveEvent* event)
{
int tabIdx = tabAt(event->pos());
if (tabIdx != -1) {
setCurrentIndex(tabIdx);
}
}
void DetachableTabBar::paintEvent(QPaintEvent *event)
{
QTabBar::paintEvent(event);
if (!event->isAccepted()) {
return; // Reduces repainting
}
QPainter painter(this);
painter.setPen(Qt::NoPen);
for (int tabIndex = 0; tabIndex < count(); tabIndex++) {
const QVariant data = tabData(tabIndex);
if (!data.isValid() || data.isNull()) {
continue;
}
QColor varColor = data.value<QColor>();
if (!varColor.isValid()) {
continue;
}
painter.setBrush(varColor);
QRect tRect = tabRect(tabIndex);
tRect.setTop(painter.fontMetrics().height() + 6); // Color bar top position consider a height the font and fixed spacing of 6px
tRect.setHeight(4);
tRect.setLeft(tRect.left() + 6);
tRect.setWidth(tRect.width() - 6);
painter.drawRect(tRect);
}
}
}