Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Utilities
Kate
Commits
615c9fdd
Commit
615c9fdd
authored
Jan 16, 2022
by
Waqar Ahmed
Committed by
Christoph Cullmann
Jan 29, 2022
Browse files
Allow DND of tabs among viewspaces
BUG: 426768
parent
16019ddf
Changes
9
Hide whitespace changes
Inline
Side-by-side
kate/CMakeLists.txt
View file @
615c9fdd
...
...
@@ -92,6 +92,7 @@ target_sources(
kateviewmanager.cpp
kateviewspace.cpp
katewaiter.cpp
tabmimedata.cpp
katecommandbar.cpp
commandmodel.cpp
...
...
kate/katetabbar.cpp
View file @
615c9fdd
...
...
@@ -8,12 +8,17 @@
#include
"katetabbar.h"
#include
"kateapp.h"
#include
"tabmimedata.h"
#include
<QApplication>
#include
<QDrag>
#include
<QIcon>
#include
<QMimeData>
#include
<QPainter>
#include
<QPixmap>
#include
<QResizeEvent>
#include
<QStyleOptionTab>
#include
<QStylePainter>
#include
<QWheelEvent>
#include
<KAcceleratorManager>
...
...
@@ -160,6 +165,13 @@ void KateTabBar::mousePressEvent(QMouseEvent *event)
if
(
!
isActive
())
{
Q_EMIT
activateViewSpaceRequested
();
}
if
(
event
->
button
()
==
Qt
::
LeftButton
&&
tabAt
(
event
->
pos
())
!=
-
1
)
{
dragStartPos
=
event
->
pos
();
}
else
{
dragStartPos
=
{};
}
QTabBar
::
mousePressEvent
(
event
);
// handle close for middle mouse button
...
...
@@ -171,6 +183,59 @@ void KateTabBar::mousePressEvent(QMouseEvent *event)
}
}
void
KateTabBar
::
mouseMoveEvent
(
QMouseEvent
*
event
)
{
if
(
dragStartPos
.
isNull
())
{
QTabBar
::
mouseMoveEvent
(
event
);
return
;
}
if
((
event
->
pos
()
-
dragStartPos
).
manhattanLength
()
<
QApplication
::
startDragDistance
())
{
QTabBar
::
mouseMoveEvent
(
event
);
return
;
}
if
(
rect
().
contains
(
event
->
pos
()))
{
return
QTabBar
::
mouseMoveEvent
(
event
);
}
QDrag
*
drag
=
new
QDrag
(
this
);
int
tab
=
tabAt
(
dragStartPos
);
QRect
rect
=
tabRect
(
tab
);
QPixmap
p
(
rect
.
size
());
p
.
setDevicePixelRatio
(
this
->
devicePixelRatioF
());
p
.
fill
(
Qt
::
transparent
);
// For some reason initStyleOption with tabIdx directly
// wasn't working, so manually set some stuff
QStyleOptionTabV4
opt
;
initStyleOption
(
&
opt
,
0
);
opt
.
text
=
tabText
(
tab
);
opt
.
state
=
QStyle
::
State_Selected
|
QStyle
::
State_Raised
;
opt
.
tabIndex
=
tab
;
opt
.
features
=
QStyleOptionTab
::
TabFeature
::
HasFrame
;
QStylePainter
paint
(
&
p
,
this
);
paint
.
drawControl
(
QStyle
::
CE_TabBarTab
,
opt
);
paint
.
end
();
auto
parentViewSpace
=
qobject_cast
<
KateViewSpace
*>
(
parentWidget
());
Q_ASSERT
(
parentViewSpace
);
auto
mime
=
new
TabMimeData
(
parentViewSpace
,
tabDocument
(
tab
),
tab
);
drag
->
setMimeData
(
mime
);
drag
->
setPixmap
(
p
);
QPoint
hp
;
hp
.
setX
(
dragStartPos
.
x
()
-
rect
.
x
());
drag
->
setHotSpot
(
hp
);
dragStartPos
=
{};
drag
->
exec
();
}
void
KateTabBar
::
contextMenuEvent
(
QContextMenuEvent
*
ev
)
{
int
id
=
tabAt
(
ev
->
pos
());
...
...
kate/katetabbar.h
View file @
615c9fdd
...
...
@@ -122,6 +122,8 @@ protected:
//! Override to request making the tab bar active.
void
mousePressEvent
(
QMouseEvent
*
event
)
override
;
void
mouseMoveEvent
(
QMouseEvent
*
)
override
;
//! Request context menu
void
contextMenuEvent
(
QContextMenuEvent
*
ev
)
override
;
...
...
@@ -167,6 +169,8 @@ private:
* is a bit strange tab replacement a few times
*/
std
::
unordered_map
<
KTextEditor
::
Document
*
,
std
::
pair
<
quint64
,
bool
>>
m_docToLruCounterAndHasTab
;
QPoint
dragStartPos
;
};
#endif // KATE_TAB_BAR_H
kate/kateviewmanager.cpp
View file @
615c9fdd
...
...
@@ -783,6 +783,15 @@ void KateViewManager::closeView(KTextEditor::View *view)
}
}
void
KateViewManager
::
moveViewToViewSpace
(
KateViewSpace
*
dest
,
KateViewSpace
*
src
,
KTextEditor
::
Document
*
doc
)
{
// We always have an active view at this point which is what we are moving
Q_ASSERT
(
activeView
());
auto
view
=
src
->
takeView
(
doc
);
dest
->
addView
(
view
);
setActiveSpace
(
dest
);
}
void
KateViewManager
::
splitViewSpace
(
KateViewSpace
*
vs
,
// = 0
Qt
::
Orientation
o
)
// = Qt::Horizontal
{
...
...
kate/kateviewmanager.h
View file @
615c9fdd
...
...
@@ -75,6 +75,8 @@ public:
void
closeView
(
KTextEditor
::
View
*
view
);
KateMainWindow
*
mainWindow
();
void
moveViewToViewSpace
(
KateViewSpace
*
dest
,
KateViewSpace
*
src
,
KTextEditor
::
Document
*
doc
);
private
Q_SLOTS
:
void
activateView
(
KTextEditor
::
View
*
view
);
void
activateSpace
(
KTextEditor
::
View
*
v
);
...
...
kate/kateviewspace.cpp
View file @
615c9fdd
...
...
@@ -15,6 +15,7 @@
#include
"katesessionmanager.h"
#include
"kateupdatedisabler.h"
#include
"kateviewmanager.h"
#include
"tabmimedata.h"
#include
<KActionCollection>
#include
<KAcceleratorManager>
...
...
@@ -26,6 +27,7 @@
#include
<QHelpEvent>
#include
<QMenu>
#include
<QMessageBox>
#include
<QRubberBand>
#include
<QStackedWidget>
#include
<QToolButton>
#include
<QToolTip>
...
...
@@ -129,11 +131,16 @@ KateViewSpace::KateViewSpace(KateViewManager *viewManager, QWidget *parent, cons
connect
(
this
,
&
KateViewSpace
::
viewSpaceEmptied
,
m_viewManager
,
&
KateViewManager
::
onViewSpaceEmptied
);
// we accept drops (tabs from other viewspaces / windows)
setAcceptDrops
(
true
);
// init the bars...
statusBarToggled
();
tabBarToggled
();
}
KateViewSpace
::~
KateViewSpace
()
=
default
;
bool
KateViewSpace
::
eventFilter
(
QObject
*
obj
,
QEvent
*
event
)
{
QToolButton
*
button
=
qobject_cast
<
QToolButton
*>
(
obj
);
...
...
@@ -397,6 +404,7 @@ void KateViewSpace::registerDocument(KTextEditor::Document *doc)
connect
(
m_tabBar
,
&
KateTabBar
::
currentChanged
,
this
,
&
KateViewSpace
::
changeView
);
}
void
KateViewSpace
::
closeDocument
(
KTextEditor
::
Document
*
doc
)
{
// If this is the only view of the document,
...
...
@@ -423,6 +431,64 @@ void KateViewSpace::closeDocument(KTextEditor::Document *doc)
}
}
void
KateViewSpace
::
dragEnterEvent
(
QDragEnterEvent
*
e
)
{
auto
mimeData
=
qobject_cast
<
const
TabMimeData
*>
(
e
->
mimeData
());
if
(
mimeData
&&
this
!=
mimeData
->
sourceVS
&&
!
hasDocument
(
mimeData
->
doc
))
{
m_dropIndicator
.
reset
(
new
QRubberBand
(
QRubberBand
::
Rectangle
,
this
));
m_dropIndicator
->
setGeometry
(
rect
());
m_dropIndicator
->
show
();
e
->
acceptProposedAction
();
return
;
}
QWidget
::
dragEnterEvent
(
e
);
}
void
KateViewSpace
::
dragLeaveEvent
(
QDragLeaveEvent
*
e
)
{
m_dropIndicator
.
reset
();
QWidget
::
dragLeaveEvent
(
e
);
}
void
KateViewSpace
::
dropEvent
(
QDropEvent
*
e
)
{
if
(
auto
mimeData
=
qobject_cast
<
const
TabMimeData
*>
(
e
->
mimeData
()))
{
m_viewManager
->
moveViewToViewSpace
(
this
,
mimeData
->
sourceVS
,
mimeData
->
doc
);
m_dropIndicator
.
reset
();
e
->
accept
();
return
;
}
QWidget
::
dropEvent
(
e
);
}
bool
KateViewSpace
::
hasDocument
(
KTextEditor
::
Document
*
doc
)
const
{
return
m_registeredDocuments
.
contains
(
doc
)
&&
(
m_docToView
.
find
(
doc
)
!=
m_docToView
.
end
());
}
KTextEditor
::
View
*
KateViewSpace
::
takeView
(
KTextEditor
::
Document
*
doc
)
{
auto
it
=
m_docToView
.
find
(
doc
);
if
(
it
==
m_docToView
.
end
())
{
return
nullptr
;
}
auto
*
view
=
it
->
second
;
stack
->
removeWidget
(
view
);
m_tabBar
->
removeDocument
(
doc
);
documentDestroyed
(
doc
);
return
view
;
}
void
KateViewSpace
::
addView
(
KTextEditor
::
View
*
v
)
{
registerDocument
(
v
->
document
());
m_docToView
[
v
->
document
()]
=
v
;
// We must not already have this widget
Q_ASSERT
(
stack
->
indexOf
(
v
)
==
-
1
);
stack
->
addWidget
(
v
);
showView
(
v
);
}
void
KateViewSpace
::
documentDestroyed
(
QObject
*
doc
)
{
/**
...
...
kate/kateviewspace.h
View file @
615c9fdd
...
...
@@ -31,6 +31,8 @@ class KateViewSpace : public QWidget
public:
explicit
KateViewSpace
(
KateViewManager
*
,
QWidget
*
parent
=
nullptr
,
const
char
*
name
=
nullptr
);
~
KateViewSpace
();
/**
* Returns \e true, if this view space is currently the active view space.
*/
...
...
@@ -82,6 +84,24 @@ public:
*/
void
closeDocument
(
KTextEditor
::
Document
*
doc
);
/*
* Does this viewspace contain @p doc
*/
bool
hasDocument
(
KTextEditor
::
Document
*
doc
)
const
;
/**
* Removes @p doc from this space and returns the associated
* view
* Used for dnd
*/
KTextEditor
::
View
*
takeView
(
KTextEditor
::
Document
*
doc
);
/**
* Adds @p view to this space
* Used for dnd to add a view from another viewspace
*/
void
addView
(
KTextEditor
::
View
*
v
);
/**
* Event filter to catch events from view space tool buttons.
*/
...
...
@@ -146,6 +166,12 @@ public:
void
addPositionToHistory
(
const
QUrl
&
url
,
KTextEditor
::
Cursor
,
bool
calledExternally
=
false
);
// END Location History Stuff
protected:
// DND
void
dragEnterEvent
(
QDragEnterEvent
*
e
)
override
;
void
dragLeaveEvent
(
QDragLeaveEvent
*
e
)
override
;
void
dropEvent
(
QDropEvent
*
e
)
override
;
Q_SIGNALS:
void
viewSpaceEmptied
(
KateViewSpace
*
vs
);
...
...
@@ -256,6 +282,9 @@ private:
// go forward in history button (only visible when the tab bar is visible)
QToolButton
*
m_historyForward
;
// rubber band to indicate drag and drop
std
::
unique_ptr
<
class
QRubberBand
>
m_dropIndicator
;
friend
class
LocationHistoryTest
;
};
...
...
kate/tabmimedata.cpp
0 → 100644
View file @
615c9fdd
#include
"tabmimedata.h"
TabMimeData
::
TabMimeData
(
KateViewSpace
*
vs
,
KTextEditor
::
Document
*
d
,
int
sourceTabIdx
)
:
QMimeData
()
,
sourceVS
(
vs
)
,
doc
(
d
)
,
tabIdx
(
sourceTabIdx
)
{
}
kate/tabmimedata.h
0 → 100644
View file @
615c9fdd
#ifndef KATE_TAB_MIME_DATA_H
#define KATE_TAB_MIME_DATA_H
#include
<QMimeData>
#include
"kateviewspace.h"
namespace
KTextEditor
{
class
Document
;
}
class
TabMimeData
:
public
QMimeData
{
Q_OBJECT
public:
TabMimeData
(
KateViewSpace
*
vs
,
KTextEditor
::
Document
*
d
,
int
sourceTabIdx
);
KateViewSpace
*
const
sourceVS
;
KTextEditor
::
Document
*
const
doc
;
const
int
tabIdx
;
};
#endif
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment