2011-04-25 15:25:33 +02:00
|
|
|
/******************************************************************************\
|
|
|
|
* Copyright (c) 2004-2011
|
|
|
|
*
|
|
|
|
* Author(s):
|
|
|
|
* Volker Fischer
|
|
|
|
*
|
|
|
|
******************************************************************************
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it under
|
|
|
|
* the terms of the GNU General Public License as published by the Free Software
|
|
|
|
* Foundation; either version 2 of the License, or (at your option) any later
|
|
|
|
* version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
|
* details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
\******************************************************************************/
|
|
|
|
|
|
|
|
#include <qapplication.h>
|
|
|
|
#include <qmessagebox.h>
|
|
|
|
#include <qdir.h>
|
|
|
|
#include <qtextstream.h>
|
|
|
|
#include "global.h"
|
|
|
|
#include "llconclientdlg.h"
|
|
|
|
#include "llconserverdlg.h"
|
|
|
|
#include "settings.h"
|
|
|
|
#include "testbench.h"
|
|
|
|
|
|
|
|
|
|
|
|
// Implementation **************************************************************
|
|
|
|
// these pointers are only used for the post-event routine
|
|
|
|
QApplication* pApp = NULL;
|
|
|
|
QDialog* pMainWindow = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
int main ( int argc, char** argv )
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
// no console on windows -> just write in string and dump it
|
|
|
|
QString strDummySink;
|
|
|
|
QTextStream tsConsole ( &strDummySink );
|
|
|
|
#else
|
|
|
|
QTextStream tsConsole ( stdout );
|
|
|
|
#endif
|
|
|
|
QString strArgument;
|
|
|
|
double rDbleArgument;
|
|
|
|
|
|
|
|
// initialize all flags and string which might be changed by command line
|
|
|
|
// arguments
|
|
|
|
bool bIsClient = true;
|
|
|
|
bool bUseGUI = true;
|
|
|
|
bool bConnectOnStartup = false;
|
|
|
|
bool bDisalbeLEDs = false;
|
|
|
|
quint16 iPortNumber = LLCON_DEFAULT_PORT_NUMBER;
|
|
|
|
QString strIniFileName = "";
|
|
|
|
QString strHTMLStatusFileName = "";
|
|
|
|
QString strServerName = "";
|
|
|
|
QString strLoggingFileName = "";
|
|
|
|
QString strHistoryFileName = "";
|
|
|
|
QString strCentralServer = "";
|
|
|
|
QString strServerInfo = "";
|
|
|
|
|
|
|
|
// QT docu: argv()[0] is the program name, argv()[1] is the first
|
|
|
|
// argument and argv()[argc()-1] is the last argument.
|
|
|
|
// Start with first argument, therefore "i = 1"
|
|
|
|
for ( int i = 1; i < argc; i++ )
|
|
|
|
{
|
|
|
|
// Server mode flag ----------------------------------------------------
|
|
|
|
if ( GetFlagArgument ( argv,
|
|
|
|
i,
|
|
|
|
"-s",
|
|
|
|
"--server" ) )
|
|
|
|
{
|
|
|
|
bIsClient = false;
|
|
|
|
tsConsole << "- server mode chosen" << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Use GUI flag --------------------------------------------------------
|
|
|
|
if ( GetFlagArgument ( argv,
|
|
|
|
i,
|
|
|
|
"-n",
|
|
|
|
"--nogui" ) )
|
|
|
|
{
|
|
|
|
bUseGUI = false;
|
|
|
|
tsConsole << "- no GUI mode chosen" << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Disable LEDs flag ---------------------------------------------------
|
|
|
|
if ( GetFlagArgument ( argv,
|
|
|
|
i,
|
|
|
|
"-d",
|
|
|
|
"--disableleds" ) )
|
|
|
|
{
|
|
|
|
bDisalbeLEDs = true;
|
|
|
|
tsConsole << "- disable LEDs in main window" << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Use logging ---------------------------------------------------------
|
|
|
|
if ( GetStringArgument ( tsConsole,
|
|
|
|
argc,
|
|
|
|
argv,
|
|
|
|
i,
|
|
|
|
"-l",
|
|
|
|
"--log",
|
|
|
|
strArgument ) )
|
|
|
|
{
|
|
|
|
strLoggingFileName = strArgument;
|
|
|
|
tsConsole << "- logging file name: " << strLoggingFileName << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Port number ---------------------------------------------------------
|
|
|
|
if ( GetNumericArgument ( tsConsole,
|
|
|
|
argc,
|
|
|
|
argv,
|
|
|
|
i,
|
|
|
|
"-p",
|
|
|
|
"--port",
|
|
|
|
0,
|
|
|
|
65535,
|
|
|
|
rDbleArgument ) )
|
|
|
|
{
|
|
|
|
iPortNumber = static_cast<quint16> ( rDbleArgument );
|
|
|
|
tsConsole << "- selected port number: " << iPortNumber << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// HTML status file ----------------------------------------------------
|
|
|
|
if ( GetStringArgument ( tsConsole,
|
|
|
|
argc,
|
|
|
|
argv,
|
|
|
|
i,
|
|
|
|
"-m",
|
|
|
|
"--htmlstatus",
|
|
|
|
strArgument ) )
|
|
|
|
{
|
|
|
|
strHTMLStatusFileName = strArgument;
|
|
|
|
tsConsole << "- HTML status file name: " << strHTMLStatusFileName << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( GetStringArgument ( tsConsole,
|
|
|
|
argc,
|
|
|
|
argv,
|
|
|
|
i,
|
|
|
|
"-a",
|
|
|
|
"--servername",
|
|
|
|
strArgument ) )
|
|
|
|
{
|
|
|
|
strServerName = strArgument;
|
|
|
|
tsConsole << "- server name for HTML status file: " << strServerName << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// HTML status file ----------------------------------------------------
|
|
|
|
if ( GetStringArgument ( tsConsole,
|
|
|
|
argc,
|
|
|
|
argv,
|
|
|
|
i,
|
|
|
|
"-y",
|
|
|
|
"--history",
|
|
|
|
strArgument ) )
|
|
|
|
{
|
|
|
|
strHistoryFileName = strArgument;
|
|
|
|
tsConsole << "- history file name: " << strHistoryFileName << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Central server ------------------------------------------------------
|
|
|
|
if ( GetStringArgument ( tsConsole,
|
|
|
|
argc,
|
|
|
|
argv,
|
|
|
|
i,
|
|
|
|
"-e",
|
|
|
|
"--centralserver",
|
|
|
|
strArgument ) )
|
|
|
|
{
|
|
|
|
strCentralServer = strArgument;
|
|
|
|
tsConsole << "- central server: " << strCentralServer << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Server info ---------------------------------------------------------
|
|
|
|
if ( GetStringArgument ( tsConsole,
|
|
|
|
argc,
|
|
|
|
argv,
|
|
|
|
i,
|
|
|
|
"-o",
|
|
|
|
"--serverinfo",
|
|
|
|
strArgument ) )
|
|
|
|
{
|
|
|
|
strServerInfo = strArgument;
|
|
|
|
tsConsole << "- server info: " << strServerInfo << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Initialization file -------------------------------------------------
|
|
|
|
if ( GetStringArgument ( tsConsole,
|
|
|
|
argc,
|
|
|
|
argv,
|
|
|
|
i,
|
|
|
|
"-i",
|
|
|
|
"--inifile",
|
|
|
|
strArgument ) )
|
|
|
|
{
|
|
|
|
strIniFileName = strArgument;
|
|
|
|
tsConsole << "- initialization file name: " << strIniFileName << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Connect on startup --------------------------------------------------
|
|
|
|
if ( GetFlagArgument ( argv,
|
|
|
|
i,
|
|
|
|
"-c",
|
|
|
|
"--connect" ) )
|
|
|
|
{
|
|
|
|
bConnectOnStartup = true;
|
|
|
|
tsConsole << "- connect on startup enabled" << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Help (usage) flag ---------------------------------------------------
|
|
|
|
if ( ( !strcmp ( argv[i], "--help" ) ) ||
|
|
|
|
( !strcmp ( argv[i], "-h" ) ) ||
|
|
|
|
( !strcmp ( argv[i], "-?" ) ) )
|
|
|
|
{
|
|
|
|
const QString strHelp = UsageArguments ( argv );
|
|
|
|
tsConsole << strHelp << endl;
|
|
|
|
|
|
|
|
exit ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unknown option ------------------------------------------------------
|
|
|
|
tsConsole << argv[0] << ": ";
|
|
|
|
tsConsole << "Unknown option '" <<
|
|
|
|
argv[i] << "' -- use '--help' for help" << endl;
|
|
|
|
|
|
|
|
// clicking on the Mac application bundle, the actual application
|
|
|
|
// is called with weird command line args -> do not exit on these
|
|
|
|
#if !( defined ( __APPLE__ ) || defined ( __MACOSX ) )
|
|
|
|
exit ( 1 );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Dependencies ------------------------------------------------------------
|
|
|
|
// per definition: if we are in "GUI" server mode and no central server
|
|
|
|
// address is given, we use the default central server address
|
|
|
|
if ( !bIsClient && bUseGUI && strCentralServer.isEmpty() )
|
|
|
|
{
|
|
|
|
strCentralServer = DEFAULT_SERVER_ADDRESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Application/GUI setup ---------------------------------------------------
|
|
|
|
// Application object
|
|
|
|
QApplication app ( argc, argv, bUseGUI );
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
// Set application priority class -> high priority
|
|
|
|
SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS );
|
|
|
|
|
|
|
|
// For accessible support we need to add a plugin to qt. The plugin has to
|
|
|
|
// be located in the install directory of llcon by the installer. Here, we
|
|
|
|
// set the path to our application
|
|
|
|
QDir ApplDir ( QApplication::applicationDirPath() );
|
|
|
|
app.addLibraryPath ( QString ( ApplDir.absolutePath() ) );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// init resources
|
|
|
|
#ifdef _IS_QMAKE_CONFIG
|
|
|
|
Q_INIT_RESOURCE(resources);
|
|
|
|
#else
|
|
|
|
extern int qInitResources();
|
|
|
|
qInitResources();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// TEST -> activate the following line to activate the test bench,
|
|
|
|
//CTestbench Testbench ( "127.0.0.1", LLCON_DEFAULT_PORT_NUMBER );
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if ( bIsClient )
|
|
|
|
{
|
|
|
|
// Client:
|
|
|
|
// actual client object
|
|
|
|
CClient Client ( iPortNumber );
|
|
|
|
|
|
|
|
// load settings from init-file
|
|
|
|
CSettings Settings ( &Client );
|
|
|
|
Settings.Load ( strIniFileName );
|
|
|
|
|
|
|
|
// GUI object
|
|
|
|
CLlconClientDlg ClientDlg (
|
|
|
|
&Client,
|
|
|
|
bConnectOnStartup,
|
|
|
|
bDisalbeLEDs,
|
|
|
|
0
|
|
|
|
#ifdef _WIN32
|
|
|
|
// this somehow only works reliable on Windows
|
|
|
|
, Qt::WindowMinMaxButtonsHint
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
|
|
|
|
// set main window
|
|
|
|
pMainWindow = &ClientDlg;
|
|
|
|
pApp = &app; // Needed for post-event routine
|
|
|
|
|
|
|
|
// show dialog
|
|
|
|
ClientDlg.show();
|
|
|
|
app.exec();
|
|
|
|
|
|
|
|
// save settings to init-file
|
|
|
|
Settings.Save ( strIniFileName );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Server:
|
|
|
|
// actual server object
|
|
|
|
CServer Server ( strLoggingFileName,
|
|
|
|
iPortNumber,
|
|
|
|
strHTMLStatusFileName,
|
|
|
|
strHistoryFileName,
|
|
|
|
strServerName,
|
|
|
|
strCentralServer,
|
|
|
|
strServerInfo );
|
|
|
|
|
|
|
|
if ( bUseGUI )
|
|
|
|
{
|
2011-04-25 18:16:31 +02:00
|
|
|
// load settings from init-file
|
|
|
|
CSettings Settings ( &Server );
|
|
|
|
Settings.Load ( strIniFileName );
|
|
|
|
|
2011-04-30 15:01:26 +02:00
|
|
|
// update server list AFTER restoring the settings from the
|
|
|
|
// settings file
|
|
|
|
Server.UpdateServerList();
|
|
|
|
|
2011-04-25 15:25:33 +02:00
|
|
|
// GUI object for the server
|
|
|
|
CLlconServerDlg ServerDlg ( &Server, 0 );
|
|
|
|
|
|
|
|
// set main window
|
|
|
|
pMainWindow = &ServerDlg;
|
|
|
|
pApp = &app; // needed for post-event routine
|
|
|
|
|
|
|
|
// show dialog
|
|
|
|
ServerDlg.show();
|
|
|
|
app.exec();
|
2011-04-25 18:16:31 +02:00
|
|
|
|
|
|
|
// save settings to init-file
|
|
|
|
Settings.Save ( strIniFileName );
|
2011-04-25 15:25:33 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-04-30 15:01:26 +02:00
|
|
|
// update serverlist
|
|
|
|
Server.UpdateServerList();
|
|
|
|
|
2011-04-25 15:25:33 +02:00
|
|
|
// only start application without using the GUI
|
|
|
|
tsConsole << CAboutDlg::GetVersionAndNameStr ( false ) << endl;
|
|
|
|
|
|
|
|
app.exec();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
catch ( CGenErr generr )
|
|
|
|
{
|
|
|
|
// show generic error
|
|
|
|
if ( bUseGUI )
|
|
|
|
{
|
|
|
|
QMessageBox::critical ( 0,
|
|
|
|
APP_NAME,
|
|
|
|
generr.GetErrorText(),
|
|
|
|
"Quit",
|
|
|
|
0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tsConsole << generr.GetErrorText() << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************\
|
|
|
|
* Command Line Argument Parsing *
|
|
|
|
\******************************************************************************/
|
|
|
|
QString UsageArguments ( char **argv )
|
|
|
|
{
|
|
|
|
return
|
|
|
|
"Usage: " + QString ( argv[0] ) + " [option] [argument]\n"
|
|
|
|
"\nRecognized options:\n"
|
|
|
|
" -s, --server start server\n"
|
|
|
|
" -n, --nogui disable GUI (server only)\n"
|
|
|
|
" -l, --log enable logging, set file name\n"
|
|
|
|
" -i, --inifile initialization file name (client only)\n"
|
|
|
|
" -p, --port local port number (server only)\n"
|
|
|
|
" -m, --htmlstatus enable HTML status file, set file name (server\n"
|
|
|
|
" only)\n"
|
|
|
|
" -a, --servername server name, required for HTML status (server\n"
|
|
|
|
" only)\n"
|
|
|
|
" -y, --history enable connection history and set file\n"
|
|
|
|
" name (server only)\n"
|
|
|
|
" -e, --centralserver address of the central server (server only)\n"
|
|
|
|
" -o, --serverinfo infos of the server in the format:"
|
|
|
|
" [name];[city];[country as QLocale ID] (server "
|
|
|
|
" only)\n"
|
|
|
|
" -c, --connect connect to last server on startup (client\n"
|
|
|
|
" only)\n"
|
|
|
|
" -d, --disableleds disable LEDs in main window (client only)\n"
|
|
|
|
" -h, -?, --help this help text\n"
|
|
|
|
"\nExample: " + QString ( argv[0] ) + " -l -inifile myinifile.ini\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetFlagArgument ( char** argv,
|
|
|
|
int& i,
|
|
|
|
QString strShortOpt,
|
|
|
|
QString strLongOpt )
|
|
|
|
{
|
|
|
|
if ( ( !strShortOpt.compare ( argv[i] ) ) ||
|
|
|
|
( !strLongOpt.compare ( argv[i] ) ) )
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetStringArgument ( QTextStream& tsConsole,
|
|
|
|
int argc,
|
|
|
|
char** argv,
|
|
|
|
int& i,
|
|
|
|
QString strShortOpt,
|
|
|
|
QString strLongOpt,
|
|
|
|
QString& strArg )
|
|
|
|
{
|
|
|
|
if ( ( !strShortOpt.compare ( argv[i] ) ) ||
|
|
|
|
( !strLongOpt.compare ( argv[i] ) ) )
|
|
|
|
{
|
|
|
|
if ( ++i >= argc )
|
|
|
|
{
|
|
|
|
tsConsole << argv[0] << ": ";
|
|
|
|
tsConsole << "'" << strLongOpt << "' needs a string argument" << endl;
|
|
|
|
exit ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
strArg = argv[i];
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetNumericArgument ( QTextStream& tsConsole,
|
|
|
|
int argc,
|
|
|
|
char** argv,
|
|
|
|
int& i,
|
|
|
|
QString strShortOpt,
|
|
|
|
QString strLongOpt,
|
|
|
|
double rRangeStart,
|
|
|
|
double rRangeStop,
|
|
|
|
double& rValue )
|
|
|
|
{
|
|
|
|
if ( ( !strShortOpt.compare ( argv[i] ) ) ||
|
|
|
|
( !strLongOpt.compare ( argv[i] ) ) )
|
|
|
|
{
|
|
|
|
if ( ++i >= argc )
|
|
|
|
{
|
|
|
|
tsConsole << argv[0] << ": ";
|
|
|
|
|
|
|
|
tsConsole << "'" <<
|
|
|
|
strLongOpt << "' needs a numeric argument between " <<
|
|
|
|
rRangeStart << " and " << rRangeStop << endl;
|
|
|
|
|
|
|
|
exit ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
char *p;
|
|
|
|
rValue = strtod ( argv[i], &p );
|
|
|
|
if ( *p ||
|
|
|
|
( rValue < rRangeStart ) ||
|
|
|
|
( rValue > rRangeStop ) )
|
|
|
|
{
|
|
|
|
tsConsole << argv[0] << ": ";
|
|
|
|
|
|
|
|
tsConsole << "'" <<
|
|
|
|
strLongOpt << "' needs a numeric argument between " <<
|
|
|
|
rRangeStart << " and " << rRangeStop << endl;
|
|
|
|
|
|
|
|
exit ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************\
|
|
|
|
* Window Message System *
|
|
|
|
\******************************************************************************/
|
|
|
|
void PostWinMessage ( const _MESSAGE_IDENT MessID,
|
|
|
|
const int iMessageParam,
|
|
|
|
const int iChanNum )
|
|
|
|
{
|
|
|
|
// first check if application is initialized
|
|
|
|
if ( pApp != NULL )
|
|
|
|
{
|
|
|
|
CLlconEvent* LlconEv =
|
|
|
|
new CLlconEvent ( MessID, iMessageParam, iChanNum );
|
|
|
|
|
|
|
|
// Qt will delete the event object when done
|
|
|
|
QCoreApplication::postEvent ( pMainWindow, LlconEv );
|
|
|
|
}
|
|
|
|
}
|