From 2ea64fa4e5d8acc55445230e94fc3ccbb8927135 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Tue, 26 Aug 2014 12:01:03 +0200 Subject: [PATCH 01/14] Update README.md added build instructions for ubuntu --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index c55e480..3ec4e99 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,17 @@ cmake .. -DCMAKE_BUILD_TYPE=Release make sudo make install ``` +### Build instructions (Ubuntu) + +Install: `sudo apt-get install cmake qtbase5-dev` + +Switch to UTLauncher source folder and type: +``` +mkdir UTLauncher +cd UTLauncher +cmake .. -DCMAKE_BUILD_TYPE=Release +make +``` ## License Licensed under the MIT license From dd300167bf12cbaac315fc722f207b2cb9790343 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Tue, 26 Aug 2014 12:07:42 +0200 Subject: [PATCH 02/14] Update README.md add QtAwesome deps --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 3ec4e99..c9731f3 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ Double click on a server to join. It will ask for UnrealTournament.exe For compiled binaries no installation is necessary. For source, see below: +## First Step +Get QtAwesome from: https://github.com/gamecreature/QtAwesome. +Copy QtAwesome folder to: `/UTLauncher-master/3rdparty/QtAwesome/`. +Now the folder structure should look like: `/UTLauncher-master/3rdparty/QtAwesome/QtAwesome`. + ### Arch Linux UTLauncher is available in AUR as [utlauncher-git](https://aur.archlinux.org/packages/utlauncher-git/). Installation is as follows: From 33f47097d470d719a9d394e3a1450942e5838616 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Tue, 26 Aug 2014 13:53:38 +0200 Subject: [PATCH 03/14] Update utlauncher.cpp - added basic ubuntu appindicator functions not working atm - remove qt5 tray icon when using unity desktop (not working on unity) --- utlauncher.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/utlauncher.cpp b/utlauncher.cpp index 7371c4e..89c3cda 100644 --- a/utlauncher.cpp +++ b/utlauncher.cpp @@ -6,6 +6,51 @@ #include "configdialog.h" +/* +#undef signals +extern "C" { + #include + #include + + void quitIndicator(GtkMenu *, gpointer); + +} +#define signals public + +void quitIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + QApplication *self = static_cast(data); + + self->quit(); +} + +void ShowUnityAppIndicator() +{ + AppIndicator *indicator; + GtkWidget *menu, *item; + + menu = gtk_menu_new(); + + item = gtk_menu_item_new_with_label("Quit"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + g_signal_connect(item, "activate", + G_CALLBACK(quitIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(item); + + indicator = app_indicator_new( + "unique-application-name", + "indicator-messages", + APP_INDICATOR_CATEGORY_APPLICATION_STATUS + ); + + app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE); + app_indicator_set_menu(indicator, GTK_MENU(menu)); +}*/ + QtAwesome* awesome; QColor UTLauncher::iconColor() const { @@ -178,26 +223,44 @@ void UTLauncher::startServerBrowser() systemTrayMenu->addAction(quitAction); systemTray.setContextMenu(systemTrayMenu); - systemTray.show(); - connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) { - qApp->setQuitOnLastWindowClosed(true); - - runEditorAction->setVisible(hasEditorSupport()); - - switch(reason) { - + //desktop type + QString desktop; + bool is_unity; + + desktop = getenv("XDG_CURRENT_DESKTOP"); + is_unity = (desktop.toLower() == "unity"); + + if(is_unity) + { + // shows unity appindicator + // ShowUnityAppIndicator(); //TODO: implement appindicator + // hide qt systemtray - not working on unity + systemTray.hide(); + } + else + { + systemTray.show(); + + connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) + { + qApp->setQuitOnLastWindowClosed(true); + runEditorAction->setVisible(hasEditorSupport()); + switch(reason) + { case QSystemTrayIcon::Trigger: { - if(browser->isHidden()) { + if(browser->isHidden()) + { browser->show(); - } else { + } + else + { browser->hide(); } break; + } } - - } - }); - -} \ No newline at end of file + }); + } +} From 65f3ef57be128f9f1f8cf1da74c254623d6c3800 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Tue, 26 Aug 2014 13:57:29 +0200 Subject: [PATCH 04/14] Update configdialog.h - hide ui button when using unity --- configdialog.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/configdialog.h b/configdialog.h index 147ead1..8e2a0c5 100644 --- a/configdialog.h +++ b/configdialog.h @@ -270,6 +270,19 @@ class ConfigDialog : public QDialog locationsButton->setSizeHint(QSize(80, 64)); buttonMap[locationsButton] = 0; + // desktop type + QString desktop; + bool is_unity; + + desktop = getenv("XDG_CURRENT_DESKTOP"); + is_unity = (desktop.toLower() == "unity"); + + if(is_unity) + { + //dont show ui button + } + else + { auto uiButton = new QListWidgetItem(contentsWidget); uiButton->setIcon(awesome->icon(fa::desktop)); uiButton->setText(tr("UI")); @@ -277,6 +290,7 @@ class ConfigDialog : public QDialog uiButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); uiButton->setSizeHint(QSize(80, 64)); buttonMap[uiButton] = 1; + } connect(contentsWidget, @@ -291,4 +305,4 @@ public slots: }; -#endif // CONFIGDIALOG_H \ No newline at end of file +#endif // CONFIGDIALOG_H From ab7bf682f7c55590934317e794c82c5b6c661ce2 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Wed, 15 Oct 2014 20:54:46 +0200 Subject: [PATCH 05/14] make appindicator build optional --- CMakeLists.txt | 49 +++++++-- README.md | 35 +++--- appindicator.h | 144 +++++++++++++++++++++++++ bootstrap.h | 24 ++++- configdialog.h | 80 +++++++++----- download.cpp | 23 +++- download.h | 2 + files.qrc | 1 + icon.png | Bin 5469 -> 5900 bytes indicator_utlauncher.png | Bin 0 -> 9169 bytes main.cpp | 13 +-- serverbrowser.h | 139 ++++++++++++++++++++---- ubuntu_dependencies | 3 + utlauncher.cpp | 225 +++++++++++++++++++++++++++++---------- utlauncher.h | 2 +- 15 files changed, 592 insertions(+), 148 deletions(-) create mode 100644 appindicator.h create mode 100644 indicator_utlauncher.png create mode 100644 ubuntu_dependencies diff --git a/CMakeLists.txt b/CMakeLists.txt index 589c86d..912ab51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,20 +14,47 @@ set(CMAKE_AUTOMOC ON) find_package(Qt5Widgets) find_package(Qt5Network) find_package(PkgConfig) +find_package(ZLIB) #find_package(Boost COMPONENTS system REQUIRED) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +# appindicator -------------------------------------------- +IF(WITH_APPINDICATOR) + pkg_check_modules(PC_APPINDICATOR REQUIRED appindicator-0.1) + pkg_check_modules(GTK2 REQUIRED gtk+-2.0) + + find_path(APPINDICATOR_INCLUDE_DIR NAMES libappindicator/app-indicator.h + HINTS ${PC_APPINDICATOR_INCLUDEDIR} ${PC_APPINDICATOR_INCLUDE_DIRS} + PATH_SUFFIXES libappindicator-0.1) + + find_library(APPINDICATOR_LIBRARY NAMES appindicator) + + include(FindPackageHandleStandardArgs) + + find_package_handle_standard_args(APPINDICATOR DEFAULT_MSG APPINDICATOR_LIBRARY APPINDICATOR_INCLUDE_DIR) + + if(APPINDICATOR_FOUND) + set(APPINDICATOR_LIBRARIES ${APPINDICATOR_LIBRARY}) + set(APPINDICATOR_INCLUDE_DIRS ${APPINDICATOR_INCLUDE_DIR}) + endif() + + mark_as_advanced(APPINDICATOR_INCLUDE_DIR APPINDICATOR_LIBRARY) +ENDIF() +# ------------------------------------------------------------ + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") #pkg_check_modules(LIBTORRENT libtorrent-rasterbar) #string (REPLACE ";" " " LIBTORRENT_CFLAGS_STR "${LIBTORRENT_CFLAGS} -DBOOST_THREAD_USE_LIB") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBTORRENT_CFLAGS_STR}") if(CMAKE_BUILD_TYPE MATCHES Release) -add_definitions(-DQT_NO_DEBUG_OUTPUT) +#add_definitions(-DQT_NO_DEBUG_OUTPUT) endif() add_subdirectory(3rdparty) -include_directories(${3rdparty_INCLUDE_DIRS}) +#include_directories(${3rdparty_INCLUDE_DIRS}) +include_directories(${3rdparty_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${APPINDICATOR_INCLUDE_DIR}) +link_directories(${GTK2_LIBRARY_DIRS} ${APPINDICATOR_LIBRARY}) qt5_add_resources(resources files.qrc flags.qrc) @@ -37,23 +64,29 @@ endif(CMAKE_SYSTEM_NAME MATCHES Windows) if(CMAKE_SYSTEM_NAME MATCHES Windows AND CMAKE_BUILD_TYPE MATCHES Release) set(BUILD_TYPE WIN32) + add_definitions(-DLAUNCH_WITH_UE4) else() set(BUILD_TYPE "") endif() -set(UTLauncher_VERSION "0.2.6" CACHE STRING "Version number" FORCE INTERNAL) +set(UTLauncher_VERSION "0.3.2" CACHE STRING "Version number" FORCE INTERNAL) set_version_number(UTLauncher) add_definitions(-DNO_DOWNLOAD -DVERSION_MAJOR=${UTLauncher_VERSION_MAJOR} -DVERSION_MINOR=${UTLauncher_VERSION_MINOR} -DVERSION_PATCH=${UTLauncher_VERSION_PATCH}) -add_executable(UTLauncher ${BUILD_TYPE} ${resources} ${rc_srcs} main.cpp utlauncher.cpp download.cpp utsplash.cpp bootstrap.cpp serverbrowser.cpp configdialog.cpp $) +add_executable(UTLauncher ${BUILD_TYPE} ${resources} ${rc_srcs} main.cpp utlauncher.cpp download.cpp utsplash.cpp bootstrap.cpp serverbrowser.cpp configdialog.cpp $ $) if(STATIC_BUILD_WIN32) pkg_check_modules(QT5WIDGETS Qt5Widgets) add_definitions(-DSTATIC_PLUGIN_WINDOWS) - target_link_libraries(UTLauncher Qt5::Widgets Qt5::QWindowsIntegrationPlugin Qt5::Network ${QT5WIDGETS_LDFLAGS}) + target_link_libraries(UTLauncher Qt5::Widgets Qt5::QWindowsIntegrationPlugin Qt5::Network ${QT5WIDGETS_LDFLAGS} ${ZLIB_LIBRARY}) else() - target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY}) + if(APPINDICATOR_FOUND) + add_definitions(-DAPPINDICATOR) + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY} ${GTK2_LIBRARIES} ${APPINDICATOR_LIBRARY}) + else() + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) + endif() endif() -install(TARGETS UTLauncher RUNTIME DESTINATION bin) \ No newline at end of file +install(TARGETS UTLauncher RUNTIME DESTINATION bin) diff --git a/README.md b/README.md index c9731f3..42d1393 100644 --- a/README.md +++ b/README.md @@ -3,17 +3,12 @@ UTLauncher is a standalone application to join UT4 servers. You will need latest raxxy's UT build to use this though. In the future it is planned to automatically download latest UT playable releases. -Double click on a server to join. It will ask for UnrealTournament.exe +Double click on a server to join. It will ask for `UnrealTournament.exe` on Windows or `UnrealTournament` on Linux or Mac. ## Installation For compiled binaries no installation is necessary. For source, see below: -## First Step -Get QtAwesome from: https://github.com/gamecreature/QtAwesome. -Copy QtAwesome folder to: `/UTLauncher-master/3rdparty/QtAwesome/`. -Now the folder structure should look like: `/UTLauncher-master/3rdparty/QtAwesome/QtAwesome`. - ### Arch Linux UTLauncher is available in AUR as [utlauncher-git](https://aur.archlinux.org/packages/utlauncher-git/). Installation is as follows: @@ -26,12 +21,23 @@ makepkg -s pacman -U utlauncher-git*.pkg.tar.xz ``` -### Build instructions (Linux) +### Build instructions -You need to install Qt5 base development package. In openSUSE it is `libqt5-qtbase-devel`. +#### Requirements +You need to install Qt5 base development package, G++ compiler and cmake. -openSUSE + Qt5 repo mey be: `libQt5Gui-devel` `libQt5Network-devel` `libQt5Widgets-devel` +##### Ubuntu +``` +sudo apt-add-repository ppa:ubuntu-sdk-team/ppa +sudo apt-get update +sudo apt-get install qtbase5-dev g++ cmake +``` +##### openSUSE +`sudo zypper install libqt5-qtbase-devel gcc-c++ cmake` +##### openSUSE + Qt5 repo +`sudo zypper install libQt5Gui-devel libQt5Network-devel libQt5Widgets-devel gcc-c++ cmake` +### Build ``` git clone https://github.com/CodeCharmLtd/UTLauncher.git mkdir UTLauncher/build @@ -42,17 +48,6 @@ cmake .. -DCMAKE_BUILD_TYPE=Release make sudo make install ``` -### Build instructions (Ubuntu) - -Install: `sudo apt-get install cmake qtbase5-dev` - -Switch to UTLauncher source folder and type: -``` -mkdir UTLauncher -cd UTLauncher -cmake .. -DCMAKE_BUILD_TYPE=Release -make -``` ## License Licensed under the MIT license diff --git a/appindicator.h b/appindicator.h new file mode 100644 index 0000000..8e43e46 --- /dev/null +++ b/appindicator.h @@ -0,0 +1,144 @@ +#ifndef APPINDICATOR_H +#define APPINDICATOR_H + +//#ifdef APPINDICATOR +#undef signals +extern "C" { + + #include + #include + + void serverlistIndicator(GtkMenu *, gpointer); + void runutIndicator(GtkMenu *, gpointer); + void runeditorIndicator(GtkMenu *, gpointer); + void quitIndicator(GtkMenu *, gpointer); +} +#define signals public +//#endif +/* +void UTLauncher::startServerBrowser() + systemTrayMenu->addAction(showBrowser); + systemTrayMenu->addSeparator(); + systemTrayMenu->addAction(runUTAction); + systemTrayMenu->addAction(runEditorAction); + systemTrayMenu->addSeparator(); + systemTrayMenu->addAction(quitAction); +*/ + + +void serverlistIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + //UTLauncher *self = static_cast(data); + + //self->startServerBrowser().showBrowser.exec(); + //showBrowser +} + +void runutIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + //runUTAction +} + +void runeditorIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + //runEditorAction +} + +void quitIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + QApplication *self = static_cast(data); + + self->quit(); +} + +void ShowUnityAppIndicator() +{ + AppIndicator *indicator; + GtkWidget *menu, *quit_item, *serverlist_item, *runut_item, *runeditor_item; + + menu = gtk_menu_new(); + + serverlist_item = gtk_menu_item_new_with_label("Server List"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), serverlist_item); + g_signal_connect(serverlist_item, "activate", + G_CALLBACK(serverlistIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(serverlist_item); + + runut_item = gtk_menu_item_new_with_label("Run UT"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), runut_item); + g_signal_connect(runut_item, "activate", + G_CALLBACK(runutIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(runut_item); + + runeditor_item = gtk_menu_item_new_with_label("Run Editor"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), runeditor_item); + g_signal_connect(runeditor_item, "activate", + G_CALLBACK(runeditorIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(runeditor_item); + + quit_item = gtk_menu_item_new_with_label("Quit"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit_item); + g_signal_connect(quit_item, "activate", + G_CALLBACK(quitIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(quit_item); + + +/* +auto showBrowser = new QAction(awesome->icon(fa::listalt), "Server List", this); + connect(showBrowser, &QAction::triggered, [=]() { + browser->showNormal(); + browser->raise(); + browser->activateWindow(); + }); + + auto runUTAction = new QAction(awesome->icon( fa::gamepad ),"Run UT", this); + connect(runUTAction, &QAction::triggered, [=]() { + QString exePath = bootstrap.programExePath(); + if(!exePath.length()) { + browser->show(); + openSettings(); + return; + } + QProcess::startDetached(exePath); + }); + + auto runEditorAction = new QAction(awesome->icon( fa::code ),"Run Editor", this); + connect(runEditorAction, &QAction::triggered, [=]() { + QString editorPath = bootstrap.editorExePath(); + QString projectPath = bootstrap.projectPath(); + QProcess::startDetached(editorPath, QStringList() << projectPath); + }); +*/ + + + + indicator = app_indicator_new( + "UTLauncher", //id + "indicator_utlauncher", //icon default:indicator-messages + APP_INDICATOR_CATEGORY_APPLICATION_STATUS //category + ); + + QFile::copy(":/indicator_utlauncher.png", QDir::tempPath()+"/indicator_utlauncher.png"); + app_indicator_set_icon_theme_path(indicator, "/tmp"); + app_indicator_set_icon_full(indicator, "indicator_utlauncher", ""); + + app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE); + app_indicator_set_menu(indicator, GTK_MENU(menu)); +} +#endif diff --git a/bootstrap.h b/bootstrap.h index c7bdd24..6e8afa5 100644 --- a/bootstrap.h +++ b/bootstrap.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,8 @@ class Bootstrap : public QObject { QString releasePath; QString torrentFullFile; QSettings& settings; + QSet stockMaps; + QTimer bootstrapRedownloadTimer; @@ -55,6 +58,10 @@ private slots: return motd; } + bool isStockMap(QString map) const { + return stockMaps.contains(map); + } + Bootstrap(QSettings& _settings, QObject* parent = nullptr) : QObject(parent), settings(_settings) { download.setTarget("https://utlauncher.rushbase.net/bootstrap.json"); @@ -85,6 +92,11 @@ private slots: downloadServers.download(); bootstrapRedownloadTimer.singleShot(15*60000, &download, SLOT(download())); + stockMaps.clear(); + for(auto stockMap : json.value("stockMaps").toArray()) { + auto mapString = stockMap.toString(); + stockMaps.insert(mapString); + } #ifdef NO_DOWNLOAD emit ready(); @@ -164,14 +176,16 @@ private slots: } QString programExePath() { -#ifdef NO_DOWNLOAD - QString path = settings.value("UTExePath").toString(); + QString path = settings.value( + #ifdef LAUNCH_WITH_UE4 + "UTExePathUE4" + #else + "UTExePath" + #endif + ).toString(); if(QFile::exists(path)) return path; return ""; -#else - return releasePath + "/WindowsNoEditor/UnrealTournament/Binaries/Win64/UnrealTournament.exe"; -#endif } QString editorExePath() { diff --git a/configdialog.h b/configdialog.h index 8e2a0c5..a0ae964 100644 --- a/configdialog.h +++ b/configdialog.h @@ -92,19 +92,44 @@ class LocationsPage : public QWidget LocationsPage(QSettings& settings, bool mandatoryEditor, QWidget* parent = nullptr) { auto configGroup = new QGroupBox("Unreal Tournament location"); { + auto exeKey = + #ifdef LAUNCH_WITH_UE4 + "UTExePathUE4"; + #else + "UTExePath"; + #endif + auto layout = new QVBoxLayout; - auto fileInput = new FileInput(settings.value("UTExePath").toString(), "UnrealTournament executable", QString("UnrealTournament")+ -#ifdef __WIN32__ - "*.exe" -#else - QString() -#endif - ,true,this); - connect(fileInput, &FileInput::changed, [&](QString val) { - settings.setValue("UTExePath", val); + + auto fileInput = new FileInput(settings.value(exeKey).toString(), "UnrealTournament executable", + QString( + #ifdef LAUNCH_WITH_UE4 + "UE4" + #else + "UnrealTournament" + #endif + ) + #ifdef __WIN32__ + ".exe" + //#else + // QString() //Stupid Compile Error + #endif + ,true,this); + + connect(fileInput, &FileInput::changed, [&,exeKey](QString val) { + settings.setValue(exeKey, val); settings.sync(); }); layout->addWidget(fileInput); + + #ifdef LAUNCH_WITH_UE4 + auto info = new QLabel("Look for UE4" + #ifdef __WIN32__ + ".exe" + #endif + " file inside Engine/Binaries/*", this); + layout->addWidget(info); + #endif configGroup->setLayout(layout); } @@ -271,28 +296,27 @@ class ConfigDialog : public QDialog buttonMap[locationsButton] = 0; // desktop type - QString desktop; - bool is_unity; + QString desktop; + bool is_unity; - desktop = getenv("XDG_CURRENT_DESKTOP"); - is_unity = (desktop.toLower() == "unity"); + desktop = getenv("XDG_CURRENT_DESKTOP"); + is_unity = (desktop.toLower() == "unity"); - if(is_unity) - { - //dont show ui button - } - else - { - auto uiButton = new QListWidgetItem(contentsWidget); - uiButton->setIcon(awesome->icon(fa::desktop)); - uiButton->setText(tr("UI")); - uiButton->setTextAlignment(Qt::AlignHCenter); - uiButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - uiButton->setSizeHint(QSize(80, 64)); - buttonMap[uiButton] = 1; + if(is_unity) + { + //dont show ui button + } + else + { + auto uiButton = new QListWidgetItem(contentsWidget); + uiButton->setIcon(awesome->icon(fa::desktop)); + uiButton->setText(tr("UI")); + uiButton->setTextAlignment(Qt::AlignHCenter); + uiButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + uiButton->setSizeHint(QSize(80, 64)); + buttonMap[uiButton] = 1; } - connect(contentsWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*))); @@ -305,4 +329,4 @@ public slots: }; -#endif // CONFIGDIALOG_H +#endif // CONFIGDIALOG_H \ No newline at end of file diff --git a/download.cpp b/download.cpp index 3d7d253..7d196db 100644 --- a/download.cpp +++ b/download.cpp @@ -16,10 +16,12 @@ Download::~Download() { void Download::setTarget(const QString &t) { + this->target = t; } void Download::downloadFinished(QNetworkReply *data) { + emit done(data->readAll()); } @@ -29,6 +31,7 @@ void Download::download() { request.sslConfiguration().setProtocol(QSsl::AnyProtocol); + httpCode = 0; request.setRawHeader( "User-Agent" , QString("UTLauncher %1.%2.%3 / %4").arg(VERSION_MAJOR).arg(VERSION_MINOR).arg(VERSION_PATCH).arg( #if defined Q_OS_WINDOWS "Windows" @@ -42,14 +45,28 @@ void Download::download() { ).toUtf8() ); QNetworkReply* reply = manager.get(request); QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64))); + if(receivers(SIGNAL(chunk(QByteArray)))) { connect(reply, &QNetworkReply::readyRead, [=] { - emit chunk(reply->readAll()); + if(httpCode == 200) + emit chunk(reply->readAll()); }); } + QObject::connect(reply, &QNetworkReply::metaDataChanged, [=]() { + + auto statusCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ); + if ( statusCode.isValid() ) { + int replyCode = statusCode.toInt(); + httpCode = replyCode; + if(replyCode != 200) { + emit error(replyCode, reply->readAll()); + disconnect(this, SLOT(downloadProgress(qint64, qint64))); + } + return; + } + }); QObject::connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError))); QObject::connect(reply, SIGNAL(sslErrors(QList)), SLOT(downloadSslErrors(QList))); - } @@ -64,5 +81,5 @@ void Download::downloadError(QNetworkReply::NetworkError error) { } void Download::downloadProgress(qint64 recieved, qint64 total) { - qDebug() << recieved << total; + emit progress((double)recieved / total); } \ No newline at end of file diff --git a/download.h b/download.h index cf7e555..bdf83ae 100644 --- a/download.h +++ b/download.h @@ -17,6 +17,7 @@ class Download : public QObject { void setTarget(const QString& t); private: + int httpCode; QNetworkAccessManager manager; QString target; @@ -25,6 +26,7 @@ class Download : public QObject { void progress(double progress); void chunk(QByteArray chunk); + void error(int code, QByteArray data); public slots: void download(); diff --git a/files.qrc b/files.qrc index ff9fec4..bb89979 100644 --- a/files.qrc +++ b/files.qrc @@ -2,5 +2,6 @@ splash.jpg icon.png + indicator_utlauncher.png \ No newline at end of file diff --git a/icon.png b/icon.png index 2e074f14af6708bd2dcf4707699724b4ad6c506b..6eecc1bb99e959dd12403426d95ee2afee551e5d 100644 GIT binary patch delta 5889 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 XAD!UnLa>6*00000NkvXXu0mjfa!heJ delta 5457 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 b+t4rL)v#6(svp41Hz0LoZ6!3!I^zET3{QjC literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp index caf9e86..871633c 100644 --- a/main.cpp +++ b/main.cpp @@ -9,20 +9,22 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS QByteArray localMsg = msg.toLocal8Bit(); switch (type) { case QtDebugMsg: - fprintf(stderr, "Debug: %s\n\0 (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "Debug: %s\n (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtWarningMsg: - fprintf(stderr, "Warning: %s\n\0 (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "Warning: %s\n (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtCriticalMsg: - fprintf(stderr, "Critical: %s\n\0 (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "Critical: %s\n (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtFatalMsg: - fprintf(stderr, "Fatal: %s\n\0 (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "Fatal: %s\n (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); abort(); } } +#include + int main(int argc, char** argv) { qInstallMessageHandler(myMessageOutput); @@ -31,9 +33,8 @@ int main(int argc, char** argv) QCoreApplication::setOrganizationDomain("codecharm.co.uk"); QCoreApplication::setApplicationName("UTLauncher"); -// QApplication::setDesktopSettingsAware(false); UTLauncher app(argc, argv); - + return app.exec(); } diff --git a/serverbrowser.h b/serverbrowser.h index 33198fd..e97fdcd 100644 --- a/serverbrowser.h +++ b/serverbrowser.h @@ -19,6 +19,7 @@ #include #include +#include #include @@ -74,7 +75,6 @@ class ServerEntry : public QObject { }; QList players; public: - QString address() const { return host + ":" + QString::number(port); @@ -93,7 +93,6 @@ public slots: socket->deleteLater(); } socket = new QTcpSocket(this); - qDebug() << host << queryPort; socket->connectToHost(host, queryPort); connect(socket, &QTcpSocket::stateChanged, [=](QAbstractSocket::SocketState state) { toQuery = QList() << "GameMode" << "Map" << "PlayerNum" << "PlayerList"; @@ -109,7 +108,6 @@ public slots: connect(socket, &QTcpSocket::readyRead, [=]() { QString query = toQuery.takeFirst(); QString answer = QString(socket->readAll()).trimmed(); - qDebug() << "Got answer" << answer; if(query == "Map") { map = answer; } else if(query == "GameMode") { @@ -146,11 +144,10 @@ public slots: } else { avgPing = (9*avgPing + ping)/10; } - qDebug() << "Ping" << ping; lastQueryTime = QTime::currentTime(); emit queryDone(id); - queryTimer.singleShot(10000 + qrand() % 10000, this, SLOT(query())); + queryTimer.singleShot(15000 + qrand() % 15000, this, SLOT(query())); } }); } @@ -206,6 +203,13 @@ class ServerListModel : public QAbstractTableModel emit headerDataChanged(Qt::Horizontal, 0, (int)Column::MaxColumn-1); } + ServerEntry* serverEntryFromAddress(QString address) { + if(serverMap.contains(address)) { + return serverMap[address]; + } + return nullptr; + } + void loadFromJson(QJsonObject object) { beginResetModel(); @@ -307,6 +311,14 @@ class ServerListModel : public QAbstractTableModel static QStringList headers = { "", "Count", "Gametype", "Map", "Server Name", "Ping" }; + if(section == 0 && orientation == Qt::Horizontal) { + if(role == Qt::DecorationRole) + return awesome->icon(fa::flag); + if(role == Qt::TextAlignmentRole) + return Qt::AlignCenter; + } + + if(orientation == Qt::Horizontal && role == Qt::DisplayRole) { return headers[section]; } @@ -348,19 +360,33 @@ class ServerListProxyModel : public QSortFilterProxyModel QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); } bool lessThan(const QModelIndex &left, const QModelIndex &right) const { - if(left.column() == (int)Column::Country && right.column() == (int)Column::Country) { - auto& leftEntry = model->entryById(left.row()); - auto& rightEntry = model->entryById(right.row()); - return QString::compare(leftEntry.countryCode, rightEntry.countryCode) < 0; - } - if(left.column() == (int)Column::Ping && right.column() == (int)Column::Ping) { - auto& leftEntry = model->entryById(left.row()); - auto& rightEntry = model->entryById(right.row()); - - return leftEntry.avgPing < rightEntry.avgPing; - } - - QSortFilterProxyModel::lessThan(left, right); + + bool sortByCountry = (left.column() == (int)Column::Country && right.column() == (int)Column::Country); + bool sortByPing = (left.column() == (int)Column::Ping && right.column() == (int)Column::Ping); + + if(sortByCountry) { + auto& leftEntry = model->entryById(left.row()); + auto& rightEntry = model->entryById(right.row()); + + if(leftEntry.countryCode != rightEntry.countryCode) + return QString::compare(leftEntry.countryCode, rightEntry.countryCode) < 0; + sortByPing = true; + } + + if(sortByPing) { + auto& leftEntry = model->entryById(left.row()); + auto& rightEntry = model->entryById(right.row()); + + int leftPing = std::round(leftEntry.avgPing); + int rightPing = std::round(rightEntry.avgPing); + + if(leftPing == rightPing) { + return leftEntry.port < rightEntry.port; + } + return leftPing < rightPing; + } + + QSortFilterProxyModel::lessThan(left, right); } }; @@ -399,6 +425,9 @@ class iconned_dock_style: public QProxyStyle{ #include #include +#include +#include +#include class ServerBrowser : public QMainWindow { @@ -413,6 +442,8 @@ class ServerBrowser : public QMainWindow QLabel* statusLabel; QToolBar* buttonsToolbar; + + QToolBar* helpToolbar; QAction* settingsAction; QAction* playAction; QAction* spectateAction; @@ -441,6 +472,10 @@ class ServerBrowser : public QMainWindow motdLabel->setText(motd); } + const ServerEntry* serverEntryFromAddress(QString address) { + return model->serverEntryFromAddress(address); + } + ServerBrowser(QWidget* parent = nullptr) : model(new ServerListModel(this)), proxyModel(model, this), QMainWindow(parent) { table = new QTableView(this); @@ -550,6 +585,63 @@ class ServerBrowser : public QMainWindow } addToolBar(Qt::LeftToolBarArea, toolbar); + + + helpToolbar = new QToolBar("Links", this); + helpToolbar->setToolButtonStyle( Qt::ToolButtonTextBesideIcon ); + + auto spacerWidget = new QWidget(this); + spacerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + spacerWidget->setVisible(true); + helpToolbar->addWidget(spacerWidget); + + { + auto font = helpToolbar->font(); + font.setPointSizeF(font.pointSizeF()*0.8); + QFontMetrics metrics(font); + helpToolbar->setIconSize(QSize(metrics.height(), metrics.height())); + helpToolbar->setFont(font); + + + auto about = new QAction(awesome->icon(fa::handoup), "About", this); + connect(about, &QAction::triggered, [=] { + QMessageBox::about(this, "UTLauncher", "Brought to you by Damian \"Rush\" Kaczmarek from Code Charm Ltd

Servers delivered and hosted by raxxy and others. Server query code done by TimeH.

Big thanks to Epic Games for delivering us Unreal Tournament in open fashion!

Please visit Unreal Tournament forums to participate in development."); + }); + + helpToolbar->addAction(about); + + auto needHelp = new QAction(awesome->icon(fa::questioncircle), "Help", this); + + + auto github = new QAction(awesome->icon(fa::github), "Github", this); + connect(github, &QAction::triggered, [=] { + QDesktopServices::openUrl(QUrl("https://github.com/CodeCharmLtd/UTLauncher")); + }); + + auto helpAction = new QAction(awesome->icon(fa::comments), "IRC Chat", this); + connect(helpAction, &QAction::triggered, [=] { + QDesktopServices::openUrl(QUrl("http://webchat.globalgamers.net/?channels=beyondunreal")); + }); + + + helpToolbar->addAction(needHelp); + auto needHelpWidget = (QToolButton*)helpToolbar->widgetForAction(needHelp); + + needHelpWidget->setPopupMode(QToolButton::InstantPopup); + needHelpWidget->setArrowType(Qt::NoArrow); + needHelpWidget->setStyleSheet("QToolButton::menu-indicator { image: none; }"); + + + auto menu = new QMenu(this); + menu->addAction(github); + menu->addAction(helpAction); + + needHelpWidget->setMenu(menu); + } + + + addToolBar(Qt::LeftToolBarArea, helpToolbar); + } { auto dockWidget = new QDockWidget("Currently playing", this); @@ -592,6 +684,7 @@ class ServerBrowser : public QMainWindow playerListWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); playerListWidget->setSelectionBehavior(QAbstractItemView::SelectRows); playerListWidget->setSelectionMode(QAbstractItemView::SingleSelection); + playerListWidget->horizontalHeader()->setStretchLastSection(true); playerListWidget->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch); playerListWidget->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Fixed); @@ -660,6 +753,7 @@ class ServerBrowser : public QMainWindow table->setSortingEnabled(true); table->setSelectionMode(QAbstractItemView::SingleSelection); table->setModel(&proxyModel); + table->horizontalHeader()->setStretchLastSection(true); proxyModel.setDynamicSortFilter(true); @@ -720,6 +814,15 @@ class ServerBrowser : public QMainWindow for(QAction* action: actions) { buttonsToolbar->widgetForAction(action)->setMinimumWidth(maxWidth); } + auto pos = helpToolbar->pos(); + + + //buttonsToolbar->setSize(QSize()); + + helpToolbar->move(pos.x(), pos.y() + 100); + + qDebug() << "help toolbar" << pos; + QMainWindow::showEvent(show); } diff --git a/ubuntu_dependencies b/ubuntu_dependencies new file mode 100644 index 0000000..4afe997 --- /dev/null +++ b/ubuntu_dependencies @@ -0,0 +1,3 @@ +sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev +sudo apt-get remove qtbase5-dev g++ cmake libappindicator-dev + diff --git a/utlauncher.cpp b/utlauncher.cpp index 89c3cda..c9a8b32 100644 --- a/utlauncher.cpp +++ b/utlauncher.cpp @@ -5,51 +5,11 @@ #include #include "configdialog.h" +#include -/* -#undef signals -extern "C" { - #include - #include - - void quitIndicator(GtkMenu *, gpointer); - -} -#define signals public - -void quitIndicator(GtkMenu *menu, gpointer data) { - Q_UNUSED(menu); - QApplication *self = static_cast(data); - - self->quit(); -} - -void ShowUnityAppIndicator() -{ - AppIndicator *indicator; - GtkWidget *menu, *item; - - menu = gtk_menu_new(); - - item = gtk_menu_item_new_with_label("Quit"); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - g_signal_connect(item, "activate", - G_CALLBACK(quitIndicator), qApp); // We cannot connect - // gtk signal and qt slot so we need to create proxy - // function later on, we pass qApp pointer as an argument. - // This is useful when we need to call signals on "this" - //object so external function can access current object - gtk_widget_show(item); - - indicator = app_indicator_new( - "unique-application-name", - "indicator-messages", - APP_INDICATOR_CATEGORY_APPLICATION_STATUS - ); - - app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE); - app_indicator_set_menu(indicator, GTK_MENU(menu)); -}*/ +#ifdef APPINDICATOR +#include "appindicator.h" +#endif QtAwesome* awesome; @@ -124,6 +84,10 @@ void UTLauncher::closeSplash() } } +#include <3rdparty/quazip/quazip/quazip.h> +#include <3rdparty/quazip/quazip/quazipfile.h> +#include + void UTLauncher::startServerBrowser() { splashTimer.singleShot(2000, this, SLOT(closeSplash())); @@ -165,7 +129,142 @@ void UTLauncher::startServerBrowser() openSettings(); return; } - QProcess::startDetached(exePath, QStringList() << (url + (spectate?"?SpectatorOnly=1":"")) ); + const auto serverEntry = browser->serverEntryFromAddress(url); + auto launch = [=] { + qDebug() << "Launching!!\n"; + QProcess::startDetached(exePath, QStringList() + #ifdef LAUNCH_WITH_UE4 + << "UnrealTournament" + #endif + << (url + (spectate?"?SpectatorOnly=1":"")) ); + }; + + if(serverEntry) { + if(bootstrap.isStockMap(serverEntry->map)) { + launch(); + return; + } + + + QString exePath = bootstrap.programExePath(); + QFileInfo exeInfo(exePath); + auto contentDir = QDir(exeInfo.dir()); + contentDir.cdUp(); + contentDir.cdUp(); + contentDir.cd("Content"); + auto zipFilePath = contentDir.absoluteFilePath(serverEntry->map + ".zip"); + + if(QFile::exists(zipFilePath)) { + launch(); + return; + } + + Download mapDownload; + mapDownload.setTarget("https://ut.rushbase.net/customcontent/Data/" + serverEntry->map + ".zip"); + QProgressDialog dialog("Downloading map: " + serverEntry->map, "Cancel", 0, 100); + + QFile zipFile(zipFilePath); + zipFile.open(QIODevice::WriteOnly); + + int httpCode = 200; + connect(&mapDownload, &Download::error, [&](int code) { + httpCode = code; + if(code != 200) { + zipFile.remove(); + QMessageBox::critical(nullptr, "Unable to download map", QString("Got code %1 while trying to download map:
%2").arg(code).arg(serverEntry->map)); + } + }); + + connect(&mapDownload, &Download::chunk, [&](QByteArray chunk) { + qDebug() << "Reading!\n"; + zipFile.write(chunk); + }); + connect(&mapDownload, &Download::progress, [&](double progress) { + dialog.setValue(100*progress); + if(progress == 1.0) { + dialog.accept(); + } + }); + + + mapDownload.download(); + qDebug() << "Downloading map " << serverEntry->map; + if(!dialog.exec() || httpCode != 200) { + zipFile.remove(); // remove unfinished download + return; + } + zipFile.close(); + + QProgressDialog installDialog("Installing map: " + serverEntry->map, "", 0, 100); + installDialog.setWindowModality(Qt::ApplicationModal); + installDialog.show(); + installDialog.setValue(0); + + qDebug() << "Installed!!\n"; + QuaZip zip(zipFilePath); + + auto textCodec = QTextCodec::codecForName("TSCII"); + zip.setFileNameCodec(textCodec); + zip.setCommentCodec(textCodec); + zip.open(QuaZip::mdUnzip); + + QuaZipFile file(&zip); + + size_t totalSize = 0; + for(bool f=zip.goToFirstFile(); f; f=zip.goToNextFile()) { + QuaZipFileInfo info; + zip.getCurrentFileInfo(&info); + totalSize += info.uncompressedSize; + } + qDebug() << "Total size " << totalSize; + size_t accumulatedSize = 0; + /* TODO!!!!: this whole thing needs to be redone asynchronously */ + for(bool f=zip.goToFirstFile(); f; f=zip.goToNextFile()) { + file.open(QIODevice::ReadOnly); + //same functionality as QIODevice::readData() -- data is a char*, maxSize is qint64 + //file.readData(data,maxSize); + QString filename = file.getActualFileName(); + if(file.isOpen()) { + qApp->processEvents(); + qDebug() << installDialog.isVisible() << installDialog.value(); + if(!installDialog.isVisible() && installDialog.value() != 100 && installDialog.value() != -1) + return; + bool isDir = (filename.right(1) == "/"); + if(isDir) { + contentDir.mkpath(filename); + } else { + QFile f(contentDir.absoluteFilePath(filename)); + f.open(QIODevice::WriteOnly); + auto data = file.readAll(); + accumulatedSize += data.size(); + qDebug() << accumulatedSize; + installDialog.setValue(100 * (double)accumulatedSize / totalSize); + qApp->processEvents(); + qDebug() << installDialog.isVisible() << installDialog.value(); + if(!installDialog.isVisible() && installDialog.value() != 100 && installDialog.value() != -1) + return; + + f.write(data); + } + qDebug() << file.getActualFileName() << isDir; + + //do something with the data + if(file.isOpen()) + file.close(); + qApp->processEvents(); + qDebug() << installDialog.isVisible() << installDialog.value(); + if(!installDialog.isVisible() && installDialog.value() != 100 && installDialog.value() != -1) + return; + } + else { + qDebug() << "Cannot open" << filename << "inside zip";; + } + } + qDebug() << "Closing zip\n"; + zip.close(); + + launch(); + } } }); @@ -199,7 +298,11 @@ void UTLauncher::startServerBrowser() openSettings(); return; } - QProcess::startDetached(exePath); + QProcess::startDetached(exePath + #ifdef LAUNCH_WITH_UE4 + QStringList() << "UnrealTournament" + #endif + ); }); auto runEditorAction = new QAction(awesome->icon( fa::code ),"Run Editor", this); @@ -223,20 +326,22 @@ void UTLauncher::startServerBrowser() systemTrayMenu->addAction(quitAction); systemTray.setContextMenu(systemTrayMenu); - + //desktop type QString desktop; bool is_unity; desktop = getenv("XDG_CURRENT_DESKTOP"); is_unity = (desktop.toLower() == "unity"); - + if(is_unity) { - // shows unity appindicator - // ShowUnityAppIndicator(); //TODO: implement appindicator // hide qt systemtray - not working on unity systemTray.hide(); + // shows unity appindicator + #ifdef APPINDICATOR + ShowUnityAppIndicator(); //TODO: implement appindicator + #endif } else { @@ -245,22 +350,24 @@ void UTLauncher::startServerBrowser() connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) { qApp->setQuitOnLastWindowClosed(true); + runEditorAction->setVisible(hasEditorSupport()); + switch(reason) { - case QSystemTrayIcon::Trigger: - { - if(browser->isHidden()) + case QSystemTrayIcon::Trigger: { + if(browser->isHidden()) + { browser->show(); - } - else - { + } + else + { browser->hide(); - } - break; + } + break; } } }); } -} +} \ No newline at end of file diff --git a/utlauncher.h b/utlauncher.h index 8fa8436..ddf9c13 100644 --- a/utlauncher.h +++ b/utlauncher.h @@ -39,7 +39,7 @@ class UTLauncher: public QApplication QTimer serversRefreshTimer; QTimer splashTimer; QSystemTrayIcon systemTray; - + void prepareConfig(); QColor iconColor() const; From c2b93d682851da50d4c9590f41f4ef09c3e2e006 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Wed, 15 Oct 2014 21:00:12 +0200 Subject: [PATCH 06/14] Update README.md new build instructions for appindicator --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 42d1393..6d4f404 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,11 @@ pacman -U utlauncher-git*.pkg.tar.xz ### Build instructions #### Requirements -You need to install Qt5 base development package, G++ compiler and cmake. +You need to install Qt5 base development package, libappindicator-dev, G++ compiler and cmake. ##### Ubuntu ``` -sudo apt-add-repository ppa:ubuntu-sdk-team/ppa -sudo apt-get update -sudo apt-get install qtbase5-dev g++ cmake +sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev ``` ##### openSUSE `sudo zypper install libqt5-qtbase-devel gcc-c++ cmake` @@ -45,7 +43,17 @@ cd UTLauncher git submodule update --init --recursive cd build cmake .. -DCMAKE_BUILD_TYPE=Release +``` +to build with ubuntu appindicator: +``` +cmake .. -DCMAKE_BUILD_TYPE=Release -DWITH_APPINDICATOR=1 +``` + +``` make +``` +optional: +``` sudo make install ``` From 60de660be2b66525e281d9092d8bd55630144833 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Thu, 16 Oct 2014 00:14:58 +0200 Subject: [PATCH 07/14] minor changes, removed unity detection, use APPINDICATOR symbol --- configdialog.h | 30 ++++++------------- ubuntu_dependencies | 3 -- utlauncher.cpp | 71 +++++++++++++++++++-------------------------- 3 files changed, 39 insertions(+), 65 deletions(-) delete mode 100644 ubuntu_dependencies diff --git a/configdialog.h b/configdialog.h index a0ae964..e298ad2 100644 --- a/configdialog.h +++ b/configdialog.h @@ -295,28 +295,16 @@ class ConfigDialog : public QDialog locationsButton->setSizeHint(QSize(80, 64)); buttonMap[locationsButton] = 0; - // desktop type - QString desktop; - bool is_unity; + #ifndef APPINDICATOR + auto uiButton = new QListWidgetItem(contentsWidget); + uiButton->setIcon(awesome->icon(fa::desktop)); + uiButton->setText(tr("UI")); + uiButton->setTextAlignment(Qt::AlignHCenter); + uiButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + uiButton->setSizeHint(QSize(80, 64)); + buttonMap[uiButton] = 1; + #endif - desktop = getenv("XDG_CURRENT_DESKTOP"); - is_unity = (desktop.toLower() == "unity"); - - if(is_unity) - { - //dont show ui button - } - else - { - auto uiButton = new QListWidgetItem(contentsWidget); - uiButton->setIcon(awesome->icon(fa::desktop)); - uiButton->setText(tr("UI")); - uiButton->setTextAlignment(Qt::AlignHCenter); - uiButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - uiButton->setSizeHint(QSize(80, 64)); - buttonMap[uiButton] = 1; - } - connect(contentsWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*))); diff --git a/ubuntu_dependencies b/ubuntu_dependencies deleted file mode 100644 index 4afe997..0000000 --- a/ubuntu_dependencies +++ /dev/null @@ -1,3 +0,0 @@ -sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev -sudo apt-get remove qtbase5-dev g++ cmake libappindicator-dev - diff --git a/utlauncher.cpp b/utlauncher.cpp index c9a8b32..73ad3da 100644 --- a/utlauncher.cpp +++ b/utlauncher.cpp @@ -327,47 +327,36 @@ void UTLauncher::startServerBrowser() systemTray.setContextMenu(systemTrayMenu); - //desktop type - QString desktop; - bool is_unity; - desktop = getenv("XDG_CURRENT_DESKTOP"); - is_unity = (desktop.toLower() == "unity"); - - if(is_unity) - { - // hide qt systemtray - not working on unity - systemTray.hide(); - // shows unity appindicator - #ifdef APPINDICATOR - ShowUnityAppIndicator(); //TODO: implement appindicator - #endif - } - else + // shows unity appindicator + #ifdef APPINDICATOR + // hide qt systemtray - not working on unity + systemTray.hide(); + ShowUnityAppIndicator(); //TODO: implement appindicator + #endif + + #ifndef APPINDICATOR + systemTray.show(); + + connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) { - systemTray.show(); - - connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) - { - qApp->setQuitOnLastWindowClosed(true); - - runEditorAction->setVisible(hasEditorSupport()); - - switch(reason) - { - case QSystemTrayIcon::Trigger: - { - if(browser->isHidden()) - { - browser->show(); - } - else - { - browser->hide(); - } - break; - } - } - }); - } + qApp->setQuitOnLastWindowClosed(true); + runEditorAction->setVisible(hasEditorSupport()); + switch(reason) + { + case QSystemTrayIcon::Trigger: + { + if(browser->isHidden()) + { + browser->show(); + } + else + { + browser->hide(); + } + break; + } + } + }); + #endif } \ No newline at end of file From b01c6a693da6a3899dbe6788af7946c753f20926 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Thu, 16 Oct 2014 02:20:54 +0200 Subject: [PATCH 08/14] updated source to newest release, only cmake.txt is custom --- CMakeLists.txt | 5 +++-- appindicator.h | 13 ++++++------- download.cpp | 15 ++++++++++----- icon.ico | Bin 5694 -> 16958 bytes icon.png | Bin 5900 -> 14456 bytes indicator_utlauncher.png | Bin 9169 -> 14456 bytes serverbrowser.h | 34 ++++++++++++++++++++++++++++------ splash.jpg | Bin 45716 -> 99193 bytes ubuntu_dependencies | 3 +++ utlauncher.cpp | 7 ++++--- 10 files changed, 54 insertions(+), 23 deletions(-) create mode 100644 ubuntu_dependencies diff --git a/CMakeLists.txt b/CMakeLists.txt index 912ab51..15b02d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,14 +62,15 @@ if(CMAKE_SYSTEM_NAME MATCHES Windows) add_win32_resource(rc_srcs application.rc) endif(CMAKE_SYSTEM_NAME MATCHES Windows) +add_definitions(-DLAUNCH_WITH_UE4) if(CMAKE_SYSTEM_NAME MATCHES Windows AND CMAKE_BUILD_TYPE MATCHES Release) set(BUILD_TYPE WIN32) - add_definitions(-DLAUNCH_WITH_UE4) + #add_definitions(-DLAUNCH_WITH_UE4) else() set(BUILD_TYPE "") endif() -set(UTLauncher_VERSION "0.3.2" CACHE STRING "Version number" FORCE INTERNAL) +set(UTLauncher_VERSION "0.3.6" CACHE STRING "Version number" FORCE INTERNAL) set_version_number(UTLauncher) add_definitions(-DNO_DOWNLOAD -DVERSION_MAJOR=${UTLauncher_VERSION_MAJOR} -DVERSION_MINOR=${UTLauncher_VERSION_MINOR} -DVERSION_PATCH=${UTLauncher_VERSION_PATCH}) diff --git a/appindicator.h b/appindicator.h index 8e43e46..56b944f 100644 --- a/appindicator.h +++ b/appindicator.h @@ -1,7 +1,6 @@ #ifndef APPINDICATOR_H #define APPINDICATOR_H -//#ifdef APPINDICATOR #undef signals extern "C" { @@ -14,7 +13,6 @@ extern "C" { void quitIndicator(GtkMenu *, gpointer); } #define signals public -//#endif /* void UTLauncher::startServerBrowser() systemTrayMenu->addAction(showBrowser); @@ -125,16 +123,17 @@ auto showBrowser = new QAction(awesome->icon(fa::listalt), "Server List", this); QProcess::startDetached(editorPath, QStringList() << projectPath); }); */ - - - indicator = app_indicator_new( "UTLauncher", //id "indicator_utlauncher", //icon default:indicator-messages APP_INDICATOR_CATEGORY_APPLICATION_STATUS //category ); - - QFile::copy(":/indicator_utlauncher.png", QDir::tempPath()+"/indicator_utlauncher.png"); + + QFile tempfile; + tempfile.copy(":/indicator_utlauncher.png", QDir::tempPath()+"/indicator_utlauncher.png"); + // not working... + //tempfile.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser | QFile::ReadOther | QFile::WriteOther); + app_indicator_set_icon_theme_path(indicator, "/tmp"); app_indicator_set_icon_full(indicator, "indicator_utlauncher", ""); diff --git a/download.cpp b/download.cpp index 7d196db..60a4840 100644 --- a/download.cpp +++ b/download.cpp @@ -23,6 +23,7 @@ void Download::setTarget(const QString &t) { void Download::downloadFinished(QNetworkReply *data) { emit done(data->readAll()); + data->deleteLater(); } void Download::download() { @@ -34,15 +35,15 @@ void Download::download() { httpCode = 0; request.setRawHeader( "User-Agent" , QString("UTLauncher %1.%2.%3 / %4").arg(VERSION_MAJOR).arg(VERSION_MINOR).arg(VERSION_PATCH).arg( #if defined Q_OS_WINDOWS - "Windows" + "Windows" #elif defined Q_OS_LINUX - "Linux" + "Linux" #elif defined Q_OS_MAX - "MacOSX" + "MacOSX" #else - "Unknown" + "Unknown" #endif - ).toUtf8() ); + ).toUtf8() ); QNetworkReply* reply = manager.get(request); QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64))); @@ -61,10 +62,12 @@ void Download::download() { if(replyCode != 200) { emit error(replyCode, reply->readAll()); disconnect(this, SLOT(downloadProgress(qint64, qint64))); + reply->deleteLater(); } return; } }); + QObject::connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError))); QObject::connect(reply, SIGNAL(sslErrors(QList)), SLOT(downloadSslErrors(QList))); } @@ -78,6 +81,8 @@ void Download::downloadSslErrors(QList errors) { void Download::downloadError(QNetworkReply::NetworkError error) { qDebug() << "Got download error" << error; + + QObject::sender()->deleteLater(); } void Download::downloadProgress(qint64 recieved, qint64 total) { diff --git a/icon.ico b/icon.ico index ef2a376cdb2cd5b7d0639e1f3c72480b0044d72c..b6ee2cc2e4b7b8319e963da29d8404538bab0cd7 100644 GIT binary patch literal 16958 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 GjfO2IQI8p_rbE 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 KMNUMnLSTZRdu#&$ literal 5900 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 GjfO2IQI8p_rbE z^GkA7t>y*8BeVt4BvCU%+uov~*lGfd;xH`uNTHoP`{ndKitX zp$+Vk8*Dh`J`*)+CAsoEPW+T{Q;l`^!aC|7ALV92`A3d)%JaLn%Z7(Hs93Q`q9sKv z(Gj1bQj2F}6={)(k3>RGPp`D?-!1)vM+bNm3K4?ZAYyjz+$B$K-mK!s7PIHA=F{ef zFe@isY-Pko;IsI0FrN=$Ufhq}FUars%Es}`Blg&VAo$#`Jny!8ev1L1pUP=pe7`)` z0!vtU>|)AAtdF?P(}4+H9@j>-i{qNmzWL&YK+%Jw0(k1_C&Bs~%kz6$(!(ajuoyin zGb|expG3nb)uUGKqiQs0F1AP5U{Lx) zoH<0NdnuJC&n6&Pq-#kFPW;Lemh;e&t=pfKO^rXe85PED za2vR1)(EfJvSo{k6cb@_fZKI;zgagHUbb-nCXQ@Cpyj`Pm%3#paXu*M@i5#4;J-s& zWP-jITgFl=&bbZlTrxkx zdgHT8vFlYp76B9=;uEjAw}gi_*eN>d5Q{?@!b~j1r>QY-RH@B*s1~z|k8m_Zm;)6t zcle*i1sG?=vt3Pi@0qy#m!7u=rtnn~3%32PWh|L;W^j&l@MD|FWc@gPjLl|ACnDT8 zS6J3a>!^{P0MK`nN&t||F|2C^P2$GW#ye|SC7T>6u5{x-F#9_`EsPb>8uc5XEQw-B zI2O@nKE~6Gh8Wv7#A+K|W@i?*D*^mb1^79tZ?V+tAXB9n9zm8`gzo}p*3c%>#J_C6!p~F!DbbpSxfz6dJQDI_((Nx>F zTFUsSa~ol9h%*z=N8+JRPu`$&(?w`oI9O+Su&L|NRDvchR8dHMj8dRdiCs zP3grEBW`Ye{Q?mIO>bFgjc07Ti;h-z)H**%W6Kv!Hy)n%2FMwX^Z%0{@jDz?L>3 z;olE=-qc;bKd%NVl^-z3yH9-#JL;!cQUo|euuht(%>e+bm$j&*RBoM6jm2 z;=sy2EYoE3^4KuecqN+M^MVOHoCvb#7#HbBqaCtH_54WO8EE4&{O0rlRJ>agiQ>i} z_%-}wD%{_^LinAKFX_=b`b9rX(^k)$A4Z=#@#rmAxg<%(g)XvQ6#61pRJ(Bpb+kBG z%t~rxpo>W!N5SUt+N@ZnSWUDT1)B^v0Nd~Q*OlUki%;s2);T4T`l%{fZ}s?n3ZAJa6!sAo$<;D6!IZ0$_JS5Ws~#{CWU!6D*|DAdH&PU@zf{d>O*d zxQ^&Yz$~x92fOKoYz=yJ3Fbvoip&R&#a!ozajN?c`j-DYR7%lbOM>ZMWz;+soVkxr76^z-?WTYwR ztBzLcgwkvgU##V$Xyr`tf>^i{^x3)ohrnq$--H z0~8(Z8^LTq(Rsu~O368PeeQe1w5~Yrh2N(k+3}l{qmG&j@hOem$9B}R3ZhR=vCKY0 zi%X)f;%R{a_UWJ0bHpOw8%7g%u!w}*%3)1IK@dW(g*!wJ?+?Sj!r^bp7{8GBY9qiF zdN~(@%0J!^hUYGY&~6e}md|j2GXd?p@lm0v^nsSr05)rKU_ALbBt|gLLM9BAcplO?f;J{&#yTP+xk?6a@ zC;U_9zb^#XQi;xA3>EmN6Fu*Oso)66eXo|*2q~8Ub0GmzAj=@>QEUB{4efMDV{w>$ z+c)p-4WsWmD)4pCoePl=2`o#|Z_7J96gb(=dmH!+_r>n#LG`V`B>?}=xb0uCwx3ME z|Gp7m3pwI!Q2n1(hvDmB1&wcjXc~uhP(<(}nF(`{I9`{|8NF5i=;z7<7lSFd1Pm#e zZX3m!xo<=wpQAwrx9_=3Uc!xm;76l-Q>n1CR0`UHpcnT(o~f$3>%j2vzsX4wH-88S zu!V4AboDaqT-hkHvNoBlt}GV4DXc@K(gasPk_hYT@ZeO%vw{C^z*$F_kpJzWaQUjr^!1aUPU z=4oXkxPzaBfb#Te?Q?_#E)l>`gF_URXUWNVB8LbWb>E7If1+R4gc2{nR_+C9?;Z`q zN7ISK`dq0*pmVU?%l;zviRkYZ?@xp5ZiMqz0c4~gl9HT= z4D#O#Tpk$P5VAc0z)J&Rn8!6kqZBQkcL0dl2B1@!GQ+-GUIj{jspSt10WY=~QaH|) zMihrz(p=}Lk4hKN=XFI6e&)w=Br5;wbX)$WQAH|0=}L91%YOhTOqiv@4@AZQ0000< KMNUMnLSTZRdu#&$ literal 9169 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 b+t4rL)v#6(svp41Hz0LoZ6!3!I^zET3{QjC diff --git a/serverbrowser.h b/serverbrowser.h index e97fdcd..3eab237 100644 --- a/serverbrowser.h +++ b/serverbrowser.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -60,7 +61,7 @@ class ServerEntry : public QObject { QList toQuery; QTime timer; QTime elapsed; - QList pingResults; + QLinkedList pingResults; QTimer queryTimer; QTime lastQueryTime; @@ -79,9 +80,14 @@ class ServerEntry : public QObject { QString address() const { return host + ":" + QString::number(port); } + ~ServerEntry() { + if(socket) + delete socket; + } private slots: void onError(QAbstractSocket::SocketError socketError) { + qDebug() << "Got error!!!!!!\n"; queryTimer.stop(); queryTimer.singleShot(5000, this, SLOT(query())); ping = MAX_PING; @@ -90,9 +96,12 @@ private slots: public slots: void query() { if(socket) { - socket->deleteLater(); + delete socket; } socket = new QTcpSocket(this); + + pingResults.clear(); + socket->connectToHost(host, queryPort); connect(socket, &QTcpSocket::stateChanged, [=](QAbstractSocket::SocketState state) { toQuery = QList() << "GameMode" << "Map" << "PlayerNum" << "PlayerList"; @@ -125,6 +134,7 @@ public slots: } } + qDebug() << "Append " << timer.elapsed() << host; pingResults.append(timer.elapsed()); if(toQuery.size()) { @@ -178,6 +188,12 @@ class ServerListModel : public QAbstractTableModel QMap serverMap; public: + ~ServerListModel() { + for(auto server: servers) { + server->deleteLater(); + } + } + int playerCount() { int count = 0; for(auto server: servers) { @@ -239,16 +255,16 @@ class ServerListModel : public QAbstractTableModel if(!entry) { entry = new ServerEntry(); serverMap[address] = entry; + connect(entry, &ServerEntry::queryDone, [=](int id) { + emit dataChanged(createIndex(id, 0),createIndex(id, (int)Column::MaxColumn-1)); + }); } entry->id = id++; servers.append(entry); entry->updateFromJson(object); - connect(entry, &ServerEntry::queryDone, [=](int id) { - emit dataChanged(createIndex(id, 0),createIndex(id, (int)Column::MaxColumn-1)); - }); - + qDebug() << "Immediate query " << address; entry->query(); } // redo ids @@ -456,6 +472,12 @@ class ServerBrowser : public QMainWindow event->ignore(); this->hide(); return; + + /* not working --> file is read only... + #ifdef APPINDICATOR + QFile::remove(QDir::tempPath()+"/indicator_utlauncher.png"); + #endif + */ } QMainWindow::closeEvent(event); } diff --git a/splash.jpg b/splash.jpg index d618e7be46e3083d45b78a603ea2d562fba888df..e4c3a3064184866801538357d97c65351ff84c3c 100644 GIT binary patch delta 94533 zcma&NWo#ZnvnBkPnc05K%*@QpOo=gOX3Cf;W{R1anVpz1X2zJAA;!e(`(Az0-A^m+ zmgY}aS68WfS~b(>RHqz3K8M35;6h^LB;rS*va<=Wag%Yd3vhA?aPlVBaiHksLxG?{ zAP~gI!=8Al1c`2*ECkUGVczrrF%ALT(Zfv+X>@3?ojoq>`z;=gy)ks>ra;JBuJ{kV zgLF1!3n~U~mTR<~HkC%d?s?|3N3~+z=7t9{<4)I?HrdNMiP^yJvO$O{gzxl1KtLZc z#~+B{qK6^EnQB&N{HgrLkn4puxSMyFe|q*j1GBm9O#jabpEk4Ls4^yS^4JCV#})6w zN=hf;i&`Uwr}7I3X~h4GSD}Nn4n&G>!#qmXE+Vd6 zbAQZ7(9*1cVFn4duv{)|%&7s8Np5mBNG6&{+iD`zkCL49t<_8Q;ZCieCcHw?PLXw-uKG%F+ta**?YYrq1(& zi&_>q<3?zm5^dFGD@+q~HqtsP{ba)DQyr58c8v?`cEy z4UQsM?h}YKel%evrUuGQlaq?IlSV;yB-QEaJgc9M`+P;YrF+$9UibXWdUnX)Y$!`g zRb6(b<>;REO?6B5b%?n4=(aL}MFky$w*10SK=e<|LMa_HZFdZDNg~4fgRrOom~noI z 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≫oM~32X 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 delta 39681 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 diff --git a/ubuntu_dependencies b/ubuntu_dependencies new file mode 100644 index 0000000..4afe997 --- /dev/null +++ b/ubuntu_dependencies @@ -0,0 +1,3 @@ +sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev +sudo apt-get remove qtbase5-dev g++ cmake libappindicator-dev + diff --git a/utlauncher.cpp b/utlauncher.cpp index 73ad3da..27c86e7 100644 --- a/utlauncher.cpp +++ b/utlauncher.cpp @@ -136,7 +136,8 @@ void UTLauncher::startServerBrowser() #ifdef LAUNCH_WITH_UE4 << "UnrealTournament" #endif - << (url + (spectate?"?SpectatorOnly=1":"")) ); + << (url + (spectate?"?SpectatorOnly=1":"")) + << "-SaveToUserDir"); }; if(serverEntry) { @@ -300,7 +301,7 @@ void UTLauncher::startServerBrowser() } QProcess::startDetached(exePath #ifdef LAUNCH_WITH_UE4 - QStringList() << "UnrealTournament" + , QStringList() << "UnrealTournament" << "-SaveToUserDir" #endif ); }); @@ -334,7 +335,7 @@ void UTLauncher::startServerBrowser() systemTray.hide(); ShowUnityAppIndicator(); //TODO: implement appindicator #endif - + #ifndef APPINDICATOR systemTray.show(); From 8c8d49acacdf72d0280beb78e96ade71fa43a423 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Thu, 16 Oct 2014 17:21:27 +0200 Subject: [PATCH 09/14] updated source to newest release, read readme to build on ubuntu --- 3rdparty/CMakeLists.txt | 19 ++ CMakeLists.txt | 96 ++++++---- CMakeLists_ubuntu.txt | 96 ++++++++++ CMakeModules/DeployQt5.cmake | 338 +++++++++++++++++++++++++++++++++++ CMakeModules/Version.cmake | 1 - README.md | 1 + bootstrap.h | 8 +- configdialog.h | 61 +++---- download.cpp | 10 +- icon.icns | Bin 0 -> 13661 bytes serverbrowser.h | 76 ++++---- utlauncher.cpp | 62 ++++--- 12 files changed, 624 insertions(+), 144 deletions(-) create mode 100644 CMakeLists_ubuntu.txt create mode 100644 CMakeModules/DeployQt5.cmake create mode 100644 icon.icns diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 260d41e..8887d55 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -9,6 +9,25 @@ add_library(QtAwesome OBJECT QtAwesome/QtAwesome/QtAwesome.cpp ${faresources}) set_target_properties(QtAwesome PROPERTIES COMPILE_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") + + + + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/quazip/quazip + ${CMAKE_CURRENT_BINARY_DIR}/quazip/quazip + ${ZLIB_INCLUDE_DIR} +) + +file(GLOB SRCS "quazip/quazip/*.c" "quazip/quazip/*.cpp") +file(GLOB PUBLIC_HEADERS "quazip/quazip/*.h") + +# Must be added to enable export macro +ADD_DEFINITIONS(-DQUAZIP_BUILD) + +add_library(quazip OBJECT ${SRCS}) +#target_link_libraries(quazip Qt5::Core ${ZLIB_LIBRARY}) + set(3rdparty_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/QtAwesome/QtAwesome CACHE INTERNAL "") #target_link_libraries(QtAwesome Qt5::Widgets) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15b02d7..83d6c78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,17 @@ -cmake_minimum_required(VERSION 2.8.12) - -project(UTLauncher) +if(WITH_APPINDICATOR) + cmake_minimum_required(VERSION 2.8.12) +else() + cmake_minimum_required(VERSION 3.0.0) + cmake_policy(SET CMP0048 NEW) +endif() +project(UTLauncher VERSION 0.3.6) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") include(MingwResource) include(Version) +if(APPLE) + include(DeployQt5) # For Mac +endif() # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -17,28 +24,28 @@ find_package(PkgConfig) find_package(ZLIB) #find_package(Boost COMPONENTS system REQUIRED) -# appindicator -------------------------------------------- -IF(WITH_APPINDICATOR) - pkg_check_modules(PC_APPINDICATOR REQUIRED appindicator-0.1) - pkg_check_modules(GTK2 REQUIRED gtk+-2.0) +# Ubuntu Appindicator GTK2-------------------------------------------- +if(WITH_APPINDICATOR) + pkg_check_modules(PC_APPINDICATOR REQUIRED appindicator-0.1) + pkg_check_modules(GTK2 REQUIRED gtk+-2.0) - find_path(APPINDICATOR_INCLUDE_DIR NAMES libappindicator/app-indicator.h - HINTS ${PC_APPINDICATOR_INCLUDEDIR} ${PC_APPINDICATOR_INCLUDE_DIRS} - PATH_SUFFIXES libappindicator-0.1) + find_path(APPINDICATOR_INCLUDE_DIR NAMES libappindicator/app-indicator.h + HINTS ${PC_APPINDICATOR_INCLUDEDIR} ${PC_APPINDICATOR_INCLUDE_DIRS} + PATH_SUFFIXES libappindicator-0.1) - find_library(APPINDICATOR_LIBRARY NAMES appindicator) + find_library(APPINDICATOR_LIBRARY NAMES appindicator) - include(FindPackageHandleStandardArgs) + include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(APPINDICATOR DEFAULT_MSG APPINDICATOR_LIBRARY APPINDICATOR_INCLUDE_DIR) + find_package_handle_standard_args(APPINDICATOR DEFAULT_MSG APPINDICATOR_LIBRARY APPINDICATOR_INCLUDE_DIR) - if(APPINDICATOR_FOUND) - set(APPINDICATOR_LIBRARIES ${APPINDICATOR_LIBRARY}) - set(APPINDICATOR_INCLUDE_DIRS ${APPINDICATOR_INCLUDE_DIR}) - endif() + if(APPINDICATOR_FOUND) + set(APPINDICATOR_LIBRARIES ${APPINDICATOR_LIBRARY}) + set(APPINDICATOR_INCLUDE_DIRS ${APPINDICATOR_INCLUDE_DIR}) + endif() - mark_as_advanced(APPINDICATOR_INCLUDE_DIR APPINDICATOR_LIBRARY) -ENDIF() + mark_as_advanced(APPINDICATOR_INCLUDE_DIR APPINDICATOR_LIBRARY) +endif() # ------------------------------------------------------------ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") @@ -48,46 +55,69 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBTORRENT_CFLAGS_STR}") if(CMAKE_BUILD_TYPE MATCHES Release) -#add_definitions(-DQT_NO_DEBUG_OUTPUT) + add_definitions(-DQT_NO_DEBUG_OUTPUT) endif() add_subdirectory(3rdparty) -#include_directories(${3rdparty_INCLUDE_DIRS}) -include_directories(${3rdparty_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${APPINDICATOR_INCLUDE_DIR}) -link_directories(${GTK2_LIBRARY_DIRS} ${APPINDICATOR_LIBRARY}) +if(APPINDICATOR_FOUND) + include_directories(${3rdparty_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${APPINDICATOR_INCLUDE_DIR}) + link_directories(${GTK2_LIBRARY_DIRS} ${APPINDICATOR_LIBRARY}) +else() + include_directories(${3rdparty_INCLUDE_DIRS}) +endif() qt5_add_resources(resources files.qrc flags.qrc) if(CMAKE_SYSTEM_NAME MATCHES Windows) -add_win32_resource(rc_srcs application.rc) + add_win32_resource(rc_srcs application.rc) endif(CMAKE_SYSTEM_NAME MATCHES Windows) add_definitions(-DLAUNCH_WITH_UE4) if(CMAKE_SYSTEM_NAME MATCHES Windows AND CMAKE_BUILD_TYPE MATCHES Release) set(BUILD_TYPE WIN32) - #add_definitions(-DLAUNCH_WITH_UE4) + +elseif(CMAKE_SYSTEM_NAME MATCHES Darwin) + set(BUILD_TYPE MACOSX_BUNDLE) + set(MACOSX_BUNDLE_ICON_FILE icon.icns) + set(resources ${resources} ${PROJECT_SOURCE_DIR}/icon.icns) + set_source_files_properties(icon.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") else() set(BUILD_TYPE "") endif() -set(UTLauncher_VERSION "0.3.6" CACHE STRING "Version number" FORCE INTERNAL) +set(UTLauncher_VERSION "${PROJECT_VERSION}" CACHE STRING "Version number" FORCE INTERNAL) set_version_number(UTLauncher) add_definitions(-DNO_DOWNLOAD -DVERSION_MAJOR=${UTLauncher_VERSION_MAJOR} -DVERSION_MINOR=${UTLauncher_VERSION_MINOR} -DVERSION_PATCH=${UTLauncher_VERSION_PATCH}) add_executable(UTLauncher ${BUILD_TYPE} ${resources} ${rc_srcs} main.cpp utlauncher.cpp download.cpp utsplash.cpp bootstrap.cpp serverbrowser.cpp configdialog.cpp $ $) - if(STATIC_BUILD_WIN32) pkg_check_modules(QT5WIDGETS Qt5Widgets) add_definitions(-DSTATIC_PLUGIN_WINDOWS) target_link_libraries(UTLauncher Qt5::Widgets Qt5::QWindowsIntegrationPlugin Qt5::Network ${QT5WIDGETS_LDFLAGS} ${ZLIB_LIBRARY}) else() if(APPINDICATOR_FOUND) - add_definitions(-DAPPINDICATOR) - target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY} ${GTK2_LIBRARIES} ${APPINDICATOR_LIBRARY}) - else() - target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) - endif() + add_definitions(-DAPPINDICATOR) + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY} ${GTK2_LIBRARIES} ${APPINDICATOR_LIBRARY}) + else() + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) + endif() endif() -install(TARGETS UTLauncher RUNTIME DESTINATION bin) +install(TARGETS UTLauncher BUNDLE DESTINATION . RUNTIME DESTINATION bin) + +if(APPLE) + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/bundle") + install_qt5_executable(UTLauncher.app "cocoa") + set(CMAKE_INSTALL_PREFIX "/Applications") + set(CPACK_GENERATOR "DragNDrop") + set(CPACK_DMG_FORMAT "UDBZ") + set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}") + set(CPACK_SYSTEM_NAME "OSX") + set(CPACK_PACKAGE_VENDOR "Code Charm Ltd") + set(CPACK_PACKAGE_NAME "UTLauncher") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") + set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/icon.icns") + set(CPACK_DMG_BACKGROUND_IMAGE "${PROJECT_SOURCE_DIR}/splash.jpg") + include(CPack) +endif() diff --git a/CMakeLists_ubuntu.txt b/CMakeLists_ubuntu.txt new file mode 100644 index 0000000..6d6c0da --- /dev/null +++ b/CMakeLists_ubuntu.txt @@ -0,0 +1,96 @@ +cmake_minimum_required(VERSION 2.8.12) + +project(UTLauncher) + +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") +include(MingwResource) +include(Version) + +# Find includes in corresponding build directories +set(CMAKE_INCLUDE_CURRENT_DIR ON) +# Instruct CMake to run moc automatically when needed. +set(CMAKE_AUTOMOC ON) + +find_package(Qt5Widgets) +find_package(Qt5Network) +find_package(PkgConfig) +find_package(ZLIB) +#find_package(Boost COMPONENTS system REQUIRED) + +# appindicator -------------------------------------------- +if(WITH_APPINDICATOR) + pkg_check_modules(PC_APPINDICATOR REQUIRED appindicator-0.1) + pkg_check_modules(GTK2 REQUIRED gtk+-2.0) + + find_path(APPINDICATOR_INCLUDE_DIR NAMES libappindicator/app-indicator.h + HINTS ${PC_APPINDICATOR_INCLUDEDIR} ${PC_APPINDICATOR_INCLUDE_DIRS} + PATH_SUFFIXES libappindicator-0.1) + + find_library(APPINDICATOR_LIBRARY NAMES appindicator) + + include(FindPackageHandleStandardArgs) + + find_package_handle_standard_args(APPINDICATOR DEFAULT_MSG APPINDICATOR_LIBRARY APPINDICATOR_INCLUDE_DIR) + + if(APPINDICATOR_FOUND) + set(APPINDICATOR_LIBRARIES ${APPINDICATOR_LIBRARY}) + set(APPINDICATOR_INCLUDE_DIRS ${APPINDICATOR_INCLUDE_DIR}) + endif() + + mark_as_advanced(APPINDICATOR_INCLUDE_DIR APPINDICATOR_LIBRARY) +endif() +# ------------------------------------------------------------ + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") + +#pkg_check_modules(LIBTORRENT libtorrent-rasterbar) +#string (REPLACE ";" " " LIBTORRENT_CFLAGS_STR "${LIBTORRENT_CFLAGS} -DBOOST_THREAD_USE_LIB") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBTORRENT_CFLAGS_STR}") + +if(CMAKE_BUILD_TYPE MATCHES Release) +#add_definitions(-DQT_NO_DEBUG_OUTPUT) +endif() + +add_subdirectory(3rdparty) +if(APPINDICATOR_FOUND) + include_directories(${3rdparty_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${APPINDICATOR_INCLUDE_DIR}) + link_directories(${GTK2_LIBRARY_DIRS} ${APPINDICATOR_LIBRARY}) +else() + include_directories(${3rdparty_INCLUDE_DIRS}) +endif() + +qt5_add_resources(resources files.qrc flags.qrc) + +if(CMAKE_SYSTEM_NAME MATCHES Windows) +add_win32_resource(rc_srcs application.rc) +endif(CMAKE_SYSTEM_NAME MATCHES Windows) + +add_definitions(-DLAUNCH_WITH_UE4) +if(CMAKE_SYSTEM_NAME MATCHES Windows AND CMAKE_BUILD_TYPE MATCHES Release) + set(BUILD_TYPE WIN32) + #add_definitions(-DLAUNCH_WITH_UE4) +else() + set(BUILD_TYPE "") +endif() + +set(UTLauncher_VERSION "0.3.6" CACHE STRING "Version number" FORCE INTERNAL) +set_version_number(UTLauncher) + +add_definitions(-DNO_DOWNLOAD -DVERSION_MAJOR=${UTLauncher_VERSION_MAJOR} -DVERSION_MINOR=${UTLauncher_VERSION_MINOR} -DVERSION_PATCH=${UTLauncher_VERSION_PATCH}) +add_executable(UTLauncher ${BUILD_TYPE} ${resources} ${rc_srcs} main.cpp utlauncher.cpp download.cpp utsplash.cpp bootstrap.cpp serverbrowser.cpp configdialog.cpp $ $) + + +if(STATIC_BUILD_WIN32) + pkg_check_modules(QT5WIDGETS Qt5Widgets) + add_definitions(-DSTATIC_PLUGIN_WINDOWS) + target_link_libraries(UTLauncher Qt5::Widgets Qt5::QWindowsIntegrationPlugin Qt5::Network ${QT5WIDGETS_LDFLAGS} ${ZLIB_LIBRARY}) +else() + if(APPINDICATOR_FOUND) + add_definitions(-DAPPINDICATOR) + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY} ${GTK2_LIBRARIES} ${APPINDICATOR_LIBRARY}) + else() + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) + endif() +endif() + +install(TARGETS UTLauncher RUNTIME DESTINATION bin) diff --git a/CMakeModules/DeployQt5.cmake b/CMakeModules/DeployQt5.cmake new file mode 100644 index 0000000..35d1569 --- /dev/null +++ b/CMakeModules/DeployQt5.cmake @@ -0,0 +1,338 @@ +#.rst: +# DeployQt5 +# --------- +# +# Functions to help assemble a standalone Qt5 executable. +# +# A collection of CMake utility functions useful for deploying Qt5 +# executables. +# +# The following functions are provided by this module: +# +# :: +# +# write_qt5_conf +# resolve_qt5_paths +# fixup_qt5_executable +# install_qt5_plugin_path +# install_qt5_plugin +# install_qt5_executable +# +# Requires CMake 2.8.9 or greater because Qt 5 does. +# Also depends on BundleUtilities.cmake. +# +# :: +# +# WRITE_QT5_CONF( ) +# +# Writes a qt.conf file with the into . +# +# :: +# +# RESOLVE_QT5_PATHS( []) +# +# Loop through list and if any don't exist resolve them +# relative to the (if supplied) or the +# CMAKE_INSTALL_PREFIX. +# +# :: +# +# FIXUP_QT5_EXECUTABLE( [ ]) +# +# Copies Qt plugins, writes a Qt configuration file (if needed) and +# fixes up a Qt5 executable using BundleUtilities so it is standalone +# and can be drag-and-drop copied to another machine as long as all of +# the system libraries are compatible. +# +# should point to the executable to be fixed-up. +# +# should contain a list of the names or paths of any Qt +# plugins to be installed. +# +# will be passed to BundleUtilities and should be a list of any +# already installed plugins, libraries or executables to also be +# fixed-up. +# +# will be passed to BundleUtilities and should contain and +# directories to be searched to find library dependencies. +# +# allows an custom plugins directory to be used. +# +# will force a qt.conf file to be written even if not +# needed. +# +# :: +# +# INSTALL_QT5_PLUGIN_PATH(plugin executable copy installed_plugin_path_var ) +# +# Install (or copy) a resolved to the default plugins directory +# (or ) relative to and store the result in +# . +# +# If is set to TRUE then the plugins will be copied rather than +# installed. This is to allow this module to be used at CMake time +# rather than install time. +# +# If is set then anything installed will use this COMPONENT. +# +# :: +# +# INSTALL_QT5_PLUGIN(plugin executable copy installed_plugin_path_var ) +# +# Install (or copy) an unresolved to the default plugins +# directory (or ) relative to and store the +# result in . See documentation of +# INSTALL_QT5_PLUGIN_PATH. +# +# :: +# +# INSTALL_QT5_EXECUTABLE( [ ]) +# +# Installs Qt plugins, writes a Qt configuration file (if needed) and +# fixes up a Qt5 executable using BundleUtilities so it is standalone +# and can be drag-and-drop copied to another machine as long as all of +# the system libraries are compatible. The executable will be fixed-up +# at install time. is the COMPONENT used for bundle fixup +# and plugin installation. See documentation of FIXUP_QT5_BUNDLE. + +#============================================================================= +# Copyright 2011 Mike McQuaid +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# The functions defined in this file depend on the fixup_bundle function +# (and others) found in BundleUtilities.cmake + +include(BundleUtilities) +set(DeployQt5_cmake_dir "${CMAKE_CURRENT_LIST_DIR}") +set(DeployQt5_apple_plugins_dir "PlugIns") + +function(write_qt5_conf qt_conf_dir qt_conf_contents) + set(qt_conf_path "${qt_conf_dir}/qt.conf") + message(STATUS "Writing ${qt_conf_path}") + file(WRITE "${qt_conf_path}" "${qt_conf_contents}") +endfunction() + +function(resolve_qt5_paths paths_var) + set(executable_path ${ARGV1}) + + set(paths_resolved) + foreach(path ${${paths_var}}) + if(EXISTS "${path}") + list(APPEND paths_resolved "${path}") + else() + if(${executable_path}) + list(APPEND paths_resolved "${executable_path}/${path}") + else() + list(APPEND paths_resolved "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${path}") + endif() + endif() + endforeach() + set(${paths_var} ${paths_resolved} PARENT_SCOPE) +endfunction() + +function(fixup_qt5_executable executable) + set(qtplugins ${ARGV1}) + set(libs ${ARGV2}) + set(dirs ${ARGV3}) + set(plugins_dir ${ARGV4}) + set(request_qt_conf ${ARGV5}) + + message(STATUS "fixup_qt5_executable") + message(STATUS " executable='${executable}'") + message(STATUS " qtplugins='${qtplugins}'") + message(STATUS " libs='${libs}'") + message(STATUS " dirs='${dirs}'") + message(STATUS " plugins_dir='${plugins_dir}'") + message(STATUS " request_qt_conf='${request_qt_conf}'") + + if(QT_LIBRARY_DIR) + list(APPEND dirs "${QT_LIBRARY_DIR}") + endif() + if(QT_BINARY_DIR) + list(APPEND dirs "${QT_BINARY_DIR}") + endif() + + if(APPLE) + set(qt_conf_dir "${executable}/Contents/Resources") + set(executable_path "${executable}") + set(write_qt_conf TRUE) + if(NOT plugins_dir) + set(plugins_dir "${DeployQt5_apple_plugins_dir}") + endif() + else() + get_filename_component(executable_path "${executable}" PATH) + if(NOT executable_path) + set(executable_path ".") + endif() + set(qt_conf_dir "${executable_path}") + set(write_qt_conf ${request_qt_conf}) + endif() + + foreach(plugin ${qtplugins}) + set(installed_plugin_path "") + install_qt5_plugin("${plugin}" "${executable}" 1 installed_plugin_path) + list(APPEND libs ${installed_plugin_path}) + endforeach() + + foreach(lib ${libs}) + if(NOT EXISTS "${lib}") + message(FATAL_ERROR "Library does not exist: ${lib}") + endif() + endforeach() + + resolve_qt5_paths(libs "${executable_path}") + + if(write_qt_conf) + set(qt_conf_contents "[Paths]\nPlugins = ${plugins_dir}") + write_qt5_conf("${qt_conf_dir}" "${qt_conf_contents}") + endif() + + fixup_bundle("${executable}" "${libs}" "${dirs}") +endfunction() + +function(install_qt5_plugin_path plugin executable copy installed_plugin_path_var) + set(plugins_dir ${ARGV4}) + set(component ${ARGV5}) + set(configurations ${ARGV6}) + if(EXISTS "${plugin}") + if(APPLE) + if(NOT plugins_dir) + set(plugins_dir "${DeployQt5_apple_plugins_dir}") + endif() + set(plugins_path "${executable}/Contents/${plugins_dir}") + else() + get_filename_component(plugins_path "${executable}" PATH) + if(NOT plugins_path) + set(plugins_path ".") + endif() + if(plugins_dir) + set(plugins_path "${plugins_path}/${plugins_dir}") + endif() + endif() + + set(plugin_group "") + + get_filename_component(plugin_path "${plugin}" PATH) + get_filename_component(plugin_parent_path "${plugin_path}" PATH) + get_filename_component(plugin_parent_dir_name "${plugin_parent_path}" NAME) + get_filename_component(plugin_name "${plugin}" NAME) + string(TOLOWER "${plugin_parent_dir_name}" plugin_parent_dir_name) + + if("${plugin_parent_dir_name}" STREQUAL "plugins") + get_filename_component(plugin_group "${plugin_path}" NAME) + set(${plugin_group_var} "${plugin_group}") + endif() + set(plugins_path "${plugins_path}/${plugin_group}") + + if(${copy}) + file(MAKE_DIRECTORY "${plugins_path}") + file(COPY "${plugin}" DESTINATION "${plugins_path}") + else() + if(configurations AND (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)) + set(configurations CONFIGURATIONS ${configurations}) + else() + unset(configurations) + endif() + install(FILES "${plugin}" DESTINATION "${plugins_path}" ${configurations} ${component}) + endif() + set(${installed_plugin_path_var} "${plugins_path}/${plugin_name}" PARENT_SCOPE) + endif() +endfunction() + +function(install_qt5_plugin plugin executable copy installed_plugin_path_var) + set(plugins_dir ${ARGV4}) + set(component ${ARGV5}) + if(EXISTS "${plugin}") + install_qt5_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") + else() + string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var) + set(plugin_release_var "${plugin_var}_RELEASE") + set(plugin_debug_var "${plugin_var}_DEBUG") + set(plugin_release "${${plugin_release_var}}") + set(plugin_debug "${${plugin_debug_var}}") + if(DEFINED "${plugin_release_var}" AND DEFINED "${plugin_debug_var}" AND NOT EXISTS "${plugin_release}" AND NOT EXISTS "${plugin_debug}") + message(WARNING "Qt plugin \"${plugin}\" not recognized or found.") + endif() + if(NOT EXISTS "${${plugin_debug_var}}") + set(plugin_debug "${plugin_release}") + endif() + + if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) + install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}_release" "${plugins_dir}" "${component}" "Release|RelWithDebInfo|MinSizeRel") + install_qt5_plugin_path("${plugin_debug}" "${executable}" "${copy}" "${installed_plugin_path_var}_debug" "${plugins_dir}" "${component}" "Debug") + + if(CMAKE_BUILD_TYPE MATCHES "^Debug$") + set(${installed_plugin_path_var} ${${installed_plugin_path_var}_debug}) + else() + set(${installed_plugin_path_var} ${${installed_plugin_path_var}_release}) + endif() + else() + install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") + endif() + endif() + set(${installed_plugin_path_var} ${${installed_plugin_path_var}} PARENT_SCOPE) +endfunction() + +function(install_qt5_executable executable) + set(qtplugins ${ARGV1}) + set(libs ${ARGV2}) + set(dirs ${ARGV3}) + set(plugins_dir ${ARGV4}) + set(request_qt_conf ${ARGV5}) + set(component ${ARGV6}) + if(QT_LIBRARY_DIR) + list(APPEND dirs "${QT_LIBRARY_DIR}") + endif() + if(QT_BINARY_DIR) + list(APPEND dirs "${QT_BINARY_DIR}") + endif() + if(component) + set(component COMPONENT ${component}) + else() + unset(component) + endif() + + get_filename_component(executable_absolute "${executable}" ABSOLUTE) + if(EXISTS "${QT_QTCORE_LIBRARY_RELEASE}") + gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_RELEASE}" qtcore_type) + elseif(EXISTS "${QT_QTCORE_LIBRARY_DEBUG}") + gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_DEBUG}" qtcore_type) + endif() + if(qtcore_type STREQUAL "system") + set(qt_plugins_dir "") + endif() + + if(QT_IS_STATIC) + message(WARNING "Qt built statically: not installing plugins.") + else() + if(APPLE) + get_property(loc TARGET Qt5::QCocoaIntegrationPlugin + PROPERTY LOCATION_RELEASE) + install_qt5_plugin("${loc}" "${executable}" 0 installed_plugin_paths "PlugIns" "${component}") + list(APPEND libs ${installed_plugin_paths}) + endif() + foreach(plugin ${qtplugins}) + set(installed_plugin_paths "") + install_qt5_plugin("${plugin}" "${executable}" 0 installed_plugin_paths "${plugins_dir}" "${component}") + list(APPEND libs ${installed_plugin_paths}) + endforeach() + endif() + + resolve_qt5_paths(libs "") + + install(CODE + "include(\"${DeployQt5_cmake_dir}/DeployQt5.cmake\") + set(BU_CHMOD_BUNDLE_ITEMS TRUE) + FIXUP_QT5_EXECUTABLE(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")" + ${component} + ) +endfunction() diff --git a/CMakeModules/Version.cmake b/CMakeModules/Version.cmake index a987b99..81dadb9 100644 --- a/CMakeModules/Version.cmake +++ b/CMakeModules/Version.cmake @@ -1,6 +1,5 @@ macro (set_version_number _packageName) if (DEFINED ${_packageName}_VERSION) - message(STATUS "STATUS DEFAINED!! ${_packageName} ${${_packageName}_VERSION}") string (REGEX MATCHALL "[0-9]+" _versionComponents "${${_packageName}_VERSION}") list (LENGTH _versionComponents _len) if (${_len} GREATER 0) diff --git a/README.md b/README.md index 6d4f404..35a0691 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ You need to install Qt5 base development package, libappindicator-dev, G++ compi ##### Ubuntu ``` sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev +Important: rename CMakeLists.txt to CMakeLists.txt.bak and CMakeLists_ubuntu.txt to CMakeLists.txt to allow compiling on ubuntu! ``` ##### openSUSE `sudo zypper install libqt5-qtbase-devel gcc-c++ cmake` diff --git a/bootstrap.h b/bootstrap.h index 6e8afa5..9c28ac9 100644 --- a/bootstrap.h +++ b/bootstrap.h @@ -177,12 +177,12 @@ private slots: QString programExePath() { QString path = settings.value( - #ifdef LAUNCH_WITH_UE4 +#ifdef LAUNCH_WITH_UE4 "UTExePathUE4" - #else +#else "UTExePath" - #endif - ).toString(); +#endif + ).toString(); if(QFile::exists(path)) return path; return ""; diff --git a/configdialog.h b/configdialog.h index e298ad2..a6371aa 100644 --- a/configdialog.h +++ b/configdialog.h @@ -20,9 +20,6 @@ class FileInput : public QWidget { Q_OBJECT - bool isError(QString value) { - - } public: FileInput(QString value, QString label, QString filter, bool mandatory = false, QWidget* parent = nullptr) : QWidget(parent) { auto layout = new QHBoxLayout; @@ -92,44 +89,43 @@ class LocationsPage : public QWidget LocationsPage(QSettings& settings, bool mandatoryEditor, QWidget* parent = nullptr) { auto configGroup = new QGroupBox("Unreal Tournament location"); { - auto exeKey = - #ifdef LAUNCH_WITH_UE4 + + auto exeKey = +#ifdef LAUNCH_WITH_UE4 "UTExePathUE4"; - #else +#else "UTExePath"; - #endif - +#endif auto layout = new QVBoxLayout; - auto fileInput = new FileInput(settings.value(exeKey).toString(), "UnrealTournament executable", - QString( - #ifdef LAUNCH_WITH_UE4 - "UE4" - #else - "UnrealTournament" - #endif - ) - #ifdef __WIN32__ - ".exe" - //#else - // QString() //Stupid Compile Error - #endif - ,true,this); - + QString( +#ifdef LAUNCH_WITH_UE4 + "UE4" +#else + "UnrealTournament" +#endif + )+ + +#ifdef __WIN32__ + ".exe" +#else + QString() +#endif + ,true,this); connect(fileInput, &FileInput::changed, [&,exeKey](QString val) { settings.setValue(exeKey, val); settings.sync(); }); layout->addWidget(fileInput); - - #ifdef LAUNCH_WITH_UE4 - auto info = new QLabel("Look for UE4" - #ifdef __WIN32__ - ".exe" - #endif - " file inside Engine/Binaries/*", this); - layout->addWidget(info); - #endif + +#ifdef LAUNCH_WITH_UE4 + auto info = new QLabel("Look for UE4" +#ifdef __WIN32__ + ".exe" +#endif + " file inside Engine/Binaries/*", this); + layout->addWidget(info); +#endif configGroup->setLayout(layout); } @@ -295,6 +291,7 @@ class ConfigDialog : public QDialog locationsButton->setSizeHint(QSize(80, 64)); buttonMap[locationsButton] = 0; + //only show when appindicator is disabled #ifndef APPINDICATOR auto uiButton = new QListWidgetItem(contentsWidget); uiButton->setIcon(awesome->icon(fa::desktop)); diff --git a/download.cpp b/download.cpp index 60a4840..31ecf8b 100644 --- a/download.cpp +++ b/download.cpp @@ -35,15 +35,15 @@ void Download::download() { httpCode = 0; request.setRawHeader( "User-Agent" , QString("UTLauncher %1.%2.%3 / %4").arg(VERSION_MAJOR).arg(VERSION_MINOR).arg(VERSION_PATCH).arg( #if defined Q_OS_WINDOWS - "Windows" + "Windows" #elif defined Q_OS_LINUX - "Linux" + "Linux" #elif defined Q_OS_MAX - "MacOSX" + "MacOSX" #else - "Unknown" + "Unknown" #endif - ).toUtf8() ); + ).toUtf8() ); QNetworkReply* reply = manager.get(request); QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64))); diff --git a/icon.icns b/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..3c80b40f8b066467bcf7722f06d1c095609eb1b3 GIT binary patch literal 13661 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, queryPort); connect(socket, &QTcpSocket::stateChanged, [=](QAbstractSocket::SocketState state) { toQuery = QList() << "GameMode" << "Map" << "PlayerNum" << "PlayerList"; @@ -157,7 +158,7 @@ public slots: lastQueryTime = QTime::currentTime(); emit queryDone(id); - queryTimer.singleShot(15000 + qrand() % 15000, this, SLOT(query())); + queryTimer.singleShot(10000 + qrand() % 10000, this, SLOT(query())); } }); } @@ -193,7 +194,7 @@ class ServerListModel : public QAbstractTableModel server->deleteLater(); } } - + int playerCount() { int count = 0; for(auto server: servers) { @@ -373,36 +374,34 @@ class ServerListProxyModel : public QSortFilterProxyModel if(entry.ping == MAX_PING) return false; - QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); + return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); } bool lessThan(const QModelIndex &left, const QModelIndex &right) const { - - bool sortByCountry = (left.column() == (int)Column::Country && right.column() == (int)Column::Country); - bool sortByPing = (left.column() == (int)Column::Ping && right.column() == (int)Column::Ping); - - if(sortByCountry) { - auto& leftEntry = model->entryById(left.row()); - auto& rightEntry = model->entryById(right.row()); - - if(leftEntry.countryCode != rightEntry.countryCode) - return QString::compare(leftEntry.countryCode, rightEntry.countryCode) < 0; - sortByPing = true; - } - - if(sortByPing) { - auto& leftEntry = model->entryById(left.row()); - auto& rightEntry = model->entryById(right.row()); - - int leftPing = std::round(leftEntry.avgPing); - int rightPing = std::round(rightEntry.avgPing); - - if(leftPing == rightPing) { - return leftEntry.port < rightEntry.port; - } - return leftPing < rightPing; - } - - QSortFilterProxyModel::lessThan(left, right); + bool sortByCountry = (left.column() == (int)Column::Country && right.column() == (int)Column::Country); + bool sortByPing = (left.column() == (int)Column::Ping && right.column() == (int)Column::Ping); + + if(sortByCountry) { + auto& leftEntry = model->entryById(left.row()); + auto& rightEntry = model->entryById(right.row()); + + if(leftEntry.countryCode != rightEntry.countryCode) + return QString::compare(leftEntry.countryCode, rightEntry.countryCode) < 0; + sortByPing = true; + } + if(sortByPing) { + auto& leftEntry = model->entryById(left.row()); + auto& rightEntry = model->entryById(right.row()); + + int leftPing = std::round(leftEntry.avgPing); + int rightPing = std::round(rightEntry.avgPing); + + if(leftPing == rightPing) { + return leftEntry.port < rightEntry.port; + } + return leftPing < rightPing; + } + + return QSortFilterProxyModel::lessThan(left, right); } }; @@ -472,13 +471,14 @@ class ServerBrowser : public QMainWindow event->ignore(); this->hide(); return; - - /* not working --> file is read only... + } + + /* not working --> file is read only... #ifdef APPINDICATOR QFile::remove(QDir::tempPath()+"/indicator_utlauncher.png"); #endif */ - } + QMainWindow::closeEvent(event); } @@ -627,7 +627,7 @@ class ServerBrowser : public QMainWindow auto about = new QAction(awesome->icon(fa::handoup), "About", this); connect(about, &QAction::triggered, [=] { - QMessageBox::about(this, "UTLauncher", "Brought to you by Damian \"Rush\" Kaczmarek from Code Charm Ltd

Servers delivered and hosted by raxxy and others. Server query code done by TimeH.

Big thanks to Epic Games for delivering us Unreal Tournament in open fashion!

Please visit Unreal Tournament forums to participate in development."); + QMessageBox::about(this, "UTLauncher", "Brought to you by Damian \"Rush\" Kaczmarek from Code Charm Ltd and other contributors:

Servers delivered and hosted by raxxy and others. Server query code done by TimeH. Splash logo made by Henrik Roysa. Icon made by Archer.

Big thanks to Epic Games for delivering us Unreal Tournament in open fashion!

Please visit Unreal Tournament forums to participate in development."); }); helpToolbar->addAction(about); @@ -642,7 +642,7 @@ class ServerBrowser : public QMainWindow auto helpAction = new QAction(awesome->icon(fa::comments), "IRC Chat", this); connect(helpAction, &QAction::triggered, [=] { - QDesktopServices::openUrl(QUrl("http://webchat.globalgamers.net/?channels=beyondunreal")); + QDesktopServices::openUrl(QUrl("http://webchat.globalgamers.net/?channels=UnrealTournament")); }); @@ -667,9 +667,11 @@ class ServerBrowser : public QMainWindow } { auto dockWidget = new QDockWidget("Currently playing", this); +#ifndef __APPLE__ dockWidget->setStyle(new iconned_dock_style(awesome->icon(fa::user, { {"scale-factor", 0.6} }), dockWidget->style() )); +#endif //auto toolbar = new QToolBar("Currently playing", this); diff --git a/utlauncher.cpp b/utlauncher.cpp index 27c86e7..8d72cbf 100644 --- a/utlauncher.cpp +++ b/utlauncher.cpp @@ -132,12 +132,12 @@ void UTLauncher::startServerBrowser() const auto serverEntry = browser->serverEntryFromAddress(url); auto launch = [=] { qDebug() << "Launching!!\n"; - QProcess::startDetached(exePath, QStringList() - #ifdef LAUNCH_WITH_UE4 - << "UnrealTournament" - #endif - << (url + (spectate?"?SpectatorOnly=1":"")) - << "-SaveToUserDir"); + QProcess::startDetached(exePath, QStringList() +#ifdef LAUNCH_WITH_UE4 + << "UnrealTournament" +#endif + << (url + (spectate?"?SpectatorOnly=1":"")) + << "-SaveToUserDir"); }; if(serverEntry) { @@ -300,10 +300,10 @@ void UTLauncher::startServerBrowser() return; } QProcess::startDetached(exePath - #ifdef LAUNCH_WITH_UE4 - , QStringList() << "UnrealTournament" << "-SaveToUserDir" - #endif - ); +#ifdef LAUNCH_WITH_UE4 + , QStringList() << "UnrealTournament" << "-SaveToUserDir" +#endif + ); }); auto runEditorAction = new QAction(awesome->icon( fa::code ),"Run Editor", this); @@ -327,37 +327,35 @@ void UTLauncher::startServerBrowser() systemTrayMenu->addAction(quitAction); systemTray.setContextMenu(systemTrayMenu); - - + // shows unity appindicator #ifdef APPINDICATOR // hide qt systemtray - not working on unity systemTray.hide(); - ShowUnityAppIndicator(); //TODO: implement appindicator + ShowUnityAppIndicator(); //TODO: implement full appindicator #endif #ifndef APPINDICATOR systemTray.show(); - connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) - { - qApp->setQuitOnLastWindowClosed(true); - runEditorAction->setVisible(hasEditorSupport()); - switch(reason) - { - case QSystemTrayIcon::Trigger: - { - if(browser->isHidden()) - { - browser->show(); - } - else - { - browser->hide(); - } - break; - } - } + connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) { + qApp->setQuitOnLastWindowClosed(true); + + runEditorAction->setVisible(hasEditorSupport()); + + switch(reason) { + + case QSystemTrayIcon::Trigger: + { + if(browser->isHidden()) { + browser->show(); + } else { + browser->hide(); + } + break; + } + + } }); #endif } \ No newline at end of file From fa1d6be446147432d866e969086c407ae7a68189 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Thu, 16 Oct 2014 17:28:22 +0200 Subject: [PATCH 10/14] now deletes tmp file on close --- serverbrowser.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/serverbrowser.h b/serverbrowser.h index afbd0bf..d1142f1 100644 --- a/serverbrowser.h +++ b/serverbrowser.h @@ -473,11 +473,11 @@ class ServerBrowser : public QMainWindow return; } - /* not working --> file is read only... - #ifdef APPINDICATOR - QFile::remove(QDir::tempPath()+"/indicator_utlauncher.png"); - #endif - */ + //not working --> file is read only... + #ifdef APPINDICATOR + QFile::remove(QDir::tempPath()+"/indicator_utlauncher.png"); + #endif + QMainWindow::closeEvent(event); } From f95a996a458070082525b4dc537b2a9571d740e3 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Thu, 16 Oct 2014 17:43:05 +0200 Subject: [PATCH 11/14] cmake will use version 2.8.12 on ubuntu --- CMakeLists.txt | 12 ++++-- CMakeLists_ubuntu.txt | 96 ------------------------------------------- README.md | 2 +- 3 files changed, 10 insertions(+), 100 deletions(-) delete mode 100644 CMakeLists_ubuntu.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 83d6c78..ab6be95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,11 @@ if(WITH_APPINDICATOR) cmake_minimum_required(VERSION 2.8.12) + project(UTLauncher) else() cmake_minimum_required(VERSION 3.0.0) cmake_policy(SET CMP0048 NEW) + project(UTLauncher VERSION 0.3.6) endif() -project(UTLauncher VERSION 0.3.6) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") include(MingwResource) @@ -85,8 +86,13 @@ else() set(BUILD_TYPE "") endif() -set(UTLauncher_VERSION "${PROJECT_VERSION}" CACHE STRING "Version number" FORCE INTERNAL) -set_version_number(UTLauncher) +if(APPINDICATOR_FOUND) + set(UTLauncher_VERSION "0.3.6" CACHE STRING "Version number" FORCE INTERNAL) + set_version_number(UTLauncher) +else() + set(UTLauncher_VERSION "${PROJECT_VERSION}" CACHE STRING "Version number" FORCE INTERNAL) + set_version_number(UTLauncher) +endif() add_definitions(-DNO_DOWNLOAD -DVERSION_MAJOR=${UTLauncher_VERSION_MAJOR} -DVERSION_MINOR=${UTLauncher_VERSION_MINOR} -DVERSION_PATCH=${UTLauncher_VERSION_PATCH}) add_executable(UTLauncher ${BUILD_TYPE} ${resources} ${rc_srcs} main.cpp utlauncher.cpp download.cpp utsplash.cpp bootstrap.cpp serverbrowser.cpp configdialog.cpp $ $) diff --git a/CMakeLists_ubuntu.txt b/CMakeLists_ubuntu.txt deleted file mode 100644 index 6d6c0da..0000000 --- a/CMakeLists_ubuntu.txt +++ /dev/null @@ -1,96 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -project(UTLauncher) - -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") -include(MingwResource) -include(Version) - -# Find includes in corresponding build directories -set(CMAKE_INCLUDE_CURRENT_DIR ON) -# Instruct CMake to run moc automatically when needed. -set(CMAKE_AUTOMOC ON) - -find_package(Qt5Widgets) -find_package(Qt5Network) -find_package(PkgConfig) -find_package(ZLIB) -#find_package(Boost COMPONENTS system REQUIRED) - -# appindicator -------------------------------------------- -if(WITH_APPINDICATOR) - pkg_check_modules(PC_APPINDICATOR REQUIRED appindicator-0.1) - pkg_check_modules(GTK2 REQUIRED gtk+-2.0) - - find_path(APPINDICATOR_INCLUDE_DIR NAMES libappindicator/app-indicator.h - HINTS ${PC_APPINDICATOR_INCLUDEDIR} ${PC_APPINDICATOR_INCLUDE_DIRS} - PATH_SUFFIXES libappindicator-0.1) - - find_library(APPINDICATOR_LIBRARY NAMES appindicator) - - include(FindPackageHandleStandardArgs) - - find_package_handle_standard_args(APPINDICATOR DEFAULT_MSG APPINDICATOR_LIBRARY APPINDICATOR_INCLUDE_DIR) - - if(APPINDICATOR_FOUND) - set(APPINDICATOR_LIBRARIES ${APPINDICATOR_LIBRARY}) - set(APPINDICATOR_INCLUDE_DIRS ${APPINDICATOR_INCLUDE_DIR}) - endif() - - mark_as_advanced(APPINDICATOR_INCLUDE_DIR APPINDICATOR_LIBRARY) -endif() -# ------------------------------------------------------------ - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") - -#pkg_check_modules(LIBTORRENT libtorrent-rasterbar) -#string (REPLACE ";" " " LIBTORRENT_CFLAGS_STR "${LIBTORRENT_CFLAGS} -DBOOST_THREAD_USE_LIB") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBTORRENT_CFLAGS_STR}") - -if(CMAKE_BUILD_TYPE MATCHES Release) -#add_definitions(-DQT_NO_DEBUG_OUTPUT) -endif() - -add_subdirectory(3rdparty) -if(APPINDICATOR_FOUND) - include_directories(${3rdparty_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${APPINDICATOR_INCLUDE_DIR}) - link_directories(${GTK2_LIBRARY_DIRS} ${APPINDICATOR_LIBRARY}) -else() - include_directories(${3rdparty_INCLUDE_DIRS}) -endif() - -qt5_add_resources(resources files.qrc flags.qrc) - -if(CMAKE_SYSTEM_NAME MATCHES Windows) -add_win32_resource(rc_srcs application.rc) -endif(CMAKE_SYSTEM_NAME MATCHES Windows) - -add_definitions(-DLAUNCH_WITH_UE4) -if(CMAKE_SYSTEM_NAME MATCHES Windows AND CMAKE_BUILD_TYPE MATCHES Release) - set(BUILD_TYPE WIN32) - #add_definitions(-DLAUNCH_WITH_UE4) -else() - set(BUILD_TYPE "") -endif() - -set(UTLauncher_VERSION "0.3.6" CACHE STRING "Version number" FORCE INTERNAL) -set_version_number(UTLauncher) - -add_definitions(-DNO_DOWNLOAD -DVERSION_MAJOR=${UTLauncher_VERSION_MAJOR} -DVERSION_MINOR=${UTLauncher_VERSION_MINOR} -DVERSION_PATCH=${UTLauncher_VERSION_PATCH}) -add_executable(UTLauncher ${BUILD_TYPE} ${resources} ${rc_srcs} main.cpp utlauncher.cpp download.cpp utsplash.cpp bootstrap.cpp serverbrowser.cpp configdialog.cpp $ $) - - -if(STATIC_BUILD_WIN32) - pkg_check_modules(QT5WIDGETS Qt5Widgets) - add_definitions(-DSTATIC_PLUGIN_WINDOWS) - target_link_libraries(UTLauncher Qt5::Widgets Qt5::QWindowsIntegrationPlugin Qt5::Network ${QT5WIDGETS_LDFLAGS} ${ZLIB_LIBRARY}) -else() - if(APPINDICATOR_FOUND) - add_definitions(-DAPPINDICATOR) - target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY} ${GTK2_LIBRARIES} ${APPINDICATOR_LIBRARY}) - else() - target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) - endif() -endif() - -install(TARGETS UTLauncher RUNTIME DESTINATION bin) diff --git a/README.md b/README.md index 35a0691..478533c 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ You need to install Qt5 base development package, libappindicator-dev, G++ compi ##### Ubuntu ``` sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev -Important: rename CMakeLists.txt to CMakeLists.txt.bak and CMakeLists_ubuntu.txt to CMakeLists.txt to allow compiling on ubuntu! +Important: Build will fail without "-DWITH_APPINDICATOR=1" ``` ##### openSUSE `sudo zypper install libqt5-qtbase-devel gcc-c++ cmake` From 7a2faa83db51f3f4ba142db1d0fb2783fb0ba8c3 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Sat, 18 Oct 2014 10:58:23 +0200 Subject: [PATCH 12/14] now based on original master --- CMakeLists.txt | 75 +++++++++++--------- README.md | 17 +++-- appindicator.h | 143 +++++++++++++++++++++++++++++++++++++++ configdialog.h | 2 + files.qrc | 1 + indicator_utlauncher.png | Bin 0 -> 14456 bytes serverbrowser.h | 5 ++ utlauncher.cpp | 13 ++++ 8 files changed, 221 insertions(+), 35 deletions(-) create mode 100644 appindicator.h create mode 100644 indicator_utlauncher.png diff --git a/CMakeLists.txt b/CMakeLists.txt index fee4070..6d6c0da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,10 @@ -cmake_minimum_required(VERSION 3.0.0) -cmake_policy(SET CMP0048 NEW) -project(UTLauncher VERSION 0.3.6) +cmake_minimum_required(VERSION 2.8.12) + +project(UTLauncher) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") include(MingwResource) include(Version) -include(DeployQt5) # For Mac # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -18,6 +17,30 @@ find_package(PkgConfig) find_package(ZLIB) #find_package(Boost COMPONENTS system REQUIRED) +# appindicator -------------------------------------------- +if(WITH_APPINDICATOR) + pkg_check_modules(PC_APPINDICATOR REQUIRED appindicator-0.1) + pkg_check_modules(GTK2 REQUIRED gtk+-2.0) + + find_path(APPINDICATOR_INCLUDE_DIR NAMES libappindicator/app-indicator.h + HINTS ${PC_APPINDICATOR_INCLUDEDIR} ${PC_APPINDICATOR_INCLUDE_DIRS} + PATH_SUFFIXES libappindicator-0.1) + + find_library(APPINDICATOR_LIBRARY NAMES appindicator) + + include(FindPackageHandleStandardArgs) + + find_package_handle_standard_args(APPINDICATOR DEFAULT_MSG APPINDICATOR_LIBRARY APPINDICATOR_INCLUDE_DIR) + + if(APPINDICATOR_FOUND) + set(APPINDICATOR_LIBRARIES ${APPINDICATOR_LIBRARY}) + set(APPINDICATOR_INCLUDE_DIRS ${APPINDICATOR_INCLUDE_DIR}) + endif() + + mark_as_advanced(APPINDICATOR_INCLUDE_DIR APPINDICATOR_LIBRARY) +endif() +# ------------------------------------------------------------ + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") #pkg_check_modules(LIBTORRENT libtorrent-rasterbar) @@ -25,11 +48,16 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBTORRENT_CFLAGS_STR}") if(CMAKE_BUILD_TYPE MATCHES Release) -add_definitions(-DQT_NO_DEBUG_OUTPUT) +#add_definitions(-DQT_NO_DEBUG_OUTPUT) endif() add_subdirectory(3rdparty) -include_directories(${3rdparty_INCLUDE_DIRS}) +if(APPINDICATOR_FOUND) + include_directories(${3rdparty_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${APPINDICATOR_INCLUDE_DIR}) + link_directories(${GTK2_LIBRARY_DIRS} ${APPINDICATOR_LIBRARY}) +else() + include_directories(${3rdparty_INCLUDE_DIRS}) +endif() qt5_add_resources(resources files.qrc flags.qrc) @@ -40,44 +68,29 @@ endif(CMAKE_SYSTEM_NAME MATCHES Windows) add_definitions(-DLAUNCH_WITH_UE4) if(CMAKE_SYSTEM_NAME MATCHES Windows AND CMAKE_BUILD_TYPE MATCHES Release) set(BUILD_TYPE WIN32) - -elseif(CMAKE_SYSTEM_NAME MATCHES Darwin) - set(BUILD_TYPE MACOSX_BUNDLE) - set(MACOSX_BUNDLE_ICON_FILE icon.icns) - set(resources ${resources} ${PROJECT_SOURCE_DIR}/icon.icns) - set_source_files_properties(icon.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") + #add_definitions(-DLAUNCH_WITH_UE4) else() set(BUILD_TYPE "") endif() -set(UTLauncher_VERSION "${PROJECT_VERSION}" CACHE STRING "Version number" FORCE INTERNAL) +set(UTLauncher_VERSION "0.3.6" CACHE STRING "Version number" FORCE INTERNAL) set_version_number(UTLauncher) add_definitions(-DNO_DOWNLOAD -DVERSION_MAJOR=${UTLauncher_VERSION_MAJOR} -DVERSION_MINOR=${UTLauncher_VERSION_MINOR} -DVERSION_PATCH=${UTLauncher_VERSION_PATCH}) add_executable(UTLauncher ${BUILD_TYPE} ${resources} ${rc_srcs} main.cpp utlauncher.cpp download.cpp utsplash.cpp bootstrap.cpp serverbrowser.cpp configdialog.cpp $ $) + if(STATIC_BUILD_WIN32) pkg_check_modules(QT5WIDGETS Qt5Widgets) add_definitions(-DSTATIC_PLUGIN_WINDOWS) target_link_libraries(UTLauncher Qt5::Widgets Qt5::QWindowsIntegrationPlugin Qt5::Network ${QT5WIDGETS_LDFLAGS} ${ZLIB_LIBRARY}) else() - target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) + if(APPINDICATOR_FOUND) + add_definitions(-DAPPINDICATOR) + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY} ${GTK2_LIBRARIES} ${APPINDICATOR_LIBRARY}) + else() + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) + endif() endif() -install(TARGETS UTLauncher BUNDLE DESTINATION . RUNTIME DESTINATION bin) - -if(APPLE) - set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/bundle") - install_qt5_executable(UTLauncher.app "cocoa") - set(CMAKE_INSTALL_PREFIX "/Applications") - set(CPACK_GENERATOR "DragNDrop") - set(CPACK_DMG_FORMAT "UDBZ") - set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}") - set(CPACK_SYSTEM_NAME "OSX") - set(CPACK_PACKAGE_VENDOR "Code Charm Ltd") - set(CPACK_PACKAGE_NAME "UTLauncher") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") - set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/icon.icns") - set(CPACK_DMG_BACKGROUND_IMAGE "${PROJECT_SOURCE_DIR}/splash.jpg") - include(CPack) -endif() +install(TARGETS UTLauncher RUNTIME DESTINATION bin) diff --git a/README.md b/README.md index 42d1393..35a0691 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,12 @@ pacman -U utlauncher-git*.pkg.tar.xz ### Build instructions #### Requirements -You need to install Qt5 base development package, G++ compiler and cmake. +You need to install Qt5 base development package, libappindicator-dev, G++ compiler and cmake. ##### Ubuntu ``` -sudo apt-add-repository ppa:ubuntu-sdk-team/ppa -sudo apt-get update -sudo apt-get install qtbase5-dev g++ cmake +sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev +Important: rename CMakeLists.txt to CMakeLists.txt.bak and CMakeLists_ubuntu.txt to CMakeLists.txt to allow compiling on ubuntu! ``` ##### openSUSE `sudo zypper install libqt5-qtbase-devel gcc-c++ cmake` @@ -45,7 +44,17 @@ cd UTLauncher git submodule update --init --recursive cd build cmake .. -DCMAKE_BUILD_TYPE=Release +``` +to build with ubuntu appindicator: +``` +cmake .. -DCMAKE_BUILD_TYPE=Release -DWITH_APPINDICATOR=1 +``` + +``` make +``` +optional: +``` sudo make install ``` diff --git a/appindicator.h b/appindicator.h new file mode 100644 index 0000000..56b944f --- /dev/null +++ b/appindicator.h @@ -0,0 +1,143 @@ +#ifndef APPINDICATOR_H +#define APPINDICATOR_H + +#undef signals +extern "C" { + + #include + #include + + void serverlistIndicator(GtkMenu *, gpointer); + void runutIndicator(GtkMenu *, gpointer); + void runeditorIndicator(GtkMenu *, gpointer); + void quitIndicator(GtkMenu *, gpointer); +} +#define signals public +/* +void UTLauncher::startServerBrowser() + systemTrayMenu->addAction(showBrowser); + systemTrayMenu->addSeparator(); + systemTrayMenu->addAction(runUTAction); + systemTrayMenu->addAction(runEditorAction); + systemTrayMenu->addSeparator(); + systemTrayMenu->addAction(quitAction); +*/ + + +void serverlistIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + //UTLauncher *self = static_cast(data); + + //self->startServerBrowser().showBrowser.exec(); + //showBrowser +} + +void runutIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + //runUTAction +} + +void runeditorIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + //runEditorAction +} + +void quitIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + QApplication *self = static_cast(data); + + self->quit(); +} + +void ShowUnityAppIndicator() +{ + AppIndicator *indicator; + GtkWidget *menu, *quit_item, *serverlist_item, *runut_item, *runeditor_item; + + menu = gtk_menu_new(); + + serverlist_item = gtk_menu_item_new_with_label("Server List"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), serverlist_item); + g_signal_connect(serverlist_item, "activate", + G_CALLBACK(serverlistIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(serverlist_item); + + runut_item = gtk_menu_item_new_with_label("Run UT"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), runut_item); + g_signal_connect(runut_item, "activate", + G_CALLBACK(runutIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(runut_item); + + runeditor_item = gtk_menu_item_new_with_label("Run Editor"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), runeditor_item); + g_signal_connect(runeditor_item, "activate", + G_CALLBACK(runeditorIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(runeditor_item); + + quit_item = gtk_menu_item_new_with_label("Quit"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit_item); + g_signal_connect(quit_item, "activate", + G_CALLBACK(quitIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(quit_item); + + +/* +auto showBrowser = new QAction(awesome->icon(fa::listalt), "Server List", this); + connect(showBrowser, &QAction::triggered, [=]() { + browser->showNormal(); + browser->raise(); + browser->activateWindow(); + }); + + auto runUTAction = new QAction(awesome->icon( fa::gamepad ),"Run UT", this); + connect(runUTAction, &QAction::triggered, [=]() { + QString exePath = bootstrap.programExePath(); + if(!exePath.length()) { + browser->show(); + openSettings(); + return; + } + QProcess::startDetached(exePath); + }); + + auto runEditorAction = new QAction(awesome->icon( fa::code ),"Run Editor", this); + connect(runEditorAction, &QAction::triggered, [=]() { + QString editorPath = bootstrap.editorExePath(); + QString projectPath = bootstrap.projectPath(); + QProcess::startDetached(editorPath, QStringList() << projectPath); + }); +*/ + indicator = app_indicator_new( + "UTLauncher", //id + "indicator_utlauncher", //icon default:indicator-messages + APP_INDICATOR_CATEGORY_APPLICATION_STATUS //category + ); + + QFile tempfile; + tempfile.copy(":/indicator_utlauncher.png", QDir::tempPath()+"/indicator_utlauncher.png"); + // not working... + //tempfile.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser | QFile::ReadOther | QFile::WriteOther); + + app_indicator_set_icon_theme_path(indicator, "/tmp"); + app_indicator_set_icon_full(indicator, "indicator_utlauncher", ""); + + app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE); + app_indicator_set_menu(indicator, GTK_MENU(menu)); +} +#endif diff --git a/configdialog.h b/configdialog.h index 042d017..8fd7afa 100644 --- a/configdialog.h +++ b/configdialog.h @@ -291,6 +291,7 @@ class ConfigDialog : public QDialog locationsButton->setSizeHint(QSize(80, 64)); buttonMap[locationsButton] = 0; + #ifndef APPINDICATOR auto uiButton = new QListWidgetItem(contentsWidget); uiButton->setIcon(awesome->icon(fa::desktop)); uiButton->setText(tr("UI")); @@ -298,6 +299,7 @@ class ConfigDialog : public QDialog uiButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); uiButton->setSizeHint(QSize(80, 64)); buttonMap[uiButton] = 1; + #endif connect(contentsWidget, diff --git a/files.qrc b/files.qrc index ff9fec4..bb89979 100644 --- a/files.qrc +++ b/files.qrc @@ -2,5 +2,6 @@ splash.jpg icon.png + indicator_utlauncher.png \ No newline at end of file diff --git a/indicator_utlauncher.png b/indicator_utlauncher.png new file mode 100644 index 0000000000000000000000000000000000000000..f1759e0b600bd106230ff953cd0aebeb6a14ac22 GIT binary patch literal 14456 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 GjfO2IQI8p_rbE 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 KMNUMnLSTZRdu#&$ literal 0 HcmV?d00001 diff --git a/serverbrowser.h b/serverbrowser.h index 0473e2a..7f35da1 100644 --- a/serverbrowser.h +++ b/serverbrowser.h @@ -472,6 +472,11 @@ class ServerBrowser : public QMainWindow this->hide(); return; } + + #ifdef APPINDICATOR + QFile::remove(QDir::tempPath()+"/indicator_utlauncher.png"); + #endif + QMainWindow::closeEvent(event); } diff --git a/utlauncher.cpp b/utlauncher.cpp index b4b3d8e..8abf650 100644 --- a/utlauncher.cpp +++ b/utlauncher.cpp @@ -7,6 +7,10 @@ #include "configdialog.h" #include +ifdef APPINDICATOR +#include "appindicator.h" +#endif + QtAwesome* awesome; QColor UTLauncher::iconColor() const { @@ -323,6 +327,14 @@ void UTLauncher::startServerBrowser() systemTrayMenu->addAction(quitAction); systemTray.setContextMenu(systemTrayMenu); + // shows unity appindicator + #ifdef APPINDICATOR + // hide qt systemtray - not working on unity + systemTray.hide(); + ShowUnityAppIndicator(); //TODO: implement full appindicator + #endif + + #ifndef APPINDICATOR systemTray.show(); connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) { @@ -344,5 +356,6 @@ void UTLauncher::startServerBrowser() } }); + #endif } \ No newline at end of file From 51b62e7d2a0e8d6e67fcd5e3d387f2fee56660e8 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Sat, 18 Oct 2014 11:15:09 +0200 Subject: [PATCH 13/14] now based on original master --- CMakeLists.txt | 97 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d6c0da..ab6be95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,18 @@ -cmake_minimum_required(VERSION 2.8.12) - -project(UTLauncher) +if(WITH_APPINDICATOR) + cmake_minimum_required(VERSION 2.8.12) + project(UTLauncher) +else() + cmake_minimum_required(VERSION 3.0.0) + cmake_policy(SET CMP0048 NEW) + project(UTLauncher VERSION 0.3.6) +endif() set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") include(MingwResource) include(Version) +if(APPLE) + include(DeployQt5) # For Mac +endif() # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -17,27 +25,27 @@ find_package(PkgConfig) find_package(ZLIB) #find_package(Boost COMPONENTS system REQUIRED) -# appindicator -------------------------------------------- +# Ubuntu Appindicator GTK2-------------------------------------------- if(WITH_APPINDICATOR) - pkg_check_modules(PC_APPINDICATOR REQUIRED appindicator-0.1) - pkg_check_modules(GTK2 REQUIRED gtk+-2.0) + pkg_check_modules(PC_APPINDICATOR REQUIRED appindicator-0.1) + pkg_check_modules(GTK2 REQUIRED gtk+-2.0) - find_path(APPINDICATOR_INCLUDE_DIR NAMES libappindicator/app-indicator.h - HINTS ${PC_APPINDICATOR_INCLUDEDIR} ${PC_APPINDICATOR_INCLUDE_DIRS} - PATH_SUFFIXES libappindicator-0.1) + find_path(APPINDICATOR_INCLUDE_DIR NAMES libappindicator/app-indicator.h + HINTS ${PC_APPINDICATOR_INCLUDEDIR} ${PC_APPINDICATOR_INCLUDE_DIRS} + PATH_SUFFIXES libappindicator-0.1) - find_library(APPINDICATOR_LIBRARY NAMES appindicator) + find_library(APPINDICATOR_LIBRARY NAMES appindicator) - include(FindPackageHandleStandardArgs) + include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(APPINDICATOR DEFAULT_MSG APPINDICATOR_LIBRARY APPINDICATOR_INCLUDE_DIR) + find_package_handle_standard_args(APPINDICATOR DEFAULT_MSG APPINDICATOR_LIBRARY APPINDICATOR_INCLUDE_DIR) - if(APPINDICATOR_FOUND) - set(APPINDICATOR_LIBRARIES ${APPINDICATOR_LIBRARY}) - set(APPINDICATOR_INCLUDE_DIRS ${APPINDICATOR_INCLUDE_DIR}) - endif() + if(APPINDICATOR_FOUND) + set(APPINDICATOR_LIBRARIES ${APPINDICATOR_LIBRARY}) + set(APPINDICATOR_INCLUDE_DIRS ${APPINDICATOR_INCLUDE_DIR}) + endif() - mark_as_advanced(APPINDICATOR_INCLUDE_DIR APPINDICATOR_LIBRARY) + mark_as_advanced(APPINDICATOR_INCLUDE_DIR APPINDICATOR_LIBRARY) endif() # ------------------------------------------------------------ @@ -48,49 +56,74 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBTORRENT_CFLAGS_STR}") if(CMAKE_BUILD_TYPE MATCHES Release) -#add_definitions(-DQT_NO_DEBUG_OUTPUT) + add_definitions(-DQT_NO_DEBUG_OUTPUT) endif() add_subdirectory(3rdparty) if(APPINDICATOR_FOUND) - include_directories(${3rdparty_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${APPINDICATOR_INCLUDE_DIR}) - link_directories(${GTK2_LIBRARY_DIRS} ${APPINDICATOR_LIBRARY}) + include_directories(${3rdparty_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${APPINDICATOR_INCLUDE_DIR}) + link_directories(${GTK2_LIBRARY_DIRS} ${APPINDICATOR_LIBRARY}) else() - include_directories(${3rdparty_INCLUDE_DIRS}) + include_directories(${3rdparty_INCLUDE_DIRS}) endif() qt5_add_resources(resources files.qrc flags.qrc) if(CMAKE_SYSTEM_NAME MATCHES Windows) -add_win32_resource(rc_srcs application.rc) + add_win32_resource(rc_srcs application.rc) endif(CMAKE_SYSTEM_NAME MATCHES Windows) add_definitions(-DLAUNCH_WITH_UE4) if(CMAKE_SYSTEM_NAME MATCHES Windows AND CMAKE_BUILD_TYPE MATCHES Release) set(BUILD_TYPE WIN32) - #add_definitions(-DLAUNCH_WITH_UE4) + +elseif(CMAKE_SYSTEM_NAME MATCHES Darwin) + set(BUILD_TYPE MACOSX_BUNDLE) + set(MACOSX_BUNDLE_ICON_FILE icon.icns) + set(resources ${resources} ${PROJECT_SOURCE_DIR}/icon.icns) + set_source_files_properties(icon.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") else() set(BUILD_TYPE "") endif() -set(UTLauncher_VERSION "0.3.6" CACHE STRING "Version number" FORCE INTERNAL) -set_version_number(UTLauncher) +if(APPINDICATOR_FOUND) + set(UTLauncher_VERSION "0.3.6" CACHE STRING "Version number" FORCE INTERNAL) + set_version_number(UTLauncher) +else() + set(UTLauncher_VERSION "${PROJECT_VERSION}" CACHE STRING "Version number" FORCE INTERNAL) + set_version_number(UTLauncher) +endif() add_definitions(-DNO_DOWNLOAD -DVERSION_MAJOR=${UTLauncher_VERSION_MAJOR} -DVERSION_MINOR=${UTLauncher_VERSION_MINOR} -DVERSION_PATCH=${UTLauncher_VERSION_PATCH}) add_executable(UTLauncher ${BUILD_TYPE} ${resources} ${rc_srcs} main.cpp utlauncher.cpp download.cpp utsplash.cpp bootstrap.cpp serverbrowser.cpp configdialog.cpp $ $) - if(STATIC_BUILD_WIN32) pkg_check_modules(QT5WIDGETS Qt5Widgets) add_definitions(-DSTATIC_PLUGIN_WINDOWS) target_link_libraries(UTLauncher Qt5::Widgets Qt5::QWindowsIntegrationPlugin Qt5::Network ${QT5WIDGETS_LDFLAGS} ${ZLIB_LIBRARY}) else() if(APPINDICATOR_FOUND) - add_definitions(-DAPPINDICATOR) - target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY} ${GTK2_LIBRARIES} ${APPINDICATOR_LIBRARY}) - else() - target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) - endif() + add_definitions(-DAPPINDICATOR) + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY} ${GTK2_LIBRARIES} ${APPINDICATOR_LIBRARY}) + else() + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) + endif() endif() -install(TARGETS UTLauncher RUNTIME DESTINATION bin) +install(TARGETS UTLauncher BUNDLE DESTINATION . RUNTIME DESTINATION bin) + +if(APPLE) + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/bundle") + install_qt5_executable(UTLauncher.app "cocoa") + set(CMAKE_INSTALL_PREFIX "/Applications") + set(CPACK_GENERATOR "DragNDrop") + set(CPACK_DMG_FORMAT "UDBZ") + set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}") + set(CPACK_SYSTEM_NAME "OSX") + set(CPACK_PACKAGE_VENDOR "Code Charm Ltd") + set(CPACK_PACKAGE_NAME "UTLauncher") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") + set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/icon.icns") + set(CPACK_DMG_BACKGROUND_IMAGE "${PROJECT_SOURCE_DIR}/splash.jpg") + include(CPack) +endif() From 6800c654efa55dcd49ffb47090a1b7c90ea0e743 Mon Sep 17 00:00:00 2001 From: vincent-t Date: Wed, 5 Nov 2014 21:39:40 +0100 Subject: [PATCH 14/14] Fixing stupid commit... --- README.md | 4 ---- configdialog.h | 7 ------- serverbrowser.h | 7 ------- utlauncher.cpp | 13 +------------ 4 files changed, 1 insertion(+), 30 deletions(-) diff --git a/README.md b/README.md index 1bbaeff..478533c 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,7 @@ You need to install Qt5 base development package, libappindicator-dev, G++ compi ##### Ubuntu ``` sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev -<<<<<<< HEAD Important: Build will fail without "-DWITH_APPINDICATOR=1" -======= -Important: rename CMakeLists.txt to CMakeLists.txt.bak and CMakeLists_ubuntu.txt to CMakeLists.txt to allow compiling on ubuntu! ->>>>>>> origin/master_newest ``` ##### openSUSE `sudo zypper install libqt5-qtbase-devel gcc-c++ cmake` diff --git a/configdialog.h b/configdialog.h index 6d1f135..a6371aa 100644 --- a/configdialog.h +++ b/configdialog.h @@ -291,10 +291,7 @@ class ConfigDialog : public QDialog locationsButton->setSizeHint(QSize(80, 64)); buttonMap[locationsButton] = 0; -<<<<<<< HEAD //only show when appindicator is disabled -======= ->>>>>>> origin/master_newest #ifndef APPINDICATOR auto uiButton = new QListWidgetItem(contentsWidget); uiButton->setIcon(awesome->icon(fa::desktop)); @@ -304,10 +301,6 @@ class ConfigDialog : public QDialog uiButton->setSizeHint(QSize(80, 64)); buttonMap[uiButton] = 1; #endif -<<<<<<< HEAD -======= - ->>>>>>> origin/master_newest connect(contentsWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), diff --git a/serverbrowser.h b/serverbrowser.h index cbf37e2..4f33b3a 100644 --- a/serverbrowser.h +++ b/serverbrowser.h @@ -473,17 +473,10 @@ class ServerBrowser : public QMainWindow return; } -<<<<<<< HEAD //not working --> file is read only... #ifdef APPINDICATOR QFile::remove(QDir::tempPath()+"/indicator_utlauncher.png"); #endif - -======= - #ifdef APPINDICATOR - QFile::remove(QDir::tempPath()+"/indicator_utlauncher.png"); - #endif ->>>>>>> origin/master_newest QMainWindow::closeEvent(event); } diff --git a/utlauncher.cpp b/utlauncher.cpp index aee5e0a..dc5b655 100644 --- a/utlauncher.cpp +++ b/utlauncher.cpp @@ -7,11 +7,7 @@ #include "configdialog.h" #include -<<<<<<< HEAD #ifdef APPINDICATOR -======= -ifdef APPINDICATOR ->>>>>>> origin/master_newest #include "appindicator.h" #endif @@ -331,10 +327,7 @@ void UTLauncher::startServerBrowser() systemTrayMenu->addAction(quitAction); systemTray.setContextMenu(systemTrayMenu); -<<<<<<< HEAD - -======= ->>>>>>> origin/master_newest + // shows unity appindicator #ifdef APPINDICATOR // hide qt systemtray - not working on unity @@ -365,8 +358,4 @@ void UTLauncher::startServerBrowser() } }); #endif -<<<<<<< HEAD -======= - ->>>>>>> origin/master_newest } \ No newline at end of file