Skip to content

Commit

Permalink
#5231: Move clipboard handling to separate module to prevent crashes …
Browse files Browse the repository at this point in the history
…at shutdown due to memory allocation/deallocation problems.
  • Loading branch information
codereader committed Jul 9, 2020
1 parent 239df58 commit 6ec1bd3
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 57 deletions.
43 changes: 43 additions & 0 deletions include/iclipboard.h
@@ -0,0 +1,43 @@
#pragma once

#include <string>
#include "imodule.h"

namespace radiant
{

/**
* Interface to DarkRadiant's clipboard which is able to
* store and retrieve a string from and to the system clipboard.
* Access it through the GlobalClipboard() function.
*
* This module might not be present in all configurations
* so its advisable to check for its presence first.
*/
class IClipboard :
public RegisterableModule
{
public:
virtual ~IClipboard() {}

/// Return the contents of the clipboard as a string
virtual std::string getString() = 0;

/// Copy the given string to the system clipboard
virtual void setString(const std::string& str) = 0;
};

}

const char* const MODULE_CLIPBOARD("Clipboard");

inline radiant::IClipboard& GlobalClipboard()
{
// Cache the reference locally
static radiant::IClipboard& _instance(
*std::static_pointer_cast<radiant::IClipboard>(
module::GlobalModuleRegistry().getModule(MODULE_CLIPBOARD)
)
);
return _instance;
}
1 change: 0 additions & 1 deletion libs/wxutil/Makefile.am
Expand Up @@ -47,6 +47,5 @@ libwxutil_la_SOURCES = ConsoleView.cpp \
MouseToolHandler.cpp \
SerialisableWidgets.cpp \
SourceView.cpp \
clipboard.cpp \
DirChooser.cpp \
FileChooser.cpp
37 changes: 0 additions & 37 deletions libs/wxutil/clipboard.cpp

This file was deleted.

12 changes: 0 additions & 12 deletions libs/wxutil/clipboard.h

This file was deleted.

59 changes: 59 additions & 0 deletions radiant/clipboard/ClipboardModule.cpp
@@ -0,0 +1,59 @@
#include "ClipboardModule.h"

#include "itextstream.h"
#include <wx/clipbrd.h>

#include "module/StaticModule.h"

namespace ui
{

std::string ClipboardModule::getString()
{
std::string returnValue;

if (wxTheClipboard->Open())
{
if (wxTheClipboard->IsSupported(wxDF_TEXT))
{
wxTextDataObject data;
wxTheClipboard->GetData(data);
returnValue = data.GetText().ToStdString();
}

wxTheClipboard->Close();
}

return returnValue;
}

void ClipboardModule::setString(const std::string& str)
{
if (wxTheClipboard->Open())
{
// This data objects are held by the clipboard, so do not delete them in the app.
wxTheClipboard->SetData(new wxTextDataObject(str));
wxTheClipboard->Close();
}
}

const std::string& ClipboardModule::getName() const
{
static std::string _name(MODULE_CLIPBOARD);
return _name;
}

const StringSet& ClipboardModule::getDependencies() const
{
static StringSet _dependencies;
return _dependencies;
}

void ClipboardModule::initialiseModule(const ApplicationContext& ctx)
{
rMessage() << getName() << "::initialiseModule called." << std::endl;
}

module::StaticModule<ClipboardModule> clipboardModule;

}
20 changes: 20 additions & 0 deletions radiant/clipboard/ClipboardModule.h
@@ -0,0 +1,20 @@
#pragma once

#include "iclipboard.h"

namespace ui
{

class ClipboardModule :
public radiant::IClipboard
{
public:
std::string getString() override;
void setString(const std::string& str) override;

const std::string& getName() const override;
const StringSet& getDependencies() const override;
void initialiseModule(const ApplicationContext& ctx) override;
};

}
17 changes: 14 additions & 3 deletions radiantcore/selection/clipboard/Clipboard.cpp
Expand Up @@ -4,13 +4,14 @@
#include "igrid.h"
#include "icamera.h"
#include "imapformat.h"
#include "iclipboard.h"

#include "wxutil/clipboard.h"
#include "map/Map.h"
#include "brush/FaceInstance.h"
#include "map/algorithm/Import.h"
#include "selection/algorithm/General.h"
#include "selection/algorithm/Transformation.h"
#include "command/ExecutionNotPossible.h"

namespace selection
{
Expand All @@ -20,14 +21,24 @@ namespace clipboard

void pasteToMap()
{
std::stringstream stream(wxutil::pasteFromClipboard());
if (!module::GlobalModuleRegistry().moduleExists(MODULE_CLIPBOARD))
{
throw cmd::ExecutionNotPossible(_("No clipboard module attached, cannot perform this action."));
}

std::stringstream stream(GlobalClipboard().getString());
map::algorithm::importFromStream(stream);
}

void copy(const cmd::ArgumentList& args)
{
if (FaceInstance::Selection().empty())
{
if (!module::GlobalModuleRegistry().moduleExists(MODULE_CLIPBOARD))
{
throw cmd::ExecutionNotPossible(_("No clipboard module attached, cannot perform this action."));
}

// When exporting to the system clipboard, use the portable format
auto format = GlobalMapFormatManager().getMapFormatByName(map::PORTABLE_MAP_FORMAT_NAME);

Expand All @@ -36,7 +47,7 @@ void copy(const cmd::ArgumentList& args)
GlobalMap().exportSelected(out, format);

// Copy the resulting string to the clipboard
wxutil::copyToClipboard(out.str());
GlobalClipboard().setString(out.str());
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions tools/msvc/DarkRadiant.vcxproj
Expand Up @@ -195,6 +195,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\radiant\camera\CamRenderer.cpp" />
<ClCompile Include="..\..\radiant\clipboard\ClipboardModule.cpp" />
<ClCompile Include="..\..\radiant\eventmanager\Accelerator.cpp" />
<ClCompile Include="..\..\radiant\eventmanager\EventManager.cpp" />
<ClCompile Include="..\..\radiant\eventmanager\GlobalKeyEventFilter.cpp" />
Expand Down Expand Up @@ -371,6 +372,7 @@
<ClInclude Include="..\..\radiant\camera\tools\JumpToObjectTool.h" />
<ClInclude Include="..\..\radiant\camera\tools\PanViewTool.h" />
<ClInclude Include="..\..\radiant\camera\tools\ShaderClipboardTools.h" />
<ClInclude Include="..\..\radiant\clipboard\ClipboardModule.h" />
<ClInclude Include="..\..\radiant\eventmanager\Accelerator.h" />
<ClInclude Include="..\..\radiant\eventmanager\Event.h" />
<ClInclude Include="..\..\radiant\eventmanager\EventManager.h" />
Expand Down
9 changes: 9 additions & 0 deletions tools/msvc/DarkRadiant.vcxproj.filters
Expand Up @@ -167,6 +167,9 @@
<Filter Include="src\ui\shaderclipboard">
<UniqueIdentifier>{f4546842-2dad-4e9d-bc49-d4888d8776db}</UniqueIdentifier>
</Filter>
<Filter Include="src\clipboard">
<UniqueIdentifier>{a12b340c-f537-4113-bc7c-2bbfb35b8d0b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\radiant\main.cpp">
Expand Down Expand Up @@ -652,6 +655,9 @@
<ClCompile Include="..\..\radiant\ui\brush\FindBrush.cpp">
<Filter>src\ui\brush</Filter>
</ClCompile>
<ClCompile Include="..\..\radiant\clipboard\ClipboardModule.cpp">
<Filter>src\clipboard</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\radiant\RadiantModule.h">
Expand Down Expand Up @@ -1260,6 +1266,9 @@
<ClInclude Include="..\..\radiant\ui\shaderclipboard\ShaderClipboardStatus.h">
<Filter>src\ui\shaderclipboard</Filter>
</ClInclude>
<ClInclude Include="..\..\radiant\clipboard\ClipboardModule.h">
<Filter>src\clipboard</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\radiant\darkradiant.rc" />
Expand Down
1 change: 1 addition & 0 deletions tools/msvc/include.vcxproj
Expand Up @@ -103,6 +103,7 @@
<ClInclude Include="..\..\include\ibrush.h" />
<ClInclude Include="..\..\include\icamera.h" />
<ClInclude Include="..\..\include\icameraview.h" />
<ClInclude Include="..\..\include\iclipboard.h" />
<ClInclude Include="..\..\include\iclipper.h" />
<ClInclude Include="..\..\include\icommandsystem.h" />
<ClInclude Include="..\..\include\icounter.h" />
Expand Down
2 changes: 0 additions & 2 deletions tools/msvc/wxutillib.vcxproj
Expand Up @@ -137,7 +137,6 @@
<ItemGroup>
<ClInclude Include="..\..\libs\wxutil\Button.h" />
<ClInclude Include="..\..\libs\wxutil\ChoiceHelper.h" />
<ClInclude Include="..\..\libs\wxutil\clipboard.h" />
<ClInclude Include="..\..\libs\wxutil\ConsoleView.h" />
<ClInclude Include="..\..\libs\wxutil\ControlButton.h" />
<ClInclude Include="..\..\libs\wxutil\DeferredMotionDelta.h" />
Expand Down Expand Up @@ -188,7 +187,6 @@
<ClInclude Include="..\..\libs\wxutil\XmlResourceBasedWidget.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\libs\wxutil\clipboard.cpp" />
<ClCompile Include="..\..\libs\wxutil\ConsoleView.cpp" />
<ClCompile Include="..\..\libs\wxutil\dialog\Dialog.cpp" />
<ClCompile Include="..\..\libs\wxutil\dialog\DialogBase.cpp" />
Expand Down
2 changes: 0 additions & 2 deletions tools/msvc/wxutillib.vcxproj.filters
Expand Up @@ -78,7 +78,6 @@
<ClInclude Include="..\..\libs\wxutil\WindowPosition.h" />
<ClInclude Include="..\..\libs\wxutil\XmlResourceBasedWidget.h" />
<ClInclude Include="..\..\libs\wxutil\ChoiceHelper.h" />
<ClInclude Include="..\..\libs\wxutil\clipboard.h" />
<ClInclude Include="..\..\libs\wxutil\ConsoleView.h" />
<ClInclude Include="..\..\libs\wxutil\ControlButton.h" />
<ClInclude Include="..\..\libs\wxutil\DeferredMotionDelta.h" />
Expand Down Expand Up @@ -137,7 +136,6 @@
<ClCompile Include="..\..\libs\wxutil\TreeModelFilter.cpp" />
<ClCompile Include="..\..\libs\wxutil\VFSTreePopulator.cpp" />
<ClCompile Include="..\..\libs\wxutil\WindowPosition.cpp" />
<ClCompile Include="..\..\libs\wxutil\clipboard.cpp" />
<ClCompile Include="..\..\libs\wxutil\ConsoleView.cpp" />
<ClCompile Include="..\..\libs\wxutil\DirChooser.cpp" />
<ClCompile Include="..\..\libs\wxutil\FileChooser.cpp" />
Expand Down

0 comments on commit 6ec1bd3

Please sign in to comment.