2007-11-14 22:18:48 -05:00
/****************************************************************
* RetroShare QT Gui is distributed under the following license :
*
* Copyright ( C ) 2006 , crypton
*
* This program 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 2
* of the License , or ( at your option ) any later version .
*
* This program 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 .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor ,
* Boston , MA 02110 - 1301 , USA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <QObject>
2010-07-23 14:52:58 -04:00
# include <QMessageBox>
2010-10-19 14:06:22 -04:00
# include <QSplashScreen>
2007-11-14 22:18:48 -05:00
# include <rshare.h>
2010-06-08 17:38:36 -04:00
# include "gui/MainWindow.h"
2011-05-17 13:27:47 -04:00
# include "gui/FriendsDialog.h"
2010-06-08 17:38:36 -04:00
# include "gui/SearchDialog.h"
# include "gui/TransfersDialog.h"
# include "gui/MessagesDialog.h"
# include "gui/SharedFilesDialog.h"
2010-08-31 16:00:49 -04:00
# include "gui/NetworkDialog.h"
2012-01-17 15:36:36 -05:00
# include "gui/chat/ChatDialog.h"
2011-02-22 09:51:03 -05:00
# include "gui/QuickStartWizard.h"
2010-06-08 17:38:36 -04:00
# include "gui/MessengerWindow.h"
# include "gui/StartDialog.h"
# include "gui/GenCertDialog.h"
# include "gui/settings/rsharesettings.h"
2010-09-10 14:38:46 -04:00
# include "gui/settings/RsharePeerSettings.h"
2010-06-08 17:38:36 -04:00
# include "gui/connect/ConfCertDialog.h"
2010-07-17 19:19:43 -04:00
# include "idle/idle.h"
2010-09-14 13:47:11 -04:00
# include "gui/common/Emoticons.h"
2011-04-14 17:59:51 -04:00
# include "util/EventReceiver.h"
2011-04-14 19:58:30 -04:00
# include "gui/RetroShareLink.h"
2012-01-22 17:58:23 -05:00
# include "gui/SoundManager.h"
2007-11-14 22:18:48 -05:00
/*** WINDOWS DON'T LIKE THIS - REDEFINES VER numbers.
# include <gui/qskinobject/qskinobject.h>
* * * */
2008-08-15 15:03:50 -04:00
# include <util/stringutil.h>
2010-08-06 05:40:23 -04:00
# include <retroshare/rsinit.h>
# include <retroshare/rsiface.h>
2009-12-30 20:34:23 -05:00
# include "gui/notifyqt.h"
2012-04-12 19:29:39 -04:00
# include <unistd.h>
2007-11-14 22:18:48 -05:00
int main ( int argc , char * argv [ ] )
{
2010-11-04 18:54:18 -04:00
# ifdef WINDOWS_SYS
{
/* Set the current directory to the application dir,
because the start dir with autostart from the registry run key is not the exe dir */
QApplication app ( argc , argv ) ;
QDir : : setCurrent ( QCoreApplication : : applicationDirPath ( ) ) ;
}
# endif
2007-11-14 22:18:48 -05:00
2012-01-22 17:58:23 -05:00
QStringList args = char_array_to_stringlist ( argv + 1 , argc - 1 ) ;
Q_INIT_RESOURCE ( images ) ;
2007-11-14 22:18:48 -05:00
rsiface = NULL ;
2010-07-18 07:43:39 -04:00
NotifyQt * notify = NotifyQt : : Create ( ) ;
2009-11-05 14:38:10 -05:00
createRsIface ( * notify ) ;
createRsControl ( * rsiface , * notify ) ;
2012-01-22 17:58:23 -05:00
/* RetroShare Core Objects */
2009-02-08 09:30:28 -05:00
RsInit : : InitRsConfig ( ) ;
2010-11-03 18:54:34 -04:00
int initResult = RsInit : : InitRetroShare ( argc , argv ) ;
2012-06-09 17:01:22 -04:00
if ( initResult = = RS_INIT_NO_KEYRING ) // happens when we already have accounts, but no pgp key. This is when switching to the openpgp-sdk version.
{
QApplication dummyApp ( argc , argv ) ; // needed for QMessageBox
QMessageBox msgBox ;
2012-06-19 18:31:37 -04:00
msgBox . setText ( QObject : : tr ( " This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although GPG keys are mentionned by existing RetroShare accounts, probably because you just changed to this new version of the software. " ) ) ;
2012-07-13 08:20:44 -04:00
msgBox . setInformativeText ( QObject : : tr ( " Choose between:<br><ul><li><b>Ok</b> to copy the existing keyring from gnupg (safest bet), or </li><li><b>Close without saving</b> to start fresh with an empty keyring (you will be asked to create a new PGP key to work with RetroShare, or import a previously saved pgp keypair). </li><li><b>Cancel</b> to quit and forge a keyring by yourself (needs some PGP skills)</li></ul> " ) ) ;
2012-06-09 17:01:22 -04:00
msgBox . setStandardButtons ( QMessageBox : : Ok | QMessageBox : : Discard | QMessageBox : : Cancel ) ;
msgBox . setDefaultButton ( QMessageBox : : Ok ) ;
2012-06-19 18:31:37 -04:00
msgBox . setWindowIcon ( QIcon ( " :/images/rstray3.png " ) ) ;
2012-06-09 17:01:22 -04:00
int ret = msgBox . exec ( ) ;
if ( ret = = QMessageBox : : Cancel )
return 0 ;
if ( ret = = QMessageBox : : Ok )
{
if ( ! RsInit : : copyGnuPGKeyrings ( ) )
return 0 ;
initResult = RsInit : : InitRetroShare ( argc , argv ) ;
}
else
initResult = RS_INIT_OK ;
}
2010-11-03 18:54:34 -04:00
if ( initResult < 0 ) {
/* Error occured */
QApplication dummyApp ( argc , argv ) ; // needed for QMessageBox
QMessageBox mb ( QMessageBox : : Critical , QObject : : tr ( " RetroShare " ) , " " , QMessageBox : : Ok ) ;
mb . setWindowIcon ( QIcon ( " :/images/rstray3.png " ) ) ;
2012-06-09 17:01:22 -04:00
switch ( initResult )
{
case RS_INIT_AUTH_FAILED :
std : : cerr < < " RsInit::InitRetroShare AuthGPG::InitAuth failed " < < std : : endl ;
mb . setText ( QObject : : tr ( " Inititialize failed. Wrong or missing installation of gpg. " ) ) ;
break ;
default :
/* Unexpected return code */
std : : cerr < < " RsInit::InitRetroShare unexpected return code " < < initResult < < std : : endl ;
mb . setText ( QObject : : tr ( " An unexpected error occured. Please report 'RsInit::InitRetroShare unexpected return code %1'. " ) . arg ( initResult ) ) ;
break ;
2010-11-03 18:54:34 -04:00
}
mb . exec ( ) ;
return 1 ;
}
2010-05-20 17:53:27 -04:00
2010-06-14 09:32:13 -04:00
/* create global settings object
path maybe wrong , when no profile exist
in this case it can be use only for default values */
2010-05-20 17:53:27 -04:00
RshareSettings : : Create ( ) ;
2007-11-14 22:18:48 -05:00
/* Setup The GUI Stuff */
Rshare rshare ( args , argc , argv ,
2011-10-12 19:36:25 -04:00
QString : : fromUtf8 ( RsInit : : RsConfigDirectory ( ) . c_str ( ) ) ) ;
2007-11-14 22:18:48 -05:00
2011-04-14 19:58:30 -04:00
std : : string url = RsInit : : getRetroShareLink ( ) ;
if ( ! url . empty ( ) ) {
2011-04-14 17:59:51 -04:00
/* start with RetroShare link */
EventReceiver eventReceiver ;
2011-04-14 19:58:30 -04:00
if ( eventReceiver . sendRetroShareLink ( QString : : fromStdString ( url ) ) ) {
return 0 ;
}
/* Start RetroShare */
2011-04-14 17:59:51 -04:00
}
2010-10-19 14:06:22 -04:00
QSplashScreen splashScreen ( QPixmap ( " :/images/splash.png " ) /* , Qt::WindowStaysOnTopHint*/ ) ;
2010-11-03 18:54:34 -04:00
switch ( initResult ) {
case RS_INIT_OK :
2007-11-14 22:18:48 -05:00
{
2010-11-03 18:54:34 -04:00
/* Login Dialog */
/* check for existing Certificate */
StartDialog * sd = NULL ;
bool genCert = false ;
std : : list < std : : string > accountIds ;
if ( RsInit : : getAccountIds ( accountIds ) & & ( accountIds . size ( ) > 0 ) )
2009-02-08 09:30:28 -05:00
{
2010-11-03 18:54:34 -04:00
sd = new StartDialog ( ) ;
sd - > show ( ) ;
while ( sd - > isVisible ( ) )
{
rshare . processEvents ( ) ;
2007-11-14 22:18:48 -05:00
# ifdef WIN32
2010-11-03 18:54:34 -04:00
Sleep ( 10 ) ;
2007-11-14 22:18:48 -05:00
# else // __LINUX__
2010-11-03 18:54:34 -04:00
usleep ( 10000 ) ;
2007-11-14 22:18:48 -05:00
# endif
2010-11-03 18:54:34 -04:00
}
/* if we're logged in */
genCert = sd - > requestedNewCert ( ) ;
delete ( sd ) ;
}
else
{
genCert = true ;
2009-02-08 09:30:28 -05:00
}
2007-11-14 22:18:48 -05:00
2010-11-03 18:54:34 -04:00
if ( genCert )
{
GenCertDialog gd ;
gd . exec ( ) ;
}
2007-11-14 22:18:48 -05:00
2010-11-03 18:54:34 -04:00
splashScreen . show ( ) ;
2007-11-14 22:18:48 -05:00
}
2010-11-03 18:54:34 -04:00
break ;
case RS_INIT_HAVE_ACCOUNT :
{
splashScreen . show ( ) ;
splashScreen . showMessage ( rshare . translate ( " SplashScreen " , " Load profile " ) , Qt : : AlignHCenter | Qt : : AlignBottom ) ;
2010-10-19 14:06:22 -04:00
2010-11-03 18:54:34 -04:00
std : : string preferredId , gpgId , gpgName , gpgEmail , sslName ;
RsInit : : getPreferedAccountId ( preferredId ) ;
2010-04-08 11:51:10 -04:00
2010-11-03 18:54:34 -04:00
if ( RsInit : : getAccountDetails ( preferredId , gpgId , gpgName , gpgEmail , sslName ) )
{
RsInit : : SelectGPGAccount ( gpgId ) ;
}
2010-04-08 11:51:10 -04:00
2010-11-03 18:54:34 -04:00
// true: note auto-login is active
2012-01-22 17:58:23 -05:00
std : : string lockFile ;
int retVal = RsInit : : LockAndLoadCertificates ( true , lockFile ) ;
2010-07-01 16:30:36 -04:00
switch ( retVal )
{
case 0 : break ;
case 1 : QMessageBox : : warning ( 0 ,
QObject : : tr ( " Multiple instances " ) ,
QObject : : tr ( " Another RetroShare using the same profile is "
2012-01-22 17:58:23 -05:00
" already running on your system. Please close "
" that instance first \n Lock file: \n " ) +
QString : : fromStdString ( lockFile ) ) ;
2010-07-01 16:30:36 -04:00
return 1 ;
case 2 : QMessageBox : : critical ( 0 ,
QObject : : tr ( " Multiple instances " ) ,
QObject : : tr ( " An unexpected error occurred when Retroshare "
2012-01-22 17:58:23 -05:00
" tried to acquire the single instance lock \n Lock file: \n " ) +
QString : : fromStdString ( lockFile ) ) ;
2010-07-01 16:30:36 -04:00
return 1 ;
case 3 : QMessageBox : : critical ( 0 ,
QObject : : tr ( " Login Failure " ) ,
QObject : : tr ( " Maybe password is wrong " ) ) ;
return 1 ;
default : std : : cerr < < " StartDialog::loadCertificates() unexpected switch value " < < retVal < < std : : endl ;
}
2010-11-03 18:54:34 -04:00
}
break ;
default :
/* Unexpected return code */
std : : cerr < < " RsInit::InitRetroShare unexpected return code " < < initResult < < std : : endl ;
QMessageBox : : warning ( 0 , QObject : : tr ( " RetroShare " ) , QObject : : tr ( " An unexpected error occured. Please report 'RsInit::InitRetroShare unexpected return code %1'. " ) . arg ( initResult ) ) ;
return 1 ;
2007-11-14 22:18:48 -05:00
}
2012-01-22 17:58:23 -05:00
/* recreate global settings object, now with correct path */
2011-10-14 17:16:34 -04:00
RshareSettings : : Create ( true ) ;
Rshare : : resetLanguageAndStyle ( ) ;
2012-01-22 17:58:23 -05:00
SoundManager : : create ( ) ;
2010-10-19 14:06:22 -04:00
splashScreen . showMessage ( rshare . translate ( " SplashScreen " , " Load configuration " ) , Qt : : AlignHCenter | Qt : : AlignBottom ) ;
2012-02-02 19:15:49 -05:00
/* stop Retroshare if startup fails */
if ( ! rsicontrol - > StartupRetroShare ( ) )
{
std : : cerr < < " libretroshare failed to startup! " < < std : : endl ;
return 1 ;
}
2011-11-17 16:17:24 -05:00
Rshare : : initPlugins ( ) ;
2007-11-14 22:18:48 -05:00
2010-10-19 14:06:22 -04:00
splashScreen . showMessage ( rshare . translate ( " SplashScreen " , " Create interface " ) , Qt : : AlignHCenter | Qt : : AlignBottom ) ;
2010-09-10 14:38:46 -04:00
RsharePeerSettings : : Create ( ) ;
2010-06-14 09:32:13 -04:00
2010-09-14 13:47:11 -04:00
Emoticons : : load ( ) ;
2010-10-19 14:06:22 -04:00
if ( Settings - > value ( QString : : fromUtf8 ( " FirstRun " ) , true ) . toBool ( ) ) {
splashScreen . hide ( ) ;
Settings - > setValue ( QString : : fromUtf8 ( " FirstRun " ) , false ) ;
2012-02-02 19:15:49 -05:00
# ifdef __APPLE__
/* For OSX, we set the default to "cleanlooks", as the AQUA style hides some input boxes
* only on the first run - as the user might want to change it ; )
*/
QString osx_style ( " cleanlooks " ) ;
Rshare : : setStyle ( osx_style ) ;
Settings - > setInterfaceStyle ( osx_style ) ;
# endif
2012-01-27 08:52:13 -05:00
// This is now disabled - as it doesn't add very much.
// Need to make sure that defaults are sensible!
# ifdef ENABLE_QUICKSTART_WIZARD
2010-10-19 14:06:22 -04:00
QuickStartWizard qstartWizard ;
qstartWizard . exec ( ) ;
2012-01-27 08:52:13 -05:00
# endif
2012-02-02 19:15:49 -05:00
2010-10-19 14:06:22 -04:00
}
2010-05-02 20:09:55 -04:00
MainWindow * w = MainWindow : : Create ( ) ;
2010-10-19 14:06:22 -04:00
splashScreen . finish ( w ) ;
2009-01-22 16:06:54 -05:00
2011-04-14 17:59:51 -04:00
EventReceiver * eventReceiver = NULL ;
if ( Settings - > getRetroShareProtocol ( ) ) {
/* Create event receiver */
eventReceiver = new EventReceiver ;
if ( eventReceiver - > start ( ) ) {
QObject : : connect ( eventReceiver , SIGNAL ( linkReceived ( const QUrl & ) ) , w , SLOT ( linkActivated ( const QUrl & ) ) ) ;
}
}
2011-04-14 19:58:30 -04:00
if ( ! url . empty ( ) ) {
/* Now use link from the command line, because no RetroShare was running */
RetroShareLink link ( QString : : fromStdString ( url ) ) ;
if ( link . valid ( ) ) {
w - > linkActivated ( link . toUrl ( ) ) ;
}
}
2009-01-22 16:06:54 -05:00
// I'm using a signal to transfer the hashing info to the mainwindow, because Qt schedules signals properly to
// avoid clashes between infos from threads.
//
2009-08-16 16:10:53 -04:00
qRegisterMetaType < FileDetail > ( " FileDetail " ) ;
2009-03-15 18:45:40 -04:00
std : : cerr < < " connecting signals and slots " < < std : : endl ;
2009-08-16 16:10:53 -04:00
QObject : : connect ( notify , SIGNAL ( gotTurtleSearchResult ( qulonglong , FileDetail ) ) , w - > searchDialog , SLOT ( updateFiles ( qulonglong , FileDetail ) ) ) ;
2010-05-21 16:49:48 -04:00
QObject : : connect ( notify , SIGNAL ( diskFull ( int , int ) ) , w , SLOT ( displayDiskSpaceWarning ( int , int ) ) ) ;
2009-08-16 16:10:53 -04:00
QObject : : connect ( notify , SIGNAL ( filesPreModChanged ( bool ) ) , w - > sharedfilesDialog , SLOT ( preModDirectories ( bool ) ) ) ;
QObject : : connect ( notify , SIGNAL ( filesPostModChanged ( bool ) ) , w - > sharedfilesDialog , SLOT ( postModDirectories ( bool ) ) ) ;
2010-04-24 18:09:47 -04:00
QObject : : connect ( notify , SIGNAL ( filesPostModChanged ( bool ) ) , w , SLOT ( postModDirectories ( bool ) ) ) ;
2009-08-16 16:10:53 -04:00
QObject : : connect ( notify , SIGNAL ( transfersChanged ( ) ) , w - > transfersDialog , SLOT ( insertTransfers ( ) ) ) ;
2011-05-17 13:27:47 -04:00
QObject : : connect ( notify , SIGNAL ( publicChatChanged ( int ) ) , w - > friendsDialog , SLOT ( publicChatChanged ( int ) ) ) ;
2010-09-20 20:08:06 -04:00
QObject : : connect ( notify , SIGNAL ( privateChatChanged ( int , int ) ) , w , SLOT ( privateChatChanged ( int , int ) ) ) ;
2011-08-21 18:28:19 -04:00
QObject : : connect ( notify , SIGNAL ( neighboursChanged ( ) ) , w - > networkDialog , SLOT ( insertConnect ( ) ) ) ;
2009-08-16 16:10:53 -04:00
QObject : : connect ( notify , SIGNAL ( messagesChanged ( ) ) , w - > messagesDialog , SLOT ( insertMessages ( ) ) ) ;
2010-08-22 18:12:26 -04:00
QObject : : connect ( notify , SIGNAL ( messagesTagsChanged ( ) ) , w - > messagesDialog , SLOT ( messagesTagsChanged ( ) ) ) ;
2010-08-09 08:16:21 -04:00
QObject : : connect ( notify , SIGNAL ( messagesChanged ( ) ) , w , SLOT ( updateMessages ( ) ) ) ;
2010-08-09 17:20:34 -04:00
QObject : : connect ( notify , SIGNAL ( forumsChanged ( ) ) , w , SLOT ( updateForums ( ) ) , Qt : : QueuedConnection ) ;
2010-10-06 20:17:42 -04:00
QObject : : connect ( notify , SIGNAL ( channelsChanged ( int ) ) , w , SLOT ( updateChannels ( int ) ) , Qt : : QueuedConnection ) ;
2010-11-24 19:20:25 -05:00
QObject : : connect ( notify , SIGNAL ( downloadCompleteCountChanged ( int ) ) , w , SLOT ( updateTransfers ( int ) ) ) ;
2007-11-14 22:18:48 -05:00
2011-05-17 13:27:47 -04:00
QObject : : connect ( notify , SIGNAL ( chatStatusChanged ( const QString & , const QString & , bool ) ) , w - > friendsDialog , SLOT ( updatePeerStatusString ( const QString & , const QString & , bool ) ) ) ;
QObject : : connect ( notify , SIGNAL ( ownStatusMessageChanged ( ) ) , w - > friendsDialog , SLOT ( loadmypersonalstatus ( ) ) ) ;
2009-10-05 15:07:02 -04:00
2010-11-05 18:46:40 -04:00
QObject : : connect ( notify , SIGNAL ( logInfoChanged ( const QString & ) ) , w - > networkDialog , SLOT ( setLogInfo ( QString ) ) ) ;
QObject : : connect ( notify , SIGNAL ( discInfoChanged ( ) ) , w - > networkDialog , SLOT ( updateNewDiscoveryInfo ( ) ) , Qt : : QueuedConnection ) ;
2010-02-07 13:10:12 -05:00
QObject : : connect ( notify , SIGNAL ( errorOccurred ( int , int , const QString & ) ) , w , SLOT ( displayErrorMessage ( int , int , const QString & ) ) ) ;
2009-05-05 09:18:53 -04:00
2010-06-15 12:51:48 -04:00
w - > installGroupChatNotifier ( ) ;
2009-07-13 10:01:49 -04:00
2010-06-15 12:51:48 -04:00
/* only show window, if not startMinimized */
2011-04-14 17:59:51 -04:00
if ( RsInit : : getStartMinimised ( ) | | Settings - > getStartMinimized ( ) )
2007-11-14 22:18:48 -05:00
{
2010-10-19 14:06:22 -04:00
splashScreen . close ( ) ;
2010-11-21 17:18:56 -05:00
} else {
w - > show ( ) ;
2008-10-18 12:02:06 -04:00
}
2009-02-08 09:30:28 -05:00
2007-11-14 22:18:48 -05:00
/* Startup a Timer to keep the gui's updated */
QTimer * timer = new QTimer ( w ) ;
timer - > connect ( timer , SIGNAL ( timeout ( ) ) , notify , SLOT ( UpdateGUI ( ) ) ) ;
2009-02-08 09:30:28 -05:00
timer - > start ( 1000 ) ;
2010-08-31 16:00:49 -04:00
2012-05-15 16:35:05 -04:00
notify - > enable ( ) ; // enable notification system after GUI creation, to avoid data races in Qt.
2009-02-08 09:30:28 -05:00
/* dive into the endless loop */
2010-05-20 17:53:27 -04:00
int ti = rshare . exec ( ) ;
delete w ;
2007-11-14 22:18:48 -05:00
2011-04-14 17:59:51 -04:00
if ( eventReceiver ) {
/* Destroy event receiver */
delete eventReceiver ;
eventReceiver = NULL ;
}
2010-06-17 13:39:32 -04:00
/* cleanup */
2012-01-17 15:36:36 -05:00
ChatDialog : : cleanupChat ( ) ;
2010-06-17 13:39:32 -04:00
2010-05-29 11:14:25 -04:00
rsicontrol - > rsGlobalShutDown ( ) ;
2012-01-22 17:58:23 -05:00
delete ( soundManager ) ;
soundManager = NULL ;
2010-05-20 17:53:27 -04:00
Settings - > sync ( ) ;
2012-01-22 17:58:23 -05:00
delete ( Settings ) ;
2007-11-14 22:18:48 -05:00
2010-05-20 17:53:27 -04:00
return ti ;
}