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 .
2015-10-03 13:16:42 +00:00
In addition , as a special exception , the copyright holders give permission
to link the code of portions of this program with the OpenSSL library .
2014-05-30 08:53:19 +00:00
Full license : https : //github.com/telegramdesktop/tdesktop/blob/master/LICENSE
2015-10-03 13:16:42 +00:00
Copyright ( c ) 2014 - 2015 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-12-03 18:16:34 +00:00
if ( cPlatform ( ) = = dbipMac | | cPlatform ( ) = = dbipMacOld ) {
2015-10-12 21:31:05 +00:00
if ( ev - > key ( ) = = Qt : : Key_W & & ( ev - > modifiers ( ) & Qt : : ControlModifier ) ) {
2015-07-13 17:55:59 +00:00
if ( cWorkMode ( ) = = dbiwmTrayOnly | | cWorkMode ( ) = = dbiwmWindowAndTray ) {
App : : wnd ( ) - > minimizeToTray ( ) ;
return true ;
} else {
App : : wnd ( ) - > hide ( ) ;
App : : wnd ( ) - > updateIsActive ( cOfflineBlurTimeout ( ) ) ;
App : : wnd ( ) - > updateGlobalMenu ( ) ;
return true ;
}
2015-10-12 21:31:05 +00:00
} else if ( ev - > key ( ) = = Qt : : Key_M & & ( ev - > modifiers ( ) & Qt : : ControlModifier ) ) {
2015-07-13 17:55:59 +00:00
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-10-15 11:51:10 +00:00
connect ( & _mtpUnpauseTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( doMtpUnpause ( ) ) ) ;
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 ( ) ;
2015-12-03 18:16:34 +00:00
QString url = m . captured ( 2 ) ;
bool betaVersion = false ;
if ( url . startsWith ( qstr ( " beta_ " ) ) ) {
betaVersion = true ;
url = url . mid ( 5 ) + ' _ ' + countBetaVersionSignature ( currentVersion ) ;
}
if ( ( ! betaVersion | | cBetaVersion ( ) ) & & currentVersion > ( betaVersion ? cBetaVersion ( ) : AppVersion ) ) {
2014-05-30 08:53:19 +00:00
updateThread = new QThread ( ) ;
2014-11-27 18:58:51 +00:00
connect ( updateThread , SIGNAL ( finished ( ) ) , updateThread , SLOT ( deleteLater ( ) ) ) ;
2015-12-03 18:16:34 +00:00
updateDownloader = new UpdateDownloader ( updateThread , url ) ;
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-12-03 18:16:34 +00:00
if ( QRegularExpression ( " ^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd) \\ d+(_[a-z \\ 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 ;
}
}
}
2015-10-15 11:51:10 +00:00
void Application : : mtpPause ( ) {
MTP : : pause ( ) ;
2015-10-17 14:52:26 +00:00
_mtpUnpauseTimer . start ( st : : slideDuration * 2 ) ;
2015-10-15 11:51:10 +00:00
}
2015-10-15 10:18:24 +00:00
void Application : : mtpUnpause ( ) {
2015-10-15 11:51:10 +00:00
_mtpUnpauseTimer . start ( 1 ) ;
2015-10-15 10:18:24 +00:00
}
void Application : : doMtpUnpause ( ) {
MTP : : unpause ( ) ;
}
2014-05-30 08:53:19 +00:00
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 ) {
2015-10-06 19:49:23 +00:00
if ( mtpIsFlood ( error ) ) return false ;
2015-04-04 20:01:34 +00:00
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 ) ) {
2015-09-16 21:15:13 +00:00
MTP : : send ( MTPmessages_EditChatPhoto ( peerToBareMTPInt ( id ) , MTP_inputChatPhotoEmpty ( ) ) , rpcDone ( & Application : : chatPhotoCleared , id ) , rpcFail ( & Application : : peerPhotoFail , id ) ) ;
2015-09-03 10:48:40 +00:00
} else if ( peerIsChannel ( id ) ) {
if ( ChannelData * channel = App : : channelLoaded ( id ) ) {
2015-09-16 21:15:13 +00:00
MTP : : send ( MTPchannels_EditPhoto ( channel - > inputChannel , MTP_inputChatPhotoEmpty ( ) ) , rpcDone ( & Application : : chatPhotoCleared , id ) , rpcFail ( & Application : : peerPhotoFail , id ) ) ;
2015-09-03 10:48:40 +00:00
}
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 ) ) ;
2015-09-16 21:15:13 +00:00
} else if ( peerIsChat ( id ) ) {
2015-09-03 10:48:40 +00:00
History * hist = App : : history ( id ) ;
2015-09-16 21:15:13 +00:00
hist - > sendRequestId = MTP : : send ( MTPmessages_EditChatPhoto ( hist - > peer - > asChat ( ) - > 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 ) ;
} else if ( peerIsChannel ( id ) ) {
History * hist = App : : history ( id ) ;
hist - > sendRequestId = MTP : : send ( MTPchannels_EditPhoto ( hist - > peer - > asChannel ( ) - > inputChannel , 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-10-27 02:39:02 +00:00
ReadyLocalMedia ready ( PreparePhoto , file , filename , filesize , data , id , id , qsl ( " jpg " ) , peerId , photo , MTP_audioEmpty ( MTP_long ( 0 ) ) , photoThumbs , MTP_documentEmpty ( MTP_long ( 0 ) ) , jpeg , false , 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-12-03 18:16:34 +00:00
if ( QRegularExpression ( " ^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd) \\ d+(_[a-z \\ 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-12-03 18:16:34 +00:00
if ( cBetaVersion ( ) ) {
url . setQuery ( qsl ( " version=%1&beta=%2 " ) . arg ( AppVersion ) . arg ( cBetaVersion ( ) ) ) ;
} else if ( cDevVersion ( ) ) {
2015-07-28 13:47:21 +00:00
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-12-03 18:16:34 +00:00
if ( cDevVersion ( ) & & Local : : oldMapVersion ( ) < 9014 ) {
versionFeatures = QString : : fromUtf8 ( " \xe2 \x80 \x94 Sticker management: manually rearrange your sticker packs, pack order is now synced across all your devices \n \xe2 \x80 \x94 New context menu for chats in chats list \n \xe2 \x80 \x94 Support for all existing emoji " ) ; // .replace('@', qsl("@") + QChar(0x200D));
2015-11-24 18:11:17 +00:00
} else if ( Local : : oldMapVersion ( ) < 9013 ) {
2015-12-03 18:27:45 +00:00
versionFeatures = lang ( lng_new_version_text ) . trimmed ( ) ;
2015-09-10 13:20:22 +00:00
} else {
versionFeatures = lang ( lng_new_version_minor ) . 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 ) ;
}
}
}
2015-11-26 17:34:52 +00:00
if ( cNeedConfigResave ( ) ) {
Local : : writeUserSettings ( ) ;
}
2015-03-02 12:34:16 +00:00
}
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 ;
}