Skip to content

Commit

Permalink
Version 13.1 (2023-10-23)
Browse files Browse the repository at this point in the history
  • Loading branch information
hkneptune committed Oct 24, 2023
1 parent b5a6eea commit 23ab55b
Show file tree
Hide file tree
Showing 50 changed files with 5,311 additions and 5,305 deletions.
4 changes: 2 additions & 2 deletions Bugs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ the ones mentioned below. The remaining issues that are yet to be fixed are list


----------------
| libcurl 7.88|
| libcurl 8.4.0|
----------------
__________________________________________________________________________________________________________
/lib/ftp.c
Expand Down Expand Up @@ -65,7 +65,7 @@ ________________________________________________________________________________


-------------------
| wxWidgets 3.2.2 |
| wxWidgets 3.2.3 |
-------------------
__________________________________________________________________________________________________________
/include/wx/features.h
Expand Down
9 changes: 9 additions & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
FreeFileSync 13.1 [2023-10-23]
------------------------------
Keep comparison results when only changing cloud connection settings
Sync button: indicate if database will be used
Remove leading/trailing space during manual file rename
Set environment variable "DISPLAY=:0" if missing (Linux)
Support dropping ffs_gui/ffs_real config on RealTimeSync directory input field


FreeFileSync 13.0 [2023-09-12]
------------------------------
Rename (multiple) files manually (F2 key)
Expand Down
13 changes: 5 additions & 8 deletions FreeFileSync/Source/RealTimeSync/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,22 +208,19 @@ wxLayoutDirection Application::GetLayoutDirection() const { return fff::getLayou


int Application::OnRun()
{
[[maybe_unused]] const int rc = wxApp::OnRun();
return static_cast<int>(FfsExitCode::success); //process exit code
}


void Application::OnUnhandledException() //handles both wxApp::OnInit() + wxApp::OnRun()
{
try
{
throw; //just re-throw
#if wxUSE_EXCEPTIONS
#error why is wxWidgets uncaught exception handling enabled!?
#endif
[[maybe_unused]] const int rc = wxApp::OnRun();
}
catch (const std::bad_alloc& e) //the only kind of exception we don't want crash dumps for
{
notifyAppError(utfTo<std::wstring>(e.what()));
terminateProcess(static_cast<int>(FfsExitCode::exception));
}
//catch (...) -> Windows: let it crash and create mini dump!!! Linux/macOS: std::exception::what() logged to console
return static_cast<int>(FfsExitCode::success); //process exit code
}
2 changes: 0 additions & 2 deletions FreeFileSync/Source/RealTimeSync/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ class Application : public wxApp
bool OnInit() override;
int OnRun () override;
int OnExit() override;
bool OnExceptionInMainLoop() override { throw; } //just re-throw and avoid display of additional messagebox: it will be caught in OnUnhandledException()
void OnUnhandledException () override;
wxLayoutDirection GetLayoutDirection() const override;

void onEnterEventLoop();
Expand Down
1 change: 0 additions & 1 deletion FreeFileSync/Source/RealTimeSync/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <zen/file_access.h>
#include <zen/process_exec.h>
#include <zenxml/xml.h>
//#include <wx/intl.h>
#include <wx/uilocale.h>
#include "../ffs_paths.h"
#include "../localization.h"
Expand Down
33 changes: 18 additions & 15 deletions FreeFileSync/Source/RealTimeSync/folder_selector2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ void setFolderPath(const Zstring& dirpath, wxTextCtrl* txtCtrl, wxWindow& toolti
staticText->SetLabel(equalNativePath(appendSeparator(trimCpy(dirpath)), appendSeparator(folderPathFmt)) ?
wxString(_("Drag && drop")) : utfTo<wxString>(folderPathFmt));
}


}

//##############################################################################################################
Expand All @@ -47,7 +49,9 @@ FolderSelector2::FolderSelector2(wxWindow* parent,
wxButton& selectButton,
wxTextCtrl& folderPathCtrl,
Zstring& folderLastSelected,
wxStaticText* staticText) :
wxStaticText* staticText,
const std::function<bool (const std::vector<Zstring>& shellItemPaths)>& droppedPathsFilter) :
droppedPathsFilter_ (droppedPathsFilter),
parent_(parent),
dropWindow_(dropWindow),
selectButton_(selectButton),
Expand All @@ -59,7 +63,6 @@ FolderSelector2::FolderSelector2(wxWindow* parent,
if (GtkWidget* widget = folderPathCtrl.GetConnectWidget())
::gtk_drag_dest_unset(widget);

//prepare drag & drop
setupFileDrop(dropWindow_);
dropWindow_.Bind(EVENT_DROP_FILE, &FolderSelector2::onFilesDropped, this);

Expand Down Expand Up @@ -100,20 +103,22 @@ void FolderSelector2::onFilesDropped(FileDropEvent& event)
if (event.itemPaths_.empty())
return;

Zstring itemPath = event.itemPaths_[0];
try
if (!droppedPathsFilter_ || droppedPathsFilter_(event.itemPaths_))
{
if (getItemType(itemPath) == ItemType::file) //throw FileError
if (const std::optional<Zstring>& parentPath = getParentFolderPath(itemPath))
itemPath = *parentPath;
}
catch (FileError&) {} //e.g. good for inactive mapped network shares, not so nice for C:\pagefile.sys

if (endsWith(itemPath, Zstr(' '))) //prevent getResolvedFilePath() from trimming legit trailing blank!
itemPath += FILE_NAME_SEPARATOR;
Zstring itemPath = event.itemPaths_[0];
try
{
if (getItemType(itemPath) == ItemType::file) //throw FileError
if (const std::optional<Zstring>& parentPath = getParentFolderPath(itemPath))
itemPath = *parentPath;
}
catch (FileError&) {} //e.g. good for inactive mapped network shares, not so nice for C:\pagefile.sys

setPath(itemPath);
if (endsWith(itemPath, Zstr(' '))) //prevent getResolvedFilePath() from trimming legit trailing blank!
itemPath += FILE_NAME_SEPARATOR;

setPath(itemPath);
}
//event.Skip();
}

Expand All @@ -125,8 +130,6 @@ void FolderSelector2::onEditFolderPath(wxCommandEvent& event)
}




void FolderSelector2::onSelectDir(wxCommandEvent& event)
{
//IFileDialog requirements for default path: 1. accepts native paths only!!! 2. path must exist!
Expand Down
5 changes: 4 additions & 1 deletion FreeFileSync/Source/RealTimeSync/folder_selector2.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class FolderSelector2 : public wxEvtHandler
wxButton& selectButton,
wxTextCtrl& folderPathCtrl,
Zstring& folderLastSelected,
wxStaticText* staticText); //optional
wxStaticText* staticText, //optional
const std::function<bool (const std::vector<Zstring>& shellItemPaths)>& droppedPathsFilter); //optional

~FolderSelector2();

Expand All @@ -37,6 +38,8 @@ class FolderSelector2 : public wxEvtHandler
void onEditFolderPath(wxCommandEvent& event);
void onSelectDir (wxCommandEvent& event);

const std::function<bool(const std::vector<Zstring>& shellItemPaths)> droppedPathsFilter_;

wxWindow* parent_;
wxWindow& dropWindow_;
wxButton& selectButton_;
Expand Down
33 changes: 29 additions & 4 deletions FreeFileSync/Source/RealTimeSync/main_dlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,39 @@ std::wstring extractJobName(const Zstring& cfgFilePath)
}


bool acceptDialogFileDrop(const std::vector<Zstring>& shellItemPaths)
{
if (shellItemPaths.empty())
return false;

const Zstring ext = getFileExtension(shellItemPaths[0]);
return equalAsciiNoCase(ext, "ffs_real") ||
equalAsciiNoCase(ext, "ffs_batch");
}
}


std::function<bool(const std::vector<Zstring>& shellItemPaths)> getDroppedPathsFilter(MainDialog& mainDlg)
{
return [&mainDlg](const std::vector<Zstring>& shellItemPaths)
{
if (acceptDialogFileDrop(shellItemPaths))
{
assert(!shellItemPaths.empty());
mainDlg.loadConfig(shellItemPaths[0]);
return false; //don't set dropped paths
}
return true; //do set dropped paths
};
}


class rts::DirectoryPanel : public FolderGenerated
{
public:
DirectoryPanel(wxWindow* parent, Zstring& folderLastSelected) :
DirectoryPanel(wxWindow* parent, MainDialog& mainDlg, Zstring& folderLastSelected) :
FolderGenerated(parent),
folderSelector_(parent, *this, *m_buttonSelectFolder, *m_txtCtrlDirectory, folderLastSelected, nullptr /*staticText*/)
folderSelector_(parent, *this, *m_buttonSelectFolder, *m_txtCtrlDirectory, folderLastSelected, nullptr /*staticText*/, getDroppedPathsFilter(mainDlg))
{
setImage(*m_bpButtonRemoveFolder, loadImage("item_remove"));
}
Expand Down Expand Up @@ -101,7 +125,8 @@ MainDialog::MainDialog(const Zstring& cfgFilePath) :
setGlobalWindow(this);

//prepare drag & drop
firstFolderPanel_ = std::make_unique<FolderSelector2>(this, *m_panelMainFolder, *m_buttonSelectFolderMain, *m_txtCtrlDirectoryMain, folderLastSelected_, nullptr /*staticText*/);
firstFolderPanel_ = std::make_unique<FolderSelector2>(this, *m_panelMainFolder, *m_buttonSelectFolderMain, *m_txtCtrlDirectoryMain, folderLastSelected_,
nullptr /*staticText*/, getDroppedPathsFilter(*this));

//--------------------------- load config values ------------------------------------
XmlRealConfig newConfig;
Expand Down Expand Up @@ -412,7 +437,7 @@ void MainDialog::insertAddFolder(const std::vector<Zstring>& newFolders, size_t
for (size_t i = 0; i < newFolders.size(); ++i)
{
//add new folder pair
DirectoryPanel* newFolder = new DirectoryPanel(m_scrolledWinFolders, folderLastSelected_);
DirectoryPanel* newFolder = new DirectoryPanel(m_scrolledWinFolders, *this, folderLastSelected_);

bSizerFolders->Insert(pos + i, newFolder, 0, wxEXPAND);
additionalFolderPanels_.insert(additionalFolderPanels_.begin() + pos + i, newFolder);
Expand Down
4 changes: 2 additions & 2 deletions FreeFileSync/Source/RealTimeSync/main_dlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ class MainDialog: public MainDlgGenerated
public:
static void create(const Zstring& cfgFilePath);

void loadConfig(const Zstring& filepath);

private:
MainDialog(const Zstring& cfgFilePath);
~MainDialog();

void onBeforeSystemShutdown(); //last chance to do something useful before killing the application!

void loadConfig(const Zstring& filepath);

void onClose (wxCloseEvent& event ) override { Destroy(); }
void onShowHelp (wxCommandEvent& event) override { wxLaunchDefaultBrowser(L"https://freefilesync.org/manual.php?topic=realtimesync"); }
void onMenuAbout (wxCommandEvent& event) override;
Expand Down
2 changes: 1 addition & 1 deletion FreeFileSync/Source/afs/gdrive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ GdriveAccessInfo gdriveAuthorizeAccess(const std::string& gdriveLoginHint, const
addrinfo* servinfo = nullptr;
ZEN_ON_SCOPE_EXIT(if (servinfo) ::freeaddrinfo(servinfo));

//ServiceName == "0" => open the next best free port
//ServiceName == "0": open the next best free port
const int rcGai = ::getaddrinfo(nullptr, //_In_opt_ PCSTR pNodeName
"0", //_In_opt_ PCSTR pServiceName
&hints, //_In_opt_ const ADDRINFOA* pHints
Expand Down
16 changes: 7 additions & 9 deletions FreeFileSync/Source/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ bool Application::OnInit()
// drawback: missing MTP and network links in folder picker: https://freefilesync.org/forum/viewtopic.php?t=6871
//if (::setenv("GIO_USE_VFS", "local", true /*overwrite*/) != 0)
// std::cerr << utfTo<std::string>(formatSystemError("setenv(GIO_USE_VFS)", errno)) + '\n';
//
// //BUGZ!?: "Modifications of environment variables are not allowed in multi-threaded programs" - https://rachelbythebay.com/w/2017/01/30/env/

//=> work around 2:
[[maybe_unused]] GVfs* defaultFs = ::g_vfs_get_default(); //not owned by us!
//no such issue on GTK3!
Expand Down Expand Up @@ -241,24 +242,21 @@ wxLayoutDirection Application::GetLayoutDirection() const { return getLayoutDire


int Application::OnRun()
{
[[maybe_unused]] const int rc = wxApp::OnRun();
return static_cast<int>(exitCode_);
}


void Application::OnUnhandledException() //handles both wxApp::OnInit() + wxApp::OnRun()
{
try
{
throw; //just re-throw
#if wxUSE_EXCEPTIONS
#error why is wxWidgets uncaught exception handling enabled!?
#endif
[[maybe_unused]] const int rc = wxApp::OnRun();
}
catch (const std::bad_alloc& e) //the only kind of exception we don't want crash dumps for
{
notifyAppError(utfTo<std::wstring>(e.what()));
terminateProcess(static_cast<int>(FfsExitCode::exception));
}
//catch (...) -> Windows: let it crash and create mini dump!!! Linux/macOS: std::exception::what() logged to console
return static_cast<int>(exitCode_);
}


Expand Down
2 changes: 0 additions & 2 deletions FreeFileSync/Source/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ class Application : public wxApp
bool OnInit() override;
int OnRun () override;
int OnExit() override;
bool OnExceptionInMainLoop() override { throw; } //just re-throw and avoid display of additional messagebox: it will be caught in OnUnhandledException()
void OnUnhandledException () override;
wxLayoutDirection GetLayoutDirection() const override;
void onEnterEventLoop();

Expand Down
15 changes: 9 additions & 6 deletions FreeFileSync/Source/base/algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ class DetectMovedFiles
if (fileLeftOnly->isActive() != fileRightOnly->isActive()) //just in case
fileLeftOnly->setActive(false);

fileRightOnly->removeObject<SelectSide::right>(); //=> call ContainerObject::removeDoubleEmpty() later!
fileRightOnly->removeItem<SelectSide::right>(); //=> call ContainerObject::removeDoubleEmpty() later!
}
else //regular move pair: mark it!
{
Expand Down Expand Up @@ -1503,31 +1503,34 @@ void deleteFilesOneSide(const std::vector<FileSystemObject*>& rowsToDelete,

if (!fsObj->isEmpty<side>()) //element may be implicitly deleted, e.g. if parent folder was deleted first
{
visitFSObject(*fsObj, [&](const FolderPair& folder)
visitFSObject(*fsObj, [&](FolderPair& folder)
{
if (folder.isFollowedSymlink<side>())
removeSymlink(folder.getAbstractPath<side>(), statReporter); //throw FileError, X
else
removeFolder(folder.getAbstractPath<side>(), statReporter); //throw FileError, X

folder.removeItem<side>(); //removes recursively!
},

[&](const FilePair& file)
[&](FilePair& file)
{
if (file.isFollowedSymlink<side>())
removeSymlink(file.getAbstractPath<side>(), statReporter); //throw FileError, X
else
removeFile(file.getAbstractPath<side>(), statReporter); //throw FileError, X

file.removeItem<side>();
},

[&](const SymlinkPair& symlink)
[&](SymlinkPair& symlink)
{
removeSymlink(symlink.getAbstractPath<side>(), statReporter); //throw FileError, X
symlink.removeItem<side>();
});
//------- no-throw from here on -------
const CompareFileResult catOld = fsObj->getCategory();

fsObj->removeObject<side>(); //if directory: removes recursively!

//update sync direction: don't call redetermineSyncDirection() because user may have manually changed directions
if (catOld == CompareFileResult::FILE_EQUAL)
{
Expand Down
5 changes: 2 additions & 3 deletions FreeFileSync/Source/base/comparison.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ FolderComparison ComparisonBuffer::execute(const std::vector<std::pair<ResolvedF
foldersToRead.emplace(DirectoryKey{folderPair.folderPathLeft, fpCfg.filter.nameFilter, fpCfg.handleSymlinks});
if (getBaseFolderStatus(folderPair.folderPathRight) == BaseFolderStatus::existing)
foldersToRead.emplace(DirectoryKey{folderPair.folderPathRight, fpCfg.filter.nameFilter, fpCfg.handleSymlinks});
warn_static("remove DirectoryKey{} prefix once mac supports it")
}

//------------------------------------------------------------------
Expand Down Expand Up @@ -653,7 +652,7 @@ class MergeSides
static void execute(const FolderContainer& lhs, const FolderContainer& rhs,
const std::unordered_map<Zstring, Zstringc>& errorsByRelPathL,
const std::unordered_map<Zstring, Zstringc>& errorsByRelPathR,
ContainerObject& output,
ContainerObject& output,
std::vector<FilePair*>& undefinedFilesOut,
std::vector<SymlinkPair*>& undefinedSymlinksOut)
{
Expand Down Expand Up @@ -1033,7 +1032,7 @@ SharedRef<BaseFolderPair> ComparisonBuffer::performComparison(const ResolvedFold
fileTimeTolerance_,
fpCfg.ignoreTimeShiftMinutes);
//PERF_START;
MergeSides::execute(*folderContL, *folderContR, failedReadsL, failedReadsR,
MergeSides::execute(*folderContL, *folderContR, failedReadsL, failedReadsR,
output.ref(), undefinedFiles, undefinedSymlinks);
//PERF_STOP;

Expand Down
3 changes: 0 additions & 3 deletions FreeFileSync/Source/base/db_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,12 @@ struct InSyncFolder
{
files.emplace(fileName, InSyncFile {descrL, descrR, cmpVar, fileSize});
assert(inserted);
warn_static("use try_emplace once mac is up to the task!!!")
//"Parenthesized initialization of aggregates" https://en.cppreference.com/w/cpp/compiler_support/20
}

void addSymlink(const Zstring& linkName, const InSyncDescrLink& descrL, const InSyncDescrLink& descrR, CompareVariant cmpVar)
{
symlinks.emplace(linkName, InSyncSymlink {descrL, descrR, cmpVar});
assert(inserted);
warn_static("use try_emplace once mac is up to the task!!!")
}
};

Expand Down
Loading

0 comments on commit 23ab55b

Please sign in to comment.