31 from python_qt_binding.QtCore
import qDebug, QEvent, QPoint, QRect, Qt
32 from python_qt_binding.QtGui
import QMouseEvent
33 from python_qt_binding.QtWidgets
import QApplication, QDockWidget
40 """Widget with the capability to be reparented via drag-and-drop to any other main window.""" 53 if e.type() == QEvent.MouseButtonPress
and e.button() == Qt.LeftButton:
54 qDebug(
'%spress, rel=%s, global=%s, diff=%s' % (
56 e.pos(), e.globalPos(), e.globalPos() - self.pos()))
58 if e.type() == QEvent.MouseButtonRelease
and e.button() == Qt.LeftButton:
59 qDebug(
'%srelease, rel=%s, global=%s, diff=%s' % (
61 e.pos(), e.globalPos(), e.globalPos() - self.pos()))
66 e.type() == QEvent.MouseButtonPress
and \
67 e.button() == Qt.LeftButton
and \
68 bool(self.features() & QDockWidget.DockWidgetMovable):
73 e.type() == QEvent.Move
and \
74 QApplication.mouseButtons() & Qt.LeftButton:
77 'DockWidget._event() start drag, dockwidget=%s, parent=%s, ' 78 'floating=%s, pos=%s' % (
79 str(self), str(self.parent()),
80 str(self.isFloating()),
85 self.setAttribute(Qt.WA_TransparentForMouseEvents)
89 self.
_main_windows = [self._container_manager.get_root_main_window()]
90 for container
in self._container_manager.get_containers():
93 self._main_windows.append(container.main_window)
98 e.type() == QEvent.MouseButtonRelease
and \
99 e.button() == Qt.LeftButton \
104 e.type() == QEvent.MouseButtonRelease
and \
105 e.button() == Qt.LeftButton
and \
107 qDebug(
'DockWidget._event() stop drag, dockwidget=%s, parent=%s\n' %
108 (self, self.parent()))
110 self.setAttribute(Qt.WA_TransparentForMouseEvents,
False)
114 e.type() == QEvent.MouseMove
and \
115 e.buttons() & Qt.LeftButton
and \
120 if new_parent
is not None and new_parent != self.parent():
124 mouse_release_event = QMouseEvent(
126 e.globalPos(), Qt.LeftButton, Qt.NoButton, e.modifiers())
127 QApplication.instance().postEvent(self, mouse_release_event)
128 QApplication.sendPostedEvents()
133 QApplication.sendPostedEvents()
136 self.setAttribute(Qt.WA_TransparentForMouseEvents,
False)
139 mouse_repress_event = QMouseEvent(
141 Qt.LeftButton, Qt.LeftButton, e.modifiers())
142 QApplication.instance().postEvent(self, mouse_repress_event)
143 QApplication.sendPostedEvents()
147 mouse_move_event = QMouseEvent(
150 e.globalPos() + QPoint(QApplication.startDragDistance(), 1),
154 QApplication.instance().postEvent(self, mouse_move_event)
155 QApplication.sendPostedEvents()
157 mouse_move_event = QMouseEvent(
159 Qt.NoButton, Qt.LeftButton, e.modifiers())
160 QApplication.instance().postEvent(self, mouse_move_event)
161 QApplication.sendPostedEvents()
164 self.setAttribute(Qt.WA_TransparentForMouseEvents)
168 return super(DockWidget, self).
event(e)
171 from .dock_widget_container
import DockWidgetContainer
172 if isinstance(widget, DockWidgetContainer):
173 if widget.isFloating():
175 widget = widget.parent()
176 while widget
is not None:
177 if isinstance(widget, DockableMainWindow):
179 if not callable(widget.parent):
181 widget = widget.parent()
186 widget = QApplication.widgetAt(global_point)
188 root_main_window = self._container_manager.get_root_main_window()
191 if widget == root_main_window
and \
197 if widget
is None and self.isFloating():
202 parent = main_window.parent()
203 is_floating = parent
is None or parent.isFloating()
204 overlapping[main_window] = is_floating
207 if len(overlapping) == 1:
209 widget, _ = overlapping.popitem()
210 elif len(overlapping) > 1:
213 overlapping_docked = [mw
for mw, floating
in overlapping.items()
if not floating]
217 if len(overlapping_docked) >= len(overlapping) - 1:
224 for mw1
in overlapping_docked:
226 parent = mw1.parent()
230 parent = parent.parent()
233 for mw2
in overlapping_docked:
236 for parent
in parents:
237 overlapping_docked.remove(parent)
241 if len(overlapping_docked) == 1:
243 widget = overlapping_docked[0]
254 topleft = widget.mapToGlobal(widget.mapFromParent(widget.geometry().topLeft()))
255 rect = QRect(topleft, widget.geometry().size())
256 return rect.contains(point)
264 title_bar = self.titleBarWidget()
265 title_bar.save_settings(settings)
268 serial_number = settings.value(
'parent',
None)
271 if serial_number
is not None:
272 serial_number = int(serial_number)
275 floating = self.isFloating()
277 new_container = self._container_manager.get_container(serial_number)
278 if new_container
is not None:
279 new_parent = new_container.main_window
281 new_parent = self._container_manager.get_root_main_window()
282 area = self.parent().dockWidgetArea(self)
283 new_parent.addDockWidget(area, self)
285 self.setFloating(floating)
288 title_bar = self.titleBarWidget()
289 title_bar.restore_settings(settings)
292 from .dock_widget_container
import DockWidgetContainer
293 parent = dock_widget.parent()
294 if parent
is not None:
295 parent = parent.parent()
296 if isinstance(parent, DockWidgetContainer):
303 if parent
is not None:
304 serial_number = parent.serial_number()