diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/binary.cpp | 8 | ||||
-rw-r--r-- | lib/db_file.cpp | 226 | ||||
-rw-r--r-- | lib/dir_lock.cpp | 9 | ||||
-rw-r--r-- | lib/error_log.h | 43 | ||||
-rw-r--r-- | lib/generate_logfile.h | 15 | ||||
-rw-r--r-- | lib/hard_filter.h | 4 | ||||
-rw-r--r-- | lib/localization.cpp | 22 | ||||
-rw-r--r-- | lib/perf_check.cpp | 4 | ||||
-rw-r--r-- | lib/process_xml.cpp | 104 | ||||
-rw-r--r-- | lib/process_xml.h | 2 |
10 files changed, 172 insertions, 265 deletions
diff --git a/lib/binary.cpp b/lib/binary.cpp index 4fc1d408..2065e13e 100644 --- a/lib/binary.cpp +++ b/lib/binary.cpp @@ -44,7 +44,7 @@ public: operator size_t() const { return bufSize; } private: - static const size_t BUFFER_SIZE_MIN = 128 * 1024; + static const size_t BUFFER_SIZE_MIN = 64 * 1024; static const size_t BUFFER_SIZE_START = 512 * 1024; //512 kb seems to be a reasonable initial buffer size static const size_t BUFFER_SIZE_MAX = 16 * 1024 * 1024; @@ -72,9 +72,6 @@ const std::int64_t TICKS_PER_SEC = ticksPerSec(); bool zen::filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, CompareCallback& callback) { - FileInput file1(filename1); //throw FileError - FileInput file2(filename2); //throw FileError - static boost::thread_specific_ptr<std::vector<char>> cpyBuf1; static boost::thread_specific_ptr<std::vector<char>> cpyBuf2; if (!cpyBuf1.get()) @@ -85,6 +82,9 @@ bool zen::filesHaveSameContent(const Zstring& filename1, const Zstring& filename std::vector<char>& memory1 = *cpyBuf1; std::vector<char>& memory2 = *cpyBuf2; + FileInput file1(filename1); //throw FileError + FileInput file2(filename2); // + BufferSize bufferSize; UInt64 bytesCompared; diff --git a/lib/db_file.cpp b/lib/db_file.cpp index 787325e2..2c299236 100644 --- a/lib/db_file.cpp +++ b/lib/db_file.cpp @@ -5,21 +5,12 @@ // ************************************************************************** #include "db_file.h" -#include <zen/file_error.h> #include <zen/file_handling.h> #include <zen/scope_guard.h> #include <zen/guid.h> #include <zen/utf.h> +#include <zen/serialize.h> #include <wx+/zlib_wrap.h> -#include <wx+/serialize.h> - -#ifdef FFS_WIN -warn_static("get rid of wx headers") -#endif -#include <wx/wfstream.h> -#include <wx/zstream.h> -#include <wx/mstream.h> -#include <zen/perf.h> #ifdef FFS_WIN #include <zen/win.h> //includes "windows.h" @@ -91,13 +82,6 @@ void saveStreams(const StreamMapping& streamList, const Zstring& filename) //thr } -#ifdef FFS_WIN -warn_static("remove after migration") -#endif - -StreamMapping loadStreams_v8(const Zstring& filename); //throw FileError - - StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorDatabaseNotExisting { try @@ -113,13 +97,7 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorD const int version = readNumber<std::int32_t>(streamIn); //throw UnexpectedEndOfStreamError if (version != FILE_FORMAT_VER) //read file format version# - //throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename))); - return loadStreams_v8(filename); - - #ifdef FFS_WIN -warn_static("fix after migration") -#endif - + throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename))); //read stream lists StreamMapping output; @@ -153,10 +131,6 @@ warn_static("fix after migration") //####################################################################################################################################### -#ifdef FFS_WIN -warn_static("remove v8Compatibilty after migration") -#endif - class StreamGenerator //for db-file back-wards compatibility we stick with two output streams until further { public: @@ -164,8 +138,7 @@ public: const Zstring& filenameL, //used for diagnostics only const Zstring& filenameR, BinaryStream& streamL, - BinaryStream& streamR, - bool v8Compatibilty) + BinaryStream& streamR) { StreamGenerator generator; @@ -210,12 +183,6 @@ public: size_t size1stPart = tmpB.size() / 2; size_t size2ndPart = tmpB.size() - size1stPart; - if (v8Compatibilty) - { - size1stPart = tmpB.size(); - size2ndPart = 0; - } - writeNumber<std::uint64_t>(outL, size1stPart); writeNumber<std::uint64_t>(outR, size2ndPart); @@ -326,13 +293,8 @@ public: bool has1stPartL = readNumber<bool>(inL); //throw UnexpectedEndOfStreamError bool has1stPartR = readNumber<bool>(inR); // - -#ifdef FFS_WIN -warn_static("restore check after migration!") -#endif - - //if (has1stPartL == has1stPartR) - // throw UnexpectedEndOfStreamError(); + if (has1stPartL == has1stPartR) + throw UnexpectedEndOfStreamError(); BinStreamIn& in1stPart = has1stPartL ? inL : inR; BinStreamIn& in2ndPart = has1stPartL ? inR : inL; @@ -766,7 +728,7 @@ void zen::saveLastSynchronousState(const BaseDirMapping& baseMapping) //throw Fi dbNameLeft, dbNameRight, updatedStreamLeft, - updatedStreamRight, false); //throw FileError + updatedStreamRight); //throw FileError //check if there is some work to do at all if (streamIterLeftOld != streamListLeft .end() && updatedStreamLeft == streamIterLeftOld ->second && @@ -803,179 +765,3 @@ void zen::saveLastSynchronousState(const BaseDirMapping& baseMapping) //throw Fi guardTempFileLeft. dismiss(); //no need to delete temp file anymore guardTempFileRight.dismiss(); // } - -#ifdef FFS_WIN -warn_static("remove after migration") -#endif - -namespace -{ -class CheckedDbReader : public CheckedReader -{ -public: - CheckedDbReader(wxInputStream& stream, const Zstring& errorObjName) : CheckedReader(stream), errorObjName_(errorObjName) {} - -private: - virtual void throwException() const { throw FileError(replaceCpy(_("Cannot read file %x."), L"%x", fmtFileName(errorObjName_))); } - - const Zstring errorObjName_; -}; - - -class StreamParser_v8 //for db-file back-wards compatibility we stick with two output streams until further -{ -public: - static std::shared_ptr<InSyncDir> execute(const BinaryStream& streamL, const BinaryStream& streamR, //throw FileError - const Zstring& filenameL, //used for diagnostics only - const Zstring& filenameR) - { - try - { - auto output = std::make_shared<InSyncDir>(InSyncDir::STATUS_IN_SYNC); - StreamParser_v8 parser(streamL, streamR); //throw UnexpectedEndOfStreamError, std::bad_alloc - parser.recurse(*output); - return output; - } - catch (const UnexpectedEndOfStreamError&) - { - throw FileError(_("Database file is corrupt:") + L"\n" + fmtFileName(filenameL) + L"\n" + fmtFileName(filenameR)); - } - catch (const std::bad_alloc& e) - { - throw FileError(_("Out of memory!") + L" " + utfCvrtTo<std::wstring>(e.what())); - } - } - -private: - StreamParser_v8(const BinaryStream& bufferL, - const BinaryStream& bufferR) : - inputLeft (bufferL), //input is referenced only! - inputRight(bufferR) {} - - static Zstring readUtf8(BinStreamIn& input) { return utfCvrtTo<Zstring>(readContainer<Zbase<char>>(input)); } //throw UnexpectedEndOfStreamError - - static void read(BinStreamIn& input, Zstring& shortName, FileDescriptor& descr) - { - //attention: order of function argument evaluation is undefined! So do it one after the other... - shortName = readUtf8(input); - descr.lastWriteTimeRaw = readNumber<std::int64_t>(input); //throw UnexpectedEndOfStreamError - descr.fileSize = readNumber<std::uint64_t>(input); - descr.id.first = static_cast<decltype(descr.id.first )>(readNumber<std::uint64_t>(input)); // - descr.id.second = static_cast<decltype(descr.id.second)>(readNumber<std::uint64_t>(input)); //silence "loss of precision" compiler warnings - } - - static void read(BinStreamIn& input, Zstring& shortName, LinkDescriptor& descr) - { - shortName = readUtf8(input); - descr.lastWriteTimeRaw = readNumber<std::int64_t>(input); - descr.targetPath = readUtf8(input); //file name - descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input)); - } - - void recurse(InSyncDir& dir) - { - for (;;) //files - { - bool haveItemL = readNumber<bool>(inputLeft ); //remove redundancy in next db format - bool haveItemR = readNumber<bool>(inputRight); // - assert(haveItemL == haveItemR); - if (!haveItemL || !haveItemR) break; - - Zstring shortName; - FileDescriptor dataL; - FileDescriptor dataR; - read(inputLeft, shortName, dataL); - read(inputRight, shortName, dataR); - - dir.addFile(shortName, dataL, dataR, InSyncFile::IN_SYNC_ATTRIBUTES_EQUAL); - } - - for (;;) //symlinks - { - bool haveItemL = readNumber<bool>(inputLeft ); - bool haveItemR = readNumber<bool>(inputRight); - assert(haveItemL == haveItemR); - if (!haveItemL || !haveItemR) break; - - Zstring shortName; - LinkDescriptor dataL; - LinkDescriptor dataR; - read(inputLeft, shortName, dataL); - read(inputRight, shortName, dataR); - - dir.addSymlink(shortName, dataL, dataR); - } - - for (;;) //directories - { - bool haveItemL = readNumber<bool>(inputLeft ); - bool haveItemR = readNumber<bool>(inputRight); - assert(haveItemL == haveItemR); - if (!haveItemL || !haveItemR) break; - - Zstring shortName = readUtf8(inputLeft); - shortName = readUtf8(inputRight); - InSyncDir& subDir = dir.addDir(shortName, InSyncDir::STATUS_IN_SYNC); - recurse(subDir); - } - } - - BinStreamIn inputLeft; - BinStreamIn inputRight; -}; - - -StreamMapping loadStreams_v8(const Zstring& filename) //throw FileError -{ - try - { - //read format description (uncompressed) - FileInputStream rawStream(filename); //throw FileError, ErrorNotExisting - - //read FreeFileSync file identifier - char formatDescr[sizeof(FILE_FORMAT_DESCR)] = {}; - rawStream.Read(formatDescr, sizeof(formatDescr)); //throw FileError - - if (!std::equal(FILE_FORMAT_DESCR, FILE_FORMAT_DESCR + sizeof(FILE_FORMAT_DESCR), formatDescr)) - throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename))); - - wxZlibInputStream decompressed(rawStream, wxZLIB_ZLIB); - - CheckedDbReader cr(decompressed, filename); - - std::int32_t version = cr.readPOD<std::int32_t>(); - if (version != 8) //read file format version# - throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename))); - - //read stream lists - StreamMapping output; - - std::uint32_t dbCount = cr.readPOD<std::uint32_t>(); //number of databases: one for each sync-pair - while (dbCount-- != 0) - { - //DB id of partner databases - std::string sessionID = cr.readString<std::string>(); - BinaryStream stream = cr.readString<BinaryStream>(); //read db-entry stream (containing DirInformation) - - //convert streams - std::shared_ptr<InSyncDir> lastSyncState = StreamParser_v8::execute(stream, stream, filename, filename); //throw FileError - - //serialize again - BinaryStream strL; - BinaryStream strR; - StreamGenerator::execute(*lastSyncState, filename, filename, strL, strR, true); //throw FileError - output[sessionID] = std::move(strL); - } - return output; - } - catch (ErrorNotExisting&) - { - throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n" + - replaceCpy(_("Database file %x does not yet exist."), L"%x", fmtFileName(filename))); - } - catch (const std::bad_alloc& e) - { - throw FileError(_("Out of memory!") + L" " + utfCvrtTo<std::wstring>(e.what())); - } -} -} diff --git a/lib/dir_lock.cpp b/lib/dir_lock.cpp index 682612a7..e385c9a8 100644 --- a/lib/dir_lock.cpp +++ b/lib/dir_lock.cpp @@ -17,7 +17,7 @@ #include <zen/assert_static.h> #include <zen/int64.h> #include <zen/file_handling.h> -#include <wx+/serialize.h> +#include <zen/serialize.h> #ifdef FFS_WIN #include <tlhelp32.h> @@ -27,7 +27,8 @@ #include <Lmcons.h> //UNLEN #elif defined FFS_LINUX -#include <sys/stat.h> +#include <fcntl.h> //::open() +#include <sys/stat.h> // #include <unistd.h> #endif @@ -484,7 +485,7 @@ void releaseLock(const Zstring& lockfilename) //throw () { try { - removeFile(lockfilename); + removeFile(lockfilename); //throw FileError } catch (...) {} } @@ -511,6 +512,8 @@ bool tryLock(const Zstring& lockfilename) //throw FileError } ::CloseHandle(fileHandle); + ::SetFileAttributes(applyLongPathPrefix(lockfilename).c_str(), FILE_ATTRIBUTE_HIDDEN); //(try to) hide it + #elif defined FFS_LINUX //O_EXCL contains a race condition on NFS file systems: http://linux.die.net/man/2/open ::umask(0); //important! -> why? diff --git a/lib/error_log.h b/lib/error_log.h new file mode 100644 index 00000000..07a8b383 --- /dev/null +++ b/lib/error_log.h @@ -0,0 +1,43 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved * +// ************************************************************************** + +#ifndef ERROR_LOG_89734181783491324134 +#define ERROR_LOG_89734181783491324134 + +#include <cassert> +#include <zen/serialize.h> +#include <zen/time.h> +#include "ffs_paths.h" + + +namespace zen +{ +//write error message to a file (even with corrupted stack)- call in desperate situations when no other means of error handling is available +void logError(const std::string& msg); //throw() + + + + + + + + + +//##################### implementation ############################ +inline +void logError(const std::string& msg) //throw() +{ + assert(false); //this is stuff we like to debug + const std::string logEntry = "[" + formatTime<std::string>(FORMAT_DATE) + " "+ formatTime<std::string>(FORMAT_TIME) + "] " + msg; + try + { + saveBinStream(getConfigDir() + Zstr("LastError.txt"), logEntry); //throw FileError + } + catch (const FileError&) {} +} +} + +#endif //ERROR_LOG_89734181783491324134 diff --git a/lib/generate_logfile.h b/lib/generate_logfile.h index 8feb696a..b54b4893 100644 --- a/lib/generate_logfile.h +++ b/lib/generate_logfile.h @@ -9,8 +9,8 @@ #include <zen/error_log.h> #include <zen/file_io.h> +#include <zen/serialize.h> #include <wx+/format_unit.h> -#include <wx+/serialize.h> #include "ffs_paths.h" @@ -129,7 +129,18 @@ void saveToLastSyncsLog(const Utf8String& logstream) //throw FileError } //limit file size: 128 kB (but do not truncate new log) - newStream.resize(std::min(newStream.size(), std::max<size_t>(logstream.size(), 128 * 1024))); + const size_t newSize = std::min(newStream.size(), std::max<size_t>(logstream.size(), 128 * 1024)); + + //do not cut in the middle of a row + auto iter = std::search(newStream.begin() + newSize, newStream.end(), std::begin(LINE_BREAK), std::end(LINE_BREAK) - 1); + if (iter != newStream.end()) + { + newStream.resize(iter - newStream.begin()); + + newStream += LINE_BREAK; + newStream += "[...]"; + newStream += LINE_BREAK; + } saveBinStream(filename, newStream); //throw FileError } diff --git a/lib/hard_filter.h b/lib/hard_filter.h index 90cd33fc..723c7bdf 100644 --- a/lib/hard_filter.h +++ b/lib/hard_filter.h @@ -252,7 +252,7 @@ HardFilter::FilterRef combineFilters(const HardFilter::FilterRef& first, if (first->isNull()) { if (second->isNull()) - return HardFilter::FilterRef(new NullFilter); + return std::make_shared<NullFilter>(); else return second; } @@ -261,7 +261,7 @@ HardFilter::FilterRef combineFilters(const HardFilter::FilterRef& first, if (second->isNull()) return first; else - return HardFilter::FilterRef(new CombinedFilter(first, second)); + return std::make_shared<CombinedFilter>(first, second); } } } diff --git a/lib/localization.cpp b/lib/localization.cpp index 5bbb31d1..16dcac9a 100644 --- a/lib/localization.cpp +++ b/lib/localization.cpp @@ -54,7 +54,6 @@ public: if (0 <= formNo && formNo < static_cast<int>(iter->second.size())) return iter->second[formNo]; } - return n == 1 ? singular : plural; //fallback } @@ -75,7 +74,7 @@ FFSLocale::FFSLocale(const wxString& filename, wxLanguage languageId) : langId_( std::string inputStream; try { - inputStream = loadStream(filename);; //throw XmlFileError + inputStream = loadStream(filename); //throw XmlFileError } catch (...) { @@ -92,7 +91,7 @@ FFSLocale::FFSLocale(const wxString& filename, wxLanguage languageId) : langId_( const std::wstring original = utfCvrtTo<std::wstring>(i->first); const std::wstring translation = utfCvrtTo<std::wstring>(i->second); assert(!translation.empty()); - transMapping.insert(std::make_pair(original , translation)); + transMapping.insert(std::make_pair(original, translation)); } for (lngfile::TranslationPluralMap::const_iterator i = transPluralInput.begin(); i != transPluralInput.end(); ++i) @@ -164,10 +163,10 @@ ExistingTranslations::ExistingTranslations() //default entry: ExistingTranslations::Entry newEntry; newEntry.languageID = wxLANGUAGE_ENGLISH_US; - newEntry.languageName = wxT("English (US)"); - newEntry.languageFile = wxT(""); - newEntry.translatorName = wxT("ZenJu"); - newEntry.languageFlag = wxT("usa.png"); + newEntry.languageName = L"English (US)"; + newEntry.languageFile = L""; + newEntry.translatorName = L"ZenJu"; + newEntry.languageFlag = L"usa.png"; locMapping.push_back(newEntry); } @@ -196,7 +195,7 @@ ExistingTranslations::ExistingTranslations() ExistingTranslations::Entry newEntry; newEntry.languageID = locInfo->Language; newEntry.languageName = utfCvrtTo<wxString>(lngHeader.languageName); - newEntry.languageFile = toWx(*i); + newEntry.languageFile = utfCvrtTo<wxString>(*i); newEntry.translatorName = utfCvrtTo<wxString>(lngHeader.translatorName); newEntry.languageFlag = utfCvrtTo<wxString>(lngHeader.flagFile); locMapping.push_back(newEntry); @@ -297,6 +296,7 @@ wxLanguage mapLanguageDialect(wxLanguage language) //case wxLANGUAGE_HUNGARIAN: //case wxLANGUAGE_PORTUGUESE: //case wxLANGUAGE_PORTUGUESE_BRAZILIAN: + //case wxLANGUAGE_SCOTS_GAELIC: //case wxLANGUAGE_KOREAN: //case wxLANGUAGE_UKRAINIAN: //case wxLANGUAGE_CROATIAN: @@ -365,6 +365,8 @@ private: void zen::setLanguage(int language) { + if (language == getLanguage()) return; //support polling + //(try to) retrieve language file wxString languageFile; @@ -375,13 +377,11 @@ void zen::setLanguage(int language) break; } - //handle RTL swapping: we need wxWidgets to do this static std::unique_ptr<CustomLocale> dummy; dummy.reset(); //avoid global locale lifetime overlap! wxWidgets cannot handle this and will crash! dummy.reset(new CustomLocale(languageFile.empty() ? wxLANGUAGE_ENGLISH : language)); - //reset to english language; in case of error show error message just once zen::setTranslator(); @@ -408,7 +408,7 @@ void zen::setLanguage(int language) int zen::getLanguage() { - FFSLocale* loc = dynamic_cast<FFSLocale*>(zen::getTranslator()); + const FFSLocale* loc = dynamic_cast<const FFSLocale*>(zen::getTranslator()); return loc ? loc->langId() : wxLANGUAGE_ENGLISH_US; } diff --git a/lib/perf_check.cpp b/lib/perf_check.cpp index ab0f7769..f01af061 100644 --- a/lib/perf_check.cpp +++ b/lib/perf_check.cpp @@ -154,7 +154,7 @@ z_1 + z_2 * X / m = F / m => we obtain a new (artificial) measurement with size X / m and time F / m to be used in the linear approximation above -Statistics::Statistics(const int totalObjectCount, const double totalDataAmount, const unsigned recordCount) : +Statistics::Statistics(int totalObjectCount, double totalDataAmount, unsigned recordCount) : objectsTotal(totalObjectCount), dataTotal(totalDataAmount), recordsMax(recordCount), @@ -166,7 +166,7 @@ Statistics::Statistics(const int totalObjectCount, const double totalDataAmount, dummyRecordPresent(false) {} -wxString Statistics::getRemainingTime(const int objectsCurrent, const double dataCurrent) +wxString Statistics::getRemainingTime(int objectsCurrent, double dataCurrent) { //add new measurement point const int m = objectsCurrent - objectsLast; diff --git a/lib/process_xml.cpp b/lib/process_xml.cpp index 39b1520b..f5a6a4d1 100644 --- a/lib/process_xml.cpp +++ b/lib/process_xml.cpp @@ -542,13 +542,53 @@ bool readText(const std::string& input, UnitTime& value) template <> inline void writeText(const ColumnTypeRim& value, std::string& output) { - output = numberTo<std::string>(value); + switch (value) + { + case COL_TYPE_DIRECTORY: + output = "Base"; + break; + case COL_TYPE_FULL_PATH: + output = "Full"; + break; + case COL_TYPE_REL_PATH: + output = "Rel"; + break; + case COL_TYPE_FILENAME: + output = "Name"; + break; + case COL_TYPE_SIZE: + output = "Size"; + break; + case COL_TYPE_DATE: + output = "Date"; + break; + case COL_TYPE_EXTENSION: + output = "Ext"; + break; + } } template <> inline bool readText(const std::string& input, ColumnTypeRim& value) { - value = static_cast<ColumnTypeRim>(stringTo<int>(input)); + std::string tmp = input; + zen::trim(tmp); + if (tmp == "Base") + value = COL_TYPE_DIRECTORY; + else if (tmp == "Full") + value = COL_TYPE_FULL_PATH; + else if (tmp == "Rel") + value = COL_TYPE_REL_PATH; + else if (tmp == "Name") + value = COL_TYPE_FILENAME; + else if (tmp == "Size") + value = COL_TYPE_SIZE; + else if (tmp == "Date") + value = COL_TYPE_DATE; + else if (tmp == "Ext") + value = COL_TYPE_EXTENSION; + else + return false; return true; } @@ -556,13 +596,28 @@ bool readText(const std::string& input, ColumnTypeRim& value) template <> inline void writeText(const ColumnTypeNavi& value, std::string& output) { - output = numberTo<std::string>(value); + switch (value) + { + case COL_TYPE_NAVI_BYTES: + output = "Bytes"; + break; + case COL_TYPE_NAVI_DIRECTORY: + output = "Tree"; + break; + } } template <> inline bool readText(const std::string& input, ColumnTypeNavi& value) { - value = static_cast<ColumnTypeNavi>(stringTo<int>(input)); + std::string tmp = input; + zen::trim(tmp); + if (tmp == "Bytes") + value = COL_TYPE_NAVI_BYTES; + else if (tmp == "Tree") + value = COL_TYPE_NAVI_DIRECTORY; + else + return false; return true; } @@ -651,17 +706,19 @@ bool readStruc(const XmlElement& input, ColumnAttributeRim& value) XmlIn in(input); bool rv1 = in.attribute("Type", value.type_); bool rv2 = in.attribute("Visible", value.visible_); - bool rv3 = in.attribute("Width", value.width_); - return rv1 && rv2 && rv3; + bool rv3 = in.attribute("Width", value.offset_); //offset == width if stretch is 0 + bool rv4 = in.attribute("Stretch", value.stretch_); + return rv1 && rv2 && rv3 && rv4; } template <> inline void writeStruc(const ColumnAttributeRim& value, XmlElement& output) { XmlOut out(output); - out.attribute("Type", value.type_); - out.attribute("Visible", value.visible_); - out.attribute("Width", value.width_); + out.attribute("Type", value.type_); + out.attribute("Visible", value.visible_); + out.attribute("Width", value.offset_); + out.attribute("Stretch", value.stretch_); } @@ -671,8 +728,9 @@ bool readStruc(const XmlElement& input, ColumnAttributeNavi& value) XmlIn in(input); bool rv1 = in.attribute("Type", value.type_); bool rv2 = in.attribute("Visible", value.visible_); - bool rv3 = in.attribute("Width", value.width_); - return rv1 && rv2 && rv3; + bool rv3 = in.attribute("Width", value.offset_); //offset == width if stretch is 0 + bool rv4 = in.attribute("Stretch", value.stretch_); + return rv1 && rv2 && rv3 && rv4; } template <> inline @@ -681,7 +739,8 @@ void writeStruc(const ColumnAttributeNavi& value, XmlElement& output) XmlOut out(output); out.attribute("Type", value.type_); out.attribute("Visible", value.visible_); - out.attribute("Width", value.width_); + out.attribute("Width", value.offset_); + out.attribute("Stretch", value.stretch_); } } @@ -747,7 +806,7 @@ void readConfig(const XmlIn& in, FolderPairEnh& enhPair) CompConfig altCmpCfg; readConfig(inAltCmp, altCmpCfg); - enhPair.altCmpConfig = std::make_shared<CompConfig>(altCmpCfg);; + enhPair.altCmpConfig = std::make_shared<CompConfig>(altCmpCfg); } //########################################################### //alternate sync configuration (optional) @@ -883,12 +942,14 @@ void readConfig(const XmlIn& in, XmlGlobalSettings& config) inColNavi(config.gui.columnAttribNavi); inColNavi.attribute("ShowPercentage", config.gui.showPercentBar); - inColNavi.attribute("SortByColumn", config.gui.naviLastSortColumn); - inColNavi.attribute("SortAscending", config.gui.naviLastSortAscending); + inColNavi.attribute("SortByColumn", config.gui.naviLastSortColumn); + inColNavi.attribute("SortAscending", config.gui.naviLastSortAscending); XmlIn inMainGrid = inWnd["MainGrid"]; - inMainGrid.attribute("ShowIcons", config.gui.showIcons); - inMainGrid.attribute("IconSize", config.gui.iconSize); + inMainGrid.attribute("ShowIcons", config.gui.showIcons); + inMainGrid.attribute("IconSize", config.gui.iconSize); + inMainGrid.attribute("SashOffset", config.gui.sashOffset); + XmlIn inColLeft = inMainGrid["ColumnsLeft"]; inColLeft(config.gui.columnAttribLeft); @@ -1153,12 +1214,13 @@ void writeConfig(const XmlGlobalSettings& config, XmlOut& out) outColNavi(config.gui.columnAttribNavi); outColNavi.attribute("ShowPercentage", config.gui.showPercentBar); - outColNavi.attribute("SortByColumn", config.gui.naviLastSortColumn); - outColNavi.attribute("SortAscending", config.gui.naviLastSortAscending); + outColNavi.attribute("SortByColumn", config.gui.naviLastSortColumn); + outColNavi.attribute("SortAscending", config.gui.naviLastSortAscending); XmlOut outMainGrid = outWnd["MainGrid"]; - outMainGrid.attribute("ShowIcons", config.gui.showIcons); - outMainGrid.attribute("IconSize", config.gui.iconSize); + outMainGrid.attribute("ShowIcons", config.gui.showIcons); + outMainGrid.attribute("IconSize", config.gui.iconSize); + outMainGrid.attribute("SashOffset", config.gui.sashOffset); XmlOut outColLeft = outMainGrid["ColumnsLeft"]; outColLeft(config.gui.columnAttribLeft); diff --git a/lib/process_xml.h b/lib/process_xml.h index 43dedb51..540b4ef3 100644 --- a/lib/process_xml.h +++ b/lib/process_xml.h @@ -147,6 +147,7 @@ struct XmlGlobalSettings dlgPos(wxDefaultCoord, wxDefaultCoord), dlgSize(wxDefaultCoord, wxDefaultCoord), isMaximized(false), + sashOffset(0), maxFolderPairsVisible(6), columnAttribNavi (zen::getDefaultColumnAttributesNavi()), columnAttribLeft (zen::getDefaultColumnAttributesLeft()), @@ -184,6 +185,7 @@ struct XmlGlobalSettings wxPoint dlgPos; wxSize dlgSize; bool isMaximized; + int sashOffset; int maxFolderPairsVisible; |