From 54a807fe3d752ef8da30ba6e2c80787ebfb0e5b1 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 21 Dec 2017 14:27:07 -0500 Subject: [PATCH] 2017-12-21 Fred Gleason * Added log locking logic to rdlogmanager(1). --- ChangeLog | 2 + lib/librd_cs.ts | 8 ++++ lib/librd_de.ts | 8 ++++ lib/librd_es.ts | 8 ++++ lib/librd_fr.ts | 8 ++++ lib/librd_nb.ts | 8 ++++ lib/librd_nn.ts | 8 ++++ lib/librd_pt_BR.ts | 8 ++++ lib/rdsvc.cpp | 74 ++++++++++++++++++++++++------ lib/rdsvc.h | 11 +++-- rdlogmanager/commandline_ops.cpp | 31 ++++++++++--- rdlogmanager/generate_log.cpp | 67 ++++++++++++++++++++++----- rdlogmanager/rdlogmanager_cs.ts | 24 ++++++++++ rdlogmanager/rdlogmanager_de.ts | 24 ++++++++++ rdlogmanager/rdlogmanager_es.ts | 24 ++++++++++ rdlogmanager/rdlogmanager_fr.ts | 24 ++++++++++ rdlogmanager/rdlogmanager_nb.ts | 24 ++++++++++ rdlogmanager/rdlogmanager_nn.ts | 24 ++++++++++ rdlogmanager/rdlogmanager_pt_BR.ts | 24 ++++++++++ tests/log_unlink_test.cpp | 42 ++++++++++------- tests/log_unlink_test.h | 13 ++++++ 21 files changed, 413 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 697d6f37..cd4222a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16535,3 +16535,5 @@ rdclilogedit(1). 2017-12-21 Fred Gleason * Added log locking logic to the 'SaveLog' Web API call. +2017-12-21 Fred Gleason + * Added log locking logic to rdlogmanager(1). diff --git a/lib/librd_cs.ts b/lib/librd_cs.ts index 9cacf4e6..8eae3c4f 100644 --- a/lib/librd_cs.ts +++ b/lib/librd_cs.ts @@ -2438,5 +2438,13 @@ Zkuste to, prosím, znovu! Chyba plnění události + + Log in use by + + + + Import failed + + diff --git a/lib/librd_de.ts b/lib/librd_de.ts index 44e28f4e..24608ed4 100644 --- a/lib/librd_de.ts +++ b/lib/librd_de.ts @@ -2433,5 +2433,13 @@ bitte erneut versuchen! Event-Füllfehler + + Log in use by + + + + Import failed + + diff --git a/lib/librd_es.ts b/lib/librd_es.ts index 5136c045..ed782c76 100644 --- a/lib/librd_es.ts +++ b/lib/librd_es.ts @@ -2425,5 +2425,13 @@ please try again! Errores al llenar eventos + + Log in use by + + + + Import failed + + diff --git a/lib/librd_fr.ts b/lib/librd_fr.ts index 6d424b2b..0c87c518 100644 --- a/lib/librd_fr.ts +++ b/lib/librd_fr.ts @@ -2019,5 +2019,13 @@ please try again! + + Log in use by + + + + Import failed + + diff --git a/lib/librd_nb.ts b/lib/librd_nb.ts index 41ab2692..deb236ec 100644 --- a/lib/librd_nb.ts +++ b/lib/librd_nb.ts @@ -2370,5 +2370,13 @@ prøv ein gong til! + + Log in use by + + + + Import failed + + diff --git a/lib/librd_nn.ts b/lib/librd_nn.ts index 41ab2692..deb236ec 100644 --- a/lib/librd_nn.ts +++ b/lib/librd_nn.ts @@ -2370,5 +2370,13 @@ prøv ein gong til! + + Log in use by + + + + Import failed + + diff --git a/lib/librd_pt_BR.ts b/lib/librd_pt_BR.ts index d6974c59..268518cd 100644 --- a/lib/librd_pt_BR.ts +++ b/lib/librd_pt_BR.ts @@ -2384,5 +2384,13 @@ por favor, tente novamente! Erros de Auto Preenchimento + + Log in use by + + + + Import failed + + diff --git a/lib/rdsvc.cpp b/lib/rdsvc.cpp index 77f8d071..48bd486c 100644 --- a/lib/rdsvc.cpp +++ b/lib/rdsvc.cpp @@ -20,16 +20,15 @@ #include -#include -#include -#include -#include -#include #include -#include - +#include +#include +#include #include +#include #include +#include +#include #include // @@ -710,13 +709,15 @@ bool RDSvc::import(ImportSource src,const QDate &date,const QString &break_str, bool RDSvc::generateLog(const QDate &date,const QString &logname, - const QString &nextname,QString *report,RDUser *user) + const QString &nextname,QString *report,RDUser *user, + QString *err_msg) { QString sql; RDSqlQuery *q; RDClock clock; - QString err_msg; + // QString err_msg; RDLog *log=NULL; + RDLogLock *log_lock=NULL; if((!date.isValid()||logname.isEmpty())) { return false; @@ -728,9 +729,20 @@ bool RDSvc::generateLog(const QDate &date,const QString &logname, // Generate Log Structure // if(RDLog::exists(logname)) { + log_lock=new RDLogLock(logname,user,svc_station,this); + if(!TryLock(log_lock,err_msg)) { + delete log_lock; + return false; + } RDLog::remove(logname,svc_station,user,svc_config); + delete log_lock; + } + RDLog::create(logname,svc_name,"RDLogManager",err_msg,svc_config); + log_lock=new RDLogLock(logname,user,svc_station,this); + if(!TryLock(log_lock,err_msg)) { + delete log_lock; + return false; } - RDLog::create(logname,svc_name,"RDLogManager",&err_msg,svc_config); log=new RDLog(logname); log->setDescription(RDDateDecode(descriptionTemplate(),date,svc_station, svc_config,svc_name)); @@ -792,18 +804,26 @@ bool RDSvc::generateLog(const QDate &date,const QString &logname, log->setNextId(count); log->setAutoRefresh(autoRefresh()); delete log; + delete log_lock; return true; } bool RDSvc::linkLog(RDSvc::ImportSource src,const QDate &date, - const QString &logname,QString *report) + const QString &logname,QString *report,RDUser *user, + QString *err_msg) { QString sql; RDSqlQuery *q; QString autofill_errors; + RDLogLock *log_lock=new RDLogLock(logname,user,svc_station,this); + if(!TryLock(log_lock,err_msg)) { + delete log_lock; + return false; + } + emit generationProgress(0); // @@ -822,6 +842,8 @@ bool RDSvc::linkLog(RDSvc::ImportSource src,const QDate &date, import_name.replace(" ","_"); if(!import(src,date,breakString(),trackString(src),import_name)) { + *err_msg=tr("Import failed"); + delete log_lock; return false; } @@ -943,13 +965,20 @@ bool RDSvc::linkLog(RDSvc::ImportSource src,const QDate &date, sql=QString().sprintf("drop table `%s`",(const char *)import_name); q=new RDSqlQuery(sql); delete q; + delete log_lock; return true; } -void RDSvc::clearLogLinks(RDSvc::ImportSource src,const QString &logname) +bool RDSvc::clearLogLinks(RDSvc::ImportSource src,const QString &logname, + RDUser *user,QString *err_msg) { + RDLogLock *log_lock=new RDLogLock(logname,user,svc_station,this); + if(!TryLock(log_lock,err_msg)) { + delete log_lock; + return false; + } std::vector cleared_ids; RDLogLine::Type event_type=RDLogLine::UnknownType; RDLogLine::Source event_source=RDLogLine::Manual; @@ -1012,7 +1041,9 @@ void RDSvc::clearLogLinks(RDSvc::ImportSource src,const QString &logname) log->setLinkState(RDLog::SourceMusic,false); } delete log; - + delete log_lock; + *err_msg="OK"; + return true; } @@ -1447,6 +1478,23 @@ QString RDSvc::timeString(int hour,int secs) } +bool RDSvc::TryLock(RDLogLock *lock,QString *err_msg) +{ + QString username; + QString stationname; + QHostAddress addr; + + if(!lock->tryLock(&username,&stationname,&addr)) { + *err_msg=tr("Log in use by")+" "+username+"@"+stationname; + if(stationname!=addr.toString()) { + *err_msg+=" ["+addr.toString()+"]"; + } + return false; + } + return true; +} + + QString RDSvc::SourceString(ImportSource src) const { QString fieldname; diff --git a/lib/rdsvc.h b/lib/rdsvc.h index 91e72f50..1e036030 100644 --- a/lib/rdsvc.h +++ b/lib/rdsvc.h @@ -27,6 +27,7 @@ #include #include "rdconfig.h" +#include "rdloglock.h" #include "rdstation.h" #include "rduser.h" @@ -86,10 +87,13 @@ class RDSvc : public QObject const QString &track_str,const QString &dest_table) const; bool generateLog(const QDate &date,const QString &logname, - const QString &nextname,QString *report,RDUser *user); + const QString &nextname,QString *report,RDUser *user, + QString *err_msg); bool linkLog(RDSvc::ImportSource src,const QDate &date, - const QString &logname,QString *report); - void clearLogLinks(RDSvc::ImportSource src,const QString &logname); + const QString &logname,QString *report,RDUser *user, + QString *err_msg); + bool clearLogLinks(RDSvc::ImportSource src,const QString &logname, + RDUser *user,QString *err_msg); void create(const QString exemplar) const; void remove() const; QString xml() const; @@ -104,6 +108,7 @@ class RDSvc : public QObject void generationProgress(int step); private: + bool TryLock(RDLogLock *lock,QString *err_msg); QString SourceString(ImportSource src) const; QString OsString(ImportOs os) const; QString FieldString(ImportField field) const; diff --git a/rdlogmanager/commandline_ops.cpp b/rdlogmanager/commandline_ops.cpp index c885061d..63a95ff5 100644 --- a/rdlogmanager/commandline_ops.cpp +++ b/rdlogmanager/commandline_ops.cpp @@ -45,6 +45,7 @@ int RunLogOperation(int argc,char *argv[],const QString &svcname, QString svcname_table=svcname; svcname_table.replace(" ","_"); unsigned schema=0; + QString err_msg; QApplication a(argc,argv,false); @@ -112,8 +113,8 @@ int RunLogOperation(int argc,char *argv[],const QString &svcname, rdstation_conf,config,svc->name()), RDDateDecode(svc->nameTemplate(),start_date.addDays(1), rdstation_conf,config,svc->name()), - &unused_report,rduser)) { - fprintf(stderr,"rdlogmanager: unable to generate log\n"); + &unused_report,rduser,&err_msg)) { + fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg); return 256; } log->updateTracks(); @@ -147,15 +148,24 @@ int RunLogOperation(int argc,char *argv[],const QString &svcname, } report=""; log->removeTracks(rdstation_conf,rduser,config); - svc->clearLogLinks(RDSvc::Traffic,logname); - svc->clearLogLinks(RDSvc::Music,logname); - if(svc->linkLog(RDSvc::Music,start_date,logname,&report)) { + if(!svc->clearLogLinks(RDSvc::Traffic,logname,rduser,&err_msg)) { + fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg); + return 256; + } + if(!svc->clearLogLinks(RDSvc::Music,logname,rduser,&err_msg)) { + fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg); + return 256; + } + if(svc->linkLog(RDSvc::Music,start_date,logname,&report,rduser,&err_msg)) { printf("%s\n",(const char*)report); } else { + fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg); + /* fprintf(stderr, "rdlogmanager: unable to open music schedule file at \"%s\"\n", (const char *)svc->importFilename(RDSvc::Music,start_date)); + */ exit(256); } } @@ -176,14 +186,21 @@ int RunLogOperation(int argc,char *argv[],const QString &svcname, return 256; } report=""; - svc->clearLogLinks(RDSvc::Traffic,logname); - if(svc->linkLog(RDSvc::Traffic,start_date,logname,&report)) { + if(!svc->clearLogLinks(RDSvc::Traffic,logname,rduser,&err_msg)) { + fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg); + return 256; + } + if(svc->linkLog(RDSvc::Traffic,start_date,logname,&report,rduser, + &err_msg)) { printf("%s\n",(const char*)report); } else { + fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg); + /* fprintf(stderr, "rdlogmanager: unable to open traffic schedule file at \"%s\"\n", (const char *)svc->importFilename(RDSvc::Traffic,start_date)); + */ } } diff --git a/rdlogmanager/generate_log.cpp b/rdlogmanager/generate_log.cpp index 8efcc0f5..8e0d038c 100644 --- a/rdlogmanager/generate_log.cpp +++ b/rdlogmanager/generate_log.cpp @@ -298,6 +298,7 @@ void GenerateLog::createData() QString str1; QString str2; unsigned tracks=0; + QString err_msg; // // Generate Log @@ -359,13 +360,20 @@ void GenerateLog::createData() connect(svc,SIGNAL(generationProgress(int)), gen_progress_dialog,SLOT(setProgress(int))); - svc->generateLog(gen_date_edit->date(), - RDDateDecode(svc->nameTemplate(),gen_date_edit->date(), - rdstation_conf,log_config,svc->name()), - RDDateDecode(svc->nameTemplate(),gen_date_edit->date(). - addDays(1),rdstation_conf,log_config, - svc->name()), - &unused_report,rduser); + if(!svc->generateLog(gen_date_edit->date(), + RDDateDecode(svc->nameTemplate(),gen_date_edit->date(), + rdstation_conf,log_config,svc->name()), + RDDateDecode(svc->nameTemplate(),gen_date_edit->date(). + addDays(1),rdstation_conf,log_config, + svc->name()), + &unused_report,rduser,&err_msg)) { + QMessageBox::warning(this,"RDLogManager - "+tr("Error"), + tr("Unable to generate log")+": "+err_msg); + gen_progress_dialog->setProgress(gen_progress_dialog->totalSteps()); + delete svc; + delete log; + return; + } log->updateTracks(); delete log; delete svc; @@ -392,6 +400,7 @@ void GenerateLog::createData() void GenerateLog::musicData() { unsigned tracks=0; + QString err_msg; RDSvc *svc= new RDSvc(gen_service_box->currentText(),rdstation_conf,log_config,this); @@ -428,13 +437,33 @@ void GenerateLog::musicData() } } log->removeTracks(rdstation_conf,rduser,log_config); - svc->clearLogLinks(RDSvc::Traffic,logname); - svc->clearLogLinks(RDSvc::Music,logname); + if(!svc->clearLogLinks(RDSvc::Traffic,logname,rduser,&err_msg)) { + QMessageBox::warning(this,"RDLogManager - "+tr("Error"), + tr("Unable to clear traffic links")+": "+err_msg); + delete log; + delete svc; + return; + } + if(!svc->clearLogLinks(RDSvc::Music,logname,rduser,&err_msg)) { + QMessageBox::warning(this,"RDLogManager - "+tr("Error"), + tr("Unable to clear music links")+": "+err_msg); + delete log; + delete svc; + return; + } } connect(svc,SIGNAL(generationProgress(int)), gen_progress_dialog,SLOT(setProgress(int))); QString report; - svc->linkLog(RDSvc::Music,gen_date_edit->date(),logname,&report); + if(!svc->linkLog(RDSvc::Music,gen_date_edit->date(),logname,&report,rduser, + &err_msg)) { + + QMessageBox::warning(this,"RDLogManager - "+tr("Error"), + tr("Unable to link music log")+": "+err_msg); + delete log; + delete svc; + return; + } delete log; delete svc; if(!report.isEmpty()) { @@ -446,6 +475,7 @@ void GenerateLog::musicData() void GenerateLog::trafficData() { + QString err_msg; RDSvc *svc= new RDSvc(gen_service_box->currentText(),rdstation_conf,log_config,this); QString logname=RDDateDecode(svc->nameTemplate(),gen_date_edit->date(), @@ -464,13 +494,26 @@ void GenerateLog::trafficData() delete svc; return; } - svc->clearLogLinks(RDSvc::Traffic,logname); + if(!svc->clearLogLinks(RDSvc::Traffic,logname,rduser,&err_msg)) { + QMessageBox::warning(this,"RDLogManager - "+tr("Error"), + tr("Unable to clear traffic links")+": "+err_msg); + delete log; + delete svc; + return; + } } connect(svc,SIGNAL(generationProgress(int)), gen_progress_dialog,SLOT(setProgress(int))); QString report; - svc->linkLog(RDSvc::Traffic,gen_date_edit->date(),logname,&report); + if(!svc->linkLog(RDSvc::Traffic,gen_date_edit->date(),logname,&report,rduser, + &err_msg)) { + QMessageBox::warning(this,"RDLogManager - "+tr("Error"), + tr("Unable to link traffic log")+": "+err_msg); + delete log; + delete svc; + return; + } delete log; delete svc; if(!report.isEmpty()) { diff --git a/rdlogmanager/rdlogmanager_cs.ts b/rdlogmanager/rdlogmanager_cs.ts index 1d0fb702..35878718 100644 --- a/rdlogmanager/rdlogmanager_cs.ts +++ b/rdlogmanager/rdlogmanager_cs.ts @@ -855,6 +855,30 @@ Opětovné sloučení tato data smaže. Sloučit znovu? Generate Log - User: Vytvořit zápis - Uživatel: + + Error + + + + Unable to generate log + + + + Unable to clear traffic links + + + + Unable to clear music links + + + + Unable to link music log + + + + Unable to link traffic log + + ImportListView diff --git a/rdlogmanager/rdlogmanager_de.ts b/rdlogmanager/rdlogmanager_de.ts index 2a894e31..dd6b4676 100644 --- a/rdlogmanager/rdlogmanager_de.ts +++ b/rdlogmanager/rdlogmanager_de.ts @@ -855,6 +855,30 @@ Einbinden wird diese entfernen. Fortfahren? Generate Log - User: Generiere Log - User: + + Error + + + + Unable to generate log + + + + Unable to clear traffic links + + + + Unable to clear music links + + + + Unable to link music log + + + + Unable to link traffic log + + ImportListView diff --git a/rdlogmanager/rdlogmanager_es.ts b/rdlogmanager/rdlogmanager_es.ts index b8d82f51..a6e737a0 100644 --- a/rdlogmanager/rdlogmanager_es.ts +++ b/rdlogmanager/rdlogmanager_es.ts @@ -857,6 +857,30 @@ removerá estos datos. ¿Remezclar? Generate Log - User: Generar lista - Usuario: + + Error + + + + Unable to generate log + + + + Unable to clear traffic links + + + + Unable to clear music links + + + + Unable to link music log + + + + Unable to link traffic log + + ImportListView diff --git a/rdlogmanager/rdlogmanager_fr.ts b/rdlogmanager/rdlogmanager_fr.ts index c246b056..128b1de7 100644 --- a/rdlogmanager/rdlogmanager_fr.ts +++ b/rdlogmanager/rdlogmanager_fr.ts @@ -837,6 +837,30 @@ will remove this data. Remerge? Generate Log - User: + + Error + + + + Unable to generate log + + + + Unable to clear traffic links + + + + Unable to clear music links + + + + Unable to link music log + + + + Unable to link traffic log + + ImportListView diff --git a/rdlogmanager/rdlogmanager_nb.ts b/rdlogmanager/rdlogmanager_nb.ts index cc79a241..c27f8be2 100644 --- a/rdlogmanager/rdlogmanager_nb.ts +++ b/rdlogmanager/rdlogmanager_nb.ts @@ -868,6 +868,30 @@ Flettar du på nytt, vil du fjerna desse dataa. Flett på nytt? Generate Log - User: + + Error + + + + Unable to generate log + + + + Unable to clear traffic links + + + + Unable to clear music links + + + + Unable to link music log + + + + Unable to link traffic log + + ImportListView diff --git a/rdlogmanager/rdlogmanager_nn.ts b/rdlogmanager/rdlogmanager_nn.ts index cc79a241..c27f8be2 100644 --- a/rdlogmanager/rdlogmanager_nn.ts +++ b/rdlogmanager/rdlogmanager_nn.ts @@ -868,6 +868,30 @@ Flettar du på nytt, vil du fjerna desse dataa. Flett på nytt? Generate Log - User: + + Error + + + + Unable to generate log + + + + Unable to clear traffic links + + + + Unable to clear music links + + + + Unable to link music log + + + + Unable to link traffic log + + ImportListView diff --git a/rdlogmanager/rdlogmanager_pt_BR.ts b/rdlogmanager/rdlogmanager_pt_BR.ts index e567db4e..7222cd6d 100644 --- a/rdlogmanager/rdlogmanager_pt_BR.ts +++ b/rdlogmanager/rdlogmanager_pt_BR.ts @@ -857,6 +857,30 @@ Re-agregar removerá estes dados. Re-agregar? Traffic Exists Tráfego Existente + + Error + + + + Unable to generate log + + + + Unable to clear traffic links + + + + Unable to clear music links + + + + Unable to link music log + + + + Unable to link traffic log + + ImportListView diff --git a/tests/log_unlink_test.cpp b/tests/log_unlink_test.cpp index 5059c8ab..d17f871d 100644 --- a/tests/log_unlink_test.cpp +++ b/tests/log_unlink_test.cpp @@ -37,10 +37,7 @@ MainObject::MainObject(QObject *parent) :QObject(parent) { - QString log_name=""; - RDSvc::ImportSource import_source=RDSvc::Traffic; - RDConfig *config=NULL; - RDStation *station=NULL; + test_import_source=RDSvc::Traffic; unsigned schema=0; // @@ -51,16 +48,16 @@ MainObject::MainObject(QObject *parent) LOG_UNLINK_TEST_USAGE); for(unsigned i=0;ikeys();i++) { if(cmd->key(i)=="--log") { - log_name=cmd->value(i); + test_log_name=cmd->value(i); cmd->setProcessed(i,true); } if(cmd->key(i)=="--source") { if(cmd->value(i).lower()=="traffic") { - import_source=RDSvc::Traffic; + test_import_source=RDSvc::Traffic; } else { if(cmd->value(i).lower()=="music") { - import_source=RDSvc::Music; + test_import_source=RDSvc::Music; } else { fprintf(stderr, @@ -76,7 +73,7 @@ MainObject::MainObject(QObject *parent) exit(256); } } - if(log_name.isEmpty()) { + if(test_log_name.isEmpty()) { fprintf(stderr,"log_unlink_test: you must specify a log name with \"--log=\"\n"); exit(1); } @@ -84,9 +81,9 @@ MainObject::MainObject(QObject *parent) // // Load Configuration // - config=new RDConfig(); - config->load(); - config->setModuleName("reserve_carts_test"); + test_config=new RDConfig(); + test_config->load(); + test_config->setModuleName("reserve_carts_test"); // // Open Database @@ -98,18 +95,31 @@ MainObject::MainObject(QObject *parent) delete cmd; exit(256); } - station=new RDStation(config->stationName()); + test_station=new RDStation(test_config->stationName()); + test_ripc=new RDRipc(test_station,test_config,this); + connect(test_ripc,SIGNAL(userChanged()),this,SLOT(userData())); + test_ripc->connectHost("localhost",RIPCD_TCP_PORT,test_config->password()); +} + + +void MainObject::userData() +{ + QString err_msg; // // Run the Test // - if(!RDLog::exists(log_name)) { + if(!RDLog::exists(test_log_name)) { fprintf(stderr,"log_unlink_test: no such log\n"); exit(1); } - RDLog *log=new RDLog(log_name); - RDSvc *svc=new RDSvc(log->service(),station,config,this); - svc->clearLogLinks(import_source,log_name); + RDLog *log=new RDLog(test_log_name); + RDSvc *svc=new RDSvc(log->service(),test_station,test_config,this); + if(!svc->clearLogLinks(test_import_source,test_log_name, + new RDUser(test_ripc->user()),&err_msg)) { + fprintf(stderr,"log_unlink_test: %s\n",(const char *)err_msg); + exit(1); + } exit(0); } diff --git a/tests/log_unlink_test.h b/tests/log_unlink_test.h index 6da8b2b3..c1af8b2e 100644 --- a/tests/log_unlink_test.h +++ b/tests/log_unlink_test.h @@ -23,12 +23,25 @@ #include +#include +#include + #define LOG_UNLINK_TEST_USAGE "[options]\n\nTest the Rivendell log unlinker methods\n\nOptions are:\n--log=\n Name of log to unlink.\n\n--source=music|traffic\n Data source to unlink\n\n" class MainObject : public QObject { public: MainObject(QObject *parent=0); + + private slots: + void userData(); + + private: + RDSvc::ImportSource test_import_source; + QString test_log_name; + RDStation *test_station; + RDRipc *test_ripc; + RDConfig *test_config; };