1/*
2 Copyright (c) 2009 Volker Krause <vkrause@kde.org>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "setupmanager.h"
21#include "resource.h"
22#include "setuppage.h"
23#include "transport.h"
24#include "configfile.h"
25#include "ldap.h"
26#include "identity.h"
27
28#include <kemailsettings.h>
29#include <kwallet.h>
30
31SetupManager::SetupManager( QWidget* parent) :
32 QObject(parent),
33 m_currentSetupObject( 0 ),
34 m_page( 0 ),
35 m_wallet( 0 ),
36 m_personalDataAvailable( false ),
37 m_rollbackRequested( false )
38{
39 KEMailSettings e;
40 m_name = e.getSetting( KEMailSettings::RealName );
41 m_email = e.getSetting( KEMailSettings::EmailAddress );
42}
43
44SetupManager::~SetupManager()
45{
46 delete m_wallet;
47}
48
49void SetupManager::setSetupPage(SetupPage* page)
50{
51 m_page = page;
52}
53
54QObject* SetupManager::createResource(const QString& type)
55{
56 return connectObject( new Resource( type, this ) );
57}
58
59QObject* SetupManager::createTransport(const QString& type)
60{
61 return connectObject( new Transport( type, this ) );
62}
63
64QObject* SetupManager::createConfigFile(const QString& fileName)
65{
66 return connectObject( new ConfigFile( fileName, this ) );
67}
68
69QObject* SetupManager::createLdap()
70{
71 return connectObject( new Ldap( this ) );
72}
73
74
75QObject* SetupManager::createIdentity()
76{
77 return connectObject( new Identity( this ) );
78}
79
80static bool dependencyCompare( SetupObject *left, SetupObject *right )
81{
82 if ( !left->dependsOn() && right->dependsOn() )
83 return true;
84 return false;
85}
86
87void SetupManager::execute()
88{
89 m_page->setStatus( i18n( "Setting up account..." ) );
90 m_page->setValid( false );
91
92 // ### FIXME this is a bad over-simplification and would need a real topological sort
93 // but for current usage it is good enough
94 qStableSort( m_objectToSetup.begin(), m_objectToSetup.end(), dependencyCompare );
95 setupNext();
96}
97
98void SetupManager::setupSucceeded(const QString& msg)
99{
100 Q_ASSERT( m_page );
101 m_page->addMessage( SetupPage::Success, msg );
102 if(m_currentSetupObject) {
103 m_setupObjects.append( m_currentSetupObject );
104 m_currentSetupObject = 0;
105 }
106 setupNext();
107}
108
109void SetupManager::setupFailed(const QString& msg)
110{
111 Q_ASSERT( m_page );
112 m_page->addMessage( SetupPage::Error, msg );
113 if( m_currentSetupObject ) {
114 m_setupObjects.append( m_currentSetupObject );
115 m_currentSetupObject = 0;
116 }
117 rollback();
118}
119
120void SetupManager::setupInfo(const QString& msg)
121{
122 Q_ASSERT( m_page );
123 m_page->addMessage( SetupPage::Info, msg );
124}
125
126void SetupManager::setupNext()
127{
128 // user canceld during the previous setup step
129 if ( m_rollbackRequested ) {
130 rollback();
131 return;
132 }
133
134 if ( m_objectToSetup.isEmpty() ) {
135 m_page->setStatus( i18n( "Setup complete." ) );
136 m_page->setProgress( 100 );
137 m_page->setValid( true );
138 } else {
139 const int setupObjectCount = m_objectToSetup.size() + m_setupObjects.size();
140 const int remainingObjectCount = setupObjectCount - m_objectToSetup.size();
141 m_page->setProgress( ( remainingObjectCount * 100 ) / setupObjectCount );
142 m_currentSetupObject = m_objectToSetup.takeFirst();
143 m_currentSetupObject->create();
144 }
145}
146
147void SetupManager::rollback()
148{
149 m_page->setStatus( i18n( "Failed to set up account, rolling back..." ) );
150 const int setupObjectCount = m_objectToSetup.size() + m_setupObjects.size();
151 int remainingObjectCount = m_setupObjects.size();
152 foreach ( SetupObject* obj, m_setupObjects ) {
153 m_page->setProgress( ( remainingObjectCount * 100 ) / setupObjectCount );
154 if( obj ) {
155 obj->destroy();
156 m_objectToSetup.prepend( obj );
157 }
158 }
159 m_setupObjects.clear();
160 m_page->setProgress( 0 );
161 m_page->setStatus( i18n( "Failed to set up account." ) );
162 m_page->setValid( true );
163 m_rollbackRequested = false;
164 emit rollbackComplete();
165}
166
167SetupObject* SetupManager::connectObject(SetupObject* obj)
168{
169 connect( obj, SIGNAL(finished(QString)), SLOT(setupSucceeded(QString)) );
170 connect( obj, SIGNAL(info(QString)), SLOT(setupInfo(QString)) );
171 connect( obj, SIGNAL(error(QString)), SLOT(setupFailed(QString)) );
172 m_objectToSetup.append( obj );
173 return obj;
174}
175
176void SetupManager::setName( const QString& name )
177{
178 m_name = name;
179}
180
181QString SetupManager::name()
182{
183 return m_name;
184}
185
186void SetupManager::setEmail( const QString& email)
187{
188 m_email = email;
189}
190
191QString SetupManager::email()
192{
193 return m_email;
194}
195
196void SetupManager::setPassword( const QString& password)
197{
198 m_password = password;
199}
200
201QString SetupManager::password()
202{
203 return m_password;
204}
205
206QString SetupManager::country()
207{
208 return KGlobal::locale()->country();
209}
210
211void SetupManager::openWallet()
212{
213 using namespace KWallet;
214 if ( Wallet::isOpen( Wallet::NetworkWallet() ) )
215 return;
216
217 Q_ASSERT( parent()->isWidgetType() );
218 m_wallet = Wallet::openWallet( Wallet::NetworkWallet(), qobject_cast<QWidget*>( parent() )->effectiveWinId(), Wallet::Asynchronous );
219 QEventLoop loop;
220 connect( m_wallet, SIGNAL(walletOpened(bool)), &loop, SLOT(quit()) );
221 loop.exec();
222}
223
224bool SetupManager::personalDataAvailable()
225{
226 return m_personalDataAvailable;
227}
228
229void SetupManager::setPersonalDataAvailable(bool available)
230{
231 m_personalDataAvailable = available;
232}
233
234void SetupManager::requestRollback()
235{
236 if ( m_setupObjects.isEmpty() ) {
237 emit rollbackComplete();
238 } else {
239 m_rollbackRequested = true;
240 if ( !m_currentSetupObject )
241 rollback();
242 }
243}
244
245
246