1 /***************************************************************************
2     dxcluster.cpp  -  description
3        -------------------
4 begin                : oct 2011
5 copyright            : (C) 2011 by Jaime Robles
6 email                : jaime@robles.es
7 ***************************************************************************/
8 
9 /*****************************************************************************
10 * This file is part of KLog.                                                *
11 *                                                                           *
12 *    KLog is free software: you can redistribute it and/or modify           *
13 *    it under the terms of the GNU General Public License as published by   *
14 *    the Free Software Foundation, either version 3 of the License, or      *
15 *    (at your option) any later version.                                    *
16 *                                                                           *
17 *    KLog is distributed in the hope that it will be useful,                *
18 *    but WITHOUT ANY WARRANTY; without even the implied warranty of         *
19 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
20 *    GNU General Public License for more details.                           *
21 *                                                                           *
22 *    You should have received a copy of the GNU General Public License      *
23 *    along with KLog.  If not, see <https://www.gnu.org/licenses/>.          *
24 *                                                                           *
25 *****************************************************************************/
26 #include <QFont>
27 #include "dxcluster.h"
28 
DXClusterWidget(DataProxy_SQLite * dp,QWidget * parent)29 DXClusterWidget::DXClusterWidget(DataProxy_SQLite *dp, QWidget *parent)
30           : QWidget(parent)
31 {
32        //qDebug() << "DXClusterWidget::DXClusterWidget" << QT_ENDL;
33     dataProxy = dp;
34     constrid = 1;
35     awards = new Awards(dataProxy, Q_FUNC_INFO);
36     util = new Utilities;
37     saveSpotsFile = new QFile();
38 
39 
40     initClass();
41        //qDebug() << "DXClusterWidget::DXClusterWidget - END" << QT_ENDL;
42 }
43 
DXClusterWidget(DataProxy_SQLite * dp,const QString & clusterToConnect,const int portToConnect,QWidget * parent)44 DXClusterWidget::DXClusterWidget(DataProxy_SQLite *dp, const QString &clusterToConnect, const int portToConnect, QWidget *parent)
45           : QWidget(parent)
46 {
47       //qDebug() << "DXClusterWidget::DXClusterWidget2" << clusterToConnect << QString::number(portToConnect) << QT_ENDL;
48    constrid = 2;
49    util = new Utilities;
50    saveSpotsFile = new QFile();
51 
52     initClass();
53     server = clusterToConnect;
54     port = quint16(portToConnect);
55 
56     dxSpotColor.setNamedColor("slategrey");
57     //defaultColor.setNamedColor("slategrey");
58     //neededColor.setNamedColor("slategrey");
59     //workedColor.setNamedColor("slategrey");
60     //confirmedColor.setNamedColor("slategrey");
61     //newOneColor.setNamedColor("slategrey");
62     dataProxy = dp;
63     world = new World(dataProxy, Q_FUNC_INFO);
64     awards = new Awards(dataProxy, Q_FUNC_INFO);
65 
66 
67     tcpSocket = new QTcpSocket(this);
68 
69     dxClusterListWidget = new QListWidget();
70     inputCommand = new QLineEdit;
71     sendButton = new QPushButton;
72     clearButton = new QPushButton;
73 
74     inputCommand->setDisabled(true);
75     inputCommand->setToolTip(tr("Click on Connect to connect to the DX-Cluster server"));
76 
77     dxClusterListWidget->setMouseTracking(true);
78 
79     sendButton->setText(tr("Connect"));
80     clearButton->setText(tr("Clear"));
81 
82     QHBoxLayout *bottonLayout = new QHBoxLayout;
83     bottonLayout->addWidget(inputCommand);
84     bottonLayout->addWidget(sendButton);
85     bottonLayout->addWidget(clearButton);
86 
87     QVBoxLayout *layout = new QVBoxLayout;
88     layout->addWidget(dxClusterListWidget);
89     layout->addLayout(bottonLayout);
90 
91     setLayout(layout);
92 
93     connect(sendButton , SIGNAL(clicked()), this, SLOT(slotClusterSendToServer()) );
94     connect(inputCommand, SIGNAL(textChanged(QString)), this, SLOT(slotClusterInputTextChanged()) );
95 
96     //connect(searchResultsTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(slotDoubleClickSearch(QTreeWidgetItem *, int)));
97     connect(dxClusterListWidget, SIGNAL(itemDoubleClicked ( QListWidgetItem *)), this, SLOT(slotClusterDXClusterWidgetItemDoubleClicked( QListWidgetItem * )) );
98     connect(dxClusterListWidget, SIGNAL(itemEntered ( QListWidgetItem *)), this, SLOT(slotClusterDXClusterWidgetItemEntered( QListWidgetItem * )) );
99     connect(dxClusterListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(slotClusterDXClusterWidgetItemSelected() ) );
100 
101 //void QListWidget::itemDoubleClicked ( QListWidgetItem * item ) [signal]
102 
103     // TO BE DELETED
104     addData();
105 
106      //TESTADDSPOT();
107        //qDebug() << "DXClusterWidget::DXClusterWidget2 - END"  << QT_ENDL;
108 
109 }
110 
initClass()111 void DXClusterWidget::initClass()
112 {
113     dxClusterConnected = false;
114     dxClusterAlreadyConnected = false;
115     showDxMarathon = false;
116 
117     showhf = true;
118     showvhf = true;
119     showwarc = true;
120     showworked = true;
121     showconfirmed = true;
122     showann = true;
123     showwwv = true;
124     showwcy = true;
125     saveSpots = false;
126     myQrz = QString();
127     currentLog = 0;
128     saveSpotsFile->setFileName(util->getSaveSpotsLogFile());
129 }
130 
setMyQRZ(const QString & _qrz)131 void DXClusterWidget::setMyQRZ(const QString &_qrz)
132 {
133     if (_qrz.length()>2)
134     {
135         myQrz = _qrz;
136     }
137 
138 }
139 
addData()140 void DXClusterWidget::addData()
141 {
142        //qDebug() << "DXClusterWidget::addData " << QT_ENDL;
143 
144     /*
145                 QTreeWidgetItem *item = new QTreeWidgetItem(searchResultsTreeWidget);
146                 i = world->getQRZARRLId(_call);
147                 aux = world->getEntityName(i) + " - CQ: " + QString::number(world->getEntityCqz(i));
148                 item->setToolTip(0, aux);
149                 item->setToolTip(1, aux);
150                 item->setToolTip(2, aux);
151                 item->setToolTip(3, aux);
152                 item->setToolTip(4, aux);
153                 item->setToolTip(5, aux);
154                 item->setToolTip(6, aux);
155 */
156 
157     dxClusterSpotItem * item = new dxClusterSpotItem(dxClusterListWidget, tr("Click on connect to connect to the DX-Cluster"), awards->getDefaultColor());
158 
159 
160 
161 }
162 
~DXClusterWidget()163 DXClusterWidget::~DXClusterWidget()
164 {
165        //qDebug() << "DXClusterWidget::~DXClusterWidget" << QT_ENDL;
166 }
167 
168 
slotClusterDXClusterWidgetItemDoubleClicked(QListWidgetItem * item)169 void DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked( QListWidgetItem * item )
170 {
171       //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: " << item->text() << QT_ENDL;
172 
173     QStringList ql;
174     ql.clear();
175 
176     if (item)
177     {
178         ql = readItem(item);
179            //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: Length: " << QString::number(ql.length())  << QT_ENDL;
180         if (ql.length()==2)
181         {
182             ql << "double";
183                //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: EMMITED"  << QT_ENDL;
184             emit dxspotclicked(ql);
185         }
186         else
187         {
188                //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: NOT EMMITED-1"  << QT_ENDL;
189         }
190     }
191     else
192     {
193            //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: NOT EMMITED-2 (no item)"  << QT_ENDL;
194     }
195 
196 }
197 
connectToDXCluster()198 void DXClusterWidget::connectToDXCluster()
199 {
200        //qDebug() << "DXClusterWidget::connectToDXCluster" << QT_ENDL;
201     if (dxClusterConnected)
202     {
203            //qDebug() << "DXClusterWidget::connectToDXCluster: - Already connected!!" << QT_ENDL;
204         return; // If we are connected we don't want to start another connection
205     }
206 
207     connect(tcpSocket, SIGNAL(connected()), SLOT(slotClusterSocketConnected()) );
208     connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(slotClusterDataArrived() ));
209     connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotClusterDisplayError(QAbstractSocket::SocketError)));
210     connect(tcpSocket, SIGNAL(disconnected()), SLOT(slotClusterSocketConnectionClosed()) );
211     connect(inputCommand, SIGNAL(returnPressed()), this, SLOT(slotClusterSendToServer()) );
212     connect(clearButton, SIGNAL(clicked()), this, SLOT(slotClusterClearLineInput()) );
213     //openFile(); // This functions opens the file to save the DX-Cluster activity. The file will be closed when the DX is disconnected.
214     tcpSocket->connectToHost( server, port );
215     dxClusterListWidget->setSortingEnabled (false);
216 
217     //dxClusterSpotItem * item = new dxClusterSpotItem(dxClusterListWidget, tr("Trying to connect to the server") + "\n", awards->getDefaultColor());
218     dxClusterListWidget->addItem (new dxClusterSpotItem(dxClusterListWidget, tr("Trying to connect to the server") + "\n", awards->getDefaultColor()));
219 
220 
221 }
222 
223 
slotClusterDisplayError(QAbstractSocket::SocketError socketError)224 void DXClusterWidget::slotClusterDisplayError(QAbstractSocket::SocketError socketError)
225 {
226        //qDebug() << "DXClusterWidget:displayError:" << QT_ENDL;
227      switch (socketError) {
228      case QAbstractSocket::RemoteHostClosedError:
229          break;
230      case QAbstractSocket::HostNotFoundError:
231          QMessageBox::warning(this, tr("KLog DXCluster"),
232                                   tr("The host was not found. Please check:") + "\n\n" +
233                                      tr ("- your network connection;\n"
234                                      "- the host name and port settings."));
235          break;
236      case QAbstractSocket::ConnectionRefusedError:
237          QMessageBox::warning(this, tr("KLog DXCluster"),
238                                   tr("The connection was refused by the peer. "
239                                      "Make sure the DXCluster server is running, "
240                                      "and check that the host name and port "
241                                      "settings are correct."));
242          break;
243      default:
244          QMessageBox::warning(this, tr("KLog DXCluster"),
245                                   tr("The following error occurred: %1.")
246                                   .arg(tcpSocket->errorString()));
247      }
248 
249  }
250 
checkIfNeedsToBePrinted(const QString & _DXEntity,int const _band,const int _mode)251 bool DXClusterWidget::checkIfNeedsToBePrinted(const QString &_DXEntity, int const _band, const int _mode)
252 {
253       //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: " << _DXEntity << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< QT_ENDL;
254     QStringList qs;
255     qs.clear();
256     qs << _DXEntity << QString::number(_band) << QString::number(_mode)  << QString::number(currentLog);
257     //bool isConfirmed = false;
258     bool status = awards->isThisSpotConfirmed (qs);
259 
260       //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: Status: " << _DXEntity << "/" << QString::number(status);
261 
262     if (!showconfirmed)
263     {
264           //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is confirmed? ("<< QString::number(status)<< ")" << QT_ENDL;
265         if (status)
266         {
267               //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: It is confirmed: DON'T' print: " << _DXEntity <<"/" << dataProxy->getNameFromBandId(_band) << QT_ENDL;
268             return false;
269         }
270     }
271 
272     if (!showhf)
273     {
274           //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is HF?" << QT_ENDL;
275         if (dataProxy->isHF(_band))
276         {
277               //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: Not showing HF but... is it WARC?" << QT_ENDL;
278             if ( (showwarc) && dataProxy->isWARC(_band) )
279             {
280                   //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: Not showing HF but... is WARC, print!" << QT_ENDL;
281                 return true;
282             }
283 
284               //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is HF: DON'T print: "<< _DXEntity << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< QT_ENDL;
285             return false;
286         }
287         else
288         {
289               //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is NOT HF" << QT_ENDL;
290         }
291     }
292 
293     if (!showwarc)
294     {
295           //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is WARC?" << QT_ENDL;
296         if (dataProxy->isWARC(_band))
297         {
298               //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is WARC, DON'T print: "<< _DXEntity << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< QT_ENDL;
299             return false;
300         }
301         else
302         {
303               //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is NOT WARC" << QT_ENDL;
304         }
305     }
306 
307     if (!showvhf)
308     {
309            //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is VHF?" << QT_ENDL;
310         if (dataProxy->isVHF(_band))
311         {
312                //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is VHF, DON'T print: "<< _DXEntity << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< QT_ENDL;
313             return false;
314         }
315         else
316         {
317                //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is NOT VHF " << QT_ENDL;
318         }
319     }
320        //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: returns TRUE and will be printed: " << _DXEntity << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< QT_ENDL;
321     return true;
322 }
323 
setCurrentLog(const int _log)324 void DXClusterWidget::setCurrentLog(const int _log)
325 {
326     if (dataProxy->doesThisLogExist(_log))
327     {
328         currentLog = _log;
329     }
330     else
331     {
332         currentLog = -1;
333     }
334 
335 }
336 
slotClusterDataArrived()337 void DXClusterWidget::slotClusterDataArrived()
338 {
339       //qDebug() << "DXClusterWidget::slotClusterDataArrived" << QT_ENDL;
340     QStringList qs;
341     QString dxClusterString;
342     QString dxCall;
343     QString dxFrequency;
344     QString spotBand;
345     spotBand = "-1";
346     //bool isADXSpot = false;
347     int dxEntity = -1;
348 
349     while ( tcpSocket->canReadLine() )
350     {
351         dxClusterString =  tcpSocket->readLine();
352         dxClusterString = dxClusterString.trimmed();
353         // Remove BELL-string if exists
354         dxClusterString = dxClusterString.remove("\a");
355         saveSpot(dxClusterString);
356 
357         QStringList tokens = dxClusterString.split(" ", QT_SKIP);
358         if (tokens.size()<2){
359             return;
360         }
361         // It is a "DX de SP0TTER FREC DXCALL"
362         //0 = DX, 1 = de, 2 = spotter, 3 = Freq, 4 = dxcall, 5 = comment
363           //qDebug() << "DXClusterWidget::slotClusterDataArrived: " << "DXCLUSTER->" << dxClusterString << "\nTOKENS: " << tokens << QT_ENDL;
364 
365         if ((tokens[0] == "DX") && (tokens[1] == "de"))
366         {
367               //qDebug() << "******************** DXClusterWidget::slotClusterDataArrived: DX DE" << QT_ENDL;
368             //isADXSpot = true;
369             QString spotter = tokens[2];
370             spotter.truncate(spotter.size() - 1);
371             dxFrequency = tokens[3];
372             // Convert KHz to MHz...
373             //dxFrequency = QString::number(abs (dxFrequency.toFloat())/1000);
374             dxFrequency = QString::number( (dxFrequency.toDouble())/1000);
375             dxCall = tokens[4];
376             dxEntity = world->getQRZARRLId(dxCall);
377             //
378             spotBand = QString::number(dataProxy->getBandIdFromFreq(  dxFrequency.toDouble()  ) );
379 
380 
381             qs.clear();
382             //spotBand = QString::number(world->getBandIdFromFreq(  dxFrequency  ) );
383             qs << QString::number(dxEntity) << spotBand << "-1" << QString::number(currentLog) ;
384                //qDebug() << "DXClusterWidget::slotClusterDataArrived: Calling-2: " << QString::number(dxEntity) << QT_ENDL;
385             dxSpotColor = awards->getQRZDXStatusColor(qs);
386             if  (showDxMarathon)
387             {
388                 if (awards->isDXMarathonNeed(dxEntity, world->getQRZCqz(dxCall), QDateTime::currentDateTime().date().year(), currentLog))
389                 {
390                     dxClusterString = dxClusterString + "  ### Needed for DXMarathon - " + QString::number(QDateTime::currentDateTime().date().year()) + " ###";
391                 }
392             }
393 
394 
395               //qDebug() << "DX de ->" << "Spotter: " << spotter << "Freq: "<< dxFrequency << "DX: " << dxCall << QT_ENDL;
396 
397         }
398         else if ((tokens[0] == "To") && (tokens[1] == "ALL"))
399         {
400               //qDebug() << "DXClusterWidget::slotClusterDataArrived: TO ALL" << QT_ENDL;
401             dxSpotColor = awards->getDefaultColor();
402         }
403         else if ( (dxClusterString.length()>=5) && (world->checkQRZValidFormat(tokens[1])) && (tokens[0]!="login:"))
404         { // Freq / DXCall / Date // time
405            //_qs << QRZ << Freq in MHz << lognumber;
406              //qDebug() << "DXClusterWidget::slotClusterDataArrived: LENGTH >= 5" << QT_ENDL;
407              //qDebug() << "DXClusterWidget::slotClusterDataArrived: token0=" << tokens[0] << " / token1=" << tokens[1] << QT_ENDL;
408 
409             //isADXSpot = true;
410             dxCall = tokens[1];
411             dxFrequency = tokens[0];
412             dxFrequency = QString::number( (dxFrequency.toDouble())/1000);
413 
414             qs.clear();
415             spotBand = QString::number(dataProxy->getBandIdFromFreq(  dxFrequency.toDouble()  ) );
416             dxEntity = world->getQRZARRLId(dxCall);
417                //qDebug() << "DXClusterWidget::slotClusterDataArrived: Calling-1: " << QString::number(dxEntity) << QT_ENDL;
418             qs << QString::number(dxEntity) << spotBand << "-1" << QString::number(currentLog) ;
419             dxSpotColor = awards->getQRZDXStatusColor(qs);
420             if (showDxMarathon)
421             {
422                 if (awards->isDXMarathonNeed(dxEntity, world->getQRZCqz(dxCall), QDateTime::currentDateTime().date().year(), currentLog))
423                 {
424                     dxClusterString = dxClusterString + "  ### Needed for DXMarathon - " + QString::number(QDateTime::currentDateTime().date().year()) + " ###";
425                 }
426             }
427 
428 
429         }
430         else
431         {
432                //qDebug() << "DXClusterWidget::slotClusterDataArrived: DEFAULT" << QT_ENDL;
433             dxSpotColor = awards->getDefaultColor();
434         }
435 
436       //  qs.clear();
437         //spotBand = QString::number(world->getBandIdFromFreq(  dxFrequency  ) );
438         //qs << dxCall << spotBand << "0";
439 
440         //dxSpotColor = awards->getQRZDXStatusColor(qs);
441            //qDebug() << "DXClusterWidget::slotClusterDataArrived: Call/dxSpotColor: " << dxCall <<"/"<< dxSpotColor.name() << QT_ENDL;
442         //dxClusterSpotItem * item = new dxClusterSpotItem(dxClusterListWidget, dxClusterString, dxSpotColor);
443         //TODO: Change the "-1" by the mode
444         if (!checkIfNeedsToBePrinted(QString::number(dxEntity), spotBand.toInt(), -1))
445         {
446               //qDebug() << "DXClusterWidget::slotClusterDataArrived - Not to be printed!: " << dxCall << QT_ENDL;
447             return;
448         }
449 
450 //        QString flagSt;
451 //        QString aux;
452 
453         QListWidgetItem *item = new QListWidgetItem();
454         item->setForeground(QBrush(dxSpotColor));
455         item->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
456         item->setText(dxClusterString);
457 
458 /*
459         if (dxEntity>0)
460         {
461             flagSt.clear();
462 
463             aux = dataProxy->getISOName(dxEntity);
464             if (aux.length()>1)
465             {
466                 flagSt = ":/" + aux + ".png";
467             }
468             else
469             {
470                 flagSt.clear();
471             }
472 
473             flagSt = ":/flags/" + dataProxy->getISOName(dxEntity) + ".png";
474             QIcon flagIcon(flagSt);
475             item->setIcon(flagIcon);
476 
477         }
478 */
479         dxClusterListWidget->insertItem(0,item);
480 
481         //dxClusterListWidget->insertItem(0,item);
482         //QListWidgetItem *item = new QListWidgetItem();
483         //item->setForeground(QBrush(awards->getQRZDXStatusColor(qs)));
484         //item->setText(dxClusterString);
485         //dxClusterListWidget->insertItem(0,item);
486     }
487 
488        //qDebug() << "--------------------- DXClusterWidget::slotClusterDataArrived: " << dxClusterString << QT_ENDL;
489 
490       //qDebug() << "DXClusterWidget::slotClusterDataArrived: " << dxClusterString << QT_ENDL;
491 
492 }
493 
slotClusterSocketConnected()494 void DXClusterWidget::slotClusterSocketConnected()
495 {
496        //qDebug() << "DXClusterWidget::slotClusterSocketConnected" << QT_ENDL;
497 
498     QListWidgetItem *item = new QListWidgetItem();
499     item->setForeground(QBrush(awards->getDefaultColor()));
500     item->setText(tr("Connected to server"));
501     dxClusterListWidget->insertItem(0,item);
502 
503 
504 //    dxClusterSpotItem * item = new dxClusterSpotItem(dxclusterListWidget, i18n("Connected to server"), awards->getDefaultColor());
505     dxClusterConnected = true;
506     inputCommand->setFocus(Qt::OtherFocusReason);
507 
508     if (( dxClusterConnected ) && (!dxClusterAlreadyConnected) ){
509         bool ok;
510         QString callsignText;
511         if (myQrz.length()>2)
512         {
513             callsignText = QInputDialog::getText(this, tr("KLog message"), tr("Enter your callsign to connect to the cluster:"), QLineEdit::Normal, myQrz, &ok);
514         }
515         else
516         {
517             callsignText = QInputDialog::getText(this, tr("KLog message"), tr("Enter your callsign to connect to the cluster:"), QLineEdit::Normal, "", &ok);
518         }
519 
520         //QString callsignText = QInputDialog::getText(this, tr("KLog message"), tr("Enter your callsign to connect to the cluster:"), QLineEdit::Normal, "", &ok);
521         QString passwordText = QInputDialog::getText(this, tr("KLog message"), tr("Enter your password to connect to the cluster:\n(Just hit enter for no password)"), QLineEdit::Normal, "", &ok);
522         QTextStream os(tcpSocket);
523         if ( callsignText.length() > 2 && ok ) {
524             os << callsignText << "\n";
525         //TODO: Check the DXCluster answer and enter the password if needed.
526             sendButton->setText(tr("Disconnect"));
527             clearButton->setText(tr("Clear"));
528             dxClusterAlreadyConnected = true;
529         } else {
530             os << tr("Not logged on, you may need to enter your callsign again.") << "\n";
531             dxClusterAlreadyConnected = false;
532         }
533         inputCommand->setEnabled(true);
534         inputCommand->setToolTip(tr("Enter here the commands to be sent to the DX-Cluster server."));
535 
536     }
537 }
538 
slotClusterSocketConnectionClosed()539 void DXClusterWidget::slotClusterSocketConnectionClosed()
540 {
541        //qDebug() << "DXClusterWidget::slotClusterSocketConnectionClosed" << QT_ENDL;
542     QListWidgetItem *item = new QListWidgetItem();
543     item->setForeground(QBrush(awards->getDefaultColor()));
544     item->setText(tr("Connection closed by the server"));
545     dxClusterListWidget->insertItem(0,item);
546     dxClusterConnected = false;
547     dxClusterAlreadyConnected = false;
548     sendButton->setText(tr("Connect"));
549     inputCommand->setDisabled(true);
550     inputCommand->setToolTip(tr("Click on Connect to connect to the DX-Cluster server."));
551     //connect(inputCommand, SIGNAL(returnPressed()), this, SLOT(slotClusterSendToServer()) );
552     disconnect (inputCommand, SIGNAL(returnPressed()), this, SLOT(slotClusterSendToServer()) );
553 }
554 
slotClusterSendToServer()555 void DXClusterWidget::slotClusterSendToServer()
556 {
557        //qDebug() << "DXClusterWidget::slotClusterSendToServer()" << QT_ENDL;
558     if (!dxClusterConnected)
559     {
560 
561         connectToDXCluster();
562         return; // If we try to connect...
563     }
564     if (( inputCommand ->text().length() < 1 ) && ( sendButton->text() == tr("Disconnect") ) )
565     {
566 
567         //qDebug() << "DXClusterWidget::slotClusterSendToServer() - Disconnecting" << QT_ENDL;
568         QTextStream os(tcpSocket);
569         os << "bye\n";
570         return;
571     }
572     else if ( inputCommand ->text().length() < 1 )
573     {
574         //qDebug() << "DXClusterWidget::slotClusterSendToServer() - Empty" << QT_ENDL;
575         return;
576     }
577 
578 
579     //  write to the server
580     QTextStream os(tcpSocket);
581     os << inputCommand ->text() << "\n";
582     inputCommand ->clear();
583 }
584 
slotClusterClearLineInput()585 void DXClusterWidget::slotClusterClearLineInput()
586 {
587        //qDebug() << "DXClusterWidget::slotClusterClearLineInput" << QT_ENDL;
588 
589     inputCommand->clear();
590 }
591 
slotClusterInputTextChanged()592 void DXClusterWidget::slotClusterInputTextChanged()
593 {
594        //qDebug() << "DXClusterWidget::slotClusterInputTextChanged" << QT_ENDL;
595 
596     if ( ((inputCommand->text()).length()) <= 0 )
597     {
598         sendButton->setText(tr("Disconnect"));
599         clearButton->setText(tr("Clear"));
600     }
601     else if (dxClusterConnected)
602     {
603         sendButton->setText(tr("Send"));
604         clearButton->setText(tr("Clear"));
605     }
606     else
607     {}
608 }
609 
setColors(const QString & _newOne,const QString & _needed,const QString & _worked,const QString & _confirmed,const QString & _default)610 void DXClusterWidget::setColors (const QString &_newOne, const QString &_needed, const QString &_worked, const QString &_confirmed, const QString &_default)
611 {
612        //qDebug() << "DXClusterWidget::setColors: " << _newOne << "/" << _needed << "/" << _worked << "/" << _confirmed << "/" << _default << QT_ENDL;
613     // Just to pass the colors to the awards class
614     awards->setColors(_newOne,  _needed, _worked,  _confirmed, _default);
615 
616 }
617 
setDXClusterSpotConfig(bool _showhf,bool _showvhf,bool _showwarc,bool _showworked,bool _showconfirmed,bool _showann,bool _showwwv,bool _showwcy)618 void DXClusterWidget::setDXClusterSpotConfig(bool _showhf, bool _showvhf, bool _showwarc, bool _showworked, bool _showconfirmed, bool _showann, bool _showwwv, bool _showwcy )
619 {
620        //qDebug() << "DXClusterWidget::setDXClusterSpotConfig " << QT_ENDL;
621 
622     showhf = _showhf;
623     showvhf = _showvhf;
624     showwarc = _showwarc;
625     showworked = _showworked;
626     showconfirmed = _showconfirmed;
627     showann = _showann;
628     showwwv = _showwwv;
629     showwcy = _showwcy;
630 }
631 
slotClusterDXClusterWidgetItemSelected()632 void DXClusterWidget::slotClusterDXClusterWidgetItemSelected()
633 {
634        //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemSelected " << QT_ENDL;
635     QListWidgetItem * item = dxClusterListWidget->currentItem();
636 
637     QStringList ql;
638     ql.clear();
639 
640     ql = readItem(item);
641     if (ql.length()==2)
642     {
643         ql << "selected";
644         emit dxspotclicked(ql);
645     }
646     else
647     {
648     }
649 
650 }
651 
slotClusterDXClusterWidgetItemEntered(QListWidgetItem * item)652 void DXClusterWidget::slotClusterDXClusterWidgetItemEntered( QListWidgetItem * item )
653 {
654        //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemEntered" << QT_ENDL;
655 /*
656     This code comes from slotClusterDXClusterWidgetItemDoubleClicked
657 */
658     QString tip;
659     tip.clear();
660     QStringList ql;
661     ql.clear();
662 
663     if (item)
664     {
665         ql = readItem(item);
666         if (ql.length()==2)
667         {
668             tip = world->getQRZEntityName(ql.at(0));
669             item->setToolTip(tip);
670         }
671         else
672         {
673         }
674     }
675     else
676     {
677     }
678 
679 }
680 
681 
isConnected()682 bool DXClusterWidget::isConnected()
683 {
684     return dxClusterConnected;
685 }
686 
readItem(QListWidgetItem * item)687 QStringList DXClusterWidget::readItem(QListWidgetItem * item)
688 {
689       //qDebug() << "DXClusterWidget::readItem" << QT_ENDL;
690 
691     QStringList fields;
692     QString dxClusterString;
693     //int currentEntity;
694     QString dxCallsign, dxFreq;
695     bool FirstFrecOK;
696 
697     if (item) {
698 
699         fields.clear();
700         dxClusterString = ((item->data(0)).toString()).simplified();
701         fields << dxClusterString.split(" ");
702 
703         (fields.at(0)).toFloat(&FirstFrecOK); // Just to see if the first string is a frecuency
704 
705         if ( (fields.at(0) == "DX" ) && (fields.at(1) == "de" ) )
706         { // DX de EA0XXX: 21200.1 EA0K The comment 1550
707 
708             if ( world->getQRZARRLId(fields.at(4))> 0 )
709             {
710                    //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: ARRLid: " << QString::number(world->getQRZARRLId(fields.at(4)))  << QT_ENDL;
711                 dxCallsign = (fields.at(4)).toUpper();
712                 (fields.at(3)).toFloat(&FirstFrecOK);
713                 if (FirstFrecOK)
714                 { // The frecuency is valid
715                     dxFreq = fields.at(3);
716                     fields.clear();
717                     //TODO: Change FREQ into bandId
718                     fields << dxCallsign << dxFreq;
719                     return fields;
720 
721                 }
722                 else
723                 { // the frecuency is not a number!
724                     dxCallsign.clear();
725                     dxFreq.clear();
726                     fields.clear();
727                 }
728             }
729             else
730             { // The callsign is not from a valid country
731               // TODO: if it is from a new entity/prefix it would not work.
732                    //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: Entity not valid"  << QT_ENDL;
733                 dxCallsign.clear();
734                 dxFreq.clear();
735                 fields.clear();
736             }
737         }
738         //else if (( isAFrecuency(fields.at(0) ) ) && ( isACall(fields.at(1)) ) )
739         else if ( (((fields.at(0)).toDouble()) > 0.0 )&& ( world->getQRZARRLId(fields.at(1))> 0 ) )
740         { // 14205.0 EA0K   5-Mar-2012 1500Z    <EA0XXX>
741 
742             dxCallsign = (fields.at(1)).toUpper();
743             dxFreq = fields.at(0);
744             fields.clear();
745             fields << dxCallsign << dxFreq;
746             return fields;
747         }
748         else
749         {
750             dxCallsign.clear();
751             dxFreq.clear();
752             fields.clear();
753         }
754     }
755     else
756     {  // No Item
757     }
758 
759     return fields;
760 
761 }
762 
setDXClusterServer(const QString & clusterToConnect,const int portToConnect)763 void DXClusterWidget::setDXClusterServer(const QString &clusterToConnect, const int portToConnect)
764 {
765     server = clusterToConnect;
766     port = quint16(portToConnect);
767        //qDebug() << "DXClusterWidget::setDXClusterServer: " << server << ":"<< QString::number(port)  << QT_ENDL;
768 }
769 
setDXMarathon(const bool _enable)770 void DXClusterWidget::setDXMarathon (const bool _enable)
771 {
772     showDxMarathon = _enable;
773 }
774 
setSaveSpots(const bool _enable)775 void  DXClusterWidget::setSaveSpots (const bool _enable)
776 {
777     saveSpots = _enable;
778 }
779 
openFile()780 bool DXClusterWidget::openFile()
781 {
782     if (saveSpotsFile->isOpen())
783     {
784         return true;
785     }
786     if (!saveSpotsFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) /* Flawfinder: ignore */
787     {
788         QMessageBox msgBox;
789         msgBox.setIcon(QMessageBox::Warning);
790         QString aux = tr("It was not possible to open the file to save the DX-Spots for writing. DX-Cluster activity will not be saved!");
791         msgBox.setText(aux);
792         msgBox.setStandardButtons(QMessageBox::Ok);
793         msgBox.setDefaultButton(QMessageBox::Ok);
794         msgBox.exec();
795         return false;
796     }
797     else
798     {
799         return true;
800     }
801 }
802 
saveSpot(const QString & _spot)803 void DXClusterWidget::saveSpot(const QString &_spot)
804 {
805       //qDebug() << "DXClusterWidget::saveSpot: " << _spot  << QT_ENDL;
806     if (!saveSpots)
807     {
808           //qDebug() << "DXClusterWidget::saveSpot: Not saving" << QT_ENDL;
809         return;
810     }
811     else
812     {
813         if (openFile())
814         {
815               //qDebug() << "DXClusterWidget::saveSpot: File Open" << QT_ENDL;
816             QTextStream out(saveSpotsFile);
817 
818             out << util->getDateTimeSQLiteStringFromDateTime(QDateTime::currentDateTime()) << " - " << _spot  << QT_ENDL;
819             saveSpotsFile->close();
820         }
821         else {
822             {
823                   //qDebug() << "DXClusterWidget::saveSpot: File NOT Open" << QT_ENDL;
824             }
825         }
826     }
827 }
828 
829 /*
830 void DXClusterWidget::TESTADDSPOT()
831 {
832        //qDebug() << "DXClusterWidget::TESTADDSPOT "   << QT_ENDL;
833     ; // Just a test spot
834     QListWidgetItem *item = new QListWidgetItem();
835     item->setForeground(QBrush(dxSpotColor));
836     item->setText("DX de SP0TTER 14.000 DX1CALL");
837     dxClusterListWidget->insertItem(0,item);
838 }
839 */
840 
841 
842 
843 
844 /***************************************************************************
845 ** This is an auxiliary class intended to provide color to the DX-Cluster **
846 ** spots.                                                                 **
847 ** It may be moved to a self .h & .cpp archives                           **
848 ****************************************************************************/
dxClusterSpotItem(QListWidget * parent,const QString & spot,const QColor & color)849 dxClusterSpotItem::dxClusterSpotItem( QListWidget *parent, const QString& spot, const QColor& color ) : QListWidgetItem( parent ){
850        //qDebug() << "dxClusterSpotItem::dxClusterSpotItem - Constructor" << QT_ENDL;
851     spotColor = color;
852     setText(spot);
853     // Experimenting with fonts for the cluster
854     QFont f("Helvetica");
855     f.setFixedPitch(true);
856     setFont(f);
857 }
858 
~dxClusterSpotItem()859 dxClusterSpotItem::~dxClusterSpotItem()
860 {
861        //qDebug() << "dxClusterSpotItem::dxClusterSpotItem - Destructor" << QT_ENDL;
862 }
863 
864