mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2026-04-04 03:11:32 +02:00
Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e31d86596 | ||
|
|
ab007e2bb2 | ||
|
|
c45d55b94b | ||
|
|
7048bd8cc9 | ||
|
|
cae6ca987f | ||
|
|
65171cfb3a | ||
|
|
7ec636aeb6 | ||
|
|
c96980a57d | ||
|
|
0959ceeff2 | ||
|
|
1988c9d8c4 | ||
|
|
1eaa1e47fe | ||
|
|
31923b314e | ||
|
|
ee840b62e5 | ||
|
|
363efaa408 | ||
|
|
b0beeea95f | ||
|
|
d0a4650d69 | ||
|
|
ec5a84cf01 | ||
|
|
a057eb8590 | ||
|
|
6a8753b119 | ||
|
|
23fab90a31 | ||
|
|
8fdf9cac6b | ||
|
|
525d12f5a2 | ||
|
|
15d247a708 | ||
|
|
a1d0b85277 | ||
|
|
5e5a77b040 | ||
|
|
e420ae6942 | ||
|
|
0be7c0273e | ||
|
|
864b7cd41e | ||
|
|
78c8f13645 | ||
|
|
c87c456ae0 | ||
|
|
94d9b8fb39 | ||
|
|
2dad027001 | ||
|
|
f97bb240d7 | ||
|
|
80332fb6ab | ||
|
|
287ec2f3df | ||
|
|
eb5824f713 | ||
|
|
eded901f69 | ||
|
|
fd30df82cb | ||
|
|
d8888432c3 | ||
|
|
51712fea53 | ||
|
|
f597f99198 | ||
|
|
74ec37f3c7 | ||
|
|
05178f0fbf |
22
ChangeLog
22
ChangeLog
@@ -1,5 +1,27 @@
|
||||
ChangeLog
|
||||
=========
|
||||
version 1.4.1 (release 2013-09-24 ), csync 0.90.1 required
|
||||
|
||||
* Translation and documentation fixes.
|
||||
* Fixed error display in settings/status dialog, displays multi
|
||||
line error messages now correctly.
|
||||
* Wait up to 30 secs before complaining about missing systray
|
||||
Fixes bug #949
|
||||
* Fixed utf8 issues with basic auth authentication, fixes bug #941
|
||||
* Fixed remote folder selector, avoid recursive syncing, fixes bug #962
|
||||
* Handle and display network problems at startup correctly.
|
||||
* Enable and disable the folder watcher during syncs correctly.
|
||||
* Fix setting of thread priority.
|
||||
* Fixed file size display.
|
||||
* Fixed various folder wizard issues, bug #992
|
||||
* Made "Sync started" message optional, fixes bug #934
|
||||
* Fixed shutdown, avoid crashed config on win32, fixes bug #945
|
||||
* Pop up config wizard if no server url is configured, fixes bug #1018
|
||||
* Settings: calculate sidebar width dynamically, fixes bug #1020
|
||||
* Fixed a crash if sync folders were removed, fixes bug #713
|
||||
* Do proper resync after network disconnect, fixes bug #1007
|
||||
* Various minor code fixes
|
||||
|
||||
version 1.4.0 (release 2013-09-04 ), csync 0.90.0 required
|
||||
|
||||
* New Scheduler: Only sync when there are actual changes in the server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
set( VERSION_MAJOR 1 )
|
||||
set( VERSION_MINOR 4 )
|
||||
set( VERSION_PATCH 0 )
|
||||
set( VERSION_PATCH 1 )
|
||||
set( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX}")
|
||||
set( SOVERSION 0 )
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#cmakedefine APPLICATION_NAME "@APPLICATION_NAME@"
|
||||
#cmakedefine APPLICATION_SHORTNAME "@APPLICATION_SHORTNAME@"
|
||||
#cmakedefine APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@"
|
||||
|
||||
#cmakedefine SYSCONFDIR "@SYSCONFDIR@"
|
||||
#cmakedefine DATADIR "@DATADIR@"
|
||||
|
||||
@@ -22,7 +22,7 @@ if(SPHINX_FOUND)
|
||||
add_custom_target(doc DEPENDS doc-html doc-man COMMENT "Building documentation...")
|
||||
endif(WITH_DOC)
|
||||
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ocdoc")
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ocdoc/_shared_assets")
|
||||
add_dependencies(doc doc-html-org)
|
||||
add_dependencies(doc doc-html-com)
|
||||
endif()
|
||||
|
||||
@@ -36,9 +36,14 @@ its own repository which contains non-standard recipes. Add it with::
|
||||
|
||||
Next, install the missing dependencies::
|
||||
|
||||
brew install $(brew deps ocsync)
|
||||
brew install $(brew deps ocsync)
|
||||
brew install $(brew deps mirall)
|
||||
|
||||
bug:
|
||||
iniparser is not provideed by $(brew deps ocsync)
|
||||
fix with brew install iniparser
|
||||
|
||||
|
||||
To build mirall and csync, follow the `generic build instructions`_.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -64,7 +64,7 @@ release = '@VERSION@'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
exclude_patterns = ['_build','scripts/*']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
@@ -5,4 +5,4 @@ Exec=@APPLICATION_EXECUTABLE@
|
||||
Name=@APPLICATION_NAME@ desktop sync client
|
||||
GenericName=Folder Sync
|
||||
Icon=@APPLICATION_EXECUTABLE@
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
|
||||
|
||||
@@ -254,7 +254,15 @@ set( final_src
|
||||
include( AddAppIconMacro )
|
||||
set(ownCloud_old ${ownCloud})
|
||||
|
||||
kde4_add_app_icon( ownCloud "${theme_dir}/colored/${APPLICATION_EXECUTABLE}-icon*.png")
|
||||
# set an icon_app_name. For historical reasons we can not use the
|
||||
# application_shortname for ownCloud but must rather set it manually.
|
||||
if ( EXISTS ${OEM_THEME_DIR}/OEM.cmake )
|
||||
set(ICON_APP_NAME ${APPLICATION_SHORTNAME})
|
||||
else()
|
||||
set(ICON_APP_NAME "owncloud")
|
||||
endif()
|
||||
|
||||
kde4_add_app_icon( ownCloud "${theme_dir}/colored/${ICON_APP_NAME}-icon*.png")
|
||||
list(APPEND final_src ${ownCloud})
|
||||
set(ownCloud ${ownCloud_old})
|
||||
|
||||
@@ -262,11 +270,11 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
||||
if(NOT WIN32)
|
||||
file( GLOB _icons "${theme_dir}/colored/${APPLICATION_EXECUTABLE}-icon-*.png" )
|
||||
file( GLOB _icons "${theme_dir}/colored/${ICON_APP_NAME}-icon-*.png" )
|
||||
foreach( _file ${_icons} )
|
||||
string( REPLACE "${theme_dir}/colored/${APPLICATION_EXECUTABLE}-icon-" "" _res ${_file} )
|
||||
string( REPLACE "${theme_dir}/colored/${ICON_APP_NAME}-icon-" "" _res ${_file} )
|
||||
string( REPLACE ".png" "" _res ${_res} )
|
||||
install( FILES ${_file} RENAME ${APPLICATION_EXECUTABLE}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps )
|
||||
install( FILES ${_file} RENAME ${ICON_APP_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps )
|
||||
endforeach( _file )
|
||||
endif(NOT WIN32)
|
||||
|
||||
|
||||
@@ -67,11 +67,25 @@ int getauth(const char *prompt,
|
||||
|
||||
} // ns
|
||||
|
||||
class HttpCredentialsAccessManager : public MirallAccessManager {
|
||||
public:
|
||||
HttpCredentialsAccessManager(const HttpCredentials *cred, QObject* parent = 0)
|
||||
: MirallAccessManager(parent), _cred(cred) {}
|
||||
protected:
|
||||
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) {
|
||||
QByteArray credHash = QByteArray(_cred->user().toUtf8()+":"+_cred->password().toUtf8()).toBase64();
|
||||
QNetworkRequest req(request);
|
||||
req.setRawHeader(QByteArray("Authorization"), QByteArray("Basic ") + credHash);
|
||||
return MirallAccessManager::createRequest(op, req, outgoingData);\
|
||||
}
|
||||
private:
|
||||
const HttpCredentials *_cred;
|
||||
};
|
||||
|
||||
HttpCredentials::HttpCredentials()
|
||||
: _user(),
|
||||
_password(),
|
||||
_ready(false),
|
||||
_attempts()
|
||||
_ready(false)
|
||||
{}
|
||||
|
||||
HttpCredentials::HttpCredentials(const QString& user, const QString& password)
|
||||
@@ -134,7 +148,7 @@ QString HttpCredentials::password() const
|
||||
|
||||
QNetworkAccessManager* HttpCredentials::getQNAM() const
|
||||
{
|
||||
MirallAccessManager* qnam = new MirallAccessManager;
|
||||
MirallAccessManager* qnam = new HttpCredentialsAccessManager(this);
|
||||
|
||||
connect( qnam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)),
|
||||
this, SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));
|
||||
@@ -180,30 +194,12 @@ void HttpCredentials::slotCredentialsFetched(bool ok)
|
||||
|
||||
void HttpCredentials::slotAuthentication(QNetworkReply* reply, QAuthenticator* authenticator)
|
||||
{
|
||||
if( !(authenticator && reply) ) return;
|
||||
|
||||
qDebug() << "Authenticating request for " << reply->url();
|
||||
|
||||
if (_attempts.contains(reply)) {
|
||||
++_attempts[reply];
|
||||
} else {
|
||||
connect(reply, SIGNAL(finished()),
|
||||
this, SLOT(slotReplyFinished()));
|
||||
_attempts[reply] = 1;
|
||||
}
|
||||
// TODO: Replace it with something meaningful...
|
||||
//if( reply->url().toString().startsWith( webdavUrl( _connection ) ) ) {
|
||||
if (_attempts[reply] > 1) {
|
||||
qDebug() << "Too many attempts to authenticate. Stop request.";
|
||||
reply->close();
|
||||
} else {
|
||||
authenticator->setUser( _user );
|
||||
authenticator->setPassword( _password );
|
||||
}
|
||||
//} else {
|
||||
// qDebug() << "WRN: attempt to authenticate to different url - closing.";
|
||||
// reply->close();
|
||||
//}
|
||||
Q_UNUSED(authenticator)
|
||||
// we cannot use QAuthenticator, because it sends username and passwords with latin1
|
||||
// instead of utf8 encoding. Instead, we send it manually. Thus, if we reach this signal,
|
||||
// those credentials were invalid and we terminate.
|
||||
qDebug() << "Stop request: Authentication failed for " << reply->url().toString();
|
||||
reply->close();
|
||||
}
|
||||
|
||||
void HttpCredentials::slotReplyFinished()
|
||||
@@ -212,7 +208,6 @@ void HttpCredentials::slotReplyFinished()
|
||||
|
||||
disconnect(reply, SIGNAL(finished()),
|
||||
this, SLOT(slotReplyFinished()));
|
||||
_attempts.remove (reply);
|
||||
}
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
@@ -56,7 +56,6 @@ private:
|
||||
QString _user;
|
||||
QString _password;
|
||||
bool _ready;
|
||||
QMap<QNetworkReply*, int> _attempts;
|
||||
};
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
30
src/main.cpp
30
src/main.cpp
@@ -14,8 +14,20 @@
|
||||
|
||||
#include "mirall/application.h"
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/utility.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
|
||||
void warnSystray()
|
||||
{
|
||||
QMessageBox::critical(0, qApp->translate("main.cpp", "System Tray not available"),
|
||||
qApp->translate("main.cpp", "%1 requires on a working system tray. "
|
||||
"If you are running XFCE, please follow "
|
||||
"<a href=\"http://docs.xfce.org/xfce/xfce4-panel/systray\">these instructions</a>. "
|
||||
"Otherwise, please install a system tray application such as 'trayer' and try again.")
|
||||
.arg(Mirall::Theme::instance()->appNameGUI()));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@@ -39,13 +51,17 @@ int main(int argc, char **argv)
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
if (!QSystemTrayIcon::isSystemTrayAvailable() && qgetenv("DESKTOP_SESSION") != "ubuntu") {
|
||||
QMessageBox::critical(0, qApp->translate("main.cpp", "System Tray not available"),
|
||||
qApp->translate("main.cpp", "%1 requires on a working system tray. "
|
||||
"If you are running XFCE, please follow "
|
||||
"<a href=\"http://docs.xfce.org/xfce/xfce4-panel/systray\">these instructions</a>. "
|
||||
"Otherwise, please install a system tray application such as 'trayer' and try again.")
|
||||
.arg(Mirall::Theme::instance()->appNameGUI()));
|
||||
int attempts = 0;
|
||||
forever {
|
||||
if (!QSystemTrayIcon::isSystemTrayAvailable() && qgetenv("DESKTOP_SESSION") != "ubuntu") {
|
||||
Mirall::Utility::sleep(1);
|
||||
attempts++;
|
||||
if (attempts < 30) continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
warnSystray();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return app.exec();
|
||||
|
||||
@@ -50,8 +50,7 @@ static const char progressBarStyleC[] =
|
||||
|
||||
AccountSettings::AccountSettings(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::AccountSettings),
|
||||
_item(0)
|
||||
ui(new Ui::AccountSettings)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@@ -205,9 +204,9 @@ void AccountSettings::buttonsSetEnabled()
|
||||
ui->_ButtonInfo->setEnabled(isSelected);
|
||||
}
|
||||
|
||||
void AccountSettings::setListWidgetItem( QListWidgetItem *item )
|
||||
void AccountSettings::setGeneralErrors( const QStringList& errors )
|
||||
{
|
||||
_item = item;
|
||||
_generalErrors = errors;
|
||||
}
|
||||
|
||||
void AccountSettings::folderToModelItem( QStandardItem *item, Folder *f )
|
||||
@@ -223,10 +222,6 @@ void AccountSettings::folderToModelItem( QStandardItem *item, Folder *f )
|
||||
SyncResult::Status status = res.status();
|
||||
|
||||
QStringList errorList = res.errorStrings();
|
||||
QString errors;
|
||||
if( ! errorList.isEmpty() ) {
|
||||
errors = res.errorStrings().join(QLatin1String("<br/>"));
|
||||
}
|
||||
|
||||
Theme *theme = Theme::instance();
|
||||
item->setData( theme->statusHeaderText( status ), Qt::ToolTipRole );
|
||||
@@ -236,14 +231,17 @@ void AccountSettings::folderToModelItem( QStandardItem *item, Folder *f )
|
||||
item->setData( theme->folderDisabledIcon( ), FolderStatusDelegate::FolderStatusIconRole ); // size 48 before
|
||||
}
|
||||
item->setData( theme->statusHeaderText( status ), FolderStatusDelegate::FolderStatus );
|
||||
item->setData( errors, FolderStatusDelegate::FolderErrorMsg );
|
||||
|
||||
if( errors.isEmpty() && (status == SyncResult::Error ||
|
||||
status == SyncResult::SetupError ||
|
||||
status == SyncResult::Unavailable )) {
|
||||
item->setData( theme->statusHeaderText(status), FolderStatusDelegate::FolderErrorMsg);
|
||||
if( errorList.isEmpty() ) {
|
||||
if( (status == SyncResult::Error ||
|
||||
status == SyncResult::SetupError ||
|
||||
status == SyncResult::Unavailable )) {
|
||||
errorList << theme->statusHeaderText(status);
|
||||
}
|
||||
}
|
||||
|
||||
item->setData( errorList, FolderStatusDelegate::FolderErrorMsg);
|
||||
|
||||
bool ongoing = false;
|
||||
item->setData( QVariant(res.warnCount()), FolderStatusDelegate::WarningCount );
|
||||
if( status == SyncResult::SyncRunning ) {
|
||||
@@ -257,6 +255,8 @@ void AccountSettings::slotRemoveCurrentFolder()
|
||||
{
|
||||
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
|
||||
if( selected.isValid() ) {
|
||||
int row = selected.row();
|
||||
|
||||
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
|
||||
qDebug() << "Remove Folder alias " << alias;
|
||||
if( !alias.isEmpty() ) {
|
||||
@@ -270,9 +270,22 @@ void AccountSettings::slotRemoveCurrentFolder()
|
||||
if( ret == QMessageBox::No ) {
|
||||
return;
|
||||
}
|
||||
/* Remove the selected item from the timer hash. */
|
||||
QStandardItem *item = NULL;
|
||||
if( selected.isValid() )
|
||||
item = _model->itemFromIndex(selected);
|
||||
|
||||
if( selected.isValid() && item && _hideProgressTimers.contains(item) ) {
|
||||
QTimer *t = _hideProgressTimers[item];
|
||||
t->stop();
|
||||
_hideProgressTimers.remove(item);
|
||||
delete(t);
|
||||
}
|
||||
|
||||
FolderMan *folderMan = FolderMan::instance();
|
||||
folderMan->slotRemoveFolder( alias );
|
||||
setFolderList(folderMan->map());
|
||||
_model->removeRow(row);
|
||||
|
||||
emit folderChanged();
|
||||
slotCheckConnection();
|
||||
}
|
||||
@@ -308,6 +321,22 @@ void AccountSettings::slotDoubleClicked( const QModelIndex& indx )
|
||||
emit openFolderAlias( alias );
|
||||
}
|
||||
|
||||
void AccountSettings::showConnectionLabel( const QString& message, const QString& tooltip )
|
||||
{
|
||||
const QString errStyle = QLatin1String("color:#ffffff; background-color:#bb4d4d;padding:5px;"
|
||||
"border-width: 1px; border-style: solid; border-color: #aaaaaa;"
|
||||
"border-radius:5px;");
|
||||
if( _generalErrors.isEmpty() ) {
|
||||
ui->connectLabel->setText( message );
|
||||
ui->connectLabel->setToolTip(tooltip);
|
||||
} else {
|
||||
const QString msg = _generalErrors.join(QLatin1String("\n"));
|
||||
ui->connectLabel->setText( msg );
|
||||
ui->connectLabel->setToolTip(QString());
|
||||
ui->connectLabel->setStyleSheet(errStyle);
|
||||
}
|
||||
}
|
||||
|
||||
void AccountSettings::slotCheckConnection()
|
||||
{
|
||||
if( ownCloudInfo::instance()->isConfigured() ) {
|
||||
@@ -316,12 +345,12 @@ void AccountSettings::slotCheckConnection()
|
||||
connect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
|
||||
this, SLOT(slotOCInfoFail(QNetworkReply*)));
|
||||
|
||||
ui->connectLabel->setText( tr("Checking %1 connection...").arg(Theme::instance()->appNameGUI()));
|
||||
showConnectionLabel( tr("Checking %1 connection...").arg(Theme::instance()->appNameGUI()));
|
||||
qDebug() << "Check status.php from statusdialog.";
|
||||
ownCloudInfo::instance()->checkInstallation();
|
||||
} else {
|
||||
// ownCloud is not yet configured.
|
||||
ui->connectLabel->setText( tr("No %1 connection configured.").arg(Theme::instance()->appNameGUI()));
|
||||
showConnectionLabel( tr("No %1 connection configured.").arg(Theme::instance()->appNameGUI()) );
|
||||
ui->_ButtonAdd->setEnabled( false);
|
||||
}
|
||||
}
|
||||
@@ -329,8 +358,14 @@ void AccountSettings::slotCheckConnection()
|
||||
void AccountSettings::setFolderList( const Folder::Map &folders )
|
||||
{
|
||||
_model->clear();
|
||||
|
||||
foreach(QTimer *t, _hideProgressTimers) {
|
||||
t->stop();
|
||||
delete t;
|
||||
}
|
||||
_hideProgressTimers.clear();
|
||||
|
||||
foreach( Folder *f, folders ) {
|
||||
qDebug() << "Folder: " << f;
|
||||
slotAddFolder( f );
|
||||
}
|
||||
|
||||
@@ -450,8 +485,8 @@ void AccountSettings::slotOCInfo( const QString& url, const QString& versionStr,
|
||||
ui->connectLabel->setOpenExternalLinks(true);
|
||||
QUrl safeUrl(url);
|
||||
safeUrl.setPassword(QString()); // Remove the password from the URL to avoid showing it in the UI
|
||||
ui->connectLabel->setText( tr("Connected to <a href=\"%1\">%2</a>.").arg(url, safeUrl.toString()) );
|
||||
ui->connectLabel->setToolTip( tr("Version: %1 (%2)").arg(versionStr).arg(version));
|
||||
showConnectionLabel( tr("Connected to <a href=\"%1\">%2</a>.").arg(url, safeUrl.toString()),
|
||||
tr("Version: %1 (%2)").arg(versionStr).arg(version) );
|
||||
ui->_ButtonAdd->setEnabled(true);
|
||||
|
||||
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),
|
||||
@@ -465,7 +500,7 @@ void AccountSettings::slotOCInfoFail( QNetworkReply *reply)
|
||||
QString errStr = tr("unknown problem.");
|
||||
if( reply ) errStr = reply->errorString();
|
||||
|
||||
ui->connectLabel->setText( tr("<p>Failed to connect to %1: <tt>%2</tt></p>").arg(Theme::instance()->appNameGUI()).arg(errStr) );
|
||||
showConnectionLabel( tr("<p>Failed to connect to %1: <tt>%2</tt></p>").arg(Theme::instance()->appNameGUI()).arg(errStr) );
|
||||
ui->_ButtonAdd->setEnabled( false);
|
||||
|
||||
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),
|
||||
@@ -654,12 +689,21 @@ void AccountSettings::slotHideProgress()
|
||||
while (i != _hideProgressTimers.constEnd()) {
|
||||
if( i.value() == send_timer ) {
|
||||
QStandardItem *item = i.key();
|
||||
item->setData( QVariant(false), FolderStatusDelegate::AddProgressSpace );
|
||||
item->setData( QVariant(QString::null), FolderStatusDelegate::SyncProgressOverallString );
|
||||
item->setData( QVariant(QString::null), FolderStatusDelegate::SyncProgressItemString );
|
||||
item->setData( 0, FolderStatusDelegate::SyncProgressOverallPercent );
|
||||
|
||||
ui->_folderList->repaint();
|
||||
/* Check if this item is still existing */
|
||||
bool ok = false;
|
||||
for( int r = 0; !ok && r < _model->rowCount(); r++) {
|
||||
if( item == _model->item(r,0) ) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( ok ) {
|
||||
item->setData( QVariant(false), FolderStatusDelegate::AddProgressSpace );
|
||||
item->setData( QVariant(QString::null), FolderStatusDelegate::SyncProgressOverallString );
|
||||
item->setData( QVariant(QString::null), FolderStatusDelegate::SyncProgressItemString );
|
||||
item->setData( 0, FolderStatusDelegate::SyncProgressOverallPercent );
|
||||
}
|
||||
_hideProgressTimers.remove(item);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ public:
|
||||
|
||||
void setFolderList( const Folder::Map& );
|
||||
void buttonsSetEnabled();
|
||||
void setListWidgetItem(QListWidgetItem* item);
|
||||
|
||||
signals:
|
||||
void folderChanged();
|
||||
@@ -74,6 +73,8 @@ public slots:
|
||||
void slotUpdateQuota( qint64,qint64 );
|
||||
void slotIgnoreFilesEditor();
|
||||
|
||||
void setGeneralErrors( const QStringList& errors );
|
||||
|
||||
protected slots:
|
||||
void slotAddFolder();
|
||||
void slotAddFolder( Folder* );
|
||||
@@ -90,15 +91,16 @@ private:
|
||||
QString shortenFilename( const QString& folder, const QString& file ) const;
|
||||
void folderToModelItem( QStandardItem *, Folder * );
|
||||
QStandardItem* itemForFolder(const QString& );
|
||||
void showConnectionLabel( const QString& message, const QString& tooltip = QString() );
|
||||
|
||||
Ui::AccountSettings *ui;
|
||||
QPointer<ItemProgressDialog> _fileItemDialog;
|
||||
QPointer<IgnoreListEditor> _ignoreEditor;
|
||||
QStandardItemModel *_model;
|
||||
QListWidgetItem *_item;
|
||||
QUrl _OCUrl;
|
||||
QHash<QStandardItem*, QTimer*> _hideProgressTimers;
|
||||
QString _kindContext;
|
||||
QStringList _generalErrors;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/folderman.h"
|
||||
#include "mirall/folderwatcher.h"
|
||||
#include "mirall/folderwizard.h"
|
||||
#include "mirall/networklocation.h"
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/owncloudsetupwizard.h"
|
||||
@@ -83,7 +82,7 @@ static const char optionsC[] =
|
||||
QString applicationTrPath()
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
return QString::fromLatin1(DATADIR"/i18n/");
|
||||
return QString::fromLatin1(DATADIR"/"APPLICATION_EXECUTABLE"/i18n/");
|
||||
#endif
|
||||
#ifdef Q_OS_MAC
|
||||
return QApplication::applicationDirPath()+QLatin1String("/../Resources/Translations"); // path defaults to app dir.
|
||||
@@ -179,18 +178,13 @@ Application::Application(int &argc, char **argv) :
|
||||
connect( ownCloudInfo::instance(), SIGNAL(quotaUpdated(qint64,qint64)),
|
||||
SLOT(slotRefreshQuotaDisplay(qint64, qint64)));
|
||||
|
||||
connect (this, SIGNAL(aboutToQuit()), SLOT(slotCleanup()));
|
||||
|
||||
qDebug() << "Network Location: " << NetworkLocation::currentLocation().encoded();
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
if (_settingsDialog) {
|
||||
delete _settingsDialog.data();
|
||||
}
|
||||
|
||||
delete _logBrowser;
|
||||
delete _tray; // needed, see ctor
|
||||
|
||||
qDebug() << "* Mirall shutdown";
|
||||
}
|
||||
|
||||
@@ -229,8 +223,24 @@ void Application::slotCredentialsFetched()
|
||||
runValidator();
|
||||
}
|
||||
|
||||
void Application::slotCleanup()
|
||||
{
|
||||
// explicitly close windows. This is somewhat of a hack to ensure
|
||||
// that saving the geometries happens ASAP during a OS shutdown
|
||||
|
||||
// those do delete on close
|
||||
if (!_settingsDialog.isNull()) _settingsDialog->close();
|
||||
if (!_progressDialog.isNull()) _progressDialog->close();
|
||||
|
||||
// those need an extra invitation
|
||||
if (!_tray.isNull()) _tray->deleteLater();
|
||||
if (!_logBrowser.isNull()) _logBrowser->deleteLater();
|
||||
}
|
||||
|
||||
void Application::runValidator()
|
||||
{
|
||||
_startupFail.clear();
|
||||
|
||||
_conValidator = new ConnectionValidator();
|
||||
connect( _conValidator, SIGNAL(connectionResult(ConnectionValidator::Status)),
|
||||
this, SLOT(slotConnectionValidatorResult(ConnectionValidator::Status)) );
|
||||
@@ -249,20 +259,21 @@ void Application::slotConnectionValidatorResult(ConnectionValidator::Status stat
|
||||
_tray->show();
|
||||
|
||||
int cnt = folderMan->map().size();
|
||||
slotShowTrayMessage(tr("%1 Sync Started").arg(_theme->appNameGUI()),
|
||||
slotShowOptionalTrayMessage(tr("%1 Sync Started").arg(_theme->appNameGUI()),
|
||||
tr("Sync started for %n configured sync folder(s).","", cnt));
|
||||
|
||||
// queue up the sync for all folders.
|
||||
folderMan->slotScheduleAllFolders();
|
||||
|
||||
computeOverallSyncStatus();
|
||||
|
||||
setupContextMenu();
|
||||
} else if( status == ConnectionValidator::NotConfigured ) {
|
||||
// this can not happen, it should be caught in first step of startup.
|
||||
} else {
|
||||
// What else?
|
||||
// if we have problems here, it's unlikely that syncing will work.
|
||||
FolderMan::instance()->setSyncEnabled(false);
|
||||
|
||||
_startupFail = _conValidator->errors();
|
||||
}
|
||||
computeOverallSyncStatus();
|
||||
setupContextMenu();
|
||||
|
||||
_conValidator->deleteLater();
|
||||
}
|
||||
|
||||
@@ -347,7 +358,7 @@ void Application::setupSystemTray()
|
||||
_tray = new Systray();
|
||||
_tray->setIcon( _theme->syncStateIcon( SyncResult::NotYetStarted, true ) );
|
||||
|
||||
connect(_tray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||
connect(_tray.data(), SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||
SLOT(slotTrayClicked(QSystemTrayIcon::ActivationReason)));
|
||||
|
||||
setupContextMenu();
|
||||
@@ -425,7 +436,7 @@ void Application::setupContextMenu()
|
||||
void Application::setupLogBrowser()
|
||||
{
|
||||
// might be called from second instance
|
||||
if (!_logBrowser) {
|
||||
if (_logBrowser.isNull()) {
|
||||
// init the log browser.
|
||||
qInstallMsgHandler( mirallLogCatcher );
|
||||
_logBrowser = new LogBrowser;
|
||||
@@ -662,7 +673,7 @@ bool Application::checkConfigExists(bool openSettings)
|
||||
// if no config file is there, start the configuration wizard.
|
||||
MirallConfigFile cfgFile;
|
||||
|
||||
if( cfgFile.exists() ) {
|
||||
if( cfgFile.exists() && !cfgFile.ownCloudUrl().isEmpty() ) {
|
||||
if( openSettings ) {
|
||||
slotSettings();
|
||||
}
|
||||
@@ -694,7 +705,9 @@ void Application::slotSettings()
|
||||
_settingsDialog->setAttribute( Qt::WA_DeleteOnClose, true );
|
||||
_settingsDialog->show();
|
||||
}
|
||||
Utility::raiseDialog(_settingsDialog);
|
||||
|
||||
_settingsDialog->setGeneralErrors( _startupFail );
|
||||
Utility::raiseDialog(_settingsDialog.data());
|
||||
}
|
||||
|
||||
void Application::slotItemProgressDialog()
|
||||
@@ -705,7 +718,7 @@ void Application::slotItemProgressDialog()
|
||||
_progressDialog->setupList();
|
||||
_progressDialog->show();
|
||||
}
|
||||
Utility::raiseDialog(_progressDialog);
|
||||
Utility::raiseDialog(_progressDialog.data());
|
||||
}
|
||||
|
||||
void Application::slotParseOptions(const QString &opts)
|
||||
@@ -816,23 +829,31 @@ void Application::computeOverallSyncStatus()
|
||||
Folder::Map map = folderMan->map();
|
||||
SyncResult overallResult = FolderMan::accountStatus(map.values());
|
||||
|
||||
// create the tray blob message, check if we have an defined state
|
||||
if( overallResult.status() != SyncResult::Undefined ) {
|
||||
QStringList allStatusStrings;
|
||||
foreach(Folder* folder, map.values()) {
|
||||
qDebug() << "Folder in overallStatus Message: " << folder << " with name " << folder->alias();
|
||||
QString folderMessage = folderMan->statusToString(folder->syncResult().status(), folder->syncEnabled());
|
||||
allStatusStrings += tr("Folder %1: %2").arg(folder->alias(), folderMessage);
|
||||
}
|
||||
|
||||
if( ! allStatusStrings.isEmpty() )
|
||||
trayMessage = allStatusStrings.join(QLatin1String("\n"));
|
||||
else
|
||||
trayMessage = tr("No sync folders configured.");
|
||||
|
||||
QIcon statusIcon = _theme->syncStateIcon( overallResult.status(), true);
|
||||
// if there have been startup problems, show an error message.
|
||||
if( !_startupFail.isEmpty() ) {
|
||||
trayMessage = _startupFail.join(QLatin1String("\n"));
|
||||
QIcon statusIcon = _theme->syncStateIcon( SyncResult::Error, true );
|
||||
_tray->setIcon( statusIcon );
|
||||
_tray->setToolTip(trayMessage);
|
||||
} else {
|
||||
// create the tray blob message, check if we have an defined state
|
||||
if( overallResult.status() != SyncResult::Undefined ) {
|
||||
QStringList allStatusStrings;
|
||||
foreach(Folder* folder, map.values()) {
|
||||
qDebug() << "Folder in overallStatus Message: " << folder << " with name " << folder->alias();
|
||||
QString folderMessage = folderMan->statusToString(folder->syncResult().status(), folder->syncEnabled());
|
||||
allStatusStrings += tr("Folder %1: %2").arg(folder->alias(), folderMessage);
|
||||
}
|
||||
|
||||
if( ! allStatusStrings.isEmpty() )
|
||||
trayMessage = allStatusStrings.join(QLatin1String("\n"));
|
||||
else
|
||||
trayMessage = tr("No sync folders configured.");
|
||||
|
||||
QIcon statusIcon = _theme->syncStateIcon( overallResult.status(), true);
|
||||
_tray->setIcon( statusIcon );
|
||||
_tray->setToolTip(trayMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace Mirall {
|
||||
class Theme;
|
||||
class Folder;
|
||||
class FolderWatcher;
|
||||
class FolderWizard;
|
||||
class ownCloudInfo;
|
||||
class SslErrorDialog;
|
||||
class SettingsDialog;
|
||||
@@ -107,13 +106,14 @@ protected slots:
|
||||
void slotDisplayIdle();
|
||||
void slotHelp();
|
||||
void slotCredentialsFetched();
|
||||
void slotCleanup();
|
||||
private:
|
||||
void setHelp();
|
||||
void raiseDialog( QWidget* );
|
||||
void rebuildRecentMenus();
|
||||
void runValidator();
|
||||
|
||||
Systray *_tray;
|
||||
QPointer<Systray> _tray;
|
||||
QAction *_actionOpenoC;
|
||||
QAction *_actionSettings;
|
||||
QAction *_actionQuota;
|
||||
@@ -124,7 +124,6 @@ private:
|
||||
|
||||
QNetworkConfigurationManager *_networkMgr;
|
||||
|
||||
QPointer<FolderWizard> _folderWizard;
|
||||
SslErrorDialog *_sslErrorDialog;
|
||||
ConnectionValidator *_conValidator;
|
||||
|
||||
@@ -134,12 +133,13 @@ private:
|
||||
|
||||
Theme *_theme;
|
||||
QSignalMapper *_folderOpenActionMapper;
|
||||
LogBrowser *_logBrowser;
|
||||
QPointer<LogBrowser>_logBrowser;
|
||||
QPointer<SettingsDialog> _settingsDialog;
|
||||
QPointer<ItemProgressDialog> _progressDialog;
|
||||
|
||||
QString _logFile;
|
||||
QString _logDirectory;
|
||||
QStringList _startupFail;
|
||||
|
||||
int _logExpire;
|
||||
bool _showLogWindow;
|
||||
|
||||
@@ -89,6 +89,7 @@ void ConnectionValidator::checkConnection()
|
||||
// checks for status.php
|
||||
ownCloudInfo::instance()->checkInstallation();
|
||||
} else {
|
||||
_errors << tr("No ownCloud connection configured");
|
||||
emit connectionResult( NotConfigured );
|
||||
}
|
||||
}
|
||||
@@ -109,8 +110,8 @@ void ConnectionValidator::slotStatusFound( const QString& url, const QString& ve
|
||||
this, SLOT(slotNoStatusFound(QNetworkReply*)));
|
||||
|
||||
if( version.startsWith("4.0") ) {
|
||||
_errors.append( tr("<p>The configured server for this client is too old.</p>"
|
||||
"<p>Please update to the latest server and restart the client.</p>"));
|
||||
_errors.append( tr("The configured server for this client is too old") );
|
||||
_errors.append( tr("Please update to the latest server and restart the client.") );
|
||||
emit connectionResult( ServerVersionMismatch );
|
||||
return;
|
||||
}
|
||||
@@ -144,15 +145,17 @@ void ConnectionValidator::slotCheckAuthentication()
|
||||
// continue in slotAuthCheck here :-)
|
||||
}
|
||||
|
||||
void ConnectionValidator::slotAuthCheck( const QString& ,QNetworkReply *reply )
|
||||
void ConnectionValidator::slotAuthCheck( const QString&, QNetworkReply *reply )
|
||||
{
|
||||
Status stat = Connected;
|
||||
|
||||
if( reply->error() == QNetworkReply::AuthenticationRequiredError ||
|
||||
reply->error() == QNetworkReply::OperationCanceledError ) { // returned if the user is wrong.
|
||||
qDebug() << "******** Password is wrong!";
|
||||
_errors << "The provided credentials are wrong.";
|
||||
_errors << tr("The provided credentials are not correct");
|
||||
stat = CredentialsWrong;
|
||||
} else if( reply->error() != QNetworkReply::NoError ) {
|
||||
_errors << reply->errorString();
|
||||
}
|
||||
|
||||
// disconnect from ownCloud Info signals
|
||||
|
||||
@@ -111,6 +111,7 @@ bool Folder::init()
|
||||
}
|
||||
return _csync_ctx;
|
||||
}
|
||||
|
||||
Folder::~Folder()
|
||||
{
|
||||
if( _thread ) {
|
||||
@@ -196,15 +197,13 @@ bool Folder::syncEnabled() const
|
||||
void Folder::setSyncEnabled( bool doit )
|
||||
{
|
||||
_enabled = doit;
|
||||
_watcher->setEventsEnabled( doit );
|
||||
|
||||
qDebug() << "setSyncEnabled - ############################ " << doit;
|
||||
if( doit ) {
|
||||
// undefined until next sync
|
||||
_syncResult.setStatus( SyncResult::NotYetStarted);
|
||||
_syncResult.clearErrors();
|
||||
evaluateSync( QStringList() );
|
||||
// qDebug() << "Syncing enabled on folder " << name();
|
||||
} else {
|
||||
// do not stop or start the watcher here, that is done internally by
|
||||
// folder class. Even if the watcher fires, the folder does not
|
||||
// schedule itself because it checks the var. _enabled before.
|
||||
_pollTimer.stop();
|
||||
}
|
||||
}
|
||||
@@ -227,6 +226,7 @@ void Folder::evaluateSync(const QStringList &/*pathList*/)
|
||||
}
|
||||
|
||||
_syncResult.setStatus( SyncResult::NotYetStarted );
|
||||
_syncResult.clearErrors();
|
||||
emit scheduleToSync( alias() );
|
||||
|
||||
}
|
||||
@@ -235,8 +235,9 @@ void Folder::slotPollTimerTimeout()
|
||||
{
|
||||
qDebug() << "* Polling" << alias() << "for changes. (time since next sync:" << (_timeSinceLastSync.elapsed() / 1000) << "s)";
|
||||
|
||||
if (quint64(_timeSinceLastSync.elapsed()) > MirallConfigFile().forceSyncInterval()) {
|
||||
qDebug() << "* Force Sync now";
|
||||
if (quint64(_timeSinceLastSync.elapsed()) > MirallConfigFile().forceSyncInterval() ||
|
||||
_syncResult.status() != SyncResult::Success ) {
|
||||
qDebug() << "** Force Sync now";
|
||||
evaluateSync(QStringList());
|
||||
} else {
|
||||
RequestEtagJob* job = new RequestEtagJob(secondPath(), this);
|
||||
@@ -561,7 +562,6 @@ void Folder::startSync(const QStringList &pathList)
|
||||
|
||||
qDebug() << "*** Start syncing";
|
||||
_thread = new QThread(this);
|
||||
_thread->setPriority(QThread::LowPriority);
|
||||
setIgnoredFiles();
|
||||
_csync = new CSyncThread( _csync_ctx );
|
||||
_csync->moveToThread(_thread);
|
||||
@@ -584,6 +584,7 @@ void Folder::startSync(const QStringList &pathList)
|
||||
connect(_csync, SIGNAL(transmissionProgress(Progress::Info)), this, SLOT(slotTransmissionProgress(Progress::Info)));
|
||||
|
||||
_thread->start();
|
||||
_thread->setPriority(QThread::LowPriority);
|
||||
QMetaObject::invokeMethod(_csync, "startSync", Qt::QueuedConnection);
|
||||
|
||||
// disable events until syncing is done
|
||||
|
||||
@@ -280,6 +280,7 @@ void FolderMan::slotEnableFolder( const QString& alias, bool enable )
|
||||
Folder *f = _folderMap[alias];
|
||||
if( f ) {
|
||||
f->setSyncEnabled(enable);
|
||||
f->evaluateSync(QStringList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,6 +362,10 @@ void FolderMan::setSyncEnabled( bool enabled )
|
||||
QTimer::singleShot(200, this, SLOT(slotScheduleFolderSync()));
|
||||
}
|
||||
_syncEnabled = enabled;
|
||||
|
||||
foreach( Folder *f, _folderMap.values() ) {
|
||||
f->setSyncEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -467,7 +472,10 @@ void FolderMan::removeFolder( const QString& alias )
|
||||
qDebug() << "Remove folder config file " << file.fileName();
|
||||
file.remove();
|
||||
}
|
||||
f->deleteLater();
|
||||
// FIXME: this is a temporar dirty fix against a crash happening because
|
||||
// the csync owncloud module still has static components. Activate the
|
||||
// delete once the module is fixed.
|
||||
// f->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,8 +81,9 @@ QSize FolderStatusDelegate::sizeHint(const QStyleOptionViewItem & option ,
|
||||
h += aliasMargin; // bottom margin
|
||||
|
||||
// add some space to show an error condition.
|
||||
if( ! qvariant_cast<QString>(index.data(FolderErrorMsg)).isEmpty() ) {
|
||||
h += aliasMargin*2+fm.height();
|
||||
if( ! qvariant_cast<QStringList>(index.data(FolderErrorMsg)).isEmpty() ) {
|
||||
QStringList errMsgs = qvariant_cast<QStringList>(index.data(FolderErrorMsg));
|
||||
h += aliasMargin*2 + errMsgs.count()*fm.height();
|
||||
}
|
||||
|
||||
if( qvariant_cast<bool>(index.data(AddProgressSpace)) ) {
|
||||
@@ -122,7 +123,7 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
QString aliasText = qvariant_cast<QString>(index.data(FolderAliasRole));
|
||||
QString pathText = qvariant_cast<QString>(index.data(FolderPathRole));
|
||||
QString remotePath = qvariant_cast<QString>(index.data(FolderSecondPathRole));
|
||||
QString errorText = qvariant_cast<QString>(index.data(FolderErrorMsg));
|
||||
QStringList errorTexts= qvariant_cast<QStringList>(index.data(FolderErrorMsg));
|
||||
|
||||
int overallPercent = qvariant_cast<int>(index.data(SyncProgressOverallPercent));
|
||||
QString overallString = qvariant_cast<QString>(index.data(SyncProgressOverallString));
|
||||
@@ -211,12 +212,12 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
// paint an error overlay if there is an error string
|
||||
|
||||
int h = iconRect.bottom();
|
||||
if( !errorText.isEmpty() ) {
|
||||
if( !errorTexts.isEmpty() ) {
|
||||
h += aliasMargin;
|
||||
QRect errorRect = localPathRect;
|
||||
errorRect.setLeft( iconRect.left());
|
||||
errorRect.setTop( h );
|
||||
errorRect.setHeight(subFm.height()+aliasMargin);
|
||||
errorRect.setHeight(errorTexts.count() * subFm.height()+aliasMargin);
|
||||
errorRect.setRight( option.rect.right()-aliasMargin );
|
||||
|
||||
painter->setBrush( QColor(0xbb, 0x4d, 0x4d) );
|
||||
@@ -226,15 +227,16 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
painter->setPen( Qt::white );
|
||||
painter->setFont(errorFont);
|
||||
QRect errorTextRect = errorRect;
|
||||
errorTextRect.setLeft( errorTextRect.left()+aliasMargin +16);
|
||||
errorTextRect.setLeft( errorTextRect.left()+aliasMargin );
|
||||
errorTextRect.setTop( errorTextRect.top()+aliasMargin/2 );
|
||||
|
||||
int linebreak = errorText.indexOf(QLatin1String("<br"));
|
||||
QString eText = errorText;
|
||||
if(linebreak) {
|
||||
eText = errorText.left(linebreak);
|
||||
int x = errorTextRect.left();
|
||||
int y = errorTextRect.top()+aliasMargin/2 + subFm.height()/2;
|
||||
|
||||
foreach( QString eText, errorTexts ) {
|
||||
painter->drawText(x, y, subFm.elidedText( eText, Qt::ElideLeft, errorTextRect.width()-2*aliasMargin));
|
||||
y += subFm.height();
|
||||
}
|
||||
painter->drawText(errorTextRect, eText);
|
||||
|
||||
h = errorRect.bottom();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "mirall/folderwizard.h"
|
||||
#include "mirall/folderman.h"
|
||||
#include "mirall/owncloudinfo.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/theme.h"
|
||||
@@ -242,6 +243,7 @@ static void recursiveInsert(QTreeWidgetItem *parent, QStringList pathTrail, QStr
|
||||
item = new QTreeWidgetItem(parent);
|
||||
item->setIcon(0, folderIcon);
|
||||
item->setText(0, pathTrail.first());
|
||||
item->setData(0, Qt::UserRole, pathTrail.first());
|
||||
item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
|
||||
}
|
||||
|
||||
@@ -252,17 +254,13 @@ static void recursiveInsert(QTreeWidgetItem *parent, QStringList pathTrail, QStr
|
||||
|
||||
void FolderWizardTargetPage::slotUpdateDirectories(QStringList list)
|
||||
{
|
||||
QFileIconProvider prov;
|
||||
QIcon folderIcon = prov.icon(QFileIconProvider::Folder);
|
||||
|
||||
QString webdavFolder = QUrl(ownCloudInfo::instance()->webdavUrl()).path();
|
||||
connect(_ui.folderTreeWidget, SIGNAL(itemExpanded(QTreeWidgetItem*)), SLOT(slotItemExpanded(QTreeWidgetItem*)));
|
||||
|
||||
QTreeWidgetItem *root = _ui.folderTreeWidget->topLevelItem(0);
|
||||
if (!root) {
|
||||
root = new QTreeWidgetItem(_ui.folderTreeWidget);
|
||||
root->setText(0, tr("Root (\"/\")", "root folder"));
|
||||
root->setIcon(0, folderIcon);
|
||||
root->setText(0, Theme::instance()->appNameGUI());
|
||||
root->setIcon(0, Theme::instance()->applicationIcon());
|
||||
root->setToolTip(0, tr("Choose this to sync the entire account"));
|
||||
root->setData(0, Qt::UserRole, "/");
|
||||
}
|
||||
@@ -283,7 +281,7 @@ void FolderWizardTargetPage::slotRefreshFolders()
|
||||
|
||||
void FolderWizardTargetPage::slotItemExpanded(QTreeWidgetItem *item)
|
||||
{
|
||||
ownCloudInfo::instance()->getDirectoryListing(item->text(0));
|
||||
ownCloudInfo::instance()->getDirectoryListing(item->data(0, Qt::UserRole).toString());
|
||||
}
|
||||
|
||||
FolderWizardTargetPage::~FolderWizardTargetPage()
|
||||
@@ -298,6 +296,22 @@ bool FolderWizardTargetPage::isComplete() const
|
||||
QString dir = _ui.folderTreeWidget->currentItem()->data(0, Qt::UserRole).toString();
|
||||
wizard()->setProperty("targetPath", dir);
|
||||
|
||||
Folder::Map map = _folderMap;
|
||||
Folder::Map::const_iterator i = map.constBegin();
|
||||
for(i = map.constBegin();i != map.constEnd(); i++ ) {
|
||||
Folder *f = static_cast<Folder*>(i.value());
|
||||
QString curDir = f->secondPath();
|
||||
if (dir == curDir) {
|
||||
showWarn( tr("This directory is already being synced.") );
|
||||
return false;
|
||||
} else if (dir.startsWith(curDir)) {
|
||||
if (dir.isEmpty()) dir = QLatin1Char('/');
|
||||
if (curDir.isEmpty()) curDir = QLatin1Char('/');
|
||||
showWarn( tr("You are already syncing <i>%1</i>, which is a parent folder of <i>%2</i>.").arg(curDir).arg(dir) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( dir == QLatin1String("/") ) {
|
||||
showWarn( tr("If you sync the root folder, you can <b>not</b> configure another sync directory."));
|
||||
return true;
|
||||
@@ -325,6 +339,8 @@ void FolderWizardTargetPage::initializePage()
|
||||
SLOT(slotCreateRemoteFolderFinished( QNetworkReply::NetworkError )));
|
||||
connect( ocInfo, SIGNAL(directoryListingUpdated(QStringList)),
|
||||
SLOT(slotUpdateDirectories(QStringList)));
|
||||
connect(_ui.folderTreeWidget, SIGNAL(itemExpanded(QTreeWidgetItem*)),
|
||||
SLOT(slotItemExpanded(QTreeWidgetItem*)));
|
||||
|
||||
slotRefreshFolders();
|
||||
}
|
||||
@@ -370,6 +386,7 @@ FolderWizard::~FolderWizard()
|
||||
void FolderWizard::setFolderMap( const Folder::Map& fm)
|
||||
{
|
||||
_folderWizardSourcePage->setFolderMap( fm );
|
||||
_folderWizardTargetPage->setFolderMap( fm );
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
@@ -69,6 +69,8 @@ public:
|
||||
virtual void initializePage();
|
||||
virtual void cleanupPage();
|
||||
|
||||
void setFolderMap( const Folder::Map &fm ) { _folderMap = fm; }
|
||||
|
||||
protected slots:
|
||||
|
||||
void showWarn( const QString& = QString() ) const;
|
||||
@@ -83,6 +85,7 @@ private:
|
||||
ownCloudInfo *_ownCloudDirCheck;
|
||||
bool _dirChecked;
|
||||
bool _warnWasVisible;
|
||||
Folder::Map _folderMap;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -127,11 +127,16 @@ LogBrowser::LogBrowser(QWidget *parent) :
|
||||
}
|
||||
|
||||
LogBrowser::~LogBrowser()
|
||||
{
|
||||
}
|
||||
|
||||
void LogBrowser::closeEvent(QCloseEvent *)
|
||||
{
|
||||
MirallConfigFile cfg;
|
||||
cfg.saveGeometry(this);
|
||||
}
|
||||
|
||||
|
||||
void LogBrowser::slotNewLog( const QString& msg )
|
||||
{
|
||||
if( _logWidget->isVisible() ) {
|
||||
|
||||
@@ -47,6 +47,9 @@ public:
|
||||
|
||||
void setLogFile(const QString& , bool );
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
|
||||
protected slots:
|
||||
void slotNewLog( const QString &msg );
|
||||
void slotFind();
|
||||
|
||||
@@ -138,7 +138,8 @@ QNetworkReply* ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
qDebug() << "OCInfo Making dir " << dir;
|
||||
_authAttempts = 0;
|
||||
QNetworkRequest req;
|
||||
QUrl url = QUrl(webdavUrl(_connection));
|
||||
QUrl url( webdavUrl(_connection) );
|
||||
// ensure #, ? and co are interpreted as part of the path and nothing else
|
||||
url.setEncodedPath(url.encodedPath()+QUrl::toPercentEncoding(dir, "/"));
|
||||
|
||||
req.setUrl( url );
|
||||
@@ -162,7 +163,7 @@ QNetworkReply* ownCloudInfo::mkdirRequest( const QString& dir )
|
||||
QNetworkReply* ownCloudInfo::getQuotaRequest( const QString& dir )
|
||||
{
|
||||
QNetworkRequest req;
|
||||
req.setUrl( QUrl( webdavUrl(_connection) + dir ) );
|
||||
req.setUrl( QUrl( webdavUrl(_connection) + QUrl::toPercentEncoding(dir, "/") ) );
|
||||
req.setRawHeader("Depth", "0");
|
||||
QByteArray xml("<?xml version=\"1.0\" ?>\n"
|
||||
"<d:propfind xmlns:d=\"DAV:\">\n"
|
||||
@@ -190,7 +191,10 @@ QNetworkReply* ownCloudInfo::getQuotaRequest( const QString& dir )
|
||||
QNetworkReply* ownCloudInfo::getDirectoryListing( const QString& dir )
|
||||
{
|
||||
QNetworkRequest req;
|
||||
req.setUrl( QUrl( webdavUrl(_connection) + dir ) );
|
||||
QUrl url( webdavUrl(_connection) );
|
||||
// ensure #, ? and co are interpreted as part of the path and nothing else
|
||||
url.setPath(url.path() + dir );
|
||||
req.setUrl( url );
|
||||
req.setRawHeader("Depth", "1");
|
||||
QByteArray xml("<?xml version=\"1.0\" ?>\n"
|
||||
"<d:propfind xmlns:d=\"DAV:\">\n"
|
||||
|
||||
@@ -63,8 +63,15 @@ OwncloudSetupWizard::~OwncloudSetupWizard()
|
||||
|
||||
void OwncloudSetupWizard::runWizard(QObject* obj, const char* amember, QWidget *parent)
|
||||
{
|
||||
OwncloudSetupWizard *wiz = new OwncloudSetupWizard(parent);
|
||||
static QPointer<OwncloudSetupWizard> wiz;
|
||||
|
||||
if (!wiz.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
wiz = new OwncloudSetupWizard(parent);
|
||||
connect( wiz, SIGNAL(ownCloudWizardDone(int)), obj, amember);
|
||||
connect( wiz, SIGNAL(ownCloudWizardDone(int)), wiz, SLOT(deleteLater()));
|
||||
FolderMan::instance()->setSyncEnabled(false);
|
||||
wiz->startWizard();
|
||||
}
|
||||
|
||||
@@ -95,15 +95,29 @@ SettingsDialog::SettingsDialog(Application *app, QWidget *parent) :
|
||||
connect(showLogWindow, SIGNAL(triggered()), app, SLOT(slotOpenLogBrowser()));
|
||||
addAction(showLogWindow);
|
||||
|
||||
int iconSize = 32;
|
||||
QListWidget *listWidget = _ui->labelWidget;
|
||||
int spacing = 20;
|
||||
// reverse at least ~8 characters
|
||||
int effectiveWidth = fontMetrics().averageCharWidth() * 8 + iconSize + spacing;
|
||||
// less than ~16 characters, elide otherwise
|
||||
int maxWidth = fontMetrics().averageCharWidth() * 16 + iconSize + spacing;
|
||||
for (int i = 0; i < listWidget->count(); i++) {
|
||||
QListWidgetItem *item = listWidget->item(i);
|
||||
QFontMetrics fm(item->font());
|
||||
int curWidth = fm.width(item->text()) + iconSize + spacing;
|
||||
effectiveWidth = qMax(curWidth, effectiveWidth);
|
||||
if (curWidth > maxWidth) item->setToolTip(item->text());
|
||||
}
|
||||
effectiveWidth = qMin(effectiveWidth, maxWidth);
|
||||
listWidget->setFixedWidth(effectiveWidth);
|
||||
|
||||
MirallConfigFile cfg;
|
||||
cfg.restoreGeometry(this);
|
||||
}
|
||||
|
||||
SettingsDialog::~SettingsDialog()
|
||||
{
|
||||
MirallConfigFile cfg;
|
||||
cfg.saveGeometry(this);
|
||||
|
||||
delete _ui;
|
||||
}
|
||||
|
||||
@@ -123,4 +137,23 @@ void SettingsDialog::slotUpdateAccountState()
|
||||
_accountItem->setIcon(Theme::instance()->syncStateIcon(state.status()));
|
||||
}
|
||||
|
||||
void SettingsDialog::setGeneralErrors(const QStringList &errors)
|
||||
{
|
||||
_accountSettings->setGeneralErrors(errors);
|
||||
}
|
||||
|
||||
|
||||
// close event is not being called here
|
||||
void SettingsDialog::reject() {
|
||||
MirallConfigFile cfg;
|
||||
cfg.saveGeometry(this);
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
void SettingsDialog::accept() {
|
||||
MirallConfigFile cfg;
|
||||
cfg.saveGeometry(this);
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
} // namespace Mirall
|
||||
|
||||
@@ -40,6 +40,11 @@ public:
|
||||
~SettingsDialog();
|
||||
|
||||
void addAccount(const QString &title, QWidget *widget);
|
||||
void setGeneralErrors( const QStringList& errors );
|
||||
|
||||
protected:
|
||||
void reject();
|
||||
void accept();
|
||||
|
||||
protected slots:
|
||||
void slotUpdateAccountState();
|
||||
@@ -48,7 +53,6 @@ private:
|
||||
Ui::SettingsDialog *_ui;
|
||||
AccountSettings *_accountSettings;
|
||||
QListWidgetItem *_accountItem;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,16 +14,7 @@
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
@@ -37,12 +28,6 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
class QSslError;
|
||||
class QSslCertificate;
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
namespace Ui {
|
||||
class SslErrorDialog;
|
||||
}
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
class SslErrorDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
|
||||
QList<QSslCertificate> _unknownCerts;
|
||||
QString _customConfigHandle;
|
||||
::Ui::SslErrorDialog *_ui;
|
||||
Ui::SslErrorDialog *_ui;
|
||||
};
|
||||
} // end namespace
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SslErrorDialog</class>
|
||||
<widget class="QWidget" name="SslErrorDialog">
|
||||
<class>Mirall::SslErrorDialog</class>
|
||||
<widget class="QWidget" name="Mirall::SslErrorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef SYNCFILEITEM_H
|
||||
#define SYNCFILEITEM_H
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -37,6 +38,7 @@
|
||||
#elif defined(Q_OS_WIN)
|
||||
#include <shlobj.h>
|
||||
#include <winbase.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace Mirall {
|
||||
@@ -103,10 +105,10 @@ void Utility::setupFavLink(const QString &folder)
|
||||
|
||||
QString Utility::octetsToString( qint64 octets )
|
||||
{
|
||||
static const qint64 kb = 1000;
|
||||
static const qint64 mb = 1000 * kb;
|
||||
static const qint64 gb = 1000 * mb;
|
||||
static const qint64 tb = 1000 * gb;
|
||||
static const qint64 kb = 1024;
|
||||
static const qint64 mb = 1024 * kb;
|
||||
static const qint64 gb = 1024 * mb;
|
||||
static const qint64 tb = 1024 * gb;
|
||||
|
||||
QString s;
|
||||
qreal value = octets;
|
||||
@@ -366,4 +368,12 @@ QString Utility::toCSyncScheme(const QString &urlStr)
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
void Utility::sleep(int sec)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
::Sleep(sec*1000);
|
||||
#else
|
||||
::sleep(sec);
|
||||
#endif
|
||||
}
|
||||
} // namespace Mirall
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace Mirall {
|
||||
|
||||
namespace Utility
|
||||
{
|
||||
void sleep(int sec);
|
||||
QString formatFingerprint( const QByteArray& );
|
||||
void setupFavLink( const QString &folder );
|
||||
QString octetsToString( qint64 octets );
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QUrl>
|
||||
#include <QTimer>
|
||||
|
||||
#include "QProgressIndicator.h"
|
||||
|
||||
@@ -26,7 +27,6 @@
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "creds/abstractcredentials.h"
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
@@ -89,8 +89,8 @@ void OwncloudAdvancedSetupPage::initializePage()
|
||||
// call to init label
|
||||
updateStatus();
|
||||
|
||||
// TODO: focus
|
||||
_ui.pbSelectLocalFolder->setFocus();
|
||||
// ensure "next" gets the focus, not obSelectLocalFolder
|
||||
QTimer::singleShot(0, wizard()->button(QWizard::NextButton), SLOT(setFocus()));
|
||||
}
|
||||
|
||||
// Called if the user changes the user- or url field. Adjust the texts and
|
||||
|
||||
@@ -26,27 +26,31 @@ private slots:
|
||||
}
|
||||
void testOctetsToString()
|
||||
{
|
||||
QLocale::setDefault(QLocale("en"));
|
||||
QCOMPARE(octetsToString(999) , QString("999 B"));
|
||||
QCOMPARE(octetsToString(1000) , QString("1 kB"));
|
||||
QCOMPARE(octetsToString(1010) , QString("1 kB"));
|
||||
QCOMPARE(octetsToString(1000) , QString("1,000 B"));
|
||||
QCOMPARE(octetsToString(1010) , QString("1,010 B"));
|
||||
QCOMPARE(octetsToString(1024) , QString("1 kB"));
|
||||
QCOMPARE(octetsToString(1110) , QString("1.1 kB"));
|
||||
|
||||
QCOMPARE(octetsToString(9110) , QString("9.1 kB"));
|
||||
QCOMPARE(octetsToString(9910) , QString("9.9 kB"));
|
||||
QCOMPARE(octetsToString(9999) , QString("10 kB"));
|
||||
QCOMPARE(octetsToString(9110) , QString("8.9 kB"));
|
||||
QCOMPARE(octetsToString(9910) , QString("9.7 kB"));
|
||||
QCOMPARE(octetsToString(9999) , QString("9.8 kB"));
|
||||
QCOMPARE(octetsToString(10240) , QString("10 kB"));
|
||||
|
||||
QCOMPARE(octetsToString(123456) , QString("123 kB"));
|
||||
QCOMPARE(octetsToString(123456) , QString("121 kB"));
|
||||
QCOMPARE(octetsToString(1234567) , QString("1.2 MB"));
|
||||
QCOMPARE(octetsToString(12345678) , QString("12 MB"));
|
||||
QCOMPARE(octetsToString(123456789) , QString("123 MB"));
|
||||
QCOMPARE(octetsToString(1000LL*1000*1000 * 5) , QString("5 GB"));
|
||||
QCOMPARE(octetsToString(123456789) , QString("118 MB"));
|
||||
QCOMPARE(octetsToString(1000LL*1000*1000 * 5) , QString("4.7 GB"));
|
||||
QCOMPARE(octetsToString(1024LL*1024*1024 * 5) , QString("5 GB"));
|
||||
|
||||
QCOMPARE(octetsToString(1), QString("1 B"));
|
||||
QCOMPARE(octetsToString(2), QString("2 B"));
|
||||
QCOMPARE(octetsToString(1024), QString("1 kB"));
|
||||
QCOMPARE(octetsToString(1024*1024), QString("1 MB"));
|
||||
QCOMPARE(octetsToString(1024LL*1024*1024), QString("1.1 GB"));
|
||||
QCOMPARE(octetsToString(1024LL*1024*1024*1024), QString("1.1 TB"));
|
||||
QCOMPARE(octetsToString(1024LL*1024*1024), QString("1 GB"));
|
||||
QCOMPARE(octetsToString(1024LL*1024*1024*1024), QString("1 TB"));
|
||||
}
|
||||
|
||||
void testLaunchOnStartup()
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 739 B After Width: | Height: | Size: 781 B |
Reference in New Issue
Block a user