320 lines
9.9 KiB
C++
320 lines
9.9 KiB
C++
// This file is part of VSTGUI. It is subject to the license terms
|
|
// in the LICENSE file found in the top-level directory of this
|
|
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
|
|
|
#include "platform/iplatformfileselector.h"
|
|
#include "platform/platformfactory.h"
|
|
#include "cfileselector.h"
|
|
#include "cframe.h"
|
|
#include "cstring.h"
|
|
#include <algorithm>
|
|
|
|
namespace VSTGUI {
|
|
|
|
//-----------------------------------------------------------------------------
|
|
struct CFileExtension::Impl : PlatformFileExtension
|
|
{
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CFileExtension::CFileExtension ()
|
|
{
|
|
impl = std::make_unique<Impl> ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CFileExtension::CFileExtension (const UTF8String& inDescription, const UTF8String& inExtension,
|
|
const UTF8String& inMimeType, int32_t inMacType,
|
|
const UTF8String& inUti)
|
|
: CFileExtension ()
|
|
{
|
|
init (inDescription, inExtension, inMimeType, inUti);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CFileExtension::CFileExtension (const CFileExtension& ext) : CFileExtension ()
|
|
{
|
|
*impl = *ext.impl;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CFileExtension::~CFileExtension () noexcept = default;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CFileExtension::CFileExtension (CFileExtension&& ext) noexcept
|
|
{
|
|
*this = std::move (ext);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CFileExtension& CFileExtension::operator= (CFileExtension&& ext) noexcept
|
|
{
|
|
std::swap (impl, ext.impl);
|
|
return *this;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CFileExtension::init (const UTF8String& inDescription, const UTF8String& inExtension,
|
|
const UTF8String& inMimeType, const UTF8String& inUti)
|
|
{
|
|
impl->description = inDescription;
|
|
impl->extension = inExtension;
|
|
impl->mimeType = inMimeType;
|
|
impl->uti = inUti;
|
|
|
|
if (impl->description == nullptr && !impl->extension.empty ())
|
|
{
|
|
// TODO: query system for file type description
|
|
// Win32: AssocGetPerceivedType
|
|
// Mac: Uniform Type Identifier
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool CFileExtension::operator== (const CFileExtension& ext) const
|
|
{
|
|
bool result = false;
|
|
result = impl->extension == ext.impl->extension;
|
|
if (!result)
|
|
result = impl->mimeType == ext.impl->mimeType;
|
|
if (!result)
|
|
result = impl->uti == ext.impl->uti;
|
|
if (!result && impl->macType != 0 && ext.impl->macType != 0)
|
|
result = (impl->macType == ext.impl->macType);
|
|
return result;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
const UTF8String& CFileExtension::getDescription () const
|
|
{
|
|
return impl->description;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
const UTF8String& CFileExtension::getExtension () const
|
|
{
|
|
return impl->extension;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
const UTF8String& CFileExtension::getMimeType () const
|
|
{
|
|
return impl->mimeType;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
const UTF8String& CFileExtension::getUTI () const
|
|
{
|
|
return impl->uti;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int32_t CFileExtension::getMacType () const
|
|
{
|
|
return impl->macType;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CFileExtension::CFileExtension (const PlatformFileExtension& ext) : CFileExtension ()
|
|
{
|
|
impl->description = ext.description;
|
|
impl->extension = ext.extension;
|
|
impl->mimeType = ext.mimeType;
|
|
impl->uti = ext.uti;
|
|
impl->macType = ext.macType;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
const PlatformFileExtension& CFileExtension::getPlatformFileExtension () const
|
|
{
|
|
return *impl;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
const CFileExtension& CNewFileSelector::getAllFilesExtension ()
|
|
{
|
|
static CFileExtension allFilesExtension (PlatformAllFilesExtension);
|
|
return allFilesExtension;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
IdStringPtr CNewFileSelector::kSelectEndMessage = "CNewFileSelector Select End Message";
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CNewFileSelector Implementation
|
|
//-----------------------------------------------------------------------------
|
|
struct CNewFileSelector::Impl : PlatformFileSelectorConfig
|
|
{
|
|
PlatformFileSelectorPtr platformFileSelector;
|
|
CFrame* frame {nullptr};
|
|
std::vector<UTF8String> result;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CNewFileSelector::CNewFileSelector (PlatformFileSelectorPtr&& platformFileSelector, CFrame* parent)
|
|
{
|
|
impl = std::make_unique<Impl> ();
|
|
impl->platformFileSelector = std::move (platformFileSelector);
|
|
impl->frame = parent;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CNewFileSelector::~CNewFileSelector () noexcept = default;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool CNewFileSelector::run (CBaseObject* delegate)
|
|
{
|
|
if (delegate == nullptr)
|
|
{
|
|
#if DEBUG
|
|
DebugPrint ("You need to specify a delegate in CNewFileSelector::run (CBaseObject* delegate, void* parentWindow)\n");
|
|
#endif
|
|
return false;
|
|
}
|
|
if (impl->frame)
|
|
impl->frame->onStartLocalEventLoop ();
|
|
|
|
impl->doneCallback = [this, del = shared (delegate)] (std::vector<UTF8String>&& files) {
|
|
impl->result = std::move (files);
|
|
del->notify (this, CNewFileSelector::kSelectEndMessage);
|
|
};
|
|
|
|
setBit (impl->flags, PlatformFileSelectorFlags::RunModal, false);
|
|
return impl->platformFileSelector->run (*impl);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool CNewFileSelector::run (CallbackFunc&& callback)
|
|
{
|
|
if (impl->frame)
|
|
impl->frame->onStartLocalEventLoop ();
|
|
|
|
remember ();
|
|
impl->doneCallback = [this,
|
|
cb = std::move (callback)] (std::vector<UTF8String>&& files) {
|
|
impl->result = std::move (files);
|
|
cb (this);
|
|
forget ();
|
|
};
|
|
|
|
setBit (impl->flags, PlatformFileSelectorFlags::RunModal, false);
|
|
return impl->platformFileSelector->run (*impl);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CNewFileSelector::cancel ()
|
|
{
|
|
impl->platformFileSelector->cancel ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool CNewFileSelector::runModal ()
|
|
{
|
|
if (impl->frame)
|
|
impl->frame->onStartLocalEventLoop ();
|
|
setBit (impl->flags, PlatformFileSelectorFlags::RunModal, true);
|
|
impl->doneCallback = [&] (std::vector<UTF8String>&& files) {
|
|
impl->result = std::move (files);
|
|
};
|
|
|
|
return impl->platformFileSelector->run (*impl);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CNewFileSelector::setTitle (const UTF8String& inTitle)
|
|
{
|
|
impl->title = inTitle;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CNewFileSelector::setInitialDirectory (const UTF8String& path)
|
|
{
|
|
impl->initialPath = path;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CNewFileSelector::setDefaultSaveName (const UTF8String& name)
|
|
{
|
|
impl->defaultSaveName = name;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CNewFileSelector::setAllowMultiFileSelection (bool state)
|
|
{
|
|
setBit (impl->flags, PlatformFileSelectorFlags::MultiFileSelection, state);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CNewFileSelector::setDefaultExtension (const CFileExtension& extension)
|
|
{
|
|
if (impl->defaultExtension != PlatformNoFileExtension)
|
|
{
|
|
#if DEBUG
|
|
DebugPrint ("VSTGUI Warning: It's not allowed to set a default extension twice on a "
|
|
"CFileSelector instance\n");
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
auto it = std::find (impl->extensions.begin (), impl->extensions.end (),
|
|
extension.getPlatformFileExtension ());
|
|
if (it == impl->extensions.end ())
|
|
addFileExtension (extension);
|
|
impl->defaultExtension = extension.getPlatformFileExtension ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CNewFileSelector::addFileExtension (const CFileExtension& extension)
|
|
{
|
|
impl->extensions.emplace_back (extension.getPlatformFileExtension ());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CNewFileSelector::addFileExtension (CFileExtension&& extension)
|
|
{
|
|
impl->extensions.emplace_back (std::move (extension.getPlatformFileExtension ()));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
uint32_t CNewFileSelector::getNumSelectedFiles () const
|
|
{
|
|
return static_cast<uint32_t> (impl->result.size ());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
UTF8StringPtr CNewFileSelector::getSelectedFile (uint32_t index) const
|
|
{
|
|
if (index < impl->result.size ())
|
|
return impl->result[index];
|
|
return nullptr;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
CNewFileSelector* CNewFileSelector::create (CFrame* parent, Style style)
|
|
{
|
|
PlatformFileSelectorStyle platformStyle;
|
|
switch (style)
|
|
{
|
|
case Style::kSelectFile:
|
|
platformStyle = PlatformFileSelectorStyle::SelectFile;
|
|
break;
|
|
case Style::kSelectDirectory:
|
|
platformStyle = PlatformFileSelectorStyle::SelectDirectory;
|
|
break;
|
|
case Style::kSelectSaveFile:
|
|
platformStyle = PlatformFileSelectorStyle::SelectSaveFile;
|
|
break;
|
|
default:
|
|
vstgui_assert (false);
|
|
return nullptr;
|
|
}
|
|
if (auto platformSelector = getPlatformFactory ().createFileSelector (
|
|
platformStyle, parent ? parent->getPlatformFrame () : nullptr))
|
|
{
|
|
return new CNewFileSelector (std::move (platformSelector), parent);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
} // VSTGUI
|