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
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); |
|
} |
|
} |
|
|
|
}
|
|
|