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: Settings.cpp 1476 2021-01-07 10:43:54Z mastroddi $
21 //
22 //////////////////////////////////////////////////////////////////////
23
24 #include "BeeApplication.h"
25 #include "BeeUtils.h"
26 #include "ChatMessage.h"
27 #include "NetworkAddress.h"
28 #include "Random.h"
29 #include "Settings.h"
30 #include "Version.h"
31
32
33 Settings* Settings::mp_instance = Q_NULLPTR;
34
Settings()35 Settings::Settings()
36 : m_localUser( ID_LOCAL_USER )
37 {
38 m_settingsVersion = BEEBEEP_SETTINGS_VERSION;
39 m_currentFilePath = "";
40
41 /* Default RC start */
42 m_enableSaveData = true;
43 m_useChatWithAllUsers = true;
44 m_useSettingsFileIni = true;
45 m_broadcastOnlyToHostsIni = false;
46 m_allowOnlyHostAddressesFromHostsIni = false;
47 m_useOnlyMulticast = false;
48 m_defaultBroadcastPort = DEFAULT_BROADCAST_PORT;
49 m_defaultListenerPort = DEFAULT_LISTENER_PORT;
50 m_defaultFileTransferPort = DEFAULT_FILE_TRANSFER_PORT;
51
52 m_resetGeometryAtStartup = false;
53 m_saveGeometryOnExit = false;
54 m_saveDataInDocumentsFolder = false;
55 m_disableMenuSettings = false;
56
57 // In windows native dialogs are application modal and the connection goes in timeout...
58 // In MacOSX instead it seems to work... I have changed the connection timeout...
59 m_useNativeDialogs = true;
60 m_useFontEmoticons = false;
61 #if QT_VERSION >= 0x050000
62 m_useHiResEmoticons = true;
63 #else
64 m_useHiResEmoticons = false;
65 #endif
66
67 #ifdef MAKE_BEEBEEP_PORTABLE
68 m_saveDataInUserApplicationFolder = false;
69 #else
70 m_saveDataInUserApplicationFolder = true;
71 #endif
72
73 #ifdef BEEBEEP_USE_MULTICAST_DNS
74 #ifdef Q_OS_MAC
75 m_useMulticastDns = true;
76 #else
77 m_useMulticastDns = false;
78 #endif
79 #else
80 m_useMulticastDns = false;
81 #endif
82
83 m_allowMultipleInstances = false;
84 m_dataFolderInRC = "";
85 m_addAccountNameToDataFolder = false;
86 m_addNicknameToDataFolder = false;
87 m_preferredSubnets = "";
88 m_disableSystemProxyForConnections = true;
89 m_useDefaultMulticastGroupAddress = true;
90 m_ipMulticastTtl = DEFAULT_IPV4_MULTICAST_TTL_OPTION;
91 m_useIPv6 = false;
92 m_useHive = false;
93 m_checkNewVersionAtStartup = true;
94 m_postUsageStatistics = true;
95 m_useHostnameForDefaultUsername = false;
96 m_useEasyConnection = false;
97 m_useUserFullName = false;
98 m_appendHostNameToUserName = false;
99 m_useCompactDataSaving = true;
100
101 #ifdef BEEBEEP_DISABLE_FILE_TRANSFER
102 m_disableFileTransfer = true;
103 m_disableFileSharing = true;
104 #else
105 m_disableFileTransfer = false;
106 m_disableFileSharing = false;
107 #endif
108 #ifdef BEEBEEP_DISABLE_SEND_MESSAGE
109 m_disableSendMessage = true;
110 #else
111 m_disableSendMessage = false;
112 #endif
113 #ifdef BEEBEEP_USE_SHAREDESKTOP
114 m_disableDesktopSharing = false;
115 #else
116 m_disableDesktopSharing = true;
117 #endif
118 #ifdef BEEBEEP_USE_VOICE_CHAT
119 m_disableVoiceMessages = false;
120 #else
121 m_disableVoiceMessages = true;
122 #endif
123
124 m_startMinimized = false;
125 m_signature = "";
126 m_useOnlyTextEmoticons = false;
127 m_disablePrivateChats = false;
128 m_disableMulticast = false;
129 m_userRecognitionMethod = RecognizeByDefaultMethod;
130 m_canAddMembersToGroup = true;
131 m_canRemoveMembersFromGroup = true;
132 m_allowEditNickname = true;
133 m_disableCreateMessage = false;
134 m_clearCacheAfterDays = 96;
135 m_removePartiallyDownloadedFilesAfterDays = 5;
136
137 m_checkUserConnectedFromDatagramIp = false;
138 m_skipLocalHardwareAddresses = QStringList();
139
140 m_disableConnectionSocketEncryption = false;
141 m_allowNotEncryptedConnectionsAlso = false;
142 m_allowEncryptedConnectionsAlso = true;
143 m_disableConnectionSocketDataCompression = false;
144
145 m_allowedFileExtensionsInFileTransfer = QStringList();
146
147 m_rcFileExists = false;
148
149 m_connectionKeyExchangeMethod = ConnectionKeyExchangeAuto;
150 /* Default RC end */
151
152 m_emoticonSizeInEdit = 16;
153
154 QFont f = QApplication::font();
155 setChatFont( f );
156 m_emoticonSizeInMenu = 24;
157 m_emoticonInRecentMenu = 48;
158 m_confirmOnDownloadFile = false;
159 m_resetMinimumWidthForStyle = true;
160 m_onExistingFileAction = GenerateNewFileName;
161 m_resumeFileTransfer = true;
162 m_promptOnCloseEvent = true;
163 m_saveUserList = true;
164 m_saveGroupList = true;
165 m_localUser.setStatus( User::Online );
166 m_localUser.setVersion( version( false, false, false ) );
167 setPassword( defaultPassword() );
168
169 m_resourceFolder = ".";
170 #if QT_VERSION >= 0x050400
171 m_dataFolder = Bee::convertToNativeFolderSeparator( QStandardPaths::writableLocation( QStandardPaths::AppDataLocation ) );
172 #elif QT_VERSION >= 0x050000
173 m_dataFolder = Bee::convertToNativeFolderSeparator( QString( "%1/%2" )
174 .arg( QStandardPaths::writableLocation( QStandardPaths::DataLocation ) )
175 .arg( programName() ) );
176 #else
177 m_dataFolder = Bee::convertToNativeFolderSeparator( QDesktopServices::storageLocation( QDesktopServices::DataLocation ) );
178 #endif
179 m_cacheFolder = defaultCacheFolderPath();
180
181 m_lastSave = QDateTime::currentDateTime();
182
183 m_preventMultipleConnectionsFromSingleHostAddress = true;
184 m_acceptConnectionsOnlyFromWorkgroups = false;
185 m_maxUserStatusDescriptionInList = 10;
186
187 m_tickIntervalConnectionTimeout = TICK_INTERVAL_CONNECTION_TIMEOUT;
188 m_useReturnToSendMessage = true;
189 m_tickIntervalCheckIdle = 13;
190 m_tickIntervalCheckNetwork = 5;
191 m_tickIntervalBroadcasting = 0;
192 m_broadcastToOfflineUsers = false;
193 m_broadcastToLocalSubnetAlways = true;
194
195 m_chatMessageFilter = QBitArray( static_cast<int>(ChatMessage::NumTypes) );
196 for( int i = 0; i < ChatMessage::NumTypes; i++ )
197 m_chatMessageFilter.setBit( i, false );
198
199 #ifdef Q_OS_WIN
200 m_usePreviewFileDialog = true;
201 #else
202 m_usePreviewFileDialog = false;
203 #endif
204 m_previewFileDialogGeometry = "";
205 m_previewFileDialogImageSize = 200;
206 m_maxUsersToConnectInATick = 25;
207 m_showTextInModeRTL = false;
208 m_showChatsInOneWindow = false;
209 m_maxLogLines = 5000;
210 m_enableDefaultChatNotifications = true;
211
212 m_enableFileTransfer = true;
213 m_enableFileSharing = false;
214
215 m_iconSourcePath = "";
216 m_emoticonSourcePath = "";
217
218 m_maxDaysOfUserInactivity = 31;
219
220 m_shareDesktopCaptureDelay = 2100;
221
222 m_delayConnectionAtStartup = 5000;
223
224 m_maxChatsToOpenAfterSendingMessage = 6;
225 m_showUsersOnConnection = false;
226 m_showChatsOnConnection = false;
227 m_hideEmptyChatsInList = true;
228
229 m_chatActiveWindowOpacityLevel = 100;
230 m_chatInactiveWindowOpacityLevel = chatInactiveWindowDefaultOpacityLevel();
231
232 m_tickIntervalChatAutoSave = 61;
233
234 m_useMessageTimestampWithAP = false;
235 m_useDarkStyle = false;
236
237 m_saveMessagesTimestamp = QDateTime::currentDateTime();
238
239 m_voiceMessageMaxDuration = 120;
240 m_useVoicePlayer = true;
241 m_useCustomVoiceEncoderSettings = false;
242 m_useSystemVoiceEncoderSettings = false;
243
244 m_keepModificationDateOnFileTransferred = true;
245
246 m_allowedFileExtensionsInFileTransfer = QStringList();
247
248 resetAllColors();
249 }
250
resourceFolders() const251 QStringList Settings::resourceFolders() const
252 {
253 QStringList system_folders;
254 system_folders.append( dataFolder() );
255 system_folders.append( resourceFolder() );
256 #ifdef Q_OS_MAC
257 QDir mac_plugin_dir( QApplication::applicationDirPath() );
258 if( mac_plugin_dir.cdUp() && mac_plugin_dir.cd( "PlugIns" ) )
259 system_folders.append( Bee::convertToNativeFolderSeparator( mac_plugin_dir.absolutePath() ) );
260 #endif
261 #ifdef Q_OS_UNIX
262 system_folders.append( QLatin1String( "/etc/beebeep/" ) );
263 system_folders.append( QLatin1String( "/usr/local/etc/beebeep/" ) );
264 system_folders.append( QLatin1String( "/usr/lib/beebeep/" ) );
265 system_folders.append( QLatin1String( "/usr/local/lib/beebeep/" ) );
266 #endif
267 system_folders.removeDuplicates();
268 return system_folders;
269 }
270
dataFolders() const271 QStringList Settings::dataFolders() const
272 {
273 QStringList data_folders;
274 data_folders.append( dataFolder() );
275 #if QT_VERSION >= 0x050400
276 data_folders.append( Bee::convertToNativeFolderSeparator( QStandardPaths::writableLocation( QStandardPaths::AppDataLocation ) ) );
277 #elif QT_VERSION >= 0x050000
278 data_folders.append( Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( QStandardPaths::writableLocation( QStandardPaths::DataLocation ) ).arg( programName() ) ) );
279 #else
280 data_folders.append( Bee::convertToNativeFolderSeparator( QDesktopServices::storageLocation( QDesktopServices::DataLocation ) ) );
281 #endif
282 #ifdef Q_OS_UNIX
283 data_folders.append( QLatin1String( "/usr/share/beebeep/" ) );
284 data_folders.append( QLatin1String( "/usr/local/share/beebeep/" ) );
285 #endif
286 data_folders.append( cacheFolder() );
287 data_folders.removeDuplicates();
288 return data_folders;
289 }
290
findFileInFolders(const QString & file_name,const QStringList & folder_list,bool return_folder_path) const291 QString Settings::findFileInFolders( const QString& file_name, const QStringList& folder_list, bool return_folder_path ) const
292 {
293 foreach( QString folder_path, folder_list )
294 {
295 if( folder_path.trimmed().isEmpty() )
296 continue;
297 folder_path = Bee::convertToNativeFolderSeparator( folder_path );
298 QString file_path = folder_path;
299 if( !file_path.endsWith( Bee::nativeFolderSeparator() ) )
300 file_path.append( Bee::nativeFolderSeparator() );
301 file_path += file_name;
302 QFileInfo fi( file_path );
303 if( fi.exists() )
304 {
305 if( !fi.isReadable() )
306 qWarning() << "Skip file" << qPrintable( file_path ) << "because is not readable";
307 else
308 return return_folder_path ? folder_path : file_path;
309 }
310 }
311 return QString();
312 }
313
setDefaultFolders()314 void Settings::setDefaultFolders()
315 {
316 QString app_folder = Bee::convertToNativeFolderSeparator( QApplication::applicationDirPath() );
317 qDebug() << "Applicaction folder:" << qPrintable( app_folder );
318
319 #ifdef Q_OS_MAC
320 QDir macos_dir( app_folder );
321 if( macos_dir.cdUp() && macos_dir.cd( "Resources" ) )
322 m_resourceFolder = Bee::convertToNativeFolderSeparator( macos_dir.absolutePath() );
323 else
324 m_resourceFolder = app_folder;
325 #else
326 m_resourceFolder = app_folder;
327 #endif
328 qDebug() << "Resource folder:" << qPrintable( m_resourceFolder );
329
330 if( !Bee::folderIsWriteable( m_resourceFolder, false ) )
331 {
332 #if QT_VERSION >= 0x050400
333 m_dataFolder = Bee::convertToNativeFolderSeparator( QStandardPaths::writableLocation( QStandardPaths::AppDataLocation ) );
334 #elif QT_VERSION >= 0x050000
335 m_dataFolder = Bee::convertToNativeFolderSeparator( QString( "%1/%2" )
336 .arg( QStandardPaths::writableLocation( QStandardPaths::DataLocation ) )
337 .arg( programName() ) );
338 #else
339 m_dataFolder = Bee::convertToNativeFolderSeparator( QDesktopServices::storageLocation( QDesktopServices::DataLocation ) );
340 #endif
341 }
342 else
343 m_dataFolder = m_resourceFolder;
344 m_cacheFolder = defaultCacheFolderPath();
345 }
346
defaultListBackgroundColor() const347 QString Settings::defaultListBackgroundColor() const
348 {
349 return m_useDarkStyle ? Bee::colorDarkGrey().name() : QLatin1String( "#ffffff" );
350 }
351
defaultSystemBackgroundColor() const352 QString Settings::defaultSystemBackgroundColor() const
353 {
354 return m_useDarkStyle ? Bee::colorBlack().name() : QLatin1String( "#e0e0e0" );
355 }
356
resetAllColors()357 void Settings::resetAllColors()
358 {
359 m_chatDefaultUserNameColor = m_useDarkStyle ? "#ffffff" : "#000000";
360 m_homeBackgroundColor = defaultSystemBackgroundColor();
361 m_defaultChatBackgroundColor = defaultSystemBackgroundColor();
362 m_userListBackgroundColor = defaultListBackgroundColor();
363 m_chatListBackgroundColor = defaultListBackgroundColor();
364 m_groupListBackgroundColor = defaultListBackgroundColor();
365 m_savedChatListBackgroundColor = defaultListBackgroundColor();
366 m_chatFontColor = m_useDarkStyle ? "#ffffff" : "#000000";
367 m_chatBackgroundColor = m_useDarkStyle ? Bee::colorDarkGrey().name() : "#ffffff";
368 m_chatDefaultTextColor = m_useDarkStyle ? "#ffffff" : "#000000";
369 m_chatSystemTextColor = m_useDarkStyle ? Bee::colorGrey().name() : "#555555";
370 m_chatQuoteBackgroundColor = Bee::colorGrey().name();
371 m_chatQuoteTextColor = Bee::colorBlack().name();
372 }
373
createApplicationUuid()374 void Settings::createApplicationUuid()
375 {
376 if( m_applicationUuid.isEmpty() )
377 {
378 m_applicationUuid = QUuid::createUuid().toString();
379 m_applicationUuidCreationDate = QDate::currentDate();
380 qDebug() << "Create new application uuid" << qPrintable( m_applicationUuid );
381 }
382 else
383 {
384 qint64 uuid_days_life = m_applicationUuidCreationDate.daysTo( QDate::currentDate() );
385 #ifdef BEEBEEP_DEBUG
386 qDebug() << "Application uuid is created" << uuid_days_life << "days ago";
387 #endif
388 if( uuid_days_life > 31 )
389 {
390 m_applicationUuid = QUuid::createUuid().toString();
391 m_applicationUuidCreationDate = QDate::currentDate();
392 qDebug() << "Renew application uuid" << qPrintable( m_applicationUuid ) << "after" << uuid_days_life << "days";
393 }
394 else
395 qDebug() << "Continue to use application uuid" << qPrintable( m_applicationUuid ) << "created in date" << qPrintable( m_applicationUuidCreationDate.toString( "yyyy-MM-dd" ) );
396 }
397 }
398
systemNetworkProxy(const QNetworkProxyQuery & npq) const399 QNetworkProxy Settings::systemNetworkProxy( const QNetworkProxyQuery& npq ) const
400 {
401 QList<QNetworkProxy> proxy_list = QNetworkProxyFactory::systemProxyForQuery( npq );
402 if( proxy_list.isEmpty() )
403 return QNetworkProxy( QNetworkProxy::NoProxy );
404 else
405 return proxy_list.first();
406 }
407
setChatFont(const QFont & new_value)408 void Settings::setChatFont( const QFont& new_value )
409 {
410 m_chatFont = new_value;
411 QFontMetrics fm( m_chatFont );
412 m_emoticonSizeInChat = qMax( 24, qMin( 160, fm.height() ) );
413 m_emoticonSizeInEdit = qMax( 16, qMin( 48, fm.height() ) );
414 if( m_emoticonSizeInChat % 2 )
415 m_emoticonSizeInChat++;
416 if( m_emoticonSizeInEdit % 2 )
417 m_emoticonSizeInEdit++;
418 }
419
accountNameFromSystemEnvinroment() const420 QString Settings::accountNameFromSystemEnvinroment() const
421 {
422 QProcessEnvironment pe = QProcessEnvironment::systemEnvironment();
423 QString host_name = QHostInfo::localHostName();
424 QString account_name = pe.value( "USERNAME", "" );
425 if( account_name.isEmpty() )
426 account_name = pe.value( "USER", "" );
427 return m_useHostnameForDefaultUsername ? host_name.simplified() : account_name.simplified();
428 }
429
createLocalUser(const QString & user_name)430 void Settings::createLocalUser( const QString& user_name )
431 {
432 m_localUser = User( ID_LOCAL_USER );
433
434 QString account_name = accountNameFromSystemEnvinroment();
435 if( account_name.isEmpty() )
436 {
437 qWarning() << "USERNAME and USER variabile not found in system environment";
438 account_name = QString( "Bee %1" ).arg( QTime::currentTime().toString( "zzzsmh" ) );
439 }
440 m_localUser.setAccountName( account_name.toLower() );
441 if( user_name.isEmpty() )
442 m_localUser.setName( account_name );
443 else
444 m_localUser.setName( user_name );
445
446 m_localUser.setQtVersion( qtMajorVersion() );
447 m_localUser.setProtocolVersion( protocolVersion() );
448 m_localUser.setDomainName( QHostInfo::localDomainName() );
449 m_localUser.setHash( Settings::instance().createLocalUserHash() );
450 m_localUser.setLocalHostName( QHostInfo::localHostName() );
451
452 qDebug() << "System - user name:" << qPrintable( m_localUser.name() );
453 qDebug() << "System - account:" << qPrintable( m_localUser.accountName() );
454 qDebug() << "System - domain name:" << qPrintable( m_localUser.domainName() );
455 qDebug() << "System - host name:" << qPrintable( m_localUser.localHostName() );
456 #ifdef BEEBEEP_DEBUG
457 qDebug() << "Local user hash:" << qPrintable( m_localUser.hash() );
458 #endif
459
460 if( user_name.isEmpty() && m_addNicknameToDataFolder )
461 setDataFolder();
462 }
463
createLocalUserHash()464 QString Settings::createLocalUserHash()
465 {
466 QString hash_parameters = QString( "%1%2%3%4%5%6%7%8" )
467 .arg( QString::number( Random::number32( 6475, 36475 ) ) )
468 .arg( m_localUser.accountName() ).arg( m_localUser.name() )
469 .arg( QString::number( Random::number32( 6475, 36475 ) ) )
470 .arg( m_localUser.domainName() ).arg( m_localUser.localHostName() ).arg( version( true, true, true ) )
471 .arg( QDateTime::currentDateTime().toString( "dd.MM.yyyy-hh:mm:ss.zzz" ) );
472 QString local_user_hash = simpleHash( hash_parameters );
473 #ifdef BEEBEEP_DEBUG
474 qDebug() << "Local user HASH created:" << qPrintable( local_user_hash );
475 #endif
476 return local_user_hash;
477 }
478
createDefaultRcFile()479 bool Settings::createDefaultRcFile()
480 {
481 QFileInfo rc_file_info( dataFolder() + Bee::nativeFolderSeparator() + QLatin1String( "beebeep.rc" ) );
482 if( rc_file_info.exists() )
483 {
484 qDebug() << "RC default configuration file exists in" << qPrintable( rc_file_info.absoluteFilePath() );
485 return false;
486 }
487
488 QSettings* sets = new QSettings( rc_file_info.absoluteFilePath(), QSettings::IniFormat );
489 bool rc_file_created = false;
490 if( sets->isWritable() )
491 {
492 sets->beginGroup( "BeeBEEP" );
493 sets->setValue( "EnableSaveData", m_enableSaveData );
494 sets->setValue( "UseConfigurationFileIni", m_useSettingsFileIni );
495 sets->setValue( "BroadcastOnlyToHostsIni", m_broadcastOnlyToHostsIni );
496 sets->setValue( "AllowOnlyHostAddressesFromHostsIni", m_allowOnlyHostAddressesFromHostsIni );
497 sets->setValue( "UseOnlyMulticast", m_useOnlyMulticast );
498 sets->setValue( "BroadcastPort", m_defaultBroadcastPort );
499 sets->setValue( "DefaultListenerPort", m_defaultListenerPort );
500 sets->setValue( "DefaultFileTransferPort", m_defaultFileTransferPort );
501 sets->setValue( "SaveDataInDocumentsFolder", m_saveDataInDocumentsFolder );
502 sets->setValue( "SaveDataInUserApplicationFolder", m_saveDataInUserApplicationFolder );
503 sets->setValue( "AllowMultipleInstances", m_allowMultipleInstances );
504 sets->setValue( "DataFolderPath", m_dataFolderInRC );
505 sets->setValue( "AddAccountNameToDataFolder", m_addAccountNameToDataFolder );
506 sets->setValue( "AddNicknameToDataFolder", m_addNicknameToDataFolder );
507 #ifdef BEEBEEP_USE_MULTICAST_DNS
508 sets->setValue( "UseMulticastDns", m_useMulticastDns );
509 #endif
510 sets->setValue( "PreventMultipleConnectionsFromSingleHostAddress", m_preventMultipleConnectionsFromSingleHostAddress );
511 sets->setValue( "PreferredSubnets", m_preferredSubnets );
512 sets->setValue( "UseIPv6", m_useIPv6 );
513 if( m_multicastGroupAddress.isNull() )
514 sets->setValue( "MulticastGroupAddress", "" );
515 else
516 sets->setValue( "MulticastGroupAddress", m_multicastGroupAddress.toString() );
517 sets->setValue( "EnableChatWithAllUsers", m_useChatWithAllUsers );
518 sets->setValue( "UseHive", m_useHive );
519 sets->setValue( "UseHostnameForDefaultUsername", m_useHostnameForDefaultUsername );
520 sets->setValue( "DisableFileTransfer", m_disableFileTransfer );
521 sets->setValue( "DisableFileSharing", m_disableFileSharing );
522 sets->setValue( "DisableDesktopSharing", m_disableDesktopSharing );
523 sets->setValue( "DisableSendMessage", m_disableSendMessage );
524 sets->setValue( "DisableVoiceMessages", m_disableVoiceMessages );
525 sets->setValue( "UseEasyConnection", m_useEasyConnection );
526 sets->setValue( "UseCompactDataSaving", m_useCompactDataSaving );
527 sets->setValue( "StartMinimized", m_startMinimized );
528 sets->setValue( "Signature", m_signature );
529 sets->setValue( "UseOnlyTextEmoticons", m_useOnlyTextEmoticons );
530 sets->setValue( "DisablePrivateChats", m_disablePrivateChats );
531 sets->setValue( "DisableMulticast", m_disableMulticast );
532 sets->setValue( "UserRecognitionMethod", m_userRecognitionMethod );
533 sets->setValue( "AllowAddMembersToGroup", m_canAddMembersToGroup );
534 sets->setValue( "AllowRemoveMembersFromGroup", m_canRemoveMembersFromGroup );
535 sets->setValue( "AllowEditNickname", m_allowEditNickname );
536 sets->setValue( "DisableCreateMessage", m_disableCreateMessage );
537 sets->setValue( "DisableMenuSettings", m_disableMenuSettings );
538 sets->setValue( "CheckUserConnectedFromDatagramIp", m_checkUserConnectedFromDatagramIp );
539 sets->setValue( "SkipLocalHardwareAddresses", m_skipLocalHardwareAddresses.isEmpty() ? QString( "" ) : m_skipLocalHardwareAddresses.join( ", " ) );
540 sets->setValue( "DisableEncryptedConnections", m_disableConnectionSocketEncryption );
541 sets->setValue( "AllowNotEncryptedConnectionsAlso", m_allowNotEncryptedConnectionsAlso );
542 sets->setValue( "AllowEncryptedConnectionsAlso", m_allowEncryptedConnectionsAlso );
543 sets->setValue( "UseUserFullName", m_useUserFullName );
544 sets->setValue( "AppendHostNameToUserName", m_appendHostNameToUserName );
545 sets->setValue( "DisableConnectionSocketDataCompression", m_disableConnectionSocketDataCompression );
546 sets->setValue( "AllowedFileExtensionsInFileTransfer", m_allowedFileExtensionsInFileTransfer.isEmpty() ? QString( "" ) : m_allowedFileExtensionsInFileTransfer.join( ", " ) );
547 sets->setValue( "ConnectionKeyExchangeMethod", m_connectionKeyExchangeMethod );
548 sets->setValue( "TickIntervalChatAutoSave", m_tickIntervalChatAutoSave );
549 sets->endGroup();
550 sets->sync();
551 qDebug() << "RC default configuration file created in" << qPrintable( Bee::convertToNativeFolderSeparator( sets->fileName() ) );
552 rc_file_created = true;
553 }
554 else
555 qWarning() << "Unable to create RC default configuration file in" << qPrintable( Bee::convertToNativeFolderSeparator( sets->fileName() ) );
556
557 sets->deleteLater();
558 return rc_file_created;
559 }
560
objectRcSettings() const561 QSettings* Settings::objectRcSettings() const
562 {
563 QString rc_file_path = findFileInFolders( QLatin1String( "beebeep.rc" ), resourceFolders() );
564 if( rc_file_path.isEmpty() )
565 return Q_NULLPTR;
566 QSettings* sets = new QSettings( rc_file_path, QSettings::IniFormat );
567 sets->setFallbacksEnabled( false );
568 return sets;
569 }
570
loadRcFile()571 void Settings::loadRcFile()
572 {
573 QSettings *sets = objectRcSettings();
574 if( sets )
575 {
576 qDebug() << "Loading settings from RC configuration file" << qPrintable( sets->fileName() );
577 m_rcFileExists = true;
578 }
579 else
580 {
581 qDebug() << "RC configuration file not found";
582 m_rcFileExists = false;
583 return;
584 }
585
586 bool ok = false;
587 sets->beginGroup( "Groups" );
588 bool trust_system_account = sets->value( "TrustSystemAccount", false ).toBool(); // for compatibility
589 sets->endGroup();
590
591 sets->beginGroup( "BeeBEEP" );
592 m_enableSaveData = sets->value( "EnableSaveData", m_enableSaveData ).toBool();
593 m_useSettingsFileIni = sets->value( "UseConfigurationFileIni", m_useSettingsFileIni ).toBool();
594 m_broadcastOnlyToHostsIni = sets->value( "BroadcastOnlyToHostsIni", m_broadcastOnlyToHostsIni ).toBool();
595 m_allowOnlyHostAddressesFromHostsIni = sets->value( "AllowOnlyHostAddressesFromHostsIni", m_allowOnlyHostAddressesFromHostsIni ).toBool();
596 m_useOnlyMulticast = sets->value( "UseOnlyMulticast", m_useOnlyMulticast ).toBool();
597 m_defaultBroadcastPort = sets->value( "BroadcastPort", m_defaultBroadcastPort ).toInt();
598 m_defaultListenerPort = sets->value( "DefaultListenerPort", m_defaultListenerPort ).toInt();
599 m_defaultFileTransferPort = sets->value( "DefaultFileTransferPort", m_defaultFileTransferPort ).toInt();
600 m_saveDataInDocumentsFolder = sets->value( "SaveDataInDocumentsFolder", m_saveDataInDocumentsFolder ).toBool();
601 m_saveDataInUserApplicationFolder = sets->value( "SaveDataInUserApplicationFolder", m_saveDataInUserApplicationFolder ).toBool();
602 m_allowMultipleInstances = sets->value( "AllowMultipleInstances", m_allowMultipleInstances ).toBool();
603 m_dataFolderInRC = Bee::convertToNativeFolderSeparator( sets->value( "DataFolderPath", m_dataFolderInRC ).toString() );
604 m_addAccountNameToDataFolder = sets->value( "AddAccountNameToDataFolder", m_addAccountNameToDataFolder ).toBool();
605 m_addNicknameToDataFolder = sets->value( "AddNicknameToDataFolder", m_addNicknameToDataFolder ).toBool();
606 #ifdef BEEBEEP_USE_MULTICAST_DNS
607 m_useMulticastDns = sets->value( "UseMulticastDns", m_useMulticastDns ).toBool();
608 #endif
609 m_preventMultipleConnectionsFromSingleHostAddress = sets->value( "PreventMultipleConnectionsFromSingleHostAddress", m_preventMultipleConnectionsFromSingleHostAddress ).toBool();
610 m_preferredSubnets = sets->value( "PreferredSubnets", m_preferredSubnets ).toString();
611 m_useIPv6 = sets->value( "UseIPv6", m_useIPv6 ).toBool();
612 QString multicast_group_address = sets->value( "MulticastGroupAddress", "" ).toString();
613 if( multicast_group_address.isEmpty() )
614 m_multicastGroupAddress = QHostAddress();
615 else
616 m_multicastGroupAddress = QHostAddress( multicast_group_address );
617 m_useChatWithAllUsers = sets->value( "EnableChatWithAllUsers", m_useChatWithAllUsers ).toBool();
618 m_useHive = sets->value( "UseHive", m_useHive ).toBool();
619 m_useHostnameForDefaultUsername = sets->value( "UseHostnameForDefaultUsername", m_useHostnameForDefaultUsername ).toBool();
620 #ifdef BEEBEEP_DISABLE_FILE_TRANSFER
621 m_disableFileTransfer = true;
622 m_disableFileSharing = true;
623 #else
624 m_disableFileTransfer = sets->value( "DisableFileTransfer", m_disableFileTransfer ).toBool();
625 if( m_disableFileTransfer )
626 m_disableFileSharing = true;
627 else
628 m_disableFileSharing = sets->value( "DisableFileSharing", m_disableFileSharing ).toBool();
629 #endif
630 m_disableDesktopSharing = sets->value( "DisableDesktopSharing", m_disableDesktopSharing ).toBool();
631 m_disableSendMessage = sets->value( "DisableSendMessage", m_disableSendMessage ).toBool();
632 m_disableVoiceMessages = sets->value( "DisableVoiceMessages", m_disableVoiceMessages ).toBool();
633 m_useEasyConnection = sets->value( "UseEasyConnection", m_useEasyConnection ).toBool();
634 m_useCompactDataSaving = sets->value( "UseCompactDataSaving", m_useCompactDataSaving ).toBool();
635 m_startMinimized = sets->value( "StartMinimized", m_startMinimized ).toBool();
636 m_signature = sets->value( "Signature", m_signature ).toString();
637 m_useOnlyTextEmoticons = sets->value( "UseOnlyTextEmoticons", m_useOnlyTextEmoticons ).toBool();
638 m_disablePrivateChats = sets->value( "DisablePrivateChats", m_disablePrivateChats ).toBool();
639 m_disableMulticast = sets->value( "DisableMulticast", m_disableMulticast ).toBool();
640 int user_recognition_method = sets->value( "UserRecognitionMethod", -1 ).toInt();
641 setUserRecognitionMethod( (user_recognition_method < 0 ? (trust_system_account ? RecognizeByAccount : m_userRecognitionMethod) : user_recognition_method) );
642
643 m_canAddMembersToGroup = sets->value( "AllowAddMembersToGroup", m_canAddMembersToGroup ).toBool();
644 m_canRemoveMembersFromGroup = sets->value( "AllowRemoveMembersFromGroup", m_canRemoveMembersFromGroup ).toBool();
645 m_allowEditNickname = sets->value( "AllowEditNickname", m_allowEditNickname ).toBool();
646 m_disableCreateMessage = sets->value( "DisableCreateMessage", m_disableCreateMessage ).toBool();
647 m_disableMenuSettings = sets->value( "DisableMenuSettings", m_disableMenuSettings ).toBool();
648 m_clearCacheAfterDays = qMax( -1, sets->value( "ClearCacheAfterDays", m_clearCacheAfterDays ).toInt() );
649 m_removePartiallyDownloadedFilesAfterDays = qMax( -1, sets->value( "RemovePartiallyDownloadedFilesAfterDays", m_removePartiallyDownloadedFilesAfterDays ).toInt() );
650 m_checkUserConnectedFromDatagramIp = sets->value( "CheckUserConnectedFromDatagramIp", m_checkUserConnectedFromDatagramIp ).toBool();
651 // Remember to use "" for the string in INI files
652 QString local_hw_addresses = sets->value( "SkipLocalHardwareAddresses", m_skipLocalHardwareAddresses.join( "," ) ).toString().simplified();
653 m_skipLocalHardwareAddresses.clear();
654 if( !local_hw_addresses.isEmpty() )
655 {
656 QStringList local_hw_address_list = local_hw_addresses.split( "," );
657 foreach( QString hw_value, local_hw_address_list )
658 {
659 hw_value = hw_value.trimmed();
660 if( !hw_value.isEmpty() )
661 m_skipLocalHardwareAddresses.append( hw_value );
662 }
663 m_skipLocalHardwareAddresses.removeDuplicates();
664 }
665 m_disableConnectionSocketEncryption = sets->value( "DisableEncryptedConnections", m_disableConnectionSocketEncryption ).toBool();
666 m_allowNotEncryptedConnectionsAlso = sets->value( "AllowNotEncryptedConnectionsAlso", m_allowNotEncryptedConnectionsAlso ).toBool();
667 m_allowEncryptedConnectionsAlso = sets->value( "AllowEncryptedConnectionsAlso", m_allowEncryptedConnectionsAlso ).toBool();
668 m_useUserFullName = sets->value( "UseUserFullName", m_useUserFullName ).toBool();
669 m_appendHostNameToUserName = sets->value( "AppendHostNameToUserName", m_appendHostNameToUserName ).toBool();
670 m_disableConnectionSocketDataCompression = sets->value( "DisableConnectionSocketDataCompression", m_disableConnectionSocketDataCompression ).toBool();
671 // Remember to use "" for the string in INI files
672 QString allowed_file_extensions = sets->value( "AllowedFileExtensionsInFileTransfer", m_allowedFileExtensionsInFileTransfer.join( "," ) ).toString().simplified();
673 m_allowedFileExtensionsInFileTransfer.clear();
674 if( !allowed_file_extensions.trimmed().isEmpty() )
675 {
676 QStringList allowed_file_extensions_list = allowed_file_extensions.split( "," );
677 foreach( QString file_ext, allowed_file_extensions_list )
678 {
679 file_ext = file_ext.trimmed();
680 if( !file_ext.isEmpty() )
681 {
682 if( file_ext.startsWith( "*" ) )
683 file_ext.remove( 0, 1 );
684 if( file_ext.startsWith( "." ) )
685 file_ext.remove( 0, 1 );
686 if( !file_ext.isEmpty() )
687 m_allowedFileExtensionsInFileTransfer.append( file_ext.toLower() );
688 }
689 }
690 m_allowedFileExtensionsInFileTransfer.removeDuplicates();
691 }
692
693 m_connectionKeyExchangeMethod = sets->value( "ConnectionKeyExchangeMethod", m_connectionKeyExchangeMethod ).toInt( &ok );
694 if( !ok || m_connectionKeyExchangeMethod < 0 || m_connectionKeyExchangeMethod >= NumConnectionKeyExchangeMethods )
695 m_connectionKeyExchangeMethod = ConnectionKeyExchangeAuto;
696 sets->endGroup();
697
698 QStringList key_list = sets->allKeys();
699 foreach( QString key, key_list )
700 {
701 QString sets_value = sets->value( key ).toString();
702 if( sets_value.isEmpty() )
703 sets_value = sets->value( key ).toStringList().join( ", " );
704 qDebug() << "RC read ->" << qPrintable( key ) << "=" << qPrintable( sets_value );
705 }
706 qDebug() << "RC configuration file read";
707 if( !m_skipLocalHardwareAddresses.isEmpty() )
708 {
709 foreach( QString hw_value, m_skipLocalHardwareAddresses )
710 qDebug() << "Skip local hardware address:" << qPrintable( hw_value );
711 }
712 if( !m_allowedFileExtensionsInFileTransfer.isEmpty() )
713 qWarning() << "File transfer allows only these extensions:" << qPrintable( m_allowedFileExtensionsInFileTransfer.join( ", " ).toUpper() );
714 delete sets;
715 }
716
createDefaultHostsFile()717 bool Settings::createDefaultHostsFile()
718 {
719 QStringList sl;
720
721 sl << "# This is a sample HOSTS file used by BeeBEEP.";
722 sl << "#";
723 sl << "# This file contains the IP addresses (something like 10.0.0.123)";
724 sl << "# or subnet (10.0.0.255 means that BeeBEEP tries to connect every";
725 sl << "# client from the IP 10.0.0.1 to IP 10.0.0.254).";
726 sl << "# Each entry should be kept on an individual line.";
727 sl << "#";
728 sl << "# Additionally, comments (such as these) may be inserted";
729 sl << "# on individual line denoted by a '#', '*' or '/' symbol.";
730 sl << "#";
731 sl << "# For example:";
732 sl << "#";
733 sl << "# 10.184.9.132";
734 sl << "# 192.168.2.17";
735 sl << "# 10.184.5.255";
736 sl << "# 10.2.4.255";
737 sl << "# 2001:db8:1f70::999:de8:7648:6e8";
738 sl << "#";
739 sl << "# From version 3.0.1 you can also add port to the host addresses";
740 sl << "# (ipv4 and ipv6 supported). For example:";
741 sl << "#";
742 sl << "# 10.184.9.132:6475";
743 sl << "# [2001:db8:1f70::999:de8:7648:6e8]:6475";
744 sl << "#";
745 sl << " ";
746
747 QString file_hosts_path = dataFolder() + Bee::nativeFolderSeparator() + QLatin1String( "beehosts.ini" );
748 QFile file_hosts_ini( file_hosts_path );
749 if( file_hosts_ini.exists() )
750 {
751 qDebug() << "HOSTS default configuration file exists in" << qPrintable( file_hosts_path );
752 return false;
753 }
754
755 if( file_hosts_ini.open( QIODevice::WriteOnly ) )
756 {
757 QTextStream ts( &file_hosts_ini );
758 foreach( QString line, sl )
759 ts << line << "\n";
760 ts.flush();
761 file_hosts_ini.close();
762 qDebug() << "HOSTS default configuration file created in" << qPrintable( file_hosts_path );
763 return true;
764 }
765 else
766 {
767 qWarning() << "Unable to create the HOSTS default configuration file in" << qPrintable( file_hosts_path );
768 return false;
769 }
770 }
771
setUserRecognitionMethod(int new_value)772 void Settings::setUserRecognitionMethod( int new_value )
773 {
774 if( new_value <= 0 || new_value >= NumUserRecognitionMethods )
775 m_userRecognitionMethod = RecognizeByDefaultMethod;
776 else
777 m_userRecognitionMethod = new_value;
778 }
779
isDevelopmentVersion(const QString & v) const780 bool Settings::isDevelopmentVersion( const QString& v ) const
781 {
782 QString s_version;
783 if( v.isEmpty() )
784 s_version = QString( BEEBEEP_VERSION );
785 else
786 s_version = v;
787
788 QStringList sl = s_version.split( "." );
789 if( sl.isEmpty() )
790 {
791 qWarning() << "INVALID BEEBEEP VERSION FOUND";
792 return true;
793 }
794 int v_num = sl.last().toInt();
795 return v_num % 2 == 1;
796 }
797
version(bool build_version,bool qt_version,bool debug_info) const798 QString Settings::version( bool build_version, bool qt_version, bool debug_info ) const
799 {
800 QString s_version = QString( BEEBEEP_VERSION );
801 if( build_version )
802 s_version += QString( "-%1" ).arg( BEEBEEP_BUILD );
803
804 if( debug_info )
805 {
806 s_version += QString( "-p%2" ).arg( BEEBEEP_PROTO_VERSION );
807 #ifdef BEEBEEP_DISABLE_FILE_TRANSFER
808 s_version += QLatin1String( "-noft" );
809 #endif
810 #ifdef BEEBEEP_DISABLE_SEND_MESSAGE
811 s_version += QLatin1String( "-nosm" );
812 #endif
813 }
814
815 if( qt_version )
816 {
817 s_version += QString( "-qt%1" ).arg( qtMajorVersion() );
818 #if defined( Q_PROCESSOR_X86_64 )
819 s_version += QString( "-64bit" );
820 #else
821 s_version += QString( "-32bit" );
822 #endif
823 }
824 return s_version;
825 }
826
httpUserAgent() const827 QString Settings::httpUserAgent() const
828 {
829 return QString( "%1 %2" ).arg( programName() ).arg( version( false, false, false ) );
830 }
831
protocolVersion() const832 int Settings::protocolVersion() const
833 {
834 return BEEBEEP_PROTO_VERSION;
835 }
836
defaultMulticastGroupAddress() const837 QHostAddress Settings::defaultMulticastGroupAddress() const
838 {
839 return m_useIPv6 ? QHostAddress( QString( DEFAULT_IPV6_MULTICAST_ADDRESS ) ) : QHostAddress( QString( DEFAULT_IPV4_MULTICAST_ADDRESS ) );
840 }
841
programName() const842 QString Settings::programName() const
843 {
844 return QString( BEEBEEP_NAME );
845 }
846
organizationName() const847 QString Settings::organizationName() const
848 {
849 return QString( BEEBEEP_ORGANIZATION );
850 }
851
organizationDomain() const852 QString Settings::organizationDomain() const
853 {
854 return QString( BEEBEEP_ORGANIZATION_DOMAIN );
855 }
856
officialWebSite() const857 QString Settings::officialWebSite() const
858 {
859 return QString( BEEBEEP_WEBSITE );
860 }
861
pluginWebSite() const862 QString Settings::pluginWebSite() const
863 {
864 return officialWebSite() + QString( BEEBEEP_DOWNLOAD_WEBSITE ) + "#plugin";
865 }
866
downloadWebSite() const867 QString Settings::downloadWebSite() const
868 {
869 return officialWebSite() + QString( BEEBEEP_DOWNLOAD_WEBSITE );
870 }
871
donationWebSite() const872 QString Settings::donationWebSite() const
873 {
874 return officialWebSite() + QString( BEEBEEP_DONATE_WEBSITE );
875 }
876
helpWebSite() const877 QString Settings::helpWebSite() const
878 {
879 QString web_url = officialWebSite() + QString( BEEBEEP_HELP_WEBSITE );
880 if( m_language == "it" )
881 web_url += QString( "?lang=it_IT" );
882 else
883 web_url += QString( "?lang=en_US" );
884 return web_url;
885 }
886
languageWebSite() const887 QString Settings::languageWebSite() const
888 {
889 return officialWebSite() + QString( BEEBEEP_LANGUAGE_WEBSITE );
890 }
891
lastVersionUrl() const892 QString Settings::lastVersionUrl() const
893 {
894 return officialWebSite() + QString( BEEBEEP_LAST_VERSION_FILE );
895 }
896
newsWebSite() const897 QString Settings::newsWebSite() const
898 {
899 return officialWebSite() + QString( BEEBEEP_NEWS_WEBSITE );
900 }
901
developerWebSite() const902 QString Settings::developerWebSite() const
903 {
904 QString web_url = QString::fromLatin1( QByteArray::fromBase64( "aHR0cHM6Ly93d3cubWFyY29tYXN0cm9kZGkuY29tL2Fib3V0X21lLnBocD9sYW5nPQ==" ) );
905 if( m_language == "it" )
906 web_url += QString( "it_IT" );
907 else
908 web_url += QString( "en_US" );
909 return web_url;
910 }
911
tipsWebSite() const912 QString Settings::tipsWebSite() const
913 {
914 QString web_url = officialWebSite() + QString( BEEBEEP_TIPS_WEBSITE );
915 if( m_language == "it" )
916 web_url += QString( "?lang=it_IT" );
917 else
918 web_url += QString( "?lang=en_US" );
919 return web_url;
920 }
921
factWebSite() const922 QString Settings::factWebSite() const
923 {
924 QString web_url = officialWebSite() + QString( BEEBEEP_FACT_WEBSITE );
925 if( m_language == "it" )
926 web_url += QString( "?lang=it_IT" );
927 else
928 web_url += QString( "?lang=en_US" );
929 return web_url;
930 }
931
faqWebSite() const932 QString Settings::faqWebSite() const
933 {
934 QString web_url = officialWebSite() + QString( BEEBEEP_FAQ_WEBSITE );
935 if( m_language == "it" )
936 web_url += QString( "?lang=it_IT" );
937 else
938 web_url += QString( "?lang=en_US" );
939 return web_url;
940 }
941
hunspellVersion() const942 QString Settings::hunspellVersion() const
943 {
944 return QString( HUNSPELL_VERSION );
945 }
946
operatingSystem(bool use_long_name) const947 QString Settings::operatingSystem( bool use_long_name ) const
948 {
949 QString os_name_long = "Unknown OS";
950 QString os_name_short = "unknown";
951 #ifdef Q_OS_WIN
952 os_name_long = "Microsoft Windows";
953 os_name_short = "Windows";
954 #endif
955 #ifdef Q_OS_LINUX
956 os_name_long = "Linux";
957 os_name_short = "Linux";
958 #endif
959 #ifdef Q_OS_MAC
960 os_name_long = "Apple MacOSX";
961 os_name_short = "MacOSX";
962 #endif
963 #ifdef Q_OS_OS2
964 os_name_long = "OS/2";
965 os_name_short = "OS2";
966 #endif
967 #ifdef BEEBEEP_FOR_RASPBERRY_PI
968 os_name_long = "Raspberry PI";
969 os_name_short = "PI";
970 #endif
971 return use_long_name ? os_name_long : os_name_short;
972 }
973
operatingSystemIconPath() const974 QString Settings::operatingSystemIconPath() const
975 {
976 QString os_icon_path = "beebeep.png";
977
978 #ifdef Q_OS_WIN
979 os_icon_path = "windows.png";
980 #endif
981 #ifdef Q_OS_LINUX
982 os_icon_path = "linux.png";
983 #endif
984 #ifdef Q_OS_MAC
985 os_icon_path = "macosx.png";
986 #endif
987 #ifdef Q_OS_OS2
988 os_icon_path = "os2.png";
989 #endif
990 #ifdef BEEBEEP_FOR_RASPBERRY_PI
991 os_icon_path = "raspberry-pi.png";
992 #endif
993 return os_icon_path;
994 }
995
checkVersionWebSite() const996 QString Settings::checkVersionWebSite() const
997 {
998 QString os_type = operatingSystem( false ).toLower();
999 return officialWebSite() + QString( "%1?beebeep-version=%2&beebeep-os=%3" ).arg( QString( BEEBEEP_CHECK_VERSION_WEBSITE ) ).arg( QString( BEEBEEP_VERSION ) ).arg( os_type );
1000 }
1001
languageFilePath(const QString & language_folder,const QString & language_selected) const1002 QString Settings::languageFilePath( const QString& language_folder, const QString& language_selected ) const
1003 {
1004 return Bee::convertToNativeFolderSeparator( QString( "%1/%2_%3.qm" ).arg( language_folder, Settings::instance().programName().toLower(), language_selected ) );
1005 }
1006
dnsRecord() const1007 QString Settings::dnsRecord() const
1008 {
1009 return QString( BEEBEEP_DNS_RECORD );
1010 }
1011
gaTrackingId() const1012 QString Settings::gaTrackingId() const
1013 {
1014 return QString( BEEBEEP_GA_TRACKING_ID );
1015 }
1016
gaUrl() const1017 QString Settings::gaUrl() const
1018 {
1019 return QString( BEEBEEP_GA_URL );
1020 }
1021
gaEventVersion() const1022 QString Settings::gaEventVersion() const
1023 {
1024 return QString( BEEBEEP_GA_EVENT_VERSION );
1025 }
1026
hash(const QString & string_to_hash) const1027 QByteArray Settings::hash( const QString& string_to_hash ) const
1028 {
1029 QByteArray hash_pre = string_to_hash.toUtf8() + m_password;
1030 if( !m_signature.isEmpty() )
1031 hash_pre += m_signature.toUtf8();
1032 QByteArray hash_generated = QCryptographicHash::hash( hash_pre, QCryptographicHash::Sha1 );
1033 return hash_generated.toHex();
1034 }
1035
simpleHash(const QString & string_to_hash) const1036 QString Settings::simpleHash( const QString& string_to_hash ) const
1037 {
1038 #if QT_VERSION >= 0x050000
1039 QByteArray hash_generated = QCryptographicHash::hash( string_to_hash.toUtf8(), QCryptographicHash::Sha256 );
1040 #else
1041 QByteArray hash_generated = QCryptographicHash::hash( string_to_hash.toUtf8(), QCryptographicHash::Sha1 );
1042 #endif
1043 return QString::fromLatin1( hash_generated.toHex() );
1044 }
1045
setPassword(const QString & new_value)1046 void Settings::setPassword( const QString& new_value )
1047 {
1048 m_passwordBeforeHash = new_value;
1049 QString pwd_tmp = new_value.isEmpty() || new_value == defaultPassword() ? QString( "*6475*" ) : new_value;
1050 if( !m_signature.isEmpty() )
1051 pwd_tmp.prepend( m_signature );
1052 m_password = QCryptographicHash::hash( pwd_tmp.toUtf8(), QCryptographicHash::Sha1 ).toHex();
1053 }
1054
currentHash() const1055 QString Settings::currentHash() const
1056 {
1057 return QString::fromUtf8( hash( m_localUser.name() ) );
1058 }
1059
hostAddressToListen()1060 QHostAddress Settings::hostAddressToListen()
1061 {
1062 #if QT_VERSION >= 0x050000
1063 return m_useIPv6 ? QHostAddress::Any : QHostAddress::AnyIPv4;
1064 #else
1065 return m_useIPv6 ? QHostAddress::AnyIPv6 : QHostAddress::Any;
1066 #endif
1067 }
1068
setLocalUserHost(const QHostAddress & host_address,quint16 host_port)1069 void Settings::setLocalUserHost( const QHostAddress& host_address, quint16 host_port )
1070 {
1071 if( host_address.isNull() || host_address.toString() == QString( "0.0.0.0" ) )
1072 m_localUser.setNetworkAddress( NetworkAddress( m_useIPv6 ? QHostAddress::LocalHostIPv6 : QHostAddress::LocalHost, host_port ) );
1073 else
1074 m_localUser.setNetworkAddress( NetworkAddress( host_address, host_port ) );
1075 }
1076
defaultHostsFilePath() const1077 QString Settings::defaultHostsFilePath() const
1078 {
1079 return findFileInFolders( QLatin1String( "beehosts.ini" ), resourceFolders() );
1080 }
1081
loadBroadcastAddressesFromFileHosts()1082 void Settings::loadBroadcastAddressesFromFileHosts()
1083 {
1084 if( !m_broadcastAddressesInFileHosts.isEmpty() )
1085 m_broadcastAddressesInFileHosts.clear();
1086
1087 QString hosts_file_path = defaultHostsFilePath();
1088 if( hosts_file_path.isNull() )
1089 {
1090 qDebug() << "File beehosts.ini not found";
1091 return;
1092 }
1093
1094 QFile file( hosts_file_path );
1095 if( !file.open( QIODevice::ReadOnly ) )
1096 {
1097 qWarning() << "Cannot open file HOSTS in path" << qPrintable( hosts_file_path );
1098 return;
1099 }
1100
1101 qDebug() << "Reading HOSTS from file" << qPrintable( hosts_file_path );
1102 QString address_string;
1103 QString line_read;
1104 int num_lines = 0;
1105 char c;
1106 int hosts_found = 0;
1107
1108 while( !file.atEnd() )
1109 {
1110 num_lines++;
1111 line_read = file.readLine();
1112 if( line_read.size() > 0 )
1113 {
1114 address_string = line_read.simplified();
1115
1116 if( address_string.size() > 0 )
1117 {
1118 c = address_string.at( 0 ).toLatin1();
1119 if( c == '#' || c == '/' || c == '*' )
1120 continue;
1121
1122 NetworkAddress na = NetworkAddress::fromString( address_string );
1123 if( !na.isHostAddressValid() )
1124 {
1125 qWarning() << "Invalid broadcast address found in line" << num_lines << ":" << address_string;
1126 continue;
1127 }
1128
1129 if( m_broadcastAddressesInFileHosts.contains( address_string ) )
1130 {
1131 qDebug() << "Broadcast address is already in list";
1132 continue;
1133 }
1134
1135 qDebug() << "Adding broadcast address:" << address_string;
1136 m_broadcastAddressesInFileHosts << address_string;
1137 hosts_found++;
1138 }
1139 }
1140 }
1141
1142 qDebug() << "HOSTS file read:" << hosts_found << "IP addresses found";
1143 file.close();
1144 }
1145
currentSettingsFilePath() const1146 QString Settings::currentSettingsFilePath() const
1147 {
1148 if( m_useSettingsFileIni )
1149 return defaultSettingsFilePath();
1150 else
1151 return QLatin1String( "Native OS Settings" );
1152 }
1153
checkFilePath(const QString & file_path,const QString & default_value)1154 QString Settings::checkFilePath( const QString& file_path, const QString& default_value )
1155 {
1156 QFile file( file_path );
1157 return file.exists() ? file_path : default_value;
1158 }
1159
checkFolderPath(const QString & folder_path,const QString & default_value,bool check_writable)1160 QString Settings::checkFolderPath( const QString& folder_path, const QString& default_value, bool check_writable )
1161 {
1162 if( folder_path.isEmpty() )
1163 return default_value;
1164
1165 if( check_writable )
1166 {
1167 if( Bee::folderIsWriteable( folder_path, false ) )
1168 return folder_path;
1169 }
1170 else
1171 {
1172 if( QFile::exists( folder_path ) )
1173 return folder_path;
1174 }
1175
1176 qWarning() << "The folder" << folder_path << "load in settings is not usable and" << default_value << "is taken by default";
1177 return default_value;
1178 }
1179
objectSettings() const1180 QSettings* Settings::objectSettings() const
1181 {
1182 QSettings *sets;
1183
1184 if( m_useSettingsFileIni )
1185 {
1186 sets = new QSettings( defaultSettingsFilePath(), QSettings::IniFormat );
1187 sets->setFallbacksEnabled( false );
1188 }
1189 else
1190 sets = new QSettings( QSettings::NativeFormat, QSettings::UserScope, organizationName(), programName() );
1191
1192 if( !sets->isWritable() )
1193 qWarning() << sets->fileName() << "is not a writable path. Settings cannot be saved.";
1194 // remember to delete it
1195 return sets;
1196 }
1197
load()1198 void Settings::load()
1199 {
1200 qDebug() << "Loading settings";
1201 QSettings *sets = objectSettings();
1202 #ifdef Q_OS_WIN
1203 if( m_useSettingsFileIni )
1204 m_currentFilePath = Bee::convertToNativeFolderSeparator( sets->fileName() );
1205 else
1206 m_currentFilePath = ""; // registry path
1207 #else
1208 m_currentFilePath = Bee::convertToNativeFolderSeparator( sets->fileName() );
1209 #endif
1210 beeApp->setSettingsFilePath( m_currentFilePath );
1211
1212 m_firstTime = sets->allKeys().isEmpty();
1213 sets->beginGroup( "Version" );
1214 m_settingsVersion = sets->value( "Settings", BEEBEEP_SETTINGS_VERSION ).toInt();
1215 m_dataStreamVersion = sets->value( "DataStream", static_cast<int>(DATASTREAM_VERSION_1) ).toInt();
1216 m_settingsCreationDate = sets->value( "BeeBang", QDate() ).toDate();
1217 if( m_settingsCreationDate.isNull() )
1218 m_settingsCreationDate = QDate::currentDate();
1219 QString qt_version_in_settings = sets->value( "Qt", qtMajorMinorVersion() ).toString();
1220 sets->endGroup();
1221
1222 bool qt_is_compatible = qt_version_in_settings == qtMajorMinorVersion();
1223 loadCommonSettings( sets );
1224
1225 sets->beginGroup( "VCard" );
1226 VCard vc;
1227 vc.setNickName( sets->value( "NickName", m_localUser.vCard().nickName() ).toString() );
1228 vc.setFirstName( sets->value( "FirstName", m_localUser.vCard().firstName() ).toString() );
1229 vc.setLastName( sets->value( "LastName", m_localUser.vCard().lastName() ).toString() );
1230 QDate dt = sets->value( "Birthday", m_localUser.vCard().birthday() ).toDate();
1231 if( dt.isValid() )
1232 vc.setBirthday( dt );
1233 vc.setEmail( sets->value( "Email", m_localUser.vCard().email() ).toString() );
1234 QPixmap pix = sets->value( "Photo", m_localUser.vCard().photo() ).value<QPixmap>();
1235 if( !pix.isNull() )
1236 vc.setPhoto( pix );
1237 vc.setPhoneNumber( sets->value( "Phone", m_localUser.vCard().phoneNumber() ).toString() );
1238 vc.setInfo( sets->value( "Info", m_localUser.vCard().info() ).toString() );
1239 m_localUser.setVCard( vc );
1240 sets->endGroup();
1241
1242 sets->beginGroup( "Gui" );
1243 if( m_resetGeometryAtStartup || m_settingsVersion < 9 || !qt_is_compatible )
1244 {
1245 m_guiGeometry = "";
1246 m_guiState = "";
1247 m_floatingChatGeometry = "";
1248 m_floatingChatState = "";
1249 m_floatingChatSplitterState = "";
1250 m_mainBarIconSize = QSize( 24, 24 );
1251 m_avatarIconSize = QSize( 28, 28 );
1252 m_previewFileDialogGeometry = "";
1253 m_createMessageGeometry = "";
1254 m_fileSharingGeometry = "";
1255 qDebug() << "The geometry has been reset at startup";
1256 }
1257 else
1258 {
1259 m_guiGeometry = sets->value( "MainWindowGeometry", "" ).toByteArray();
1260 m_guiState = sets->value( "MainWindowState", "" ).toByteArray();
1261 m_floatingChatGeometry = sets->value( "FloatingChatGeometry", "" ).toByteArray();
1262 m_floatingChatState = sets->value( "FloatingChatState", "" ).toByteArray();
1263 m_floatingChatSplitterState = sets->value( "FloatingChatSplitterState", "" ).toByteArray();
1264 m_previewFileDialogGeometry = sets->value( "PreviewFileDialogGeometry", "" ).toByteArray();
1265 m_createMessageGeometry = sets->value( "CreateMessageGeometry", "" ).toByteArray();
1266 m_fileSharingGeometry = sets->value( "FileSharingGeometry", "" ).toByteArray();
1267 }
1268
1269 #if QT_VERSION == 0x050906
1270 if( m_settingsVersion < 11 )
1271 {
1272 // Bug in restore state for QDockWidgets
1273 // https://bugreports.qt.io/browse/QTBUG-68939
1274 m_guiState = "";
1275 m_floatingChatState = "";
1276 }
1277 #endif
1278
1279 #if QT_VERSION >= 0x050000
1280 m_lastDirectorySelected = Bee::convertToNativeFolderSeparator( sets->value( "LastDirectorySelected", QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation ) ).toString() );
1281 m_downloadDirectory = Bee::convertToNativeFolderSeparator( sets->value( "DownloadDirectory", QStandardPaths::writableLocation( QStandardPaths::DownloadLocation ) ).toString() );
1282 #else
1283 m_lastDirectorySelected = Bee::convertToNativeFolderSeparator( sets->value( "LastDirectorySelected", QDesktopServices::storageLocation( QDesktopServices::DocumentsLocation ) ).toString() );
1284 m_downloadDirectory = Bee::convertToNativeFolderSeparator( sets->value( "DownloadDirectory", QDesktopServices::storageLocation( QDesktopServices::DocumentsLocation ) ).toString() );
1285 #endif
1286 m_downloadDirectory = checkFolderPath( m_downloadDirectory, defaultDownloadFolderPath(), true );
1287 m_lastDirectorySelected = checkFolderPath( m_lastDirectorySelected, dataFolder(), false );
1288 m_logPath = checkFolderPath( Bee::convertToNativeFolderSeparator( sets->value( "LogFolderPath", dataFolder() ).toString() ), dataFolder(), true );
1289 QString plugin_folder_path = defaultPluginFolderPath();
1290 m_pluginPath = checkFolderPath( Bee::convertToNativeFolderSeparator( sets->value( "PluginPath", plugin_folder_path ).toString() ), plugin_folder_path, false );
1291 QString language_folder_path = defaultLanguageFolderPath();
1292 m_languagePath = checkFolderPath( Bee::convertToNativeFolderSeparator( sets->value( "LanguagePath", language_folder_path ).toString() ), language_folder_path, false );
1293 m_beepFilePath = checkFilePath( Bee::convertToNativeFolderSeparator( sets->value( "BeepFilePath", defaultBeepFilePath() ).toString() ), defaultBeepFilePath() );
1294 sets->endGroup();
1295
1296 sets->beginGroup( "Plugin" );
1297 QStringList key_list = sets->value( "List", QStringList() ).toStringList();
1298 if( !key_list.isEmpty() )
1299 {
1300 QStringList plugin_settings_tmp;
1301 QStringList::const_iterator it = key_list.constBegin();
1302 while( it != key_list.constEnd() )
1303 {
1304 plugin_settings_tmp = sets->value( *it, QStringList() ).toStringList();
1305 if( !plugin_settings_tmp.isEmpty() )
1306 setPluginSettings( *it, plugin_settings_tmp );
1307 ++it;
1308 }
1309 }
1310 sets->endGroup();
1311
1312 if( !m_allowEditNickname && userRecognitionMethod() != Settings::RecognizeByNickname )
1313 {
1314 if( m_localUser.name() != m_localUser.accountName() )
1315 {
1316 qWarning() << "AllowEditNickname is disabled but nickname changed to" << qPrintable( m_localUser.name() );
1317 qDebug() << "Restoring system account name:" << qPrintable( m_localUser.accountName() );
1318 m_localUser.setName( m_localUser.accountName() );
1319 }
1320 }
1321
1322 m_lastSave = QDateTime::currentDateTime();
1323 qDebug() << "Loading host addresses from file HOSTS";
1324 Settings::instance().loadBroadcastAddressesFromFileHosts();
1325 qDebug() << "Loading settings completed";
1326 delete sets;
1327 }
1328
1329
beginCommonGroup(QSettings * system_rc,QSettings * user_ini,const QString & group_name)1330 void Settings::beginCommonGroup( QSettings* system_rc, QSettings* user_ini, const QString& group_name )
1331 {
1332 if( system_rc )
1333 system_rc->beginGroup( group_name );
1334 if( user_ini )
1335 user_ini->beginGroup( group_name );
1336 }
1337
endCommonGroup(QSettings * system_rc,QSettings * user_ini)1338 void Settings::endCommonGroup( QSettings* system_rc, QSettings* user_ini )
1339 {
1340 if( system_rc )
1341 system_rc->endGroup();
1342 if( user_ini )
1343 user_ini->endGroup();
1344 }
1345
commonValue(QSettings * system_rc,QSettings * user_ini,const QString & key,const QVariant & default_value)1346 QVariant Settings::commonValue( QSettings* system_rc, QSettings* user_ini, const QString& key, const QVariant& default_value )
1347 {
1348 if( system_rc && user_ini )
1349 return system_rc->value( key, user_ini->value( key, default_value ) );
1350 else if( system_rc )
1351 return system_rc->value( key, default_value );
1352 else if( user_ini )
1353 return user_ini->value( key, default_value );
1354 else
1355 return default_value;
1356 }
1357
loadCommonSettings(QSettings * user_ini)1358 void Settings::loadCommonSettings( QSettings* user_ini )
1359 {
1360 qDebug() << "Loading settings eventually overruled by RC file";
1361 QSettings* system_rc = objectRcSettings();
1362 beginCommonGroup( system_rc, user_ini, "Chat" );
1363 QString chat_font_string = commonValue( system_rc, user_ini, "Font", "" ).toString();
1364
1365 if( !chat_font_string.isEmpty() )
1366 {
1367 QFont f;
1368 if( f.fromString( chat_font_string ) )
1369 setChatFont( f );
1370 else
1371 qWarning() << "Invalid font string found in ChatFont setting value:" << chat_font_string;
1372 }
1373 else
1374 setChatFont( QApplication::font() );
1375 m_chatFontColor = commonValue( system_rc, user_ini, "FontColor", QColor( Qt::black ).name() ).toString();
1376 m_defaultChatBackgroundColor = commonValue( system_rc, user_ini, "DefaultChatBackgroundColor", m_defaultChatBackgroundColor ).toString();
1377 m_chatCompact = commonValue( system_rc, user_ini, "CompactMessage", true ).toBool();
1378 m_chatShowMessageTimestamp = commonValue( system_rc, user_ini, "ShowMessageTimestamp", true ).toBool();
1379 m_beepOnNewMessageArrived = commonValue( system_rc, user_ini, "BeepOnNewMessageArrived", true ).toBool();
1380 m_disableBeepInUserStatusBusy = commonValue( system_rc, user_ini, "DisableBeepInUserStatusBusy", false ).toBool();
1381 m_beepInActiveWindowAlso = commonValue( system_rc, user_ini, "EnableBeepInActiveWindow", false ).toBool();
1382 m_chatUseHtmlTags = commonValue( system_rc, user_ini, "UseHtmlTags", false ).toBool();
1383 m_chatUseClickableLinks = commonValue( system_rc, user_ini, "UseClickableLinks", true ).toBool();
1384 m_chatMessageHistorySize = commonValue( system_rc, user_ini, "MessageHistorySize", 10 ).toInt();
1385 m_showEmoticons = commonValue( system_rc, user_ini, "ShowEmoticons", true ).toBool();
1386 m_showMessagesGroupByUser = commonValue( system_rc, user_ini, "ShowMessagesGroupByUsers", true ).toBool();
1387 m_chatMessageFilter = commonValue( system_rc, user_ini, "MessageFilter", m_chatMessageFilter ).toBitArray();
1388 if( m_chatMessageFilter.size() < static_cast<int>(ChatMessage::NumTypes) )
1389 m_chatMessageFilter.resize( static_cast<int>(ChatMessage::NumTypes) );
1390 m_showOnlyMessagesInDefaultChat = commonValue( system_rc, user_ini, "ShowOnlyMessagesInDefaultChat", true ).toBool();
1391 m_chatMessagesToShow = commonValue( system_rc, user_ini, "MaxMessagesToShow", defaultChatMessagesToShow() ).toInt();
1392 m_imagePreviewHeight = qMax( 48, commonValue( system_rc, user_ini, "ImagePreviewHeight", 160 ).toInt() );
1393 m_useReturnToSendMessage = commonValue( system_rc, user_ini, "UseKeyReturnToSendMessage", m_useReturnToSendMessage ).toBool();
1394 m_chatUseYourNameInsteadOfYou = commonValue( system_rc, user_ini, "UseYourNameInsteadOfYou", false ).toBool();
1395 m_chatClearAllReadMessages = commonValue( system_rc, user_ini, "ClearAllReadMessages", false ).toBool();
1396 m_chatUseColoredUserNames = commonValue( system_rc, user_ini, "UseColoredUserNames", true ).toBool();
1397 m_chatDefaultUserNameColor = commonValue( system_rc, user_ini, "DefaultUserNameColor", "#000" ).toString();
1398 m_chatActiveWindowOpacityLevel = qMax( 10, qMin( 100, commonValue( system_rc, user_ini, "ActiveWindowOpacityLevel", m_chatActiveWindowOpacityLevel ).toInt() ) );
1399 m_chatInactiveWindowOpacityLevel = qMax( 10, qMin( 100, commonValue( system_rc, user_ini, "InactiveWindowOpacityLevel", m_chatInactiveWindowOpacityLevel ).toInt() ) );
1400 m_chatBackgroundColor = commonValue( system_rc, user_ini, "BackgroundColor", m_chatBackgroundColor ).toString();
1401 m_chatDefaultTextColor = commonValue( system_rc, user_ini, "DefaultTextColor", m_chatDefaultTextColor ).toString();
1402 m_chatSystemTextColor = commonValue( system_rc, user_ini, "SystemTextColor", m_chatSystemTextColor ).toString();
1403 m_enableDefaultChatNotifications = commonValue( system_rc, user_ini, "EnableDefaultChatNotifications", m_enableDefaultChatNotifications ).toBool();
1404 m_useMessageTimestampWithAP = commonValue( system_rc, user_ini, "UseMessageTimestampWithAP", m_useMessageTimestampWithAP ).toBool();
1405 m_chatQuoteBackgroundColor = commonValue( system_rc, user_ini, "QuoteBackgroundColor", m_chatQuoteBackgroundColor ).toString();
1406 m_chatQuoteTextColor = commonValue( system_rc, user_ini, "QuoteTextColor", m_chatQuoteTextColor ).toString();
1407 m_chatOnSendingMessage = commonValue( system_rc, user_ini, "CloseOnSendingMessage", SkipOnSendingMessage ).toInt();
1408 if( m_chatOnSendingMessage < 0 || m_chatOnSendingMessage >= NumChatOnSendingMessageTypes )
1409 m_chatOnSendingMessage = SkipOnSendingMessage;
1410 endCommonGroup( system_rc, user_ini );
1411
1412 beginCommonGroup( system_rc, user_ini, "User" );
1413 setUserRecognitionMethod( commonValue( system_rc, user_ini, "RecognitionMethod", m_userRecognitionMethod ).toInt() );
1414 m_localUser.setHash( user_ini->value( "LocalHash", m_localUser.hash() ).toString() );
1415 m_localUser.setName( user_ini->value( "LocalName", m_localUser.name() ).toString() );
1416 m_localUser.setColor( user_ini->value( "LocalColor", m_localUser.color() ).toString() );
1417 m_localUser.setStatusDescription( user_ini->value( "LocalLastStatusDescription", m_localUser.statusDescription() ).toString() );
1418 m_autoUserAway = commonValue( system_rc, user_ini, "AutoAwayStatus", false ).toBool();
1419 m_userAwayTimeout = qMax( commonValue( system_rc, user_ini, "UserAwayTimeout", 10 ).toInt(), 1 ); // minutes
1420 if( m_useEasyConnection )
1421 {
1422 m_useDefaultPassword = true;
1423 m_askChangeUserAtStartup = false;
1424 m_askPasswordAtStartup = false;
1425 }
1426 else
1427 {
1428 m_useDefaultPassword = user_ini->value( "UseDefaultPassword", true ).toBool();
1429 m_askChangeUserAtStartup = user_ini->value( "AskChangeUserAtStartup", m_firstTime ).toBool();
1430 m_askPasswordAtStartup = user_ini->value( "AskPasswordAtStartup", false ).toBool();
1431 }
1432
1433 m_savePassword = user_ini->value( "SavePassword", false ).toBool();
1434 QString enc_pass = "";
1435 if( m_savePassword )
1436 enc_pass = simpleDecrypt( user_ini->value( "EncPwd", "" ).toString() );
1437 setPassword( enc_pass );
1438 m_saveUserList = commonValue( system_rc, user_ini, "SaveUsers", m_saveUserList ).toBool();
1439 QString user_list = user_ini->value( "List", "" ).toString();
1440 if( !user_list.isEmpty() )
1441 m_userList = simpleDecrypt( user_list ).split( QString( "\n" ) );
1442 else
1443 m_userList = QStringList();
1444 QString user_status_list = user_ini->value( "StatusList", "" ).toString();
1445 if( !user_status_list.isEmpty() )
1446 m_userStatusList = simpleDecrypt( user_status_list ).split( QString( "\n" ) );
1447 else
1448 m_userStatusList = QStringList();
1449 m_refusedChats = user_ini->value( "RefusedChats", QStringList() ).toStringList();
1450
1451 m_maxUserStatusDescriptionInList = commonValue( system_rc, user_ini, "MaxStatusDescriptionInList", m_maxUserStatusDescriptionInList ).toInt();
1452 m_presetMessages = commonValue( system_rc, user_ini, "PresetMessages", QMap<QString,QVariant>() ).toMap();
1453 m_maxDaysOfUserInactivity = commonValue( system_rc, user_ini, "MaxDaysOfUserInactivity", m_maxDaysOfUserInactivity ).toInt();
1454 m_removeInactiveUsers = commonValue( system_rc, user_ini, "RemoveInactiveUsers", true ).toBool();
1455 endCommonGroup( system_rc, user_ini );
1456
1457 beginCommonGroup( system_rc, user_ini, "Gui" );
1458 m_mainBarIconSize = commonValue( system_rc, user_ini, "MainBarIconSize", QSize( 24, 24 ) ).toSize();
1459 m_avatarIconSize = commonValue( system_rc, user_ini, "AvatarIconSize", QSize( 28, 28 ) ).toSize();
1460 m_resetGeometryAtStartup = commonValue( system_rc, user_ini, "ResetWindowGeometryAtStartup", m_resetGeometryAtStartup ).toBool();
1461 m_saveGeometryOnExit = commonValue( system_rc, user_ini, "SaveGeometryOnExit", m_saveGeometryOnExit ).toBool();
1462 m_language = commonValue( system_rc, user_ini, "Language", QLocale::system().name() ).toString();
1463 if( m_language.size() > 2 )
1464 m_language.resize( 2 );
1465 m_keyEscapeMinimizeInTray = commonValue( system_rc, user_ini, "KeyEscapeMinimizeInTray", true ).toBool();
1466 #ifdef Q_OS_MAC
1467 m_closeMinimizeInTray = false;
1468 #else
1469 if( m_settingsVersion < 18 )
1470 m_closeMinimizeInTray = commonValue( system_rc, user_ini, "MinimizeInTray", true ).toBool();
1471 else
1472 m_closeMinimizeInTray = commonValue( system_rc, user_ini, "CloseMinimizeInTray", true ).toBool();
1473 #endif
1474 m_stayOnTop = commonValue( system_rc, user_ini, "StayOnTop", false ).toBool();
1475 m_raiseOnNewMessageArrived = commonValue( system_rc, user_ini, "RaiseOnNewMessageArrived", false ).toBool();
1476 m_raiseMainWindowOnNewMessageArrived = commonValue( system_rc, user_ini, "RaiseMainWindowOnNewMessageArrived", false ).toBool();
1477 m_alwaysShowFileTransferProgress = commonValue( system_rc, user_ini, "AlwaysShowFileTransferProgress", false ).toBool();
1478 m_alwaysOpenChatOnNewMessageArrived = commonValue( system_rc, user_ini, "AlwaysOpenChatOnNewMessageArrived", true ).toBool();
1479 m_loadOnTrayAtStartup = commonValue( system_rc, user_ini, "LoadOnTrayAtStartup", false ).toBool();
1480 m_showNotificationOnTray = commonValue( system_rc, user_ini, "ShowNotificationOnTray", true ).toBool();
1481 m_showOnlyMessageNotificationOnTray = commonValue( system_rc, user_ini, "ShowOnlyMessageNotificationOnTray", true ).toBool();
1482 m_trayMessageTimeout = qMax( commonValue( system_rc, user_ini, "ShowNotificationOnTrayTimeout", 10000 ).toInt(), 1000 );
1483 m_showChatMessageOnTray = commonValue( system_rc, user_ini, "ShowChatMessageOnTray", false ).toBool();
1484 m_textSizeInChatMessagePreviewOnTray = commonValue( system_rc, user_ini, "TextSizeInChatMessagePreviewOnTray", 40 ).toInt();
1485 m_showFileTransferCompletedOnTray = commonValue( system_rc, user_ini, "ShowFileTransferCompletedOnTray", true ).toBool();
1486 m_chatAutoSave = commonValue( system_rc, user_ini, "ChatAutoSave", true ).toBool();
1487 m_tickIntervalChatAutoSave = commonValue( system_rc, user_ini, "TickIntervalChatAutoSave", m_tickIntervalChatAutoSave ).toInt();
1488 m_chatSaveUnsentMessages = commonValue( system_rc, user_ini, "ChatSaveUnsentMessages", true ).toBool();
1489 m_chatMaxLineSaved = commonValue( system_rc, user_ini, "ChatMaxLineSaved", 9000 ).toInt();
1490 m_chatSaveFileTransfers = commonValue( system_rc, user_ini, "ChatSaveFileTransfers", m_chatAutoSave ).toBool();
1491 m_chatSaveSystemMessages = commonValue( system_rc, user_ini, "ChatSaveSystemMessages", false ).toBool();
1492 m_showChatToolbar = commonValue( system_rc, user_ini, "ShowChatToolbar", true ).toBool();
1493 m_showOnlyOnlineUsers = commonValue( system_rc, user_ini, "ShowOnlyOnlineUsers", false ).toBool();
1494 m_showUserPhoto = commonValue( system_rc, user_ini, "ShowUserPhoto", true ).toBool();
1495 m_showVCardOnRightClick = commonValue( system_rc, user_ini, "ShowVCardOnRightClick", true ).toBool();
1496 m_showEmoticonMenu = commonValue( system_rc, user_ini, "ShowEmoticonMenu", false ).toBool();
1497 m_showPresetMessages = commonValue( system_rc, user_ini, "ShowPresetMessages", false ).toBool();
1498 m_emoticonSizeInEdit = qMax( 12, commonValue( system_rc, user_ini, "EmoticonSizeInEdit", m_emoticonSizeInEdit ).toInt() );
1499 m_emoticonSizeInChat = qMax( 12, commonValue( system_rc, user_ini, "EmoticonSizeInChat", m_emoticonSizeInChat ).toInt() );
1500 m_emoticonSizeInMenu = commonValue( system_rc, user_ini, "EmoticonSizeInMenu", m_emoticonSizeInMenu ).toInt();
1501 m_emoticonInRecentMenu = commonValue( system_rc, user_ini, "EmoticonsInRecentMenu", m_emoticonInRecentMenu ).toInt();
1502 m_favoriteEmoticons = user_ini->value( "FavoriteEmoticons", QStringList() ).toStringList();
1503 m_recentEmoticons = user_ini->value( "RecentEmoticons", QStringList() ).toStringList();
1504 m_useFontEmoticons = commonValue( system_rc, user_ini, "UseFontEmoticons", m_useFontEmoticons ).toBool();
1505 #if QT_VERSION >= 0x050000
1506 m_useHiResEmoticons = commonValue( system_rc, user_ini, "UseHighResolutionEmoticons", m_useHiResEmoticons ).toBool();
1507 #else
1508 m_useHiResEmoticons = false;
1509 #endif
1510 m_showMinimizedAtStartup = commonValue( system_rc, user_ini, "ShowMinimizedAtStartup", m_startMinimized ).toBool();
1511 m_promptOnCloseEvent = commonValue( system_rc, user_ini, "PromptOnCloseEvent", m_promptOnCloseEvent ).toBool();
1512 m_showUserStatusBackgroundColor = commonValue( system_rc, user_ini, "ShowUserStatusBackgroundColor", false ).toBool();
1513 m_showUserStatusDescription = commonValue( system_rc, user_ini, "ShowUserStatusDescription", true ).toBool();
1514 m_shortcuts = commonValue( system_rc, user_ini, "Shortcuts", QStringList() ).toStringList();
1515 m_useShortcuts = commonValue( system_rc, user_ini, "UseShortcuts", false ).toBool();
1516 m_useNativeDialogs = commonValue( system_rc, user_ini, "UseNativeFileDialogs", m_useNativeDialogs ).toBool();
1517 m_homeShowMessageTimestamp = commonValue( system_rc, user_ini, "ShowActivitiesTimestamp", false ).toBool();
1518 m_homeBackgroundColor = commonValue( system_rc, user_ini, "HomeBackgroundColor", m_homeBackgroundColor ).toString();
1519 m_userListBackgroundColor = commonValue( system_rc, user_ini, "UserListBackgroundColor", m_userListBackgroundColor ).toString();
1520 m_chatListBackgroundColor = commonValue( system_rc, user_ini, "ChatListBackgroundColor", m_chatListBackgroundColor ).toString();
1521 m_groupListBackgroundColor = commonValue( system_rc, user_ini, "GroupListBackgroundColor", m_groupListBackgroundColor ).toString();
1522 m_savedChatListBackgroundColor = commonValue( system_rc, user_ini, "SavedChatListBackgroundColor", m_savedChatListBackgroundColor ).toString();
1523 m_usePreviewFileDialog = commonValue( system_rc, user_ini, "UsePreviewFileDialog", m_usePreviewFileDialog ).toBool();
1524 m_previewFileDialogImageSize = qMax( 100, commonValue( system_rc, user_ini, "PreviewFileDialogImageSize", m_previewFileDialogImageSize ).toInt() );
1525 m_userSortingMode = qMax( 0, commonValue( system_rc, user_ini, "UserSortingMode", 0 ).toInt() );
1526 m_sortUsersAscending = commonValue( system_rc, user_ini, "SortUsersAscending", true ).toBool();
1527 m_showTextInModeRTL = commonValue( system_rc, user_ini, "ShowChatTextInModeRTL", m_showTextInModeRTL ).toBool();
1528 m_playBuzzSound = commonValue( system_rc, user_ini, "PlayBuzzSound", true ).toBool();
1529 bool open_chat_in_new_window = commonValue( system_rc, user_ini, "AlwaysOpenNewFloatingChat", !m_showChatsInOneWindow ).toBool();
1530 m_showChatsInOneWindow = commonValue( system_rc, user_ini, "ShowChatsInOneWindow", !open_chat_in_new_window ).toBool();
1531 m_iconSourcePath = commonValue( system_rc, user_ini, "IconSourcePath", m_iconSourcePath ).toString();
1532 m_emoticonSourcePath = commonValue( system_rc, user_ini, "EmoticonSourcePath", m_emoticonSourcePath ).toString();
1533 m_maxChatsToOpenAfterSendingMessage = commonValue( system_rc, user_ini, "MaxChatsToOpenAfterSendingMessage", m_maxChatsToOpenAfterSendingMessage ).toInt();
1534 m_showUsersOnConnection = commonValue( system_rc, user_ini, "ShowUsersOnConnection", m_showUsersOnConnection ).toBool();
1535 m_showChatsOnConnection = commonValue( system_rc, user_ini, "ShowChatsOnConnection", m_showChatsOnConnection ).toBool();
1536 if( m_showChatsOnConnection && m_showUsersOnConnection )
1537 m_showUsersOnConnection = false;
1538 m_hideEmptyChatsInList = commonValue( system_rc, user_ini, "HideEmptyChatsInList", m_hideEmptyChatsInList ).toBool();
1539 m_enableMaximizeButton = commonValue( system_rc, user_ini, "EnableMaximizeButton", false ).toBool();
1540 #if QT_VERSION > 0x050000
1541 m_useDarkStyle = user_ini->value( "UseDarkStyle", m_useDarkStyle ).toBool();
1542 #else
1543 m_useDarkStyle = false;
1544 #endif
1545 m_showUsersInWorkgroups = commonValue( system_rc, user_ini, "ShowUsersInWorkgroups", false ).toBool();
1546 m_openChatWhenSendNewMessage = user_ini->value( "OpenChatWhenSendNewMessage", true ).toBool();
1547 m_sendNewMessageIndividually = user_ini->value( "SendNewMessageIndividually", false ).toBool();
1548 m_useUserFirstNameFirstInFullName = commonValue( system_rc, user_ini, "ShowUserFirstNameFirstInFullName", useUserFirstNameFirstInFullNameFromLanguage() ).toBool();
1549 m_resetMinimumWidthForStyle = commonValue( system_rc, user_ini, "ResetMinimumWidthForStyle", m_resetMinimumWidthForStyle ).toBool();
1550 endCommonGroup( system_rc, user_ini );
1551
1552 beginCommonGroup( system_rc, user_ini, "Tools" );
1553 m_logToFile = commonValue( system_rc, user_ini, "LogToFile", false ).toBool();
1554 m_maxLogLines = commonValue( system_rc, user_ini, "MaxLogLines", m_maxLogLines ).toInt();
1555 m_useSpellChecker = commonValue( system_rc, user_ini, "UseSpellChecker", true ).toBool();
1556 m_useWordCompleter = commonValue( system_rc, user_ini, "UseWordCompleter", false ).toBool();
1557 m_checkNewVersionAtStartup = commonValue( system_rc, user_ini, "SearchForNewVersionAtStartup", m_checkNewVersionAtStartup ).toBool();
1558 m_postUsageStatistics = commonValue( system_rc, user_ini, "SendAnonymousUsageStatistics", m_postUsageStatistics ).toBool();
1559 m_dictionaryPath = checkFilePath( user_ini->value( "DictionaryPath", "" ).toString(), "" );
1560 m_applicationUuid = user_ini->value( "Uuid", "" ).toString();
1561 m_applicationUuidCreationDate = user_ini->value( "UuidCreationDate", QDate::currentDate() ).toDate();
1562 m_statsPostDate = user_ini->value( "StatsPostDate", QDate() ).toDate();
1563 endCommonGroup( system_rc, user_ini );
1564
1565 beginCommonGroup( system_rc, user_ini, "Misc" );
1566 m_tickIntervalCheckIdle = qMax( commonValue( system_rc, user_ini, "TickIntervalCheckIdle", m_tickIntervalCheckIdle ).toInt(), 2 );
1567 m_tickIntervalCheckNetwork = qMax( commonValue( system_rc, user_ini, "TickIntervalCheckNetwork", m_tickIntervalCheckNetwork ).toInt(), 5 );
1568 m_tickIntervalBroadcasting = qMax( commonValue( system_rc, user_ini, "TickIntervalBroadcasting", m_tickIntervalBroadcasting ).toInt(), 0 );
1569 NetworkAddress local_user_network_address = m_localUser.networkAddress();
1570 local_user_network_address.setHostPort( static_cast<quint16>(commonValue( system_rc, user_ini, "ListenerPort", DEFAULT_LISTENER_PORT ).toUInt()) );
1571 m_localUser.setNetworkAddress( local_user_network_address );
1572 m_pongTimeout = qMax( commonValue( system_rc, user_ini, "ConnectionActivityTimeout_ms", PONG_DEFAULT_TIMEOUT ).toInt(), 13000 );
1573 if( m_pongTimeout > 40000 )
1574 m_pongTimeout = 40000;
1575 m_writingTimeout = qMax( commonValue( system_rc, user_ini, "WritingTimeout_ms", 3000 ).toInt(), 3000 );
1576 m_tickIntervalConnectionTimeout = qMax( commonValue( system_rc, user_ini, "TickIntervalConnectionTimeout", m_tickIntervalConnectionTimeout ).toInt(), 5 );
1577 if( m_settingsVersion < 6 && m_tickIntervalConnectionTimeout < TICK_INTERVAL_CONNECTION_TIMEOUT )
1578 m_tickIntervalConnectionTimeout = TICK_INTERVAL_CONNECTION_TIMEOUT;
1579 m_useLowDelayOptionOnSocket = commonValue( system_rc, user_ini, "UseLowDelayOptionOnSocket", false ).toBool();
1580 m_delayConnectionAtStartup = qMax( 3000, commonValue( system_rc, user_ini, "DelayConnectionAtStartup_ms", m_delayConnectionAtStartup ).toInt() );
1581 if( m_delayConnectionAtStartup > 50000 )
1582 m_delayConnectionAtStartup = 50000;
1583 m_delayContactUsers = qMax( 7000, commonValue( system_rc, user_ini, "DelayContactUsers_ms", DELAY_CONTACT_USERS ).toInt() );
1584 if( m_delayContactUsers > 30000 )
1585 m_delayContactUsers = 30000;
1586 m_sendOfflineMessagesToDefaultChat = commonValue( system_rc, user_ini, "SendOfflineMessagesToDefaultChat", false ).toBool();
1587 m_saveMessagesTimestamp = user_ini->value( "SaveMessagesTimestamp", QDateTime() ).toDateTime();
1588 if( m_saveMessagesTimestamp.isNull() )
1589 {
1590 qDebug() << "Generating new save messages timestamp";
1591 m_saveMessagesTimestamp = QDateTime::currentDateTime();
1592 }
1593 m_clearCacheAfterDays = qMax( -1, commonValue( system_rc, user_ini, "ClearCacheAfterDays", m_clearCacheAfterDays ).toInt() );
1594 m_removePartiallyDownloadedFilesAfterDays = qMax( -1, commonValue( system_rc, user_ini, "RemovePartiallyDownloadedFilesAfterDays", m_removePartiallyDownloadedFilesAfterDays ).toInt() );
1595 endCommonGroup( system_rc, user_ini );
1596
1597 beginCommonGroup( system_rc, user_ini, "Network");
1598 QString local_host_address = user_ini->value( "LocalHostAddressForced", "" ).toString();
1599 if( !local_host_address.isEmpty() )
1600 m_localHostAddressForced = QHostAddress( local_host_address );
1601 m_networkAddressList = commonValue( system_rc, user_ini, "UserPathList", QStringList() ).toStringList();
1602 m_localSubnetForced = commonValue( system_rc, user_ini, "LocalSubnetForced", "" ).toString();
1603 m_localUser.setWorkgroups( commonValue( system_rc, user_ini, "Workgroups", QStringList() ).toStringList() );
1604 m_acceptConnectionsOnlyFromWorkgroups = commonValue( system_rc, user_ini, "AcceptConnectionsOnlyFromWorkgroups", m_acceptConnectionsOnlyFromWorkgroups ).toBool();
1605
1606 #ifdef BEEBEEP_USE_MULTICAST_DNS
1607 m_useMulticastDns = commonValue( system_rc, user_ini, "UseMulticastDns", m_useMulticastDns ).toBool();
1608 #endif
1609 m_maxUsersToConnectInATick = commonValue( system_rc, user_ini, "MaxUsersToConnectInATick", m_maxUsersToConnectInATick ).toInt();
1610 m_preventMultipleConnectionsFromSingleHostAddress = commonValue( system_rc, user_ini, "PreventMultipleConnectionsFromSingleHostAddress", m_preventMultipleConnectionsFromSingleHostAddress ).toBool();
1611 m_useHive = commonValue( system_rc, user_ini, "UseHiveProtocol", m_useHive ).toBool();
1612 m_disableSystemProxyForConnections = commonValue( system_rc, user_ini, "DisableSystemProxyForConnections", m_disableSystemProxyForConnections ).toBool();
1613 m_useDefaultMulticastGroupAddress = commonValue( system_rc, user_ini, "UseDefaultMulticastGroupAddress", m_useDefaultMulticastGroupAddress ).toBool();
1614 m_broadcastToOfflineUsers = commonValue( system_rc, user_ini, "BroadcastToOfflineUsers", m_broadcastToOfflineUsers ).toBool();
1615 m_broadcastToLocalSubnetAlways = commonValue( system_rc, user_ini, "BroadcastToLocalSubnet", m_broadcastToLocalSubnetAlways ).toBool();
1616 m_ipMulticastTtl = commonValue( system_rc, user_ini, "IpMulticastTtl", m_ipMulticastTtl ).toInt();
1617 endCommonGroup( system_rc, user_ini );
1618
1619 beginCommonGroup( system_rc, user_ini, "FileShare" );
1620 if( m_disableFileTransfer )
1621 m_enableFileTransfer = false;
1622 else
1623 m_enableFileTransfer = user_ini->value( "EnableFileTransfer", true ).toBool();
1624
1625 if( m_enableFileTransfer )
1626 {
1627 if( m_disableFileSharing )
1628 m_enableFileSharing = false;
1629 else
1630 m_enableFileSharing = user_ini->value( "EnableFileSharing", false ).toBool();
1631
1632 if( m_enableFileSharing )
1633 m_useShareBox = user_ini->value( "UseShareBox", false ).toBool();
1634 else
1635 m_useShareBox = false;
1636 }
1637 else
1638 {
1639 m_enableFileSharing = false;
1640 m_useShareBox = false;
1641 }
1642
1643 m_maxFileShared = qMax( 1024, commonValue( system_rc, user_ini, "MaxSharedFiles", 8192 ).toInt() );
1644 m_shareBoxPath = checkFolderPath( user_ini->value( "ShareBoxPath", "" ).toString(), "", false );
1645 m_maxSimultaneousDownloads = commonValue( system_rc, user_ini, "MaxSimultaneousDownloads", 3 ).toInt();
1646 m_maxQueuedDownloads = qMax( 1, commonValue( system_rc, user_ini, "MaxQueuedDownloads", 400 ).toInt() );
1647 m_fileTransferConfirmTimeout = qMax( commonValue( system_rc, user_ini, "FileTransferConfirmTimeout", 30000 ).toInt(), 1000 );
1648 m_fileTransferBufferSize = qMax( commonValue( system_rc, user_ini, "FileTransferBufferSize", 65456 ).toInt(), 2048 );
1649 int mod_buffer_size = m_fileTransferBufferSize % ENCRYPTED_DATA_BLOCK_SIZE; // For a corrected encryption
1650 if( mod_buffer_size > 0 )
1651 m_fileTransferBufferSize -= mod_buffer_size;
1652 if( m_fileTransferBufferSize < 2048 )
1653 m_fileTransferBufferSize = 2048;
1654 bool automatic_file_name = commonValue( system_rc, user_ini, "SetAutomaticFileNameOnSave", false ).toBool();
1655 if( automatic_file_name )
1656 m_onExistingFileAction = GenerateNewFileName;
1657 bool overwrite_existing_files = commonValue( system_rc, user_ini, "OverwriteExistingFiles", false ).toBool();
1658 if( overwrite_existing_files )
1659 m_onExistingFileAction = OverwriteExistingFile;
1660 m_onExistingFileAction = commonValue( system_rc, user_ini, "OnExistingFileAction", (int)m_onExistingFileAction ).toInt();
1661 if( m_onExistingFileAction < 0 || m_onExistingFileAction >= NumOnExistingFileActionTypes )
1662 m_onExistingFileAction = OverwriteOlderExistingFile;
1663 m_resumeFileTransfer = commonValue( system_rc, user_ini, "ResumeFileTransfer", m_resumeFileTransfer ).toBool();
1664 m_confirmOnDownloadFile = commonValue( system_rc, user_ini, "ConfirmOnDownloadFile", m_confirmOnDownloadFile ).toBool();
1665 m_downloadInUserFolder = commonValue( system_rc, user_ini, "DownloadInUserFolder", false ).toBool();
1666 m_keepModificationDateOnFileTransferred = commonValue( system_rc, user_ini, "KeepModificationDateOnFileTransferred", m_keepModificationDateOnFileTransferred ).toBool();
1667 QStringList local_share = user_ini->value( "ShareList", QStringList() ).toStringList();
1668 if( !local_share.isEmpty() )
1669 {
1670 foreach( QString share_path, local_share )
1671 m_localShare.append( Bee::convertToNativeFolderSeparator( share_path ) );
1672 }
1673 else
1674 m_localShare = local_share;
1675 endCommonGroup( system_rc, user_ini );
1676
1677 beginCommonGroup( system_rc, user_ini, "Group" );
1678 m_saveGroupList = commonValue( system_rc, user_ini, "SaveGroups", m_saveGroupList ).toBool();
1679 m_groupSilenced = user_ini->value( "Silenced", QStringList() ).toStringList();
1680 m_groupList = user_ini->value( "List", QStringList() ).toStringList();
1681 endCommonGroup( system_rc, user_ini );
1682
1683 beginCommonGroup( system_rc, user_ini, "ShareDesktop" );
1684 if( m_disableDesktopSharing )
1685 m_enableShareDesktop = false;
1686 else
1687 m_enableShareDesktop = commonValue( system_rc, user_ini, "Enable", m_enableShareDesktop ).toBool();
1688 m_shareDesktopCaptureDelay = qMax( 1000, commonValue( system_rc, user_ini, "CaptureScreenInterval", m_shareDesktopCaptureDelay ).toInt() );
1689 m_shareDesktopFitToScreen = commonValue( system_rc, user_ini, "FitToScreen", false ).toBool();
1690 m_shareDesktopImageType = commonValue( system_rc, user_ini, "ImageType", "png" ).toString();
1691 m_shareDesktopImageQuality = commonValue( system_rc, user_ini, "ImageQuality", 20 ).toInt();
1692 endCommonGroup( system_rc, user_ini );
1693
1694 beginCommonGroup( system_rc, user_ini, "VoiceMessage" );
1695 m_voiceMessageMaxDuration = qMax( 5, commonValue( system_rc, user_ini, "MaxDuration", m_voiceMessageMaxDuration ).toInt() );
1696 m_useVoicePlayer = commonValue( system_rc, user_ini, "UseVoicePlayer", m_useVoicePlayer ).toBool();
1697 m_voiceInputDeviceName = user_ini->value( "VoiceInputDeviceName", QString() ).toString();
1698 m_voiceFileMessageContainer = commonValue( system_rc, user_ini, "VoiceFileMessageContainer", QString() ).toString();
1699 m_voiceCodec = commonValue( system_rc, user_ini, "VoiceCodec", QString() ).toString();
1700 m_voiceSampleRate = commonValue( system_rc, user_ini, "VoiceSampleRate", 0 ).toInt();
1701 m_voiceBitRate = commonValue( system_rc, user_ini, "VoiceBitRate", 0 ).toInt();
1702 m_voiceChannels = commonValue( system_rc, user_ini, "VoiceChannels", -1 ).toInt();
1703 m_voiceEncodingMode = commonValue( system_rc, user_ini, "VoiceEncodingMode", -1 ).toInt();
1704 m_voiceEncodingQuality = commonValue( system_rc, user_ini, "VoiceEncodingQuality", -1 ).toInt();
1705 m_useCustomVoiceEncoderSettings = commonValue( system_rc, user_ini, "UseCustomVoiceEncoderSettings", m_useCustomVoiceEncoderSettings ).toBool();
1706 m_useSystemVoiceEncoderSettings = commonValue( system_rc, user_ini, "UseSystemVoiceEncoderSettings", m_useSystemVoiceEncoderSettings ).toBool();
1707 endCommonGroup( system_rc, user_ini );
1708 delete system_rc;
1709 }
1710
qtMajorVersion() const1711 QString Settings::qtMajorVersion() const
1712 {
1713 QString qt_version( qVersion() );
1714 QStringList sl_version = qt_version.split( "." );
1715 if( sl_version.isEmpty() )
1716 return QString( "0" );
1717 else
1718 return sl_version.at( 0 );
1719 }
1720
qtMajorMinorVersion() const1721 QString Settings::qtMajorMinorVersion() const
1722 {
1723 QString qt_version( qVersion() );
1724 QStringList sl_version = qt_version.split( "." );
1725 if( sl_version.isEmpty() )
1726 return QString( "0" );
1727 else if( sl_version.size() < 2 )
1728 return sl_version.at( 0 );
1729 else
1730 return QString( "%1.%2" ).arg( sl_version.at( 0 ) ).arg( sl_version.at( 1 ) );
1731 }
1732
save()1733 void Settings::save()
1734 {
1735 if( !m_enableSaveData )
1736 {
1737 qWarning() << "Skip savings settings because you have disabled it in RC file";
1738 return;
1739 }
1740
1741 beeApp->setCheckSettingsFilePath( false );
1742 QSettings *sets = objectSettings();
1743 sets->clear();
1744
1745 sets->beginGroup( "Version" );
1746 sets->setValue( "Program", version( true, false, true ) );
1747 sets->setValue( "Proto", protocolVersion() );
1748 sets->setValue( "Settings", BEEBEEP_SETTINGS_VERSION );
1749 sets->setValue( "DataStream", dataStreamVersion( false ) );
1750 sets->setValue( "BeeBang", m_settingsCreationDate );
1751 sets->setValue( "Qt", qtMajorMinorVersion() );
1752 sets->endGroup();
1753 sets->beginGroup( "Chat" );
1754 sets->setValue( "Font", m_chatFont.toString() );
1755 sets->setValue( "FontColor", m_chatFontColor );
1756 sets->setValue( "DefaultChatBackgroundColor", m_defaultChatBackgroundColor );
1757 sets->setValue( "CompactMessage", m_chatCompact );
1758 sets->setValue( "ShowMessageTimestamp", m_chatShowMessageTimestamp );
1759 sets->setValue( "BeepOnNewMessageArrived", m_beepOnNewMessageArrived );
1760 sets->setValue( "DisableBeepInUserStatusBusy", m_disableBeepInUserStatusBusy );
1761 sets->setValue( "EnableBeepInActiveWindow", m_beepInActiveWindowAlso );
1762 sets->setValue( "UseHtmlTags", m_chatUseHtmlTags );
1763 sets->setValue( "UseClickableLinks", m_chatUseClickableLinks );
1764 sets->setValue( "MessageHistorySize", m_chatMessageHistorySize );
1765 sets->setValue( "ShowEmoticons", m_showEmoticons );
1766 sets->setValue( "ShowMessagesGroupByUsers", m_showMessagesGroupByUser );
1767 sets->setValue( "MessageFilter", m_chatMessageFilter );
1768 sets->setValue( "ShowOnlyMessagesInDefaultChat", m_showOnlyMessagesInDefaultChat );
1769 sets->setValue( "MaxMessagesToShow", m_chatMessagesToShow );
1770 sets->setValue( "ImagePreviewHeight", m_imagePreviewHeight );
1771 sets->setValue( "UseKeyReturnToSendMessage", m_useReturnToSendMessage );
1772 sets->setValue( "UseYourNameInsteadOfYou", m_chatUseYourNameInsteadOfYou );
1773 sets->setValue( "ClearAllReadMessages", m_chatClearAllReadMessages );
1774 sets->setValue( "UseColoredUserNames", m_chatUseColoredUserNames );
1775 sets->setValue( "DefaultUserNameColor", m_chatDefaultUserNameColor );
1776 sets->setValue( "ActiveWindowOpacityLevel", m_chatActiveWindowOpacityLevel );
1777 sets->setValue( "InactiveWindowOpacityLevel", m_chatInactiveWindowOpacityLevel );
1778 sets->setValue( "BackgroundColor", m_chatBackgroundColor );
1779 sets->setValue( "DefaultTextColor", m_chatDefaultTextColor );
1780 sets->setValue( "SystemTextColor", m_chatSystemTextColor );
1781 sets->setValue( "EnableDefaultChatNotifications", m_enableDefaultChatNotifications );
1782 sets->setValue( "UseMessageTimestampWithAP", m_useMessageTimestampWithAP );
1783 sets->setValue( "QuoteBackgroundColor", m_chatQuoteBackgroundColor );
1784 sets->setValue( "QuoteTextColor", m_chatQuoteTextColor );
1785 sets->setValue( "CloseOnSendingMessage", m_chatOnSendingMessage );
1786 sets->endGroup();
1787 sets->beginGroup( "User" );
1788 if( m_userRecognitionMethod != RecognizeByDefaultMethod )
1789 sets->setValue( "RecognitionMethod", m_userRecognitionMethod );
1790 sets->setValue( "LocalHash", m_localUser.hash() );
1791 sets->setValue( "LocalColor", m_localUser.color() );
1792 sets->setValue( "LocalLastStatusDescription", m_localUser.statusDescription() );
1793 sets->setValue( "AutoAwayStatus", m_autoUserAway );
1794 sets->setValue( "UserAwayTimeout", m_userAwayTimeout ); // minutes
1795 sets->setValue( "AskChangeUserAtStartup", m_askChangeUserAtStartup );
1796 sets->setValue( "UseDefaultPassword", m_useDefaultPassword );
1797 sets->setValue( "AskPasswordAtStartup", m_askPasswordAtStartup );
1798 if( m_savePassword )
1799 {
1800 sets->setValue( "SavePassword", true );
1801 sets->setValue( "EncPwd", simpleEncrypt( m_passwordBeforeHash ) );
1802 }
1803 else
1804 {
1805 sets->remove( "SavePassword" );
1806 sets->remove( "EncPwd" );
1807 }
1808
1809 sets->setValue( "SaveUsers", m_saveUserList );
1810 if( m_saveUserList )
1811 {
1812 // I need a QString to avoid " in file ini
1813 QString user_list_to_save = simpleEncrypt( m_userList.join( QString( "\n" ) ) );
1814 sets->setValue( "List", user_list_to_save );
1815 }
1816 else
1817 sets->remove( "List" );
1818
1819 if( !m_userStatusList.isEmpty() )
1820 {
1821 QString user_status_list_to_save = simpleEncrypt( m_userStatusList.join( QString( "\n" ) ) );
1822 sets->setValue( "StatusList", user_status_list_to_save );
1823 }
1824 else
1825 sets->remove( "StatusList" );
1826
1827 sets->setValue( "MaxStatusDescriptionInList", m_maxUserStatusDescriptionInList );
1828 sets->setValue( "PresetMessages", m_presetMessages );
1829 sets->setValue( "RefusedChats", m_refusedChats );
1830 sets->setValue( "MaxDaysOfUserInactivity", m_maxDaysOfUserInactivity );
1831 sets->setValue( "RemoveInactiveUsers", m_removeInactiveUsers );
1832 sets->endGroup();
1833
1834 sets->beginGroup( "VCard" );
1835 sets->setValue( "NickName", m_localUser.vCard().nickName() );
1836 sets->setValue( "FirstName", m_localUser.vCard().firstName() );
1837 sets->setValue( "LastName", m_localUser.vCard().lastName() );
1838 sets->setValue( "Birthday", m_localUser.vCard().birthday() );
1839 sets->setValue( "Email", m_localUser.vCard().email() );
1840 sets->setValue( "Photo", m_localUser.vCard().photo() );
1841 sets->setValue( "Phone", m_localUser.vCard().phoneNumber() );
1842 sets->setValue( "Info", m_localUser.vCard().info() );
1843 sets->endGroup();
1844 sets->beginGroup( "Gui" );
1845 sets->setValue( "MainWindowGeometry", m_guiGeometry );
1846 sets->setValue( "MainWindowState", m_guiState );
1847 sets->setValue( "FloatingChatGeometry", m_floatingChatGeometry );
1848 sets->setValue( "FloatingChatState", m_floatingChatState );
1849 sets->setValue( "FloatingChatSplitterState", m_floatingChatSplitterState );
1850 sets->setValue( "CreateMessageGeometry", m_createMessageGeometry );
1851 sets->setValue( "FileSharingGeometry", m_fileSharingGeometry );
1852 sets->setValue( "MainBarIconSize", m_mainBarIconSize );
1853 sets->setValue( "AvatarIconSize", m_avatarIconSize );
1854 sets->setValue( "Language", m_language );
1855 sets->setValue( "LastDirectorySelected", m_lastDirectorySelected );
1856 sets->setValue( "DownloadDirectory", m_downloadDirectory );
1857 sets->setValue( "LogFolderPath", m_logPath );
1858 sets->setValue( "PluginPath", m_pluginPath );
1859 sets->setValue( "LanguagePath", m_languagePath );
1860 sets->setValue( "KeyEscapeMinimizeInTray", m_keyEscapeMinimizeInTray );
1861 sets->setValue( "CloseMinimizeInTray", m_closeMinimizeInTray );
1862 sets->setValue( "StayOnTop", m_stayOnTop );
1863 sets->setValue( "BeepFilePath", m_beepFilePath );
1864 sets->setValue( "RaiseOnNewMessageArrived", m_raiseOnNewMessageArrived );
1865 sets->setValue( "RaiseMainWindowOnNewMessageArrived", m_raiseMainWindowOnNewMessageArrived );
1866 sets->setValue( "AlwaysShowFileTransferProgress", m_alwaysShowFileTransferProgress );
1867 sets->setValue( "AlwaysOpenChatOnNewMessageArrived", m_alwaysOpenChatOnNewMessageArrived );
1868 sets->setValue( "LoadOnTrayAtStartup", m_loadOnTrayAtStartup );
1869 sets->setValue( "ShowNotificationOnTray", m_showNotificationOnTray );
1870 sets->setValue( "ShowOnlyMessageNotificationOnTray", m_showOnlyMessageNotificationOnTray );
1871 sets->setValue( "ShowNotificationOnTrayTimeout", m_trayMessageTimeout );
1872 sets->setValue( "ShowChatMessageOnTray", m_showChatMessageOnTray );
1873 sets->setValue( "TextSizeInChatMessagePreviewOnTray", m_textSizeInChatMessagePreviewOnTray );
1874 sets->setValue( "ShowFileTransferCompletedOnTray", m_showFileTransferCompletedOnTray );
1875 sets->setValue( "ChatAutoSave", m_chatAutoSave );
1876 sets->setValue( "TickIntervalChatAutoSave", m_tickIntervalChatAutoSave );
1877 sets->setValue( "ChatMaxLineSaved", m_chatMaxLineSaved );
1878 sets->setValue( "ChatSaveUnsentMessages", m_chatSaveUnsentMessages );
1879 sets->setValue( "ChatSaveFileTransfers", m_chatSaveFileTransfers );
1880 sets->setValue( "ChatSaveSystemMessages", m_chatSaveSystemMessages );
1881 sets->setValue( "ShowChatToolbar", m_showChatToolbar );
1882 sets->setValue( "ShowOnlyOnlineUsers", m_showOnlyOnlineUsers );
1883 sets->setValue( "ShowUserPhoto", m_showUserPhoto );
1884 sets->setValue( "ShowVCardOnRightClick", m_showVCardOnRightClick );
1885 sets->setValue( "ResetWindowGeometryAtStartup", m_resetGeometryAtStartup );
1886 sets->setValue( "SaveGeometryOnExit", m_saveGeometryOnExit );
1887 sets->setValue( "ShowEmoticonMenu", m_showEmoticonMenu );
1888 sets->setValue( "ShowPresetMessages", m_showPresetMessages );
1889 sets->setValue( "EmoticonSizeInEdit", m_emoticonSizeInEdit );
1890 sets->setValue( "EmoticonSizeInChat", m_emoticonSizeInChat );
1891 sets->setValue( "EmoticonSizeInMenu", m_emoticonSizeInMenu );
1892 sets->setValue( "EmoticonsInRecentMenu", m_emoticonInRecentMenu );
1893 sets->setValue( "FavoriteEmoticons", m_favoriteEmoticons );
1894 sets->setValue( "RecentEmoticons", m_recentEmoticons );
1895 sets->setValue( "UseFontEmoticons", m_useFontEmoticons );
1896 sets->setValue( "UseHighResolutionEmoticons", m_useHiResEmoticons );
1897 sets->setValue( "ShowMinimizedAtStartup", m_showMinimizedAtStartup );
1898 sets->setValue( "PromptOnCloseEvent", m_promptOnCloseEvent );
1899 sets->setValue( "ShowUserStatusBackgroundColor", m_showUserStatusBackgroundColor );
1900 sets->setValue( "ShowUserStatusDescription", m_showUserStatusDescription );
1901 sets->setValue( "Shortcuts", m_shortcuts );
1902 sets->setValue( "UseShortcuts", m_useShortcuts );
1903 sets->setValue( "UseNativeFileDialogs", m_useNativeDialogs );
1904 sets->setValue( "ShowActivitiesTimestamp", m_homeShowMessageTimestamp );
1905 sets->setValue( "HomeBackgroundColor", m_homeBackgroundColor );
1906 sets->setValue( "UserListBackgroundColor", m_userListBackgroundColor );
1907 sets->setValue( "ChatListBackgroundColor", m_chatListBackgroundColor );
1908 sets->setValue( "GroupListBackgroundColor", m_groupListBackgroundColor );
1909 sets->setValue( "SavedChatListBackgroundColor", m_savedChatListBackgroundColor );
1910 sets->setValue( "UsePreviewFileDialog", m_usePreviewFileDialog );
1911 sets->setValue( "PreviewFileDialogGeometry", m_previewFileDialogGeometry );
1912 sets->setValue( "PreviewFileDialogImageSize", m_previewFileDialogImageSize );
1913 sets->setValue( "UserSortingMode", m_userSortingMode );
1914 sets->setValue( "SortUsersAscending", m_sortUsersAscending );
1915 sets->setValue( "ShowChatTextInModeRTL", m_showTextInModeRTL );
1916 sets->setValue( "PlayBuzzSound", m_playBuzzSound );
1917 sets->setValue( "ShowChatsInOneWindow", m_showChatsInOneWindow );
1918 sets->setValue( "IconSourcePath", m_iconSourcePath );
1919 sets->setValue( "EmoticonSourcePath", m_emoticonSourcePath );
1920 sets->setValue( "MaxChatsToOpenAfterSendingMessage", m_maxChatsToOpenAfterSendingMessage );
1921 sets->setValue( "ShowUsersOnConnection", m_showUsersOnConnection );
1922 sets->setValue( "ShowChatsOnConnection", m_showChatsOnConnection );
1923 sets->setValue( "HideEmptyChatsInList", m_hideEmptyChatsInList );
1924 sets->setValue( "EnableMaximizeButton", m_enableMaximizeButton );
1925 sets->setValue( "UseDarkStyle", m_useDarkStyle );
1926 sets->setValue( "ShowUsersInWorkgroups", m_showUsersInWorkgroups );
1927 sets->setValue( "OpenChatWhenSendNewMessage", m_openChatWhenSendNewMessage );
1928 sets->setValue( "SendNewMessageIndividually", m_sendNewMessageIndividually );
1929 sets->setValue( "ShowUserFirstNameFirstInFullName", m_useUserFirstNameFirstInFullName );
1930 sets->setValue( "ResetMinimumWidthForStyle", m_resetMinimumWidthForStyle );
1931 sets->endGroup();
1932 sets->beginGroup( "Tools" );
1933 sets->setValue( "LogToFile", m_logToFile );
1934 sets->setValue( "UseSpellChecker", m_useSpellChecker );
1935 sets->setValue( "UseWordCompleter", m_useWordCompleter );
1936 sets->setValue( "DictionaryPath", m_dictionaryPath );
1937 sets->setValue( "SearchForNewVersionAtStartup", m_checkNewVersionAtStartup );
1938 sets->setValue( "SendAnonymousUsageStatistics", m_postUsageStatistics );
1939 sets->setValue( "Uuid", m_applicationUuid );
1940 sets->setValue( "UuidCreationDate", m_applicationUuidCreationDate );
1941 sets->setValue( "StatsPostDate", m_statsPostDate );
1942 sets->endGroup();
1943 sets->beginGroup( "Misc" );
1944 sets->setValue( "TickIntervalCheckIdle", m_tickIntervalCheckIdle );
1945 sets->setValue( "TickIntervalCheckNetwork", m_tickIntervalCheckNetwork );
1946 sets->setValue( "ListenerPort", m_localUser.networkAddress().hostPort() );
1947 sets->setValue( "ConnectionActivityTimeout_ms", m_pongTimeout );
1948 sets->setValue( "WritingTimeout_ms", m_writingTimeout );
1949 sets->setValue( "DelayContactUsers_ms", m_delayContactUsers );
1950 sets->setValue( "TickIntervalConnectionTimeout", m_tickIntervalConnectionTimeout );
1951 sets->setValue( "UseLowDelayOptionOnSocket", m_useLowDelayOptionOnSocket );
1952 sets->setValue( "TickIntervalBroadcasting", m_tickIntervalBroadcasting );
1953 sets->setValue( "DelayConnectionAtStartup_ms", m_delayConnectionAtStartup );
1954 sets->setValue( "SendOfflineMessagesToDefaultChat", m_sendOfflineMessagesToDefaultChat );
1955 sets->setValue( "SaveMessagesTimestamp", m_saveMessagesTimestamp );
1956 sets->setValue( "ClearCacheAfterDays", m_clearCacheAfterDays );
1957 sets->setValue( "RemovePartiallyDownloadedFilesAfterDays", m_removePartiallyDownloadedFilesAfterDays );
1958 sets->endGroup();
1959 sets->beginGroup( "Network");
1960 #ifdef BEEBEEP_USE_MULTICAST_DNS
1961 sets->setValue( "UseMulticastDns", m_useMulticastDns );
1962 #endif
1963 sets->setValue( "PreventMultipleConnectionsFromSingleHostAddress", m_preventMultipleConnectionsFromSingleHostAddress );
1964 if( !m_localHostAddressForced.isNull() )
1965 sets->setValue( "LocalHostAddressForced", m_localHostAddressForced.toString() );
1966 else
1967 sets->setValue( "LocalHostAddressForced", QString( "" ) );
1968 sets->setValue( "LocalSubnetForced", m_localSubnetForced );
1969 sets->setValue( "UserPathList", m_networkAddressList );
1970 sets->setValue( "AcceptConnectionsOnlyFromWorkgroups", m_acceptConnectionsOnlyFromWorkgroups );
1971 sets->setValue( "Workgroups", m_localUser.workgroups() );
1972 sets->setValue( "MaxUsersToConnectInATick", m_maxUsersToConnectInATick );
1973 sets->setValue( "UseHiveProtocol", m_useHive );
1974 sets->setValue( "DisableSystemProxyForConnections", m_disableSystemProxyForConnections );
1975 sets->setValue( "UseDefaultMulticastGroupAddress", m_useDefaultMulticastGroupAddress );
1976 sets->setValue( "BroadcastToOfflineUsers", m_broadcastToOfflineUsers );
1977 sets->setValue( "BroadcastToLocalSubnet", m_broadcastToLocalSubnetAlways );
1978 sets->setValue( "IpMulticastTtl", m_ipMulticastTtl );
1979 sets->endGroup();
1980 sets->beginGroup( "FileShare" );
1981 sets->setValue( "EnableFileTransfer", m_enableFileTransfer );
1982 sets->setValue( "EnableFileSharing", m_enableFileSharing );
1983 sets->setValue( "UseShareBox", m_useShareBox );
1984 sets->setValue( "MaxSharedFiles", m_maxFileShared );
1985 sets->setValue( "ShareBoxPath", m_shareBoxPath );
1986 sets->setValue( "OnExistingFileAction", m_onExistingFileAction );
1987 sets->setValue( "ResumeFileTransfer", m_resumeFileTransfer );
1988 sets->setValue( "FileTransferConfirmTimeout", m_fileTransferConfirmTimeout );
1989 sets->setValue( "FileTransferBufferSize", m_fileTransferBufferSize );
1990 sets->setValue( "MaxSimultaneousDownloads", m_maxSimultaneousDownloads );
1991 sets->setValue( "MaxQueuedDownloads", m_maxQueuedDownloads );
1992 sets->setValue( "ConfirmOnDownloadFile", m_confirmOnDownloadFile );
1993 sets->setValue( "ShareList", m_localShare );
1994 sets->setValue( "DownloadInUserFolder", m_downloadInUserFolder );
1995 sets->setValue( "KeepModificationDateOnFileTransferred", m_keepModificationDateOnFileTransferred );
1996 sets->endGroup();
1997
1998 sets->beginGroup( "Group" );
1999 sets->setValue( "SaveGroups", m_saveGroupList );
2000 if( m_saveGroupList && !m_groupList.isEmpty() )
2001 {
2002 sets->setValue( "Silenced", m_groupSilenced );
2003 sets->setValue( "List", m_groupList );
2004 }
2005 sets->endGroup();
2006
2007 sets->beginGroup( "ShareDesktop" );
2008 sets->setValue( "Enable", m_enableShareDesktop );
2009 sets->setValue( "CaptureScreenInterval", m_shareDesktopCaptureDelay );
2010 sets->setValue( "FitToScreen", m_shareDesktopFitToScreen );
2011 sets->setValue( "ImageType", m_shareDesktopImageType );
2012 sets->setValue( "ImageQuality", m_shareDesktopImageQuality );
2013 sets->endGroup();
2014
2015 sets->beginGroup( "VoiceMessage" );
2016 sets->setValue( "MaxDuration", m_voiceMessageMaxDuration );
2017 sets->setValue( "UseVoicePlayer", m_useVoicePlayer );
2018 sets->setValue( "VoiceInputDeviceName", m_voiceInputDeviceName );
2019 sets->setValue( "VoiceFileMessageContainer", m_voiceFileMessageContainer );
2020 sets->setValue( "VoiceCodec", m_voiceCodec );
2021 sets->setValue( "VoiceSampleRate", m_voiceSampleRate );
2022 sets->setValue( "VoiceBitRate", m_voiceBitRate );
2023 sets->setValue( "VoiceChannels", m_voiceChannels );
2024 sets->setValue( "VoiceEncodingMode", m_voiceEncodingMode );
2025 sets->setValue( "VoiceEncodingQuality", m_voiceEncodingQuality );
2026 sets->setValue( "UseCustomVoiceEncoderSettings", m_useCustomVoiceEncoderSettings );
2027 sets->setValue( "UseSystemVoiceEncoderSettings", m_useSystemVoiceEncoderSettings );
2028 sets->endGroup();
2029
2030 if( !m_pluginSettings.isEmpty() )
2031 {
2032 sets->beginGroup( "Plugin" );
2033 QStringList key_list( m_pluginSettings.keys() );
2034 sets->setValue( "List", key_list );
2035 QMap<QString, QStringList>::const_iterator it = m_pluginSettings.constBegin();
2036 while( it != m_pluginSettings.constEnd() )
2037 {
2038 sets->setValue( it.key(), it.value() );
2039 ++it;
2040 }
2041 sets->endGroup();
2042 }
2043
2044 if( sets->isWritable() )
2045 {
2046 sets->sync();
2047 qDebug() << "Settings saved in" << qPrintable( Bee::convertToNativeFolderSeparator( sets->fileName() ) );
2048 m_lastSave = QDateTime::currentDateTime();
2049 }
2050
2051 #ifdef Q_OS_WIN
2052 if( m_useSettingsFileIni )
2053 m_currentFilePath = Bee::convertToNativeFolderSeparator( sets->fileName() );
2054 else
2055 m_currentFilePath = ""; // registry path
2056 #else
2057 m_currentFilePath = Bee::convertToNativeFolderSeparator( sets->fileName() );
2058 #endif
2059
2060 beeApp->setSettingsFilePath( m_currentFilePath );
2061 beeApp->setCheckSettingsFilePath( true );
2062 sets->deleteLater();
2063 }
2064
askPassword() const2065 bool Settings::askPassword() const
2066 {
2067 if( askPasswordAtStartup() )
2068 return true;
2069
2070 if( useDefaultPassword() )
2071 return false;
2072
2073 if( !savePassword() )
2074 return true;
2075
2076 if( m_passwordBeforeHash.isEmpty() )
2077 return true;
2078
2079 return false;
2080 }
2081
setLastDirectorySelectedFromFile(const QString & file_path)2082 void Settings::setLastDirectorySelectedFromFile( const QString& file_path )
2083 {
2084 QFileInfo file_info( file_path );
2085 setLastDirectorySelected( file_info.absoluteDir().absolutePath() );
2086 }
2087
addTemporaryFilePath(const QString & file_path)2088 void Settings::addTemporaryFilePath( const QString& file_path )
2089 {
2090 if( file_path.isEmpty() )
2091 return;
2092 if( !m_tempFilePathList.contains( file_path ) )
2093 {
2094 if( QFile::exists( file_path ) )
2095 {
2096 m_tempFilePathList.append( file_path );
2097 qDebug() << "Temporary file added:" << qPrintable( file_path );
2098 }
2099 }
2100 }
2101
isFileImageInCache(const QString & file_path) const2102 bool Settings::isFileImageInCache( const QString& file_path ) const
2103 {
2104 QFileInfo file_info( file_path );
2105 if( !Bee::isFileTypeImage( file_info.suffix() ) )
2106 return false;
2107 QString base_folder_path = Bee::convertToNativeFolderSeparator( file_info.absoluteDir().path() );
2108 if( base_folder_path == m_cacheFolder )
2109 {
2110 #ifdef BEEBEEP_DEBUG
2111 qDebug() << qPrintable( file_path ) << "is in cache";
2112 #endif
2113 return true;
2114 }
2115 else
2116 {
2117 #ifdef BEEBEEP_DEBUG
2118 qDebug() << qPrintable( file_path ) << "is NOT in cache but in:" << qPrintable( base_folder_path );
2119 #endif
2120 return false;
2121 }
2122 }
2123
partiallyDownloadedFileExtension() const2124 QString Settings::partiallyDownloadedFileExtension() const
2125 {
2126 #ifdef Q_OS_OS2
2127 return QString( "par" );
2128 #else
2129 return QString( "part" );
2130 #endif
2131 }
2132
clearTemporaryFiles()2133 void Settings::clearTemporaryFiles()
2134 {
2135 if( m_tempFilePathList.isEmpty() )
2136 return;
2137
2138 foreach( QString file_path, m_tempFilePathList )
2139 {
2140 if( m_chatSaveFileTransfers && isFileImageInCache( file_path ) )
2141 continue;
2142
2143 if( QFile::exists( file_path ) )
2144 {
2145 if( !QFile::remove( file_path ) )
2146 qWarning() << "Unable to remove temporary file:" << qPrintable( file_path );
2147 else
2148 qDebug() << "Temporary file removed:" << qPrintable( file_path );
2149 }
2150 }
2151
2152 m_tempFilePathList.clear();
2153 }
2154
setNotificationEnabledForGroup(const QString & group_id,bool enable_notification)2155 void Settings::setNotificationEnabledForGroup( const QString& group_id, bool enable_notification )
2156 {
2157 if( group_id.isEmpty() )
2158 {
2159 qWarning() << "Empty private group id in set notification enabled";
2160 return;
2161 }
2162
2163 if( enable_notification )
2164 {
2165 m_groupSilenced.removeOne( group_id );
2166 }
2167 else
2168 {
2169 if( !m_groupSilenced.contains( group_id ) )
2170 m_groupSilenced.append( group_id );
2171 }
2172 }
2173
addStartOnSystemBoot()2174 bool Settings::addStartOnSystemBoot()
2175 {
2176 #ifdef Q_OS_WIN
2177 QString program_path = Bee::convertToNativeFolderSeparator( qApp->applicationFilePath() );
2178 QSettings sets( "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat );
2179 if( sets.isWritable() )
2180 {
2181 sets.setValue( programName(), program_path );
2182 sets.sync();
2183 return true;
2184 }
2185 qWarning() << "Unable to add auto start in registry key:" << qPrintable( sets.fileName() );
2186 #endif
2187 return false;
2188 }
2189
removeStartOnSystemBoot()2190 bool Settings::removeStartOnSystemBoot()
2191 {
2192 #ifdef Q_OS_WIN
2193 QSettings sets( "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat );
2194 if( sets.isWritable() )
2195 {
2196 sets.remove( programName() );
2197 sets.sync();
2198 return true;
2199 }
2200 qWarning() << "Unable to remove auto start from registry key:" << sets.fileName();
2201 #endif
2202 return false;
2203 }
2204
hasStartOnSystemBoot() const2205 bool Settings::hasStartOnSystemBoot() const
2206 {
2207 #ifdef Q_OS_WIN
2208 QString program_path = qApp->applicationFilePath().replace( "/", "\\" );
2209 QSettings sets( "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat );
2210 return sets.value( programName(), "" ).toString() == program_path;
2211 #else
2212 return false;
2213 #endif
2214 }
2215
clearNativeSettings()2216 void Settings::clearNativeSettings()
2217 {
2218 QSettings sets( QSettings::NativeFormat, QSettings::UserScope, organizationName(), programName() );
2219 if( !sets.allKeys().isEmpty() )
2220 sets.clear();
2221 }
2222
searchDataFolder()2223 bool Settings::searchDataFolder()
2224 {
2225 qDebug() << "Searching data folder...";
2226 QString data_folder = m_addAccountNameToDataFolder ? Bee::removeInvalidCharactersForFilePath( accountNameFromSystemEnvinroment() ) : QLatin1String( "beebeep-data" );
2227 QString root_folder;
2228 #ifdef Q_OS_MAC
2229 bool rc_folder_is_writable = false;
2230 #else
2231 bool rc_folder_is_writable = Bee::folderIsWriteable( m_resourceFolder, false );
2232 #ifdef Q_OS_WIN
2233 QProcessEnvironment pe = QProcessEnvironment::systemEnvironment();
2234 QString env_program_files = pe.value( "PROGRAMFILES", QLatin1String( ":\\Program File" ) );
2235 if( !env_program_files.isEmpty() )
2236 qDebug() << "Checking if BeeBEEP is installed in system folder:" << qPrintable( env_program_files ) << "...";
2237 if( m_resourceFolder.contains( "Program Files", Qt::CaseInsensitive ) || m_resourceFolder.contains( env_program_files, Qt::CaseInsensitive ) )
2238 {
2239 qDebug() << "BeeBEEP is installed in system folder:" << qPrintable( m_resourceFolder );
2240 qDebug() << "Resource folder is default Windows Program Files and will not be used as data folder";
2241 rc_folder_is_writable = false;
2242 }
2243 else
2244 qDebug() << "BeeBEEP is installed in custom folder:" << qPrintable( m_resourceFolder );
2245 #endif
2246 #endif
2247
2248 #if QT_VERSION >= 0x050400
2249 if( !m_dataFolderInRC.isEmpty() )
2250 root_folder = m_dataFolderInRC;
2251 else if( m_saveDataInUserApplicationFolder )
2252 root_folder = QStandardPaths::writableLocation( QStandardPaths::AppDataLocation );
2253 else if( m_saveDataInDocumentsFolder )
2254 root_folder = QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation );
2255 else
2256 root_folder = rc_folder_is_writable ? m_resourceFolder : QStandardPaths::writableLocation( QStandardPaths::AppDataLocation );
2257 #elif QT_VERSION >= 0x050000
2258 if( !m_dataFolderInRC.isEmpty() )
2259 root_folder = m_dataFolderInRC;
2260 else if( m_saveDataInUserApplicationFolder )
2261 root_folder = QString( "%1/%2" ).arg( QStandardPaths::writableLocation( QStandardPaths::DataLocation ) ).arg( programName() );
2262 else if( m_saveDataInDocumentsFolder )
2263 root_folder = QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation );
2264 else
2265 root_folder = QString( "%1/%2" ).arg( rc_folder_is_writable ? m_resourceFolder : QStandardPaths::writableLocation( QStandardPaths::DataLocation ) ).arg( programName() );
2266 #else
2267 if( !m_dataFolderInRC.isEmpty() )
2268 root_folder = m_dataFolderInRC;
2269 else if( m_saveDataInUserApplicationFolder )
2270 root_folder = QDesktopServices::storageLocation( QDesktopServices::DataLocation );
2271 else if( m_saveDataInDocumentsFolder )
2272 root_folder = QDesktopServices::storageLocation( QDesktopServices::DocumentsLocation );
2273 else
2274 root_folder = rc_folder_is_writable ? m_resourceFolder : QDesktopServices::storageLocation( QDesktopServices::DataLocation );
2275 #endif
2276
2277 if( m_addAccountNameToDataFolder || m_saveDataInDocumentsFolder )
2278 m_dataFolder = Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( root_folder, data_folder ) );
2279 else
2280 m_dataFolder = Bee::convertToNativeFolderSeparator( root_folder );
2281
2282 QDir folder( m_dataFolder );
2283 if( !folder.exists() )
2284 {
2285 qWarning() << "Data folder not found in" << qPrintable( folder.absolutePath() );
2286 if( !folder.mkpath( m_dataFolder ) )
2287 {
2288 qWarning() << "Unable to create data folder" << qPrintable( folder.absolutePath() ) ;
2289 m_dataFolder = root_folder;
2290 }
2291 else
2292 qDebug() << "Data folder created in" << qPrintable( m_dataFolder );
2293 }
2294
2295 if( !Bee::folderIsWriteable( m_dataFolder, false ) )
2296 {
2297 qWarning() << "Data folder" << qPrintable( m_dataFolder ) << "is not writeable";
2298 return false;
2299 }
2300 qDebug() << "Data folder (found):" << qPrintable( m_dataFolder );
2301 return true;
2302 }
2303
setDataFolder()2304 bool Settings::setDataFolder()
2305 {
2306 if( !rcFileExists() )
2307 {
2308 QStringList default_data_folders;
2309 default_data_folders.append( m_dataFolder );
2310 if( m_dataFolder != m_resourceFolder )
2311 default_data_folders.append( m_resourceFolder );
2312 m_dataFolder = findFileInFolders( "beebeep.ini", default_data_folders, true );
2313 }
2314 else
2315 m_dataFolder = "";
2316
2317 if( m_dataFolder.isEmpty() )
2318 {
2319 if( !searchDataFolder() )
2320 qWarning() << "Unable to save data. Check your FS permissions";
2321 }
2322
2323 if( m_addNicknameToDataFolder )
2324 m_dataFolder = Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( m_dataFolder ).arg( Bee::removeInvalidCharactersForFilePath( m_localUser.name() ) ) );
2325 qDebug() << "Data folder:" << qPrintable( m_dataFolder );
2326
2327 m_cacheFolder = defaultCacheFolderPath();
2328 QDir cache_folder( m_cacheFolder );
2329 if( !cache_folder.exists() )
2330 {
2331 if( !cache_folder.mkpath( m_cacheFolder ) )
2332 {
2333 qWarning() << "Unable to create cache folder" << qPrintable( cache_folder.absolutePath() ) ;
2334 m_cacheFolder = m_dataFolder;
2335 }
2336 else
2337 qDebug() << "Cache folder created in" << qPrintable( m_cacheFolder );
2338 }
2339 qDebug() << "Cache folder:" << qPrintable( m_cacheFolder );
2340
2341 QStringList folder_list = resourceFolders();
2342 if( folder_list.size() > 1 )
2343 qDebug() << "System files will be searched in the following folders:\n -" << qPrintable( resourceFolders().join( "\n - " ) );
2344 else if( folder_list.size() == 1 )
2345 qDebug() << "System files will be searched in the following folder:\n -" << qPrintable( folder_list.first() );
2346 else
2347 qDebug() << "System files will not be searched";
2348
2349 folder_list = dataFolders();
2350 if( folder_list.size() > 1 )
2351 qDebug() << "Configuration and data files will be searched in the following folders:\n -" << qPrintable( folder_list.join( "\n - " ) );
2352 else if( folder_list.size() == 1 )
2353 qDebug() << "Configuration and data files will be searched in the following folder:\n -" << qPrintable( folder_list.first() );
2354 else
2355 qDebug() << "Configuration and data files will not be searched";
2356 return true;
2357 }
2358
defaultDownloadFolderPath() const2359 QString Settings::defaultDownloadFolderPath() const
2360 {
2361 #if QT_VERSION >= 0x050000
2362 QString default_download_folder = Bee::convertToNativeFolderSeparator( QStandardPaths::writableLocation( QStandardPaths::DownloadLocation ) );
2363 #else
2364 QString default_download_folder = Bee::convertToNativeFolderSeparator( QDesktopServices::storageLocation( QDesktopServices::DocumentsLocation ) );
2365 #endif
2366 if( Bee::folderIsWriteable( default_download_folder, false ) )
2367 return default_download_folder;
2368
2369 default_download_folder = Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( dataFolder() ).arg( "download" ) );
2370 if( Bee::folderIsWriteable( default_download_folder, true ) )
2371 return default_download_folder;
2372 else
2373 return dataFolder();
2374 }
2375
defaultCacheFolderPath() const2376 QString Settings::defaultCacheFolderPath() const
2377 {
2378 return Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( dataFolder() ).arg( "cache" ) );
2379 }
2380
savedChatsFilePath() const2381 QString Settings::savedChatsFilePath() const
2382 {
2383 return Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( dataFolder() ).arg( "beebeep.dat" ) );
2384 }
2385
autoSavedChatsFilePath() const2386 QString Settings::autoSavedChatsFilePath() const
2387 {
2388 return Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( dataFolder() ).arg( "beebeep.bak" ) );
2389 }
2390
unsentMessagesFilePath() const2391 QString Settings::unsentMessagesFilePath() const
2392 {
2393 return Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( dataFolder() ).arg( "beebeep.off" ) );
2394 }
2395
defaultSettingsFilePath() const2396 QString Settings::defaultSettingsFilePath() const
2397 {
2398 return Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( dataFolder() ).arg( QLatin1String( "beebeep.ini" ) ) );
2399 }
2400
defaultBeepFilePath()2401 QString Settings::defaultBeepFilePath()
2402 {
2403 if( m_beepDefaultFilePath.isEmpty() )
2404 {
2405 QStringList data_folders;
2406 data_folders.append( Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( dataFolder() ).arg( QLatin1String( "resources" ) ) ) );
2407 data_folders.append( dataFolders() );
2408 #ifndef Q_OS_MAC
2409 data_folders.append( Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( resourceFolder() ).arg( QLatin1String( "resources" ) ) ) );
2410 #endif
2411 data_folders.append( resourceFolders() );
2412 data_folders.removeDuplicates();
2413 QString beep_file_path = findFileInFolders( QLatin1String( "beep.wav" ), data_folders );
2414 if( beep_file_path.isNull() )
2415 m_beepDefaultFilePath = Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( resourceFolder() ).arg( QLatin1String( "beep.wav" ) ) );
2416 else
2417 m_beepDefaultFilePath = beep_file_path;
2418 }
2419 return m_beepDefaultFilePath;
2420 }
2421
defaultPluginFolderPath() const2422 QString Settings::defaultPluginFolderPath() const
2423 {
2424 QStringList data_folders;
2425 data_folders.append( Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( dataFolder() ).arg( QLatin1String( "plugins" ) ) ) );
2426 data_folders.append( dataFolders() );
2427 #ifndef Q_OS_MAC
2428 data_folders.append( Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( resourceFolder() ).arg( QLatin1String( "plugins" ) ) ) );
2429 #endif
2430 data_folders.append( resourceFolders() );
2431 data_folders.removeDuplicates();
2432 QString test_plugin_file = QLatin1String( "libnumbertextmarker." ) + Bee::pluginFileExtension();
2433 QString test_plugin_path = findFileInFolders( test_plugin_file, data_folders, true );
2434 return test_plugin_path.isNull() ? resourceFolder() : test_plugin_path;
2435 }
2436
defaultLanguageFolderPath() const2437 QString Settings::defaultLanguageFolderPath() const
2438 {
2439 QStringList data_folders;
2440 data_folders.append( Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( dataFolder() ).arg( QLatin1String( "languages" ) ) ) );
2441 data_folders.append( dataFolders() );
2442 #ifndef Q_OS_MAC
2443 data_folders.append( Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( resourceFolder() ).arg( QLatin1String( "languages" ) ) ) );
2444 #endif
2445 data_folders.append( resourceFolders() );
2446 data_folders.removeDuplicates();
2447 QString test_language_file = QLatin1String( "beebeep_it.qm" );
2448 QString test_language_path = findFileInFolders( test_language_file, data_folders, true );
2449 return test_language_path.isNull() ? resourceFolder() : test_language_path;
2450 }
2451
simpleEncrypt(const QString & text_to_encrypt)2452 QString Settings::simpleEncrypt( const QString& text_to_encrypt )
2453 {
2454 if( text_to_encrypt.size() <= 0 )
2455 return QLatin1String( "" );
2456
2457 QByteArray byte_array_encrypted = text_to_encrypt.toUtf8().toBase64();
2458
2459 return QString::fromLatin1( byte_array_encrypted );
2460 }
2461
simpleDecrypt(const QString & text_to_decrypt)2462 QString Settings::simpleDecrypt( const QString& text_to_decrypt )
2463 {
2464 if( text_to_decrypt.size() <= 0 )
2465 return QLatin1String( "" );
2466
2467 QString text_decrypted = "";
2468
2469 if( m_settingsVersion < 5 )
2470 {
2471 // Old Decryption
2472 char key = 'k';
2473 foreach( QChar c, text_to_decrypt )
2474 text_decrypted += c.toLatin1() ^ key;
2475 }
2476 else
2477 {
2478 QByteArray byte_array_to_decrypt = text_to_decrypt.toLatin1();
2479 text_decrypted = QString::fromUtf8( QByteArray::fromBase64( byte_array_to_decrypt ) );
2480 }
2481
2482 return text_decrypted;
2483 }
2484
guiCustomListStyleSheet(const QString & background_color,const QString & background_image_path) const2485 QString Settings::guiCustomListStyleSheet( const QString& background_color, const QString& background_image_path ) const
2486 {
2487 return QString( "#GuiCustomList { background: %1 url(%2);"
2488 "background-repeat: no-repeat;"
2489 "background-position: bottom center;"
2490 "background-attachment: fixed;"
2491 "padding-bottom: 32px;"
2492 "}" ).arg( background_color ).arg( background_image_path );
2493 }
2494
autoresponderName() const2495 QString Settings::autoresponderName() const
2496 {
2497 return QT_TRANSLATE_NOOP( "Settings", "Autoresponder" );
2498 }
2499
defaultChatMessagesToShow() const2500 int Settings::defaultChatMessagesToShow() const
2501 {
2502 #if QT_VERSION >= 0x050000
2503 return 800;
2504 #else
2505 return 400;
2506 #endif
2507 }
2508
downloadDirectoryForUser(const User & u) const2509 QString Settings::downloadDirectoryForUser( const User& u ) const
2510 {
2511 if( Settings::instance().downloadInUserFolder() )
2512 {
2513 QString user_name = Bee::removeInvalidCharactersForFilePath( u.name() );
2514 return Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( downloadDirectory() ).arg( user_name ) );
2515 }
2516 else
2517 return downloadDirectory();
2518 }
2519
useUserFirstNameFirstInFullNameFromLanguage() const2520 bool Settings::useUserFirstNameFirstInFullNameFromLanguage() const
2521 {
2522 if( m_language == "ja" ) // japanese
2523 return false;
2524 else
2525 return true;
2526 }
2527
isFileExtensionAllowedInFileTransfer(const QString & file_ext) const2528 bool Settings::isFileExtensionAllowedInFileTransfer( const QString& file_ext ) const
2529 {
2530 if( m_allowedFileExtensionsInFileTransfer.isEmpty() )
2531 return true;
2532 if( file_ext.toLower() == partiallyDownloadedFileExtension().toLower() )
2533 return true;
2534 return file_ext.isEmpty() ? false : m_allowedFileExtensionsInFileTransfer.contains( file_ext, Qt::CaseInsensitive );
2535 }
2536