summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2025-09-30 16:55:23 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2025-10-05 17:07:05 -0500
commit15de3774dcbcdc2913a5e334a47bc169e877902e (patch)
tree1875da20c3b8d73c6995aff40f36c8de3fd4837d
parent270b1b4accb42c6345b5544f0cae32ac3c1aa67b (diff)
downloadkcmldapmanager-15de3774dcbcdc2913a5e334a47bc169e877902e.tar.gz
kcmldapmanager-15de3774dcbcdc2913a5e334a47bc169e877902e.zip
Add ability to set user profile avatars
Signed-off-by: Timothy Pearson <kb9vqf@pearsoncomputing.net>
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/chfacedlg.cpp59
-rw-r--r--src/chfacedlg.h3
-rw-r--r--src/userconfigbase.ui80
-rw-r--r--src/userconfigdlg.cpp58
-rw-r--r--src/userconfigdlg.h5
6 files changed, 153 insertions, 53 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index dd9b197..734f12d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -29,6 +29,7 @@ tde_add_kpart( kcm_ldapmanager AUTOMOC
groupconfigdlg.cpp
machineconfigdlg.cpp
serviceconfigdlg.cpp
+ chfacedlg.cpp
LINK
tdeio-shared
tdeui-shared
diff --git a/src/chfacedlg.cpp b/src/chfacedlg.cpp
index bea316c..1b1293a 100644
--- a/src/chfacedlg.cpp
+++ b/src/chfacedlg.cpp
@@ -41,11 +41,9 @@
#include <kimagefilepreview.h>
#include <kimageio.h>
#include <tdemessagebox.h>
-#include <konq_operations.h>
#include <kurl.h>
#include "chfacedlg.h"
-#include "settings.h" // TDEConfigXT
@@ -55,6 +53,9 @@
ChFaceDlg::ChFaceDlg(const TQString& picsdir, TQWidget *parent, const char *name, bool modal)
: KDialogBase( parent, name, modal, i18n("Change your Face"), Ok|Cancel, Ok, true )
{
+ // Global settings
+ m_maxFaceSize = 64;
+
TQWidget *page = new TQWidget(this);
setMainWidget( page );
@@ -95,15 +96,6 @@ ChFaceDlg::ChFaceDlg(const TQString& picsdir, TQWidget *parent, const char *name
for ( TQStringList::Iterator it = picslist.begin(); it != picslist.end(); ++it )
new TQIconViewItem( m_FacesWidget, (*it).section(".",0,0), TQPixmap( picsdir + *it ) );
}
- facesDir.setPath( KCFGUserAccount::userFaceDir() );
- if ( facesDir.exists() )
- {
- TQStringList picslist = facesDir.entryList( TQDir::Files );
- for ( TQStringList::Iterator it = picslist.begin(); it != picslist.end(); ++it )
- new TQIconViewItem( m_FacesWidget, "/"+(*it) == KCFGUserAccount::customFaceFile() ?
- i18n("(Custom)") : (*it).section(".",0,0),
- TQPixmap( KCFGUserAccount::userFaceDir() + *it ) );
- }
m_FacesWidget->setResizeMode( TQIconView::Adjust );
//m_FacesWidget->setGridX( FACE_PIX_SIZE - 10 );
@@ -115,7 +107,7 @@ ChFaceDlg::ChFaceDlg(const TQString& picsdir, TQWidget *parent, const char *name
resize( 420, 400 );
}
-void ChFaceDlg::addCustomPixmap( TQString imPath, bool saveCopy )
+void ChFaceDlg::addCustomPixmap( TQString imPath )
{
TQImage pix( imPath );
// TODO: save pix to TMPDIR/userinfo-tmp,
@@ -126,37 +118,19 @@ void ChFaceDlg::addCustomPixmap( TQString imPath, bool saveCopy )
KMessageBox::sorry( this, i18n("There was an error loading the image.") );
return;
}
- if ( (pix.width() > KCFGUserAccount::faceSize())
- || (pix.height() > KCFGUserAccount::faceSize()) )
- pix = pix.scale( KCFGUserAccount::faceSize(), KCFGUserAccount::faceSize(), TQImage::ScaleMin );// Should be no bigger than certain size.
-
- if ( saveCopy )
- {
- // If we should save a copy:
- TQDir userfaces( KCFGUserAccount::userFaceDir() );
- if ( !userfaces.exists( ) )
- userfaces.mkdir( userfaces.absPath() );
-
- pix.save( userfaces.absPath() + "/.userinfo-tmp" , "PNG" );
- KonqOperations::copy( this, KonqOperations::COPY, KURL::List( KURL( userfaces.absPath() + "/.userinfo-tmp" ) ), KURL( userfaces.absPath() + "/" + TQFileInfo(imPath).fileName().section(".",0,0) ) );
-#if 0
- if ( !pix.save( userfaces.absPath() + "/" + imPath , "PNG" ) )
- KMessageBox::sorry(this, i18n("There was an error saving the image:\n%1").arg( userfaces.absPath() ) );
-#endif
- }
+ if ( (pix.width() > m_maxFaceSize)
+ || (pix.height() > m_maxFaceSize) )
+ pix = pix.scale( m_maxFaceSize, m_maxFaceSize, TQImage::ScaleMin );// Should be no bigger than certain size.
TQIconViewItem* newface = new TQIconViewItem( m_FacesWidget, TQFileInfo(imPath).fileName().section(".",0,0) , pix );
- newface->setKey( KCFGUserAccount::customKey() );// Add custom items to end
m_FacesWidget->ensureItemVisible( newface );
m_FacesWidget->setCurrentItem( newface );
}
void ChFaceDlg::slotGetCustomImage( )
{
- TQCheckBox* checkWidget = new TQCheckBox( i18n("&Save copy in custom faces folder for future use"), 0 );
-
KFileDialog *dlg = new KFileDialog( TQDir::homeDirPath(), KImageIO::pattern( KImageIO::Reading ),
- this, 0, true, checkWidget);
+ this, 0, true);
dlg->setOperationMode( KFileDialog::Opening );
dlg->setCaption( i18n("Choose Image") );
@@ -165,24 +139,9 @@ void ChFaceDlg::slotGetCustomImage( )
KImageFilePreview *ip = new KImageFilePreview( dlg );
dlg->setPreviewWidget( ip );
if (dlg->exec() == TQDialog::Accepted)
- addCustomPixmap( dlg->selectedFile(), checkWidget->isChecked() );
+ addCustomPixmap( dlg->selectedFile() );
// Because we give it a parent we have to close it ourselves.
dlg->close(true);
}
-#if 0
-void ChFaceDlg::slotSaveCustomImage()
-{
- if ( m_FacesWidget->currentItem()->key() == USER_CUSTOM_KEY)
- {
- TQDir userfaces( TQDir::homeDirPath() + USER_FACES_DIR );
- if ( !userfaces.exists( ) )
- userfaces.mkdir( userfaces.absPath() );
-
- if ( !m_FacesWidget->currentItem()->pixmap()->save( userfaces.absPath() + USER_CUSTOM_FILE , "PNG" ) )
- KMessageBox::sorry(this, i18n("There was an error saving the image:\n%1").arg( userfaces.absPath() ) );
- }
-}
-#endif
-
#include "chfacedlg.moc"
diff --git a/src/chfacedlg.h b/src/chfacedlg.h
index 6ae6a1c..6fafce9 100644
--- a/src/chfacedlg.h
+++ b/src/chfacedlg.h
@@ -61,8 +61,9 @@ private slots:
//void slotSaveCustomImage();
private:
- void addCustomPixmap( TQString imPath, bool saveCopy );
+ void addCustomPixmap( TQString imPath );
+ int m_maxFaceSize;
TDEIconView *m_FacesWidget;
};
diff --git a/src/userconfigbase.ui b/src/userconfigbase.ui
index 7840f46..9e11934 100644
--- a/src/userconfigbase.ui
+++ b/src/userconfigbase.ui
@@ -439,7 +439,83 @@
<cstring>email</cstring>
</property>
</widget>
- <spacer row="10" column="0">
+ <widget class="TQFrame" row="10" column="0" colspan="5">
+ <property name="name">
+ <cstring>unnamed_separator</cstring>
+ </property>
+ <property name="name">
+ <cstring>unnamed_separator</cstring>
+ </property>
+ <property name="minimumHeight">
+ <number>25</number>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="11" column="0" colspan="2">
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="text">
+ <string>Profile Avatar</string>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="11" column="2" colspan="3">
+ <property name="name">
+ <cstring>changeAvatar</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>74</width>
+ <height>74</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>74</width>
+ <height>74</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+
+ <widget class="KPushButton" row="12" column="2" colspan="3">
+ <property name="name">
+ <cstring>clearAvatar</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ <spacer row="13" column="0">
<property name="name" stdset="0">
<cstring>Spacer20</cstring>
</property>
@@ -1070,4 +1146,4 @@
</includes>
<layoutdefaults spacing="3" margin="6"/>
<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
-</UI> \ No newline at end of file
+</UI>
diff --git a/src/userconfigdlg.cpp b/src/userconfigdlg.cpp
index 32fad5f..b731f13 100644
--- a/src/userconfigdlg.cpp
+++ b/src/userconfigdlg.cpp
@@ -41,10 +41,12 @@
#include <kdatetimewidget.h>
#include <kpassdlg.h>
#include <kiconloader.h>
+#include <kmdcodec.h>
#include <ksslcertificate.h>
#include "ldapmgr.h"
#include "userconfigdlg.h"
+#include "chfacedlg.h"
UserConfigDialog::UserConfigDialog(LDAPUserInfo user, LDAPConfig* parent, const char* name)
: KDialogBase(parent, name, true, i18n("LDAP User Properties"), Ok|Cancel, Ok, true), m_user(user), m_ldapconfig(parent)
@@ -77,6 +79,8 @@ UserConfigDialog::UserConfigDialog(LDAPUserInfo user, LDAPConfig* parent, const
connect(m_base->passwordExpireDisabled, TQ_SIGNAL(clicked()), this, TQ_SLOT(processLockouts()));
connect(m_base->requirePasswordAging, TQ_SIGNAL(clicked()), this, TQ_SLOT(processLockouts()));
connect(m_base->requirePasswordMinAge, TQ_SIGNAL(clicked()), this, TQ_SLOT(processLockouts()));
+ connect(m_base->changeAvatar, TQ_SIGNAL(clicked()), this, TQ_SLOT(changeAvatar()));
+ connect(m_base->clearAvatar, TQ_SIGNAL(clicked()), this, TQ_SLOT(clearAvatar()));
connect(m_base->primaryGroup, TQ_SIGNAL(activated(const TQString&)), this, TQ_SLOT(processLockouts()));
connect(m_base->certGenPrivateKey, TQ_SIGNAL(clicked()), this, TQ_SLOT(processLockouts()));
connect(m_base->certPrivateKeyFileName, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(processLockouts()));
@@ -145,6 +149,14 @@ UserConfigDialog::UserConfigDialog(LDAPUserInfo user, LDAPConfig* parent, const
m_base->telephoneNumber->setText(m_user.telephoneNumber);
m_base->faxNumber->setText(m_user.faxNumber);
m_base->email->setText(m_user.email);
+ if (!m_user.profileAvatar.isNull()) {
+ TQPixmap pixmapAvatar;
+ pixmapAvatar.loadFromData(m_user.profileAvatar);
+ if (!pixmapAvatar.isNull()) {
+ m_profileAvatar = pixmapAvatar;
+ m_base->changeAvatar->setPixmap(m_profileAvatar);
+ }
+ }
// Certificate generation information
TQDateTime suggestedExpiration = TQDateTime::currentDateTime().addDays(KERBEROS_PKI_KRB_EXPIRY_DAYS);
@@ -322,6 +334,52 @@ void UserConfigDialog::processLockouts() {
m_prevPrimaryGroup = m_base->primaryGroup->currentText();
}
+void UserConfigDialog::setNewAvatar(const TQPixmap &pix) {
+ if (pix.isNull()) {
+ KMessageBox::sorry(this, i18n("There was an error loading the image."));
+ return;
+ }
+
+ TQByteArray rawImage;
+ TQBuffer imageBuffer(rawImage);
+ imageBuffer.open(IO_WriteOnly);
+ // NOTE:
+ // While the LDAP attribute technically specifies JPEG, in practice compatibility has improved to include PNG
+ // with later versions of Microsoft software (e.g., the thumbnailPhoto aliased attribute)
+ // JPEG does not store alpha channel information, which causes ugly graphical artifacts
+ // Use PNG, even though it is in technical violation of the LDAP standards, for an improved user experience
+ if (!pix.save(&imageBuffer, "PNG")) {
+ KMessageBox::sorry(this, i18n("There was an error preparing the image."));
+ }
+ imageBuffer.close();
+ m_user.profileAvatar = rawImage;
+
+ m_profileAvatar = pix;
+ m_base->changeAvatar->setPixmap(m_profileAvatar);
+}
+
+void UserConfigDialog::changeAvatar() {
+ ChFaceDlg* avatarPickerDialog = new ChFaceDlg( TDEGlobal::dirs()->resourceDirs("data").last() + "/tdm/pics/users/" );
+
+ if (avatarPickerDialog->exec() == TQDialog::Accepted && !avatarPickerDialog->getFaceImage().isNull()) {
+ setNewAvatar(avatarPickerDialog->getFaceImage());
+ }
+
+ delete avatarPickerDialog;
+
+ processLockouts();
+}
+
+void UserConfigDialog::clearAvatar() {
+ TQPixmap nullPixmap;
+
+ m_user.profileAvatar = TQByteArray();
+ m_profileAvatar = nullPixmap;
+ m_base->changeAvatar->setPixmap(m_profileAvatar);
+
+ processLockouts();
+}
+
void UserConfigDialog::createPKICertificate() {
int ret;
TQString errorstring;
diff --git a/src/userconfigdlg.h b/src/userconfigdlg.h
index b9b746f..a83e68d 100644
--- a/src/userconfigdlg.h
+++ b/src/userconfigdlg.h
@@ -45,6 +45,8 @@ public slots:
void revokePKICertificate();
void downloadPKICertificate();
void updatePKICertificateList();
+ void changeAvatar();
+ void clearAvatar();
public:
LDAPUserConfigBase *m_base;
@@ -52,8 +54,11 @@ public:
TQStringList selectedGroups;
private:
+ void setNewAvatar(const TQPixmap &pix);
+
LDAPConfig* m_ldapconfig;
TQString m_prevPrimaryGroup;
+ TQPixmap m_profileAvatar;
};
#endif // _USERCONFIGDIALOG_H_