Commit 2916f7e9 authored by Waqar Ahmed's avatar Waqar Ahmed
Browse files

Allow DND of widgets between viewspaces

parent 79c85bad
Pipeline #259250 failed with stage
in 7 minutes and 8 seconds
......@@ -224,8 +224,7 @@ void KateTabBar::mouseMoveEvent(QMouseEvent *event)
QRect rect = tabRect(tab);
const auto tabData = this->tabData(tab).value<DocOrWidget>();
auto *tabObject = tabData.qobject();
// We don't support moving widgets atm
if (!tabData.doc()) {
if (!tabObject) {
return;
}
......@@ -253,20 +252,20 @@ void KateTabBar::mouseMoveEvent(QMouseEvent *event)
paint.drawControl(QStyle::CE_TabBarTab, opt);
paint.end();
QByteArray data;
auto view = viewSpace->currentView();
if (!view) {
if (view) {
KTextEditor::Cursor cp = view->cursorPosition();
QDataStream ds(&data, QIODevice::WriteOnly);
ds << cp.line();
ds << cp.column();
ds << view->document()->url();
} else if (!viewSpace->currentWidget()) {
qWarning() << "No view or widget, why?";
return;
}
QByteArray data;
KTextEditor::Cursor cp = view->cursorPosition();
QDataStream ds(&data, QIODevice::WriteOnly);
ds << cp.line();
ds << cp.column();
ds << view->document()->url();
auto doc = tabDocument(tab).doc(); // We know for sure there is a doc because of above check
auto mime = new TabMimeData(viewSpace, doc);
auto mime = new TabMimeData(viewSpace, tabData);
mime->setData(QStringLiteral("application/kate.tab.mimedata"), data);
QDrag *drag = new QDrag(this);
......@@ -290,7 +289,7 @@ void KateTabBar::mouseMoveEvent(QMouseEvent *event)
for (; tabIdx < count(); ++tabIdx) {
auto d = this->tabData(tabIdx);
// We only expect doc, no dnd support for widgets
if (d.value<DocOrWidget>().doc() == tabObject) {
if (d.value<DocOrWidget>().qobject() == tabObject) {
found = true;
break;
}
......
......@@ -1003,7 +1003,7 @@ void KateViewManager::closeView(KTextEditor::View *view)
}
}
void KateViewManager::moveViewToViewSpace(KateViewSpace *dest, KateViewSpace *src, KTextEditor::Document *doc)
void KateViewManager::moveViewToViewSpace(KateViewSpace *dest, KateViewSpace *src, DocOrWidget docOrWidget)
{
// We always have an active view at this point which is what we are moving
Q_ASSERT(activeView());
......@@ -1014,15 +1014,20 @@ void KateViewManager::moveViewToViewSpace(KateViewSpace *dest, KateViewSpace *sr
return;
}
auto view = src->takeView(doc);
QWidget *view = src->takeView(docOrWidget);
if (!view) {
qWarning() << Q_FUNC_INFO << "Unexpected null view when trying to drag the view to a different viewspace" << doc;
qWarning() << Q_FUNC_INFO << "Unexpected null view when trying to drag the view to a different viewspace" << docOrWidget.qobject();
return;
}
dest->addView(view);
setActiveSpace(dest);
activateView(view);
auto kteView = qobject_cast<KTextEditor::View *>(view);
if (kteView) {
activateView(kteView->document());
} else {
activateView(view);
}
}
void KateViewManager::splitViewSpace(KateViewSpace *vs, // = 0
......
......@@ -89,7 +89,7 @@ public:
void closeView(KTextEditor::View *view);
KateMainWindow *mainWindow();
void moveViewToViewSpace(KateViewSpace *dest, KateViewSpace *src, KTextEditor::Document *doc);
void moveViewToViewSpace(KateViewSpace *dest, KateViewSpace *src, DocOrWidget doc);
private Q_SLOTS:
void activateView(KTextEditor::View *view);
......
......@@ -619,23 +619,36 @@ void KateViewSpace::dropEvent(QDropEvent *e)
QWidget::dropEvent(e);
}
bool KateViewSpace::hasDocument(KTextEditor::Document *doc) const
bool KateViewSpace::hasDocument(DocOrWidget doc) const
{
return m_registeredDocuments.contains(doc);
}
KTextEditor::View *KateViewSpace::takeView(KTextEditor::Document *doc)
QWidget *KateViewSpace::takeView(DocOrWidget docOrWidget)
{
auto it = m_docToView.find(doc);
if (it == m_docToView.end()) {
return nullptr;
QWidget *ret;
if (docOrWidget.doc()) {
auto it = m_docToView.find(docOrWidget.doc());
if (it == m_docToView.end()) {
qWarning() << "Unexpected unable to find a view for " << docOrWidget.qobject();
return nullptr;
}
ret = it->second;
// remove it from the stack
stack->removeWidget(ret);
// remove it from our doc->view mapping
m_docToView.erase(it);
documentDestroyed(docOrWidget.doc());
} else if (docOrWidget.widget()) {
stack->removeWidget(docOrWidget.widget());
m_registeredDocuments.removeAll(docOrWidget);
m_tabBar->removeDocument(docOrWidget);
ret = docOrWidget.widget();
} else {
qWarning() << "Unexpected docOrWidget: " << docOrWidget.qobject();
ret = nullptr;
Q_UNREACHABLE();
}
auto *view = it->second;
// remove it from the stack
stack->removeWidget(view);
// remove it from our doc->view mapping
m_docToView.erase(it);
documentDestroyed(doc);
// Did we just loose our last doc?
// Send a delayed signal. Delay is important as we want to kill
......@@ -649,16 +662,21 @@ KTextEditor::View *KateViewSpace::takeView(KTextEditor::Document *doc)
Qt::QueuedConnection);
}
return view;
return ret;
}
void KateViewSpace::addView(KTextEditor::View *v)
void KateViewSpace::addView(QWidget *w)
{
registerDocument(v->document());
m_docToView[v->document()] = v;
// We must not already have this widget
Q_ASSERT(stack->indexOf(v) == -1);
stack->addWidget(v);
Q_ASSERT(stack->indexOf(w) == -1);
if (auto v = qobject_cast<KTextEditor::View *>(w)) {
registerDocument(v->document());
m_docToView[v->document()] = v;
stack->addWidget(v);
} else {
addWidgetAsTab(w);
}
}
void KateViewSpace::documentDestroyed(QObject *doc)
......
......@@ -107,20 +107,20 @@ public:
/*
* Does this viewspace contain @p doc
*/
bool hasDocument(KTextEditor::Document *doc) const;
bool hasDocument(DocOrWidget doc) const;
/**
* Removes @p doc from this space and returns the associated
* view
* view or a widget
* Used for dnd
*/
KTextEditor::View *takeView(KTextEditor::Document *doc);
QWidget *takeView(DocOrWidget);
/**
* Adds @p view to this space
* Used for dnd to add a view from another viewspace
*/
void addView(KTextEditor::View *v);
void addView(QWidget *w);
/**
* Event filter to catch events from view space tool buttons.
......
......@@ -8,7 +8,7 @@
#include <QDataStream>
TabMimeData::TabMimeData(KateViewSpace *vs, KTextEditor::Document *d)
TabMimeData::TabMimeData(KateViewSpace *vs, DocOrWidget d)
: QMimeData()
, sourceVS(vs)
, doc(d)
......
......@@ -28,14 +28,14 @@ public:
QUrl url;
};
TabMimeData(KateViewSpace *vs, KTextEditor::Document *d);
TabMimeData(KateViewSpace *vs, DocOrWidget d);
static bool hasValidData(const QMimeData *md);
static std::optional<DroppedData> data(const QMimeData *md);
KateViewSpace *const sourceVS;
KTextEditor::Document *const doc;
const DocOrWidget doc;
};
#endif
  • This crashes

    
    
    #0  0x000072aeb0ea164c in ?? () from /usr/lib/libc.so.6
    #1  0x000072aeb0e51958 in raise () from /usr/lib/libc.so.6
    #2  0x000072aeb4896af5 in KCrash::defaultCrashHandler (sig=6)
        at /home/eric/kde/src/kcrash/src/kcrash.cpp:633
    #3  <signal handler called>
    #4  0x000072aeb0ea164c in ?? () from /usr/lib/libc.so.6
    #5  0x000072aeb0e51958 in raise () from /usr/lib/libc.so.6
    #6  0x000072aeb0e3b53d in abort () from /usr/lib/libc.so.6
    #7  0x000072aeb149fede in QMessageLogger::fatal(char const*, ...) const ()
       from /usr/lib/libQt5Core.so.5
    #8  0x000072aeb149ff3c in qt_assert(char const*, char const*, int) ()
       from /usr/lib/libQt5Core.so.5
    #9  0x000072aeb4711143 in KateViewManager::moveViewToViewSpace (this=0x5a64bb2e64c0, 
        dest=0x5a64baf74ec0, src=0x5a64bb2e7460, docOrWidget=...)
        at /home/eric/kde/src/kate/apps/lib/kateviewmanager.cpp:1009
    #10 0x000072aeb471f305 in KateViewSpace::dropEvent (this=0x5a64baf74ec0, e=0x7ffdfa31e750)
        at /home/eric/kde/src/kate/apps/lib/kateviewspace.cpp:602
    #11 0x000072aeb23af558 in QWidget::event(QEvent*) () from /usr/lib/libQt5Widgets.so.5
    #12 0x000072aeb2378b1c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
       from /usr/lib/libQt5Widgets.so.5
    #13 0x000072aeb237f016 in QApplication::notify(QObject*, QEvent*) ()
       from /usr/lib/libQt5Widgets.so.5
    #14 0x000072aeb168cf98 in QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
       from /usr/lib/libQt5Core.so.5
    #15 0x000072aeb23cfa94 in ?? () from /usr/lib/libQt5Widgets.so.5
    #16 0x000072aeb2378b1c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
       from /usr/lib/libQt5Widgets.so.5
    #17 0x000072aeb168cf98 in QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
       from /usr/lib/libQt5Core.so.5
    #18 0x000072aeb1b49f2f in QGuiApplicationPrivate::processDrop(QWindow*, QMimeData const*, QPoint const&, QFlags<Qt::DropAction>, QFlags<Qt::MouseButton>, QFlags<Qt::KeyboardModifier>) ()
       from /usr/lib/libQt5Gui.so.5
    #19 0x000072aeb1b281f6 in QWindowSystemInterface::handleDrop(QWindow*, QMimeData const*, QPoint const&, QFlags<Qt::DropAction>, QFlags<Qt::MouseButton>, QFlags<Qt::KeyboardModifier>) ()
       from /usr/lib/libQt5Gui.so.5
    #20 0x000072aeaf8ab5fb in ?? () from /usr/lib/libQt5WaylandClient.so.5
    #21 0x000072aeaf0a94f6 in ?? () from /usr/lib/libffi.so.8
    #22 0x000072aeaf0a5f5e in ?? () from /usr/lib/libffi.so.8
    #23 0x000072aeaf0a8b73 in ffi_call () from /usr/lib/libffi.so.8
    #24 0x000072aeb0e0e645 in ?? () from /usr/lib/libwayland-client.so.0
    #25 0x000072aeb0e0ee03 in ?? () from /usr/lib/libwayland-client.so.0
    #26 0x000072aeb0e0effc in wl_display_dispatch_
    
  • I tried dragging a widget tab between viewspaces

  • @eric yeah, the assert was wrong. fixed in master

Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment