2017-04-06 02:06:42 +03:00
/*
* nheko Copyright ( C ) 2017 Konstantinos Sideris < siderisk @ auth . gr >
*
* 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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
2019-12-23 07:22:03 +03:00
# include <iostream>
2017-04-06 02:06:42 +03:00
# include <QApplication>
2018-07-15 14:53:18 +03:00
# include <QCommandLineParser>
2017-04-15 17:23:35 +03:00
# include <QDesktopWidget>
2018-06-12 20:36:16 +03:00
# include <QDir>
2017-11-16 17:33:52 +03:00
# include <QFile>
2017-04-06 02:06:42 +03:00
# include <QFontDatabase>
2019-07-05 04:20:19 +03:00
# include <QGuiApplication>
2017-12-14 22:55:00 +03:00
# include <QLabel>
2017-05-29 19:09:12 +03:00
# include <QLibraryInfo>
2018-07-22 20:26:50 +03:00
# include <QMessageBox>
2017-12-14 22:55:00 +03:00
# include <QPoint>
2019-07-05 04:20:19 +03:00
# include <QScreen>
2017-10-28 15:46:39 +03:00
# include <QSettings>
2018-06-09 16:03:14 +03:00
# include <QStandardPaths>
2017-05-29 19:09:12 +03:00
# include <QTranslator>
2017-04-06 02:06:42 +03:00
2017-12-14 22:55:00 +03:00
# include "Config.h"
2018-07-17 16:37:25 +03:00
# include "Logging.h"
2017-04-06 02:06:42 +03:00
# include "MainWindow.h"
2018-06-09 16:03:14 +03:00
# include "MatrixClient.h"
2018-07-22 19:48:58 +03:00
# include "Utils.h"
2018-09-30 14:33:54 +03:00
# include "config/nheko.h"
2020-02-23 15:40:04 +03:00
# include "singleapplication.h"
2017-12-14 22:55:00 +03:00
2018-09-19 23:38:36 +03:00
# if defined(Q_OS_MAC)
# include "emoji/MacHelper.h"
# endif
2019-12-15 01:48:02 +03:00
# ifdef QML_DEBUGGING
# include <QQmlDebuggingEnabler>
QQmlDebuggingEnabler enabler ;
# endif
2019-12-23 07:22:03 +03:00
# if defined(Q_OS_LINUX)
# include <boost/stacktrace.hpp>
# include <csignal>
2018-07-01 19:40:53 +03:00
void
stacktraceHandler ( int signum )
{
std : : signal ( signum , SIG_DFL ) ;
2018-07-01 22:57:14 +03:00
boost : : stacktrace : : safe_dump_to ( " ./nheko-backtrace.dump " ) ;
2018-07-01 19:40:53 +03:00
std : : raise ( SIGABRT ) ;
}
void
registerSignalHandlers ( )
{
std : : signal ( SIGSEGV , & stacktraceHandler ) ;
std : : signal ( SIGABRT , & stacktraceHandler ) ;
}
# else
// No implementation for systems with no stacktrace support.
void
registerSignalHandlers ( )
{ }
# endif
2017-12-14 22:55:00 +03:00
QPoint
screenCenter ( int width , int height )
{
2019-07-05 04:20:19 +03:00
// Deprecated in 5.13: QRect screenGeometry = QApplication::desktop()->screenGeometry();
QRect screenGeometry = QGuiApplication : : primaryScreen ( ) - > geometry ( ) ;
2017-12-14 22:55:00 +03:00
int x = ( screenGeometry . width ( ) - width ) / 2 ;
int y = ( screenGeometry . height ( ) - height ) / 2 ;
return QPoint ( x , y ) ;
}
2017-04-06 02:06:42 +03:00
2018-06-12 20:36:16 +03:00
void
createCacheDirectory ( )
{
auto dir = QStandardPaths : : writableLocation ( QStandardPaths : : CacheLocation ) ;
if ( ! QDir ( ) . mkpath ( dir ) ) {
throw std : : runtime_error (
( " Unable to create state directory: " + dir ) . toStdString ( ) . c_str ( ) ) ;
}
}
2017-08-20 13:47:22 +03:00
int
main ( int argc , char * argv [ ] )
2017-04-06 02:06:42 +03:00
{
2020-10-22 02:20:02 +03:00
// needed for settings so need to register before any settings are read to prevent warnings
2020-06-11 19:37:09 +03:00
qRegisterMetaType < UserSettings : : Presence > ( ) ;
2020-10-22 02:20:02 +03:00
// This is some hacky programming, but it's necessary (AFAIK?) to get the unique config name parsed
// before the app name is set.
QString appName { " nheko " } ;
for ( int i = 0 ; i < argc ; + + i )
{
if ( QString { argv [ i ] } . startsWith ( " --profile= " ) )
{
QString q { argv [ i ] } ;
q . remove ( " --profile= " ) ;
appName + = " - " + q ;
}
else if ( QString { argv [ i ] } . startsWith ( " --p= " ) )
{
QString q { argv [ i ] } ;
q . remove ( " -p= " ) ;
appName + = " - " + q ;
}
else if ( QString { argv [ i ] } = = " --profile " | | QString { argv [ i ] } = = " -p " )
{
if ( i < argc - 1 ) // if i is less than argc - 1, we still have a parameter left to process as the name
{
+ + i ; // the next arg is the name, so increment
appName + = " - " + QString { argv [ i ] } ;
}
}
}
QCoreApplication : : setApplicationName ( appName ) ;
2020-06-12 00:08:15 +03:00
QCoreApplication : : setApplicationVersion ( nheko : : version ) ;
QCoreApplication : : setOrganizationName ( " nheko " ) ;
QCoreApplication : : setAttribute ( Qt : : AA_DontCreateNativeWidgetSiblings ) ;
QCoreApplication : : setAttribute ( Qt : : AA_UseHighDpiPixmaps ) ;
QCoreApplication : : setAttribute ( Qt : : AA_EnableHighDpiScaling ) ;
// this needs to be after setting the application name. Or how would we find our settings
// file then?
2018-08-12 09:33:36 +03:00
# if defined(Q_OS_LINUX) || defined(Q_OS_WIN) || defined(Q_OS_FREEBSD)
2018-07-22 19:48:58 +03:00
if ( qgetenv ( " QT_SCALE_FACTOR " ) . size ( ) = = 0 ) {
float factor = utils : : scaleFactor ( ) ;
if ( factor ! = - 1 )
qputenv ( " QT_SCALE_FACTOR " , QString : : number ( factor ) . toUtf8 ( ) ) ;
}
# endif
2020-02-23 15:40:04 +03:00
SingleApplication app ( argc ,
argv ,
false ,
SingleApplication : : Mode : : User |
SingleApplication : : Mode : : ExcludeAppPath |
SingleApplication : : Mode : : ExcludeAppVersion ) ;
2017-04-06 02:06:42 +03:00
2018-07-15 14:53:18 +03:00
QCommandLineParser parser ;
parser . addHelpOption ( ) ;
parser . addVersionOption ( ) ;
2020-04-16 00:28:04 +03:00
QCommandLineOption debugOption ( " debug " , " Enable debug output " ) ;
parser . addOption ( debugOption ) ;
2020-10-22 02:20:02 +03:00
// This option is not actually parsed via Qt due to the need to parse it before the app
// name is set. It only exists to keep Qt from complaining about the --profile/-p
// option and thereby crashing the app.
QCommandLineOption configName ( QStringList ( ) < < " p " < < " profile " ,
QCoreApplication : : tr ( " Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. " ) ,
QCoreApplication : : tr ( " profile " ) , QCoreApplication : : tr ( " profile name " ) ) ;
parser . addOption ( configName ) ;
2018-07-15 14:53:18 +03:00
parser . process ( app ) ;
2017-05-03 23:32:51 +03:00
2017-09-10 12:59:21 +03:00
app . setWindowIcon ( QIcon ( " :/logos/nheko.png " ) ) ;
2018-06-09 16:03:14 +03:00
http : : init ( ) ;
2018-06-12 20:36:16 +03:00
createCacheDirectory ( ) ;
2018-07-01 19:40:53 +03:00
registerSignalHandlers ( ) ;
2020-04-16 00:28:04 +03:00
if ( parser . isSet ( debugOption ) )
nhlog : : enable_debug_log_from_commandline = true ;
2018-06-09 16:03:14 +03:00
try {
2018-06-14 02:28:35 +03:00
nhlog : : init ( QString ( " %1/nheko.log " )
. arg ( QStandardPaths : : writableLocation ( QStandardPaths : : CacheLocation ) )
. toStdString ( ) ) ;
2018-06-09 16:03:14 +03:00
} catch ( const spdlog : : spdlog_ex & ex ) {
std : : cout < < " Log initialization failed: " < < ex . what ( ) < < std : : endl ;
std : : exit ( 1 ) ;
}
2017-04-06 02:06:42 +03:00
2018-10-01 17:56:46 +03:00
QSettings settings ;
2018-10-07 13:27:20 +03:00
QFont font ;
2019-01-19 19:20:41 +03:00
QString userFontFamily = settings . value ( " user/font_family " , " " ) . toString ( ) ;
if ( ! userFontFamily . isEmpty ( ) ) {
font . setFamily ( userFontFamily ) ;
}
2018-10-01 17:56:46 +03:00
font . setPointSizeF ( settings . value ( " user/font_size " , font . pointSizeF ( ) ) . toDouble ( ) ) ;
app . setFont ( font ) ;
2017-04-06 02:06:42 +03:00
2017-09-10 12:59:21 +03:00
QString lang = QLocale : : system ( ) . name ( ) ;
2017-05-29 19:09:12 +03:00
2017-09-10 12:59:21 +03:00
QTranslator qtTranslator ;
2020-07-10 04:17:23 +03:00
qtTranslator . load (
QLocale ( ) , " qt " , " _ " , QLibraryInfo : : location ( QLibraryInfo : : TranslationsPath ) ) ;
2017-09-10 12:59:21 +03:00
app . installTranslator ( & qtTranslator ) ;
2017-05-29 19:09:12 +03:00
2017-09-10 12:59:21 +03:00
QTranslator appTranslator ;
2020-07-10 04:17:23 +03:00
appTranslator . load ( QLocale ( ) , " nheko " , " _ " , " :/translations " ) ;
2017-09-10 12:59:21 +03:00
app . installTranslator ( & appTranslator ) ;
2017-05-29 19:09:12 +03:00
2020-10-22 02:20:02 +03:00
MainWindow w { ( appName = = " nheko " ? " " : appName . remove ( " nheko- " ) ) } ;
2017-04-15 17:23:35 +03:00
2017-09-10 12:59:21 +03:00
// Move the MainWindow to the center
2017-12-14 22:55:00 +03:00
w . move ( screenCenter ( w . width ( ) , w . height ( ) ) ) ;
2018-05-08 23:53:40 +03:00
if ( ! settings . value ( " user/window/start_in_tray " , false ) . toBool ( ) | |
! settings . value ( " user/window/tray " , true ) . toBool ( ) )
w . show ( ) ;
2017-04-06 02:06:42 +03:00
2018-06-10 20:03:45 +03:00
QObject : : connect ( & app , & QApplication : : aboutToQuit , & w , [ & w ] ( ) {
w . saveCurrentWindowSize ( ) ;
2018-07-15 19:09:08 +03:00
if ( http : : client ( ) ! = nullptr ) {
2018-06-22 19:47:55 +03:00
nhlog : : net ( ) - > debug ( " shutting down all I/O threads & open connections " ) ;
2018-07-15 19:09:08 +03:00
http : : client ( ) - > close ( true ) ;
2018-06-22 19:47:55 +03:00
nhlog : : net ( ) - > debug ( " bye " ) ;
2018-06-10 20:03:45 +03:00
}
} ) ;
2020-02-23 15:40:04 +03:00
QObject : : connect ( & app , & SingleApplication : : instanceStarted , & w , [ & w ] ( ) {
w . show ( ) ;
w . raise ( ) ;
w . activateWindow ( ) ;
} ) ;
2017-07-30 13:59:28 +03:00
2018-09-19 23:38:36 +03:00
# if defined(Q_OS_MAC)
// Temporary solution for the emoji picker until
// nheko has a proper menu bar with more functionality.
MacHelper : : initializeMenus ( ) ;
# endif
2018-06-14 02:28:35 +03:00
nhlog : : ui ( ) - > info ( " starting nheko {} " , nheko : : version ) ;
2018-06-09 16:03:14 +03:00
2017-09-10 12:59:21 +03:00
return app . exec ( ) ;
2017-04-06 02:06:42 +03:00
}