nextcloud-desktop/src/mirall/folderwizard.cpp

377 lines
11 KiB
C++
Raw Normal View History

2011-04-06 13:48:02 +04:00
/*
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*/
2012-05-21 18:48:49 +04:00
#include "mirall/folderwizard.h"
#include "mirall/owncloudinfo.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/theme.h"
#include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QFileDialog>
#include <QFileInfo>
2013-08-01 20:22:13 +04:00
#include <QFileIconProvider>
#include <QInputDialog>
#include <QUrl>
#include <QValidator>
#include <QWizardPage>
#include <QTreeWidget>
#include <stdlib.h>
2011-04-05 13:10:44 +04:00
namespace Mirall
{
FolderWizardSourcePage::FolderWizardSourcePage()
: QWizardPage()
{
_ui.setupUi(this);
2012-08-17 19:13:17 +04:00
registerField(QLatin1String("sourceFolder*"), _ui.localFolderLineEdit);
QString defaultPath = QString::fromLatin1( "%1/%2").arg( QDir::homePath() ).arg(Theme::instance()->appName() );
_ui.localFolderLineEdit->setText( QDir::toNativeSeparators( defaultPath ) );
2012-08-17 19:13:17 +04:00
registerField(QLatin1String("alias*"), _ui.aliasLineEdit);
_ui.aliasLineEdit->setText( Theme::instance()->appNameGUI() );
2011-10-11 17:39:25 +04:00
_ui.warnLabel->hide();
}
FolderWizardSourcePage::~FolderWizardSourcePage()
{
2011-10-11 17:39:25 +04:00
}
void FolderWizardSourcePage::initializePage()
{
_ui.warnLabel->hide();
}
void FolderWizardSourcePage::cleanupPage()
{
_ui.warnLabel->hide();
}
bool FolderWizardSourcePage::isComplete() const
{
QFileInfo selFile( QDir::fromNativeSeparators(_ui.localFolderLineEdit->text()) );
QString userInput = selFile.canonicalFilePath();
2011-10-11 17:39:25 +04:00
QString warnString;
bool isOk = selFile.isDir();
2011-10-11 17:39:25 +04:00
if( !isOk ) {
warnString = tr("No local folder selected!");
}
if (isOk && !selFile.isWritable()) {
isOk = false;
warnString += tr("You have no permission to write to the selected folder!");
}
// check if the local directory isn't used yet in another ownCloud sync
Folder::Map map = _folderMap;
if( isOk ) {
Folder::Map::const_iterator i = map.constBegin();
while( isOk && i != map.constEnd() ) {
2011-10-11 17:39:25 +04:00
Folder *f = static_cast<Folder*>(i.value());
QString folderDir = QDir( f->path() ).canonicalPath();
if( folderDir.isEmpty() )
{
isOk = true;
qDebug() << "Absolute path for folder: " << f->path() << " doesn't exist. Skipping.";
i++;
continue;
}
2012-08-17 19:13:17 +04:00
if( ! folderDir.endsWith(QLatin1Char('/')) ) folderDir.append(QLatin1Char('/'));
qDebug() << "Checking local path: " << folderDir << " <-> " << userInput;
if( QFileInfo( f->path() ) == userInput ) {
isOk = false;
warnString.append( tr("The local path %1 is already an upload folder.<br/>Please pick another one!")
.arg(QDir::toNativeSeparators(userInput)) );
}
if( isOk && folderDir.startsWith( userInput )) {
qDebug() << "A already configured folder is child of the current selected";
warnString.append( tr("An already configured folder is contained in the current entry."));
isOk = false;
}
if( isOk && userInput.startsWith( folderDir ) ) {
qDebug() << "An already configured folder is parent of the current selected";
warnString.append( tr("An already configured folder contains the currently entered directory."));
isOk = false;
}
i++;
}
}
// check if the alias is unique.
QString alias = _ui.aliasLineEdit->text();
2011-10-11 17:39:25 +04:00
if( alias.isEmpty() ) {
warnString.append( tr("The alias can not be empty. Please provide a descriptive alias word.") );
isOk = false;
}
Folder::Map::const_iterator i = map.constBegin();
2011-10-11 17:39:25 +04:00
bool goon = true;
while( goon && i != map.constEnd() ) {
2013-07-08 03:44:29 +04:00
Folder *f = i.value();
2011-10-11 17:39:25 +04:00
qDebug() << "Checking local alias: " << f->alias();
if( f ) {
if( f->alias() == alias ) {
2011-10-20 12:26:40 +04:00
warnString.append( tr("<br/>The alias <i>%1</i> is already in use. Please pick another alias.").arg(alias) );
2011-10-11 17:39:25 +04:00
isOk = false;
goon = false;
}
}
2011-10-11 17:39:25 +04:00
i++;
}
if( isOk ) {
_ui.warnLabel->hide();
2012-08-17 19:13:17 +04:00
_ui.warnLabel->setText( QString::null );
2011-10-11 17:39:25 +04:00
} else {
_ui.warnLabel->show();
_ui.warnLabel->setText( warnString );
}
return isOk;
}
void FolderWizardSourcePage::on_localFolderChooseBtn_clicked()
{
QString dir = QFileDialog::getExistingDirectory(this,
tr("Select the source folder"),
QDesktopServices::storageLocation(QDesktopServices::HomeLocation));
if (!dir.isEmpty()) {
_ui.localFolderLineEdit->setText(QDir::toNativeSeparators(dir));
}
}
void FolderWizardSourcePage::on_localFolderLineEdit_textChanged()
{
emit completeChanged();
}
// =================================================================================
FolderWizardTargetPage::FolderWizardTargetPage()
: _warnWasVisible(false)
{
_ui.setupUi(this);
_ui.warnFrame->hide();
connect(_ui.addFolderButton, SIGNAL(clicked()), SLOT(slotAddRemoteFolder()));
connect(_ui.refreshButton, SIGNAL(clicked()), SLOT(slotRefreshFolders()));
connect(_ui.folderTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), SIGNAL(completeChanged()));
connect(_ui.folderTreeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), SIGNAL(completeChanged()));
}
void FolderWizardTargetPage::slotAddRemoteFolder()
{
QTreeWidgetItem *current = _ui.folderTreeWidget->currentItem();
QString parent('/');
if (current) {
parent = current->data(0, Qt::UserRole).toString();
}
QInputDialog *dlg = new QInputDialog(this);
2013-08-01 20:22:13 +04:00
dlg->setWindowTitle(tr("Add Remote Folder"));
dlg->setLabelText(tr("Enter the name of the new folder:"));
dlg->setTextValue(parent);
dlg->open(this, SLOT(slotCreateRemoteFolder(QString)));
dlg->setAttribute(Qt::WA_DeleteOnClose);
}
void FolderWizardTargetPage::slotCreateRemoteFolder(QString folder)
{
if( folder.isEmpty() ) return;
ownCloudInfo::instance()->mkdirRequest( folder );
}
void FolderWizardTargetPage::slotCreateRemoteFolderFinished( QNetworkReply::NetworkError error )
{
qDebug() << "** webdav mkdir request finished " << error;
// the webDAV server seems to return a 202 even if mkdir was successful.
if( error == QNetworkReply::NoError ||
error == QNetworkReply::ContentOperationNotPermittedError) {
showWarn( tr("Folder was successfully created on %1.").arg( Theme::instance()->appNameGUI() ) );
slotRefreshFolders();
} else {
showWarn( tr("Failed to create the folder on %1.<br/>Please check manually.").arg( Theme::instance()->appNameGUI() ) );
}
}
static QTreeWidgetItem* findFirstChild(QTreeWidgetItem *parent, const QString& text)
{
for (int i = 0; i < parent->childCount(); ++i) {
QTreeWidgetItem *child = parent->child(i);
if (child->text(0) == text) {
return child;
}
}
}
static void recursiveInsert(QTreeWidgetItem *parent, QStringList pathTrail, QString path)
{
QFileIconProvider prov;
QIcon folderIcon = prov.icon(QFileIconProvider::Folder);
if (pathTrail.size() == 0) {
if (path.endsWith('/')) {
path.chop(1);
}
parent->setToolTip(0, path);
parent->setData(0, Qt::UserRole, path);
} else {
QTreeWidgetItem *item = findFirstChild(parent, pathTrail.first());
if (!item) {
item = new QTreeWidgetItem(parent);
item->setIcon(0, folderIcon);
item->setText(0, pathTrail.first());
item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
}
pathTrail.removeFirst();
recursiveInsert(item, pathTrail, path);
}
}
void FolderWizardTargetPage::slotUpdateDirectories(QStringList list)
{
2013-08-01 20:22:13 +04:00
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->setToolTip(0, tr("Choose this to sync the entire account"));
root->setData(0, Qt::UserRole, "/");
}
2013-08-01 20:22:13 +04:00
foreach (QString path, list) {
path.remove(webdavFolder);
QStringList paths = path.split('/');
if (paths.last().isEmpty()) paths.removeLast();
recursiveInsert(root, paths, path);
}
root->setExpanded(true);
}
void FolderWizardTargetPage::slotRefreshFolders()
{
ownCloudInfo::instance()->getDirectoryListing("/");
_ui.folderTreeWidget->clear();
}
void FolderWizardTargetPage::slotItemExpanded(QTreeWidgetItem *item)
{
ownCloudInfo::instance()->getDirectoryListing(item->text(0));
}
FolderWizardTargetPage::~FolderWizardTargetPage()
{
}
bool FolderWizardTargetPage::isComplete() const
{
if (!_ui.folderTreeWidget->currentItem())
return false;
QString dir = _ui.folderTreeWidget->currentItem()->data(0, Qt::UserRole).toString();
wizard()->setProperty("targetPath", dir);
if( dir == QLatin1String("/") ) {
showWarn( tr("If you sync the root folder, you can <b>not</b> configure another sync directory."));
return true;
} else {
showWarn();
return true;
}
}
void FolderWizardTargetPage::cleanupPage()
{
showWarn();
}
void FolderWizardTargetPage::initializePage()
{
showWarn();
2011-10-05 19:49:03 +04:00
/* check the owncloud configuration file and query the ownCloud */
ownCloudInfo *ocInfo = ownCloudInfo::instance();
2011-10-05 19:49:03 +04:00
if( ocInfo->isConfigured() ) {
connect( ocInfo, SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
SLOT(slotDirCheckReply(QString,QNetworkReply*)));
connect( ocInfo, SIGNAL(webdavColCreated(QNetworkReply::NetworkError)),
SLOT(slotCreateRemoteFolderFinished( QNetworkReply::NetworkError )));
connect( ocInfo, SIGNAL(directoryListingUpdated(QStringList)),
SLOT(slotUpdateDirectories(QStringList)));
slotRefreshFolders();
}
}
2011-10-05 19:49:03 +04:00
void FolderWizardTargetPage::showWarn( const QString& msg ) const
{
if( msg.isEmpty() ) {
_ui.warnFrame->hide();
} else {
_ui.warnFrame->show();
_ui.warnLabel->setText( msg );
}
2011-10-12 17:14:39 +04:00
}
// ====================================================================================
/**
* Folder wizard itself
*/
FolderWizard::FolderWizard( QWidget *parent )
: QWizard(parent),
_folderWizardSourcePage(new FolderWizardSourcePage),
2013-04-08 16:50:26 +04:00
_folderWizardTargetPage(0)
2011-04-05 13:10:44 +04:00
{
setPage(Page_Source, _folderWizardSourcePage );
2013-04-08 16:50:26 +04:00
if (!Theme::instance()->singleSyncFolder()) {
_folderWizardTargetPage = new FolderWizardTargetPage();
setPage(Page_Target, _folderWizardTargetPage );
}
setWindowTitle( tr( "%1 Folder Wizard" ).arg( Theme::instance()->appNameGUI() ) );
#ifdef Q_WS_MAC
setWizardStyle( QWizard::ModernStyle );
#endif
2011-04-05 13:10:44 +04:00
}
2013-04-08 16:50:26 +04:00
FolderWizard::~FolderWizard()
{
}
void FolderWizard::setFolderMap( const Folder::Map& fm)
{
_folderWizardSourcePage->setFolderMap( fm );
}
} // end namespace
2011-04-05 13:10:44 +04:00