Commit squashed refactoring branch

- introduce settings dialog
- general settings for general / proxy settings
- standalone proxy settings dialog removed
- standalone status dialog removed
- moved status dialog into settings dialog
- radically cut down links in context menu
- add help link to context menu

This needs more cleanup and testing. Known issues:

- When the wizard is called while the settings dialog
  is open, it will not show old information (see FIXME)
- Some settings are not implemented yet (greyed out)
- The counter in the FileItemDialog is not correct the
  first time around.

Based on the discussion done with Jan and Klaas during the
Nuenberg workshop.
This commit is contained in:
Daniel Molkentin 2013-07-04 19:59:40 +02:00
parent 5171e5880d
commit c164beb040
42 changed files with 2026 additions and 1662 deletions

View file

@ -14,11 +14,12 @@ endif()
set(mirall_UI
mirall/folderwizardsourcepage.ui
mirall/folderwizardtargetpage.ui
mirall/statusdialog.ui
mirall/owncloudsetuppage_ng.ui
mirall/owncloudwizardresultpage.ui
mirall/sslerrordialog.ui
mirall/proxydialog.ui
mirall/settingsdialog.ui
mirall/generalsettings.ui
mirall/accountsettings.ui
mirall/fileitemdialog.ui
)
@ -144,15 +145,17 @@ set(mirall_SRCS
mirall/application.cpp
mirall/systray.cpp
mirall/folderwizard.cpp
mirall/statusdialog.cpp
mirall/folderstatusmodel.cpp
mirall/owncloudwizard.cpp
mirall/owncloudsetupwizard.cpp
mirall/updatedetector.cpp
mirall/occinfo.cpp
mirall/sslerrordialog.cpp
mirall/logbrowser.cpp
mirall/proxydialog.cpp
mirall/fileitemdialog.cpp
mirall/settingsdialog.cpp
mirall/generalsettings.cpp
mirall/accountsettings.cpp
)
set(mirall_HEADERS
@ -161,12 +164,15 @@ set(mirall_HEADERS
mirall/folderwizard.h
mirall/owncloudsetupwizard.h
mirall/owncloudwizard.h
mirall/statusdialog.h
mirall/folderstatusmodel.h
mirall/updatedetector.h
mirall/sslerrordialog.h
mirall/logbrowser.h
mirall/proxydialog.h
mirall/fileitemdialog.h
mirall/settingsdialog.h
mirall/generalsettings.h
mirall/accountsettings.h
mirall/theme.h
)
if( UNIX AND NOT APPLE)

View file

@ -0,0 +1,502 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@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.
*/
#include "accountsettings.h"
#include "ui_accountsettings.h"
#include "mirall/theme.h"
#include "mirall/folderman.h"
#include "mirall/owncloudinfo.h"
#include "mirall/credentialstore.h"
#include "mirall/folderwizard.h"
#include "mirall/folderstatusmodel.h"
#include "mirall/utility.h"
#include "mirall/application.h"
#include "mirall/fileitemdialog.h"
#include "mirall/owncloudsetupwizard.h"
#include <QDebug>
#include <QDesktopServices>
#include <QListWidgetItem>
#include <QMessageBox>
namespace Mirall {
AccountSettings::AccountSettings(FolderMan *folderMan, QWidget *parent) :
QWidget(parent),
ui(new Ui::AccountSettings),
_folderMan(folderMan),
_item(0)
{
ui->setupUi(this);
_model = new FolderStatusModel;
FolderStatusDelegate *delegate = new FolderStatusDelegate;
ui->_folderList->setItemDelegate( delegate );
ui->_folderList->setModel( _model );
ui->_folderList->setMinimumWidth( 300 );
ui->_folderList->setEditTriggers( QAbstractItemView::NoEditTriggers );
ui->_ButtonRemove->setEnabled(false);
ui->_ButtonReset->setEnabled(false);
ui->_ButtonEnable->setEnabled(false);
ui->_ButtonInfo->setEnabled(false);
ui->_ButtonAdd->setEnabled(true);
connect(ui->_ButtonRemove, SIGNAL(clicked()), this, SLOT(slotRemoveCurrentFolder()));
connect(ui->_ButtonReset, SIGNAL(clicked()), this, SLOT(slotResetCurrentFolder()));
connect(ui->_ButtonEnable, SIGNAL(clicked()), this, SLOT(slotEnableCurrentFolder()));
connect(ui->_ButtonInfo, SIGNAL(clicked()), this, SLOT(slotInfoAboutCurrentFolder()));
connect(ui->_ButtonAdd, SIGNAL(clicked()), this, SLOT(slotAddFolder()));
connect(ui->modifyAccountButton, SIGNAL(clicked()), this, SLOT(slotOpenAccountWizard()));
connect(ui->_folderList, SIGNAL(clicked(QModelIndex)), SLOT(slotFolderActivated(QModelIndex)));
connect(ui->_folderList, SIGNAL(doubleClicked(QModelIndex)),SLOT(slotDoubleClicked(QModelIndex)));
ownCloudInfo *ocInfo = ownCloudInfo::instance();
slotUpdateQuota(ocInfo->lastQuotaTotalBytes(), ocInfo->lastQuotaUsedBytes());
connect(ocInfo, SIGNAL(quotaUpdated(qint64,qint64)), SLOT(slotUpdateQuota(qint64,qint64)));
ui->connectLabel->setWordWrap( true );
setFolderList(folderMan->map());
slotCheckConnection();
}
void AccountSettings::slotFolderActivated( const QModelIndex& indx )
{
bool state = indx.isValid();
ui->_ButtonRemove->setEnabled( state );
ui->_ButtonReset->setEnabled( state );
ui->_ButtonReset->setEnabled( state );
ui->_ButtonEnable->setEnabled( state );
ui->_ButtonInfo->setEnabled( state );
if ( state ) {
bool folderEnabled = _model->data( indx, FolderStatusDelegate::FolderSyncEnabled).toBool();
qDebug() << "folder is sync enabled: " << folderEnabled;
if ( folderEnabled ) {
ui->_ButtonEnable->setText( tr( "Pause" ) );
} else {
ui->_ButtonEnable->setText( tr( "Resume" ) );
}
}
}
void AccountSettings::slotAddFolder()
{
_folderMan->setSyncEnabled(false); // do not start more syncs.
FolderWizard *folderWizard = new FolderWizard(this);
Folder::Map folderMap = _folderMan->map();
folderWizard->setFolderMap( folderMap );
connect(folderWizard, SIGNAL(accepted()), SLOT(slotFolderWizardAccepted()));
connect(folderWizard, SIGNAL(rejected()), SLOT(slotFolderWizardRejected()));
folderWizard->open();
}
void AccountSettings::slotFolderWizardAccepted()
{
FolderWizard *folderWizard = qobject_cast<FolderWizard*>(sender());
qDebug() << "* Folder wizard completed";
QString alias = folderWizard->field(QLatin1String("alias")).toString();
QString sourceFolder = folderWizard->field(QLatin1String("sourceFolder")).toString();
QString targetPath = folderWizard->field(QLatin1String("OCFolderLineEdit")).toString();
QString backend = QLatin1String("owncloud");
if (!FolderMan::ensureJournalGone( sourceFolder ))
return;
_folderMan->addFolderDefinition( backend, alias, sourceFolder, targetPath, false );
Folder *f = _folderMan->setupFolderFromConfigFile( alias );
slotAddFolder( f );
_folderMan->setSyncEnabled(true);
if( f ) {
_folderMan->slotScheduleAllFolders();
emit folderChanged();
}
}
void AccountSettings::slotFolderWizardRejected()
{
qDebug() << "* Folder wizard cancelled";
_folderMan->setSyncEnabled(true);
_folderMan->slotScheduleAllFolders();
}
void AccountSettings::slotOpenAccountWizard()
{
OwncloudSetupWizard::runWizard(_folderMan, qApp, SLOT(slotownCloudWizardDone(int)), this);
}
void AccountSettings::slotAddFolder( Folder *folder )
{
if( ! folder || folder->alias().isEmpty() ) return;
QStandardItem *item = new QStandardItem();
folderToModelItem( item, folder );
_model->appendRow( item );
slotCheckConnection();
}
void AccountSettings::buttonsSetEnabled()
{
bool haveFolders = ui->_folderList->model()->rowCount() > 0;
ui->_ButtonRemove->setEnabled(false);
if( Theme::instance()->singleSyncFolder() ) {
// only one folder synced folder allowed.
ui->_ButtonAdd->setVisible(!haveFolders);
} else {
ui->_ButtonAdd->setVisible(true);
ui->_ButtonAdd->setEnabled(true);
}
QModelIndex selected = ui->_folderList->currentIndex();
bool isSelected = selected.isValid();
ui->_ButtonEnable->setEnabled(isSelected);
ui->_ButtonReset->setEnabled(isSelected);
ui->_ButtonRemove->setEnabled(isSelected);
ui->_ButtonInfo->setEnabled(isSelected);
}
void AccountSettings::setListWidgetItem( QListWidgetItem *item )
{
_item = item;
}
void AccountSettings::folderToModelItem( QStandardItem *item, Folder *f )
{
if( ! item || !f ) return;
item->setData( f->nativePath(), FolderStatusDelegate::FolderPathRole );
item->setData( f->secondPath(), FolderStatusDelegate::FolderSecondPathRole );
item->setData( f->alias(), FolderStatusDelegate::FolderAliasRole );
item->setData( f->syncEnabled(), FolderStatusDelegate::FolderSyncEnabled );
SyncResult res = f->syncResult();
SyncResult::Status status = res.status();
QString errors = res.errorStrings().join(QLatin1String("<br/>"));
Theme *theme = Theme::instance();
item->setData( theme->statusHeaderText( status ), Qt::ToolTipRole );
if( f->syncEnabled() ) {
item->setData( theme->syncStateIcon( status ), FolderStatusDelegate::FolderStatusIconRole );
} else {
item->setData( theme->folderDisabledIcon( ), FolderStatusDelegate::FolderStatusIconRole ); // size 48 before
}
item->setData( theme->statusHeaderText( status ), FolderStatusDelegate::FolderStatus );
item->setData( errors, FolderStatusDelegate::FolderErrorMsg );
}
void AccountSettings::slotRemoveCurrentFolder()
{
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
if( selected.isValid() ) {
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
qDebug() << "Remove Folder alias " << alias;
if( !alias.isEmpty() ) {
// remove from file system through folder man
// _model->removeRow( selected.row() );
int ret = QMessageBox::question( this, tr("Confirm Folder Remove"),
tr("<p>Do you really want to stop syncing the folder <i>%1</i>?</p>"
"<p><b>Note:</b> This will not remove the files from your client.</p>").arg(alias),
QMessageBox::Yes|QMessageBox::No );
if( ret == QMessageBox::No ) {
return;
}
_folderMan->slotRemoveFolder( alias );
setFolderList(_folderMan->map());
emit folderChanged();
slotCheckConnection();
}
}
}
void AccountSettings::slotResetCurrentFolder()
{
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
if( selected.isValid() ) {
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
int ret = QMessageBox::question( 0, tr("Confirm Folder Reset"),
tr("<p>Do you really want to reset folder <i>%1</i> and rebuild your client database?</p>"
"<p><b>Note:</b> While no files will be removed, this can cause significant data "
"traffic and take several minutes to hours, depending on the size of the folder.</p>").arg(alias),
QMessageBox::Yes|QMessageBox::No );
if( ret == QMessageBox::Yes ) {
Folder *f = _folderMan->folder(alias);
f->slotTerminateSync();
f->wipe();
_folderMan->slotScheduleAllFolders();
}
}
}
void AccountSettings::slotDoubleClicked( const QModelIndex& indx )
{
if( ! indx.isValid() ) return;
QString alias = _model->data( indx, FolderStatusDelegate::FolderAliasRole ).toString();
emit openFolderAlias( alias );
}
void AccountSettings::slotCheckConnection()
{
if( ownCloudInfo::instance()->isConfigured() ) {
connect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),
this, SLOT(slotOCInfo( const QString&, const QString&, const QString&, const QString& )));
connect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotOCInfoFail(QNetworkReply*)));
ui->connectLabel->setText( 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()));
ui->_ButtonAdd->setEnabled( false);
}
}
void AccountSettings::setFolderList( const Folder::Map &folders )
{
_model->clear();
foreach( Folder *f, folders ) {
qDebug() << "Folder: " << f;
slotAddFolder( f );
}
QModelIndex idx = _model->index(0, 0);
if (idx.isValid())
ui->_folderList->setCurrentIndex(idx);
buttonsSetEnabled();
}
// move from Application
void AccountSettings::slotFolderOpenAction( const QString& alias )
{
Folder *f = _folderMan->folder(alias);
qDebug() << "opening local url " << f->path();
if( f ) {
QUrl url(f->path(), QUrl::TolerantMode);
url.setScheme( QLatin1String("file") );
#ifdef Q_OS_WIN32
// work around a bug in QDesktopServices on Win32, see i-net
QString filePath = f->path();
if (filePath.startsWith(QLatin1String("\\\\")) || filePath.startsWith(QLatin1String("//")))
url.setUrl(QDir::toNativeSeparators(filePath));
else
url = QUrl::fromLocalFile(filePath);
#endif
QDesktopServices::openUrl(url);
}
}
void AccountSettings::slotEnableCurrentFolder()
{
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
if( selected.isValid() ) {
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
bool folderEnabled = _model->data( selected, FolderStatusDelegate::FolderSyncEnabled).toBool();
qDebug() << "Toggle enabled/disabled Folder alias " << alias << " - current state: " << folderEnabled;
if( !alias.isEmpty() ) {
qDebug() << "Application: enable folder with alias " << alias;
bool terminate = false;
// this sets the folder status to disabled but does not interrupt it.
Folder *f = _folderMan->folder( alias );
if( f && !folderEnabled ) {
// check if a sync is still running and if so, ask if we should terminate.
if( f->isBusy() ) { // its still running
int reply = QMessageBox::question( 0, tr("Sync Running"),
tr("The syncing operation is running.<br/>Do you want to terminate it?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes );
if ( reply == QMessageBox::Yes )
terminate = true;
else
return; // do nothing
}
}
// message box can return at any time while the thread keeps running,
// so better check again after the user has responded.
if ( f->isBusy() && terminate )
_folderMan->terminateSyncProcess( alias );
_folderMan->slotEnableFolder( alias, !folderEnabled );
slotUpdateFolderState (f);
// set the button text accordingly.
slotFolderActivated( selected );
}
}
}
void AccountSettings::slotUpdateFolderState( Folder *folder )
{
QStandardItem *item = 0;
int row = 0;
if( ! folder ) return;
item = _model->item( row );
while( item ) {
if( item->data( FolderStatusDelegate::FolderAliasRole ) == folder->alias() ) {
// its the item to update!
break;
}
item = _model->item( ++row );
}
if( !_fileItemDialog.isNull() && _fileItemDialog->isVisible() ) {
_fileItemDialog->setSyncResult( _folderMan->syncResult(folder) );
}
if( item ) {
folderToModelItem( item, folder );
} else {
// the dialog is not visible.
}
slotCheckConnection();
}
void AccountSettings::slotOCInfo( const QString& url, const QString& versionStr, const QString& version, const QString& )
{
#ifdef Q_OS_WIN32
// work around a bug in QDesktopServices on Win32, see i-net
QString filePath = url;
if (filePath.startsWith("\\\\") || filePath.startsWith("//"))
_OCUrl.setUrl(QDir::toNativeSeparators(filePath));
else
_OCUrl = QUrl::fromLocalFile(filePath);
#else
_OCUrl = QUrl::fromLocalFile(url);
#endif
qDebug() << "#-------# oC found on " << url;
/* enable the open button */
ui->connectLabel->setOpenExternalLinks(true);
ui->connectLabel->setText( tr("Connected to <a href=\"%1\">%1</a> as <i>%2</i>.")
.arg(url).arg( CredentialStore::instance()->user()) );
ui->connectLabel->setToolTip( 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&)),
this, SLOT(slotOCInfo( const QString&, const QString&, const QString&, const QString& )));
disconnect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotOCInfoFail(QNetworkReply*)));
}
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) );
ui->_ButtonAdd->setEnabled( false);
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),
this, SLOT(slotOCInfo( const QString&, const QString&, const QString&, const QString& )));
disconnect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotOCInfoFail(QNetworkReply*)));
}
void AccountSettings::slotOpenOC()
{
if( _OCUrl.isValid() )
QDesktopServices::openUrl( _OCUrl );
}
void AccountSettings::slotSetProgress( const QString& folder, const QString& file, long p1, long p2 )
{
// if( p1 == 0 && p2 > 0 ) {
// // sync start
// ui->progressBar->setMaximum( p2 );
// ui->progressBar->setValue( p1 );
// ui->progressBar->setEnabled(true);
// ui->fileProgressLabel->setText(tr("Uploading %1").arg(file));
// // ui->progressBar->show();
// } else if( p1 == p2 ) {
// // sync end
// // ui->progressBar->setMaximum(0);
// ui->progressBar->setValue(0);
// ui->progressBar->setEnabled(false);
// ui->fileProgressLabel->setText(tr("No activity."));
// // ui->progressBar->hide();
// } else {
// ui->progressBar->setValue( p1 );
// }
}
void AccountSettings::slotUpdateQuota(qint64 total, qint64 used)
{
ui->quotaProgressBar->setEnabled(true);
// workaround the label only accepting ints (which may be only 32 bit wide)
ui->quotaProgressBar->setMaximum(100);
ui->quotaProgressBar->setValue(used/(double)total * 100);
QString usedStr = Utility::octetsToString(used);
QString totalStr = Utility::octetsToString(total);
ui->quotaLabel->setText(tr("You are using %1 of your available %2 storage.").arg(usedStr, totalStr));
}
void AccountSettings::slotInfoAboutCurrentFolder()
{
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
if( selected.isValid() ) {
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
qDebug() << "Info Folder alias " << alias;
if( !alias.isEmpty() ) {
qDebug() << "details of folder with alias " << alias;
if( _fileItemDialog.isNull() ) {
_fileItemDialog = new FileItemDialog(this);
_fileItemDialog->open();
} else {
Utility::raiseDialog( _fileItemDialog );
}
_fileItemDialog->setSyncResult( _folderMan->syncResult( alias ) );
}
}
}
AccountSettings::~AccountSettings()
{
delete ui;
}
} // namespace Mirall

View file

@ -0,0 +1,90 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@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 ACCOUNTSETTINGS_H
#define ACCOUNTSETTINGS_H
#include <QWidget>
#include <QUrl>
#include <QPointer>
#include "mirall/folder.h"
class QStandardItemModel;
class QModelIndex;
class QStandardItem;
class QNetworkReply;
class QListWidgetItem;
namespace Mirall {
namespace Ui {
class AccountSettings;
}
class FolderMan;
class FileItemDialog;
class AccountSettings : public QWidget
{
Q_OBJECT
public:
explicit AccountSettings(FolderMan *folderMan, QWidget *parent = 0);
~AccountSettings();
void setFolderList( const Folder::Map& );
void buttonsSetEnabled();
void setListWidgetItem(QListWidgetItem* item);
signals:
void folderChanged();
void openFolderAlias( const QString& );
void infoFolderAlias( const QString& );
public slots:
void slotFolderActivated( const QModelIndex& );
void slotOpenOC();
void slotUpdateFolderState( Folder* );
void slotCheckConnection();
void slotOCInfo( const QString&, const QString&, const QString&, const QString& );
void slotOCInfoFail( QNetworkReply* );
void slotDoubleClicked( const QModelIndex& );
void slotFolderOpenAction( const QString& );
void slotSetProgress( const QString&, const QString&, long, long );
void slotUpdateQuota( qint64,qint64 );
protected slots:
void slotAddFolder();
void slotAddFolder( Folder* );
void slotEnableCurrentFolder();
void slotRemoveCurrentFolder();
void slotInfoAboutCurrentFolder();
void slotResetCurrentFolder();
void slotFolderWizardAccepted();
void slotFolderWizardRejected();
void slotOpenAccountWizard();
private:
void folderToModelItem( QStandardItem *, Folder * );
Ui::AccountSettings *ui;
QPointer<FileItemDialog> _fileItemDialog;
FolderMan *_folderMan;
QStandardItemModel *_model;
QListWidgetItem *_item;
QUrl _OCUrl;
};
} // namespace Mirall
#endif // ACCOUNTSETTINGS_H

View file

@ -0,0 +1,193 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Mirall::AccountSettings</class>
<widget class="QWidget" name="Mirall::AccountSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>639</width>
<height>391</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="syncStatusGroupBox">
<property name="title">
<string>Sync Status</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="connectLabel">
<property name="text">
<string>Connected with &lt;server&gt; as &lt;user&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QListView" name="_folderList"/>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="_ButtonAdd">
<property name="text">
<string>Add Sync...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_ButtonEnable">
<property name="text">
<string>Pause</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="_ButtonRemove">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_ButtonReset">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="_ButtonInfo">
<property name="text">
<string>Info...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="storageGroupBox">
<property name="title">
<string>Storage Usage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QProgressBar" name="quotaProgressBar">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="quotaLabel">
<property name="text">
<string>Retrieving usage information...</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;b&gt;Note:&lt;/b&gt; Some folders, including network mounted or shared folders, might have different limits.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="maintenanceGroupBox">
<property name="title">
<string>Account Maintenance</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="changePasswordButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Change Password</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeAccountButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Remove Account</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="modifyAccountButton">
<property name="text">
<string>Modify Account</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -21,17 +21,16 @@
#include "mirall/folderwizard.h"
#include "mirall/networklocation.h"
#include "mirall/owncloudfolder.h"
#include "mirall/statusdialog.h"
#include "mirall/owncloudsetupwizard.h"
#include "mirall/owncloudinfo.h"
#include "mirall/sslerrordialog.h"
#include "mirall/theme.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/updatedetector.h"
#include "mirall/proxydialog.h"
#include "mirall/credentialstore.h"
#include "mirall/logger.h"
#include "mirall/settingsdialog.h"
#include "mirall/utility.h"
#include "mirall/inotify.h"
#if defined(Q_OS_WIN)
@ -70,7 +69,6 @@ static const char optionsC[] =
" --logexpire <hours> : removes logs older than <hours> hours.\n"
" (to be used with --logdir)\n"
" --logflush : flush the log file after every write.\n"
" --monoicons : Use black/white pictograms for systray.\n"
" --confdir <dirname> : Use the given configuration directory.\n"
;
@ -105,8 +103,7 @@ Application::Application(int &argc, char **argv) :
_logExpire(0),
_showLogWindow(false),
_logFlush(false),
_helpOnly(false),
_fileItemDialog(0)
_helpOnly(false)
{
setApplicationName( _theme->appNameGUI() );
setWindowIcon( _theme->applicationIcon() );
@ -133,20 +130,6 @@ Application::Application(int &argc, char **argv) :
setQuitOnLastWindowClosed(false);
_statusDialog = new StatusDialog( _theme );
connect( _statusDialog, SIGNAL(addASync()), this, SLOT(slotAddFolder()) );
connect( _statusDialog, SIGNAL(removeFolderAlias( const QString&)),
SLOT(slotRemoveFolder(const QString&)));
connect( _statusDialog, SIGNAL(resetFolderAlias( const QString&)),
SLOT(slotResetFolder(const QString&)));
connect( _statusDialog, SIGNAL(enableFolderAlias(QString,bool)),
SLOT(slotEnableFolder(QString,bool)));
connect( _statusDialog, SIGNAL(infoFolderAlias(const QString&)),
SLOT(slotInfoFolder( const QString&)));
connect( _statusDialog, SIGNAL(openFolderAlias(const QString&)),
SLOT(slotFolderOpenAction(QString)));
#if 0
#if QT_VERSION >= 0x040700
qDebug() << "* Network is" << (_networkMgr->isOnline() ? "online" : "offline");
@ -155,20 +138,19 @@ Application::Application(int &argc, char **argv) :
}
#endif
#endif
MirallConfigFile cfg;
_theme->setSystrayUseMonoIcons(cfg.monoIcons());
connect (_theme, SIGNAL(systrayUseMonoIconsChanged(bool)), SLOT(slotUseMonoIconsChanged(bool)));
setupActions();
setupSystemTray();
slotSetupProxy();
int cnt = _folderMan->setupFolders();
_statusDialog->setFolderList( _folderMan->map() );
QObject::connect( this, SIGNAL(messageReceived(QString)),
this, SLOT(slotOpenStatus()) );
QTimer::singleShot( 0, this, SLOT( slotStartFolderSetup() ));
MirallConfigFile cfg;
if( !cfg.ownCloudSkipUpdateCheck() ) {
QTimer::singleShot( 3000, this, SLOT( slotStartUpdateDetector() ));
}
@ -185,8 +167,7 @@ Application::Application(int &argc, char **argv) :
Application::~Application()
{
delete _tray; // needed, see ctor
delete _fileItemDialog;
delete _statusDialog;
qDebug() << "* Mirall shutdown";
}
@ -209,7 +190,7 @@ void Application::slotStartFolderSetup( int result )
ownCloudInfo::instance()->checkInstallation();
} else {
slotConfigure();
slotCheckConfig();
}
} else {
qDebug() << "Setup Wizard was canceled. No reparsing of config.";
@ -245,8 +226,6 @@ void Application::slotNoOwnCloudFound( QNetworkReply* reply )
qDebug() << "** Application: NO ownCloud found! Going offline";
_actionAddFolder->setEnabled( false );
// Disconnect.
disconnect( ownCloudInfo::instance(),SIGNAL(ownCloudInfoFound(QString,QString,QString,QString)),
this, SLOT(slotOwnCloudFound(QString,QString,QString,QString)));
@ -284,8 +263,6 @@ void Application::slotFetchCredentials()
if( !trayMessage.isEmpty() ) {
slotShowTrayMessage(tr("Credentials"), trayMessage);
_actionOpenStatus->setEnabled( false );
_actionAddFolder->setEnabled( false );
}
}
}
@ -307,8 +284,6 @@ void Application::slotCredentialsFetched(bool ok)
}
qDebug() << "Could not fetch credentials";
_actionAddFolder->setEnabled( false );
_actionOpenStatus->setEnabled( false );
} else {
ownCloudInfo::instance()->setCredentials( CredentialStore::instance()->user(),
CredentialStore::instance()->password() );
@ -339,7 +314,6 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
tr("<p>Your %1 credentials are not correct.</p>"
"<p>Please correct them by starting the configuration dialog from the tray!</p>")
.arg(_theme->appNameGUI()));
_actionAddFolder->setEnabled( false );
ok = false;
} else if( reply->error() == QNetworkReply::OperationCanceledError ) {
// the username was wrong and ownCloudInfo was closing the request after a couple of auth tries.
@ -347,11 +321,10 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
QMessageBox::warning(0, tr("No %1 Connection").arg(_theme->appNameGUI()),
tr("<p>Either your user name or your password are not correct.</p>"
"<p>Please correct it by starting the configuration dialog from the tray!</p>"));
_actionAddFolder->setEnabled( false );
ok = false;
}
// disconnect from ownCloud Info signals
// disconnect from o` wnCloud Info signals
disconnect( ownCloudInfo::instance(),SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
this,SLOT(slotAuthCheck(QString,QNetworkReply*)));
@ -373,8 +346,6 @@ void Application::slotAuthCheck( const QString& ,QNetworkReply *reply )
computeOverallSyncStatus();
_actionAddFolder->setEnabled( true );
_actionOpenStatus->setEnabled( true );
setupContextMenu();
}
}
@ -420,30 +391,23 @@ void Application::slotownCloudWizardDone( int res )
if( res == QDialog::Accepted ) {
int cnt = _folderMan->setupFolders();
qDebug() << "Set up " << cnt << " folders.";
_statusDialog->setFolderList( _folderMan->map() );
// FIXME!
// _statusDialog->setFolderList( _folderMan->map() );
}
_folderMan->setSyncEnabled( true );
slotStartFolderSetup( res );
_owncloudSetupWizard.reset(0);
}
void Application::setupActions()
{
_actionOpenoC = new QAction(tr("Open %1 in browser...").arg(_theme->appNameGUI()), this);
_actionOpenoC = new QAction(tr("Open %1 in browser").arg(_theme->appNameGUI()), this);
QObject::connect(_actionOpenoC, SIGNAL(triggered(bool)), SLOT(slotOpenOwnCloud()));
_actionOpenStatus = new QAction(tr("Open status..."), this);
QObject::connect(_actionOpenStatus, SIGNAL(triggered(bool)), SLOT(slotOpenStatus()));
_actionOpenStatus->setEnabled( false );
_actionQuota = new QAction(tr("Calculating quota..."), this);
_actionQuota->setEnabled( false );
_actionAddFolder = new QAction(tr("Add folder..."), this);
QObject::connect(_actionAddFolder, SIGNAL(triggered(bool)), SLOT(slotAddFolder()));
_actionConfigure = new QAction(tr("Configure..."), this);
QObject::connect(_actionConfigure, SIGNAL(triggered(bool)), SLOT(slotConfigure()));
_actionConfigureProxy = new QAction(tr("Configure proxy..."), this);
QObject::connect(_actionConfigureProxy, SIGNAL(triggered(bool)), SLOT(slotConfigureProxy()));
_actionAbout = new QAction(tr("About..."), this);
QObject::connect(_actionAbout, SIGNAL(triggered(bool)), SLOT(slotAbout()));
_actionSettings = new QAction(tr("Settings..."), this);
QObject::connect(_actionSettings, SIGNAL(triggered(bool)), SLOT(slotSettings()));
_actionHelp = new QAction(tr("Help"), this);
QObject::connect(_actionHelp, SIGNAL(triggered(bool)), SLOT(slotHelp()));
_actionQuit = new QAction(tr("Quit"), this);
QObject::connect(_actionQuit, SIGNAL(triggered(bool)), SLOT(quit()));
}
@ -467,9 +431,7 @@ void Application::setupContextMenu()
{
bool isConfigured = ownCloudInfo::instance()->isConfigured();
_actionOpenStatus->setEnabled(isConfigured);
_actionOpenoC->setEnabled(isConfigured);
_actionAddFolder->setEnabled(isConfigured);
if( _contextMenu ) {
_contextMenu->clear();
@ -480,27 +442,18 @@ void Application::setupContextMenu()
_tray->setContextMenu(_contextMenu);
}
_contextMenu->setTitle(_theme->appNameGUI() );
_contextMenu->addAction(_actionOpenStatus);
_contextMenu->addAction(_actionOpenoC);
_contextMenu->addSeparator();
_contextMenu->addAction(_actionQuota);
_contextMenu->addSeparator();
int folderCnt = _folderMan->map().size();
// add open actions for all sync folders to the tray menu
if( _theme->singleSyncFolder() ) {
if( folderCnt == 0 ) {
// if there is no folder configured yet, show the add action.
_contextMenu->addAction(_actionAddFolder);
} else {
// there should be exactly one folder. No sync-folder add action will be shown.
QStringList li = _folderMan->map().keys();
if( li.size() == 1 ) {
Folder *folder = _folderMan->map().value(li.first());
if( folder ) {
// if there is singleFolder mode, a generic open action is displayed.
QAction *action = new QAction( tr("Open %1 folder").arg(_theme->appNameGUI()), this);
QAction *action = new QAction( tr("Open local folder '%1'").arg(_theme->appNameGUI()), this);
action->setIcon( _theme->trayFolderIcon( folder->backend()) );
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
@ -509,33 +462,26 @@ void Application::setupContextMenu()
_contextMenu->addAction(action);
}
}
}
} else {
// show a grouping with more than one folder.
if ( folderCnt ) {
if ( folderCnt > 1) {
_contextMenu->addAction(tr("Managed Folders:"))->setDisabled(true);
}
foreach (Folder *folder, _folderMan->map() ) {
QAction *action = new QAction( folder->alias(), this );
action->setIcon( _theme->trayFolderIcon( folder->backend()) );
QAction *action = new QAction( tr("Open folder '%1'").arg(folder->alias()), this );
connect( action, SIGNAL(triggered()),_folderOpenActionMapper,SLOT(map()));
_folderOpenActionMapper->setMapping( action, folder->alias() );
_contextMenu->addAction(action);
}
_contextMenu->addAction(_actionAddFolder);
}
_contextMenu->addSeparator();
_contextMenu->addAction(_actionConfigure);
_contextMenu->addAction(_actionConfigureProxy);
_contextMenu->addAction(_actionQuota);
_contextMenu->addSeparator();
if (!Theme::instance()->about().isEmpty()) {
_contextMenu->addAction(_actionAbout);
_contextMenu->addAction(_actionSettings);
_contextMenu->addAction(_actionHelp);
_contextMenu->addSeparator();
}
_contextMenu->addAction(_actionQuit);
}
@ -600,6 +546,10 @@ void Application::enterNextLogFile()
QNetworkProxy proxyFromConfig(const MirallConfigFile& cfg)
{
QNetworkProxy proxy;
if (cfg.proxyHostName().isEmpty())
return QNetworkProxy();
proxy.setHostName(cfg.proxyHostName());
proxy.setPort(cfg.proxyPort());
if (cfg.proxyNeedsAuth()) {
@ -636,23 +586,6 @@ void Application::slotSetupProxy()
_folderMan->setProxy();
}
static QString octetsToString( qint64 octets )
{
const qint64 kb = 1024;
const qint64 mb = 1024 * kb;
const qint64 gb = 1024 * mb;
if (octets >= gb) {
return QString::number(octets/gb) + QLatin1String(" GB");
} else if (octets >= mb) {
return QString::number(octets/mb) + QLatin1String(" MB");
} else if (octets >= kb) {
return QString::number(octets/kb) + QLatin1String(" KB");
} else {
return octets + QLatin1String(" bytes");
}
}
void Application::slotRefreshQuotaDisplay( qint64 total, qint64 used )
{
if (total == 0) {
@ -672,10 +605,20 @@ void Application::slotRefreshQuotaDisplay( qint64 total, qint64 used )
} else {
percentFormatted = QString::number((int)percent);
}
QString totalFormatted = octetsToString(total);
QString totalFormatted = Utility::octetsToString(total);
_actionQuota->setText(tr("%1% of %2 used").arg(percentFormatted).arg(totalFormatted));
}
void Application::slotUseMonoIconsChanged(bool)
{
computeOverallSyncStatus();
}
void Application::slotHelp()
{
QDesktopServices::openUrl(QUrl(_theme->helpUrl()));
}
/*
* open the folder with the given Alais
*/
@ -719,109 +662,21 @@ void Application::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
}
#if defined Q_WS_WIN || defined Q_WS_X11
if( reason == QSystemTrayIcon::Trigger ) {
slotOpenStatus();
slotCheckConfig();
}
#endif
}
void Application::slotAddFolder()
void Application::slotCheckConfig()
{
/** Helper class to ensure sync is always switched back on */
class SyncDisabler
{
public:
SyncDisabler(Application *app) : _app(app)
{
_app->_folderMan->setSyncEnabled(false);
}
~SyncDisabler() {
_app->_folderMan->setSyncEnabled(true);
_app->computeOverallSyncStatus();
_app->_folderMan->slotScheduleAllFolders();
}
private:
Application *_app;
};
if (!_folderWizard.isNull()) {
raiseDialog(_folderWizard);
return;
}
// disables sync queuing while in scope
SyncDisabler disableSync(this);
Folder::Map folderMap = _folderMan->map();
_folderWizard = new FolderWizard;
_folderWizard->setFolderMap( &folderMap );
if (_folderWizard->exec() == QDialog::Accepted) {
qDebug() << "* Folder wizard completed";
QString alias = _folderWizard->field(QLatin1String("alias")).toString();
QString sourceFolder = _folderWizard->field(QLatin1String("sourceFolder")).toString();
QString targetPath = _folderWizard->field(QLatin1String("OCFolderLineEdit")).toString();
QString backend = QLatin1String("owncloud");
if (!FolderMan::ensureJournalGone( sourceFolder ))
return;
_folderMan->addFolderDefinition( backend, alias, sourceFolder, targetPath, false );
Folder *f = _folderMan->setupFolderFromConfigFile( alias );
if( f ) {
_statusDialog->slotAddFolder( f );
_statusDialog->buttonsSetEnabled();
setupContextMenu();
}
} else {
qDebug() << "* Folder wizard cancelled";
}
_folderWizard->deleteLater();
}
void Application::slotOpenStatus()
{
if( ! _statusDialog ) return;
QWidget *raiseWidget = 0;
// check if there is a mirall.cfg already.
if( !_owncloudSetupWizard.isNull() &&
_owncloudSetupWizard->wizard()->isVisible() ) {
raiseWidget = _owncloudSetupWizard->wizard();
}
// if no config file is there, start the configuration wizard.
if( ! raiseWidget ) {
MirallConfigFile cfgFile;
if( !cfgFile.exists() ) {
qDebug() << "No configured folders yet, start the Owncloud integration dialog.";
slotConfigure();
if( cfgFile.exists() ) {
slotSettings();
} else {
qDebug() << "#============# Status dialog starting #=============#";
raiseWidget = _statusDialog;
_statusDialog->setFolderList( _folderMan->map() );
}
}
raiseDialog( raiseWidget );
}
void Application::raiseDialog( QWidget *raiseWidget )
{
// viel hilft viel ;-)
if( raiseWidget ) {
#if defined(Q_WS_WIN) || defined (Q_OS_MAC)
Qt::WindowFlags eFlags = raiseWidget->windowFlags();
eFlags |= Qt::WindowStaysOnTopHint;
raiseWidget->setWindowFlags(eFlags);
raiseWidget->show();
eFlags &= ~Qt::WindowStaysOnTopHint;
raiseWidget->setWindowFlags(eFlags);
#endif
raiseWidget->show();
raiseWidget->raise();
raiseWidget->activateWindow();
qDebug() << "No configured folders yet, starting setup wizard";
OwncloudSetupWizard::runWizard(_folderMan, this, SLOT(slotownCloudWizardDone(int)));
}
}
@ -831,117 +686,19 @@ void Application::slotOpenLogBrowser()
_logBrowser->raise();
}
void Application::slotAbout()
void Application::slotFoldersChanged()
{
QMessageBox::about(0, tr("About %1").arg(_theme->appNameGUI()),
Theme::instance()->about());
}
/*
* the folder is to be removed. The slot is called from a signal emitted by
* the status dialog, which removes the folder from its list by itself.
*/
void Application::slotRemoveFolder( const QString& alias )
{
int ret = QMessageBox::question( 0, tr("Confirm Folder Remove"),
tr("<p>Do you really want to stop syncing the folder <i>%1</i>?</p>"
"<p><b>Note:</b> This will not remove the files from your client.</p>").arg(alias),
QMessageBox::Yes|QMessageBox::No );
if( ret == QMessageBox::No ) {
return;
}
_folderMan->slotRemoveFolder( alias );
_statusDialog->slotRemoveSelectedFolder( );
computeOverallSyncStatus();
setupContextMenu();
}
void Application::slotResetFolder( const QString & alias )
void Application::slotSettings()
{
int ret = QMessageBox::question( 0, tr("Confirm Folder Reset"),
tr("<p>Do you really want to reset folder <i>%1</i> and rebuild your client database?</p>"
"<p><b>Note:</b> While no files will be removed, this can cause significant data "
"traffic and take several minutes to hours, depending on the size of the folder.</p>").arg(alias),
QMessageBox::Yes|QMessageBox::No );
if( ret == QMessageBox::No ) {
return;
}
Folder *f = _folderMan->folder(alias);
f->slotTerminateSync();
f->wipe();
_folderMan->slotScheduleAllFolders();
}
// Open the File list info dialog.
void Application::slotInfoFolder( const QString& alias )
{
qDebug() << "details of folder with alias " << alias;
if( !_fileItemDialog ) {
_fileItemDialog = new FileItemDialog(_theme);
}
SyncResult folderResult = _folderMan->syncResult( alias );
_fileItemDialog->setSyncResult( folderResult );
raiseDialog( _fileItemDialog );
}
void Application::slotEnableFolder(const QString& alias, const bool enable)
{
qDebug() << "Application: enable folder with alias " << alias;
bool terminate = false;
// this sets the folder status to disabled but does not interrupt it.
Folder *f = _folderMan->folder( alias );
if( f && !enable ) {
// check if a sync is still running and if so, ask if we should terminate.
if( f->isBusy() ) { // its still running
int reply = QMessageBox::question( 0, tr("Sync Running"),
tr("The syncing operation is running.<br/>Do you want to terminate it?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes );
if ( reply == QMessageBox::Yes )
terminate = true;
else
return; // do nothing
}
}
// message box can return at any time while the thread keeps running,
// so better check again after the user has responded.
if ( f->isBusy() && terminate )
_folderMan->terminateSyncProcess( alias );
_folderMan->slotEnableFolder( alias, enable );
_statusDialog->slotUpdateFolderState( f );
}
void Application::slotConfigure()
{
if (!_owncloudSetupWizard.isNull() &&
!_owncloudSetupWizard->wizard()->isVisible()) {
raiseDialog(_owncloudSetupWizard->wizard());
return;
}
_owncloudSetupWizard.reset(new OwncloudSetupWizard( _folderMan, _theme, this ));;
connect( _owncloudSetupWizard.data(), SIGNAL(ownCloudWizardDone(int)),
this, SLOT(slotownCloudWizardDone(int)));
_folderMan->setSyncEnabled(false); // do not start more syncs.
_owncloudSetupWizard->startWizard();
}
void Application::slotConfigureProxy()
{
if (_proxyDialog.isNull()) {
_proxyDialog = new ProxyDialog;
_proxyDialog->open();
connect(_proxyDialog, SIGNAL(accept()), SLOT(slotSetupProxy()));
if (_settingsDialog.isNull()) {
_settingsDialog = new SettingsDialog(this);
_settingsDialog->open();
} else {
raiseDialog(_proxyDialog);
Utility::raiseDialog(_settingsDialog);
}
}
@ -954,7 +711,7 @@ void Application::slotParseOptions(const QString &opts)
void Application::slotShowTrayMessage(const QString &title, const QString &msg)
{
if( _tray != NULL )
if( _tray )
_tray->showMessage(title, msg);
else
qDebug() << "Tray not ready: " << msg;
@ -964,11 +721,8 @@ void Application::slotSyncStateChange( const QString& alias )
{
SyncResult result = _folderMan->syncResult( alias );
_statusDialog->slotUpdateFolderState( _folderMan->folder(alias) );
emit folderStateChanged( _folderMan->folder(alias) );
if( _fileItemDialog && _fileItemDialog->isVisible() ) {
_fileItemDialog->setSyncResult( _folderMan->syncResult(alias) );
}
computeOverallSyncStatus();
qDebug() << "Sync state changed for folder " << alias << ": " << result.statusString();
@ -1013,8 +767,6 @@ void Application::parseOptions(const QStringList &options)
}
} else if (option == QLatin1String("--logflush")) {
_logFlush = true;
} else if (option == QLatin1String("--monoicons")) {
_theme->setSystrayUseMonoIcons(true);
} else if (option == QLatin1String("--confdir")) {
if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) {
QString confDir = it.next();

View file

@ -23,10 +23,8 @@
#include "qtsingleapplication.h"
#include "mirall/syncresult.h"
#include "mirall/folder.h"
#include "mirall/logbrowser.h"
#include "mirall/folderman.h"
#include "mirall/fileitemdialog.h"
#include "mirall/systray.h"
class QAction;
@ -38,42 +36,29 @@ class QNetworkReply;
namespace Mirall {
class Theme;
class Folder;
class FolderWatcher;
class FolderWizard;
class StatusDialog;
class OwncloudSetupWizard;
class ownCloudInfo;
class SslErrorDialog;
class ProxyDialog;
class SettingsDialog;
class Application : public SharedTools::QtSingleApplication
{
Q_OBJECT
public:
friend class SettingsDialog;
explicit Application(int &argc, char **argv);
~Application();
bool giveHelp();
void showHelp();
signals:
protected slots:
void slotAddFolder();
void slotOpenStatus();
void slotRemoveFolder( const QString& );
void slotResetFolder( const QString& );
void slotEnableFolder( const QString&, const bool );
void slotInfoFolder( const QString& );
void slotConfigure();
void slotConfigureProxy();
void slotParseOptions( const QString& );
void slotShowTrayMessage(const QString&, const QString&);
void slotSyncStateChange( const QString& );
public slots:
// TODO: this should not be public
void slotownCloudWizardDone(int);
protected:
protected:
void parseOptions(const QStringList& );
void setupTranslations();
void setupActions();
@ -90,7 +75,18 @@ protected:
bool winEventFilter( MSG * message, long * result );
#endif
signals:
void folderRemoved();
void folderStateChanged(Folder*);
protected slots:
void slotFoldersChanged();
void slotCheckConfig();
void slotSettings();
void slotParseOptions( const QString& );
void slotShowTrayMessage(const QString&, const QString&);
void slotSyncStateChange( const QString& );
void slotTrayClicked( QSystemTrayIcon::ActivationReason );
void slotFolderOpenAction(const QString & );
void slotOpenOwnCloud();
@ -100,47 +96,40 @@ protected slots:
void slotCheckAuthentication();
void slotAuthCheck( const QString& ,QNetworkReply* );
void slotOpenLogBrowser();
void slotAbout();
void slotSSLFailed( QNetworkReply *reply, QList<QSslError> errors );
void slotFetchCredentials();
void slotCredentialsFetched( bool );
void slotStartUpdateDetector();
void slotSetupProxy();
void slotRefreshQuotaDisplay( qint64 total, qint64 used );
void slotUseMonoIconsChanged( bool );
void slotHelp();
private:
void setHelp();
void raiseDialog( QWidget* );
// configuration file -> folder
Systray *_tray;
QAction *_actionQuit;
QAction *_actionAddFolder;
QAction *_actionOpenStatus;
QAction *_actionQuota;
QAction *_actionConfigure;
QAction *_actionOpenoC;
QAction *_actionConfigureProxy;
QAction *_actionAbout;
QAction *_actionSettings;
QAction *_actionQuota;
QAction *_actionHelp;
QAction *_actionQuit;
#if QT_VERSION >= 0x040700
QNetworkConfigurationManager *_networkMgr;
#endif
QPointer<FolderWizard> _folderWizard;
QScopedPointer<OwncloudSetupWizard> _owncloudSetupWizard;
SslErrorDialog *_sslErrorDialog;
// tray's menu
QMenu *_contextMenu;
StatusDialog *_statusDialog;
FileItemDialog *_fileItemDialog;
FolderMan *_folderMan;
Theme *_theme;
QSignalMapper *_folderOpenActionMapper;
LogBrowser *_logBrowser;
QPointer<ProxyDialog> _proxyDialog;
QPointer<SettingsDialog> _settingsDialog;
QString _logFile;
QString _logDirectory;
int _logExpire;

View file

@ -14,10 +14,11 @@
#include <QtGui>
#include "mirall/fileitemdialog.h"
#include "mirall/theme.h"
#include "mirall/syncresult.h"
#include "mirall/logger.h"
#include "ui_fileitemdialog.h"
#define TYPE_SUCCESS 1
#define TYPE_CONFLICT 2
#define TYPE_NEW 3
@ -30,32 +31,37 @@
namespace Mirall {
FileItemDialog::FileItemDialog(Theme *theme, QWidget *parent) :
FileItemDialog::FileItemDialog(QWidget *parent) :
QDialog(parent),
_theme(theme)
_ui(new Ui::FileItemDialog)
{
setupUi(this);
connect(_dialogButtonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()),
_ui->setupUi(this);
connect(_ui->_dialogButtonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()),
this, SLOT(accept()));
QStringList header;
header << tr("Files");
QString firstColString = tr("File Count");
header << firstColString;
_treeWidget->setHeaderLabels( header );
_ui->_treeWidget->setHeaderLabels( header );
_treeWidget->setColumnWidth(0, 480);
_ui->_treeWidget->setColumnWidth(0, 480);
_timer.setInterval(1000);
connect(&_timer, SIGNAL(timeout()), this, SLOT(slotSetFolderMessage()));
connect(this, SIGNAL(guiLog(QString,QString)), Logger::instance(), SIGNAL(guiLog(QString,QString)));
QPushButton *copyBtn = _dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
QPushButton *copyBtn = _ui->_dialogButtonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
connect(copyBtn, SIGNAL(clicked()), SLOT(copyToClipboard()));
setWindowTitle(tr("Sync Protocol"));
}
FileItemDialog::~FileItemDialog()
{
delete _ui;
}
void FileItemDialog::setSyncResult( const SyncResult& result )
{
QString folderMessage;
@ -94,17 +100,17 @@ void FileItemDialog::setSyncResult( const SyncResult& result )
_lastSyncTime = result.syncTime();
if( result.errorStrings().count() ) {
_errorLabel->setVisible(true);
_errorLabel->setTextFormat(Qt::RichText);
_ui->_errorLabel->setVisible(true);
_ui->_errorLabel->setTextFormat(Qt::RichText);
QString errStr;
foreach( QString err, result.errorStrings() ) {
errStr.append(QString("<p>%1</p>").arg(err));
}
_errorLabel->setText(errStr);
_ui->_errorLabel->setText(errStr);
} else {
_errorLabel->setText(QString::null);
_errorLabel->setVisible(false);
_ui->_errorLabel->setText(QString::null);
_ui->_errorLabel->setVisible(false);
}
slotSetFolderMessage();
@ -124,9 +130,9 @@ void FileItemDialog::slotSetFolderMessage()
int secs = _lastSyncTime.secsTo(now);
if (secs < 60)
_timelabel->setText(tr("%1 (last finished %n sec. ago)", "", secs).arg(_folderMessage));
_ui->_timelabel->setText(tr("%1 (last finished %n sec. ago)", "", secs).arg(_folderMessage));
else
_timelabel->setText(tr("%1 (last finished %n min. ago)", "", secs/60).arg(_folderMessage));
_ui->_timelabel->setText(tr("%1 (last finished %n min. ago)", "", secs/60).arg(_folderMessage));
}
void FileItemDialog::copyToClipboard()
@ -134,9 +140,9 @@ void FileItemDialog::copyToClipboard()
QString text;
QTextStream ts(&text);
int topLevelItems = _treeWidget->topLevelItemCount();
int topLevelItems = _ui->_treeWidget->topLevelItemCount();
for (int i = 0; i < topLevelItems; i++) {
QTreeWidgetItem *item = _treeWidget->topLevelItem(i);
QTreeWidgetItem *item = _ui->_treeWidget->topLevelItem(i);
ts << left << qSetFieldWidth(50)
<< item->data(0, Qt::DisplayRole).toString()
<< right << qSetFieldWidth(6)
@ -166,52 +172,52 @@ void FileItemDialog::accept()
void FileItemDialog::setSyncFileItems( const SyncFileItemVector& list )
{
_treeWidget->clear();
_ui->_treeWidget->clear();
QStringList strings;
QFont headerFont;
headerFont.setWeight(QFont::Bold);
strings.clear();
strings.append(tr("Synced Files"));
_syncedFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_SUCCESS );
_syncedFileItem = new QTreeWidgetItem( _ui->_treeWidget, strings, TYPE_SUCCESS );
_syncedFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_syncedFileItem);
_ui->_treeWidget->addTopLevelItem(_syncedFileItem);
strings.clear();
strings.append(tr("New Files"));
_newFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_NEW );
_newFileItem = new QTreeWidgetItem( _ui->_treeWidget, strings, TYPE_NEW );
_newFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_newFileItem);
_ui->_treeWidget->addTopLevelItem(_newFileItem);
strings.clear();
strings.append(tr("Deleted Files"));
_deletedFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_DELETED );
_deletedFileItem = new QTreeWidgetItem( _ui->_treeWidget, strings, TYPE_DELETED );
_deletedFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_deletedFileItem);
_ui->_treeWidget->addTopLevelItem(_deletedFileItem);
strings.clear();
strings.append(tr("Renamed Files"));
_renamedFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_RENAME);
_renamedFileItem = new QTreeWidgetItem( _ui->_treeWidget, strings, TYPE_RENAME);
_renamedFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_renamedFileItem);
_ui->_treeWidget->addTopLevelItem(_renamedFileItem);
strings.clear();
strings.append(tr("Ignored Files"));
_ignoredFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_IGNORE);
_ignoredFileItem = new QTreeWidgetItem( _ui->_treeWidget, strings, TYPE_IGNORE);
_ignoredFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_renamedFileItem);
_ui->_treeWidget->addTopLevelItem(_renamedFileItem);
strings.clear();
strings.append(tr("Errors"));
_errorFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_ERROR );
_errorFileItem = new QTreeWidgetItem( _ui->_treeWidget, strings, TYPE_ERROR );
_errorFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_errorFileItem);
_ui->_treeWidget->addTopLevelItem(_errorFileItem);
strings.clear();
strings.append(tr("Conflicts"));
_conflictFileItem = new QTreeWidgetItem( _treeWidget, strings, TYPE_CONFLICT);
_conflictFileItem = new QTreeWidgetItem( _ui->_treeWidget, strings, TYPE_CONFLICT);
_conflictFileItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_treeWidget->addTopLevelItem(_conflictFileItem);
_ui->_treeWidget->addTopLevelItem(_conflictFileItem);
QList<QTreeWidgetItem*> syncedItems;
QList<QTreeWidgetItem*> renamedItems;

View file

@ -23,15 +23,18 @@
#include "ui_fileitemdialog.h"
namespace Mirall {
class Theme;
class SyncResult;
namespace Ui {
class FileItemDialog;
}
class FileItemDialog : public QDialog, public Ui::_fileItemDialog
class FileItemDialog : public QDialog
{
Q_OBJECT
public:
explicit FileItemDialog(Theme*, QWidget *parent = 0);
explicit FileItemDialog(QWidget *parent = 0);
~FileItemDialog();
void setSyncResult( const SyncResult& );
signals:
@ -58,10 +61,10 @@ private:
QTreeWidgetItem *_conflictFileItem;
QTreeWidgetItem *_ignoredFileItem;
Theme *_theme;
QString _folderMessage;
QDateTime _lastSyncTime;
QTimer _timer;
Ui::FileItemDialog *_ui;
};
}

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>_fileItemDialog</class>
<widget class="QWidget" name="_fileItemDialog">
<class>Mirall::FileItemDialog</class>
<widget class="QWidget" name="Mirall::FileItemDialog">
<property name="geometry">
<rect>
<x>0</x>

View file

@ -322,13 +322,13 @@ Folder *FolderMan::folder( const QString& alias )
SyncResult FolderMan::syncResult( const QString& alias )
{
SyncResult res;
Folder *f = folder( alias );
return syncResult(f);
}
if( f ) {
res = f->syncResult();
}
return res;
SyncResult FolderMan::syncResult( Folder *f )
{
return f ? f->syncResult() : SyncResult();
}
void FolderMan::slotScheduleAllFolders()

View file

@ -61,6 +61,11 @@ public:
*/
SyncResult syncResult( const QString& );
/**
* return the last sync result by Folder
*/
SyncResult syncResult( Folder* );
/**
* creates a folder for a specific configuration, identified by alias.
*/

View file

@ -0,0 +1,215 @@
/*
* Copyright (C) by Klaas Freitag <freitag@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.
*/
#include "mirall/folderstatusmodel.h"
#include <QtCore>
#include <QtGui>
namespace Mirall {
FolderStatusModel::FolderStatusModel()
:QStandardItemModel()
{
}
Qt::ItemFlags FolderStatusModel::flags ( const QModelIndex& )
{
return Qt::ItemIsSelectable;
}
QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role == Qt::EditRole)
return QVariant();
else
return QStandardItemModel::data(index,role);
}
// ====================================================================================
FolderStatusDelegate::FolderStatusDelegate()
:QStyledItemDelegate()
{
}
FolderStatusDelegate::~FolderStatusDelegate()
{
// TODO Auto-generated destructor stub
}
//alocate each item size in listview.
QSize FolderStatusDelegate::sizeHint(const QStyleOptionViewItem & option ,
const QModelIndex & index) const
{
Q_UNUSED(option)
QFont aliasFont = option.font;
QFont font = option.font;
aliasFont.setPointSize( font.pointSize() +2 );
QFontMetrics fm(font);
QFontMetrics aliasFm(aliasFont);
int aliasMargin = aliasFm.height()/2;
int margin = fm.height()/4;
// calc height
int h = aliasMargin; // margin to top
h += aliasFm.height(); // alias
h += margin; // between alias and local path
h += fm.height(); // local path
h += margin; // between local and remote path
h += fm.height(); // remote path
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();
}
return QSize( 0, h);
}
void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyledItemDelegate::paint(painter,option,index);
painter->save();
QFont aliasFont = option.font;
QFont subFont = option.font;
QFont errorFont = subFont;
//font.setPixelSize(font.weight()+);
aliasFont.setBold(true);
aliasFont.setPointSize( subFont.pointSize()+2 );
QFontMetrics subFm( subFont );
QFontMetrics aliasFm( aliasFont );
int aliasMargin = aliasFm.height()/2;
int margin = subFm.height()/4;
QIcon statusIcon = qvariant_cast<QIcon>(index.data(FolderStatusIconRole));
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));
// QString statusText = qvariant_cast<QString>(index.data(FolderStatus));
bool syncEnabled = index.data(FolderSyncEnabled).toBool();
// QString syncStatus = syncEnabled? tr( "Enabled" ) : tr( "Disabled" );
QRect iconRect = option.rect;
QRect aliasRect = option.rect;
iconRect.setLeft( aliasMargin );
iconRect.setTop( iconRect.top() + aliasMargin ); // (iconRect.height()-iconsize.height())/2);
// local directory box
aliasRect.setTop(aliasRect.top() + aliasMargin );
aliasRect.setBottom(aliasRect.top() + aliasFm.height());
aliasRect.setRight(aliasRect.right() - aliasMargin );
// local directory box
QRect localPathRect = aliasRect;
localPathRect.setTop(aliasRect.bottom() + margin );
localPathRect.setBottom(localPathRect.top() + subFm.height());
// remote directory box
QRect remotePathRect = localPathRect;
remotePathRect.setTop( localPathRect.bottom() + margin );
remotePathRect.setBottom( remotePathRect.top() + subFm.height());
iconRect.setBottom(remotePathRect.bottom());
iconRect.setWidth(iconRect.height());
int nextToIcon = iconRect.right()+aliasMargin;
aliasRect.setLeft(nextToIcon);
localPathRect.setLeft(nextToIcon);
remotePathRect.setLeft(nextToIcon);
int iconSize = iconRect.width();
QPixmap pm = statusIcon.pixmap(iconSize, iconSize, syncEnabled ? QIcon::Normal : QIcon::Disabled );
painter->drawPixmap(QPoint(iconRect.left(), iconRect.top()), pm);
if ((option.state & QStyle::State_Selected)
&& (option.state & QStyle::State_Active)
// Hack: Windows Vista's light blue is not contrasting enough for white
&& !qApp->style()->inherits("QWindowsVistaStyle")) {
painter->setPen(option.palette.color(QPalette::HighlightedText));
} else {
painter->setPen(option.palette.color(QPalette::Text));
}
QString elidedAlias = aliasFm.elidedText(aliasText, Qt::ElideRight, aliasRect.width());
painter->setFont(aliasFont);
painter->drawText(aliasRect, elidedAlias);
painter->setFont(subFont);
QString elidedPathText = subFm.elidedText(pathText, Qt::ElideMiddle, localPathRect.width());
painter->drawText(localPathRect, elidedPathText);
QString elidedRemotePathText = subFm.elidedText(tr("Remote path: %1").arg(remotePath),
Qt::ElideMiddle, remotePathRect.width());
painter->drawText(remotePathRect, elidedRemotePathText);
// paint an error overlay if there is an error string
if( !errorText.isEmpty() ) {
QRect errorRect = localPathRect;
errorRect.setLeft( iconRect.left());
errorRect.setTop( iconRect.bottom()+subFm.height()/2 );
errorRect.setHeight(subFm.height()+aliasMargin);
errorRect.setRight( option.rect.right()-aliasMargin );
painter->setBrush( QColor(0xbb, 0x4d, 0x4d) );
painter->setPen( QColor(0xaa, 0xaa, 0xaa));
painter->drawRoundedRect( errorRect, 4, 4 );
QIcon warnIcon(":/mirall/resources/warning-16");
QPoint warnPos(errorRect.left()+aliasMargin/2, errorRect.top()+aliasMargin/2);
painter->drawPixmap( warnPos, warnIcon.pixmap(QSize(16,16)));
painter->setPen( Qt::white );
painter->setFont(errorFont);
QRect errorTextRect = errorRect;
errorTextRect.setLeft( errorTextRect.left()+aliasMargin +16);
errorTextRect.setTop( errorTextRect.top()+aliasMargin/2 );
int linebreak = errorText.indexOf(QLatin1String("<br"));
QString eText = errorText;
if(linebreak) {
eText = errorText.left(linebreak);
}
painter->drawText(errorTextRect, eText);
}
// painter->drawText(lastSyncRect, tr("Last Sync: %1").arg( statusText ));
// painter->drawText(statusRect, tr("Sync Status: %1").arg( syncStatus ));
painter->restore();
}
bool FolderStatusDelegate::editorEvent ( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index )
{
return false;
}
} // namespace Mirall

View file

@ -0,0 +1,58 @@
/*
* Copyright (C) by Klaas Freitag <freitag@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.
*/
#ifndef FOLDERSTATUSMODEL_H
#define FOLDERSTATUSMODEL_H
#include "ui_statusdialog.h"
#include <QStyledItemDelegate>
#include <QStandardItemModel>
namespace Mirall {
class FolderStatusModel : public QStandardItemModel
{
public:
FolderStatusModel();
virtual Qt::ItemFlags flags( const QModelIndex& );
QVariant data(const QModelIndex &index, int role) const;
};
class FolderStatusDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
FolderStatusDelegate();
virtual ~FolderStatusDelegate();
enum datarole { FolderAliasRole = Qt::UserRole + 100,
FolderPathRole,
FolderSecondPathRole,
FolderRemotePath,
FolderStatus,
FolderErrorMsg,
FolderSyncEnabled,
FolderStatusIconRole
};
void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const;
QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const;
bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option,
const QModelIndex& index );
};
} // namespace Mirall
#endif // FOLDERSTATUSMODEL_H

View file

@ -32,7 +32,7 @@ namespace Mirall
{
FolderWizardSourcePage::FolderWizardSourcePage()
:_folderMap(0)
: QWizardPage()
{
_ui.setupUi(this);
registerField(QLatin1String("sourceFolder*"), _ui.localFolderLineEdit);
@ -75,12 +75,11 @@ bool FolderWizardSourcePage::isComplete() const
warnString = tr("No local directory selected!");
}
// check if the local directory isn't used yet in another ownCloud sync
Folder::Map *map = _folderMap;
if( ! map ) return false;
Folder::Map map = _folderMap;
if( isOk ) {
Folder::Map::const_iterator i = map->constBegin();
while( isOk && i != map->constEnd() ) {
Folder::Map::const_iterator i = map.constBegin();
while( isOk && i != map.constEnd() ) {
Folder *f = static_cast<Folder*>(i.value());
QString folderDir = QDir( f->path() ).canonicalPath();
if( folderDir.isEmpty() )
@ -119,9 +118,9 @@ bool FolderWizardSourcePage::isComplete() const
isOk = false;
}
Folder::Map::const_iterator i = map->constBegin();
Folder::Map::const_iterator i = map.constBegin();
bool goon = true;
while( goon && i != map->constEnd() ) {
while( goon && i != map.constEnd() ) {
Folder *f = static_cast<Folder*>(i.value());
qDebug() << "Checking local alias: " << f->alias();
if( f ) {
@ -332,10 +331,9 @@ void FolderWizardTargetPage::showWarn( const QString& msg, bool showCreateButton
FolderWizard::FolderWizard( QWidget *parent )
: QWizard(parent),
_folderWizardSourcePage(0),
_folderWizardSourcePage(new FolderWizardSourcePage),
_folderWizardTargetPage(0)
{
_folderWizardSourcePage = new FolderWizardSourcePage();
setPage(Page_Source, _folderWizardSourcePage );
if (!Theme::instance()->singleSyncFolder()) {
_folderWizardTargetPage = new FolderWizardTargetPage();
@ -350,16 +348,11 @@ FolderWizard::FolderWizard( QWidget *parent )
FolderWizard::~FolderWizard()
{
delete _folderWizardSourcePage;
if( _folderWizardTargetPage )
delete _folderWizardTargetPage;
}
void FolderWizard::setFolderMap( Folder::Map *fm)
void FolderWizard::setFolderMap( const Folder::Map& fm)
{
if( _folderWizardSourcePage ) {
_folderWizardSourcePage->setFolderMap( fm );
}
}
} // end namespace

View file

@ -42,14 +42,14 @@ public:
void initializePage();
void cleanupPage();
void setFolderMap( Folder::Map *fm ) { _folderMap = fm; }
void setFolderMap( const Folder::Map &fm ) { _folderMap = fm; }
protected slots:
void on_localFolderChooseBtn_clicked();
void on_localFolderLineEdit_textChanged();
private:
Ui_FolderWizardSourcePage _ui;
Folder::Map *_folderMap;
Folder::Map _folderMap;
};
@ -103,7 +103,7 @@ public:
FolderWizard(QWidget *parent = 0);
~FolderWizard();
void setFolderMap( Folder::Map* );
void setFolderMap( const Folder::Map &map );
private:

View file

@ -0,0 +1,150 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@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.
*/
#include "generalsettings.h"
#include "ui_generalsettings.h"
#include "mirall/theme.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/application.h"
#include <QNetworkProxy>
namespace Mirall {
GeneralSettings::GeneralSettings(QWidget *parent) :
QWidget(parent),
_ui(new Ui::GeneralSettings)
{
_ui->setupUi(this);
#if QT_VERSION >= 0x040700
_ui->hostLineEdit->setPlaceholderText(tr("Hostname of proxy server"));
_ui->userLineEdit->setPlaceholderText(tr("Username for proxy server"));
_ui->passwordLineEdit->setPlaceholderText(tr("Password for proxy server"));
#endif
_ui->typeComboBox->addItem(tr("HTTP(S) proxy"), QNetworkProxy::HttpProxy);
_ui->typeComboBox->addItem(tr("SOCKS5 proxy"), QNetworkProxy::Socks5Proxy);
// not implemented yet
_ui->desktopNotificationsCheckBox->setEnabled(false);
_ui->autostartCheckBox->setEnabled(false);
// setup about section
QString about = Theme::instance()->about();
if (about.isEmpty()) {
_ui->aboutGroupBox->hide();
} else {
_ui->aboutLabel->setText(about);
_ui->aboutLabel->setOpenExternalLinks(true);
}
_ui->authRequiredcheckBox->setEnabled(true);
connect(_ui->manualProxyRadioButton, SIGNAL(toggled(bool)),
_ui->manualSettings, SLOT(setEnabled(bool)));
connect(_ui->manualProxyRadioButton, SIGNAL(toggled(bool)),
_ui->typeComboBox, SLOT(setEnabled(bool)));
connect(_ui->authRequiredcheckBox, SIGNAL(toggled(bool)),
_ui->authWidgets, SLOT(setEnabled(bool)));
loadProxySettings();
loadMiscSettings();
// misc
connect(_ui->monoIconsCheckBox, SIGNAL(toggled(bool)), SLOT(saveMiscSettings()));
// proxy
connect(_ui->typeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(saveProxySettings()));
connect(_ui->proxyButtonGroup, SIGNAL(buttonClicked(int)), SLOT(saveProxySettings()));
connect(_ui->hostLineEdit, SIGNAL(editingFinished()), SLOT(saveProxySettings()));
connect(_ui->userLineEdit, SIGNAL(editingFinished()), SLOT(saveProxySettings()));
connect(_ui->passwordLineEdit, SIGNAL(editingFinished()), SLOT(saveProxySettings()));
connect(_ui->portSpinBox, SIGNAL(editingFinished()), SLOT(saveProxySettings()));
}
GeneralSettings::~GeneralSettings()
{
delete _ui;
}
void GeneralSettings::loadProxySettings()
{
// load current proxy settings
Mirall::MirallConfigFile cfgFile;
int type = cfgFile.proxyType();
switch (type) {
case QNetworkProxy::NoProxy:
_ui->noProxyRadioButton->setChecked(true);
break;
case QNetworkProxy::DefaultProxy:
_ui->systemProxyRadioButton->setChecked(true);
break;
case QNetworkProxy::Socks5Proxy:
case QNetworkProxy::HttpProxy:
_ui->typeComboBox->setCurrentIndex(_ui->typeComboBox->findData(type));
_ui->manualProxyRadioButton->setChecked(true);
break;
default:
break;
}
_ui->hostLineEdit->setText(cfgFile.proxyHostName());
int port = cfgFile.proxyPort();
if (port == 0)
port = 8080;
_ui->portSpinBox->setValue(port);
if (!cfgFile.proxyUser().isEmpty())
{
_ui->authRequiredcheckBox->setChecked(true);
_ui->userLineEdit->setText(cfgFile.proxyUser());
_ui->passwordLineEdit->setText(cfgFile.proxyPassword());
}
}
void GeneralSettings::loadMiscSettings()
{
MirallConfigFile cfgFile;
_ui->monoIconsCheckBox->setChecked(cfgFile.monoIcons());
}
void GeneralSettings::saveMiscSettings()
{
MirallConfigFile cfgFile;
bool isChecked = _ui->monoIconsCheckBox->isChecked();
cfgFile.setMonoIcons(isChecked);
Theme::instance()->setSystrayUseMonoIcons(isChecked);
}
void GeneralSettings::saveProxySettings()
{
MirallConfigFile cfgFile;
if (_ui->noProxyRadioButton->isChecked()){
cfgFile.setProxyType(QNetworkProxy::NoProxy);
} else if (_ui->systemProxyRadioButton->isChecked()){
cfgFile.setProxyType(QNetworkProxy::DefaultProxy);
} else if (_ui->manualProxyRadioButton->isChecked()) {
int type = _ui->typeComboBox->itemData(_ui->typeComboBox->currentIndex()).toInt();
bool needsAuth = _ui->authRequiredcheckBox->isChecked();
QString user = _ui->userLineEdit->text();
QString pass = _ui->passwordLineEdit->text();
cfgFile.setProxyType(type, _ui->hostLineEdit->text(),
_ui->portSpinBox->value(), needsAuth, user, pass);
}
emit proxySettingsChanged();
}
} // namespace Mirall

View file

@ -0,0 +1,50 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@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 MIRALL_GENERALSETTINGS_H
#define MIRALL_GENERALSETTINGS_H
#include <QWidget>
namespace Mirall {
namespace Ui {
class GeneralSettings;
}
class GeneralSettings : public QWidget
{
Q_OBJECT
public:
explicit GeneralSettings(QWidget *parent = 0);
~GeneralSettings();
signals:
void proxySettingsChanged();
private slots:
void saveProxySettings();
void saveMiscSettings();
private:
void loadProxySettings();
void loadMiscSettings();
Ui::GeneralSettings *_ui;
};
} // namespace Mirall
#endif // MIRALL_GENERALSETTINGS_H

View file

@ -0,0 +1,232 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Mirall::GeneralSettings</class>
<widget class="QWidget" name="Mirall::GeneralSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>384</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="generalGroupBox">
<property name="title">
<string>General</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="autostartCheckBox">
<property name="text">
<string>Launch on System Startup</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="desktopNotificationsCheckBox">
<property name="text">
<string>Show Desktop Notifications</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="monoIconsCheckBox">
<property name="text">
<string>Use Monochrome Icons</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="proxyGroupBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Proxy Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QRadioButton" name="noProxyRadioButton">
<property name="text">
<string>No Proxy</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">proxyButtonGroup</string>
</attribute>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="systemProxyRadioButton">
<property name="text">
<string>Use system proxy</string>
</property>
<attribute name="buttonGroup">
<string notr="true">proxyButtonGroup</string>
</attribute>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="manualProxyRadioButton">
<property name="text">
<string>Specify proxy manually as</string>
</property>
<attribute name="buttonGroup">
<string notr="true">proxyButtonGroup</string>
</attribute>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="typeComboBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QWidget" name="manualSettings" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="rightMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="hostLabel">
<property name="text">
<string>Host</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="hostLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="portSpinBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>8080</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="authRequiredcheckBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Proxy server requires authentication</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="authWidgets" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="userLineEdit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="passwordLineEdit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string/>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="aboutGroupBox">
<property name="title">
<string>About</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="aboutLabel">
<property name="text">
<string>About</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="proxyButtonGroup"/>
</buttongroups>
</ui>

View file

@ -556,4 +556,16 @@ QString MirallConfigFile::proxyPassword() const
return QString::fromUtf8(QByteArray::fromBase64(pass));
}
bool MirallConfigFile::monoIcons() const
{
QSettings settings( configFile(), QSettings::IniFormat );
return settings.value("monoIcons", false).toBool();
}
void MirallConfigFile::setMonoIcons(bool useMonoIcons)
{
QSettings settings( configFile(), QSettings::IniFormat );
settings.setValue("monoIcons", useMonoIcons);
}
}

View file

@ -84,6 +84,9 @@ public:
// Custom Config: remove the custom config file.
void cleanupCustomConfig();
bool monoIcons() const;
void setMonoIcons(bool);
// proxy settings
void setProxyType(int proxyType,
const QString& host = QString(),

View file

@ -63,7 +63,9 @@ ownCloudInfo* ownCloudInfo::instance()
ownCloudInfo::ownCloudInfo() :
QObject(0),
_manager(0)
_manager(0),
_lastQuotaTotalBytes(0),
_lastQuotaUsedBytes(0)
{
_connection = Theme::instance()->appName();
connect(this, SIGNAL(guiLog(QString,QString)),
@ -317,7 +319,6 @@ void ownCloudInfo::slotGetQuotaFinished()
if (type == QXmlStreamReader::StartElement &&
reader.namespaceUri() == QLatin1String("DAV:")) {
QString name = reader.name().toString();
QString ns = reader.namespaceUri().toString();
if (name == QLatin1String("quota-used-bytes")) {
quotaUsedBytes = reader.readElementText().toLongLong(&ok);
if (!ok) quotaUsedBytes = 0;
@ -330,6 +331,8 @@ void ownCloudInfo::slotGetQuotaFinished()
qint64 total = quotaUsedBytes + quotaAvailableBytes;
_lastQuotaTotalBytes = total;
_lastQuotaUsedBytes = quotaUsedBytes;
emit quotaUpdated(total, quotaUsedBytes);
reply->deleteLater();

View file

@ -115,6 +115,9 @@ public:
*/
QString webdavUrl(const QString& connection = QString());
qint64 lastQuotaUsedBytes() const { return _lastQuotaUsedBytes; }
qint64 lastQuotaTotalBytes() const { return _lastQuotaTotalBytes; }
signals:
// result signal with url- and version string.
void ownCloudInfoFound( const QString&, const QString&, const QString&, const QString& );
@ -125,7 +128,6 @@ signals:
void sslFailed( QNetworkReply *reply, QList<QSslError> errors );
void guiLog( const QString& title, const QString& content );
void quotaUpdated( qint64 total, qint64 quotaUsedBytes );
public slots:
protected slots:
void slotReplyFinished( );
@ -173,6 +175,8 @@ private:
QMap<QString, oCICredentials> _credentials;
QMutex _certChainMutex;
int _redirectCount;
qint64 _lastQuotaUsedBytes;
qint64 _lastQuotaTotalBytes;
};
};

View file

@ -26,9 +26,7 @@
namespace Mirall {
class Theme;
OwncloudSetupWizard::OwncloudSetupWizard( FolderMan *folderMan, Theme *theme, QObject *parent ) :
OwncloudSetupWizard::OwncloudSetupWizard( FolderMan *folderMan, QObject *parent ) :
QObject( parent ),
_mkdirRequestReply(0),
_checkInstallationRequest(0),
@ -44,7 +42,7 @@ OwncloudSetupWizard::OwncloudSetupWizard( FolderMan *folderMan, Theme *theme, QO
connect( _ocWizard, SIGNAL(clearPendingRequests()),
this, SLOT(slotClearPendingRequests()));
_ocWizard->setWindowTitle( tr("%1 Connection Wizard").arg( theme->appNameGUI() ) );
_ocWizard->setWindowTitle( tr("%1 Connection Wizard").arg( Theme::instance()->appNameGUI() ) );
}
OwncloudSetupWizard::~OwncloudSetupWizard()
@ -56,6 +54,14 @@ OwncloudWizard *OwncloudSetupWizard::wizard() {
return _ocWizard;
}
void OwncloudSetupWizard::runWizard(FolderMan *folderMan, QObject* obj, const char* amember, QWidget *parent)
{
OwncloudSetupWizard *wiz = new OwncloudSetupWizard(folderMan, parent);
connect( wiz, SIGNAL(ownCloudWizardDone(int)), obj, amember);
folderMan->setSyncEnabled(false);
wiz->startWizard();
}
void OwncloudSetupWizard::startWizard()
{
// Set useful default values.
@ -93,7 +99,7 @@ void OwncloudSetupWizard::startWizard()
// settings re-initialized in initPage must be set here after restart
_ocWizard->setMultipleFoldersExist(_folderMan->map().count() > 1);
_ocWizard->show();
_ocWizard->open();
_ocWizard->raise();
}

View file

@ -35,7 +35,7 @@ class OwncloudSetupWizard : public QObject
{
Q_OBJECT
public:
explicit OwncloudSetupWizard( FolderMan *folderMan = 0, Theme *theme = 0, QObject *parent = 0 );
explicit OwncloudSetupWizard( FolderMan *folderMan, QObject *parent = 0 );
~OwncloudSetupWizard();
@ -59,6 +59,9 @@ public:
OwncloudWizard *wizard();
/** Run the wizard */
static void runWizard( FolderMan *folderMan, QObject *obj, const char* amember, QWidget *parent = 0 );
signals:
// issued if the oC Setup process (owncloud-admin) is finished.
void ownCloudSetupFinished( bool );

View file

@ -52,32 +52,28 @@ QString ownCloudTheme::about() const
QString devString;
#ifdef GIT_SHA1
const QString githubPrefix(QLatin1String(
" https://github.com/owncloud/mirall/commit/"));
"https://github.com/owncloud/mirall/commit/"));
const QString gitSha1(QLatin1String(GIT_SHA1));
devString = QCoreApplication::translate("ownCloudTheme::about()",
"<p><small>Built from Git revision <a href=\"%1\">%2</a>"
" on %3, %4<br>using OCsync %5 and Qt %6.</small><p>")
" on %3, %4 using OCsync %5 and Qt %6.</small><p>")
.arg(githubPrefix+gitSha1).arg(gitSha1.left(6))
.arg(__DATE__).arg(__TIME__)
.arg(MIRALL_STRINGIFY(LIBCSYNC_VERSION))
.arg(QT_VERSION_STR);
#endif
return QCoreApplication::translate("ownCloudTheme::about()",
"<p><b>%1 Client Version %2</b></p>"
"<p><b>Authors</b>"
"<br><a href=\"mailto:freitag@owncloud.com\">"
"Klaas Freitag</a>, ownCloud, Inc."
"<br><a href=\"mailto:danimo@owncloud.com\">"
"Daniel Molkentin</a>, ownCloud, Inc."
"<br><br>Based on Mirall by Duncan Mac-Vicar P.</p>"
"<p>For more information visit <a href=\"%3\">%4</a>.</p>"
"<p>Version %2. "
"For more information visit <a href=\"%3\">%4</a></p>"
"<p><small>written by Klaas Freitag, Daniel Molkentin, ownCloud Inc., "
"based on Mirall by Duncan Mac-Vicar P.</small></p>"
"%7"
)
.arg(appName())
.arg(MIRALL_STRINGIFY(MIRALL_VERSION))
.arg("http://" MIRALL_STRINGIFY(APPLICATION_DOMAIN))
.arg(MIRALL_STRINGIFY(APPLICATION_DOMAIN))
.arg(devString);
}
QIcon ownCloudTheme::trayFolderIcon( const QString& ) const
@ -109,6 +105,11 @@ QVariant ownCloudTheme::customMedia(Theme::CustomMediaType type)
}
}
QString ownCloudTheme::helpUrl() const
{
return QString::fromLatin1("http://doc.owncloud.org/desktop/%1.%2/").arg(MIRALL_VERSION_MAJOR).arg(MIRALL_VERSION_MINOR);
}
QColor ownCloudTheme::wizardHeaderBackgroundColor() const
{
return QColor("#1d2d42");
@ -124,5 +125,7 @@ QPixmap ownCloudTheme::wizardHeaderLogo() const
return QPixmap(":/mirall/theme/colored/wizard_logo.png");
}
}

View file

@ -35,6 +35,7 @@ public:
QIcon applicationIcon() const;
QVariant customMedia(CustomMediaType type);
QString helpUrl() const;
QColor wizardHeaderBackgroundColor() const;
QColor wizardHeaderTitleColor() const;

View file

@ -1,112 +0,0 @@
/*
* Copyright (C) by Thomas Mueller <thomas.mueller@tmit.eu>
*
* 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.
*/
#include <QNetworkProxy>
#include "proxydialog.h"
#include "mirallconfigfile.h"
Mirall::ProxyDialog::ProxyDialog( QWidget* parent )
: QDialog(parent)
{
setupUi(this);
// designer is buggy, so do it programmatically
manualSettings->setEnabled(false);
#if QT_VERSION >= 0x040700
hostLineEdit->setPlaceholderText(tr("Hostname of proxy server"));
userLineEdit->setPlaceholderText(tr("Username for proxy server"));
passwordLineEdit->setPlaceholderText(tr("Password for proxy server"));
#endif
// load current proxy settings
Mirall::MirallConfigFile cfgFile;
switch (cfgFile.proxyType()) {
case QNetworkProxy::NoProxy:
noProxyRadioButton->setChecked(true);
break;
case QNetworkProxy::DefaultProxy:
systemProxyRadioButton->setChecked(true);
break;
case QNetworkProxy::Socks5Proxy:
cbSocks->setChecked(true);
// fall through
case QNetworkProxy::HttpProxy:
case QNetworkProxy::HttpCachingProxy:
manualProxyRadioButton->setChecked(true);
break;
default:
break;
}
hostLineEdit->setText(cfgFile.proxyHostName());
int port = cfgFile.proxyPort();
if (port == 0) port = 8080;
portSpinBox->setValue(port);
if (!cfgFile.proxyUser().isEmpty())
{
authRequiredcheckBox->setChecked(true);
userLineEdit->setText(cfgFile.proxyUser());
passwordLineEdit->setText(cfgFile.proxyPassword());
}
}
void Mirall::ProxyDialog::saveSettings()
{
Mirall::MirallConfigFile cfgFile;
if (noProxyRadioButton->isChecked())
{
cfgFile.setProxyType(QNetworkProxy::NoProxy);
}
if (systemProxyRadioButton->isChecked())
{
cfgFile.setProxyType(QNetworkProxy::DefaultProxy);
}
if (manualProxyRadioButton->isChecked())
{
int proxyType = cbSocks->isChecked() ? QNetworkProxy::Socks5Proxy
: QNetworkProxy::HttpProxy;
QString user = userLineEdit->text();
QString pass = passwordLineEdit->text();
cfgFile.setProxyType(proxyType, hostLineEdit->text(),
portSpinBox->value(),
authRequiredcheckBox->isChecked(),
user, pass);
}
}
void Mirall::ProxyDialog::on_authRequiredcheckBox_stateChanged(int state)
{
bool e = (state == Qt::Checked);
userLineEdit->setEnabled(e);
passwordLineEdit->setEnabled(e);
proxyUserLabel->setEnabled(e);
proxyPasswordLabel->setEnabled(e);
}
void Mirall::ProxyDialog::on_manualProxyRadioButton_toggled(bool checked)
{
manualSettings->setEnabled(checked);
}
void Mirall::ProxyDialog::on_buttonBox_accepted()
{
saveSettings();
}

View file

@ -1,43 +0,0 @@
/*
* Copyright (C) by Thomas Mueller <thomas.mueller@tmit.eu>
*
* 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.
*/
#ifndef PROXYDIALOG_H
#define PROXYDIALOG_H
#include <QtCore>
#include <QDialog>
#include "ui_proxydialog.h"
namespace Mirall
{
class ProxyDialog : public QDialog, public Ui::proxyDialog
{
Q_OBJECT
public:
explicit ProxyDialog( QWidget* parent = 0 );
~ProxyDialog() {}
void saveSettings();
private slots:
void on_buttonBox_accepted();
void on_manualProxyRadioButton_toggled(bool checked);
void on_authRequiredcheckBox_stateChanged(int );
};
} // end namespace
#endif // PROXYDIALOG_H

View file

@ -1,252 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>proxyDialog</class>
<widget class="QWidget" name="proxyDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>405</width>
<height>319</height>
</rect>
</property>
<property name="windowTitle">
<string>Proxy Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>20</number>
</property>
<item>
<widget class="QRadioButton" name="noProxyRadioButton">
<property name="text">
<string>No Proxy</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="systemProxyRadioButton">
<property name="text">
<string>Use system proxy</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="manualProxyRadioButton">
<property name="text">
<string>Manual proxy configuration</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="manualSettings" native="true">
<property name="enabled">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="hostLabel">
<property name="text">
<string>Host</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="hostLineEdit">
<property name="maximumSize">
<size>
<width>300</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="portLabel">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="portSpinBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>8080</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbSocks">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Use as SOCKSv5 proxy</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="authRequiredcheckBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Proxy server requires password</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="proxyUserLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>User</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="userLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="proxyPasswordLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="passwordLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>proxyDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>proxyDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -0,0 +1,95 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@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.
*/
#include "settingsdialog.h"
#include "ui_settingsdialog.h"
#include "mirall/theme.h"
#include "mirall/generalsettings.h"
#include "mirall/accountsettings.h"
#include "mirall/application.h"
#include <QLabel>
#include <QStandardItemModel>
#include <QPushButton>
#include <QDebug>
namespace Mirall {
QIcon createDummy() {
QIcon icon;
QPixmap p(32,32);
p.fill(Qt::transparent);
icon.addPixmap(p);
return icon;
}
SettingsDialog::SettingsDialog(Application *app, QWidget *parent) :
QDialog(parent),
_ui(new Ui::SettingsDialog)
{
_ui->setupUi(this);
setWindowTitle(tr("%1 Settings").arg(Theme::instance()->appNameGUI()));
QListWidgetItem *general = new QListWidgetItem(tr("General Settings"), _ui->labelWidget);
general->setSizeHint(QSize(0, 32));
_ui->labelWidget->addItem(general);
GeneralSettings *generalSettings = new GeneralSettings;
connect(generalSettings, SIGNAL(proxySettingsChanged()), app, SLOT(slotSetupProxy()));
connect(generalSettings, SIGNAL(proxySettingsChanged()), app->_folderMan, SLOT(slotScheduleAllFolders()));
_ui->stack->addWidget(generalSettings);
//connect(generalSettings, SIGNAL(resizeToSizeHint()), SLOT(resizeToSizeHint()));
_accountSettings = new AccountSettings(app->_folderMan);
addAccount(tr("Account Details"), _accountSettings);
connect( app, SIGNAL(folderStateChanged(Folder*)), _accountSettings, SLOT(slotUpdateFolderState(Folder*)));
connect( _accountSettings, SIGNAL(addASync()), app, SLOT(slotFolderAdded()) );
connect( _accountSettings, SIGNAL(folderChanged()), app, SLOT(slotFoldersChanged()));
connect( _accountSettings, SIGNAL(openFolderAlias(const QString&)),
app, SLOT(slotFolderOpenAction(QString)));
_ui->labelWidget->setCurrentRow(_ui->labelWidget->row(general));
connect(_ui->labelWidget, SIGNAL(currentRowChanged(int)),
_ui->stack, SLOT(setCurrentIndex(int)));
QPushButton *closeButton = _ui->buttonBox->button(QDialogButtonBox::Close);
connect(closeButton, SIGNAL(pressed()), SLOT(accept()));
}
SettingsDialog::~SettingsDialog()
{
delete _ui;
}
void SettingsDialog::addAccount(const QString &title, QWidget *widget)
{
QListWidgetItem *item = new QListWidgetItem(title);
item->setSizeHint(QSize(0, 32));
_ui->labelWidget->addItem(item);
_ui->stack->addWidget(widget);
}
void SettingsDialog::slotFolderUploadProgress( const QString& folderAlias, const QString& file, long p1, long p2)
{
qDebug() << " SettingsDialog: XX - File " << file << p1 << p2;
_accountSettings->slotSetProgress(folderAlias, file, p1, p2);
}
} // namespace Mirall

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) by Daniel Molkentin <danimo@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 SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include <QDialog>
#include <QStyledItemDelegate>
class QStandardItemModel;
class QListWidgetItem;
namespace Mirall {
namespace Ui {
class SettingsDialog;
}
class AccountSettings;
class Application;
class SettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit SettingsDialog(Application *app, QWidget *parent = 0);
~SettingsDialog();
void addAccount(const QString &title, QWidget *widget);
public slots:
// Progress, parameter is
// - filename
// - progress bytes, overall size.
void slotFolderUploadProgress( const QString&, const QString&, long, long );
private:
Ui::SettingsDialog *_ui;
QListWidgetItem *_addItem;
AccountSettings *_accountSettings;
};
}
#endif // SETTINGSDIALOG_H

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Mirall::SettingsDialog</class>
<widget class="QDialog" name="Mirall::SettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>704</width>
<height>515</height>
</rect>
</property>
<property name="windowTitle">
<string>Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0" rowspan="2">
<widget class="QListWidget" name="labelWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QStackedWidget" name="stack"/>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -19,19 +19,21 @@
#include <QtGui>
#include <QtNetwork>
#include "ui_sslerrordialog.h"
namespace Mirall
{
SslErrorDialog::SslErrorDialog(QWidget *parent) :
QDialog(parent), _allTrusted(false)
QDialog(parent), _allTrusted(false), _ui(new Ui::SslErrorDialog)
{
setupUi( this );
_ui->setupUi( this );
setWindowTitle( tr("SSL Connection") );
QPushButton *okButton =
_dialogButtonBox->button( QDialogButtonBox::Ok );
_ui->_dialogButtonBox->button( QDialogButtonBox::Ok );
QPushButton *cancelButton =
_dialogButtonBox->button( QDialogButtonBox::Cancel );
_ui->_dialogButtonBox->button( QDialogButtonBox::Cancel );
okButton->setEnabled(false);
connect(_cbTrustConnect, SIGNAL(clicked(bool)),
connect(_ui->_cbTrustConnect, SIGNAL(clicked(bool)),
okButton, SLOT(setEnabled(bool)));
if( okButton ) {
@ -41,6 +43,11 @@ SslErrorDialog::SslErrorDialog(QWidget *parent) :
}
}
SslErrorDialog::~SslErrorDialog()
{
delete _ui;
}
QString SslErrorDialog::styleSheet() const
{
@ -120,8 +127,8 @@ bool SslErrorDialog::setErrorList( QList<QSslError> errors )
doc->addResource( QTextDocument::StyleSheetResource, QUrl( QL("format.css") ), style);
doc->setHtml( msg );
_tbErrors->setDocument( doc );
_tbErrors->show();
_ui->_tbErrors->setDocument( doc );
_ui->_tbErrors->show();
return false;
}
@ -148,10 +155,8 @@ QString SslErrorDialog::certDiv( QSslCertificate cert ) const
msg += QL("<p>");
Utility util;
QString md5sum = util.formatFingerprint(cert.digest(QCryptographicHash::Md5).toHex());
QString sha1sum = util.formatFingerprint(cert.digest(QCryptographicHash::Sha1).toHex());
QString md5sum = Utility::formatFingerprint(cert.digest(QCryptographicHash::Md5).toHex());
QString sha1sum = Utility::formatFingerprint(cert.digest(QCryptographicHash::Sha1).toHex());
msg += tr("Fingerprint (MD5): <tt>%1</tt>").arg(md5sum) + QL("<br/>");
msg += tr("Fingerprint (SHA1): <tt>%1</tt>").arg(sha1sum) + QL("<br/>");
msg += QL("<br/>");
@ -177,7 +182,7 @@ bool SslErrorDialog::trustConnection()
{
if( _allTrusted ) return true;
bool stat = ( _cbTrustConnect->checkState() == Qt::Checked );
bool stat = ( _ui->_cbTrustConnect->checkState() == Qt::Checked );
qDebug() << "SSL-Connection is trusted: " << stat;
return stat;

View file

@ -19,20 +19,22 @@
#include <QSslCertificate>
#include <QList>
#include "ui_sslerrordialog.h"
class QSslError;
class QSslCertificate;
namespace Ui {
class SslErrorDialog;
}
namespace Mirall
{
class SslErrorDialog : public QDialog, public Ui::sslErrorDialog
class SslErrorDialog : public QDialog
{
Q_OBJECT
public:
explicit SslErrorDialog(QWidget *parent = 0);
~SslErrorDialog();
bool setErrorList( QList<QSslError> errors );
@ -55,6 +57,7 @@ private:
QList<QSslCertificate> _unknownCerts;
QString _customConfigHandle;
::Ui::SslErrorDialog *_ui;
};
} // end namespace

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>sslErrorDialog</class>
<widget class="QWidget" name="sslErrorDialog">
<class>SslErrorDialog</class>
<widget class="QWidget" name="SslErrorDialog">
<property name="geometry">
<rect>
<x>0</x>

View file

@ -1,536 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@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.
*/
#include "mirall/statusdialog.h"
#include "mirall/folder.h"
#include "mirall/theme.h"
#include "mirall/owncloudinfo.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/credentialstore.h"
#include "mirall/fileitemdialog.h"
#include <QtCore>
#include <QtGui>
namespace Mirall {
FolderStatusModel::FolderStatusModel()
:QStandardItemModel()
{
}
Qt::ItemFlags FolderStatusModel::flags ( const QModelIndex& )
{
return Qt::ItemIsSelectable;
}
QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role == Qt::EditRole)
return QVariant();
else
return QStandardItemModel::data(index,role);
}
// ====================================================================================
FolderViewDelegate::FolderViewDelegate()
:QStyledItemDelegate()
{
}
FolderViewDelegate::~FolderViewDelegate()
{
// TODO Auto-generated destructor stub
}
//alocate each item size in listview.
QSize FolderViewDelegate::sizeHint(const QStyleOptionViewItem & option ,
const QModelIndex & index) const
{
Q_UNUSED(option)
QFont aliasFont = option.font;
QFont font = option.font;
aliasFont.setPointSize( font.pointSize() +2 );
QFontMetrics fm(font);
QFontMetrics aliasFm(aliasFont);
int aliasMargin = aliasFm.height()/2;
int margin = fm.height()/4;
// calc height
int h = aliasMargin; // margin to top
h += aliasFm.height(); // alias
h += margin; // between alias and local path
h += fm.height(); // local path
h += margin; // between local and remote path
h += fm.height(); // remote path
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();
}
return QSize( 0, h);
}
void FolderViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyledItemDelegate::paint(painter,option,index);
painter->save();
QFont aliasFont = option.font;
QFont subFont = option.font;
QFont errorFont = subFont;
//font.setPixelSize(font.weight()+);
aliasFont.setBold(true);
aliasFont.setPointSize( subFont.pointSize()+2 );
QFontMetrics subFm( subFont );
QFontMetrics aliasFm( aliasFont );
int aliasMargin = aliasFm.height()/2;
int margin = subFm.height()/4;
QIcon statusIcon = qvariant_cast<QIcon>(index.data(FolderStatusIconRole));
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));
// QString statusText = qvariant_cast<QString>(index.data(FolderStatus));
bool syncEnabled = index.data(FolderSyncEnabled).toBool();
// QString syncStatus = syncEnabled? tr( "Enabled" ) : tr( "Disabled" );
QRect iconRect = option.rect;
QRect aliasRect = option.rect;
iconRect.setLeft( aliasMargin );
iconRect.setTop( iconRect.top() + aliasMargin ); // (iconRect.height()-iconsize.height())/2);
// local directory box
aliasRect.setTop(aliasRect.top() + aliasMargin );
aliasRect.setBottom(aliasRect.top() + aliasFm.height());
aliasRect.setRight(aliasRect.right() - aliasMargin );
// local directory box
QRect localPathRect = aliasRect;
localPathRect.setTop(aliasRect.bottom() + margin );
localPathRect.setBottom(localPathRect.top() + subFm.height());
// remote directory box
QRect remotePathRect = localPathRect;
remotePathRect.setTop( localPathRect.bottom() + margin );
remotePathRect.setBottom( remotePathRect.top() + subFm.height());
iconRect.setBottom(remotePathRect.bottom());
iconRect.setWidth(iconRect.height());
int nextToIcon = iconRect.right()+aliasMargin;
aliasRect.setLeft(nextToIcon);
localPathRect.setLeft(nextToIcon);
remotePathRect.setLeft(nextToIcon);
int iconSize = iconRect.width();
QPixmap pm = statusIcon.pixmap(iconSize, iconSize, syncEnabled ? QIcon::Normal : QIcon::Disabled );
painter->drawPixmap(QPoint(iconRect.left(), iconRect.top()), pm);
if ((option.state & QStyle::State_Selected)
&& (option.state & QStyle::State_Active)
// Hack: Windows Vista's light blue is not contrasting enough for white
&& !Application::style()->inherits("QWindowsVistaStyle")) {
painter->setPen(option.palette.color(QPalette::HighlightedText));
} else {
painter->setPen(option.palette.color(QPalette::Text));
}
QString elidedAlias = aliasFm.elidedText(aliasText, Qt::ElideRight, aliasRect.width());
painter->setFont(aliasFont);
painter->drawText(aliasRect, elidedAlias);
painter->setFont(subFont);
QString elidedPathText = subFm.elidedText(pathText, Qt::ElideMiddle, localPathRect.width());
painter->drawText(localPathRect, elidedPathText);
QString elidedRemotePathText = subFm.elidedText(tr("Remote path: %1").arg(remotePath),
Qt::ElideMiddle, remotePathRect.width());
painter->drawText(remotePathRect, elidedRemotePathText);
// paint an error overlay if there is an error string
if( !errorText.isEmpty() ) {
QRect errorRect = localPathRect;
errorRect.setLeft( iconRect.left());
errorRect.setTop( iconRect.bottom()+subFm.height()/2 );
errorRect.setHeight(subFm.height()+aliasMargin);
errorRect.setRight( option.rect.right()-aliasMargin );
painter->setBrush( QColor(0xbb, 0x4d, 0x4d) );
painter->setPen( QColor(0xaa, 0xaa, 0xaa));
painter->drawRoundedRect( errorRect, 4, 4 );
QIcon warnIcon(":/mirall/resources/warning-16");
QPoint warnPos(errorRect.left()+aliasMargin/2, errorRect.top()+aliasMargin/2);
painter->drawPixmap( warnPos, warnIcon.pixmap(QSize(16,16)));
painter->setPen( Qt::white );
painter->setFont(errorFont);
QRect errorTextRect = errorRect;
errorTextRect.setLeft( errorTextRect.left()+aliasMargin +16);
errorTextRect.setTop( errorTextRect.top()+aliasMargin/2 );
int linebreak = errorText.indexOf(QLatin1String("<br"));
QString eText = errorText;
if(linebreak) {
eText = errorText.left(linebreak);
}
painter->drawText(errorTextRect, eText);
}
// painter->drawText(lastSyncRect, tr("Last Sync: %1").arg( statusText ));
// painter->drawText(statusRect, tr("Sync Status: %1").arg( syncStatus ));
painter->restore();
}
bool FolderViewDelegate::editorEvent ( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index )
{
return false;
}
// ====================================================================================
StatusDialog::StatusDialog( Theme *theme, QWidget *parent) :
QDialog(parent),
_theme( theme )
{
setupUi( this );
setWindowTitle( QString::fromLatin1( "%1 %2" ).arg(_theme->appNameGUI(), _theme->version() ) );
_model = new FolderStatusModel();
_delegate = new FolderViewDelegate();
_folderList->setItemDelegate( _delegate );
_folderList->setModel( _model );
_folderList->setMinimumWidth( 300 );
_folderList->setEditTriggers( QAbstractItemView::NoEditTriggers );
connect(_ButtonClose, SIGNAL(clicked()), this, SLOT(accept()));
connect(_ButtonRemove, SIGNAL(clicked()), this, SLOT(slotRemoveFolder()));
connect(_ButtonReset, SIGNAL(clicked()), this, SLOT(slotResetFolder()));
connect(_ButtonEnable, SIGNAL(clicked()), this, SLOT(slotEnableFolder()));
connect(_ButtonInfo, SIGNAL(clicked()), this, SLOT(slotInfoFolder()));
connect(_ButtonAdd, SIGNAL(clicked()), this, SLOT(slotAddSync()));
_ButtonRemove->setEnabled(false);
_ButtonEnable->setEnabled(false);
_ButtonReset->setEnabled(false);
_ButtonInfo->setEnabled(false);
_ButtonAdd->setEnabled(true);
connect(_folderList, SIGNAL(clicked(QModelIndex)), SLOT(slotFolderActivated(QModelIndex)));
connect(_folderList, SIGNAL(doubleClicked(QModelIndex)),SLOT(slotDoubleClicked(QModelIndex)));
_ocUrlLabel->setWordWrap( true );
}
StatusDialog::~StatusDialog()
{
delete _model;
delete _delegate;
}
void StatusDialog::slotFolderActivated( const QModelIndex& indx )
{
bool state = indx.isValid();
_ButtonRemove->setEnabled( state );
_ButtonEnable->setEnabled( state );
_ButtonReset->setEnabled( state );
_ButtonInfo->setEnabled( state );
if ( state ) {
bool folderEnabled = _model->data( indx, FolderViewDelegate::FolderSyncEnabled).toBool();
qDebug() << "folder is sync enabled: " << folderEnabled;
if ( folderEnabled ) {
_ButtonEnable->setText( tr( "Pause" ) );
} else {
_ButtonEnable->setText( tr( "Resume" ) );
}
}
}
void StatusDialog::slotDoubleClicked( const QModelIndex& indx )
{
if( ! indx.isValid() ) return;
QString alias = _model->data( indx, FolderViewDelegate::FolderAliasRole ).toString();
emit openFolderAlias( alias );
}
void StatusDialog::setFolderList( Folder::Map folders )
{
_model->clear();
foreach( Folder *f, folders ) {
qDebug() << "Folder: " << f;
slotAddFolder( f );
}
QModelIndex idx = _model->index(0, 0);
if (idx.isValid())
_folderList->setCurrentIndex(idx);
buttonsSetEnabled();
}
void StatusDialog::slotAddFolder( Folder *folder )
{
if( ! folder || folder->alias().isEmpty() ) return;
QStandardItem *item = new QStandardItem();
folderToModelItem( item, folder );
_model->appendRow( item );
slotCheckConnection();
}
void StatusDialog::buttonsSetEnabled()
{
bool haveFolders = _folderList->model()->rowCount() > 0;
if( _theme->singleSyncFolder() ) {
// only one folder synced folder allowed.
_ButtonAdd->setVisible(!haveFolders);
} else {
_ButtonAdd->setVisible(true);
_ButtonAdd->setEnabled(true);
}
QModelIndex selected = _folderList->currentIndex();
bool isSelected = selected.isValid();
_ButtonEnable->setEnabled(isSelected);
_ButtonRemove->setEnabled(isSelected);
_ButtonInfo->setEnabled(isSelected);
_ButtonReset->setEnabled(isSelected);
}
void StatusDialog::slotUpdateFolderState( Folder *folder )
{
QStandardItem *item = 0;
int row = 0;
if( ! folder ) return;
item = _model->item( row );
while( item ) {
if( item->data( FolderViewDelegate::FolderAliasRole ) == folder->alias() ) {
// its the item to update!
break;
}
item = _model->item( ++row );
}
if( item ) {
folderToModelItem( item, folder );
} else {
// the dialog is not visible.
}
slotCheckConnection();
}
void StatusDialog::folderToModelItem( QStandardItem *item, Folder *f )
{
if( ! item || !f ) return;
item->setData( f->nativePath(), FolderViewDelegate::FolderPathRole );
item->setData( f->secondPath(), FolderViewDelegate::FolderSecondPathRole );
item->setData( f->alias(), FolderViewDelegate::FolderAliasRole );
item->setData( f->syncEnabled(), FolderViewDelegate::FolderSyncEnabled );
SyncResult res = f->syncResult();
SyncResult::Status status = res.status();
QString errors = res.errorStrings().join(QLatin1String("<br/>"));
item->setData( _theme->statusHeaderText( status ), Qt::ToolTipRole );
if( f->syncEnabled() ) {
item->setData( _theme->syncStateIcon( status ), FolderViewDelegate::FolderStatusIconRole );
} else {
item->setData( _theme->folderDisabledIcon( ), FolderViewDelegate::FolderStatusIconRole ); // size 48 before
}
item->setData( _theme->statusHeaderText( status ), FolderViewDelegate::FolderStatus );
item->setData( errors, FolderViewDelegate::FolderErrorMsg );
}
void StatusDialog::slotRemoveFolder()
{
QModelIndex selected = _folderList->selectionModel()->currentIndex();
if( selected.isValid() ) {
QString alias = _model->data( selected, FolderViewDelegate::FolderAliasRole ).toString();
qDebug() << "Remove Folder alias " << alias;
if( !alias.isEmpty() ) {
// remove from file system through folder man
emit(removeFolderAlias( alias ));
// _model->removeRow( selected.row() );
}
}
slotCheckConnection();
}
void StatusDialog::slotResetFolder()
{
QModelIndex selected = _folderList->selectionModel()->currentIndex();
if( selected.isValid() ) {
QString alias = _model->data( selected, FolderViewDelegate::FolderAliasRole ).toString();
emit(resetFolderAlias( alias ));
}
}
void StatusDialog::slotRemoveSelectedFolder()
{
QModelIndex selected = _folderList->selectionModel()->currentIndex();
if( selected.isValid() ) {
_model->removeRow( selected.row() );
}
buttonsSetEnabled();
slotCheckConnection();
}
void StatusDialog::slotEnableFolder()
{
QModelIndex selected = _folderList->selectionModel()->currentIndex();
if( selected.isValid() ) {
QString alias = _model->data( selected, FolderViewDelegate::FolderAliasRole ).toString();
bool folderEnabled = _model->data( selected, FolderViewDelegate::FolderSyncEnabled).toBool();
qDebug() << "Toggle enabled/disabled Folder alias " << alias << " - current state: " << folderEnabled;
if( !alias.isEmpty() ) {
emit(enableFolderAlias( alias, !folderEnabled ));
// set the button text accordingly.
slotFolderActivated( selected );
}
}
}
void StatusDialog::slotInfoFolder()
{
QModelIndex selected = _folderList->selectionModel()->currentIndex();
if( selected.isValid() ) {
QString alias = _model->data( selected, FolderViewDelegate::FolderAliasRole ).toString();
qDebug() << "Info Folder alias " << alias;
if( !alias.isEmpty() ) {
emit(infoFolderAlias( alias ));
}
}
}
void StatusDialog::slotAddSync()
{
qDebug() << "Add a sync requested.";
emit addASync();
}
void StatusDialog::slotCheckConnection()
{
if( ownCloudInfo::instance()->isConfigured() ) {
connect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),
this, SLOT(slotOCInfo( const QString&, const QString&, const QString&, const QString& )));
connect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotOCInfoFail(QNetworkReply*)));
_ocUrlLabel->setText( tr("Checking %1 connection...").arg(Theme::instance()->appNameGUI()));
qDebug() << "Check status.php from statusdialog.";
ownCloudInfo::instance()->checkInstallation();
} else {
// ownCloud is not yet configured.
_ocUrlLabel->setText( tr("No %1 connection configured.").arg(Theme::instance()->appNameGUI()));
_ButtonAdd->setEnabled( false);
}
}
void StatusDialog::slotOCInfo( const QString& url, const QString& versionStr, const QString& version, const QString& )
{
#ifdef Q_OS_WIN32
// work around a bug in QDesktopServices on Win32, see i-net
QString filePath = url;
if (filePath.startsWith("\\\\") || filePath.startsWith("//"))
_OCUrl.setUrl(QDir::toNativeSeparators(filePath));
else
_OCUrl = QUrl::fromLocalFile(filePath);
#else
_OCUrl = QUrl::fromLocalFile(url);
#endif
qDebug() << "#-------# oC found on " << url;
/* enable the open button */
MirallConfigFile cfg;
_ocUrlLabel->setOpenExternalLinks(true);
_ocUrlLabel->setText( tr("Connected to <a href=\"%1\">%1</a> as <i>%2</i>.")
.arg(url).arg( CredentialStore::instance()->user()) );
_ocUrlLabel->setToolTip( tr("Version: %1 (%2)").arg(versionStr).arg(version));
_ButtonAdd->setEnabled(true);
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),
this, SLOT(slotOCInfo( const QString&, const QString&, const QString&, const QString& )));
disconnect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotOCInfoFail(QNetworkReply*)));
}
void StatusDialog::slotOCInfoFail( QNetworkReply *reply)
{
QString errStr = tr("unknown problem.");
if( reply ) errStr = reply->errorString();
_ocUrlLabel->setText( tr("<p>Failed to connect to %1: <tt>%2</tt></p>").arg(Theme::instance()->appNameGUI()).arg(errStr) );
_ButtonAdd->setEnabled( false);
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(const QString&, const QString&, const QString&, const QString&)),
this, SLOT(slotOCInfo( const QString&, const QString&, const QString&, const QString& )));
disconnect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotOCInfoFail(QNetworkReply*)));
}
void StatusDialog::slotOpenOC()
{
if( _OCUrl.isValid() )
QDesktopServices::openUrl( _OCUrl );
}
/*
* in the show event, start a connection check to the ownCloud.
*/
void StatusDialog::showEvent ( QShowEvent *event )
{
QTimer::singleShot(0, this, SLOT(slotCheckConnection()));
QDialog::showEvent( event );
}
}

View file

@ -1,112 +0,0 @@
/*
* Copyright (C) by Klaas Freitag <freitag@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.
*/
#ifndef STATUSDIALOG_H
#define STATUSDIALOG_H
#include <QDialog>
#include <QStyledItemDelegate>
#include <QStandardItemModel>
#include <QUrl>
#include "ui_statusdialog.h"
#include "application.h"
namespace Mirall {
class Theme;
class ownCloudInfo;
class FolderStatusModel : public QStandardItemModel
{
public:
FolderStatusModel();
virtual Qt::ItemFlags flags( const QModelIndex& );
QVariant data(const QModelIndex &index, int role) const;
};
class FolderViewDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
FolderViewDelegate();
virtual ~FolderViewDelegate();
enum datarole { FolderAliasRole = Qt::UserRole + 100,
FolderPathRole,
FolderSecondPathRole,
FolderRemotePath,
FolderStatus,
FolderErrorMsg,
FolderSyncEnabled,
FolderStatusIconRole
};
void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const;
QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const;
bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option,
const QModelIndex& index );
};
class StatusDialog : public QDialog, protected Ui::statusDialog
{
Q_OBJECT
public:
explicit StatusDialog( Theme *theme, QWidget *parent = 0);
~StatusDialog();
void setFolderList( Folder::Map );
void buttonsSetEnabled();
signals:
void removeFolderAlias( const QString& );
void resetFolderAlias( const QString& );
void enableFolderAlias( const QString&, const bool );
void infoFolderAlias( const QString& );
void openFolderAlias( const QString& );
/* start the add a folder wizard. */
void addASync();
public slots:
void slotRemoveFolder();
void slotResetFolder();
void slotRemoveSelectedFolder();
void slotFolderActivated( const QModelIndex& );
void slotOpenOC();
void slotEnableFolder();
void slotInfoFolder();
void slotAddSync();
void slotAddFolder( Folder* );
void slotUpdateFolderState( Folder* );
void slotCheckConnection();
void slotOCInfoFail(QNetworkReply*);
void slotOCInfo( const QString&, const QString&, const QString&, const QString& );
void slotDoubleClicked( const QModelIndex& );
protected:
void showEvent ( QShowEvent* );
private:
void folderToModelItem( QStandardItem*, Folder* );
QStandardItemModel *_model;
FolderViewDelegate *_delegate;
QUrl _OCUrl;
Theme *_theme;
};
}
#endif // STATUSDIALOG_H

View file

@ -1,143 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>statusDialog</class>
<widget class="QWidget" name="statusDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>544</width>
<height>313</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Sync Directory Status</string>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListView" name="_folderList"/>
</item>
</layout>
</item>
<item row="1" column="1" colspan="2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="_ButtonAdd">
<property name="text">
<string>Add Sync...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_ButtonEnable">
<property name="text">
<string>Pause</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="_ButtonRemove">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_ButtonReset">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="_ButtonInfo">
<property name="text">
<string>Info...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0">
<item>
<widget class="QLabel" name="_ocUrlLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>255</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="2">
<widget class="QPushButton" name="_ButtonClose">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -113,14 +113,22 @@ QIcon Theme::themeIcon( const QString& name, bool sysTray ) const
foreach (int size, sizes) {
QString pixmapName = QString::fromLatin1(":/mirall/theme/%1/%2-%3.png").arg(flavor).arg(name).arg(size);
if (QFile::exists(pixmapName)) {
icon.addFile(pixmapName, QSize(size, size));
QPixmap px(pixmapName);
// HACK, get rid of it by supporting FDO icon themes, this is really just emulating ubuntu-mono
if (qgetenv("DESKTOP_SESSION") == "ubuntu") {
QBitmap mask = px.createMaskFromColor(Qt::white, Qt::MaskOutColor);
QPainter p(&px);
p.setPen(QColor("#dfdbd2"));
p.drawPixmap(px.rect(), mask, mask.rect());
}
icon.addPixmap(px);
}
}
if (icon.isNull()) {
foreach (int size, sizes) {
QString pixmapName = QString::fromLatin1(":/mirall/resources/%1-%2.png").arg(name).arg(size);
if (QFile::exists(pixmapName)) {
icon.addFile(pixmapName, QSize(size, size));
icon.addFile(pixmapName);
}
}
}
@ -152,6 +160,7 @@ QString Theme::defaultClientFolder() const
void Theme::setSystrayUseMonoIcons(bool mono)
{
_mono = mono;
emit systrayUseMonoIconsChanged(mono);
}
bool Theme::systrayUseMonoIcons() const

View file

@ -28,8 +28,9 @@ namespace Mirall {
class SyncResult;
class Theme
class Theme : public QObject
{
Q_OBJECT
public:
enum CustomMediaType {
oCSetupTop, // ownCloud connect page
@ -92,6 +93,11 @@ public:
*/
virtual bool singleSyncFolder() const;
/**
* URL to help file
*/
virtual QString helpUrl() const { return QString::null; }
/**
* Setting a value here will pre-define the server url.
*
@ -159,6 +165,9 @@ protected:
QIcon themeIcon(const QString& name, bool sysTray = false) const;
Theme() {}
signals:
void systrayUseMonoIconsChanged(bool);
private:
Theme(Theme const&);
Theme& operator=(Theme const&);

View file

@ -19,6 +19,7 @@
#include <QDir>
#include <QFile>
#include <QUrl>
#include <QWidget>
#include <QDebug>
@ -93,6 +94,23 @@ void Utility::setupFavLink(const QString &folder)
#endif
}
QString Utility::octetsToString( qint64 octets )
{
const qint64 kb = 1024;
const qint64 mb = 1024 * kb;
const qint64 gb = 1024 * mb;
if (octets >= gb) {
return QString::number(octets/gb) + QLatin1String(" GB");
} else if (octets >= mb) {
return QString::number(octets/mb) + QLatin1String(" MB");
} else if (octets >= kb) {
return QString::number(octets/kb) + QLatin1String(" KB");
} else {
return octets + QLatin1String(" bytes");
}
}
// Qtified version of get_platforms() in csync_owncloud.c
QString Utility::platform()
{
@ -125,4 +143,22 @@ QByteArray Utility::userAgentString()
.toLatin1();
}
void Utility::raiseDialog( QWidget *raiseWidget )
{
// viel hilft viel ;-)
if( raiseWidget ) {
#if defined(Q_WS_WIN) || defined (Q_OS_MAC)
Qt::WindowFlags eFlags = raiseWidget->windowFlags();
eFlags |= Qt::WindowStaysOnTopHint;
raiseWidget->setWindowFlags(eFlags);
raiseWidget->show();
eFlags &= ~Qt::WindowStaysOnTopHint;
raiseWidget->setWindowFlags(eFlags);
#endif
raiseWidget->show();
raiseWidget->raise();
raiseWidget->activateWindow();
}
}
} // namespace Mirall

View file

@ -17,17 +17,19 @@
#include <QString>
#include <QByteArray>
class QWidget;
namespace Mirall {
class Utility
namespace Utility
{
public:
static QString formatFingerprint( const QByteArray& );
static void setupFavLink( const QString &folder );
static QString platform();
static QByteArray userAgentString();
};
QString formatFingerprint( const QByteArray& );
void setupFavLink( const QString &folder );
QString octetsToString( qint64 octets );
QString platform();
QByteArray userAgentString();
void raiseDialog(QWidget *);
}
}
#endif // UTILITY_H