Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Donald Haase
Cockatrice
Commits
66fda086
Commit
66fda086
authored
Dec 28, 2015
by
Michael Milton
Browse files
Client update implementation
parent
36c3536e
Changes
10
Hide whitespace changes
Inline
Side-by-side
cmake/createversionfile.cmake
View file @
66fda086
...
...
@@ -2,8 +2,10 @@ set(VERSION_STRING_CPP "${PROJECT_BINARY_DIR}/version_string.cpp")
set
(
VERSION_STRING_H
"
${
PROJECT_BINARY_DIR
}
/version_string.h"
)
INCLUDE_DIRECTORIES
(
${
PROJECT_BINARY_DIR
}
)
set
(
hstring
"extern const char *VERSION_STRING
\;\n
"
)
set
(
cppstring
"const char * VERSION_STRING =
\"
${
PROJECT_VERSION_FRIENDLY
}
\"\;\n
"
)
set
(
hstring
"extern const char *VERSION_STRING
\;
extern const char *VERSION_DATE
\;\n
"
)
set
(
cppstring
"const char *VERSION_STRING =
\"
${
PROJECT_VERSION_FRIENDLY
}
\"\;
const char *VERSION_DATE =
\"
${
GIT_COMMIT_DATE_FRIENDLY
}
\"\;\n
"
)
file
(
WRITE
${
PROJECT_BINARY_DIR
}
/version_string.cpp.txt
${
cppstring
}
)
file
(
WRITE
${
PROJECT_BINARY_DIR
}
/version_string.h.txt
${
hstring
}
)
...
...
cockatrice/CMakeLists.txt
View file @
66fda086
...
...
@@ -16,7 +16,8 @@ SET(cockatrice_SOURCES
src/dlg_edit_tokens.cpp
src/dlg_edit_user.cpp
src/dlg_register.cpp
src/abstractclient.cpp
src/dlg_update.cpp
src/abstractclient.cpp
src/remoteclient.cpp
src/main.cpp
src/window_main.cpp
...
...
@@ -107,6 +108,8 @@ SET(cockatrice_SOURCES
src/settings/messagesettings.cpp
src/settings/gamefilterssettings.cpp
src/settings/layoutssettings.cpp
src/update_checker.cpp
src/update_downloader.cpp
${
VERSION_STRING_CPP
}
)
...
...
cockatrice/src/dlg_update.cpp
0 → 100644
View file @
66fda086
#define HUMAN_DOWNLOAD_URL "https://bintray.com/cockatrice/Cockatrice/Cockatrice/_latestVersion"
#define API_DOWNLOAD_BASE_URL "https://dl.bintray.com/cockatrice/Cockatrice/"
#define DATE_LENGTH 10
#define MAX_DATE_LENGTH 100
#define SHORT_SHA1_HASH_LENGTH 7
#include
<QtNetwork>
#include
<QProgressDialog>
#include
<QDesktopServices>
#include
<QMessageBox>
#include
<QVBoxLayout>
#include
<QDialogButtonBox>
#include
<QPushButton>
#include
<QLabel>
#include
<QProgressBar>
#include
<QApplication>
#include
"dlg_update.h"
#include
"window_main.h"
DlgUpdate
::
DlgUpdate
(
QWidget
*
parent
)
:
QDialog
(
parent
)
{
//Handle layout
text
=
new
QLabel
(
this
);
progress
=
new
QProgressBar
(
this
);
QDialogButtonBox
*
buttonBox
=
new
QDialogButtonBox
(
this
);
ok
=
new
QPushButton
(
"Ok"
,
this
);
manualDownload
=
new
QPushButton
(
"Update Anyway"
,
this
);
enableUpdateButton
(
false
);
//Unless we know there's an update available, you can't install
gotoDownload
=
new
QPushButton
(
"Open Download Page"
,
this
);
buttonBox
->
addButton
(
manualDownload
,
QDialogButtonBox
::
ActionRole
);
buttonBox
->
addButton
(
gotoDownload
,
QDialogButtonBox
::
ActionRole
);
buttonBox
->
addButton
(
ok
,
QDialogButtonBox
::
AcceptRole
);
connect
(
gotoDownload
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
gotoDownloadPage
()));
connect
(
manualDownload
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
downloadUpdate
()));
connect
(
ok
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
closeDialog
()));
QVBoxLayout
*
parentLayout
=
new
QVBoxLayout
(
this
);
parentLayout
->
addWidget
(
text
);
parentLayout
->
addWidget
(
progress
);
parentLayout
->
addWidget
(
buttonBox
);
setLayout
(
parentLayout
);
//Check for SSL (this probably isn't necessary)
if
(
!
QSslSocket
::
supportsSsl
())
{
enableUpdateButton
(
false
);
QMessageBox
::
critical
(
this
,
tr
(
"Error"
),
tr
(
"Cockatrice was not built with SSL support, so cannot download updates! "
"Please visit the download page and update manually."
));
}
//Initialize the checker and downloader class
uDownloader
=
new
UpdateDownloader
(
this
);
connect
(
uDownloader
,
SIGNAL
(
downloadSuccessful
(
QUrl
)),
this
,
SLOT
(
downloadSuccessful
(
QUrl
)));
connect
(
uDownloader
,
SIGNAL
(
progressMade
(
qint64
,
qint64
)),
this
,
SLOT
(
downloadProgressMade
(
qint64
,
qint64
)));
connect
(
uDownloader
,
SIGNAL
(
error
(
QString
)),
this
,
SLOT
(
downloadError
(
QString
)));
uChecker
=
new
UpdateChecker
(
this
);
connect
(
uChecker
,
SIGNAL
(
finishedCheck
(
bool
,
bool
,
QVariantMap
*
)),
this
,
SLOT
(
finishedUpdateCheck
(
bool
,
bool
,
QVariantMap
*
)));
connect
(
uChecker
,
SIGNAL
(
error
(
QString
)),
this
,
SLOT
(
updateCheckError
(
QString
)));
//Check for updates
beginUpdateCheck
();
}
void
DlgUpdate
::
closeDialog
()
{
accept
();
}
void
DlgUpdate
::
gotoDownloadPage
()
{
QUrl
openUrl
(
HUMAN_DOWNLOAD_URL
);
QDesktopServices
::
openUrl
(
openUrl
);
}
void
DlgUpdate
::
downloadUpdate
()
{
setLabel
(
"Downloading update..."
);
uDownloader
->
beginDownload
(
updateUrl
);
}
void
DlgUpdate
::
beginUpdateCheck
()
{
progress
->
setMinimum
(
0
);
progress
->
setMaximum
(
0
);
setLabel
(
"Checking for updates..."
);
uChecker
->
check
();
}
void
DlgUpdate
::
finishedUpdateCheck
(
bool
needToUpdate
,
bool
isCompatible
,
QVariantMap
*
build
)
{
QString
commitHash
,
commitDate
;
//Update the UI to say we've finished
progress
->
setMaximum
(
100
);
setLabel
(
"Finished checking for updates."
);
//If there are no available builds, then they can't auto update.
enableUpdateButton
(
isCompatible
);
//If there is an update, save its URL and work out its name
if
(
isCompatible
)
{
QString
endUrl
=
(
*
build
)[
"path"
].
toString
();
updateUrl
=
API_DOWNLOAD_BASE_URL
+
endUrl
;
commitHash
=
(
*
build
)[
"sha1"
].
toString
().
left
(
SHORT_SHA1_HASH_LENGTH
);
commitDate
=
(
*
build
)[
"created"
].
toString
().
remove
(
DATE_LENGTH
,
MAX_DATE_LENGTH
);
}
//Give the user the appropriate message
if
(
needToUpdate
)
{
if
(
isCompatible
)
{
QMessageBox
::
StandardButton
reply
;
reply
=
QMessageBox
::
question
(
this
,
"Update Available"
,
"A new build (commit "
+
commitHash
+
") from "
+
commitDate
+
" is available. Download?"
,
QMessageBox
::
Yes
|
QMessageBox
::
No
);
if
(
reply
==
QMessageBox
::
Yes
)
downloadUpdate
();
}
else
{
QMessageBox
::
information
(
this
,
"Cockatrice Update"
,
tr
(
"Your version of Cockatrice is out of date, but there are no packages"
" available for your operating system. You may have to use a developer build or build from source"
" yourself. Please visit the download page."
));
}
}
else
{
//If there's no need to update, tell them that. However we still allow them to run the
//downloader themselves if there's a compatible build
QMessageBox
::
information
(
this
,
tr
(
"Cockatrice Update"
),
tr
(
"Your version of Cockatrice is up to date."
));
}
}
void
DlgUpdate
::
enableUpdateButton
(
bool
enable
)
{
manualDownload
->
setEnabled
(
enable
);
}
void
DlgUpdate
::
setLabel
(
QString
newText
)
{
text
->
setText
(
newText
);
}
void
DlgUpdate
::
updateCheckError
(
QString
errorString
)
{
setLabel
(
"Error"
);
QMessageBox
::
critical
(
this
,
tr
(
"Update Error"
),
"An error occurred while checking for updates: "
+
errorString
);
}
void
DlgUpdate
::
downloadError
(
QString
errorString
)
{
setLabel
(
"Error"
);
QMessageBox
::
critical
(
this
,
tr
(
"Update Error"
),
"An error occurred while downloading an update: "
+
errorString
);
}
void
DlgUpdate
::
downloadSuccessful
(
QUrl
filepath
)
{
setLabel
(
"Installing..."
);
//Try to open the installer. If it opens, quit Cockatrice
if
(
QDesktopServices
::
openUrl
(
filepath
))
{
QMetaObject
::
invokeMethod
((
MainWindow
*
)
parent
(),
"close"
,
Qt
::
QueuedConnection
);
close
();
}
else
{
setLabel
(
"Error"
);
QMessageBox
::
critical
(
this
,
tr
(
"Update Error"
),
"Unable to open the installer. You might be able to manually update"
" by closing Cockatrice and running the installer at "
+
filepath
.
toLocalFile
()
+
"."
);
}
}
void
DlgUpdate
::
downloadProgressMade
(
qint64
bytesRead
,
qint64
totalBytes
)
{
progress
->
setMaximum
(
totalBytes
);
progress
->
setValue
(
bytesRead
);
}
cockatrice/src/dlg_update.h
0 → 100644
View file @
66fda086
#ifndef DLG_UPDATE_H
#define DLG_UPDATE_H
#include
<QtNetwork>
#include
<QProgressDialog>
#include
"update_checker.h"
#include
"update_downloader.h"
class
DlgUpdate
:
public
QDialog
{
Q_OBJECT
public:
DlgUpdate
(
QWidget
*
parent
);
private
slots
:
void
finishedUpdateCheck
(
bool
needToUpdate
,
bool
isCompatible
,
QVariantMap
*
build
);
void
gotoDownloadPage
();
void
downloadUpdate
();
void
updateCheckError
(
QString
errorString
);
void
downloadSuccessful
(
QUrl
filepath
);
void
downloadProgressMade
(
qint64
bytesRead
,
qint64
totalBytes
);
void
downloadError
(
QString
errorString
);
void
closeDialog
();
private:
QUrl
updateUrl
;
void
enableUpdateButton
(
bool
enable
);
void
beginUpdateCheck
();
void
setLabel
(
QString
text
);
QLabel
*
text
;
QProgressBar
*
progress
;
QPushButton
*
manualDownload
,
*
gotoDownload
,
*
ok
;
QPushButton
*
cancel
;
UpdateChecker
*
uChecker
;
UpdateDownloader
*
uDownloader
;
};
#endif
cockatrice/src/update_checker.cpp
0 → 100644
View file @
66fda086
//
// Created by miguel on 28/12/15.
//
#include
<algorithm>
#include
<QMessageBox>
#include
"update_checker.h"
#include
"version_string.h"
#include
"qt-json/json.h"
#define LATEST_FILES_URL "https://api.bintray.com/packages/cockatrice/Cockatrice/Cockatrice/files"
UpdateChecker
::
UpdateChecker
(
QObject
*
parent
)
:
QObject
(
parent
){
//Parse the commit date. We'll use this to check for new versions
//We know the format because it's based on `git log` which is documented here:
// https://git-scm.com/docs/git-log#_commit_formatting
buildDate
=
QDate
::
fromString
(
VERSION_DATE
,
"yyyy-MM-dd"
);
latestFilesUrl
=
QUrl
(
LATEST_FILES_URL
);
response
=
NULL
;
netMan
=
new
QNetworkAccessManager
(
this
);
build
=
NULL
;
}
UpdateChecker
::~
UpdateChecker
()
{
delete
build
;
}
void
UpdateChecker
::
check
()
{
response
=
netMan
->
get
(
QNetworkRequest
(
latestFilesUrl
));
connect
(
response
,
SIGNAL
(
finished
()),
this
,
SLOT
(
fileListFinished
()));
}
#if defined(Q_OS_OSX)
bool
UpdateChecker
::
downloadMatchesCurrentOS
(
QVariant
build
)
{
return
build
.
toMap
()[
"name"
]
.
toString
()
.
contains
(
"osx"
);
}
#elif defined(Q_OS_WIN)
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
bool
UpdateChecker
::
downloadMatchesCurrentOS
(
QVariant
build
)
{
return
build
.
toMap
()[
"name"
]
.
toString
()
.
contains
(
"qt5.exe"
);
}
#else
bool
UpdateChecker
::
downloadMatchesCurrentOS
(
QVariant
build
)
{
return
build
.
toMap
()[
"name"
]
.
toString
()
.
contains
(
"qt4.exe"
);
}
#endif
#else
bool
UpdateChecker
::
downloadMatchesCurrentOS
(
QVariant
)
{
//If the OS doesn't fit one of the above #defines, then it will never match
return
false
;
}
#endif
QDate
UpdateChecker
::
dateFromBuild
(
QVariant
build
)
{
QString
formatString
=
"yyyy-MM-dd"
;
QString
dateString
=
build
.
toMap
()[
"date"
].
toString
();
dateString
=
dateString
.
remove
(
formatString
.
length
(),
dateString
.
length
());
return
QDate
::
fromString
(
dateString
,
formatString
);
}
QDate
UpdateChecker
::
findOldestBuild
(
QVariantList
allBuilds
)
{
//Map the build array into an array of dates
std
::
vector
<
QDate
>
dateArray
(
allBuilds
.
size
());
std
::
transform
(
allBuilds
.
begin
(),
allBuilds
.
end
(),
dateArray
.
begin
(),
dateFromBuild
);
//Return the first date
return
*
std
::
min_element
(
dateArray
.
begin
(),
dateArray
.
end
());
}
QVariantMap
*
UpdateChecker
::
findCompatibleBuild
(
QVariantList
allBuilds
)
{
QVariantList
::
iterator
result
=
std
::
find_if
(
allBuilds
.
begin
(),
allBuilds
.
end
(),
downloadMatchesCurrentOS
);
//If there is no compatible version, return NULL
if
(
result
==
allBuilds
.
end
())
return
NULL
;
else
{
QVariantMap
*
ret
=
new
QVariantMap
;
*
ret
=
(
*
result
).
toMap
();
return
ret
;
}
}
void
UpdateChecker
::
fileListFinished
()
{
try
{
QVariantList
builds
=
QtJson
::
Json
::
parse
(
response
->
readAll
()).
toList
();
build
=
findCompatibleBuild
(
builds
);
QDate
bintrayBuildDate
=
findOldestBuild
(
builds
);
bool
needToUpdate
=
bintrayBuildDate
>
buildDate
;
bool
compatibleVersion
=
build
!=
NULL
;
emit
finishedCheck
(
needToUpdate
,
compatibleVersion
,
build
);
}
catch
(
const
std
::
exception
&
exc
){
emit
error
(
exc
.
what
());
}
}
cockatrice/src/update_checker.h
0 → 100644
View file @
66fda086
//
// Created by miguel on 28/12/15.
//
#ifndef COCKATRICE_UPDATECHECKER_H
#define COCKATRICE_UPDATECHECKER_H
#include
<QObject>
#include
<QUrl>
#include
<QDate>
#include
<QtNetwork>
class
UpdateChecker
:
public
QObject
{
Q_OBJECT
public:
UpdateChecker
(
QObject
*
parent
);
~
UpdateChecker
();
void
check
();
signals:
void
finishedCheck
(
bool
needToUpdate
,
bool
isCompatible
,
QVariantMap
*
build
);
void
error
(
QString
errorString
);
private:
static
QVariantMap
*
findCompatibleBuild
();
static
QDate
findOldestBuild
(
QVariantList
allBuilds
);
static
QDate
dateFromBuild
(
QVariant
build
);
static
QVariantMap
*
findCompatibleBuild
(
QVariantList
allBuilds
);
static
bool
downloadMatchesCurrentOS
(
QVariant
build
);
QVariantMap
*
build
;
QUrl
latestFilesUrl
;
QDate
buildDate
;
QNetworkAccessManager
*
netMan
;
QNetworkReply
*
response
;
private
slots
:
void
fileListFinished
();
};
#endif //COCKATRICE_UPDATECHECKER_H
cockatrice/src/update_downloader.cpp
0 → 100644
View file @
66fda086
#include
<QUrl>
#include
"update_downloader.h"
UpdateDownloader
::
UpdateDownloader
(
QObject
*
parent
)
:
QObject
(
parent
)
{
netMan
=
new
QNetworkAccessManager
(
this
);
}
void
UpdateDownloader
::
beginDownload
(
QUrl
downloadUrl
)
{
//Save the original URL because we need it for the filename
if
(
originalUrl
.
isEmpty
())
originalUrl
=
downloadUrl
;
response
=
netMan
->
get
(
QNetworkRequest
(
downloadUrl
));
connect
(
response
,
SIGNAL
(
finished
()),
this
,
SLOT
(
fileFinished
()));
connect
(
response
,
SIGNAL
(
readyRead
()),
this
,
SLOT
(
fileReadyRead
()));
connect
(
response
,
SIGNAL
(
downloadProgress
(
qint64
,
qint64
)),
this
,
SLOT
(
downloadProgress
(
qint64
,
qint64
)));
connect
(
response
,
SIGNAL
(
error
(
QNetworkReply
::
NetworkError
)),
this
,
SLOT
(
downloadError
(
QNetworkReply
::
NetworkError
)));
}
void
UpdateDownloader
::
downloadError
(
QNetworkReply
::
NetworkError
)
{
emit
error
(
response
->
errorString
().
toUtf8
());
}
void
UpdateDownloader
::
fileFinished
()
{
//If we finished but there's a redirect, follow it
QVariant
redirect
=
response
->
attribute
(
QNetworkRequest
::
RedirectionTargetAttribute
);
if
(
!
redirect
.
isNull
())
{
beginDownload
(
redirect
.
toUrl
());
return
;
}
//Handle any errors we had
if
(
response
->
error
())
{
emit
error
(
response
->
errorString
());
return
;
}
//Work out the file name of the download
QString
fileName
=
QDir
::
temp
().
path
()
+
QDir
::
separator
()
+
originalUrl
.
toString
().
section
(
'/'
,
-
1
);
//Save the build in a temporary directory
QFile
file
(
fileName
);
if
(
!
file
.
open
(
QIODevice
::
WriteOnly
))
{
emit
error
(
"Could not open the file for reading."
);
return
;
}
file
.
write
(
response
->
readAll
());
file
.
close
();
//Emit the success signal with a URL to the download file
emit
downloadSuccessful
(
QUrl
::
fromLocalFile
(
fileName
));
}
void
UpdateDownloader
::
downloadProgress
(
qint64
bytesRead
,
qint64
totalBytes
)
{
emit
progressMade
(
bytesRead
,
totalBytes
);
}
cockatrice/src/update_downloader.h
0 → 100644
View file @
66fda086
//
// Created by miguel on 28/12/15.
//
#ifndef COCKATRICE_UPDATEDOWNLOADER_H
#define COCKATRICE_UPDATEDOWNLOADER_H
#include
<QObject>
#include
<QUrl>
#include
<QDate>
#include
<QtNetwork>
class
UpdateDownloader
:
public
QObject
{
Q_OBJECT
public:
UpdateDownloader
(
QObject
*
parent
);
void
beginDownload
(
QUrl
url
);
signals:
void
downloadSuccessful
(
QUrl
filepath
);
void
progressMade
(
qint64
bytesRead
,
qint64
totalBytes
);
void
error
(
QString
errorString
);
private:
QUrl
originalUrl
;
QNetworkAccessManager
*
netMan
;
QNetworkReply
*
response
;
private
slots
:
void
fileFinished
();
void
downloadProgress
(
qint64
bytesRead
,
qint64
totalBytes
);
void
downloadError
(
QNetworkReply
::
NetworkError
);
};
#endif //COCKATRICE_UPDATEDOWNLOADER_H
cockatrice/src/window_main.cpp
View file @
66fda086
...
...
@@ -30,6 +30,7 @@
#include
<QDateTime>
#include
<QSystemTrayIcon>
#include
<QApplication>
#include
<QtNetwork>
#if QT_VERSION < 0x050000
#include
<QtGui/qtextdocument.h>
// for Qt::escape()
...
...
@@ -40,6 +41,7 @@
#include
"dlg_connect.h"
#include
"dlg_register.h"
#include
"dlg_settings.h"
#include
"dlg_update.h"
#include
"tab_supervisor.h"
#include
"remoteclient.h"
#include
"localserver.h"
...
...
@@ -48,6 +50,7 @@
#include
"settingscache.h"
#include
"tab_game.h"
#include
"version_string.h"
#include
"update_checker.h"
#include
"pb/game_replay.pb.h"
#include
"pb/room_commands.pb.h"
...
...
@@ -62,6 +65,8 @@
#define GITHUB_TROUBLESHOOTING_URL "https://github.com/Cockatrice/Cockatrice/wiki/Troubleshooting"
#define GITHUB_FAQ_URL "https://github.com/Cockatrice/Cockatrice/wiki/Frequently-Asked-Questions"
#define DOWNLOAD_URL "https://dl.bintray.com/cockatrice/Cockatrice/"
const
QString
MainWindow
::
appName
=
"Cockatrice"
;
void
MainWindow
::
updateTabMenu
(
const
QList
<
QMenu
*>
&
newMenuList
)
...
...
@@ -288,6 +293,12 @@ void MainWindow::actAbout()
));
}
void
MainWindow
::
actUpdate
()
{
DlgUpdate
dlg
(
this
);
dlg
.
exec
();
}
void
MainWindow
::
serverTimeout
()
{
QMessageBox
::
critical
(
this
,
tr
(
"Error"
),
tr
(
"Server timeout"
));
...
...
@@ -495,6 +506,7 @@ void MainWindow::retranslateUi()
#endif
aAbout
->
setText
(
tr
(
"&About Cockatrice"
));
aUpdate
->
setText
(
tr
(
"&Update Cockatrice"
));
helpMenu
->
setTitle
(
tr
(
"&Help"
));
aCheckCardUpdates
->
setText
(
tr
(
"Check for card updates..."
));
tabSupervisor
->
retranslateUi
();
...
...
@@ -525,6 +537,8 @@ void MainWindow::createActions()
aAbout
=
new
QAction
(
this
);
connect
(
aAbout
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
actAbout
()));
aUpdate
=
new
QAction
(
this
);
connect
(
aUpdate
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
actUpdate
()));
aCheckCardUpdates
=
new
QAction
(
this
);
connect
(
aCheckCardUpdates
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
actCheckCardUpdates
()));
...
...
@@ -566,6 +580,7 @@ void MainWindow::createMenus()
helpMenu
=
menuBar
()
->
addMenu
(
QString
());
helpMenu
->
addAction
(
aAbout
);
helpMenu
->
addAction
(
aUpdate
);
}
MainWindow
::
MainWindow
(
QWidget
*
parent
)
...
...
cockatrice/src/window_main.h
View file @
66fda086
...
...
@@ -25,8 +25,11 @@
#include
<QSystemTrayIcon>
#include
<QProcess>
#include
<QMessageBox>
#include
<QtNetwork>
#include
"abstractclient.h"
#include
"pb/response.pb.h"
#include
"update_checker.h"
class
TabSupervisor
;
class
RemoteClient
;
...
...
@@ -66,6 +69,7 @@ private slots:
void
actExit
();
void
actAbout
();
void
actUpdate
();
void
iconActivated
(
QSystemTrayIcon
::
ActivationReason
reason
);
...
...
@@ -90,7 +94,7 @@ private:
QList
<
QMenu
*>
tabMenus
;
QMenu
*
cockatriceMenu
,
*
helpMenu
;
QAction
*
aConnect
,
*
aDisconnect
,
*
aSinglePlayer
,
*
aWatchReplay
,
*
aDeckEditor
,
*
aFullScreen
,
*
aSettings
,
*
aExit
,
*
aAbout
,
*
aCheckCardUpdates
,
*
aRegister
;
*
aAbout
,
*
aCheckCardUpdates
,
*
aRegister
,
*
aUpdate
;
TabSupervisor
*
tabSupervisor
;
QMenu
*
trayIconMenu
;
...
...
@@ -105,6 +109,7 @@ private:
QMessageBox
serverShutdownMessageBox
;
QProcess
*
cardUpdateProcess
;
public:
MainWindow
(
QWidget
*
parent
=
0
);
~
MainWindow
();
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment