1 /***************************************************************************
2     This class manages the profiles that were defined by the user.
3                              -------------------
4     begin                : Mi Aug 06 2014
5     copyright            : (C) 2014-2019 by Alexander Reinholdt
6     email                : alexander.reinholdt@kdemail.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  *   This program is distributed in the hope that it will be useful, but   *
16  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
18  *   General Public License for more details.                              *
19  *                                                                         *
20  *   You should have received a copy of the GNU General Public License     *
21  *   along with this program; if not, write to the                         *
22  *   Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston,*
23  *   MA 02110-1335, USA                                                    *
24  ***************************************************************************/
25 
26 // application specific includes
27 #include "smb4kprofilemanager.h"
28 #include "smb4kprofilemanager_p.h"
29 #include "smb4ksettings.h"
30 #include "smb4khomesshareshandler.h"
31 #include "smb4kcustomoptionsmanager.h"
32 #include "smb4kbookmarkhandler.h"
33 
34 // Qt includes
35 #include <QPointer>
36 #include <QTest>
37 #include <QApplication>
38 
39 
40 Q_GLOBAL_STATIC(Smb4KProfileManagerStatic, p);
41 
42 
43 //
44 // NOTE: Do not invoke writeConfig() here, because this will/might
45 // trigger the configChanged() signal which can lead to unwanted
46 // effects.
47 //
48 
49 
Smb4KProfileManager(QObject * parent)50 Smb4KProfileManager::Smb4KProfileManager(QObject* parent)
51 : QObject(parent), d(new Smb4KProfileManagerPrivate)
52 {
53   d->useProfiles  = Smb4KSettings::useProfiles();
54 
55   if (d->useProfiles)
56   {
57     d->profiles = Smb4KSettings::profilesList();
58     d->activeProfile = !Smb4KSettings::activeProfile().isEmpty() ?
59                        Smb4KSettings::activeProfile() :
60                        d->profiles.first();
61   }
62   else
63   {
64     d->profiles.clear();
65     d->activeProfile.clear();
66   }
67 
68   connect(Smb4KSettings::self(), SIGNAL(configChanged()), this, SLOT(slotConfigChanged()));
69 }
70 
71 
~Smb4KProfileManager()72 Smb4KProfileManager::~Smb4KProfileManager()
73 {
74 }
75 
76 
self()77 Smb4KProfileManager* Smb4KProfileManager::self()
78 {
79   return &p->instance;
80 }
81 
82 
setActiveProfile(const QString & name)83 void Smb4KProfileManager::setActiveProfile(const QString& name)
84 {
85   //
86   // Check if the active profile is going to be changed. If so,
87   // notify the program so that things can be done before the
88   // profile is actually changed.
89   //
90   bool change = false;
91 
92   if (d->useProfiles)
93   {
94     if (name != d->activeProfile)
95     {
96       emit aboutToChangeProfile();
97       change = true;
98     }
99   }
100   else
101   {
102     if (!d->activeProfile.isEmpty())
103     {
104       emit aboutToChangeProfile();
105       change = true;
106     }
107   }
108 
109   //
110   // Now change the profile
111   //
112   if (change)
113   {
114     d->activeProfile = d->useProfiles ? name : QString();
115     Smb4KSettings::setActiveProfile(d->activeProfile);
116     emit activeProfileChanged(d->activeProfile);
117   }
118 }
119 
120 
activeProfile() const121 QString Smb4KProfileManager::activeProfile() const
122 {
123   return d->activeProfile;
124 }
125 
126 
profilesList() const127 QStringList Smb4KProfileManager::profilesList() const
128 {
129   return d->useProfiles ? d->profiles : QStringList();
130 }
131 
132 
useProfiles() const133 bool Smb4KProfileManager::useProfiles() const
134 {
135   return d->useProfiles;
136 }
137 
138 
migrateProfile(const QString & from,const QString & to)139 void Smb4KProfileManager::migrateProfile(const QString& from, const QString& to)
140 {
141   QList<QPair<QString,QString>> list;
142   list << QPair<QString,QString>(from, to);
143   migrateProfiles(list);
144 }
145 
146 
migrateProfiles(const QList<QPair<QString,QString>> & list)147 void Smb4KProfileManager::migrateProfiles(const QList<QPair<QString,QString>>& list)
148 {
149   if (d->useProfiles || (list.size() == 1 && list.first().second.isEmpty()))
150   {
151     for (int i = 0; i < list.size(); ++i)
152     {
153       QString from = list.at(i).first;
154       QString to = list.at(i).second;
155 
156       if (!to.isEmpty())
157       {
158         // Migrate one/the default profile to another one.
159         // First exchange the old profile.
160         for (int j = 0; j < d->profiles.size(); ++j)
161         {
162           if (QString::compare(from, d->profiles.at(j), Qt::CaseSensitive) == 0)
163           {
164             d->profiles.replace(j, to);
165             break;
166           }
167         }
168 
169         // Migrate profiles.
170         Smb4KBookmarkHandler::self()->migrateProfile(from, to);
171         Smb4KCustomOptionsManager::self()->migrateProfile(from, to);
172         Smb4KHomesSharesHandler::self()->migrateProfile(from, to);
173         emit migratedProfile(from, to);
174 
175         // In case the active profile was modified, rename it according
176         // the value passed.
177         if (QString::compare(from, d->activeProfile, Qt::CaseSensitive) == 0)
178         {
179           setActiveProfile(to);
180         }
181       }
182       else
183       {
184         // Migrate all profiles to the default one.
185         for (int j = 0; j < d->profiles.size(); ++j)
186         {
187           Smb4KBookmarkHandler::self()->migrateProfile(d->profiles.at(j), to);
188           Smb4KCustomOptionsManager::self()->migrateProfile(d->profiles.at(j), to);
189           Smb4KHomesSharesHandler::self()->migrateProfile(d->profiles.at(j), to);
190           emit migratedProfile(d->profiles.at(i), to);
191         }
192       }
193     }
194 
195     Smb4KSettings::setProfilesList(d->profiles);
196     emit profilesListChanged(d->profiles);
197   }
198 }
199 
200 
removeProfile(const QString & name)201 void Smb4KProfileManager::removeProfile(const QString& name)
202 {
203   QStringList list;
204   list << name;
205   removeProfiles(list);
206 }
207 
208 
removeProfiles(const QStringList & list)209 void Smb4KProfileManager::removeProfiles(const QStringList& list)
210 {
211   if (d->useProfiles)
212   {
213     for (int i = 0; i < list.size(); ++i)
214     {
215       QString name = list.at(i);
216 
217       // First remove the profile from the list.
218       QMutableStringListIterator it(d->profiles);
219 
220       while (it.hasNext())
221       {
222         QString entry = it.next();
223 
224         if (QString::compare(name, entry, Qt::CaseSensitive) == 0)
225         {
226           it.remove();
227           break;
228         }
229       }
230 
231       if (!d->profiles.isEmpty())
232       {
233         // Ask the user if he/she wants to migrate the entries
234         // of the removed profile to another one.
235         if (Smb4KSettings::useMigrationAssistant())
236         {
237           QPointer<Smb4KProfileMigrationDialog> dlg = new Smb4KProfileMigrationDialog(QStringList(name), d->profiles, QApplication::activeWindow());
238 
239           if (dlg->exec() == QDialog::Accepted)
240           {
241             migrateProfile(dlg->from(), dlg->to());
242           }
243 
244           delete dlg;
245         }
246       }
247 
248       // Remove the profile.
249       Smb4KBookmarkHandler::self()->removeProfile(name);
250       Smb4KCustomOptionsManager::self()->removeProfile(name);
251       Smb4KHomesSharesHandler::self()->removeProfile(name);
252       emit removedProfile(name);
253 
254       // Set a new active profile if the user removed the current one.
255       if (QString::compare(name, d->activeProfile, Qt::CaseSensitive) == 0)
256       {
257         setActiveProfile(!d->profiles.isEmpty() ? d->profiles.first() : QString());
258       }
259     }
260 
261     Smb4KSettings::setProfilesList(d->profiles);
262     emit profilesListChanged(d->profiles);
263   }
264 }
265 
266 
slotConfigChanged()267 void Smb4KProfileManager::slotConfigChanged()
268 {
269   bool usageChanged = false;
270 
271   //
272   // Check if the usage of profiles changed
273   //
274   if (d->useProfiles != Smb4KSettings::useProfiles())
275   {
276     d->useProfiles = Smb4KSettings::useProfiles();
277     emit profileUsageChanged(d->useProfiles);
278     usageChanged = true;
279   }
280 
281   //
282   // Updated the list of profiles
283   //
284   if (d->profiles != Smb4KSettings::profilesList())
285   {
286     d->profiles = Smb4KSettings::profilesList();
287     emit profilesListChanged(d->profiles);
288   }
289 
290   //
291   // Migrate profiles.
292   // Profiles are only migrated, if the usage changed and the
293   // user chose to use the migration assistant.
294   //
295   if (usageChanged && Smb4KSettings::useMigrationAssistant())
296   {
297     QStringList from, to;
298 
299     if (d->useProfiles)
300     {
301       // Since the setting changed, the use of profiles was
302       // switched off before. So, ask the user if he/she wants
303       // to migrate the default profile to any other one.
304       // Therefore, from needs to get one empty entry (default
305       // profile) and to has to be d->profiles.
306       from << QString();
307       to << d->profiles;
308     }
309     else
310     {
311       // Here it is vice versa: Ask the user if he/she wants to
312       // migrate all profiles to the default profile. Therefore,
313       // set from to d->profiles and to to empty.
314       from << d->profiles;
315       to << QString();
316     }
317 
318     // Now, launch the migration dialog.
319     QPointer<Smb4KProfileMigrationDialog> dlg = new Smb4KProfileMigrationDialog(from, to, QApplication::activeWindow());
320 
321     if (dlg->exec() == QDialog::Accepted)
322     {
323       migrateProfile(dlg->from(), dlg->to());
324     }
325 
326     delete dlg;
327   }
328 
329   //
330   // Set the active profile
331   //
332   if (!Smb4KSettings::activeProfile().isEmpty() && d->profiles.contains(Smb4KSettings::activeProfile()))
333   {
334     setActiveProfile(Smb4KSettings::activeProfile());
335   }
336   else
337   {
338     setActiveProfile(d->profiles.first());
339   }
340 }
341 
342