summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:00:17 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:00:17 +0200
commitfd0853d2623dd278b08288331ed42e3be59252fb (patch)
treea7645daeaef8bdbed064faf4eb88e72cee58726c /library
parent2.1 (diff)
downloadFreeFileSync-fd0853d2623dd278b08288331ed42e3be59252fb.tar.gz
FreeFileSync-fd0853d2623dd278b08288331ed42e3be59252fb.tar.bz2
FreeFileSync-fd0853d2623dd278b08288331ed42e3be59252fb.zip
2.2
Diffstat (limited to 'library')
-rw-r--r--library/CustomGrid.cpp287
-rw-r--r--library/CustomGrid.h16
-rw-r--r--library/errorLogging.cpp48
-rw-r--r--library/errorLogging.h43
-rw-r--r--library/filter.cpp16
-rw-r--r--library/filter.h3
-rw-r--r--library/iconBuffer.cpp132
-rw-r--r--library/iconBuffer.h4
-rw-r--r--library/pch.h3
-rw-r--r--library/processXml.cpp1073
-rw-r--r--library/processXml.h54
-rw-r--r--library/resources.cpp44
-rw-r--r--library/resources.h14
-rw-r--r--library/statistics.cpp3
-rw-r--r--library/statusHandler.h6
15 files changed, 793 insertions, 953 deletions
diff --git a/library/CustomGrid.cpp b/library/CustomGrid.cpp
index 591230e2..4cb82961 100644
--- a/library/CustomGrid.cpp
+++ b/library/CustomGrid.cpp
@@ -1,5 +1,5 @@
#include "customGrid.h"
-#include "globalFunctions.h"
+#include "../shared/globalFunctions.h"
#include "resources.h"
#include <wx/dc.h>
#include "../algorithm.h"
@@ -7,6 +7,7 @@
#include <typeinfo>
#include "../ui/gridView.h"
#include "../synchronization.h"
+#include "../shared/customTooltip.h"
#ifdef FFS_WIN
#include <wx/timer.h>
@@ -60,9 +61,9 @@ public:
virtual ~CustomGridTable() {}
- void setGridDataTable(const GridView* gridDataView)
+ void setGridDataTable(const GridView* view)
{
- this->gridDataView = gridDataView;
+ this->gridDataView = view;
}
@@ -275,15 +276,15 @@ public:
switch (getTypeAtPos(col))
{
case xmlAccess::FULL_PATH:
- return wxString(gridLine->fileDescrLeft.fullName.c_str()).BeforeLast(FreeFileSync::FILE_NAME_SEPARATOR);
+ return wxString(gridLine->fileDescrLeft.fullName.c_str()).BeforeLast(globalFunctions::FILE_NAME_SEPARATOR);
case xmlAccess::FILENAME: //filename
- return wxString(gridLine->fileDescrLeft.relativeName.c_str()).AfterLast(FreeFileSync::FILE_NAME_SEPARATOR);
+ return wxString(gridLine->fileDescrLeft.relativeName.c_str()).AfterLast(globalFunctions::FILE_NAME_SEPARATOR);
case xmlAccess::REL_PATH: //relative path
- return wxString(gridLine->fileDescrLeft.relativeName.c_str()).BeforeLast(FreeFileSync::FILE_NAME_SEPARATOR);
+ return wxString(gridLine->fileDescrLeft.relativeName.c_str()).BeforeLast(globalFunctions::FILE_NAME_SEPARATOR);
case xmlAccess::DIRECTORY:
return gridDataView->getFolderPair(row).leftDirectory.c_str();
case xmlAccess::SIZE: //file size
- return globalFunctions::includeNumberSeparator(gridLine->fileDescrLeft.fileSize.ToString());
+ return FreeFileSync::includeNumberSeparator(gridLine->fileDescrLeft.fileSize.ToString());
case xmlAccess::DATE: //date
return FreeFileSync::utcTimeToLocalString(gridLine->fileDescrLeft.lastWriteTimeRaw, gridLine->fileDescrLeft.fullName);
}
@@ -355,15 +356,15 @@ public:
switch (getTypeAtPos(col))
{
case xmlAccess::FULL_PATH:
- return wxString(gridLine->fileDescrRight.fullName.c_str()).BeforeLast(FreeFileSync::FILE_NAME_SEPARATOR);
+ return wxString(gridLine->fileDescrRight.fullName.c_str()).BeforeLast(globalFunctions::FILE_NAME_SEPARATOR);
case xmlAccess::FILENAME: //filename
- return wxString(gridLine->fileDescrRight.relativeName.c_str()).AfterLast(FreeFileSync::FILE_NAME_SEPARATOR);
+ return wxString(gridLine->fileDescrRight.relativeName.c_str()).AfterLast(globalFunctions::FILE_NAME_SEPARATOR);
case xmlAccess::REL_PATH: //relative path
- return wxString(gridLine->fileDescrRight.relativeName.c_str()).BeforeLast(FreeFileSync::FILE_NAME_SEPARATOR);
+ return wxString(gridLine->fileDescrRight.relativeName.c_str()).BeforeLast(globalFunctions::FILE_NAME_SEPARATOR);
case xmlAccess::DIRECTORY:
return gridDataView->getFolderPair(row).rightDirectory.c_str();
case xmlAccess::SIZE: //file size
- return globalFunctions::includeNumberSeparator(gridLine->fileDescrRight.fileSize.ToString());
+ return FreeFileSync::includeNumberSeparator(gridLine->fileDescrRight.fileSize.ToString());
case xmlAccess::DATE: //date
return FreeFileSync::utcTimeToLocalString(gridLine->fileDescrRight.lastWriteTimeRaw, gridLine->fileDescrRight.fullName);
}
@@ -449,7 +450,7 @@ private:
if (syncPreviewActive) //synchronization preview
{
- switch (gridLine->direction)
+ switch (gridLine->syncDir)
{
case SYNC_DIR_LEFT:
return COLOR_SYNC_BLUE;
@@ -904,77 +905,98 @@ public:
{
//############## show windows explorer file icons ######################
- if (showFileIcons) //evaluate at compile time
+ if ( showFileIcons && //evaluate at compile time
+ m_gridDataTable->getTypeAtPos(col) == xmlAccess::FILENAME)
{
- if ( m_gridDataTable->getTypeAtPos(col) == xmlAccess::FILENAME &&
- rect.GetWidth() >= IconBuffer::ICON_SIZE)
+ if (rect.GetWidth() >= IconBuffer::ICON_SIZE)
{
+ // Partitioning:
+ // _____________________
+ // | 2 pix | icon | rest |
+ // ---------------------
+
+ //clear area where icon will be placed
+ wxRect rectShrinked(rect);
+ rectShrinked.SetWidth(IconBuffer::ICON_SIZE + LEFT_BORDER); //add 2 pixel border
+ wxGridCellRenderer::Draw(grid, attr, dc, rectShrinked, row, col, isSelected);
+
+ //draw rest
+ wxRect rest(rect); //unscrolled
+ rest.x += IconBuffer::ICON_SIZE + LEFT_BORDER;
+ rest.width -= IconBuffer::ICON_SIZE + LEFT_BORDER;
+ wxGridCellStringRenderer::Draw(grid, attr, dc, rest, row, col, isSelected);
+
+ //try to draw icon
//retrieve grid data
const Zstring fileName = m_gridDataTable->getFileName(row);
if (!fileName.empty())
{
- // Partitioning:
- // _____________________
- // | 2 pix | icon | rest |
- // ---------------------
-
- //clear area where icon will be placed
- wxRect rectShrinked(rect);
- rectShrinked.SetWidth(IconBuffer::ICON_SIZE + 2); //add 2 pixel border
- wxGridCellRenderer::Draw(grid, attr, dc, rectShrinked, row, col, isSelected);
-
- //try to draw icon
wxIcon icon;
+ bool iconDrawnFully = false;
const bool iconLoaded = IconBuffer::getInstance().requestIcon(fileName, &icon); //returns false if icon is not in buffer
if (iconLoaded)
- dc.DrawIcon(icon, rectShrinked.GetX() + 2, rectShrinked.GetY());
+ {
+ dc.DrawIcon(icon, rectShrinked.GetX() + LEFT_BORDER, rectShrinked.GetY());
- //-----------------------------------------------------------------------------------------------
- //only mark as successful if icon was drawn fully!
- //(attention: when scrolling, rows get partially updated, which can result in the upper half being blank!)
+ //-----------------------------------------------------------------------------------------------
+ //only mark as successful if icon was drawn fully!
+ //(attention: when scrolling, rows get partially updated, which can result in the upper half being blank!)
- //rect where icon was placed
- wxRect iconRect(rect); //unscrolled
- iconRect.x += 2;
- iconRect.SetWidth(IconBuffer::ICON_SIZE);
+ //rect where icon was placed
+ wxRect iconRect(rect); //unscrolled
+ iconRect.x += LEFT_BORDER;
+ iconRect.SetWidth(IconBuffer::ICON_SIZE);
- //convert to scrolled coordinates
- grid.CalcScrolledPosition(iconRect.x, iconRect.y, &iconRect.x, &iconRect.y);
+ //convert to scrolled coordinates
+ grid.CalcScrolledPosition(iconRect.x, iconRect.y, &iconRect.x, &iconRect.y);
- bool iconDrawnFully = false;
- wxRegionIterator regionsInv(grid.GetGridWindow()->GetUpdateRegion());
- while (regionsInv)
- {
- if (regionsInv.GetRect().Contains(iconRect))
+ wxRegionIterator regionsInv(grid.GetGridWindow()->GetUpdateRegion());
+ while (regionsInv)
{
- iconDrawnFully = true;
- break;
+ if (regionsInv.GetRect().Contains(iconRect))
+ {
+ iconDrawnFully = true;
+ break;
+ }
+ ++regionsInv;
}
- ++regionsInv;
}
//-----------------------------------------------------------------------------------------------
-
-
//save status of last icon load -> used for async. icon loading
m_loadIconSuccess[row] = iconLoaded && iconDrawnFully;
-
- //draw rest
- wxRect rest(rect); //unscrolled
- rest.x += IconBuffer::ICON_SIZE + 2;
- rest.width -= IconBuffer::ICON_SIZE + 2;
-
- wxGridCellStringRenderer::Draw(grid, attr, dc, rest, row, col, isSelected);
- return;
}
}
+ return;
}
+
//default
wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
}
+
+ virtual wxSize GetBestSize(wxGrid& grid, //adapt reported width if file icons are shown
+ wxGridCellAttr& attr,
+ wxDC& dc,
+ int row, int col)
+ {
+ if ( showFileIcons && //evaluate at compile time
+ m_gridDataTable->getTypeAtPos(col) == xmlAccess::FILENAME)
+ {
+ wxSize rv = wxGridCellStringRenderer::GetBestSize(grid, attr, dc, row, col);
+ rv.SetWidth(rv.GetWidth() + LEFT_BORDER + IconBuffer::ICON_SIZE);
+ return rv;
+ }
+
+ //default
+ return wxGridCellStringRenderer::GetBestSize(grid, attr, dc, row, col);
+ }
+
+
private:
CustomGridRim::LoadSuccess& m_loadIconSuccess;
const CustomGridTableRim* const m_gridDataTable;
+
+ static const int LEFT_BORDER = 2;
};
#endif
@@ -1268,7 +1290,7 @@ IconUpdater::IconUpdater(CustomGridLeft* leftGrid, CustomGridRight* rightGrid) :
m_timer(new wxTimer) //connect timer event for async. icon loading
{
m_timer->Connect(wxEVT_TIMER, wxEventHandler(IconUpdater::loadIconsAsynchronously), NULL, this);
- m_timer->Start(50); //timer interval
+ m_timer->Start(50); //timer interval in ms
}
@@ -1280,7 +1302,8 @@ void IconUpdater::loadIconsAsynchronously(wxEvent& event) //loads all (not yet)
std::vector<Zstring> newLoad;
m_rightGrid->getIconsToBeLoaded(newLoad);
- globalFunctions::mergeVectors(iconsLeft, newLoad);
+ //merge vectors
+ newLoad.insert(newLoad.end(), iconsLeft.begin(), iconsLeft.end());
FreeFileSync::IconBuffer::getInstance().setWorkload(newLoad); //attention: newLoad is invalidated after this call!!!
@@ -1424,7 +1447,8 @@ CustomGridMiddle::CustomGridMiddle(wxWindow *parent,
selectionPos(BLOCKPOS_CHECK_BOX),
highlightedRow(-1),
highlightedPos(BLOCKPOS_CHECK_BOX),
- gridDataTable(NULL)
+ gridDataTable(NULL),
+ toolTip(new CustomTooltip)
{
//connect events for dynamic selection of sync direction
GetGridWindow()->Connect(wxEVT_MOTION, wxMouseEventHandler(CustomGridMiddle::OnMouseMovement), NULL, this);
@@ -1480,6 +1504,9 @@ void CustomGridMiddle::OnMouseMovement(wxMouseEvent& event)
if ( highlightedRowOld >= 0 &&
highlightedRow != highlightedRowOld)
RefreshCell(highlightedRowOld, 0);
+
+ //handle tooltip
+ showToolTip(highlightedRow, GetGridWindow()->ClientToScreen(event.GetPosition()));
}
event.Skip();
@@ -1491,6 +1518,78 @@ void CustomGridMiddle::OnLeaveWindow(wxMouseEvent& event)
highlightedRow = -1;
highlightedPos = BLOCKPOS_CHECK_BOX;
Refresh();
+
+ //handle tooltip
+ toolTip->hide();
+}
+
+
+void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos)
+{
+ const FileCompareLine* const rowData = gridDataTable->getRawData(rowNumber);
+ if (rowData == NULL) //if invalid row...
+ {
+ toolTip->hide();
+ return;
+ }
+
+ if (gridDataTable->syncPreviewIsActive()) //synchronization preview
+ {
+ switch (getSyncOperation(*rowData))
+ {
+ case SO_CREATE_NEW_LEFT:
+ toolTip->show(_("Copy from right to left"), pos, GlobalResources::getInstance().bitmapSyncCreateLeftAct);
+ break;
+ case SO_CREATE_NEW_RIGHT:
+ toolTip->show(_("Copy from left to right"), pos, GlobalResources::getInstance().bitmapSyncCreateRightAct);
+ break;
+ case SO_DELETE_LEFT:
+ toolTip->show(_("Delete files/folders existing on left side only"), pos, GlobalResources::getInstance().bitmapSyncDeleteLeftAct);
+ break;
+ case SO_DELETE_RIGHT:
+ toolTip->show(_("Delete files/folders existing on right side only"), pos, GlobalResources::getInstance().bitmapSyncDeleteRightAct);
+ break;
+ case SO_OVERWRITE_LEFT:
+ toolTip->show(_("Copy from right to left overwriting"), pos, GlobalResources::getInstance().bitmapSyncDirLeftAct);
+ break;
+ case SO_OVERWRITE_RIGHT:
+ toolTip->show(_("Copy from left to right overwriting"), pos, GlobalResources::getInstance().bitmapSyncDirRightAct);
+ break;
+ case SO_DO_NOTHING:
+ toolTip->show(_("Do nothing"), pos, GlobalResources::getInstance().bitmapSyncDirNoneAct);
+ break;
+ case SO_UNRESOLVED_CONFLICT:
+ toolTip->show(rowData->conflictDescription.get(), pos, GlobalResources::getInstance().bitmapConflictAct);
+ break;
+ };
+ }
+ else
+ {
+ switch (rowData->cmpResult)
+ {
+ case FILE_LEFT_SIDE_ONLY:
+ toolTip->show(_("Files/folders that exist on left side only"), pos, GlobalResources::getInstance().bitmapLeftOnlyAct);
+ break;
+ case FILE_RIGHT_SIDE_ONLY:
+ toolTip->show(_("Files/folders that exist on right side only"), pos, GlobalResources::getInstance().bitmapRightOnlyAct);
+ break;
+ case FILE_LEFT_NEWER:
+ toolTip->show(_("Files that exist on both sides, left one is newer"), pos, GlobalResources::getInstance().bitmapLeftNewerAct);
+ break;
+ case FILE_RIGHT_NEWER:
+ toolTip->show(_("Files that exist on both sides, right one is newer"), pos, GlobalResources::getInstance().bitmapRightNewerAct);
+ break;
+ case FILE_DIFFERENT:
+ toolTip->show(_("Files that exist on both sides and have different content"), pos, GlobalResources::getInstance().bitmapDifferentAct);
+ break;
+ case FILE_EQUAL:
+ toolTip->show(_(""), pos, GlobalResources::getInstance().bitmapEqualAct);
+ break;
+ case FILE_CONFLICT:
+ toolTip->show(rowData->conflictDescription.get(), pos, GlobalResources::getInstance().bitmapConflictAct);
+ break;
+ }
+ }
}
@@ -1594,32 +1693,6 @@ void CustomGridMiddle::enableSyncPreview(bool value)
{
assert(gridDataTable);
gridDataTable->enableSyncPreview(value);
-
- //update legend
- wxString toolTip;
-
- if (gridDataTable->syncPreviewIsActive()) //synchronization preview
- {
- const wxString header = _("Synchronization Preview");
- toolTip = header + wxT("\n") + wxString().Pad(header.Len(), wxChar('-')) + wxT("\n");
- toolTip += wxString(_("<- copy to left side\n")) +
- _("-> copy to right side\n") +
- wxT(" ")+ _("- do not copy\n") +
- _("flash conflict\n");
- }
- else //compare results view
- {
- const wxString header = _("Comparison Result");
- toolTip = header + wxT("\n") + wxString().Pad(header.Len(), wxChar('-')) + wxT("\n");
- toolTip += wxString(_("<| file on left side only\n")) +
- _("|> file on right side only\n") +
- _("<< left file is newer\n") +
- _(">> right file is newer\n") +
- _("!= files are different\n") +
- _("== files are equal\n") +
- _("flash conflict\n");
- }
- GetGridColLabelWindow()->SetToolTip(toolTip);
}
@@ -1643,6 +1716,8 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
{
if (rect.GetWidth() > CHECK_BOX_WIDTH)
{
+ const bool rowIsHighlighted = row == m_gridMiddle->highlightedRow;
+
wxRect rectShrinked(rect);
//clean first block of rect that will receive image of checkbox
@@ -1651,14 +1726,17 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
//print image into first block
rectShrinked.SetX(rect.GetX() + 1);
- bool selected = rowData->selectedForSynchronization;
//HIGHLIGHTNING:
- if ( row == m_gridMiddle->highlightedRow &&
- m_gridMiddle->highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX)
- selected = !selected;
-
- if (selected)
+ if (rowIsHighlighted && m_gridMiddle->highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX)
+ {
+ if (rowData->selectedForSynchronization)
+ dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxTrueFocus, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ else
+ dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxFalseFocus, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ }
+ //default
+ else if (rowData->selectedForSynchronization)
dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxTrue, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
else
dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxFalse, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
@@ -1674,7 +1752,7 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
//print sync direction into second block
//HIGHLIGHTNING:
- if (row == m_gridMiddle->highlightedRow && m_gridMiddle->highlightedPos != CustomGridMiddle::BLOCKPOS_CHECK_BOX)
+ if (rowIsHighlighted && m_gridMiddle->highlightedPos != CustomGridMiddle::BLOCKPOS_CHECK_BOX)
switch (m_gridMiddle->highlightedPos)
{
case CustomGridMiddle::BLOCKPOS_CHECK_BOX:
@@ -1691,7 +1769,7 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
}
else //default
{
- const wxBitmap& syncOpIcon = getSyncOpImage(rowData->cmpResult, rowData->selectedForSynchronization, rowData->direction);
+ const wxBitmap& syncOpIcon = getSyncOpImage(rowData->cmpResult, rowData->selectedForSynchronization, rowData->syncDir);
dc.DrawLabel(wxEmptyString, syncOpIcon, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
}
}
@@ -1755,3 +1833,30 @@ void CustomGridMiddle::DrawColLabel(wxDC& dc, int col)
dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCmpViewSmall, rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
}
+
+const wxBitmap& FreeFileSync::getSyncOpImage(const CompareFilesResult cmpResult,
+ const bool selectedForSynchronization,
+ const SyncDirection syncDir)
+{
+ switch (getSyncOperation(cmpResult, selectedForSynchronization, syncDir)) //evaluate comparison result and sync direction
+ {
+ case SO_CREATE_NEW_LEFT:
+ return *GlobalResources::getInstance().bitmapCreateLeftSmall;
+ case SO_CREATE_NEW_RIGHT:
+ return *GlobalResources::getInstance().bitmapCreateRightSmall;
+ case SO_DELETE_LEFT:
+ return *GlobalResources::getInstance().bitmapDeleteLeftSmall;
+ case SO_DELETE_RIGHT:
+ return *GlobalResources::getInstance().bitmapDeleteRightSmall;
+ case SO_OVERWRITE_RIGHT:
+ return *GlobalResources::getInstance().bitmapSyncDirRightSmall;
+ case SO_OVERWRITE_LEFT:
+ return *GlobalResources::getInstance().bitmapSyncDirLeftSmall;
+ case SO_DO_NOTHING:
+ return *GlobalResources::getInstance().bitmapSyncDirNoneSmall;
+ case SO_UNRESOLVED_CONFLICT:
+ return *GlobalResources::getInstance().bitmapConflictSmall;
+ }
+
+ return wxNullBitmap; //dummy
+}
diff --git a/library/CustomGrid.h b/library/CustomGrid.h
index 98e86e11..a71b985a 100644
--- a/library/CustomGrid.h
+++ b/library/CustomGrid.h
@@ -3,7 +3,6 @@
#include <vector>
#include <wx/grid.h>
-#include "../structures.h"
#include "processXml.h"
#include <map>
#include <memory>
@@ -14,6 +13,7 @@ class CustomGridTableRight;
class CustomGridTableMiddle;
class GridCellRendererMiddle;
class wxTimer;
+class CustomTooltip;
class CustomGridRim;
class CustomGridLeft;
class CustomGridMiddle;
@@ -22,6 +22,10 @@ class CustomGridRight;
namespace FreeFileSync
{
class GridView;
+
+ const wxBitmap& getSyncOpImage(const CompareFilesResult cmpResult,
+ const bool selectedForSynchronization,
+ const SyncDirection syncDir);
}
//##################################################################################
@@ -103,7 +107,7 @@ class GridCellRenderer;
//-----------------------------------------------------------
#ifdef FFS_WIN
-class IconUpdater : public wxEvtHandler //update file icons periodically: use SINGLE instance to coordinate left and right grid at once
+class IconUpdater : private wxEvtHandler //update file icons periodically: use SINGLE instance to coordinate left and right grid at once
{
public:
IconUpdater(CustomGridLeft* leftGrid, CustomGridRight* rightGrid);
@@ -123,8 +127,8 @@ private:
class CustomGridRim : public CustomGrid
{
friend class IconUpdater;
- template <bool showFileIcons>
- friend class GridCellRenderer;
+ template <bool showFileIcons>
+ friend class GridCellRenderer;
public:
CustomGridRim(wxWindow *parent,
@@ -257,6 +261,8 @@ private:
void OnLeftMouseDown(wxMouseEvent& event);
void OnLeftMouseUp(wxMouseEvent& event);
+ void showToolTip(int rowNumber, wxPoint pos);
+
//small helper methods
enum BlockPosition //each cell can be divided into four blocks concerning mouse selections
{
@@ -276,6 +282,8 @@ private:
BlockPosition highlightedPos;
CustomGridTableMiddle* gridDataTable;
+
+ std::auto_ptr<CustomTooltip> toolTip;
};
//custom events for middle grid:
diff --git a/library/errorLogging.cpp b/library/errorLogging.cpp
new file mode 100644
index 00000000..000dce4d
--- /dev/null
+++ b/library/errorLogging.cpp
@@ -0,0 +1,48 @@
+#include "errorLogging.h"
+#include <wx/datetime.h>
+#include <wx/intl.h>
+
+
+using FreeFileSync::ErrorLogging;
+
+
+void ErrorLogging::logError(const wxString& errorMessage)
+{
+ ++errorCount;
+
+ const wxString prefix = wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + _("Error") + wxT(": ");
+ formattedMessages.push_back(assembleMessage(prefix, errorMessage));
+}
+
+
+void ErrorLogging::logWarning(const wxString& warningMessage)
+{
+ const wxString prefix = wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + _("Warning") + wxT(": ");
+ formattedMessages.push_back(assembleMessage(prefix, warningMessage));
+}
+
+
+void ErrorLogging::logInfo(const wxString& infoMessage)
+{
+ const wxString prefix = wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + _("Info") + wxT(": ");
+ formattedMessages.push_back(assembleMessage(prefix, infoMessage));
+}
+
+
+wxString ErrorLogging::assembleMessage(const wxString& prefix, const wxString& message)
+{
+ const size_t prefixLength = prefix.size();
+ wxString formattedText = prefix;
+ for (wxString::const_iterator i = message.begin(); i != message.end(); ++i)
+ if (*i == wxChar('\n'))
+ {
+ formattedText += wxString(wxChar('\n')).Pad(prefixLength, wxChar(' '), true);
+ while (*++i == wxChar('\n')) //remove duplicate newlines
+ ;
+ --i;
+ }
+ else
+ formattedText += *i;
+
+ return formattedText;
+}
diff --git a/library/errorLogging.h b/library/errorLogging.h
new file mode 100644
index 00000000..5fc5dacd
--- /dev/null
+++ b/library/errorLogging.h
@@ -0,0 +1,43 @@
+#ifndef ERRORLOGGING_H_INCLUDED
+#define ERRORLOGGING_H_INCLUDED
+
+#include <wx/string.h>
+#include <vector>
+
+class Zstring;
+
+namespace FreeFileSync
+{
+ class ErrorLogging
+ {
+ public:
+ ErrorLogging() : errorCount(0) {}
+
+ void logError(const wxString& errorMessage);
+ void logWarning(const wxString& warningMessage);
+ void logInfo(const wxString& infoMessage);
+
+ int errorsTotal()
+ {
+ return errorCount;
+ }
+
+ const std::vector<wxString>& getFormattedMessages()
+ {
+ return formattedMessages;
+ }
+
+ size_t messageCount()
+ {
+ return formattedMessages.size();
+ }
+
+ private:
+ wxString assembleMessage(const wxString& prefix, const wxString& message);
+
+ std::vector<wxString> formattedMessages; //list of non-resolved errors and warnings
+ int errorCount;
+ };
+}
+
+#endif // ERRORLOGGING_H_INCLUDED
diff --git a/library/filter.cpp b/library/filter.cpp
index 65513630..bd281c7c 100644
--- a/library/filter.cpp
+++ b/library/filter.cpp
@@ -1,10 +1,10 @@
#include "filter.h"
-#include "zstring.h"
+#include "../shared/zstring.h"
#include <wx/string.h>
#include <set>
#include <vector>
-#include "resources.h"
-#include "globalFunctions.h"
+#include "../shared/globalFunctions.h"
+#include "../structures.h"
using FreeFileSync::FilterProcess;
@@ -49,7 +49,7 @@ std::vector<Zstring> compoundStringToFilter(const Zstring& filterString)
std::vector<Zstring> newEntries;
compoundStringToTable(*i, wxT("\n"), newEntries);
- globalFunctions::mergeVectors(newEntries, filterList);
+ filterList.insert(filterList.end(), newEntries.begin(), newEntries.end());
}
return filterList;
@@ -70,12 +70,12 @@ void addFilterEntry(const Zstring& filtername, std::set<Zstring>& fileFilter, st
#endif
//remove leading separators (keep BEFORE test for Zstring::empty()!)
- if (filterFormatted.length() > 0 && *filterFormatted.c_str() == FreeFileSync::FILE_NAME_SEPARATOR)
+ if (filterFormatted.length() > 0 && *filterFormatted.c_str() == globalFunctions::FILE_NAME_SEPARATOR)
filterFormatted = Zstring(filterFormatted.c_str() + 1);
if (!filterFormatted.empty())
{
- //Test if filterFormatted ends with FreeFileSync::FILE_NAME_SEPARATOR, ignoring '*' and '?'.
+ //Test if filterFormatted ends with globalFunctions::FILE_NAME_SEPARATOR, ignoring '*' and '?'.
//If so, treat as filter for directory and add to directoryFilter.
const DefaultChar* filter = filterFormatted.c_str();
int i = filterFormatted.length() - 1;
@@ -87,7 +87,7 @@ void addFilterEntry(const Zstring& filtername, std::set<Zstring>& fileFilter, st
break;
}
- if (i >= 0 && filter[i] == FreeFileSync::FILE_NAME_SEPARATOR) //last FILE_NAME_SEPARATOR found
+ if (i >= 0 && filter[i] == globalFunctions::FILE_NAME_SEPARATOR) //last FILE_NAME_SEPARATOR found
{
if (i != int(filterFormatted.length()) - 1) // "name\*"
{
@@ -119,7 +119,7 @@ bool matchesFilter(const DefaultChar* name, const std::set<Zstring>& filter)
#endif
for (std::set<Zstring>::const_iterator j = filter.begin(); j != filter.end(); ++j)
- if (Zstring::Matches(nameFormatted, *j))
+ if (Zstring::Matches(nameFormatted, j->c_str()))
return true;
return false;
diff --git a/library/filter.h b/library/filter.h
index 85df591c..53e4d9b1 100644
--- a/library/filter.h
+++ b/library/filter.h
@@ -1,6 +1,9 @@
#ifndef FFS_FILTER_H_INCLUDED
#define FFS_FILTER_H_INCLUDED
+#include <wx/string.h>
+#include "../shared/zstring.h"
+#include <set>
#include "../structures.h"
diff --git a/library/iconBuffer.cpp b/library/iconBuffer.cpp
index a969f689..f73164e0 100644
--- a/library/iconBuffer.cpp
+++ b/library/iconBuffer.cpp
@@ -1,11 +1,9 @@
#include "iconBuffer.h"
#include <wx/thread.h>
-#include "globalFunctions.h"
-#include <wx/utils.h>
+#include "../shared/globalFunctions.h"
#include <wx/bitmap.h>
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include <wx/msgdlg.h>
-#include "../algorithm.h"
#include <wx/icon.h>
#include <map>
#include <queue>
@@ -13,53 +11,7 @@
using FreeFileSync::IconBuffer;
-class BasicString //simple thread safe string class
-{
-public:
- BasicString()
- {
- data = new DefaultChar[1]; //compliance with delete []
- *data = 0; //compliance with c_str()
- }
-
- BasicString(const Zstring& other) //make DEEP COPY from Zstring!
- {
- data = new DefaultChar[other.length() + 1];
- memcpy(data, other.c_str(), (other.length() + 1) * sizeof(DefaultChar));
- }
-
- BasicString(const BasicString& other)
- {
- const size_t otherLen = defaultLength(other.c_str());
- data = new DefaultChar[otherLen + 1];
- memcpy(data, other.c_str(), (otherLen + 1) * sizeof(DefaultChar));
- }
-
- ~BasicString()
- {
- delete [] data;
- }
-
- BasicString& operator=(const BasicString& other)
- { //exception safety; handle self-assignment implicitly
- const size_t otherLen = defaultLength(other.c_str());
- DefaultChar* dataNew = new DefaultChar[otherLen + 1];
- memcpy(dataNew, other.c_str(), (otherLen + 1) * sizeof(DefaultChar));
-
- delete data;
- data = dataNew;
-
- return *this;
- }
-
- const DefaultChar* c_str() const
- {
- return data;
- }
-
-private:
- DefaultChar* data;
-};
+typedef std::vector<DefaultChar> BasicString; //simple thread safe string class: std::vector is guaranteed to not use reference counting, Effective STL, item 13
class WorkerThread : public wxThread
@@ -123,7 +75,7 @@ void WorkerThread::setWorkload(const std::vector<Zstring>& load) //(re-)set new
workload.clear();
for (std::vector<Zstring>::const_iterator i = load.begin(); i != load.end(); ++i)
- workload.push_back(*i); //make DEEP COPY from Zstring!
+ workload.push_back(FileName(i->c_str(), i->c_str() + i->length() + 1)); //make DEEP COPY from Zstring (include null-termination)!
if (!workload.empty())
continueWork.Signal(); //wake thread IF he is waiting
@@ -132,9 +84,12 @@ void WorkerThread::setWorkload(const std::vector<Zstring>& load) //(re-)set new
void WorkerThread::quitThread()
{
- wxMutexLocker dummy(threadIsListening); //wait until thread is in waiting state
- threadExitIsRequested = true; //no sharing conflicts in this situation
- continueWork.Signal(); //exit thread
+ {
+ wxMutexLocker dummy(threadIsListening); //wait until thread is in waiting state
+ threadExitIsRequested = true; //no sharing conflicts in this situation
+ continueWork.Signal(); //exit thread
+ }
+ Wait(); //wait until thread has exitted
}
@@ -144,7 +99,7 @@ wxThread::ExitCode WorkerThread::Entry()
{
wxMutexLocker dummy(threadIsListening); //this lock needs to be called from WITHIN the thread => calling it from constructor(Main thread) would be useless
{ //this mutex STAYS locked all the time except of continueWork.Wait()!
- wxCriticalSectionLocker dummy(lockWorkload);
+ wxCriticalSectionLocker dummy2(lockWorkload);
threadHasMutex = true;
}
@@ -170,7 +125,7 @@ wxThread::ExitCode WorkerThread::Entry()
void WorkerThread::doWork()
{
- BasicString fileName; //don't use Zstring: reference-counted objects are NOT THREADSAFE!!! e.g. double deletion might happen
+ FileName fileName; //don't use Zstring: reference-counted objects are NOT THREADSAFE!!! e.g. double deletion might happen
//do work: get the file icon.
while (true)
@@ -183,38 +138,46 @@ void WorkerThread::doWork()
workload.pop_back();
}
- if (iconBuffer->requestIcon(Zstring(fileName.c_str()))) //thread safety: Zstring okay, won't be reference-counted in requestIcon()
+ if (iconBuffer->requestIcon(Zstring(&fileName[0]))) //thread safety: Zstring okay, won't be reference-counted in requestIcon(), fileName is NOT empty
break; //icon already in buffer: enter waiting state
- //load icon
- SHFILEINFO fileInfo;
- fileInfo.hIcon = 0; //initialize hIcon
-
- if (SHGetFileInfo(fileName.c_str(), //NOTE: CoInitializeEx()/CoUninitialize() implicitly called by wxWidgets on program startup!
- 0,
- &fileInfo,
- sizeof(fileInfo),
- SHGFI_ICON | SHGFI_SMALLICON) &&
-
- fileInfo.hIcon != 0) //fix for weird error: SHGetFileInfo() might return successfully WITHOUT filling fileInfo.hIcon!!
- { //bug report: https://sourceforge.net/tracker/?func=detail&aid=2768004&group_id=234430&atid=1093080
-
- wxIcon newIcon; //attention: wxIcon uses reference counting!
- newIcon.SetHICON(fileInfo.hIcon);
- newIcon.SetSize(IconBuffer::ICON_SIZE, IconBuffer::ICON_SIZE);
-
- iconBuffer->insertIntoBuffer(fileName.c_str(), newIcon); //thread safety: icon may be deleted only within insertIntoBuffer()
-
- //freeing of icon handle seems to happen somewhere beyond wxIcon destructor
- //if (!DestroyIcon(fileInfo.hIcon))
- // throw RuntimeException(wxString(wxT("Error deallocating Icon handle!\n\n")) + FreeFileSync::getLastErrorFormatted());
-
- }
- else
+ //despite what docu says about SHGetFileInfo() it can't handle all relative filenames, e.g. "\DirName"
+ const unsigned int BUFFER_SIZE = 10000;
+ DefaultChar fullName[BUFFER_SIZE];
+ const DWORD rv = ::GetFullPathName(
+ &fileName[0], //__in LPCTSTR lpFileName,
+ BUFFER_SIZE, //__in DWORD nBufferLength,
+ fullName, //__out LPTSTR lpBuffer,
+ NULL); //__out LPTSTR *lpFilePart
+ if (rv < BUFFER_SIZE && rv != 0)
{
- //if loading of icon fails for whatever reason, just save a dummy icon to avoid re-loading
- iconBuffer->insertIntoBuffer(fileName.c_str(), wxNullIcon);
+ //load icon
+ SHFILEINFO fileInfo;
+ fileInfo.hIcon = 0; //initialize hIcon
+
+ if (::SHGetFileInfo(fullName, //NOTE: CoInitializeEx()/CoUninitialize() implicitly called by wxWidgets on program startup!
+ 0,
+ &fileInfo,
+ sizeof(fileInfo),
+ SHGFI_ICON | SHGFI_SMALLICON) &&
+
+ fileInfo.hIcon != 0) //fix for weird error: SHGetFileInfo() might return successfully WITHOUT filling fileInfo.hIcon!!
+ { //bug report: https://sourceforge.net/tracker/?func=detail&aid=2768004&group_id=234430&atid=1093080
+
+ wxIcon newIcon; //attention: wxIcon uses reference counting!
+ newIcon.SetHICON(fileInfo.hIcon);
+ newIcon.SetSize(IconBuffer::ICON_SIZE, IconBuffer::ICON_SIZE);
+
+ iconBuffer->insertIntoBuffer(&fileName[0], newIcon); //thread safety: icon may be deleted only within insertIntoBuffer()
+
+ //freeing of icon handle seems to happen somewhere beyond wxIcon destructor
+ //if (!DestroyIcon(fileInfo.hIcon))
+ // throw RuntimeException(wxString(wxT("Error deallocating Icon handle!\n\n")) + FreeFileSync::getLastErrorFormatted());
+ continue;
+ }
}
+ //if loading of icon fails for whatever reason, just save a dummy icon to avoid re-loading
+ iconBuffer->insertIntoBuffer(&fileName[0], wxNullIcon);
}
}
@@ -245,7 +208,6 @@ IconBuffer::IconBuffer() :
IconBuffer::~IconBuffer()
{
worker->quitThread();
- worker->Wait(); //wait until thread has exitted
}
diff --git a/library/iconBuffer.h b/library/iconBuffer.h
index ba905d22..f62a2772 100644
--- a/library/iconBuffer.h
+++ b/library/iconBuffer.h
@@ -2,11 +2,11 @@
#define ICONBUFFER_H_INCLUDED
#ifndef FFS_WIN
-#warning //this header should be used in the windows build only!
+header should be used in the windows build only!
#endif
#include <vector>
-#include "zstring.h"
+#include "../shared/zstring.h"
#include <memory>
class wxCriticalSection;
diff --git a/library/pch.h b/library/pch.h
index b561d448..22ed251f 100644
--- a/library/pch.h
+++ b/library/pch.h
@@ -25,6 +25,7 @@ do NOT use in release build!
#include <stack>
#include <set>
#include <map>
+#include <memory>
#include <fstream>
#ifdef FFS_LINUX
@@ -85,7 +86,7 @@ do NOT use in release build!
#include <wx/notebook.h>
//other
-#include "tinyxml/tinyxml.h"
+#include "../shared/tinyxml/tinyxml.h"
#include <sys/stat.h>
#ifdef FFS_WIN
diff --git a/library/processXml.cpp b/library/processXml.cpp
index 4b8ffe27..43d7fdb9 100644
--- a/library/processXml.cpp
+++ b/library/processXml.cpp
@@ -1,9 +1,10 @@
#include "processXml.h"
+#include "../shared/xmlBase.h"
#include <wx/filefn.h>
-#include <wx/ffile.h>
#include <wx/intl.h>
-#include "globalFunctions.h"
-#include "tinyxml/tinyxml.h"
+#include "../shared/globalFunctions.h"
+#include "../shared/fileHandling.h"
+#include "../shared/standardPaths.h"
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
@@ -12,290 +13,142 @@
using namespace FreeFileSync;
-//small helper functions
-bool readXmlElementValue(std::string& output, const TiXmlElement* parent, const std::string& name);
-bool readXmlElementValue(int& output, const TiXmlElement* parent, const std::string& name);
-bool readXmlElementValue(CompareVariant& output, const TiXmlElement* parent, const std::string& name);
-bool readXmlElementValue(SyncDirection& output, const TiXmlElement* parent, const std::string& name);
-bool readXmlElementValue(bool& output, const TiXmlElement* parent, const std::string& name);
-
-void addXmlElement(TiXmlElement* parent, const std::string& name, const std::string& value);
-void addXmlElement(TiXmlElement* parent, const std::string& name, const int value);
-void addXmlElement(TiXmlElement* parent, const std::string& name, const SyncDirection value);
-void addXmlElement(TiXmlElement* parent, const std::string& name, const bool value);
-
-
-class XmlConfigInput
+class FfsXmlParser : public xmlAccess::XmlParser
{
public:
- XmlConfigInput(const wxString& fileName, const xmlAccess::XmlType type);
- ~XmlConfigInput() {}
-
- bool loadedSuccessfully()
- {
- return loadSuccess;
- }
+ FfsXmlParser(const TiXmlElement* rootElement) : xmlAccess::XmlParser(rootElement) {}
//read gui settings, all values retrieved are optional, so check for initial values! (== -1)
- bool readXmlGuiConfig(xmlAccess::XmlGuiConfig& outputCfg);
+ void readXmlGuiConfig(xmlAccess::XmlGuiConfig& outputCfg);
//read batch settings, all values retrieved are optional
- bool readXmlBatchConfig(xmlAccess::XmlBatchConfig& outputCfg);
+ void readXmlBatchConfig(xmlAccess::XmlBatchConfig& outputCfg);
//read global settings, valid for both GUI and batch mode, independent from configuration
- bool readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg);
+ void readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg);
private:
//read basic FreefileSync settings (used by commandline and GUI), return true if ALL values have been retrieved successfully
- bool readXmlMainConfig(MainConfiguration& mainCfg, std::vector<FolderPair>& directoryPairs);
-
- TiXmlDocument doc;
- bool loadSuccess;
+ void readXmlMainConfig(MainConfiguration& mainCfg, std::vector<FolderPair>& directoryPairs);
};
-class XmlConfigOutput
-{
-public:
- XmlConfigOutput(const wxString& fileName, const xmlAccess::XmlType type);
- ~XmlConfigOutput() {}
-
- bool writeToFile();
-
- //write gui settings
- bool writeXmlGuiConfig(const xmlAccess::XmlGuiConfig& outputCfg);
- //write batch settings
- bool writeXmlBatchConfig(const xmlAccess::XmlBatchConfig& outputCfg);
- //write global settings
- bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& outputCfg);
-
-private:
- //write basic FreefileSync settings (used by commandline and GUI), return true if everything was written successfully
- bool writeXmlMainConfig(const MainConfiguration& mainCfg, const std::vector<FolderPair>& directoryPairs);
-
- TiXmlDocument doc;
- const wxString& m_fileName;
-};
-
-
-xmlAccess::XmlType xmlAccess::getXmlType(const wxString& filename)
-{
- if (!wxFileExists(filename))
- return XML_OTHER;
-
- //workaround to get a FILE* from a unicode filename
- wxFFile configFile(filename, wxT("rb"));
- if (!configFile.IsOpened())
- return XML_OTHER;
-
- FILE* inputFile = configFile.fp();
-
- TiXmlDocument doc;
- if (!doc.LoadFile(inputFile)) //fails if inputFile is no proper XML
- return XML_OTHER;
-
- TiXmlElement* root = doc.RootElement();
-
- if (!root || (root->ValueStr() != std::string("FreeFileSync"))) //check for FFS configuration xml
- return XML_OTHER;
+//write gui settings
+bool writeXmlGuiConfig(const xmlAccess::XmlGuiConfig& outputCfg, TiXmlDocument& doc);
+//write batch settings
+bool writeXmlBatchConfig(const xmlAccess::XmlBatchConfig& outputCfg, TiXmlDocument& doc);
+//write global settings
+bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& outputCfg, TiXmlDocument& doc);
+//write basic FreefileSync settings (used by commandline and GUI), return true if everything was written successfully
+bool writeXmlMainConfig(const MainConfiguration& mainCfg, const std::vector<FolderPair>& directoryPairs, TiXmlDocument& doc);
- const char* cfgType = root->Attribute("XmlType");
- if (!cfgType)
- return XML_OTHER;
-
- if (std::string(cfgType) == "BATCH")
- return XML_BATCH_CONFIG;
- else if (std::string(cfgType) == "GUI")
- return XML_GUI_CONFIG;
- else if (std::string(cfgType) == "GLOBAL")
- return XML_GLOBAL_SETTINGS;
- else
- return XML_OTHER;
-}
-
-xmlAccess::XmlGuiConfig xmlAccess::readGuiConfig(const wxString& filename)
+void xmlAccess::readGuiConfig(const wxString& filename, xmlAccess::XmlGuiConfig& config)
{
//load XML
if (!wxFileExists(filename))
- throw FileError(Zstring(_("File does not exist:")) + wxT(" \"") + filename.c_str() + wxT("\""));
-
- XmlConfigInput inputFile(filename, XML_GUI_CONFIG);
-
- XmlGuiConfig outputCfg;
+ throw XmlError(wxString(_("File does not exist:")) + wxT(" \"") + filename + wxT("\""));
- if (!inputFile.loadedSuccessfully())
- throw FileError(Zstring(_("Error reading file:")) + wxT(" \"") + filename.c_str() + wxT("\""));
+ TiXmlDocument doc;
+ if (!loadXmlDocument(filename, XML_GUI_CONFIG, doc))
+ throw XmlError(wxString(_("Error reading file:")) + wxT(" \"") + filename + wxT("\""));
- if (!inputFile.readXmlGuiConfig(outputCfg)) //read GUI layout configuration
- throw FileError(Zstring(_("Error parsing configuration file:")) + wxT(" \"") + filename.c_str() + wxT("\""));
+ FfsXmlParser parser(doc.RootElement());
+ parser.readXmlGuiConfig(config); //read GUI layout configuration
- return outputCfg;
+ if (parser.errorsOccured())
+ throw XmlError(wxString(_("Error parsing configuration file:")) + wxT(" \"") + filename + wxT("\"\n\n") +
+ parser.getErrorMessageFormatted(), XmlError::WARNING);
}
-xmlAccess::XmlBatchConfig xmlAccess::readBatchConfig(const wxString& filename)
+void xmlAccess::readBatchConfig(const wxString& filename, xmlAccess::XmlBatchConfig& config)
{
//load XML
if (!wxFileExists(filename))
- throw FileError(Zstring(_("File does not exist:")) + wxT(" \"") + filename.c_str() + wxT("\""));
-
- XmlConfigInput inputFile(filename, XML_BATCH_CONFIG);
-
- XmlBatchConfig outputCfg;
+ throw XmlError(wxString(_("File does not exist:")) + wxT(" \"") + filename + wxT("\""));
- if (!inputFile.loadedSuccessfully())
- throw FileError(Zstring(_("Error reading file:")) + wxT(" \"") + filename.c_str() + wxT("\""));
+ TiXmlDocument doc;
+ if (!loadXmlDocument(filename, XML_BATCH_CONFIG, doc))
+ throw XmlError(wxString(_("Error reading file:")) + wxT(" \"") + filename + wxT("\""));
- if (!inputFile.readXmlBatchConfig(outputCfg))
- throw FileError(Zstring(_("Error parsing configuration file:")) + wxT(" \"") + filename.c_str() + wxT("\""));
+ FfsXmlParser parser(doc.RootElement());
+ parser.readXmlBatchConfig(config); //read GUI layout configuration
- return outputCfg;
+ if (parser.errorsOccured())
+ throw XmlError(wxString(_("Error parsing configuration file:")) + wxT(" \"") + filename + wxT("\"\n\n") +
+ parser.getErrorMessageFormatted(), XmlError::WARNING);
}
-xmlAccess::XmlGlobalSettings xmlAccess::readGlobalSettings()
+void xmlAccess::readGlobalSettings(xmlAccess::XmlGlobalSettings& config)
{
//load XML
if (!wxFileExists(FreeFileSync::getGlobalConfigFile()))
- throw FileError(Zstring(_("File does not exist:")) + wxT(" \"") + FreeFileSync::getGlobalConfigFile().c_str() + wxT("\""));
-
- XmlConfigInput inputFile(FreeFileSync::getGlobalConfigFile(), XML_GLOBAL_SETTINGS);
-
- XmlGlobalSettings outputCfg;
+ throw XmlError(wxString(_("File does not exist:")) + wxT(" \"") + FreeFileSync::getGlobalConfigFile() + wxT("\""));
- if (!inputFile.loadedSuccessfully())
- throw FileError(Zstring(_("Error reading file:")) + wxT(" \"") + FreeFileSync::getGlobalConfigFile().c_str() + wxT("\""));
+ TiXmlDocument doc;
+ if (!loadXmlDocument(FreeFileSync::getGlobalConfigFile(), XML_GLOBAL_SETTINGS, doc))
+ throw XmlError(wxString(_("Error reading file:")) + wxT(" \"") + FreeFileSync::getGlobalConfigFile() + wxT("\""));
- if (!inputFile.readXmlGlobalSettings(outputCfg))
- throw FileError(Zstring(_("Error parsing configuration file:")) + wxT(" \"") + FreeFileSync::getGlobalConfigFile().c_str() + wxT("\""));
+ FfsXmlParser parser(doc.RootElement());
+ parser.readXmlGlobalSettings(config); //read GUI layout configuration
- return outputCfg;
+ if (parser.errorsOccured())
+ throw XmlError(wxString(_("Error parsing configuration file:")) + wxT(" \"") + FreeFileSync::getGlobalConfigFile() + wxT("\"\n\n") +
+ parser.getErrorMessageFormatted(), XmlError::WARNING);
}
-void xmlAccess::writeGuiConfig(const wxString& filename, const XmlGuiConfig& outputCfg)
+void xmlAccess::writeGuiConfig(const XmlGuiConfig& outputCfg, const wxString& filename)
{
- XmlConfigOutput outputFile(filename, XML_GUI_CONFIG);
+ TiXmlDocument doc;
+ getDefaultXmlDocument(XML_GUI_CONFIG, doc);
//populate and write XML tree
- if ( !outputFile.writeXmlGuiConfig(outputCfg) || //add GUI layout configuration settings
- !outputFile.writeToFile()) //save XML
- throw FileError(Zstring(_("Error writing file:")) + wxT(" \"") + filename.c_str() + wxT("\""));
+ if ( !writeXmlGuiConfig(outputCfg, doc) || //add GUI layout configuration settings
+ !saveXmlDocument(filename, doc)) //save XML
+ throw XmlError(wxString(_("Error writing file:")) + wxT(" \"") + filename + wxT("\""));
return;
}
-void xmlAccess::writeBatchConfig(const wxString& filename, const XmlBatchConfig& outputCfg)
+void xmlAccess::writeBatchConfig(const XmlBatchConfig& outputCfg, const wxString& filename)
{
- XmlConfigOutput outputFile(filename, XML_BATCH_CONFIG);
+ TiXmlDocument doc;
+ getDefaultXmlDocument(XML_BATCH_CONFIG, doc);
//populate and write XML tree
- if ( !outputFile.writeXmlBatchConfig(outputCfg) || //add batch configuration settings
- !outputFile.writeToFile()) //save XML
- throw FileError(Zstring(_("Error writing file:")) + wxT(" \"") + filename.c_str() + wxT("\""));
+ if ( !writeXmlBatchConfig(outputCfg, doc) || //add batch configuration settings
+ !saveXmlDocument(filename, doc)) //save XML
+ throw XmlError(wxString(_("Error writing file:")) + wxT(" \"") + filename + wxT("\""));
return;
}
void xmlAccess::writeGlobalSettings(const XmlGlobalSettings& outputCfg)
{
- XmlConfigOutput outputFile(FreeFileSync::getGlobalConfigFile(), XML_GLOBAL_SETTINGS);
+ TiXmlDocument doc;
+ getDefaultXmlDocument(XML_GLOBAL_SETTINGS, doc);
//populate and write XML tree
- if ( !outputFile.writeXmlGlobalSettings(outputCfg) || //add GUI layout configuration settings
- !outputFile.writeToFile()) //save XML
- throw FileError(Zstring(_("Error writing file:")) + wxT(" \"") + FreeFileSync::getGlobalConfigFile().c_str() + wxT("\""));
+ if ( !writeXmlGlobalSettings(outputCfg, doc) || //add GUI layout configuration settings
+ !saveXmlDocument(FreeFileSync::getGlobalConfigFile(), doc)) //save XML
+ throw XmlError(wxString(_("Error writing file:")) + wxT(" \"") + FreeFileSync::getGlobalConfigFile() + wxT("\""));
return;
}
-XmlConfigInput::XmlConfigInput(const wxString& fileName, const xmlAccess::XmlType type) :
- loadSuccess(false)
-{
- if (!wxFileExists(fileName)) //avoid wxWidgets error message when wxFFile receives not existing file
- return;
-
- //workaround to get a FILE* from a unicode filename
- wxFFile dummyFile(fileName, wxT("rb"));
- if (dummyFile.IsOpened())
- {
- FILE* inputFile = dummyFile.fp();
-
- TiXmlBase::SetCondenseWhiteSpace(false); //do not condense whitespace characters
-
- if (doc.LoadFile(inputFile)) //load XML; fails if inputFile is no proper XML
- {
- TiXmlElement* root = doc.RootElement();
-
- if (root && (root->ValueStr() == std::string("FreeFileSync"))) //check for FFS configuration xml
- {
- const char* cfgType = root->Attribute("XmlType");
- if (cfgType)
- {
- if (type == xmlAccess::XML_GUI_CONFIG)
- loadSuccess = std::string(cfgType) == "GUI";
- else if (type == xmlAccess::XML_BATCH_CONFIG)
- loadSuccess = std::string(cfgType) == "BATCH";
- else if (type == xmlAccess::XML_GLOBAL_SETTINGS)
- loadSuccess = std::string(cfgType) == "GLOBAL";
- }
- }
- }
- }
-}
-
-
-bool readXmlElementValue(std::string& output, const TiXmlElement* parent, const std::string& name)
+bool readXmlElement(const std::string& name, const TiXmlElement* parent, CompareVariant& output)
{
- if (parent)
- {
- const TiXmlElement* child = parent->FirstChildElement(name);
- if (child)
- {
- const char* text = child->GetText();
- if (text) //may be NULL!!
- output = text;
- else
- output.clear();
- return true;
- }
- }
-
- return false;
-}
-
-
-bool readXmlElementValue(int& output, const TiXmlElement* parent, const std::string& name)
-{
- std::string temp;
- if (readXmlElementValue(temp, parent, name))
- {
- output = globalFunctions::stringToInt(temp);
- return true;
- }
- else
- return false;
-}
-
-
-bool readXmlElementValue(long& output, const TiXmlElement* parent, const std::string& name)
-{
- std::string temp;
- if (readXmlElementValue(temp, parent, name))
+ std::string dummy;
+ if (xmlAccess::readXmlElement(name, parent, dummy))
{
- output = globalFunctions::stringToLong(temp);
- return true;
- }
- else
- return false;
-}
+ if (dummy == "ByTimeAndSize")
+ output = FreeFileSync::CMP_BY_TIME_SIZE;
+ else if (dummy == "ByContent")
+ output = FreeFileSync::CMP_BY_CONTENT;
+ else
+ return false;
-
-bool readXmlElementValue(CompareVariant& output, const TiXmlElement* parent, const std::string& name)
-{
- int dummy = 0;
- if (readXmlElementValue(dummy, parent, name))
- {
- output = CompareVariant(dummy);
return true;
}
else
@@ -303,17 +156,17 @@ bool readXmlElementValue(CompareVariant& output, const TiXmlElement* parent, con
}
-bool readXmlElementValue(SyncDirection& output, const TiXmlElement* parent, const std::string& name)
+bool readXmlElement(const std::string& name, const TiXmlElement* parent, SyncDirectionCfg& output)
{
std::string dummy;
- if (readXmlElementValue(dummy, parent, name))
+ if (xmlAccess::readXmlElement(name, parent, dummy))
{
if (dummy == "left")
- output = SYNC_DIR_LEFT;
+ output = SYNC_DIR_CFG_LEFT;
else if (dummy == "right")
- output = SYNC_DIR_RIGHT;
+ output = SYNC_DIR_CFG_RIGHT;
else //treat all other input as "none"
- output = SYNC_DIR_NONE;
+ output = SYNC_DIR_CFG_NONE;
return true;
}
@@ -322,23 +175,10 @@ bool readXmlElementValue(SyncDirection& output, const TiXmlElement* parent, cons
}
-bool readXmlElementValue(bool& output, const TiXmlElement* parent, const std::string& name)
-{
- std::string dummy;
- if (readXmlElementValue(dummy, parent, name))
- {
- output = (dummy == "true");
- return true;
- }
- else
- return false;
-}
-
-
-bool readXmlElementValue(xmlAccess::OnError& output, const TiXmlElement* parent, const std::string& name)
+bool readXmlElement(const std::string& name, const TiXmlElement* parent, xmlAccess::OnError& output)
{
std::string dummy;
- if (readXmlElementValue(dummy, parent, name))
+ if (xmlAccess::readXmlElement(name, parent, dummy))
{
if (dummy == "Ignore")
output = xmlAccess::ON_ERROR_IGNORE;
@@ -354,430 +194,319 @@ bool readXmlElementValue(xmlAccess::OnError& output, const TiXmlElement* parent,
}
-void readXmlElementTable(std::vector<wxString>& output, const TiXmlElement* parent, const std::string& name)
+bool readXmlElement(const std::string& name, const TiXmlElement* parent , FreeFileSync::DeletionPolicy& output)
{
- output.clear();
-
- if (parent)
+ std::string dummy;
+ if (xmlAccess::readXmlElement(name, parent, dummy))
{
- //load elements
- const TiXmlElement* element = parent->FirstChildElement(name);
- while (element)
- {
- const char* text = element->GetText();
- if (text) //may be NULL!!
- output.push_back(wxString::FromUTF8(text));
- else
- break;
- element = element->NextSiblingElement();
- }
+ if (dummy == "DeletePermanently")
+ output = FreeFileSync::DELETE_PERMANENTLY;
+ else if (dummy == "MoveToRecycleBin")
+ output = FreeFileSync::MOVE_TO_RECYCLE_BIN;
+ else if (dummy == "MoveToCustomDirectory")
+ output = FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY;
+ else
+ return false;
+
+ return true;
}
-}
-//################################################################################################################
+ return false;
+}
-bool XmlConfigInput::readXmlMainConfig(MainConfiguration& mainCfg, std::vector<FolderPair>& directoryPairs)
+bool readXmlAttribute(const std::string& name, const TiXmlElement* node, xmlAccess::ColumnTypes& output)
{
- TiXmlElement* root = doc.RootElement();
- if (!root) return false;
+ int dummy;
+ if (xmlAccess::readXmlAttribute(name, node, dummy))
+ {
+ output = static_cast<xmlAccess::ColumnTypes>(dummy);
+ return true;
+ }
+ else
+ return false;
+}
- TiXmlHandle hRoot(root);
- TiXmlElement* cmpSettings = hRoot.FirstChild("MainConfig").FirstChild("Comparison").ToElement();
- TiXmlElement* syncConfig = hRoot.FirstChild("MainConfig").FirstChild("Synchronization").FirstChild("Directions").ToElement();
- TiXmlElement* miscSettings = hRoot.FirstChild("MainConfig").FirstChild("Miscellaneous").ToElement();
- TiXmlElement* filter = TiXmlHandle(miscSettings).FirstChild("Filter").ToElement();
+//################################################################################################################
+void FfsXmlParser::readXmlMainConfig(MainConfiguration& mainCfg, std::vector<FolderPair>& directoryPairs)
+{
+ TiXmlHandleConst hRoot(root); //custom const handle: TiXml API seems broken in this regard
- if (!cmpSettings || !syncConfig || !miscSettings || !filter)
- return false;
+ const TiXmlElement* cmpSettings = hRoot.FirstChild("MainConfig").FirstChild("Comparison").ToElement();
+ const TiXmlElement* syncConfig = hRoot.FirstChild("MainConfig").FirstChild("Synchronization").FirstChild("Directions").ToElement();
+ const TiXmlElement* miscSettings = hRoot.FirstChild("MainConfig").FirstChild("Miscellaneous").ToElement();
+ const TiXmlElement* filter = TiXmlHandleConst(miscSettings).FirstChild("Filter").ToElement();
- std::string tempString;
//###########################################################
//read compare variant
- if (!readXmlElementValue(mainCfg.compareVar, cmpSettings, "Variant")) return false;
+ readXmlElementLogging("Variant", cmpSettings, mainCfg.compareVar);
//read folder pair(s)
- TiXmlElement* folderPair = TiXmlHandle(cmpSettings).FirstChild("Folders").FirstChild("Pair").ToElement();
+ const TiXmlElement* folderPair = TiXmlHandleConst(cmpSettings).FirstChild("Folders").FirstChild("Pair").ToElement();
//read folder pairs
directoryPairs.clear();
while (folderPair)
{
- FolderPair newPair;
-
- if (!readXmlElementValue(tempString, folderPair, "Left")) return false;
- newPair.leftDirectory = wxString::FromUTF8(tempString.c_str()).c_str();
-
- if (!readXmlElementValue(tempString, folderPair, "Right")) return false;
- newPair.rightDirectory = wxString::FromUTF8(tempString.c_str()).c_str();
-
- directoryPairs.push_back(newPair);
+ wxString temp;
+ wxString temp2;
+ readXmlElementLogging("Left", folderPair, temp);
+ readXmlElementLogging("Right", folderPair, temp2);
+ directoryPairs.push_back(FolderPair(temp.c_str(), temp2.c_str()));
folderPair = folderPair->NextSiblingElement();
}
//###########################################################
//read sync configuration
- if (!readXmlElementValue(mainCfg.syncConfiguration.exLeftSideOnly, syncConfig, "LeftOnly")) return false;
- if (!readXmlElementValue(mainCfg.syncConfiguration.exRightSideOnly, syncConfig, "RightOnly")) return false;
- if (!readXmlElementValue(mainCfg.syncConfiguration.leftNewer, syncConfig, "LeftNewer")) return false;
- if (!readXmlElementValue(mainCfg.syncConfiguration.rightNewer, syncConfig, "RightNewer")) return false;
- if (!readXmlElementValue(mainCfg.syncConfiguration.different, syncConfig, "Different")) return false;
+ readXmlElementLogging("LeftOnly", syncConfig, mainCfg.syncConfiguration.exLeftSideOnly);
+ readXmlElementLogging("RightOnly", syncConfig, mainCfg.syncConfiguration.exRightSideOnly);
+ readXmlElementLogging("LeftNewer", syncConfig, mainCfg.syncConfiguration.leftNewer);
+ readXmlElementLogging("RightNewer", syncConfig, mainCfg.syncConfiguration.rightNewer);
+ readXmlElementLogging("Different", syncConfig, mainCfg.syncConfiguration.different);
+
//###########################################################
//read filter settings
- if (!readXmlElementValue(mainCfg.filterIsActive, filter, "Active")) return false;
-
- if (!readXmlElementValue(tempString, filter, "Include")) return false;
- mainCfg.includeFilter = wxString::FromUTF8(tempString.c_str());
-
- if (!readXmlElementValue(tempString, filter, "Exclude")) return false;
- mainCfg.excludeFilter = wxString::FromUTF8(tempString.c_str());
+ readXmlElementLogging("Active", filter, mainCfg.filterIsActive);
+ readXmlElementLogging("Include", filter, mainCfg.includeFilter);
+ readXmlElementLogging("Exclude", filter, mainCfg.excludeFilter);
//###########################################################
//other
- readXmlElementValue(mainCfg.useRecycleBin, miscSettings, "UseRecycler");
-
- return true;
+ readXmlElementLogging("DeletionPolicy", miscSettings, mainCfg.handleDeletion);
+ readXmlElementLogging("CustomDeletionFolder", miscSettings, mainCfg.customDeletionDirectory);
}
-bool XmlConfigInput::readXmlGuiConfig(xmlAccess::XmlGuiConfig& outputCfg)
+void FfsXmlParser::readXmlGuiConfig(xmlAccess::XmlGuiConfig& outputCfg)
{
//read main config
- if (!readXmlMainConfig(outputCfg.mainCfg, outputCfg.directoryPairs))
- return false;
+ readXmlMainConfig(outputCfg.mainCfg, outputCfg.directoryPairs);
//read GUI specific config data
- TiXmlElement* root = doc.RootElement();
- if (!root) return false;
+ const TiXmlElement* guiConfig = TiXmlHandleConst(root).FirstChild("GuiConfig").ToElement();
- TiXmlHandle hRoot(root);
+ readXmlElementLogging("HideFiltered", guiConfig, outputCfg.hideFilteredElements);
- TiXmlElement* guiConfig = hRoot.FirstChild("GuiConfig").ToElement();
- if (guiConfig)
- {
- readXmlElementValue(outputCfg.hideFilteredElements, guiConfig, "HideFiltered");
- readXmlElementValue(outputCfg.ignoreErrors, guiConfig, "IgnoreErrors");
- readXmlElementValue(outputCfg.syncPreviewEnabled, guiConfig, "SyncPreviewActive");
- }
+ xmlAccess::OnError errorHand;
+ readXmlElementLogging("HandleError", guiConfig, errorHand);
+ outputCfg.ignoreErrors = errorHand == xmlAccess::ON_ERROR_IGNORE;
- return true;
+ readXmlElementLogging("SyncPreviewActive", guiConfig, outputCfg.syncPreviewEnabled);
}
-bool XmlConfigInput::readXmlBatchConfig(xmlAccess::XmlBatchConfig& outputCfg)
+void FfsXmlParser::readXmlBatchConfig(xmlAccess::XmlBatchConfig& outputCfg)
{
//read main config
- if (!readXmlMainConfig(outputCfg.mainCfg, outputCfg.directoryPairs))
- return false;
+ readXmlMainConfig(outputCfg.mainCfg, outputCfg.directoryPairs);
//read batch specific config
- TiXmlElement* root = doc.RootElement();
- if (!root) return false;
-
- TiXmlHandle hRoot(root);
+ const TiXmlElement* batchConfig = TiXmlHandleConst(root).FirstChild("BatchConfig").ToElement();
- //read batch settings
- TiXmlElement* batchConfig = hRoot.FirstChild("BatchConfig").ToElement();
- if (batchConfig)
- {
- readXmlElementValue(outputCfg.silent, batchConfig, "Silent");
-
- std::string tempString;
- if (readXmlElementValue(tempString, batchConfig, "LogfileDirectory"))
- outputCfg.logFileDirectory = wxString::FromUTF8(tempString.c_str());
-
- readXmlElementValue(outputCfg.handleError, batchConfig, "HandleError");
- }
-
- return true;
+ readXmlElementLogging("Silent", batchConfig, outputCfg.silent);
+ readXmlElementLogging("LogfileDirectory", batchConfig, outputCfg.logFileDirectory);
+ readXmlElementLogging("HandleError", batchConfig, outputCfg.handleError);
}
-bool XmlConfigInput::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg)
+void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg)
{
- TiXmlElement* root = doc.RootElement();
- if (!root) return false;
-
- TiXmlHandle hRoot(root);
-
//read global settings
- TiXmlElement* global = hRoot.FirstChild("Shared").ToElement();
- if (global)
- {
- //try to read program language setting
- readXmlElementValue(outputCfg.programLanguage, global, "Language");
-
- //max. allowed file time deviation
- int dummy = 0;
- if (readXmlElementValue(dummy, global, "FileTimeTolerance"))
- outputCfg.fileTimeTolerance = dummy;
-
- //ignore +/- 1 hour due to DST change
- readXmlElementValue(outputCfg.ignoreOneHourDiff, global, "IgnoreOneHourDifference");
+ const TiXmlElement* global = TiXmlHandleConst(root).FirstChild("Shared").ToElement();
- //traverse into symbolic links (to folders)
- readXmlElementValue(outputCfg.traverseDirectorySymlinks, global, "TraverseDirectorySymlinks");
+ //try to read program language setting
+ readXmlElementLogging("Language", global, outputCfg.programLanguage);
- //copy symbolic links to files
- readXmlElementValue(outputCfg.copyFileSymlinks, global, "CopyFileSymlinks");
-
- //last update check
- readXmlElementValue(outputCfg.lastUpdateCheck, global, "LastCheckForUpdates");
- }
+ //max. allowed file time deviation
+ readXmlElementLogging("FileTimeTolerance", global, outputCfg.fileTimeTolerance);
- TiXmlElement* warnings = hRoot.FirstChild("Shared").FirstChild("Warnings").ToElement();
- if (warnings)
- {
- //folder dependency check
- readXmlElementValue(outputCfg.warnings.warningDependentFolders, warnings, "CheckForDependentFolders");
+ //ignore +/- 1 hour due to DST change
+ readXmlElementLogging("IgnoreOneHourDifference", global, outputCfg.ignoreOneHourDiff);
- //significant difference check
- readXmlElementValue(outputCfg.warnings.warningSignificantDifference, warnings, "CheckForSignificantDifference");
+ //traverse into symbolic links (to folders)
+ readXmlElementLogging("TraverseDirectorySymlinks", global, outputCfg.traverseDirectorySymlinks);
- //check free disk space
- readXmlElementValue(outputCfg.warnings.warningNotEnoughDiskSpace, warnings, "CheckForFreeDiskSpace");
+ //copy symbolic links to files
+ readXmlElementLogging("CopyFileSymlinks", global, outputCfg.copyFileSymlinks);
- //check for unresolved conflicts
- readXmlElementValue(outputCfg.warnings.warningUnresolvedConflicts, warnings, "CheckForUnresolvedConflicts");
+ //last update check
+ readXmlElementLogging("LastCheckForUpdates", global, outputCfg.lastUpdateCheck);
- //check for very old dates or dates in the future
- readXmlElementValue(outputCfg.warnings.warningInvalidDate, warnings, "CheckForInvalidFileDate");
- //check for changed files with same modification date
- readXmlElementValue(outputCfg.warnings.warningSameDateDiffSize, warnings, "SameDateDifferentFileSize");
+ const TiXmlElement* warnings = TiXmlHandleConst(root).FirstChild("Shared").FirstChild("Warnings").ToElement();
- //check for files that have a difference in file modification date below 1 hour when DST check is active
- readXmlElementValue(outputCfg.warnings.warningDSTChangeWithinHour, warnings, "FileChangeWithinHour");
- }
+ //folder dependency check
+ readXmlElementLogging("CheckForDependentFolders", warnings, outputCfg.warnings.warningDependentFolders);
+ //significant difference check
+ readXmlElementLogging("CheckForSignificantDifference", warnings, outputCfg.warnings.warningSignificantDifference);
+ //check free disk space
+ readXmlElementLogging("CheckForFreeDiskSpace", warnings, outputCfg.warnings.warningNotEnoughDiskSpace);
+ //check for unresolved conflicts
+ readXmlElementLogging("CheckForUnresolvedConflicts", warnings, outputCfg.warnings.warningUnresolvedConflicts);
//gui specific global settings (optional)
- TiXmlElement* mainWindow = hRoot.FirstChild("Gui").FirstChild("Windows").FirstChild("Main").ToElement();
- if (mainWindow)
- {
- //read application window size and position
- readXmlElementValue(outputCfg.gui.widthNotMaximized, mainWindow, "Width");
- readXmlElementValue(outputCfg.gui.heightNotMaximized, mainWindow, "Height");
- readXmlElementValue(outputCfg.gui.posXNotMaximized, mainWindow, "PosX");
- readXmlElementValue(outputCfg.gui.posYNotMaximized, mainWindow, "PosY");
- readXmlElementValue(outputCfg.gui.isMaximized, mainWindow, "Maximized");
-
- readXmlElementValue(outputCfg.gui.deleteOnBothSides, mainWindow, "ManualDeletionOnBothSides");
- readXmlElementValue(outputCfg.gui.useRecyclerForManualDeletion, mainWindow, "ManualDeletionUseRecycler");
- readXmlElementValue(outputCfg.gui.showFileIconsLeft, mainWindow, "ShowFileIconsLeft");
- readXmlElementValue(outputCfg.gui.showFileIconsRight, mainWindow, "ShowFileIconsRight");
- readXmlElementValue(outputCfg.gui.popupOnConfigChange, mainWindow, "PopupOnConfigChange");
- readXmlElementValue(outputCfg.gui.showSummaryBeforeSync, mainWindow, "SummaryBeforeSync");
+ const TiXmlElement* mainWindow = TiXmlHandleConst(root).FirstChild("Gui").FirstChild("Windows").FirstChild("Main").ToElement();
+
+ //read application window size and position
+ readXmlElementLogging("Width", mainWindow, outputCfg.gui.widthNotMaximized);
+ readXmlElementLogging("Height", mainWindow, outputCfg.gui.heightNotMaximized);
+ readXmlElementLogging("PosX", mainWindow, outputCfg.gui.posXNotMaximized);
+ readXmlElementLogging("PosY", mainWindow, outputCfg.gui.posYNotMaximized);
+ readXmlElementLogging("Maximized", mainWindow, outputCfg.gui.isMaximized);
+
+ readXmlElementLogging("ManualDeletionOnBothSides", mainWindow, outputCfg.gui.deleteOnBothSides);
+ readXmlElementLogging("ManualDeletionUseRecycler", mainWindow, outputCfg.gui.useRecyclerForManualDeletion);
+ readXmlElementLogging("ShowFileIconsLeft", mainWindow, outputCfg.gui.showFileIconsLeft);
+ readXmlElementLogging("ShowFileIconsRight", mainWindow, outputCfg.gui.showFileIconsRight);
+ readXmlElementLogging("PopupOnConfigChange", mainWindow, outputCfg.gui.popupOnConfigChange);
+ readXmlElementLogging("SummaryBeforeSync", mainWindow, outputCfg.gui.showSummaryBeforeSync);
//###########################################################
- //read column attributes
- TiXmlElement* leftColumn = TiXmlHandle(mainWindow).FirstChild("LeftColumns").FirstChild("Column").ToElement();
- unsigned int colPos = 0;
- while (leftColumn)
- {
- const char* type = leftColumn->Attribute("Type");
- const char* visible = leftColumn->Attribute("Visible");
- const char* width = leftColumn->Attribute("Width");
-
- if (type && visible && width) //may be NULL!!
- {
- xmlAccess::ColumnAttrib newAttrib;
- newAttrib.type = xmlAccess::ColumnTypes(globalFunctions::stringToInt(type));
- newAttrib.visible = std::string(visible) != std::string("false");
- newAttrib.position = colPos;
- newAttrib.width = globalFunctions::stringToInt(width);
- outputCfg.gui.columnAttribLeft.push_back(newAttrib);
- }
- else
- break;
-
- leftColumn = leftColumn->NextSiblingElement();
- ++colPos;
- }
-
- TiXmlElement* rightColumn = TiXmlHandle(mainWindow).FirstChild("RightColumns").FirstChild("Column").ToElement();
- colPos = 0;
- while (rightColumn)
- {
- const char* type = rightColumn->Attribute("Type");
- const char* visible = rightColumn->Attribute("Visible");
- const char* width = rightColumn->Attribute("Width");
-
- if (type && visible && width) //may be NULL!!
- {
- xmlAccess::ColumnAttrib newAttrib;
- newAttrib.type = xmlAccess::ColumnTypes(globalFunctions::stringToInt(type));
- newAttrib.visible = std::string(visible) != std::string("false");
- newAttrib.position = colPos;
- newAttrib.width = globalFunctions::stringToInt(width);
- outputCfg.gui.columnAttribRight.push_back(newAttrib);
- }
- else
- break;
-
- rightColumn = rightColumn->NextSiblingElement();
- ++colPos;
- }
-
- //load folder history elements
- const TiXmlElement* historyLeft = TiXmlHandle(mainWindow).FirstChild("FolderHistoryLeft").ToElement();
- if (historyLeft)
- {
- //load max. history size
- const char* histSizeMax = historyLeft->Attribute("MaximumSize");
- if (histSizeMax) //may be NULL!
- outputCfg.gui.folderHistLeftMax = globalFunctions::stringToInt(histSizeMax);
-
- //load config history elements
- readXmlElementTable(outputCfg.gui.folderHistoryLeft, historyLeft, "Folder");
- }
-
- const TiXmlElement* historyRight = TiXmlHandle(mainWindow).FirstChild("FolderHistoryRight").ToElement();
- if (historyRight)
- {
- //load max. history size
- const char* histSizeMax = historyRight->Attribute("MaximumSize");
- if (histSizeMax) //may be NULL!
- outputCfg.gui.folderHistRightMax = globalFunctions::stringToInt(histSizeMax);
-
- //load config history elements
- readXmlElementTable(outputCfg.gui.folderHistoryRight, historyRight, "Folder");
- }
-
- readXmlElementValue(outputCfg.gui.selectedTabBottomLeft, mainWindow, "SelectedTabBottomLeft");
- }
+ //read column attributes
+ readXmlAttributeLogging("AutoAdjust", TiXmlHandleConst(mainWindow).FirstChild("LeftColumns").ToElement(), outputCfg.gui.autoAdjustColumnsLeft);
- TiXmlElement* gui = hRoot.FirstChild("Gui").ToElement();
- if (gui)
+ const TiXmlElement* leftColumn = TiXmlHandleConst(mainWindow).FirstChild("LeftColumns").FirstChild("Column").ToElement();
+ unsigned int colPos = 0;
+ while (leftColumn)
{
- //commandline for file manager integration
- std::string tempString;
- if (readXmlElementValue(tempString, gui, "FileManager"))
- outputCfg.gui.commandLineFileManager = wxString::FromUTF8(tempString.c_str());
+ xmlAccess::ColumnAttrib newAttrib;
+ newAttrib.position = colPos++;
+ readXmlAttributeLogging("Type", leftColumn, newAttrib.type);
+ readXmlAttributeLogging("Visible", leftColumn, newAttrib.visible);
+ readXmlAttributeLogging("Width", leftColumn, newAttrib.width);
+ outputCfg.gui.columnAttribLeft.push_back(newAttrib);
+
+ leftColumn = leftColumn->NextSiblingElement();
}
- //load config file history
- TiXmlElement* cfgHistory = hRoot.FirstChild("Gui").FirstChild("ConfigHistory").ToElement();
- if (cfgHistory)
- {
- //load max. history size
- const char* histSizeMax = cfgHistory->Attribute("MaximumSize");
- if (histSizeMax) //may be NULL!
- outputCfg.gui.cfgHistoryMax = globalFunctions::stringToInt(histSizeMax);
+ readXmlAttributeLogging("AutoAdjust", TiXmlHandleConst(mainWindow).FirstChild("RightColumns").ToElement(), outputCfg.gui.autoAdjustColumnsRight);
- //load config history elements
- readXmlElementTable(outputCfg.gui.cfgFileHistory, cfgHistory, "File");
+ const TiXmlElement* rightColumn = TiXmlHandleConst(mainWindow).FirstChild("RightColumns").FirstChild("Column").ToElement();
+ colPos = 0;
+ while (rightColumn)
+ {
+ xmlAccess::ColumnAttrib newAttrib;
+ newAttrib.position = colPos++;
+ readXmlAttributeLogging("Type", rightColumn, newAttrib.type);
+ readXmlAttributeLogging("Visible", rightColumn, newAttrib.visible);
+ readXmlAttributeLogging("Width", rightColumn, newAttrib.width);
+ outputCfg.gui.columnAttribRight.push_back(newAttrib);
+
+ rightColumn = rightColumn->NextSiblingElement();
}
+ //load folder history elements
+ const TiXmlElement* historyLeft = TiXmlHandleConst(mainWindow).FirstChild("FolderHistoryLeft").ToElement();
+ //load max. history size
+ readXmlAttributeLogging("MaximumSize", historyLeft, outputCfg.gui.folderHistLeftMax);
+ //load config history elements
+ readXmlElementLogging("Folder", historyLeft, outputCfg.gui.folderHistoryLeft);
-//batch specific global settings
- TiXmlElement* batch = hRoot.FirstChild("Batch").ToElement();
- if (!batch) return false;
- return true;
-}
+ const TiXmlElement* historyRight = TiXmlHandleConst(mainWindow).FirstChild("FolderHistoryRight").ToElement();
+ //load max. history size
+ readXmlAttributeLogging("MaximumSize", historyRight, outputCfg.gui.folderHistRightMax);
+ //load config history elements
+ readXmlElementLogging("Folder", historyRight, outputCfg.gui.folderHistoryRight);
-XmlConfigOutput::XmlConfigOutput(const wxString& fileName, const xmlAccess::XmlType type) :
- m_fileName(fileName)
-{
- TiXmlBase::SetCondenseWhiteSpace(false); //do not condense whitespace characters
-
- TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", ""); //delete won't be necessary later; ownership passed to TiXmlDocument!
- doc.LinkEndChild(decl);
-
- TiXmlElement* root = new TiXmlElement("FreeFileSync");
- if (type == xmlAccess::XML_GUI_CONFIG)
- root->SetAttribute("XmlType", "GUI"); //xml configuration type
- else if (type == xmlAccess::XML_BATCH_CONFIG)
- root->SetAttribute("XmlType", "BATCH");
- else if (type == xmlAccess::XML_GLOBAL_SETTINGS)
- root->SetAttribute("XmlType", "GLOBAL");
- else
- assert(false);
- doc.LinkEndChild(root);
-}
+ readXmlElementLogging("SelectedTabBottomLeft", mainWindow, outputCfg.gui.selectedTabBottomLeft);
-bool XmlConfigOutput::writeToFile()
-{
- //workaround to get a FILE* from a unicode filename
- wxFFile dummyFile(m_fileName, wxT("w")); //no need for "binary" mode here
- if (!dummyFile.IsOpened())
- return false;
+ const TiXmlElement* gui = TiXmlHandleConst(root).FirstChild("Gui").ToElement();
- FILE* outputFile = dummyFile.fp();
+ //commandline for file manager integration
+ readXmlElementLogging("FileManager", gui, outputCfg.gui.commandLineFileManager);
- return doc.SaveFile(outputFile); //save XML
-}
+ //load config file history
+ const TiXmlElement* cfgHistory = TiXmlHandleConst(root).FirstChild("Gui").FirstChild("ConfigHistory").ToElement();
-void addXmlElement(TiXmlElement* parent, const std::string& name, const std::string& value)
-{
- if (parent)
- {
- TiXmlElement* subElement = new TiXmlElement(name);
- parent->LinkEndChild(subElement);
- subElement->LinkEndChild(new TiXmlText(value));
- }
-}
+ //load max. history size
+ readXmlAttributeLogging("MaximumSize", cfgHistory, outputCfg.gui.cfgHistoryMax);
+ //load config history elements
+ readXmlElementLogging("File", cfgHistory, outputCfg.gui.cfgFileHistory);
-void addXmlElement(TiXmlElement* parent, const std::string& name, const int value)
-{
- addXmlElement(parent, name, globalFunctions::numberToString(value));
+
+ //batch specific global settings
+ //const TiXmlElement* batch = TiXmlHandleConst(root).FirstChild("Batch").ToElement();
}
-void addXmlElement(TiXmlElement* parent, const std::string& name, const long value)
+void addXmlElement(const std::string& name, const CompareVariant variant, TiXmlElement* parent)
{
- addXmlElement(parent, name, globalFunctions::numberToString(value));
+ switch (variant)
+ {
+ case FreeFileSync::CMP_BY_TIME_SIZE:
+ xmlAccess::addXmlElement(name, std::string("ByTimeAndSize"), parent);
+ break;
+ case FreeFileSync::CMP_BY_CONTENT:
+ xmlAccess::addXmlElement(name, std::string("ByContent"), parent);
+ break;
+ }
}
-void addXmlElement(TiXmlElement* parent, const std::string& name, const SyncDirection value)
+void addXmlElement(TiXmlElement* parent, const std::string& name, const SyncDirectionCfg value)
{
- if (value == SYNC_DIR_LEFT)
- addXmlElement(parent, name, std::string("left"));
- else if (value == SYNC_DIR_RIGHT)
- addXmlElement(parent, name, std::string("right"));
- else if (value == SYNC_DIR_NONE)
- addXmlElement(parent, name, std::string("none"));
- else
- assert(false);
+ switch (value)
+ {
+ case SYNC_DIR_CFG_LEFT:
+ xmlAccess::addXmlElement(name, std::string("left"), parent);
+ break;
+ case SYNC_DIR_CFG_RIGHT:
+ xmlAccess::addXmlElement(name, std::string("right"), parent);
+ break;
+ case SYNC_DIR_CFG_NONE:
+ xmlAccess::addXmlElement(name, std::string("none"), parent);
+ break;
+ }
}
-void addXmlElement(TiXmlElement* parent, const std::string& name, const bool value)
+void addXmlElement(const std::string& name, const xmlAccess::OnError value, TiXmlElement* parent)
{
- if (value)
- addXmlElement(parent, name, std::string("true"));
- else
- addXmlElement(parent, name, std::string("false"));
+ switch (value)
+ {
+ case xmlAccess::ON_ERROR_IGNORE:
+ xmlAccess::addXmlElement(name, std::string("Ignore"), parent);
+ break;
+ case xmlAccess::ON_ERROR_EXIT:
+ xmlAccess::addXmlElement(name, std::string("Exit"), parent);
+ break;
+ case xmlAccess::ON_ERROR_POPUP:
+ xmlAccess::addXmlElement(name, std::string("Popup"), parent);
+ break;
+ }
}
-void addXmlElement(TiXmlElement* parent, const std::string& name, const xmlAccess::OnError value)
+void addXmlElement(const std::string& name, const FreeFileSync::DeletionPolicy value, TiXmlElement* parent)
{
- if (value == xmlAccess::ON_ERROR_IGNORE)
- addXmlElement(parent, name, std::string("Ignore"));
- else if (value == xmlAccess::ON_ERROR_EXIT)
- addXmlElement(parent, name, std::string("Exit"));
- else if (value == xmlAccess::ON_ERROR_POPUP)
- addXmlElement(parent, name, std::string("Popup"));
- else
- assert(false);
+ switch (value)
+ {
+ case FreeFileSync::DELETE_PERMANENTLY:
+ xmlAccess::addXmlElement(name, std::string("DeletePermanently"), parent);
+ break;
+ case FreeFileSync::MOVE_TO_RECYCLE_BIN:
+ xmlAccess::addXmlElement(name, std::string("MoveToRecycleBin"), parent);
+ break;
+ case FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY:
+ xmlAccess::addXmlElement(name, std::string("MoveToCustomDirectory"), parent);
+ break;
+ }
}
-void addXmlElementTable(TiXmlElement* parent, const std::string& name, const std::vector<wxString>& input)
+void addXmlAttribute(const std::string& name, const xmlAccess::ColumnTypes value, TiXmlElement* node)
{
- for (std::vector<wxString>::const_iterator i = input.begin(); i != input.end(); ++i)
- addXmlElement(parent, name, std::string(i->ToUTF8()));
+ xmlAccess::addXmlAttribute(name, static_cast<int>(value), node);
}
-bool XmlConfigOutput::writeXmlMainConfig(const MainConfiguration& mainCfg, const std::vector<FolderPair>& directoryPairs)
+bool writeXmlMainConfig(const MainConfiguration& mainCfg, const std::vector<FolderPair>& directoryPairs, TiXmlDocument& doc)
{
TiXmlElement* root = doc.RootElement();
if (!root) return false;
@@ -790,7 +519,7 @@ bool XmlConfigOutput::writeXmlMainConfig(const MainConfiguration& mainCfg, const
settings->LinkEndChild(cmpSettings);
//write compare algorithm
- addXmlElement(cmpSettings, "Variant", mainCfg.compareVar);
+ ::addXmlElement("Variant", mainCfg.compareVar, cmpSettings);
//write folder pair(s)
TiXmlElement* folders = new TiXmlElement("Folders");
@@ -802,8 +531,8 @@ bool XmlConfigOutput::writeXmlMainConfig(const MainConfiguration& mainCfg, const
TiXmlElement* folderPair = new TiXmlElement("Pair");
folders->LinkEndChild(folderPair);
- addXmlElement(folderPair, "Left", std::string(wxString(i->leftDirectory.c_str()).ToUTF8()));
- addXmlElement(folderPair, "Right", std::string(wxString(i->rightDirectory.c_str()).ToUTF8()));
+ xmlAccess::addXmlElement("Left", wxString(i->leftDirectory.c_str()), folderPair);
+ xmlAccess::addXmlElement("Right", wxString(i->rightDirectory.c_str()), folderPair);
}
//###########################################################
@@ -814,11 +543,11 @@ bool XmlConfigOutput::writeXmlMainConfig(const MainConfiguration& mainCfg, const
TiXmlElement* syncConfig = new TiXmlElement("Directions");
syncSettings->LinkEndChild(syncConfig);
- addXmlElement(syncConfig, "LeftOnly", mainCfg.syncConfiguration.exLeftSideOnly);
- addXmlElement(syncConfig, "RightOnly", mainCfg.syncConfiguration.exRightSideOnly);
- addXmlElement(syncConfig, "LeftNewer", mainCfg.syncConfiguration.leftNewer);
- addXmlElement(syncConfig, "RightNewer", mainCfg.syncConfiguration.rightNewer);
- addXmlElement(syncConfig, "Different", mainCfg.syncConfiguration.different);
+ ::addXmlElement(syncConfig, "LeftOnly", mainCfg.syncConfiguration.exLeftSideOnly);
+ ::addXmlElement(syncConfig, "RightOnly", mainCfg.syncConfiguration.exRightSideOnly);
+ ::addXmlElement(syncConfig, "LeftNewer", mainCfg.syncConfiguration.leftNewer);
+ ::addXmlElement(syncConfig, "RightNewer", mainCfg.syncConfiguration.rightNewer);
+ ::addXmlElement(syncConfig, "Different", mainCfg.syncConfiguration.different);
//###########################################################
TiXmlElement* miscSettings = new TiXmlElement("Miscellaneous");
@@ -828,22 +557,23 @@ bool XmlConfigOutput::writeXmlMainConfig(const MainConfiguration& mainCfg, const
TiXmlElement* filter = new TiXmlElement("Filter");
miscSettings->LinkEndChild(filter);
- addXmlElement(filter, "Active", mainCfg.filterIsActive);
- addXmlElement(filter, "Include", std::string((mainCfg.includeFilter).ToUTF8()));
- addXmlElement(filter, "Exclude", std::string((mainCfg.excludeFilter).ToUTF8()));
+ xmlAccess::addXmlElement("Active", mainCfg.filterIsActive, filter);
+ xmlAccess::addXmlElement("Include", mainCfg.includeFilter, filter);
+ xmlAccess::addXmlElement("Exclude", mainCfg.excludeFilter, filter);
//other
- addXmlElement(miscSettings, "UseRecycler", mainCfg.useRecycleBin);
+ addXmlElement("DeletionPolicy", mainCfg.handleDeletion, miscSettings);
+ xmlAccess::addXmlElement("CustomDeletionFolder", mainCfg.customDeletionDirectory, miscSettings);
//###########################################################
return true;
}
-bool XmlConfigOutput::writeXmlGuiConfig(const xmlAccess::XmlGuiConfig& inputCfg)
+bool writeXmlGuiConfig(const xmlAccess::XmlGuiConfig& inputCfg, TiXmlDocument& doc)
{
//write main config
- if (!writeXmlMainConfig(inputCfg.mainCfg, inputCfg.directoryPairs))
+ if (!writeXmlMainConfig(inputCfg.mainCfg, inputCfg.directoryPairs, doc))
return false;
//write GUI specific config
@@ -853,18 +583,20 @@ bool XmlConfigOutput::writeXmlGuiConfig(const xmlAccess::XmlGuiConfig& inputCfg)
TiXmlElement* guiConfig = new TiXmlElement("GuiConfig");
root->LinkEndChild(guiConfig);
- addXmlElement(guiConfig, "HideFiltered", inputCfg.hideFilteredElements);
- addXmlElement(guiConfig, "IgnoreErrors", inputCfg.ignoreErrors);
- addXmlElement(guiConfig, "SyncPreviewActive", inputCfg.syncPreviewEnabled);
+ xmlAccess::addXmlElement("HideFiltered", inputCfg.hideFilteredElements, guiConfig);
+
+ ::addXmlElement("HandleError", inputCfg.ignoreErrors ? xmlAccess::ON_ERROR_IGNORE : xmlAccess::ON_ERROR_POPUP, guiConfig);
+
+ xmlAccess::addXmlElement("SyncPreviewActive", inputCfg.syncPreviewEnabled, guiConfig);
return true;
}
-bool XmlConfigOutput::writeXmlBatchConfig(const xmlAccess::XmlBatchConfig& inputCfg)
+bool writeXmlBatchConfig(const xmlAccess::XmlBatchConfig& inputCfg, TiXmlDocument& doc)
{
//write main config
- if (!writeXmlMainConfig(inputCfg.mainCfg, inputCfg.directoryPairs))
+ if (!writeXmlMainConfig(inputCfg.mainCfg, inputCfg.directoryPairs, doc))
return false;
//write GUI specific config
@@ -874,15 +606,15 @@ bool XmlConfigOutput::writeXmlBatchConfig(const xmlAccess::XmlBatchConfig& input
TiXmlElement* batchConfig = new TiXmlElement("BatchConfig");
root->LinkEndChild(batchConfig);
- addXmlElement(batchConfig, "Silent", inputCfg.silent);
- addXmlElement(batchConfig, "LogfileDirectory", std::string(inputCfg.logFileDirectory.ToUTF8()));
- addXmlElement(batchConfig, "HandleError", inputCfg.handleError);
+ xmlAccess::addXmlElement("Silent", inputCfg.silent, batchConfig);
+ xmlAccess::addXmlElement("LogfileDirectory", inputCfg.logFileDirectory, batchConfig);
+ ::addXmlElement("HandleError", inputCfg.handleError, batchConfig);
return true;
}
-bool XmlConfigOutput::writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg)
+bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlDocument& doc)
{
TiXmlElement* root = doc.RootElement();
if (!root) return false;
@@ -893,47 +625,38 @@ bool XmlConfigOutput::writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings&
root->LinkEndChild(global);
//program language
- addXmlElement(global, "Language", inputCfg.programLanguage);
+ xmlAccess::addXmlElement("Language", inputCfg.programLanguage, global);
//max. allowed file time deviation
- addXmlElement(global, "FileTimeTolerance", int(inputCfg.fileTimeTolerance));
+ xmlAccess::addXmlElement("FileTimeTolerance", inputCfg.fileTimeTolerance, global);
//ignore +/- 1 hour due to DST change
- addXmlElement(global, "IgnoreOneHourDifference", inputCfg.ignoreOneHourDiff);
+ xmlAccess::addXmlElement("IgnoreOneHourDifference", inputCfg.ignoreOneHourDiff, global);
//traverse into symbolic links (to folders)
- addXmlElement(global, "TraverseDirectorySymlinks", inputCfg.traverseDirectorySymlinks);
+ xmlAccess::addXmlElement("TraverseDirectorySymlinks", inputCfg.traverseDirectorySymlinks, global);
//copy symbolic links to files
- addXmlElement(global, "CopyFileSymlinks", inputCfg.copyFileSymlinks);
+ xmlAccess::addXmlElement("CopyFileSymlinks", inputCfg.copyFileSymlinks, global);
//last update check
- addXmlElement(global, "LastCheckForUpdates", inputCfg.lastUpdateCheck);
+ xmlAccess::addXmlElement("LastCheckForUpdates", inputCfg.lastUpdateCheck, global);
//warnings
TiXmlElement* warnings = new TiXmlElement("Warnings");
global->LinkEndChild(warnings);
//warning: dependent folders
- addXmlElement(warnings, "CheckForDependentFolders", inputCfg.warnings.warningDependentFolders);
+ xmlAccess::addXmlElement("CheckForDependentFolders", inputCfg.warnings.warningDependentFolders, warnings);
//significant difference check
- addXmlElement(warnings, "CheckForSignificantDifference", inputCfg.warnings.warningSignificantDifference);
+ xmlAccess::addXmlElement("CheckForSignificantDifference", inputCfg.warnings.warningSignificantDifference, warnings);
//check free disk space
- addXmlElement(warnings, "CheckForFreeDiskSpace", inputCfg.warnings.warningNotEnoughDiskSpace);
+ xmlAccess::addXmlElement("CheckForFreeDiskSpace", inputCfg.warnings.warningNotEnoughDiskSpace, warnings);
//check for unresolved conflicts
- addXmlElement(warnings, "CheckForUnresolvedConflicts", inputCfg.warnings.warningUnresolvedConflicts);
-
- //check for very old dates or dates in the future
- addXmlElement(warnings, "CheckForInvalidFileDate", inputCfg.warnings.warningInvalidDate);
-
- //check for changed files with same modification date
- addXmlElement(warnings, "SameDateDifferentFileSize", inputCfg.warnings.warningSameDateDiffSize);
-
- //check for files that have a difference in file modification date below 1 hour when DST check is active
- addXmlElement(warnings, "FileChangeWithinHour", inputCfg.warnings.warningDSTChangeWithinHour);
+ xmlAccess::addXmlElement("CheckForUnresolvedConflicts", inputCfg.warnings.warningUnresolvedConflicts, warnings);
//###################################################################
@@ -948,24 +671,27 @@ bool XmlConfigOutput::writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings&
windows->LinkEndChild(mainWindow);
//window size
- addXmlElement(mainWindow, "Width", inputCfg.gui.widthNotMaximized);
- addXmlElement(mainWindow, "Height", inputCfg.gui.heightNotMaximized);
+ xmlAccess::addXmlElement("Width", inputCfg.gui.widthNotMaximized, mainWindow);
+ xmlAccess::addXmlElement("Height", inputCfg.gui.heightNotMaximized, mainWindow);
//window position
- addXmlElement(mainWindow, "PosX", inputCfg.gui.posXNotMaximized);
- addXmlElement(mainWindow, "PosY", inputCfg.gui.posYNotMaximized);
- addXmlElement(mainWindow, "Maximized", inputCfg.gui.isMaximized);
+ xmlAccess::addXmlElement("PosX", inputCfg.gui.posXNotMaximized, mainWindow);
+ xmlAccess::addXmlElement("PosY", inputCfg.gui.posYNotMaximized, mainWindow);
+ xmlAccess::addXmlElement("Maximized", inputCfg.gui.isMaximized, mainWindow);
- addXmlElement(mainWindow, "ManualDeletionOnBothSides", inputCfg.gui.deleteOnBothSides);
- addXmlElement(mainWindow, "ManualDeletionUseRecycler", inputCfg.gui.useRecyclerForManualDeletion);
- addXmlElement(mainWindow, "ShowFileIconsLeft", inputCfg.gui.showFileIconsLeft);
- addXmlElement(mainWindow, "ShowFileIconsRight", inputCfg.gui.showFileIconsRight);
- addXmlElement(mainWindow, "PopupOnConfigChange", inputCfg.gui.popupOnConfigChange);
- addXmlElement(mainWindow, "SummaryBeforeSync", inputCfg.gui.showSummaryBeforeSync);
+ xmlAccess::addXmlElement("ManualDeletionOnBothSides", inputCfg.gui.deleteOnBothSides, mainWindow);
+ xmlAccess::addXmlElement("ManualDeletionUseRecycler", inputCfg.gui.useRecyclerForManualDeletion, mainWindow);
+ xmlAccess::addXmlElement("ShowFileIconsLeft", inputCfg.gui.showFileIconsLeft, mainWindow);
+ xmlAccess::addXmlElement("ShowFileIconsRight", inputCfg.gui.showFileIconsRight, mainWindow);
+ xmlAccess::addXmlElement("PopupOnConfigChange", inputCfg.gui.popupOnConfigChange, mainWindow);
+ xmlAccess::addXmlElement("SummaryBeforeSync", inputCfg.gui.showSummaryBeforeSync, mainWindow);
//write column attributes
TiXmlElement* leftColumn = new TiXmlElement("LeftColumns");
mainWindow->LinkEndChild(leftColumn);
+
+ xmlAccess::addXmlAttribute("AutoAdjust", inputCfg.gui.autoAdjustColumnsLeft, leftColumn);
+
xmlAccess::ColumnAttributes columnAtrribLeftCopy = inputCfg.gui.columnAttribLeft; //can't change const vector
sort(columnAtrribLeftCopy.begin(), columnAtrribLeftCopy.end(), xmlAccess::sortByPositionOnly);
for (unsigned int i = 0; i < columnAtrribLeftCopy.size(); ++i)
@@ -974,14 +700,16 @@ bool XmlConfigOutput::writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings&
leftColumn->LinkEndChild(subElement);
const xmlAccess::ColumnAttrib& colAttrib = columnAtrribLeftCopy[i];
- subElement->SetAttribute("Type", colAttrib.type);
- if (colAttrib.visible) subElement->SetAttribute("Visible", "true");
- else subElement->SetAttribute("Visible", "false");
- subElement->SetAttribute("Width", colAttrib.width);
+ addXmlAttribute("Type", colAttrib.type, subElement);
+ xmlAccess::addXmlAttribute("Visible", colAttrib.visible, subElement);
+ xmlAccess::addXmlAttribute("Width", colAttrib.width, subElement);
}
TiXmlElement* rightColumn = new TiXmlElement("RightColumns");
mainWindow->LinkEndChild(rightColumn);
+
+ xmlAccess::addXmlAttribute("AutoAdjust", inputCfg.gui.autoAdjustColumnsRight, rightColumn);
+
xmlAccess::ColumnAttributes columnAtrribRightCopy = inputCfg.gui.columnAttribRight;
sort(columnAtrribRightCopy.begin(), columnAtrribRightCopy.end(), xmlAccess::sortByPositionOnly);
for (unsigned int i = 0; i < columnAtrribRightCopy.size(); ++i)
@@ -990,10 +718,9 @@ bool XmlConfigOutput::writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings&
rightColumn->LinkEndChild(subElement);
const xmlAccess::ColumnAttrib& colAttrib = columnAtrribRightCopy[i];
- subElement->SetAttribute("Type", colAttrib.type);
- if (colAttrib.visible) subElement->SetAttribute("Visible", "true");
- else subElement->SetAttribute("Visible", "false");
- subElement->SetAttribute("Width", colAttrib.width);
+ addXmlAttribute("Type", colAttrib.type, subElement);
+ xmlAccess::addXmlAttribute("Visible", colAttrib.visible, subElement);
+ xmlAccess::addXmlAttribute("Width", colAttrib.width, subElement);
}
//write folder history elements
@@ -1002,23 +729,23 @@ bool XmlConfigOutput::writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings&
TiXmlElement* historyRight = new TiXmlElement("FolderHistoryRight");
mainWindow->LinkEndChild(historyRight);
- historyLeft->SetAttribute("MaximumSize", globalFunctions::numberToString(inputCfg.gui.folderHistLeftMax));
- addXmlElementTable(historyLeft, "Folder", inputCfg.gui.folderHistoryLeft);
+ xmlAccess::addXmlAttribute("MaximumSize", inputCfg.gui.folderHistLeftMax, historyLeft);
+ xmlAccess::addXmlAttribute("MaximumSize", inputCfg.gui.folderHistRightMax, historyRight);
- historyRight->SetAttribute("MaximumSize", globalFunctions::numberToString(inputCfg.gui.folderHistRightMax));
- addXmlElementTable(historyRight, "Folder", inputCfg.gui.folderHistoryRight);
+ xmlAccess::addXmlElement("Folder", inputCfg.gui.folderHistoryLeft, historyLeft);
+ xmlAccess::addXmlElement("Folder", inputCfg.gui.folderHistoryRight, historyRight);
- addXmlElement(mainWindow, "SelectedTabBottomLeft", inputCfg.gui.selectedTabBottomLeft);
+ xmlAccess::addXmlElement("SelectedTabBottomLeft", inputCfg.gui.selectedTabBottomLeft, mainWindow);
//commandline for file manager integration
- addXmlElement(gui, "FileManager", std::string((inputCfg.gui.commandLineFileManager).ToUTF8()));
+ xmlAccess::addXmlElement("FileManager", inputCfg.gui.commandLineFileManager, gui);
//write config file history
TiXmlElement* cfgHistory = new TiXmlElement("ConfigHistory");
gui->LinkEndChild(cfgHistory);
- cfgHistory->SetAttribute("MaximumSize", globalFunctions::numberToString(inputCfg.gui.cfgHistoryMax));
- addXmlElementTable(cfgHistory, "File", inputCfg.gui.cfgFileHistory);
+ xmlAccess::addXmlAttribute("MaximumSize", inputCfg.gui.cfgHistoryMax, cfgHistory);
+ xmlAccess::addXmlElement("File", inputCfg.gui.cfgFileHistory, cfgHistory);
//###################################################################
//write global batch settings
@@ -1032,98 +759,13 @@ bool XmlConfigOutput::writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings&
int xmlAccess::retrieveSystemLanguage()
{
- const int lang = wxLocale::GetSystemLanguage();
-
- switch (lang) //map language dialects
- {
- //variants of wxLANGUAGE_GERMAN
- case wxLANGUAGE_GERMAN_AUSTRIAN:
- case wxLANGUAGE_GERMAN_BELGIUM:
- case wxLANGUAGE_GERMAN_LIECHTENSTEIN:
- case wxLANGUAGE_GERMAN_LUXEMBOURG:
- case wxLANGUAGE_GERMAN_SWISS:
- return wxLANGUAGE_GERMAN;
-
- //variants of wxLANGUAGE_FRENCH
- case wxLANGUAGE_FRENCH_BELGIAN:
- case wxLANGUAGE_FRENCH_CANADIAN:
- case wxLANGUAGE_FRENCH_LUXEMBOURG:
- case wxLANGUAGE_FRENCH_MONACO:
- case wxLANGUAGE_FRENCH_SWISS:
- return wxLANGUAGE_FRENCH;
-
- //variants of wxLANGUAGE_DUTCH
- case wxLANGUAGE_DUTCH_BELGIAN:
- return wxLANGUAGE_DUTCH;
-
- //variants of wxLANGUAGE_ITALIAN
- case wxLANGUAGE_ITALIAN_SWISS:
- return wxLANGUAGE_ITALIAN;
-
- //variants of wxLANGUAGE_CHINESE_SIMPLIFIED
- case wxLANGUAGE_CHINESE:
- case wxLANGUAGE_CHINESE_TRADITIONAL:
- case wxLANGUAGE_CHINESE_HONGKONG:
- case wxLANGUAGE_CHINESE_MACAU:
- case wxLANGUAGE_CHINESE_SINGAPORE:
- case wxLANGUAGE_CHINESE_TAIWAN:
- return wxLANGUAGE_CHINESE_SIMPLIFIED;
-
- //variants of wxLANGUAGE_RUSSIAN
- case wxLANGUAGE_RUSSIAN_UKRAINE:
- return wxLANGUAGE_RUSSIAN;
-
- //variants of wxLANGUAGE_SPANISH
- case wxLANGUAGE_SPANISH_ARGENTINA:
- case wxLANGUAGE_SPANISH_BOLIVIA:
- case wxLANGUAGE_SPANISH_CHILE:
- case wxLANGUAGE_SPANISH_COLOMBIA:
- case wxLANGUAGE_SPANISH_COSTA_RICA:
- case wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC:
- case wxLANGUAGE_SPANISH_ECUADOR:
- case wxLANGUAGE_SPANISH_EL_SALVADOR:
- case wxLANGUAGE_SPANISH_GUATEMALA:
- case wxLANGUAGE_SPANISH_HONDURAS:
- case wxLANGUAGE_SPANISH_MEXICAN:
- case wxLANGUAGE_SPANISH_MODERN:
- case wxLANGUAGE_SPANISH_NICARAGUA:
- case wxLANGUAGE_SPANISH_PANAMA:
- case wxLANGUAGE_SPANISH_PARAGUAY:
- case wxLANGUAGE_SPANISH_PERU:
- case wxLANGUAGE_SPANISH_PUERTO_RICO:
- case wxLANGUAGE_SPANISH_URUGUAY:
- case wxLANGUAGE_SPANISH_US:
- case wxLANGUAGE_SPANISH_VENEZUELA:
- return wxLANGUAGE_SPANISH;
-
- //case wxLANGUAGE_JAPANESE:
- //case wxLANGUAGE_POLISH:
- //case wxLANGUAGE_SLOVENIAN:
- //case wxLANGUAGE_HUNGARIAN:
- //case wxLANGUAGE_PORTUGUESE:
- //case wxLANGUAGE_PORTUGUESE_BRAZILIAN:
-
- default:
- return lang;
- }
+ return wxLocale::GetSystemLanguage();
}
-bool xmlAccess::supportForSymbolicLinks()
+bool xmlAccess::recycleBinAvailable()
{
-#ifdef FFS_WIN
- OSVERSIONINFO osvi;
- ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- //symbolic links are supported starting with Vista
- if (GetVersionEx(&osvi))
- return osvi.dwMajorVersion > 5; //XP has majorVersion == 5, minorVersion == 1, Vista majorVersion == 6
-
- return false;
-#elif defined FFS_LINUX
- return true;
-#endif
+ return FreeFileSync::recycleBinExists();
}
@@ -1133,7 +775,4 @@ void xmlAccess::WarningMessages::resetWarnings()
warningSignificantDifference = true;
warningNotEnoughDiskSpace = true;
warningUnresolvedConflicts = true;
- warningInvalidDate = true;
- warningSameDateDiffSize = true;
- warningDSTChangeWithinHour = true;
}
diff --git a/library/processXml.h b/library/processXml.h
index 15972289..9fad5cd7 100644
--- a/library/processXml.h
+++ b/library/processXml.h
@@ -2,7 +2,6 @@
#define PROCESSXML_H_INCLUDED
#include "../structures.h"
-#include "fileHandling.h"
namespace xmlAccess
{
@@ -13,14 +12,6 @@ namespace xmlAccess
ON_ERROR_EXIT
};
- enum XmlType
- {
- XML_GUI_CONFIG,
- XML_BATCH_CONFIG,
- XML_GLOBAL_SETTINGS,
- XML_OTHER
- };
-
enum ColumnTypes
{
DIRECTORY,
@@ -30,7 +21,7 @@ namespace xmlAccess
SIZE,
DATE
};
- const unsigned COLUMN_TYPE_COUNT = 6;
+ const unsigned int COLUMN_TYPE_COUNT = 6;
struct ColumnAttrib
{
@@ -41,7 +32,6 @@ namespace xmlAccess
};
typedef std::vector<ColumnAttrib> ColumnAttributes;
- XmlType getXmlType(const wxString& filename);
//---------------------------------------------------------------------
struct XmlGuiConfig
@@ -60,11 +50,11 @@ namespace xmlAccess
bool operator==(const XmlGuiConfig& other) const
{
- return mainCfg == other.mainCfg &&
- directoryPairs == other.directoryPairs &&
- hideFilteredElements == other.hideFilteredElements &&
- ignoreErrors == other.ignoreErrors &&
- syncPreviewEnabled == other.syncPreviewEnabled;
+ return mainCfg == other.mainCfg &&
+ directoryPairs == other.directoryPairs &&
+ hideFilteredElements == other.hideFilteredElements &&
+ ignoreErrors == other.ignoreErrors &&
+ syncPreviewEnabled == other.syncPreviewEnabled;
}
bool operator!=(const XmlGuiConfig& other) const
@@ -87,7 +77,7 @@ namespace xmlAccess
};
int retrieveSystemLanguage();
- bool supportForSymbolicLinks();
+ bool recycleBinAvailable();
struct WarningMessages
@@ -103,9 +93,6 @@ namespace xmlAccess
bool warningSignificantDifference;
bool warningNotEnoughDiskSpace;
bool warningUnresolvedConflicts;
- bool warningInvalidDate;
- bool warningSameDateDiffSize;
- bool warningDSTChangeWithinHour;
};
@@ -118,7 +105,7 @@ namespace xmlAccess
fileTimeTolerance(2), //default 2s: FAT vs NTFS
ignoreOneHourDiff(true),
traverseDirectorySymlinks(false),
- copyFileSymlinks(supportForSymbolicLinks()),
+ copyFileSymlinks(true),
lastUpdateCheck(0) {}
int programLanguage;
@@ -126,7 +113,7 @@ namespace xmlAccess
bool ignoreOneHourDiff; //ignore +/- 1 hour due to DST change
bool traverseDirectorySymlinks;
bool copyFileSymlinks; //copy symbolic link instead of target file
- long lastUpdateCheck; //time of last update check
+ long lastUpdateCheck; //time of last update check
WarningMessages warnings;
@@ -139,17 +126,19 @@ namespace xmlAccess
posXNotMaximized(wxDefaultCoord),
posYNotMaximized(wxDefaultCoord),
isMaximized(false),
+ autoAdjustColumnsLeft(false),
+ autoAdjustColumnsRight(false),
#ifdef FFS_WIN
commandLineFileManager(wxT("explorer /select, %name")),
#elif defined FFS_LINUX
- commandLineFileManager(wxT("konqueror \"%path\"")),
+ commandLineFileManager(wxT("konqueror \"%dir\"")),
#endif
cfgHistoryMax(10),
folderHistLeftMax(12),
folderHistRightMax(12),
selectedTabBottomLeft(0),
deleteOnBothSides(false),
- useRecyclerForManualDeletion(FreeFileSync::recycleBinExists()), //enable if OS supports it; else user will have to activate first and then get an error message
+ useRecyclerForManualDeletion(recycleBinAvailable()), //enable if OS supports it; else user will have to activate first and then get an error message
showFileIconsLeft(true),
showFileIconsRight(true),
popupOnConfigChange(true),
@@ -164,6 +153,9 @@ namespace xmlAccess
ColumnAttributes columnAttribLeft;
ColumnAttributes columnAttribRight;
+ bool autoAdjustColumnsLeft;
+ bool autoAdjustColumnsRight;
+
wxString commandLineFileManager;
std::vector<wxString> cfgFileHistory;
@@ -214,15 +206,13 @@ namespace xmlAccess
return a.position < b.position;
}
+ void readGuiConfig( const wxString& filename, XmlGuiConfig& config); //throw (xmlAccess::XmlError);
+ void readBatchConfig(const wxString& filename, XmlBatchConfig& config); //throw (xmlAccess::XmlError);
+ void readGlobalSettings( XmlGlobalSettings& config); //throw (xmlAccess::XmlError);
- XmlGuiConfig readGuiConfig(const wxString& filename);
- XmlBatchConfig readBatchConfig(const wxString& filename);
- XmlGlobalSettings readGlobalSettings(); //used for both GUI and batch mode, independent from configuration instance
-
- void writeGuiConfig(const wxString& filename, const XmlGuiConfig& outputCfg);
- void writeBatchConfig(const wxString& filename, const XmlBatchConfig& outputCfg);
- void writeGlobalSettings(const XmlGlobalSettings& outputCfg);
-
+ void writeGuiConfig( const XmlGuiConfig& outputCfg, const wxString& filename); //throw (xmlAccess::XmlError);
+ void writeBatchConfig( const XmlBatchConfig& outputCfg, const wxString& filename); //throw (xmlAccess::XmlError);
+ void writeGlobalSettings(const XmlGlobalSettings& outputCfg); //throw (xmlAccess::XmlError);
}
diff --git a/library/resources.cpp b/library/resources.cpp
index 38f2a051..3e7b5a4e 100644
--- a/library/resources.cpp
+++ b/library/resources.cpp
@@ -4,8 +4,9 @@
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/mstream.h>
-#include "globalFunctions.h"
-#include "../structures.h"
+#include "../shared/globalFunctions.h"
+//#include "../shared/systemFunctions.h"
+#include "../shared/standardPaths.h"
const GlobalResources& GlobalResources::getInstance()
@@ -98,16 +99,20 @@ GlobalResources::GlobalResources()
bitmapResource[wxT("batch_small.png")] = (bitmapBatchSmall = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("move up.png")] = (bitmapMoveUp = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("move down.png")] = (bitmapMoveDown = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("checkbox true.png")] = (bitmapCheckBoxTrue = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("checkbox false.png")] = (bitmapCheckBoxFalse = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("checkbox_true.png")] = (bitmapCheckBoxTrue = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("checkbox_true_focus.png")] = (bitmapCheckBoxTrueFocus = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("checkbox_false.png")] = (bitmapCheckBoxFalse = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("checkbox_false_focus.png")] = (bitmapCheckBoxFalseFocus = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("settings.png")] = (bitmapSettings = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("settings_small.png")] = (bitmapSettingsSmall = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("recycler.png")] = (bitmapRecycler = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("shift.png")] = (bitmapShift = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("syncConfig.png")] = (bitmapSyncCfg = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("cmpConfig.png")] = (bitmapCmpCfg = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("syncPreview.png")] = (bitmapPreview = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("syncPreviewDisabl.png")] = (bitmapPreviewDisabled = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("question.png")] = (bitmapQuestion = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("czechRep.png")] = (bitmapCzechRep = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("china.png")] = (bitmapChina = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("holland.png")] = (bitmapHolland = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("england.png")] = (bitmapEngland = new wxBitmap(wxNullBitmap));
@@ -120,8 +125,16 @@ GlobalResources::GlobalResources()
bitmapResource[wxT("portugal.png")] = (bitmapPortugal = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("brazil.png")] = (bitmapBrazil = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("slovakia.png")] = (bitmapSlovakia = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("spain.png")] = (bitmapSpain = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("russia.png")] = (bitmapRussia = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("spain.png")] = (bitmapSpain = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("russia.png")] = (bitmapRussia = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("syncCreateLeftAct.png")] = (bitmapSyncCreateLeftAct = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("syncCreateLeftDeact.png")] = (bitmapSyncCreateLeftDeact = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("syncCreateRightAct.png")] = (bitmapSyncCreateRightAct = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("syncCreateRightDeact.png")] = (bitmapSyncCreateRightDeact = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("syncDeleteLeftAct.png")] = (bitmapSyncDeleteLeftAct = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("syncDeleteLeftDeact.png")] = (bitmapSyncDeleteLeftDeact = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("syncDeleteRightAct.png")] = (bitmapSyncDeleteRightAct = new wxBitmap(wxNullBitmap));
+ bitmapResource[wxT("syncDeleteRightDeact.png")] = (bitmapSyncDeleteRightDeact = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("syncDirLeftAct.png")] = (bitmapSyncDirLeftAct = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("syncDirLeftDeact.png")] = (bitmapSyncDirLeftDeact = new wxBitmap(wxNullBitmap));
bitmapResource[wxT("syncDirRightAct.png")] = (bitmapSyncDirRightAct = new wxBitmap(wxNullBitmap));
@@ -191,7 +204,7 @@ void loadAnimFromZip(wxZipInputStream& zipInput, wxAnimation* animation)
void GlobalResources::load() const
{
- wxFileInputStream input(FreeFileSync::getInstallationDir() + FreeFileSync::FILE_NAME_SEPARATOR + wxT("Resources.dat"));
+ wxFFileInputStream input(FreeFileSync::getInstallationDir() + globalFunctions::FILE_NAME_SEPARATOR + wxT("Resources.dat"));
if (input.IsOk()) //if not... we don't want to react too harsh here
{
//activate support for .png files
@@ -199,10 +212,13 @@ void GlobalResources::load() const
wxZipInputStream resourceFile(input);
- wxZipEntry* entry = NULL;
std::map<wxString, wxBitmap*>::iterator bmp;
- while ((entry = resourceFile.GetNextEntry()))
+ while (true)
{
+ std::auto_ptr<wxZipEntry> entry(resourceFile.GetNextEntry());
+ if (entry.get() == NULL)
+ break;
+
const wxString name = entry->GetName();
//search if entry is available in map
@@ -222,3 +238,13 @@ void GlobalResources::load() const
*programIcon = wxIcon(FreeFileSync_xpm);
#endif
}
+
+
+const wxBitmap& GlobalResources::getImageByName(const wxString& imageName) const
+{
+ std::map<wxString, wxBitmap*>::const_iterator bmp = bitmapResource.find(imageName);
+ if (bmp != bitmapResource.end())
+ return *bmp->second;
+ else
+ return wxNullBitmap;
+}
diff --git a/library/resources.h b/library/resources.h
index 1ce7d20e..5f4e51f0 100644
--- a/library/resources.h
+++ b/library/resources.h
@@ -12,6 +12,8 @@ class GlobalResources
public:
static const GlobalResources& getInstance();
+ const wxBitmap& getImageByName(const wxString& imageName) const;
+
//image resource objects
wxBitmap* bitmapArrowLeft;
wxBitmap* bitmapArrowRight;
@@ -94,15 +96,19 @@ public:
wxBitmap* bitmapMoveUp;
wxBitmap* bitmapMoveDown;
wxBitmap* bitmapCheckBoxTrue;
+ wxBitmap* bitmapCheckBoxTrueFocus;
wxBitmap* bitmapCheckBoxFalse;
+ wxBitmap* bitmapCheckBoxFalseFocus;
wxBitmap* bitmapSettings;
wxBitmap* bitmapSettingsSmall;
wxBitmap* bitmapRecycler;
wxBitmap* bitmapShift;
wxBitmap* bitmapSyncCfg;
+ wxBitmap* bitmapCmpCfg;
wxBitmap* bitmapPreview;
wxBitmap* bitmapPreviewDisabled;
wxBitmap* bitmapQuestion;
+ wxBitmap* bitmapCzechRep;
wxBitmap* bitmapChina;
wxBitmap* bitmapHolland;
wxBitmap* bitmapEngland;
@@ -117,6 +123,14 @@ public:
wxBitmap* bitmapSlovakia;
wxBitmap* bitmapSpain;
wxBitmap* bitmapRussia;
+ wxBitmap* bitmapSyncCreateLeftAct;
+ wxBitmap* bitmapSyncCreateLeftDeact;
+ wxBitmap* bitmapSyncCreateRightAct;
+ wxBitmap* bitmapSyncCreateRightDeact;
+ wxBitmap* bitmapSyncDeleteLeftAct;
+ wxBitmap* bitmapSyncDeleteLeftDeact;
+ wxBitmap* bitmapSyncDeleteRightAct;
+ wxBitmap* bitmapSyncDeleteRightDeact;
wxBitmap* bitmapSyncDirLeftAct;
wxBitmap* bitmapSyncDirLeftDeact;
wxBitmap* bitmapSyncDirRightAct;
diff --git a/library/statistics.cpp b/library/statistics.cpp
index f2506da8..f317c114 100644
--- a/library/statistics.cpp
+++ b/library/statistics.cpp
@@ -1,9 +1,10 @@
#include "statistics.h"
#include <wx/ffile.h>
-#include "globalFunctions.h"
+#include "../shared/globalFunctions.h"
#include "statusHandler.h"
#include "../algorithm.h"
+#include <wx/intl.h>
#include <limits>
#include <wx/stopwatch.h>
diff --git a/library/statusHandler.h b/library/statusHandler.h
index fe64f3cd..d4163d2f 100644
--- a/library/statusHandler.h
+++ b/library/statusHandler.h
@@ -59,9 +59,9 @@ public:
//error handling:
- virtual ErrorHandler::Response reportError(const Zstring& errorMessage) = 0; //recoverable error situation
- virtual void reportFatalError(const Zstring& errorMessage) = 0; //non-recoverable error situation, implement abort!
- virtual void reportWarning(const Zstring& warningMessage, bool& dontShowAgain) = 0;
+ virtual ErrorHandler::Response reportError(const wxString& errorMessage) = 0; //recoverable error situation
+ virtual void reportFatalError(const wxString& errorMessage) = 0; //non-recoverable error situation, implement abort!
+ virtual void reportWarning(const wxString& warningMessage, bool& warningActive) = 0;
private:
virtual void abortThisProcess() = 0;
bgstack15