Skip to content

Commit

Permalink
#92 : Settings UI can now display / handle base custom commands
Browse files Browse the repository at this point in the history
  • Loading branch information
clechasseur committed Jan 19, 2020
1 parent d22b1c0 commit 9830a0d
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 134 deletions.
8 changes: 6 additions & 2 deletions PathCopyCopy/plugins/prihdr/PipelinePlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <PathCopyCopyPrivateTypes.h>
#include <Plugin.h>

#include <optional>


namespace PCC
{
Expand All @@ -47,6 +49,7 @@ namespace PCC
PipelinePlugin& operator=(const PipelinePlugin&) = delete;

const Pipeline* GetPipeline(GUIDS* p_psSeenPluginIds = nullptr) const;
std::string GetPipelineError() const;

const GUID& Id() const noexcept(false) override;

Expand All @@ -69,8 +72,9 @@ namespace PCC
const std::wstring m_IconFile; // Plugin icon file.
const bool m_UseDefaultIcon; // Whether to use default icon for plugin.
const std::wstring m_EncodedElements; // Pipeline encoded elements.
mutable PipelineSP m_spPipeline; // Pipeline to execute on each path received.
mutable bool m_PipelineCreated; // Whether m_spPipeline has been created.
mutable std::optional<PipelineSP>
m_spPipeline; // Pipeline to execute on each path received.
mutable std::string m_PipelineError; // If pipeline failed to load, can contain the error message.
};

} // namespace Plugins
Expand Down
35 changes: 27 additions & 8 deletions PathCopyCopy/plugins/src/PipelinePlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ namespace PCC
m_UseDefaultIcon(p_UseDefaultIcon),
m_EncodedElements(p_EncodedElements),
m_spPipeline(),
m_PipelineCreated(false)
m_PipelineError()
{
}

Expand All @@ -68,21 +68,38 @@ namespace PCC
//
const Pipeline* PipelinePlugin::GetPipeline(GUIDS* const p_psSeenPluginIds /*= nullptr*/) const
{
if (!m_PipelineCreated) {
if (!m_spPipeline.has_value()) {
try {
m_spPipeline = std::make_shared<Pipeline>(m_EncodedElements);
PipelineSP spPipeline = std::make_shared<Pipeline>(m_EncodedElements);

// Make sure pipeline is valid.
GUIDS sSeenPluginIds;
GUIDS& rsSeenPluginIds = p_psSeenPluginIds != nullptr ? *p_psSeenPluginIds : sSeenPluginIds;
if (!rsSeenPluginIds.emplace(Id()).second || !m_spPipeline->Valid(m_pPluginProvider, rsSeenPluginIds)) {
m_spPipeline = nullptr;
if (!rsSeenPluginIds.emplace(Id()).second) {
throw InvalidPipelineException(ATL::CStringA(MAKEINTRESOURCEA(IDS_INVALIDPIPELINE_LOOP_DETECTED)));
}
} catch (const InvalidPipelineException&) {
spPipeline->Validate(m_pPluginProvider, rsSeenPluginIds);

m_spPipeline = spPipeline;
m_PipelineError.clear();
} catch (const std::exception& e) {
m_spPipeline = std::make_optional<PipelineSP>(nullptr);
m_PipelineError = e.what();
}
m_PipelineCreated = true;
}
return m_spPipeline.get();
return m_spPipeline.value().get();
}

//
// Returns any error message retrieved when this plugin's pipeline
// has been loaded. Call this if GetPipeline returns nullptr to
// perhaps get more information.
//
// @return Error message. May be empty even if pipeline failed to load.
//
std::string PipelinePlugin::GetPipelineError() const
{
return m_PipelineError;
}

//
Expand Down Expand Up @@ -154,6 +171,8 @@ namespace PCC
const Pipeline* pPipeline = GetPipeline();
if (pPipeline != nullptr) {
pPipeline->ModifyPath(modifiedPath, m_pPluginProvider);
} else if (!m_PipelineError.empty()) {
modifiedPath = ATL::CStringW(m_PipelineError.c_str());
}
return modifiedPath;
}
Expand Down
20 changes: 16 additions & 4 deletions PathCopyCopy/prihdr/PluginPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "PathCopyCopyPrivateTypes.h"
#include "PluginProvider.h"

#include <exception>
#include <string>


Expand Down Expand Up @@ -70,8 +71,8 @@ namespace PCC
Pipeline(const Pipeline&) = delete;
Pipeline& operator=(const Pipeline&) = delete;

bool Valid(const PluginProvider* p_pPluginProvider,
GUIDS& p_rsSeenPluginIds) const;
void Validate(const PluginProvider* p_pPluginProvider,
GUIDS& p_rsSeenPluginIds) const;

void ModifyPath(std::wstring& p_rPath,
const PluginProvider* p_pPluginProvider) const;
Expand Down Expand Up @@ -100,8 +101,8 @@ namespace PCC
PipelineElement& operator=(PipelineElement&&) = delete;
virtual ~PipelineElement() = default;

virtual bool Valid(const PluginProvider* p_pPluginProvider,
GUIDS& p_rsSeenPluginIds) const noexcept(false);
virtual void Validate(const PluginProvider* p_pPluginProvider,
GUIDS& p_rsSeenPluginIds) const noexcept(false);

virtual void ModifyPath(std::wstring& p_rPath,
const PluginProvider* p_pPluginProvider) const = 0;
Expand All @@ -111,4 +112,15 @@ namespace PCC
const PluginProvider* p_pPluginProvider) const noexcept(false);
};

//
// Exception type thrown when a pipeline is invalid.
//
class InvalidPipelineException : public std::runtime_error
{
public:
[[gsl::suppress(f.6)]]
InvalidPipelineException();
explicit InvalidPipelineException(const char* p_pWhat);
};

} // namespace PCC
21 changes: 0 additions & 21 deletions PathCopyCopy/prihdr/PluginPipelineDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

#include "PathCopyCopyPrivateTypes.h"

#include <exception>
#include <string>


Expand Down Expand Up @@ -56,8 +55,6 @@ namespace PCC
EncodedElementsStream&
operator=(const EncodedElementsStream&) = delete;

auto GetEncodedElements() const noexcept -> const std::wstring&;

auto ReadData(std::wstring::size_type p_DataSize) -> std::wstring;
auto ReadElementCount() -> size_t;
auto ReadLong() -> long;
Expand All @@ -82,22 +79,4 @@ namespace PCC
EncodedElementsStream& p_rStream) -> PipelineElementSP;
};

//
// Exception type thrown when a encoded pipeline string is invalid.
//
class InvalidPipelineException : public std::exception
{
public:
InvalidPipelineException() noexcept;
explicit InvalidPipelineException(const std::wstring& p_EncodedElements);

const std::wstring&
EncodedElements() const noexcept;

const char* what() const noexcept override;

private:
std::wstring m_EncodedElements; // The pipeline's encoded string.
};

} // namespace PCC
4 changes: 2 additions & 2 deletions PathCopyCopy/prihdr/PluginPipelineElements.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,8 @@ namespace PCC
ApplyPipelinePluginPipelineElement&
operator=(const ApplyPipelinePluginPipelineElement&) = delete;

bool Valid(const PluginProvider* p_pPluginProvider,
GUIDS& p_rsSeenPluginIds) const override;
void Validate(const PluginProvider* p_pPluginProvider,
GUIDS& p_rsSeenPluginIds) const override;
};

//
Expand Down
5 changes: 5 additions & 0 deletions PathCopyCopy/rsrc/PathCopyCopy.rc
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ BEGIN
IDS_MSYS_PATH_PLUGIN_DESCRIPTION "Copy MS&YS/MSYS2 Path"
IDS_MSYS_PATH_PLUGIN_HINT
"Copies the path of the file/folder to the clipboard in MSYS/MSYS2 format."
IDS_INVALIDPIPELINE "<< Invalid custom command >>"
IDS_INVALIDPIPELINE_LOOP_DETECTED
"<< Loop detected in custom command elements >>"
IDS_INVALIDPIPELINE_POSSIBLE_DOWNGRADE
"<< Invalid custom command element (possible downgrade) >>"
END

#endif // English (United States) resources
Expand Down
3 changes: 3 additions & 0 deletions PathCopyCopy/rsrc/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
#define IDS_SAMBA_PATH_PLUGIN_HINT 148
#define IDS_MSYS_PATH_PLUGIN_DESCRIPTION 149
#define IDS_MSYS_PATH_PLUGIN_HINT 150
#define IDS_INVALIDPIPELINE 151
#define IDS_INVALIDPIPELINE_LOOP_DETECTED 152
#define IDS_INVALIDPIPELINE_POSSIBLE_DOWNGRADE 153
#define IDR_PATHCOPYCOPYCONTEXTMENUEXT 201
#define IDR_PATHCOPYCOPYDATAHANDLER 202
#define IDR_PATHCOPYCOPYCONFIGHELPER 203
Expand Down
44 changes: 32 additions & 12 deletions PathCopyCopy/src/PluginPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,19 +117,20 @@ namespace PCC
// Validates the pipeline. A pipeline is valid if all its elements
// are considered valid.
//
// When the pipeline is invalid, an InvalidPipelineException is thrown.
//
// @param p_pPluginProvider Optional plugin provider that can be used
// during validation.
// @param p_rsSeenPluginIds Set that should be used to store seen plugin IDs.
// Any collision means a loop is detected and
// pipeline should be considered invalid.
// @return true if the pipeline is valid.
//
bool Pipeline::Valid(const PluginProvider* const p_pPluginProvider,
GUIDS& p_rsSeenPluginIds) const
void Pipeline::Validate(const PluginProvider* const p_pPluginProvider,
GUIDS& p_rsSeenPluginIds) const
{
return std::all_of(m_vspElements.cbegin(), m_vspElements.cend(), [&](const auto& spElement) {
return spElement->Valid(p_pPluginProvider, p_rsSeenPluginIds);
});
for (const auto& spElement : m_vspElements) {
spElement->Validate(p_pPluginProvider, p_rsSeenPluginIds);
}
}


Expand All @@ -143,7 +144,7 @@ namespace PCC
void Pipeline::ModifyPath(std::wstring& p_rPath,
const PluginProvider* const p_pPluginProvider) const
{
for (const PipelineElementSP& spElement : m_vspElements) {
for (const auto& spElement : m_vspElements) {
spElement->ModifyPath(p_rPath, p_pPluginProvider);
}
}
Expand All @@ -156,7 +157,7 @@ namespace PCC
//
void Pipeline::ModifyOptions(PipelineOptions& p_rOptions) const
{
for (const PipelineElementSP& spElement : m_vspElements) {
for (const auto& spElement : m_vspElements) {
spElement->ModifyOptions(p_rOptions);
}
}
Expand Down Expand Up @@ -184,18 +185,19 @@ namespace PCC
// is implementation-specific, but should be used to detect recursion
// in plugin usage, for instance.
//
// When the pipeline element is invalid, an InvalidPipelineException
// should be thrown.
//
// @param p_pPluginProvider Optional plugin provider that can be used
// during validation.
// @param p_rsSeenPluginIds Set that should be used to store seen plugin IDs.
// Any collision means a loop is detected and
// pipeline element should be considered invalid.
// @return true if pipeline element is valid.
//
bool PipelineElement::Valid(const PluginProvider* const /*p_pPluginProvider*/,
GUIDS& /*p_rsSeenPluginIds*/) const noexcept(false)
void PipelineElement::Validate(const PluginProvider* const /*p_pPluginProvider*/,
GUIDS& /*p_rsSeenPluginIds*/) const noexcept(false)
{
// All pipeline elements are considered valid by default.
return true;
}

//
Expand Down Expand Up @@ -224,4 +226,22 @@ namespace PCC
return true;
}

//
// Default constructor.
//
InvalidPipelineException::InvalidPipelineException()
: std::runtime_error(ATL::CStringA(MAKEINTRESOURCEA(IDS_INVALIDPIPELINE)))
{
}

//
// Constructor with explanation string.
//
// @param p_pWhat Explanation string.
//
InvalidPipelineException::InvalidPipelineException(const char* const p_pWhat)
: std::runtime_error(p_pWhat)
{
}

} // namespace PCC
Loading

0 comments on commit 9830a0d

Please sign in to comment.