mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
Merge remote-tracking branch 'origin/2.5'
This commit is contained in:
commit
db866afb60
10
ChangeLog
10
ChangeLog
@ -1,15 +1,19 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
version 2.5.4 (unreleased)
|
||||
version 2.5.4 (2019-03-xx)
|
||||
* Crash fix: Infinite recursion for bad paths on Windows (#7041)
|
||||
* Crash fix: SocketApi mustn't send if readyRead happens after disconnected (#7044)
|
||||
* Fix rare error causing spurious local deletes (#6677)
|
||||
* Disable HTTP2 support due to bugs in Qt 5.12.1 (#7020, QTBUG-73947)
|
||||
* Fix loading of persisted cookies when loading accounts (#7054)
|
||||
* Windows: Fix breaking of unrelated explorer actions (#7004, #7023)
|
||||
* Windows: Forbid syncing of files with bytes 0x00 to 0x1F in filenames (#6987)
|
||||
* OSX: Opt out of dark mode until problems can be addressed (#7043)
|
||||
* OSX: Fix folder dehydration requests (#6977)
|
||||
* macOS: Opt out of dark mode until problems can be addressed (#7043)
|
||||
* macOS: Fix folder dehydration requests (#6977)
|
||||
* Linux: Tray: Try to establish tray after 10s if failed initially (#6518)
|
||||
* Linux: FolderWatcher: Work around missing notifications (#7068)
|
||||
* Shares: "copy link" action can create shares with expiry (#7061)
|
||||
* Selective sync: Don't collapse folder tree when changing selection (#7055)
|
||||
* Client cert dialog: Avoid incorrect behavior due to multiple signal connections
|
||||
|
||||
|
||||
@ -338,10 +338,31 @@ bool SqlQuery::exec()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SqlQuery::next()
|
||||
auto SqlQuery::next() -> NextResult
|
||||
{
|
||||
SQLITE_DO(sqlite3_step(_stmt));
|
||||
return _errId == SQLITE_ROW;
|
||||
const bool firstStep = !sqlite3_stmt_busy(_stmt);
|
||||
|
||||
int n = 0;
|
||||
forever {
|
||||
_errId = sqlite3_step(_stmt);
|
||||
if (n < SQLITE_REPEAT_COUNT && firstStep && (_errId == SQLITE_LOCKED || _errId == SQLITE_BUSY)) {
|
||||
sqlite3_reset(_stmt); // not necessary after sqlite version 3.6.23.1
|
||||
n++;
|
||||
OCC::Utility::usleep(SQLITE_SLEEP_TIME_USEC);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NextResult result;
|
||||
result.ok = _errId == SQLITE_ROW || _errId == SQLITE_DONE;
|
||||
result.hasData = _errId == SQLITE_ROW;
|
||||
if (!result.ok) {
|
||||
_error = QString::fromUtf8(sqlite3_errmsg(_db));
|
||||
qCWarning(lcSql) << "Sqlite step statement error:" << _errId << _error << "in" << _sql;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SqlQuery::bindValue(int pos, const QVariant &value)
|
||||
|
||||
@ -129,7 +129,14 @@ public:
|
||||
bool isSelect();
|
||||
bool isPragma();
|
||||
bool exec();
|
||||
bool next();
|
||||
|
||||
struct NextResult
|
||||
{
|
||||
bool ok = false;
|
||||
bool hasData = false;
|
||||
};
|
||||
NextResult next();
|
||||
|
||||
void bindValue(int pos, const QVariant &value);
|
||||
QString lastQuery() const;
|
||||
int numRowsAffected();
|
||||
|
||||
@ -521,7 +521,7 @@ bool SyncJournalDb::checkConnect()
|
||||
bool forceRemoteDiscovery = false;
|
||||
|
||||
SqlQuery versionQuery("SELECT major, minor, patch FROM version;", _db);
|
||||
if (!versionQuery.next()) {
|
||||
if (!versionQuery.next().hasData) {
|
||||
// If there was no entry in the table, it means we are likely upgrading from 1.5
|
||||
qCInfo(lcDb) << "possibleUpgradeFromMirall_1_5 detected!";
|
||||
forceRemoteDiscovery = true;
|
||||
@ -850,7 +850,7 @@ QVector<QByteArray> SyncJournalDb::tableColumns(const QByteArray &table)
|
||||
if (!query.exec()) {
|
||||
return columns;
|
||||
}
|
||||
while (query.next()) {
|
||||
while (query.next().hasData) {
|
||||
columns.append(query.baValue(1));
|
||||
}
|
||||
qCDebug(lcDb) << "Columns in the current journal: " << columns;
|
||||
@ -1000,15 +1000,15 @@ bool SyncJournalDb::getFileRecord(const QByteArray &filename, SyncJournalFileRec
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_getFileRecordQuery.next()) {
|
||||
auto next = _getFileRecordQuery.next();
|
||||
if (!next.ok) {
|
||||
QString err = _getFileRecordQuery.error();
|
||||
qCWarning(lcDb) << "No journal entry found for " << filename << "Error: " << err;
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
if (next.hasData) {
|
||||
fillFileRecordFromGetQuery(*rec, _getFileRecordQuery);
|
||||
} else {
|
||||
int errId = _getFileRecordQuery.errorId();
|
||||
if (errId != SQLITE_DONE) { // only do this if the problem is different from SQLITE_DONE
|
||||
QString err = _getFileRecordQuery.error();
|
||||
qCWarning(lcDb) << "No journal entry found for " << filename << "Error: " << err;
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -1037,7 +1037,10 @@ bool SyncJournalDb::getFileRecordByInode(quint64 inode, SyncJournalFileRecord *r
|
||||
if (!_getFileRecordQueryByInode.exec())
|
||||
return false;
|
||||
|
||||
if (_getFileRecordQueryByInode.next())
|
||||
auto next = _getFileRecordQueryByInode.next();
|
||||
if (!next.ok)
|
||||
return false;
|
||||
if (next.hasData)
|
||||
fillFileRecordFromGetQuery(*rec, _getFileRecordQueryByInode);
|
||||
|
||||
return true;
|
||||
@ -1061,7 +1064,13 @@ bool SyncJournalDb::getFileRecordsByFileId(const QByteArray &fileId, const std::
|
||||
if (!_getFileRecordQueryByFileId.exec())
|
||||
return false;
|
||||
|
||||
while (_getFileRecordQueryByFileId.next()) {
|
||||
forever {
|
||||
auto next = _getFileRecordQueryByFileId.next();
|
||||
if (!next.ok)
|
||||
return false;
|
||||
if (!next.hasData)
|
||||
break;
|
||||
|
||||
SyncJournalFileRecord rec;
|
||||
fillFileRecordFromGetQuery(rec, _getFileRecordQueryByFileId);
|
||||
rowCallback(rec);
|
||||
@ -1113,7 +1122,13 @@ bool SyncJournalDb::getFilesBelowPath(const QByteArray &path, const std::functio
|
||||
return false;
|
||||
}
|
||||
|
||||
while (query->next()) {
|
||||
forever {
|
||||
auto next = query->next();
|
||||
if (!next.ok)
|
||||
return false;
|
||||
if (!next.hasData)
|
||||
break;
|
||||
|
||||
SyncJournalFileRecord rec;
|
||||
fillFileRecordFromGetQuery(rec, *query);
|
||||
rowCallback(rec);
|
||||
@ -1142,7 +1157,13 @@ bool SyncJournalDb::listFilesInPath(const QByteArray& path,
|
||||
if (!_listFilesInPathQuery.exec())
|
||||
return false;
|
||||
|
||||
while (_listFilesInPathQuery.next()) {
|
||||
forever {
|
||||
auto next = _listFilesInPathQuery.next();
|
||||
if (!next.ok)
|
||||
return false;
|
||||
if (!next.hasData)
|
||||
break;
|
||||
|
||||
SyncJournalFileRecord rec;
|
||||
fillFileRecordFromGetQuery(rec, _listFilesInPathQuery);
|
||||
if (!rec._path.startsWith(path) || rec._path.indexOf("/", path.size() + 1) > 0) {
|
||||
@ -1166,7 +1187,7 @@ int SyncJournalDb::getFileRecordCount()
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (query.next()) {
|
||||
if (query.next().hasData) {
|
||||
int count = query.intValue(0);
|
||||
return count;
|
||||
}
|
||||
@ -1277,10 +1298,8 @@ SyncJournalDb::DownloadInfo SyncJournalDb::getDownloadInfo(const QString &file)
|
||||
return res;
|
||||
}
|
||||
|
||||
if (_getDownloadInfoQuery.next()) {
|
||||
if (_getDownloadInfoQuery.next().hasData) {
|
||||
toDownloadInfo(_getDownloadInfoQuery, &res);
|
||||
} else {
|
||||
res._valid = false;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@ -1334,7 +1353,7 @@ QVector<SyncJournalDb::DownloadInfo> SyncJournalDb::getAndDeleteStaleDownloadInf
|
||||
QStringList superfluousPaths;
|
||||
QVector<SyncJournalDb::DownloadInfo> deleted_entries;
|
||||
|
||||
while (query.next()) {
|
||||
while (query.next().hasData) {
|
||||
const QString file = query.stringValue(3); // path
|
||||
if (!keep.contains(file)) {
|
||||
superfluousPaths.append(file);
|
||||
@ -1361,7 +1380,7 @@ int SyncJournalDb::downloadInfoCount()
|
||||
if (!query.exec()) {
|
||||
sqlFail("Count number of downloadinfo entries failed", query);
|
||||
}
|
||||
if (query.next()) {
|
||||
if (query.next().hasData) {
|
||||
re = query.intValue(0);
|
||||
}
|
||||
}
|
||||
@ -1386,7 +1405,7 @@ SyncJournalDb::UploadInfo SyncJournalDb::getUploadInfo(const QString &file)
|
||||
return res;
|
||||
}
|
||||
|
||||
if (_getUploadInfoQuery.next()) {
|
||||
if (_getUploadInfoQuery.next().hasData) {
|
||||
bool ok = true;
|
||||
res._chunk = _getUploadInfoQuery.intValue(0);
|
||||
res._transferid = _getUploadInfoQuery.intValue(1);
|
||||
@ -1455,7 +1474,7 @@ QVector<uint> SyncJournalDb::deleteStaleUploadInfos(const QSet<QString> &keep)
|
||||
|
||||
QStringList superfluousPaths;
|
||||
|
||||
while (query.next()) {
|
||||
while (query.next().hasData) {
|
||||
const QString file = query.stringValue(0);
|
||||
if (!keep.contains(file)) {
|
||||
superfluousPaths.append(file);
|
||||
@ -1479,7 +1498,7 @@ SyncJournalErrorBlacklistRecord SyncJournalDb::errorBlacklistEntry(const QString
|
||||
_getErrorBlacklistQuery.reset_and_clear_bindings();
|
||||
_getErrorBlacklistQuery.bindValue(1, file);
|
||||
if (_getErrorBlacklistQuery.exec()) {
|
||||
if (_getErrorBlacklistQuery.next()) {
|
||||
if (_getErrorBlacklistQuery.next().hasData) {
|
||||
entry._lastTryEtag = _getErrorBlacklistQuery.baValue(0);
|
||||
entry._lastTryModtime = _getErrorBlacklistQuery.int64Value(1);
|
||||
entry._retryCount = _getErrorBlacklistQuery.intValue(2);
|
||||
@ -1515,7 +1534,7 @@ bool SyncJournalDb::deleteStaleErrorBlacklistEntries(const QSet<QString> &keep)
|
||||
|
||||
QStringList superfluousPaths;
|
||||
|
||||
while (query.next()) {
|
||||
while (query.next().hasData) {
|
||||
const QString file = query.stringValue(0);
|
||||
if (!keep.contains(file)) {
|
||||
superfluousPaths.append(file);
|
||||
@ -1538,7 +1557,7 @@ int SyncJournalDb::errorBlackListEntryCount()
|
||||
if (!query.exec()) {
|
||||
sqlFail("Count number of blacklist entries failed", query);
|
||||
}
|
||||
if (query.next()) {
|
||||
if (query.next().hasData) {
|
||||
re = query.intValue(0);
|
||||
}
|
||||
}
|
||||
@ -1642,7 +1661,7 @@ QVector<SyncJournalDb::PollInfo> SyncJournalDb::getPollInfos()
|
||||
return res;
|
||||
}
|
||||
|
||||
while (query.next()) {
|
||||
while (query.next().hasData) {
|
||||
PollInfo info;
|
||||
info._file = query.stringValue(0);
|
||||
info._modtime = query.int64Value(1);
|
||||
@ -1696,7 +1715,15 @@ QStringList SyncJournalDb::getSelectiveSyncList(SyncJournalDb::SelectiveSyncList
|
||||
*ok = false;
|
||||
return result;
|
||||
}
|
||||
while (_getSelectiveSyncListQuery.next()) {
|
||||
forever {
|
||||
auto next = _getSelectiveSyncListQuery.next();
|
||||
if (!next.ok) {
|
||||
*ok = false;
|
||||
return result;
|
||||
}
|
||||
if (!next.hasData)
|
||||
break;
|
||||
|
||||
auto entry = _getSelectiveSyncListQuery.stringValue(0);
|
||||
if (!entry.endsWith(QLatin1Char('/'))) {
|
||||
entry.append(QLatin1Char('/'));
|
||||
@ -1819,12 +1846,12 @@ QByteArray SyncJournalDb::getChecksumType(int checksumTypeId)
|
||||
return {};
|
||||
query.bindValue(1, checksumTypeId);
|
||||
if (!query.exec()) {
|
||||
return 0;
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
if (!query.next()) {
|
||||
if (!query.next().hasData) {
|
||||
qCWarning(lcDb) << "No checksum type mapping found for" << checksumTypeId;
|
||||
return 0;
|
||||
return QByteArray();
|
||||
}
|
||||
return query.baValue(0);
|
||||
}
|
||||
@ -1855,7 +1882,7 @@ int SyncJournalDb::mapChecksumType(const QByteArray &checksumType)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_getChecksumTypeIdQuery.next()) {
|
||||
if (!_getChecksumTypeIdQuery.next().hasData) {
|
||||
qCWarning(lcDb) << "No checksum type mapping found for" << checksumType;
|
||||
return 0;
|
||||
}
|
||||
@ -1878,7 +1905,7 @@ QByteArray SyncJournalDb::dataFingerprint()
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
if (!_getDataFingerprintQuery.next()) {
|
||||
if (!_getDataFingerprintQuery.next().hasData) {
|
||||
return QByteArray();
|
||||
}
|
||||
return _getDataFingerprintQuery.baValue(0);
|
||||
@ -1933,7 +1960,7 @@ ConflictRecord SyncJournalDb::conflictRecord(const QByteArray &path)
|
||||
ASSERT(query.initOrReset(QByteArrayLiteral("SELECT baseFileId, baseModtime, baseEtag, basePath FROM conflicts WHERE path=?1;"), _db));
|
||||
query.bindValue(1, path);
|
||||
ASSERT(query.exec());
|
||||
if (!query.next())
|
||||
if (!query.next().hasData)
|
||||
return entry;
|
||||
|
||||
entry.path = path;
|
||||
@ -1966,7 +1993,7 @@ QByteArrayList SyncJournalDb::conflictRecordPaths()
|
||||
ASSERT(query.exec());
|
||||
|
||||
QByteArrayList paths;
|
||||
while (query.next())
|
||||
while (query.next().hasData)
|
||||
paths.append(query.baValue(0));
|
||||
|
||||
return paths;
|
||||
@ -2031,8 +2058,11 @@ Optional<PinState> SyncJournalDb::PinStateInterface::rawForPath(const QByteArray
|
||||
query.bindValue(1, path);
|
||||
query.exec();
|
||||
|
||||
auto next = query.next();
|
||||
if (!next.ok)
|
||||
return {};
|
||||
// no-entry means Inherited
|
||||
if (!query.next())
|
||||
if (!next.hasData)
|
||||
return PinState::Inherited;
|
||||
|
||||
return static_cast<PinState>(query.intValue(0));
|
||||
@ -2056,8 +2086,11 @@ Optional<PinState> SyncJournalDb::PinStateInterface::effectiveForPath(const QByt
|
||||
query.bindValue(1, path);
|
||||
query.exec();
|
||||
|
||||
auto next = query.next();
|
||||
if (!next.ok)
|
||||
return {};
|
||||
// If the root path has no setting, assume AlwaysLocal
|
||||
if (!query.next())
|
||||
if (!next.hasData)
|
||||
return PinState::AlwaysLocal;
|
||||
|
||||
return static_cast<PinState>(query.intValue(0));
|
||||
@ -2110,7 +2143,12 @@ SyncJournalDb::PinStateInterface::rawList()
|
||||
query.exec();
|
||||
|
||||
QVector<QPair<QByteArray, PinState>> result;
|
||||
while (query.next()) {
|
||||
forever {
|
||||
auto next = query.next();
|
||||
if (!next.ok)
|
||||
return {};
|
||||
if (!next.hasData)
|
||||
break;
|
||||
result.append({ query.baValue(0), static_cast<PinState>(query.intValue(1)) });
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -766,6 +766,13 @@ void Application::openVirtualFile(const QString &filename)
|
||||
});
|
||||
}
|
||||
|
||||
void Application::tryTrayAgain()
|
||||
{
|
||||
qCInfo(lcApplication) << "Trying tray icon, tray available:" << QSystemTrayIcon::isSystemTrayAvailable();
|
||||
if (!_gui->contextMenuVisible())
|
||||
_gui->hideAndShowTray();
|
||||
}
|
||||
|
||||
bool Application::event(QEvent *event)
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
@ -80,6 +80,9 @@ public slots:
|
||||
*/
|
||||
void openVirtualFile(const QString &filename);
|
||||
|
||||
/// Attempt to show() the tray icon again. Used if no systray was available initially.
|
||||
void tryTrayAgain();
|
||||
|
||||
protected:
|
||||
void parseOptions(const QStringList &);
|
||||
void setupTranslations();
|
||||
|
||||
@ -127,6 +127,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We can't call isSystemTrayAvailable with appmenu-qt5 begause it hides the systemtray
|
||||
// (issue #4693)
|
||||
if (qgetenv("QT_QPA_PLATFORMTHEME") != "appmenu-qt5")
|
||||
@ -135,27 +136,34 @@ int main(int argc, char **argv)
|
||||
// If the systemtray is not there, we will wait one second for it to maybe start
|
||||
// (eg boot time) then we show the settings dialog if there is still no systemtray.
|
||||
// On XFCE however, we show a message box with explainaition how to install a systemtray.
|
||||
qCInfo(lcApplication) << "System tray is not available, waiting...";
|
||||
Utility::sleep(1);
|
||||
|
||||
auto desktopSession = qgetenv("XDG_CURRENT_DESKTOP").toLower();
|
||||
if (desktopSession.isEmpty()) {
|
||||
desktopSession = qgetenv("DESKTOP_SESSION").toLower();
|
||||
}
|
||||
if (desktopSession == "xfce") {
|
||||
int attempts = 0;
|
||||
forever {
|
||||
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
Utility::sleep(1);
|
||||
attempts++;
|
||||
if (attempts < 30)
|
||||
continue;
|
||||
} else {
|
||||
while (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
attempts++;
|
||||
if (attempts >= 30) {
|
||||
qCWarning(lcApplication) << "System tray unavailable (xfce)";
|
||||
warnSystray();
|
||||
break;
|
||||
}
|
||||
warnSystray();
|
||||
Utility::sleep(1);
|
||||
}
|
||||
}
|
||||
if (!QSystemTrayIcon::isSystemTrayAvailable() && desktopSession != "ubuntu") {
|
||||
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
app.tryTrayAgain();
|
||||
} else if (desktopSession != "ubuntu") {
|
||||
qCInfo(lcApplication) << "System tray still not available, showing window and trying again later";
|
||||
app.showSettingsDialog();
|
||||
QTimer::singleShot(10000, &app, &Application::tryTrayAgain);
|
||||
} else {
|
||||
qCInfo(lcApplication) << "System tray still not available, but assuming it's fine on 'ubuntu' desktop";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,6 +426,12 @@ bool ownCloudGui::contextMenuVisible() const
|
||||
return _contextMenu->isVisible();
|
||||
}
|
||||
|
||||
void ownCloudGui::hideAndShowTray()
|
||||
{
|
||||
_tray->hide();
|
||||
_tray->show();
|
||||
}
|
||||
|
||||
static bool minimalTrayMenu()
|
||||
{
|
||||
static QByteArray var = qgetenv("OWNCLOUD_MINIMAL_TRAY_MENU");
|
||||
|
||||
@ -61,6 +61,8 @@ public:
|
||||
/// Whether the tray menu is visible
|
||||
bool contextMenuVisible() const;
|
||||
|
||||
void hideAndShowTray();
|
||||
|
||||
signals:
|
||||
void setupProxy();
|
||||
|
||||
|
||||
@ -145,7 +145,7 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
|
||||
if (_account->capabilities().sharePublicLinkEnforceExpireDate()) {
|
||||
_ui->checkBox_expire->setEnabled(false);
|
||||
_ui->calendar->setMaximumDate(QDate::currentDate().addDays(
|
||||
_account->capabilities().sharePublicLinkExpireDateDays()));
|
||||
_account->capabilities().sharePublicLinkDefaultExpireDateDays()));
|
||||
_expiryRequired = true;
|
||||
}
|
||||
|
||||
|
||||
@ -487,6 +487,7 @@ public:
|
||||
GetOrCreatePublicLinkShare(const AccountPtr &account, const QString &localFile,
|
||||
std::function<void(const QString &link)> targetFun, QObject *parent)
|
||||
: QObject(parent)
|
||||
, _account(account)
|
||||
, _shareManager(account)
|
||||
, _localFile(localFile)
|
||||
, _targetFun(targetFun)
|
||||
@ -509,6 +510,12 @@ private slots:
|
||||
void sharesFetched(const QList<QSharedPointer<Share>> &shares)
|
||||
{
|
||||
auto shareName = SocketApi::tr("Context menu share");
|
||||
|
||||
// If shares will expire, create a new one every day.
|
||||
if (_account->capabilities().sharePublicLinkDefaultExpire()) {
|
||||
shareName = SocketApi::tr("Context menu share %1").arg(QDate::currentDate().toString(Qt::ISODate));
|
||||
}
|
||||
|
||||
// If there already is a context menu share, reuse it
|
||||
for (const auto &share : shares) {
|
||||
const auto linkShare = qSharedPointerDynamicCast<LinkShare>(share);
|
||||
@ -551,6 +558,7 @@ private:
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
AccountPtr _account;
|
||||
ShareManager _shareManager;
|
||||
QString _localFile;
|
||||
std::function<void(const QString &url)> _targetFun;
|
||||
@ -778,7 +786,6 @@ void SocketApi::sendSharingContextMenuOptions(const FileData &fileData, SocketLi
|
||||
|
||||
// Is is possible to create a public link without user choices?
|
||||
bool canCreateDefaultPublicLink = publicLinksEnabled
|
||||
&& !capabilities.sharePublicLinkEnforceExpireDate()
|
||||
&& !capabilities.sharePublicLinkEnforcePassword();
|
||||
|
||||
if (canCreateDefaultPublicLink) {
|
||||
|
||||
@ -60,16 +60,21 @@ bool Capabilities::sharePublicLinkEnforcePassword() const
|
||||
return _capabilities["files_sharing"].toMap()["public"].toMap()["password"].toMap()["enforced"].toBool();
|
||||
}
|
||||
|
||||
bool Capabilities::sharePublicLinkDefaultExpire() const
|
||||
{
|
||||
return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date"].toMap()["enabled"].toBool();
|
||||
}
|
||||
|
||||
int Capabilities::sharePublicLinkDefaultExpireDateDays() const
|
||||
{
|
||||
return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date"].toMap()["days"].toInt();
|
||||
}
|
||||
|
||||
bool Capabilities::sharePublicLinkEnforceExpireDate() const
|
||||
{
|
||||
return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date"].toMap()["enforced"].toBool();
|
||||
}
|
||||
|
||||
int Capabilities::sharePublicLinkExpireDateDays() const
|
||||
{
|
||||
return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date"].toMap()["days"].toInt();
|
||||
}
|
||||
|
||||
bool Capabilities::sharePublicLinkMultiple() const
|
||||
{
|
||||
return _capabilities["files_sharing"].toMap()["public"].toMap()["multiple"].toBool();
|
||||
|
||||
@ -38,8 +38,9 @@ public:
|
||||
bool sharePublicLinkAllowUpload() const;
|
||||
bool sharePublicLinkSupportsUploadOnly() const;
|
||||
bool sharePublicLinkEnforcePassword() const;
|
||||
bool sharePublicLinkDefaultExpire() const;
|
||||
int sharePublicLinkDefaultExpireDateDays() const;
|
||||
bool sharePublicLinkEnforceExpireDate() const;
|
||||
int sharePublicLinkExpireDateDays() const;
|
||||
bool sharePublicLinkMultiple() const;
|
||||
bool shareResharing() const;
|
||||
bool chunkingNg() const;
|
||||
|
||||
@ -71,7 +71,7 @@ private slots:
|
||||
q.prepare(sql);
|
||||
|
||||
q.exec();
|
||||
while( q.next() ) {
|
||||
while( q.next().hasData ) {
|
||||
qDebug() << "Name: " << q.stringValue(1);
|
||||
qDebug() << "Address: " << q.stringValue(2);
|
||||
}
|
||||
@ -83,7 +83,7 @@ private slots:
|
||||
q.prepare(sql);
|
||||
q.bindValue(1, 2);
|
||||
q.exec();
|
||||
if( q.next() ) {
|
||||
if( q.next().hasData ) {
|
||||
qDebug() << "Name:" << q.stringValue(1);
|
||||
qDebug() << "Address:" << q.stringValue(2);
|
||||
}
|
||||
@ -96,7 +96,7 @@ private slots:
|
||||
int rc = q.prepare(sql);
|
||||
qDebug() << "Pragma:" << rc;
|
||||
q.exec();
|
||||
if( q.next() ) {
|
||||
if( q.next().hasData ) {
|
||||
qDebug() << "P:" << q.stringValue(1);
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ private slots:
|
||||
SqlQuery q(_db);
|
||||
q.prepare(sql);
|
||||
|
||||
if(q.next()) {
|
||||
if(q.next().hasData) {
|
||||
QString name = q.stringValue(1);
|
||||
QString address = q.stringValue(2);
|
||||
QVERIFY( name == QString::fromUtf8("пятницы") );
|
||||
|
||||
@ -31,7 +31,7 @@ static void assertCsyncJournalOk(SyncJournalDb &journal)
|
||||
QVERIFY(db.openReadOnly(journal.databaseFilePath()));
|
||||
SqlQuery q("SELECT count(*) from metadata where length(fileId) == 0", db);
|
||||
QVERIFY(q.exec());
|
||||
QVERIFY(q.next());
|
||||
QVERIFY(q.next().hasData);
|
||||
QCOMPARE(q.intValue(0), 0);
|
||||
#if defined(Q_OS_WIN) // Make sure the file does not appear in the FileInfo
|
||||
FileSystem::setFileHidden(journal.databaseFilePath() + "-shm", true);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user