Files
ResInsight/ApplicationLibCode/UnitTests/RimDockWindowController-Test.cpp
T
Magne Sjaastad 9ac6ad3bec #14903: Avoid duplicate dock window ids for copied plots
Copies and plots created from templates kept the source DockWindowId. The dock
manager identifies dock widgets by name, so the earlier dock widget was deleted on
dock state restore, leaving a dangling pointer that crashed in setActiveViewer.

- Do not copy DockWindowId; copies get a new id
- Assign a new id if a dock widget with the same name exists
- Use QPointer for the dock widget
2026-10-12 18:49:08 +02:00

49 lines
2.2 KiB
C++

#include "gtest/gtest.h"
#include "RimDockWindowController.h"
#include "RimSummaryPlot.h"
#include "cafPdmDefaultObjectFactory.h"
#include <memory>
//--------------------------------------------------------------------------------------------------
/// handleViewerDeletion() used to dereference viewPdmObject() (m_viewToControl) unconditionally.
/// Calling it before setViewToControl() has ever been called (m_viewToControl is null) must not crash.
//--------------------------------------------------------------------------------------------------
TEST( RimDockWindowControllerTest, HandleViewerDeletionWithoutViewToControlDoesNotCrash )
{
RimDockWindowController controller;
EXPECT_NO_FATAL_FAILURE( controller.handleViewerDeletion() );
}
//--------------------------------------------------------------------------------------------------
/// The dock manager identifies dock widgets by the dock window id. Copied views, including plots created from a plot
/// template, must get a new id, while reading a project (or undoing a delete) must keep it.
//--------------------------------------------------------------------------------------------------
TEST( RimDockWindowControllerTest, DockWindowIdIsNotCopied )
{
RimSummaryPlot plot;
const QString dockId = plot.dockWindowName();
ASSERT_FALSE( dockId.isEmpty() );
std::unique_ptr<RimSummaryPlot> copy( plot.copyObject<RimSummaryPlot>() );
ASSERT_TRUE( copy );
EXPECT_NE( dockId, copy->dockWindowName() );
const QString xml = plot.writeObjectToXmlString();
std::unique_ptr<caf::PdmObjectHandle> fromTemplate(
caf::PdmXmlObjectHandle::readUnknownObjectFromXmlString( xml, caf::PdmDefaultObjectFactory::instance(), true ) );
auto templatePlot = dynamic_cast<RimSummaryPlot*>( fromTemplate.get() );
ASSERT_TRUE( templatePlot );
EXPECT_NE( dockId, templatePlot->dockWindowName() );
std::unique_ptr<caf::PdmObjectHandle> fromProject(
caf::PdmXmlObjectHandle::readUnknownObjectFromXmlString( xml, caf::PdmDefaultObjectFactory::instance(), false ) );
auto projectPlot = dynamic_cast<RimSummaryPlot*>( fromProject.get() );
ASSERT_TRUE( projectPlot );
EXPECT_EQ( dockId, projectPlot->dockWindowName() );
}