233 lines
6.6 KiB
C++
233 lines
6.6 KiB
C++
![]() |
#include "stdafx.h"
|
||
|
|
||
|
#include "xtr/ExtSourceManager.h"
|
||
|
|
||
|
#include "resource.h"
|
||
|
#include "xtr/dialog/BasicDlg.h"
|
||
|
#include "xtr/Exteor.h"
|
||
|
#include "xtr/doc/RSFormDoc.h"
|
||
|
#include "xtr/doc/OSSDoc.h"
|
||
|
|
||
|
namespace xtr {
|
||
|
|
||
|
static constexpr auto noView = true;
|
||
|
|
||
|
using ccl::src::Descriptor;
|
||
|
using ccl::src::Source;
|
||
|
using ccl::src::SrcType;
|
||
|
|
||
|
Source* ExtSourceManager::Find(const Descriptor& desc) {
|
||
|
switch (desc.type) {
|
||
|
default: return SourceManager::Find(desc);
|
||
|
case SrcType::rsDoc:
|
||
|
return ExteorApplication::Docs().FindRSDocByPath(std::filesystem::path(desc.name).c_str());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool ExtSourceManager::TestDomain(const Descriptor& global, const std::u8string& domain) const {
|
||
|
switch (global.type) {
|
||
|
default: return SourceManager::TestDomain(global, domain);
|
||
|
case SrcType::rsDoc: {
|
||
|
auto domainDir = std::filesystem::path(domain);
|
||
|
if (std::empty(domainDir.filename())) {
|
||
|
domainDir = domainDir.parent_path();
|
||
|
}
|
||
|
return std::filesystem::path(global.name).parent_path().lexically_normal() == domainDir.lexically_normal();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Descriptor ExtSourceManager::Convert2Local(const Descriptor& global, const std::u8string& domain) const {
|
||
|
switch (global.type) {
|
||
|
default: return SourceManager::Convert2Local(global, domain);
|
||
|
case SrcType::rsDoc:
|
||
|
Descriptor local = global;
|
||
|
if (!std::empty(domain)) {
|
||
|
local.name = std::filesystem::relative(std::filesystem::path(global.name), std::filesystem::path(domain)).u8string();
|
||
|
}
|
||
|
return local;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Descriptor ExtSourceManager::Convert2Global(const Descriptor& local, const std::u8string& domain) const {
|
||
|
switch (local.type) {
|
||
|
default: return SourceManager::Convert2Global(local, domain);
|
||
|
case SrcType::rsDoc: {
|
||
|
Descriptor global = local;
|
||
|
if (!std::empty(domain)) {
|
||
|
global.name = (std::filesystem::path(domain) / std::filesystem::path(local.name).filename()).u8string();
|
||
|
}
|
||
|
return global;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Descriptor ExtSourceManager::CreateLocalDesc(SrcType type, std::u8string localName) const {
|
||
|
switch (type) {
|
||
|
default: return SourceManager::CreateLocalDesc(type, localName);
|
||
|
case SrcType::rsDoc: {
|
||
|
Descriptor result{};
|
||
|
result.type = type;
|
||
|
result.name = FixFilename(localName) + mfc::ToUTF8(ExtensionFor(FileType::trs));
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
std::u8string ExtSourceManager::FixFilename(const std::u8string& name) {
|
||
|
std::u8string result{};
|
||
|
for (const auto symb : name) {
|
||
|
if (symb != '?' && symb != '\\' && symb != ':' && symb != '*'
|
||
|
&& symb != '"' && symb != '<' && symb != '>' && symb != '|') {
|
||
|
result += symb;
|
||
|
}
|
||
|
}
|
||
|
if (std::empty(result)) {
|
||
|
return u8"noname";
|
||
|
} else {
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Descriptor ExtSourceManager::GetDescriptor(const Source& src) const {
|
||
|
switch (src.Type()) {
|
||
|
default: return SourceManager::GetDescriptor(src);
|
||
|
case SrcType::rsDoc: {
|
||
|
const auto& path = RSCast(src).GetPathName();
|
||
|
return Descriptor{ src.Type(), mfc::ToUTF8(path.IsEmpty() ? RSCast(src).GetTitle() : path) };
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool ExtSourceManager::ChangeDescriptor(const Descriptor& desc, const Descriptor& newDesc) {
|
||
|
if (desc.type != newDesc.type) {
|
||
|
return false;
|
||
|
}
|
||
|
if (auto* src = Find(desc); src != nullptr) {
|
||
|
Close(*src);
|
||
|
}
|
||
|
const auto oldPath = std::filesystem::path(desc.name);
|
||
|
const auto newPath = std::filesystem::path(newDesc.name);
|
||
|
switch (desc.type) {
|
||
|
default: return false;
|
||
|
case SrcType::rsDoc: {
|
||
|
if (!std::filesystem::exists(oldPath)) {
|
||
|
::AfxMessageBox(mfc::FormatSID(IXTRE_FILE_NOT_FOUND, oldPath.c_str()), MB_ICONEXCLAMATION);
|
||
|
return false;
|
||
|
} else if (std::filesystem::exists(newPath)) {
|
||
|
::AfxMessageBox(mfc::FormatSID(IXTRS_RENAME_FILE_EXISTS, newPath.c_str()), MB_ICONEXCLAMATION);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
std::filesystem::rename(oldPath, newPath);
|
||
|
g_Exteor.RemoveMRUItem(oldPath.c_str());
|
||
|
return true;
|
||
|
} catch (...) {
|
||
|
::AfxMessageBox(mfc::LoadSID(IXTRE_RENAME_UNKNOWN), MB_ICONEXCLAMATION);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Source* ExtSourceManager::CreateNew(const Descriptor& desc) {
|
||
|
if (Find(desc) != nullptr) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
const auto path = std::filesystem::path(desc.name);
|
||
|
if (std::filesystem::exists(path) &&
|
||
|
::AfxMessageBox(mfc::FormatSID(IXTRS_ASK_REWRITE_FILE, path.c_str()), MB_YESNO | MB_ICONQUESTION) != IDYES) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
const auto guardSilent = XTROptions::App().GuardSilence();
|
||
|
switch (desc.type) {
|
||
|
default: break;
|
||
|
case SrcType::rsDoc: {
|
||
|
if (auto* src = ExteorApplication::Docs().NewRSFormDoc(noView); src != nullptr) {
|
||
|
if (auto& doc = RSCast(*src); doc.OnSaveDocument(path.c_str())) {
|
||
|
return src;
|
||
|
} else {
|
||
|
src->OnCloseDocument();
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
void ExtSourceManager::Discard(const Descriptor& desc) {
|
||
|
auto* src = Open(desc);
|
||
|
if (src == nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
src->ReleaseClaim();
|
||
|
Close(*src);
|
||
|
|
||
|
switch (desc.type) {
|
||
|
default: break;
|
||
|
case SrcType::rsDoc: {
|
||
|
auto newPath = std::filesystem::path(desc.name);
|
||
|
CString newName = newPath.stem().c_str();
|
||
|
newName += CTime::GetCurrentTime().Format(LR"(%Y%m%d_%H%M)");
|
||
|
newName += newPath.extension().c_str();
|
||
|
newPath = newPath.replace_filename(newName.GetString());
|
||
|
ChangeDescriptor(desc, Descriptor{ SrcType::rsDoc, newPath.u8string() });
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Source* ExtSourceManager::Open(const Descriptor& desc) {
|
||
|
const auto path = std::filesystem::path(desc.name);
|
||
|
if (!std::filesystem::exists(path)) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
const auto guardSilent = XTROptions::App().GuardSilence();
|
||
|
switch (desc.type) {
|
||
|
default: return SourceManager::Open(desc);
|
||
|
case SrcType::rsDoc: return ExteorApplication::Docs().OpenRSFormDoc(path.c_str(), noView);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ExtSourceManager::Close(Source& src) {
|
||
|
switch (src.Type()) {
|
||
|
default: break;
|
||
|
case SrcType::rsDoc: {
|
||
|
RSCast(src).OnCloseDocument();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool ExtSourceManager::SaveState(Source& src) {
|
||
|
switch (src.Type()) {
|
||
|
default: return false;
|
||
|
case SrcType::rsDoc: {
|
||
|
const auto path = std::filesystem::path(RSCast(src).GetPathName().GetString());
|
||
|
if (path.has_parent_path() && !std::filesystem::exists(path)) {
|
||
|
return false;
|
||
|
} else {
|
||
|
return RSCast(src).DoFileSave();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// false positive noexcept recomendation for function using dynamic_cast to references
|
||
|
#pragma warning( push )
|
||
|
#pragma warning( disable : 26496 26440 )
|
||
|
|
||
|
const doc::RSFormDoc& ExtSourceManager::RSCast(const Source& src) {
|
||
|
return dynamic_cast<const doc::RSFormDoc&>(src);
|
||
|
}
|
||
|
|
||
|
doc::RSFormDoc& ExtSourceManager::RSCast(Source& src) {
|
||
|
return dynamic_cast<doc::RSFormDoc&>(src);
|
||
|
}
|
||
|
|
||
|
#pragma warning( pop )
|
||
|
|
||
|
} // namespace xtr
|