summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:20:50 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:20:50 +0200
commit7e706cf64654aea466c059c307e5723e2423ed5d (patch)
treee85f0d28d7c81b6d21419fc38e1a654cca2212b1 /lib
parent5.5 (diff)
downloadFreeFileSync-7e706cf64654aea466c059c307e5723e2423ed5d.tar.gz
FreeFileSync-7e706cf64654aea466c059c307e5723e2423ed5d.tar.bz2
FreeFileSync-7e706cf64654aea466c059c307e5723e2423ed5d.zip
5.6
Diffstat (limited to 'lib')
-rw-r--r--lib/binary.cpp8
-rw-r--r--lib/db_file.cpp226
-rw-r--r--lib/dir_lock.cpp9
-rw-r--r--lib/error_log.h43
-rw-r--r--lib/generate_logfile.h15
-rw-r--r--lib/hard_filter.h4
-rw-r--r--lib/localization.cpp22
-rw-r--r--lib/perf_check.cpp4
-rw-r--r--lib/process_xml.cpp104
-rw-r--r--lib/process_xml.h2
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;
bgstack15