2014-05-30 08:53:19 +00:00
/*
This file is part of Telegram Desktop ,
2014-12-01 10:47:38 +00:00
the official desktop version of Telegram messaging app , see https : //telegram.org
2014-05-30 08:53:19 +00:00
Telegram Desktop is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
It is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
Full license : https : //github.com/telegramdesktop/tdesktop/blob/master/LICENSE
2014-12-01 10:47:38 +00:00
Copyright ( c ) 2014 John Preston , https : //desktop.telegram.org
2014-05-30 08:53:19 +00:00
*/
# include "stdafx.h"
# include "application.h"
# include "style.h"
# include "pspecific.h"
# include "fileuploader.h"
# include "mainwidget.h"
# include "lang.h"
# include "boxes/confirmbox.h"
# include "langloaderplain.h"
2014-11-22 09:45:04 +00:00
# include "localstorage.h"
2015-06-03 18:13:01 +00:00
# include "autoupdater.h"
2014-05-30 08:53:19 +00:00
namespace {
Application * mainApp = 0 ;
FileUploader * uploader = 0 ;
QString lng ;
void mtpStateChanged ( int32 dc , int32 state ) {
if ( App : : wnd ( ) ) {
App : : wnd ( ) - > mtpStateChanged ( dc , state ) ;
}
}
2014-08-01 18:49:43 +00:00
void mtpSessionReset ( int32 dc ) {
if ( App : : main ( ) & & dc = = MTP : : maindc ( ) ) {
App : : main ( ) - > getDifference ( ) ;
}
}
2015-07-13 17:55:59 +00:00
class EventFilterForKeys : public QObject {
2014-05-30 08:53:19 +00:00
public :
2015-07-13 17:55:59 +00:00
EventFilterForKeys ( QObject * parent ) : QObject ( parent ) {
2014-05-30 08:53:19 +00:00
}
bool eventFilter ( QObject * o , QEvent * e ) {
if ( e - > type ( ) = = QEvent : : KeyPress ) {
QKeyEvent * ev = static_cast < QKeyEvent * > ( e ) ;
2015-07-13 17:55:59 +00:00
if ( cPlatform ( ) = = dbipMac ) {
if ( ev - > key ( ) = = Qt : : Key_W & & ( ev - > modifiers ( ) & ( Qt : : MetaModifier | Qt : : ControlModifier ) ) ) {
if ( cWorkMode ( ) = = dbiwmTrayOnly | | cWorkMode ( ) = = dbiwmWindowAndTray ) {
App : : wnd ( ) - > minimizeToTray ( ) ;
return true ;
} else {
App : : wnd ( ) - > hide ( ) ;
App : : wnd ( ) - > updateIsActive ( cOfflineBlurTimeout ( ) ) ;
App : : wnd ( ) - > updateGlobalMenu ( ) ;
return true ;
}
} else if ( ev - > key ( ) = = Qt : : Key_M & & ( ev - > modifiers ( ) & ( Qt : : MetaModifier | Qt : : ControlModifier ) ) ) {
App : : wnd ( ) - > setWindowState ( Qt : : WindowMinimized ) ;
2015-04-19 19:01:45 +00:00
return true ;
2014-09-26 23:48:19 +00:00
}
2015-07-13 17:55:59 +00:00
}
if ( ev - > key ( ) = = Qt : : Key_MediaPlay ) {
if ( App : : main ( ) ) App : : main ( ) - > player ( ) - > playPressed ( ) ;
} else if ( ev - > key ( ) = = Qt : : Key_MediaPause ) {
if ( App : : main ( ) ) App : : main ( ) - > player ( ) - > pausePressed ( ) ;
} else if ( ev - > key ( ) = = Qt : : Key_MediaTogglePlayPause ) {
if ( App : : main ( ) ) App : : main ( ) - > player ( ) - > playPausePressed ( ) ;
} else if ( ev - > key ( ) = = Qt : : Key_MediaStop ) {
if ( App : : main ( ) ) App : : main ( ) - > player ( ) - > stopPressed ( ) ;
} else if ( ev - > key ( ) = = Qt : : Key_MediaPrevious ) {
if ( App : : main ( ) ) App : : main ( ) - > player ( ) - > prevPressed ( ) ;
} else if ( ev - > key ( ) = = Qt : : Key_MediaNext ) {
if ( App : : main ( ) ) App : : main ( ) - > player ( ) - > nextPressed ( ) ;
2014-09-26 23:48:19 +00:00
}
2014-05-30 08:53:19 +00:00
}
return QObject : : eventFilter ( o , e ) ;
}
} ;
}
2014-06-14 19:32:11 +00:00
Application : : Application ( int & argc , char * * argv ) : PsApplication ( argc , argv ) ,
2014-05-30 08:53:19 +00:00
serverName ( psServerPrefix ( ) + cGUIDStr ( ) ) , closing ( false ) ,
2015-08-19 22:00:37 +00:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
updateRequestId ( 0 ) , updateReply ( 0 ) , updateThread ( 0 ) , updateDownloader ( 0 ) ,
# endif
_translator ( 0 ) {
2014-07-18 10:37:34 +00:00
2014-11-26 16:45:52 +00:00
DEBUG_LOG ( ( " Application Info: creation.. " ) ) ;
2014-07-18 10:37:34 +00:00
QByteArray d ( QDir ( ( cPlatform ( ) = = dbipWindows ? cExeDir ( ) : cWorkingDir ( ) ) . toLower ( ) ) . absolutePath ( ) . toUtf8 ( ) ) ;
char h [ 33 ] = { 0 } ;
hashMd5Hex ( d . constData ( ) , d . size ( ) , h ) ;
serverName = psServerPrefix ( ) + h + ' - ' + cGUIDStr ( ) ;
2014-05-30 08:53:19 +00:00
if ( mainApp ) {
DEBUG_LOG ( ( " Application Error: another Application was created, terminating.. " ) ) ;
exit ( 0 ) ;
}
mainApp = this ;
2015-07-13 17:55:59 +00:00
installEventFilter ( new EventFilterForKeys ( this ) ) ;
2014-05-30 08:53:19 +00:00
2014-07-14 05:16:21 +00:00
QFontDatabase : : addApplicationFont ( qsl ( " :/gui/art/fonts/OpenSans-Regular.ttf " ) ) ;
QFontDatabase : : addApplicationFont ( qsl ( " :/gui/art/fonts/OpenSans-Bold.ttf " ) ) ;
QFontDatabase : : addApplicationFont ( qsl ( " :/gui/art/fonts/OpenSans-Semibold.ttf " ) ) ;
2014-05-30 08:53:19 +00:00
float64 dpi = primaryScreen ( ) - > logicalDotsPerInch ( ) ;
if ( dpi < = 108 ) { // 0-96-108
cSetScreenScale ( dbisOne ) ;
} else if ( dpi < = 132 ) { // 108-120-132
cSetScreenScale ( dbisOneAndQuarter ) ;
} else if ( dpi < = 168 ) { // 132-144-168
cSetScreenScale ( dbisOneAndHalf ) ;
} else { // 168-192-inf
cSetScreenScale ( dbisTwo ) ;
}
2014-06-15 12:31:03 +00:00
if ( devicePixelRatio ( ) > 1 ) {
cSetRetina ( true ) ;
cSetRetinaFactor ( devicePixelRatio ( ) ) ;
cSetIntRetinaFactor ( int32 ( cRetinaFactor ( ) ) ) ;
2015-02-03 15:06:15 +00:00
cSetConfigScale ( dbisOne ) ;
cSetRealScale ( dbisOne ) ;
2014-06-15 12:31:03 +00:00
}
2014-12-20 21:33:08 +00:00
if ( cLang ( ) < languageTest ) {
2014-12-19 21:20:30 +00:00
cSetLang ( languageId ( ) ) ;
}
2014-12-20 21:33:08 +00:00
if ( cLang ( ) = = languageTest ) {
if ( QFileInfo ( cLangFile ( ) ) . exists ( ) ) {
LangLoaderPlain loader ( cLangFile ( ) ) ;
2014-12-19 21:20:30 +00:00
cSetLangErrors ( loader . errors ( ) ) ;
if ( ! cLangErrors ( ) . isEmpty ( ) ) {
LOG ( ( " Lang load errors: %1 " ) . arg ( cLangErrors ( ) ) ) ;
} else if ( ! loader . warnings ( ) . isEmpty ( ) ) {
LOG ( ( " Lang load warnings: %1 " ) . arg ( loader . warnings ( ) ) ) ;
}
} else {
2014-12-20 21:33:08 +00:00
cSetLang ( languageDefault ) ;
2014-12-19 21:20:30 +00:00
}
2014-12-20 21:33:08 +00:00
} else if ( cLang ( ) > languageDefault & & cLang ( ) < languageCount ) {
2014-12-19 21:20:30 +00:00
LangLoaderPlain loader ( qsl ( " :/langs/lang_ " ) + LanguageCodes [ cLang ( ) ] + qsl ( " .strings " ) ) ;
if ( ! loader . errors ( ) . isEmpty ( ) ) {
LOG ( ( " Lang load errors: %1 " ) . arg ( loader . errors ( ) ) ) ;
2014-05-30 08:53:19 +00:00
} else if ( ! loader . warnings ( ) . isEmpty ( ) ) {
LOG ( ( " Lang load warnings: %1 " ) . arg ( loader . warnings ( ) ) ) ;
}
}
2015-01-05 20:19:05 +00:00
installTranslator ( _translator = new Translator ( ) ) ;
2014-05-30 08:53:19 +00:00
style : : startManager ( ) ;
anim : : startManager ( ) ;
historyInit ( ) ;
2014-11-26 16:45:52 +00:00
DEBUG_LOG ( ( " Application Info: inited.. " ) ) ;
2014-07-14 05:16:21 +00:00
window = new Window ( ) ;
2014-05-30 08:53:19 +00:00
2014-11-26 16:45:52 +00:00
psInstallEventFilter ( ) ;
2014-05-30 08:53:19 +00:00
connect ( & socket , SIGNAL ( connected ( ) ) , this , SLOT ( socketConnected ( ) ) ) ;
connect ( & socket , SIGNAL ( disconnected ( ) ) , this , SLOT ( socketDisconnected ( ) ) ) ;
connect ( & socket , SIGNAL ( error ( QLocalSocket : : LocalSocketError ) ) , this , SLOT ( socketError ( QLocalSocket : : LocalSocketError ) ) ) ;
connect ( & socket , SIGNAL ( bytesWritten ( qint64 ) ) , this , SLOT ( socketWritten ( qint64 ) ) ) ;
connect ( & socket , SIGNAL ( readyRead ( ) ) , this , SLOT ( socketReading ( ) ) ) ;
connect ( & server , SIGNAL ( newConnection ( ) ) , this , SLOT ( newInstanceConnected ( ) ) ) ;
connect ( this , SIGNAL ( aboutToQuit ( ) ) , this , SLOT ( closeApplication ( ) ) ) ;
2015-08-19 22:00:37 +00:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
2014-05-30 08:53:19 +00:00
connect ( & updateCheckTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( startUpdateCheck ( ) ) ) ;
connect ( this , SIGNAL ( updateFailed ( ) ) , this , SLOT ( onUpdateFailed ( ) ) ) ;
connect ( this , SIGNAL ( updateReady ( ) ) , this , SLOT ( onUpdateReady ( ) ) ) ;
2015-08-19 22:00:37 +00:00
# endif
2014-11-12 20:30:26 +00:00
connect ( this , SIGNAL ( applicationStateChanged ( Qt : : ApplicationState ) ) , this , SLOT ( onAppStateChanged ( Qt : : ApplicationState ) ) ) ;
2015-03-02 12:34:16 +00:00
//connect(&writeUserConfigTimer, SIGNAL(timeout()), this, SLOT(onWriteUserConfig()));
//writeUserConfigTimer.setSingleShot(true);
2014-05-30 08:53:19 +00:00
2014-10-30 16:23:44 +00:00
connect ( & killDownloadSessionsTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( killDownloadSessions ( ) ) ) ;
2014-11-26 16:45:52 +00:00
if ( cManyInstance ( ) ) {
2014-05-30 08:53:19 +00:00
startApp ( ) ;
} else {
DEBUG_LOG ( ( " Application Info: connecting local socket to %1.. " ) . arg ( serverName ) ) ;
socket . connectToServer ( serverName ) ;
}
}
2015-08-19 22:00:37 +00:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
2014-05-30 08:53:19 +00:00
void Application : : updateGotCurrent ( ) {
if ( ! updateReply | | updateThread ) return ;
cSetLastUpdateCheck ( unixtime ( ) ) ;
QRegularExpressionMatch m = QRegularExpression ( qsl ( " ^ \\ s*( \\ d+) \\ s*: \\ s*([ \\ x21- \\ x7f]+) \\ s*$ " ) ) . match ( QString : : fromUtf8 ( updateReply - > readAll ( ) ) ) ;
if ( m . hasMatch ( ) ) {
int32 currentVersion = m . captured ( 1 ) . toInt ( ) ;
if ( currentVersion > AppVersion ) {
updateThread = new QThread ( ) ;
2014-11-27 18:58:51 +00:00
connect ( updateThread , SIGNAL ( finished ( ) ) , updateThread , SLOT ( deleteLater ( ) ) ) ;
2015-06-03 18:13:01 +00:00
updateDownloader = new UpdateDownloader ( updateThread , m . captured ( 2 ) ) ;
2014-05-30 08:53:19 +00:00
updateThread - > start ( ) ;
}
}
if ( updateReply ) updateReply - > deleteLater ( ) ;
updateReply = 0 ;
if ( ! updateThread ) {
QDir updates ( cWorkingDir ( ) + " tupdates " ) ;
if ( updates . exists ( ) ) {
QFileInfoList list = updates . entryInfoList ( QDir : : Files ) ;
for ( QFileInfoList : : iterator i = list . begin ( ) , e = list . end ( ) ; i ! = e ; + + i ) {
2015-07-28 13:47:21 +00:00
if ( QRegularExpression ( " ^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd) \\ d+$ " , QRegularExpression : : CaseInsensitiveOption ) . match ( i - > fileName ( ) ) . hasMatch ( ) ) {
2014-05-30 08:53:19 +00:00
QFile ( i - > absoluteFilePath ( ) ) . remove ( ) ;
}
}
}
emit updateLatest ( ) ;
}
startUpdateCheck ( true ) ;
2015-03-02 12:34:16 +00:00
Local : : writeSettings ( ) ;
2014-05-30 08:53:19 +00:00
}
void Application : : updateFailedCurrent ( QNetworkReply : : NetworkError e ) {
LOG ( ( " App Error: could not get current version (update check): %1 " ) . arg ( e ) ) ;
if ( updateReply ) updateReply - > deleteLater ( ) ;
updateReply = 0 ;
emit updateFailed ( ) ;
startUpdateCheck ( true ) ;
}
void Application : : onUpdateReady ( ) {
if ( updateDownloader ) {
updateDownloader - > deleteLater ( ) ;
updateDownloader = 0 ;
}
updateCheckTimer . stop ( ) ;
cSetLastUpdateCheck ( unixtime ( ) ) ;
2015-03-02 12:34:16 +00:00
Local : : writeSettings ( ) ;
2014-05-30 08:53:19 +00:00
}
void Application : : onUpdateFailed ( ) {
if ( updateDownloader ) {
updateDownloader - > deleteLater ( ) ;
updateDownloader = 0 ;
2014-11-27 18:58:51 +00:00
if ( updateThread ) updateThread - > quit ( ) ;
2014-05-30 08:53:19 +00:00
updateThread = 0 ;
}
cSetLastUpdateCheck ( unixtime ( ) ) ;
2015-03-02 12:34:16 +00:00
Local : : writeSettings ( ) ;
2014-05-30 08:53:19 +00:00
}
2015-08-19 22:00:37 +00:00
# endif
2014-05-30 08:53:19 +00:00
2015-09-03 10:48:40 +00:00
void Application : : regPhotoUpdate ( const PeerId & peer , const FullMsgId & msgId ) {
2014-05-30 08:53:19 +00:00
photoUpdates . insert ( msgId , peer ) ;
}
void Application : : clearPhotoUpdates ( ) {
photoUpdates . clear ( ) ;
}
bool Application : : isPhotoUpdating ( const PeerId & peer ) {
2015-09-03 10:48:40 +00:00
for ( QMap < FullMsgId , PeerId > : : iterator i = photoUpdates . begin ( ) , e = photoUpdates . end ( ) ; i ! = e ; + + i ) {
2014-05-30 08:53:19 +00:00
if ( i . value ( ) = = peer ) {
return true ;
}
}
return false ;
}
void Application : : cancelPhotoUpdate ( const PeerId & peer ) {
2015-09-03 10:48:40 +00:00
for ( QMap < FullMsgId , PeerId > : : iterator i = photoUpdates . begin ( ) , e = photoUpdates . end ( ) ; i ! = e ; ) {
2014-05-30 08:53:19 +00:00
if ( i . value ( ) = = peer ) {
i = photoUpdates . erase ( i ) ;
} else {
+ + i ;
}
}
}
void Application : : selfPhotoCleared ( const MTPUserProfilePhoto & result ) {
if ( ! App : : self ( ) ) return ;
App : : self ( ) - > setPhoto ( result ) ;
emit peerPhotoDone ( App : : self ( ) - > id ) ;
}
2015-04-02 10:33:19 +00:00
void Application : : chatPhotoCleared ( PeerId peer , const MTPUpdates & updates ) {
2014-05-30 08:53:19 +00:00
if ( App : : main ( ) ) {
2015-04-02 10:33:19 +00:00
App : : main ( ) - > sentUpdatesReceived ( updates ) ;
2014-05-30 08:53:19 +00:00
}
cancelPhotoUpdate ( peer ) ;
emit peerPhotoDone ( peer ) ;
}
void Application : : selfPhotoDone ( const MTPphotos_Photo & result ) {
if ( ! App : : self ( ) ) return ;
const MTPDphotos_photo & photo ( result . c_photos_photo ( ) ) ;
App : : feedPhoto ( photo . vphoto ) ;
App : : feedUsers ( photo . vusers ) ;
cancelPhotoUpdate ( App : : self ( ) - > id ) ;
emit peerPhotoDone ( App : : self ( ) - > id ) ;
}
2015-04-02 10:33:19 +00:00
void Application : : chatPhotoDone ( PeerId peer , const MTPUpdates & updates ) {
2014-05-30 08:53:19 +00:00
if ( App : : main ( ) ) {
2015-04-02 10:33:19 +00:00
App : : main ( ) - > sentUpdatesReceived ( updates ) ;
2014-05-30 08:53:19 +00:00
}
cancelPhotoUpdate ( peer ) ;
emit peerPhotoDone ( peer ) ;
}
2015-04-04 20:01:34 +00:00
bool Application : : peerPhotoFail ( PeerId peer , const RPCError & error ) {
if ( error . type ( ) . startsWith ( qsl ( " FLOOD_WAIT_ " ) ) ) return false ;
LOG ( ( " Application Error: update photo failed %1: %2 " ) . arg ( error . type ( ) ) . arg ( error . description ( ) ) ) ;
2014-05-30 08:53:19 +00:00
cancelPhotoUpdate ( peer ) ;
emit peerPhotoFail ( peer ) ;
return true ;
}
2015-09-03 10:48:40 +00:00
void Application : : peerClearPhoto ( PeerId id ) {
if ( MTP : : authedId ( ) & & peerToUser ( id ) = = MTP : : authedId ( ) ) {
MTP : : send ( MTPphotos_UpdateProfilePhoto ( MTP_inputPhotoEmpty ( ) , MTP_inputPhotoCropAuto ( ) ) , rpcDone ( & Application : : selfPhotoCleared ) , rpcFail ( & Application : : peerPhotoFail , id ) ) ;
} else if ( peerIsChat ( id ) ) {
MTP : : send ( MTPmessages_EditChatPhoto ( MTP_inputChat ( peerToBareMTPInt ( id ) ) , MTP_inputChatPhotoEmpty ( ) ) , rpcDone ( & Application : : chatPhotoCleared , id ) , rpcFail ( & Application : : peerPhotoFail , id ) ) ;
} else if ( peerIsChannel ( id ) ) {
if ( ChannelData * channel = App : : channelLoaded ( id ) ) {
MTP : : send ( MTPmessages_EditChatPhoto ( channel - > inputChat , MTP_inputChatPhotoEmpty ( ) ) , rpcDone ( & Application : : chatPhotoCleared , id ) , rpcFail ( & Application : : peerPhotoFail , id ) ) ;
}
2014-05-30 08:53:19 +00:00
}
}
2014-10-30 16:23:44 +00:00
void Application : : killDownloadSessionsStart ( int32 dc ) {
if ( killDownloadSessionTimes . constFind ( dc ) = = killDownloadSessionTimes . cend ( ) ) {
2014-11-05 17:43:32 +00:00
killDownloadSessionTimes . insert ( dc , getms ( ) + MTPAckSendWaiting + MTPKillFileSessionTimeout ) ;
2014-10-30 16:23:44 +00:00
}
if ( ! killDownloadSessionsTimer . isActive ( ) ) {
2014-11-05 17:43:32 +00:00
killDownloadSessionsTimer . start ( MTPAckSendWaiting + MTPKillFileSessionTimeout + 5 ) ;
2014-10-30 16:23:44 +00:00
}
}
void Application : : killDownloadSessionsStop ( int32 dc ) {
killDownloadSessionTimes . remove ( dc ) ;
if ( killDownloadSessionTimes . isEmpty ( ) & & killDownloadSessionsTimer . isActive ( ) ) {
killDownloadSessionsTimer . stop ( ) ;
}
}
2014-11-12 20:30:26 +00:00
void Application : : checkLocalTime ( ) {
if ( App : : main ( ) ) App : : main ( ) - > checkLastUpdate ( checkms ( ) ) ;
}
void Application : : onAppStateChanged ( Qt : : ApplicationState state ) {
checkLocalTime ( ) ;
2015-01-26 13:04:41 +00:00
if ( window ) window - > updateIsActive ( ( state = = Qt : : ApplicationActive ) ? cOnlineFocusTimeout ( ) : cOfflineBlurTimeout ( ) ) ;
2014-11-12 20:30:26 +00:00
}
2014-10-30 16:23:44 +00:00
void Application : : killDownloadSessions ( ) {
2014-11-05 17:43:32 +00:00
uint64 ms = getms ( ) , left = MTPAckSendWaiting + MTPKillFileSessionTimeout ;
2014-10-30 16:23:44 +00:00
for ( QMap < int32 , uint64 > : : iterator i = killDownloadSessionTimes . begin ( ) ; i ! = killDownloadSessionTimes . end ( ) ; ) {
if ( i . value ( ) < = ms ) {
2014-12-05 13:44:27 +00:00
for ( int j = 0 ; j < MTPDownloadSessionsCount ; + + j ) {
MTP : : stopSession ( MTP : : dld [ j ] + i . key ( ) ) ;
2014-10-30 16:23:44 +00:00
}
i = killDownloadSessionTimes . erase ( i ) ;
} else {
if ( i . value ( ) - ms < left ) {
left = i . value ( ) - ms ;
}
+ + i ;
}
}
if ( ! killDownloadSessionTimes . isEmpty ( ) ) {
killDownloadSessionsTimer . start ( left ) ;
}
}
2015-09-03 10:48:40 +00:00
void Application : : photoUpdated ( const FullMsgId & msgId , const MTPInputFile & file ) {
2014-05-30 08:53:19 +00:00
if ( ! App : : self ( ) ) return ;
2015-09-03 10:48:40 +00:00
QMap < FullMsgId , PeerId > : : iterator i = photoUpdates . find ( msgId ) ;
2014-05-30 08:53:19 +00:00
if ( i ! = photoUpdates . end ( ) ) {
2015-09-03 10:48:40 +00:00
PeerId id = i . value ( ) ;
if ( MTP : : authedId ( ) & & peerToUser ( id ) = = MTP : : authedId ( ) ) {
MTP : : send ( MTPphotos_UploadProfilePhoto ( file , MTP_string ( " " ) , MTP_inputGeoPointEmpty ( ) , MTP_inputPhotoCrop ( MTP_double ( 0 ) , MTP_double ( 0 ) , MTP_double ( 100 ) ) ) , rpcDone ( & Application : : selfPhotoDone ) , rpcFail ( & Application : : peerPhotoFail , id ) ) ;
} else if ( peerIsChat ( id ) | | peerIsChannel ( id ) ) {
History * hist = App : : history ( id ) ;
hist - > sendRequestId = MTP : : send ( MTPmessages_EditChatPhoto ( hist - > peer - > isChat ( ) ? hist - > peer - > asChat ( ) - > inputChat : hist - > peer - > asChannel ( ) - > inputChat , MTP_inputChatUploadedPhoto ( file , MTP_inputPhotoCrop ( MTP_double ( 0 ) , MTP_double ( 0 ) , MTP_double ( 100 ) ) ) ) , rpcDone ( & Application : : chatPhotoDone , id ) , rpcFail ( & Application : : peerPhotoFail , id ) , 0 , 0 , hist - > sendRequestId ) ;
2014-05-30 08:53:19 +00:00
}
}
}
2015-04-02 10:33:19 +00:00
void Application : : onSwitchDebugMode ( ) {
if ( cDebug ( ) ) {
QFile ( cWorkingDir ( ) + qsl ( " tdata/withdebug " ) ) . remove ( ) ;
cSetDebug ( false ) ;
cSetRestarting ( true ) ;
cSetRestartingToSettings ( true ) ;
App : : quit ( ) ;
} else {
2014-05-30 08:53:19 +00:00
logsInitDebug ( ) ;
cSetDebug ( true ) ;
2014-09-30 14:11:09 +00:00
QFile f ( cWorkingDir ( ) + qsl ( " tdata/withdebug " ) ) ;
if ( f . open ( QIODevice : : WriteOnly ) ) {
f . write ( " 1 " ) ;
f . close ( ) ;
}
2015-04-02 10:33:19 +00:00
App : : wnd ( ) - > hideLayer ( ) ;
}
}
void Application : : onSwitchTestMode ( ) {
if ( cTestMode ( ) ) {
QFile ( cWorkingDir ( ) + qsl ( " tdata/withtestmode " ) ) . remove ( ) ;
cSetTestMode ( false ) ;
} else {
QFile f ( cWorkingDir ( ) + qsl ( " tdata/withtestmode " ) ) ;
if ( f . open ( QIODevice : : WriteOnly ) ) {
f . write ( " 1 " ) ;
f . close ( ) ;
}
cSetTestMode ( true ) ;
2014-05-30 08:53:19 +00:00
}
2015-04-02 10:33:19 +00:00
cSetRestarting ( true ) ;
cSetRestartingToSettings ( true ) ;
App : : quit ( ) ;
2014-05-30 08:53:19 +00:00
}
Application : : UpdatingState Application : : updatingState ( ) {
2015-08-19 22:00:37 +00:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
2014-05-30 08:53:19 +00:00
if ( ! updateThread ) return Application : : UpdatingNone ;
if ( ! updateDownloader ) return Application : : UpdatingReady ;
return Application : : UpdatingDownload ;
2015-08-19 22:00:37 +00:00
# else
return Application : : UpdatingNone ;
# endif
2014-05-30 08:53:19 +00:00
}
2015-08-19 22:00:37 +00:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
2014-05-30 08:53:19 +00:00
int32 Application : : updatingSize ( ) {
if ( ! updateDownloader ) return 0 ;
return updateDownloader - > size ( ) ;
}
int32 Application : : updatingReady ( ) {
if ( ! updateDownloader ) return 0 ;
return updateDownloader - > ready ( ) ;
}
2015-08-19 22:00:37 +00:00
# endif
2014-05-30 08:53:19 +00:00
FileUploader * Application : : uploader ( ) {
if ( ! : : uploader ) : : uploader = new FileUploader ( ) ;
return : : uploader ;
}
void Application : : uploadProfilePhoto ( const QImage & tosend , const PeerId & peerId ) {
PreparedPhotoThumbs photoThumbs ;
QVector < MTPPhotoSize > photoSizes ;
2014-12-22 23:11:37 +00:00
QPixmap thumb = QPixmap : : fromImage ( tosend . scaled ( 160 , 160 , Qt : : KeepAspectRatio , Qt : : SmoothTransformation ) , Qt : : ColorOnly ) ;
2014-05-30 08:53:19 +00:00
photoThumbs . insert ( ' a ' , thumb ) ;
photoSizes . push_back ( MTP_photoSize ( MTP_string ( " a " ) , MTP_fileLocationUnavailable ( MTP_long ( 0 ) , MTP_int ( 0 ) , MTP_long ( 0 ) ) , MTP_int ( thumb . width ( ) ) , MTP_int ( thumb . height ( ) ) , MTP_int ( 0 ) ) ) ;
2014-12-22 23:11:37 +00:00
QPixmap medium = QPixmap : : fromImage ( tosend . scaled ( 320 , 320 , Qt : : KeepAspectRatio , Qt : : SmoothTransformation ) , Qt : : ColorOnly ) ;
2014-08-15 11:19:32 +00:00
photoThumbs . insert ( ' b ' , medium ) ;
photoSizes . push_back ( MTP_photoSize ( MTP_string ( " b " ) , MTP_fileLocationUnavailable ( MTP_long ( 0 ) , MTP_int ( 0 ) , MTP_long ( 0 ) ) , MTP_int ( medium . width ( ) ) , MTP_int ( medium . height ( ) ) , MTP_int ( 0 ) ) ) ;
2014-12-22 23:11:37 +00:00
QPixmap full = QPixmap : : fromImage ( tosend , Qt : : ColorOnly ) ;
2014-05-30 08:53:19 +00:00
photoThumbs . insert ( ' c ' , full ) ;
photoSizes . push_back ( MTP_photoSize ( MTP_string ( " c " ) , MTP_fileLocationUnavailable ( MTP_long ( 0 ) , MTP_int ( 0 ) , MTP_long ( 0 ) ) , MTP_int ( full . width ( ) ) , MTP_int ( full . height ( ) ) , MTP_int ( 0 ) ) ) ;
QByteArray jpeg ;
QBuffer jpegBuffer ( & jpeg ) ;
full . save ( & jpegBuffer , " JPG " , 87 ) ;
PhotoId id = MTP : : nonce < PhotoId > ( ) ;
2015-08-12 18:01:32 +00:00
MTPPhoto photo ( MTP_photo ( MTP_long ( id ) , MTP_long ( 0 ) , MTP_int ( unixtime ( ) ) , MTP_vector < MTPPhotoSize > ( photoSizes ) ) ) ;
2014-05-30 08:53:19 +00:00
QString file , filename ;
int32 filesize = 0 ;
QByteArray data ;
2015-05-29 18:52:43 +00:00
ReadyLocalMedia ready ( ToPreparePhoto , file , filename , filesize , data , id , id , qsl ( " jpg " ) , peerId , photo , MTP_audioEmpty ( MTP_long ( 0 ) ) , photoThumbs , MTP_documentEmpty ( MTP_long ( 0 ) ) , jpeg , false , 0 ) ;
2014-05-30 08:53:19 +00:00
2015-09-03 10:48:40 +00:00
connect ( App : : uploader ( ) , SIGNAL ( photoReady ( const FullMsgId & , const MTPInputFile & ) ) , App : : app ( ) , SLOT ( photoUpdated ( const FullMsgId & , const MTPInputFile & ) ) , Qt : : UniqueConnection ) ;
2014-05-30 08:53:19 +00:00
2015-09-03 10:48:40 +00:00
FullMsgId newId ( peerToChannel ( peerId ) , clientMsgId ( ) ) ;
2014-05-30 08:53:19 +00:00
App : : app ( ) - > regPhotoUpdate ( peerId , newId ) ;
App : : uploader ( ) - > uploadMedia ( newId , ready ) ;
}
2015-08-19 22:00:37 +00:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
2014-05-30 08:53:19 +00:00
void Application : : stopUpdate ( ) {
if ( updateReply ) {
updateReply - > abort ( ) ;
updateReply - > deleteLater ( ) ;
updateReply = 0 ;
}
if ( updateDownloader ) {
updateDownloader - > deleteLater ( ) ;
updateDownloader = 0 ;
2014-11-27 18:58:51 +00:00
if ( updateThread ) updateThread - > quit ( ) ;
2014-05-30 08:53:19 +00:00
updateThread = 0 ;
}
}
void Application : : startUpdateCheck ( bool forceWait ) {
updateCheckTimer . stop ( ) ;
if ( updateRequestId | | updateThread | | updateReply | | ! cAutoUpdate ( ) ) return ;
2015-02-09 13:26:59 +00:00
int32 updateInSecs = cLastUpdateCheck ( ) + UpdateDelayConstPart + ( rand ( ) % UpdateDelayRandPart ) - unixtime ( ) ;
bool sendRequest = ( updateInSecs < = 0 | | updateInSecs > ( UpdateDelayConstPart + UpdateDelayRandPart ) ) ;
2014-05-30 08:53:19 +00:00
if ( ! sendRequest & & ! forceWait ) {
QDir updates ( cWorkingDir ( ) + " tupdates " ) ;
if ( updates . exists ( ) ) {
QFileInfoList list = updates . entryInfoList ( QDir : : Files ) ;
for ( QFileInfoList : : iterator i = list . begin ( ) , e = list . end ( ) ; i ! = e ; + + i ) {
2015-07-28 13:47:21 +00:00
if ( QRegularExpression ( " ^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd) \\ d+$ " , QRegularExpression : : CaseInsensitiveOption ) . match ( i - > fileName ( ) ) . hasMatch ( ) ) {
2014-05-30 08:53:19 +00:00
sendRequest = true ;
}
}
}
}
2014-07-14 05:16:21 +00:00
if ( cManyInstance ( ) & & ! cDebug ( ) ) return ; // only main instance is updating
2014-05-30 08:53:19 +00:00
if ( sendRequest ) {
2015-02-05 14:49:50 +00:00
QUrl url ( cUpdateURL ( ) ) ;
2015-07-28 13:47:21 +00:00
if ( cDevVersion ( ) ) {
url . setQuery ( qsl ( " version=%1&dev=1 " ) . arg ( AppVersion ) ) ;
} else {
url . setQuery ( qsl ( " version=%1 " ) . arg ( AppVersion ) ) ;
}
2015-02-05 14:49:50 +00:00
QString u = url . toString ( ) ;
QNetworkRequest checkVersion ( url ) ;
2014-05-30 08:53:19 +00:00
if ( updateReply ) updateReply - > deleteLater ( ) ;
App : : setProxySettings ( updateManager ) ;
updateReply = updateManager . get ( checkVersion ) ;
connect ( updateReply , SIGNAL ( finished ( ) ) , this , SLOT ( updateGotCurrent ( ) ) ) ;
connect ( updateReply , SIGNAL ( error ( QNetworkReply : : NetworkError ) ) , this , SLOT ( updateFailedCurrent ( QNetworkReply : : NetworkError ) ) ) ;
emit updateChecking ( ) ;
} else {
updateCheckTimer . start ( ( updateInSecs + 5 ) * 1000 ) ;
}
}
2015-08-19 22:00:37 +00:00
# endif
2014-05-30 08:53:19 +00:00
2014-07-18 10:37:34 +00:00
namespace {
QChar _toHex ( ushort v ) {
v = v & 0x000F ;
return QChar : : fromLatin1 ( ( v > = 10 ) ? ( ' a ' + ( v - 10 ) ) : ( ' 0 ' + v ) ) ;
}
ushort _fromHex ( QChar c ) {
return ( ( c . unicode ( ) > = uchar ( ' a ' ) ) ? ( c . unicode ( ) - uchar ( ' a ' ) + 10 ) : ( c . unicode ( ) - uchar ( ' 0 ' ) ) ) & 0x000F ;
}
QString _escapeTo7bit ( const QString & str ) {
QString result ;
result . reserve ( str . size ( ) * 2 ) ;
for ( int i = 0 , l = str . size ( ) ; i ! = l ; + + i ) {
QChar ch ( str . at ( i ) ) ;
ushort uch ( ch . unicode ( ) ) ;
if ( uch < 32 | | uch > 127 | | uch = = ushort ( uchar ( ' % ' ) ) ) {
result . append ( ' % ' ) . append ( _toHex ( uch > > 12 ) ) . append ( _toHex ( uch > > 8 ) ) . append ( _toHex ( uch > > 4 ) ) . append ( _toHex ( uch ) ) ;
} else {
result . append ( ch ) ;
}
}
return result ;
}
QString _escapeFrom7bit ( const QString & str ) {
QString result ;
result . reserve ( str . size ( ) ) ;
for ( int i = 0 , l = str . size ( ) ; i ! = l ; + + i ) {
QChar ch ( str . at ( i ) ) ;
if ( ch = = QChar : : fromLatin1 ( ' % ' ) & & i + 4 < l ) {
result . append ( QChar ( ushort ( ( _fromHex ( str . at ( i + 1 ) ) < < 12 ) | ( _fromHex ( str . at ( i + 2 ) ) < < 8 ) | ( _fromHex ( str . at ( i + 3 ) ) < < 4 ) | _fromHex ( str . at ( i + 4 ) ) ) ) ) ;
i + = 4 ;
} else {
result . append ( ch ) ;
}
}
return result ;
}
}
2014-05-30 08:53:19 +00:00
void Application : : socketConnected ( ) {
DEBUG_LOG ( ( " Application Info: socket connected, this is not the first application instance, sending show command.. " ) ) ;
closing = true ;
2014-07-18 10:37:34 +00:00
QString commands ;
const QStringList & lst ( cSendPaths ( ) ) ;
for ( QStringList : : const_iterator i = lst . cbegin ( ) , e = lst . cend ( ) ; i ! = e ; + + i ) {
commands + = qsl ( " SEND: " ) + _escapeTo7bit ( * i ) + ' ; ' ;
}
2014-12-03 13:10:32 +00:00
if ( ! cStartUrl ( ) . isEmpty ( ) ) {
commands + = qsl ( " OPEN: " ) + _escapeTo7bit ( cStartUrl ( ) ) + ' ; ' ;
}
2014-07-18 10:37:34 +00:00
commands + = qsl ( " CMD:show; " ) ;
DEBUG_LOG ( ( " Application Info: writing commands %1 " ) . arg ( commands ) ) ;
socket . write ( commands . toLocal8Bit ( ) ) ;
2014-05-30 08:53:19 +00:00
}
void Application : : socketWritten ( qint64 /* bytes*/ ) {
if ( socket . state ( ) ! = QLocalSocket : : ConnectedState ) {
DEBUG_LOG ( ( " Application Error: socket is not connected %1 " ) . arg ( socket . state ( ) ) ) ;
return ;
}
if ( socket . bytesToWrite ( ) ) {
return ;
}
DEBUG_LOG ( ( " Application Info: show command written, waiting response.. " ) ) ;
}
void Application : : socketReading ( ) {
if ( socket . state ( ) ! = QLocalSocket : : ConnectedState ) {
DEBUG_LOG ( ( " Application Error: socket is not connected %1 " ) . arg ( socket . state ( ) ) ) ;
return ;
}
socketRead . append ( socket . readAll ( ) ) ;
if ( QRegularExpression ( " RES:( \\ d+); " ) . match ( socketRead ) . hasMatch ( ) ) {
uint64 pid = socketRead . mid ( 4 , socketRead . length ( ) - 5 ) . toULongLong ( ) ;
psActivateProcess ( pid ) ;
DEBUG_LOG ( ( " Application Info: show command response received, pid = %1, activating and quiting.. " ) . arg ( pid ) ) ;
return App : : quit ( ) ;
}
}
void Application : : socketError ( QLocalSocket : : LocalSocketError e ) {
if ( closing ) {
DEBUG_LOG ( ( " Application Error: could not write show command, error %1, quiting.. " ) . arg ( e ) ) ;
return App : : quit ( ) ;
}
if ( e = = QLocalSocket : : ServerNotFoundError ) {
DEBUG_LOG ( ( " Application Info: this is the only instance of Telegram, starting server and app.. " ) ) ;
} else {
DEBUG_LOG ( ( " Application Info: socket connect error %1, starting server and app.. " ) . arg ( e ) ) ;
}
socket . close ( ) ;
psCheckLocalSocket ( serverName ) ;
if ( ! server . listen ( serverName ) ) {
2014-07-18 10:37:34 +00:00
DEBUG_LOG ( ( " Application Error: failed to start listening to %1 server, error %2 " ) . arg ( serverName ) . arg ( int ( server . serverError ( ) ) ) ) ;
2014-05-30 08:53:19 +00:00
return App : : quit ( ) ;
}
2015-08-19 22:00:37 +00:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
2015-06-03 18:13:01 +00:00
if ( ! cNoStartUpdate ( ) & & checkReadyUpdate ( ) ) {
2014-05-30 08:53:19 +00:00
cSetRestartingUpdate ( true ) ;
DEBUG_LOG ( ( " Application Info: installing update instead of starting app.. " ) ) ;
return App : : quit ( ) ;
}
2015-08-19 22:00:37 +00:00
# endif
2014-05-30 08:53:19 +00:00
startApp ( ) ;
}
2015-03-02 12:34:16 +00:00
void Application : : checkMapVersion ( ) {
2015-06-02 12:29:02 +00:00
if ( Local : : oldMapVersion ( ) < AppVersion ) {
2015-03-02 12:34:16 +00:00
if ( Local : : oldMapVersion ( ) ) {
QString versionFeatures ;
2015-08-31 15:05:57 +00:00
if ( cDevVersion ( ) & & Local : : oldMapVersion ( ) < 8054 ) {
versionFeatures = QString : : fromUtf8 ( " \xe2 \x80 \x94 Preview when sending links to GIF animations and PDF files \n \xe2 \x80 \x94 Full date and time shown when mouse over message timestamp " ) ; // .replace('@', qsl("@") + QChar(0x200D));
2015-09-01 14:00:32 +00:00
} else if ( ! cDevVersion ( ) & & Local : : oldMapVersion ( ) < 8055 ) {
versionFeatures = lang ( lng_new_version_text ) . trimmed ( ) ;
2015-03-02 12:34:16 +00:00
}
if ( ! versionFeatures . isEmpty ( ) ) {
versionFeatures = lng_new_version_wrap ( lt_version , QString : : fromStdWString ( AppVersionStr ) , lt_changes , versionFeatures , lt_link , qsl ( " https://desktop.telegram.org/#changelog " ) ) ;
window - > serviceNotification ( versionFeatures ) ;
}
}
}
}
2014-05-30 08:53:19 +00:00
void Application : : startApp ( ) {
2015-02-10 18:55:04 +00:00
cChangeTimeFormat ( QLocale : : system ( ) . timeFormat ( QLocale : : ShortFormat ) ) ;
2014-11-26 16:45:52 +00:00
DEBUG_LOG ( ( " Application Info: starting app.. " ) ) ;
2015-04-19 10:29:19 +00:00
QMimeDatabase ( ) . mimeTypeForName ( qsl ( " text/plain " ) ) ; // create mime database
2014-05-30 08:53:19 +00:00
window - > createWinId ( ) ;
window - > init ( ) ;
2014-11-26 16:45:52 +00:00
DEBUG_LOG ( ( " Application Info: window created.. " ) ) ;
2014-05-30 08:53:19 +00:00
2015-03-19 09:18:19 +00:00
initImageLinkManager ( ) ;
App : : initMedia ( ) ;
Local : : ReadMapState state = Local : : readMap ( QByteArray ( ) ) ;
if ( state = = Local : : ReadMapPassNeeded ) {
cSetHasPasscode ( true ) ;
DEBUG_LOG ( ( " Application Info: passcode nneded.. " ) ) ;
} else {
DEBUG_LOG ( ( " Application Info: local map read.. " ) ) ;
2015-03-02 12:34:16 +00:00
MTP : : start ( ) ;
}
2015-03-19 09:18:19 +00:00
2014-05-30 08:53:19 +00:00
MTP : : setStateChangedHandler ( mtpStateChanged ) ;
2014-08-01 18:49:43 +00:00
MTP : : setSessionResetHandler ( mtpSessionReset ) ;
2014-05-30 08:53:19 +00:00
2014-11-26 16:45:52 +00:00
DEBUG_LOG ( ( " Application Info: MTP started.. " ) ) ;
DEBUG_LOG ( ( " Application Info: showing. " ) ) ;
2015-03-02 12:34:16 +00:00
if ( state = = Local : : ReadMapPassNeeded ) {
window - > setupPasscode ( false ) ;
2014-05-30 08:53:19 +00:00
} else {
2015-03-02 12:34:16 +00:00
if ( MTP : : authedId ( ) ) {
window - > setupMain ( false ) ;
} else {
window - > setupIntro ( false ) ;
}
2014-05-30 08:53:19 +00:00
}
2014-09-29 02:47:30 +00:00
window - > firstShow ( ) ;
2014-05-30 08:53:19 +00:00
if ( cStartToSettings ( ) ) {
window - > showSettings ( ) ;
}
QNetworkProxyFactory : : setUseSystemConfiguration ( true ) ;
2015-03-02 12:34:16 +00:00
if ( state ! = Local : : ReadMapPassNeeded ) {
checkMapVersion ( ) ;
2014-12-03 13:10:32 +00:00
}
2014-12-18 18:40:49 +00:00
2015-01-26 13:04:41 +00:00
window - > updateIsActive ( cOnlineFocusTimeout ( ) ) ;
2014-05-30 08:53:19 +00:00
}
void Application : : socketDisconnected ( ) {
if ( closing ) {
DEBUG_LOG ( ( " Application Error: socket disconnected before command response received, quiting.. " ) ) ;
return App : : quit ( ) ;
}
}
void Application : : newInstanceConnected ( ) {
DEBUG_LOG ( ( " Application Info: new local socket connected " ) ) ;
for ( QLocalSocket * client = server . nextPendingConnection ( ) ; client ; client = server . nextPendingConnection ( ) ) {
clients . push_back ( ClientSocket ( client , QByteArray ( ) ) ) ;
connect ( client , SIGNAL ( readyRead ( ) ) , this , SLOT ( readClients ( ) ) ) ;
connect ( client , SIGNAL ( disconnected ( ) ) , this , SLOT ( removeClients ( ) ) ) ;
}
}
void Application : : readClients ( ) {
2014-12-03 13:10:32 +00:00
QString startUrl ;
2014-07-18 10:37:34 +00:00
QStringList toSend ;
2014-05-30 08:53:19 +00:00
for ( ClientSockets : : iterator i = clients . begin ( ) , e = clients . end ( ) ; i ! = e ; + + i ) {
i - > second . append ( i - > first - > readAll ( ) ) ;
if ( i - > second . size ( ) ) {
2014-07-18 10:37:34 +00:00
QString cmds ( QString : : fromLocal8Bit ( i - > second ) ) ;
2014-05-30 08:53:19 +00:00
int32 from = 0 , l = cmds . length ( ) ;
for ( int32 to = cmds . indexOf ( QChar ( ' ; ' ) , from ) ; to > = from ; to = ( from < l ) ? cmds . indexOf ( QChar ( ' ; ' ) , from ) : - 1 ) {
QStringRef cmd ( & cmds , from , to - from ) ;
2014-08-22 09:53:53 +00:00
if ( cmd . startsWith ( qsl ( " CMD: " ) ) ) {
2014-05-30 08:53:19 +00:00
execExternal ( cmds . mid ( from + 4 , to - from - 4 ) ) ;
2014-08-22 09:53:53 +00:00
QByteArray response ( qsl ( " RES:%1; " ) . arg ( QCoreApplication : : applicationPid ( ) ) . toUtf8 ( ) ) ;
2014-05-30 08:53:19 +00:00
i - > first - > write ( response . data ( ) , response . size ( ) ) ;
2014-08-22 09:53:53 +00:00
} else if ( cmd . startsWith ( qsl ( " SEND: " ) ) ) {
2014-07-18 10:37:34 +00:00
if ( cSendPaths ( ) . isEmpty ( ) ) {
toSend . append ( _escapeFrom7bit ( cmds . mid ( from + 5 , to - from - 5 ) ) ) ;
}
2014-12-03 13:10:32 +00:00
} else if ( cmd . startsWith ( qsl ( " OPEN: " ) ) ) {
if ( cStartUrl ( ) . isEmpty ( ) ) {
startUrl = _escapeFrom7bit ( cmds . mid ( from + 5 , to - from - 5 ) ) ;
}
2014-05-30 08:53:19 +00:00
} else {
LOG ( ( " Application Error: unknown command %1 passed in local socket " ) . arg ( QString ( cmd . constData ( ) , cmd . length ( ) ) ) ) ;
}
from = to + 1 ;
}
if ( from > 0 ) {
i - > second = i - > second . mid ( from ) ;
}
}
}
2014-07-18 10:37:34 +00:00
if ( ! toSend . isEmpty ( ) ) {
QStringList paths ( cSendPaths ( ) ) ;
paths . append ( toSend ) ;
cSetSendPaths ( paths ) ;
}
if ( ! cSendPaths ( ) . isEmpty ( ) ) {
if ( App : : wnd ( ) ) {
App : : wnd ( ) - > sendPaths ( ) ;
}
}
2014-12-03 13:10:32 +00:00
if ( ! startUrl . isEmpty ( ) ) {
cSetStartUrl ( startUrl ) ;
}
if ( ! cStartUrl ( ) . isEmpty ( ) & & App : : main ( ) & & App : : self ( ) ) {
App : : main ( ) - > openLocalUrl ( cStartUrl ( ) ) ;
cSetStartUrl ( QString ( ) ) ;
}
2014-05-30 08:53:19 +00:00
}
void Application : : removeClients ( ) {
DEBUG_LOG ( ( " Application Info: remove clients slot called, clients %1 " ) . arg ( clients . size ( ) ) ) ;
for ( ClientSockets : : iterator i = clients . begin ( ) , e = clients . end ( ) ; i ! = e ; ) {
if ( i - > first - > state ( ) ! = QLocalSocket : : ConnectedState ) {
DEBUG_LOG ( ( " Application Info: removing client " ) ) ;
i = clients . erase ( i ) ;
e = clients . end ( ) ;
} else {
+ + i ;
}
}
}
void Application : : execExternal ( const QString & cmd ) {
DEBUG_LOG ( ( " Application Info: executing external command '%1' " ) . arg ( cmd ) ) ;
if ( cmd = = " show " ) {
window - > activate ( ) ;
}
}
void Application : : closeApplication ( ) {
// close server
server . close ( ) ;
for ( ClientSockets : : iterator i = clients . begin ( ) , e = clients . end ( ) ; i ! = e ; + + i ) {
disconnect ( i - > first , SIGNAL ( disconnected ( ) ) , this , SLOT ( removeClients ( ) ) ) ;
i - > first - > close ( ) ;
}
clients . clear ( ) ;
MTP : : stop ( ) ;
}
Application : : ~ Application ( ) {
App : : setQuiting ( ) ;
window - > setParent ( 0 ) ;
anim : : stopManager ( ) ;
socket . close ( ) ;
closeApplication ( ) ;
App : : deinitMedia ( ) ;
2014-11-12 20:18:00 +00:00
deinitImageLinkManager ( ) ;
2014-05-30 08:53:19 +00:00
mainApp = 0 ;
delete : : uploader ;
2015-08-19 22:00:37 +00:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
delete updateReply ;
2014-05-30 08:53:19 +00:00
updateReply = 0 ;
2014-11-27 18:58:51 +00:00
if ( updateDownloader ) updateDownloader - > deleteLater ( ) ;
2014-05-30 08:53:19 +00:00
updateDownloader = 0 ;
2014-11-27 18:58:51 +00:00
if ( updateThread ) updateThread - > quit ( ) ;
2014-05-30 08:53:19 +00:00
updateThread = 0 ;
2015-08-19 22:00:37 +00:00
# endif
2014-05-30 08:53:19 +00:00
delete window ;
2015-02-03 15:02:46 +00:00
delete cChatBackground ( ) ;
cSetChatBackground ( 0 ) ;
delete cChatDogImage ( ) ;
cSetChatDogImage ( 0 ) ;
2014-05-30 08:53:19 +00:00
style : : stopManager ( ) ;
2015-03-02 12:34:16 +00:00
2015-01-05 20:19:05 +00:00
delete _translator ;
2014-05-30 08:53:19 +00:00
}
Application * Application : : app ( ) {
return mainApp ;
}
Window * Application : : wnd ( ) {
return mainApp ? mainApp - > window : 0 ;
}
2014-12-18 18:40:49 +00:00
QString Application : : language ( ) {
2014-05-30 08:53:19 +00:00
if ( ! lng . length ( ) ) {
lng = psCurrentLanguage ( ) ;
}
if ( ! lng . length ( ) ) {
lng = " en " ;
}
return lng ;
}
2014-12-19 21:20:30 +00:00
int32 Application : : languageId ( ) {
QByteArray l = language ( ) . toLatin1 ( ) ;
2014-12-19 22:03:50 +00:00
for ( int32 i = 0 ; i < languageCount ; + + i ) {
2015-01-02 15:20:23 +00:00
if ( l . at ( 0 ) = = LanguageCodes [ i ] [ 0 ] & & l . at ( 1 ) = = LanguageCodes [ i ] [ 1 ] ) {
2014-12-19 21:20:30 +00:00
return i ;
}
}
2014-12-20 21:33:08 +00:00
return languageDefault ;
2014-12-19 21:20:30 +00:00
}
2014-05-30 08:53:19 +00:00
MainWidget * Application : : main ( ) {
return mainApp ? mainApp - > window - > mainWidget ( ) : 0 ;
}