#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(src); } doc::RSFormDoc& ExtSourceManager::RSCast(Source& src) { return dynamic_cast(src); } #pragma warning( pop ) } // namespace xtr