Qt GUI now builds and runs on Windows. On Windows it can (via its manifest) automatically request admin rights on launch, which plugs it nicely into Windows' admin rights system without requiring file copies and such.

This commit is contained in:
Adam Ierymenko 2014-01-24 23:15:14 -08:00
parent 434ce96f2c
commit b65f7f7895
6 changed files with 123 additions and 142 deletions

View File

@ -3,105 +3,107 @@ TARGET = "ZeroTier One"
TEMPLATE = app TEMPLATE = app
win32:RC_FILE = ZeroTierUI.rc win32:RC_FILE = ZeroTierUI.rc
win32:LIBS += winhttp.lib Iphlpapi.lib ws2_32.lib advapi32.lib Shell32.lib Rpcrt4.lib
win32:QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
mac:ICON = zt1icon.icns mac:ICON = zt1icon.icns
mac:QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 mac:QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
mac:QMAKE_INFO_PLIST = Info.plist mac:QMAKE_INFO_PLIST = Info.plist
mac:LIBS += -framework Cocoa mac:LIBS += -framework Cocoa
SOURCES += main.cpp\ SOURCES += main.cpp \
mainwindow.cpp \ mainwindow.cpp \
aboutwindow.cpp \ aboutwindow.cpp \
../node/C25519.cpp \ ../node/C25519.cpp \
../node/CertificateOfMembership.cpp \ ../node/CertificateOfMembership.cpp \
../node/Defaults.cpp \ ../node/Defaults.cpp \
../node/Demarc.cpp \ ../node/Demarc.cpp \
../node/EthernetTap.cpp \ ../node/EthernetTap.cpp \
../node/HttpClient.cpp \ ../node/HttpClient.cpp \
../node/Identity.cpp \ ../node/Identity.cpp \
../node/InetAddress.cpp \ ../node/InetAddress.cpp \
../node/Logger.cpp \ ../node/Logger.cpp \
../node/Multicaster.cpp \ ../node/Multicaster.cpp \
../node/Network.cpp \ ../node/Network.cpp \
../node/NetworkConfig.cpp \ ../node/NetworkConfig.cpp \
../node/Node.cpp \ ../node/Node.cpp \
../node/NodeConfig.cpp \ ../node/NodeConfig.cpp \
../node/Packet.cpp \ ../node/Packet.cpp \
../node/PacketDecoder.cpp \ ../node/PacketDecoder.cpp \
../node/Peer.cpp \ ../node/Peer.cpp \
../node/Poly1305.cpp \ ../node/Poly1305.cpp \
../node/Salsa20.cpp \ ../node/Salsa20.cpp \
../node/Service.cpp \ ../node/Service.cpp \
../node/SHA512.cpp \ ../node/SHA512.cpp \
../node/SoftwareUpdater.cpp \ ../node/SoftwareUpdater.cpp \
../node/Switch.cpp \ ../node/Switch.cpp \
../node/SysEnv.cpp \ ../node/SysEnv.cpp \
../node/Topology.cpp \ ../node/Topology.cpp \
../node/UdpSocket.cpp \ ../node/UdpSocket.cpp \
../node/Utils.cpp \ ../node/Utils.cpp \
../ext/lz4/lz4.c \ ../ext/lz4/lz4.c \
../ext/lz4/lz4hc.c \ ../ext/lz4/lz4hc.c \
networkwidget.cpp \ networkwidget.cpp \
installdialog.cpp \ installdialog.cpp \
licensedialog.cpp licensedialog.cpp
HEADERS += mainwindow.h \ HEADERS += mainwindow.h \
aboutwindow.h \ aboutwindow.h \
../node/Node.hpp \ ../node/Node.hpp \
../node/Utils.hpp \ ../node/Utils.hpp \
../node/Defaults.hpp \ ../node/Defaults.hpp \
../node/Address.hpp \ ../node/Address.hpp \
../node/Array.hpp \ ../node/Array.hpp \
../node/AtomicCounter.hpp \ ../node/AtomicCounter.hpp \
../node/BandwidthAccount.hpp \ ../node/BandwidthAccount.hpp \
../node/Buffer.hpp \ ../node/Buffer.hpp \
../node/C25519.hpp \ ../node/C25519.hpp \
../node/CertificateOfMembership.hpp \ ../node/CertificateOfMembership.hpp \
../node/CMWC4096.hpp \ ../node/CMWC4096.hpp \
../node/Condition.hpp \ ../node/Condition.hpp \
../node/Constants.hpp \ ../node/Constants.hpp \
../node/Demarc.hpp \ ../node/Demarc.hpp \
../node/Dictionary.hpp \ ../node/Dictionary.hpp \
../node/EthernetTap.hpp \ ../node/EthernetTap.hpp \
../node/HttpClient.hpp \ ../node/HttpClient.hpp \
../node/Identity.hpp \ ../node/Identity.hpp \
../node/InetAddress.hpp \ ../node/InetAddress.hpp \
../node/Logger.hpp \ ../node/Logger.hpp \
../node/MAC.hpp \ ../node/MAC.hpp \
../node/Multicaster.hpp \ ../node/Multicaster.hpp \
../node/MulticastGroup.hpp \ ../node/MulticastGroup.hpp \
../node/Mutex.hpp \ ../node/Mutex.hpp \
../node/Network.hpp \ ../node/Network.hpp \
../node/NetworkConfig.hpp \ ../node/NetworkConfig.hpp \
../node/NodeConfig.hpp \ ../node/NodeConfig.hpp \
../node/NonCopyable.hpp \ ../node/NonCopyable.hpp \
../node/Packet.hpp \ ../node/Packet.hpp \
../node/PacketDecoder.hpp \ ../node/PacketDecoder.hpp \
../node/Peer.hpp \ ../node/Peer.hpp \
../node/Poly1305.hpp \ ../node/Poly1305.hpp \
../node/RuntimeEnvironment.hpp \ ../node/RuntimeEnvironment.hpp \
../node/Salsa20.hpp \ ../node/Salsa20.hpp \
../node/Service.hpp \ ../node/Service.hpp \
../node/SHA512.hpp \ ../node/SHA512.hpp \
../node/SharedPtr.hpp \ ../node/SharedPtr.hpp \
../node/SoftwareUpdater.hpp \ ../node/SoftwareUpdater.hpp \
../node/Switch.hpp \ ../node/Switch.hpp \
../node/SysEnv.hpp \ ../node/SysEnv.hpp \
../node/Thread.hpp \ ../node/Thread.hpp \
../node/Topology.hpp \ ../node/Topology.hpp \
../node/UdpSocket.hpp \ ../node/UdpSocket.hpp \
../ext/lz4/lz4.h \ ../ext/lz4/lz4.h \
../ext/lz4/lz4hc.h \ ../ext/lz4/lz4hc.h \
networkwidget.h \ networkwidget.h \
installdialog.h \ installdialog.h \
mac_doprivileged.h \ mac_doprivileged.h \
licensedialog.h \ licensedialog.h \
main.h main.h
FORMS += mainwindow.ui \ FORMS += mainwindow.ui \
aboutwindow.ui \ aboutwindow.ui \
networkwidget.ui \ networkwidget.ui \
installdialog.ui \ installdialog.ui \
licensedialog.ui licensedialog.ui
RESOURCES += \ RESOURCES += \

View File

@ -134,7 +134,7 @@
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Sunken</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>

View File

@ -59,6 +59,8 @@ int main(int argc, char *argv[])
#ifdef __APPLE__ #ifdef __APPLE__
{ {
// Put QSettings here because this is one of the writable directories allowed
// in Apple's app store sandbox specs. We might end up in app store someday.
QString zt1AppSupport(QDir::homePath() + "/Library/Application Support/ZeroTier/One"); QString zt1AppSupport(QDir::homePath() + "/Library/Application Support/ZeroTier/One");
QDir::root().mkpath(zt1AppSupport); QDir::root().mkpath(zt1AppSupport);
settings = new QSettings(zt1AppSupport + "/ui.ini",QSettings::IniFormat); settings = new QSettings(zt1AppSupport + "/ui.ini",QSettings::IniFormat);

View File

@ -99,13 +99,19 @@ MainWindow::MainWindow(QWidget *parent) :
ui->setupUi(this); ui->setupUi(this);
if (ui->networkListWidget->verticalScrollBar()) if (ui->networkListWidget->verticalScrollBar())
ui->networkListWidget->verticalScrollBar()->setSingleStep(8); ui->networkListWidget->verticalScrollBar()->setSingleStep(8);
#ifdef __APPLE__
QWidgetList widgets = this->findChildren<QWidget*>(); QWidgetList widgets = this->findChildren<QWidget*>();
foreach(QWidget *widget, widgets) foreach(QWidget *widget, widgets)
widget->setAttribute(Qt::WA_MacShowFocusRect,false); widget->setAttribute(Qt::WA_MacShowFocusRect,false);
ui->noNetworksLabel->setText("Connecting to Service..."); // changed when result is received #endif
ui->noNetworksLabel->setVisible(true);
ui->noNetworksLabel->setText("Connecting to Service...");
ui->bottomContainerWidget->setVisible(false);
ui->networkListWidget->setVisible(false);
this->pollServiceTimerId = this->startTimer(1000); this->pollServiceTimerId = this->startTimer(1000);
this->setEnabled(false); // gets enabled when updates are received
this->cyclesSinceResponseFromService = 0; this->cyclesSinceResponseFromService = 0;
} }
@ -173,19 +179,25 @@ void MainWindow::timerEvent(QTimerEvent *event)
#endif #endif
if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) { if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
QMessageBox::critical(this,"Cannot Authorize","Unable to authorize this user to administrate ZeroTier One. (Did you enter your password correctly?)",QMessageBox::Ok,QMessageBox::NoButton); if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultSystemPath().c_str(),authToken)) {
QApplication::exit(1); QMessageBox::critical(this,"Cannot Authorize","Unable to authorize this user to administrate ZeroTier One. (Did you enter your password correctly?)",QMessageBox::Ok,QMessageBox::NoButton);
return; QApplication::exit(1);
return;
}
} }
} }
zeroTierClient = new ZeroTier::Node::LocalClient(authToken.c_str(),0,&handleZTMessage,this); zeroTierClient = new ZeroTier::Node::LocalClient(authToken.c_str(),0,&handleZTMessage,this);
} }
// TODO: do something more user-friendly here... or maybe try to restart if (++this->cyclesSinceResponseFromService >= 4) {
// the service? if (this->cyclesSinceResponseFromService == 4)
if (++this->cyclesSinceResponseFromService == 4) QMessageBox::warning(this,"Service Not Running","Can't Connect to the ZeroTier One service. Is it running?",QMessageBox::Ok);
QMessageBox::critical(this,"No Response from Service","The ZeroTier One service does not appear to be running.",QMessageBox::Ok,QMessageBox::NoButton); ui->noNetworksLabel->setVisible(true);
ui->noNetworksLabel->setText("Connecting to Service...");
ui->bottomContainerWidget->setVisible(false);
ui->networkListWidget->setVisible(false);
}
zeroTierClient->send("info"); zeroTierClient->send("info");
zeroTierClient->send("listnetworks"); zeroTierClient->send("listnetworks");
@ -281,6 +293,11 @@ void MainWindow::customEvent(QEvent *event)
ui->noNetworksLabel->setVisible(true); ui->noNetworksLabel->setVisible(true);
} else ui->noNetworksLabel->setVisible(false); } else ui->noNetworksLabel->setVisible(false);
if (!ui->bottomContainerWidget->isVisible())
ui->bottomContainerWidget->setVisible(true);
if (!ui->networkListWidget->isVisible())
ui->networkListWidget->setVisible(true);
if (this->myAddress.size()) if (this->myAddress.size())
ui->addressButton->setText(this->myAddress); ui->addressButton->setText(this->myAddress);
else ui->addressButton->setText(" "); else ui->addressButton->setText(" ");
@ -292,14 +309,6 @@ void MainWindow::customEvent(QEvent *event)
st += QString::number(this->numPeers); st += QString::number(this->numPeers);
st += " direct links to peers"; st += " direct links to peers";
ui->statusLabel->setText(st); ui->statusLabel->setText(st);
if (this->myStatus == "ONLINE") {
if (!this->isEnabled())
this->setEnabled(true);
} else {
if (this->isEnabled())
this->setEnabled(false);
}
} }
void MainWindow::on_joinNetworkButton_clicked() void MainWindow::on_joinNetworkButton_clicked()

View File

@ -36,43 +36,6 @@
</property> </property>
<item> <item>
<widget class="QLabel" name="noNetworksLabel"> <widget class="QLabel" name="noNetworksLabel">
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="64">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="64">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="font"> <property name="font">
<font> <font>
<pointsize>16</pointsize> <pointsize>16</pointsize>
@ -267,7 +230,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>668</width> <width>668</width>
<height>22</height> <height>18</height>
</rect> </rect>
</property> </property>
<property name="layoutDirection"> <property name="layoutDirection">

View File

@ -80,6 +80,11 @@ QLabel.networkName {
padding: 0; padding: 0;
} }
#noNetworksLabel {
background: transparent;
color: #ffffff;
}
#networkListWidget { #networkListWidget {
background: palette(dark); background: palette(dark);
margin: 0 0 2px 0; margin: 0 0 2px 0;