1 //////////////////////////////////////////////////////////////////////
2 //
3 // BeeBEEP Copyright (C) 2010-2021 Marco Mastroddi
4 //
5 // BeeBEEP is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published
7 // by the Free Software Foundation, either version 3 of the License,
8 // or (at your option) any later version.
9 //
10 // BeeBEEP 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.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with BeeBEEP. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // Author: Marco Mastroddi <marco.mastroddi(AT)gmail.com>
19 //
20 // $Id: GuiEditVCard.cpp 1455 2020-12-23 10:17:53Z mastroddi $
21 //
22 //////////////////////////////////////////////////////////////////////
23 
24 #include "Avatar.h"
25 #include "BeeUtils.h"
26 #include "FileDialog.h"
27 #include "GuiEditVCard.h"
28 #include "IconManager.h"
29 #include "Settings.h"
30 #include "UserManager.h"
31 
32 
GuiEditVCard(QWidget * parent)33 GuiEditVCard::GuiEditVCard( QWidget *parent )
34   : QDialog( parent ), m_vCard(), m_userColor( "#000000" ), m_regenerateUserHash( false )
35 {
36   setupUi( this );
37   setObjectName( "GuiEditVCard" );
38   setWindowTitle( tr( "Edit your profile" ) + QString( " - %1" ).arg( Settings::instance().programName() ) );
39   setWindowIcon( IconManager::instance().icon( "profile-edit.png" ) );
40   Bee::removeContextHelpButton( this );
41 
42   mp_pbChangePhoto->setIcon( IconManager::instance().icon( "add.png" ) );
43   mp_pbRemovePhoto->setIcon( IconManager::instance().icon( "delete.png" ) );
44   mp_pbColor->setIcon( IconManager::instance().icon( "font-color.png" ) );
45   mp_deBirthday->setToolTip( tr( "If you don't want to show the year to other users use 1900. To remove your birthday use 01/01/1900" ) );
46 
47   connect( mp_pbOk, SIGNAL( clicked() ), this, SLOT( onOkClicked() ) );
48   connect( mp_pbCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
49   connect( mp_pbChangePhoto, SIGNAL( clicked() ), this, SLOT( changePhoto() ) );
50   connect( mp_pbRemovePhoto, SIGNAL( clicked() ), this, SLOT( removePhoto() ) );
51   connect( mp_pbColor, SIGNAL( clicked() ), this, SLOT( changeUserColor() ) );
52   connect( mp_pbRegenerateHash, SIGNAL( clicked() ), this, SLOT( regenerateHash() ) );
53 }
54 
currentAvatarName() const55 QString GuiEditVCard::currentAvatarName() const
56 {
57   QString current_avatar_name = "";
58   if( Settings::instance().useUserFullName() )
59     current_avatar_name = QString( "%1 %2" ).arg( mp_leFirstName->text().simplified() ).arg( mp_leLastName->text().simplified() ).trimmed();
60 
61   if( current_avatar_name.isEmpty() )
62     current_avatar_name = mp_leNickname->text().simplified();
63   return current_avatar_name.isEmpty() ? QLatin1String( "??" ) : current_avatar_name;
64 }
65 
setUserColor(const QString & new_value)66 void GuiEditVCard::setUserColor( const QString& new_value )
67 {
68   m_userColor = new_value;
69   QColor c( m_userColor );
70   QPalette palette = mp_leNickname->palette();
71   palette.setColor( QPalette::Text, c );
72   mp_leNickname->setPalette( palette );
73   palette.setColor( QPalette::Foreground, c );
74   mp_lNickname->setPalette( palette );
75   if( m_vCard.photo().isNull() )
76     mp_lPhoto->setPixmap( Avatar::create( currentAvatarName(), m_userColor, QSize( 96, 96 ) ) );
77 }
78 
setUser(const User & u)79 void GuiEditVCard::setUser( const User& u )
80 {
81   m_vCard = u.vCard();
82   setUserColor( u.color() );
83   m_regenerateUserHash = false;
84   loadVCard();
85 }
86 
loadVCard()87 void GuiEditVCard::loadVCard()
88 {
89   mp_leNickname->setText( m_vCard.nickName() );
90   if( Settings::instance().allowEditNickname() )
91   {
92     mp_leNickname->setEnabled( true  );
93     mp_leNickname->setReadOnly( false );
94     mp_leNickname->setToolTip( "" );
95   }
96   else
97   {
98     mp_leNickname->setEnabled( false  );
99     mp_leNickname->setReadOnly( true  );
100     mp_leNickname->setToolTip( tr( "Disabled by system administrator" ) );
101   }
102   mp_leFirstName->setText( m_vCard.firstName() );
103   mp_leLastName->setText( m_vCard.lastName() );
104 
105   if( m_vCard.birthday().isValid() )
106     mp_deBirthday->setDate( m_vCard.birthday() );
107   else
108     mp_deBirthday->setDate( QDate( 1900, 1, 1 ) );
109 
110   mp_leEmail->setText( m_vCard.email() );
111 
112   if( m_vCard.photo().isNull() )
113     mp_lPhoto->setPixmap( Avatar::create( currentAvatarName(), m_userColor, QSize( 96, 96 ) ) );
114   else
115     mp_lPhoto->setPixmap( m_vCard.photo() );
116 
117   mp_lePhone->setText( m_vCard.phoneNumber() );
118 
119   mp_teInfo->setPlainText( m_vCard.info() );
120 
121   mp_leNickname->setFocus();
122 }
123 
changePhoto()124 void GuiEditVCard::changePhoto()
125 {
126   QList<QByteArray> supported_formats = QImageReader::supportedImageFormats();
127   QString supported_formats_string = "";
128 
129   foreach( QByteArray sf, supported_formats )
130   {
131     supported_formats_string += QString( " *." );
132     supported_formats_string.append( sf );
133   }
134 
135   QString photo_path = FileDialog::getOpenFileName( true, this, tr( "%1 - Select your profile photo" ).arg( Settings::instance().programName() ),
136                                                      Settings::instance().lastDirectorySelected(), tr( "Images" ) + QString( " (%1)" ).arg( supported_formats_string.simplified() ) );
137   if( photo_path.isNull() || photo_path.isEmpty() )
138     return;
139 
140   Settings::instance().setLastDirectorySelectedFromFile( photo_path );
141 
142   QImage img;
143   QImageReader img_reader( photo_path );
144   img_reader.setAutoDetectImageFormat( true );
145   if( !img_reader.read( &img ) )
146   {
147     QMessageBox::warning( this, Settings::instance().programName(), tr( "Unable to load image %1." ).arg( photo_path ), tr( "Ok" ) );
148     qWarning() << "Can not load profile picture. Format supported:" << supported_formats_string;
149     return;
150   }
151 
152   if( img.width() != img.height() )
153     QMessageBox::information( this, Settings::instance().programName(), tr( "It is preferable to use square images to avoid display problems." ), tr( "Ok" ) );
154   QPixmap pix = QPixmap::fromImage( img.scaled( 96, 96, Qt::KeepAspectRatio ) );
155   if( !pix.isNull() )
156   {
157     mp_lPhoto->setPixmap( pix );
158     m_vCard.setPhoto( pix );
159   }
160 }
161 
removePhoto()162 void GuiEditVCard::removePhoto()
163 {
164   mp_lPhoto->setPixmap( Avatar::create( currentAvatarName(), m_userColor, QSize( 96, 96 ) ) );
165   m_vCard.setPhoto( QPixmap() );
166 }
167 
changeUserColor()168 void GuiEditVCard::changeUserColor()
169 {
170   QColor c = QColorDialog::getColor( QColor( Settings::instance().chatFontColor() ), this );
171   if( c.isValid() )
172     setUserColor( c.name() );
173 }
174 
checkLineEdit(QLineEdit * ple,const QString & msg)175 bool GuiEditVCard::checkLineEdit( QLineEdit* ple, const QString& msg )
176 {
177   QString s = ple->text().simplified();
178   if( s.isEmpty() )
179   {
180     QMessageBox::information( this, Settings::instance().programName(), msg, tr( "Ok" ) );
181     ple->setFocus();
182     return false;
183   }
184   return true;
185 }
186 
checkData()187 bool GuiEditVCard::checkData()
188 {
189   if( !checkLineEdit( mp_leNickname, tr( "Please insert your nickname." ) ) )
190     return false;
191 
192   QString user_nickname = mp_leNickname->text().simplified();
193   User u = UserManager::instance().findUserByNickname( user_nickname );
194   if( u.isValid() && !u.isLocal() )
195   {
196     QMessageBox::warning( this, Settings::instance().programName(),
197                           tr( "The nickname '%1' is already in use by the user %2." )
198                             .arg( user_nickname ).arg( u.path() ) );
199     mp_leNickname->setFocus();
200     return false;
201   }
202 
203   return true;
204 }
205 
saveVCard()206 void GuiEditVCard::saveVCard()
207 {
208   m_vCard.setNickName( mp_leNickname->text().simplified() );
209   m_vCard.setFirstName( mp_leFirstName->text().simplified() );
210   m_vCard.setLastName( mp_leLastName->text().simplified() );
211   if( mp_deBirthday->date() != QDate( 1900, 1, 1 ) )
212     m_vCard.setBirthday( mp_deBirthday->date() );
213   else
214     m_vCard.setBirthday( QDate() );
215   m_vCard.setEmail( mp_leEmail->text().simplified() );
216   m_vCard.setPhoneNumber( mp_lePhone->text().simplified() );
217   m_vCard.setInfo( mp_teInfo->toPlainText().trimmed() );
218 }
219 
onOkClicked()220 void GuiEditVCard::onOkClicked()
221 {
222   if( !checkData() )
223     return;
224   saveVCard();
225   accept();
226 }
227 
regenerateHash()228 void GuiEditVCard::regenerateHash()
229 {
230   if( !checkData() )
231     return;
232 
233   if( QMessageBox::question( this, Settings::instance().programName(),
234                  tr( "Be careful, by changing the hash code you may no longer be a member of some groups and you will have to get invited again. Do you really want to regenerate your hash code?" ),
235                  tr( "Yes" ), tr( "No" ), QString(), 1, 1 ) == 0 )
236   {
237     m_regenerateUserHash = true;
238     saveVCard();
239     accept();
240   }
241 }
242