3 * Copyright (C) 2004 Frans Englich <frans.englich@telia.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
19 * Please see the README
25 #include <QtGui/QLayout>
26 #include <QtGui/QLabel>
27 #include <QtGui/QLineEdit>
28 #include <QtCore/QEvent>
29 #include <QtGui/QPixmap>
30 #include <QtCore/QStringList>
31 #include <QtGui/QDragEnterEvent>
33 #include <kpushbutton.h>
35 #include <kpassworddialog.h>
39 #include <kmimetype.h>
40 #include <kstandarddirs.h>
41 #include <kaboutdata.h>
42 #include <kmessagebox.h>
44 #include <kio/netaccess.h>
49 #include "chfnprocess.h"
50 #include <KPluginFactory>
51 #include <KPluginLoader>
53 K_PLUGIN_FACTORY(Factory
,
54 registerPlugin
<KCMUserAccount
>();
56 K_EXPORT_PLUGIN(Factory("useraccount"))
58 KCMUserAccount::KCMUserAccount( QWidget
*parent
, const QVariantList
&)
59 : KCModule( Factory::componentData(), parent
)
61 QVBoxLayout
*topLayout
= new QVBoxLayout(this);
62 topLayout
->setSpacing(KDialog::spacingHint());
63 topLayout
->setMargin(0);
65 _mw
= new MainWidget(this);
66 topLayout
->addWidget( _mw
);
68 connect( _mw
->btnChangeFace
, SIGNAL(clicked()), SLOT(slotFaceButtonClicked()));
69 connect( _mw
->btnChangePassword
, SIGNAL(clicked()), SLOT(slotChangePassword()));
70 _mw
->btnChangePassword
->setGuiItem( KGuiItem( i18n("Change &Password..."), "preferences-desktop-user-password" ));
72 connect( _mw
->leRealname
, SIGNAL(textChanged(const QString
&)), SLOT(changed()));
73 connect( _mw
->leOrganization
, SIGNAL(textChanged(const QString
&)), SLOT(changed()));
74 connect( _mw
->leEmail
, SIGNAL(textChanged(const QString
&)), SLOT(changed()));
75 connect( _mw
->leSMTP
, SIGNAL(textChanged(const QString
&)), SLOT(changed()));
78 _kes
= new KEMailSettings();
80 _mw
->lblUsername
->setText( _ku
->loginName() );
81 _mw
->lblUID
->setText( QString().number(_ku
->uid()) );
83 KAboutData
*about
= new KAboutData("kcm_useraccount", 0,
84 ki18n("Password & User Information"), 0, KLocalizedString(),
85 KAboutData::License_GPL
,
86 ki18n("(C) 2002, Braden MacDonald, "
87 "(C) 2004 Ravikiran Rajagopal"));
89 about
->addAuthor(ki18n("Frans Englich"), ki18n("Maintainer"), "frans.englich@telia.com");
90 about
->addAuthor(ki18n("Ravikiran Rajagopal"), KLocalizedString(), "ravi@kde.org");
91 about
->addAuthor(ki18n("Michael H\303\244ckel"), KLocalizedString(), "haeckel@kde.org" );
93 about
->addAuthor(ki18n("Braden MacDonald"), ki18n("Face editor"), "bradenm_k@shaw.ca");
94 about
->addAuthor(ki18n("Geert Jansen"), ki18n("Password changer"), "jansen@kde.org",
95 "http://www.stack.nl/~geertj/");
96 about
->addAuthor(ki18n("Daniel Molkentin"));
97 about
->addAuthor(ki18n("Alex Zepeda"));
98 about
->addAuthor(ki18n("Hans Karlsson"), ki18n("Icons"), "karlsson.h@home.se");
99 about
->addAuthor(ki18n("Hermann Thomas"), ki18n("Icons"), "h.thomas@gmx.de");
102 setQuickHelp( i18n("<qt>Here you can change your personal information, which "
103 "will be used in mail programs and word processors, for example. You can "
104 "change your login password by clicking <em>Change Password...</em>.</qt>") );
106 addConfig( KCFGPassword::self(), this );
110 void KCMUserAccount::slotChangePassword()
112 QString bin
= KGlobal::dirs()->findExe("kdepasswd");
115 kDebug() << "kcm_useraccount: kdepasswd was not found.";
116 KMessageBox::sorry ( this, i18n( "A program error occurred: the internal "
117 "program 'kdepasswd' could not be found. You will "
118 "not be able to change your password."));
120 _mw
->btnChangePassword
->setEnabled(false);
124 lst
<< _ku
->loginName();
125 QProcess::startDetached(bin
,lst
);
130 KCMUserAccount::~KCMUserAccount()
136 void KCMUserAccount::load()
138 _mw
->lblUsername
->setText(_ku
->loginName());
140 _kes
->setProfile(_kes
->defaultProfileName());
142 _mw
->leRealname
->setText( _kes
->getSetting( KEMailSettings::RealName
));
143 _mw
->leEmail
->setText( _kes
->getSetting( KEMailSettings::EmailAddress
));
144 _mw
->leOrganization
->setText( _kes
->getSetting( KEMailSettings::Organization
));
145 _mw
->leSMTP
->setText( _kes
->getSetting( KEMailSettings::OutServer
));
147 QString _userPicsDir
= KCFGUserAccount::faceDir() +
148 KGlobal::dirs()->resourceDirs("data").last() + "kdm/faces/";
150 QString fs
= KCFGUserAccount::faceSource();
151 if (fs
== QLatin1String("UserOnly"))
152 _facePerm
= userOnly
;
153 else if (fs
== QLatin1String("PreferUser"))
154 _facePerm
= userFirst
;
155 else if (fs
== QLatin1String("PreferAdmin"))
156 _facePerm
= adminFirst
;
158 _facePerm
= adminOnly
; // Admin Only
160 if ( _facePerm
== adminFirst
)
161 { // If the administrator's choice takes preference
162 _facePixmap
= QPixmap( _userPicsDir
+ _ku
->loginName() + ".face.icon" );
164 if ( _facePixmap
.isNull() )
165 _facePerm
= userFirst
;
167 _mw
->btnChangeFace
->setIcon( KIcon(_facePixmap
) );
170 if ( _facePerm
>= userFirst
)
172 // If the user's choice takes preference
173 _facePixmap
= QPixmap( KCFGUserAccount::faceFile() );
175 // The user has no face, should we check for the admin's setting?
176 if ( _facePixmap
.isNull() && _facePerm
== userFirst
)
177 _facePixmap
= QPixmap( _userPicsDir
+ _ku
->loginName() + ".face.icon" );
179 if ( _facePixmap
.isNull() )
180 _facePixmap
= QPixmap( _userPicsDir
+ KCFGUserAccount::defaultFile() );
182 _mw
->btnChangeFace
->setIcon( KIcon(_facePixmap
) );
184 else if ( _facePerm
<= adminOnly
)
187 _facePixmap
= QPixmap( _userPicsDir
+ _ku
->loginName() + ".face.icon" );
188 if ( _facePixmap
.isNull() )
189 _facePixmap
= QPixmap( _userPicsDir
+ KCFGUserAccount::defaultFile() );
190 _mw
->btnChangeFace
->setIcon( KIcon(_facePixmap
) );
193 if (!_facePixmap
.isNull()) {
194 _mw
->btnChangeFace
->setIconSize(_facePixmap
.size());
197 KCModule::load(); /* KConfigXT */
201 void KCMUserAccount::save()
203 KCModule::save(); /* KConfigXT */
205 /* Save KDE's homebrewn settings */
206 _kes
->setSetting( KEMailSettings::RealName
, _mw
->leRealname
->text() );
207 _kes
->setSetting( KEMailSettings::EmailAddress
, _mw
->leEmail
->text() );
208 _kes
->setSetting( KEMailSettings::Organization
, _mw
->leOrganization
->text() );
209 _kes
->setSetting( KEMailSettings::OutServer
, _mw
->leSMTP
->text() );
211 /* Save realname to /etc/passwd */
212 if ( _mw
->leRealname
->isModified() )
214 KPasswordDialog
dlg( _mw
);
215 dlg
.setPrompt(i18n("Please enter your password in order to save your settings:"));
218 KMessageBox::sorry( this, i18n("You must enter "
219 "your password in order to change your information."));
223 ChfnProcess
*proc
= new ChfnProcess();
224 int ret
= proc
->exec(dlg
.password().toAscii() , _mw
->leRealname
->text().toAscii() );
227 if ( ret
== ChfnProcess::PasswordError
)
228 KMessageBox::sorry( this, i18n("You must enter a correct password."));
232 KMessageBox::sorry( this, i18n("An error occurred and your password has "
233 "probably not been changed. The error "
234 "message was:\n%1", QString::fromLocal8Bit(proc
->error())));
235 kDebug() << "ChfnProcess->exec() failed. Error code: " << ret
236 << "\nOutput:" << proc
->error() << endl
;
244 if( !_facePixmap
.isNull() ) {
245 if( !_facePixmap
.save( KCFGUserAccount::faceFile(), "PNG" ))
246 KMessageBox::error( this, i18n("There was an error saving the image: %1" ,
247 KCFGUserAccount::faceFile()) );
252 void KCMUserAccount::changeFace(const QPixmap
&pix
)
254 if ( _facePerm
< userFirst
)
255 return; // If the user isn't allowed to change their face, don't!
257 if ( pix
.isNull() ) {
258 KMessageBox::sorry( this, i18n("There was an error loading the image.") );
263 _mw
->btnChangeFace
->setIcon( KIcon(_facePixmap
) );
264 _mw
->btnChangeFace
->setIconSize(_facePixmap
.size());
265 emit
changed( true );
268 void KCMUserAccount::slotFaceButtonClicked()
270 if ( _facePerm
< userFirst
)
272 KMessageBox::sorry( this, i18n("Your administrator has disallowed changing your image.") );
276 ChFaceDlg
* pDlg
= new ChFaceDlg( KGlobal::dirs()->resourceDirs("data").last() +
277 "/kdm/pics/users/", this );
279 if ( pDlg
->exec() == QDialog::Accepted
&& !pDlg
->getFaceImage().isNull() )
280 changeFace( pDlg
->getFaceImage() );
286 * I merged faceButtonDropEvent into this /Frans
287 * The function was called after checking event type and
288 * the code is now below that if statement
290 bool KCMUserAccount::eventFilter(QObject
*, QEvent
*e
)
292 if (e
->type() == QEvent::DragEnter
)
294 QDragEnterEvent
*ee
= (QDragEnterEvent
*) e
;
295 if (!KUrl::List::fromMimeData( ee
->mimeData() ).isEmpty())
302 if (e
->type() == QEvent::Drop
)
304 if ( _facePerm
< userFirst
)
306 KMessageBox::sorry( this, i18n("Your administrator "
307 "has disallowed changing your image.") );
311 KUrl
*url
= decodeImgDrop( (QDropEvent
*) e
, this);
315 KIO::NetAccess::download(*url
, pixPath
, this);
316 changeFace( QPixmap( pixPath
) );
317 KIO::NetAccess::removeTempFile(pixPath
);
325 inline KUrl
*KCMUserAccount::decodeImgDrop(QDropEvent
*e
, QWidget
*wdg
)
327 KUrl::List uris
= KUrl::List::fromMimeData(e
->mimeData());
330 KUrl
*url
= new KUrl(uris
.first());
332 KMimeType::Ptr mime
= KMimeType::findByUrl( *url
);
333 if ( mime
&& KImageIO::isSupported( mime
->name(), KImageIO::Reading
) )
336 QStringList qs
= KImageIO::pattern().split( '\n');
337 qs
.erase(qs
.begin());
339 QString msg
= i18n( "%1 does not appear to be an image file.\n"
340 "Please use files with these extensions:\n"
341 "%2", url
->fileName(), qs
.join("\n"));
342 KMessageBox::sorry( wdg
, msg
);