spelling and formatting
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
parent
a28193430c
commit
0c986ba4d0
@ -328,7 +328,7 @@ bool create_link::operator()(const QString& offset, bool dryRun)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief make a list off all the links ot make
|
* @brief make a list off all the links to
|
||||||
* @param offset subdirectory form src to link to dest
|
* @param offset subdirectory form src to link to dest
|
||||||
* @return if there was an error during the attempt to link
|
* @return if there was an error during the attempt to link
|
||||||
*/
|
*/
|
||||||
@ -363,7 +363,7 @@ void create_link::make_link_list(const QString& offset)
|
|||||||
link_file(src, "");
|
link_file(src, "");
|
||||||
} else {
|
} else {
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
qDebug() << "linking recursivly:" << src << "to" << dst << "max_depth:" << m_max_depth;
|
qDebug() << "linking recursively:" << src << "to" << dst << "max_depth:" << m_max_depth;
|
||||||
QDir src_dir(src);
|
QDir src_dir(src);
|
||||||
QDirIterator source_it(src, QDir::Filter::Files | QDir::Filter::Hidden, QDirIterator::Subdirectories);
|
QDirIterator source_it(src, QDir::Filter::Files | QDir::Filter::Hidden, QDirIterator::Subdirectories);
|
||||||
|
|
||||||
@ -414,7 +414,7 @@ bool create_link::make_links()
|
|||||||
qWarning() << "Failed to link files:" << QString::fromStdString(m_os_err.message());
|
qWarning() << "Failed to link files:" << QString::fromStdString(m_os_err.message());
|
||||||
qDebug() << "Source file:" << src_path;
|
qDebug() << "Source file:" << src_path;
|
||||||
qDebug() << "Destination file:" << dst_path;
|
qDebug() << "Destination file:" << dst_path;
|
||||||
qDebug() << "Error catagory:" << m_os_err.category().name();
|
qDebug() << "Error category:" << m_os_err.category().name();
|
||||||
qDebug() << "Error code:" << m_os_err.value();
|
qDebug() << "Error code:" << m_os_err.value();
|
||||||
emit linkFailed(src_path, dst_path, QString::fromStdString(m_os_err.message()), m_os_err.value());
|
emit linkFailed(src_path, dst_path, QString::fromStdString(m_os_err.message()), m_os_err.value());
|
||||||
} else {
|
} else {
|
||||||
@ -469,7 +469,7 @@ void create_link::runPrivileged(const QString& offset)
|
|||||||
in.setDevice(clientConnection);
|
in.setDevice(clientConnection);
|
||||||
in.setVersion(QDataStream::Qt_5_0);
|
in.setVersion(QDataStream::Qt_5_0);
|
||||||
qDebug() << "Reading path results from client";
|
qDebug() << "Reading path results from client";
|
||||||
qDebug() << "bytes avalible" << clientConnection->bytesAvailable();
|
qDebug() << "bytes available" << clientConnection->bytesAvailable();
|
||||||
|
|
||||||
// Relies on the fact that QDataStream serializes a quint32 into
|
// Relies on the fact that QDataStream serializes a quint32 into
|
||||||
// sizeof(quint32) bytes
|
// sizeof(quint32) bytes
|
||||||
@ -479,7 +479,7 @@ void create_link::runPrivileged(const QString& offset)
|
|||||||
in >> blockSize;
|
in >> blockSize;
|
||||||
|
|
||||||
qDebug() << "blocksize is" << blockSize;
|
qDebug() << "blocksize is" << blockSize;
|
||||||
qDebug() << "bytes avalible" << clientConnection->bytesAvailable();
|
qDebug() << "bytes available" << clientConnection->bytesAvailable();
|
||||||
if (clientConnection->bytesAvailable() < blockSize || in.atEnd())
|
if (clientConnection->bytesAvailable() < blockSize || in.atEnd())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -506,7 +506,7 @@ void create_link::runPrivileged(const QString& offset)
|
|||||||
m_path_results.append(result);
|
m_path_results.append(result);
|
||||||
}
|
}
|
||||||
gotResults = true;
|
gotResults = true;
|
||||||
qDebug() << "results recieved, closing connection";
|
qDebug() << "results received, closing connection";
|
||||||
clientConnection->close();
|
clientConnection->close();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -981,7 +981,7 @@ FilesystemType getFilesystemType(const QString& name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief path to the near ancestor that exsists
|
* @brief path to the near ancestor that exists
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
QString NearestExistentAncestor(const QString& path)
|
QString NearestExistentAncestor(const QString& path)
|
||||||
|
@ -44,9 +44,9 @@
|
|||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFlags>
|
#include <QFlags>
|
||||||
|
#include <QLocalServer>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QLocalServer>
|
|
||||||
|
|
||||||
namespace FS {
|
namespace FS {
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ bool ensureFolderPathExists(QString filenamepath);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies a directory and it's contents from src to dest
|
* @brief Copies a directory and it's contents from src to dest
|
||||||
*/
|
*/
|
||||||
class copy : public QObject {
|
class copy : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -167,17 +167,14 @@ class ExternalLinkFileProcess : public QThread {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief links (a file / a directory and it's contents) from src to dest
|
* @brief links (a file / a directory and it's contents) from src to dest
|
||||||
*/
|
*/
|
||||||
class create_link : public QObject {
|
class create_link : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
create_link(const QList<LinkPair> path_pairs, QObject* parent = nullptr) : QObject(parent)
|
create_link(const QList<LinkPair> path_pairs, QObject* parent = nullptr) : QObject(parent) { m_path_pairs.append(path_pairs); }
|
||||||
{
|
|
||||||
m_path_pairs.append(path_pairs);
|
|
||||||
}
|
|
||||||
create_link(const QString& src, const QString& dst, QObject* parent = nullptr) : QObject(parent)
|
create_link(const QString& src, const QString& dst, QObject* parent = nullptr) : QObject(parent)
|
||||||
{
|
{
|
||||||
LinkPair pair = {src, dst};
|
LinkPair pair = { src, dst };
|
||||||
m_path_pairs.append(pair);
|
m_path_pairs.append(pair);
|
||||||
}
|
}
|
||||||
create_link& useHardLinks(const bool useHard)
|
create_link& useHardLinks(const bool useHard)
|
||||||
@ -211,28 +208,23 @@ class create_link : public QObject {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code getOSError() {
|
std::error_code getOSError() { return m_os_err; }
|
||||||
return m_os_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); }
|
bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); }
|
||||||
|
|
||||||
int totalLinked() { return m_linked; }
|
int totalLinked() { return m_linked; }
|
||||||
|
|
||||||
|
|
||||||
void runPrivileged() { runPrivileged(QString()); }
|
void runPrivileged() { runPrivileged(QString()); }
|
||||||
void runPrivileged(const QString& offset);
|
void runPrivileged(const QString& offset);
|
||||||
|
|
||||||
QList<LinkResult> getResults() { return m_path_results; }
|
QList<LinkResult> getResults() { return m_path_results; }
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void fileLinked(const QString& srcName, const QString& dstName);
|
void fileLinked(const QString& srcName, const QString& dstName);
|
||||||
void linkFailed(const QString& srcName, const QString& dstName, const QString& err_msg, int err_value);
|
void linkFailed(const QString& srcName, const QString& dstName, const QString& err_msg, int err_value);
|
||||||
void finished();
|
void finished();
|
||||||
void finishedPrivileged(bool gotResults);
|
void finishedPrivileged(bool gotResults);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool operator()(const QString& offset, bool dryRun = false);
|
bool operator()(const QString& offset, bool dryRun = false);
|
||||||
void make_link_list(const QString& offset);
|
void make_link_list(const QString& offset);
|
||||||
@ -262,9 +254,9 @@ class create_link : public QObject {
|
|||||||
* @brief moves a file by renaming it
|
* @brief moves a file by renaming it
|
||||||
* @param source source file path
|
* @param source source file path
|
||||||
* @param dest destination filepath
|
* @param dest destination filepath
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool move(const QString& source, const QString& dest);
|
bool move(const QString& source, const QString& dest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a folder recursively
|
* Delete a folder recursively
|
||||||
@ -274,7 +266,7 @@ bool deletePath(QString path);
|
|||||||
/**
|
/**
|
||||||
* Trash a folder / file
|
* Trash a folder / file
|
||||||
*/
|
*/
|
||||||
bool trash(QString path, QString *pathInTrash = nullptr);
|
bool trash(QString path, QString* pathInTrash = nullptr);
|
||||||
|
|
||||||
QString PathCombine(const QString& path1, const QString& path2);
|
QString PathCombine(const QString& path1, const QString& path2);
|
||||||
QString PathCombine(const QString& path1, const QString& path2, const QString& path3);
|
QString PathCombine(const QString& path1, const QString& path2, const QString& path3);
|
||||||
@ -284,16 +276,15 @@ QString AbsolutePath(const QString& path);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief depth of path. "foo.txt" -> 0 , "bar/foo.txt" -> 1, /baz/bar/foo.txt -> 2, etc.
|
* @brief depth of path. "foo.txt" -> 0 , "bar/foo.txt" -> 1, /baz/bar/foo.txt -> 2, etc.
|
||||||
*
|
*
|
||||||
* @param path path to measure
|
* @param path path to measure
|
||||||
* @return int number of componants before base path
|
* @return int number of components before base path
|
||||||
*/
|
*/
|
||||||
int PathDepth(const QString& path);
|
int PathDepth(const QString& path);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief cut off segments of path untill it is a max of length depth
|
* @brief cut off segments of path until it is a max of length depth
|
||||||
*
|
*
|
||||||
* @param path path to truncate
|
* @param path path to truncate
|
||||||
* @param depth max depth of new path
|
* @param depth max depth of new path
|
||||||
* @return QString truncated path
|
* @return QString truncated path
|
||||||
@ -363,124 +354,118 @@ enum class FilesystemType {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Ordered Mapping of enum types to reported filesystem names
|
* @brief Ordered Mapping of enum types to reported filesystem names
|
||||||
* this maping is non exsaustive, it just attempts to capture the filesystems which could be reasonalbly be in use .
|
* this mapping is non exsaustive, it just attempts to capture the filesystems which could be reasonalbly be in use .
|
||||||
* all string values are in uppercase, use `QString.toUpper()` or equivalent during lookup.
|
* all string values are in uppercase, use `QString.toUpper()` or equivalent during lookup.
|
||||||
*
|
*
|
||||||
* QMap is ordered
|
* QMap is ordered
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static const QMap<FilesystemType, QString> s_filesystem_type_names = {
|
static const QMap<FilesystemType, QString> s_filesystem_type_names = { { FilesystemType::FAT, QString("FAT") },
|
||||||
{FilesystemType::FAT, QString("FAT")},
|
{ FilesystemType::NTFS, QString("NTFS") },
|
||||||
{FilesystemType::NTFS, QString("NTFS")},
|
{ FilesystemType::REFS, QString("REFS") },
|
||||||
{FilesystemType::REFS, QString("REFS")},
|
{ FilesystemType::EXT, QString("EXT") },
|
||||||
{FilesystemType::EXT, QString("EXT")},
|
{ FilesystemType::EXT_2_OLD, QString("EXT_2_OLD") },
|
||||||
{FilesystemType::EXT_2_OLD, QString("EXT_2_OLD")},
|
{ FilesystemType::EXT_2_3_4, QString("EXT2/3/4") },
|
||||||
{FilesystemType::EXT_2_3_4, QString("EXT2/3/4")},
|
{ FilesystemType::XFS, QString("XFS") },
|
||||||
{FilesystemType::XFS, QString("XFS")},
|
{ FilesystemType::BTRFS, QString("BTRFS") },
|
||||||
{FilesystemType::BTRFS, QString("BTRFS")},
|
{ FilesystemType::NFS, QString("NFS") },
|
||||||
{FilesystemType::NFS, QString("NFS")},
|
{ FilesystemType::ZFS, QString("ZFS") },
|
||||||
{FilesystemType::ZFS, QString("ZFS")},
|
{ FilesystemType::APFS, QString("APFS") },
|
||||||
{FilesystemType::APFS, QString("APFS")},
|
{ FilesystemType::HFS, QString("HFS") },
|
||||||
{FilesystemType::HFS, QString("HFS")},
|
{ FilesystemType::HFSPLUS, QString("HFSPLUS") },
|
||||||
{FilesystemType::HFSPLUS, QString("HFSPLUS")},
|
{ FilesystemType::HFSX, QString("HFSX") },
|
||||||
{FilesystemType::HFSX, QString("HFSX")},
|
{ FilesystemType::FUSEBLK, QString("FUSEBLK") },
|
||||||
{FilesystemType::FUSEBLK, QString("FUSEBLK")},
|
{ FilesystemType::F2FS, QString("F2FS") },
|
||||||
{FilesystemType::F2FS, QString("F2FS")},
|
{ FilesystemType::UNKNOWN, QString("UNKNOWN") } };
|
||||||
{FilesystemType::UNKNOWN, QString("UNKNOWN")}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Ordered Mapping of reported filesystem names to enum types
|
* @brief Ordered Mapping of reported filesystem names to enum types
|
||||||
* this maping is non exsaustive, it just attempts to capture the many way these filesystems could be reported.
|
* this mapping is non exsaustive, it just attempts to capture the many way these filesystems could be reported.
|
||||||
* all keys are in uppercase, use `QString.toUpper()` or equivalent during lookup.
|
* all keys are in uppercase, use `QString.toUpper()` or equivalent during lookup.
|
||||||
*
|
*
|
||||||
* QMap is ordered
|
* QMap is ordered
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static const QMap<QString, FilesystemType> s_filesystem_type_names_inverse = {
|
static const QMap<QString, FilesystemType> s_filesystem_type_names_inverse = {
|
||||||
{QString("FAT"), FilesystemType::FAT},
|
{ QString("FAT"), FilesystemType::FAT },
|
||||||
{QString("NTFS"), FilesystemType::NTFS},
|
{ QString("NTFS"), FilesystemType::NTFS },
|
||||||
{QString("REFS"), FilesystemType::REFS},
|
{ QString("REFS"), FilesystemType::REFS },
|
||||||
{QString("EXT2_OLD"), FilesystemType::EXT_2_OLD},
|
{ QString("EXT2_OLD"), FilesystemType::EXT_2_OLD },
|
||||||
{QString("EXT_2_OLD"), FilesystemType::EXT_2_OLD},
|
{ QString("EXT_2_OLD"), FilesystemType::EXT_2_OLD },
|
||||||
{QString("EXT2"), FilesystemType::EXT_2_3_4},
|
{ QString("EXT2"), FilesystemType::EXT_2_3_4 },
|
||||||
{QString("EXT3"), FilesystemType::EXT_2_3_4},
|
{ QString("EXT3"), FilesystemType::EXT_2_3_4 },
|
||||||
{QString("EXT4"), FilesystemType::EXT_2_3_4},
|
{ QString("EXT4"), FilesystemType::EXT_2_3_4 },
|
||||||
{QString("EXT2/3/4"), FilesystemType::EXT_2_3_4},
|
{ QString("EXT2/3/4"), FilesystemType::EXT_2_3_4 },
|
||||||
{QString("EXT_2_3_4"), FilesystemType::EXT_2_3_4},
|
{ QString("EXT_2_3_4"), FilesystemType::EXT_2_3_4 },
|
||||||
{QString("EXT"), FilesystemType::EXT}, // must come after all other EXT variants to prevent greedy detection
|
{ QString("EXT"), FilesystemType::EXT }, // must come after all other EXT variants to prevent greedy detection
|
||||||
{QString("XFS"), FilesystemType::XFS},
|
{ QString("XFS"), FilesystemType::XFS },
|
||||||
{QString("BTRFS"), FilesystemType::BTRFS},
|
{ QString("BTRFS"), FilesystemType::BTRFS },
|
||||||
{QString("NFS"), FilesystemType::NFS},
|
{ QString("NFS"), FilesystemType::NFS },
|
||||||
{QString("ZFS"), FilesystemType::ZFS},
|
{ QString("ZFS"), FilesystemType::ZFS },
|
||||||
{QString("APFS"), FilesystemType::APFS},
|
{ QString("APFS"), FilesystemType::APFS },
|
||||||
{QString("HFSPLUS"), FilesystemType::HFSPLUS},
|
{ QString("HFSPLUS"), FilesystemType::HFSPLUS },
|
||||||
{QString("HFSX"), FilesystemType::HFSX},
|
{ QString("HFSX"), FilesystemType::HFSX },
|
||||||
{QString("HFS"), FilesystemType::HFS},
|
{ QString("HFS"), FilesystemType::HFS },
|
||||||
{QString("FUSEBLK"), FilesystemType::FUSEBLK},
|
{ QString("FUSEBLK"), FilesystemType::FUSEBLK },
|
||||||
{QString("F2FS"), FilesystemType::F2FS},
|
{ QString("F2FS"), FilesystemType::F2FS },
|
||||||
{QString("UNKNOWN"), FilesystemType::UNKNOWN}
|
{ QString("UNKNOWN"), FilesystemType::UNKNOWN }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the string name of Filesystem enum object
|
* @brief Get the string name of Filesystem enum object
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
* @return QString
|
* @return QString
|
||||||
*/
|
*/
|
||||||
QString getFilesystemTypeName(FilesystemType type);
|
QString getFilesystemTypeName(FilesystemType type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the Filesystem enum object from a name
|
* @brief Get the Filesystem enum object from a name
|
||||||
* Does a lookup of the type name and returns an exact match
|
* Does a lookup of the type name and returns an exact match
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* @return FilesystemType
|
* @return FilesystemType
|
||||||
*/
|
*/
|
||||||
FilesystemType getFilesystemType(const QString& name);
|
FilesystemType getFilesystemType(const QString& name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the Filesystem enum object from a name
|
* @brief Get the Filesystem enum object from a name
|
||||||
* Does a fuzzy lookup of the type name and returns an apropreate match
|
* Does a fuzzy lookup of the type name and returns an apropreate match
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* @return FilesystemType
|
* @return FilesystemType
|
||||||
*/
|
*/
|
||||||
FilesystemType getFilesystemTypeFuzzy(const QString& name);
|
FilesystemType getFilesystemTypeFuzzy(const QString& name);
|
||||||
|
|
||||||
|
|
||||||
struct FilesystemInfo {
|
struct FilesystemInfo {
|
||||||
FilesystemType fsType = FilesystemType::UNKNOWN;
|
FilesystemType fsType = FilesystemType::UNKNOWN;
|
||||||
QString fsTypeName;
|
QString fsTypeName;
|
||||||
int blockSize;
|
int blockSize;
|
||||||
qint64 bytesAvailable;
|
qint64 bytesAvailable;
|
||||||
qint64 bytesFree;
|
qint64 bytesFree;
|
||||||
qint64 bytesTotal;
|
qint64 bytesTotal;
|
||||||
QString name;
|
QString name;
|
||||||
QString rootPath;
|
QString rootPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief path to the near ancestor that exsists
|
* @brief path to the near ancestor that exists
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
QString NearestExistentAncestor(const QString& path);
|
QString NearestExistentAncestor(const QString& path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief colect information about the filesystem under a file
|
* @brief colect information about the filesystem under a file
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
FilesystemInfo statFS(const QString& path);
|
FilesystemInfo statFS(const QString& path);
|
||||||
|
|
||||||
static const QList<FilesystemType> s_clone_filesystems = {
|
static const QList<FilesystemType> s_clone_filesystems = { FilesystemType::BTRFS, FilesystemType::APFS, FilesystemType::ZFS,
|
||||||
FilesystemType::BTRFS, FilesystemType::APFS, FilesystemType::ZFS,
|
FilesystemType::XFS, FilesystemType::REFS };
|
||||||
FilesystemType::XFS, FilesystemType::REFS
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief if the Filesystem is reflink/clone capable
|
* @brief if the Filesystem is reflink/clone capable
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool canCloneOnFS(const QString& path);
|
bool canCloneOnFS(const QString& path);
|
||||||
bool canCloneOnFS(const FilesystemInfo& info);
|
bool canCloneOnFS(const FilesystemInfo& info);
|
||||||
@ -488,13 +473,13 @@ bool canCloneOnFS(FilesystemType type);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief if the Filesystems are reflink/clone capable and both are on the same device
|
* @brief if the Filesystems are reflink/clone capable and both are on the same device
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool canClone(const QString& src, const QString& dst);
|
bool canClone(const QString& src, const QString& dst);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies a directory and it's contents from src to dest
|
* @brief Copies a directory and it's contents from src to dest
|
||||||
*/
|
*/
|
||||||
class clone : public QObject {
|
class clone : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -535,7 +520,7 @@ class clone : public QObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief clone/reflink file from src to dst
|
* @brief clone/reflink file from src to dst
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool clone_file(const QString& src, const QString& dst, std::error_code& ec);
|
bool clone_file(const QString& src, const QString& dst, std::error_code& ec);
|
||||||
|
|
||||||
@ -552,8 +537,8 @@ static const QList<FilesystemType> s_non_link_filesystems = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief if the Filesystem is symlink capable
|
* @brief if the Filesystem is symlink capable
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool canLinkOnFS(const QString& path);
|
bool canLinkOnFS(const QString& path);
|
||||||
bool canLinkOnFS(const FilesystemInfo& info);
|
bool canLinkOnFS(const FilesystemInfo& info);
|
||||||
@ -561,10 +546,10 @@ bool canLinkOnFS(FilesystemType type);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief if the Filesystem is symlink capable on both ends
|
* @brief if the Filesystem is symlink capable on both ends
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool canLink(const QString& src, const QString& dst);
|
bool canLink(const QString& src, const QString& dst);
|
||||||
|
|
||||||
uintmax_t hardLinkCount(const QString& path);
|
uintmax_t hardLinkCount(const QString& path);
|
||||||
|
|
||||||
}
|
} // namespace FS
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#include "InstanceCopyTask.h"
|
#include "InstanceCopyTask.h"
|
||||||
#include "settings/INISettingsObject.h"
|
#include <QDebug>
|
||||||
|
#include <QtConcurrentRun>
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "NullInstance.h"
|
#include "NullInstance.h"
|
||||||
#include "pathmatcher/RegexpMatcher.h"
|
#include "pathmatcher/RegexpMatcher.h"
|
||||||
#include <QtConcurrentRun>
|
#include "settings/INISettingsObject.h"
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs)
|
InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs)
|
||||||
{
|
{
|
||||||
@ -15,17 +15,17 @@ InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyP
|
|||||||
m_useHardLinks = prefs.isLinkRecursivelyEnabled() && prefs.isUseHardLinksEnabled();
|
m_useHardLinks = prefs.isLinkRecursivelyEnabled() && prefs.isUseHardLinksEnabled();
|
||||||
m_copySaves = prefs.isLinkRecursivelyEnabled() && prefs.isDontLinkSavesEnabled() && prefs.isCopySavesEnabled();
|
m_copySaves = prefs.isLinkRecursivelyEnabled() && prefs.isDontLinkSavesEnabled() && prefs.isCopySavesEnabled();
|
||||||
m_useClone = prefs.isUseCloneEnabled();
|
m_useClone = prefs.isUseCloneEnabled();
|
||||||
|
|
||||||
QString filters = prefs.getSelectedFiltersAsRegex();
|
QString filters = prefs.getSelectedFiltersAsRegex();
|
||||||
if (m_useLinks || m_useHardLinks) {
|
if (m_useLinks || m_useHardLinks) {
|
||||||
if (!filters.isEmpty()) filters += "|";
|
if (!filters.isEmpty())
|
||||||
|
filters += "|";
|
||||||
filters += "instance.cfg";
|
filters += "instance.cfg";
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "CopyFilters:" << filters;
|
qDebug() << "CopyFilters:" << filters;
|
||||||
|
|
||||||
if (!filters.isEmpty())
|
if (!filters.isEmpty()) {
|
||||||
{
|
|
||||||
// Set regex filter:
|
// Set regex filter:
|
||||||
// FIXME: get this from the original instance type...
|
// FIXME: get this from the original instance type...
|
||||||
auto matcherReal = new RegexpMatcher(filters);
|
auto matcherReal = new RegexpMatcher(filters);
|
||||||
@ -38,14 +38,14 @@ void InstanceCopyTask::executeTask()
|
|||||||
{
|
{
|
||||||
setStatus(tr("Copying instance %1").arg(m_origInstance->name()));
|
setStatus(tr("Copying instance %1").arg(m_origInstance->name()));
|
||||||
|
|
||||||
auto copySaves = [&](){
|
auto copySaves = [&]() {
|
||||||
FS::copy savesCopy(FS::PathCombine(m_origInstance->instanceRoot(), "saves") , FS::PathCombine(m_stagingPath, "saves"));
|
FS::copy savesCopy(FS::PathCombine(m_origInstance->instanceRoot(), "saves"), FS::PathCombine(m_stagingPath, "saves"));
|
||||||
savesCopy.followSymlinks(true);
|
savesCopy.followSymlinks(true);
|
||||||
|
|
||||||
return savesCopy();
|
return savesCopy();
|
||||||
};
|
};
|
||||||
|
|
||||||
m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this, copySaves]{
|
m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this, copySaves] {
|
||||||
if (m_useClone) {
|
if (m_useClone) {
|
||||||
FS::clone folderClone(m_origInstance->instanceRoot(), m_stagingPath);
|
FS::clone folderClone(m_origInstance->instanceRoot(), m_stagingPath);
|
||||||
folderClone.matcher(m_matcher.get());
|
folderClone.matcher(m_matcher.get());
|
||||||
@ -53,22 +53,22 @@ void InstanceCopyTask::executeTask()
|
|||||||
return folderClone();
|
return folderClone();
|
||||||
} else if (m_useLinks || m_useHardLinks) {
|
} else if (m_useLinks || m_useHardLinks) {
|
||||||
FS::create_link folderLink(m_origInstance->instanceRoot(), m_stagingPath);
|
FS::create_link folderLink(m_origInstance->instanceRoot(), m_stagingPath);
|
||||||
int depth = m_linkRecursively ? -1 : 0; // we need to at least link the top level instead of the instance folder
|
int depth = m_linkRecursively ? -1 : 0; // we need to at least link the top level instead of the instance folder
|
||||||
folderLink.linkRecursively(true).setMaxDepth(depth).useHardLinks(m_useHardLinks).matcher(m_matcher.get());
|
folderLink.linkRecursively(true).setMaxDepth(depth).useHardLinks(m_useHardLinks).matcher(m_matcher.get());
|
||||||
|
|
||||||
bool there_were_errors = false;
|
bool there_were_errors = false;
|
||||||
|
|
||||||
if(!folderLink()){
|
if (!folderLink()) {
|
||||||
#if defined Q_OS_WIN32
|
#if defined Q_OS_WIN32
|
||||||
if (!m_useHardLinks) {
|
if (!m_useHardLinks) {
|
||||||
qDebug() << "EXPECTED: Link failure, Windows requires permissions for symlinks";
|
qDebug() << "EXPECTED: Link failure, Windows requires permissions for symlinks";
|
||||||
|
|
||||||
qDebug() << "atempting to run with privelage";
|
qDebug() << "attempting to run with privelage";
|
||||||
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
bool got_priv_results = false;
|
bool got_priv_results = false;
|
||||||
|
|
||||||
connect(&folderLink, &FS::create_link::finishedPrivileged, this, [&](bool gotResults){
|
connect(&folderLink, &FS::create_link::finishedPrivileged, this, [&](bool gotResults) {
|
||||||
if (!gotResults) {
|
if (!gotResults) {
|
||||||
qDebug() << "Privileged run exited without results!";
|
qDebug() << "Privileged run exited without results!";
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ void InstanceCopyTask::executeTask()
|
|||||||
});
|
});
|
||||||
folderLink.runPrivileged();
|
folderLink.runPrivileged();
|
||||||
|
|
||||||
loop.exec(); // wait for the finished signal
|
loop.exec(); // wait for the finished signal
|
||||||
|
|
||||||
for (auto result : folderLink.getResults()) {
|
for (auto result : folderLink.getResults()) {
|
||||||
if (result.err_value != 0) {
|
if (result.err_value != 0) {
|
||||||
@ -88,17 +88,17 @@ void InstanceCopyTask::executeTask()
|
|||||||
if (m_copySaves) {
|
if (m_copySaves) {
|
||||||
there_were_errors |= !copySaves();
|
there_were_errors |= !copySaves();
|
||||||
}
|
}
|
||||||
|
|
||||||
return got_priv_results && !there_were_errors;
|
return got_priv_results && !there_were_errors;
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Link Failed!" << folderLink.getOSError().value() << folderLink.getOSError().message().c_str();
|
qDebug() << "Link Failed!" << folderLink.getOSError().value() << folderLink.getOSError().message().c_str();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
qDebug() << "Link Failed!" << folderLink.getOSError().value() << folderLink.getOSError().message().c_str();
|
qDebug() << "Link Failed!" << folderLink.getOSError().value() << folderLink.getOSError().message().c_str();
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_copySaves) {
|
if (m_copySaves) {
|
||||||
there_were_errors |= !copySaves();
|
there_were_errors |= !copySaves();
|
||||||
}
|
}
|
||||||
@ -119,8 +119,7 @@ void InstanceCopyTask::executeTask()
|
|||||||
void InstanceCopyTask::copyFinished()
|
void InstanceCopyTask::copyFinished()
|
||||||
{
|
{
|
||||||
auto successful = m_copyFuture.result();
|
auto successful = m_copyFuture.result();
|
||||||
if(!successful)
|
if (!successful) {
|
||||||
{
|
|
||||||
emitFailed(tr("Instance folder copy failed."));
|
emitFailed(tr("Instance folder copy failed."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -130,7 +129,7 @@ void InstanceCopyTask::copyFinished()
|
|||||||
InstancePtr inst(new NullInstance(m_globalSettings, instanceSettings, m_stagingPath));
|
InstancePtr inst(new NullInstance(m_globalSettings, instanceSettings, m_stagingPath));
|
||||||
inst->setName(name());
|
inst->setName(name());
|
||||||
inst->setIconKey(m_instIcon);
|
inst->setIconKey(m_instIcon);
|
||||||
if(!m_keepPlaytime) {
|
if (!m_keepPlaytime) {
|
||||||
inst->resetTimePlayed();
|
inst->resetTimePlayed();
|
||||||
}
|
}
|
||||||
if (m_useLinks)
|
if (m_useLinks)
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <QAccessible>
|
#include <QAccessible>
|
||||||
@ -41,53 +40,47 @@
|
|||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Snippet from https://github.com/gulrak/filesystem#using-it-as-single-file-header
|
// Snippet from https://github.com/gulrak/filesystem#using-it-as-single-file-header
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <Availability.h> // for deployment target to support pre-catalina targets without std::fs
|
#include <Availability.h> // for deployment target to support pre-catalina targets without std::fs
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
#define GHC_USE_STD_FS
|
#define GHC_USE_STD_FS
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
#endif // MacOS min version check
|
#endif // MacOS min version check
|
||||||
#endif // Other OSes version check
|
#endif // Other OSes version check
|
||||||
|
|
||||||
#ifndef GHC_USE_STD_FS
|
#ifndef GHC_USE_STD_FS
|
||||||
#include <ghc/filesystem.hpp>
|
#include <ghc/filesystem.hpp>
|
||||||
namespace fs = ghc::filesystem;
|
namespace fs = ghc::filesystem;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FileLinkApp::FileLinkApp(int& argc, char** argv) : QCoreApplication(argc, argv), socket(new QLocalSocket(this))
|
||||||
|
|
||||||
FileLinkApp::FileLinkApp(int &argc, char **argv) : QCoreApplication(argc, argv), socket(new QLocalSocket(this))
|
|
||||||
{
|
{
|
||||||
#if defined Q_OS_WIN32
|
#if defined Q_OS_WIN32
|
||||||
// attach the parent console
|
// attach the parent console
|
||||||
if(AttachConsole(ATTACH_PARENT_PROCESS))
|
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||||
{
|
|
||||||
// if attach succeeds, reopen and sync all the i/o
|
// if attach succeeds, reopen and sync all the i/o
|
||||||
if(freopen("CON", "w", stdout))
|
if (freopen("CON", "w", stdout)) {
|
||||||
{
|
|
||||||
std::cout.sync_with_stdio();
|
std::cout.sync_with_stdio();
|
||||||
}
|
}
|
||||||
if(freopen("CON", "w", stderr))
|
if (freopen("CON", "w", stderr)) {
|
||||||
{
|
|
||||||
std::cerr.sync_with_stdio();
|
std::cerr.sync_with_stdio();
|
||||||
}
|
}
|
||||||
if(freopen("CON", "r", stdin))
|
if (freopen("CON", "r", stdin)) {
|
||||||
{
|
|
||||||
std::cin.sync_with_stdio();
|
std::cin.sync_with_stdio();
|
||||||
}
|
}
|
||||||
auto out = GetStdHandle (STD_OUTPUT_HANDLE);
|
auto out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
DWORD written;
|
DWORD written;
|
||||||
const char * endline = "\n";
|
const char* endline = "\n";
|
||||||
WriteConsole(out, endline, strlen(endline), &written, NULL);
|
WriteConsole(out, endline, strlen(endline), &written, NULL);
|
||||||
consoleAttached = true;
|
consoleAttached = true;
|
||||||
}
|
}
|
||||||
@ -101,10 +94,8 @@ FileLinkApp::FileLinkApp(int &argc, char **argv) : QCoreApplication(argc, argv),
|
|||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription(QObject::tr("a batch MKLINK program for windows to be used with prismlauncher"));
|
parser.setApplicationDescription(QObject::tr("a batch MKLINK program for windows to be used with prismlauncher"));
|
||||||
|
|
||||||
parser.addOptions({
|
parser.addOptions({ { { "s", "server" }, "Join the specified server on launch", "pipe name" },
|
||||||
{{"s", "server"}, "Join the specified server on launch", "pipe name"},
|
{ { "H", "hard" }, "use hard links instead of symbolic", "true/false" } });
|
||||||
{{"H", "hard"}, "use hard links insted of symbolic", "true/false"}
|
|
||||||
});
|
|
||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
parser.addVersionOption();
|
parser.addVersionOption();
|
||||||
|
|
||||||
@ -122,63 +113,57 @@ FileLinkApp::FileLinkApp(int &argc, char **argv) : QCoreApplication(argc, argv),
|
|||||||
qDebug() << "no server to join";
|
qDebug() << "no server to join";
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileLinkApp::joinServer(QString server)
|
void FileLinkApp::joinServer(QString server)
|
||||||
{
|
{
|
||||||
|
blockSize = 0;
|
||||||
blockSize = 0;
|
|
||||||
|
|
||||||
in.setDevice(&socket);
|
in.setDevice(&socket);
|
||||||
in.setVersion(QDataStream::Qt_5_0);
|
in.setVersion(QDataStream::Qt_5_0);
|
||||||
|
|
||||||
connect(&socket, &QLocalSocket::connected, this, [&](){
|
connect(&socket, &QLocalSocket::connected, this, [&]() { qDebug() << "connected to server"; });
|
||||||
qDebug() << "connected to server";
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(&socket, &QLocalSocket::readyRead, this, &FileLinkApp::readPathPairs);
|
connect(&socket, &QLocalSocket::readyRead, this, &FileLinkApp::readPathPairs);
|
||||||
|
|
||||||
connect(&socket, &QLocalSocket::errorOccurred, this, [&](QLocalSocket::LocalSocketError socketError){
|
connect(&socket, &QLocalSocket::errorOccurred, this, [&](QLocalSocket::LocalSocketError socketError) {
|
||||||
switch (socketError) {
|
switch (socketError) {
|
||||||
case QLocalSocket::ServerNotFoundError:
|
case QLocalSocket::ServerNotFoundError:
|
||||||
qDebug() << ("The host was not found. Please make sure "
|
qDebug()
|
||||||
|
<< ("The host was not found. Please make sure "
|
||||||
"that the server is running and that the "
|
"that the server is running and that the "
|
||||||
"server name is correct.");
|
"server name is correct.");
|
||||||
break;
|
break;
|
||||||
case QLocalSocket::ConnectionRefusedError:
|
case QLocalSocket::ConnectionRefusedError:
|
||||||
qDebug() << ("The connection was refused by the peer. "
|
qDebug()
|
||||||
|
<< ("The connection was refused by the peer. "
|
||||||
"Make sure the server is running, "
|
"Make sure the server is running, "
|
||||||
"and check that the server name "
|
"and check that the server name "
|
||||||
"is correct.");
|
"is correct.");
|
||||||
break;
|
break;
|
||||||
case QLocalSocket::PeerClosedError:
|
case QLocalSocket::PeerClosedError:
|
||||||
qDebug() << ("The connection was closed by the peer. ");
|
qDebug() << ("The connection was closed by the peer. ");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qDebug() << "The following error occurred: " << socket.errorString();
|
qDebug() << "The following error occurred: " << socket.errorString();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&socket, &QLocalSocket::disconnected, this, [&](){
|
connect(&socket, &QLocalSocket::disconnected, this, [&]() {
|
||||||
qDebug() << "dissconnected from server, should exit";
|
qDebug() << "disconnected from server, should exit";
|
||||||
exit();
|
exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.connectToServer(server);
|
socket.connectToServer(server);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileLinkApp::runLink()
|
void FileLinkApp::runLink()
|
||||||
{
|
{
|
||||||
|
|
||||||
std::error_code os_err;
|
std::error_code os_err;
|
||||||
|
|
||||||
qDebug() << "creating links";
|
qDebug() << "creating links";
|
||||||
|
|
||||||
for (auto link : m_links_to_make) {
|
for (auto link : m_links_to_make) {
|
||||||
|
|
||||||
QString src_path = link.src;
|
QString src_path = link.src;
|
||||||
QString dst_path = link.dst;
|
QString dst_path = link.dst;
|
||||||
|
|
||||||
@ -192,26 +177,25 @@ void FileLinkApp::runLink()
|
|||||||
} else {
|
} else {
|
||||||
qDebug() << "making symlink:" << src_path << "to" << dst_path;
|
qDebug() << "making symlink:" << src_path << "to" << dst_path;
|
||||||
fs::create_symlink(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), os_err);
|
fs::create_symlink(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), os_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (os_err) {
|
if (os_err) {
|
||||||
qWarning() << "Failed to link files:" << QString::fromStdString(os_err.message());
|
qWarning() << "Failed to link files:" << QString::fromStdString(os_err.message());
|
||||||
qDebug() << "Source file:" << src_path;
|
qDebug() << "Source file:" << src_path;
|
||||||
qDebug() << "Destination file:" << dst_path;
|
qDebug() << "Destination file:" << dst_path;
|
||||||
qDebug() << "Error catagory:" << os_err.category().name();
|
qDebug() << "Error category:" << os_err.category().name();
|
||||||
qDebug() << "Error code:" << os_err.value();
|
qDebug() << "Error code:" << os_err.value();
|
||||||
|
|
||||||
FS::LinkResult result = {src_path, dst_path, QString::fromStdString(os_err.message()), os_err.value()};
|
FS::LinkResult result = { src_path, dst_path, QString::fromStdString(os_err.message()), os_err.value() };
|
||||||
m_path_results.append(result);
|
m_path_results.append(result);
|
||||||
} else {
|
} else {
|
||||||
FS::LinkResult result = {src_path, dst_path};
|
FS::LinkResult result = { src_path, dst_path };
|
||||||
m_path_results.append(result);
|
m_path_results.append(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendResults();
|
sendResults();
|
||||||
qDebug() << "done, should exit soon";
|
qDebug() << "done, should exit soon";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileLinkApp::sendResults()
|
void FileLinkApp::sendResults()
|
||||||
@ -245,10 +229,10 @@ void FileLinkApp::sendResults()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FileLinkApp::readPathPairs()
|
void FileLinkApp::readPathPairs()
|
||||||
{
|
{
|
||||||
m_links_to_make.clear();
|
m_links_to_make.clear();
|
||||||
qDebug() << "Reading path pairs from server";
|
qDebug() << "Reading path pairs from server";
|
||||||
qDebug() << "bytes avalible" << socket.bytesAvailable();
|
qDebug() << "bytes available" << socket.bytesAvailable();
|
||||||
if (blockSize == 0) {
|
if (blockSize == 0) {
|
||||||
// Relies on the fact that QDataStream serializes a quint32 into
|
// Relies on the fact that QDataStream serializes a quint32 into
|
||||||
// sizeof(quint32) bytes
|
// sizeof(quint32) bytes
|
||||||
@ -258,15 +242,15 @@ void FileLinkApp::readPathPairs()
|
|||||||
in >> blockSize;
|
in >> blockSize;
|
||||||
}
|
}
|
||||||
qDebug() << "blocksize is" << blockSize;
|
qDebug() << "blocksize is" << blockSize;
|
||||||
qDebug() << "bytes avalible" << socket.bytesAvailable();
|
qDebug() << "bytes available" << socket.bytesAvailable();
|
||||||
if (socket.bytesAvailable() < blockSize || in.atEnd())
|
if (socket.bytesAvailable() < blockSize || in.atEnd())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
quint32 numLinks;
|
quint32 numLinks;
|
||||||
in >> numLinks;
|
in >> numLinks;
|
||||||
qDebug() << "numLinks" << numLinks;
|
qDebug() << "numLinks" << numLinks;
|
||||||
|
|
||||||
for(int i = 0; i < numLinks; i++) {
|
for (int i = 0; i < numLinks; i++) {
|
||||||
FS::LinkPair pair;
|
FS::LinkPair pair;
|
||||||
in >> pair.src;
|
in >> pair.src;
|
||||||
in >> pair.dst;
|
in >> pair.dst;
|
||||||
@ -277,17 +261,15 @@ void FileLinkApp::readPathPairs()
|
|||||||
runLink();
|
runLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FileLinkApp::~FileLinkApp()
|
FileLinkApp::~FileLinkApp()
|
||||||
{
|
{
|
||||||
qDebug() << "link program shutting down";
|
qDebug() << "link program shutting down";
|
||||||
// Shut down logger by setting the logger function to nothing
|
// Shut down logger by setting the logger function to nothing
|
||||||
qInstallMessageHandler(nullptr);
|
qInstallMessageHandler(nullptr);
|
||||||
|
|
||||||
#if defined Q_OS_WIN32
|
#if defined Q_OS_WIN32
|
||||||
// Detach from Windows console
|
// Detach from Windows console
|
||||||
if(consoleAttached)
|
if (consoleAttached) {
|
||||||
{
|
|
||||||
fclose(stdout);
|
fclose(stdout);
|
||||||
fclose(stdin);
|
fclose(stdin);
|
||||||
fclose(stderr);
|
fclose(stderr);
|
||||||
@ -295,7 +277,3 @@ FileLinkApp::~FileLinkApp()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,30 +25,26 @@
|
|||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <memory>
|
#include <QDataStream>
|
||||||
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFlag>
|
#include <QFlag>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QDateTime>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QDataStream>
|
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#define PRISM_EXTERNAL_EXE
|
#define PRISM_EXTERNAL_EXE
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
|
|
||||||
class FileLinkApp : public QCoreApplication
|
class FileLinkApp : public QCoreApplication {
|
||||||
{
|
|
||||||
// friends for the purpose of limiting access to deprecated stuff
|
// friends for the purpose of limiting access to deprecated stuff
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
FileLinkApp(int& argc, char** argv);
|
||||||
FileLinkApp(int &argc, char **argv);
|
|
||||||
virtual ~FileLinkApp();
|
virtual ~FileLinkApp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void joinServer(QString server);
|
void joinServer(QString server);
|
||||||
void readPathPairs();
|
void readPathPairs();
|
||||||
void runLink();
|
void runLink();
|
||||||
|
@ -22,10 +22,9 @@
|
|||||||
|
|
||||||
#include "FileLink.h"
|
#include "FileLink.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
|
||||||
FileLinkApp ldh(argc, argv);
|
FileLinkApp ldh(argc, argv);
|
||||||
|
|
||||||
return ldh.exec();
|
return ldh.exec();
|
||||||
}
|
}
|
||||||
|
@ -43,15 +43,15 @@
|
|||||||
|
|
||||||
#include "ui/dialogs/IconPickerDialog.h"
|
#include "ui/dialogs/IconPickerDialog.h"
|
||||||
|
|
||||||
#include "BaseVersion.h"
|
|
||||||
#include "icons/IconList.h"
|
|
||||||
#include "BaseInstance.h"
|
#include "BaseInstance.h"
|
||||||
#include "InstanceList.h"
|
#include "BaseVersion.h"
|
||||||
#include "FileSystem.h"
|
|
||||||
#include "DesktopServices.h"
|
#include "DesktopServices.h"
|
||||||
|
#include "FileSystem.h"
|
||||||
|
#include "InstanceList.h"
|
||||||
|
#include "icons/IconList.h"
|
||||||
|
|
||||||
CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent)
|
CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget* parent)
|
||||||
:QDialog(parent), ui(new Ui::CopyInstanceDialog), m_original(original)
|
: QDialog(parent), ui(new Ui::CopyInstanceDialog), m_original(original)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
resize(minimumSizeHint());
|
resize(minimumSizeHint());
|
||||||
@ -74,8 +74,7 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent)
|
|||||||
groupList.push_front("");
|
groupList.push_front("");
|
||||||
ui->groupBox->addItems(groupList);
|
ui->groupBox->addItems(groupList);
|
||||||
int index = groupList.indexOf(APPLICATION->instances()->getInstanceGroup(m_original->id()));
|
int index = groupList.indexOf(APPLICATION->instances()->getInstanceGroup(m_original->id()));
|
||||||
if(index == -1)
|
if (index == -1) {
|
||||||
{
|
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
ui->groupBox->setCurrentIndex(index);
|
ui->groupBox->setCurrentIndex(index);
|
||||||
@ -108,10 +107,8 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent)
|
|||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
ui->symbolicLinksCheckbox->setIcon(style()->standardIcon(QStyle::SP_VistaShield));
|
ui->symbolicLinksCheckbox->setIcon(style()->standardIcon(QStyle::SP_VistaShield));
|
||||||
ui->symbolicLinksCheckbox->setToolTip(
|
ui->symbolicLinksCheckbox->setToolTip(tr("Use symbolic links instead of copying files.") +
|
||||||
tr("Use symbolic links instead of copying files.") +
|
tr("\nOn windows symbolic links may require admin permission to create."));
|
||||||
tr("\nOn windows symbolic links may require admin permision to create.")
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
updateLinkOptions();
|
updateLinkOptions();
|
||||||
@ -119,7 +116,6 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent)
|
|||||||
|
|
||||||
auto HelpButton = ui->buttonBox->button(QDialogButtonBox::Help);
|
auto HelpButton = ui->buttonBox->button(QDialogButtonBox::Help);
|
||||||
connect(HelpButton, &QPushButton::clicked, this, &CopyInstanceDialog::help);
|
connect(HelpButton, &QPushButton::clicked, this, &CopyInstanceDialog::help);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyInstanceDialog::~CopyInstanceDialog()
|
CopyInstanceDialog::~CopyInstanceDialog()
|
||||||
@ -131,8 +127,7 @@ void CopyInstanceDialog::updateDialogState()
|
|||||||
{
|
{
|
||||||
auto allowOK = !instName().isEmpty();
|
auto allowOK = !instName().isEmpty();
|
||||||
auto OkButton = ui->buttonBox->button(QDialogButtonBox::Ok);
|
auto OkButton = ui->buttonBox->button(QDialogButtonBox::Ok);
|
||||||
if(OkButton->isEnabled() != allowOK)
|
if (OkButton->isEnabled() != allowOK) {
|
||||||
{
|
|
||||||
OkButton->setEnabled(allowOK);
|
OkButton->setEnabled(allowOK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,8 +135,7 @@ void CopyInstanceDialog::updateDialogState()
|
|||||||
QString CopyInstanceDialog::instName() const
|
QString CopyInstanceDialog::instName() const
|
||||||
{
|
{
|
||||||
auto result = ui->instNameTextBox->text().trimmed();
|
auto result = ui->instNameTextBox->text().trimmed();
|
||||||
if(result.size())
|
if (result.size()) {
|
||||||
{
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
@ -162,7 +156,6 @@ const InstanceCopyPrefs& CopyInstanceDialog::getChosenOptions() const
|
|||||||
return m_selectedOptions;
|
return m_selectedOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CopyInstanceDialog::help()
|
void CopyInstanceDialog::help()
|
||||||
{
|
{
|
||||||
DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg("instance-copy")));
|
DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg("instance-copy")));
|
||||||
@ -200,7 +193,8 @@ void CopyInstanceDialog::updateLinkOptions()
|
|||||||
ui->symbolicLinksCheckbox->setEnabled(m_linkSupported && !ui->hardLinksCheckbox->isChecked() && !ui->useCloneCheckbox->isChecked());
|
ui->symbolicLinksCheckbox->setEnabled(m_linkSupported && !ui->hardLinksCheckbox->isChecked() && !ui->useCloneCheckbox->isChecked());
|
||||||
ui->hardLinksCheckbox->setEnabled(m_linkSupported && !ui->symbolicLinksCheckbox->isChecked() && !ui->useCloneCheckbox->isChecked());
|
ui->hardLinksCheckbox->setEnabled(m_linkSupported && !ui->symbolicLinksCheckbox->isChecked() && !ui->useCloneCheckbox->isChecked());
|
||||||
|
|
||||||
ui->symbolicLinksCheckbox->setChecked(m_linkSupported && m_selectedOptions.isUseSymLinksEnabled() && !ui->useCloneCheckbox->isChecked());
|
ui->symbolicLinksCheckbox->setChecked(m_linkSupported && m_selectedOptions.isUseSymLinksEnabled() &&
|
||||||
|
!ui->useCloneCheckbox->isChecked());
|
||||||
ui->hardLinksCheckbox->setChecked(m_linkSupported && m_selectedOptions.isUseHardLinksEnabled() && !ui->useCloneCheckbox->isChecked());
|
ui->hardLinksCheckbox->setChecked(m_linkSupported && m_selectedOptions.isUseHardLinksEnabled() && !ui->useCloneCheckbox->isChecked());
|
||||||
|
|
||||||
bool linksInUse = (ui->symbolicLinksCheckbox->isChecked() || ui->hardLinksCheckbox->isChecked());
|
bool linksInUse = (ui->symbolicLinksCheckbox->isChecked() || ui->hardLinksCheckbox->isChecked());
|
||||||
@ -220,15 +214,13 @@ void CopyInstanceDialog::on_iconButton_clicked()
|
|||||||
IconPickerDialog dlg(this);
|
IconPickerDialog dlg(this);
|
||||||
dlg.execWithSelection(InstIconKey);
|
dlg.execWithSelection(InstIconKey);
|
||||||
|
|
||||||
if (dlg.result() == QDialog::Accepted)
|
if (dlg.result() == QDialog::Accepted) {
|
||||||
{
|
|
||||||
InstIconKey = dlg.selectedIconKey;
|
InstIconKey = dlg.selectedIconKey;
|
||||||
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
|
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString& arg1)
|
||||||
void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1)
|
|
||||||
{
|
{
|
||||||
updateDialogState();
|
updateDialogState();
|
||||||
}
|
}
|
||||||
@ -247,7 +239,6 @@ void CopyInstanceDialog::on_copySavesCheckbox_stateChanged(int state)
|
|||||||
updateSelectAllCheckbox();
|
updateSelectAllCheckbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state)
|
void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state)
|
||||||
{
|
{
|
||||||
m_selectedOptions.enableKeepPlaytime(state == Qt::Checked);
|
m_selectedOptions.enableKeepPlaytime(state == Qt::Checked);
|
||||||
@ -311,7 +302,6 @@ void CopyInstanceDialog::on_recursiveLinkCheckbox_stateChanged(int state)
|
|||||||
{
|
{
|
||||||
m_selectedOptions.enableLinkRecursively(state == Qt::Checked);
|
m_selectedOptions.enableLinkRecursively(state == Qt::Checked);
|
||||||
updateLinkOptions();
|
updateLinkOptions();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyInstanceDialog::on_dontLinkSavesCheckbox_stateChanged(int state)
|
void CopyInstanceDialog::on_dontLinkSavesCheckbox_stateChanged(int state)
|
||||||
|
@ -22,17 +22,15 @@
|
|||||||
|
|
||||||
class BaseInstance;
|
class BaseInstance;
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui {
|
||||||
{
|
|
||||||
class CopyInstanceDialog;
|
class CopyInstanceDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CopyInstanceDialog : public QDialog
|
class CopyInstanceDialog : public QDialog {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CopyInstanceDialog(InstancePtr original, QWidget *parent = 0);
|
explicit CopyInstanceDialog(InstancePtr original, QWidget* parent = 0);
|
||||||
~CopyInstanceDialog();
|
~CopyInstanceDialog();
|
||||||
|
|
||||||
void updateDialogState();
|
void updateDialogState();
|
||||||
@ -42,13 +40,12 @@ public:
|
|||||||
QString iconKey() const;
|
QString iconKey() const;
|
||||||
const InstanceCopyPrefs& getChosenOptions() const;
|
const InstanceCopyPrefs& getChosenOptions() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void help();
|
void help();
|
||||||
|
|
||||||
private
|
private slots:
|
||||||
slots:
|
|
||||||
void on_iconButton_clicked();
|
void on_iconButton_clicked();
|
||||||
void on_instNameTextBox_textChanged(const QString &arg1);
|
void on_instNameTextBox_textChanged(const QString& arg1);
|
||||||
// Checkboxes
|
// Checkboxes
|
||||||
void on_selectAllCheckbox_stateChanged(int state);
|
void on_selectAllCheckbox_stateChanged(int state);
|
||||||
void on_copySavesCheckbox_stateChanged(int state);
|
void on_copySavesCheckbox_stateChanged(int state);
|
||||||
@ -65,14 +62,14 @@ slots:
|
|||||||
void on_dontLinkSavesCheckbox_stateChanged(int state);
|
void on_dontLinkSavesCheckbox_stateChanged(int state);
|
||||||
void on_useCloneCheckbox_stateChanged(int state);
|
void on_useCloneCheckbox_stateChanged(int state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkAllCheckboxes(const bool& b);
|
void checkAllCheckboxes(const bool& b);
|
||||||
void updateSelectAllCheckbox();
|
void updateSelectAllCheckbox();
|
||||||
void updateUseCloneCheckbox();
|
void updateUseCloneCheckbox();
|
||||||
void updateLinkOptions();
|
void updateLinkOptions();
|
||||||
|
|
||||||
/* data */
|
/* data */
|
||||||
Ui::CopyInstanceDialog *ui;
|
Ui::CopyInstanceDialog* ui;
|
||||||
QString InstIconKey;
|
QString InstIconKey;
|
||||||
InstancePtr m_original;
|
InstancePtr m_original;
|
||||||
InstanceCopyPrefs m_selectedOptions;
|
InstanceCopyPrefs m_selectedOptions;
|
||||||
|
Loading…
Reference in New Issue
Block a user