mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-11 05:07:00 -04:00
Use LocalFileName class for file names inside a package.
This commit is contained in:
@@ -18,7 +18,6 @@ using boost::tribool;
|
||||
|
||||
void GetDefaultMember::handle(const Char* v) { value = to_script(v); }
|
||||
template <> void GetDefaultMember::handle(const String& v) { value = to_script(v); }
|
||||
template <> void GetDefaultMember::handle(const FileName& v) { value = to_script(v); }
|
||||
template <> void GetDefaultMember::handle(const int& v) { value = to_script(v); }
|
||||
template <> void GetDefaultMember::handle(const unsigned int& v) { value = to_script((int)v); }
|
||||
template <> void GetDefaultMember::handle(const double& v) { value = to_script(v); }
|
||||
|
||||
+45
-7
@@ -245,7 +245,7 @@ String Package::nameOut(const String& file) {
|
||||
}
|
||||
}
|
||||
|
||||
FileName Package::newFileName(const String& prefix, const String& suffix) {
|
||||
LocalFileName Package::newFileName(const String& prefix, const String& suffix) {
|
||||
assert(wxThread::IsMain()); // Writing should only be done from the main thread
|
||||
String name;
|
||||
UInt infix = 0;
|
||||
@@ -273,21 +273,23 @@ void Package::referenceFile(const String& file) {
|
||||
it->second.keep = true;
|
||||
}
|
||||
|
||||
String Package::absoluteName(const String& file) {
|
||||
// ----------------------------------------------------------------------------- : LocalFileNames and absolute file references
|
||||
|
||||
String Package::absoluteName(const LocalFileName& file) {
|
||||
assert(wxThread::IsMain());
|
||||
FileInfos::iterator it = files.find(normalize_internal_filename(file));
|
||||
FileInfos::iterator it = files.find(normalize_internal_filename(file.fn));
|
||||
if (it == files.end()) {
|
||||
throw FileNotFoundError(file, filename);
|
||||
throw FileNotFoundError(file.fn, filename);
|
||||
}
|
||||
if (it->second.wasWritten()) {
|
||||
// written to this file, return the temp file
|
||||
return it->second.tempName;
|
||||
} else if (wxFileExists(filename+_("/")+file)) {
|
||||
} else if (wxFileExists(filename + _("/") + file.fn)) {
|
||||
// dir package
|
||||
return filename+_("/")+file;
|
||||
return filename + _("/") + file.fn;
|
||||
} else {
|
||||
// assume zip package
|
||||
return filename+_("\1")+file;
|
||||
return filename + _("\1") + file.fn;
|
||||
}
|
||||
}
|
||||
// Open a file that is in some package
|
||||
@@ -306,6 +308,42 @@ unique_ptr<wxInputStream> Package::openAbsoluteFile(const String& name) {
|
||||
}
|
||||
}
|
||||
|
||||
String LocalFileName::toStringForWriting() const {
|
||||
if (!fn.empty() && clipboard_package()) {
|
||||
// use absolute names on clipboard
|
||||
try {
|
||||
return clipboard_package()->absoluteName(fn);
|
||||
} catch (const Error&) {
|
||||
// ignore errors
|
||||
return String();
|
||||
}
|
||||
} else if (!fn.empty() && writing_package()) {
|
||||
writing_package()->referenceFile(fn);
|
||||
return fn;
|
||||
} else {
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
|
||||
LocalFileName LocalFileName::fromReadString(String const& fn, String const& prefix, String const& suffix) {
|
||||
if (!fn.empty() && clipboard_package()) {
|
||||
// copy file into current package
|
||||
try {
|
||||
LocalFileName local_name = clipboard_package()->newFileName(_("image"),_("")); // a new unique name in the package, assume it's an image
|
||||
auto out_stream = clipboard_package()->openOut(local_name);
|
||||
auto in_stream = Package::openAbsoluteFile(fn);
|
||||
out_stream->Write(*in_stream); // copy
|
||||
return local_name;
|
||||
} catch (const Error&) {
|
||||
// ignore errors
|
||||
return LocalFileName();
|
||||
}
|
||||
} else {
|
||||
return LocalFileName(fn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- : Package : private
|
||||
|
||||
Package::FileInfo::FileInfo()
|
||||
|
||||
+57
-13
@@ -25,6 +25,40 @@ DECLARE_DYNAMIC_ARG(Package*, writing_package);
|
||||
/// The package that is being put onto/read from the clipboard
|
||||
DECLARE_DYNAMIC_ARG(Package*, clipboard_package);
|
||||
|
||||
// ----------------------------------------------------------------------------- : File names
|
||||
|
||||
/// A string standing for a filename in a package
|
||||
/// Differs from a string because when writing the file should be included in the package
|
||||
/// Behaviour is controled by dynamic args:
|
||||
/// * clipboard_package
|
||||
/// * writing_package
|
||||
class LocalFileName {
|
||||
public:
|
||||
LocalFileName() {}
|
||||
|
||||
// Convert to a string that can be written to a package.
|
||||
// notifies the package that the underlying file is in use.
|
||||
// when writing to the clipboard, instead returns a global file reference.
|
||||
String toStringForWriting() const;
|
||||
// Construct a LocalFileName based on a string read from a package.
|
||||
// when reading from the clipboard, this will instead be a global file reference, and it is converted at this point.
|
||||
static LocalFileName fromReadString(const String&, const String& prefix = _("image"), String const& suffix = _(""));
|
||||
|
||||
inline bool empty() const {
|
||||
return fn.empty();
|
||||
}
|
||||
inline bool operator == (LocalFileName const& that) const {
|
||||
return this->fn == that.fn;
|
||||
}
|
||||
|
||||
inline String const& toStringForKey() const { return fn; }
|
||||
|
||||
private:
|
||||
LocalFileName(const wxString& fn) : fn(fn) {}
|
||||
String fn;
|
||||
friend class Package;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Package
|
||||
|
||||
/// A package is a container for files. On disk it is either a directory or a zip file.
|
||||
@@ -100,39 +134,41 @@ class Package : public IntrusivePtrVirtualBase {
|
||||
|
||||
/// Open an input stream for a file in the package.
|
||||
unique_ptr<wxInputStream> openIn(const String& file);
|
||||
inline unique_ptr<wxInputStream> openIn(const LocalFileName& file) {
|
||||
return openIn(file.fn);
|
||||
}
|
||||
|
||||
/// Open an output stream for a file in the package.
|
||||
/// (changes are only committed with save())
|
||||
unique_ptr<wxOutputStream> openOut(const String& file);
|
||||
inline unique_ptr<wxOutputStream> openOut(const LocalFileName& file) {
|
||||
return openOut(file.fn);
|
||||
}
|
||||
|
||||
/// Get a filename that can be written to to modfify a file in the package
|
||||
/// (changes are only committed with save())
|
||||
String nameOut(const String& file);
|
||||
inline String nameOut(const LocalFileName& file) {
|
||||
return nameOut(file.fn);
|
||||
}
|
||||
|
||||
/// Creates a new, unique, filename with the specified prefix and suffix
|
||||
/// for example newFileName("image/",".jpg") -> "image/1.jpg"
|
||||
/// Returns the name of a temporary file that can be written to.
|
||||
FileName newFileName(const String& prefix, const String& suffix);
|
||||
LocalFileName newFileName(const String& prefix, const String& suffix);
|
||||
|
||||
/// Signal that a file is still used by this package.
|
||||
/// Must be called for files not opened using openOut/nameOut
|
||||
/// If they are to be kept in the package.
|
||||
void referenceFile(const String& file);
|
||||
|
||||
/// Get an 'absolute filename' for a file in the package.
|
||||
/// This file can later be opened from anywhere (other process) using openAbsoluteFile()
|
||||
String absoluteName(const String& file);
|
||||
|
||||
/// Open a file given an absolute filename
|
||||
static unique_ptr<wxInputStream> openAbsoluteFile(const String& name);
|
||||
|
||||
// --------------------------------------------------- : Managing the inside of the package : Reader/writer
|
||||
|
||||
template <typename T>
|
||||
void readFile(const String& file, T& obj);
|
||||
void readFile(const LocalFileName& file, T& obj);
|
||||
|
||||
template <typename T>
|
||||
T readFile(const String& file) {
|
||||
T readFile(const LocalFileName& file) {
|
||||
T obj;
|
||||
readFile(file, obj);
|
||||
return obj;
|
||||
@@ -194,6 +230,14 @@ class Package : public IntrusivePtrVirtualBase {
|
||||
void saveToZipfile(const String&, bool remove_unused, bool is_copy);
|
||||
void saveToDirectory(const String&, bool remove_unused, bool is_copy);
|
||||
FileInfos::iterator addFile(const String& file);
|
||||
|
||||
/// Get an 'absolute filename' for a file in the package.
|
||||
/// This file can later be opened from anywhere (other process) using openAbsoluteFile()
|
||||
String absoluteName(const LocalFileName& file);
|
||||
|
||||
/// Open a file given an absolute filename
|
||||
static unique_ptr<wxInputStream> openAbsoluteFile(const String& name);
|
||||
friend class LocalFileName;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Packaged
|
||||
@@ -291,13 +335,13 @@ intrusive_ptr<T> open_package(const String& filename) {
|
||||
|
||||
// This is here because it uses dynamic_cast and must be to a complete type.
|
||||
template <typename T>
|
||||
inline void Package::readFile(const String& file, T& obj) {
|
||||
inline void Package::readFile(const LocalFileName& file, T& obj) {
|
||||
auto stream = openIn(file);
|
||||
Reader reader(*stream, dynamic_cast<Packaged*>(this), absoluteFilename() + _("/") + file);
|
||||
Reader reader(*stream, dynamic_cast<Packaged*>(this), absoluteFilename() + _("/") + file.fn);
|
||||
try {
|
||||
reader.handle_greedy(obj);
|
||||
} catch (const ParseError& err) {
|
||||
throw FileParseError(err.what(), absoluteFilename() + _("/") + file); // more detailed message
|
||||
throw FileParseError(err.what(), absoluteFilename() + _("/") + file.fn); // more detailed message
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-20
@@ -354,26 +354,8 @@ template <> void Reader::handle(Vector2D& vec) {
|
||||
}
|
||||
}
|
||||
|
||||
template <> void Reader::handle(FileName& f) {
|
||||
if (clipboard_package()) {
|
||||
String str = getValue();
|
||||
if (!str.empty()) {
|
||||
// copy file into current package
|
||||
try {
|
||||
String packaged_name = clipboard_package()->newFileName(_("image"),_("")); // a new unique name in the package, assume it's an image
|
||||
auto out_stream = clipboard_package()->openOut(packaged_name);
|
||||
auto in_stream = Package::openAbsoluteFile(str);
|
||||
out_stream->Write(*in_stream); // copy
|
||||
f.assign(packaged_name);
|
||||
} catch (Error const&) {
|
||||
// ignore errors
|
||||
}
|
||||
} else {
|
||||
f.assign(str);
|
||||
}
|
||||
} else {
|
||||
handle(static_cast<String&>(f));
|
||||
}
|
||||
template <> void Reader::handle(LocalFileName& f) {
|
||||
f = LocalFileName::fromReadString(this->getValue());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : EnumReader
|
||||
|
||||
+2
-14
@@ -131,18 +131,6 @@ template <> void Writer::handle(const Vector2D& vec) {
|
||||
handle(String::Format(_("(%.10lf,%.10lf)"), vec.x, vec.y));
|
||||
}
|
||||
|
||||
template <> void Writer::handle(const FileName& value) {
|
||||
if (clipboard_package() && !value.empty()) {
|
||||
// use absolute names on clipboard
|
||||
try {
|
||||
handle(clipboard_package()->absoluteName(value));
|
||||
} catch (const Error&) {
|
||||
// ignore errors
|
||||
}
|
||||
} else {
|
||||
handle(static_cast<const String&>(value));
|
||||
if (writing_package()) {
|
||||
writing_package()->referenceFile(value);
|
||||
}
|
||||
}
|
||||
template <> void Writer::handle(const LocalFileName& value) {
|
||||
handle(value.toStringForWriting());
|
||||
}
|
||||
|
||||
@@ -84,13 +84,6 @@ typedef wxOutputStream OutputStream;
|
||||
typedef unsigned char Byte;
|
||||
typedef unsigned int UInt;
|
||||
|
||||
/// A string standing for a filename, has different behaviour when reading/writing
|
||||
class FileName : public wxString {
|
||||
public:
|
||||
FileName() {}
|
||||
FileName(const wxString& s) : wxString(s) {}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : MSE Headers
|
||||
|
||||
// MSE utility headers (ones unlikely to change and used everywhere)
|
||||
|
||||
Reference in New Issue
Block a user