klog-0.9.2.9/0000755000076700000620000000000013237613540010577 5ustar staffklog-0.9.2.9/setuppagelogs.h0000644000076700000620000001213513233376355013642 0ustar staff#ifndef SETUPPAGELOGS_H #define SETUPPAGELOGS_H /*************************************************************************** setuppagelogs.h - description ------------------- begin : feb 2012 copyright : (C) 2012 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include #include #include #include "dataproxy.h" #include "setuppagelogsnew.h" const int CONTEST_DX = 0; const int CONTEST_CQ_WW_SSB = 1; const int CONTEST_CQ_WW_CW = 2; const int CONTEST_CQ_WPX_SSB = 3; const int CONTEST_CQ_WPX_CW = 4; class SetupPageLogs : public QWidget { Q_OBJECT public: SetupPageLogs(DataProxy *dp, QWidget *parent=0); ~SetupPageLogs(); int getSelectedLog(); void setSelectedLog(const int _i); void createNewLog(); void setDefaultStationCallsign (const QString _p); void setDefaultOperators(const QString _p); /* QString getBands(); // 10m, 12m, 15m QString getModes(); //ssb, CW void setActiveBands(QStringList q); void setActiveModes(QStringList q); */ private slots: /* void slotBandActiveItemDoubleClicked ( QListWidgetItem * item ); void slotBandNotActiveItemDoubleClicked ( QListWidgetItem * item ); void slotBandSelButtonClicked( ); void slotBandUnSelButtonClicked( ); void slotModeSelButtonClicked( ); void slotModeUnSelButtonClicked( ); */ void slotNewButtonClicked(); void slotEditButtonClicked(); void slotRemoveButtonClicked(); void slotAnalyzeNewLogData(const QStringList _qs); void slotLogSelected(const QModelIndex & index); void slotLogDoubleClicked(const QModelIndex & index); void slotLogsCancelled(const bool _q); //void slotCreateLog(); // signals: //void exitSignal(const int status); // 1 = OK, -1 = NOK, 2 = Cancel clicked void newLogData(const QStringList _qs); // Station QRZ + Operators to be shown in the main tab void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution private: //void createActions(); QStringList readLogs(); void createLogsPanel(); void createLogsModel(); void createActions(); //bool addNewLog(const QStringList _qs); void updateSelectedLogs(); void readSelectedLog(const int _i); void showError(const QString _errorC); /* Wizard to create a new log*/ //QWizardPage *createLogTypePage(); //QWizard *newLogWizard; // Wizard to create a new log /*^Wizard to create a new log^*/ QSqlRelationalTableModel *logsModel; QWidget *logsPanel; QTableView *logsView; QAbstractButton *finishButton; //QWidget *logsWidget; //QTreeWidget *logsQTreeWidget; //QListWidget *bandsNotActiveListWidget, *bandsActiveListWidget; //QListWidget *modesNotActiveListWidget, *modesActiveListWidget; //QStringList bands, modes; QPushButton *newLogPushButton, *editPushButton, *removePushButton; //*loadAllPushButton, *loadSelectedPushButton, *clearPushButton,; int lastLog; QString currentLogComment; QString currentStationCallSign; QComboBox *currentLogs; QStringList logsAvailable; SetupPageLogsNew *newLog; QString stationCallsign, operators, comment, dateString, typeContest; int contestCatMode, contestCatOperators, contestCatAssisted, contestCatPower, contestCatBands, contestBands, typeContestN; DataProxy *dataProxy; int selectedLog; QString defaultStationCallSign, defaultOperators; }; #endif // SETUPPAGELOGS_H klog-0.9.2.9/setuppageuserdata.h0000644000076700000620000001226213233376355014507 0ustar staff#ifndef SETUPPAGEUSERDATA_H #define SETUPPAGEUSERDATA_H /*************************************************************************** setuppageuserdata.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include //#include #include "world.h" #include "locator.h" #include "dataproxy.h" class SetupPageUserDataPage : public QWidget { Q_OBJECT public: SetupPageUserDataPage(DataProxy *dp, QWidget *parent=0); ~SetupPageUserDataPage(); QString getStationQrz(); QString getOperators(); QString getStationLocator(); int getCQz(); int getITUz(); QString getName(); QStringList getAddress(); QString getAddress1(); QString getAddress2(); QString getAddress3(); QString getAddress4(); QString getCity(); QString getZipCode(); QString getProvince(); QString getCountry(); bool setName (const QString _aux); bool setAddress1 (const QString _aux); bool setAddress2 (const QString _aux); bool setAddress3 (const QString _aux); bool setAddress4 (const QString _aux); bool setAddress (const QStringList _aux); bool setCity (const QString _aux); bool setZipCode (const QString _aux); bool setProvince (const QString _aux); bool setCountry (const QString _aux); bool setStationQrz(const QString _qrz); bool setOperators(const QString _aux); bool setStationLocator(const QString _loc); bool setCQz(const int _cqz); bool setITUz(const int _ituz); QString getRig1(); QString getRig2(); QString getRig3(); QString getAntenna1(); QString getAntenna2(); QString getAntenna3(); QStringList getRigs(); QStringList getAntennas(); QString getPower(); bool setRigs(const QStringList _aux); bool setAntennas(const QStringList _aux); bool setPower(const QString _aux); bool setRig1 (const QString _aux); bool setRig2 (const QString _aux); bool setRig3 (const QString _aux); bool setAntenna1 (const QString _aux); bool setAntenna2 (const QString _aux); bool setAntenna3 (const QString _aux); signals: void stationCallSignal (const QString _p); void operatorsSignal (const QString _p); void enterKey(); private slots: void slotMyLocatorTextChanged(); void slotOperatorsChanged(); void slotEnterKeyPressed(); void slotQRZTextChanged(); // void slotContestOverLayChanged(int i); private: bool checkOperatorsLineQString(const QString _auxLine); QTabWidget *tabWidget; QLineEdit *qrzLineEdit; // Station Callsign QLineEdit *operatorsLineEdit; //Operators QLineEdit *cqzLineEdit; QLineEdit *ituzLineEdit; QLineEdit *myLocatorLineEdit; QLabel *myLocatorLabel; //Personal Tab QLineEdit *nameLineEdit; QTextEdit *addressTextEdit; QLineEdit *address1LineEdit; QLineEdit *address2LineEdit; QLineEdit *address3LineEdit; QLineEdit *address4LineEdit; QLineEdit *cityLineEdit; QLineEdit *zipLineEdit; QLineEdit *provinceLineEdit; QLineEdit *countryLineEdit; // Station Tab QLineEdit *rig1LineEdit; QLineEdit *rig2LineEdit; QLineEdit *rig3LineEdit; QLineEdit *ant1LineEdit; QLineEdit *ant2LineEdit; QLineEdit *ant3LineEdit; //QLineEdit *powerLineEdit; QDoubleSpinBox *myPowerSpinBox; QPalette *defaultPalette, *wrongPalette; QColor redColor; Locator *locator; World *world; DataProxy *dataProxy; bool operatorsOK; bool operatorOK; }; #endif // SETUPPAGEUSERDATA_H klog-0.9.2.9/setuppagecolors.h0000644000076700000620000000641013233376355014176 0ustar staff#ifndef SETUPPAGECOLORS_H #define SETUPPAGECOLORS_H /*************************************************************************** setuppagecolors.h - description ------------------- begin : nov 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include //#include #include class SetupPageColors : public QWidget { Q_OBJECT public: SetupPageColors(QWidget *parent=0); ~SetupPageColors(); QString getNewOneColor(); QString getNeededColor(); QString getWorkedColor(); QString getConfirmedColor(); QString getDefaultColor(); void setNewOneColor(const QString c); void setNeededColor(const QString c); void setWorkedColor(const QString c); void setConfirmedColor(const QString c); void setDefaultColor(const QString c); private slots: void slotNewOneColorButtonClicked(); void slotConfirmedColorButtonClicked(); void slotWorkedColorButtonClicked(); void slotNeededColorButtonClicked(); void slotDefaultColorButtonClicked(); private: QColor giveColor (QColor c); QPalette palette; QPushButton *newOneColorButton; // In ANY band QPushButton *neededColorButton; // In this band QPushButton *workedColorButton; // In this band QPushButton *confirmedColorButton; // In this band QPushButton *defaultColorButton; // In this band QColor color; /* 0 - New one. 1 - Worked but not confirmed: New one in this band. 2 - Worked but not confirmed: Worked in this band. 3 - Confirmed: New one in this band. 4 - Confirmed: Worked in this band. 5 - Confirmed: Confirmed in this band. */ }; #endif // SETUPPAGECOLORS_H klog-0.9.2.9/INSTALL-linux0000644000076700000620000000310213233376355012767 0ustar staffFollow these steps to build KLog. KLog requires Qt5 to be built. Currently, many distributions are still distributing Qt4 as a default Qt version so it may be needed that you install Qt5 to be able to build KLog in your system. install may depend on your distribution, however, check for similar names & versions and it will probably work :-) If you have any suggestion for this file, please contact me. (Contact details in the AUTHORS file). 1. Install the KLog dependencies - Install g++, make, qt5-qmake, qtbase5-dev & qttools5-dev packages In Debian it is done with: apt-get install g++ make qt5-qmake qtbase5-dev qttools5-dev In your distribution, you should know how to install new packages :-) Make sure you have qt5 available. You can do it with the qtchooser command. The output should be something like: user@debian:~$ qtchooser -l 4 5 default qt4-i386-linux-gnu qt4 qt5-i386-linux-gnu qt5 user@debian:~$ It should return the list of qt versions available, qt5 must be one of them. If qt5 is still not there, check your instalallation as one of the previous packages may be missing. 2.- Select the appropriate Qt version (Qt5) export QT_SELECT=qt5 3.- Untar klog tar xyzf klog-version.tar.gz enter the KLog directory cd klog-version 4.- Generate the Makefile qmake PREFIX=/usr/local KLog.pro 5. Make everything. make If everything goes OK, you should have the klog executable in the folder. 6.- To install KLog, execute the following from the root account. make install Now you are done. Just execute klog and enjoy! 73 klog-0.9.2.9/mainwindow.h0000644000076700000620000005207513233376355013143 0ustar staff#ifndef MAINWINDOW_H #define MAINWINDOW_H /*************************************************************************** mainwindow.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include #include #include #include #include "database.h" #include "setupdialog.h" //#include "helpaboutdialog.h" #include "aboutdialog.h" #include "world.h" #include "filemanager.h" #include "contest.h" #include "contest_cqwwdxssb.h" #include "dataproxy.h" #include "dataproxy_sqlite.h" #include "locator.h" #include "dxcluster.h" #include "awards.h" #include "mainwindowsattab.h" #include "mainwindowmydatatab.h" #include "mainwindowinputcomment.h" #include "mainwindowinputothers.h" #include "mainwindowinputeqsl.h" #include "mainwindowinputqsl.h" #include "elogclublog.h" #include "utilities.h" #include "downloadcty.h" #include "dxccstatuswidget.h" #include "softwareupdate.h" #include "logmodel.h" #include "logwindow.h" #include "searchwidget.h" #include "infowidget.h" #include "showerrordialog.h" class QTimer; class QDateTime; class QPushButton; class QLineEdit; class QComboBox; class QTimeEdit; class QDateEdit; //class QStatusBar; class QMenuBar; class QMenu; class QMessageBox; class QTextEdit; class QProgressDialog; class QPoint; class QGroupBox; class QTabWidget; class QFrame; class QTableView; class QLabel; enum { Log_Id = 0, Log_Name = 1, Log_BandId = 2, Log_ModeId = 3, Log_DateId = 4, Log_TimeId = 5 }; enum { DX = 0, NoContest = 0, CQ_WW_SSB = 1, CQ_WW_CW = 2, CQ_WPX_SSB = 3, CQ_WPX_CW = 4, CQ_WPX_RTTY = 5 }; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(const QString _klogDir, const QString tversion); ~MainWindow(); private slots: //void slotQueryErrorManagement(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); void slotQueryErrorManagement(QString functionFailed, QString errorCodeS, int errorCodeN, QString queryFailed); void slotQRZReturnPressed(); void slotQRZSpacePressed(); void slotQRZTextChanged(); void slotSRXTextChanged(); void slotSTXTextChanged(); void slotUpdateLocator(QString _loc); void slotLocatorTextChanged(); void slotMyLocatorTextChanged(); void slotFreqTXChanged(); void slotFreqRXChanged(); void slotSearchBoxTextChanged(); void slotSearchToolNeededQSLToSend(); void slotToolSearchRequestedQSLToSend(); void slotToolSearchNeededQSLPendingToReceive(); void slotToolSearchNeededQSLRequested(); void slotToolLoTWMarkAllQueuedThisLog(); void slotToolLoTWMarkAllQueued(); void slotToolLoTWMarkAllYesThisLog(); void slotToolLoTWMarkAllYes(); //void slotSearchExportButtonClicked(); //void slotSearchBoxSelectAllButtonClicked(); //void slotSearchClearButtonClicked(); //void slotSearchBoxSelectionChanged(); //void slotSearchBoxReSearchButtonClicked(); //void showMenuRightButtonSearchCreateActions(); //void righButtonSearchMenu(const int trow); void slotModeComboBoxChanged(); void slotBandComboBoxChanged(); //void slotIOTAComboBoxChanged(); void slotOperatingYearComboBoxChanged(); void slotOKButtonClicked(); void slotSpotItButtonClicked(); void slotClearButtonClicked(); void slotRefreshDXCCWidget(); void slotUpdateTime(); void slotLogWinShow(); void slotLogRefresh(); void slotScoreWinShow(); void slotQSODelete(const int _id); void slotShowAwards(); void slotUpdateStatusBar(const QString statusm); void slotSetup(const int _page=0); //void slotQsoDeleteFromSearch(); //void slotQSLSentViaBureauFromSearch(); //void slotQSLSentViaDirectFromSearch(); //void slotQSLSentViaDirectMarkDXReqFromSearch(); //void slotQSLSentViaBureuMarkDXReqFromSearch(); //void slotQSLRecViaDirectFromSearch(); //void slotQSLRecViaBureauFromSearch(); //void slotQSLRecViaDirectMarkReqFromSearch(); //void slotQSLRecViaBureauMarkReqFromSearch(); //void slotQSLSentMarkAsRequested(); //void slotQSLRecMarkAsRequested(); //void slotQSOToEditFromSearch(); void slotrstTXTextChanged(); void slotrstRXTextChanged(); void slotADIFExport(); void slotLoTWImport(); void slotLoTWExport(); void slotADIFExportAll(); void slotADIFImport(); void slotRQSLExport(); void slotCabrilloExport(); //void slotQSLViaTextChanged(); //TODO: REMOVE EQSL //void slotQSLRecvComboBoxChanged(); //void slotQSLSentComboBoxChanged(); //void sloteQSLRecvComboBoxChanged(); //void sloteQSLSentComboBoxChanged(); //void slotLotwRecvComboBoxChanged(); //void slotLotwSentComboBoxChanged(); void slotSetPropMode(const QString _p); void slotFillEmptyDXCCInTheLog(); void slotUpdateCTYDAT(); void slotWorldReload(); void slotExitFromSlotDialog(const int exitID); //void slotDownloadFinished(QNetworkReply *reply); void fillQSOData(); void newFile(); void openFile(); bool saveFile(const QString _fileName); bool saveFileAs(); bool slotOpenKLogFolder(); void slotFilePrint(); //void slotFileClose(); //void slotHelpHelpAction(); void slotHelpAboutAction(); void slotHelpCheckUpdatesAction(); void slotAboutQt(); void slotRecalculateAwardsButtonClicked(); // logpanel //void slotRighButtonFromLog( const QPoint& pos); void slotDoubleClickLog( const int _qsoID); //void slotDoubleClickLog( const QModelIndex & index); //SEARCH void slotShowSearchWidget(); // The SearchWidget request being shown //void slotDoubleClickSearch( QTreeWidgetItem* item, int); // Double click on a QSO in the search box //void slotRighButtonSearch(const QPoint& pos); //void slotToolSearchNeededQSLToSend(); //void slotToolSearchNeededQSLPendingToReceive(); //void slotToolSearchNeededQSLRequested(); //void slotToolSearchQSL(const int actionQSL); //SEARCH // CLUSTER void slotAnalyzeDxClusterSignal(const QStringList _qs); // CLUSTER //CLUBLOG void slotElogClubLogShowMessage(const QString _s); void slotElogClubLogProcessAnswer(const int _i, const int _qID); void slotElogClubLogDisable(const bool _b); //CLUBLOG void slotShowSoftUpdateResults(const bool _b); // Software Update: Receives the signal to see if it is needed or not to update //SATELLITE void slotSatBandTXComboBoxChanged(const QString _q); void slotDefineNewBands(const QStringList _bands); void slotChangeRXFreq(const QString _f); void slotChangeTXFreq(const QString _f); private: bool maybeSave(); //UPDATE CTY.DAT /* bool downloadCTYFile(); bool downloadCtyDatFile(); bool saveToDisk(const QString &filename, QIODevice *data); QString saveFileName(const QUrl &url); QNetworkAccessManager manager; QNetworkRequest request; */ // NEW DownLoadCTY *downloadcty; // void createStatusBar(); void createUI(); void createUICQWW(); void createUIDX(); //void createDXClusterUI(); void clearBandLabels(); void createMenusCommon(); void createMenusCQWW(); void createActionsCommon(); void createActionsCQWW(); void createActionsDX(); //void createlogPanel(); //void createlogModel(const int _i); void createScorePanel(); //void createSearchResultsPanel(); void initialContestModeConfiguration(); //void createKeyEvents(); bool readCtyFile(); //void righButtonFromLogMenu(const int trow); //void qslRecViaBureauMarkReq(const int _qsoId); //void qslRecViaDirectMarkReq(const int _qsoId); bool isQSLReceived(const int _qsoId); bool isQSLSent(const int _qsoId); bool validCharactersInCall(const QString _qrz); // Looks for SQLi and no valid chars in the QRZ QString readDataFromUI(); // Reads the QSO data from the UI and returns the SQL Query QString readDataFromUIDX(); QString readDataFromUIDXModifying(); //int getDXCCFromComboBox(); //QString getPropModeFromComboBox(); //QString readDataFromUICQWW(); void setAwardDXCC(const int _qsoId, bool modifying); // Adds or modify the status of a DXCC entity // data << dxcc(id) << band(id) << mode(id) << confirmed(0/1) << qsoid(id) << modify(0/1); void checkIfWorkedB4(const QString _qrz); bool checkContest(); void showStatusOfDXCC(const QStringList _qs); void showDXMarathonNeeded(const int _dxcc, const int _cqz, const int _year, const int _log); bool createConnection(); void createData(); bool processConfigLine(const QString _line); void readConfigData(); void defineStationCallsign(); QString selectStationCallsign(); void checkIfNewBandOrMode(); void readActiveBands (const QStringList actives); void readActiveModes (const QStringList actives); void qsoToEdit (const int _qso); //void showInfoFromLocators(const QString _loc1, const QString _loc2); //void clearInfoFromLocators(); void completeWithPreviousQSO(const QString _call); //void showQRZEntityInfo(const QString _qrz); //void showEntityInfo(const int _enti, int _cq=-1, int _itu=-1); //QString getStyleColorToLabelFromBand(const QString _b, const QString _q); // Band, Entity void showAwards(); void showDXMarathon(const int _year); void updateQSLRecAndSent(); double checkFreqRanges(double _f); //void selectCorrectComboBoxEntity(const int _ent); // Select the appropriate entity in the ComboBox //int Km2Mile(const bool _imperialSystemSelected, const bool _dataInMiles, const int _km); // CLUSTER void clusterSpotToLog(const QString _call, const QString _freq); QStringList dxclusterServersList; QString dxclusterServerToConnect; int dxclusterServerPort; // CLUSTER QWidget *mainWidget; //QWidget *dxClusterTabWidget;//, *searchTabWidget; World *world; FileManager *filemanager; Locator *locator; Awards *awards; Utilities *util; //WorldEditorWidget *worldEditor; //HelpHelpDialog *helpHelpDialog; //HelpAboutDialog *helpAboutDialog; AboutDialog *aboutDialog; QPushButton *addButton; //QLabel *distShortLabelN; //QLabel *distLongLabelN; DXCCStatusWidget *dxccStatusWidget; //QSqlRelationalTableModel *logModel; //QWidget *logPanel; //QTableView *logView; //QTreeWidget *searchResultsTreeWidget; QLabel *logLabel; QWidget *scoreWindow; //, dxWindow; QTextEdit *scoreTextEdit; LogModel *logModel; LogWindow *logWindow; ShowErrorDialog *showErrorDialog; // QGroupBox *gridGroupBox, *qrzgroupBox;//, *searchgroupBox; QFrame *dxUpLeftInputFrame;//, *dxUpRightOutputFrame; QLineEdit *qrzLineEdit, *nameLineEdit, *qthLineEdit, *locatorLineEdit; QComboBox *bandComboBox, *modeComboBox; QDateEdit *dateEdit; QTimeEdit *timeEdit; //QStatusBar *statusBar, *qsoStatusBar; QString statusBarMessage; QTabWidget *dxBottonTab, *dxUpLeftTab, *dxUpRightTab; QMenu *fileMenu; QMenu *toolMenu; QMenu *qslToolMenu; QMenu *lotwToolMenu; //QMenu *lotwMarkAllAsQueuedMenu; //QMenu *lotwMarkAllInThisLogAsQueuedMenu; QMenu *viewMenu; QMenu *setupMenu; QMenu *helpMenu; QAction *klogFolderAct; QAction *openAct; QAction *saveAct; QAction *exitAct; QAction *printLogAct; QAction *addAct; QAction *editAct; QAction *removeAct; QAction *logWinAct; QAction *setupAct; QAction *helpAct; QAction *aboutAct; QAction *aboutQtAct; QAction *updateAct; QAction *scoreWinAct; QAction *scoreeWinAct; QAction *ADIFExport; QAction *ADIFExportAll; QAction *ADIFImport; QAction *LoTWExport; QAction *LoTWImport; QAction *ReqQSLExport; QAction *CabrilloExport; QAction *fillQsoAct; QAction *fillDXCCAct; QAction *findQSO2QSLAct; QAction *findRequestedQSLAct; QAction *findQSLPendingToReceiveAct; QAction *findQSLDXRequestedAct; QAction *lotwMarkSentQueuedThisLogAct; QAction *lotwMarkSentQueuedAct; QAction *lotwMarkSentYesThisLogAct; QAction *lotwMarkSentYesAct; QAction *downloadCTYAct; QAction *loggWinAct; /* QAction *delQSOFromLogAct; QAction *qsoToEditFromLogAct; QAction *qslSentViaBureauFromLogAct; QAction *qslSentViaDirectFromLogAct; QAction *qslRecViaBureauFromLogAct; QAction *qslRecViaDirectFromLogAct; */ QAction *qslSentRequestedAct; QAction *qslRecRequestedAct; //QAction *delQSOFromSearchAct; //QAction *qsoToEditFromSearchAct; //QAction *qslSentViaBureauFromSearchAct; //QAction *qslSentViaDirectFromSearchAct; //QAction *qslSentViaDirectMarkRcvReqFromSearchAct; //QAction *qslSentViaBureauMarkRcvReqFromSearchAct; //QAction *qslRecViaBureauFromSearchAct; //QAction *qslRecViaDirectFromSearchAct; //QAction *qslRecViaBureauMarkReqFromSearchAct; //QAction *qslRecViaDirectMarkReqFromSearchAct; QLineEdit *rstTXLineEdit; QLineEdit *rstRXLineEdit; QLineEdit *STXLineEdit; QLineEdit *SRXLineEdit; QPushButton *OKButton, *spotItButton, *clearButton; QStringList bands; QStringList modes; QStringList entitiesList, propModeList; // UI DX //QLabel *entitySecLabel, *iotaAwardLabel, *entityNameLabel, *propModeLabel; //entityPrimLabel QLabel *infoLabel1, *infoLabel2; //QPushButton *flagIcon; // To paint a flag of the worked entity //QLabel *bandLabel1, *bandLabel2, *bandLabel3, *bandLabel4; //QLabel *bandLabel5, *bandLabel6, *bandLabel7, *bandLabel8; //QLabel *bandLabel9, *bandLabel10, *bandLabel11, *bandLabel12; //QLabel *continentLabel, *prefixLabel, *cqzLabel, *ituzLabel; //QLabel *gradShortLabel, *distShortLabel; //QLabel *gradLongLabel, *distLongLabel; //QComboBox *iotaContinentComboBox, *entityPrimDivComboBox, *entitySecDivComboBox, *entityNameComboBox, *propModeComboBox; QComboBox *operatingYearsComboBox; QLineEdit *operatorLineEdit, *stationCallSignLineEdit, *myLocatorLineEdit;//, *commentLineEdit, *iotaNumberLineEdit; QTextEdit *notesTextEdit; QDoubleSpinBox *rxPowerSpinBox, *txFreqSpinBox, *rxFreqSpinBox; //*myPowerSpinBox, QLCDNumber *freqQLCDNumber; QLCDNumber *dxccConfirmedQLCDNumber, *dxccWorkedQLCDNumber, *wazConfirmedQLCDNumber, *wazWorkedQLCDNumber, *localConfirmedQLCDNumber, *localWorkedQLCDNumber, *qsoConfirmedQLCDNumber, *qsoWorkedQLCDNumber, *dxMarathonQSOLCDNumber, *dxMarathonDXCCQLCDNumber, *dxMarathonCQQLCDNumber, *dxMarathonPointsQLCDNumber; //eQSL //QComboBox *eqslSentComboBox, *eqslRecComboBox, *lotwSentComboBox, *lotwRecComboBox, *clublogComboBox; //QDateEdit *eqslSentQDateEdit, *eqslRecQDateEdit, *lotwSentQDateEdit, *lotwRecQDateEdit, *clublogQDateEdit; //QComboBox *qslSentComboBox, *qslRecComboBox, *qslSentViaComboBox, *qslRecViaComboBox; //QDateEdit *qslSentQDateEdit, *qslRecQDateEdit; //QTextEdit *qslmsgTextEdit; //QLineEdit *qslViaLineEdit; //QLineEdit *searchBoxLineEdit; //QPushButton *searchBoxClearButton, *searchBoxExportButton, *searchBoxSelectAllButton, *searchBoxReSearchButton; //QRadioButton *searchAllRadioButton; QPushButton *recalculateAwardsButton; //bool searchSelectAllClicked, stationCallSignShownInSearch; bool checkNewVersions, reportInfo; // Selected in the Setup->Misc to check if new versions and report info back to KLog's servers bool qslingNeeded; bool noMoreErrorShown; // If true, the errors shown in slotQueryErrorManagement will not be shown anymore in that KLog execution MainWindowSatTab *satTabWidget; MainWindowMyDataTab *myDataTabWidget; MainWindowInputComment *commentTabWidget; MainWindowInputOthers *othersTabWidget; MainWindowInputEQSL *eQSLTabWidget; MainWindowInputQSL *QSLTabWidget; SearchWidget *searchWidget; InfoWidget *infoWidget; bool keepSatPage; // UI DX SetupDialog *setupDialog; // DXClusterWidget *dxClusterWidget; bool dxClusterShowHF, dxClusterShowVHF, dxClusterShowWARC, dxClusterShowWorked, dxClusterShowConfirmed, dxClusterShowAnn, dxClusterShowWWV, dxClusterShowWCY; //QWidget *dxClusterWidget; //QListWidget *dxClusterListWidget; //QPushButton *sendDXClusterButton; //QLineEdit *inputDXClusterLineEdit; // // QTimer *timer; QDateTime *dateTime; QString klogDir, ctyDatFile, defaultADIFLogFile, configFileName; QString softwareVersion; bool itIsANewversion; QString currentQrz; QString previousQrz; QString stx; QString srx; QPalette palRed, palBlack; // To paint Text in red or black(normal) bool realTime, UTCTime, alwaysADIF, needToSave, useDefaultLogFileName, upAndRunning, qrzSmallModDontCalculate, imperialSystem, sendQSLWhenRec, keepMyData, completeWithPrevious, completedWithPreviousQTH, completedWithPreviousLocator, completedWithPreviousName, completedWithPreviousIOTA, completedWithPreviousQSLVia; bool cleaning; bool manageMode; // If true, the DXCC and awards will take the mode into consideration to decide if needed or worked. False implies only band is taken into account // Station Setup bool configured, modify; bool needToEnd; // Just to control if the software needs to end. bool qrzAutoChanging; //To stop executing the slotQRZTextChanged just because KLog uppercase a letter QString mainQRZ, stationQRZ, operatorQRZ, myLocator, dxLocator; QString lastOperatorQRZ, lastStationQRZ, lastMyLocator; double myPower, lastPower; int my_CQz, my_ITUz, defaultMode, defaultBand, currentMode, currentModeShown, currentBand, currentBandShown; int currentEntity, previousEntity; bool InValidCharsInPrevCall; int currentLog; // This is to be able to manage multiple logs without showing // them all at the same time. int modifyingQSO; // When modifying, the QSO is saved here. int selectedYear; // Station Setup QColor defaultColor; QColor neededColor; QColor workedColor; QColor confirmedColor; QColor newOneColor; // bool clublogActive, clublogRealTime; QString clublogUser, clublogPass, clublogEmail; eLogClubLog *elogClublog; int clublogAnswer; QStringList clublogPrevQSO; // // Contest int points, qsoPoints, multipliers, qsoMultiplier; QString contestMode; Contest *contest; // Contest DataProxy *dataProxy; DataBase *db; bool DBinMemory; QTextDocument *doc; SoftwareUpdate *softUpdate; bool callingUpdate; //LOGVIEW //QString bandOld, modeOld; //LOGVIEW signals: void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution protected: void keyPressEvent(QKeyEvent *event); void closeEvent(QCloseEvent *event); }; #endif klog-0.9.2.9/elogclublog.h0000644000076700000620000000661613233376355013265 0ustar staff#ifndef ELOGCLUBLOG_H #define ELOGCLUBLOG_H /*************************************************************************** elogclublog.h - description ------------------- begin : feb 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include #include #include #include #include #include class eLogClubLog : public QObject { Q_OBJECT public: explicit eLogClubLog(); ~eLogClubLog(); void setCredentials(const QString _call, const QString _email, const QString _pass, const bool _useQSOStationCall); int sendQSO(QStringList _qso); int deleteQSO(QStringList _qso); int modifyQSO (QStringList _oldQSO, QStringList _newQSO); private: QString getClubLogAdif(const QStringList _q); int sendData(const QString _q); // Sends the data (http post) to ClubLog QString prepareToTranslate(const QString _m); // Get the message and put it in a tr to be able to translate it QString call, email, pass, api, stationCallsign; QNetworkAccessManager *manager; QNetworkReply* reply; int currentQSO; int result; QString target; bool useQSOStationCallsign; private slots: void slotQsoUploadFinished(QNetworkReply* data); void slotFileUploadFinished(QNetworkReply* data); void downloadProgress(qint64 received, qint64 total); void slotErrorManagement(QNetworkReply::NetworkError networkError); signals: void actionReturnDownload(const int _i, const int _qsoId); void done(); void actionShowProgres(qint64 received, qint64 total); void actionError(const int _i); void showMessage(const QString _t); void disableClubLogAction(const bool _b); }; #endif // DOWNLOADCTY_H klog-0.9.2.9/contest.cpp0000644000076700000620000000506513237613103012763 0ustar staff/*************************************************************************** contest.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "contest.h" //#include Contest::Contest() { constrid = 1; //qDebug() << "Contest::Contest - START:END" << endl; } Contest::Contest(const QStringList _qs) { constrid = 2; //qDebug() << "Contest::Contest (_qs) - START:END" << endl; } Contest::~Contest() { } bool Contest::isMultiplier(const QStringList _qs) { //qDebug() << "Contest::isMultiplier" << endl; return false; } int Contest::getQSOPoints(const QStringList _qs) { //qDebug() << "Contest::getQSOPoints" << endl; return 0; } int Contest::getTotalScore() { return 0; } int Contest::getMultipliers() { return 0; } int Contest::getPoints() { return 0; } bool Contest::saveFileToSend(const QString& _fileName) { //qDebug() << "Contest::saveFileToSend" << endl; return false; } klog-0.9.2.9/README-DEVEL0000644000076700000620000002134613233376355012330 0ustar staffThis is a file to read if you want to join the KLog development team. This document will explain the KLog architecture, requirements, tips and important to know things to take into account when joining the KLog development team. CONTENT: 1 - BEFORE CODING 2 - KLOG ARCHITECTURE 3 - BEFORE CODING 4 - CODING 5 - AFTER CODING 6 - GUI 7 - DOCUMENTATION 8 - TRANSLATIONS 9 - DEPLOYING 0 - MISSION AND OBJECTIVE The objective of KLog is to provide a free software that runs in Linux, macOS and Windows. KLog will provide hamradio contest and DX logging support. 0.1 - REQUIREMENTS - Able to run in Linux, macOS and Windows. - Easy to use. - Able to localize to any language. - Any data can be exportable into ADIF (http://www.adif.org). - Can import standard ADIF. - Can export to Cabrillo (http://www.kkn.net/~trey/cabrillo/). - Provides a user manual / documentation. 1 - BEFORE CODING: Read this document. Join the KLog mailing list and send a "Hello that's me and I am here" message: http//MAILINGLIST Interesting links: http://www.qtcentre.org/wiki/index.php?title=Keeping_the_GUI_Responsive Packer: http://upx.sourceforge.net/ = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 2 - KLOG ARCHITECTURE KLog is intended to be a MODULAR software with the requirement to be modular ;-) so it is easy to add new features (mainly contests and awards support). 2.1 IMPORTANT THINGS TO HAVE IN MIND DEPRECATED - KLog version number is using the following system: Release versions: The Decimal part of the version number will always use even numbers like 0, 1.2, 2.20, ... while the decimal part of the development or Release Candidate versions will always be an odd number ie 0.1, 1.3, ... The release number is defined in the "main.cpp" file. - KLog should manage several logs. The "log" table of the DB has a column called "lognumber". ALL QSO has a lognumber id that identifies the log it belongs to. Each lognumber will have associated a Name and/or ID (TBD) so the user is able to "open" just that log. It is important that all the QSO operations are aware of this lognumber id. - The log table has a "marked" column. This column is to allow mass operations. Changing this column has to be done with care and leave it "unmarked" once the desired operation is finished. KLog should unmark(N) all QSO when starts and exits. Mark = 'X', unmark='N' or other. Marked column should not be saved. - Any change to the DB architecture must be communicated and agreed with the development team before commiting to the SVN and following the 2.4 DB UPDATES area in this document. 2.2 CONTEST SUPPORT The "Contest" class (in contest.h) is a base class and all the contest should inherit it. The "Contest" class has several virtual functions that should re-implemented in all derived classes. 2.2.1 ADDING A NEW CONTEST To add a new contest, a new class, inheriting the "Contest" class should be created. The new contest file should be named: "contest_nameofthecontest.h" and "contest_nameofthecontest.cpp" and should be included in the mainwindow.h All the calls to the contest class should be implemented in the virtual class. A new contest must include the implementation of all the functions of the virtual class. 2.3 AWARD SUPPORT 2.4 DB UPDATES A DB update consist on: - All the intended changes. - Update the softwarecontrol TABLE on the DB To update the DB structure there are several things to have in mind: - The current version of the DB is defined in database.h const float DBVersionf = 0.003; - All the actions to update the DB to the new structure are done here: DataBase::updateIfNeeded - After making any update = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 3 - BEFORE CODING Update your sources from the SVN: Remember that other developer may has done a commit. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 4 - CODING - The development language is English. - All Strings to be shown to the user must be translatable. i.e. tr("String") 4.1 - STYLE 4.2 - ADIF SUPPORT KLog is using some application defined ADIF fields: APP_{PROGRAMID}_{FIELDNAME} Header fields: APP_KLOG_LOG_DATE_EXPORT: The date and time (in UTC) when the log was exported. APP_KLOG_QSOS: The number of QSOs in the log. DEPRECATED: APP_KLOG_RELEASE: Release of KLog used to export the log file. CHANGED TO PROGRAMVERSION (ADIF standard) QSO fields: APP_KLOG_POINTS: Points given by the QSO. APP_KLOG_MULTIPLIER: Information about the multiplier status of the QSO. APP_KLOG_LOGN: Lognumber if the ADIF file contains several logs. KLog is also importing other application defined ADIF fields: APP_N1MM_POINTS: That is imported into the points column in the log table. KLog should not export any ADIF header that comming from other application without renaming it to APP_KLOG_ 4.3 SHORTCUTS Before adding or modifying any shortcut: - It should be agreed in the devel mailing list. - It should be as standard as possible, reuse the same shortcuts of main/popular contest software. - It should be checked and added to a list below. 4.4 DATA BASE - The DB version has to be checked and modified after a DB schema modification. - Any modification to the DB has to be provided with the code to update from any previous version. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 5 - AFTER CODING Test that your code compiles and does not break the previous code. Document your changes and close/update the tasks/bugs you have worked on. Remember to commit your code to the SVN. Try to do "atomic" commits. That is to commit updates that may be disabled as a block. i.e. A new function or a modification to a function. Don't commit several things at once if you can avoid it. This is just a recommendation to avoid big commits that, in case of a problem are difficult to trace. Document your commits: ALWAYS add a clear comment to the commits so it is easy to know what is it about. 5.1 TEST CHECKLIST Here is the list of tests to be done before releasing new software: - Install in a new installation of Windows/macOS - Upgrade from a previous version - Create a new log - Add a new QSO - Check that the DXCC & IOTA continent make sense - Edit a QSO from log - Modify at least one field in each tab - Edit a QSO from the search box - Remove a QSO - Update the DXCC status tab - Connect to the DXCluster - Click on a spot on the DXCluster - Export an ADIF file - Import an ADIF file - Remove KLog in Windows = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 6 - GUI 6.1 CONTEST GUI - The GUI should only have the data fields that are needed for that contest, keeping the GUI simple and easy to use. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 7 - DOCUMENTATION - One feature will not be considered completed until it is not added to the user manual. Please document in the klog-handbook.xml your feature so the user knows how to use it. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 9 - TRANSLATIONS 9.1 ADDING TRANSLATIONS To add a new translation add the new language file to the klog.pro file following the sintax: TRANSLATIONS = KLog_es.ts \ klog_fr.ts Being es, fr, the ISO codes naming the language. After a translation is added, you also need to update the aboutdialog.cpp to include a new Translator line. 9.2 TRANSLATING Translators should work in the *.ts files. 9.2 UPDATING TRANSLATIONS Update translations: Run: lupdate -verbose klog.pro in the klog directory to update the language files = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 9 - DEPLOYING Before deploying, translations should be updated. 9.1 DEPLOYING ON LINUX 9.2 DEPLOYING ON macOS Build KLog with QTCreator Run the following command from the build directory: mv klog.app KLog.app create new folder in KLog.app/Contents/PlugIns/sqldrivers copy $QT_DIR/plugins/sqldrivers/libqsqlite.dylib to the new folder (/Developer/Applications/Qt/plugins/) create new folder: KLog.app/Contents/MacOs/translations copy the *.qm (translation) files into KLog.app/Contents/MacOS/translations macdeployqt KLog.app/ -dmg mv KLog.dmg KLog-[VERSION].dmg 9.3 DEPLOYING ON WINDOWS Currently using an Open Source Licence of: BitRock InstallBuilder 9.4 ICON Follow this link for all the OS: http://doc.qt.io/qt-5/appicon.html Installer: http://en.wikipedia.org/wiki/List_of_installation_software klog-0.9.2.9/logwindow.cpp0000644000076700000620000004054613233376355013333 0ustar staff/*************************************************************************** logwindow.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "logwindow.h" LogWindow::LogWindow(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "LogWindow::LogWindow: " << endl; dataProxy = dp; logModel = new LogModel(dataProxy, this); connect(logModel, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); logView = new QTableView; dxccStatusWidget = new DXCCStatusWidget(dataProxy); elogClublog = new eLogClubLog(); currentLog = -1; awards = new Awards(dataProxy); createUI(); createActions(); setDefaultData(); //qDebug() << "LogWindow::LogWindow: - END" << endl; } LogWindow::~LogWindow() { } void LogWindow::clear() { //qDebug() << "LogWindow::clear " << endl; } void LogWindow::createUI() { //qDebug() << "LogWindow::createUI" << endl; logView->setContextMenuPolicy(Qt::CustomContextMenu); logView->setSortingEnabled(true); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(logView); setLayout(layout); } void LogWindow::setDefaultData() { //qDebug() << "LogWindow::setDefaultData" << endl; } void LogWindow::createlogPanel(const int _currentLog) { //qDebug() << "LogWindow::createlogPanel: " << QString::number(_contestID) << endl; currentLog = _currentLog; logModel->createlogModel(currentLog); logView->setModel(logModel); logView->setCurrentIndex(logModel->index(0, 0)); QString contestMode = dataProxy->getLogTypeOfUserLog(currentLog); if (contestMode == "DX") { //qDebug() << "LogWindow::createlogPanel: DX" << endl; setColumnsToDX(); } else if (contestMode == "CQ-WW-SSB") { //qDebug() << "LogWindow::createlogPanel: CQ-WW-SSB" << endl; } else { // THIS POINT SHOULD NOT BE REACHED. It means that there is a kind of contest not supported. // Maybe the way should be to move ALL the actions from DX here. //qDebug() << "LogWindow::createlogPanel: No log type found!" << endl; } logView->setItemDelegate(new QSqlRelationalDelegate(this)); logView->setSelectionMode( QAbstractItemView::SingleSelection); logView->setSelectionBehavior(QAbstractItemView::SelectRows); logView->resizeColumnsToContents(); logView->horizontalHeader()->setStretchLastSection(true); } void LogWindow::setColumnsToDX() { //qDebug() << "LogWindow::setColumnsToDX" << endl; QString stringQuery; stringQuery = QString("SELECT * FROM log LIMIT 1"); QSqlQuery query; bool sqlOK = query.exec(stringQuery); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } QSqlRecord rec; rec = query.record(); // Number of columns int columns = rec.count(); for (int i=0; i < columns; i++) { logView->setColumnHidden(i, true); } columns = rec.indexOf("qso_date"); logView->setColumnHidden(columns, false); columns = rec.indexOf("time_on"); logView->setColumnHidden(columns, false); columns = rec.indexOf("call"); logView->setColumnHidden(columns, false); columns = rec.indexOf("rst_sent"); logView->setColumnHidden(columns, false); columns = rec.indexOf("rst_rcvd"); logView->setColumnHidden(columns, false); columns = rec.indexOf("bandid"); logView->setColumnHidden(columns, false); columns = rec.indexOf("modeid"); logView->setColumnHidden(columns, false); columns = rec.indexOf("comment"); logView->setColumnHidden(columns, false); } void LogWindow::refresh() { logModel->select(); } ; void LogWindow::createActions() { createActionsCommon(); } void LogWindow::createActionsCommon() { //LOG VIEW connect(logView, SIGNAL(customContextMenuRequested( const QPoint& ) ), this, SLOT(slotRighButtonFromLog( const QPoint& ) ) ); connect(logView, SIGNAL(doubleClicked ( const QModelIndex& ) ), this, SLOT(slotDoubleClickLog( const QModelIndex& ) ) ); } void LogWindow::slotRighButtonFromLog(const QPoint& pos) { //qDebug() << "LogWindow::slotshowRighButtonFromLog" << endl; int row = (logView->indexAt(pos)).row(); showMenuRightButtonFromLogCreateActions(); righButtonFromLogMenu(row); //TODO: To be added to the logWindow and create an action that emist the QSO id } void LogWindow::righButtonFromLogMenu(const int trow) { //qDebug() << "LogWindow::slotshowRighButtonFromLogMenu: " << QString::number(trow) << endl; int _qsoID = ((logModel->index(trow, 0)).data(0)).toInt(); //qDebug() << "LogWindow::slotshowRighButtonFromLogMenu: QSOid: " << QString::number(_qsoID) << endl; bool qslReceived = isQSLReceived(_qsoID); bool qslSent = isQSLSent(_qsoID); QMenu menu(this); menu.addAction(delQSOFromLogAct); delQSOFromLogAct->setData(trow); menu.addAction(qsoToEditFromLogAct); qsoToEditFromLogAct->setData(trow); QString contestMode = dataProxy->getLogTypeOfUserLog(currentLog); if (contestMode == "DX") { menu.addSeparator(); if (qslSent) { } else { QMenu *menuSentQsl = menu.addMenu(tr("QSL Send")); menuSentQsl->addAction(qslSentViaBureauFromLogAct); menuSentQsl->addAction(qslSentViaDirectFromLogAct); qslSentViaBureauFromLogAct->setData(trow); qslSentViaDirectFromLogAct->setData(trow); } if (qslReceived) { } else { QMenu *menuRecQsl = menu.addMenu(tr("QSL Rcvd")); menuRecQsl->addAction(qslRecViaBureauFromLogAct); menuRecQsl->addAction(qslRecViaDirectFromLogAct); qslRecViaBureauFromLogAct->setData(trow); qslRecViaDirectFromLogAct->setData(trow); } } else if (contestMode == "CQ-WW-SSB") { } else { // THIS POINT SHOULD NOT BE REACHED. It means that there is a kind of contest not supported. // Maybe the way should be to move ALL the actions from DX here. } menu.exec(QCursor::pos()); } void LogWindow::slotDoubleClickLog(const QModelIndex & index) { //qDebug() << "LogWindow::slotDoubleClickLog: Row: " << QString::number(index.row()) << "Column: " << QString::number(index.column()) << endl; int row = index.row(); //qsoToEdit((logModel->index(row, 0)).data(0).toInt()); int qsoID = ((logModel->index(row, Qt::DisplayRole)).data(0)).toInt(); //qDebug() << "LogWindow::slotDoubleClickLog: n: " << QString::number (logModel->data(index, Qt::DisplayRole).toInt()) << endl; //qDebug() << "LogWindow::slotDoubleClickLog: emitted: " << QString::number (((logModel->index(row, Qt::DisplayRole)).data(0)).toInt()) << endl; emit actionQSODoubleClicked(qsoID); //qsoToEdit((logModel->index(row, 0)).data(0).toInt()); //TODO: To be added to the logWindow and create an action that emist the QSO id to be edited logModel->select(); } bool LogWindow::isQSLReceived(const int _qsoId) { //qDebug() << "LogWindow::isQSLReceived: " << QString::number(_qsoId) << endl; return dataProxy->isQSLReceived(_qsoId); } bool LogWindow::isQSLSent(const int _qsoId) { //qDebug() << "LogWindow::isQSLSent: " << QString::number(_qsoId) << endl; return dataProxy->isQSLSent(_qsoId); } void LogWindow::showMenuRightButtonFromLogCreateActions() { //qDebug() << "LogWindow::showMenuRightButtonFromLogCreateActions" << endl; delQSOFromLogAct = new QAction(tr("&Delete"), this); delQSOFromLogAct->setShortcut(Qt::CTRL + Qt::Key_D); delQSOFromLogAct->setStatusTip(tr("Delete a QSO")); connect(delQSOFromLogAct, SIGNAL(triggered()), this, SLOT(slotQsoDeleteFromLog())); qsoToEditFromLogAct = new QAction(tr("&Edit QSO"), this); qsoToEditFromLogAct->setShortcut(Qt::CTRL + Qt::Key_E); qsoToEditFromLogAct->setStatusTip(tr("Edit this QSO")); connect(qsoToEditFromLogAct, SIGNAL(triggered()), this, SLOT(slotQSOToEditFromLog())); qslSentViaBureauFromLogAct = new QAction(tr("Via &bureau"), this); qslSentViaBureauFromLogAct->setShortcut(Qt::CTRL + Qt::Key_B); qslSentViaBureauFromLogAct->setStatusTip(tr("Send this QSL via bureau")); connect(qslSentViaBureauFromLogAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaBureauFromLog() )); qslSentViaDirectFromLogAct = new QAction(tr("D&irect"), this); qslSentViaDirectFromLogAct->setShortcut(Qt::CTRL + Qt::Key_I); qslSentViaDirectFromLogAct->setStatusTip(tr("Send this QSL via direct")); connect(qslSentViaDirectFromLogAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaDirectFromLog() )); qslRecViaBureauFromLogAct = new QAction(tr("Via bureau"), this); qslRecViaBureauFromLogAct->setShortcut(Qt::CTRL + Qt::Key_R); qslRecViaBureauFromLogAct->setStatusTip(tr("QSL &received via bureau")); connect(qslRecViaBureauFromLogAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaBureauFromLog() )); qslRecViaDirectFromLogAct = new QAction(tr("Direct"), this); qslRecViaDirectFromLogAct->setShortcut(Qt::CTRL + Qt::Key_T); qslRecViaDirectFromLogAct->setStatusTip(tr("QSL received via direc&t")); connect(qslRecViaDirectFromLogAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaDirectFromLog() )); } void LogWindow::slotQSLSentViaBureauFromLog() { //qDebug() << "LogWindow::slotQSLSentViaBureauFromLog: " << (qslSentViaBureauFromLogAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaBureauFromLogAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = ((logModel->index( ( (qslSentViaBureauFromLogAct->data()).toInt() ) , 0)).data(0).toInt()); qslSentViaBureau(_qsoId); } void LogWindow::slotQSLSentViaDirectFromLog() { //qDebug() << "LogWindow::slotQSLSentViaDirectFromLog: " << (qslSentViaDirectFromLogAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = ((logModel->index( ( (qslSentViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()); dataProxy->qslSentViaDirect(_qsoId, (QDateTime::currentDateTime()).toString("yyyy/MM/dd")); } void LogWindow::slotQSLRecViaBureauFromLog() { //qDebug() << "LogWindow::slotQSLRecViaBureauFromLog: " << (qslRecViaBureauAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslRecViaBureauAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = ((logModel->index( ( (qslRecViaBureauFromLogAct->data()).toInt() ) , 0)).data(0).toInt()); qslRecViaBureau(_qsoId); //TODO: To be added to the logWindow and create an action that emist the QSO id } void LogWindow::slotQSLRecViaDirectFromLog() { //qDebug() << "LogWindow::slotQSLRecViaDirectFromLog: " << (qslRecViaDirectFromLogAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslRecViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = ((logModel->index( ( (qslRecViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()); qslRecViaDirect(_qsoId); // Mark Sent, Bureau, date, update log. //TODO: To be added to the logWindow and create an action that emist the QSO id } void LogWindow::slotQSOToEditFromLog() { //qDebug() << "slotQSOToEditFromLog: " << (qsoToEditFromLogAct->data()).toString() << endl; //qsoToEdit((logModel->index((qsoToEditFromLogAct->data()).toInt(), 0)).data(0).toInt()); int QSOid = ((logModel->index((qsoToEditFromLogAct->data()).toInt(), 0)).data(0)).toInt(); //int row = index.row(); //qsoToEdit((logModel->index(row, 0)).data(0).toInt()); emit actionQSODoubleClicked(QSOid); //TODO: To be added to the logWindow and create an action that emist the QSO id } void LogWindow::deleteQSO(const int _qsoID) { //qDebug() << "LogWindow::deleteQSO: " << QString::number(_qsoID) << endl; elogClublog->deleteQSO(dataProxy->getClubLogRealTimeFromId(_qsoID)); dataProxy->deleteQSO(_qsoID); //logModel->removeRow((delQSOFromLogAct->data()).toInt()); //TODO: This has been replaced by the previous line awards->recalculateAwards(); refresh(); dxccStatusWidget->refresh(); emit updateAwards(); emit updateSearchText(); } void LogWindow::slotQsoDeleteFromLog() { //qDebug() << "LogWindow::slotQsoDeleteFromLog: " << (delQSOFromLogAct->data()).toString() << endl; //TODO: To be added to the logWindow and create an action that emist the QSO id QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("You have requested to delete this QSO.")); msgBox.setInformativeText(tr("Are you sure?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); int QSOid = ((logModel->index((delQSOFromLogAct->data()).toInt(), 0)).data(0)).toInt(); //qDebug() << "LogWindow::slotQsoDeleteFromLog (id): " << QString::number(QSOid) << endl; switch (ret) { case QMessageBox::Yes: //qDebug() << "LogWindow::slotQsoDeleteFromLog (id): -1" << endl; deleteQSO(QSOid); break; case QMessageBox::No: // No was clicked break; default: // should never be reached break; } } void LogWindow::qslSentViaBureau(const int _qsoId) { //qDebug() << "LogWindow::qslSentViaBureau: " << QString::number(_qsoId) << endl; dataProxy->qslSentViaBureau(_qsoId, (QDateTime::currentDateTime()).toString("yyyy/MM/dd")); } void LogWindow::qslRecViaBureau(const int _qsoId) { // //qDebug() << "LogWindow::qslRecViaBureau: " << QString::number(_qsoId) << "/" << (dateTime->currentDateTime()).toString("yyyy/MM/dd") << endl; dataProxy->qslRecViaBureau(_qsoId, (QDateTime::currentDateTime()).toString("yyyy/MM/dd"), false); awards->setAwards(_qsoId); //Update the Award status refresh(); emit updateAwards(); } void LogWindow::qslRecViaDirect(const int _qsoId) { //qDebug() << "LogWindow::qslRecViaDirect: " << QString::number(_qsoId) << endl; dataProxy->qslRecViaDirect(_qsoId, (QDateTime::currentDateTime()).toString("yyyy/MM/dd"), false); awards->setAwards(_qsoId); refresh(); emit updateAwards(); } void LogWindow::slotQueryErrorManagement(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery) { emit queryError(functionFailed, errorCodeS, errorCodeN, failedQuery); } klog-0.9.2.9/README0000644000076700000620000000173513233376355011473 0ustar staffKLog is an updated version of KLog The objective of KLog is to provide a free software that runs in Linux, macOS and Windows. KLog will provide hamradio contest and DX logging support. Check http://www.klog.xyz for news & updates. Check http://jaime.robles.es for the author homepage. Please join the mailing list at: - Users: https://lists.nongnu.org/mailman/listinfo/klog-users - Developers: https://lists.nongnu.org/mailman/listinfo/klog-devel If you are a native in a language different than English or Spanish, please consider helping us translating KLog into your native language. Please contact me at jaimeNOMORESPAMrobles.es (change "NOMORESPAM" by @). Read the INSTALL.txt for installation purposes. Read the changelog (windows users, rename to changelog.txt) to see the changes from one version to another. Read README-DEVEL.txt if you want to help with KLog development. Please send all your suggestions & bug reports. I hope you enjoy KLog! 73 de Jaime, EA4TV klog-0.9.2.9/dataproxy_sqlite.cpp0000644000076700000620000051412413233376355014714 0ustar staff/*************************************************************************** dataproxy_sqlite.cpp - description ------------------- begin : sept 2014 copyright : (C) 2014 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "dataproxy_sqlite.h" #include "utilities.h" //#include DataProxy_SQLite::DataProxy_SQLite(const QString _softVersion, const QString _parentFunction) { //qDebug() << "DataProxy_SQLite::DataProxy_SQLite" << _softVersion << _parentFunction << endl; //qDebug() << "DataProxy_SQLite::DataProxy_SQLite 1" << endl; util = new Utilities(); util->setVersion(_softVersion); db = new DataBase(Q_FUNC_INFO, _softVersion, util->getKLogDBFile()); //db = new DataBase(Q_FUNC_INFO, util->getKLogDBFile()); dbCreated = db->createConnection(); //dbCreated = db->createBandModeMaps(); //qDebug() << "DataProxy_SQLite::DataProxy_SQLite - END" << endl; searching = false; executionN = 0; //preparedQuery = new QSqlQuery; //db = new DataBase(0); //dataProxy = new DataProxy_SQLite(); //qDebug() << "DataProxy_SQLite::DataProxy_SQLite END" << endl; } DataProxy_SQLite::~DataProxy_SQLite(){ //qDebug() << "DataProxy_SQLite::~DataProxy_SQLite" << endl; } QString DataProxy_SQLite::getSoftVersion() { //SELECT MAX (softversion) FROM softwarecontrol QSqlQuery query; QString stQuery = QString("SELECT MAX (softversion) FROM softwarecontrol"); if (query.exec(stQuery)) { query.next(); if (query.isValid()) { QString v = (query.value(0)).toString(); query.finish(); //qDebug() << "DataProxy_SQLite::getSoftVersion: DATA: " << v << endl; if (v.length()<1) { //The following is not a query error but if the softwareversion value is lower than 0 or empty queryError(Q_FUNC_INFO, tr("Software version in DB is null"), -1, tr("No query failed")); // To alert about any failed query execution } return v; } else { query.finish(); //qDebug() << "DataProxy_SQLite::getSoftVersion: version empty-1" << endl; return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); //qDebug() << "DataProxy_SQLite::getSoftVersion: version empty-1 - ERROR" << endl; return QString(); } } QString DataProxy_SQLite::getDBVersion() { //SELECT MAX (dbversion) FROM softwarecontrol QSqlQuery query; QString stQuery = QString("SELECT MAX (dbversion) FROM softwarecontrol"); if (query.exec(stQuery)) { query.next(); if (query.isValid()) { QString v = (query.value(0)).toString(); query.finish(); return v; } else { query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } } bool DataProxy_SQLite::reconnectDB() { return db->reConnect(util->getKLogDBFile()); } void DataProxy_SQLite::createLogModel(){ //qDebug() << "DataProxy_SQLite::createLogModel" << endl; } void DataProxy_SQLite::createLogPanel(){ //qDebug() << "DataProxy_SQLite::createLogPanel" << endl; } int DataProxy_SQLite::getIdFromModeName(const QString& _modeName) { //qDebug() << "DataProxy_SQLite::getIdFromModeName: " << _modeName << "/" << QString::number(db->getModeIDFromName2(_modeName)) << endl; if (_modeName.length()<2) { return -4; } return db->getModeIDFromName2(_modeName); } int DataProxy_SQLite::getSubModeIdFromSubMode(const QString _subModeName) { //qDebug() << "DataProxy_SQLite::getSubModeIdFromSubMode: " << _subModeName << endl; if (_subModeName.length()<2) { return -3; } QSqlQuery query; QString stQuery = QString("SELECT id FROM mode WHERE submode='%1'").arg(_subModeName); if (query.exec(stQuery)) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -2; } } int DataProxy_SQLite::getModeIdFromSubModeId(const int _sm) { return getIdFromModeName(getNameFromSubMode(getSubModeFromId(_sm))); } bool DataProxy_SQLite::isModeDeprecated (const QString _sm) { if (_sm.length()<2) { return -3; } QSqlQuery query; QString stQuery = QString("SELECT deprecated FROM mode WHERE submode='%1'").arg(_sm); if (query.exec(stQuery)) { query.next(); if (query.isValid()) { if ( (query.value(0)).toInt() == 1 ) { query.finish(); return true; } else { query.finish(); return false; } } else { query.finish(); return false; // In case we can't check, we don't state it as deprecated } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; // In case we can't check, we don't state it as deprecated } } int DataProxy_SQLite::getIdFromBandName(const QString& _bandName) { //qDebug() << "DataProxy_SQLite::getIdFromBandName: " << _bandName << "/" << QString::number(db->getBandIDFromName2(_bandName))<< endl; if (_bandName.length()<1) { return -4; } return db->getBandIDFromName2(_bandName); } QString DataProxy_SQLite::getNameFromBandId (const int _id) { //qDebug() << "DataProxy_SQLite::getNameFromBandId " << endl; return db->getBandNameFromID2(_id); } QString DataProxy_SQLite::getNameFromModeId (const int _id) { //qDebug() << "DataProxy_SQLite::getNameFromModeId" << endl; //return db->getModeNameFromID2(_id); return db->getModeNameFromNumber(_id); } QString DataProxy_SQLite::getNameFromSubModeId (const int _id) { //qDebug() << "DataProxy_SQLite::getNameFromSubModeId: " << QString::number(_id) << "DB: " << db->getModeNameFromID2(_id) << endl; return db->getSubModeNameFromID2(_id); /* QSqlQuery query; QString queryString = QString("SELECT submode, name, deprecated FROM mode WHERE id='%1'").arg(_id); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { if ( (query.value(2)).toInt()<0 ) { // DEPRECATED VALUE, return the MODE return (query.value(1)).toString(); } else { return (query.value(0)).toString(); } } else { return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return QString(); } */ } QString DataProxy_SQLite::getSubModeFromId (const int _id) { //qDebug() << "DataProxy_SQLite::getSubModeFromId: " << QString::number(_id) << endl; QSqlQuery query; QString queryString = QString("SELECT submode FROM mode WHERE id='%1'").arg(_id); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { QString v = (query.value(0)).toString(); query.finish(); return v; } else { query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } return QString(); } QString DataProxy_SQLite::getNameFromSubMode (const QString _sm) { QSqlQuery query; QString queryString = QString("SELECT name FROM mode WHERE submode='%1'").arg(_sm.toUpper()); //QString queryString = QString("SELECT name, deprecated FROM mode WHERE submode='%1'").arg(_sm.toUpper()); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { QString v = (query.value(0)).toString(); query.finish(); return v; } else { query.finish(); return QString(); } query.finish(); return QString(); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } } QString DataProxy_SQLite::getFreqFromBandId(const int _id) { return db->getFreqFromBandId(_id); } int DataProxy_SQLite::getBandIdFromFreq(const double _n) { //qDebug() << "DataProxy_SQLite::getBandIdFromFreq: " << QString::number(_n) << endl; //Freq should be in MHz bool sqlOk = false; QString queryString = QString("SELECT id FROM band WHERE lower <= '%1' and upper >= '%2'").arg(_n).arg(_n); QSqlQuery query(queryString); sqlOk = query.exec(); //qDebug() << "DataProxy_SQLite::getBandIdFromFreq: Query: " << query.lastQuery() << endl; if (sqlOk) { //qDebug() << "DataProxy_SQLite::getBandIdFromFreq: Query OK" << endl; query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { //qDebug() << "DataProxy_SQLite::getBandIdFromFreq: Query NOK" << endl; emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -2; } return -3; } QString DataProxy_SQLite::getBandNameFromFreq(const double _n) { return getNameFromBandId(getBandIdFromFreq(_n)); } double DataProxy_SQLite::getLowLimitBandFromBandName(const QString _sm) { //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandName: " << _sm << endl; QSqlQuery query; QString queryString = QString("SELECT lower FROM band WHERE name='%1' OR name='%2'").arg(_sm).arg(_sm.toUpper()); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { if ( (query.value(0)).toDouble()<0 ) { //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandName: -1.0-1" << endl; query.finish(); return -1.0; } else { //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandName(else): " << QString::number((query.value(0)).toDouble()) << endl; double v = (query.value(0)).toDouble(); query.finish(); return v; } } else { //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandName: -1.0-2" << endl; query.finish(); return -1.0; } //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandName: -1.0-3" << endl; query.finish(); return -1.0; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1.0; } return -1.0; } double DataProxy_SQLite::getLowLimitBandFromBandId(const QString _sm) { //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandId" << endl; QSqlQuery query; QString queryString = QString("SELECT lower FROM band WHERE id='%1'").arg(_sm.toUpper()); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { if ( (query.value(1)).toDouble()<0 ) { //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandId: -1.0-1" << endl; query.finish(); return -1.0; } else { //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandId: " << QString::number((query.value(0)).toDouble()) << endl; double v = (query.value(0)).toDouble(); query.finish(); return v; } } else { //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandId: -1.0-2" << endl; query.finish(); return -1.0; } //qDebug() << "DataProxy_SQLite::getLowLimitBandFromBandId: -1.0-3" << endl; query.finish(); return -1.0; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1.0; } return -1.0; } bool DataProxy_SQLite::isThisFreqInBand(const QString b, const QString fr) { return db->isThisFreqInBand(b, fr); } QStringList DataProxy_SQLite::getBands() { //qDebug() << "DataProxy_SQLite::getBands - DEPRECATED please use getBandNames - TODO: Remove this function and change the calls" << endl; return getBandNames(); /* QStringList bands = QStringList(); QSqlQuery query("SELECT name FROM band"); while (query.next()) { if (query.isValid()){ bands << query.value(0).toString(); } } //return bands; return sortBandNamesBottonUp(bands); */ } QStringList DataProxy_SQLite::getBandNames() { //qDebug() << "DataProxy_SQLite::getBandNames" << endl; QStringList bands = QStringList(); QSqlQuery query; QString queryString; bool sqlOK; queryString = QString("SELECT DISTINCT name FROM band"); sqlOK = query.exec(queryString); if (sqlOK) { while(query.next()) { if (query.isValid()) { queryString = (query.value(0)).toString(); //qDebug() << "DataProxy_SQLite::getBandNames: " << queryString << endl; bands.append(queryString); } else { query.finish(); return QStringList(); } } query.finish(); return sortBandNamesBottonUp(bands); //return bands; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } } QStringList DataProxy_SQLite::getModes() { QStringList modes = QStringList(); QSqlQuery query("SELECT submode FROM mode ORDER BY submode"); while (query.next()) { if (query.isValid()){ modes << query.value(0).toString(); } } query.finish(); return modes; } QStringList DataProxy_SQLite::sortBandNamesBottonUp(const QStringList _qs) { //Receives a list of band names, sorts it from the lower band to the upper band and returns //qDebug() << "DataProxy_SQLite::sortBandNamesBottonUp" << endl; //Next lines to be commented out for (int i=0; i<_qs.length();i++) { //qDebug() << "DataProxy_SQLite::sortBandNamesBottonUp - band: " << _qs.at(i) << endl; } //Previous lines to be commented out QMap map; QStringList qs; qs.clear(); for (int j=0; j<_qs.count(); j++) { map.insert(getLowLimitBandFromBandName(_qs.at(j)), _qs.at(j)); } QMap::const_iterator i = map.constBegin(); while (i != map.constEnd()) { qs << i.value(); ++i; } //qDebug() << "DataProxy_SQLite::sortBandNamesBottonUp - END -lengh = " << QString::number(qs.length()) << endl; qs.removeDuplicates(); return qs; } QStringList DataProxy_SQLite::getBandIDs() { //qDebug() << "DataProxy_SQLite::getBandIDs" << endl; QStringList bands = QStringList(); QSqlQuery query("SELECT id FROM band"); while (query.next()) { if (query.isValid()){ bands << query.value(0).toString(); } } query.finish(); return sortBandIdBottonUp(bands); } QStringList DataProxy_SQLite::sortBandIdBottonUp(const QStringList _qs) { //Receives a list of band id, sorts it from the lower band to the upper band and returns QMap map; QStringList qs; qs.clear(); for (int j=0; j<_qs.count(); j++) { map.insert(getLowLimitBandFromBandId(_qs.at(j)), _qs.at(j)); } QMap::const_iterator i = map.constBegin(); while (i != map.constEnd()) { qs << i.value(); ++i; } return qs; } QStringList DataProxy_SQLite::getModesIDs() { QStringList modes = QStringList(); QSqlQuery query("SELECT id FROM mode"); while (query.next()) { if (query.isValid()){ modes << query.value(0).toString(); } } query.finish(); return modes; } QStringList DataProxy_SQLite::getBandsInLog(const int _log) { //qDebug() << "DataProxy_SQLite::getBandsInLog: " << endl; QStringList bands = QStringList(); QString queryString = QString(); if (_log <= 0) { queryString = QString("SELECT DISTINCT band.name FROM log, band WHERE band.id = log.bandid ORDER BY band.id DESC"); } else { queryString = QString("SELECT DISTINCT band.name FROM log, band WHERE band.id = log.bandid AND log.lognumber='%1' ORDER BY band.id DESC").arg(_log); } QSqlQuery query(queryString); while (query.next()) { if (query.isValid()){ bands << query.value(0).toString(); } } query.finish(); return sortBandNamesBottonUp(bands); //return bands; } QStringList DataProxy_SQLite::getModesInLog(const int _log) { //qDebug() << "DataProxy_SQLite::getModesInLog: " << endl; QStringList modes = QStringList(); QString queryString = QString(); if (_log <=0 ) { queryString = QString("SELECT mode.id, mode.submode, COUNT (mode.submode) FROM log, mode WHERE mode.id = log.modeid GROUP BY mode.submode ORDER BY count (mode.submode) DESC"); } else { queryString = QString("SELECT mode.id, mode.submode, COUNT (mode.submode) FROM log, mode WHERE mode.id = log.modeid AND log.lognumber='%1' GROUP BY mode.submode ORDER BY count (mode.submode) DESC").arg(_log); } QSqlQuery query(queryString); while (query.next()) { if (query.isValid()){ modes << query.value(1).toString(); } } query.finish(); //qDebug() << "DataProxy_SQLite::getModesInLog: " << modes.join(" - ") << endl; return modes; } int DataProxy_SQLite::getMostUsedBand(const int _log) { //qDebug() << "DataProxy_SQLite::getMostUsedBand: " << endl; QString queryString = QString(); if (_log <=0 ) { queryString = QString("SELECT band.id, band.name, COUNT (band.name) FROM log, band WHERE band.id = log.bandid GROUP BY band.id ORDER BY count (band.id) DESC LIMIT 1"); } else { queryString = QString("SELECT band.id, band.name, COUNT (band.name) FROM log, band WHERE band.id = log.bandid AND log.lognumber='%1' GROUP BY band.id ORDER BY count (band.id) DESC LIMIT 1").arg(_log); } QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { if (query.next()) { if (query.isValid()) { int v = query.value(0).toInt(); query.finish(); return v; } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } return -1; } int DataProxy_SQLite::getMostUsedMode(const int _log) { //qDebug() << "DataProxy_SQLite::getMostUsedMode: " << endl; QString queryString = QString(); if (_log <=0 ) { queryString = QString("SELECT mode.id, mode.submode, COUNT (mode.submode) FROM log, mode WHERE mode.id = log.modeid GROUP BY mode.submode ORDER BY count (mode.submode) DESC LIMIT 1"); } else { queryString = QString("SELECT mode.id, mode.submode, COUNT (mode.submode) FROM log, mode WHERE mode.id = log.modeid AND log.lognumber='%1' GROUP BY mode.submode ORDER BY count (mode.submode) DESC LIMIT 1").arg(_log); } QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { if (query.next()) { if (query.isValid()) { int v = query.value(0).toInt(); query.finish(); return v; } } query.finish(); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } return -1; } int DataProxy_SQLite::getLastQSOid() { //qDebug() << "DataProxy_SQLite::getLastQSOid" << endl; QSqlQuery query; bool sqlOK = query.exec("SELECT MAX(id) from log"); if (sqlOK) { query.next(); if (query.isValid()) { int v = query.value(0).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } } bool DataProxy_SQLite::clearLog() { //qDebug() << "DataProxy_SQLite::clearLog" << endl; //int errorCode = 0; QSqlQuery query; bool sqlOK = query.exec("DELETE FROM log"); if (sqlOK) { //qDebug() << "DataProxy_SQLite::clearLog: Log deleted!" << endl; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::clearLog: Log deleted FAILED" << endl; //errorCode = query.lastError().number(); //qDebug() << "DataProxy_SQLite::clearLog - query error: " << QString::number(errorCode) << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastQuery: " << query.lastQuery() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-n: " << QString::number(query.lastError().number() ) << endl; } query.finish(); sqlOK = query.exec("DELETE FROM awarddxcc"); if (sqlOK) { //qDebug() << "DataProxy_SQLite::clearLog: Awarddxcc deleted!" << endl; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::clearLog: Awarddxcc deletedFAILED" << endl; //errorCode = query.lastError().number(); //qDebug() << "DataProxy_SQLite::clearLog - query error: " << QString::number(errorCode) << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastQuery: " << query.lastQuery() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-n: " << QString::number(query.lastError().number() ) << endl; } query.finish(); if (query.exec("DELETE FROM awardwaz")) { //qDebug() << "DataProxy_SQLite::clearLog: Awardwaz deleted!" << endl; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::clearLog: Awardwaz deleted FAILED" << endl; //errorCode = query.lastError().number(); //qDebug() << "DataProxy_SQLite::clearLog - query error: " << QString::number(errorCode) << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastQuery: " << query.lastQuery() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-n: " << QString::number(query.lastError().number() ) << endl; } query.finish(); //query.clear(); if (query.isActive()) { //qDebug() << "DataProxy_SQLite::clearLog: Query Active!" << endl; query.finish(); return false; } else { query.prepare("VACUUM;"); //qDebug() << "DataProxy_SQLite::clearLog: Query Not Active!" << endl; if (query.exec()) { //qDebug() << "DataProxy_SQLite::clearLog: VACUUM OK!" << endl; query.finish(); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::clearLog: VACUUM FAILED" << endl; //errorCode = query.lastError().number(); //qDebug() << "DataProxy_SQLite::clearLog - query error: " << QString::number(errorCode) << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastQuery: " << query.lastQuery() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "DataProxy_SQLite::clearLog: LastError-n: " << QString::number(query.lastError().number() ) << endl; } } query.finish(); return false; } bool DataProxy_SQLite::qslSentViaDirect(const int _qsoId, const QString _updateDate) { //qDebug() << "DataProxy_SQLite::qslSentViaDirect" << endl; QSqlQuery query; QString queryString; queryString = QString("UPDATE log SET qsl_sent = 'Y', qsl_sent_via = 'D', qslsdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); //qDebug() << "DataProxy_SQLite::qslSentViaDirect: " << queryString << endl; bool sqlOK = query.exec(queryString); query.finish(); if (sqlOK) { return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } return false; } bool DataProxy_SQLite::qslSentViaBureau(const int _qsoId, const QString _updateDate) { //qDebug() << "DataProxy_SQLite::qslSentViaBureau" << endl; QSqlQuery query; QString queryString; queryString = QString("UPDATE log SET qsl_sent = 'Y', qsl_sent_via = 'B', qslsdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); bool sqlOK = query.exec(queryString); query.finish(); if (sqlOK) { return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } return false; } bool DataProxy_SQLite::qslRecViaBureau(const int _qsoId, const QString _updateDate) { //qDebug() << "DataProxy_SQLite::" << QString::number (_qsoId) << "/" << _updateDate << endl; QSqlQuery query; QString queryString; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'B', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); bool sqlOK = query.exec(queryString); query.finish(); if (sqlOK) { //qDebug() << "DataProxy_SQLite:: TRUE" << endl; setDXCCAwardStatus(_qsoId); setWAZAwardStatus(_qsoId); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } //qDebug() << "DataProxy_SQLite:: FALSE" << endl; return false; } bool DataProxy_SQLite::qslRecViaBureau(const int _qsoId, const QString _updateDate, const bool _queueSentQSL) { //qDebug() << "DataProxy_SQLite::qslRecViaBureau: " << _updateDate << endl; QSqlQuery query; QString queryString; //bool requestQSL = false; bool sqlOK; if (_queueSentQSL) { queryString = QString("SELECT qsl_sent FROM log WHERE id = '%1'").arg(_qsoId); sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { queryString = (query.value(0)).toString(); if ((queryString == "Y") || (queryString == "R")) { // NO ACTION REQUIRED, QSL IS ALREADY SENT //qDebug() << "DataProxy_SQLite::qslRecViaBureau: QSL already requested" << endl; //requestQSL = false; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'B', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); } else { //qDebug() << "DataProxy_SQLite::qslRecViaBureau: Request QSL-1" << endl; //requestQSL = true; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'B', qsl_sent='R', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); } } else { //qDebug() << "DataProxy_SQLite::qslRecViaBureau: Request QSL-2" << endl; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'B', qsl_sent='R', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); //requestQSL = true; } } else { //qDebug() << "DataProxy_SQLite::qslRecViaBureau: Request QSL-3" << endl; emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'B', qsl_sent='R', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); //requestQSL = true; } } else { //requestQSL = false; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'B', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); } query.finish(); sqlOK = query.exec(queryString); //queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'B', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); if (sqlOK) { //qDebug() << "DataProxy_SQLite::qslRecViaBureau TRUE" << endl; query.finish(); setDXCCAwardStatus(_qsoId); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } //qDebug() << "DataProxy_SQLite::qslRecViaBureau FALSE" << endl; query.finish(); return false; } bool DataProxy_SQLite::qslRecViaDirect(const int _qsoId, const QString _updateDate) { //qDebug() << "DataProxy_SQLite::qslRecViaDirect" << endl; QSqlQuery query; QString queryString; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'D', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.finish(); setDXCCAwardStatus(_qsoId); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } query.finish(); return false; } bool DataProxy_SQLite::qslRecViaDirect(const int _qsoId, const QString _updateDate, const bool _queueSentQSL) { //qDebug() << "DataProxy_SQLite::qslRecViaDirect: " << _updateDate << endl; QSqlQuery query; QString queryString; bool sqlOK; if (_queueSentQSL) { queryString = QString("SELECT qsl_sent FROM log WHERE id = '%1'").arg(_qsoId); sqlOK = query.exec(queryString); if(sqlOK) { query.next(); if (query.isValid()) { queryString = (query.value(0)).toString(); if ((queryString == "Y") || (queryString == "R")) { // NO ACTION REQUIRED, QSL IS ALREADY SENT //qDebug() << "DataProxy_SQLite::qslRecViaDirect: QSL already requested" << endl; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'D', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); } else { //qDebug() << "DataProxy_SQLite::qslRecViaDirect: Request QSL-1" << endl; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'D', qsl_sent='R', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); } } else { //qDebug() << "DataProxy_SQLite::qslRecViaDirect: Request QSL-2" << endl; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'D', qsl_sent='R', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::qslRecViaDirect: Request QSL-3" << endl; queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'D', qsl_sent='R', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); } } else { queryString = QString("UPDATE log SET qsl_rcvd = 'Y', qsl_rcvd_via = 'D', qslrdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); } query.finish(); sqlOK = query.exec(queryString); if (sqlOK) { //qDebug() << "DataProxy_SQLite::qslRecViaDirect TRUE" << endl; query.finish(); setDXCCAwardStatus(_qsoId); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } //qDebug() << "DataProxy_SQLite::qslRecViaDirect FALSE" << endl; query.finish(); return false; } bool DataProxy_SQLite::qslSentAsRequested(const int _qsoId, const QString _updateDate) { //TODO: Add some protection to the data before modifying //qDebug() << "DataProxy_SQLite::qslSentAsRequested" << endl; QSqlQuery query; QString queryString; queryString = QString("UPDATE log SET qsl_sent = 'R', qslsdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); //qDebug() << "DataProxy_SQLite::qslSentAsRequested: " << queryString << endl; bool sqlOK = query.exec(queryString); if (sqlOK) { //qDebug() << "DataProxy_SQLite::qslSentAsRequested" << endl; query.finish(); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } query.finish(); return false; } bool DataProxy_SQLite::qslRecAsRequested(const int _qsoId, const QString _updateDate) { //TODO: Add some protection to the data before modifying //qDebug() << "DataProxy_SQLite::qslRecAsRequested" << endl; QSqlQuery query; QString queryString; queryString = QString("UPDATE log SET qsl_rcvd = 'R', qslsdate = '%1' WHERE id = '%2'").arg(_updateDate).arg(_qsoId); //qDebug() << "DataProxy_SQLite::qslRecAsRequested: " << queryString << endl; bool sqlOK = query.exec(queryString); if (sqlOK) { //qDebug() << "DataProxy_SQLite::qslRecAsRequested" << endl; query.finish(); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } query.finish(); return false; } bool DataProxy_SQLite::setClubLogSent(const int _qsoId, const QString _st, const QString _updateDate) { // Updates the QSO with the ClubLog status & date QSqlQuery query; QString queryString; queryString = QString("UPDATE log SET clublog_qso_upload_status = '%1', clublog_qso_upload_date = '%2' WHERE id = '%3'").arg(_st).arg(_updateDate).arg(_qsoId); //qDebug() << "DataProxy_SQLite::setClubLogSent: " << queryString << endl; bool sqlOK = query.exec(queryString); if (sqlOK) { //qDebug() << "DataProxy_SQLite::setClubLogSent - TRUE" << endl; query.finish(); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } //qDebug() << "DataProxy_SQLite::setClubLogSent - FALSE" << endl; query.finish(); return false; } bool DataProxy_SQLite::isQSLReceived(const int _qsoId) { //qDebug() << "DataProxy_SQLite::isQSLReceived" << QString::number(_qsoId) << endl; QSqlQuery query; QString queryString; queryString = QString("SELECT qsl_rcvd FROM log WHERE id = '%1'").arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { queryString = (query.value(0)).toString(); query.finish(); if (queryString == "Y") { //qDebug() << "DataProxy_SQLitew::isQSLReceived: " << QString::number(_qsoId) << "QSL Received" << endl; return true; } else { //qDebug() << "DataProxy_SQLite::isQSLReceived: " << QString::number(_qsoId) << "QSL NOT Received-1" << endl; return false; } } else { //qDebug() << "DataProxy_SQLite::isQSLReceived: " << QString::number(_qsoId) << "QSL NOT Received-2" << endl; query.finish(); return false; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); } return false; } bool DataProxy_SQLite::isQSLSent(const int _qsoId) { //qDebug() << "DataProxy_SQLite::isQSLSent: " << QString::number(_qsoId) << endl; QSqlQuery query; QString queryString; queryString = QString("SELECT qsl_sent FROM log WHERE id = '%1'").arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { queryString = (query.value(0)).toString(); query.finish(); if (queryString == "Y") { //qDebug() << "DataProxy_SQLite::isQSLSent: " << QString::number(_qsoId) << "QSL Sent" << endl; return true; } else { //qDebug() << "DataProxy_SQLite::isQSLSent: " << QString::number(_qsoId) << "QSL NOT Sent-1" << endl; return false; } } else { //qDebug() << "DataProxy_SQLite::isQSLSent: " << QString::number(_qsoId) << "QSL NOT Sent-2" << endl; return false; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } return false; } int DataProxy_SQLite::getBandFromId(const int _qsoId) { QSqlQuery query; QString queryString = QString("SELECT bandid FROM log WHERE id='%1'").arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); } return -1; } int DataProxy_SQLite::getModeFromId(const int _qsoId) { QSqlQuery query; QString queryString = QString("SELECT modeid FROM log WHERE id='%1'").arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); } return -1; } int DataProxy_SQLite::getDXCCFromId(const int _qsoId) { QSqlQuery query; QString queryString = QString("SELECT dxcc FROM log WHERE id='%1'").arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); } return -1; } int DataProxy_SQLite::getCQZFromId(const int _qsoId) { QSqlQuery query; QString queryString = QString("SELECT cqz FROM log WHERE id='%1'").arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); } return -1; } QString DataProxy_SQLite::getCallFromId(const int _qsoId) { //qDebug() << "DataProxy_SQLite::getCallFromId" << endl; QSqlQuery query; QString queryString = QString("SELECT call FROM log WHERE id='%1'").arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { QString v = (query.value(0)).toString(); query.finish(); return v; } else { query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); } return QString(); } QStringList DataProxy_SQLite::getClubLogRealTimeFromId(const int _qsoId) { //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId: " << QString::number(_qsoId) << endl; /* Return a QStringList with 16 fields with these data: QSO_DATE, TIME_ON, QSLRDATE, QSLSDATE, CALL, OPERATOR, MODE, BAND, BAND_RX, FREQ, QSL_RCVD, LOTW_QSL_RCVD, QSL_SENT, DXCC, PROP_MODE, CREDIT_GRANTED */ QSqlQuery query, query2; int nameCol = -1; QStringList dataC = QStringList(); QString aux1 = QString(); QString aux2 = QString(); QString call = QString(); // IMPORTANT: band_rx is not always present, and if it is not present, the query with INNER JOIN will fail. // To fix that we will do two queries, one to check if I have all the data and if not another one with a reduced scope. QString queryString = QString("SELECT qso_date, time_on, qslrdate, qslsdate, call, station_callsign, operator, M.name, B.name, R.name, freq, qsl_rcvd, lotw_qsl_rcvd, qsl_sent, dxcc, prop_mode, credit_granted FROM log INNER JOIN band as B ON bandid = B.id INNER JOIN band as R ON band_rx = R.id INNER JOIN mode as M ON modeid = M.id WHERE log.id='%1'").arg(_qsoId); bool sqlOk = query.exec(queryString); dataC << QString::number(_qsoId); if (sqlOk) { QSqlRecord rec = query.record(); //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId sqlOK" << endl; if (query.next()) //if (1) { if (query.isValid()) { nameCol = rec.indexOf("qso_date"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("time_on"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId time: " << aux1 << endl; if ( ((aux1.length()) == 5) || ((aux1.length()) == 8) ){ aux1.remove(QChar(':'), Qt::CaseInsensitive); dataC << aux1; //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId time1.5: " << aux1 << endl; } //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId time2: " << aux1 << endl; dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("qslrdate"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("qslsdate"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("call"); call = (query.value(nameCol)).toString(); dataC << call; nameCol = rec.indexOf("operator"); dataC << (query.value(nameCol)).toString(); //nameCol = rec.indexOf("M.name"); //TODO: Fix this to get the proper column dataC << (query.value(7)).toString(); //nameCol = rec.indexOf("B.name"); dataC << (query.value(8)).toString(); //TODO: Fix this to get the proper column //nameCol = rec.indexOf("R.name"); //TODO: Fix this to get the proper column (use an index instead of a number) dataC << (query.value(9)).toString(); nameCol = rec.indexOf("freq"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("qsl_rcvd"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("lotw_qsl_rcvd"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("qsl_sent"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("dxcc"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("prop_mode"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("credit_granted"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("station_callsign"); aux2 = (query.value(nameCol)).toString(); if (aux2.length()>2) { dataC << aux2; } else { dataC << call; } //dataC << (query.value(nameCol)).toString(); //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId: RETURNING ... OK" << endl; return dataC; } else { //NO VALID //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId NO VALID NOT OK" << endl; query.finish(); return QStringList(); } query.finish(); } else { QString queryString = QString("SELECT qso_date, time_on, qslrdate, qslsdate, call, station_callsign, operator, M.name, B.name, freq, qsl_rcvd, lotw_qsl_rcvd, qsl_sent, dxcc, prop_mode, credit_granted FROM log INNER JOIN band as B ON bandid = B.id INNER JOIN mode as M ON modeid = M.id WHERE log.id='%1'").arg(_qsoId); //QString queryString = QString("SELECT qso_date, time_on, qslrdate, qslsdate, call, operator, M.name, B.name, freq, qsl_rcvd, lotw_qsl_rcvd, qsl_sent, dxcc, prop_mode, credit_granted FROM log INNER JOIN band as B ON bandid = B.id INNER JOIN mode as M ON modeid = M.id WHERE log.id='%1'").arg(_qsoId); //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId NO NEXT NOT OK" << endl; call = QString(); sqlOk = query2.exec(queryString); rec = query2.record(); if (sqlOk) { //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId OK2" << endl; if (query2.next()) { //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId NEXT OK2" << endl; if (query2.isValid()) { nameCol = rec.indexOf("qso_date"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("time_on"); aux1 = (query2.value(nameCol)).toString(); //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId time2-1: " << aux1 << endl; if ( ((aux1.length()) == 5) || ((aux1.length()) == 8) ){ aux1.remove(QChar(':'), Qt::CaseInsensitive); dataC << aux1; //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId time2-1.5: " << aux1 << endl; } //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId time2-2: " << aux1 << endl; //dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("qslrdate"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("qslsdate"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("call"); call = (query2.value(nameCol)).toString(); dataC << call; nameCol = rec.indexOf("operator"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("M.name"); //TODO: Fix this to get the proper column dataC << (query2.value(7)).toString(); nameCol = rec.indexOf("B.name"); dataC << (query2.value(8)).toString(); //TODO: Fix this to get the proper column //nameCol = rec.indexOf("band_rx"); //TODO: Fix this to get the proper column (use an index instead of a number) dataC << ""; nameCol = rec.indexOf("freq"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("qsl_rcvd"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("lotw_qsl_rcvd"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("qsl_sent"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("dxcc"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("prop_mode"); dataC << (query2.value(nameCol)).toString(); nameCol = rec.indexOf("credit_granted"); dataC << (query2.value(nameCol)).toString(); aux2 = QString(); nameCol = rec.indexOf("station_callsign"); aux2 = (query2.value(nameCol)).toString(); if (aux2.length()>2) { dataC << aux2; } else { dataC << call; } //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId: RETURNING ... OK" << endl; query2.finish(); return dataC; } else { //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId NO VALID NOT OK2" << endl; query2.finish(); return QStringList(); } } else { //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId NO NEXT NOT OK2" << endl; query.finish(); return QStringList(); } } else { //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId NOT OK2" << endl; emit queryError(Q_FUNC_INFO, query2.lastError().databaseText(), query2.lastError().number(), query2.lastQuery()); query2.finish(); return QStringList(); } query.finish(); return QStringList(); // NO NEXT } } else { //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId NOT sqlOK" << endl; //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId: 2 LastQuery: " << query.lastQuery() << endl; //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId: 2 LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId: 2 LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId: 2 LastError-n: " << QString::number(query.lastError().number() ) << endl; emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } query.finish(); query2.finish(); //qDebug() << "DataProxy_SQLite::getClubLogRealTimeFromId END NOT OK" << endl; return QStringList(); } QString DataProxy_SQLite::getNameFromQRZ(const QString _call) { if (_call.length() <= 0) { //qDebug() << "DataProxy_SQLite::getNameFromQRZ return 0" << endl; return QString(); } QSqlQuery query; QString queryString = QString("SELECT name FROM log WHERE call='%0'").arg(_call); bool sqlOk = query.exec(queryString); if (sqlOk) { while (query.next()) { if (query.isValid()) { if (((query.value(0)).toString()).length()>0) { //qDebug() << "DataProxy_SQLite::getNameFromQRZ: " << (query.value(0)).toString() << endl; QString v = (query.value(0)).toString(); query.finish(); return v; } } } query.finish(); return QString(); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } } QString DataProxy_SQLite::getQTHFromQRZ(const QString _call) { if (_call.length() <= 0) { return QString(); } QSqlQuery query; QString queryString = QString("SELECT qth FROM log WHERE call='%0'").arg(_call); bool sqlOk = query.exec(queryString); if (sqlOk) { while (query.next()) { if (query.isValid()) { if (((query.value(0)).toString()).length()>0) { QString v = (query.value(0)).toString(); query.finish(); return v; } } } query.finish(); return QString(); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } } QString DataProxy_SQLite::getLocatorFromQRZ(const QString _call) { if (_call.length() <= 0) { return QString(); } QSqlQuery query; QString queryString = QString("SELECT gridsquare FROM log WHERE call='%0'").arg(_call); bool sqlOk = query.exec(queryString); if (sqlOk) { while (query.next()) { if (query.isValid()) { if (((query.value(0)).toString()).length()>0) { QString v = (query.value(0)).toString(); query.finish(); return v; } } } query.finish(); return QString(); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } } QString DataProxy_SQLite::getIOTAFromQRZ(const QString _call) { if (_call.length() <= 0) { return QString(); } QSqlQuery query; QString queryString = QString("SELECT iota FROM log WHERE call='%0'").arg(_call); bool sqlOk = query.exec(queryString); if (sqlOk) { while (query.next()) { if (query.isValid()) { if (((query.value(0)).toString()).length()>0) { QString v = (query.value(0)).toString(); query.finish(); return v; } } } query.finish(); return QString(); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } } QString DataProxy_SQLite::getQSLViaFromQRZ(const QString _call) { if (_call.length() <= 0) { return QString(); } QSqlQuery query; QString queryString = QString("SELECT DISTINCT qsl_via FROM log WHERE call='%0'").arg(_call); bool sqlOk = query.exec(queryString); if (sqlOk) { while (query.next()) { if (query.isValid()) { if (((query.value(0)).toString()).length()>0) { QString v = (query.value(0)).toString(); query.finish(); return v; } } } query.finish(); return QString();; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } } bool DataProxy_SQLite::updateAwardDXCC() { //qDebug() << "DataProxy_SQLite::updateAwardDXCC" << endl; fillEmptyDXCCInTheLog(); return db->updateAwardDXCCTable(); } bool DataProxy_SQLite::updateAwardWAZ() { //qDebug() << "DataProxy_SQLite::updateAwardWAZ" << endl; return db->updateAwardWAZTable(); } bool DataProxy_SQLite::deleteQSO(const int _qsoId) { //qDebug() << "DataProxy_SQLite::deleteQSO" << endl; QSqlQuery query; QString queryString = QString("DELETE FROM log WHERE id='%1'").arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.finish(); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } } int DataProxy_SQLite::isWorkedB4(const QString _qrz, const int _currentLog) { //qDebug() << "DataProxy_SQLite::isWorkedB4" << endl; //Returns the QSO id QSqlQuery query; QString queryString; if (_currentLog < 0) { queryString = QString("SELECT id FROM log WHERE call='%1'").arg(_qrz); } else { queryString = QString("SELECT id FROM log WHERE call='%1' AND lognumber='%2'").arg(_qrz).arg(_currentLog); } bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } } bool DataProxy_SQLite::isThisQSODuplicated(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode) { //qDebug() << "DataProxy_SQLite::isThisQSODuplicated" << endl; QSqlQuery query; QString queryString; queryString = QString("SELECT id FROM log WHERE call='%1' AND qso_date='%2' AND time_on='%3' AND bandid='%4' AND modeid='%5'").arg(_qrz).arg(_date).arg(_time).arg(_band).arg(_mode); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { if ((query.value(0)).toInt()>0) { query.finish(); return true; } else { query.finish(); return false; } } else { query.finish(); return false; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } return false; } int DataProxy_SQLite::getDuplicatedQSOId(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode) { //qDebug() << "DataProxy_SQLite::isThisQSODuplicated" << endl; QSqlQuery query; QString queryString; int qsoId = -1; queryString = QString("SELECT id FROM log WHERE call='%1' AND qso_date='%2' AND time_on='%3' AND bandid='%4' AND modeid='%5'").arg(_qrz).arg(_date).arg(_time).arg(_band).arg(_mode); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { qsoId = (query.value(0)).toInt(); if (qsoId) { query.finish(); return qsoId; } else { query.finish(); return -1; } } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } return -1; } bool DataProxy_SQLite::isDXCCConfirmed(const int _dxcc, const int _currentLog) { //qDebug() << "DataProxy_SQLite::isDXCCConfirmed: " << QString::number(_dxcc) << "/" << QString::number(_currentLog) << endl; QString queryString = QString("SELECT confirmed from awarddxcc WHERE dxcc='%1' AND lognumber='%2'").arg(_dxcc).arg(_currentLog); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { if ( (query.value(0)).toInt() == 1) { //qDebug() << "DataProxy_SQLite::isDXCCConfrmed: TRUE" << endl; query.finish(); return true; } else { //qDebug() << "DataProxy_SQLite::isDXCCConfrmed: FALSE1" << endl; query.finish(); return false; } } else { //qDebug() << "DataProxy_SQLite::isDXCCConfrmed: FALSE2" << endl; query.finish(); return false; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::isDXCCConfrmed: FALSE3" << endl; query.finish(); return false; } //qDebug() << "DataProxy_SQLite::isDXCCConfrmed: FALSE4" << endl; return false; } bool DataProxy_SQLite::isHF(const int _band) {// 160M is considered as HF if ( (_band>=getIdFromBandName("10M")) && (_band<=getIdFromBandName("160M")) ) { //qDebug() << "DataProxy_SQLite::isHF: TRUE" << endl; return true; } else { //qDebug() << "DataProxy_SQLite::isHF: FALSE" << endl; return false; } } bool DataProxy_SQLite::isWARC(const int _band) { if ( (_band==getIdFromBandName("12M")) || (_band==getIdFromBandName("17M")) || ((_band==getIdFromBandName("30M")) ) ) { //qDebug() << "DataProxy_SQLite::isWARC: tRUE" << endl; return true; } else { //qDebug() << "DataProxy_SQLite::isWARC: FALSE" << endl; return false; } } bool DataProxy_SQLite::isVHF(const int _band) { if (_band<=getIdFromBandName("6M")) { //qDebug() << "DataProxy_SQLite::isVHF: TRUE" << endl; return true; } else { //qDebug() << "DataProxy_SQLite::isVHF: FALSE" << endl; return false; } } bool DataProxy_SQLite::isUHF(const int _band) { if (_band<=getIdFromBandName("70CM")) { //qDebug() << "DataProxy_SQLite::isUHF: TRUE" << endl; return true; } else { //qDebug() << "DataProxy_SQLite::isUHF: FALSE" << endl; return false; } } QStringList DataProxy_SQLite::getOperatingYears(const int _currentLog) { //qDebug() << "DataProxy_SQLite::getYearsOperating: " << QString::number(_currentLog) << endl; QStringList years = QStringList(); //QStringList yearsSorted = QStringList(); QSqlQuery query; QString queryString = QString("SELECT DISTINCT (substr (qso_date, 0, 5)) FROM log WHERE lognumber='%0' ORDER BY 'qso_date'").arg(_currentLog); QString year = QString(); //qDebug() << "DataProxy_SQLite::getYearsOperating: -1" << endl; bool sqlOk = query.exec(queryString); if (sqlOk) { //qDebug() << "DataProxy_SQLite::getYearsOperating: sqlOk = true" << endl; while (query.next()) { if (query.isValid()) { year = (query.value(0)).toString(); //qDebug() << "DataProxy_SQLite::getYearsOperating: year=" << year << endl; years << year; year.clear(); } else { //qDebug() << "DataProxy_SQLite::getYearsOperating: NOT VALID" << endl; } } //qDebug() << "DataProxy_SQLite::getYearsOperating: END OK - " << QString::number(years.size())<< endl; query.finish(); //return years; if (years.length()>0) { years.sort(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getYearsOperating: sqlOk = false" << endl; } return years; } void DataProxy_SQLite::compressDB() { db->compress(); } bool DataProxy_SQLite::unMarkAllQSO() { return db->unMarkAllQSO(); } bool DataProxy_SQLite::lotwSentQueue(const QString _updateDate, const int _currentLog) {// Mark LOTW QSL SENT as Q (Queued) // If currentLog <0 ALL the QSO of the log will be queued //qDebug() << "DataProxy_SQLite::lotwSentQueue: Date:" << _updateDate << " /" << QString::number(_currentLog) << endl; QString queryString; if (_currentLog<1) { queryString = QString("UPDATE log SET lotw_qsl_sent = 'Q', lotw_qslsdate = '%1' WHERE lotw_qsl_sent != 'Y' AND lotw_qsl_sent != 'N' AND lotw_qsl_sent != 'R' AND lotw_qsl_sent != 'I' AND lotw_qsl_sent != 'Q'").arg(_updateDate); } else { queryString = QString("UPDATE log SET lotw_qsl_sent = 'Q', lotw_qslsdate = '%1' WHERE lognumber = '%2' AND lotw_qsl_sent != 'Y' AND lotw_qsl_sent != 'N' AND lotw_qsl_sent != 'R' AND lotw_qsl_sent != 'I' AND lotw_qsl_sent != 'Q'").arg(_updateDate).arg(_currentLog); } QSqlQuery query; bool sqlOK = query.exec(queryString); query.finish(); if (sqlOK) { return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } return false; } bool DataProxy_SQLite::lotwSentYes(const QString _updateDate, const int _currentLog, const QString _station) {// Mark LOTW QSL SENT as Q (Queued) // If currentLog <0 ALL the QSO of the log will be queued //qDebug() << "DataProxy_SQLite::lotwSentQueue: " << QString::number(_currentLog) << endl; QString queryString; if (_currentLog<1) { if (_station == "ALL") { queryString = QString("UPDATE log SET lotw_qsl_sent = 'Y', lotw_qslsdate = '%1' WHERE lotw_qsl_sent == 'Q'"); } else { queryString = QString("UPDATE log SET lotw_qsl_sent = 'Y', lotw_qslsdate = '%1' WHERE lotw_qsl_sent == 'Q' AND station_callsign='%2'").arg(_updateDate).arg(_station); } } else { if (_station == "ALL") { queryString = QString("UPDATE log SET lotw_qsl_sent = 'Y', lotw_qslsdate = '%1' WHERE lognumber = '%2' AND lotw_qsl_sent == 'Q'").arg(_updateDate).arg(_currentLog); } else { queryString = QString("UPDATE log SET lotw_qsl_sent = 'Y', lotw_qslsdate = '%1' WHERE lognumber = '%2' AND lotw_qsl_sent == 'Q' AND station_callsign='%3'").arg(_updateDate).arg(_currentLog).arg(_station); } } QSqlQuery query; bool sqlOK = query.exec(queryString); query.finish(); if (sqlOK) { return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } return false; } int DataProxy_SQLite::getQSOonYear(const int _year, const int _logNumber) { //qDebug() << "DataProxy_SQLite::getQSOonYear: " << QString::number(_year) << "/" << QString::number(_logNumber) << endl; QSqlQuery query; QString queryString; bool sqlOK; queryString = QString("SELECT COUNT (DISTINCT id) FROM log where lognumber='%1' AND qso_date LIKE '%2%'").arg(_logNumber).arg(_year); sqlOK = query.exec(queryString); //qDebug() << "DataProxy_SQLite::getQSOonYear: queryString: " << queryString << endl; if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getQSOonYear: " << QString::number((query.value(0)).toInt()) << endl; int v = (query.value(0)).toInt(); query.finish(); return v; } else { //qDebug() << "DataProxy_SQLite::getQSOonYear: 0" << endl; query.finish(); return 0; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getDXCConYear: Query error" << endl; query.finish(); return 0; } } int DataProxy_SQLite::getDXCConYear(const int _year, const int _logNumber) { //qDebug() << "DataProxy_SQLite::getDXCConYear: " << QString::number(_year) << "/" << QString::number(_logNumber) << endl; QSqlQuery query; QString queryString; bool sqlOK; queryString = QString("SELECT COUNT (DISTINCT dxcc) FROM log where lognumber='%1' AND qso_date LIKE '%2%'").arg(_logNumber).arg(_year); sqlOK = query.exec(queryString); //qDebug() << "DataProxy_SQLite::getDXCConYear: queryString: " << queryString << endl; if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getDXCConYear: " << QString::number((query.value(0)).toInt()) << endl; int v = (query.value(0)).toInt(); query.finish(); return v; } else { //qDebug() << "DataProxy_SQLite::getDXCConYear: 0" << endl; query.finish(); return 0; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getDXCConYear: Query error" << endl; query.finish(); return 0; } } int DataProxy_SQLite::getCQzonYear(const int _year, const int _logNumber) { //qDebug() << "DataProxy_SQLite::getCQzonYear: " << QString::number(_year) << endl; QSqlQuery query; QString queryString; bool sqlOK; queryString = QString("SELECT COUNT (DISTINCT cqz) FROM log where lognumber='%1' AND qso_date LIKE '%2%'").arg(_logNumber).arg(_year); sqlOK = query.exec(queryString); //qDebug() << "DataProxy_SQLite::getCQzonYear: queryString: " << queryString << endl; if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getCQzonYear: " << QString::number((query.value(0)).toInt()) << endl; int v = (query.value(0)).toInt(); query.finish(); return v; } else { //qDebug() << "DataProxy_SQLite::getCQzonYear: 0" << endl; query.finish(); return 0; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getCQzonYear: Query error" << endl; query.finish(); return 0; } } bool DataProxy_SQLite::newDXMarathon(const int _dxcc, const int _cq, const int _year, const int _logNumber) { //qDebug() << "DataProxy_SQLite::newDXMarathon" << endl; QSqlQuery query; QString queryString; bool sqlOK; bool existingDXCC = false; bool existingCQz = false; queryString = QString("SELECT dxcc, cqz FROM log WHERE (lognumber='%1' AND qso_date LIKE'%%2%') AND (dxcc ='%3' OR cqz ='%4')").arg(_logNumber).arg(_year).arg(_dxcc).arg(_cq); sqlOK = query.exec(queryString); if (sqlOK) { while(query.next()) { if (query.isValid()) { if ( (query.value(0)).toInt() == _dxcc) { //qDebug() << "DataProxy_SQLite::newDXMarathon - Existing DXCC" << endl; existingDXCC = true; } if ( (query.value(1)).toInt() == _cq) { //qDebug() << "DataProxy_SQLite::newDXMarathon - Existing CQz" << endl; existingCQz = true; } } } if (existingDXCC && existingCQz) { //qDebug() << "DataProxy_SQLite::newDXMarathon - FALSE" << endl; query.finish(); return false; } else { //qDebug() << "DataProxy_SQLite::newDXMarathon - TRUE1" << endl; query.finish(); return true; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::newDXMarathon - TRUE2" << endl; query.finish(); return true; // It is an error inthe query but Work First Worry Later, let us work that QSO. } //qDebug() << "DataProxy_SQLite::newDXMarathon - TRUE3" << endl; return true; } QStringList DataProxy_SQLite::getContestNames() { //qDebug() << "DataProxy_SQLite::getContestNames() " << endl; QStringList contests = QStringList(); QSqlQuery query; QString queryString; bool sqlOK; queryString = QString("SELECT DISTINCT name from supportedcontests ORDER BY id ASC"); sqlOK = query.exec(queryString); if (sqlOK) { while(query.next()) { if (query.isValid()) { queryString = (query.value(0)).toString(); //qDebug() << "DataProxy_SQLite::getContestNames: " << queryString << endl; contests.append(queryString); } else { query.finish(); return QStringList(); } } query.finish(); return contests; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } return QStringList(); } QStringList DataProxy_SQLite::getContestCat(const int _catn) { QStringList contests = QStringList(); QSqlQuery query; QString queryString; bool sqlOK; switch (_catn) { case 1: queryString = QString("SELECT DISTINCT name from contestcatoperator ORDER BY id ASC"); break; case 2: queryString = QString("SELECT DISTINCT name from contestcatassisted ORDER BY id ASC"); break; case 3: queryString = QString("SELECT DISTINCT name from contestcatpower ORDER BY id ASC"); break; case 4: queryString = QString("SELECT DISTINCT name from contestcatband ORDER BY id ASC"); break; case 5: queryString = QString("SELECT DISTINCT name from contestcatoverlay ORDER BY id ASC"); break; case 6: queryString = QString("SELECT DISTINCT name from contestcatmode ORDER BY id ASC"); break; default: return QStringList(); break; } sqlOK = query.exec(queryString); if (sqlOK) { while(query.next()) { if (query.isValid()) { queryString = (query.value(0)).toString(); contests.append(queryString); } else { query.finish(); return QStringList(); } } query.finish(); return contests; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } return QStringList(); } QStringList DataProxy_SQLite::getContestOverlays() { //qDebug() << "DataProxy_SQLite::getContestOverlays: "<< endl; QStringList contests = QStringList(); QSqlQuery query; QString queryString; bool sqlOK; queryString = QString("SELECT DISTINCT name from contestcatoverlay ORDER BY id ASC"); sqlOK = query.exec(queryString); if (sqlOK) { while(query.next()) { if (query.isValid()) { queryString = (query.value(0)).toString(); //qDebug() << "DataProxy_SQLite::getContestOverlays: " << queryString << endl; contests.append(queryString); } else { query.finish(); return QStringList(); } } query.finish(); return contests; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } return QStringList(); } QStringList DataProxy_SQLite::getPropModeList() { //qDebug() << "DataProxy_SQLite::getPropModeLists" << endl; QString aux = QString(); QStringList qs; qs.clear(); QString queryString = QString("SELECT id, shortname, name FROM prop_mode_enumeration ORDER BY name"); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { while ( (query.next())) { if (query.isValid()) { aux.clear(); aux = (query.value(0)).toString() + " - " + (query.value(1)).toString() + " - " + (query.value(2)).toString(); qs << aux; } else { } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } query.finish(); return qs; } QStringList DataProxy_SQLite::getSatellitesList() { //qDebug() << "DataProxy_SQLite::getSatellitesList" << endl; QString aux = QString(); QStringList qs; qs.clear(); QString queryString = QString("SELECT satarrlid, satname FROM satellites"); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { while ( (query.next())) { if (query.isValid()) { aux.clear(); aux = (query.value(0)).toString() + " - " + (query.value(1)).toString(); qs << aux; } else { } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } query.finish(); return qs; } QString DataProxy_SQLite::getSatelliteUplink(const QString _sat) { //qDebug() << "DataProxy_SQLite::getSatelliteUplink: " << _sat << endl; QString aux = QString(); QString aux2 = QString(); //double fr1, fr2, fr; QString queryString = QString("SELECT uplink FROM satellites WHERE satarrlid='%1'").arg(_sat); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { aux = query.value(0).toString(); aux = QString::number(getFreqFromRange(aux)); } else { //qDebug() << "DataProxy_SQLite::getSatelliteUplink: query not valid" << endl; query.finish(); return QString(); } } else { //qDebug() << "DataProxy_SQLite::getSatelliteUplink: query failed: " << query.lastQuery() << endl; emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } //qDebug() << "DataProxy_SQLite::getSatelliteUplink: final: " << aux << endl; query.finish(); return aux; } QString DataProxy_SQLite::getSatelliteDownlink(const QString _sat) { //qDebug() << "DataProxy_SQLite::getSatelliteDownlink: " << _sat << endl; QString aux = QString(); QString aux2 = QString(); //double fr1, fr2, fr; QString queryString = QString("SELECT downlink FROM satellites WHERE satarrlid='%1'").arg(_sat); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { aux = query.value(0).toString(); aux = QString::number(getFreqFromRange(aux)); } else { //qDebug() << "DataProxy_SQLite::getSatelliteDownlink: query not valid" << endl; query.finish(); return QString(); } } else { //qDebug() << "DataProxy_SQLite::getSatelliteDownlink: query failed: " << query.lastQuery() << endl; emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } //qDebug() << "DataProxy_SQLite::getSatelliteDownlink: final: " << aux << endl; query.finish(); return aux; } double DataProxy_SQLite::getFreqFromRange(QString _fr) { //May even receive: 145.900-146.00 and should return the mid in the range (145.950) //qDebug() << "DataProxy_SQLite::getFreqFromRange: " << _fr << endl; QString fr1, fr2, aux; double f1, f2; fr1.clear(); fr2.clear(); f1 = 0.0; f2 = 0.0; aux.clear(); aux = _fr; if (aux.contains(',')) { // Potentially somethink like: 435.030-435.456,146.180 // We select the first range //qDebug() << "DataProxy_SQLite::getFreqFromRange: has several freqs: " << aux << endl; aux = aux.section(',', 0, 0); // We select the first package } if (aux.contains('-')) // Potentially somethink like: 435.030-435.456 { //qDebug() << "DataProxy_SQLite::getFreqFromRange: has several freqs: " << aux << endl; fr2 = aux.section('-', 1, 1); // We select the second freq fr1 = aux.section('-', 0, 0); // We select the first freq //qDebug() << "DataProxy_SQLite::getFreqFromRange: fr1: " << fr1 << endl; //qDebug() << "DataProxy_SQLite::getFreqFromRange: fr2: " << fr2 << endl; f1 = fr1.toDouble(); f2 = fr2.toDouble(); //qDebug() << "DataProxy_SQLite::getFreqFromRange: f1: " << QString::number(f1) << endl; //qDebug() << "DataProxy_SQLite::getFreqFromRange: f2: " << QString::number(f2) << endl; f1 = (f2 + f1)/2; //qDebug() << "DataProxy_SQLite::getFreqFromRange: f1 after calc: " << QString::number(f1) << endl; } else { // It is only one freq 145.950 so this is what must be returned f1 = aux.toDouble(); } //qDebug() << "DataProxy_SQLite::getFreqFromRange: Return: " << QString::number(f1) << endl; return f1; } QStringList DataProxy_SQLite::getQSLRcvdList() { //qDebug() << "DataProxy_SQLite::getQSLRcvdList" << endl; QString aux = QString(); QStringList qs; qs.clear(); QString queryString = QString("SELECT shortname, name FROM qsl_rec_status"); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { while ( (query.next())) { if (query.isValid()) { aux.clear(); aux = (query.value(0)).toString() + " - " + (query.value(1)).toString(); qs << aux; } else { } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } query.finish(); return qs; } QStringList DataProxy_SQLite::getQSLSentList() { //qDebug() << "DataProxy_SQLite::getQSLSentList" << endl; QString aux = QString(); QStringList qs; qs.clear(); QString queryString = QString("SELECT shortname, name FROM qsl_sent_status"); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { while ( (query.next())) { if (query.isValid()) { aux.clear(); aux = (query.value(0)).toString() + " - " + (query.value(1)).toString(); qs << aux; } else { } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } query.finish(); return qs; } QStringList DataProxy_SQLite::getClubLogStatusList() { //qDebug() << "DataProxy_SQLite::getClubLogStatusList" << endl; QString aux = QString(); QStringList qs; qs.clear(); QString queryString = QString("SELECT shortname, name FROM clublog_status"); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { while ( (query.next())) { if (query.isValid()) { aux.clear(); aux = (query.value(0)).toString() + " - " + (query.value(1)).toString(); qs << aux; } else { } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } query.finish(); return qs; } QStringList DataProxy_SQLite::getQSLViaList() { //qDebug() << "DataProxy_SQLite::getQSLViaList" << endl; QString aux = QString(); QStringList qs; qs.clear(); QString queryString = QString("SELECT shortname, name FROM qsl_via"); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { while ( (query.next())) { if (query.isValid()) { aux.clear(); aux = (query.value(0)).toString() + " - " + (query.value(1)).toString(); qs << aux; } else { } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } query.finish(); return qs; } QStringList DataProxy_SQLite::getValidCatOptions(const int _currentCat, const int _lowerCat) { //qDebug() << "DataProxy_SQLite::getContestNames: " << QString::number(_currentCat) <<"/" << QString::number(_lowerCat) << endl; QStringList contests = QStringList(); QSqlQuery query; QString queryString; bool sqlOK; switch (_currentCat) { case 0: queryString = QString("SELECT DISTINCT contestcatoperator.name FROM contestcatoperator JOIN contest ON contest.catoperator=contestcatoperator.id WHERE contest.contest='%1' ORDER BY contestcatoperator.id").arg(_lowerCat); break; case 1: queryString = QString("SELECT DISTINCT contestcatassisted.name FROM contestcatassisted JOIN contest ON contest.catassisted=contestcatassisted.id WHERE contest.catoperator='1' ORDER BY contestcatassisted.id").arg(_lowerCat); break; case 2: queryString = QString("SELECT DISTINCT contestcatpower.name FROM contestcatpower JOIN contest ON contest.catpower=contestcatpower.id WHERE contest.catoperator='1' ORDER BY contestcatpower.id").arg(_lowerCat); break; case 3: queryString = QString("SELECT DISTINCT contestcatband.name FROM contestcatband JOIN contest ON contest.catband=contestcatband.id WHERE contest.catoperator='1' ORDER BY contestcatband.id").arg(_lowerCat); break; case 4: queryString = QString("SELECT DISTINCT contestcatoverlay.name FROM contestcatoverlay JOIN contest ON contest.catoverlay=contestcatoverlay.id WHERE contest.catoperator='1' ORDER BY contestcatoverlay.id").arg(_lowerCat); break; case 5: queryString = QString("SELECT DISTINCT contestcatmode.name FROM contestcatmode JOIN contest ON contest.catmode=contestcatmode.id WHERE contest.catoperator='1' ORDER BY contestcatmode.id").arg(_lowerCat); break; default: return QStringList(); break; } sqlOK = query.exec(queryString); if (sqlOK) { while(query.next()) { if (query.isValid()) { queryString = (query.value(0)).toString(); contests.append(queryString); } else { query.finish(); return QStringList(); } } query.finish(); return contests; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } } bool DataProxy_SQLite::haveAtLeastOneLog() { //qDebug() << "DataProxy_SQLite::haveAtLeastOneLog()" << endl; QSqlQuery query; bool sqlOK = query.exec("SELECT COUNT(id) from logs"); if (sqlOK) { query.next(); if (query.isValid()) { if((query.value(0)).toInt()>0) { query.finish(); return true; } else { query.finish(); return false; } } else { query.finish(); return false; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } return false; } QStringList DataProxy_SQLite::getColumnNamesFromTableLog() { //qDebug() << "DataProxy_SQLite::getColumnNamesFromTableLog" << endl; return getColumnNamesFromTable("log"); } QStringList DataProxy_SQLite::getColumnNamesFromTable(const QString _tableName) { //qDebug() << "DataProxy_SQLite::getColumnNamesFromTable" << endl; return db->getColumnNamesFromTable(_tableName); } bool DataProxy_SQLite::setDXCCAwardStatus(const int _qsoId) { // If the band/mode/log is already confirmed: Return true // If the band/mode/log is already worked and status worked: Return true // If the band/mode/log is already worked and status confirmed: Update and Return true // If not worked: Add and Return true //qDebug() << "DataProxy_SQLite::setDXCCAwardStatus: " << QString::number(_qsoId) << endl; if (_qsoId <= 0) { return false; } int _dxcc = getDXCCFromId(_qsoId); if (_dxcc <= 0) { return false; } int _band = getBandFromId(_qsoId); if (_band <= 0) { return false; } int _mode = getModeFromId(_qsoId); if (_mode <= 0) { return false; } int _log = getLogNumberFromQSOId(_qsoId); if (_log <= 0) { return false; } // If the band/mode/log is already confirmed: Return true QSqlQuery query; // awarddxcc id dxcc band mode confirmed qsoid lognumber // If the band/mode/log is already confirmed: Return true // If the band/mode/log is already worked and status worked: Return true // If the band/mode/log is already worked and status confirmed: Update and Return true // If not worked: Add and Return true QString queryString = QString("SELECT id, confirmed, qsoid FROM awarddxcc WHERE band='%1' AND mode='%2' AND dxcc='%3'").arg(_band).arg(_mode).arg(_dxcc); bool sqlOK = query.exec(queryString); queryString.clear(); if (sqlOK) { QSqlRecord rec = query.record(); query.next(); int nameCol = -1; if (query.isValid()) { nameCol = rec.indexOf("id"); int __id = (query.value(nameCol)).toInt(); nameCol = rec.indexOf("confirmed"); QString __confirmed = (query.value(nameCol)).toString(); if (__confirmed == "1") { // #1 - If the band/mode/log is already confirmed: Return true query.finish(); return true; } else if (__confirmed == "0") { if (!isQSLReceived((_qsoId))) {// #2 - If the band/mode/log is already worked and status worked: Return true query.finish(); return true; } else { // #3 - If the band/mode/log is already worked and status confirmed: Update and Return true nameCol = rec.indexOf("qsoid"); //int __qsoid = (query.value(nameCol)).toInt(); queryString = QString("UPDATE awarddxcc SET confirmed = '1', qsoid = '%1' WHERE id = '%2'").arg(_qsoId).arg(__id); } } else { // This case should not happen? query.finish(); return true; } query.finish(); // #1 - If the band/mode/log is already confirmed: Return true // #2 - If the band/mode/log is already worked and status worked: Return true // #3 - If the band/mode/log is already worked and status confirmed: Update and Return true // #4 - If not worked: Add and Return true } else { //#4 - If not worked: Add and Return true query.finish(); // awarddxcc id dxcc band mode confirmed qsoid lognumber queryString = QString("INSERT INTO awarddxcc (dxcc, band, mode, confirmed, qsoid, lognumber) values('%1','%2','%3','%4', '%5', '%6')").arg(_dxcc); } if (queryString.length()>5) { if (query.exec(queryString)) { query.finish(); return true; } else { if(query.lastError().number()==19) {} else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } query.finish(); return true; } bool DataProxy_SQLite::setWAZAwardStatus(const int _qsoId) { // If the band/mode/log is already confirmed: Return true // If the band/mode/log is already worked and status worked: Return true // If the band/mode/log is already worked and status confirmed: Update and Return true // If not worked: Add and Return true //qDebug() << "DataProxy_SQLite::setDXCCAwardStatus: " << QString::number(_qsoId) << endl; if (_qsoId <= 0) { return false; } int _cqz = getCQZFromId(_qsoId); if (_cqz <= 0) { return false; } int _band = getBandFromId(_qsoId); if (_band <= 0) { return false; } int _mode = getModeFromId(_qsoId); if (_mode <= 0) { return false; } int _log = getLogNumberFromQSOId(_qsoId); if (_log <= 0) { return false; } // If the band/mode/log is already confirmed: Return true QSqlQuery query; // awarddxcc id dxcc band mode confirmed qsoid lognumber // If the band/mode/log is already confirmed: Return true // If the band/mode/log is already worked and status worked: Return true // If the band/mode/log is already worked and status confirmed: Update and Return true // If not worked: Add and Return true QString queryString = QString("SELECT id, confirmed, qsoid FROM awardwaz WHERE band='%1' AND mode='%2' AND cqz='%3'").arg(_band).arg(_mode).arg(_cqz); bool sqlOK = query.exec(queryString); queryString.clear(); if (sqlOK) { QSqlRecord rec = query.record(); query.next(); int nameCol = -1; if (query.isValid()) { nameCol = rec.indexOf("id"); int __id = (query.value(nameCol)).toInt(); nameCol = rec.indexOf("confirmed"); QString __confirmed = (query.value(nameCol)).toString(); if (__confirmed == "1") { // #1 - If the band/mode/log is already confirmed: Return true query.finish(); return true; } else if (__confirmed == "0") { if (!isQSLReceived((_qsoId))) {// #2 - If the band/mode/log is already worked and status worked: Return true query.finish(); return true; } else { // #3 - If the band/mode/log is already worked and status confirmed: Update and Return true nameCol = rec.indexOf("qsoid"); //int __qsoid = (query.value(nameCol)).toInt(); queryString = QString("UPDATE awardcqz SET confirmed = '1', qsoid = '%1' WHERE id = '%2'").arg(_qsoId).arg(__id); } } else { // This case should not happen? query.finish(); return true; } query.finish(); // #1 - If the band/mode/log is already confirmed: Return true // #2 - If the band/mode/log is already worked and status worked: Return true // #3 - If the band/mode/log is already worked and status confirmed: Update and Return true // #4 - If not worked: Add and Return true } else { //#4 - If not worked: Add and Return true query.finish(); // awarddxcc id dxcc band mode confirmed qsoid lognumber queryString = QString("INSERT INTO awardwaz (cqz, band, mode, confirmed, qsoid, lognumber) values('%1','%2','%3','%4', '%5', '%6')").arg(_cqz); } if (queryString.length()>5) { if (query.exec(queryString)) { query.finish(); return true; } else { if(query.lastError().number()==19) {} else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } query.finish(); return true; } int DataProxy_SQLite::getNumberOfManagedLogs() { //qDebug() << "DataProxy_SQLite::getNumberOfManagedLogs" << endl; QSqlQuery query; bool sqlOK = query.exec("SELECT COUNT (*) from logs"); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } return -1; } int DataProxy_SQLite::getMaxLogNumber() { QSqlQuery query; QString queryString = QString("SELECT MAX(id) FROM logs"); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } return -1; } QStringList DataProxy_SQLite::getListOfManagedLogs() { //This function returns the list of log IDs that are being managed //qDebug() << "DataProxy_SQLite::getListOfManagedLogs" << endl; QSqlQuery query; QStringList qs; qs.clear(); QString queryString = QString("SELECT id FROM logs"); bool sqlOK = query.exec(queryString); if (sqlOK) { while (query.next()) { if (query.isValid()) { qs << (query.value(0)).toString(); //qDebug() << "DataProxy_SQLite::getListOfManagedLogs: " << (query.value(0)).toString() << endl; } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); qs.clear(); } query.finish(); return qs; } QString DataProxy_SQLite::getStationCallSignFromLog(const int _log) { //qDebug() << "DataProxy_SQLite::getStationCallSignFromLog: " << QString::number(_log)<< endl; QSqlQuery query; QString queryString = QString("SELECT stationcall FROM logs WHERE id='%1'").arg(_log); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getStationCallSignFromLog: " << (query.value(0)).toString() << endl; QString v = (query.value(0)).toString(); query.finish(); return v; } else { //qDebug() << "DataProxy_SQLite::getStationCallSignFromLog: Not valid" << endl; query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getStationCallSignFromLog: query failed" << endl; query.finish(); return QString(); } //qDebug() << "DataProxy_SQLite::getStationCallSignFromLog: END" << endl; return QString(); } QStringList DataProxy_SQLite::getStationCallSignsFromLog(const int _log) { //qDebug() << "DataProxy_SQLite::getStationCallSignsFromLog" << endl; QStringList calls = QStringList(); QSqlQuery query; QString queryString; bool sqlOK; queryString = QString("SELECT DISTINCT station_callsign FROM log"); sqlOK = query.exec(queryString); if (sqlOK) { while(query.next()) { if (query.isValid()) { queryString = (query.value(0)).toString(); if (queryString.length()>2) { calls.append(queryString); } //qDebug() << "DataProxy_SQLite::getStationCallSignsFromLog: " << queryString << endl; } else { query.finish(); return QStringList(); } } query.finish(); calls.removeDuplicates(); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } return calls; } QString DataProxy_SQLite::getOperatorsFromLog(const int _log) { //qDebug() << "DataProxy_SQLite::getOperatorsFromLog: " << QString::number(_log)<< endl; QSqlQuery query; QString queryString = QString("SELECT operators FROM logs WHERE id='%1'").arg(_log); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getOperatorsFromLog: " << (query.value(0)).toString() << endl; QString v = (query.value(0)).toString(); query.finish(); return v; } else { //qDebug() << "DataProxy_SQLite::getOperatorsFromLog: Not valid" << endl; query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getOperatorsFromLog: query failed" << endl; query.finish(); return QString(); } //qDebug() << "DataProxy_SQLite::getOperatorsFromLog: END" << endl; return QString(); } QString DataProxy_SQLite::getCommentsFromLog(const int _log) { //qDebug() << "DataProxy_SQLite::getLogDateFromLog: " << QString::number(_log)<< endl; QSqlQuery query; QString queryString = QString("SELECT comment FROM logs WHERE id='%1'").arg(_log); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getLogDateFromLog: " << (query.value(0)).toString() << endl; QString v = (query.value(0)).toString(); query.finish(); return v; } else { //qDebug() << "DataProxy_SQLite::getLogDateFromLog: Not valid" << endl; query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getLogDateFromLog: query failed" << endl; query.finish(); return QString(); } //qDebug() << "DataProxy_SQLite::getCommentsFromLog: END" << endl; return QString(); } QString DataProxy_SQLite::getLogDateFromLog(const int _log) { //qDebug() << "DataProxy_SQLite::getLogDateFromLog: " << QString::number(_log)<< endl; QSqlQuery query; QString queryString = QString("SELECT logdate FROM logs WHERE id='%1'").arg(_log); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getLogDateFromLog: " << (query.value(0)).toString() << endl; QString v = (query.value(0)).toString(); query.finish(); return v; } else { //qDebug() << "DataProxy_SQLite::getLogDateFromLog: Not valid" << endl; query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getLogDateFromLog: query failed" << endl; query.finish(); return QString(); } //qDebug() << "DataProxy_SQLite::getLogDateFromLog: END" << endl; return QString(); } QString DataProxy_SQLite::getLogTypeNFromLog(const int _log) { //qDebug() << "DataProxy_SQLite::getLogTypeNFromLog: " << QString::number(_log)<< endl; QSqlQuery query; QString queryString = QString("SELECT logtypen FROM logs WHERE id='%1'").arg(_log); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getLogTypeNFromLog: " << (query.value(0)).toString() << endl; QString v = (query.value(0)).toString(); query.finish(); return v; } else { //qDebug() << "DataProxy_SQLite::getLogTypeNFromLog: Not valid" << endl; query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getLogTypeNFromLog: query failed" << endl; query.finish(); return QString(); } //qDebug() << "DataProxy_SQLite::getLogTypeNFromLog: END" << endl; return QString(); } int DataProxy_SQLite::getContestTypeN(const int _co, const int _catop, const int _catas, const int _catpo, const int _catba, const int _catov, const int _catmo) {//typeContestSelected, contestCatOperators, contestCatAssisted, contestCatPower, contestCatBands, contestCatOverlay, contestCatMode //qDebug() << "DataProxy_SQLite::getContestTypeN: " << endl; QSqlQuery query; QString queryString = QString("SELECT id FROM contest WHERE contest='%1' AND catoperator='%2' AND catassisted='%3' AND catpower='%4' AND catoverlay='%5' AND catmode='%6' AND catband='%7'").arg(_co).arg(_catop).arg(_catas).arg(_catpo).arg(_catov).arg(_catmo).arg(_catba); //qDebug() << "DataProxy_SQLite::getContestTypeN: " << st << endl; bool sqlOK = query.exec(queryString); if (sqlOK) { //qDebug() << "DataProxy_SQLite::getContestTypeN: (OK) LastQuery: " << query.lastQuery() << endl; query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getContestTypeN: " << (query.value(0)).toString() << endl; int v = (query.value(0)).toInt(); query.finish(); return v; } else { //qDebug() << "DataProxy_SQLite::getContestTypeN: Not valid (-1)" << endl; query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getContestTypeN: (ERROR) LastQuery: " << query.lastQuery() << endl; //qDebug() << "DataProxy_SQLite::getContestTypeN: query failed (-1)" << endl; query.finish(); return -1; } //qDebug() << "DataProxy_SQLite::getContestTypeN: END (-1)" << endl; return -1; } QStringList DataProxy_SQLite::getDataFromContestType(const int _n) { //qDebug() << "DataProxy_SQLite::getDataFromContestType - n: " << QString::number(_n) << endl; QStringList dataC = QStringList(); QSqlQuery query, query1; QString queryString; int nameCol = -1; bool sqlOK; queryString = QString("SELECT supportedcontests.name, contest.contest, contest.catoperator, contest.catassisted, contest.catpower, contest.catoverlay, contest.catmode, contest.catband FROM supportedcontests JOIN contest ON contest.contest=supportedcontests.id WHERE contest.id='%1'").arg(_n); sqlOK = query.exec(queryString); //qDebug() << "DataProxy_SQLite::getDataFromContestType: LastQuery: " << query.lastQuery() << endl; QSqlRecord rec = query.record(); if (sqlOK) { //qDebug() << "DataProxy_SQLite::getDataFromContestType: Query OK" << endl; if(query.next()) { //qDebug() << "DataProxy_SQLite::getDataFromContestType: Query Next" << endl; if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getDataFromContestType: Query Valid" << endl; //qDebug() << "DataProxy_SQLite::getDataFromContestType:-1 " << endl; nameCol = rec.indexOf("contest"); dataC << (query.value(nameCol)).toString(); //qDebug() << "DataProxy_SQLite::getDataFromContestType: -2" << endl; nameCol = rec.indexOf("catoperator"); dataC << (query.value(nameCol)).toString(); //qDebug() << "DataProxy_SQLite::getDataFromContestType: -3" << endl; nameCol = rec.indexOf("catassisted"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("catpower"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("catoverlay"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("catmode"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("name"); dataC << (query.value(nameCol)).toString(); nameCol = rec.indexOf("catband"); dataC << (query.value(nameCol)).toString(); query.finish(); return dataC; } else { //qDebug() << "DataProxy_SQLite::getDataFromContestType: Query value no valid" << endl; query.finish(); return QStringList(); } } else { //qDebug() << "DataProxy_SQLite::getDataFromContestType: No Next" << endl; query.finish(); return QStringList(); } query.finish(); return dataC; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getDataFromContestType: Query not OK" << endl; query.finish(); return QStringList(); } } int DataProxy_SQLite::getLogTypeNumber(const QString _logType) { return db->getLogTypeNumber(_logType); } QString DataProxy_SQLite::getLogTypeName(const int _logType) { return db->getLogTypeName(_logType); } QString DataProxy_SQLite::getLogTypeOfUserLog(const int _logN) { /* * Returns the type of log (DX, CQ-WW-SSB, ...) or DX as default if nothing found */ //qDebug() << "DataProxy_SQLite::getLogTypeOfUserLog: " << QString::number(_logN) << endl; QSqlQuery query; QString queryString; queryString = QString("SELECT logtype FROM logs WHERE id='%1'").arg(_logN); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataProxy_SQLite::getLogTypeOfUserLog: found: " << (query.value(0)).toString() << endl; queryString = (query.value(0)).toString(); query.finish(); return queryString; } else { //qDebug() << "DataProxy_SQLite::getLogTypeOfUserLog: NOT found: returning DX" << endl; query.finish(); return "DX"; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getLogTypeOfUserLog: Query error: returning DX" << endl; query.finish(); return "DX"; } } int DataProxy_SQLite::getLogNumberFromQSOId(const int _qsoId) { QSqlQuery query; QString queryString = QString("SELECT lognumber FROM log WHERE id='%1'").arg(_qsoId); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } } bool DataProxy_SQLite::fillEmptyDXCCInTheLog() { //qDebug() << "DataProxy_SQLite::fillEmptyDXCCInTheLog" << endl; int nameCol = -1; QSqlQuery query; QSqlQuery query2; QString queryString = QString("SELECT COUNT (id) FROM log WHERE dxcc =''"); bool sqlOK = query.exec(queryString); int qsos = -1; if (sqlOK) { //QSqlDatabase::database().commit(); query.next(); qsos = (query.value(0)).toInt(); query.finish(); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } if (qsos < 1) { return true; } int step = util->getProgresStepForDialog(qsos); QProgressDialog progress(QObject::tr("Updating DXCC information..."), QObject::tr("Abort updating"), 0, qsos); progress.setMaximum(qsos); progress.setWindowModality(Qt::WindowModal); queryString = QString("SELECT id, call FROM log WHERE dxcc =''"); sqlOK = query.exec(queryString); if (sqlOK) { QSqlRecord rec = query.record(); QString _call = QString(); QString _id = QString(); QString _dxcc = QString(); QString _aux = QString(); int j = 0; while (query.next()) { if (query.isValid()) { nameCol = rec.indexOf("id"); _id = (query.value(nameCol)).toString(); nameCol = rec.indexOf("call"); _call = (query.value(nameCol)).toString(); _dxcc = QString::number(getPrefixId(_call)); // UPDATE THE ID WITH THE DXCC queryString = QString("UPDATE log SET dxcc = '%1' WHERE id = '%2'").arg(_dxcc).arg(_id); sqlOK = query2.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query2.lastError().databaseText(), query2.lastError().number(), query2.lastQuery()); query.finish(); return false; } query2.finish(); if (( (j % step )== 0) ) { // To update the speed I will only show the progress once each X QSOs _aux = QObject::tr("Updating DXCC Award information...") + "\n" + QObject::tr("QSO: ") + QString::number(j) + "/" + QString::number(qsos); progress.setLabelText(_aux); progress.setValue(j); } if ( progress.wasCanceled() ) { //qDebug() << "DataBase::fillEmptyDXCCInTheLog: progress canceled" << endl; return true; } j++; } progress.setValue(qsos); } QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setWindowTitle(tr("KLog DXCC")); msgBox.setText(tr("All QSOs have been updated with a DXCC.") ); msgBox.exec(); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } query.finish(); return true; } int DataProxy_SQLite::getHowManyQSOInLog(const int _log) { QSqlQuery query; QString queryString = QString("SELECT count(id) FROM log WHERE lognumber='%1'").arg(_log); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return 0; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return 0; } } int DataProxy_SQLite::getHowManyConfirmedQSLInLog(const int _log) { if (!doesThisLogExist(_log)) { return 0; } QSqlQuery query; QString queryString = QString("SELECT count(id) FROM log WHERE qsl_rcvd='Y' AND lognumber='%1'").arg(_log); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return 0; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return 0; } } bool DataProxy_SQLite::addNewLog (const QStringList _qs) { //qDebug() << "DataProxy_SQLite::addNewLog: " << _qs.at(2) << "/" << _qs.at(5) << "/" << _qs.at(6) << endl; //_qs << dateString << stationCallsign << _qs.at(4) << comment << _qs.at(12); //qDebug() << "DataProxy_SQLite::slotAnalyzeNewLogData: " << _qs.at(4) << "/" << _qs.at(12) << endl; // Date/Call/Operators/"DX"/comment/"1" if (_qs.size()!=8) { //qDebug() << "DataProxy_SQLite::addNewLog: != 8" << endl; return false; } //qDebug() << "DataProxy_SQLite::addNewLog: Has the appropriate length" << endl; QString aux = QString(); //int nameCol = -1; QString _dateString = _qs.at(0); QString _stationCallsign = _qs.at(1); QString _operators = _qs.at(2); //_operators.clear(); //_operators << (_qs.at(2)).split(',', QString::SkipEmptyParts); QString _typeContest = _qs.at(3); QString _comment = _qs.at(4); QString _typeContestN = _qs.at(5); QString id = _qs.at(6); QString editing = _qs.at(7); QString queryString; QSqlQuery query; bool sqlOK; if (editing == "1") { // We are editing //qDebug() << "DataProxy_SQLite::addNewLog: We are editing!" << endl; queryString = QString("UPDATE logs SET logdate = '%1', stationcall = '%2', operators = '%3', comment = '%4', logtype = '%5', logtypen = '%6' WHERE id = '%7'").arg(_dateString).arg(_stationCallsign).arg(_operators).arg(_comment).arg(_typeContest).arg(_typeContestN).arg(id); sqlOK = query.exec(queryString); if (sqlOK) { //qDebug() << "DataProxy_SQLite::addNewLog: Editing OK!" << endl; query.finish(); return true; } else { //qDebug() << "DataProxy_SQLite::addNewLog: Editing NOK!" << endl; emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } return false; } //qDebug() << "DataProxy_SQLite::addNewLog: We are adding a new log" << endl; // First we check if the log is already there queryString = QString("SELECT id FROM logs WHERE logdate='%1' AND stationcall='%2' AND logtype='%3' AND logtypen='%4'").arg(_dateString).arg(_stationCallsign).arg(_typeContest).arg(_typeContestN); //"logs" //"id, logdate, stationcall, comment, logtype" //qDebug() << "DataProxy_SQLite::addNewLog query1: " << queryString << endl; sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { // It seems that the log is already existing! return false; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } //Now we add the new log queryString = QString("INSERT INTO logs (logdate, stationcall, operators, comment, logtype, logtypen) values('%1','%2','%3','%4', '%5', '%6')").arg(_dateString).arg(_stationCallsign).arg(_operators).arg(_comment).arg(_typeContest).arg(_typeContestN); //qDebug() << "DataProxy_SQLite::addNewLog query1: " << queryString << endl; sqlOK = query.exec(queryString); if (sqlOK) { query.finish(); return true; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } return false; } bool DataProxy_SQLite::doesThisLogExist(const int _log) { //qDebug() << "DataProxy_SQLite::doesThisLogExist: " << QString::number(_log) << endl; //qDebug() << "DataProxy_SQLite::doesThisLogExist - Name:" << db->getDBName() << endl; QSqlQuery query; QString queryString = QString("SELECT id FROM logs WHERE id='%1'").arg(_log); bool sqlOK = query.exec(queryString); //qDebug() << "DataProxy_SQLite::doesThisLogExist: query: " << query.lastQuery() << endl; if (sqlOK) { if (query.next()) { if (query.isValid()) { query.finish(); //qDebug() << "DataProxy_SQLite::doesThisLogExist: END TRUE" << endl; return true; } else { query.finish(); //qDebug() << "DataProxy_SQLite::doesThisLogExist: END FALSE 1" << endl; return false; } } else { query.finish(); //qDebug() << "DataProxy_SQLite::doesThisLogExist: END FALSE 2" << endl; return false; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); //qDebug() << "DataProxy_SQLite::doesThisLogExist: END FALSE 3" << endl; return false; } //qDebug() << "DataProxy_SQLite::doesThisLogExist: END FALSE 4" << endl; return false; } int DataProxy_SQLite::getContinentIdFromContinentShortName(const QString _n) { if (_n.length()!=2) { return -3; } QSqlQuery query; QString queryString = QString("SELECT id FROM continent WHERE shortname=='%1'").arg(_n); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -2; } } QString DataProxy_SQLite::getContinentShortNameFromEntity(const int _n) { QSqlQuery query; QString queryString= QString("SELECT continent.shortname FROM entity JOIN continent ON entity.continent=continent.shortname WHERE dxcc='%1'").arg(_n); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { queryString = (query.value(0)).toString(); query.finish(); return queryString; } else { query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } } int DataProxy_SQLite::getContinentIdFromEntity(const int _n) { QSqlQuery query; QString queryString = QString("SELECT continent.id FROM entity JOIN continent ON entity.continent=continent.shortname WHERE dxcc='%1'").arg(_n); bool sqlOK = query.exec(queryString); //aux = QString("SELECT continent.id FROM entity JOIN continent ON entity.continent=continent.shortname WHERE (mainprefix NOT LIKE '*%') AND dxcc='%1'").arg(_n); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -2; } } QStringList DataProxy_SQLite::getContinentShortNames() { QSqlQuery query; QStringList continents; continents.clear(); QString queryString = QString("SELECT shortname FROM continent"); bool sqlOK = query.exec(queryString); if (sqlOK) { while (query.next()) { if (query.isValid()) { continents << query.value(0).toString(); } } query.finish(); return continents; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QStringList(); } return QStringList(); } bool DataProxy_SQLite::isValidContinentShortName(const QString _n) { QString queryString = QString("SELECT id FROM continent WHERE shortname ='%1'").arg(_n); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { if (query.next()) { if (query.isValid()) { query.finish(); return true; } else { query.finish(); return false; } } else { query.finish(); return false; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } return false; } int DataProxy_SQLite::getITUzFromPrefix(const QString _p) { QSqlQuery query; QString queryString = QString("SELECT ituz FROM prefixesofentity WHERE prefix LIKE '%1'").arg(_p); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -2; } } int DataProxy_SQLite::getCQzFromPrefix(const QString _p) { QSqlQuery query; QString queryString = QString("SELECT cqz FROM prefixesofentity WHERE prefix LIKE '%1'").arg(_p); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -2; } } int DataProxy_SQLite::getCQzFromEntity(const int _n) { QSqlQuery query; QString queryString = QString("SELECT cqz FROM entity WHERE dxcc='%1'").arg(_n); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -2; } } int DataProxy_SQLite::getITUzFromEntity(const int _n) { QSqlQuery query; QString queryString = QString("SELECT ituz FROM entity WHERE dxcc='%1'").arg(_n); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -2; } } QString DataProxy_SQLite::getEntityNameFromId(const int _n) { //qDebug() << "DataProxy_SQLite::getEntityNameFromId: " << QString::number(_n) << endl; QSqlQuery query; QString queryString = QString("SELECT name FROM entity WHERE dxcc='%1'").arg(_n); QString motherEntName = QString(); bool sqlOK; if (_n > 1000) { QString aux = (QString::number(_n)).right(3); QString queryString2 = QString("SELECT name FROM entity WHERE dxcc='%1'").arg(aux); sqlOK = query.exec(queryString2); if (sqlOK) { if (query.next()) { if (query.isValid()) { motherEntName = (query.value(0)).toString(); } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } } query.finish(); sqlOK = query.exec(queryString); if (sqlOK) { if (query.next()) { if (query.isValid()) { if (_n>1000) { motherEntName = (query.value(0)).toString() + " (" + motherEntName + ")"; } else { motherEntName = (query.value(0)).toString(); } query.finish(); return motherEntName; } else { query.finish(); return QString(); } } else { query.finish(); return QString(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } return QString(); } QString DataProxy_SQLite::getEntityMainPrefix(const int _entityN) { //qDebug() << "DataProxy_SQLite::getEntityMainPrefix:" << QString::number(_entityN) << endl; if (_entityN <= 0 ) { return QString(); } QString queryString; QSqlQuery query; //queryString = QString("SELECT mainprefix FROM entity WHERE (mainprefix NOT LIKE '*%') AND dxcc='%1'").arg(_entityN); queryString = QString("SELECT mainprefix FROM entity WHERE dxcc='%1'").arg(_entityN); //queryString = "SELECT prefix FROM prefixesofentity WHERE dxcc=='" + QString::number(i) +"'"; bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } else { query.next(); if (query.isValid()) { queryString = (query.value(0)).toString(); query.finish(); return queryString; } else { query.finish(); return QString(); } } return QString(); } int DataProxy_SQLite::getDXCCFromPrefix(const QString _p) { //qDebug() << "DataProxy_SQLite::getDXCCFromPrefix(: -" << _p << "-" << endl; QSqlQuery query; QString queryString = QString("SELECT dxcc FROM prefixesofentity WHERE prefix='%1'").arg(_p); bool sqlOK = query.exec(queryString); if (sqlOK) { if (query.next()) { if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { query.finish(); return -2; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -3; } return -4; } bool DataProxy_SQLite::isNewCQz(int _c) { QSqlQuery query; QString queryString = QString("SELECT id FROM log WHERE cqz='%1'").arg(_c); //queryString = "SELECT id FROM log WHERE cqz=='" + QString::number(_cqz) +"'"; bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } else { query.next(); if (query.isValid()) { query.finish(); return true; } else { query.finish(); return false; } } return false; } bool DataProxy_SQLite::isNewEntity(int _e) { if (_e <= 0) { return false; } //QString queryString; QSqlQuery query; QString queryString = QString("SELECT id FROM log WHERE dxcc='%1'").arg(_e); //queryString = "SELECT id FROM log WHERE dxcc=='" + QString::number(_entityN) +"'"; bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } else { query.next(); if (query.isValid()) { query.finish(); return true; } else { query.finish(); return false; } } return false; } double DataProxy_SQLite::getLongitudeFromEntity(const int _e) { QString queryString = QString("SELECT longitude FROM entity WHERE dxcc='%1'").arg(_e); QSqlQuery query; bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return 0.0; } else { query.next(); if ( !(query.isValid()) ) { query.finish(); return 0.0; } else { double v = (query.value(0)).toDouble(); query.finish(); return v; } } return 0.0; } double DataProxy_SQLite::getLatitudeFromEntity(const int _e) { QString queryString = QString("SELECT latitude FROM entity WHERE dxcc='%1'").arg(_e); QSqlQuery query; bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return 0.0; } else { query.next(); if ( !(query.isValid()) ) { query.finish(); return 0.0; } else { double v = (query.value(0)).toDouble(); query.finish(); return v; } } return 0.0; } QString DataProxy_SQLite::getEntityPrefixes(const int _enti) { if (_enti<=0) { return QString(); } QString result; result = ""; QString queryString; QSqlQuery query; int i = _enti; queryString = "SELECT prefix FROM prefixesofentity WHERE dxcc=='" + QString::number(i) +"'"; bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } else { while ( (query.next())) { if (query.isValid()) { result = result + ", " + (query.value(0)).toString(); } else { } } if (result.length() < 1) { return result; } else { result = result.remove(0,2); query.finish(); return result; } } return QString(); } QStringList DataProxy_SQLite::getEntitiesNames() { //qDebug() << "DataProxy_SQLite::getEntitiesNames" << endl; QString aux = QString(); QStringList qs; qs.clear(); QString queryString = QString("SELECT mainprefix, name, dxcc FROM entity"); QSqlQuery query; bool sqlOK = query.exec(queryString); if (sqlOK) { while ( (query.next())) { if (query.isValid()) { if (query.value(2).toInt()<1000) { aux.clear(); aux = (query.value(0)).toString() + "-" + (query.value(1)).toString()+" ("+(query.value(2)).toString()+")"; //result = result + ", " + (query.value(0)).toString(); qs << aux; } } else { } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } query.finish(); return qs; } /* * The following code was showing in the Entities prefixes and entities like Sicily, African Italy... and they are not officially an entity in the DXCC QStringList DataProxy_SQLite::getEntitiesNames() { //qDebug() << "DataProxy_SQLite::getEntitiesNames" << endl; QString aux = QString(); QStringList qs; qs.clear(); QString queryString = QString("SELECT mainprefix, name, dxcc FROM entity"); QSqlQuery query,query2; int dxcc = -1; QString aux2 = QString(); if (query.exec(queryString)) { while ( (query.next())) { if (query.isValid()) { dxcc = query.value(2).toInt(); //qDebug() << "DataProxy_SQLite::getEntitiesNames - DXCC: " << QString::number(dxcc) << endl; if (dxcc > 1000) { //qDebug() << "DataProxy_SQLite::getEntitiesNames - DXCC>1000 going in details: " << endl; aux2 = QString::number(dxcc); aux2 = aux2.right(3); //qDebug() << "DataProxy_SQLite::getEntitiesNames - aux2: " << aux2 << endl; queryString = QString("SELECT mainprefix, name FROM entity WHERE dxcc ='%1'").arg(aux2); if (query2.exec(queryString)) { if (query2.next()) { if (query2.isValid()) { //aux2 = (query2.value(1)).toString(); aux.clear(); aux = (query.value(0)).toString() + "-" + (query.value(1)).toString()+" (" + (query2.value(0)).toString() + "-" + (query2.value(1)).toString() + " - " + aux2 + ")" ; } } } else { //TODO: Manage the error } } else { //qDebug() << "DataProxy_SQLite::getEntitiesNames - DXCC<1000 quick! " << endl; aux.clear(); aux = (query.value(0)).toString() + "-" + (query.value(1)).toString()+" ("+QString::number(dxcc)+")"; } //qDebug() << "DataProxy_SQLite::getEntitiesNames - AUX: " << aux << endl; //result = result + ", " + (query.value(0)).toString(); qs << aux; } else { //TODO: Manage the error } } } else { //TODO: Manage the error } return qs; } */ int DataProxy_SQLite::getHowManyEntities() { QSqlQuery query; QString queryString = QString("SELECT count(id) FROM entity"); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); query.finish(); return v; } else { query.finish(); return 0; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return 0; } } int DataProxy_SQLite::getMaxEntityID() { //SELECT MAX (dxcc) FROM entity WHERE dxcc<1000 QSqlQuery query; QString queryString = QString("SELECT MAX (dxcc) FROM entity WHERE dxcc<1000"); bool sqlOK = query.exec(queryString); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { query.finish(); return -1; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } } bool DataProxy_SQLite::updateISONames() { //qDebug() << "DataProxy_SQLite::updateISONames" << endl; bool result; result = db->updateTheEntityTableISONames(); return result; } QString DataProxy_SQLite::getISOName(const int _n) { //qDebug() << "DataProxy_SQLite::getISONames: " << QString::number(_n) << endl; if (_n <= 0 ) { //qDebug() << "DataProxy_SQLite::getISONames: NOT KNOWN - UN" << endl; return "un"; // When no flag is known, we return the UN flag } QString queryString, aux; QSqlQuery query; aux.clear(); queryString = QString("SELECT isoname FROM entity WHERE dxcc='%1'").arg(_n); bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataProxy_SQLite::getISOName: Query error - UN" << endl; query.finish(); return "nu"; // When no flag is known, we return the UN flag } else { query.next(); if (query.isValid()){ //qDebug() << "DataProxy_SQLite::getISOName: ISO Name: " << (query.value(0)).toString() << endl; aux = (query.value(0)).toString(); query.finish(); if (aux.length()>1) { return aux; } else { return "un"; // When no flag is known, we return the UN flag } } else { //qDebug() << "DataProxy_SQLite::getISOName: NO ISO Name: " << endl; query.finish(); return "un"; // When no flag is known, we return the UN flag } } //qDebug() << "DataProxy_SQLite::getISOName: NO ISO Name: default" << endl; return "un"; // When no flag is known, we return the UN flag } void DataProxy_SQLite::getFoundInLog(const QString _txt, const int _log) { //qDebug() << "DataProxy_SQLite::getFoundInLog: " << _txt << "/" << QString::number(_log) << endl; /* searching = true; executionN++; QSqlQuery query; QString queryString, aux; aux.clear(); QStringList qsoDataFound; qsoDataFound.clear(); if (_txt.length()<2) { //qDebug() << "DataProxy_SQLite::getFoundInLog: lengh shorter than 2" << endl; searching = false; return; } //qDebug() << "DataProxy_SQLite::getFoundInLog: let's go searching!" << endl; if (_log <= 0) { queryString = QString("SELECT call, qso_date, time_on, bandid, modeid, qsl_rcvd, qsl_sent, station_callsign, id FROM log WHERE call LIKE '%%1%'").arg(_txt); } else { queryString = QString("SELECT call, qso_date, time_on, bandid, modeid, qsl_rcvd, qsl_sent, station_callsign, id FROM log WHERE call LIKE '%%1%' AND lognumber='%2'").arg(_txt).arg(_log); } bool sqlOk = query.exec(queryString); if (sqlOk) { //qDebug() << "DataProxy_SQLite::getFoundInLog: Query OK" << endl; QSqlRecord rec = query.record(); int nameCol = -1; int counter = 0; while ((query.next()) && (searching)) { if (query.isValid()) { counter++; //qDebug() << "DataProxy_SQLite::getFoundInLog: Data found: - " << QString::number(counter) << endl; qsoDataFound.clear(); nameCol = rec.indexOf("call"); qsoDataFound << "call:" + (query.value(nameCol)).toString(); //qDebug() << "DataProxy_SQLite::getFoundInLog: Data found: " << (query.value(nameCol)).toString() << endl; nameCol = rec.indexOf("qso_date"); qsoDataFound << "qso_date:" + (query.value(nameCol)).toString(); nameCol = rec.indexOf("time_on"); qsoDataFound << "time_on:" + (query.value(nameCol)).toString(); nameCol = rec.indexOf("bandid"); qsoDataFound << "bandid:" + (query.value(nameCol)).toString(); nameCol = rec.indexOf("modeid"); qsoDataFound << "modeid:" + (query.value(nameCol)).toString(); nameCol = rec.indexOf("qsl_rcvd"); aux = (query.value(nameCol)).toString(); if (aux.length()<1) { aux = "N"; } qsoDataFound << "qsl_rcvd:" + aux; nameCol = rec.indexOf("qsl_sent"); aux = (query.value(nameCol)).toString(); if (aux.length()<1) { aux = "N"; } qsoDataFound << "qsl_sent:" + aux; nameCol = rec.indexOf("station_callsign"); qsoDataFound << "station_callsign:" + (query.value(nameCol)).toString(); nameCol = rec.indexOf("id"); qsoDataFound << "id:" + (query.value(nameCol)).toString(); if (qsoDataFound.length()>1) { emit qsoFound(qsoDataFound); //qDebug() << "DataProxy_SQLite::getFoundInLog: Emitting qsoDataFound... (exec: "<< QString::number(executionN) << ") Call-id: " << qsoDataFound.at(0) << "-" << qsoDataFound.at(8) << endl; } else { //qDebug() << "DataProxy_SQLite::getFoundInLog: NOT emitting qsoDataFound... (exec: "<< QString::number(executionN) << ")" << endl; //qDebug() << "DataProxy_SQLite::getFoundInLog: NOT Emitting qsoDataFound..." << endl; } } // Closes if next.isValid } // Closes While //qDebug() << "DataProxy_SQLite::getFoundInLog: No more data!" << endl; return; } else { //qDebug() << "DataProxy_SQLite::getFoundInLog: Error 1: Query NOK" << endl; searching = false; return; } //qDebug() << "DataProxy_SQLite::getFoundInLog: Error 2" << endl; searching = false; return; */ } /* bool DataProxy_SQLite::queryPrepare(const QString _query) { //qDebug() << "DataProxy_SQLite::queryPrepare: " << _query << endl; //return preparedQuery.prepare( _query ); //return preparedQuery.prepare("INSERT INTO log (call, qso_date, bandid, modeid, time_on, time_off, srx, stx, srx_string, stx_string, qso_date_off, band_rx, rst_sent, rst_rcvd, cqz, ituz, dxcc, address, age, cnty, comment, a_index, ant_az, ant_el, ant_path, arrl_sect, checkcontest, class, contacted_op, contest_id, country, credit_submitted, credit_granted, distance, eq_call, email, eqsl_qslrdate, eqsl_qslsdate, eqsl_qsl_rcvd, eqsl_qsl_sent, force_init, freq, freq_rx, gridsquare, my_gridsquare, iota, iota_island_id, my_iota, my_iota_island_id, k_index, lat, lon, my_lat, my_lon, lotw_qslrdate, lotw_qslsdate, lotw_qsl_rcvd, lotw_qsl_sent, clublog_qso_upload_date, clublog_qso_upload_status, max_bursts, ms_shower, my_city, my_cnty, my_country, my_cq_zone, my_name, name, operator, station_callsign, owner_callsign, my_rig, my_sig, my_sig_info, my_state, state, my_street, notes, nr_bursts, nr_pings, pfx, precedence, prop_mode, public_key, qslmsg, qslrdate, qslsdate, qsl_rcvd, qsl_sent, qsl_rcvd_via, qsl_sent_via, qsl_via, qso_complete, qso_random, qth, rx_pwr, tx_pwr, sat_mode, sat_name, sfi, sig, swl, ten_ten, web, points, multiplier, lognumber) VALUES (:call, :qso_date, :bandid, :modeid, :time_on, :time_off, :srx, :stx, :srx_string, :stx_string, :qso_date_off, :band_rx, :rst_sent, :rst_rcvd, :cqz, :ituz, :dxcc, :address, :age, :cnty, :comment, :a_index, :ant_az, :ant_el, :ant_path, :arrl_sect, :checkcontest, :class, :contacted_op, :contest_id, :country, :credit_submitted, :credit_granted, :distance, :eq_call, :email, :eqsl_qslrdate, :eqsl_qslsdate, :eqsl_qsl_rcvd, :eqsl_qsl_sent, :force_init, :freq, :freq_rx, :gridsquare, :my_gridsquare, :iota, :iota_island_id, :my_iota, :my_iota_island_id, :k_index, :lat, :lon, :my_lat, :my_lon, :lotw_qslrdate, :lotw_qslsdate, :lotw_qsl_rcvd, :lotw_qsl_sent, :clublog_qso_upload_date, :clublog_qso_upload_status, :max_bursts, :ms_shower, :my_city, :my_cnty, :my_country, :my_cq_zone, :my_name, :name, :operator, :station_callsign, :owner_callsign, :my_rig, :my_sig, :my_sig_info, :my_state, :state, :my_street, :notes, :nr_bursts, :nr_pings, :pfx, :precedence, :prop_mode, :public_key, :qslmsg, :qslrdate, :qslsdate, :qsl_rcvd, :qsl_sent, :qsl_rcvd_via, :qsl_sent_via, :qsl_via, :qso_complete, :qso_random, :qth, :rx_pwr, :tx_pwr, :sat_mode, :sat_name, :sfi, :sig, :swl, :ten_ten, :web, :points, :multiplier, :lognumber)"); //return db->queryPrepare("INSERT INTO log (call, qso_date, bandid, modeid, time_on, time_off, srx, stx, srx_string, stx_string, qso_date_off, band_rx, rst_sent, rst_rcvd, cqz, ituz, dxcc, address, age, cnty, comment, a_index, ant_az, ant_el, ant_path, arrl_sect, checkcontest, class, contacted_op, contest_id, country, credit_submitted, credit_granted, distance, eq_call, email, eqsl_qslrdate, eqsl_qslsdate, eqsl_qsl_rcvd, eqsl_qsl_sent, force_init, freq, freq_rx, gridsquare, my_gridsquare, iota, iota_island_id, my_iota, my_iota_island_id, k_index, lat, lon, my_lat, my_lon, lotw_qslrdate, lotw_qslsdate, lotw_qsl_rcvd, lotw_qsl_sent, clublog_qso_upload_date, clublog_qso_upload_status, max_bursts, ms_shower, my_city, my_cnty, my_country, my_cq_zone, my_name, name, operator, station_callsign, owner_callsign, my_rig, my_sig, my_sig_info, my_state, state, my_street, notes, nr_bursts, nr_pings, pfx, precedence, prop_mode, public_key, qslmsg, qslrdate, qslsdate, qsl_rcvd, qsl_sent, qsl_rcvd_via, qsl_sent_via, qsl_via, qso_complete, qso_random, qth, rx_pwr, tx_pwr, sat_mode, sat_name, sfi, sig, swl, ten_ten, web, points, multiplier, lognumber) VALUES (:call, :qso_date, :bandid, :modeid, :time_on, :time_off, :srx, :stx, :srx_string, :stx_string, :qso_date_off, :band_rx, :rst_sent, :rst_rcvd, :cqz, :ituz, :dxcc, :address, :age, :cnty, :comment, :a_index, :ant_az, :ant_el, :ant_path, :arrl_sect, :checkcontest, :class, :contacted_op, :contest_id, :country, :credit_submitted, :credit_granted, :distance, :eq_call, :email, :eqsl_qslrdate, :eqsl_qslsdate, :eqsl_qsl_rcvd, :eqsl_qsl_sent, :force_init, :freq, :freq_rx, :gridsquare, :my_gridsquare, :iota, :iota_island_id, :my_iota, :my_iota_island_id, :k_index, :lat, :lon, :my_lat, :my_lon, :lotw_qslrdate, :lotw_qslsdate, :lotw_qsl_rcvd, :lotw_qsl_sent, :clublog_qso_upload_date, :clublog_qso_upload_status, :max_bursts, :ms_shower, :my_city, :my_cnty, :my_country, :my_cq_zone, :my_name, :name, :operator, :station_callsign, :owner_callsign, :my_rig, :my_sig, :my_sig_info, :my_state, :state, :my_street, :notes, :nr_bursts, :nr_pings, :pfx, :precedence, :prop_mode, :public_key, :qslmsg, :qslrdate, :qslsdate, :qsl_rcvd, :qsl_sent, :qsl_rcvd_via, :qsl_sent_via, :qsl_via, :qso_complete, :qso_random, :qth, :rx_pwr, :tx_pwr, :sat_mode, :sat_name, :sfi, :sig, :swl, :ten_ten, :web, :points, :multiplier, :lognumber)"); return true; } bool DataProxy_SQLite::queryBind(const QString _field, const QString value) { //qDebug() << "DataProxy_SQLite::queryBind: " << _field << "/" << value << endl; //preparedQuery.bindValue( _field, value ); //db->queryBind(_field, value); return true; } bool DataProxy_SQLite::queryExec() { //qDebug() << "DataProxy_SQLite::queryExec " << endl; bool sqlOK = db->queryExec(); if (!sqlOK) { //emit queryError(Q_FUNC_INFO, preparedQuery.lastError().databaseText(), preparedQuery.lastError().number(), preparedQuery.lastQuery()); //qDebug() << "DataProxy_SQLite::queryExec - FAILED execution " << endl; } else { //qDebug() << "DataProxy_SQLite::queryExec - executed " << endl; } return sqlOK; } */ int DataProxy_SQLite::getPrefixId(const QString _qrz) { //qDebug() << "DataProxy_SQLite::getPrefixId: -" << _qrz <<"-" << endl; //TODO: Instead of going from long to short, identify prefixes from the begining: // character(may be number) + number if (_qrz.length() < 1) { return -1; } int entityID = 0; QString aux = changeSlashAndFindPrefix((_qrz).toUpper()); while ((entityID <= 0) && (aux.length()>=1) ) { entityID = getDXCCFromPrefix(aux); //qDebug() << "DataProxy_SQLite::getPrefixId: in the while" << aux << " = " << QString::number(entityID) << endl; if (entityID<=0) { aux.chop(1); } } //qDebug() << "DataProxy_SQLite::getPrefixId: " << _qrz << QString::number(entityID) << endl; return entityID; } QString DataProxy_SQLite::changeSlashAndFindPrefix(const QString _qrz) { //qDebug() << "DataProxy_SQLite::changeSlashAndFindPrefix: -" << _qrz <<"-" << endl; int iaux1, iaux2; QString aux = _qrz.toUpper(); if ((aux).count('\\')) // Replaces \ by / to ease operation. { aux.replace(QChar('\\'), QChar('/')); } else { return aux; } if (aux.count('/')) // / found! Checking different options { if (aux.endsWith("/") ) { // We look for calls ending in slash "/" or "\" aux.remove(aux.length()-1,1); } iaux1 = aux.indexOf('/'); //qDebug() << "DataProxy_SQLite::changeSlashAndFindPrefix: Slash found at: " << QString::number(iaux1) << endl; iaux2 = (aux.length())- iaux1; // iaux2 is the length of the second part if (iaux2 < 0){ iaux2 = -iaux2; } if ( iaux1 < iaux2 ) { //Like in F/EA4TV, we can simply take the first part as the prefix aux = aux.left(iaux1); } else { aux = aux.right(iaux2 -1); } } return aux; } klog-0.9.2.9/AUTHORS0000644000076700000620000000065213233376355011660 0ustar staffJaime Robles, EA4TV - (2002-today) Akihiro Koda, JL3OXR - (2016-today) Andrew Goldie, ZL2ACG - (2009-2010) Translators: Catalan - Josep Ma Ferrer, Catalan KDE Translation team Croatian - Kristijan - M0NKC Danish - Joe Hansen (debian-l10n-danish@list.debian.org) Finnish - Kristjan Lorents (debian-i18n@lists.debian.org) Italian - Simona - IU5HIU Japanese - Aki, JL3OXR Polish - Piotr, LA7RRA Spanish - Jaime, EA4TV klog-0.9.2.9/img/0000755000076700000620000000000013237613375011361 5ustar staffklog-0.9.2.9/img/klog_512x512b.png0000755000076700000620000030437613233376355014214 0ustar staffPNG  IHDRxbKGD pHYs.#.#x?vtIME *> IDATxwxՇ;b5K\pM `iemJB H;n@L1%ܻ$[}ݙ#yU-ɲrGj띙{~S@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8(AhӴ[Ļ: 2  A@ $&%%NII限5>>clllJlllKLLzx<8m8p88mq"PHB!ܛ * H$P8 ҭHd sB6-NDP;!@W GSSS%%%uNHHHIOO'--4;99ى#v t8&H8L$q,ReQ>7!mR0 W 00+-UR̒]ş[%plJ Ah NzvuF׮]vҥtIII!`0HȫP(®D"ضs1?͎6EW{gQJaJ 0 caYeSRRbx|>_\rAhL۷>{6{t Ô`0H,TUyyi00M0M6=HII fQQ甔|l[Wr: Ah ƙ9zzoСωqJ'T(: %O+ L'l㍉ EEE_qkXAD1e608##cAN6lXСCS\T#@ @8Ƶ8, uS|֚a[OW؆iMӴM'\ZZJqqq^>^ ԌN޽ك :iر#F8%JK * 1G-XVSc 8*J(Da!C)xB` w)+1gz<ƍ7N9m׫ )))Q~˲c+ƬhoԶ?mDim;N p8_Y~ @: ,4hЏF9pʔ)NFFyyT$d7W?P hYD"_+yp((;QA}~}FP(A)KA v8ngY&W <S] x`'xرcL6QJQPP@Iq aVYЗhc^ZZJ ]G |&N,zoI<ib&Px\ӪHb4 [S$[?yr "0XŔS\RRWRB  dYL/tOS)+F[M^\_^ĆK'>A #F,2eJiӦ9(_IINn?z`~<ϧ ?_{j֌{{` M?Q6]!FNxxxJ.A 򌌌N:NqOqq^GGPcB)E$!''rAzXq`F6a!:h{:wt#r WAv Yf]pBcǎ*77"eϭA0dϞ=dg|7 iyU|hk I A<{NrUY0xF|o>Ϟ={طw/PHXe[AП ܋2p8cƌ-\~}זNWܷo;wd]+Qښr v;m2:A8t… GvivaA˫Xӯɥͮ;ٶm^~[oCw-\ ##ϏsGmdg|_* L$ }6mƎ;d/O P x]!𺌌 @8o0!Cn ۥ9+_IIE}՜Eksssٺu+[lM GMlE- @t#F,9묳TRbo^# qU_u4M-[زy3eaW~ ##`F{۶3njsg99F(B)UJRN߿?7of֭m[p@VfMA ALLLl(1bč-2xpZuq [ٺu+!//!rls A²/;3ifnNY$ʋlۺҲ21Bs>t׀+BA :u3<3&%9ٻ~3h7 {uJ܅@??QDmY;wn޽{EGG"mVmFĶ%z_hQP6QDm>SL0f#';**j|o_h J8)"VSOu E \J)vŶm( e/.3J8aZA8/!!N;-!=xYWpeYڹ]w,!w3RAвOB2yO7p@c޽)++cΝ<(n~ax CAТK.?~+.+aݻ/7 dCz[JtAA ҉'9---6/77Ʈ*+#;;"ހ" XB<N:]5|p(??> (U#) BހBB @hV SJ:th3//b10orvddfYRRM}JKJ¡P>byl(F|-"]t+.AJJJE pf dH±fsΝp8hÞh8m,KFKpp:wA uwFBB Iѿ G"r r    @8*tތd(XVlU?Tn#Q[!DMb@ЀT Bsm,doɈ"!|1!EC6.DB/ 0 QҤ 4Sl(<Kh#`߀bEvӄt`=pJDze\wt3D`A8?~DLHE8tPyLBCy8CЫAZ869:K`#0SFD T-`$be8U4h;02(81@O7+C"RX6x'"@hG !j@ImJ]ਨֱNj8! /jQ30;-A,pi+,@hstwk%mLȸ< XQD\#_n H+i̽Q~woq韛q 8/5V)Y.8L%I@{L9g" rDy&Qpt6 .r6aph8eċ]ѿ{hWдt&}S]A":r di(Z @h%AO_/c8ts'ȏ-W^>pIGrhţ ֍+JўB?:;b4\Ck?@:&'gm8oNO@ypHŰ"H'sqtWp K:2R-) Xlq@ *_[,h+B $ H6wBr rڴjbk" 12D*nfɈZnfF?hwfH6&b"HW Ķuπ;xXNBm`D[. ėl<.ь.C2*m2"V)"@h<2 bl[ HP&bbvڤjC[b995D͗[ ڵvh#=A8N.>7x0-kKox6#5D͎93nǘeݽR7?&=p:vv\HaB:ν9ڷrq#Г??@hVm;0\&ó\@;֚;B3 ך Qɥh7|2AׂqxnOhIgfR ^Fy 9";`SEmu܁]8B⮻D"ֵdRfPJ-|IFNπ"4 5f8xYq7C7U*9P[@Ʊz<h72@ACARknPn0&5" E+ڵ&_ꮪ>2wر vkO@+|@6a.:@[jjGr\r՛Kުv#CODǐtZ=~\oCǴp7b)D'~esԽ/sQ㜯ݗ-[#_=wp@bkx)43 V@5H}hE{60/fw8ƿ\?}P\0 i{vw@o:+k02pnit Lːnj[k[þ %Q5ol#0 qտarU?KΕ'0VʸnʫV\~hmt+, j`)@/Z5\@ %A7 YKOnC0!5pdԨ٣(0/"˗ߺ.|9{&q\G2XmA1-ȤC+@8z8hYK@؂|G{EUf͚E(dygH䏮t1t(S./<тн.ZНЊ Fw,(r>2mUcf}U 3r{{Z hA Hq "ѮTױtjX \k+,BkbtYԣf\Sm)cc#JJ(޹}Ʈwޥ_X֡x,4yz^0xyVK[b9- `(Hp7r81ZwR غY⿄U wtwzaPN~)'Mzaa[00,>=]J1E=5nG `OfrIG݌ pnQ0KVs9Ey6tLww' HJߏ Fqplqox c{!` &'$$8^i6٘ϵrʮa;hFmG33Wgl] l I DǘH3)Gnn-,t5`bC49?k+5>7upPkֲ* ԇaÆ͞=˛x~{ 7h,~8tT%'JG~ ?Y hS^!e"ja!Jhm|~o+ࢍOOg=) Q.UHܳᅬcwoND ||]~Yc^ݧq{^vRg=_w33KN:H{+mp+\B٣yڟ[5os΀no׹3 y˖ ;Ƌf(c8cY] ,J>Fo}pi|8PO~rXԆ{sf('&7]waC.O.X? ø[msժUC?têgِ[74Po~.ؾ-,8\Eq'WOla`Q7mwk4MI!T+lI0 ;JL(^ϋZ0F)&:WJmt{eZ[t TYTA;GrL\h!e +@9|xvex E^L'{fbq]:LOu@#=zYC|^ޡiLJȎ]:aЭ[7&LHJJrBPT_m?sWQ\.9茖y݂E[Eg=Ug0KU.rQCa`NN: |܂ C_'&o$${_ >>#GZ&oi[իWsAM})ef.O@dǺ Gۥ4"cuY/V>sE@0cc{M pt[#a׈v;=Ӈ^zU*5zYf->R6ӸE0^b\9U?mQ,C.@8cNj7mA::5E7uW"Ga& 'IwޣW41Mp0/eE˵w;τLxU2&Oq&'R m6}]+/jwSrkvnQ;Е7Tl9 L c7? 5 t_)F\}7ԏg;lKoEAa!P00c(ݶŪ8X={2g{Umۦ-t|<T/Wm=x l#Dm95}@b<l@Læ%>Ym׮]䬳TV]espS؊;aPNˌ::{Z"fbf\OǶm<qgX="8M$Xn9q*=JRl߾k{_й<5 *G<XMܘu0`cix;vG"+9@6}-Q`7IջIJEII F n~35ȫ6v8sǤ3NNJ:>aW30kaZc>X/^FΚnc E|QA?Y:wVV$¸ omܷ Ef7ē~رXcXKaJ̈́ 0<'!uɤר v$Oǎq|Ki z?5;v_(U=3&V\g" 58˗ߒwӀ7-(8.λTOZ7݈b ' &sgpH$76~p&`j+Kѽ(i2a <<"޷bO272h4JA(;>*۹gJ}F~V08WDecVl`c4ƏQJmezaW]"`BzvJLLƲ,m!УgO曪m>OJE\ZS~+N\e-}kzQJQze1ccu*+o"*Ja{C/;W_5{pkl*Vm |ƌeeeosn`p ##_}} 4eT\ۦXLbv瞝!c5_n àKn|eK[n_k2܉_̇"u[ɯ, . Dz8CBR޺^sPMht<m+PN~ژ̜IE(ڱ;+Ox@ 8>=k?Y5GFYQ矓1 #F ~jetVЄH@".X[N]qp0 ]L0 L0;w 6 x-{]:P'<{w>-Ìi{̸XyOX~݈!ͧYR 7m"@>[T*E4=|5f{g:۸qMì,p8m{<_lX-(0 Loc3x֐'ZrDUl/Tàx޽b̸ï]QYpe$t*811~%QAg$q)U9b'; 7,(1~(噙yW85͙tQ RS aR繬wf9 B251M!h6пYfOd*.rR~t<UT 2Ѳ\7T'П> s綊J~i-l(/H0@W/!Եk/^L(JP(%@pի߯k׮̘15P7Tc;̘1OYYY60}_=FTv̚9G{f'mc6eaY]t}ZRš/4% +\l~ tHT߯s~O`ɒ% x]ތFf>-_{=dao,~޽1K|@CcUKHܑn]T\a .g?A|4fвWy=M|gی6bcڎK_~ɵ|rJZ($//G}g}?={QIY]%b I63^{v:Uzȑʍu}믫5x̂:رdtWu3'@bh?`@IǷ^G<1cưf͚uَEG*ݒwqs9u ff[^w=~i!)-9xi^y9FLLc}o.o"6GuWH4*5A ׶8w"}g\7!AÇU[gee:/-;Dot mmt[߀.رcZrӶmF8ny7 ^H4`y\\sŏ֭Kw,˪(WJL~BW\qE>p-s/5 0cx<&M&[w2_y]H9ObGs:M@9s(;HɶP/i8?@;MI&O*xS GJ1>W^ZP:E3{"Lqx饗j&])))Uޱ`ٲ[{O+^{_Tezs #;'ݷ^9ВHB_rQͪ{^5MVJ), .`رg߶q ݽÜ}>+])Bl/0bbPoV?4XiF6PW};Kt;aDJKٷv-y|JB$dtove6~ƾ11wB캬@I/_҈D 0xS/va,˪}zmP(ŋ?m۶muyi}7I ]0wzQ^/| W;ElZC^GY3vEa^&!Jw_ڌmSثW:Ɔc;| 8Ƞ0qg|zvT\6G^2bĉeee7._~u=gUKǹ YC"luWf[\xuu:u*w˲X--Ùz'f͏:t0VܖٽK^D΅mÇK/<~w|~?q ˶Eh͛y$ź:0 b/AAM##6?G%R;>;H΢y$'4BB[cMHطn_5:}?ؽ{<;cΝUV <tljY+VVćRJLL'JK}/ ۋ &a v=]`OHH 55/.ja= ?@b}:?s7sVQ+oJHv>]H=Z;Gqcɘ3Gw!*~+m"o׭Ó@r߾z9ݤ'={e81cO%~䢢k)o5oDn&=zdx6nhp^3#"{;m~WE3fZ^Ƨ{AeҥL:thVnV^Î>2M|wխ>zԑWp"̸8ϜIIP};v5:>@9hף' =2ZE'`;y,.@߾]SPk={c'O/0>r`P}c 1/\3gF%;#^lt͌]vnRS)Wua֬Ys9srr綠 #}+ЮO:az͜Sݚy8|x҆N7/OuH'y@pَDKK<7kʊ9j֕W^ܫǽ<.!:vg 2}Zr{:o޼]uZEZjqv}!S{17<e = ǝwJ}=۶Сw.]dI0r%p%:nM3.ngâ v>,_}Fl&Zee ~AMv]3 TaA:,ޤfp$OQ1'NǤ$aq뫿` ?͂0aB;' O333u/ZjTI$ !zn~%];AG9s=g;wPn'݅^HRRwϧ@I"R*5RZW #F0sSۓnK?H,.Z֞#qYe1"##~^i59XLq: |t_= 8eeح@1cQmv㄀zE:t o&Xi?Q#)Kl|a=7ޠxDlZZFL ;\:wHBvڵ?_i)er`FLudG"uHiH궸K̝;4=<|wω]Vkn1c9w0׮i~ _}m@)ENͭ[o0}D^N<'4=}Fr222ŋ@nlσ{H IDAT32~ rPHiM/_?'s ;iBmLgiDo# zcﭷ]>}hץs|PDzIՓ^N\Qmcϫ)-%eؖ0{?gl>l#;wPyeiuyp,>}\s2|\_XXO?Sb@:׎Qz ++@+;(.zw:1T2Uۥۑѫ{" waV/hF\ޭ[+Vt޹^q8q"ӧO_XX:?92!O|LJH٣Q};.-_D>y 3cSS}$MW_..>mv=%;w:lޔ#+H>^gS"ƛxH8_ RFlƈJar.[D\ts"/8;XƁZ/Z=*x}Yrssk{t׻.`+nJl_]͡v}!C 𔋦h_P.l&%=?ڐ玝dq MO{W}\U5⿶r[%7|s!C^sӀ_(ێ#F0amt1H Hx+/);'MƟݬz+q?yDW;{\/\pަҧC=|}Ͻ.fBB_2 Ƞ%W~f;D~>Z"%շ-~^MjQۘE;v]wI0b. ;++=~{,jϑ \~Zj cOVJE )6-%>﯈.\fYr?"t\"<ܲ,]|B5_W8D"za2d:fT4_vYW$&9'Nķgo>yS~}71)lxd[oaG"G Tpi t=n}we('坿·s/p$0s(,?6}9y{3.c D;a[fg(N''O1# mF48`Ǩ(q9s\_x۵[iϧy˥rwXZ>D 4Pt%fY8RɛׯBBmSU۶cLP>}P}gBl{(:u&[l$ sR ~AJn:tҍ!ISU, 1#Q_Xuk4MpM~ l6>ia.B6;g5ݘc5eeeI'D#nnuWevi>7gZ,=^pQ,ӟz]vVx(MˎWCoYXIvv6v[͛KyQ~ۮ5,HU nT{F$9d0&G#7o}jq$%ܵ+Cm~ix'i膁ii5 ,J$$׺kG#@3|j&cY3w-&iaEEE?G/<SnɯLF>+r&';^rf=n(.'&'cIe8sRd ڱsvEx f1VIX r' sACDkxGr|UN;[[!dYϾλޚ7o-X9oϟ ?,~$RϟɅ ,ȺꪫRB0n/3FI(h#`0ˏ,YG@k聃xo4EQl$j@ b%SJCGwySrc jAflM$*Wۇjr1Pn&N+5~t84R{~Uj>裏)~qgeJ]4RwS05e˛XQU˖SGIݫe:m*A֭HZ(DW/$65=tZKm2b?⊢t\Ι3ob%&v?mJeg(={t6 FrCuұsA U8-vj@a`fB0m?M\|oK?I!YÜ.+mr^@kq.mm@3OǙLb_s6-XM鍣Y#FnFE@@D(["G}Y@R _|iVS^ݤw^iR0z4/m'?`ʔKp\ג$ EQxiY끽O0v'&LmRFkKuWYmvSh,زykx}Yw䭗M_|{u)@-lTonYi2mڴj;j\ٯgΚň;@RE9drQidOVG]}Ņ$dEegQNg; _W_9g'el}uMmWVM4 Gr2/KgnƵlA"M|}u,&GſꫯDŽG9YPZ¶RiRS99I4##=z$TU7ߢ./NG!˲ ]ǀ[lZ&i`٤놖V˲P~Zrrr\LB KmG29 G#2^JKO:w$eeg[iY'CB,淬Fm~6ߴ%׿z˖- Gw6ø~^eYƜ릢:?㑄F=y]ǦwesLJzvǓ{(¥emifX f1ނ|:tlc:L^xƛe#F??Q՚0aMH˲ϟ_ӆ.M61forr2aJ(JA<=1pBlBj<u`&B~9!jGt~j r0:u0agc{^dYY jq MX {7tLӢظ+K/sBL'| ; „'77I~{D_>/>m?:woN{ml˅k|3fyџ&^9{1:pnKmvt\׬I[6x_펍cuאܽ;f4:ņ^`^[|h\MD.+B2 #ĸaI01F6@[Z0Y}݈HOO-^oJh޲}^B,K6hhFݏ}E‘DyUu3L_,XP($D"PXM۴isо6 B*ywA8DR:.(=/NۃpY?q-N$! FVaQ릖nٲe1p/t~"0[Gv8~{%_/cYD*+)69GdN|EڍIUpx<(;6/\>Ouum Hc,6/5eN:u&ݦLl==GJq,Df_K,i熩d , a *[z?`wۯ7@Nee,>ϞMjj*7Ïfw ؾ'|" wuw6xi#$U +%8Whu,tP,th4B8A5Xti7,UUUGZ(vf#вO9)76AzZ:$aVbB+oHWʊiTUUS[[$ɢ/ahїч~8N1zԠEs&'eWc&xDٟDӉo3ٹ`k׶N cbm(e\Ds,,h~-Ilf N?IUZM Ox^5Oÿy6ZZvnXz_=v6 B۶bWZ[KٷQ⋜?aNŐdbTX֏>b["GS=n~;}.Xd&Qn[OP+w8[F,Fj~*9#Gb"n?Ozf *ZV(S<1YQ#׹#;˹x^ޡ٣III"[&$PdY)LD0MtC<I((C7x絀L5N]O9w߅+%o,N=~hrӣ^Lj;$PRŽs:k˖*Y&__L>ng+%#+ |'߰|~eY`dA맒ڳF$*.) _/ͷc tgF',:Ў It'(x,ͽD._P?͂ tܫ=UU$Ei6_yuJNaaY"Cdea 'mgհKrEoƒ,~6҃`HN]ϽL[EUwEH=.V^w~Ǻ(--CŰA^^zb! :-%&a%G `K6ndyEhtihDj'$wi6Mvn7:_}w9SSyY~uS91cPn@B-Ύf׵(.N?t`?t|5aYNjϞ2 -`mHC@eh4 YLڵd['W@$,_3e@( IPc|rꩧz/i,1pQ][Zp0DYy~YINN&//A\v}HK"ysTٯ<pGڌ _n $Ȓ~. 7 ';}RоԔT@ǩeΝ]Z>,&OLfTd Bl-ªk'pc+S>Bbā0wkLf<;'Dc1c08r*tLM @%aƢ™%~M~·gDFȠe쳐lV^/Kn:$Ei>?& w/?MZ%6n${D@2MjgC%GU y0mՖ.d:SN{キ]R!ɒ%8U'wng,],t PRSR1|87tALYaɷK99V ipЩU;5?e)!ID(i#z(UUF0\8@])//cl۾z=ڵK*YcO>4/V#D(Z*=x!_ҥ |޽#ۚ#W3:|y$:ODvn7z4e_:VRJySg_ iM`6=8e z=-z=3'{wLܱc0$rRɧ0i"ee-\&,~٥8ރbLts[B~Hfub`TUe'TRwO>F~QJJJG=!++~}f),TTF:t(ݻuekݝ%1g 2A\|Ÿ.,l ~oд>lDAe{wҮ}~{|>I y9ēӧ^_CuIt`=.H4FjZI^yurrϷ[ P7mjtD߽; &>O)?ZEjǎK;QtFI ٵ͒nf ?-3g~R:wA  tgJ 'L氡ԭYۢUR⵵|9Vڷ,ϒADq:[F4ڬ@Cv*v~$R{[tlIݶm74;eѻ7?Iݸ%SnւΝ;=BUU;%Xա駟 ǟQ(YFdEAdErh׎ZxuS.?VXЮ[9_|b2˛ktyoEҷ'sɯ/"-#ۃd u$l-H"TUUq{pCn^iia&IIdeg{.XCH 9s邘@x5p_{.'Oő׬Yc;y{_ydp`jZqm| IDAT Y|ߣ55j֯ˤIA;-kߞg;71"f/,ܹY&c@Te;r>O ^SC0|R`!_~IRλ&#@@qa葛'߯;8QRQ F˩~kasU2BM!0xNL;ᄉv&8WXBip瓖AQ{;Qmا!iA/vyy|DQa`dddRG.!#ڋ?ߑ'IҥcdۡB!rYuɒHhlaں:LDQUN79L ϛ@n`aJ%%fIII_ڙ>z=}myATԪe Y9V킱c979jut8Of 5(I|W.)nfV>,Cøqml5$}:yQjn.+WQ'^i}JE2 TI:zKK'lDճYoLj߾؛*_v~1m/9ˆI~4&azviN}a!fIS~y^.k5^A|+˲p8<3x>ƏAyN Hc!5:zӉ%7;KAtua8.(n[u`N p[VV|k /;˴l]i~ietw-61PVdP= ,]ilYQUiɩ|p  hx`oo&Nk_E_P\\ZboYH֮dw}5.2u:$EAQn̙3nݻeZp G O1h{v90/Huegt6KE߿?$ $EFnwc%16VRdI" ڵK"kH4իW`UgTV_P6z~%Κu`) l쳽;sѯwJo-s||K7+=^WN3[!'O"k0֮%ZQeQgԭ[GZ߾2[ tY(։F3G$#IԮ\Ŏg-^ =,;f8Lqq /]Κ())%Rږy>}y9n77'c<_8 8__ݮ]Ծ=&[#a?5>[eKA@lBdw+B]}#Nii?+@& ذa^YY@waNGHIN4 gƈQTš* PPUA%I\AX.Vixҩ3~)')}^)IӨfB9Ѥ9t5ml&JV>>u;mn\Q_O'A`pzh\U~xM۷s!e8C3՗;q|XZIfo.c[ $I1hDjSX|ye,_pN@s'0M{({WvJOSQNLڍٜC$~ӞЭk7WfVKEu{菉+{nňk/@jKEBF\n$#)2+"+x2o׎sf A 7+z?'K  <@_@t0پc;ieD5t֖6L HSJd’l=i%rHOOg嘦P ˍ&??߃hO0|NwۧM՞wSRѿkrfʕ~AL>KB!T"ܺK~_eΣݨQLB\/à3t @sW4 ^k7ssUˆp1޿pϑ>p+nnw@e-8?w] }"zlN~UL>93XW&S=@֐aĢ1(-\Ր%.Ro;BNYEf@V$$E"9%^{q(*e >kiG@۲΀5訁H$"iheKڭpO   B!bF\`@30tCHKf@0 EÅ$7'WJ@7Hu"~tim}t2/pHJnSg?v+Wy>-DDvm96OvޝY\۵_+ljVW7;37$ds6$LMCv{ 69cF7q,df_Y4Rjc5"{tg3O1䑇割P3APd ;u#@ 9_.t*x|L1b8.8o3$6t_~ys8r <M0|ztI<DF#c1b(ZC ´,{`nBi =F )9T=l$INJ9p 6l_EQq9]Ȳ_."// M5 Mu Mqg0"eaM5S'IvIMdYFYa=cnjoTWH/k>@BNΝħI?Kͻh ˜+'ǯΦ﵄8l#۶5zM -¥e,-t︃C^s0p$'Qp dJbX`˲|>uHwVVU4IڕgQfm -5+V㽙8RI[A`m)}9AxuD__@˦4K 4:;WZ*ŋ/= `ܸRw &b~YUU^~evb(j  vqoMLDkE@0Fޭi0,BXt| TϸaI EAE& 1uIE_VQQWQOS u!Uq ;d-0"+%J%x<MtbZʺ'5:ρ}<{Wjj^tk_~U htSSLMÓDqJޕ̼c"k@zCFq2MIQG1'fj_Cw3ye-& $IRO>Ͻ? ĈYy6naC m;k܉7.1*uL3b1]z),z+F쀺Bi,%I 'eQ^^$Iu ).'V%~p,Ka@b2X죱A 2 $ ]PU#;+K@.X ޲Fdò,{@1M 0I" ňFFDDQ‘hӮ.JPHnm "DQ 4_8t8@U% BbQ`C ~!TTW  G„!"ш@@,'@hi>-auu 3c_'3CmL%v7Wj2 \Mno tW/vΔ{h4YCܳ!R??ʒGpNf8db_7 fbIvS9 />@@c9tCh- n51-Q~4.@@H$B$D"bn`x` @\ljkq3uLlp8;Ke P mVիV>/q-$v`Dt=z=`H*F"*FGC dge%b"`l+NMk맢jYo>6N'ߵ`wF%m-c[z(ҿ?M_v;tJr-[L!3ۿ/nQfI峪oK/gCGZ5r ~o?&oNli˗6\xUtr>Њ ++* V`t:tx4FaKhh4B4&F rUUU-qtMCt0)68n;tDcж4# TkRоp4_O (HF @ `gAuA`h4J$"` v뺛R`4! RTTk:3w7zAt^//[F)SGj]M"-#:|>{t>%R;uebcf&QpIL__viBnY뵢\3ey}; ֖#{a_"}@H3%T669}{ j(b%R "abvňE/ED1GatMGu+45{q4M#QWWG;{ܻ$IbqVهh[6 /[VUhT08``:B@((~59PP(D8Qz)"2qBEEEo7bN$a"3ldqr4qBX0z4CPJG oeYnƷC8C+ ' F(̚KPw, =3'6aYY`Z|X*~뛳x(µu"U;>V,ښ"ڏEĢ1"Äa"0c4hX"[#tXDQEa v8s)NB!</ 6`Y.H iPZVF4m_ϖW[]MuM5vZʲLm] sg~nF? ك]^\@!h&>߁8^~pp$3lZ;op[I'}1hy$fiX))3jV!O_\-_xnxi8[3kZ Xpf3޿6ѿX׿5^Zp2 ֩sǤvy ŋ)ڲvMHHZraڿeZΎji ۧ7(bٰy3{!E_-]E!-9WkgqJF  55 4b TWza4)/+ŋ))-"oΝ;qݸc`Y`-[pI'o=QZZ[o]5{9GŰ?|P/]]')?A\#Zu_~(~&7,e+;ozBh #nj'+. oVF ..f֒1?b `iܬaC)4xƍx=r _v8ٸW\|߶a~iXaI)? ²{UkVnZ-_NYY,q4-#0%%%tك^zP[[Mn^.HU$q7G@O x\^RSپc$QQY)X6fdeeaYX Á#))<.' S__zک *I5|8kj:{7HV~ HQuA~b>"I(+zjﯯi P8|v&_碋DRzt˅ r7אA_3gx<$-[l΂?q9%m;~2"9s`z_}ա$X]>0﹇py>w+YbES]'[~wI&6-Y41F,Ixb-JKK)//[^'0 ټm]r1B1p玝ޟU `ՇqcM,KiHחKa&4QPP h,8NN'm 4<,XH8Lyy9\s5$7  i&W^4 CL+C4*38AfX_h<*-(.'{m~v =^,*X=h:~:J7%T~ -'K]BʢIĪ#ccLI9$YQ"a}!xkWѣG>s֮]˺uYnC-4mR8q6&sY,z_|A$tg5Iba=, jE($_]}=^UUkC4K7mvP_^DX IDATRUq$cFû+8: ᰝ41MeNSwX$CIIO/EP*GUU[(<1uս?L@p˂OOP}믟J=)Gn(=+.a("a&z-_7^;łEi^Sbi1? >;wg4hQb%[Hfkİ[niv{p8YŴ5]ov_(y6[ߞji23EIKtrtfN>e:w njaݺuۣGˏnSXPWWSu5膖y99r#N~:a0|t]'c&.+Pmn7,c)2^z)7Vd%*#+;ZG|Pf@0|no 2aryYj/.+PU1*899?+;=O&QTGk'ZJ6u5kג`}3ZT-3ߧjcUou߃X̌P\nFmc^y=09_@DsTu$?{On .`֭r-{&??HO X~}]wX={@%lgyyyܲup8 Q TÆ^me%Bƥۃ6$KN(`޼M7\jZĀc)KtcyW^m!j"i3,YGFG.ϼ@iɝ;3CII6DzПOhcIS\.j7ldƸ }w„ ,]7x;6Èzykm۷oߕX x,,?x.%=^D"a‘ EEEsϾp[]]iYf/#-˲<e7+WfY4<,^$#IDc!+[oOaT4X,Kbuh&TTV9EON'RQxsrtuǴ6u;n,'^\-1upa1o.Q想"PTvܙs2dIuMm!& Bym6o"bhHitrn× Mk E<*];01~6|9sݟ߽cZBʂ;Xq}޿Sny5e=A@H;~uRD41 n(8' 4z=Jd7u(ItZ[MÖ[qz>ѣG_Ϝ9qƕg3TWKQ@ӂ nH$}vrrr>8uc\ V'OnѿKԩUV 8] SW@zzNvJ$OKYVnUeh^N9KM^ /iYDzaË xHL޴zWz V`Ճ9lS7lVu(-[` S#Ѐ 8{}(D޽i3m{M4F 9)~O*dʕ|͗}sa۶{o\IZe05VTTTLxxZEQDZj14iQ 0,66ӧO_7@7z 322OoQFf͚ .:H&B?W_WX_D=CWEdSDO>JEGcZvLTk+Wd.kxҧX9~c:od)?cO {%tAA7ךL3J iy`gԪU\TW)/h4gb`_e %˴nZ[l]v^믿~زeK!22R(ғ(Bӕz92jn>jWqX,܉%-xA|L׎ݻPIϏ<ߟ~z@Ö͎7>5'W=/]@mo?QǜΒ!C>MLL$==*2C޹&Bшd*=7I  mժu pCbt4ijѢkEO{ɲquLQe{~^55<%=TCk28n]N͛YtkRS|2' el~֝w*󸐐.]?9cǎqao4E׫W/waرcMUrYf_~:+]}v]{U*!V>ZURV-!1i>Aji_em}[ *1e*VQapzÆ 9]kf&K/r\VKΉԷ[Oiѣ9{,U ֭[yS%r- B S'xoѢ hyСs $+lٲ֬Y3v???ϕ޳EdIp8زe (Z>0P"yޙ3d>LoW]U|;ONmeҶm/`$iSd]FCFJ k_M4{~NxcFp "[$1f 'Q_uZU*5=?^jԫW 0~x4?/m Ik֬)xdo{Q 7n,={(#G6Vcǎ111=Y1l6GfX}-./@EΜ9_^FU,/mȸ8?7m|$T>JtxpRMPuwRm=nm&lٲWBCCFѭKVh4v!:t8Z0x,A)kVKȪ- 6W(h8h O?)*L]h87x^|B>b/iD[^ nKATqHT.AvHlѸqc[ȱozvy rZիӾ}{8 \=_=+ŒF#Y(v;wߕX^ʿ >ݸq5kF_ۿbYbiiiq\/h2ثdv;Z5}jy(h:1={}֌Gs.$'^wk jX3vW=@^^:??;%/`EzvUJ"Z??N]˲F}Oc|MΝ[Zgrɓ'w^o<-lfǏoVN%@k ѤIٳgQFFrrk}]&bjjPzf w+s]]~q! [N>§U$N'>EmH !} oʂlόrji0Y.m= ▙3ddٓg僣9DkCp0%/xTUz$<ˑ%K|ǢEW=欬,BBBhq^vԨQ <7rBW{aÆ^U+(/?? f!IRji^5 vwܙAwe(S?ZkVG۷SiSkT*)UdЛn"Gp->Xٲ9o\H5iR PW,/"[?L ݎtu-ؿKV+߅ Ă\QhL]+ …|'zW_?mĉ#VZW/\l(RfM֭[d2=].\'.^_ϏR㯿_~yzꆀ"1 ʲ˗/'%%w H85$PvoȖ2d(^=7\n I7nFN>M߿0uɵK4/4 !!p( j?{ PDhl6~{!x1NӇ3gC]c/:3Q\ryСK.uw,NW~,Ȳ$IT^#FD >*PʿKJJUn]Zfxn0dYncZIKKS/^Lvv\t_ L‡EH;E#9 q;0;o.>;s361͈rOV'@-GAI+"*kge|D8/S>3Μ9mJrG޿xb~(]aºi04h͛7ӷoU%;;[~hZF A(pS܋y1$|ٹsvEQ^C@} \Hg+d蝜ٲPU)PFV"Zd t<̽.ӧғ{ݿn[_Z7^Wu34rNfŨQlxY!_v˕'Okӕ| [vm͛eR$0p бcG tСC=Cի@XIIISo#"" XoDay3V+l2%99y-u{}{OYy~arOAW(ӊ-0i<.{N)WqXn'ݱ#߂Oȹ={Rfς *QrH$ϝw ̦GÙ;w.g&00?OFF]+m:HIIYO?q9wB7ͮ@LL Æ K:thk$+/PQs̙wQtzZ\fx&feeqY?XB0͓1\]wY&lu`֑#̟5;q*FN[V/,EP&>ҕeNʕ%~gGTuqYE_!ԩizME̟OH{>!I$Cp0S\uԽ^Oe?0;Z&e<唌ķ;zv`d2HsmqFqNGll,ƨǏ/`ݍ111yyz>v Wo!WBnwo6 LZZ/;wݛvV=_111|t~t$.]eF)M+45k,gϞb/PT xL.$}v IUǵ&MZ]@nSxmf3'Nɓ,YDٻw& U'i&"*qO2Y=Ej@'tOֿb/?മkuNT||XT\b`/>'f͂-7Ee /A-7D߿üy+Vϔz.ިQ# `0ԩS⑪<ϑ߸qンgϞ06VNp] wurO… =zeɒ%B~~4x2Y/P;oeJ?s$[c j @<8'Oidd)}@ w)."OzݯfN4cuY<`@!2Md̝KX&Tk{ 8/D/NfӋ/b/{Pn}w-..0l0s;*fs޽{o5LJPPP@BaV8t:?q#z^)ZzZZvʕc/_qoKNԭDN^.r ZF]ӧ9~8;vw:s)R?.X!Ey@ x W/ǠQh|M=ZAUŀ&?+S;QR@ j,5wxu%;37jYHDNS{fg@SncͣbL\\3rHڷoMSO=[oymOZthʻ q^rm͚7[jA6MAr\Z ׯd*1Stn'0 :u fw|>협: xҥK}G>vvVىfsyZ 3 077Cqq~7ܹsQS\dDa]w KF|Z`i C%.O$11쩺h/K^ p!t}uK=ŦɓI[5iKp 8/CY(wDasHAn6u4-^HzAHH$!nQFs/))xf6 erz N IƮBD;yybYӂ \UڈwyТE / j IDATWڥZ4mJdDVhDbXb,us999]"}4xKӡXf+Νch󤤤^Z^+8l޲,, (+ E"$j@G_FwD /l*w1[wrO.qck3OK:vߛRS[WdQr?7Ȱuk "CBo`lz%~FCvhٲeEVZW˯Z_0r uz =99dggs!ҩc-[zAkOt/ 8PرPVO4}{  ~~tzf3| v!w aӦM@Bk> ++붴{]n8.fAFGvv6e9y$IIIl޼Y^~,rjUÇ `h~~WjԨa @###9ԼO5bI/㧃.9!e{$53֭W\ $"Z䟅 Kߝ8d Q m9NE&g[&+FB힙d"t#eEbnMSh=n-ƌ^~(d;VlHHv8:zءC9dC Vsh 4M㟣`X8tGarZZ^Tz.m 6 s6w yfK-GRaaB~~fقٜlZʶ~){F1@F O`4 rU!g?/u߀5@hFsn20hRL(rͥv94r/h S9 RSY3≇{v`m7sB:e4E?{2{lRSSt.]3fU=OB6m8c2 &{oO`ё#{R^ 胂l:'k25kKZ,\%KpwӿzʧNUV\!h-I) hlNKc>}g ;_ƍiժ͚5ztu233 ##L7`_uK_{`U$Wc7N:8p@Xply_No߾b>}hڨ|,*/ٟ;ޱ5Qo guVASw=j|?ο;wv*>? """Y&T"IAAAldlOQ#6j !b^VQoΟ^^ܴʕXcF?E_U6Xebɸ@>e{?\VhH:FزJߝ;KMNj^G_D=,[=6V-|ð`ʪJQu:Gǒuطv={d֬Yԭ[} #G[os=om+6dYV"I I$֭Qd1+)))$'' KQFrKO RlDGGMlݺT h4RNBCCP? mŊwVe Tۼy#Go/*@AQ`>{{ZmVRR& ຀.eeI9"T|֭[WעE P%V%,,L w*un H AigI9 .v; ?˱DM"l{ϟOP:7!u:C"c#ZQW/ߎj;|c ᶯ꽉5%}_f}}R5j`ƌ̛7LSË \Iٴi}]?bwկ*v_(eGx8szc߷VV}-XZ5Mq<ԫW:pwѣ t $={vɾe55!U! 7jժV{rdž \Tś-IF[+EFF';kڴiN`0^O!9T ǩJ(=BrQ0$tGO_(/5?ƍcŽq0Q(eᓬVhΝië5ۨۧO+^c0pn_d1|P>Ĩ6QQ%7^;FsA~fϘB0`fbDEEUi( &L(^=N}7 cx@cô[ݪ.-zde4@dN[@+R!F!::8q6]Kh.-'[dj׮}> EQxo紳fWTƠv:f`ㆍ$tX5s-&**JӣGvSRRV700]#=`8VD1rqPZ ge'FEF3s=#""qqq"Y1A Z  Elb1%?6<) pt2{&wDU z[l{}Dsd;=+ Zo1$Պp״peCtCƢv 1y'tzk%PϙMY;aJs=5 AjlٲkY222xŢ Q~~MsMGtl|{7/؁9GF/7yzP>vf-a2] H\/λѢE N<ٳgόwΝ;D]!!! :Ocs)~P@$I,$"p5ɲJVA4W^թSؾ}{VZӊ`X8]+!8'p,WwJrWo׀aeC|Ϙ￧SkPAosFTZ??5i.J`FGJ^M ] <ja,4"O ::_~QFoY;b֬ vo}^\Io᭽{ofnEvgF!77omҨQ#Sƍg/o uU&B<EVÇWdzXE=73)@ z n֬ժU+ &YU@8@z(\||JX9z3l6( URq!a"K[uZ]3gV5jkp-,kF.'%cҥ$&&bw4hZjfjddd0i$xǸpiܘ3i* [hMS "<u9_w0 {Ϯn ̈́дiS:tC\ Dp dEv%|@ *31@H0ԩSkY4]ɲfU T3.Dk }#/al0@˯-ZEspP֒G9,Q_#Qeߒ}kG=p1qlJweh4tޝnM69o0bN>|1cƌ3oOƽYDEhXy4'a"65CZhAxxڅЋ˿0tXݎNsq9=x3ǫpzeﶹI͐R|һ'0Wîi}CLڴ Dy)%9:yy Q$ڵkǩSN<9iwZeDQT$?{EF$2j\~^~D b VXƷlٲzÆ SN@q=]AG "rpg V}gQs|`RSY#:^tzryd3܃ᖏ>,5ĢH2qI֩CG^=(L&2nŞ?I49sФIf3 н{wOxx8nD{2|w@Eˮ]߿?111D@Ѽ@uAU ilpn?Dܹx(Ձw`P.ya"Ѧ`0@aaÆ4mڴ[HHH4H, $YwzeE&;;\J[UEѸ?Vt_.мyc(ԅ(]/_ P祈(|IR=Ժ/H۶E}xp>$n'^Ow4vרi<|8Nͮ]h!>))~,MjY?9~OckժiРAMW/@Ͽ˦M8<*'\+V`Æ $&&ҭ[tw]z5O>$7<X_ZG>@&Z-?;-[z0jH} XԩS5IIIIQy.9%4$4BTE/ r5JJP%/;'@[{P8&\~n az$j 4 R-uN}PWE8rg~׮[V kqqX22(EgRY&aC0 (ս;^?EA$g?rH̙+Xt: Č3HLLDy}>Z-f^x5k5jԠw WC=1uqvJ a}QiC^EױcǺ?/DOll,mڴ Gf\5p8w+|9Eʾ* IuNVVV$w `I$mܸq` Sx8U͊$K贺Y(ǁ(gpSfV^.]-Ӧo?ҶnUkTm6jܽĿ^c.OYFh3~<LFtΟ_*eƚX:Nϗy\ 7oɟZX;vߟ}.]9l&,SD)iKhŁ\nGqX,-խy 1IYIK/KUD\\e̓h۶-SN-6?@ׯ_?ҢE ڷoϚ5koH```{z:w,YBy󘕜L3<=\us}.8 vԨQHcWwHw[Cv gŇTffR؝S ,>净FLV!""L]^.|Y 3Oʼn* D .QGF=OK/Ă hڴO?lϧ!Cx#IGP˯X>g_^ ^yyy3kDGGȾ}\>{ cKb"ks963Xy ϧE,9qF@*0l| @RRG_u^$"##1LA˨"|Y M& I@,<ǯĵ,!Gu1 b8@.Kى#| `LDDD0l呛6`h4ŒI(ץ]7WeZ{kXtJ3&6k60F]"E,7oWW_%#섂e@rM0])1sLVkս;%wo jYl|9rN.Z__ߟ|_oS?/]t!//^eZnMXX%sHH?7|3bвeQC2--iӦ1k,, :h jR_y"?tglsCZ!`W{up,뻢(DDD,>y`O2ex-?CmS;$ߍ(>}^vsvN(H +2b`` RV-\_I!h%K<)F[эl8]ҴMvy ,5*"ϟM6ZYf_Ȓ%]֏=F=^\+Q;vX3ql9%ZSֱg Gk|.lMr=՚60^yii,N.b[ngAՒ_fo,4nܘ^*}u2q"ݻw3e P' :uѪMAľbi4XvHIᅭ[t]ݕU6h4OX=⮻vڜ9sݻw_۳g8z6pЈdrQxzpMW,iYYB [. ׹voVVɄ.]}U}oQdMrQ;$Gq)qYdԨQ$&&2mڴR$w8wt~u5uSuI":!Op~ߥťK .Ǯih[n_~E}Y[:u]v(V?o[l Z5kGuU*%3?gƮ]X$ x5V%PcI_QFXd-/k@1./q`` :ucǎȲLRRׯs fP*`zEAH p8|/Ȯd6e7x}+p̣4KKc1Dw@WPXjώÁzg;4tVSUÇX3v4qtQٺu+'.. E!**nB̙3y9uJҫfMԉժ( tfΝ|z`&<(p, 04'xuRyI.mZ^:nc ۶m[ ~g38$v0t^(YYYTmAСÝ#''HId>g\@Z$ Rn.+ѕPV-.\?[oBeԭ[WosO?FIp :~'Z_|NP:~IbkW> GDEEu:V 6Lv/ +6FY||MLn;i2J'zm<ՁI6-##.cZdV(؁7nE1u 3A&Mhذ!Mnݺl6"I7Y.ֿ}NN,el6r(Bz_>6h@z1&͆(jWBQQYĶg!!!=ܺ ѣVbĈ%m$a^Z:/% CP]g`/?t ! 0dJڶ-W5w~?'/-[dС%t:233Yb֭#//@M,Ѷmr;C1n8wҮ1cG" SNMuB̟ϏGX%UPkQ)^VO[7_.JZ˚]UclDGGӷo_QP,nJ`p`wرKCh><N 8)pUsbtqR,~OYؓPxlNZo)n8P\@%hȑ#*|A$|ƍLj#6m۶m+[jeK/25ڵE;EQPBcc\HNf߬/󎏢N{fKz'$!4 A,PPTvֳC?Q<=Oyz 4 6@J(!t B %d7Y6f7z+/%;|y>e?H=Hr(  V,|ēl93vԉ_|~Xw_/V;vk.tBnݰ;wB$;3fP^ߟ 8"oK刚8*4VE-W~nJԲ|Y@WouW]u~lfحU Y}_$HLJD22"" dK?S{쉏rBуv>_f > W_1%g!x#qZQqsVVC=abFAp\DGG3qDx(/K|3r$/L^ *9I؟p (LrN |mJ\ɡX]‘m8$6vO+b׈4D- /PwX?Xtf4Ȳ$Ij $,^SppV|]wa$,$++3f駟2qĈ4;}ώy{(>w-૭MZsŊ Z@^dIB4ݎTSwFQ/==++_~͛kۧ̚ҬY3FuXjXV<?_=-[+~L^*,>1łKx~bZjI܂O;MA7jˀއ2@.1I{OQ[jn3ݗu?#v}(&F,%::I>Az|$@&v1 ,4PSSc֌3)ZO?ԽSKtc^?:\r >swMt@3XHEEE1zh TV`v䐝ʕ+ٴi,{v]v1n8 1b-Z6{۽{7o>z/gA%|y3?U|}^o{Wj^*kC PL4n1= h7*]~v `Q,' EMxe:8 _ۣ @pÌ 0 P.I" blmpPIG||`+FHHH'tF &u /%KPYYi*Tx֬Y,Xk>s3gvpԸ1v⹢"~ޣlRQ ?i?C4& \`LN*UG4LSp`oW;qqA*Wn(H!H+PhԾaf(  oEyssJ4nڷo5\溺 NyyjZ=lLЧOk>#>3:scp#Usmܳc8 HLLhށy :J͛n2vŘ1c())tޜm̠/`ƍjk4:\ciz )]M]oV¾hmssl]g/5bBF-bI`H OZ t*TTVֱ8 cbp݆P>: h#U "!b_ t2EBStԧwy'qqqN[V~Wb[oZv-[l!??;EQp:p 6qEd+P4n>'s"ca^kNDOMHH矧F$|>2228p ^x!3gdHTfJJJ47kWˣ}JSV\̄b]jx.j{Miz T}pjp{~C!:){_Vo@__L(q(rQq\N9:m({>߱'L[בW 3f'݈!7׋( >IZU6 $uMיgI~NH#GX,HĂ X~=gy&͛77xfQ;v,֭_drw7B}+Ķn}†nC,|i_s:NdYv7{$rߘZ=\&OLqq1.UVex0/{"fS4fEjd+Vոe4۝jG{ZvnG{#Zo-kN]7 7%vfY~p ubcc# PUUصjLtTT `Dᘉ72GZ.61#I4TBPEN`(`>4OƟ2qO/_fQUU_Mv((( >>ސjڷog}ٳy#.[ƔzӍ} M  ʒ>蹩tڵFBnλkժsX|9xgOMbKżfOOUs3T50esRD^״D|]Dz[beY&...6d@Ł Nv.k_+jnfiV f(_xmSLEI0tFu5]W_}5'(E]D6mꥅm6L>+W^!F<;N?|fϞ [g"6VY[n־ӧ1ٳܹ3}aۦ n\57ngme%=|[ke5@ZDw̽=w*jig3|Xm:W B?Wp , qqq8cם \VtC3jkkZ!k5}?3* '*EA5ke4 L@6\-[dȑ3("&&&ryQ^^Ί+ A`ݺulݺ^zѱcGDQ4Dp=0bƍҥK6^/zIrWiѻZ7%"΂'dGܤ$.r.\>+BLL s'Ns=S'ݛ-Z4~JG`NY5wvxO2gP~5<[k jrIšC7B ?o `O8!IR@3-s3nt8JOVdW d IDAT F +ǫ2>VQ! I^/p=e4Z2PO뮻HHH/H>̛Ge cN֭ٲe WVK,&bh"6nH߾}|o|rƎcNf]3vsJJD~gš߮_~ADEӧ$_ӦMKrrrXf\(sp"S},:R^ {Q@/d νB9;g5OÇv^[+p63 F߅@"#u2V;cx?&66CTT!]c `ts4MW4i`|B(///F~JOKlvtF{n摛K(..f˖-a;233ݻ7 X/ 2m4>s~lw~=~ ~ߍHPZ<8fs[lObb?sl8pYfM^:nۻwoxꩧ:u*ͣcz}5 ܻhhBҲQ}ہ37jՊn^x!G*5\E1NEA+Iaifn00 ߃M10;<ڿEQ2r]`?fQUUElla75T+t 2^I3HZLy&hC9pcX",Ct !%{.Gn<,v ܹ3+VF,++.]н{w?H4<.W^y%^z)o&3#X"/nV͚?lۗݻSuVoN^^999X,,8N.b.\ tNJ|F檙 Ĥyt|ھp j64=[Pݾ~~ni_hh}_&-\x8NT;ƄDoP{wp{; DF@P&T:vծ]rpԺk >gX׉. `D`Zot`瀂va<m=t :N:EQv6 6ϚGֻo?+^ERR "GH}ڵkٶm_89,p%1cpuK/&@]8x6'Jrv6sfu|]?sǣ>ʑ#GXjk~^E7RPP@zz=ht|L>m۶!n͸~ߦMhj^YWV _N P Fo/,6H ޽{vL@q8Du⫗xߺP=G: T=Q5^C<"&&Vٺ)FR`7!6Q'p<.T&<"¸$IRdNlQ(n ~q4;Yfmh}QâdYF֐> Ƨ + ?y&C=!?9Nח{nS8[qP};χ +( } cC]۰zߵkW(..fͦY(~}ܹsi׮:yq:3c > >'|%* ̿*JVGA1fV+bGVV+WdΝ6***9s&Mvg}ܹse$z޽4cR\Qxi;P>kAb^Ղq]KϴwrFQdEۓ9jƳ?|OE|f{sP%2'b D0 '''EO$9)@$?C13Ш$|b7Q:,xHMhv (d~q;w[1**I>ÙZD芃~ lU;H5Mމ#"˲CQQ{Wk. PZFW\+O?UXX־>gO)d+,ZT0kرc),,r[1`***X|9y^, oDGGxbhsԹʰrV~*+EXkx zZ1/Uw`xP{ǕZ@ `POAk6cDY~Lύ]bHpOVV?qG]F@f?و&]`b jT:|QkI*t zȴ45͓&Y'X.JノcZA yz>kx㍈l,]sϣ덣(xq\t= ECeV~$cբE z)tN ЩS'ڵkY~}{d͚5~ zd P(L()˩ 5Ni Hg>j_ @dzqlӂ{N5󯳧cW>ÖPȌd^ߊe'Ъ1(`xJ5md5BBQ(Xnv\weW]y2'7t{-jڴ@ql^'+V NH8۷ !Џ}nbժUC[V9¼yh۶-}!))\. ĠAx$Ĩ.Y,%-!+ M:E *;jE@ jAc,Zrp=U1 !I滄cf4 6L(b"UƠ*C[ho8|1 5,KDEEcFQfI`gTo" @ ~;))) bQD﫠Pٵ;+Ot~c͗QݶdD/Nԁä}=}AԡȶXj2ҐmV0u}@~ҥ K.e!ba׮]ٳ\uf7? >W_}%K}l|n7 5[^?Z Z, f4%*Û7'ٿ8u҅xFFoΔ)S;w V^.,ޮ]b91>}..\ȔmxF90:~j\r TNE·|38N- {EQ@IȲTeJhPeY&&&&" A)))uz絃cXp8dji {fFnIK]Z7G{QXxSk.ծ]; xOݼ> E`A/~u3̙O?'i 1!ghǎG ;pG~8ӔߪEuF T>+0uYN(+u`Fû{(wW3!Y>"A@UeG(f͚}z\GG:* LVll?Rjhm).܆P%;wI5myyX¨I`3##m۲~zV^]oalڴL\.]veʔ)L6I&QA͛Y6%}Νiדвwob[R]|(>łm6$j+u1;c8"cFy\t4iߪwH۶5?3nlfcގ<|9ei_G@uQ>o",dTG3+pU]fl4ĭofpKcccc# -NDT_UUUu<;uEQ7 MĨxAYZ-F4'fz}B =#p0N$x$DEwIMAIɫg(Iw6[Wz:zsu˗m۶Ӈcv+2dof͊ݴÛ6y:}Ϟ-!L32m6DzyNj++_,la3f Æ 3S*7hM::$$pfVc_#:Xƍ[jt 4 Qm:k?wFu)ԲƐP}*NVJvidPw4A ] ETՓ5Zfu/BՑ* f'.99N+Ç F1'0urP-A0Z)Rl<'ٵk] DzjAF^͞ #냏T1Gv6$i^T͡*Mw;)dX0~YZuYt֍%KPQQQݻww^rrrٳ'6͐"|XV{1F#>㨢| 9W_}F s#39}!׍e8=>8ٜ{sռfm'p}w4p@稭|]h>||sԨ_ XV۬h[(f>@excSM+!!/ \%\'%%_]vqx^XJϧO t# `:TtM4o޼Qƴ+Wp8o駟x<`+zdDes\i6-Ȟ8 @7&5g'YR~+wA]2d$***1c7oXmڴwaر4o 6 j JJJ?ArB s>>2 p])v){=ApK ;رcGDO1j YdVZq 74z/6lt"߅oڴi3:GRsgf[L/>bX,D(ObcXĔuږ-Ra.IHOOgٳ^nXp,^ӧ~Bf:|yXMỎH~5j/f…pWyy9cƌAzi+WqyLݶs hiZSSýB܇2Ex-T{i RPm}\>fG ^UWx+'@P6 P¾ɂAC@u\g ՍU0p,$$$t:#rf ̆?!JYH ѫS[\ČzcS~dnk * "k׮?gΝX,:y'K>z˅Y χ>)K EGrjZMHTϓFrz+mnݺqWӾ}zA޶:w\Νf^/#Gd̙ >3v_B8fcme%͙CI&is~z٨3OըHQ.p@'p M@ hP%\#pԗ~ŝp~A?_A{~-r*,1j1`<_bKHESh^Ȋ+L_WE|>?3gСCGET/tq{oCYC9ԫ_l ~\Hᬑ]QuaZ9sKIMM YӻWv̙3Yt%0cl6G櫯7ߤW^$&&pW^z뭜}@<8Zjg"wuN7v3 |I.;ecdF̃ Ə{2/1u*Sm괹Z|bxMGU+h :ԎMH8W{ڟX8V-h(J^hŋjrgFF1zl`?,y T@QgNJ"6v\-o:]nfqC~ڑO ȀvȊҝЂYid,ʤI̤u Y#G0{l233),,O'IG6p1{bvrGWi<)X[@tGHJJ.~cҥ6l`ՋΝ;.op8(**b…,Z(l!d"333< .۳i&V\r|br?ҺukAٷov1<8 ;PٻD5gΘ<ÉEJ$oKE8D]}VSDePߝ܎ڢXEY4`0~Ho^ӉbS#Ս)dYA2 &tUVo;]tSNsA{Gy~ՆGyd2deee,[j{BII 6lL|X,$nÛJƌxk lzb"dd9Q}@=eɒ%ر^[a?@֭),,$999ǂAvtMjz< EbPPP@nn.˖-c޽!?(cwNNN6#dgǏuIoGjR,ޞMڿBT?Guobm@O jͣ@Ze^3 EԲaV7.e Z4 * =*nL:s\af k3(5:3׺eSjtN߾}9t+W4,_l*z,—ƍYbE(krYgr mV׮VUEǏ?awOׇ4QG:֍Á>aprA.\Heee{e֬YdeeѻwoVkzєZ6h0DgSTT|\RzE۶jX/G'j ekTA=Vg3a` @=.ucSF(b`` |>.W-  kjj=F_$tYw2Ҋkq rƌu,5M|?]ͺG__|@cujo׾%!!ԫC͛7_zɲL֭+Ǣ b5駟/ywh&ߏr<5n:z$(Pr9Zɨ>ݵx P0hߍ*o$ pO'8 @1)BfgM56D`uScS[3@tQGhFCC4 u݊G>l2GהW^ݻUZeRyH>$U1- G,Zf"ή]2e yyyonT$EDiW6<^ u"s²M۶mС+Wdڵ!3p=^l7no߾HΝ;ӡCٲeKH1je̝;hx cw 15fԷQ'j[,Au[vכP;4 PPWF1nW];t`S(F"M1WR,F>(TWWPHՅF[ n"???A.//;ºR뺠Ā ]:x^8&3}=G\\_|1C 1 :ի:u*eee~AM3yj%z_ #xEoƮ.E|G 9Gt{#K^1b(p83gM(f/-[UYYܹsOvz5kuͩ*Q Q{Q=\/qtq'Ma~Emh_F&>I^j,A ,fF Qld&P_FW=bry#l0CR*|F -*glD-ڵksccc8p [ۓQ͛a(vM|G3Zso4+=>6mp5пxP4c̚5#GvIk6iӒˑH~/&O-w\fK^̥^JBBBHGݻd 8xr9s&$I1wv㽹(Чw'2ڤ!Gܟ*kS4z?թof{TSB`m@!1>E JR/lC3 (A@k DY_( 0jWp07BUUURET4 lݫ,+l.P+(/e8zdU3TJ6sՠ S8''ne EQ/_~hM{w/&@Zh7e1{6~,#8n/B F@RRÇ笳ΪW b7mĴiزe)9@ --CҧODQD$f͚a3NX^Fs>E6Ψjl-q'[~[@Ml)%IR`2f(ST]`Ń?4;W*`~@ ؃p8"2 c蹁'5x&#G*$K 1>qfT&@Ǜe,(y3py;CG-N0|$ub~>E_~\RSSfΝL2UVIjKJrǟY7Tos8dork8^GEտ]EdԢ8V[Kff&#G|>.]ʌ38%UW]ŷ~[/⑇XM &݀@WT3)DFͣPKF_wځ!{K$EQ\LWW_;_=9R .P*O/  +ԯ/Ddd/:12ЗF@b蛪x@f7mN(bD7QѺT.stICz hW{F+\5"^r%w^~GjkkBv;%%%lܸ~Ѯ];J=QOt]&LZs}wi 6{YP(l#qeen8>{TX,vˣK.ܹ3$ cXp8̛74 HHH(8 ge߾}\wE?D]$&reL=(QZn1y |u.q L JR-qͭu@=^C ` RpK-UUU1 УB ,hV@1h*1&]8 * 54<7^˗ò5vͻ f6b}-y=7$ѢE FIaam)?ٳܳ`Y7l!y O xuV,Xd }B'_@Lq\ve4k֬(gfΜIQQq 9;l2mgcj4muhN ؇jwUIMSO>@&)x %k4'x4@HAQu=Qpdt Dg/صGx׹nٿn&DEEsNMʕ+cX(x^ MԞ[VYEla<}qd~DZn7ڵcĈ;B16ٿIL8?'#)U@o N`Ю[j@;r54_upK/tɧi=+m3U2 2z| ,iD(T` Bu([R  E&T)!OnsCKQ|2 A*(&|j12s˹`n2J}C|$gQŃ/g!"00Wppf1tPǜ9s#vΙYKJJزe tAGxRSY4[>KD;3#1X^n<8;* ł"ZxjQuFneY&//\ؾ}{H&"N4 ?!@r͚5?X 1F0= Uj#xUl 7mutF4"|p7UEFPDUY JMWmKHthkIT?lKR'n/poG^6z뭔pBM/a7Ժٓ={0|8{ d>Nu (;Qɘ9v_›ڧWAB""k׮,Y$d;ٳ\zRkǎ<3ج"_}(=3N\ {z;T  o!,AU7d95a,j{ANCճ*8V0nw-Q(dEA9)uY` <W4ǣZjy\@zZZ,#F,Ȉ:RƜ03:ѫ1JwÍÎ${F7?]v,2ZAn*a+IRX:3믿C瓐jR,"5moHڸyTݏ]W\L=cm͑bc9ҾOUԴjEpll gf{,a(uD.r~7-[lܸ[ҧOT<OllhCk!a"ѧRiSu1cNRy>zΏC[Gөbʷ1:toRS?Eݡw 6+LoQbP\\)--EcJ$1 zSITgf`E)gps/B%#lt~]YFQ@D&x<36lXXbt2gϟOmmmĥ{S?>%˸xK̙,n)EutnisZN ݠT ਻s4j.k:yT@ZF*-Z%fO4We "u3PS`]}cjkkydC$%E&>zX@>,j7 tz?A^Oq;wwR[WW; :U@ۦ/<"Dγ:́ 8 .^owft፿#F” |wFZիW3zh?<iy7HCǶ4iJő3DE.Iۍ6 ZJծ]TKRɦMرcj dz=y!դh[#Y. 4y"ʬ?_($l&:uF3Pe֤ڀ@fb)t:tޝG}.9{,k֬ŋɉي+ؾ}sgm4륙|SF5>?!Z> CS)xQ>HIH-v/#7r##3ȭhPfXݯ@@KZ&5:n4aWS;xzzcѥKtǕ+Wظq#YtD gۍ h:lUn}/p=X"zE6mDq͛v8_:",\HzeuU$?K.E0vX8KII>pv/b2z:nK_a\.G`h$(8FLP)+w-a!!UP ߯f(JRwPSTdΰ4:lWp4dA ` iqMdFD )"ZŶ@TwwzE֭Y~= 2A@Pǘ1ch׮?<..[$Р jotk{nn9Kƙ<-Meݶ*hPq:JE=v{!77d3g|2M4!**d+[ȎDT(=}?*4}{>g7 ^|Ev@@LL 5kȑ#={Ba% nݺN{m7 F9~DjvI!/.%"I0Ɍ3xgJuɓ'X\@Er!$ zy#' Qd)Tky&u " P2+WW~7I9 \z0ԨQo  B7J>[%n)En+,Q؄Eze2a2W,Op/f1h FMddSB`Ϟ= 6[:=W$̬$ww:15.$άHr4 <쳴hn]zƍu5b\݇md޺N^h5p z/p,}RjUj5')))ev d*竍W1E/#sH]7VZsҥRo'N`ҥH\2Fsd* P/Sx @=?wwyN3BEj$d ,HOmݔF#a;vTJ董ltvozIS#J"fe+thzpj׮ѣ4h~~~N(?2rHN<:2-Sׅ+#mNxӬc=GphZԩC,{gD,nʟE `4"i>eN6.!MKxxxc̍eq]S󵚗g7p:I@$vx z޽{޽e[Fᬓ L` k?q*+kqJ X,\777LviSk]I]g%T ֭î*Q<7..69EeE$uC-?WKdɓӧu tΜ9̘1YJOwGOixn->[7xf@ g#hݺ5O=AAA ׯqFߏ(Zsh<̞QW+R7wBc@E-[_UAu{Pز?*eiF܊T\ٰaMimÆ l۶a#( |/.FCUXY d,n ,.CL2GEnHaa9{%TBNe$%%,k77Cxyy2yd,~] sgEZ%M; dD 1YMF5eg [@? ?`ɴhi /_fĈXa!@XU%7WC<\_iۜ  ˋ\kntzN*qquu'K.xxx8,ٳ]8M)}<-x~\FT)]8.RwHj5tA_Ίeハ. osܼd'&8oذa_/egg{9;G`)`J&l}Q}I|}qF/)) 2JTOwߐ+9}?`[oӷ7Yxw999FJxOF:\0A bFF'PwPFMFVZZ#% 5OlʧCR |inՕѣGXhe͟?˗/;:$ KrYya _g Fd|W*q@r᧟~}v֟;r~yXXKrSgx}(rΜ=O+Wt&JҪjvq~'~WjEE2pЫ6Yn{--JpE \.]D狛u VY5ι7$22:KժUIHH ;;d??W^*Es5t4.j>ч[.UalKmGڭPc/n2 nݺzҬ#>Vŋ$%%[2 d׭͕g{E#- 9 AImEZVF9ժU.]SOѷo_ׯ5kۥ*YlhjpϚ\d|%vKg$_qy$Ą ؼy3>hv/;'*Dp_-&: z=zNN @VV6>ԬiU- 1OyfddGffftv*Aҭ$҉pT*X#i;.Y)W\-vWʴ?<j1 3h 6jrɤsˢ#(&Z|QQQ=޳;f^S\EQd,7//u:z˱?dyp5#kZNl۶իWgR)UJNǟ~nZZKLž{_,RroLgD*d$^Nh %""H:YT|{ԨQ.T(r˒(HNNf˖degQ*,1y"אdڹIrS֭[G>}}qvZ_"nFK.U_ Gɐij< ڐѠ.2'WWWZliȪU"'' h4Vg*EN~ԩ#nJ2_( mHy?,NxӦM4i=zku׮]%ɜu[yd-?ѝVh4yi4s U* 7 G*sIHH`ӦM\Z|TϚ_VڜCoֿ@R-JEZzn%XşOt T*%>C+P9˾囯;<.<ĄK yF79O F$9H=:0sLZlyקN#66Ç;:w4Z.I}Ѯݺ:ZM\:Ay3jtk&0`0X%}u?:ucOzd2JT =^^xzJΰ=zᕆP?ȹh۶Uɑd2rss8|茷7knXp/.ԁp%t:->>>! 6Drsr撚ʓO>Y!O@@u#|2Ge޽% 5#%u~>E~G@N4S*mۖ-Zpa233͍`j֬I:uhܸ1!ijnsN!a56$v-UJD]۶%gK׮]Z*f IÆ Cۗz=j~~jҳ (T9+.h:^\^c 8D<yrrvVi5 `[AV; 7'OOjԨaסe)8 ŋt֮pbD;mSvswcyk;w#{WR9uHS};gQ;EXX]v[EBaѶW(4)) u^.a!WQ2Ԕ"_&c.o%ڵkM4ڵkٷo_Z.]Я_?sLlؚKt#n1v)>1ԍc>_~Hp\dXx[JPpM8@ZZӒ%ԼysիG^^ډ\^DL*%n7n STz'cϲ8LE"7lhv~`ݺu8kȠcǎK(J=ٳgٽ{7۷o'--fS QѸ7gr;[o}njѣ3> 6%K8:$ F*XY/0󣝉m&FZGnnO@dTCx{{(tV@a/HHH`\vĿ/}CV-Ez:=/]f߾[ԻN8,zQEZP8KJJb_[h OrSv\25ъ;x 2 kΩc̑#h 1*-$ޞUOOOgarLP|/^ȱcPԥ=3LѮ];[~ X# B[%_ΡPNbjpzpbҧlEq,\;|s+?6  }YvjCʕ+߿{raN:'SNeȐ!Nܽ'NмysgD瑴*= |/ڱcGb۶BJ OMnnnZ,VB`@:`-[Ns%&&G=\f7*b'YX)T@шh>[U;/\aUڵ7n۩dbٲe;g+nhʑ#qC6ٹ"3s\CDݗ0`z Ndї@NZEh?luPVelڴ eA \Tqc'ڟ.#n+]yGNFNhՈkpuueر̞=BQ$KQsr\]]Yr%o6> @1 IDAT<ü,_'Ow-`ȑ6K,"cm,'_Ol?Vi9,G$@ ,/Գш'...@h>6OW$s Q;9q vUL$N\xf,sq@@Ѱ}v㉎i*l _=e6ˋޏx5ei,*:.;ؼǟ42RaA ,,5kKZZpjsjN^i1`*<*G|rm(JZaQYVZFVVCecZjzd&YunuHEP} ~jǔ0e —?B˗"vBOBt.D{=Y&#%%ǏY|Kqqq!;;~tjժUbBkwپ2{p@D8 z3Pz/<WWŠ-Q733/:xZ@F[(""ZKa@b%j 3f ӦMg`` C a„ ;/ J۷3rHv0ZUm;=u+ 9 nj]U!;WZ#OhP33 н{wڷoB@9d?OdffJ&Ea!*\8ǐ7zXx*[-FyqV}+V=8p ~-AAAdff:⽽xwظqck[`/^ttHdggE0D,( + 0U/٢WK,2EIؼDX2^oWń xqwww:h4l2>N>]ɕ`/~)u^]M8N/HXV-Cƍ--_͛7[kRvG /4C^ NCHexVG cgB%xP\u)os`U{%7ރfRg%2YYY$$$`MxxzR)dҁtN:獏O@[.%'++{.s}ǎd\pB\۹s'DFFZugZI܁`KVdJ>}w A87lؽWRTB^P*:t!?@Tb4ٱcOzz4hGqt`W4zA`4XE7o˟Iu^*UQ XY ҥK*[OEvI#-* X(p@T!2dzX  4cac}8~8{.Q~yжm[RSSrC~B %%EqPQCֹۻ3~N:mS#*Kj^x&ƻ"R$22Pt[$''si֭k'Ex?BBg-@8b;aGm^WAG/a p@tdۗ[nq ٲe ԪUvɘ1cE+h  !<<^C政hqAPQZ5~Ih233|rEB*jEeND4{R3HY~K}HH,/%_ )au9VZEݘ-Zࡇ"114c-vՕpgZkW ,*5kJhDEE7jve}8p}]|8f" YRƍy뭷e >D?q㯈Ç#t+U >%P5wV˨Qyeb (c!amͽ.4 jP{gL+ Usu= *~h /̓qF5jرc+t-Ù0aAAAd2d2۶mcl߾)pzv0w'᚞aRnЋeP#LΫ<9 u;_a.眑5j0c L&C;, hZ,Xĉm۶C7 alĖnªᡈA>5|8*?Ywt/qjB@Q7r3nRVRζ6eJz@#`ziN̙3]6K.t"**ӧꫯRJ%Z˗3i$TJ/a$^,YًZn2=wӈ<\ٝwhy$cccYx1O<jڡsqq!))qgNl^Px+C}OO~ aPPV8}xsbrT'&&2gg ;,'gTxo~՟ d )o/.{ĊŔL{WɏEk+yRtQgySrr2o 4`۶mi׮K,K.~@JJ cܹ\vrv UJ$sMtئq :j)gKJ%cԫWaY8|0oׯ/G"qmC2a6sH ?0ug!? #?Uvȑ8YrGJT?Vd ]tK/^pP'(BIȕdS/H.)iڤ+9` uqU"Bix)tB^\^Qxg7ouE;t*ӧO3e;233ۡ;CRP 1tqVd@k7esQp_7Z+7N?#F`g\.gÆ ;:d0"~_m6´8oϞ#x B^_}Ъ†VAh^ntΝ%Q|_- m)Su )/-Xv,NRQ@zEs. A,SL@QPi < J7cԯ_wyYU̲N0@cA௿b„ _3?, F!(POKUCJlZ4R1V5EFNKQyxuHf̘0P(h4,ZSrJe8D}. 7mE ZU ԮuCZ} p4b.;v/ L @Y$Q(7`6M;#& -I* PrE|NHsY&2`Q| Rnn/ER|Z7z.\H/*b̙r* F÷~ˤI8v́R` Ά/]3ff~yilڑǗ8[E8#<’%Kڵ+:Ωs%jugΜ9 [ѩu-~=% ]c\«~]6R ϛ4cJgeԭ[ZpA}]~7tff.K3,=Z66@HJ8~: <z ƽ0a>2Ty4dqSID*Lz+ HhniSD&Ep:˔h#i)be":@.ӧOӥK._\<\.̛7h@@T*gϞeʔ)|%R۵?QdD.xrx&J?#PoVnt~ Fĉ n> YQFqAxiJC1Tm9VF!h'`3B8}p1cHOwXrdŖvi P,H 4Pɣ$WTp`7|y:Y4+.[ـwδĶuV1bZd=___L֭[3f _9 okx3j+q}uD1{:-@LL }UnBDVxbOƕ twGa\)s'}ÆBL#֭a Ц!0u*bk̞ nwAh\YPNߛ7xY >_,i@`(8Z=a {. |vl0""ժUGZjwh]Ǒ<( 92A@&#P(  pYN:S_tHrJիl2:vHe3?;8?@ ߿?!!!}>o-`1/ݩ)lޕ<كs{&F u_ؒ YZZ˗/رcN>L&d2={K.C:DM 5qAg!'̽ڵky駝VIjEjP:uc̣  fuI *L99j!ԩSb>ׯ{n*ʽL}2[*Z7/̩ ,di`!PHJLLSNtšNE4B={6A@Tr)&Mď?Hn}:Q*ΰW|/%"T\~\LG=Q<6O Ԯb’w0rHƍ(RZv-ƍeuPxS2A-hvv_!2"bn̟ `+ \З) D hri0j IDATFؕM8f `IXQHrP x(0֭[ gСN͂7nYǖL-[;v,;vҾO?ݝ>| 6d۷H0(UT|r&Lӧ?vҢ }B>_`ٚlwi)un%=cX%v\gdʄ9%;vd…tѡ*)S/l Ce"ժ܅-ƍ|GC\gwVi͢Z&HB@l̏W+3ì(Y!>kFbIieU14o4 25jw^*uޝ%KвeK SYᤤ$>c.\XlR|Sh4ErsM6˯6ٹ"}zйOv/1@neƒMotqqᥗ^b֬YԩS!QВ8}4nnnCA^btCuRAxI \VW_(eV PDԊ*lc ERX3vsh 捉mۖsJ]\\xי6maaaVQ#$ ;8ʳϴeم%*DF,h5B(۫QA qɓDA% 5ĂF)*̲;s?Δ3ev)3s̜s}_U~~)w}7O?4 -&h\Nֳ\}8^u2|<-yϷ^4hӧO; ??DԩS9Ckvxb~MvSRR‚ Xh{}ġbF/[d||PVρ̹5!X޽&E})Uu1CVVW]ugذa?kH^/ӧO!ΐ"- дWE_.iT` 4|sRrss:t(999햅tjtw)ǃa80 ӟ0pNÒu:v gRq N x r:zbUUK.ewy1l I'qǷ~KEEEa8ygmzrqY9Q/^Gi΢WOUe7PR #ƀrU۽{FN~ƌqjn?]+C5TBTw2B&}rbQSCaaa:( UxG\> KD شa?!/t]+Я_?fΜq_CaΜ9p +$rrW_eڴi2ͪ'?ZΟTϻ?N^>40iui~@ڼy3wݸpKKo,חpŜzNmOBʕ+Yn]î:&9+0v}]iH<&FIJdt=! 'Kmdd8M61rH.eL //)S0{l ֮PP??gƌ<쳭xCVgg/հ&8wz~(G?|{3eʔX<|uMSp^귩&jOOBBˌGYEd[;0yg{s=GNNw_}>3gr7ү_v rK5#u_ Ojdqo 喽mJ$zR^n&ؿH9P`VˮIl>ŕ2t6JS6ѻD2lˌ6[x R M^}8{lx3KtIpWvijjjs"s\466l2f͚Ց:y>ˎbNgPYg3U|u/XAΈcEyy9s[5>Ri跚Jc ,0=|z*.hp jg dDH5X]]9ؼysF}i9O~kb0 \.%%%̟?~ݝYczΊz6m2=sxVT7PVH&'Nu`f?]I5buIK0:Q v]Rvha:@n7>.&NU>#<כQ_://I&1gFn`~ƍ>}:+Vh3p` {}ȃV2ެ~jG懇9۔ׯZwNpl} W֓ kC- bo\إ<;SOMAA楩tAvmL6z XTNVZ7{?~v1g;(,ԢAdy?\r%ykd)0l~+XDx9 DC,e/B}61.BI`6V 8c 32?`ԨQ̛7kCccc餱K2sLn0~ ~}E_nv?>;ܜG}۷wHVisBd4:+9#۶H])RsyxI`[[,%Ƣ8ω?ѣGm۶.c2|>l|m nüyxᇩj=o.~ޗk.K'cq 7:a;='u#SisWo"uS,a7#ɺXGu;hi\it *0E'!0KlذaÆ1qD3KӇs2rHx=ĝl2뗑Ceڴis= 0v\.7p~Z|;v?)aӁF='8.+|jFRt`` $o&仟jY.mieotN rpZ<'~f̘ȫq_#dܹL2n餹%Kp]w7ߤ_|űYOHg .5 %~-r%ʓi% IjI*O]~Z}!M?QM_JIπ1@\KJJ8s9شiSF}ig 8illl3?FCw{&W^ᣏ>jfZ$}Np9aQ'&~DgF&ؔ )!VD26x]Ni,1b'On3q.]K.as1ԴiAVV97tV%+cy*`}Tl6#sxRGG=KȥK;$V V=%֖?)@}1 x(q C=Ԧ_2p@~p2`jkk۔6 ~*+M Y+NTNǓ4L\nQ^f";r ڧ 8KL'65qm #ܹs1 U4995+f9X"Cp:ߩ2̈@+Fn~iϰ<ߪKM{y U@t5.mӘXtxNܵkǏ?i8Nƌ… 9hhhO|L4)ig„ o 4LoekT30q=ƭn^HjYi?3T PtJUXv-#FcϞڠfggs饗?c=60f_϶w$.a;IM᩼ǎ #&"cG:/? P=R x,&dGy:46fVz^^r '??#x 㗿eC^Vkhf.Zԍ(@?h@ 6L,@n@f~-M MP6mf\)qX|:<;9ꨣx3a<@^_y.\.S BoClDZ'~ U{MJТ:XV̴X7Z\":tPgg~w}Ǹq;v,~dL3ojQ`s 2h m[8"mn8nN&4M˥zjXng8o%or3ydJKKu'mqxFY<;8]NBT [/z*倉 &ptӱ +$A0e~^].t sZzwfm42ۅt}r %0.;6`0Ilh BЉXKg|k;IYa;2uXb4oc9+WYޓb.\-qּ ~#J`͌z {LJR/N{u,k`#ޚVKH aͅ; 8KCNܶ /:7f֬Y!bpabeVRbdh}qqx`Y'\ etzlxò]HÖb0#`my8K,5k0j(NccVG5&nZjQQ}t+L& e4 |}`ss3MMMv\V+7mܪte?Kad,q-#( G#U=Op1fl~icPå{v@]'b%Ҳ%pg_uuu444 [SSA4YM[}mc mF@kX '/~@EE~;Gfʕd}XmrJrJ ?/ kkkM+Kdk555uA`_ zL_Dl׸j`) d+pV~Gi&.B<̎S{ԩSc,/o&}qr8sam6i!H[]]Muuu sTUUu*{4aІ`8 仦zi?Ur+׬Y)µ^KqqZ~zN?z7CRؖ̋wM'%T-PUUEmm-XU9m"Th+`Z<@Kl@WܪǟDGFQ{ҥK9c)((&9/zjG} xP i'syܡ*Gg0 "EB: t_7`Ka|X__}0"hC8$r{m۶1|F;v,={I#dhԱ>Yr]0 i%ʌRd0 JKK)..ꆆ*++eeeq緩 {?0l;WȻ l(`Egޠ7x)S0p@N9f̘o)@qq1gȐ!̚5+e /0XGR<m[̝ <&f Nmʨ4ߤؑ\ǸV85 rp8$pud;p)K5ξѺuXn8N;0ɴ͝V2?GvF񲰰QIDAT:'qd* t־XQQXXX-m -vj<4#=dVKZѽi*< 7M?翀Zӎ]}r[uX%%pt@0О1Q^^e0eǕTVV6aFHhV4l43)rQ`) H& kҒi]}W !f[RcTTT4n d;w4bYc6gq]=9߃pF< Ke{>:`Vuwr}' aP^^۹sf= 9ݱcMv zZ<nglu Z%<=OVÓ a` PK9/:ͬ!%x>clllJlllKLLzx<8m8p88mq"PHB!ܛ * H$P8 ҭHd sB6-NDP;!@W GSSS%%%uNHHHIOO'--4;99ى#v t8&H8L$q,ReQ>7!mR0 W 00+-UR̒]ş[%plJ Ah NzvuF׮]vҥtIII!`0HȫP(®D"ضs1?͎6EW{gQJaJ 0 caYeSRRbx|>_\rAhL۷>{6{t Ô`0H,TUyyi00M0M6=HII fQQ甔|l[Wr: Ah ƙ9zzoСωqJ'T(: %O+ L'l㍉ EEE_qkXAD1e608##cAN6lXСCS\T#@ @8Ƶ8, uS|֚a[OW؆iMӴM'\ZZJqqq^>^ ԌN޽ك :iر#F8%JK * 1G-XVSc 8*J(Da!C)xB` w)+1gz<ƍ7N9m׫ )))Q~˲c+ƬhoԶ?mDim;N p8_Y~ @: ,4hЏF9pʔ)NFFyyT$d7W?P hYD"_+yp((;QA}~}FP(A)KA v8ngY&W <S] x`'xرcL6QJQPP@Iq aVYЗhc^ZZJ ]G |&N,zoI<ib&Px\ӪHb4 [S$[?yr "0XŔS\RRWRB  dYL/tOS)+F[M^\_^ĆK'>A #F,2eJiӦ9(_IINn?z`~<ϧ ?_{j֌{{` M?Q6]!FNxxxJ.A 򌌌N:NqOqq^GGPcB)E$!''rAzXq`F6a!:h{:wt#r WAv Yf]pBcǎ*77"eϭA0dϞ=dg|7 iyU|hk I A<{NrUY0xF|o>Ϟ={طw/PHXe[AП ܋2p8cƌ-\~}זNWܷo;wd]+Qښr v;m2:A8t… GvivaA˫Xӯɥͮ;ٶm^~[oCw-\ ##ϏsGmdg|_* L$ }6mƎ;d/O P x]!𺌌 @8o0!Cn ۥ9+_IIE}՜Eksssٺu+[lM GMlE- @t#F,9묳TRbo^# qU_u4M-[زy3eaW~ ##`F{۶3njsg99F(B)UJRN߿?7of֭m[p@VfMA ALLLl(1bč-2xpZuq [ٺu+!//!rls A²/;3ifnNY$ʋlۺҲ21Bs>t׀+BA :u3<3&%9ٻ~3h7 {uJ܅@??QDmY;wn޽{EGG"mVmFĶ%z_hQP6QDm>SL0f#';**j|o_h J8)"VSOu E \J)vŶm( e/.3J8aZA8/!!N;-!=xYWpeYڹ]w,!w3RAвOB2yO7p@c޽)++cΝ<(n~ax CAТK.?~+.+aݻ/7 dCz[JtAA ҉'9---6/77Ʈ*+#;;"ހ" XB<N:]5|p(??> (U#) BހBB @hV SJ:th3//b10orvddfYRRM}JKJ¡P>byl(F|-"]t+.AJJJE pf dH±fsΝp8hÞh8m,KFKpp:wA uwFBB Iѿ G"r r    @8*tތd(XVlU?Tn#Q[!DMb@ЀT Bsm,doɈ"!|1!EC6.DB/ 0 QҤ 4Sl(<Kh#`߀bEvӄt`=pJDze\wt3D`A8?~DLHE8tPyLBCy8CЫAZ869:K`#0SFD T-`$be8U4h;02(81@O7+C"RX6x'"@hG !j@ImJ]ਨֱNj8! /jQ30;-A,pi+,@hstwk%mLȸ< XQD\#_n H+i̽Q~woq韛q 8/5V)Y.8L%I@{L9g" rDy&Qpt6 .r6aph8eċ]ѿ{hWдt&}S]A":r di(Z @h%AO_/c8ts'ȏ-W^>pIGrhţ ֍+JўB?:;b4\Ck?@:&'gm8oNO@ypHŰ"H'sqtWp K:2R-) Xlq@ *_[,h+B $ H6wBr rڴjbk" 12D*nfɈZnfF?hwfH6&b"HW Ķuπ;xXNBm`D[. ėl<.ь.C2*m2"V)"@h<2 bl[ HP&bbvڤjC[b995D͗[ ڵvh#=A8N.>7x0-kKox6#5D͎93nǘeݽR7?&=p:vv\HaB:ν9ڷrq#Г??@hVm;0\&ó\@;֚;B3 ך Qɥh7|2AׂqxnOhIgfR ^Fy 9";`SEmu܁]8B⮻D"ֵdRfPJ-|IFNπ"4 5f8xYq7C7U*9P[@Ʊz<h72@ACARknPn0&5" E+ڵ&_ꮪ>2wر vkO@+|@6a.:@[jjGr\r՛Kުv#CODǐtZ=~\oCǴp7b)D'~esԽ/sQ㜯ݗ-[#_=wp@bkx)43 V@5H}hE{60/fw8ƿ\?}P\0 i{vw@o:+k02pnit Lːnj[k[þ %Q5ol#0 qտarU?KΕ'0VʸnʫV\~hmt+, j`)@/Z5\@ %A7 YKOnC0!5pdԨ٣(0/"˗ߺ.|9{&q\G2XmA1-ȤC+@8z8hYK@؂|G{EUf͚E(dygH䏮t1t(S./<тн.ZНЊ Fw,(r>2mUcf}U 3r{{Z hA Hq "ѮTױtjX \k+,BkbtYԣf\Sm)cc#JJ(޹}Ʈwޥ_X֡x,4yz^0xyVK[b9- `(Hp7r81ZwR غY⿄U wtwzaPN~)'Mzaa[00,>=]J1E=5nG `OfrIG݌ pnQ0KVs9Ey6tLww' HJߏ Fqplqox c{!` &'$$8^i6٘ϵrʮa;hFmG33Wgl] l I DǘH3)Gnn-,t5`bC49?k+5>7upPkֲ* ԇaÆ͞=˛x~{ 7h,~8tT%'JG~ ?Y hS^!e"ja!Jhm|~o+ࢍOOg=) Q.UHܳᅬcwoND ||]~Yc^ݧq{^vRg=_w33KN:H{+mp+\B٣yڟ[5os΀no׹3 y˖ ;Ƌf(c8cY] ,J>Fo}pi|8PO~rXԆ{sf('&7]waC.O.X? ø[msժUC?têgِ[74Po~.ؾ-,8\Eq'WOla`Q7mwk4MI!T+lI0 ;JL(^ϋZ0F)&:WJmt{eZ[t TYTA;GrL\h!e +@9|xvex E^L'{fbq]:LOu@#=zYC|^ޡiLJȎ]:aЭ[7&LHJJrBPT_m?sWQ\.9茖y݂E[Eg=Ug0KU.rQCa`NN: |܂ C_'&o$${_ >>#GZ&oi[իWsAM})ef.O@dǺ Gۥ4"cuY/V>sE@0cc{M pt[#a׈v;=Ӈ^zU*5zYf->R6ӸE0^b\9U?mQ,C.@8cNj7mA::5E7uW"Ga& 'IwޣW41Mp0/eE˵w;τLxU2&Oq&'R m6}]+/jwSrkvnQ;Е7Tl9 L c7? 5 t_)F\}7ԏg;lKoEAa!P00c(ݶŪ8X={2g{Umۦ-t|<T/Wm=x l#Dm95}@b<l@Læ%>Ym׮]䬳TV]espS؊;aPNˌ::{Z"fbf\OǶm<qgX="8M$Xn9q*=JRl߾k{_й<5 *G<XMܘu0`cix;vG"+9@6}-Q`7IջIJEII F n~35ȫ6v8sǤ3NNJ:>aW30kaZc>X/^FΚnc E|QA?Y:wVV$¸ omܷ Ef7ē~رXcXKaJ̈́ 0<'!uɤר v$Oǎq|Ki z?5;v_(U=3&V\g" 58˗ߒwӀ7-(8.λTOZ7݈b ' &sgpH$76~p&`j+Kѽ(i2a <<"޷bO272h4JA(;>*۹gJ}F~V08WDecVl`c4ƏQJmezaW]"`BzvJLLƲ,m!УgO曪m>OJE\ZS~+N\e-}kzQJQze1ccu*+o"*Ja{C/;W_5{pkl*Vm |ƌeeeosn`p ##_}} 4eT\ۦXLbv瞝!c5_n àKn|eK[n_k2܉_̇"u[ɯ, . Dz8CBR޺^sPMht<m+PN~ژ̜IE(ڱ;+Ox@ 8>=k?Y5GFYQ矓1 #F ~jetVЄH@".X[N]qp0 ]L0 L0;w 6 x-{]:P'<{w>-Ìi{̸XyOX~݈!ͧYR 7m"@>[T*E4=|5f{g:۸qMì,p8m{<_lX-(0 Loc3x֐'ZrDUl/Tàx޽b̸ï]QYpe$t*811~%QAg$q)U9b'; 7,(1~(噙yW85͙tQ RS aR繬wf9 B251M!h6пYfOd*.rR~t<UT 2Ѳ\7T'П> s綊J~i-l(/H0@W/!Եk/^L(JP(%@pի߯k׮̘15P7Tc;̘1OYYY60}_=FTv̚9G{f'mc6eaY]t}ZRš/4% +\l~ tHT߯s~O`ɒ% x]ތFf>-_{=dao,~޽1K|@CcUKHܑn]T\a .g?A|4fвWy=M|gی6bcڎK_~ɵ|rJZ($//G}g}?={QIY]%b I63^{v:Uzȑʍu}믫5x̂:رdtWu3'@bh?`@IǷ^G<1cưf͚uَEG*ݒwqs9u ff[^w=~i!)-9xi^y9FLLc}o.o"6GuWH4*5A ׶8w"}g\7!AÇU[gee:/-;Dot mmt[߀.رcZrӶmF8ny7 ^H4`y\\sŏ֭Kw,˪(WJL~BW\qE>p-s/5 0cx<&M&[w2_y]H9ObGs:M@9s(;HɶP/i8?@;MI&O*xS GJ1>W^ZP:E3{"Lqx饗j&])))Uޱ`ٲ[{O+^{_Tezs #;'ݷ^9ВHB_rQͪ{^5MVJ), .`رg߶q ݽÜ}>+])Bl/0bbPoV?4XiF6PW};Kt;aDJKٷv-y|JB$dtove6~ƾ11wB캬@I/_҈D 0xS/va,˪}zmP(ŋ?m۶muyi}7I ]0wzQ^/| W;ElZC^GY3vEa^&!Jw_ڌmSثW:Ɔc;| 8Ƞ0qg|zvT\6G^2bĉeee7._~u=gUKǹ YC"luWf[\xuu:u*w˲X--Ùz'f͏:t0VܖٽK^D΅mÇK/<~w|~?q ˶Eh͛y$ź:0 b/AAM##6?G%R;>;H΢y$'4BB[cMHطn_5:}?ؽ{<;cΝUV <tljY+VVćRJLL'JK}/ ۋ &a v=]`OHH 55/.ja= ?@b}:?s7sVQ+oJHv>]H=Z;Gqcɘ3Gw!*~+m"o׭Ó@r߾z9ݤ'={e81cO%~䢢k)o5oDn&=zdx6nhp^3#"{;m~WE3fZ^Ƨ{AeҥL:thVnV^Î>2M|wխ>zԑWp"̸8ϜIIP};v5:>@9hף' =2ZE'`;y,.@߾]SPk={c'O/0>r`P}c 1/\3gF%;#^lt͌]vnRS)Wua֬Ys9srr綠 #}+ЮO:az͜Sݚy8|x҆N7/OuH'y@pَDKK<7kʊ9j֕W^ܫǽ<.!:vg 2}Zr{:o޼]uZEZjqv}!S{17<e = ǝwJ}=۶Сw.]dI0r%p%:nM3.ngâ v>,_}Fl&Zee ~AMv]3 TaA:,ޤfp$OQ1'NǤ$aq뫿` ?͂0aB;' O333u/ZjTI$ !zn~%];AG9s=g;wPn'݅^HRRwϧ@I"R*5RZW #F0sSۓnK?H,.Z֞#qYe1"##~^i59XLq: |t_= 8eeح@1cQmv㄀zE:t o&Xi?Q#)Kl|a=7ޠxDlZZFL ;\:wHBvڵ?_i)er`FLudG"uHiH궸K̝;4=<|wω]Vkn1c9w0׮i~ _}m@)ENͭ[o0}D^N<'4=}Fr222ŋ@nlσ{H IDAT32~ rPHiM/_?'s ;iBmLgiDo# zcﭷ]>}hץs|PDzIՓ^N\Qmcϫ)-%eؖ0{?gl>l#;wPyeiuyp,>}\s2|\_XXO?Sb@:׎Qz ++@+;(.zw:1T2Uۥۑѫ{" waV/hF\ޭ[+Vt޹^q8q"ӧO_XX:?92!O|LJH٣Q};.-_D>y 3cSS}$MW_..>mv=%;w:lޔ#+H>^gS"ƛxH8_ RFlƈJar.[D\ts"/8;XƁZ/Z=*x}Yrssk{t׻.`+nJl_]͡v}!C 𔋦h_P.l&%=?ڐ玝dq MO{W}\U5⿶r[%7|s!C^sӀ_(ێ#F0amt1H Hx+/);'MƟݬz+q?yDW;{\/\pަҧC=|}Ͻ.fBB_2 Ƞ%W~f;D~>Z"%շ-~^MjQۘE;v]wI0b. ;++=~{,jϑ \~Zj cOVJE )6-%>﯈.\fYr?"t\"<ܲ,]|B5_W8D"za2d:fT4_vYW$&9'Nķgo>yS~}71)lxd[oaG"G Tpi t=n}we('坿·s/p$0s(,?6}9y{3.c D;a[fg(N''O1# mF48`Ǩ(q9s\_x۵[iϧy˥rwXZ>D 4Pt%fY8RɛׯBBmSU۶cLP>}P}gBl{(:u&[l$ sR ~AJn:tҍ!ISU, 1#Q_Xuk4MpM~ l6>ia.B6;g5ݘc5eeeI'D#nnuWevi>7gZ,=^pQ,ӟz]vVx(MˎWCoYXIvv6v[͛KyQ~ۮ5,HU nT{F$9d0&G#7o}jq$%ܵ+Cm~ix'i膁ii5 ,J$$׺kG#@3|j&cY3w-&iaEEE?G/<SnɯLF>+r&';^rf=n(.'&'cIe8sRd ڱsvEx f1VIX r' sACDkxGr|UN;[[!dYϾλޚ7o-X9oϟ ?,~$RϟɅ ,ȺꪫRB0n/3FI(h#`0ˏ,YG@k聃xo4EQl$j@ b%SJCGwySrc jAflM$*Wۇjr1Pn&N+5~t84R{~Uj>裏)~qgeJ]4RwS05e˛XQU˖SGIݫe:m*A֭HZ(DW/$65=tZKm2b?⊢t\Ι3ob%&v?mJeg(={t6 FrCuұsA U8-vj@a`fB0m?M\|oK?I!YÜ.+mr^@kq.mm@3OǙLb_s6-XM鍣Y#FnFE@@D(["G}Y@R _|iVS^ݤw^iR0z4/m'?`ʔKp\ג$ EQxiY끽O0v'&LmRFkKuWYmvSh,زykx}Yw䭗M_|{u)@-lTonYi2mڴj;j\ٯgΚň;@RE9drQidOVG]}Ņ$dEegQNg; _W_9g'el}uMmWVM4 Gr2/KgnƵlA"M|}u,&GſꫯDŽG9YPZ¶RiRS99I4##=z$TU7ߢ./NG!˲ ]ǀ[lZ&i`٤놖V˲P~Zrrr\LB KmG29 G#2^JKO:w$eeg[iY'CB,淬Fm~6ߴ%׿z˖- Gw6ø~^eYƜ릢:?㑄F=y]ǦwesLJzvǓ{(¥emifX f1ނ|:tlc:L^xƛe#F??Q՚0aMH˲ϟ_ӆ.M61forr2aJ(JA<=1pBlBj<u`&B~9!jGt~j r0:u0agc{^dYY jq MX {7tLӢظ+K/sBL'| ; „'77I~{D_>/>m?:woN{ml˅k|3fyџ&^9{1:pnKmvt\׬I[6x_펍cuאܽ;f4:ņ^`^[|h\MD.+B2 #ĸaI01F6@[Z0Y}݈HOO-^oJh޲}^B,K6hhFݏ}E‘DyUu3L_,XP($D"PXM۴isо6 B*ywA8DR:.(=/NۃpY?q-N$! FVaQ릖nٲe1p/t~"0[Gv8~{%_/cYD*+)69GdN|EڍIUpx<(;6/\>Ouum Hc,6/5eN:u&ݦLl==GJq,Df_K,i熩d , a *[z?`wۯ7@Nee,>ϞMjj*7Ïfw ؾ'|" wuw6xi#$U +%8Whu,tP,th4B8A5Xti7,UUUGZ(vf#вO9)76AzZ:$aVbB+oHWʊiTUUS[[$ɢ/ahїч~8N1zԠEs&'eWc&xDٟDӉo3ٹ`k׶N cbm(e\Ds,,h~-Ilf N?IUZM Ox^5Oÿy6ZZvnXz_=v6 B۶bWZ[KٷQ⋜?aNŐdbTX֏>b["GS=n~;}.Xd&Qn[OP+w8[F,Fj~*9#Gb"n?Ozf *ZV(S<1YQ#׹#;˹x^ޡ٣III"[&$PdY)LD0MtC<I((C7x絀L5N]O9w߅+%o,N=~hrӣ^Lj;$PRŽs:k˖*Y&__L>ng+%#+ |'߰|~eY`dA맒ڳF$*.) _/ͷc tgF',:Ў It'(x,ͽD._P?͂ tܫ=UU$Ei6_yuJNaaY"Cdea 'mgհKrEoƒ,~6҃`HN]ϽL[EUwEH=.V^w~Ǻ(--CŰA^^zb! :-%&a%G `K6ndyEhtihDj'$wi6Mvn7:_}w9SSyY~uS91cPn@B-Ύf׵(.N?t`?t|5aYNjϞ2 -`mHC@eh4 YLڵd['W@$,_3e@( IPc|rꩧz/i,1pQ][Zp0DYy~YINN&//A\v}HK"ysTٯ<pGڌ _n $Ȓ~. 7 ';}RоԔT@ǩeΝ]Z>,&OLfTd Bl-ªk'pc+S>Bbā0wkLf<;'Dc1c08r*tLM @%aƢ™%~M~·gDFȠe쳐lV^/Kn:$Ei>?& w/?MZ%6n${D@2MjgC%GU y0mՖ.d:SN{キ]R!ɒ%8U'wng,],t PRSR1|87tALYaɷK99V ipЩU;5?e)!ID(i#z(UUF0\8@])//cl۾z=ڵK*YcO>4/V#D(Z*=x!_ҥ |޽#ۚ#W3:|y$:ODvn7z4e_:VRJySg_ iM`6=8e z=-z=3'{wLܱc0$rRɧ0i"ee-\&,~٥8ރbLts[B~Hfub`TUe'TRwO>F~QJJJG=!++~}f),TTF:t(ݻuekݝ%1g 2A\|Ÿ.,l ~oд>lDAe{wҮ}~{|>I y9ēӧ^_CuIt`=.H4FjZI^yurrϷ[ P7mjtD߽; &>O)?ZEjǎK;QtFI ٵ͒nf ?-3g~R:wA  tgJ 'L氡ԭYۢUR⵵|9Vڷ,ϒADq:[F4ڬ@Cv*v~$R{[tlIݶm74;eѻ7?Iݸ%SnւΝ;=BUU;%Xա駟 ǟQ(YFdEAdErh׎ZxuS.?VXЮ[9_|b2˛ktyoEҷ'sɯ/"-#ۃd u$l-H"TUUq{pCn^iia&IIdeg{.XCH 9s邘@x5p_{.'Oő׬Yc;y{_ydp`jZqm| IDAT Y|ߣ55j֯ˤIA;-kߞg;71"f/,ܹY&c@Te;r>O ^SC0|R`!_~IRλ&#@@qa葛'߯;8QRQ F˩~kasU2BM!0xNL;ᄉv&8WXBip瓖AQ{;Qmا!iA/vyy|DQa`dddRG.!#ڋ?ߑ'IҥcdۡB!rYuɒHhlaں:LDQUN79L ϛ@n`aJ%%fIII_ڙ>z=}myATԪe Y9V킱c979jut8Of 5(I|W.)nfV>,Cøqml5$}:yQjn.+WQ'^i}JE2 TI:zKK'lDճYoLj߾؛*_v~1m/9ˆI~4&azviN}a!fIS~y^.k5^A|+˲p8<3x>ƏAyN Hc!5:zӉ%7;KAtua8.(n[u`N p[VV|k /;˴l]i~ietw-61PVdP= ,]ilYQUiɩ|p  hx`oo&Nk_E_P\\ZboYH֮dw}5.2u:$EAQn̙3nݻeZp G O1h{v90/Huegt6KE߿?$ $EFnwc%16VRdI" ڵK"kH4իW`UgTV_P6z~%Κu`) l쳽;sѯwJo-s||K7+=^WN3[!'O"k0֮%ZQeQgԭ[GZ߾2[ tY(։F3G$#IԮ\Ŏg-^ =,;f8Lqq /]Κ())%Rږy>}y9n77'c<_8 8__ݮ]Ծ=&[#a?5>[eKA@lBdw+B]}#Nii?+@& ذa^YY@waNGHIN4 gƈQTš* PPUA%I\AX.Vixҩ3~)')}^)IӨfB9Ѥ9t5ml&JV>>u;mn\Q_O'A`pzh\U~xM۷s!e8C3՗;q|XZIfo.c[ $I1hDjSX|ye,_pN@s'0M{({WvJOSQNLڍٜC$~ӞЭk7WfVKEu{菉+{nňk/@jKEBF\n$#)2+"+x2o׎sf A 7+z?'K  <@_@t0پc;ieD5t֖6L HSJd’l=i%rHOOg嘦P ˍ&??߃hO0|NwۧM՞wSRѿkrfʕ~AL>KB!T"ܺK~_eΣݨQLB\/à3t @sW4 ^k7ssUˆp1޿pϑ>p+nnw@e-8?w] }"zlN~UL>93XW&S=@֐aĢ1(-\Ր%.Ro;BNYEf@V$$E"9%^{q(*e >kiG@۲΀5訁H$"iheKڭpO   B!bF\`@30tCHKf@0 EÅ$7'WJ@7Hu"~tim}t2/pHJnSg?v+Wy>-DDvm96OvޝY\۵_+ljVW7;37$ds6$LMCv{ 69cF7q,df_Y4Rjc5"{tg3O1䑇割P3APd ;u#@ 9_.t*x|L1b8.8o3$6t_~ys8r <M0|ztI<DF#c1b(ZC ´,{`nBi =F )9T=l$INJ9p 6l_EQq9]Ȳ_."// M5 Mu Mqg0"eaM5S'IvIMdYFYa=cnjoTWH/k>@BNΝħI?Kͻh ˜+'ǯΦ﵄8l#۶5zM -¥e,-t︃C^s0p$'Qp dJbX`˲|>uHwVVU4IڕgQfm -5+V㽙8RI[A`m)}9AxuD__@˦4K 4:;WZ*ŋ/= `ܸRw &b~YUU^~evb(j  vqoMLDkE@0Fޭi0,BXt| TϸaI EAE& 1uIE_VQQWQOS u!Uq ;d-0"+%J%x<MtbZʺ'5:ρ}<{Wjj^tk_~U htSSLMÓDqJޕ̼c"k@zCFq2MIQG1'fj_Cw3ye-& $IRO>Ͻ? ĈYy6naC m;k܉7.1*uL3b1]z),z+F쀺Bi,%I 'eQ^^$Iu ).'V%~p,Ka@b2X죱A 2 $ ]PU#;+K@.X ޲Fdò,{@1M 0I" ňFFDDQ‘hӮ.JPHnm "DQ 4_8t8@U% BbQ`C ~!TTW  G„!"ш@@,'@hi>-auu 3c_'3CmL%v7Wj2 \Mno tW/vΔ{h4YCܳ!R??ʒGpNf8db_7 fbIvS9 />@@c9tCh- n51-Q~4.@@H$B$D"bn`x` @\ljkq3uLlp8;Ke P mVիV>/q-$v`Dt=z=`H*F"*FGC dge%b"`l+NMk맢jYo>6N'ߵ`wF%m-c[z(ҿ?M_v;tJr-[L!3ۿ/nQfI峪oK/gCGZ5r ~o?&oNli˗6\xUtr>Њ ++* V`t:tx4FaKhh4B4&F rUUU-qtMCt0)68n;tDcж4# TkRоp4_O (HF @ `gAuA`h4J$"` v뺛R`4! RTTk:3w7zAt^//[F)SGj]M"-#:|>{t>%R;uebcf&QpIL__viBnY뵢\3ey}; ֖#{a_"}@H3%T669}{ j(b%R "abvňE/ED1GatMGu+45{q4M#QWWG;{ܻ$IbqVهh[6 /[VUhT08``:B@((~59PP(D8Qz)"2qBEEEo7bN$a"3ldqr4qBX0z4CPJG oeYnƷC8C+ ' F(̚KPw, =3'6aYY`Z|X*~뛳x(µu"U;>V,ښ"ڏEĢ1"Äa"0c4hX"[#tXDQEa v8s)NB!</ 6`Y.H iPZVF4m_ϖW[]MuM5vZʲLm] sg~nF? ك]^\@!h&>߁8^~pp$3lZ;op[I'}1hy$fiX))3jV!O_\-_xnxi8[3kZ Xpf3޿6ѿX׿5^Zp2 ֩sǤvy ŋ)ڲvMHHZraڿeZΎji ۧ7(bٰy3{!E_-]E!-9WkgqJF  55 4b TWza4)/+ŋ))-"oΝ;qݸc`Y`-[pI'o=QZZ[o]5{9GŰ?|P/]]')?A\#Zu_~(~&7,e+;ozBh #nj'+. oVF ..f֒1?b `iܬaC)4xƍx=r _v8ٸW\|߶a~iXaI)? ²{UkVnZ-_NYY,q4-#0%%%tك^zP[[Mn^.HU$q7G@O x\^RSپc$QQY)X6fdeeaYX Á#))<.' S__zک *I5|8kj:{7HV~ HQuA~b>"I(+zjﯯi P8|v&_碋DRzt˅ r7אA_3gx<$-[l΂?q9%m;~2"9s`z_}ա$X]>0﹇py>w+YbES]'[~wI&6-Y41F,Ixb-JKK)//[^'0 ټm]r1B1p玝ޟU `ՇqcM,KiHחKa&4QPP h,8NN'm 4<,XH8Lyy9\s5$7  i&W^4 CL+C4*38AfX_h<*-(.'{m~v =^,*X=h:~:J7%T~ -'K]BʢIĪ#ccLI9$YQ"a}!xkWѣG>s֮]˺uYnC-4mR8q6&sY,z_|A$tg5Iba=, jE($_]}=^UUkC4K7mvP_^DX IDATRUq$cFû+8: ᰝ41MeNSwX$CIIO/EP*GUU[(<1uս?L@p˂OOP}믟J=)Gn(=+.a("a&z-_7^;łEi^Sbi1? >;wg4hQb%[Hfkİ[niv{p8YŴ5]ov_(y6[ߞji23EIKtrtfN>e:w njaݺuۣGˏnSXPWWSu5膖y99r#N~:a0|t]'c&.+Pmn7,c)2^z)7Vd%*#+;ZG|Pf@0|no 2aryYj/.+PU1*899?+;=O&QTGk'ZJ6u5kג`}3ZT-3ߧjcUou߃X̌P\nFmc^y=09_@DsTu$?{On .`֭r-{&??HO X~}]wX={@%lgyyyܲup8 Q TÆ^me%Bƥۃ6$KN(`޼M7\jZĀc)KtcyW^m!j"i3,YGFG.ϼ@iɝ;3CII6DzПOhcIS\.j7ldƸ }w„ ,]7x;6Èzykm۷oߕX x,,?x.%=^D"a‘ EEEsϾp[]]iYf/#-˲<e7+WfY4<,^$#IDc!+[oOaT4X,Kbuh&TTV9EON'RQxsrtuǴ6u;n,'^\-1upa1o.Q想"PTvܙs2dIuMm!& Bym6o"bhHitrn× Mk E<*];01~6|9sݟ߽cZBʂ;Xq}޿Sny5e=A@H;~uRD41 n(8' 4z=Jd7u(ItZ[MÖ[qz>ѣG_Ϝ9qƕg3TWKQ@ӂ nH$}vrrr>8uc\ V'OnѿKԩUV 8] SW@zzNvJ$OKYVnUeh^N9KM^ /iYDzaË xHL޴zWz V`Ճ9lS7lVu(-[` S#Ѐ 8{}(D޽i3m{M4F 9)~O*dʕ|͗}sa۶{o\IZe05VTTTLxxZEQDZj14iQ 0,66ӧO_7@7z 322OoQFf͚ .:H&B?W_WX_D=CWEdSDO>JEGcZvLTk+Wd.kxҧX9~c:od)?cO {%tAA7ךL3J iy`gԪU\TW)/h4gb`_e %˴nZ[l]v^믿~زeK!22R(ғ(Bӕz92jn>jWqX,܉%-xA|L׎ݻPIϏ<ߟ~z@Ö͎7>5'W=/]@mo?QǜΒ!C>MLL$==*2C޹&Bшd*=7I  mժu pCbt4ijѢkEO{ɲquLQe{~^55<%=TCk28n]N͛YtkRS|2' el~֝w*󸐐.]?9cǎqao4E׫W/waرcMUrYf_~:+]}v]{U*!V>ZURV-!1i>Aji_em}[ *1e*VQapzÆ 9]kf&K/r\VKΉԷ[Oiѣ9{,U ֭[yS%r- B S'xoѢ hyСs $+lٲ֬Y3v???ϕ޳EdIp8زe (Z>0P"yޙ3d>LoW]U|;ONmeҶm/`$iSd]FCFJ k_M4{~NxcFp "[$1f 'Q_uZU*5=?^jԫW 0~x4?/m Ik֬)xdo{Q 7n,={(#G6Vcǎ111=Y1l6GfX}-./@EΜ9_^FU,/mȸ8?7m|$T>JtxpRMPuwRm=nm&lٲWBCCFѭKVh4v!:t8Z0x,A)kVKȪ- 6W(h8h O?)*L]h87x^|B>b/iD[^ nKATqHT.AvHlѸqc[ȱozvy rZիӾ}{8 \=_=+ŒF#Y(v;wߕX^ʿ >ݸq5kF_ۿbYbiiiq\/h2ثdv;Z5}jy(h:1={}֌Gs.$'^wk jX3vW=@^^:??;%/`EzvUJ"Z??N]˲F}Oc|MΝ[Zgrɓ'w^o<-lfǏoVN%@k ѤIٳgQFFrrk}]&bjjPzf w+s]]~q! [N>§U$N'>EmH !} oʂlόrji0Y.m= ▙3ddٓg僣9DkCp0%/xTUz$<ˑ%K|ǢEW=欬,BBBhq^vԨQ <7rBW{aÆ^U+(/?? f!IRji^5 vwܙAwe(S?ZkVG۷SiSkT*)UdЛn"Gp->Xٲ9o\H5iR PW,/"[?L ݎtu-ؿKV+߅ Ă\QhL]+ …|'zW_?mĉ#VZW/\l(RfM֭[d2=].\'.^_ϏR㯿_~yzꆀ"1 ʲ˗/'%%w H85$PvoȖ2d(^=7\n I7nFN>M߿0uɵK4/4 !!p( j?{ PDhl6~{!x1NӇ3gC]c/:3Q\ryСK.uw,NW~,Ȳ$IT^#FD >*PʿKJJUn]Zfxn0dYncZIKKS/^Lvv\t_ L‡EH;E#9 q;0;o.>;s361͈rOV'@-GAI+"*kge|D8/S>3Μ9mJrG޿xb~(]aºi04h͛7ӷoU%;;[~hZF A(pS܋y1$|ٹsvEQ^C@} \Hg+d蝜ٲPU)PFV"Zd t<̽.ӧғ{ݿn[_Z7^Wu34rNfŨQlxY!_v˕'Okӕ| [vm͛eR$0p бcG tСC=Cի@XIIISo#"" XoDay3V+l2%99y-u{}{OYy~arOAW(ӊ-0i<.{N)WqXn'ݱ#߂Oȹ={Rfς *QrH$ϝw ̦GÙ;w.g&00?OFF]+m:HIIYO?q9wB7ͮ@LL Æ K:thk$+/PQs̙wQtzZ\fx&feeqY?XB0͓1\]wY&lu`֑#̟5;q*FN[V/,EP&>ҕeNʕ%~gGTuqYE_!ԩizME̟OH{>!I$Cp0S\uԽ^Oe?0;Z&e<唌ķ;zv`d2HsmqFqNGll,ƨǏ/`ݍ111yyz>v Wo!WBnwo6 LZZ/;wݛvV=_111|t~t$.]eF)M+45k,gϞb/PT xL.$}v IUǵ&MZ]@nSxmf3'Nɓ,YDٻw& U'i&"*qO2Y=Ej@'tOֿb/?മkuNT||XT\b`/>'f͂-7Ee /A-7D߿üy+Vϔz.ިQ# `0ԩS⑪<ϑ߸qンgϞ06VNp] wurO… =zeɒ%B~~4x2Y/P;oeJ?s$[c j @<8'Oidd)}@ w)."OzݯfN4cuY<`@!2Md̝KX&Tk{ 8/D/NfӋ/b/{Pn}w-..0l0s;*fs޽{o5LJPPP@BaV8t:?q#z^)ZzZZvʕc/_qoKNԭDN^.r ZF]ӧ9~8;vw:s)R?.X!Ey@ x W/ǠQh|M=ZAUŀ&?+S;QR@ j,5wxu%;37jYHDNS{fg@SncͣbL\\3rHڷoMSO=[oymOZthʻ q^rm͚7[jA6MAr\Z ׯd*1Stn'0 :u fw|>협: xҥK}G>vvVىfsyZ 3 077Cqq~7ܹsQS\dDa]w KF|Z`i C%.O$11쩺h/K^ p!t}uK=ŦɓI[5iKp 8/CY(wDasHAn6u4-^HzAHH$!nQFs/))xf6 erz N IƮBD;yybYӂ \UڈwyТE / j IDATWڥZ4mJdDVhDbXb,us999]"}4xKӡXf+Νch󤤤^Z^+8l޲,, (+ E"$j@G_FwD /l*w1[wrO.qck3OK:vߛRS[WdQr?7Ȱuk "CBo`lz%~FCvhٲeEVZW˯Z_0r uz =99dggs!ҩc-[zAkOt/ 8PرPVO4}{  ~~tzf3| v!w aӦM@Bk> ++붴{]n8.fAFGvv6e9y$IIIl޼Y^~,rjUÇ `h~~WjԨa @###9ԼO5bI/㧃.9!e{$53֭W\ $"Z䟅 Kߝ8d Q m9NE&g[&+FB힙d"t#eEbnMSh=n-ƌ^~(d;VlHHv8:zءC9dC Vsh 4M㟣`X8tGarZZ^Tz.m 6 s6w yfK-GRaaB~~fقٜlZʶ~){F1@F O`4 rU!g?/u߀5@hFsn20hRL(rͥv94r/h S9 RSY3≇{v`m7sB:e4E?{2{lRSSt.]3fU=OB6m8c2 &{oO`ё#{R^ 胂l:'k25kKZ,\%KpwӿzʧNUV\!h-I) hlNKc>}g ;_ƍiժ͚5ztu233 ##L7`_uK_{`U$Wc7N:8p@Xply_No߾b>}hڨ|,*/ٟ;ޱ5Qo guVASw=j|?ο;wv*>? """Y&T"IAAAldlOQ#6j !b^VQoΟ^^ܴʕXcF?E_U6Xebɸ@>e{?\VhH:FزJߝ;KMNj^G_D=,[=6V-|ð`ʪJQu:Gǒuطv={d֬Yԭ[} #G[os=om+6dYV"I I$֭Qd1+)))$'' KQFrKO RlDGGMlݺT h4RNBCCP? mŊwVe Tۼy#Go/*@AQ`>{{ZmVRR& ຀.eeI9"T|֭[WעE P%V%,,L w*un H AigI9 .v; ?˱DM"l{ϟOP:7!u:C"c#ZQW/ߎj;|c ᶯ꽉5%}_f}}R5j`ƌ̛7LSË \Iٴi}]?bwկ*v_(eGx8szc߷VV}-XZ5Mq<ԫW:pwѣ t $={vɾe55!U! 7jժV{rdž \Tś-IF[+EFF';kڴiN`0^O!9T ǩJ(=BrQ0$tGO_(/5?ƍcŽq0Q(eᓬVhΝië5ۨۧO+^c0pn_d1|P>Ĩ6QQ%7^;FsA~fϘB0`fbDEEUi( &L(^=N}7 cx@cô[ݪ.-zde4@dN[@+R!F!::8q6]Kh.-'[dj׮}> EQxo紳fWTƠv:f`ㆍ$tX5s-&**JӣGvSRRV700]#=`8VD1rqPZ ge'FEF3s=#""qqq"Y1A Z  Elb1%?6<) pt2{&wDU z[l{}Dsd;=+ Zo1$Պp״peCtCƢv 1y'tzk%PϙMY;aJs=5 AjlٲkY222xŢ Q~~MsMGtl|{7/؁9GF/7yzP>vf-a2] H\/λѢE N<ٳgόwΝ;D]!!! :Ocs)~P@$I,$"p5ɲJVA4W^թSؾ}{VZӊ`X8]+!8'p,WwJrWo׀aeC|Ϙ￧SkPAosFTZ??5i.J`FGJ^M ] <ja,4"O ::_~QFoY;b֬ vo}^\Io᭽{ofnEvgF!77omҨQ#Sƍg/o uU&B<EVÇWdzXE=73)@ z n֬ժU+ &YU@8@z(\||JX9z3l6( URq!a"K[uZ]3gV5jkp-,kF.'%cҥ$&&bw4hZjfjddd0i$xǸpiܘ3i* [hMS "<u9_w0 {Ϯn ̈́дiS:tC\ Dp dEv%|@ *31@H0ԩSkY4]ɲfU T3.Dk }#/al0@˯-ZEspP֒G9,Q_#Qeߒ}kG=p1qlJweh4tޝnM69o0bN>|1cƌ3oOƽYDEhXy4'a"65CZhAxxڅЋ˿0tXݎNsq9=x3ǫpzeﶹI͐R|һ'0Wîi}CLڴ Dy)%9:yy Q$ڵkǩSN<9iwZeDQT$?{EF$2j\~^~D b VXƷlٲzÆ SN@q=]AG "rpg V}gQs|`RSY#:^tzryd3܃ᖏ>,5ĢH2qI֩CG^=(L&2nŞ?I49sФIf3 н{wOxx8nD{2|w@Eˮ]߿?111D@Ѽ@uAU ilpn?Dܹx(Ձw`P.ya"Ѧ`0@aaÆ4mڴ[HHH4H, $YwzeE&;;\J[UEѸ?Vt_.мyc(ԅ(]/_ P祈(|IR=Ժ/H۶E}xp>$n'^Ow4vרi<|8Nͮ]h!>))~,MjY?9~OckժiРAMW/@Ͽ˦M8<*'\+V`Æ $&&ҭ[tw]z5O>$7<X_ZG>@&Z-?;-[z0jH} XԩS5IIIIQy.9%4$4BTE/ r5JJP%/;'@[{P8&\~n az$j 4 R-uN}PWE8rg~׮[V kqqX22(EgRY&aC0 (ս;^?EA$g?rH̙+Xt: Č3HLLDy}>Z-f^x5k5jԠw WC=1uqvJ a}QiC^EױcǺ?/DOll,mڴ Gf\5p8w+|9Eʾ* IuNVVV$w `I$mܸq` Sx8U͊$K贺Y(ǁ(gpSfV^.]-Ӧo?ҶnUkTm6jܽĿ^c.OYFh3~<LFtΟ_*eƚX:Nϗy\ 7oɟZX;vߟ}.]9l&,SD)iKhŁ\nGqX,-խy 1IYIK/KUD\\e̓h۶-SN-6?@ׯ_?ҢE ڷoϚ5koH```{z:w,YBy󘕜L3<=\us}.8 vԨQHcWwHw[Cv gŇTffR؝S ,>净FLV!""L]^.|Y 3Oʼn* D .QGF=OK/Ă hڴO?lϧ!Cx#IGP˯X>g_^ ^yyy3kDGGȾ}\>{ cKb"ks963Xy ϧE,9qF@*0l| @RRG_u^$"##1LA˨"|Y M& I@,<ǯĵ,!Gu1 b8@.Kى#| `LDDD0l呛6`h4ŒI(ץ]7WeZ{kXtJ3&6k60F]"E,7oWW_%#섂e@rM0])1sLVkս;%wo jYl|9rN.Z__ߟ|_oS?/]t!//^eZnMXX%sHH?7|3bвeQC2--iӦ1k,, :h jR_y"?tglsCZ!`W{up,뻢(DDD,>y`O2ex-?CmS;$ߍ(>}^vsvN(H +2b`` RV-\_I!h%K<)F[эl8]ҴMvy ,5*"ϟM6ZYf_Ȓ%]֏=F=^\+Q;vX3ql9%ZSֱg Gk|.lMr=՚60^yii,N.b[ngAՒ_fo,4nܘ^*}u2q"ݻw3e P' :uѪMAľbi4XvHIᅭ[t]ݕU6h4OX=⮻vڜ9sݻw_۳g8z6pЈdrQxzpMW,iYYB [. ׹voVVɄ.]}U}oQdMrQ;$Gq)qYdԨQ$&&2mڴR$w8wt~u5uSuI":!Op~ߥťK .Ǯih[n_~E}Y[:u]v(V?o[l Z5kGuU*%3?gƮ]X$ x5V%PcI_QFXd-/k@1./q`` :ucǎȲLRRׯs fP*`zEAH p8|/Ȯd6e7x}+p̣4KKc1Dw@WPXjώÁzg;4tVSUÇX3v4qtQٺu+'.. E!**nB̙3y9uJҫfMԉժ( tfΝ|z`&<(p, 04'xuRyI.mZ^:nc ۶m[ ~g38$v0t^(YYYTmAСÝ#''HId>g\@Z$ Rn.+ѕPV-.\?[oBeԭ[WosO?FIp :~'Z_|NP:~IbkW> GDEEu:V 6Lv/ +6FY||MLn;i2J'zm<ՁI6-##.cZdV(؁7nE1u 3A&Mhذ!Mnݺl6"I7Y.ֿ}NN,el6r(Bz_>6h@z1&͆(jWBQQYĶg!!!=ܺ ѣVbĈ%m$a^Z:/% CP]g`/?t ! 0dJڶ-W5w~?'/-[dС%t:233Yb֭#//@M,Ѷmr;C1n8wҮ1cG" SNMuB̟ϏGX%UPkQ)^VO[7_.JZ˚]UclDGGӷo_QP,nJ`p`wرKCh><N 8)pUsbtqR,~OYؓPxlNZo)n8P\@%hȑ#*|A$|ƍLj#6m۶m+[jeK/25ڵE;EQPBcc\HNf߬/󎏢N{fKz'$!4 A,PPTvֳC?Q<=Oyz 4 6@J(!t B %d7Y6f7z+/%;|y>e?H=Hr(  V,|ēl93vԉ_|~Xw_/V;vk.tBnݰ;wB$;3fP^ߟ 8"oK刚8*4VE-W~nJԲ|Y@WouW]u~lfحU Y}_$HLJD22"" dK?S{쉏rBуv>_f > W_1%g!x#qZQqsVVC=abFAp\DGG3qDx(/K|3r$/L^ *9I؟p (LrN |mJ\ɡX]‘m8$6vO+b׈4D- /PwX?Xtf4Ȳ$Ij $,^SppV|]wa$,$++3f駟2qĈ4;}ώy{(>w-૭MZsŊ Z@^dIB4ݎTSwFQ/==++_~͛kۧ̚ҬY3FuXjXV<?_=-[+~L^*,>1łKx~bZjI܂O;MA7jˀއ2@.1I{OQ[jn3ݗu?#v}(&F,%::I>Az|$@&v1 ,4PSSc֌3)ZO?ԽSKtc^?:\r >swMt@3XHEEE1zh TV`v䐝ʕ+ٴi,{v]v1n8 1b-Z6{۽{7o>z/gA%|y3?U|}^o{Wj^*kC PL4n1= h7*]~v `Q,' EMxe:8 _ۣ @pÌ 0 P.I" blmpPIG||`+FHHH'tF &u /%KPYYi*Tx֬Y,Xk>s3gvpԸ1v⹢"~ޣlRQ ?i?C4& \`LN*UG4LSp`oW;qqA*Wn(H!H+PhԾaf(  oEyssJ4nڷo5\溺 NyyjZ=lLЧOk>#>3:scp#Usmܳc8 HLLhށy :J͛n2vŘ1c())tޜm̠/`ƍjk4:\ciz )]M]oV¾hmssl]g/5bBF-bI`H OZ t*TTVֱ8 cbp݆P>: h#U "!b_ t2EBStԧwy'qqqN[V~Wb[oZv-[l!??;EQp:p 6qEd+P4n>'s"ca^kNDOMHH矧F$|>2228p ^x!3gdHTfJJJ47kWˣ}JSV\̄b]jx.j{Miz T}pjp{~C!:){_Vo@__L(q(rQq\N9:m({>߱'L[בW 3f'݈!7׋( >IZU6 $uMיgI~NH#GX,HĂ X~=gy&͛77xfQ;v,֭_drw7B}+Ķn}†nC,|i_s:NdYv7{$rߘZ=\&OLqq1.UVex0/{"fS4fEjd+Vոe4۝jG{ZvnG{#Zo-kN]7 7%vfY~p ubcc# PUUصjLtTT `Dᘉ72GZ.61#I4TBPEN`(`>4OƟ2qO/_fQUU_Mv((( >>ސjڷog}ٳy#.[ƔzӍ} M  ʒ>蹩tڵFBnλkժsX|9xgOMbKżfOOUs3T50esRD^״D|]Dz[beY&...6d@Ł Nv.k_+jnfiV f(_xmSLEI0tFu5]W_}5'(E]D6mꥅm6L>+W^!F<;N?|fϞ [g"6VY[n־ӧ1ٳܹ3}aۦ n\57ngme%=|[ke5@ZDw̽=w*jig3|Xm:W B?Wp , qqq8cם \VtC3jkkZ!k5}?3* '*EA5ke4 L@6\-[dȑ3("&&&ryQ^^Ί+ A`ݺulݺ^zѱcGDQ4Dp=0bƍҥK6^/zIrWiѻZ7%"΂'dGܤ$.r.\>+BLL s'Ns=S'ݛ-Z4~JG`NY5wvxO2gP~5<[k jrIšC7B ?o `O8!IR@3-s3nt8JOVdW d IDAT F +ǫ2>VQ! I^/p=e4Z2PO뮻HHH/H>̛Ge cN֭ٲe WVK,&bh"6nH߾}|o|rƎcNf]3vsJJD~gš߮_~ADEӧ$_ӦMKrrrXf\(sp"S},:R^ {Q@/d νB9;g5OÇv^[+p63 F߅@"#u2V;cx?&66CTT!]c `ts4MW4i`|B(///F~JOKlvtF{n摛K(..f˖-a;233ݻ7 X/ 2m4>s~lw~=~ ~ߍHPZ<8fs[lObb?sl8pYfM^:nۻwoxꩧ:u*ͣcz}5 ܻhhBҲQ}ہ37jՊn^x!G*5\E1NEA+Iaifn00 ߃M10;<ڿEQ2r]`?fQUUElla75T+t 2^I3HZLy&hC9pcX",Ct !%{.Gn<,v ܹ3+VF,++.]н{w?H4<.W^y%^z)o&3#X"/nV͚?lۗݻSuVoN^^999X,,8N.b.\ tNJ|F檙 Ĥyt|ھp j64=[Pݾ~~ni_hh}_&-\x8NT;ƄDoP{wp{; DF@P&T:vծ]rpԺk >gX׉. `D`Zot`瀂va<m=t :N:EQv6 6ϚGֻo?+^ERR "GH}ڵkٶm_89,p%1cpuK/&@]8x6'Jrv6sfu|]?sǣ>ʑ#GXjk~^E7RPP@zz=ht|L>m۶!n͸~ߦMhj^YWV _N P Fo/,6H ޽{vL@q8Du⫗xߺP=G: T=Q5^C<"&&Vٺ)FR`7!6Q'p<.T&<"¸$IRdNlQ(n ~q4;Yfmh}QâdYF֐> Ƨ + ?y&C=!?9Nח{nS8[qP};χ +( } cC]۰zߵkW(..fͦY(~}ܹsi׮:yq:3c > >'|%* ̿*JVGA1fV+bGVV+WdΝ6***9s&Mvg}ܹse$z޽4cR\Qxi;P>kAb^Ղq]KϴwrFQdEۓ9jƳ?|OE|f{sP%2'b D0 '''EO$9)@$?C13Ш$|b7Q:,xHMhv (d~q;w[1**I>ÙZD芃~ lU;H5Mމ#"˲CQQ{Wk. PZFW\+O?UXX־>gO)d+,ZT0kرc),,r[1`***X|9y^, oDGGxbhsԹʰrV~*+EXkx zZ1/Uw`xP{ǕZ@ `POAk6cDY~Lύ]bHpOVV?qG]F@f?و&]`b jT:|QkI*t zȴ45͓&Y'X.JノcZA yz>kx㍈l,]sϣ덣(xq\t= ECeV~$cբE z)tN ЩS'ڵkY~}{d͚5~ zd P(L()˩ 5Ni Hg>j_ @dzqlӂ{N5󯳧cW>ÖPȌd^ߊe'Ъ1(`xJ5md5BBQ(Xnv\weW]y2'7t{-jڴ@ql^'+V NH8۷ !Џ}nbժUC[V9¼yh۶-}!))\. ĠAx$Ĩ.Y,%-!+ M:E *;jE@ jAc,Zrp=U1 !I滄cf4 6L(b"UƠ*C[ho8|1 5,KDEEcFQfI`gTo" @ ~;))) bQD﫠Pٵ;+Ot~c͗QݶdD/Nԁä}=}AԡȶXj2ҐmV0u}@~ҥ K.e!ba׮]ٳ\uf7? >W_}%K}l|n7 5[^?Z Z, f4%*Û7'ٿ8u҅xFFoΔ)S;w V^.,ޮ]b91>}..\ȔmxF90:~j\r TNE·|38N- {EQ@IȲTeJhPeY&&&&" A)))uz絃cXp8dji {fFnIK]Z7G{QXxSk.ծ]; xOݼ> E`A/~u3̙O?'i 1!ghǎG ;pG~8ӔߪEuF T>+0uYN(+u`Fû{(wW3!Y>"A@UeG(f͚}z\GG:* LVll?Rjhm).܆P%;wI5myyX¨I`3##m۲~zV^]oalڴL\.]veʔ)L6I&QA͛Y6%}Νiדвwob[R]|(>łm6$j+u1;c8"cFy\t4iߪwH۶5?3nlfcގ<|9ei_G@uQ>o",dTG3+pU]fl4ĭofpKcccc# -NDT_UUUu<;uEQ7 MĨxAYZ-F4'fz}B =#p0N$x$DEwIMAIɫg(Iw6[Wz:zsu˗m۶Ӈcv+2dof͊ݴÛ6y:}Ϟ-!L32m6DzyNj++_,la3f Æ 3S*7hM::$$pfVc_#:Xƍ[jt 4 Qm:k?wFu)ԲƐP}*NVJvidPw4A ] ETՓ5Zfu/BՑ* f'.99N+Ç F1'0urP-A0Z)Rl<'ٵk] DzjAF^͞ #냏T1Gv6$i^T͡*Mw;)dX0~YZuYt֍%KPQQQݻww^rrrٳ'6͐"|XV{1F#>㨢| 9W_}F s#39}!׍e8=>8ٜ{sռfm'p}w4p@稭|]h>||sԨ_ XV۬h[(f>@excSM+!!/ \%\'%%_]vqx^XJϧO t# `:TtM4o޼Qƴ+Wp8o駟x<`+zdDes\i6-Ȟ8 @7&5g'YR~+wA]2d$***1c7oXmڴwaر4o 6 j JJJ?ArB s>>2 p])v){=ApK ;رcGDO1j YdVZq 74z/6lt"߅oڴi3:GRsgf[L/>bX,D(ObcXĔuږ-Ra.IHOOgٳ^nXp,^ӧ~Bf:|yXMỎH~5j/f…pWyy9cƌAzi+WqyLݶs hiZSSýB܇2Ex-T{i RPm}\>fG ^UWx+'@P6 P¾ɂAC@u\g ՍU0p,$$$t:#rf ̆?!JYH ѫS[\ČzcS~dnk * "k׮?gΝX,:y'K>z˅Y χ>)K EGrjZMHTϓFrz+mnݺqWӾ}zA޶:w\Νf^/#Gd̙ >3v_B8fcme%͙CI&is~z٨3OըHQ.p@'p M@ hP%\#pԗ~ŝp~A?_A{~-r*,1j1`<_bKHESh^Ȋ+L_WE|>?3gСCGET/tq{oCYC9ԫ_l ~\Hᬑ]QuaZ9sKIMM YӻWv̙3Yt%0cl6G櫯7ߤW^$&&pW^z뭜}@<8Zjg"wuN7v3 |I.;ecdF̃ Ə{2/1u*Sm괹Z|bxMGU+h :ԎMH8W{ڟX8V-h(J^hŋjrgFF1zl`?,y T@QgNJ"6v\-o:]nfqC~ڑO ȀvȊҝЂYid,ʤI̤u Y#G0{l233),,O'IG6p1{bvrGWi<)X[@tGHJJ.~cҥ6l`ՋΝ;.op8(**b…,Z(l!d"333< .۳i&V\r|br?ҺukAٷov1<8 ;PٻD5gΘ<ÉEJ$oKE8D]}VSDePߝ܎ڢXEY4`0~Ho^ӉbS#Ս)dYA2 &tUVo;]tSNsA{Gy~ՆGyd2deee,[j{BII 6lL|X,$nÛJƌxk lzb"dd9Q}@=eɒ%ر^[a?@֭),,$999ǂAvtMjz< EbPPP@nn.˖-c޽!?(cwNNN6#dgǏuIoGjR,ޞMڿBT?Guobm@O jͣ@Ze^3 EԲaV7.e Z4 * =*nL:s\af k3(5:3׺eSjtN߾}9t+W4,_l*z,—ƍYbE(krYgr mV׮VUEǏ?awOׇ4QG:֍Á>aprA.\Heee{e֬YdeeѻwoVkzєZ6h0DgSTT|\RzE۶jX/G'j ekTA=Vg3a` @=.ucSF(b`` |>.W-  kjj=F_$tYw2Ҋkq rƌu,5M|?]ͺG__|@cujo׾%!!ԫC͛7_zɲL֭+Ǣ b5駟/ywh&ߏr<5n:z$(Pr9Zɨ>ݵx P0hߍ*o$ pO'8 @1)BfgM56D`uScS[3@tQGhFCC4 u݊G>l2GהW^ݻUZeRyH>$U1- G,Zf"ή]2e yyyonT$EDiW6<^ u"s²M۶mС+Wdڵ!3p=^l7no߾HΝ;ӡCٲeKH1je̝;hx cw 15fԷQ'j[,Au[vכP;4 PPWF1nW];t`S(F"M1WR,F>(TWWPHՅF[ n"???A.//;ºR뺠Ā ]:x^8&3}=G\\_|1C 1 :ի:u*eee~AM3yj%z_ #xEoƮ.E|G 9Gt{#K^1b(p83gM(f/-[UYYܹsOvz5kuͩ*Q Q{Q=\/qtq'Ma~Emh_F&>I^j,A ,fF Qld&P_FW=bry#l0CR*|F -*glD-ڵksccc8p [ۓQ͛a(vM|G3Zso4+=>6mp5пxP4c̚5#GvIk6iӒˑH~/&O-w\fK^̥^JBBBHGݻd 8xr9s&$I1wv㽹(Чw'2ڤ!Gܟ*kS4z?թof{TSB`m@!1>E JR/lC3 (A@k DY_( 0jWp07BUUURET4 lݫ,+l.P+(/e8zdU3TJ6sՠ S8''ne EQ/_~hM{w/&@Zh7e1{6~,#8n/B F@RRÇ笳ΪW b7mĴiزe)9@ --CҧODQD$f͚a3NX^Fs>E6Ψjl-q'[~[@Ml)%IR`2f(ST]`Ń?4;W*`~@ ؃p8"2 c蹁'5x&#G*$K 1>qfT&@Ǜe,(y3py;CG-N0|$ub~>E_~\RSSfΝL2UVIjKJrǟY7Tos8dork8^GEտ]EdԢ8V[Kff&#G|>.]ʌ38%UW]ŷ~[/⑇XM &݀@WT3)DFͣPKF_wځ!{K$EQ\LWW_;_=9R .P*O/  +ԯ/Ddd/:12ЗF@b蛪x@f7mN(bD7QѺT.stICz hW{F+\5"^r%w^~GjkkBv;%%%lܸ~Ѯ];J=QOt]&LZs}wi 6{YP(l#qeen8>{TX,vˣK.ܹ3$ cXp8̛74 HHH(8 ge߾}\wE?D]$&reL=(QZn1y |u.q L JR-qͭu@=^C ` RpK-UUU1 УB ,hV@1h*1&]8 * 54<7^˗ò5vͻ f6b}-y=7$ѢE FIaam)?ٳܳ`Y7l!y O xuV,Xd }B'_@Lq\ve4k֬(gfΜIQQq 9;l2mgcj4muhN ؇jwUIMSO>@&)x %k4'x4@HAQu=Qpdt Dg/صGx׹nٿn&DEEsNMʕ+cX(x^ MԞ[VYEla<}qd~DZn7ڵcĈ;B16ٿIL8?'#)U@o N`Ю[j@;r54_upK/tɧi=+m3U2 2z| ,iD(T` Bu([R  E&T)!OnsCKQ|2 A*(&|j12s˹`n2J}C|$gQŃ/g!"00Wppf1tPǜ9s#vΙYKJJزe tAGxRSY4[>KD;3#1X^n<8;* ł"ZxjQuFneY&//\ؾ}{H&"N4 ?!@r͚5?X 1F0= Uj#xUl 7mutF4"|p7UEFPDUY JMWmKHthkIT?lKR'n/poG^6z뭔pBM/a7Ժٓ={0|8{ d>Nu (;Qɘ9v_›ڧWAB""k׮,Y$d;ٳ\zRkǎ<3ج"_}(=3N\ {z;T  o!,AU7d95a,j{ANCճ*8V0nw-Q(dEA9)uY` <W4ǣZjy\@zZZ,#F,Ȉ:RƜ03:ѫ1JwÍÎ${F7?]v,2ZAn*a+IRX:3믿C瓐jR,"5moHڸyTݏ]W\L=cm͑bc9ҾOUԴjEpll gf{,a(uD.r~7-[lܸ[ҧOT<OllhCk!a"ѧRiSu1cNRy>zΏC[Gөbʷ1:toRS?Eݡw 6+LoQbP\\)--EcJ$1 zSITgf`E)gps/B%#lt~]YFQ@D&x<36lXXbt2gϟOmmmĥ{S?>%˸xK̙,n)EutnisZN ݠT ਻s4j.k:yT@ZF*-Z%fO4We "u3PS`]}cjkkydC$%E&>zX@>,j7 tz?A^Oq;wwR[WW; :U@ۦ/<"Dγ:́ 8 .^owft፿#F” |wFZիW3zh?<iy7HCǶ4iJő3DE.Iۍ6 ZJծ]TKRɦMرcj dz=y!դh[#Y. 4y"ʬ?_($l&:uF3Pe֤ڀ@fb)t:tޝG}.9{,k֬ŋɉي+ؾ}sgm4륙|SF5>?!Z> CS)xQ>HIH-v/#7r##3ȭhPfXݯ@@KZ&5:n4aWS;xzzcѥKtǕ+Wظq#YtD gۍ h:lUn}/p=X"zE6mDq͛v8_:",\HzeuU$?K.E0vX8KII>pv/b2z:nK_a\.G`h$(8FLP)+w-a!!UP ߯f(JRwPSTdΰ4:lWp4dA ` iqMdFD )"ZŶ@TwwzE֭Y~= 2A@Pǘ1ch׮?<..[$Р jotk{nn9Kƙ<-Meݶ*hPq:JE=v{!77d3g|2M4!**d+[ȎDT(=}?*4}{>g7 ^|Ev@@LL 5kȑ#={Ba% nݺN{m7 F9~DjvI!/.%"I0Ɍ3xgJuɓ'X\@Er!$ zy#' Qd)Tky&u " P2+WW~7I9 \z0ԨQo  B7J>[%n)En+,Q؄Eze2a2W,Op/f1h FMddSB`Ϟ= 6[:=W$̬$ww:15.$άHr4 <쳴hn]zƍu5b\݇md޺N^h5p z/p,}RjUj5')))ev d*竍W1E/#sH]7VZsҥRo'N`ҥH\2Fsd* P/Sx @=?wwyN3BEj$d ,HOmݔF#a;vTJ董ltvozIS#J"fe+thzpj׮ѣ4h~~~N(?2rHN<:2-Sׅ+#mNxӬc=GphZԩC,{gD,nʟE `4"i>eN6.!MKxxxc̍eq]S󵚗g7p:I@$vx z޽{޽e[Fᬓ L` k?q*+kqJ X,\777LviSk]I]g%T ֭î*Q<7..69EeE$uC-?WKdɓӧu tΜ9̘1YJOwGOixn->[7xf@ g#hݺ5O=AAA ׯqFߏ(Zsh<̞QW+R7wBc@E-[_UAu{Pز?*eiF܊T\ٰaMimÆ l۶a#( |/.FCUXY d,n ,.CL2GEnHaa9{%TBNe$%%,k77Cxyy2yd,~] sgEZ%M; dD 1YMF5eg [@? ?`ɴhi /_fĈXa!@XU%7WC<\_iۜ  ˋ\kntzN*qquu'K.xxx8,ٳ]8M)}<-x~\FT)]8.RwHj5tA_Ίeハ. osܼd'&8oذa_/egg{9;G`)`J&l}Q}I|}qF/)) 2JTOwߐ+9}?`[oӷ7Yxw999FJxOF:\0A bFF'PwPFMFVZZ#% 5OlʧCR |inՕѣGXhe͟?˗/;:$ KrYya _g Fd|W*q@r᧟~}v֟;r~yXXKrSgx}(rΜ=O+Wt&JҪjvq~'~WjEE2pЫ6Yn{--JpE \.]D狛u VY5ι7$22:KժUIHH ;;d??W^*Es5t4.j>ч[.UalKmGڭPc/n2 nݺzҬ#>Vŋ$%%[2 d׭͕g{E#- 9 AImEZVF9ժU.]SOѷo_ׯ5kۥ*YlhjpϚ\d|%vKg$_qy$Ą ؼy3>hv/;'*Dp_-&: z=zNN @VV6>ԬiU- 1OyfddGffftv*Aҭ$҉pT*X#i;.Y)W\-vWʴ?<j1 3h 6jrɤsˢ#(&Z|QQQ=޳;f^S\EQd,7//u:z˱?dyp5#kZNl۶իWgR)UJNǟ~nZZKLž{_,RroLgD*d$^Nh %""H:YT|{ԨQ.T(r˒(HNNf˖degQ*,1y"אdڹIrS֭[G>}}qvZ_"nFK.U_ Gɐij< ڐѠ.2'WWWZliȪU"'' h4Vg*EN~ԩ#nJ2_( mHy?,NxӦM4i=zku׮]%ɜu[yd-?ѝVh4yi4s U* 7 G*sIHH`ӦM\Z|TϚ_VڜCoֿ@R-JEZzn%XşOt T*%>C+P9˾囯;<.<ĄK yF79O F$9H=:0sLZlyקN#66Ç;:w4Z.I}Ѯݺ:ZM\:Ay3jtk&0`0X%}u?:ucOzd2JT =^^xzJΰ=zᕆP?ȹh۶Uɑd2rss8|茷7knXp/.ԁp%t:->>>! 6Drsr撚ʓO>Y!O@@u#|2Ge޽% 5#%u~>E~G@N4S*mۖ-Zpa233͍`j֬I:uhܸ1!ijnsN!a56$v-UJD]۶%gK׮]Z*f IÆ Cۗz=j~~jҳ (T9+.h:^\^c 8D<yrrvVi5 `[AV; 7'OOjԨaסe)8 ŋt֮pbD;mSvswcyk;w#{WR9uHS};gQ;EXX]v[EBaѶW(4)) u^.a!WQ2Ԕ"_&c.o%ڵkM4ڵkٷo_Z.]Я_?sLlؚKt#n1v)>1ԍc>_~Hp\dXx[JPpM8@ZZӒ%ԼysիG^^ډ\^DL*%n7n STz'cϲ8LE"7lhv~`ݺu8kȠcǎK(J=ٳgٽ{7۷o'--fS QѸ7gr;[o}njѣ3> 6%K8:$ F*XY/0󣝉m&FZGnnO@dTCx{{(tV@a/HHH`\vĿ/}CV-Ez:=/]f߾[ԻN8,zQEZP8KJJb_[h OrSv\25ъ;x 2 kΩc̑#h 1*-$ޞUOOOgarLP|/^ȱcPԥ=3LѮ];[~ X# B[%_ΡPNbjpzpbҧlEq,\;|s+?6  }YvjCʕ+߿{raN:'SNeȐ!Nܽ'NмysgD瑴*= |/ڱcGb۶BJ OMnnnZ,VB`@:`-[Ns%&&G=\f7*b'YX)T@шh>[U;/\aUڵ7n۩dbٲe;g+nhʑ#qC6ٹ"3s\CDݗ0`z Ndї@NZEh?luPVelڴ eA \Tqc'ڟ.#n+]yGNFNhՈkpuueر̞=BQ$KQsr\]]Yr%o6> @1 IDAT<ü,_'Ow-`ȑ6K,"cm,'_Ol?Vi9,G$@ ,/Գш'...@h>6OW$s Q;9q vUL$N\xf,sq@@Ѱ}v㉎i*l _=e6ˋޏx5ei,*:.;ؼǟ42RaA ,,5kKZZpjsjN^i1`*<*G|rm(JZaQYVZFVVCecZjzd&YunuHEP} ~jǔ0e —?B˗"vBOBt.D{=Y&#%%ǏY|Kqqq!;;~tjժUbBkwپ2{p@D8 z3Pz/<WWŠ-Q733/:xZ@F[(""ZKa@b%j 3f ӦMg`` C a„ ;/ J۷3rHv0ZUm;=u+ 9 nj]U!;WZ#OhP33 н{wڷoB@9d?OdffJ&Ea!*\8ǐ7zXx*[-FyqV}+V=8p ~-AAAdff:⽽xwظqck[`/^ttHdggE0D,( + 0U/٢WK,2EIؼDX2^oWń xqwww:h4l2>N>]ɕ`/~)u^]M8N/HXV-Cƍ--_͛7[kRvG /4C^ NCHexVG cgB%xP\u)os`U{%7ރfRg%2YYY$$$`MxxzR)dҁtN:獏O@[.%'++{.s}ǎd\pB\۹s'DFFZugZI܁`KVdJ>}w A87lؽWRTB^P*:t!?@Tb4ٱcOzz4hGqt`W4zA`4XE7o˟Iu^*UQ XY ҥK*[OEvI#-* X(p@T!2dzX  4cac}8~8{.Q~yжm[RSSrC~B %%EqPQCֹۻ3~N:mS#*Kj^x&ƻ"R$22Pt[$''si֭k'Ex?BBg-@8b;aGm^WAG/a p@tdۗ[nq ٲe ԪUvɘ1cE+h  !<<^C政hqAPQZ5~Ih233|rEB*jEeND4{R3HY~K}HH,/%_ )au9VZEݘ-Zࡇ"114c-vՕpgZkW ,*5kJhDEE7jve}8p}]|8f" YRƍy뭷e >D?q㯈Ç#t+U >%P5wV˨Qyeb (c!amͽ.4 jP{gL+ Usu= *~h /̓qF5jرc+t-Ù0aAAAd2d2۶mcl߾)pzv0w'᚞aRnЋeP#LΫ<9 u;_a.眑5j0c L&C;, hZ,Xĉm۶C7 alĖnªᡈA>5|8*?Ywt/qjB@Q7r3nRVRζ6eJz@#`ziN̙3]6K.t"**ӧꫯRJ%Z˗3i$TJ/a$^,YًZn2=wӈ<\ٝwhy$cccYx1O<jڡsqq!))qgNl^Px+C}OO~ aPPV8}xsbrT'&&2gg ;,'gTxo~՟ d )o/.{ĊŔL{WɏEk+yRtQgySrr2o 4`۶mi׮K,K.~@JJ cܹ\vrv UJ$sMtئq :j)gKJ%cԫWaY8|0oׯ/G"qmC2a6sH ?0ug!? #?Uvȑ8YrGJT?Vd ]tK/^pP'(BIȕdS/H.)iڤ+9` uqU"Bix)tB^\^Qxg7ouE;t*ӧO3e;233ۡ;CRP 1tqVd@k7esQp_7Z+7N?#F`g\.gÆ ;:d0"~_m6´8oϞ#x B^_}Ъ†VAh^ntΝ%Q|_- m)Su )/-Xv,NRQ@zEs. A,SL@QPi < J7cԯ_wyYU̲N0@cA௿b„ _3?, F!(POKUCJlZ4R1V5EFNKQyxuHf̘0P(h4,ZSrJe8D}. 7mE ZU ԮuCZ} p4b.;v/ L @Y$Q(7`6M;#& -I* PrE|NHsY&2`Q| Rnn/ER|Z7z.\H/*b̙r* F÷~ˤI8v́R` Ά/]3ff~yilڑǗ8[E8#<’%Kڵ+:Ωs%jugΜ9 [ѩu-~=% ]c\«~]6R ϛ4cJgeԭ[ZpA}]~7tff.K3,=Z66@HJ8~: <z ƽ0a>2Ty4dqSID*Lz+ HhniSD&Ep:˔h#i)be":@.ӧOӥK._\<\.̛7h@@T*gϞeʔ)|%R۵?QdD.xrx&J?#PoVnt~ Fĉ n> YQFqAxiJC1Tm9VF!h'`3B8}p1cHOwXrdŖvi P,H 4Pɣ$WTp`7|y:Y4+.[ـwδĶuV1bZd=___L֭[3f _9 okx3j+q}uD1{:-@LL }UnBDVxbOƕ twGa\)s'}ÆBL#֭a Ц!0u*bk̞ nwAh\YPNߛ7xY >_,i@`(8Z=a {. |vl0""ժUGZjwh]Ǒ<( 92A@&#P(  pYN:S_tHrJիl2:vHe3?;8?@ ߿?!!!}>o-`1/ݩ)lޕ<كs{&F u_ؒ YZZ˗/رcN>L&d2={K.C:DM 5qAg!'̽ڵky駝VIjEjP:uc̣  fuI *L99j!ԩSb>ׯ{n*ʽL}2[*Z7/̩ ,di`!PHJLLSNtšNE4B={6A@Tr)&Mď?Hn}:Q*ΰW|/%"T\~\LG=Q<6O Ԯb’w0rHƍ(RZv-ƍeuPxS2A-hvv_!2"bn̟ `+ \З) D hri0j IDATFؕM8f `IXQHrP x(0֭[ gСN͂7nYǖL-[;v,;vҾO?ݝ>| 6d۷H0(UT|r&Lӧ?vҢ }B>_`ٚlwi)un%=cX%v\gdʄ9%;vd…tѡ*)S/l Ce"ժ܅-ƍ|GC\gwVi͢Z&HB@l̏W+3ì(Y!>kFbIieU14o4 25jw^*uޝ%KвeK SYᤤ$>c.\XlR|Sh4ErsM6˯6ٹ"}zйOv/1@neƒMotqqᥗ^b֬YԩS!QВ8}4nnnCA^btCuRAxI \VW_(eV PDԊ*lc ERX3vsh 捉mۖsJ]\\xי6maaaVQ#$ ;8ʳϴeم%*DF,h5B(۫QA qɓDA% 5ĂF)*̲;s?Δ3ev)3s̜s}_U~~)w}7O?4 -&h\Nֳ\}8^u2|<-yϷ^4hӧO; ??DԩS9Ckvxb~MvSRR‚ Xh{}ġbF/[d||PVρ̹5!X޽&E})Uu1CVVW]ugذa?kH^/ӧO!ΐ"- дWE_.iT` 4|sRrss:t(999햅tjtw)ǃa80 ӟ0pNÒu:v gRq N x r:zbUUK.ewy1l I'qǷ~KEEEa8ygmzrqY9Q/^Gi΢WOUe7PR #ƀrU۽{FN~ƌqjn?]+C5TBTw2B&}rbQSCaaa:( UxG\> KD شa?!/t]+Я_?fΜq_CaΜ9p +$rrW_eڴi2ͪ'?ZΟTϻ?N^>40iui~@ڼy3wݸpKKo,חpŜzNmOBʕ+Yn]î:&9+0v}]iH<&FIJdt=! 'Kmdd8M61rH.eL //)S0{l ֮PP??gƌ<쳭xCVgg/հ&8wz~(G?|{3eʔX<|uMSp^귩&jOOBBˌGYEd[;0yg{s=GNNw_}>3gr7ү_v rK5#u_ Ojdqo 喽mJ$zR^n&ؿH9P`VˮIl>ŕ2t6JS6ѻD2lˌ6[x R M^}8{lx3KtIpWvijjjs"s\466l2f͚Ց:y>ˎbNgPYg3U|u/XAΈcEyy9s[5>Ri跚Jc ,0=|z*.hp jg dDH5X]]9ؼysF}i9O~kb0 \.%%%̟?~ݝYczΊz6m2=sxVT7PVH&'Nu`f?]I5buIK0:Q v]Rvha:@n7>.&NU>#<כQ_://I&1gFn`~ƍ>}:+Vh3p` {}ȃV2ެ~jG懇9۔ׯZwNpl} W֓ kC- bo\إ<;SOMAA楩tAvmL6z XTNVZ7{?~v1g;(,ԢAdy?\r%ykd)0l~+XDx9 DC,e/B}61.BI`6V 8c 32?`ԨQ̛7kCccc餱K2sLn0~ ~}E_nv?>;ܜG}۷wHVisBd4:+9#۶H])RsyxI`[[,%Ƣ8ω?ѣGm۶.c2|>l|m nüyxᇩj=o.~ޗk.K'cq 7:a;='u#SisWo"uS,a7#ɺXGu;hi\it *0E'!0KlذaÆ1qD3KӇs2rHx=ĝl2뗑Ceڴis= 0v\.7p~Z|;v?)aӁF='8.+|jFRt`` $o&仟jY.mieotN rpZ<'~f̘ȫq_#dܹL2n餹%Kp]w7ߤ_|űYOHg .5 %~-r%ʓi% IjI*O]~Z}!M?QM_JIπ1@\KJJ8s9شiSF}ig 8illl3?FCw{&W^ᣏ>jfZ$}Np9aQ'&~DgF&ؔ )!VD26x]Ni,1b'On3q.]K.as1ԴiAVV97tV%+cy*`}Tl6#sxRGG=KȥK;$V V=%֖?)@}1 x(q C=Ԧ_2p@~p2`jkk۔6 ~*+M Y+NTNǓ4L\nQ^f";r ڧ 8KL'65qm #ܹs1 U4995+f9X"Cp:ߩ2̈@+Fn~iϰ<ߪKM{y U@t5.mӘXtxNܵkǏ?i8Nƌ… 9hhhO|L4)ig„ o 4LoekT30q=ƭn^HjYi?3T PtJUXv-#FcϞڠfggs饗?c=60f_϶w$.a;IM᩼ǎ #&"cG:/? P=R x,&dGy:46fVz^^r '??#x 㗿eC^Vkhf.Zԍ(@?h@ 6L,@n@f~-M MP6mf\)qX|:<;9ꨣx3a<@^_y.\.S BoClDZ'~ U{MJТ:XV̴X7Z\":tPgg~w}Ǹq;v,~dL3ojQ`s 2h m[8"mn8nN&4M˥zjXng8o%or3ydJKKu'mqxFY<;8]NBT [/z*倉 &ptӱ +$A0e~^].t sZzwfm42ۅt}r %0.;6`0Ilh BЉXKg|k;IYa;2uXb4oc9+WYޓb.\-qּ ~#J`͌z {LJR/N{u,k`#ޚVKH aͅ; 8KCNܶ /:7f֬Y!bpabeVRbdh}qqx`Y'\ etzlxò]HÖb0#`my8K,5k0j(NccVG5&nZjQQ}t+L& e4 |}`ss3MMMv\V+7mܪte?Kad,q-#( G#U=Op1fl~icPå{v@]'b%Ҳ%pg_uuu444 [SSA4YM[}mc mF@kX '/~@EE~;Gfʕd}XmrJrJ ?/ kkkM+Kdk555uA`_ zL_Dl׸j`) d+pV~Gi&.B<̎S{ԩSc,/o&}qr8sam6i!H[]]Muuu sTUUu*{4aІ`8 仦zi?Ur+׬Y)µ^KqqZ~zN?z7CRؖ̋wM'%T-PUUEmm-XU9m"Th+`Z<@Kl@WܪǟDGFQ{ҥK9c)((&9/zjG} xP i'syܡ*Gg0 "EB: t_7`Ka|X__}0"hC8$r{m۶1|F;v,={I#dhԱ>Yr]0 i%ʌRd0 JKK)..ꆆ*++eeeq緩 {?0l;WȻ l(`Egޠ7x)S0p@N9f̘o)@qq1gȐ!̚5+e /0XGR<m[̝ <&f Nmʨ4ߤؑ\ǸV85 rp8$pud;p)K5ξѺuXn8N;0ɴ͝V2?GvF񲰰QIDAT:'qd* t־XQQXXX-m -vj<4#=dVKZѽi*< 7M?翀Zӎ]}r[uX%%pt@0О1Q^^e0eǕTVV6aFHhV4l43)rQ`) H& kҒi]}W !f[RcTTT4n d;w4bYc6gq]=9߃pF< Ke{>:`Vuwr}' aP^^۹sf= 9ݱcMv zZ<nglu Z%<=OVÓ a` PK9/:ͬ!%x.'OgIs|U L @Up*uz2pϥT2˚N0OG]K3.cA@ŕLv%E7P=*:><$VrkDW$C& `V| Z^=VAԫWAػw/ =m Ͼ" xX lLi@ifB;Uj/?[Kğ\`AAHttl2\jy&Ĥnq> VaqZ%!} C{ 02~Ww*BINɽٿ?͚a*$h,֙3f͚OIaxP Xc/$G7TKSt$Loat9A\ED-\ Zj )))WZt҅( -\$,z1 |/B\DF&KlZw[֯5>*Mw!Kgśsr\D޽9s<['O!~1$N;3g(]qwtUl.%Sbυ{o j/IިJ\f^Ƴ#GqƌD?:+W"]jK 似~ٳگжLc,EtUl>D+$^Gިr3NEѾ,6'~`n_ٳ/ $Ͼ@q8m6qMG)w}}'&i MEGO *8'~j)Un3fTD~˽z͸R%-֤1drƱclj=qe;MCSUZOxoVxzzҽ{7TU%11ɓxLwat=XUt^UxCwˮ0F%x3_/>|?U|o:#P+ri%VGD \*LJ^Dl0aȲdbѢ@7msI'y7[X*钕pLw%qWkuׁBoZQMˆ7Y&r勗p٧1{zlXj$t0=skа!c6;48  _r6pkϚ5̙3n5kf*0O~*zr @2nJ#+J<+p-3jwToْ cl]\o2zρj4RN-`:wD۶mu_, !@Q`[8^Ɋnt/z>{ ?rwoFHT*EIksy=]Er~>{1f.Z=߱c4Mԩlذ!9૟V,<4yEg@8v^=~NQfW(2`5/3z$zt7_ܱt f}U %8sn,^)|8ރl`0iSLCoh2nbO@/ (d0H $U뫧vX-?{= __"EF_QHlXN\+ I$mNPv. UڗˑY}49KͲ 9Cݘf^<$0@ڵ2"sqM]]_>j_Ջg'>'7z-\{4m<%呜̪UJ]㯆^K#DF^q@OypfeSiӄ>wl4 aXGp zuMh@<==rss2sπ8AUU[tNQ|UPdʴWͥZ_nj5nxX-,hlj?4;v'w1zxT_@3;edބ_Fx\y—{sF(r,~VY9gx.A wY^])W !111: fz"nkM!ʴ{ǏBI>lᶻ蛗fn#2(ra~ݲZ qVz}f?J! :v=d-X۩ѥ &MxUфN*QDزIHoVEEql>˗]TT@UUAҳg^G9 v=/A??e&'#3֭[&&$>ijE#+"шdBZnܼeyWٮo+!~`11T*f3g.ALΝxG̚53:L`S F4]4f7}(B 7\yՌF# ڷo>[p Fo vw;SgР $G /nt[. \N[0I'''s֬\(^! ^>1jը_n-ץ EBBcoNMMcǎqР^ajPX;n4hlPU @ݺu3gIeper| o4X}ZAq~Zv=YǏض-k}A٭!}b$8DS~m Q $))}  [Rk]E%A@u:cQjDUUz`6mڤ_SFRf޽{=lZn3ull4Ȳ,8N6hh8rɓ|%od@t힝b!ؓS |zN4yAAhy&DmY4Qxƒ˼9skl6ÆwO>L I;~p;׭͡lֿdfb^ۿ]L߅ QmAwd kQ&?9sF ѵk׳VA.tYmvQ#jTE 0O}OEQtKK b̙eYvT5}X0wZܱ;j_2,F/OomN=ȹ% ("rd:L`<=˱څ[E}9;_}ow !Wu3Ai=a,S͐&,]Ə}q~͚[o窕4}92h2n6ʑTxOdsI݆S&Ri(i۴~8B5Zp.dRiם1㕖3g^X0}FH ĉ~9sfh)Y 02:zѫ|SNO vl􌁚t3K A_VZ<\7=z9~{Ɯ+!uJDZwLKdI\WXXof3I۷s9 2W;|Xk|$Hd~m-2 TkղBh2j`ru5$6ޘW&c###=`̙3nv]Dά|lv;|}{)_8Li)vC}2ՙ>^Ȳe\q(2V &T/'~=.D_/f:UOddnZV\&=SP׿4Fg ƴr܀OzPي@~|<=2<33Dѕ9%dF^xBUӨӿG(، FBAh L,d\<$)4jнgZ561[ϔ)/l6N')ˠi,X}S] z{(%e!ܾ|"#.)e`ÏPKOkA$ k׸1unjƑAƟJ$y'Yfy_` ޽b $yN=4c\'}bئM5|({ RfFEIoϞ-z) ~w?q111g7mIޣGw zUWsjRSr8tiUv:q8ҤeME]VvK.H̙;Z~^;u @Qd%KЫmtyceM36womg,Q-[ŗP2p(&!H͞H߼y~A@e1#I?pO5ȩSĮ[_9V9TIfm;?n%??~)SnA`-lٲimS.) IDATϚ5ӣnuItt6EQ]RYQQ2h?לSӴ:u @ l_GJ:$HKcHey}h=.빬Vv-;< CqE(oWҡ=z`0ӱuïxY'rt4cnQFݥ8dY!..! c9>vLٿoznɫ\waU`sk?4o\6ۊV = "(All,}ǡhTw/a5I W-(' =o^CVZ&س8gN_MM^^D:Ⱦ}+Rh2qz2.XTȑiUID}90{6gϕk| EɓUPA i&~-Dg 1ΌK y뭷K=SN9={F㾩S*p~/Y,fpb6 AUS]Z#==ǎ7dnxAFjtpo̭QQe4]۶fYAQd?ƤI?!cfD{CxEFt@X_G.<DEhNDE]}?pnI+7`0D vѕ[X8r%~f+3Hu83.=sDA"ir#c{ XhDئMXSS9GPީ;w~RآܪU&=I5q2_RR(@Jr2~\̝37nw4mkڴɛX;$b RShެ~%Z}](.>ɰz,oFY{Eج=#(芋tHf31O?é5Wک}PWO'N(ϙ37 fcE kժAPl6"Aߟ71lh:h2qد?VBH~otn1-^d6L{8h]9;OdsWLx~N:+tN;5fٳdJR-f&#u5?$=#jSӴJip]h%f( Ϝl1E~ ݁(Zjh  0(*(Qn]z3 (Ht2"j`uEFp=:7mD2?LH23p: /뻮򊒀hiݶ 6nӋM)su2Z"Ӊi#%%xbcc=OB|)dgeaPd%(Ipɷ-]ST̈7VaxEřSt_ [zzuL>E@b%Y>EW> ^g,e= lIxI?9[JJn v׺Tرl梩;M~`rOh 4s.u=\%h_v=IիISgfEvv,T$?/CdDXxK "bw8 1!Ąx∋#>.xHO#=#$ Q4ȷ㔝($)EF{٧id;˟]xn+Z.Ж~Q`m A4ޯIz|S&]$LǦ!8hRn~ˋ6s_YVh0`KIa۸ēe.1dƍʍPC7,[_ @民L^^YdfgEFF:yyN'Nف"+d;p:ȲLnn.١íV $IDCEUO ..Xbc%>!SgNDzF:v @\B=it> ¬&GUXnʔWL+MkH=\q_[n'lmQ#˵]ʕP|գi9㕂b!m~~?w_Ve}e_]1'' EU%+;l3IKK#5-<'99dd͖aG4TMCErrr<ߥJ1%';xzz&2ժ{|Bqq'ēH|bgϞ%#-4222U~#GlAgp}@q:b95ڵ+gK]~E*XNƜh4ۋ/W>5d\O>A5lۦEм4ti_>`f#u]FP]H^8qҡ( ޞl6$3# 23HKM%';s%';rX-W^/7`֡f__?v;Zzs>DJJ fEU] @ q ܱliV5xx;ުv흷 [Fҏͪa9zut۳b N>͞={ Z $\L 8z{iflܸ//OrssПȲLNNE1 $$1{QUm۶Y`9sa[,m۴`0piTUEEV+& Uѣ;Gϝ?&9A@>ȅVoтmf͟_d8k`̵?׋lk1~}:Ť|y6Yv&o/ovSP>j: ?4Kv WӴJ5zVo߾EQ|ÃLxd2p8/~zPЬ=Mn۫j]a/Xp-:SqcbUnQE“r CVʙ~ĪUd?4h@h׮ԽJϺ+Je >?Ahd n*d6s$Rz9L87x?~*eFu`dzu}%WPٶmr٧EyM ?˫n'++ b4IOO'&&/X:x#GV1Z2I=rVf.Gl؀gfwutt2 о\3+/X.l< [JՈ`4jԨӬ[$z%+ŘΝ;/Z(B@@&@=.СC9CA'Q,[ /_nV 5h4bX ^0N{2tWm&=tsg i i۷%""A___|||ۛ\~y|7aÆ9 .+ll6駟geeʲ2>=]xlj~ ~6B:vWe Lq` -[X˝\36S>\7#,x@Ck4z%o;'gmc2ywQb:tU|ϟ?.//pld2qd`0C; INN,55BJW5MolII=QXw8۷ 6u8î'].H}7K`njziG?b8<@ѣKO;|~h6}>:l?MH)VYՉ} JLZZcƌk|qW:u5kvgddË@߾}[] __zi^{O4d}e|ݶkMn||H.gq(e? 85i$r젘ҦM.^Xs+L; 2իWgСsFs3N:uR9:t '/ԔTFcvΜ9òeؽ{ѱr1a-EAq:˗}_&GK}=5  '%Q=MEeP]zȾ}KV kCΝjvE_cyd?WfΤ]w^ җ+prU ?[oU!:<7 ^ܺkͭڶb1[}|} p*ooرc5o޼3 Ia"//.\_6Ү;xGizݣF! =ƟGbNˢE2bcc;Wӯ{+ɣZ&y|AOA8ecZv=Fg&51xxp=< Fv͙ˁƓ_Y5jI{#Bt.tMW}63ϖ"}-бc1y4l٫W/62@iUY~_5jĖo#3+Iv 1bSÆ l6#IдQ#BCCasSOeٮp.33sƎ T-OOrrrXr%X+ @/\Qo&TvN]ǹMѮ֫X9FڒXDOعcKqU^cgO}'C~FP˲Lڗ8U'NDH;>y߳5 B  ҃"TEПQE *MDP@Pi H!m)gdw)'`9{3\sN[5͛=q'ZjEʕ1L@PP^5EVts9y[?fQz?eiU@۹{0F?^@8$:צ1?T p}whĈBBbJ7"};n'N^}HiWNN/]Y =kD;cIIT3QyJ,>,O<]Ïx絴DQfׯȑ#Guu-'mv;zA1AP9(ԬYArӀxAQP 4,ԡ %"QDEE8bĈZ",,LntA0t_@Ф[q 4FG o/;tp\ 2@Ly3š#; sʘ+Uiς=ӛ-B,@-Z擞)ד{[HA&Mx׉nݺvǏn:7i¬Db1tN?ęL6a@5?Ѯ*l&yzѫW/\pԩS%-_DV\`@q.EV t@FF97)(0r @~￿X0TN|o/QVy!^S>-l9m,WT I‘l"%PUoc9w/s+7כd{k<ҬY w,[ ^]ҧNUr&ajd%N'zOD?S6SJ+c0n^MFF-7{ h0%5kSRRFU 8)2SDtH?@|DQTg lr\&M xI4bb2]_zY^Ժg}֯X&{fn^^N*1I ܴG~WCjT'}#aګrfz+;wuӦ~9cÆ 4lPdYEnݚ>k^'33~8%I͚5#c2PϞ=?>۷^EQ֭_`СCP{:u2jU+z"GR/X V&Ijj$I_~N+)[zuEQqFw@jFFfz^e0bccwFGG+QQQEEEGWL& @PoTO)Sp8呐M5jT'ڳSԿ?.ߑy@~?~&r80X/IK,Ca53U֣aaaIvvvhvC3p?(|8IIIlezaVA|RMS%oWg{}<`>[&C~!z`LRys~1 @XXg&..@VeիGLL8qdd$S ߼ʿQN@@ EI 9RU0(qy^d2;肨+I3N|] Hl MEiJ9DƯ79,KLkm۶eС_޽@C\\\tұcGB~ رۺuYxc~oV 2~'OÆ DO>>w8X,۷/ݻUNÎaw r  CIj/*PѪUڵkR$}RSN':O=uA"YףG/ʕ+駟z-/\D'*1ЊcH>Ç\; ;']̖8ViӦtޝ4DQDs N:EVrZ']o]!%%f͚;`u5Rb='0i>  T,ua }U_VX*Uf7"+2VQR  7=#]3XEV4 P(3|˲HG#De֭[^G, ]vgϞ|駬\=45~yl81;w-jDAw믱߼Iڑ#d;94N \X7:u*={toN^^VNNNѣL8X_~=}~FUpe-D~`Z}r6m@Z P{tz VOt:S5B\eN'AAY0LPLQӭWvv6ewE.*uDQD'G>XJpa>}n$phDQdĉX~.ߵkbV,Ѻ5 'QWOHEGHNEɯjՊM6q}aE DbbVtX,f̘G}MIoYy1qdР|/b]وZZ_|4$o\!MC{ hrpoOFnmd2aY-Xl9iPȏDY?ӢR_dQ3vo :ٻwo咜+W~fE*U0|>#sYo5 7I9սz `̙̞=۫噷1d7n9kıcǘʽ˺u|'Ψ'^|ݺu~n&iGm?wݺu$$$=i$>cR%8v;ьb=)tš5d2'(S[r Q.Pf}W*q{t=Fm(Xh,bfiB ҙ73S7XBVVNSrEBEQ415pe}wW֭l\$Izz='O$Im8p }壏>bƍ^اu{݌0&(%綾8 J*L>f͚(RDz=UTgڵ$%%Q;(sPIw/3cd{vSbB *e] t8΂+t:9$)7%BCBB.߬< xx_ǃ_fM7}dY[nt֍@/g̚5kHKK$z=SL믿6l-9b QHo2qu.mگ7jԈ1c]*۴iCpp0ߢbdOvM0:Oh +)23 \KrnNѪ-Z~op7LAvib-dŵo]Ox:^1vړ,^7V BCCU1I(_KODQJT @m? "dlH욵|ub׬'j gP~x.e wΕ+Wعs'VUڵGҶm[ 00w}Ç3c \|8wMш \Ov,݄ >|8+: W^\xdl6:Coٺu+9ӷ/!֥oF:+ V*n@ث\Sb*ۯdCd/ #Ratחp; n0[;gнzfÁ deQ 0f|qQ$T*hIF"2"#}"@K%"̙3_֯珇ݘ1nPBy*+|sr^\KףvíMڴZ@>/?}nm ,)F>8В:JÁW9f֠yRʵk$ IDATe?ϯ\Nz`"{!+R"t8pM6e mprqd6oD@uL7oRu~yl+ E`zbrdgy$ǎR1rH:uT">ŪUHxktzO?gի8~`YL= UA%.D[4~͊1Xm{~z*z,:ј[rc/9^:Á54''o$I\b4aYB!A'hƞ@\5fi,+'Oj%+W~Af{98c*-Y~ yDA 4H54h-Zr6>`h֬k׮eʔ)4.Ŭ@:w1 Z]viїua~\~z=?:F"^de4]lP/:*ׇ۰aC%zVX}ë"B@=3v|5GHfڌy&oB#hѢMشifHZHJJq^W>d6ɿM='mZ{{PnI&Pv&I>O3eU( St} yޘ TdD'VJr8̂p6C~@:Oפ$"""ٗ/_ٳg1 TNcς\E?׈1G(FTH6lȐ!Czׯj*KQ6mʠAfٲe|p2Yst:jF[News@l-dX+Y-%2m.֝x_@ r?nwBMy3Q^]tr9EمѪIFc뿪˚clg0ҳ 9ٳ'ݻwd2yxvbkFV %ԙMY,)M 0Uz$AMZFi3C*Qe!r!1eP*sVөZnpJ֮]Y?~? z>σ,*6dǖ5ħ \?,xY@~)[Ry^ .vEBVZQ \*u~',w:*+:ԗ+8ذaxF L2 A?{<ϫCHĸAW N6mФImիW1  ׺ukL:r}.<:gX(wLHE,E@b~>z EQA4hЀ={pĉ"}Ӛ9ڒ mg{TzhT {(O>:XIe426 T_W _ggN@oT_i Q 7 Vkt`Ӊ:y>"m۶?0qD/`'h_hci,}Bim._7y99LϞ=ѣGΝ;Yz5驩1Y9x6zvKlM]XVٳ'ݺuNNNfժU>!{LMd ~/ulW!;5dm'u+| {Z0x{ٴgւ#˱(wP+FN{BVB#NJ~S D^Vg&p%Æ AZIύZ{1X2]l_KTuΎx86)=O#tlZٸq#999[p|ƙ i| @v ѧnhpVd ;PstP[q`yVwJʡC?Yp8..x}A@m6O LE^?ߪv;OLu@dYFTmw{]'5~@M$5@Z r:No׮@O޴<!,|n~k1~K֭5g~ ;Ν[۵kk~k02ޝn' aa|U}ukYihӦ  "22ɪU%V]5+]J\x@g ~lȜ9spѣG>I8gx=jܸqؚ~!ȲBll̝wizjՌFS#^'=-oDыo]F[)FEE1e{9BCC5#u8,XiӦy<׎1ҵCsbU>9yHHH*%6mDɌT(@f҅HxcGݻ\ Ro}қ_aZ1U=?`EM:sM:շuVyRN֡ ։<:N̍7 }Mޠwq6kʯ%%%EH3:tA'N*Tx_Tq)$JjY,'PRjڴ)}sS2oy3 HիСCO޽{rt.IS$ fSt>)I0pVѲ_N;qJIII  55~T̒$ID%Ia}./^b!00i1?j#l^` |L6?i^؉~'fO[8H^SS~pKzܹsIHHмl?>b|=:عrDjI>͡r[fРATV?~˗s)m("Mk#Ӡ?mFe٤lʕVXjt_jSѪUE$Y&11('}sTaҤe'ȧ  Hݍ`20 L&RRRHyʕ+jŚRh{$=޼yBBYqwE O$~' pll, 4д2==#G@պu%{!©#?v}0<$  N@@ݺu۷/7oĉTTh6lHÆw31r«l;c?YI&?o@~JՉhҥ \`0 /4mdf`J"+WF^-Tbݻyyy;v}s-q@f֭[kRTn~}Ο?ONnaaZ3{jJVV6oߎhSN岛ܪB ={Vt:N<ɦM$&&ۣs09#O p3@Ftn> 4h@tt4׮]R|2N"jbK"'; ƍAa˟B+?NPF#.\ 99|{iFǎ"%]ƍ%0K+mqm1X,5dd'*k3p8ٳ,cvtG_Ο?Gn^.!:Ņ @vY"xt6nݺRn:uDڵ<]$v_W Ӯe e5~Xnmƍ˗5G*"'O$ [#zZ_E_SaaH޼ `` :u">>VV{L\\\ [ǏGi[{ 才7l6bZ_EV!aDEEi H ZjhIt //Ȋåv;]N;v?T+**={jez=z/]vZl& TeժUߞyz+ 2?{~<@dE* Jm J\^܏@3gPzu/^\;l63fyjժEYn'N,Ts5:t`@j>1kif:BЙE̘1ӧSJ5E/_ܵkSV 聰/6+Bx9ضFO>N:X,-?cUMQ\U6“ T0h9h <j.*XNzԙ^ѣ?59-6m'Oݣ͛믿?>Zlc4=euxka}:vhkдiSWWI$cĈ|҈^'==קOgs!p l 'OK_F>/NCUVeԩ|~,[o_ԉ=sj~IDATDQDqeEo/GȹP\?A sK.= /g{SNѩS'zիW}5k֌O>khʕ+'KLQ{2:rE6O Ym^$7/?ҥ -K.]f3GWb MR{>yOGVA«Ћ}׍79sIU$SeM(Ypi崎p016bUgp(?YkL\S*_@ڿ{T1A)Wzq?/UlHfͼx#.`0M N'`0X,\8RڷpU"/d{="""hժUB@˖-IHHdddhH'ؼy3Cv?Bf^ t~_pw}5"UbN@@۷{ȑ#X,LzҦZ+&N@t^ <篿bԩ^4jN'ڥyb\8&KKLկ0*8pS]Td:By9dܧ]JJ 6ɌN' z=V/-\,PI(|Wd,Y͛SNrݍt҅5krm8$I$''o>4ػ뛨ZEs#?:+c4 0p3["rݻKz)))4 sUGe 4xNP\Fm5vٷ,9'Zyb:LFDG/ˈAo &&HNRVNʲ6.E2%sQu?ҥ {ە+ܯh40L27S>.]hlȑ#<3W8u3!p8{ >ցJ|]/}U?N-,{U<\^<~IQV6 xTʆʓu+lJLL O?tyuӧ ,E~O<J)8 SOC'@҃! IбjNcذa̞=x5F#~ &Ήᯍ{SkL<]4*NhƏ[ƣ Pl^^@? n[z9up7yT nQ?>f  0af̘AսDD׭[3er<0o"SODp5/*\,>Ѣ(SO[!5k2c ƎѨu:6O?_˗ q f1w(S'琝=l^qw3l01`0p |M~ D'N/}xKD]sQ+v: Wwz|~tԉ.]Jٳ#w^y>3/}BTe h^~'/N `L~[`t+-ҥK.СC}z]4`E%N@YöN_u\\@ITT\֠A;wSO=i4gbߚ?C,[r촃A̘ zÇGRRRzW\ɾ}<^Dw:URVȊw$xipPJy:/+2V*pzEfݜW+Y0SC5p# W^Gz~F>;@?eoE徊\VhU)Qn[VfMf7Iѣ[n ?eYue̙3Ʉ,˚v9s>}WrkԎ1+8 X0ޘ΋o1^:uLiXzsUCe\Ħ MP|(R& 7ǀ(z?6mCY/ܮ];͛G޽/_W^a…l6AY)j>9#+JOY*T' T`ʸ.'BS7?eorNFm֯BXO?I&^={SO~7n$4`қL~2.Ƞi#sރ{/%YU꽠gU+k V(؋h4u*K\ĺLfP,h?֘A#n(s3,@f+gΜażEEqaYre z݃>F Jk8@XL%}3 =nmG?aIͦ+ VԩS?~͒%KfD({*{_(/vW~RU\iV1C3*IN<S222Bcc#֭K9S2RqIoE"lbZ@ ˿3sh[WеuoM ( ,S#>]ڨ1} uuu ]]ָn,kf(Ț CVcL(^Ϊ(T<Ƕ,0zS̅F*U/ ϟ…9l8Pp9NVef.^7:Rr`0ۑ$2<2J ;::شi;w,>pE8\E ۵{Zf  ߦH`tt7k"DRemoe;f_˗/E8{l:')<y*8&O]

>3F:Xh徾_^l'K>̛VmcRj@כK?O k}׳=Kx$U;FxBF K^ >bSn>_z\ 9<%H@)*+?v.0*_]S:Xx?zG=^ ϗ}D 3t'CO ˚Wi'ZE{?]ˆZP]nxs*AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJK 6IENDB`klog-0.9.2.9/img/klog_logo.png0000755000076700000620000001005713233376355014051 0ustar staffPNG  IHDR00WbKGD pHYs.#.#x?vtIME1qIDATh{\UUǿ{+WA@5AXVViV;9(YSi7I32h!8es~ ʚy{?gu^{z/s wީ-fh48&xٲȰa˕xB56FF"8$I lX\3 I>dFXHsF1˵H^/,#2 *Aؽ>Ec2L L2yrш[nQzPEE.֪ vܨHERKFwr]`s t"F `q$="sμFKجJ^w|`uʕyM"LC\SN,p@[۴.((Pr{NSt Eap; (M ,kdÊ=M==tPrD``ْ%Z-˖-d6 G.Sڿ+V4Z:l=~~,~j嬲]1^i_! )/)_o\a<>ll[oK;nv. oq9 x ǒ&O݀9ڷ/^ N!{`2a|rb-*h[LnKFó>צHUO.fe èdҤ;?RMMO :Kn)S4qqz= cplㅨ z|[L-{H1%^iWt؉˗/W+0f̭ ͛x/Y[^KBBm[BasǐVq5II֙-hVS֧1̝5SF?KJJPYYɺ|ƖN;cƌ,l+>smhkֿA…GytBT¯[7*t$).'j*i8|XBGv1Ց<{6{H'S""'&&?vH(*wiiџ^Y#Ï+ ZaAW)ǾO}xNSQ6W|"Pr>˅X^N:(Z,O-!|Pm*{N&#<1qVT A]1xР]=w/~]hҧ_WnJ +&I_H'TȤw0eyA"l 8 Gk}h?0>NȒn كZnOTAT~&*"2YQDU^ a!aЃ7ԁþX5)tz-NH.x{`HR">ɃP(}OGE"R0a& Ո*豷=v, rqss5}:wFy JH@et7سPLǏ'e7<_AXݒՒR(>Y?<zmZъgWK |^/}f@H(>GJ'Sg {j5aYjAp67]w_B^l|աIIrFFM6%|/EEA}oJ>\[[;rV9:ZVqYGN[dBӡ( >Nǝ۷ӥGOꋊ "%km-ͥrN&^EVj<`y饗ݶ}n$bcctNwg{8Kd钊#G2Ђ-[EŪ=鄴GZWB0Jqk]=*33>BWv49">}]z%&ҥKΟ?π~$n2x2vlOjzHV@rs)77wphh3BA'%M[Qګh RWJMV#GrӔD|*0|e5\>J`P7SQ#7I w"K.\`C6mT$=^BݑjJnɻ=Kgn^_317';/'{w.(`XCeL˗ӧӀ2H&MDeeJV4j:wYm֨jN'nӉt]"jb9{Oʴx>XYd676rp]HDSee ;qKv6C6l hZ@I:vt:#<<;w >szYΔfaYos ^?q̙Hz=‚[zvLXJ@ v-XTVtm er iO @]Qۍp`6EDkfx:/^o4QT(իWx$7}7n8 uL-)kif|\gri>!!!$''h0 lٸ?C|L{_TP2u`p@QVv;G]'!X-s=X,Z-%jL &nV ë>&22qH:*%%x^ 6?|jV8/yn󼶜Z>,6 6Fhh zD |@-bfa4-V#s0iɵ{3sQ]vѱ 5kp#hǜ, 'ώ̮z(OfaXX,$ݔHHhۨ΂#+ 1l6L-&d[.\ D@WMVrrr(!7JeпMMMx^dه ~n@"I沲ϟo9}R[[K޽k^ 8ye빤p:455˲Zj#n4֑-j/ԅO?llnI%Æ c[UuKJ%~:/&_ s?`cOIENDB`klog-0.9.2.9/img/klog.ico0000755000076700000620000026552113233376355013027 0ustar staff;kPNG  IHDRx IDATxwE=3 HJP$ (1;=ƻߝ =yzxS1Pwa8;3geβ3LoOuuUuW^AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!΀ MKVVn۶-BJJ . CJJ ۍvvmuZ|>_U@DAHbz۷oOVVtЁliӦ ~A~eUyّ#3|Qօ@)L0 L rJ(/+)//˲o&F2AHpvvJҥ =zsδmoE3 yχ?(mT>xm<ʋR 0PA0 \@XEqq1%%%PZZ~! y!Ah߾۷/:twݛݺ)++RQ^NՇGqy܎4Ja&i'Lٽ{7唔`۶e%B3`>|8={dСCIq1TSQQw<ǩ]4M޽Tҿ B"=zAq0tPڵkGݔwN Q ͐kMSϽU *eee N  4ݻw׃ bԨQ 6 5%Ŕ-/4߇ڎAJþJ+ֶZ;j*E!2 Q pzzCʖBFA.K=C9C=M]aeYPo;Q{X|Tשm_`5) RU#^bdРAbуB)--%8KbM?ՏW_jL+wdz?$uS__my$EFצ4FxyeY J. G1QF1qDRܹsR#ن z ?$ʨ;UTT :,`r\r /\Ө PH)w+D܎ Hq BQF1vXƍGee%vxngUj0BB=r9pRg}|q1%%ҒgՀ3 cAM#Ы&+B6E!Z%"2:"AQH6l?~<'N;wR7wN𑿓1cRTTDQQ;K 3nD ߐ l=0tCcMB @ ѣ0aSN)**a:QJ" ؾcEiZaˁa O4dA,׬*RMB" Whɓ'3c :vHAAŻwc 9y^6mDm~io@}#U#J[#SB# Vh 4HO2?'C-[uV6mĖ͛0&)W@КGy$3f̠]vl26_)lٸa[msF֚lHZ};Çm;xC?g4z]5kְn:,d/ԏF!q(RSSz 2Dy晴mۖ[)-) y>GKp~AAWfU,QDDRÆ c̙defef^/JGGJ)Ld-W~]@@B\E@H$ IaضG'PC)UHʚ~֭[YjkVo"&G!F'$ϧ W]k5Wzj|%B_hDilBѿ}I'a{ P05W?SVY)B_HDidBЩS'}I'ѶMnJǽφayfV+[ s_HhD%Ҹ'33SO6޽{5¹/k?R ֬^͚5kضx IEO M4,!ǏgȑoFiIIx"WZEΝb;K-iPB"QG]ؽkמ`WJq֬YC/}E!BS! IH(222ԩSؾN>˲ذ~=6n1 -j4wH#`}衇2p@nތlX;/:dZ@xFw҅1cPZ\LI !*^6oZ9b 40MS1l k0*+ٶm;w}A@Bc#4SNx.*:TضmKKE B-5@i,>E)JjJ %w5ZSXXȮb@ D4aKYI ~/|<_\\bib A/]tMV{F~KII^ DO5@xVqM]:wcE, ۶Myy9eՕ Q"ᄅF!4:55 ^s@kC *~ PBhǃ:8i^A 2% Ԅ4!h@CV ՑF ċtDDH@F$_B*_h,"! A*^h /Ɋn…X/- hHe Ѣi8_ZNh/-ql}H% E#J@B*Xh"S~wUj;5QZRB}of-aJ?a J@@*V GZH2? UU˻tHTP"H@'h=EHaQZ.RBMQ{yc֢UR/D hHe #zjBP7_#iyTfQjF(_"@2kHX=2P$?RiV/k8!@`r#:i¿Z#UvITXD-}k _YHe>ZLTQZó$#RQV/̝;Ea6͝׌9K*ZU@B*5d5?(̛7uD65o Lt>ej,2 jh/?~,]@BkmzRsr ,Xהk ˵:F<-ZRA-/?,Zெ͝s=ˬY5_- -wj@Os_# :(/oaCҨ%Qb-$>R1-e:Xxm%MP;77ɵ&ZE@40b#֙m bK3;;4 ey﷕Rֲ-?&jhIKk|H QZ0-rCaDԧ4c&~:]U(0M˭rs)ۆ9s~JJ?j 7Ev[ H~E bZIڰ8ZSgښHy19S|ca7T@.X0nXH^š),N?y}7RAa Hi+u> (-[UN!jiӆN#Fg r $gOT WY)6?Wlx]e)}4ÏWhZÃυ^ ״@ N8%t/~0gPF\u%Ǎp~AXer۪F#  r㍋Dk"}qLBHӿ8Q 1vUYm.l۸ bPP#*댌 ƶ f…6a7 EntCJA=MAy27zXk\.,ÆqO0/ٽ{ ۵F."/o^:/oA?k}C [$]"6?$9,MkXߚ:ozx9̝2Q6}>a- mY=~'=WZZ,rK,7^XH8n@JX $_F G&_v9C:~MMG瞅]}5R< O.%ϣ\@>S}`8O̩:GވZU3dY`!$%g1735QspѾ__,oݍ7Iϰjɴ&PYI'`Ҳedv֠z!*_)Rm۩y{ \|>ŇՓSH$DH>r_+6G=sDN|es6 >j/:L CQZZFj,6=4`|z ':#3%\.9昽|˹뮻+o^|h]mI)C$!ɿ32p}gn)PJQvkׯ'5͛PPP0 읻nU[">Pt٥ 8d>[z3^;*'{oЀ=2mYN'"D$B 'Fv&kMnԣ3fpʻc&Vhӡ?ǟeV #LWB),6mp_8y* ~po}[l+kRd$Ry$"K(J+UҶ-SWJJԱmٴ?d8kOԁΝ֚@E ا{&{wSSٳgsR[u&GD^|EF"KȒA$#*,bК5>N~um:NHO?(m\z v (TV{df.\%aÆ 7(w?{tP7a%'ZZKGH@q+3ucC TT4{d!k7c(M.!g{/l(Jah`]S i?DUp LC5~hlARZkrsE"M=o -¿~ .W]ofG)ibSqff]:Lޖ].z&ic.g݆ocݺucر 8Jk |-7u6Mjhݩy,Zse\JطH!'ͶO+QDr %73dp9% E_a7w22(ݼ948蠃;v ~G6xKӟgѢeBRmPK v2z4'O=Չ'?L͆P*lzmzJc.@Czǎ;\(rW9d6*g|33h'*;,+nw=Thﬠ7`mWfY! ;ZzޒgS'N[wF>,hӤۻ>f6; ϞU&e.W%7RvmөS' ,ˢ6OPC۶V)68 Ng/FivD =|х{樻LI_b ]]U(\l^>fCڶ*}8f*٠|Bf˖-ΫU/Z%D J)k!L+Q+`gp{'P+źf×_%u7,*+#ea[C9SYsFwO}W^UB n|-> cvkB镀D yh Pu2MN~Y={rfPp:񗔲UZ41M۷e˵ wǝ\N|UzqD;@5+̚5kxw#YJcAU/$F"&Nd4⫵5QJ)]z /n*+Ǫ(|w]v0 3%51nZBk|><{{ 0x*]./^[Sǎh#f8j`K $&u'i;&KJ۶1\n^|)eͿpI֕nc; .Ww}@Ze˲YTU:~eG᧟~B)a+r7?-Jt^Bi%z} 8y u*Zg I W_y;J GLEHm>yF8%ZvEEhۦqw%SO`X^/߇+3Ycبfryݲ[S9ߏO>bɒEXVNR[BĴ \?dRŃ˥_:%U lb:tglwK/Pe-t] l[0S&bCg=wJOmʹ4{6͜+==|BC_m5 wãh5Jf-Z֍50Q #j%G۸1ݶmJJa<}YpKHP8Юmv#8 IDAT)S5P7~''ƯxWFF2Ml-]Z7W8=]>ʶѕ5-ǤIne/xd8$D5`oW֚݀tuqˡ&Az! 0t0iܹsg; fL{1Fϝ$=fj ?Vyy m|;]+W:aw? ؠ)6ʶ"PVFjv6>=4R.K[@)RrlbXO=ӑo k.Y`h'E0 3Zu% t aZWZg_Vx׏++G4_Lɓ -b6] >qc|(ܵC[3|zxt>8:tF{ ,VZ[5TnM^uSO;lۦoܵvNu$%2bH4@}9CIKM {4f1˅4Mәw Uc Q ω+kT(p5^0M,_{/ʲdC.v>qt'jݻwxRSt]pWJ)**y vP;w`w!l-h ;GgUkmیuF\$mڴO}\?R! 0袋6mGR0#fmzja| mO?^CP]Y/?{om'@(Cˍ7Q_J)P]桿V-RX>1z-z}t";m[n~M͝_]}-U#dg N0Lf4SO:$J@H^eN9dv* @h!o6W^y%'N ;<ٴ˘ќt%ή}I>a[6^7fJk |9>*.je)'0 R~/PeJJpgd000th̠_{4/P\\:Tk˫ᘘ̨^TO?]"Ym+0P"Q 072d*#LJ)N=T.ZWw@J&ە1GIJ-{?;f̝w2|<*}|S6mތG&۝(L]t8N|U&;urAQ[lj 7"[ך+lL~[6=Ǣy5lGQ 0`@19|GɛoɊ+B?D NԣӦq;+t f[\q?x~1s B ' P7??H3*QeS K6SkMeq1}?SY/\Zy5MVj5jT1L"=ma#?NkTIMMOCs=sa^Q?NŘ\ L,~fhڲesw9(gqeeQ7p}5fJJ> c3bx(Uh _{=ra ++a=c_iۤz* ;Jjr,"V(rssk}^oi\,YeqhN{q.ν>$8g=A,˪eY.݅lٲ l6 09sIKM7H SO=;5kT7'QK]t]t1ܙO0sr9l{LڲHfȕWmtEe(-PڶQJ+6IR5~/4i={uTFRTD˫(~Y?{,n7ÆaF=TPo-C׫!j@)gW4>8F9فLzϜINզMB/\.gL: R-[U }O<0Ҙ޽.[_ŋqsX(bx.,R/9_ VJQ\\LfffO (++假o=N2͂ؾG?0vpdOMMwL:ޢ@){gK G)rUo(ZcSu+?? ^}[sJaWVѳ?SG ʼn̍s֔0{ҥ@n\ڵˠ荆n7^{]cl(7|m -[7'.B#Yf!'?%qpj),?#G'U'gx J&z+99 e `dݳ6ؓ^&kױ'0`GP7:LMGiᔬ]Kن 1{+$PVFw܏=:r]^/mׯcPT*? (ݴ1,xw9 pb?gd"Y?sG>ZpD猌LzyQ̒)-[t׮]Xz:ue9ڬm۵&Mg_Qwp]ǎ尼N$DA4 @w rO=Q0V2M{wCui8m4a(~ӽ{ҴF͛"֟| Çs^Y婧g]H>ِwh%71fU##m&''72{lHJҘ;'<#Le[1RRhUVv]g옚`*YG? 3^'ϤJ(Q b5tŤ`Ѵ׹O1SS TTSO!AL~cǎ ZkLM{ (rs%[P:##b^of̟??"NK(&'1<4!#GڷXOF}@pڇ$6}N;7/Ӿ}nPa{>_\7oaa*\Χw9L|Yy"v \raUVsgL_$ت櫼{m72?RqsJaUV}`_r7n\oUj ܁Ƃ?nਲ2N:$ ^Nl9HOKk'#)"##H!0yd;fyD%=m0i2&u.a48(Xt>?pnw슀ָ(>a&<v0mP ŝɰ? #ǜOƻc-^_oľ_AsL>諯)  CFf?r;*җB)^/6md ' ^N<ĽNIIaٲykUsmbHHQ/ ѿ@~A$04=w5zaT4w\ݛxkBr=z3řKnRkUYwRڶMtіEc mY)VE@)d#։3*Zc|dޟ1wؿMZ.?ALvO/CŶmI('JKg}~֮YsrJW56}g3i׷oҥ3}r4]< TI5{0=spFwaģ8t!$D QG9!/k3W},X_G-3{Ga­-1Q7|lݬ}58gOXlwF#0on؁ؖs @E_ݰ/_ڶ}~:̈́'?'%{o㧿KMm >'a{z:J2갘h>~<'_;OV* QTTȧ~ZcDli ^b*ӦM]v@UmV_ۜRq1}o~j>oN1bXןW˖'ydP~yٽvtkV>3(Ԏc߬Hk̴TJ׬ .䋹sT5GǔO~{:#_z3O®P\XJ~}wlϫEh8[nG j0Hҹt>r9zm{n#F 2=--7x5xKw]6sxgqzTB}֚~߆<1F J?IX;rԴZcW۾}{/__[?Q?T ct6,>J)6>袽գ;ﺓ㎠|۶y*@kڧfc9Q!p3sO) M]yeT-2ht8Ploe¶@y9_]r9gWK:9Ja\^ϖ.aF0 o҆/!3f>"~yN;dF)N@ms:·-d܄XVJKK)//8ʀlg|Wt5/R(M8i ̙3~Zk={dȐ!uW/ .h.sZiӆ;Mk=-xڶKxbx yr@͠K.).vVP &Jׯwy4R2uOȍaPq+/Ļekb|t9vpUqa))a_C=AQQ~GTiq8=pu-\h>`uC, ;K[WSғ'OW_eǎ5 m+@͊JӠ۵os?C›WD"4hӦM~īiQ2[c UϿ?9y :MM֘ia%?y'E_}jT^vC0xlrU!Ɨ_Į6jAii:D|̔q ggSO(EhҒu+;BǕ1Fi1ccǎ щDkcp{ vP. ={d;+(** Xa+3 8ls `a;w;m&b#:~s#ZVxKg "CW]uU3!OVxΆ3qJ)}9^{TΟerMdtUepӚի+b\6nO>,>y2SZNsvֿ(i-_yO>oՒJaedT< sӦ*];/}ԗر#G9i/o&j޼y5 NFƍy8V Lm6v[g 6\xoCi HWv^ZA!oY"14Vir-мu18䚫ZS,WZ::$v|M>,?@#نZgibyV?$B:$s)QWTķKn$Q.Weh;h \s5 s`:A&n]D(Iy勯ym{vSc͆\|Et-l5 E˻[ؽ{W5t1 WXw!U<4o_y= K9m숹лjm7zԟ3t('2\on ̔VzZ<{vP tfjj„֖B3?}I㱠Lm۬yI;|ֽF?Aߏ;+Qwθ{,CſË/[ eCֿ*ުVN`=^'m[&? ӟ}vNvv62erxgؽ{𼇨8Xp!.+ljrB]ۖv,.o~3zxXT!ڵoǠ4xѣ;gqo@<2R۷PaL^xg&L`WG!c ]dص2oahc_{t3^x;> =[ߟIO?Arqef<5 el[yVxgD(cC0n ?EYyaPQeֻ؆I7k} -g7Ҷmr!"PJqFFԴuq3^}U~簷+dwIKwJA]b*߫w/:{ fEs 0SR~|Q^} IDAT <,|F/Νx7yV8F?qrݔ3-=vxtdG2 xO< 6؁)99 "z;J b #%g_I隵tCYy%%%Ug%u m|yUpjڷorx'bʮi 03'wOˎ  #k[λ h5x]U~Z-RVțj?93ҹ+4SSqh" J4AGwˊ.իWþzKfu2ɯhMx:W`Fѣkv<64J6mbۧϐKCeҲ] ( c/o+(羐~O9琒>nVƻ};vVjDÐ@A|ed샐rX5b̳O6XA2<ʷmy_m?\SY*Vzعs^@̙z =N֡V֎O@ 2xR0M4 +*_|G}̎Kru3 w _q9dgӾ]{RjiZPl0 ~?;vsghp ,]]G;buO=YqlxuGq57< իظbNhrٌ];}Y^3%oa!<0_zm[®$SG{~s32?_$[7g,*wY:7\i:ucH% Jx23nSr}X8A/رNT8aWYxwp7&~v9N,8),D&[_{0]aK{?6Ol3 nͧ9p>#^y?Q'ףG;l,#FL1$ >Ox<@)E~A>l Xa3t{} )m$a`&}eP/h8z4f_F**r%;~@e0ּxxE6Q e^֗Mن ]Lc8~,_W0æi.gŊ17%%YNS:t5G%=#-$o>Y hiv,DQZce7 v4 vG}V{z/=g&/IFzڏ@@3tLkhEjZ }=}?[ᯬDn.]0p@Fȑ#k%%%^_~^Ŝ9s:ª)?4gO2قRSYē|8m[x"[?W6Y~һt6v,ݏ8Wj*'8@3% ?7CEA+ZַvFaNahmh;`CÞቂ2*BӆA?+`(ŊfK/A|nOΙga(t0=aPk(Zn2o0ʢK.xn|g=8O?{U-SC - t#*‹`ku-+] bDtP HO(}mwfL0=g0sν{`~^zW!;:ձ#n#y| 3fo1 YY\:(~ҥtv5PQ@ڻ @q,K6߸g6 #::xzteF((;߿?;tf2 A7a@qq˾_ƾ}{ݷW^q%6-6_~FQ[lYhLFhrn?: 3pf~^y.bHـ70ڽMQA6mc@h膁(ݿ,y}C }n~7߄HҧJˋ.>&#FzN;gRZ PŲw]ǁ?׹g?$77A ("2y7)޹ӬXW[رdg3T^U MG&5Ae`}ɡ?su֔$4_z?&PRRS6a<ݓ.B]0lxbn).d$IbtՆ,a{. 8xkCQհ[U+̸ۭ^ܓ `k›o[躎 9s&W\vlV[?#` $iiۑD KIqk~^5WOo~9 |T]cǮ{>(9jN݋Q/HiԹ\mX"#披8fQ9ET۶$ L H 9"\Řy Hv;x1suM#㫅(%"YwKTtm6:P?"`9Νq2>l6v=Vf)).(-GZ)=t/o"r'q޹q)$'E?1Z3_08-2c3 ѡ|? ѾmNv¿_+$22 n&[( O(+]בdNf͘M3=:grGGr-5t02#"ZG|j~)}om>Gfa!-Q|wux]Ѯl}-DLQU=w/R](@Epz1Aln j/Oa Hb|][\lM,qyX ={*W("*-֠ iXN:\x!IQo: jv5l6#'ӮMpaX,|MF@ 9wT(.)fb;i/kFQT:fX-6|>vܜ<^Yy @^lmvtMGE^}&@TD6I/ Id"!Jb8` iޗ$1l,Q1 <} /2jTFf8N R˨j0-=jm&!駎EY<S7sp rT^46<Qp@d=35Mua Z(r y7" 04Ν979G5O/hf +/DXۨI&ojt1mKJJٖ%K}_^T>}Dn]ag >f$'*AU]Cv*.[5YC@0$n(l`ڭ%$2x[vc FiI)W\uuI\2"s󉋎GQU4]痵kInْqD:db1%QEILn!6@!`ۉ#..o/V  pڝ%))ïq Q]85;vT5tPwoEnM[nVΛk*jG~zjt߽.,tgr2^|3~6mŧ Z-Yw]N<&MC5 ܳtǍfm@n( Oa¥ϛg.hbQDee߯`bޗ[ÙY~ΆtB-o ktt]r!X$bbf)`_|Έ# h V 4]L@40Ġ n^lKbߌC[o!":,,~oAq2)#xDGEkIfwK| EAqbAv:+:tlxj[vR8阕i"F1O 鐲l.?N (1uߏ-6~=ʙM\ަ[%v\tYwx3뗂x4lVEAT6ni:x())WI %%JJq^b*j&#N4]C``pra`ZiѼ7o1i*5 USJBRR]drƣp;ocj͂@֭*IV+23}CUGbbgp饗UCjo֌~^w + Fne94>0-2JI ?\M HՔX5N99٧q$%.:*Aڵ,ti/7sڍ7,!OA|i-$Agk:~Zl,[̵\SPu Uetؙ@@y >TUS\{0M,fjfQ!UL Y. @dT4111au"#"""h_zRZnC%5a8tYx}RZZjJ(qJ@Ii)%R<7US4մ 4 1UGYfBtt4AGU(DFEV6qq;t<708jջ.&OJndaf`ۇVo$"hќ>з }/A@e3>.+XF1b,r3Z!XSa|xGʖYtEc7UZwQݻ7?]9?P{ a= ^<@Jc !yk*5k?@߇*,kBahhJZLB4AEZli`}xߚZqÎiH6(>\.tUGD/Ȓ$ӟ&If\% ED >DI44t*I6p(bV 0tdY.Wʓ qoaing*8۫+ fUǛ=.A-:7l *Ч7'Nhuf}28b|@QQbȷ@ʸ|4䨨zKꪊ tv5Sgr`"uV@?ɾ뮻h6?5. [j.w.l*F=꫱'${,#T^f!)A lA *1l7En Xd ׬ ho ?gz`DLL4 TEA-(ĄuG'@`Q&OUR]U*VRW wI)n O#X5PC/9E `z (tcp޻uT~%|mh RPn (~i z=>4=d73t4뺎FTTU ǁsv̘.]3ch G=i5N*!I}>:& P˅ *Ae.-o7n wM|/@zn"J( }5k.'3W]Sc5ys^w};+O[4 l11U6)G #1cH4IpQz!6hc0[ǴAA?iL `F77cX0n~?~}>|>)>!TTEEUUsQp W_ PŬZTDrܻ n8ޕR6oڌ,|f ޽zrRTTp̿ev ۍ!?/ykZʼܮR<͙}NuJd`w;pgD$ٳ~-HVkse/x~w ‡~DIi B:kU/R5 j(7t.YhӺ5 ͚jZ:(蒄pf&vI\Hj/f7m8WQbdYfcʃ h7mУG"iJ>}8~VVU,zWdd5t0nW\Q/ݩ#/­bjBn42,@r8 A'1 A˳Ϣ3qߏ;#/lNG7`uO?/<';n_=[lx]-"l[v-1f7TЃ+/jJ>Lff&w^ǟa]q{~J$IBUK9q\[C]Qcdv&!Є dؠ+ dɡM۶A.;-Zf ~3LL UQC%(pJٿ?߯R =&Fʍ UV9dꘒʯoС*w-M84 p=g-Gs86$ #YyU/Crݱ#C*}grr8mP9c JO='Cǧhԩo6&L8@p|;~رc";;\˃i?n:m RZZE$T5_ތ ƌ@D iպ%yefx\4NF@xhԜlzbbcrQ\\Lbbb $IVYE1&;;;,KM៝7\n *E%p6~3TQ+-6G?ZDEWYWur0 ElªBӉhѢIec4kt4?$g?:vDW 2ÇXݬvl|a*-ޣ7!Z,w1QRNH@d;OɎ?qD.4w]v^زe o0\iRudfeRP'9 i9mO#&&܀4M ;2*l>咝K֭8̡x}`M./QG~f!oEr:u!KRX˲jj^ Mbo e àf}=U˄ Z,'b|^l1U Ԣ %*O>vW.cG]~R72S0;v`'XK!V+6+P=ĆbO0ӿhdԩC"IJNNfժUtTc<2pBPUٳ>!;'Xg"=#(_ dU6̷p:""Vo;ӪeKP Ib`ZX,X,ɬ ӲUKgqq W\R'aUQ ];c,VüWz@ w[g*[ 3me!i(f!36y$q૯X>n<{mqjfL rm9Ԉ,NZZZXYSN =*QTTNaaۤyW}۷˅ c6om~?y%Ŝֹ7L]3$!zWhMNɫ@};ޘ&vw%9zV YB?4Q, (b9\;S j l^MWw9xsTSdd!;U+UKd$k|Zti{SViJ7p7 I:,^͊N'3T6J7@${9V\iQF5Hg^^x%M% T/22^{SSٶmpe7$ ɗ]ĉg Eb~Mkmp '{F^~NȄf#,7Il6_(&M_OmPU-XO$sP>ykmj夀Tk6v>\n]%,j﹧V)ߏd3Dw^GoZMdO2?vUɓ'w^f̘Qi-[w}vףfsTf}!秎AV mAeV>;wB4t]#7/g.Fvvv(.'c\ylܸ UaXnX,v$Q@UܞR/o_Z|AڇiBD|UqgeWkN _LqK/%kZj A@)-%];F?4rddzsOq4dQN:mouYlܸO>ЫW ӹ;زe+3s/#66Jntt4N3z=x&mQTTKa/ _|>W_%ِ52A$@PYn=s>ݻvyZ MSQah#G% 2%M/7tAgfSCWul2g>rNH67wUobʯTo{9&|ct<( #& *&p+$t()aOr`Q4z~%O$UX5" nsw .䢋.ɱtYdEkIYzf1%HDQtҮ];^/Vl~\O s!Eٔ#G{K.$&&RRRGUD6}b*3)鄉Bn0DڬXKDi;W(-|wud,]V{ࢹs1c'YV+{rq8!4E%:%NIًv)a}^=!-[ލd)/ȈYH>',z<7V} ̙3ݻwνxbRSSjrN ԂcZH?@DD$@ܺ."8Nn7?C11 wAuAHĉtz(jQe'J:;ڵk=rJۗE0O=Ŏf?bd vԪ){$Pb6 geLyyUFEi%tl2; s0dz|~K V4NWO7 gOpjjsrKUM)ԩ)))f2 fy戢@4֯_Oii)ZK6f .]ʮ]K 0Gx?2Q\Bsla/W~w0 > W@߲4#/mewS1۞s<Q>>}Z(-a`x]xrr̀y+ hu9Y^Y3:\ue݆oU[+gϞz ;wGBWԿPPj%...h1cгgO:utNZ @]9sOdbcceJEB~r$@;v~k{Y$/TS5v2_;+.. D-dV jt!%_X""Xs֨hzOS WXpgfR{C$Gjf0iҤرc믫jrNϞ=:#2 餰k)Z0M M{uDY;v %%A @Uh`Ql˰RB( .H|>=sX&ŐŠGT&Xyk?6ae+/a:A~r(֭[/kQ7tڵ }gѫWp9ߐ8'M6'kGRb(.&Mq߼~cѤXc r7d%WOkP;o 0:Q<鄿p1V?66E1gΜgϞ=U59¿,B]Vn>Dw90tPl4 @h4 #̪UjW}2hѿ)Z@e4Ea^׷ުu$[m #aNJΦMնw-~聀\QDv:WQu︝ǩ:MJֆ >JRDQdƌLV!m[̸ CN@v89w.?=pZm0tBuX2*qk klɱDDk9|ybb QQw Պ(]V}˼yh_MlHC5fyc >-[K < }UDozj|' i"P{=fTH-.I7o>¿-`-)܉t=P^N;)[гhr d<VrD%"Tds$&2k%L{qqN0-Y}Zl޼ 0-ՠQ B@Xj7nD TݽVѫK/+4jexPʚ7nh|WFRRFWd9]uTUEUUĵ>/kj~z!ħm@w3yjZyFoOƁ?#%+WVٷibckaDV{-,y2B$@ӧí֪1c8|0ӧO?#;.n`wfѢEae.YhiIII\ve8c> '}Fve90ʾ*z`Gjqb4Cc14g3 H,X5 [l,c>ԏg\Ç9z REuPTt:5q%#j IDAT^CO6 w-ʔeaZywYx1ɵ ~Ç70%,X|"7~V\ul6ƍgϞFjj! *@WJJJ70ZlVʚbajexx4w5)?ATd_dO:Y& v`ԫYv㍸6 62T zt<)n)=$&q)8Pe!C,)nZe[jE۱FE!٬+ v;;fˋ.O?׸oBBg'**(f׿EaaтsNϟOnnn8 "7rr p饗vJv 49;pYG}d:tN; ͆iXél222Xb5v$BlXC+WmT8[t~*P%B)jdV:o~OӐUsQ**Ĵo_iF HV+%o" ؉Ov6-Zط }нyRj j%o6~n nF^}UF矩A{S_Lb>3ϦG$$$%YrHu"""KXb1bA^yrqc&;vSOVv!IR9~e.#i呓æMߠiOXZ*Z ޅ_1OMA8Ujl{}6Zg>On|AZM65"uP\ٲ6q;WpOH ?/ <3&cG3"P%IBs۵}0rȣ8A4JYN4!,[䬳")) 9S_ 9f͚!z&s ==}g8W_gA 8… OBl~n*m3NYE(׿ߧ3/l#Gb| }*clUAsiDjU3f#r1T<@H+XV{/{`2IAZ ߨٿ}KuNDضm1vvW(g*s=ޥK.Bl6q2j(4_akFmUQY @h_XXȞ={ؾ};s̡dj۵N@ƍ,1_A 2+7I\#H_&^A)8gUٮYnH?eC+W!V]R잿FUX"#th xrsk5..[R #5 x0|a֬Y] +PQ๦i2vX"##nݺ9gXd |1z(q)p:)ucddd 2bHYᯪ*^CΆ bK=8q"s&]A0tM>;>DDƿZ&0tf3T`ADDԫ9hJ8&Cjf1 DY曫"{*[0\=P$Yw^W9jA81e 9fEpןvo鯊`5۷/ ""/A w}7/bu꼮~d =z0$YFv'QQT^8ӧ\p)))8NdYFe$IBr($E!*2m#رgΆ>)jZ@!0?zELLLX EBW4OLDelv;$).*;odU0HMM537܀7` Պ˖߶ _vΝ;Ylm4~Ku(a#1/jPH> >1:ג#d3g*iy{^w ß~OVT_DD2sf\]$I 8޽{WTg[Gi ,^h^{.Ղ(am $3 w>aX2d[.g(!:h(""V ÁbP '租~:&cE7ވ>aHbb \E!##[rJ/^(od3t4ڶmKIhn+g: AD8N sO;? V[*3l#(ڷGb"A% KD]:F¿Сw)-|f_Iy~V/d4Ȗ-+PfOeӧ[j%SSSy'ܹs0mZ5) G1SL!)oA@$h,}aL q(3gr!^=z`ZMRPPa` ugxIzau=z1qDOE %Yb!~?lb׾]|>v޽{YlYYYp쯷C {)>0TcNx>^^/%*‚_5dQ;0~<$ рdgwm٪%Cץ Q b=dJEX=mz c\wu޽ p LDMA>};64\jΝ;i;F#'#1Hᤸ#77rsr!$ ~qèQ$I8NrrriӦqQ~}Z:vHLL F!^HaAv@Xx8f +b:PsVZY?~+#ɲ޽{ٻw/~-vM{FTT1b&==BAA˖-s!.>N*/`Eeͪ)!٧Upg`=&MAJۿ?XǎgUi?<,Ml:gN?:5Q?84fUvK>v)gRӞڵâY_~9_~ {AF(*`6Sx8_BE_9pM֭[3k,~>Cl6f$9rd?h̛7Hݽ;7j :ywab6l(qq#Ȳ$K^t6Xʪ*$)!!$f͚Exx8$a(((>;v`̙}IN/"FW^4lؐDTEWD@67jwݻ7+W;x(ЬY3k.LfMˋ Ef@fa+aZ)).fݺulܸj;^ykl6Lll[0''qq!zINILHp`infVEج}ذ~cu9RED5iR~P !KH1c8bE7s:r3vQ\ )7Dm ͛2>B Mױ׼Oy}>\IöY3mzPoDDo+l|g,]kaÆQ=JΝrг~}ee1(5<$I{ 8~vb,,:]vedtBRR"9srrs%77@W ĬY4"ѣGٹs'}T P@ՋK.!CЮukJc4$,, %+PRT=۹lePG|f٭kB lظF||HKK^z4nY1 FE!&&N:PDШa#v{3fd~-coӭal"H֜ ~u= =IQ绍쩍+OyDe9cdOZxV,ǖWVl2w?=.h[oѬY X,3 /k&L_ΤLի6ҞII\0`X_,9x7l`Æ $''Ӯ};:t@ʹ1ct$ ҥ 111^0RSS'>>H7|Sр]߿ݺ!Zִ!\@ɟ˞V;T8Ȏ;@I?$@f=@ $1qD5kFǎINNFU; h%F־ * 5A?`뫯񟡗pdC/C>~<>s&>K+"0#2:2hPPSl6F\:8.zmlu!,?Y_oԨgfѢE2HJJJXxq52t̩E^HIJKcAùm[칹,i9^Ǥ5YILL,SG"##i޼9=z+5A/ؾU%dAKehFj?Z0l߾z@J͖BgW;ׯ/x`0`X óNUo a2PN!0軞+-|V Jр'Y~=4ޝ&жFb?$ f#c{v 3Amd=6^mq  O5nI",>J͝Kdrrջ,No{hMK뮻hѢt!>`1 (AjzGOlJH`Md/..f-4m곚d2s +, [B*~j 5ƻх{GUE%%%3gEwdY_':eƑS5M"::Z;$2220 { tOvݤ&$@E7ze#I֒ʳ@*9'׭i5j]z-W\5!PZ^1VW?ro8JfQrHZ]}:~+2Vkvh Cʇ=54J u ׻IQl66<,;}/\˖-?~<-[$&&j<û˚5k~c]0*-M3Bh\a0p{6\ev|#N'aÆ$''ӿΜ9#SRttV*\Znt,M |$Q*bu6 bԫW f;S ! /@Dշ*9{>˖qエv 韲r- O 2%<#/FQĶH#,.͆p:srݸ"#W!'/rDSkJ)2ΊԄu]kh4ҩS'ڎ&O͚Pi}gpoѣ{,v0۷Өq#M(BAǎ9r ''GdggWM d*6Ǧ~xVj('@%P5= "55,ILL1-jbpu=g48P"AGq1ffcDGl0 z$m[UC b0J`+~*;8] 3xĄZHg<jݖ-[2k,ׯjl6wux LQ1}{ܙ汱EGhÇy|ֹ&YI90 VCس#,уbz_]mcbb]UQl$j'@w 2&7χ&PN`ugZh!:wL݉"))RЅl6&G )vV) z+O)SNIZ T1}b04ּ H~M#d::sl zRΌI7nW^y%Nxx8={ƣ>>|{M Q%G/+l`t#܃)2RP=$kލ?1lz Ԡ] Epנm޼9/]Hn0ƺu?~<˗/ %2ǻtΝd!8$6mbΖ-df상9@Jn1 J+%B,Ѯ];Ξ=ˑ#GDAAARJaB1wONɋU1N",aCݻ7)))lْ%B6(I=/i%_㳝j. !wt@~ ?5Tf^sʎj* hd…8Pr w'ڕCX8  E]oFNN}AKϾ./SNdee|rz&'dtwmba0(>-[<$ 4PrY3}:3g* L? d!} d4b1װjʵ^K֭q:8q%KvZڶmVPyѤI.rmf6j_qh=ђn_-[p* y@*nNtuK\e3hgg>Or(Ջ:Pkdd[@d4PN{W7j V2g)))) N2VRa(/ ر#IIIF}o<;hr\<8x sA3;vգ(9sXK 2m ,C+%_N{SD[l̘ zhb7l4sB>0kVzp_lv>uU]v1sLVTs#'Or_OXw/ | I`ݨrd%[&--%l1Ji[{VJNnͨduذa4jH!{K!ʈŅD="**TAh·! +v;x?ޚOxB"aIIHLɓL裘""V濞wslfP 0qD233)**bڵ8p ?y$O?4;v')))_ꫯ={6 y<#ڴjMdFAx>\.ǰ0F`p~RSeO#:*B9z(G i7>:ʲf*\υ(L;3~(-^VRbcBԩ餦Q xJ$eL΀+(:qYYbIp"Z(i {~>XIMe+/-Jqv6Ů`Jk}!0EFm?u7>5aĈ7$I_~oߞlw8m6{1ȑ#kDW^aΜ9p3oؐݻӷImkb4bۙs'36l/P4FB܊&t1ʌR_\zHOO]v>4炸8P@Q$**]lU~+:!(((pG#n E :WQ|kNg @_4 #Pb/G'׮Kfh>昘|`0ϰK):v GI OԨi3z4A?㗇&gϞyӧm]`eAۤIfΜIZZދ#::aÆq)~7N>9@^7߰j*FE߾}ʁfc֬Y̝;$4у !bLQmܭ[)q:k@!NW xQٳNjݯ, Z׏( ݺuСCر㜣q(fUIXsG\EQP՚sj5@|/{P!onhժIII^_^\q*(h,m% @eNG6v!v}!>;[BP?#kNNpd LoC* #2ݍ)**dѤ__YQ!0EEqz>O58B`PT䵞^(ɚ$ YgPǪ/5k \/V$Ak&_k1ǜ+7zK_i=|uŕ>]XhwuW\ADDYYY L&Æ cƌwy$N8ٳy UXz5_~9)))kDF^tOfew Fr7ߐp!I", < / 5]zꩀ 8_Jff&mڴsDEEi3{2N- }H5WU'] W,A}iTر#iiit⟿y7$I8TUK=]"N$In6;y믓Z;n䇻dChU+R'A>LbY>=Q?/@ƸqN#u&k׮Ջ/.2_\߲%bKw3 KZ/^X<&\<7)kSNKK}t\(N+į*F_N$V襀03FiӆΝ; @W[C@@+etK$d \+ЩS'̙3gHKK?gżKAyG~~NN=w#NׇG~dӋ/}xG$J1l !Cʌ%Oݷ):RK@el0Wn&&t>YF$ܵf|Яf˙3 ~6P?-@Cw7%=KJJ 5*w5w*NwD$ `P'FHI2ߙg0vDXXqqq"11z]ݎ*|R \>V ܓ7tPZn=m6SLO>]vAԖ/?̗#]K0ELQg_AΟj7lokrж _s b6iRP=z{ѷoJ;vnݺ-k6 .M***bر宻}vƎK6mQS{ͼz4X4`0P ް 9TXU.sKIG}KTT( 'B#V DDDhMTTedY&P)4z@*`RzꑐUTT _1T7UT^GV*6InQ%!![n%S#2yyyƲh"~f̘ԏ,|$-.'W+j xxSe I~4z MUc+ (8v5ϯ1"Άs"FFF2eC:@PU.]PC&..o .>JNެXiӦO?:6={2ys$U v(α`2q'w)a8P#]$~G̚5 󗪭.^zʑ#GOZ 8Rk:_SȲ̱cjdR'A~V)pyrHovMNɓ,J Nbw?HqqqAҦMC ͚5G)yBG1yd tJF~(+g0iZp j ;. >Mh׮8拹N@ӇIIIl޼ 6e1X\l"Jmg$8qNTS):yϰղώ>:H^HNN&??f/j$@sb* ;Y&_4=qmڴaСAqUUgԨQL>ݷR(l|9v/^y3Ӹo_X;BQhثÿ۶VN0!u-c]!/^ jհ0СC8AUURSSC,hAA/2O?;5M&df\osj2q&YϮQK`pcRF8h:u*l:z8::޽{ӳgOTUeǎ\7hl\VR$J*NRTTTSQ% @UK#xVx p9"""ÇӨQ# >kh}N+fakGNh4rw= vJJJPU~?SrУ"} 2k֬adddТE |^Arr2Z:#G0m4yN'F#33ysgb46 }a\]`pqR LGDkVˤ,EsBfA >.uֱvZR@REyBr]ġ8@M8 I_)`B=:t(eD3|UHI\wQpPrO8'BhҤ }_~%>lP^5kt`^w}__6(7H{)sڞbaIM šY3;AKINNvM&6UVk.w0G.شi?;,*;wHh佝;q#de/@8~~snf1EMFqqq2LmۖtvŚ5kDII Q(jSp!=gNT w_!h޼9-Znny? avdIvU됴(;-VI8{,k Ϣ=Zy٠(Xbb8l/Rݷ$wRo Ԗ-gإAIԩW\qE>Dnn.| ?3EEE^5C׮]C]t|7mۖL~'z&'r}{-s(؀۶`7X\ ,e@s7^>CslhD+;/k}XCe_ߖWnӰaC.6l$K8W- T8NN4SS}8QQQ87׷g:@tAy߇nGrEtiuKSG8u/ƌCrrrHK$IBQ{/ jSg]ĩMͦs/B:ķlɐe/I>sl%$%h{u\׫d0:,Ao̵>\uXx1< 6t~=tK.eÆ 8NdY&222$:^uٵk#[`ȑ~\޴)z5oCWsG@zhTpoQ0 0-(F=ФF"K j~ϙ4;NqC3Jwc\$EH8q(* XuzFDD`'"G@7$p{53_r大3|j#3JDqq1aaa+[iӦqJo#!3{4,qqkPUFbƍݵ-[ۿ{a!qD4!uZbABf11cǰQ)2ƍ+p˾^|;vUVQXX&B۶m۷nݺqחW0c Νh׎)ݺ "B2g6#;7o]WGhݮu9h|{cD1=[5>ٿh(YOM Iɺ7p8 j-&.(8N*:A]'3ຨQQQ ,<9 j3 I L-u#$qc2D ,Kzz:_~%-W^ sp8t.{BQcXz#H2Át"E3 !f%%|suVOOO穧"))Y򩉉\uUl߾M6a:FΊ+8x \s%(8pG}O?zaaӹ3v DuX,r37lۣG->MNu`upp 0hҤ1%%e]_tڵkQhG:w]7~(#\&EEܼmr4Gˏ'r &=#*3y.Zlny"m%l k uQ IDATqG f7⯨'${M(Ec$Յ*2ۈ yh4oziInhѢE!k#G2{dug4>3e뫯jtt4SN{X֐qEI&׏ /%K?t:*F#Ge֭v$FE1Knip +a6s('׬a}f$GˏWqf׮Im~*g؄hԨ!e+hldE+#,9g"{=/  tEuonYY  T[3cx8[j$ԺGnCUUl6[ȢGzIsWseL&{e֭vf$&l^ HI ~(`)]_\њMe/E*p+P\A%Z@ u; e-f@s]_CNDDDP$I5*TgpGH0'b`0B8.Z\N6wCy.t:59.ւZ(n6LyA$I_J D~~>˖-#55ݻ7 'IEEE4mڔŋW_n>v-G]Ok߻{]d0 ~r,j݄f̘AvB6BO|}ǽo햔I^>|Yǎqʕlw}eI^=(Ӏ#ם: F3HV+p$!4bR{\'LR^ w֕ ]VUȠRzԚB]r0ـ\uW  fpF|?_~/k$uG+Yf!袋܊od2qq 6nn\XXȀꫯ$+㽅ש3{A[!&i{x,[VZ,*Ak׮eFL40͛GqQwmK΍7Z/I`0.\Ȁ%K؞4MM_V? ^Zs͆>\Z dYᰗʫ]WL hi_AjKខ« @UK{PUhV+F\o>ЍhzRUխXFJ4m(plj ;~3&舅eJz111ߟǏa5$}vG.]hѢ,{ᮻ⪫b٬YCu8u$<;z]P!ΩŐddfA˥^%\R-yO!={0gϟ@=CLFc}s֖-3g`A ީ_~DDeuF׮]q:,[ E\\\,, ݺus^|9< @Ө(ݛ˛75Oq*+o܉յ[F-{h4 sH@ xRvq+HDv)rΖ̗esGu,Aμ$I8VV>ZԺgĸ#E&ӧOtRZlI.]X,v֍0/^̌3"P=ΣgFZ~l3V+w h3GԑATRhF_u*$(h>ۯ/7t3_{:,I8΀@c{uq xk b޽B_Eu*M&YYYt`0o>8@FFZ`0kԩSC$hޜY=z21aVhdٳܿj;huvO57T^wB3кK_!|&W^wM8u*RIpc#;o7]q8DEWYP,ڵkGqq16 Zƀ+.C 4YQ}T^?ڵ#==͛7gϞN!wߑJnyjץnݺ_p* 8o ,O;"{떠8p Ǐh4bZݳ&@FFlܸÇWfɒ%lْ ȗ޼gݻvfʹܾ%Jl[J\f[nO5Ts84!!hSPKzB'^VTbbBEטUf?t'|$@cs1^ߞo s}"zZЍht_‚Bb8:'n3_^$ AY旜,jSPӫJrЪU+.Qi3"[oИۓSؤe²ϐr0hw6 ""sϭZbݺuJOq8U{_SJO?C/(*p+zFB@3 U[V`0:.NgF@@@IRXi b,,fb1$m''LEV ~Yλf: 'Jرc[€3O۷~222HKK p8X,7bKϽ2(p# {d穧j$r[ڰa?~]3{%g#cĉnNHKK#55;vcF3gΰ~zw8:wΝTG~_1dg,tЄon n6ZE#?x*4簭Bm5Q_V(^9T1=2;Aj}ܴiSv;&L& ܹ UJH@yᚂ^QXߟg <O^˻m!Z@,0㎪kfr:M~3>\#:S~zRI^_ f3ij"o߾=lڴ{6ߓB׮] 3p@X>?^OL5LZ@ &[_{uO?SU cƌ[nAyV:?sΤm6V^ի$[x.?{UϽwf;HB-W! "bq]t-+U]A BPwd2ydmsڶՌz?;7o{S*Z;!4t4K|lC[ˆ):+}^RZeA@e眭#P$uO?UUE{ @ڰaC~{@YU @Vmn;N>][}o YK@heL{:_(&#O_]6U7o'iaM&# r3HY=sv 1zsZ рtիm۶eÆ u$IӦMڷoO?Fbڴi_>{#[v y$(IVk ^!Haa۷5O?MmAֶm[~aڴiSocԽO>q/o҄箸`c'oy;6 LXI){Bob_'Il:SgqDEwc:[Ldq~3ԅ߲9ץ R9iLKKiӦ޽۷x`0l[{ңGRRR| 7UVVҮ];f͚Ŝ9sPwn>6c*1,vLQnD6J]2,#H,ѨDnr[Vb ttr)G}ĬYp8It߳$`In;vq8'z_'U?};uq ~^ETs>9F}ן'E!222$@S_-WZZZM WU‫0o^_WIZNH.pxݺu;/ꄞ dwe:xOx/7߹k~a%& "wgӜ/'Iej*0t__9tPTwNBB{dZ>|8C weѢE!߫s{rn^ڱbb1DAtZш(ic^^siʎ 'OfȑT6L|̘18rǎ}Z̷^ș e o8UMhjw \nD'Cuṃ# -.ʊJo҃,6{fEW\DEEF09:$I7KUUjΝ hztbq *Ε89ppF#?yǏm6zpDGi;Gnk'_|רbe[#:nCtTp$lAqxN9"!W@>}h߾'((( 33Ν;c4eY`0O0zh^}Րd=a++VVJIB$MW\Qo`0xbf̘AV&4Jeƽ_ p&[JhOtp-(ꄻ꧆? jfY3-jQ@QKC͔jo6śT;,LJ{"!&&Es\])7_(ŹW\\9xK@ζ\*pntgwu/7 ڋ-[PVVƒ%K駟l.c+a/X52%p`nҐ}q0-q Ӭ=N #'uD{;aȐ!׏0_~w͂ طoKV+M4> 4.bccykU (e^}U"Kg=CN-xF}-$NFgr"?8Aܹ.( ^.=sDz@3YhzsHV4_+5h͌uP9-mxYC6b=#ު<8.=@JlI d6/(kنCC&$)cbPFwtPQڷoM7Df:zY|9FQo 2jԨ{DQ};N:aِ$C1|vΝs3eFt~%Eaբʎ 8p~o1-gVW|5In="ZB+$4C0 Mulۂ>Ƅ$UKz遢@ >GEE]_j]O***|#GBջ,'Bwco۱X,U!l׾z 7h}u)A1p@j Qټy-",?k.rrrHJJ=QL&:=7AQQ1v#Yȑ4^LA1Ff濰}ݪb0+]"I8qdffҵkW$I&MĄ ػw/~)<XZlIn0 .sN޽;!IAWTT? >}m oq0w&Y]G߼$Qp֭Lݶb7MU΂fA#*ZuE\rn3Z͸Xŋڼ^ ?T/F{ߛ /@mW%: ;u(>W\-ltw Ǻ;T::[]V? NDDDPVVƱcرcӧOS\\\:UL&őFff&͛7'##%[nMٺuɠVϜ9Ò%Khժ;wvwŋӣk+|>)Im ONā~9q.h\~ߌX 0_M>$ (4E@7QH}BwVi>zK 𜷽mnkQٗL@DWпlY ze_f>JN5p8@ :.@аaCn喀%&&2p@>ݻ]"N#T:R/S(-71ugXqW[>w\`͛7'''0ױ$MEӱ6j|+ z÷ƙZ?9vFٰa6- ?`߾}.~@}6٩-Eqxݻ۷TTTO?l/Ab +g>w`iAo9huEr1hDO@6XFxsW3^ૹ9}-?y{jHpI|??%B jVڠR$aA m޼9C%)) ł v{,MhdQQiypMdΊ^,#I{ovӗQUǙ5k;v쨖:mvA5@/QEGt$]'MٜYyW%'‚*KJӦM[СC qF~12UUbj*ǭ[kphDG2:BA;;Ќ| NNT\&?e6q,V#J3h͝Ԫk.ԜE_($@Qu=Q%胢k=U"WtUXE w1}AK.\uUHāHr:{hLI&S) jX=Pe[ИӈQw1߻&Mp7ӻwoW{g_-ZDIIOd$ng. &X5KJ:AS%w#Gl|z>R.GĠ9:p@:bbb .dÆ 5Bk]s5\uU5fyb4oꫡU Mc&>־wP?ߌV:-.pO}ᰣW:h"[D@9} Ub4K|ݣzt s1- P\a,T\p]Vo@#xy]LdZY=ubsx}aje6~3337nZRU0JKKo_\vc 4j=3m۰7#"jD TDEDeGY5{::v˓ i8FE>}0  v w^̙UP FEܹse]ZRֲ_&\hjuu䛍ƼD3ᰄ1<+;wczEN}nDA(P-E넿{@G'@tHZu3w:Y"X2EQI;}_w%@V=*83jֲ}ewDLn ѼLN|z2[̓0G1nºD^y}ϡ`4]р*q\Ջ;j*N8vxx8yyy:tΝ;ӱcG$IB, ~{?|7aEgo,+@!3“䯽&DU֠n Zj֭[ٹs arssΦI&(*mڴ!99x+OΝcs=vs"elÏs9\IE+h>}ơ4FN4Gck;+* * vF9Tiy ýxFBXU:Rq\o' S/8 !;ގ>@JKKmM8BfwT]HUVUXW`ܨXƍr+*YX *l/bgzϳ/.@NR_pEt{p@hqqqH@|^<ͰkҿhA]kpֳ*>pGDHE'O9(+SYEc~XU李F2,)Fzo `TdEMXmڴ]vY]vlũXp!-[G5dlUIϿ$nAͯ͜|Sa }MR,Mhj3AX,r7rA6n܈l׿{r!W 5n$I?fҥ\#?[d`qʻ Y :ϧ-~ /> ||.I_UqMʨ5A ;9TVp߿F \?\@wc\RRRGj"%xFA"UWqYe:i]xr6M'ø{TёM^gH6=>Hgx$1pwތ7XfF^^sa˖-. A9tY5{6DŽIbMn{'{rzw& 2[izuj%==ѣGӥKux8e$2c $p$"Dx<x H@S;\V(~}8_}ߍjiݠ (Jտ7}9ȀN!o`Ԋy/ϓu/ .E+UUQ}8K>SMHxLFੇ۲hu2iMoJiDNRVn֐Y1 6ÇRT.p`KLd׈D{1=G!!SN\FYՅTU)5Hì;4]taȑl2Er{{у@o|3?oTx/'I8$12Vʍ24E$f]wŎ;Xz5>Ǎhtسg={tH+ŝ;o/Fl߈s 9"0Q9f"ti >wpvIIvQׯڵc~W b~~>ͣM6tդÇpp$G1\/$-P e^?ໍEYSu>OnC hvGo?mV a0UEQw7P*Gs ˡ\&T[{F> lv CUnߙQ!+ ZJ_A8w\}+4O3r۰x3nsljl]CϘhfa"]fff5~/Е7oW\ALLIDMSYt q)х}{qdci/,߶bNnd#Rh$*͐`p 9r7RVVtޝ֭[W#L0 H6?{3ھuOqut ekҤ O>=ڄtXgjzpDWW+TlV|(t?IIDSYYbbn^)t)Tr(++cŚڞZ'x.Q"NmMٹ)wߚ tnwPQ)"*ё 34/s_$f1#뮻quU՚vVZŋ9}tл5)˗q|11l~l}oDȣ߰1v Mh;b&%dO1y 4' ۯ  7@ So0 3w\6o : /@nn656n;A6IB*AR6n FpIl|ls^,~ Zhv~*' 8{ѿN:0mZ Z%Vΰ7CI}^wY>^`xuTnv=犉 3 @xxXm^uU/ hØ;nU2@QQTV]=Eξ;yc5%ݷ{T{_Fv LorxMW={6'Ofl .VA (3oL )( #-++8}Tj@o*պukZhPd2QRR’%Kt9ݎ9 +iUۤg1b4i 0`ڿ:SQ)EzbMj@[/Z4cll,CeDEEą|}vIسgsΉ޶}YjkPƮ YGKX JYϣ2x㭵hB:јh ~+ьu}tmoDk2Zɓ)..棏>BQz8vw- |dYb‹ϒެ)PYi&**4bGto n#<"<@Lt4.bᅿ?np/ӿxw>=EETTdAE{[ ì]F~LƎKjjj^se1|fv8„gЩu99IQ'^o3-ӷ[ 9ːӻhr}{\SNa4z_ hرc?~mҩS'WUzS6ч>[%T4F;Òq DUI+k{Lb琖Fjj*{a(7cxٳ] ̜9 }z?7qiPie}u~47a׀47;OG DcjU4F4C'䩧v'M78vEuE~7>.sX_iCp#iպ++΁>W4WҶ]߰qDFrK522o78OdNfC=WӻԜ:D@|3Z/7!8v^t}g {ؼ)?ܘHiI:;%Ae4 GG$IodСAw۵kྊd;La{oQFiV&=3=`7_p&TY ȑއq,eb4ם3rH2`0~ٌ`O> f (Wy B 8N_vN{5hV肦7؊Vg_?(FK)\fSRRx7gfWZ_пv-MTKR5w{-0q7u}Bj." K\|5e5EF(B~W](9>ތܷq7X@mPkTU)P[D^x ZlSN[z5=˖b%Қh+/rhrzv"93+3\RXm"I*=wA=M`0l^EqiW@X(l JõbjC1c1-(UҾGTm_{={v@#< zINNfߝ`0PPPܹs9s&ӦM?@2s/{r~. µ=``!J-~:t9qh:LVVƍUV./FJJJXl+W±#ib*Z4Ct8hX0#DJQnHrD8 i gf]v;\s5 4Hl6(Oee%|I@B?> __>ZM/ Ek Էo_.]Ν;;}gm۶`N;<`;gTQ\ >!=/2 kQYwxðn!绻E.  356d$'O擜8cȲL||})&EQ3gM08v|L; ~)%U|Fx 2d[laժU <>3$}Y@f ˍih42OZJϮa,Vn#`89^h Yfa2kݻ7o^M~w> Ni@oأ4LħIڲccq7LVVVƗ_~Y/ܓSEV.`ze>fufU 8 tM9r%Kеkנ5eʔj}5W*RE P-T-TOkJZjj5G9//vڇpӔcC&#YHǨ-.  b082N x[yVx +|UX"V QF?ɓ'ӢE eXz5=+VQNL(*Ri&n/|Ќb#,>.A_j~~РAnz 'jJng͚5,\SNRP#(Gs%S'06Os`/_GohkMOЌ5ƍp8?~@+X:\oY u8fMhMyo]wEII _5͚?1ر?0f?S)K(TGsםȨjTVL& (`[\ٳ\FIe6Mc۶m!*-[II ٳgnJ f @pWTEFSպOf@[fɌ?UU1c_عsgMahj[0^DYLۇҤowX8lI~mV+mڴnsKKKYb˗/*Ӂdf!velNFlUώ@TTÆ cΝTF+¶mS̶e @[ 0 C귅O 2~i(Ջ#GҨQ#G@~'Xp!6l@UU׽mv~}u:Ae992P @$/yUU]h}JB%Khs$|Mf3J0 ,~pȲơP|ϒ@o@i_ُ,6W{Slwu$oV-pY8%%8UU~D3eʔ,~:MsTͳݳקlOq!s)r#zB\ sO:?`ʔ)3`zXX?HTyyMVxDѳgO:uhDrS iS<' s]! J06n_ϠA{]gΝ [|W{/K_DD&+:Mj~ ̙3E!>W{ *.hiQ`20BX 4oޜ3fp&NXK+++sKupFKyTQWoZ '_@wWADB*sjTtkސ v'c0Q))-Gh4ra^ziI\y|yBGޣNZmk/\4>oFxꩧ@sVZń C>_rrc36C4hLve׎\ K~V>>h?':Ra>ɒU Y$)\>oEQhԨm۶nSTT(>* `Z9pQ3M!vem[wp*[qʞM$*Sklaرdee`HTI(Q8/ݗpV'ć1zү(&d|Y(`40M,_~̙3^x-Ze>|qZ^ʅ>aVf)i)8vv;6 @iiq4o¥ u8߿sg2x.( Np,~C&ƕ hw~cޢ:5z8%Vk&9_Þ{ؼu3Q"1)1nWj&,<{﹂ y#Z PE:ˢg*X)w}'֋@;wfٲeXӀ y饗h߾=ǏYGv=N)DQD1H2κSM^=z4cǎaZټy3۷o$Bt"8R`f(l &Mnu=z4/YYYҞ|I˱!Z3 WG@:{ϕmڴ}hޢV2{,n} իLF 1s&Hѣy^wvkek`r h_3 a" Tܜzā?>#FHWQQQ9+saUU L8Aq EE|r2y'D4H9N |M"YF$$fA2[(C;EHWe5jDxx8wq>l6֬Yŋ)++sBݱ)'^^ IiF(-֨9*u[G`b߈&#ĉyIKKÉfف6\Wy1 Sf]66=+<' s}rsL_4Id2QtS h0\,j1<9鯡ޢ:R!۹&>M7 f9<<}wM2d222?Q]ݍ l2+hNRbP(__(PPP9`L^^^ZW_}}vӡ;hz+W_}u<) xw#? yfQ~-y+SIw6CO߿[Ӈ, y;ݞx#Ɓ!8dJ3o X07N'Gni x૫bwaڵȑ#G8}4ŔV6&BkxlO͌#1HxV'Fa"B2ь|К3Ë/ȃ>3W_l;jKaέ-.dw|E-!޻"RD *'6Sp|>c*6ٝgR'lLvQDDQR[+$$;9.MSгw?Єc0(((޻٧DEEѵkWʤoiBA~ꃂ2338qb<ibcc=)((Wؾ};}Ɏߊyhm'"rn)%-[[n8N<0>d+Юo0p@XعupMt~m[ROq)%v#Gh5x饗x k̛?4@ @ΝHJJfcٰ\U{@~^>t7faZrrrؿVOf)N} BBB h4Q6̺Nv \j(T[@|BkW{q2g2 !9:-i:**.]мyr m/GC{\^^n/!**f͚! HA~A~.W9/mƅ^HRRRA` 11?ȁқf͙0a[DJl&,,֭[ӭ[7zEi׮QQQs2+EF6l9Gxhm2sRRR*=1͹2d0t^Jl 999p80\s51RUs/=Fh_ّD;XH.<ht,uT!>\;v젰cIhh(#Fs򷇅2tt[%s|,Y{,M?vм jeʕ믴hnc۹ 駟ؾ};[n'##ƍc5s)vbРAM54.GͰC(B ʭZIZƶbQ7ny'M())];rHzFkQe'-*}hx}7Ձ!Fk*fcz^}ՆJtڕ?UEh4t:yϸٳ jT`仝8dc-oEsP(6 Oѿ{@1߲L!m}t֍;{n݋L@qq191Pct}eOE8;Zpkt:^8ӽ!*:Ĵ+Yf̛7C裏CXXXL&*}7x#C aСqdee_ܹs߿X[̙3ʕG+I,ԯP,oEY)jkj4D1RJ8x ȨBBB@[d-*c9Bp! EV]va21bD ` ))#Gb4INN.W0XV6nȡC֭aaa^bź{frV+NUvV.I,=}17>iMEFq8`$6nmCN=711;RPPS<Bvލj)>"$~#Ӵ=B"rzwa$ilZ]z1rs/! g^DLIUnD%\B1`ƍٳg/,,XW_UW]E|||R[KTN]R;mZ>y=Z"),(YP&ZFW B@@AuITT;wJhݮC;DFDb`p+k-y0<4 M e = 1LٓCűcp?'??.]L3(Ɲ(XL'΅ek"7: 3I>ڌB#6nayYtl?}tb6ܹ3m۶ԩSs:[رlNr{v'}h2vmhGcc2 `bĚ7d!'\xv5JC<#.W@ǎW^yeDu4?=kDRRv/]K ,+JPhNNZF6|"+03,$)*Y9 H?0seɒ% =lْ3fpBB`6ٸq#saӦM۸6sƛvʡO?Mbn^ԍ#'Bt ƖtJ,d34v;\|Ō9DIIIhp)?#o&999'HIabWU23p|g܊(@7߈>8?P(Chl1==^OvRrȓ3vEW 2zccc֭'kP۷ ڷo1;N^D~-< {gĻ"v@ut#}%1՚FHHcƌO>l޼ -.Z;hݺ5[nz>_YS'LLlKb$6;6{Y˺&^TTbm۶4 @)P@e)GcMYp+N7eAr6Tݏ=鹽OmTdZbҤIfm7>l6p8شi{}"C _ kJ Il͆a޵jEEX /S@.t6m2n8ڵkw\:ͷp؉#""Ʉh`txiJ~.]vofPi+"++7|-[T*t2n8&NHddd맦ىDEh}!=(9̩N'&!dh$##[Nf2 7tN?eÇ= NHLp;c/cG!5bcZYZXXȈ#2eJ+_5cǎ 8 r.wY}svb"l.%Tl"B#x9m۶\V2AGe+25Zk*iz_ Sos8l`n5ROn:[hТE fΜ… ILL `4/;w.6l;\qQFR|O/=9r$:tf7pX3̦eMp8hٲ%&L`̘1Fl6_g}sr'Uw fF=!W?]0hXȃ 6?Av|@!>}:>,qqq_5Hp0gΜkVDfm/?koSD)hQ*K/2 ťԥbz>J׮]YhӧO',,odf+poƛE;n+l6ӭ[74DmyxJ'f!p;@>ދ1VS޽{O3yd=qK)kU%33E)\x6i vv(l 9S @@H:u*jcǎb2YB r 5`7ҁ%gyf+Nl hwތ1 RRRjoܸ|:vXz:$Z86Ķ$$v  9|1bg,@0$RzOjׯcƌaС۷4O.tE?/e˖$&&z  ! 3\ E2 п txYEZ< DYnݺq饗1L )Sн{*_s=lڴ)а_O:>Ĥњ˩:݇-UEV+&V-[Yj[Z<A5^opTO-6 fiZip"@88x Y"ȴJ~ 83g2w:^4oޜnd^yRRR*ײ6֯_O?ĤI1bDB=GЬy{O tJ,fgQX kQ&c.&&&dnʋ/jP0 l6y>cf̘A۶m]wC+֭sx3 Bt~B->A\5!  W7_~i8@ll,&LujΝ;y /k& )ǂ*}岾hPy]Oe;ܦMƎsҝK;?8mIf&BF1%OD f3'˗ZE>$,Yµ^[;?oIaa !_GQQCnpF   GluՊ rYfE Ͼ rVĀU~o4mFHH}VUe|ׁ,K]NߏsKIPII;O;;XȀ!Dq:%67rr1VXt)?=]YjwU#< y<:Xr( ?x-dR[+-}g_BX|9 4,Ntkf{hV*.Pdw<\V n F'YPPeڵ+=\]̩Nҥ =7x#ůkl6S\\ڵkYh;w{P,ٌ (,rҭ^[=\w* Bq HBU#6lO>$\r ~]HHiii̟?gyƷϹS fBd8y+K!51g&%wMGf*NGaŊ5/ht_ g-3CJS-E`Ϟ=?I&:V!ꫯgϞl6bw^/^kFNNҹS&F2hXŒ'Ns9y'uO1sZ39.8#,&&ٳgCKQQ߲F>;m۶DO(C,YǗ !$# 1yCE|?;!4'3΂ټ2!gVu|wkl6t 7PV)dhɄt=bȳ#>$F߄1$tFَ@ /ؿ42طo_ h&Y_Իݧ7qa9p8kOT[1tБ]1WuSOIIoUig UkV> v fzjڷo?_sSt²e˸1%)%"J IDATʫʢEرckg9drp-12)JFیWO"m+_穧b„ }!!!`{9ߊi-c]eK GWFr=,&qM?awW\}լ\={RXX0>`֭y|'#C/^믿xL_"=;~"_l;cy8^|;vB_e3t^ p*f-3gw-[l!s[n]ggy/o, s"z 7{w"_ʃΝKVVVaMKصtiM W2fQ<̓EWeMTo{wnKVj)ׯ[n̞=wkZhwͽK6 ֯_ܹs/)6 [y}F,WVcvFzˋs3x\|*D$?޽;?07tFf3<YsSzɊ+ -->_ 1p݌oK9ik Bʬ60;iZUwJJ ;w`DFDb41LMF B`p72M&L&'ػZyMU} |۷o/ѣk{>un7`ӦM6!nӷo_ڴi8_vӥ9m)b'k1 '|.wTFNbڵرf͚t:1 \z饌?޷}rq @dsΆ)oFg|ꪫ 6YԻ|ӷ7=zvwp˯jf 6 mѣ[2.wߑV믯ZTrHXW `Oe+z5q j9˜1c?~|:dbԩ<#to!!!f={h"PPP4k+pt\O6dɓٜ‚b1 `V8T˜9s?>111~OњKglٲFx6#MZ;nZ[dtU}%@Or& }0#y,`zh ?̙37..sw7X|̛7M6PrY̛sٙͅ/) $D0t`3qo:]kR|q2*VPxG:ujxꩧXlY F;;ț rE,YBjjjag&l nW{dvh:۝5z;v xNʫzLǝ FmO?4aaa<3=:\+hjX(**bڵ,\{VxN,A][T?KeO;i?1& Q|BEN17RcѬ^ѣG>|ŋ}z!JrOVjĿk7<Á5MH0\ŴCgwz7ojv;Sŗ65>E'xE3iyYy=Z>42e ̘1:ꖋ/zc BZZ>(WrfJ9ݛNanwYn9KOrA{_9{HH]w˗/G~eػw/@<0u0{&XfΜ7Q)N^ѹ/`SH3tZ+L v^#ESa9rÇ3bzjt6!!!/f͚5=zSj4Z;v{nƌ_^v3-ŰL2gf!iEr|#6~me !2«8G1Cnݺ5wu{W_%##ܲvS֫uͬ[.а8xd[vLxӦVzkjMxm&q7ϰajeHIIa1\&ѕ EMLcZxEU&ׅFǬYXzumϥ^غu+~BBJJJ䪫bȑ}蘍vztj`Y.B3ښ3,k/$"vl_oCLt/?RҡCz׽{w@Â{Իl2l0 lv66 ݁ Nu,r ~`5yFۘ+}Gډ߅gJ鯙LJx'0LYS 4'x'7ٌj_f4ҎIfJFn'7>ʧg ?mOx hn+cz~ h#KbSǏϪU=zTn禛nR]yW Fk1xm*?4O+g.m1zMRZa ߠ @=S. V|`tЁ-[IJR#.rx =\Oa0ͤb VZɓ'^xU$;3ca[wZ}y\yk+[c1>st}c'g pײtRvyWj宻S } q7 N (NZihrn7UKsVjVn3&48\U%]: Rs{뗲TjYV+\s z[X'1 L8˗3l0*ZY'N|rV\Ifff׾֭Ieʨ _'iľyV,6{e_|ρ5GSYt޿ٗ<.&@2`̝;w}ׯ<}ϖ%̙p:ɉ 7]ET G6OV6mZ>zpYfwzdllIfIhI [o+kj)^I-jk:Tk=EEEkq饗|裏(,,b r8iӆSҭ[?xFv. ` ŽNas!'ni7b2"666аk/JŀlL/j"'н{+lٲZxEբg1Y۵=V߾Z ,T5 77I&1`:Va0 Yt)#FpThB`2HKKcҥ^:Yi8hcV<%6;̿-A6oAWQ;h}N:cªhE+ B]T*cAe\*"sNzu]ڰ>M7O>}6v]w;7@c0.8S3Tf,duQ??_Nغu+qaR1T@nƘLJe ;w.9egɒ%\X,+TF#ż ̛7!a̸>sʩP_<>|8а<\(AK*ͼ*W&W&}[wgcQZ(UϯS=R-E ++I&1h `Zudbܸq,]ǻ*Z'OdV^MNNp)`ƌ = E-=2d,DP,h4^тkoT*[Nz+^"m6vʍ7HnnnLkO>T8Vba׮]qA'g͚U r O\[JmeOu@6&ޭh+&6jk(={6׿hժ~L&_|3f￯ٖѣGy S#h4ܧӾN^et{wR{2z[IFH룵R_*!5t2w\`ZuK=x6m&ohnfϟρyLn1=cܩ:K+:7j#2׻r76Gs^/rWU*`PRK/ѪU+*7ih;Yx1Z"??UB Z=Ü>}:0uoDFyHS2֩kHJcU}% }V3* @R-kfcΜ9tرQ֭<3gDQn)%;wf2",XhX ಝ  }5YϪjrYY:|ӤyiUk{ߠj))))L4#G6Yr%\r EEE>S7tSgԩ\èhQG:}]\U `h0崱+PGo^ZL..Pg P-EoW^z뭜̵t3 E#ZC8q"ƍcǎu0iz :d4jx~&W!AO55jMOmiRJd~Sj6kR O 8묳IOOi5^VkaA#hUh2*ޠ?);vݸh6i FP(^em᫽T%DtܙG}2^'##+VTVQuf QON4@W0Ĩ֚,((o߾|ezIm)(쒛6~D:v,Aw*}B"(0}tT`HNN+ .`׮]u0fӦMlڴ)аc2AH\Q~'߯UԂQ&u\{@5ux(bU¥=zGL*S-E`ӦMߟӧ16뮻'L&ބ(ׂiR^Z_ϙh|HvԞɫ*>Vx.\Ye!TK`Ynݺ|r j{NAŴiHMM 4Q^E`L&;DʝED6}h={6KCOCM&w C! \.((JȔ)S())C1[H;(IflAAFF'O&֔m9QPP@hhh#5>Oo«hE*dظq# cǎL<+޽{h"55/[V!MZ +\M.ZVDHQq:*EEE5? e8~8Uep9<7^4%`U,,]AǸqxQPPP?L=xl6d; v/mT ==] mMY*AQQO&33-ZT鱾~~ystxn+>lVE5@#?? 3j(&Ll8qk׮eTM^+h2O}b1N\UM633ӧO7y߿R*8q %""զ*֚W8n-Wz:jh,_HN;v,K.Ntt4>}Ga[lR+Lfw_OFI֧!R_Nff&Ǐw?YG)t4i2СC?k{,Z~P pjE`߿ZEiaU'&sNW+dfwzR"t:Ϙ5b@~~>٤z4*ZpZʜ]j:e׫AA59*x4SPdeeZƂYHOO@BB$($7<뿔}:Ka4K9`%lq٤kA)UG;vLjbGX_)V/8 Ͽn;{ O@_ ]`'ߵYűc \{Jѣtp8HHH0TJmj[jaj: ﷨JB/:X,fAԵZ'ZzVRYjj*gJ "%%El6 -JJJ'xoS 4AYvԩpF.|EkZ:SBBB}[4&L % !v<B`ZIOOA)5EhO~ll,͚5,̨(1]V}w+BWiDjXBBluuaEj5D =RvТ=n`0ODDw?++ NFFOƢ#rrrɑmڴd2yZGGGNp.1.QR7 ZC % ?} uPqVd6QPPb5 >}Tmg,y}1ӲUKbZ%6DJ'⥗_mĺBp\tE =Bhp&OSP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP{pH ko+a3h/+IENDB`klog-0.9.2.9/setuppageworldeditor.cpp0000644000076700000620000002542313233376355015573 0ustar staff#include "setuppageworldeditor.h" SetupPageWorldEditor::SetupPageWorldEditor(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "SetupPageWorldEditor::SetupPageWorldEditor" << endl; //worldPanel = new QWidget; dataProxy = dp; world = new World(dataProxy); util = new Utilities(); setupEntityDialog = new SetupEntityDialog(); worldModel = new QSqlRelationalTableModel(this); worldView = new QTableView; worldView->setContextMenuPolicy(Qt::CustomContextMenu); worldView->setSortingEnabled(true); createWorldModel(); createWorldPanel(); worldView->setCurrentIndex(worldModel->index(0, 0)); addEntityPushButton = new QPushButton; delEntityPushButton = new QPushButton; editEntityPushButton = new QPushButton; exportWorldPushButton = new QPushButton; loadWorldPushButton = new QPushButton; addEntityPushButton->setText("Add"); delEntityPushButton->setText("Delete"); editEntityPushButton->setText("Edit"); exportWorldPushButton->setText("Export World"); loadWorldPushButton->setText("Import World"); addEntityPushButton->setEnabled(false); delEntityPushButton->setEnabled(false); editEntityPushButton->setEnabled(false); addEntityPushButton->setToolTip("Still not implemented."); delEntityPushButton->setToolTip("Still not implemented."); editEntityPushButton->setToolTip("Still not implemented."); exportWorldPushButton->setEnabled(false); loadWorldPushButton->setEnabled(true); exportWorldPushButton->setToolTip("Still not implemented."); loadWorldPushButton->setToolTip("Import a new cty.csv file"); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addWidget(exportWorldPushButton); buttonsLayout->addWidget(loadWorldPushButton); buttonsLayout->addSpacerItem(new QSpacerItem(10,0,QSizePolicy::Expanding,QSizePolicy::Maximum)); buttonsLayout->addWidget(addEntityPushButton); buttonsLayout->addWidget(editEntityPushButton); buttonsLayout->addWidget(delEntityPushButton); /* QHBoxLayout *wbuttonsLayout = new QHBoxLayout; wbuttonsLayout->addSpacerItem(new QSpacerItem(10,0,QSizePolicy::Expanding,QSizePolicy::Maximum)); wbuttonsLayout->addWidget(exportWorldPushButton); wbuttonsLayout->addWidget(loadWorldPushButton); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addLayout(wbuttonsLayout); buttonsLayout->addLayout(ebuttonsLayout); */ QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(worldView); layout->addLayout(buttonsLayout); setLayout(layout); createActions(); if (isWorldEmpty()) { QString ctyfile = util->getCTYFile(); QMessageBox msgBox; if (QFile::exists(ctyfile)) { msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("An entities information file (cty.csv) has been detected in your KLog folder and will be loaded.")); msgBox.exec(); world->recreate(ctyfile); worldModel->select(); //slotImportWorldButtonClicked(); } else { msgBox.setIcon(QMessageBox::Warning); msgBox.setText(tr("No entities information file (cty.csv) has been detected in your KLog folder.")); msgBox.setInformativeText(tr("KLog will not be able to show entities information.")); msgBox.exec(); } } //qDebug() << "SetupPageWorldEditor::SetupPageWorldEditor - END" << endl; } SetupPageWorldEditor::~SetupPageWorldEditor() { //qDebug() << "SetupPageWorldEditor::~SetupPageWorldEditor" << endl; } void SetupPageWorldEditor::createWorldPanel() { worldView->setModel(worldModel); QString stringQuery = QString("SELECT * FROM entity"); QSqlQuery query(stringQuery); QSqlRecord rec = query.record(); // Number of columns int columns = rec.count(); for (int i = 0; i < columns; i++ ){ worldView->setColumnHidden(i, true); } columns = rec.indexOf("mainprefix"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("name"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("dxcc"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("continent"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("cqz"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("ituz"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("utc"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("latitude"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("longitude"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("deleted"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("sincedate"); worldView->setColumnHidden(columns, false); columns = rec.indexOf("todate"); worldView->setColumnHidden(columns, false); worldView->setItemDelegate(new QSqlRelationalDelegate(this)); worldView->setSelectionMode( QAbstractItemView::SingleSelection); worldView->setSelectionBehavior(QAbstractItemView::SelectRows); worldView->resizeColumnsToContents(); worldView->horizontalHeader()->setStretchLastSection(true); } void SetupPageWorldEditor::createWorldModel() { /* WORLD_DXCCid = 0, WORLD_Nameid = 1, WORLD_MainPrefix = 2, WORLD_CQZ = 3, WORLD_ITUZ = 4, WORLD_Cont = 5 */ QString stringQuery = QString("SELECT * FROM entity"); QSqlQuery q(stringQuery); QSqlRecord rec = q.record(); int nameCol; //worldModel = new QSqlRelationalTableModel(this); worldModel->setTable("entity"); worldModel->setEditStrategy(QSqlTableModel::OnFieldChange); nameCol = rec.indexOf("mainprefix"); worldModel->setSort(nameCol, Qt::AscendingOrder); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("Prefix")); nameCol = rec.indexOf("name"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("Entity")); nameCol = rec.indexOf("dxcc"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("ARRL ID")); nameCol = rec.indexOf("continent"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("Continent")); nameCol = rec.indexOf("cqz"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("CQ Zone")); nameCol = rec.indexOf("ituz"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("ITU Zone")); nameCol = rec.indexOf("utc"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("UTC")); nameCol = rec.indexOf("latitude"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("Latitude")); nameCol = rec.indexOf("longitude"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("Longitude")); nameCol = rec.indexOf("deleted"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("Deleted")); nameCol = rec.indexOf("sincedate"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("Since Date")); nameCol = rec.indexOf("todate"); worldModel->setHeaderData(nameCol, Qt::Horizontal, tr("To Date")); worldModel->select(); } void SetupPageWorldEditor::createActions() { //qDebug() << "SetupPageWorldEditor::createActions" << endl; connect(addEntityPushButton, SIGNAL(clicked()), this, SLOT(slotAddButtonClicked()) ); connect(delEntityPushButton, SIGNAL(clicked()), this, SLOT(slotDelButtonClicked()) ); connect(editEntityPushButton, SIGNAL(clicked()), this, SLOT(slotEditButtonClicked()) ); connect(loadWorldPushButton, SIGNAL(clicked()), this, SLOT(slotImportWorldButtonClicked()) ); connect(worldView, SIGNAL(doubleClicked ( const QModelIndex& ) ), this, SLOT(slotDoubleClickEntity( const QModelIndex& ) ) ); //SIGNAL received from the setupEntityDialog // void entityAdded(const QStringList _qs); // entity connect(setupEntityDialog, SIGNAL(entityAdded(QStringList)), this, SLOT(slotAnalyzeEntityAddedSignal(QStringList) ) ); } void SetupPageWorldEditor::slotAnalyzeEntityAddedSignal(const QStringList _qs) { /* //qDebug() << "SetupPageWorldEditor::slotAnalyzeEntityAddedSignal\n" << _qs.at(0) << "\n" << _qs.at(1) << "\n" << _qs.at(2) << "\n" << _qs.at(3) << "\n" << _qs.at(4) << "\n" << _qs.at(5) << "\n" << _qs.at(6) << "\n" << _qs.at(7) << "\n" << _qs.at(8) << "\n" << _qs.at(9) << "\n" << _qs.at(10) << "\n" << endl; */ } bool SetupPageWorldEditor::isWorldEmpty() { // I need to check if the world is empty and I have the CTY.CSV file if (world->getHowManyEntities()<1) { return true; } else { return false; } return true; } void SetupPageWorldEditor::slotAddButtonClicked() { //qDebug() << "SetupPageWorldEditor::slotAddButtonClicked" << endl; setupEntityDialog->exec(); //TODO } void SetupPageWorldEditor::slotDelButtonClicked() { //qDebug() << "SetupPageWorldEditor::slotDelButtonClicked" << endl; //TODO } void SetupPageWorldEditor::slotEditButtonClicked() { //qDebug() << "SetupPageWorldEditor::slotEditButtonClicked" << endl; //TODO } void SetupPageWorldEditor::slotDoubleClickEntity( const QModelIndex & index) { //qDebug() << "SetupPageWorldEditor::slotDoubleClickEntity" << endl; //TODO QSqlQuery query; QString queryString; //int row = index.row(); //qDebug() << "SetupPageWorldEditor::slotDoubleClickEntity: ARRLid: " << QString::number((worldModel->index(row, 8)).data(0).toInt()) << endl; } void SetupPageWorldEditor::slotImportWorldButtonClicked() { //qDebug() << "SetupPageWorldEditor::slotImportWorldButtonClicked" << endl; QString klogDir; klogDir = util->getHomeDir(); QString worldFile; worldFile.clear(); worldFile = QFileDialog::getOpenFileName(this, tr("Open File"), klogDir, tr("BigCTY (*.csv)")); QMessageBox msgBox; //qDebug() << "SetupPageWorldEditor::slotImportWorldButtonClicked: " << worldFile << endl; if (world->recreate(worldFile) ) { msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("Entities information has been updated.")); worldModel->select(); } else { msgBox.setIcon(QMessageBox::Warning); msgBox.setText(tr("Entities information has not been updated.")); } msgBox.exec(); //qDebug() << "SetupPageWorldEditor::slotImportWorldButtonClicked - END" << endl; } klog-0.9.2.9/klog.icns0000644000076700000620000236150013233376355012426 0ustar stafficns @ic09PNG  IHDRxsRGB@IDATx]|TMB zGiA:",E}+vKG,HU@H(IHO}wfv7dws/'ܹ3߽wΙ3g(%$                                                                                         PrA@pgBP3b6sQ.~09<)lB G&8@,in Ol\7000 PW+2rKh$TAA|[m?77oH^8> N={ߍTA[ .@hN6lذGttt2|<|dll!GDDT>vY@S Ƣ"XsǪ&),-AkBh qBhq=<^=/" _4x^/C%.D1'aA(B9s8 KZ!A@8?#I!Ȭog۶m7ffdhA$kBS?ַrG@12PyyyPh1~;_2*߂k $V` .F`k VZj׮]1**Je9`Ҧ7@k&{xء ׅ.y=_^>Ξu./j+=yqkV a-R@KA&AH_?_OZ(\@w+11q<ݺuС&ѻʅg^x.s =nV?|}==,K2?GACMT>7*)F/oָ - 8"W W 1oXW!A6" @m|RgW"90>}YG^x]v-7d>M'6ͤ6MH|tk[ye `,,(2*SB" >ZwHw)E= "8R7{zA5$}L|ސBH`kg ,S /Ӆ,4͏!Wm>C DALrݤ:S/G B`::.ֶoo2ssTwU`<wk<P# 5ǽ0'5z YH[- &ߘubp1pIOaYp^'~py*&-b@1WWD"~k'|,$x,x죓~1_~Z 6 `1f2kBւaC=cǏW'RSU*DZGPhH岤l.f" -%ses s!$]{ /9\ $xҾxºo=zOݺu 4щdK;rS>; {' &{z "sK҅>ET4p` `!A##҅ Ȑ!Cze>{n㈀NB=RRR4y$_&C(ETs@Hp[DpG#s1-}}H|>4O!N['Q8p@:xPE/9J^3U JWC@{$R #0KNıp惃]Io4'IA{c'NhE޽fG Sp¹`!AmmִiY#GŢ;>{7OO-zs ='IH U,\GC140C 5(5؅"9w.3·v)Izǯg: ߽kL1k?!70G=B@u# @u#.spPq9~x{Ǐp= t[=}s,&᭿ /zG$Yi< Q i}cƌK~ƴ{ZnާsEHF `"ѥ[lE@Wrw=ӛ7o>}ܸqDcZ_R ЃPܱCEL8s0Nŷ[B@! @A+➆GBIާ?@2{WH [VM %FS 0_ .E@)uN~=}˞>OS‡!YFěĝ0>-6B@JG[ d>օ8`sKi.8ּ̑pp19̴$ *"C2cV[y'Tцkp8ρJ10S!/A@> /y.FS;X.ξf֓ h.` yIj> v?x' `*T| 4qHqKrTN!/] H>C*$# 9ZI sN=Z2{4Sfo6B#@ŀ]Mĕ -`Z 8,JN`Qӝ.F͗=_Ef͗ȃJ&Bž‡=u` }`\@ nՀ u(2+P1ЇSXCz-UdD纲=`&bwO+xžOZP̞P !Z-Ћ^|Z :Q^AB~ڍ:_m/e>ٻy-=|(A._ s4>G} DFah `L qP=b!/=Cs_ 3҃(˧fczS ^ ,ELggA`M)| "Hg`*PB4\T` _Z>PS؃'s^Q!K&/Le ǵ}7/PE=r9_lk%>{4gS? k0j'Pm*ׂ#9V oV;{g7`!CP-E`RֆsN| ~ЅK:2pp2P+bgB(\X`Z؋%MlG)`!A.B"*[ =? OkU=]B.wBZAhhgOZHٷ}){B@e'my\k03C0@Ϩ9xGjCQ׏!ijb f^tx4!AD"C fFK$g^PAQ!Q>`Q/xl|mtc&y0!;>}?nIy3f̔ƽrwF*= px?%=F~Ԑᙅo~j-{tp ;W (e4,d'Ɖjq`6|of-/Xә3g.ZS5`8 F og Elrpz ~j]5gyYZCbuN>J9y<,f~(-\_aaѝFqa35k3 @ #>K"T.#kKvUx\R' hlO5&,P+\umĭ|uW8qyzv\8U)uj5 #0u F 2 ~٫pm"*sI`6M4/RD1q0 p)7o.=W=%RAEL4s@ HG?A `C!q#pp?{f׃k %W/S;JQGwoCO,;bWN"A%B8!ri"X_{C6EA)fTYQ8"ohHYG;\?sc vF2Mpl$l-0%cлoXPP18ؚ|8W5,=դxBiwsh0`7H*fݬR'kF9q[]0| c v; G*dfӣIp K?_uUAϿ>yϴi3 (000/`'sʈ53g6-4B#.lsx2|=12"{fOLngMϳ-x=v<6>44;<L!X[=Tt&L77o.ϦΙ3S͚5WwC͡ pIy"qWs={' wJȋ`ǁ{=c&P^G2钓UTTS5x\BB @)#`yiK؆TY>v]F`rˡT ~nP)kl&Bkӡ5w\ nrѨe"k,*fl}TP:* "Bԍ࣌EE@ge4{$Jj۶KcPJI)3e !)QѷeF^xt|Px<# M{^T%^6t"b4 KE(_;AAץj:zӪ oP)*@T^MEErD~_QO݊Ο?;hI~LDeN|k9q)Mm6ᛧy# @Y 嬀<^\HQᲇv4h4Se`lƖ-[c _N'Vpܹ k4a{l޼f̘MP-YvS=Cxj/^0 G;奏 /TCPCo 0ބ^gqx{إkhȑ\N.nh5 ssܴ>P"J|b/꩚]GWT:#G{^خ]!Ck>~quD7Bic @>b9rpPY)* Rڂ(.n۶|('E5E|Bhm|P ϱ~9v9 \[Gߋ&X^4O'= ;|X%[| $W-XR+e >!ȟuiG}L͝;1id+s:aƌm&!]$m ċoɹlempSpQR%[xn=~ d.DE#nH۰iN}Sɢ´aK)0-0S'`ߪ?~Je⚛_Y^pzƱ3f9tT!0oB}ݮ@nb]QŻ  wEfU4|MES~nF1}:fa*x!*W} Ј>Hn6fWԩ/nw2 ϡcBo®3ŸYj!.j e7Y|Vc>^[m?#eWm7B@Rpx\ nUvNyyV+hjy|5iu_=Es7 ->} egCkq_8 ^p=BzbccL_ߦhjX {O9"N9P馲J@.G:޺m`C@*\-)%j.BUn@^ zhpp>?vpm 6dHeZP0_U*,fUu޿Wq^0hj:ZUl6;iuBu~7߬6mCe- ;<5m͖?͛7kZg_}c P ه H9$V'PBՈE7* x >swesݵi?K? uen=ݦMSVE'7zUG4=~\m]Z{_Cu-XPŶoFs*~RI;BդIR)OFȨv0Z33fl/]چf7aΆ[`wkP$&Q<@ ABa>=۩1*9 lmؿשL3IA/g_E! 3/ *+ W@UB:4lw8*oetCepó>s]w}m 9mMݭOy؋J:^QM ٖn)1#'HxlmwM i`=6>UZ._Z?4T;G5C_@N޷_} t͂.B`H͇a/TJڹsRŸS e^8X myK(ǎG>XҰŦf fyhlIjE?j 3p . Ă;C^Mi0v]XUу/0mŪ8ΩƈnR}5*,1QXȒhXb)} Q`68Z1huԮN֪c D ,(j5fAs #qǎz駟)5,㏩xD͟?;z/VfPYY5u]\I;V+Eho`S}NF%Z!U!T!.̺'_bX |gAC| YMD `q|GVZ3s!N\S1 ` r`8UKᆱ6>_U k~O6'(ȗdzζisBJhsb(j!~=P\?TvWqlÑ 7s\>Hڱ{} n_{wV0O?3bC]閑7ܠXRpܑ-n?FPEGvVR5s޼9]# )hͤe~ls8VF~<SaGDT;jIjԒUHݺ;oo\ϿT>p5 0?BƸoQ1K b,;v8?C/0!l7pG4ǡMP΀%η3b*1Wq${ b=1p?~WRo>IÇޏ>կ#yC0_ut,#1'Z6"c>nwߥb+Ƿo3CRڄ}4.X !Fǎ:Tj{ ?QD?򫸨2T2U?-ceAkErhJ@ȧ,~A}cņ{(/_5G]k@4@uvK># > ?~j7R(UfUEgdb8 \b* %iӦqƥB c(@-_k ܍^7u3ͧ}"Gr#@'p hNn?nSplv]_?jґwsV}j0OH/WRE zgAJk `tV__MH=qB!.P|is u), "L~ڻwZ-Xgce`0.sL6)EAD{t2|!E3v &2>fD5p5IBv^_VE9Xxި6o٪;N>|ٽ{zE#5RC:vZ?g:ObL֭oTs\zxҥKs.l$|0}>JpX[`x?xJfϲ/l~)sVN*p&r톥U /?+x$2Kԅ >uڶUc^:u1j!`TA˃7_ۨO54#i߰N{enBPB7tˋ2Y&,@ >8OYopU0B`0hlE}Ba?El3\Fvbr\ddQlV'Ǡ44lPqT-+]@|e K̆Лz>>ׂπ>c>LE4N*X2:?*=uI؉ms;dU"@+L+.WVt*0>۶my;Xhhls. : %*MG5oќp`wZ|+;W&7j;wi¿ŸpOrq˫h}<̞]jUOӳG+ ~Ti QP7VGTS?h\g [Wӣ{r/u{Qa'@ j 72/>cOډra gsg ~p*- QK6cw'ϟ5f {錯d+S1GO,0/#==8)V9;ZG \4``ĦM)B1@Y>l_֢omބ ,}f}Es( ]\m]lRʮL_w/UpKM*6q<~?( ~ mKρTXZ,@Xѭ -X3 4a7\ X df" S,K+@U!\F-g:'OnʕifB>3hhf[%T{J!*uV} R][7_}Ҵ}{YzG_l56z!]PtY=@N[}*479B5F8@sͅ>_ke6kkc O\8:C11uT/mذ6[?A[Wp.(?fizc jP{8A?XfWX\k{8r𸰰?MPh/ |ŸI`(}|rZ@J $Dtֻe'=`8Zu>! Uvmʉʉ#|GxO#ݶ R\ߥ>h;ilwGk 9r!?LaO/s*[< u-߮\2Ł<-)-4l@-Rm٢ON^vҿjRPi]xoHHaԉƸ ]sHK߹{\I?vϡ/l~[_{U4;Q)/=MmĘ2{:QRXA[JDF$S=]NNn-9\fQ;w+p9 As*yuf khڿŋn~D_!_2:\G%סFt2M*8oݺŰo<6FA";H. @gƌO6M͞>Ep dŸZV)hY6c|6NWϗuN^xYq]u9~LmVۤPWW]˽4Y#K"Cꃨg! 3{dˤmsr.܏3aj4:p ؚ`^x uGd *U&eu+X֩|QtF HA>YrKrL\&dvAwuqZO*s͛KY,?H `Z&^wN1fđ%-{n6ޖPP$Zr S2BIK`C:65hxȕ-);>P '\L8BcǎQ=z(񹱸7Y+ٝ? ]EIB..Һbgϗ&۹ _}f𷥯#g| :x)[4o,b!sK-܆beoI%Q-N\ZۧOdQdpۗ{,f<8}򙟗JC&C_9F6OV~FDZyO$| N*[ 8*CREpBmV|3qQ'.E(!0aPqp@&uQXPOAH96@ /@֋n-ʅ͆X P;ԟ4ŕrB|Jz<_ gBDdVry%NkՉ77>jSN-ٳg.(ht`O??=؋XH.>5h9 }+-9f޿7~U’i"8pHꃘ>UEU!]ැb!_HȹwOŜ9O܀ .W% 3dg \rwFV\ a?g B8T:q4x0 SkZC4[Yd>g,secsv҃i\(I]@c88+ǣ]KĮa7n9}~$wÌֿ#H}6N}HN~C+LG/D\yS.ZY^ ?  l9Kmuq x<28`@;vT?Rmڼ o\hP~fl[S϶( ጓkOw4ǟ ,u j LSt_yYlwz{S?PEq'O}ڲÄ{mѲy(/Pruu׫W`>/OZסօ.L>}<O`yMBnmԆfQ=gT~pcĹ&z.S@]r iNm۪Og`C'(SaL:{0 PaܔlE\mR[`XG*äLsaKP9 loPp=i*XknpwÊq|)xB )!oX@ɉڱLL}'|rdҤIaQQQX"޿ϡpLnѪyҥ_e r8 .{DhR-oأwzB?;W3ՇaPR0@R6t*Ug؇y7 SYRubˇ{=s 56pP*pW޻{;s6wv-Փd2ЩC#CσBN" ㊠@ WMSWR>O Zˇ#CXz%lB0Oi (Mќ@IDATŐѬ筷U|d &|DcJým~￧#ͽ_G7@Sh|5z{^ #ǩAl[xOpb}yŵ8;Vj6j_/T¢Pf_Sr-`KSNƶ<|Ҏw` Qԉ}iii]Jql 7Q6#KTU*ٍ@8RU']נcξQZJk1_} !uZ:V[|rl~@Է6uZU FxF?C ڽGC#1:h?Aeb={U#q$0**aCg GHZc0- r8ր`~ѣ* :n@]1\1*͇S0ZX0Z'=G)qr֭4 `РQXb6n39IPa* MŸ;8We6 WY+BU׭+mp4.,N\9ML?rjn =|F+pr14Xo>\={3r_9 3,im.mmsgf_})W8*'WսJ( @>zݟ3c< Sǭeʲj%vóoc۹=m^:W LD8D].lYN_Za}HFB`u^p싡H(q% <Ӭ ذo_<0I4Gk֬YקO?ɼxYCpiӦ/DpRVxd[n08A7_4UT~8DuAC.jBuuc;Ŧ/#4SES ..^* Xhkbweb]~h߱_xQϠĪX<4߆J֙&|.h(3F tXT*s^y"+S g" @1~ S-ƏW1XQ2}vw);4 [g gc>6fxlMm SZA^v#F&$$'u-;G1p uRsT-jFu7G8ޫĥi oyP:pliz=nE![X\{LbQ>DmIm2g`?\IEJ3 }v*Xr>=pՕw+oPMV-b"dbUdr3S=)UI6-~^"}QF*LӾqhd6Ϙ1oysaCgp m2raMC͗^W a] (vk_;j = (Pm?nD.4۶kCN+p(?MtvZ/.lʫ`@=c'鱗ph* ! /=zc뒎ڨ<_ >(?zD_N)mKjD7O69#㇩<w°=Ͱ؝*1!^2Z妥ks`A"}Fu/4GpCSPUJЁ7m8r֭2Άf9sSO#$AI<$E$>`(fS U,;y'R2_5|.ĨcUX鰰*+!p.QB'Z?3s6CAd0oDm@)0'hm+!(+c%'2Y}ĉ*kE?{t ˘)~q]2U9ǎ\T(Y?.S!"&6Xe0q#B3-NYB> N?PHd6š KjOT/S(SSŁCg\Z w*@'ϨՄ+4'?7!9ݽ} KO>e{JQ oh Pnq؂ wy⧟ZxL ;#,>I[Ҡqbe+ 19tBe,&:tlRn)8_Ru#a ^)04lss}PuQuתXѨSSՄ?WoKCuK/uTbh *y\e/KUx$]`|:q|(~)ֳ߯?`uG_SF.UEԖ-&KJ}Y?OOm!?#1n7WI< ?JY},}[jr㤊-0|gABŹyƌD顷aT*fXC4Ӥ}̕Ŧ8h2e*lZܞVzb6m:F,>2Iߏ R vi _D(KNp%otan$~v gQ; |`wcpgJ5@nbVp~b< *ʃ{C:AjuU1]!YA-$I%]>^qS1v|@c(P5ȷR*Kż{V{s3aΧikz4GXFgʘ|MŴ(;G5&*{bMGVg^Coҙf ܭIbY6>}z>CR[*>xݻwcģ BVhUD<4u#<$8L?|i|yyܰabhq}2vFp RorBa}XG|yا* 2ZyTy j0<0p֌qVߦE>",Q9sKtts\0x%CeV( %o %S^O d{sl_lۤ_ ŎoR{ƝΩQ^O(p(ǟXT7NBbcj: "8qwuw!: {^=GbFE{;>P Ȅg{xDtBNDAz(}=z_@Аhp49Ć oB'T )2 +/Ćߔ+Q9JzphW&cw SU]z*Q8Xr3Nr΍@mv+ª2+ۯmtݻ`;X xXO R6b7|%)`Zrjb9ktP~}?kaOܒ ai >LKj"v[w{]`ݻw|tNʯ A زzM.+ Wj:r3[e pӥJ6Laؽ[El?gõEPY\! a.<0NnބN8{_9mb:FdW?#u`-Gƹǐƨ}T}?"Aw:l2>3x`015*f= 㷚!pVD#ԧch[T&ٮ.1 M%/횮_=oﴙ'vKFz<$P90Ç,\0Ow]ΉCf_{"9Y%OªP^1ޡ48Z V-+=UtxPY04ƳDi4UxNњxש<+ENnx#2 oBldSGov>V`5ܼ=v~Zv[muWOqI7Oξ) kf%Db_׆'x){|"q3i97Ӷ%ݧ= fF{0مi[6W.NSjkT@bs)z&TU+By@t^J?NKlB^O>Վy)r\3OoB$L{PhrsZwꏇۛ#i?SFec%P b^Ʃր@D ~5j6¤ 0}̙<\C/m)׸ =dΝ;7cO_sf[ f$J2[ZS6 ap9 I0\kր`|A ̗È9& u"zqQlyg@ִ{̏NP vJa?^toMAIpv;sh B/UU?V6~sV$cBDwܡv!֗_Rpj8` EEu7< |H@艟rLݿ4a(Q W9W(>h LpzX_`i&#e #Ӣp/NA>B U`Sھ_%j֬P6" ǖ-LmDE6GU88a#6Ď1+ˤuql"Rn,'K%كmv:W!vE ó W *\0|>`: Ri:> JrJJUj6(9>T8q>}z7o—@o X`,ʧi$M)ʤh*#M<*O t7ԛ,K5gUH|͆ǑIqERcVug 9e-0YSH|Ӫh9fˎ~w|=ʿ[2Ƽ| D\G#W/T8􋉉=T9VԎ_U{?inj\ Ot28s=lz&Ldj>Kbm,}D[o{=b_WEc ;~Wh؇`͛K'p!7>>FpXEj5p.@9 L,صk7{Ć`&S^E{KCL/i5^]/>A! xt 7p|8pŪL̿CJ/fj#.M,rǔ9`b`˱ o4~H:L>T =S>9}Ssƞm pǴÇ^'8F4ե^׮jr3^Uጳp1^{]c,y,#^Ϙͮz{k]g-2鶧 >C9C~X֨VU뻦ișB8x ՞{Itǒy@ =$>+*SV:C/S'Ĝ7c,\j N ֛ujP aQRJBc{8IT~r='ω￿2)HKQ=BXuާv*v (=ڽo>vU>w?^˜*RcJOyk8-h0r<|{~WU~B.@~=VS*ٱ88GVع3=]^ g̜9eBtɮp 3f̨WW]׬QajqR5 Q e3eƌ]ʱcj#4rڗ>JiEc]Qh˥Nθw:u-Ww_UNNNu;{V<ҒŊoa\@*j~c0X+og:ȵti{D5w(Bg՛zUiYP|$FFd>}QP&lBC $ * . HO$ds5eLPbv-Dgخb`Ps=p@^q;jx`, v'[ĢjK(W7՚&?}%)oҴ@uZ SMkwlt\|I  uH 77sޟ+]`P.;( xSc7>USQJ4`) _|Ҡ~ ڇِ#p9{ D0NA-@jI4'@ٽ7egQ)s fJ[Gj8j@2"%X[s>L"Hg@@z.)(/88POhxI1f~ u!sOaJ>)9ױKkAON&tXйH+ !/%V8 $NH QIr 0n'NJ >b$tߡ;e#6Yp8 XWD~ղeKK5~}Bb^øZ5 yUZ5k)&OT? & !RQ4m''?2e ,]p1… p#~)J @oKw߆ADz6/@]FvOkNo =!x.&= ( 2k L7|R #|^U #pdm|mwAɚ5!*ĪyHwU]ظQbCHVs1a  !aذ(W<'nȕacpij)!!.P ^A6C~$Alr k,}!)&VJ5n.#N ç{zɉA000TVO:riĞ:#Ub3 (NtU&#і% q{O͔>IR煲ZlVkx9qr~Re_\v2. peTHx tSK.\1? \ I~I"޶;e"dF1&Uwsg~.J@bSgj J0;0G7lr*wR kթӦʀ5?p+V+cj?d=#}+ )hEwEA1.1!~J[ օ "H^@qOvMDO&a\`-K3/ Ĭ#7H ?Ru#G˾>2D-ɭ3Z:2K+Y3F{~W֏;$/]|9QQXw&ἙMp`}'PYVB 'ΡMRq'u5k!@tia#fI:w0΃KvƳamO_$]ht(I~W[ږAZbZ)IP"ץG6]=DJ(]C* gN#VIPsiI|*t*cL3&e z0yT@N+5ܔ'tܽSMJ H#z b7ȟnm,tl7WJ2 J#m}Cc# g2m坷6%NNZ ]D# J }ͳsTű(m 8]iR]%dPH8Q"Wjfp9'DR,YϹ nKoMC-\1?H'ባO=*=!WV\Nڥ<7rțApL}>6klPOo+}aSv8~@d4>-xfq=gV6;L?摚ܒVCCG//wlQ`hX^]Y|b9d&'Zi0bPw _T^y`HZfMa2ЧzF͚*u/[hi1c &"@eӃPZP`1v"2dLX\Wb\ek/3(m(͎Y%פ'CO1b\>A R?1yLz:h=ڀ]~\W2ޛ+ae#9\ )w1$S6xI醴a? @N3X i iu#FɵTd, cPtjx %2<`0{eYy9+6cV6ҐlVz)z1c.8i3':pNARk9&c庺 kQ ?3%y%㕎6UXbmg_\/RJsq3,4 rUx\mj,s[~rӰQ_9qHᭅH|).fJd(L D°$P֭RwdΉZF .r jnntBna,QZm}]b `m 2RO+QDq?EREQ_&&& dc5#J :S$o=k#G6&R^\x5ڵ!y1 4kT]D >P!d (X5^95wyg 0ggCW^[~bqMv0hk =d5ݲwb"3>;T%X&?vd_iY>H=)a M?QO591!R' Iy=h9ݠ:2(>T㚲^5~~Ѩǒc{m,3SaGӒǨ]u`h"jgIT\68P81MɰOe툑r11\b|GDa iv&b}>Vs+"8ֿr[S$Ug#L"'F?+b17*!q菱Z0o#qb@#ȼ Jg@ r{5B;hir>c.?vW\Me(RN$a|~tԁ1.> Ea]Bpu׮|"|P(I@' Hh$!p+?M8d)H_!xPDN IB+EA[e;/, >4h O@ W^ &tjaKjS<Qah~(ZԈH@A:yEg(Vɣ1ln~8ګ6oBRgOu>`Nfu2l˨FGK@;@4rTJW4]>&==dhTg@5Fcܓ!UsFcMG7SkH:7C.X76y q ;MNGfurQSd]0`S5TND?Q)5LZ|jQ@5ϧhu8vrrr>{K=94 PXEHKD /Ju u"}%*D&_7 "|MAe 3j( k(ѕ8>N8wݔz-}[>=^#D؁,|#,=:E /H2>F{cF0YVl}"5 F2tAVn:%Mdt[ow݇R*,*߽3D7)}Gk`7@B 6LBZ}tw$~UƍU!vds|~K{.:sIΜdc.] PLIDUBc7cb`}!% 5< \ Uqtď.Pc@O\Fl68R$N gTHh0B6DH]JÇoR)I jb!1ꉐO."&T;O3ah´'א.NdyGɿW&:t(:Kp 5mbjϜ>4D7l\p#c@VO?&1rV'QEZ {.m8һkN"ˡ{twE]XT_Yx^i(X; @"S6U=T('-Y)վh`GΎ{zSB8wgKK6o t]0x2XGw)S$9AҤz0+?ƑUl~5E[C!.NZi[ǿRh<Xz#,_m qΩڕ`\;yqk1NϞ9`B'P>EP"ڧΜ>׹SPtAH Cl"mR{" O=2R XJɓRF,=Zzm GM/W`J,;-r=LC "@;Åw;Z[9dp'(.ǰmQ%F]wI(pCqjqlW6nW8?ZC^+ @Ō&P\?|D`at6x4$S$A5Da'qB0@H|99F!$e bf!u ED^J`1 ׭F<8)qJ LeO?_*?E5Q,3,6*=(%0%Fv@ vH?G`.&E`":gߒ~J[SȔ% eɖ'K r˚B"RݻI'@[Jk !wAJhX ]~mQ75r…alV;%Hmۺ=%XcNP; /]0^hw rQ`纯3{Jo%  #UeUCJO:&MV,_ ?/G7PJj@^ȑIѻxoq؛#G%F`@@O @jR,HPOLOkq* N0>];wC {Q^AbMe1 \[8yfA0 Zupl\bLިp\!E1l7d8#"! ==wfMg9!0Z Kw쨈̃'2bV?9ˡpk֬Iׇ3ϻロpld?c Z,59Zhq]n׾- i ~rd踮sN:qcL8 Ə3 8ļr2qA&P #Gg©s 5%z_N:#+>DگUP"1N}9(('NR%Ka7u_v:*H5"4X阵Anbɦʊ6ޅ4&NZ{V&8^hze*v*=/:A8x~k&.X +3*lj7$qJU7~THnԩw:uR~uDT@k:G;ia0F ӿ?WjZJu%\2tD,u'JB_FiЋ0/#| J(_oyرaaai:ep?kРA%)Nx$j2խWWs.]B dk2_%߂~ Ⱥgó9S+\)ۤTj֦HS #YZ*c0z\wEzYJu,/u_=g04#}IdxtĠHޓNy@e~,l۶-a7f4[zx8$۴TG^^rlNյj*G#+99:G.M`ԨQҥKgM5=%ypWQY|UEQMgxaKWJ^ U]"{NP8ucXG!C` ,ED CR;F{È/!v! i? kYkPH'81:<[(I={ G_kE5q*} ׽8Tp FH|KO")5 ɩTC9fWM~PuQOX#̜v{)-w}]בs+n:5B!EGW"b+&'*Woڣ\=tp}F'@lBR<k''9:dXjA%bbd(&ڳ{]DQڡ@1#?2ifbgnçm _ l~mZU-]vE 0xWIK{,|%d^=mY|wpx4޵{{." Rj֡1?F_zgB9,O>]v"A"PIO aÇ msi揈F *J`l ۞8xSP;06,Jnq<_@a&8qhAO/=3wޓ >OM_7?Lm&O6LO98+khCؤ2_bn4+#*A ~0/ 7;pd3~{-_*uJٯ$> 6|9B~kB`d6,0@, (EvC-ϳUC~wհJ})?. >XNܿ~3/\/Lt=:>2gq u Lk09u8%{Tl޼pD$ҥDH%Jmܰ嫢`x ɉrA(F**_֠ 9 }\gg%^ # g=~q+ 7tHs$0hU0,Q_I5242ߒDžF-;!A@ϭ['^lW0}2e<RnP`> 4[]K xW`ppb歲v$uv/U/TD _z-U$\PAو ]ty{'к>OkPT"  ×k8".e=P؇U_C`"I@!2!paڂEKYMAFK4[g[[ܖFƻn 3LH[/l$gI4SJ֮%5I|PJ-@<5v\ I )A?oě)GshZ܂\SФ ?#NUn@kyXJŊ][g_: 6g AG&^FC_pM/0PDU[OX9lQBBu )@T?ٷo Fg9V`>[%!'@߹d%V/ԇ9n qҡY?ŽaIv2/12LPzM.ZR$Srn!͡]Xn^T{x '` tCԼ?eǟH"·`5Rqf $p}MCxS,/'XD%QsȐGBkBR]}]qЕ;%؊,9r<* 3\PScǎJkL;4m0 Œc:O!#S\ 4 UjGQ,rQ \2p[ރպupǼq1/JH¤4@jY5`ְzϞ?#MqKd٘gJ4vS`|en9lH N XŎ|-V.l o3gמ_ڳćE !I7yO.]*]vط#g͚%GE}5sb(QJ Cϯy,T2;s*~<QIp/OC'`G'N+aԷ Dx;'ft.]b4:0Ց8 }3Cځ0^hG4_ ;]Ex$?~YtEg]UC]J/ ,3@~Cxz0"Hmױ~MBb*UW9O7A4׿,O8ݖyau7DbzQԅzW(+WG, V@@_ }D?n?$tQNRϠ_M`KFҪ➊`rR< 8$m "bX3檒$"ɶ??" /! Ju=/J; b1"x`2s E.{{>-9s樴gOSN 4:2sO0@`T7h]!E0{^TRBBB2 }cq! gzKSS\nB?^KG{cjW([|s18 ?zm}D)u;?\!;"py_LDQ0:sFE#@?f._C9n}9 :k g:~ i@H;"a?тϪyp b??._[rcpi*|M M.o&|J鷋lzRj FA0x0u_nߙ 3m0!<(HLqw#G`?.@D͠ځK; r˛S$ć˿"O}]T#5خd:d Y|O76_Rغ!ۀ!j={N仡T%?K?=2BUo?o^P3o-… i֭Rk6 ms~=ͤB˖El Y=9 MnVgnE۾3#E.Hk å3O+m=rb7*;~C̋¬{VZ[\;wt&0 POcq'F8blǎZB ߈ ,HG'>H@Bm24DxTpa4mPNf<.M@ȝmF;"wTEB"XGx0Cbo5E ף-e9lvk'$ȯBƝe!yn+ |H{nr+ECWj]踫FS\쿷ߑC␘VDVZv W^Fm^EF r_]B2RM6xއ3}-u7C&G?ay d3~7lXPP;_E7[{_"G,YD.]7Cq&y7ASC|d\\Ӧ*p q=狇ԼN'' {+Q{DD;#?|7wYi:ny v i[A=aVC{C[ A]0':tHHldsO[KEhƠˠ#TEF>ER֐ ]?39zuN?_?Η f8/sQ/? k%0[! H޽{a6 GAߍpdR7)<sK%I۟_z Z< {%9pU\ BgWZ6f$<.G@E5;͠пl9-m#Su s~? ;]%`ݓy%  $|;[sl]k i?~KA(E<,lV[:ߤvܙ O=F( l\'yP2Vj+#vQA?Y*n@$}_ݴ v'; }S&>0I/`)'Y"36su֩G5JlO6sz6.^\8=A9`]b^Ar=.3!$/Xl+~`!Kc|T,^X9/0%R%`7\ܼE Hɯ(0a>07d֐ ݰ^rd,/>:V~x Uj~|k jNorSk@j\ٵoڡ@s#(KɫH>}h,r064yF @yCbz:Ax %d> V჏ :^n C+12̷_(̏7_>(gLd|/L&}P"ݶC3̼f#b|D}f̐Y#S# e7V`9 ݃Q/Mb;ѿϭʙ+1;a=f-I  U0>?&t<}'Ǹܖ*߿4jh2$N\Et^|O9{!}_~j jr_:&j< \:RW^:?QwQOb7AvM6 eᠻ0|4Q.,rҀv0v7[Eʸ쥌7o+ oP%`/bq8,Gڵ#!pAN Wuހ|I/@pS@τo@9nEpy\/onӍĄe0 qJnqyp5#PڡlB֗%+ƎGzAŢǠXhYt(C}@CdĞRw·$cnBu:TBN Uh'`^iƄH^h5 WJO.ldM=Һ6Kj4R5 :S^e~#p\A븃[;3$ ~v">\dP_i'5jPCs_9|/u?uX w4!T+A"ʰ`@ Y̞ h)߼6DVE`{C9tv' AAr봩7X"AFBkq礈 q6D0 "=,BLYF#2š_~C/(p{)&Z"plHT];xPߒǂ` &9zܱ< \x:UFw`胮S_x"{Bjz U"wGّo5γ( F bz vE80@WpS~8ڠ { 쉸ֺ{֬_ ]*N9cGfZV-ʹH*`4dJzB]GoBgK.J2Prl*("C</ݽ{ww1}h+Hq'Wޅ]@0.ACRC/`d[4|H^ּN \ZpaFTђf'S}OF!# Țg/`Wfב S[׿ɣH]Wb]̑?& 6x$qsݷȟLyݮ"!eBjBHAa;gmd/BǏSN)-O)Q*ADdDFY("qwxc֭[ PB]NCQ`o t_?֪]NIabsjs?0Ax`xͩOsT8+e J3(vA ſjGqoyRkήN z#A. -siaN黿F?@ta/Җc\oCP*ڡ_NN* =ݨ=AK׫/e40pqZd\p7"Cs [.̬Gc\?˦wѭBF a]*G01X{AnE:ҷ| >~D%. /0 A8ν<7|"u /te],dՃuTL>tXqP>$8׮]DmQvv0Rt G c"OMIcVhue(zT@G)"v7WH 3pL%֬\~`i.-I ҹ!i~aYF]S!l }ۆ&dcI<#h~O3Īwlo|Ĵ!U!(tUnR Z~QȜXeKnبnn>>~ЬZhsaln#S zjR{bR2 iSɶE$o/#3t6mښQoGh$ stj'&$+We˶-"EJ AGҊTXu[0Z@n@iC *,_ƭ3z(O[QL6// qX {s`zdNJ,X2gcKPzg'Q{ޮRaŚJ׶"pjh 6sð#yWbaJm }!OTXo*;)U?)c6HCCz$P5Lv=ũK !bHq&%feU`[keXUls/p;x$tmTtR9awh&M R܆)`D_ׯ_tUN=9]|dKIc% !eƍPP9p]n&k;֍Nqˁq(K)jnF]6bD#ACUqY ٨k֬%e˔Ufàv=,B靹΁4t$AΓ6qw3E3A|a風-FA:XݩDVSS!v!]V pQ]׫޻x]Ncԁm I/k/l E $gaB| ?[A.qй ]ȟ6 eI!IE%K>1@ELJ#˺THjiHɓ'W+e ;x„ ƍ !CO bK*mPu\k߶W$I AVh@J._ gκ5%z;.U<Iqz{I$|#HĢu*Pq ]sĩgF},mx8i(-~ÇξhpH94qbB/A<$t"OnE,*ODP,ȝ~ [nM*"b$3D_CadfǸ%z54^odɠey.'4eb1'HES@5)"yQDK0{!B+aZ,88؍3)@Zjyٳ'&6t*+0|P[x$\|/\tנu(n.}18rT&XX 0Ft _?uʬ5^}U38/ \}(Dhidf2 *{ &;?t2`&SM-<֗y@bha'J'Z77?~$5%#CdIJ*l?F~;0lq1ZEO0־2l5u|#d-~"?1S.^OdT#tb@a}={vǘy2eʰG 0gڑ~Y{Z@?#)p!p?$fXHB$'&Oq_5wb7v%ORD^EłT>GhQ? IQm߱=|H=5G.jO짞zj@͚5= '_0 9y@~I)O(!+U#CӺ3=E%W_5; ^e (QSo{fJi䡇aVmè7_>3'w~RQ"}ɆaS?Uߠ;"Hvi^ ? ;>yˋ4#%GW7aXպφdáo< 셛L^ށD" AI(jbfeZ;Ճ2בz·F,_:^6/[ݻz\[}ںdv?|Ffծ}wbUGeq1/ɪ'%XQzFgxDe7W,o)>e8<Nx$Ox]A=CTE4 |ɸ67@IDAT0/ZK@oN׮0|+C ̫ +a>3=^GdF˰ .uO>#eJ{lKP*r&-C6 ŒG85pgѨv4ή2I92C#QIm{<$:ܚ=5Oc"+Z`d^@pr+∈;8 BB&<er|1} ַ%ƾ~_J@,gF<-wci~ "{RURGM:S-C}1"r43NEC'E#gCE 9_CwGudhϞQAyv7> fO> I%$eWgmjn|[5㐏<)I%/X֨)>0JўSӜd2`sH笯k^ﳎ*[$+a] 3 7@$`Zq5u}7$'\|7u J0.Xj"}B$OH gm+ݑ0*anhmj4#i潪PAmh@>װ&|-(܃bb"P}% ƀȮ,-´/](L49 fL߃7Dj\L- ;@xH2{ X>V>O/[;p ÛC}Ưƒ8</]!^a+]B-##ߟlڸE?*Ǟ`m=֏sKŒP)xc0rͬ~) %i͊ݦG"3IRܐWOWu= kޜrRdB3͡:p_9~ʨ!uE&.ԣ98?86tEn?,gZ80j8Ԕ3;ZxNGH=àoЃy{! nB.w}bSG?S矫gО HBW#spu~Yn]H!(GQ,!#"±>v84spX.z ,ǀԼ~p+p[JL ѡTf"t4q<Ab'80rg(eg ?!(ar_.o+^ 984Oį4UF$`נm[(Pǭ=TC9|<^jIUuQ//yZ7^&7P$KaȌ] >CBBT(Zw!PL~'@$\%b@Ӏ}T^øBZ1O.#W >uFَ`jc .BG\o5ʲNWP< z @h9s1YT߄IpWD.^Z@"5ĩY՛SL:!XĔ>$y"F>̑>:ny/11AyϠm\ Ӫd x0?g(v)cnr? ? R.mO 2`U ?s\?y2cE_!-`0yJ݃+,ٝ;CAZ> 6̈nrԗ6A;/2NU@ Y/3=0*'0DB5qf)Csn8,2& +9Ly WINyN$@juPWp($ܚ+, B\aI)݉ESHXO1m=ZF~P5Έܿ% }6|͉J~1wzPt)ru~sH; <e#'}݋dѠUly735#>Pf \-PAqNͯat@LVngaAЀe]! ~p!A} L~@d.8808X[gGɰޮR7b!l#WK~3)i3J'l,Σ:`}j}%G|*s-[`{ \h(\t8 |h{9nIdb]vV:_^$Pb I@90@;蒿_uڵ$F)xOG*}rKbBbא<) ^Nl>Uq N#tq FқkE mZoP-i! l3I06A`H?[M 0݃Z̅B +BY۔ z!9~e5]^J*D+? 0Dܣaߕ#Xi{‡q3"Se{lFcV'=t=:{F"7߲ih~:u$b`)9^;Ƞ r{ ~p[V?PA 1ca_Y >A1ΫUo(g?b[Fv J: Ns]?z: `Hwk61@yOIM! ܥ?q(8\pm.J߾}NSIH! 0e |bRԑѐ/tm~3& RA 'ÍޢmWO3bPdryRoWE2'&9^?|/fU,O̽|-V|KAT²JFxJf6'hU]kU)d('OTvf17M R￯I07 Cr E(܇4*Ҟd(ųA~7z?$ F(tE. {5'k31q?{*^p,o_ìQ7E.T1 Lȸ}lyPQdkMȄ oK3l<@"2)ݟd'5?1p%6@x1=% 4bfHO|(;7uqm_1vselD"0r/le#0ȑt w1ma_6S_CG?S CЧ\@#nfsz*߿5d> B\͑:Au/@29t/vٵ?m401'D[s]R`}}M؉Ǻ9FEH>@O}@ً%!\ 9?Hi$B%[w$F]q0;_K5B!iu eZ>0o^4 q,"9oj{z-+/:9 {#Yݣ-Z<ՄdjVN);|PKX<L@)>P!i@ J6g|Z[֑5$<1Gj3-HO,5p=i#HVa86pW"Tiy򅽭C1 {nI:J09꒯8+YU:Aq:(! KߪbjWgsKq\ >_aqZh56HwLz#އA?"TEdl :k\H}e&, YC5m8ȢL πa8qıB@KI.?˙ EsqC[7*3_}гȗ6Yg^8lMcM2+tKi#*8%q]$Yg/h}*?}[Mڧ Տ>2W+.l]AiXsC2`3 ~-Wfh˷ DA,je*SN Fu'0ɲ 7_Ҭt-g1⳺lt^Z65h1I鳟4WuFU0!J= kR%=Un!̷WBlW4Κ#N;w@fRZy_1yČN-\gg]T\5ϬiD-&ʃ#Dtϡ 88>p_5an1ĕ' 5w#!@j]\z! U2-[G$>`[Aӝ" ^5N^x>ʵt]m/;48.*ӕDL++ꇷ&sGU+s/~.!.7r?it+%Zi <s.R|W_my,/6J0@F"撀xIFdO}3YQ֌Ͽ g}DstL(}G(‹mf~];J0gޜ A~bj&bۡ9?J /ʞst럚1#R p./8uF0/\D/󒝈q.pk[߶B})(J[}h5%[ޠn|̶@v2˛,ƧV[Z'/s:^n{k=-LǘED0S/8<0ɴ󺧞bXquGD|}E9Mw^{m6UE,_=T{.z뭫,Jg%#=qE' ĿʒH%Z#I{t9ֲDY_/ğ_y]0i4ʱ"^Ꝉ.#Ra b/.wE@P' aA~zg.G‘dJs 橳ƹ2ۂ >P (#gʠC Th%Ŭ ϖэw[wrIG1㏷Gw&h2;A+Brw0<"fcr`!H壏t;,?ٲړ.9׋T&ZQǘ}S ucn34 R#Śd7%  ioFEZžkEmM5~",I-: f}]T//7WzwTDPD Ru$s@mYc4 j ЏzNZ }_ j.<&8&9Yjr? qޙ|Ҥ}2V=Z6>t>NF%*xHsMue%@yK(4ͪۻ{kg>54`ˇ>D9^V>$&HwuzL[im);[HzO[)_H=vM{mvL X7 קXaUGGj}j"}u+L?z<0(7ZoEx.pܾk}`^l}+KVP_/1zY#E/b08Gvn+|\.EB]0o{^RKi\yM:6c|?H'Y(R u 0,NjOc~R-ʪ1s` L Q1 i uHL pe8г{"@7|^D\.ʔ9P"JjzEu3?b﷔1(zPdK8En/_*]4)rS *)DŽ3H !vPL~kgjmwpKO/Uwd~#6{W҇0BCrnM>i~4q)4ojgLD VHb-d7{r =-xn ~Di߯25N y ^fXū.bվ-@&s+2&\{93Fc܃>h!CkRQx`{ꎷ&͚~‰A߻2ÏԨ"M͂&߃.OX 032_x/Wre\{P75ĐSVCH˘c[,#eHM}kcRk71æCuɦƣ.0$VK^q)b#DTeKٖ[n$;hvȸ}ϞdS7q|/v-v.CeK:-a[6QBS!N(ى!I3D 1NŜIqqL̂IceB_`Q}[.+~9KQ!pQtf*[Qc D"ug/l!V`!0vGȑ6KGb[k/]n֣_?[Z4*IpwO?mtrĨB!aϸr%,~Q]6Ys]? D gD |>3UD92 I#[XHU48@b?Gd\f Y7>J҆ ? c,A ?$xvdl2)pf~9U ɟkm 1w @h,72\FC! $a[n e fPaUm\գ6T7{@70| :0nD4&;[6`u( gc9Z>#VT/tԑŌdMu8{gՍ]w' ~%|_|IFBXљx d]BmyOv0όR2b^2`uԠ74 9I5Nww?Ӟʈ:/_[{4y<@3g2dY*zAl$#3(^16lgC8f.C@Ȟx .q5aN ^65X ې"_Jbl aG Y (8u8V߰OJ_'-~sѬp.||XZ]nc@ ^{`cd|8)= xĎUQ\$KaF?+z xazFD! vdP✩-S=π.AwcR^-2T&3788I@V 0Z; ϟ1)-CBvvOCGtG3i9&“iҞ|>0ܝƚ\ J&:B_xTqKZ ϕp;> F|ܴqVh2,f裏2LewV>g̿e`c1>Cb:AWc|]~*\wp^u0ӊf03 B-kzƍ^0'd'xc;3s7Hs7WxzDxq>A*|JSEC/e%qRѭeR;nxxװaÂ!Vz (&|=n[[3,Rz4tLrꇏeK[rڃ~LF c"n7D'F-c# lU1Pq`x 0s.ey@_gNg&V5~t $c@K@iWp]rU.~:i=/䯐D  f Ñ&^g~ @˘*ӗs0{U'|̘1ADL콲B$0c?c^O>d`0-\ٷ=}`pS^[hVåWC.(qWe37n9gf\8.st'ӅD?V-Rh+ +`Yi|G\ĝ2|{a%˞-MFpz!?H7 rev#.qAU)_q|rm>° Hn,!&{챇cYH1+]Tǭ64W>v__@'ѵ*X#bg?"^ZEJA"^:cً/;Ɛ~t !{$N@~SH e튙^![Drx!H,V܃; Yi))8/ 9@RKuqL 3_P0̈́V3~<?3K2e']/pd"+F}:u)Ź3+fBޔN^ '8x;8Ϫ4 5υ+#=Sz=*:wF37G衇Gt ӽw."BV(#y)lW`L_~yQ_%wÍlŽn"`o#eK[hs6{k/ :ʎmHx6j\yK je1f:GD|Ouw{{=Jϊ[WJbB4;tP>M`UI72iaP~EL1KF9LZWո@)x ?v   ɥ9qQwdE插~~;%iqO[4_ZnğABV^^+\ZXHEȖF~үlAo|\sN{#E?q>F;pn+0]2ؖ@1iFݔBKuK]4|)T(; Lǒc Q?Q1|#uhx#U h1i訕Wf+4kpZ ./l*=Xxyr!5]PwZo&Vcǎ|SZ0ck}2e?߾ǹ4xy#G b>HB O)SR ɤiG x.a;$R7~ XtYE^Ze䠕_T 0]i)+ѝehl?T죽]k8Qc6lJV~0%oFpOl|-`8 l?.cM[ _$c8}L0\{DYU9v Rs=ۀeO xZdp^2I{ >PÿUw7fٲ Hؾ/ VqIF!˘g2|- ~-ig]D@'N2f~PG=d#?q<a^&bo\ DR }ȷUGN nvc@ '2h;;p{.LK|qwZ>4B{saj]?*k~ѮN nҷeӖzEj@]ƒT?m^?Ա)&\VVV.aIkcf[9fxV^{mRU~2^^C̥<'~m樏||ɢ^V /(q}Hjf>udr |5y͂ypW stȑ! Bf1ZW/ .:B>"Thay5߄mh﷿u꼄o6qMCBa$59?IKiw?ŭO^hbf.K*4xğ[L+ (j"g>!ZN;h %:-acƌU?N >M!\79Wzf|%p}~I܍$SW{@`D?Lˆfg̜QI _3n*OxD; 7by_uzwIǻy}a0i@Fs!  I^4*\˚'l^K>9x[ 7Y. dOyM6 zLb*8ٞ6Fj?IwI'F d&W(Gi#6~@; C4C7dW^-wqsAc:_ПSl n|gv)я9wo;Q LƬi=_iEĉ}QW !oHn<4@@\l7 E=BH9o&atp7I>/ N(-(3N&ߙ|t'ݏiܭ!@US)37z wtCJ@}Z̘}W%@ CQE~p箇<;quy"Jl&6e}uA[uV癧`#Td ioLHPBs"6&y$2a16 d]|6>{1K"i᭶f;pb_; OtDC2"<4@EuX84[w0 @k#޿C@Hz۪E~C0 n =#=9@.s7{a>'.$\μX Do*?񑲚P ҡpt5+7h& o|1a4>Cy:OYq2r!xF N?518 ]ħߡs4X*BqOɀ9^ѮP?V+^tnξ:l?[{nng_VlqܩX_}M!aDsVH/䈫c@;ת/>{.}~A?4\;jf9e:-PCQu9~47#AZq$mw#x~>,^H c/!)ÀR.{Yqf@K~d\,ӱً[TJ:.#lC!-A%z,(?JxaUԗO:YZVpg[]9>἟r{xS:/g @V 0#!iq@)PĿ=ğI;r-&Ma) %3QzGYOswJg !$09!2߿ѕz7T9r-s=5&2n-s6ےaX`˱EZӬٴ)ٗGdVb믿"Z7aꢥ@IDAT20 cG W^y%W +Ͽ>&#IB7/Ew-𛘰95N8}A2qJ08؍5nKv(+EDJiLTv?OIUd+\}j:8\e h eʜ aZȎ#K}7 R1έ{|?Cl\ភq pZD$=K է OSPX%8ą"b H~ ;|NO>@\i=2yG&FSistL̹쟴q|-i# N^xG:W(2Vޱ^-3vk:搽Xirs[&uCl}?EW0\.1+\+OGT~NtCG5/袠UӤ>Zuֶ>V"zb@}0IWUJ\˪>m<{5c ?$5,p lz*f] W_x*BtWi<d/,N[Se)[>ՄS.B9?r|hd5Jɜ"OGf.2s<3}|^?NyXy8wLY 8@a782wEFahLVgxCFM0SNe!΁x`TЅj >O~2J~/O:?\>3ɟ7C04Ėg۱#Q(;vߍmŽt.l h#:ͷYGVa U ofpyt, ~WC; F>nkxubi*I'.Sr{v{8 1-lh0QFxQopa4!9<R˅z (v|ÚXi)~AVT2iX0?KS.2iQPH`rSnpٙ|f:5Xg^n f?~\ؽ)aqxHà`SyX[ag!)*,U1!RYiuˏooO?Zo_ys^5fİWׯxy2BH<0!ji;e+~F$aMaiS} |G/35Wz s< $>[)Ns.|)ЯB 'Ҍݖ*Dqa#ΪI8$0A$yN$paNݥ$cw7s'w>%*OGYr([2$ӕ}r iK.ѿ?&Ŷ#l[kӺw2M -Mzz<𠵘05kmotM&yXT'G԰1Rx@[e?.FqYZ0W aVxϳ:X'qT2PY(M$G|aAEf\C;t bJW2Δe_I4b0óƥ=ն4|*«Ѐِ@7!= kF~e}^aM = si㹗SI94EZtq靆xyS0?" ))K@evJ+KzJU[(pމLZ1%LكBLZ-r!m,SiU aiwaMF"3;v7d1{jkn}m.6}6"mb_ofdkɗ_)+,c+^|MYbЪbϖ鈚YK6}HBh +VӁEK/4Nؒe=OVkok/%de9$j!ƾ!nѠo %?~\jV.\׻{M`l ɘ' 5'\܄>M dHR_ܢ' ko0fUl|lWpm!L5FrUzd1?Rb*AշR0u$Z)Nob~?< <Śfn! '#:hc082Q>иAAr?Nrs0e%Ḡw?K^(qw1046*210b9Xc4&x]o+[ԓl~[>gm|uU?dOzOʬ6Q{l5TuDAs}@q뭷~kq|'L:{o0-|ׇtYsepVnn`׺S0}bSkyq$@ cF|h?h;_5⤊x`*{<) J} @ UVt pUӃ9|O "\J/-[=LX&d)Lb&/ kI>; %[\W}&?yNÐ8\i? ꞇXB{S[`CVLt"Չ4_U Ez\s hUd<;ҦI?x˜(kbΆ`f@*c[fER3LRl:ez hg_|re:)-kա٬K03\k731ZGbmGy?dI=ꐊS|O~4S-XC?\mN f9>yW>Q W4_dQkH[ڊjx>fMv}iF鏯/z뮐m>Av.̼i._ $Xɞ+s;\3mkH'${ϝlf۲7ߦ;4M1ml4O&fj3&kG׽p&6WVh30}~З G R[OqQ'ƚ [ ՅYS&k%?٦ڬw>*?LaQΗvK/ ,~;)q$i:n#o&lhz"wd+F>B΋2(((r_*,lH Kl 1Wf2qx.'u?ߘĻ?9sy&.3;('F= Q%e`$VO4`&-\#hk{y!6ΏǮx'~~<̀/C i85|"婧W^y%HMآЈ&S#a,Cs 容^mX\yPh#.<޺yͨ_l}VYBK0Ys! ~3l!`!:1 fڷ܂&KQ?ډ>iղ9^niuR]WjRmiI ˫Իc _u\U_JȶB?R~i]K] alŊΛi" u9O\an9~t(P(^в MW-]dOӈ ~PO ZX!/m> ަub#?S&=|H'~oSv!'gqmn+D)~7}Yg.` qG?6N<V:X{ =%wpWɱK.>~i-޾Q7y/CF&"~U_4fe\Mm2먠'_ w+ЅUa5_C QZD%}QDƊ1fs ?HP\5̧տf t̹@ȣ| "'<{2g9WCM5koq VQ.;BG#NwrGٞR&O…oK2# PSʺ@P/&*f f> ̷okfu`_VED6̟$泥n-cr/:I =$2',˖N;dةΕBW JMl %aH8W{ h{~#nCGf~wWGq5d swb%kfnr?~m*8+ɇRޔrwa$ETb?-­ k],dp%aBi0*Qh8/N 5zv2[}1&Л"*̹q>3sn,/7{4tN=_|B@n/+@='4`Lyfae]CÅҊXwj0}? \!m` &! { `7M7ݴm񾌭Яi@挸op[i~÷{a!f$M!9۞{Lq˵}I|4@/V:n=C޳-|Rn4|u}~+&|ZȪ_ShP"Y%f:L!: LMjS.ig | .'[r%l)#i$ Rw (h5Eʃ4[ [#|' ZGkO.t?.aɟ\/7(YLUO nL4&eE4T(d䝏~g&Om<$.TYB$θN \Ф|{EmZcnjM|e$><1Fe]'[89KmNF2,=p VwkUǿw>ҹrC4 C+1 83 0~Ա>މxI]Ejj&"pBW^V~%܏20hD|'VML*;7!/dp7Sf2nnglM酼6zWb#t-<^.WQD=7UK n"mM)I! o.r8<9 ;GRc ^iv>0 i|$sqy9 0\o/'/ϱ/P%TAĭO @{$ Ax<`!Q\:4~0F: ^o\~[\U8+KnfrxIAsYV;Jz\D[`Ͻ=9|qt(19LAG=e#ȧmOB`D eeeo*5_if^tq3m7o>>`}0r)Adu *2`CñAN}l$`$5+i~ džGqG<@}N'"Gp!O2҄S/~|8 f_uUa+gMV6նޟV!gi[5A } r=Oqq~ji jP/\ D# jP(Ku;(7Ϥ猟I @;W& ߝWa]vY ,iaUk1A$ᗱ1mӵ'wD*m1^b^uOҸ~^œzJh],4Yvvmy Uk–|5p]lED9d- } [07>^RRoF*@z Cԑ u<{O: Nw'H3U4`&yl߬'YBT&.8m;__M񬖿m^d B7"Ig!>#(`¿0a?'o!|F_IKR%)Ye<:’cX㮿gLG;&  B@hY!&@:80{.~\l={g] SBF`@$ 0Ƴ뮻VY%~!isiw?&4GczR6yjSoy3g޽f6L/[mP]1es]@t| a{Aah8}~* |#vwVaܤe0Ķn0Lr? +:;:.t) ݌m'i4p{o|k*qDM"G+Bx fϒfk&_!,K1]x0\0')e$i4̹Z,1g/3w.Xb0NK>Ͻ%qx{(ͳyv\V t6o—yy$ NѠib$pa+xɳwr'g4ԁ8gehSK 8#H)oaN y?w LbMٛ#.gl;bZ3uK]3=|G>`}u=ʌ?ȸN+Mұ'i==7s/yߌ7VW?,{cQ}*M[m- ~c>>R3(6#zw09 7 0fuz!CBo]am[9\s`vTCe ֻ!!K "!Hj4n >[%!%ʺ$>-jAWePV_8##qKi;a(ػx]lOѨiHc:P2 0M}O-ly^/x$J=3g8O9˫ bn5][ymޓkz2ݧ[s3{nooIHմ-"@Ty?iX(N( E@"dl߷w^j?mNϼrr;s57A w"[|g\ φo[auԩ|'Ŗ̓X|r[u2Ҟw}ck#)  %!xFwp^E > ]XBI` /X)")5-=%lI*ϭ"^D4 3:@:ɓOze_}͘1igoc4̹1tm ڗ~z!{.{n <&O.o`~&ǭ/ ]b|z4Xh0H8ʞߗ }L$9\eF8uXvmn@|36۴dاd e&w֔^km(JG~y!ĺr!xN(^x} `<8 %OXfѕC{UXu>C{`3Al^)l uiZ#G g#x4Ⱦ>PGf{baZ_5ZD&۸9FulP"2vf*mդ ̰_؉˜b,Pr$x$#U}/qQXEccQ=Hcinw&:Jc^$dKG{ BOC@˅ |(aF %'7ZK/dl ̭̖Ahk1[?pO4 or<-V[@j5?9&B46Le8 P,6w<ofKxeƖXoJsWx;`Ÿ-žs5?~S; [D멎wZg= ,sثےK̴uVvxtTvPx@p~ ϖLvVN?e p A7@1kğ|ek#w(aLG{R]t'1g`?aΙ}D򔵰+~7;xM섃+?aSۑmnZgqu(|0>F݄|D)~=l$+›_ 0\.U` SwM3"zf< B+܍ˈ!Mn$3[*EOMZTMhPG4oD|WΏ[|;R_4WA_’">iYϮMmދ.ig/ZK"m,7դKO>MQ ڗE.aEI8v\p6}fe),~a[vCm^S/Ufٝ\nKzzʹ6OC8iaN>0ri#'`M*C ,UW꾥";mhiiC*޲p!ĿLxyB~^SdGp{I,'h9º$z]I~ |́>kK,r]5w}N,%< =]]yܴV,SH]dE@a0xWdG>,;C}ࢃԉ4uI0X\@`[PhR%obUIosm: 0W;ZiofnMN=04\j6:?KaxbՐUtҌ-V;O}g{s_˭SO;: ]ʜ HgڜIS+~\ź q1O ո^7x=ӶZ+7cM5af7h3f١nn]X߼'{H칏̆EBĖӄҴcuCx0:na8‚?:eȰt c(GԐ[w$qOZyv  3<y=M /()@@ѳƐ{S .{ǥa{/W^cs|qƝ ݟ`V Qnf(gYUtn:6 ж-.o/^qT_.>at֛`hbCus롰vR(z'@Q>x-0QÊĶѼ6RfyܣZ`-F q:%}q1>X~)/7PL$"`clP|c&~@mN뮻Ra'Xk:9ωTG1nҖ\^D C{Bf»("*zd*QLN9>B6"?n$z}I~*ܣ^MŒ`sZalsvwDh{:\ -=?kV_ª*ޠ@Ҁ|y#=Złw|L@ci>8HX/q7Ҫiڶiu.$+XŚC&ذ#lη:n5 v^w;WH9v:kh_:[!fp|7i?囥wt2jwe`50h[ۑ/5Ѹl*vMYW%#eUI`vx\yoA:0 Wp/lijZ;pUdzXL.>-LXd)V!BfӅ)\RHX)d! E?-„oF}Ik6KS| aՏ\0;*$~1ɗc=_b)i>{$/d'OWbUFׇ-@ҩޠ5' "Q o/A o_"suN;udh〿քuirݤ#6G $Ԣ;޺=xqXKԓ3LBe|mFaR7 C[09ǚec3tYvڱΡRF=)bh7|7nnPfϼ3>/>QOf wwB6$/Z|-]0eT:u̜9CFd;/M̭ BD߲&ucI(OƽXSM ϼ>qm@cL@rp Ν;R:`w!*LLLtD,rpsԆ?.G* Rխ];?l])JN73lv$uf؎j~`4tgܒ]^}||p ӻw~p>OnakvNt9[Y3%_xM /ZO?靻Xoΰ{T¿ Ӿ2Y(l"7l7[&β\<|g-ʄlJ})[ET/&,@*a}Ik4SWÜs-pF_nv+  mHC(ߎyƽa^Vr= Kb Ua~jq K| Th蚚qq]5WbߏnaP,hw7@H\p bNU4GV|MHVYQ };kbnSy=ۻW\n_9@g'ͭ_>Ⱥ? "Fk׮a[#Jrs &!=#W6C Ʉi̠?X^ 4 €+"ğ}6lذ7ۿyv?"䙽D[nOz>ێ?oja_j *^SGBOO? {ch8 h/۴n5g7} ll/Wz$؄$PϑMVЅ2 ~K޽oYnZ\O[30@OG}tr&ϾNHG7<xCHS3Saޞ,AOw?[E뻀!jgJ!B6~)T:2QEB Cw!Ԝ|߂$y|6_P&Yb3VHӐ?SoŪx0K=w 4|S{쵻{;+H]xL[y&cοt1:Cmq* mtPݫa@8  3` V!> 'xZ̵2.ň9cqžO<ўy*hӺ]?Hwvn_[5F+9zam[ϳZ"6m:fsƶH]wy&swƎ[I>C;{g.x O?F!`}zQrg[ǞEF~a_OWlCu~7T#÷:v’!~fL?s,u?PDK}}G:ÝZ5/ k4Ru6K+pG!S@!g BK_*4!x`8qҷo`0)ϻB}̞?/+Y(?̝9WƵ>3dxי L,lI'X1r€﫥lTcUG:Vh Vh6Ye c~{U'ҁ;Tpw=wqg $E|`FAu⭊ ߾@4tN 7-(T禶آLfkҾIORڿYҺwf?H*֭ _FhY;YA[FIY=ߖ^z*-q-SO0qTP&ڷ5ݫYF5N8ÚMj_wNbSo-mYs]u;~t (zZ"b[ˈBǁ gAّ#H6xNKOV`~cumNO1H3j "~);D_PɄ#/ϵv, &텽l(*dtxUY"MHX0)|D \?䠶[M g ,>RSjØe<Ͽ f5{̂b3 s=z~,/e\wՅft+n5*g9cyjZjY"A99@G;LwJ;| C4Εca6dP€jp}]0g Im(w񁠠{dfCe8ZܣfwM#ub`MKbk}]EW5@>aNXE@LڲO~qO/x'%^v{xRLRK̜`/?}ZI@V U]h={4˫eAn;W#LJ Ü, =l&o@2oU6>F|@\_j?{ j@]s~Ҭp"~w;%B6AFEUqBF8d8p`?ܓI;^d4G9ӥ"i@n1s,.c;; x~pxޫXXb+V] AQP?T,H{7/{.$/].fv͛q'v|ĭщA4ʌɳzjQkc/$"  @D*{Jce1Jt[-eY ,!#H2{0N^Ѩ 'YCgs-8@خр('N(v&օQ֒_>l&?T>{]5GV[ 7ea쥃~zƦ% ̤4ch:8lذ-f!5`w~Oj굷da=^{;Tm9!œM+JqeMú>+ 2H<|,;i\h`cK_-fxj%єVMſ諒; cQvq*l)-:aъdz:eclI cd[o-0#AyX@@@@6BkiCoPb3/ؘI=>߸#wϷCzD~r^F;.$s:yhag8SjdQ*!PDQRuT|A2/h0ºp\K=KCY\0+'a_/kg.z?&v]xz2ha, 4m_}w\rFUٻ@>*@>`컋Z-d[X χt[guv_5%"x~hY+om:/=پkZjk^e]uW=PبvS{f,* R7v>`= s1WȜ #Tj#⟧H-~\Gtu{=:=52 @?[UNPdJ%# ӕW^yOQC">:* nS4zR$em0 [jp߰&k.@IDATOZ8&vw,+VZ#CxG:j\I!˪3f@;&e q_lmrUAB\;?y" bsS_/jb ,70̮cO͸ bD`ry,Oluȵ=,l۬c/o{V>Uڭ `fl{nX~Z,# r{B7JWmLjXZkzƝ]g+NuTn1ܤK]Uޖ?с-Ү.]af3+PwfA-V^>u(|_.}|A‡{ձޟP=?N݅T7ZFQ=zА耔$g; >b:^?}|6 kG]]w1|'%ȱ[?#QM< @P,n6uDstF0n>^.dc/%"̥EO $1&! 0=nݺ;<e\OSڊPss$vU,w<q=p3Sg{וEx!G˞6^k p)_-_v9J&@_w,u' ~Rod֑'o=7^ވ1~Yh$<MZ4nD0kײup! Zlp uT{>y sHy3@Һp/"}U3 :00?i5(ѤIL i+ԗ*+Wm\.w to##!o!SfM2s~̘hKoܸqfH(R+.pHPWGvuLbJ)ĶWWH,O>$xo-X{IP3r\QX ƖX-6S[MUwI'Fv`^9; L:䙫awF ϶{1ג%G+_ 1RV:0λo…~=#*ev1޻||VMK-Jh:D0gsXK\4xt~D:aR8w|7÷.g21& FXճgOŖ cXW+>K:UCWՒ/%VTsՇ˱-ѓ[Ȣd;5#ʕUeZ;:>{vViL=b$.68n2@kX󯨧 iHz6o{-2n34bOq\ !C1-Clʜ7 ="< `yc{^;(PkgP<<x`A`f1i | _cUo;&]4;VݢS^C5n`M@֛H=/Z/ܠDg5k\X"o&uɿx`stiIw8$рd5hgAo8rw޶y'QU: 4+' T^u/ӏ/Ş#Na_֕a#g䐝N;fюĪ +>ad>|mK~R,O˂RS/)E#~e$4cNJ9 5V}F_*BrݞTwr ʬۗ^z)iwr+`ƽMQaG;ӣh&9Z_o']Q}r" cXL_}]L%8qRBD]n71cfRAm80qv ߽H!󉏼#3~W,1x$%%PAfh#E? r}d#CTnCrjremn"BІRSmz|e"Sw`}vH8Mp!QYf4য়~˨&O<*a?f&Y*&]N:i-uqD R۬Uk}QԲW-+O=nOdU#CWݡP;@CA ]?sl''MDr2UID7*0)i߆2f.@5h2]ps&iڴ?ξsMĝ"3q%Xt̚y>P[jC@ ?kTz]~C3%HO]=;;]*Lb3W^y[euNMWwnߪU+4\^uURx;.975ۀl*ȍv U0X~*AkGOX4pFćV-Dvn NNRr1m_#}`hu6,SjeFLLK֩Sʽޣ"NI?ly~ĉvHxҺ8f꼴+okHdqO ̞/bO?z6C$ ytn yAcnz-O4>(t *߶0^{KE00 HX{G[v{Ȋɟ7.LΪX{v4٥ϭ K@ KH5hsGݗ>Jga_gsdrl{h5PS9FۥڐХKtRXq7gcT1Ht;e7[KnBh3k:}c92qwUro=8a)@r`\1?Uo:'~cs~Ʃy"-2`\[\XNgDVf'ǘ߇vۨs8,J]ju¿-e`4C}HwdwY( 4RڴiӴ+b~HyϣF2,',QOydI^/;mJ*GԖ;.z v#\b%9L0vDYR4C'g=mqƂI`mݡoc/+tO lc9@NY|o.]lOFR",Q#:$U-|s͕ŋKcIZtRE`lu|O?O341ė̚u{`2{:Ҧm{2o@l84g7WcuB!Bd:ABn@.2z AײtYˎ veFZxgL J; <0tfQfg|P>{ߢ\kk-WWS g\HWExy;YPߊtsa<;_\weŚ0`k6FSh7 СCm \ 0zoahJjPWd>TP$U@Oi~-W @{)gpb Lu&R[41@Kd5rV ~s!n9h>Nq`\`=QBԤYLUbIMcԮv{'a%how~#K7f/2qDiM+KN!#Mp)ݍ1u4D˕isͷޔÏgw4ϓgȷ|eZD1 zm9m6z۵]cڗ3k&Ѽy0ט/ dYE=l`7G&% ‰ʀxMudD>A&ZT1E,^NN:Z9rk4=?ŻO?h h 3foH9 ]ːl0GF|_[V͑VMH7u9rdJ=ju~3cAc1̪1 l"V;q0a;Ö0DGiPLbKGXΚb{?`?YS;ۊ ^,R 0'[9 :LXK(} mS S.,T)+Ͻ5rޯQ^TR>T\_ۉqʿZWIў25s`pjlA3AqƑ>/3soV2tPsuP|/#5ŋtmԭW[=lZ*EuQ>TU.q.ݳ AҀuo֬Yjٲet D979dg[3ٕVHͥN:j)l^3g-CY_9Jg^nEb `=Zc9h \zr!m~ٳqòre5e)2pXeἙ2s^yrk_UezMvM5SAp:ю~-ͧzHX>2dJ`T*G'w>LͲVj.N3dey6F]` O?m?%`pjrdv5ӎ5ejאIEui 3;#^1ȣFMԅ{[v8\~1TE9Br$k1꒦ye+>(ڢqjđG>ҨVUZ|s̕&:|!& &?s c@I_?u>gbm6\gd Ղ yT~ӕ.h 譴\i XDS|iHh/&&Z݂(Z ?-Fد.@4y bv=|LG_:+Tp$n@ie-"=uB#l@ohb%]ƭWߕ:UX-}ԑ]-K嫟kjZ+Uo9@p0-=``A"^Lpf6E2~o&\YRϟ_Q˂=d] d>ɆZq:BY#aH1X:!N hdVZIݨLҤd2D4U^p3bLF%%jֹr=稠v_2r&ScQ#2>|xvh^xᅠӱQP,ku;-fm fۑo sn+Uo z-[ {s{ øG2 .^?K3+<4[\]~\y5﨨& w&×D2Yl hԨ4l@ .s> >y?+˝ߓl`PD9si]>Ĥ7n\o{!X3Dk t`]M:-*sOW?E" {E˲AJ~l)K Gdڧe+l+ޭz˧"'֑9 ˒9R&Q bҽp R  ۀ ÅH_6}poe72ղ6UƟIm]s@,=zmYz+Zo}7uUE8@>5Iā~:1! fe t:h3`tM|1zltwdYG<׬RNʖTC?fZNZܡu5~A}n';ȡ[; B;6۴fώ v6߀snLV*-rBһtځ bΐj1<ſw fFwQnT\I{ҫeAI _T!L~vzj&KOT 25(H0;8SlU[f"FSUQWn0n2}9k?o ʈ_Z5[Nid(ZW@?;0jrU夋9ϑ}: S+`c,XCsrҺEh2^S9s~;-P'pc=5~F8GKَf/k7YG- Z-o|EEڪqH[-U+p{gG*SHpu 0MʩyeMV5ɑ{Փwk]GzE:v|ͦ3\5!V,gCԉZ!!"2k*0#n _JΝtqw HCp3t O>1:_'M]h+(AES4k0Y"B"e.b]-ɐ a[kȏH0}!pSUL ʖU9hyh1_|: 2 e]l:?$ϡogV89^k:ԬQF>{j)&իl2s׃-ZxQԟ5IWA)҆0w0Sk*?H/Y,7Qi)pY.2ۑϤjdΧk9WۑA] $ʆz%cfZd =İ}1B{Ì1V@|I:I+N+zAɾufI@4nzy˸qi{}klNHc?i /ƊG9p~;r>ptfUUwtPĹr\lꫯe;pLV4Ip =smՋօ1~9LAr䛱 Z~f=W:_)U20ld]eNCU:[)TjXWgqg8C\Jαˏp 3f.&f00~c*$;`isҺ29tgƫ/o{Vw7^_rѭ Ύ؄X>馛k , vB\xWs9xC$:@;_}IonDzB3* ?hK,Pi3;lkow u;G#}7Ӕ%-#4H) sޕ)SȪZF|kT/Ǖ5uT 233ӁP3d#0 6&i HLuȑ6P12HłVT\Bu r(U[(\5\'}_l!;^%7lbԩC15н*e\}@m4-ugXyxgTXRwl69>;&=Jr)_*׊g_AN!V/c=}ѦKLKv[x/(I ӓi`hѲPa'mRBfmԭ;=pA 䦼5cJZUXImjL1i#=3 @}x:AecܝE){0nmC,nЎ$j{fZۨkT3ӏ-MX[\N!N5 /_IJH0 Y#[wb͢ik.QBQ)j'V.*y!u2ofyFWej#A r ez$qR&Tk-Vbm$63a# `h/ vԳPiA `*lTCY5t]ΛD;%_L׎_S",&eBuH0\;$+b̂c`pWV^lmK[n1ш0^ >@ RE?"MnY'TmSgV>=Jj۷s*6t. ltRP!!81=ꨣL(F#6>f!\ `]&U;lRG d+HKX:Ôvqϕ\eB&>%9K$4u=vP㒺 Lԏ!F]cL88bX[8'2( /iQ_V1SJ+mF_0}]X>ycAP\<%)<$iA|g,WQq4M0mWљf = lߠk"NՃ\ge0@u#̶mQmAgĉ&&5G f&_tSvcoHF~E\׳j]+މk%H5U, L #@8 '@2+hDG?, 2P%4Jg%f[ P􆄮^d"ZHgEtv0.4|Ҿ}{o%q}PoĶB\vRIfD+t0@*D;v.ni&T72C7?P3%Zgl9%9'w[%\B6}&ǵL?E`kz5n&N%0\WJAᎶ~1RdO0}81o2@DP8pAlߣ{m<Ǫ TI#߿ܫP7ߊr o~xWՓ;$/0\0qjO#ah/p;_vJn Ei&vMat68m!@'Z00?ќWV>)i:Y0pC F}Z|34X5 l1b,D!b~B6k,zJ6lSeɫ6`#US_dlZ]F+?x7g:mzn B VŃYs7GHW͑?[-SK˦ߙVXhv {a%8p3-X䌋$wd Br/TB:ەTڪz*ƪ0J̘)r";KE*(,PO A(=t30')gUښݢ{uT;{mk1g9ϘMjW2HJUe=0|}} څIt%g`DnQ ӵ҈TK);rA|4ct]ȕU*ۀ'Є [@;L33 ?nPw <֩9/m(uE|3x/Zb'oeZ8YzPY9hOV˳ۍ0A`:SltFbE8mt,cJazgrӲNyPY-U>tҥ.cJhn켟%w x2j9j[R+,T =]P7N?d`e7ʂ{c'0Pf}{0 F?6ݕ簷͐xvNڱPVF x`N,fD|*ⲁU+Iľh@,Gl *O_<\(+rOSDԽ&ڶmwO}B2ٹs `q:vV}Պ :t!LϬ\|f`.d~y*Ң:UKў/Gr-LsP @[o+C{K1\x!!] GBj_^,{) ~xD?bw0r8pg䣍SFgh+2I؀άޭq@Nre˙;kPL@K+d G̟}ϥ@8pCqJ uuh2%N9֦@cua~AMeݦ2yZ9=L]QB,o%?^M \y}jҨq3`0@B0h̳dabQ}F4BvvT>9Q[oOȈO$toR=HO=B>x>ӥ.~{H葧Ԣ j(SпC Ӆ_D)EK"lJOhOܬgzaDdఝڌ_Mz@][|uA :iݿWl``uQ1{ Q 1 0`zJj=NO_=4; (z3 UXn:Fk0܂7|$;}Om(422dW=h]v\sBydr˷SQ+HzdzT}9sA?ZhdK͢hcruj촃.m[Ȗ{j. י~6F Ȣ I螻%$D=Y@} vp}.(@{m@ܸIc7+4j6+`>]\t\`Ԯc #zA,of)NjȺNDEܗ[?yq4 q޶-VdXyo< AЃz]hÈ6[iJ7Qg,9|O  oO)#^-'VEHƎh. o.ל_K=OVfȷgI jSt>v# xLOɰ)RfػuW;fH藱jHH%zt?MBUu-"E"^g Bh$JQV H`&C Łqⷆ茌PE覟znf ;^{͖Bbu5zƍe?eي<_\+_Fn&*ȕ<亨|yW^)}5 aY>0q{47:? BCCgBOS jC 2 yq%]ǁ4~Z4[CtФXj fWSϋ@c`wk _gr#E-DO)H 2= /(I2gϽr}O(S3|n+c#}%:v 0-I3( g=2v/o6e ơ\\ynM*/+='^>W'W^\j)p qڍղHXʾWX&{wW֬ǣhkٲbwWXW,F懁)m)Bub !U]䅗?uAݫ"J<{s~HU:甗~hV\(! M )<_^e5K/̃& F ^ݧa)OG EC2TkUb~yy#۔A @; 7A6`]֭Jq߹{zxϱY4mAPRyͶcDV,뵃A_\ A5 "Nmʋ)![M8(`y㩧#{YcR #>lS*; {He 6CD>bvʊfJSWɅc6؝'s N Rި3<*-ϵyM?mk>M˂A n8W],J̒4*Ě=,+5ҙ}MF!rf0t鲀[NR.P:ԋ0ږ.^$@ÞP:|],`ASL1e jP+SQVJ9صrS堽+MV<6A7첼- e?Ii ix9|p#lWƄBϿSSs%XҞ-Rǜ AoKۺk%1j{N~ͦzO"~ɅqZ3^=i~<u} þb`" wP)ME$$|,e ~MZrr#,$9թ91(̝"©zzUb&;J[:'&KA;]{裏DXĀmNAt5'=O.Сr*s'+WSTpfɲMr9e.3aeG B٫W/l`m'0a>~U7) [S@*>BEvSMO܉3$wKEPu ̂2%2lȴ^q-kVt2b+ ) MHAWxk&iyBW.tӵHNa4EZ،|akhd @};t4!zn _ۘQp.HPYݕVK+r|qqP <1 &?H@ԔG4q7.|MˤӞN`*z,c^|ze-"57  iҏ'|R.=bF^9}k IA qLB;!j`(RIAg_a]h.&_X]kx"[XZ5R J I[u#}M{Cةo߾|qg[Ν;3xyMyn#`z~\pa@=0rI" *EVt x]dnHxUTY- 5VB+7Sp7ڹers@Xs~9#GpU<=U )=sET]|1G>uԋmnd2E3`/L&kV=C{mD?YGl~FTCGuS+G<{HWNXEP-M>r/ U;?XyX]u}~~*ALZ4k`';mk(t:~7qT;_]RPA*+UsN.hdg\&A;XzJBw2=G8PO'$S.:%>&Qj7j'4:=P> LtkUTԷH%,Rn_lcꖱK&UC@CSpא2L 46-2),=.#ܾF xOuQ:طlR.qNG`f#m_bpL1.׉Z+_Z= tƿZ *O"pZ:~ r̡UIeJZ% gu;ܶm[6$01*xOB#P#S H4g2B~G/4p8\D|ƂTy+N|RVlJO`b$Ҥ"s 0ڒG0K(_17Q  F%/1^xvP.ҠhL)8ѭ[-ӈ{%qb5 Pie* NA~c}SV,N 1@kmp!Xƈ/2mQ6L`8-84{ B3y>|M Q)qOEٯTq?Md'R/:rO]dw!(롲{Ғ&ĵ=Wl?Ԋ4Uw: QFIƍQJt%lҤqr%҆? 0 _=a8T'5rg:MeS aMcJrcd3>d+dDxy57oF9r kkF|_l m??^y4oIx v{|wυ%SAíy.6 Ne SV*ƕkWOfˈoxʏXPQdDܗ@[4{%p` 3{ӵkW%o x8-y/@jVNk̑2ﯔvە>jLA3yFr5tG*~Qζ`~&=l(>5qp[cX( qk 9Ԃ׌F!T2{2,]:pze G"F`d*XEGR&P!A_C>m~_ ) $cر& vD}9j[tC-Q"׎$vknם!\W6s&q)l+H ς ",Yz FEö,GD/+&Յfҭds Y(Y<>D+9d-i׊PJ [-PXY֋~N0!J$oRx`c=l3 ?.Xm67)gQ?V>~p,k/4(L$?qZܾB:DyBS# 6@4ChG_Z{-?,Kx5-M@'R4T{{CL17D&CpA @e_auHj kݻ;ض5_bQ? hニcD0s̱1Yjɰ! (= 7iXVSA.uhRVƏl!O]O෿ *?SǩRUbkpY'&npw% \:B*x^Vb~Ǔ$ډ|a4dselHˑA @F>DM%?~xi߾|֊Fzpm&(%~wd؈2zz}A<Ko97yݫKupUA2K@8iV!5lh%d1Rٹm99y5m!+T`KV`jxAߠBM`@,h-&gQ!J/Rah {8 6n?~@wu;3—/_.w.&yIn1nK~o ę96=?3S6דo+Q}.&Z3 {а쁌, >ڠ HT=ziEYlg~'ESY~dJ5uewi"í'`#meTd?9;;YLA~zK `=atXEa`~w3o.pp8tңu#oKt{YŠ2\]PMKMQs萢R (9|anc!YL;TNmqrIQ5~K@hR̯lUP]uR7!(ad̙3~(%M?¼c=&G}08@W=z{xJ㳫YY=xJ?M.S|RK*@<K畣*=M0?/eh *B=&mI5j\|fd'Gf>eJ{O;gqi_%NгLRϡ.˚@Zɣw0>a:J%kߖ<Ѐ+D2  RL=tZs*p/![Q|W'C0N}~w(N嫆Rt.U5PyyN>hb4tUWEAL#' tI?MiDes(}?%6c 4ڻ/ y4;Zdaa}u֪HM t cVJ:0-'\%k(½<%,]23D"0>~ 7Hvd8fm+oLR++-)}H{ O(hp;Uhi"懻)n-:fQ5TC8#.H PUL%̯iߖ^U=FݡG)/SN]Jo{CEqqgrP %@F+lN6&KP+]Tlkaޜ(ur`Et&#/6sm2 䚁#H.Q77뮻 ͛L֭>_o :]/@*|y4цv%S}'/ǻESURR15WBCQȊyjqڿ pF,Vi+R&a?mu?pA/bKlZ,b(ܠ)(Wtr@#vHLGc*i´? weyъEG(`kedUwZ@d!Z/^V Kp7?ڮGP [M0 afguK83k|C-NOhgw-[Σ652 ;e"ן?K ңӅ.b̸53>ӋrVn/]'Sfd:CD#a3A萮\듭꺨-MIIvKq$5pl u $AC() pvdc!g[z9Tpڲ].):HϞ=3XQ<묳!˚J-B!J`&{8=ک0 $'t;!r^tUԝ.isHY:HoTwjS]xS !Z rHI~+zz򥗪lz{EmZ[uV'Lc_b";=`J:3PXWf`wnO^ltDk2{2YkQu _vZO5#90{R%:F?Du]Ls&Md ~5;w{F_Uz$ޔ|Fwp-<e"X3ȳ\njԕh7~_zq}y(t`@ڼ_b8'<2kb)lKiQe= .9`zT&Zh#^6?-.53pP;uHXj*?3T 4ym t\ 2,^QA]_u =fOdw6a%'-"0l0g}iIX&%=0=%$XHj"7 aZjq!$|J3oP~?*a% RX^Or؜ϑxU܄%ʗ.;(}*}R{`Q)k…y4;ҽ{wٴ &h, K)L^M&qQӖ/4ϑK.LJs%6 voGt,d+l+)e_J$pRhy wAW7#x AMr JS)|Z֩ꐝ'0q<~c;}zSN=Ocma%(ci\JzmKIaA@󠄦FwT|``fw&.ᑥ @  %*@ްH c[i5,jWw:˄aȑn֭[K>}v[.#ل)knK$Mt $.M{s̓6 &J0ITḄ$Kb|S!^I[o)={yL>Yd"'=9 4l?a,ʧ4E@ufT;' ԯ__t"/"3"-*5C}}I۶mM/R3/bJ2ݢrjh6 vJr3h'Ԕ8 OA VVSKnf4Y_5‰Uϥw++W.KYK@?u;uoAhAA<0 ܁Pv\4iDnfej00ǩ)^bwt_yFq (Dd)Yk ^zo+4Kh\|ɷJ?nHv}N*UWjU5Γ\"Ӱ1s`7.J}1*܌4}zwuOj ?8}0''Gf.m1 UT5j U%2c /dԨQ2ztR ԑXuqS ,RTܵ($LIT*'w~~g=W.{_6L宗:U붮U,'Q3հ8山]F&tZx_ʋΎ_ϦGNd8= 5;=bK~ŝ)(3gb~\XT|}rS?*l.HM%ToOT򹣾q_ خJz{h>Я_ޞfBWW;VjY"433JQex.eŕ5W?C}ƥrո,5+ӰB⛊nGЫXcg)3MY{4^m*OztNIX0\liYK,e~]=\۲eqH`_]{W+,8;*fZ:#Q?sӉQHjß]`nݠ_ʬ%ӑNlQ雇 ?SF'𚾒o<ȯ=r2Nb$M6:&'tt_[:S\{E.Qh̟ܗ2(\aÆi=V׬ݱyss7EuMҳlZ_Tm8П>PE oOV ICRI'&2;O6T̖::>8z===7J*uc=KO*OO*֥Wjb=6@ߖ/n.NOC\ѓl׺TdUsVs>sL' ?g%-s}VCjȮe~_ ao ԝT->cZjۯ;՝;wr~R-Zf ~?~g hհWzXlU zxasRGB<@IDATx]tTG!J @HpݽEZ(PbF))RBS(hp,}alr3l޼y޹6wފlalalalala?oz gʔ'>.>CL11111 11qq׃ܹq hqc2xݿs9G׎& s^8_;;IP}GFGs&0;mvJ{,4T"#Ix0bH{완)Fa%#^@lIx;:zf!ӰH\^ Pe?zQFڵksqv$a—"n߾-wܑIȃcyl `P1Cqtt{{{30GY=vOܿL~{[ƌgDD|\vM Q%ctdnܤNݺv={A}/\K$m>%Fx F&};Ԧ5 РA^^AÇKru;Fxj)FFW]||˗oӽwʕ+#4ҭ%70BwǮ2'3nnux J'w*bAF˚?]]w#PcG@xcBќs8@&ױW@H@H h:QxFgah&x Gv&0cn@|WE 3ùHl#PQh9dD`:U" Ϡ]PϻbUbxemI ~koTO0lB(P.[ϊkyP ~@5LPmv&3>/¥KHO$xPƷ vmD=Q@"MOuxV[$yz5|-i 66 $ H)!*3tO; %1cRu3!>gޗRK|X L)ט̶ ) !qO173|N!\^fAa44&*o xTH4gyǑM')rN6mj \k" ~JLK{.eT[x b6$Sz2F}kA{"pŽ@7ݦ2 6ymiĐPg;^N-.\رcT`(up-]j~ɎB$EQ^y;*ԁeM[ jA6cD=DΝ+y֑8 )qBIza=nݺ7+Wމcaxv;#o5i[D3 V o)$`Z@ O]\}{ylR9]]rs:qϕSz9,RKkWlCH.XО;$_̀$(w}RcxdxXKRpT5Z4 [8gkH_Kg ;{l{GF`mϥdP̙eqy#`: ^~WYQZ=/,cqaIz\(n4Zqڭ{{{Kƌ  $IS 1]k3_Yd`-.|hb:O6 5Hx(U2+vK%پ)xM͈Qq gϖV+W{.B0lWt^εGwh3:2JX)H5#},]J/X(naf_3fo4XJ 3y< vQ嬖ɿg>-ϜDԅwc m|>.j =xTAgຄz Hd!pJj-u0WF Ub@ٿo{t"Z`@: 3$)ֹND I6V%X%Y'{|cb;$ R%5| ! qE \on+I ʈLR n䎉 4Wn-ZdwV$ə3'Wnp[C|A9ɞv-xF|53K|Z <>(0b)C^mˉ񟥨3`aȞ9d ǹv:ɔ?4n͛#G_wqݺuң^gc4l窤E{Ij~Y%i'}~7oDl;XbE$,4(.$@9%?Db,236թ'%|o8q̜9A_sw7EHߕoS F;<֊1kVɽl}8rDU|ڵk3gj).C DkӚY0lsa7\?Xs5u4ulM!cU@8uaڼO~pé/Q?on-6Rٗ^*{¼]blțkyq@@riRTdxxe%$KrJ`XrU<{tL. <<#ٲe+ekjb4&4hP?bΝoĦM~kժjq ("M?*@q8p`3t7Ȋ.>R ůo(0r8>3QWa LKm]{m۶ÇoŬ;7 yR+apw׭#wA姟~ZyܹF/f|'v 2+;t T&wԮL 2wRcyxVnTzrm*(]_~NYH^=1xo>euG?y",wB8ك'VNGȻa}$+$HV$TUHŐHªlٲgMt}-a4@G cO<9m Mrb3(r._u1&G53!WIPEtid>{rIS'-JUCrbxH'8jUgbU=F }zqz`tptmϰp\6;eI!-[YZqP ;p@P>8bk5sҥ K/Ɇ*i%Ewի~Sxsaa^g,W#yㇹB(Gh8{ 9=tX-c#%/0wD"J.D ktLl[7@0>Xy^!<+HFK0rڿz ,셑?&gž?+mڴ ŋڽ$%{h8ÑF3V5':u4IMݻb0? La~-mZK,ɞkԔ+pWs[# *>Х+TÝd (B|a F?UZ3n>Z;s>Cx`sߟGF+z…Mׯ[o&^Z ԭbXߚ}2͚;uu>Z~bE!s_҈6ϯft7zs={k5c.O=qլO~^>W rqd^iS Y; ՇV[h5<a`]lYēS ζr/tzfתń!O%7T s\=x;\Źɻ')Sŋu=z^O5d2o-fnOv:= e!Ot*W]!m'Q+ @4;{2뎧2C2;F$9pĨ\ۢ,]Fݾ%{>H7yHqΉ(B׬Y'W9o }eϞҡ};zWk׬͕T')0}S٭s79+P@*0l;g. صKe*M4Wgٲ D2ĩ?}c[9ħE ЈONdɏ% XУTIi}~[5Ӧ!Aݤž=QCRXEVT=[AdƔZ[WDpDOe]In,byIrPy~o3;ɍٳg99u蹏*9!Ka< J_;ȥf hT3Z7l n!TFg/ˤʫC[isH˒A,ْ0 zW<˖: /嫝FX</_ghdǏC$2}E>1s7hx7 VYFJ vll޺EB~Ɍ@ͭ[C*dYoD\Y@Ѭ<Ġ!H4$o?胪'f @uPgϔZ h UQ4we;9>CBR읷X0{?n#!p#GmGرs=c ߺuS. Y˖-1>WSހ=)m~;obRRD\rE\ d豧4dIuݦa|  "gt}H&VQxRCgtQEJ3&b}/p^:WҊg \\c#S MK:ux<7w `_M y{@5vɓ',muבs~X&UA;aQ];wbys-Zt(?<)O Mz F/TrǤSt8LCD8GUsmLZ';u3> K&eX6HisIͫ>o2|7R*bn8gtbJ |VٚmQ#F(`?by8ojWjkd!ıf܎O$Jv-G$?y*zHC`&JM~XԍKQR>J A9Auo>|(!9Lll 𘁝#t+QXL=A֭0MA&đĝ85o޼f_P̙K qI#>o Cך-uzHЁ1A}9ω|$V#HdF!|WЊl9 ׫n[S5l1qL+-YVR".\('NHB|6C7OI^YW`.LZJ1cD`DjRac#nժU)`#?BO:5#Gh;zfa LPOWz}i(kН?c0 9_.}th#ٳ=]P`C_|!Dۥ^zJܿ[ɞ)ߋHKDk9 rnХwg?aJz% =UdƍϐUUħϏΜ9ü=s>2)vF=~"t,Qz:i?M :#[4aF"х~Sՙ:9M"]mB]\_L+eSD0ca޽{= E8I6l8mƌK*`==gL¬TAV^ÉZީ˫PrZ޽+9Qߟ]X޽O&t GqJ_@HN~?S\CE)_NkN1Xk ,0Nמ*!=zf'j>4iRyloho~ȘѣueV,&.] RfΜy "1`RWRΫPBmb t`0JFڣ( )ٳZSw#4|e,r )!eVO@q㪕e*/z0p@3$dg̜='|ݕӧN h\ zpɂ>L #bZcQ@/o;]M#Pwǔ}(׷mS΅`r׎D:cT=xd;aes5}A$&v 'W>ND&g\ݔs YVke۟ČeQ‰!Դu9t~jUc~)׮=f3g U~8/73C _v"rCZ \-5%KBФ*Ut_aߍB <Ž5Xk&#'=\?`:YqrXhXN]z;Xuďs&O=|ID9%lÆ {?TD?CɁ"?SfwT0U]u/sw!Z@ "\X9I|>sרnqqB>9k<%r֭8*~H-^NB>"USq$BA\ajUOC_c*7Yóp|EMN+}hl,F+ATںut p=^32Y `5%Pgrw KN ;}98x%(F΃/@`C8}Ȑ!#xy➒ \7,/6hjDfСrdD E4sSe[}ۘQ+W^`%;lRhQpDߣ3'Xlk]+ )l2Q82VE%5 8ڹftvXF#dz^k׮E6@櫑hE@7,FqÔ&2^}TEʙ9s f"%ݯժa4OVL{-0ۈ R½twAGon#GF 2kh? ipwk@»BF8 .X),EL`! < 6nI]2 2GATA26JV4 (@pVK@-5[(d_Ҵ}d8'(hrb}mxk5)Rdr\2Yq;EcM8"_1# @|%JV-v2~%H稣e6eTJm&U4?h1="O!)SO_گ & O>%ڊ|7$bP\~89Hz =kgSx 0lHS/J"-T/$8;CHiR' VRT GW# P0qU]?o`tsQ|("z@x7XX❄؉EaTC`Вs5 %àc ~R{xOt6NxMiRt* m!gȽ 0*O_OC%RheBi/7o?ƾltɮAE0< c1rۣQ ],!&ϴQ`°3^`Cd |% /X_kQh-J}(ħr1XT#49II''Xu{c%sZG4_)-X+VJ_@G~VHҟ~)GgMv8T 3C#&q4 ikh"|Ua-az֥ޮ<ƈ~"2 9V;aŶ+AiB)UC]750 ĹVwMy`)tauHO+ c2 f#bhǿe~ƹNk/9cܱKNL'y)SH0xη#?A0))Y kzu;#@qΨF!MR]'7O̒Ԍ{NXŴ,BhTuP̩ l~F÷WynYC@9'Sd8^$vEA~*. @qEߞ1KYPH+^],\@@[z6bUb.#)5ѹsg OԋF*U>>3u;wj+!'檺W ~"9DxJf~(+ Iw%FU!qNT} `J[3 $ KӰN!2 1@e S+2eȶd! j$x8 B@vn*np*2o\QHKuUb! |\ͣ*iݪz!]]m11E< J~kH{4 }Si>j7E@d x nNe8kCz'43?$!Dǹ{}HYe*osA5y?߅ʕΜFAIxqDЏRӒgRE3T?d={vR IUdb>UB9N|r@x1Xd`JS'd $׆C0TI Eڅs6}49vR"2֠s [8{h! 8_YYx$ s$Z P˄%DS)R4DAUQ0D1>e py$d%=:gT ):k-j9~i!TG~QNt]]sNm9JC_rh @FH(jvaI§PAŁl~Y*0WEx0E, pAI:>#2<G;+Gf}@2&__Z88ȕJhR%MT _/+$Ȉ6pi1{st'WkWu{#A]Cݠ<^S (Z |bIxgdEB0u@GHbkCU4c\2*j=ķQ p|\OבY8t@ן,!-ߐFuFcLi 0W>EN 'ne"Fu^)mx;&w5|S4z攈*f%a>%!Il2}|fԧ" c{K׎%HHuSĐX|FAc4 }X4nTMhVvӫ,X}raeԱ]XE rb vItMi-鳒%9b٣O`|yJ=[믵ǃ0M'ȑMMoY4TT$ e{([8h *wYV{GdGP8"}d:9Ԡdr7 i$4:K ƧT' Tv턳΂ܠt"K\_c*?GG{uT vl[AW"[dC'd:wL^9IcYKXy{R!CN]q= 4F}7o݁e&i7P'Əm&?/nᐛhx͊Ҩ\=?r爧]SHadpJ5zAvl`?1Naxx,N4<&($>:gt-L`>lNq~?%xg: ̑#NүK)7L"#+Q*yJ̔9M2%?r9I"ƨl|N[<ŃT@M4׍+[0pJQN \v- op,M n6Kk(;DD0-`u4ycl@y~b;%`\_5ʅ $իu{T%k|jjkq,߆r%#ҼIƒ%cJ3Uڷ>qp$hRZ jt0G>,qHX!u,>T_M@vԌ 30[LIPAvӝ $;IBA>PΤF7U)&`i'OFEHm-%RWG)`3j\&cE.cʥ YitODF\Nmf Y4T֊C#BGsSqZ!^@'%5!Ɉ#ј;Gw'm scT5 8x UCѸ IM2 ay!txR$ X|A$!J4A +bNB#ìY(Y}YQa1oov.ȮCtE->v\ SkTŸ?{"xINIqQ"Ȧhڠ`%337'r^ cs^A:aυVzHՐ4&0ڂIҥ z3ɑ^ʖ]a9\w@N_tIQ${G9Kp1~MvC:Nax/,V@.ԸиGOh+Ww/5Rx~VU[jX:|]KmY%fdņzvw,CUR .&[zck5ܚZ!65M7uvܧZb@IRDY 4d u<02Nnk @CIiRUC%8Z390UNjiJ;;r V;gn^gzW %;S% )\7u{Q'rP<'cP+:6\$0(J{ wڎOh#s否8I( 8= Gz'ϴ涍*w @R @gܓ֩fa: =0?~TǙm9*OQƣC?Î>La!EOxն0%pk_`3,c,l4;씌h"Cz c,@Uq:en{^$-t(;Jك/8~Ili[դu;JZEINZJ> *T-j$@1dW@L!TyUZy+Q:6 0`À 6 0`À 6 0`À 6 0`À 6 0`À 6 0`À 6 0`À 6 0`À 6 0`ÀAzIENDB`ic12PNG  IHDR@@iqsRGBIDATxZ X~,N((* 8V3DYui9\9r6M-[8< L2sw}pn=k;Kx)x)Pxӳ4hJUYfQVvvNjZӨcǮ]-L0c#yyj<@jj*={l}x)233cXedl?W /ѣ߲e``ҥKs.GÇ!>P @.,fxbE+iKlaf:.>H~^%h'̿wq߲yuaj2kJ>߈un*jr?"D=8>#>fPa6k8<'7 ؃) Pj1~3o/+/B濮8\ԩSf͚9E=5~d}CW隠i#A9y]SS%sY,Av#ٳǬc(m+^GDuX9@ӕep]NM,.1BݷW=:z3Ɗ [j{Y>ď,+p.*PANZPw9X]U*U/Vjx8,Ʉ(! /_dc?OGffft)Ƶp֥䙂QwT6\'P.Aҳm_M}n*UAŬ + &iiȋƎkq?77KQkb d&5Af,Ozu4ӡ[&DŽȹCٖhOZ祧C 2Q$$=DCZe/W4qi MF[v 2?< -5Y'˻Wko*{~t ߆7o޼]'&h@9i׾{A}U30!<\Y?C h990-OmPzu:wqK4h0Î:tHbeժU[&%%zĄh&/-[/=`*XdtV5aߩŒ`5?;S>yfN$lڌ͇ZΘZ~~T}J'_X#kk~VB̦MhР>x_fO GH)K}ddY-:w<9iGv(++ 00Рw1x}4.kظi؁in>{ϗfN3vBpΙKu,PiI;Xe!d Zyz|I*ժiXed(;1sw^FP9E99МS}z穓Mgwx WrGN+~BW{7Ex4ofA|J ç]gS1l]J`imU?lNթ'0Z&u*5"WSV X΄b#GdZR <zn݌}k+ ۻ7TBN0)c;kkO ϝ3ϟںY9;?gka^'W6c|X cmW7oy]{ AjIh4b,,Yut[6n\J&fO_ފE7ahݸqcSpQ'Nm/&Ml|r;^}4swq BK{1 6.\P''%նm[pŋSˢqb:t6խqcPiD!P=5#45LJma WA]?_8w`c<~KdIs;@W2g O3 h> )K1 ưaZQ81GQǞ=sI&%|?c Jᅅtq!CQlWO*a$z8&&nhOϣn9 UkFGy?D g,Ń%(SPU*}*ooo Pe}Ʌ7D8׸ ̈́ Cg>} 2muSIсNdge?ͱ֭[4+T*_jrs*(19y=++k.!FT`:!.iRũ23Sc {KC&8r|<,1>ol@e竬]*d>8thڴoA&>NN,)̬zzU)ƽ URb,ˤ,|{rݺu/Ys\XFflWcǃQ\n4> .}B0`0g-\<#zzk7"YKO44CRӌS3RiISOS(-Љ Շu>rKA>w?L'Be9pⰶ^=gṛ̌{d4eT{nεɓqAfiɱԂyqe B^My*A,+V.ؚt= [<,Jh[¨@o = ,cQzu2iJGt .aY.~ai;ˆQaHs !_mm!J_}䣔Gc¸ zLA),]cװ}pr@^?{ŔO>c L䏚[1U0{tB+.^Zu.Iӧ1B!FlY"Dr#IJ+l'™ Bhhs90EyiGzWzqvNYASYSpM,oPImP3thӧ3_r;ƾ:ZWg޾Ļ9?+ t?h^Sr'¼Rh<;<*:G}yY@=2/O&|fYi98+HDpL@{ꡤSLRlG&ilH) QaÆ8.Ő j6EAxb8\Kf0 ?=Siw7[TL`lA0 0->IK )g 譙L@ZY3wD " ZHHHP:ń8y>AW/7t>?FFf!qÇCғKWaT: x ULEb*Pc71~,I>]L?MWZ{HWhM=fqҠS{A$6D3IMLMJhҤI>3%Tch"Ŧ?2FmG||M,AW$>@ȣK@f [,[;B7eߒ3 !Y{:şhil#8Yy/ ZKwh j y ?eZ-ZW_}T,Y8"15?up aɽD l,BB1`l#q =[ϞqlV{>>70IMbjW+u8k.!+,+5#:XyLX9Es:9N?SNY6_` aP2C7/V_8א{(Ȑq4f)^ޗ^]Q.yҨԵtVewbl˯|3&&K+K7jHB-[wrQl`iՔsll$m'|;gK K K K 9?🟤IENDB`ic10PNG  IHDR+sRGB@IDATxWyZie5Kd2l[U\ ncPZHH $00`Jh˶.yFGWwݝ{hswf"  @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @dY @ Tx iT'͒f11_&iXua)Xf:r 4퓼`n]{n~$O] @c%0Xg@JGi47';v-;v륺LMM544d2uuuruuu>#۴.:@o1Ӻmop%@___t'yO@A)9P&JK;-RA<SO BvWJsi$?niӦevԎ=#/> }=Mz:1ǽжi%0iJ+' @$q;;;ZV@[5[<*9P`= m0@@ PA@ PΖ'-Bf9ͫjiiJU3gΘ1#ܜۙfZaNInbtUqfG}:6o1ɴº0Uk#|@y] D*đM:oy[.D(LU^c \p ^>|p{{wWH;%~)Jv  P# bH:WrM"ɵnߴ`ǎ}ɏ{;w+`;ݮLfrvrˑxJ#жBۂ]!. G(8Xi_rРA2|^ "@[[ۀԯA@оJܽw}@H5Q^վkU;OoF._V'}ATxl_ZG|pp=>p  e p?H~.j@0@HM5HJIn¿@뛗.]Zs 'TYsΞ=;+?96^}+SɷssΧNuirimMy|@4akjzO_ʣZ8 88СC>-IIF0@ 09! *ϵgI_,Gpŋ-[VkԄ?wmk{4|ϻ~\{s~]ڒZ7mK B cدzN0S:Zu#eZ h] ' ~0Jߗ(A @`t{A@ 4({O.֪5ot'\pB'H}ΖloϸF_yI-9 ӱncq͹ԬuUqi/DoiuX/.j 9(iZdWOiQ @ (kH LHuIzjgЏ_#:no66n[Hw}v亨x(Y ,:jquIjx^?x#p5ͱ0ƺy<=+xp@_W]5HI'0@(S‘m@)'Ycy_|qyWkk12y|٩ʱцiiΟ\ixv;{p>7Z[gPx$ 80^˭H<(eIN|ojWhZhx7Х߮ia[h@ {iA@ PFBH1*ҕ9ӧOo֮Z*nۑШ/GFTF'yLr>?nᶅtgmc=ގXcB#k/v4B` 9u ,y[Z7ӉJs? tMupp tP @ =@)&?-1{f;sNGwNí?^1& <69 -ZDٱZ[[><>LB@  6I9o*Bp#M{;?KC  $@`2sn@II˥s,X|%ke˖~9q~;^N:Amw4ǎ{p=U7MrC ʃ@h)@r>,'.]r99?YۆHWc[GJ 0L,o@\ Nڠs6mprt9\u;0PLgsrhMc'сAM:;vC 9AhI 1/Z7y9F>xǎ&ݡҷ3o'?8~t C+p Z礽ahu={D߃a(&H[ 7;m.C8I tk%%{H|zB3 3 ʁ?&Y͛7ǃ͜9sTNwaQipN޽{8z EA Hl~օ}'6wЃ[$^  Pb$@ \ӦM.kP3ŋgCǣvcA B@.~l/]HC8 @`;B(k+IԬ擟?f֬Y(ß9t`[}C yp(6u`ŽݻGv$S@Zx0J7K?0@(EHRL+Ռs9I;S5ؑϓuuvf5]C#ǵ9mξ۷oݻvŵ ?\E bJwHnAq p8@J LS,]4_E]T;ߟt]R9cM۵۶mw7AKX $A #0v bMK.mv3uֹoΎ=7W::ܶ}G<\l0ڱcG]NktE LUjG |SA1UQn@!@`<8@\yKT_ŸokkVuܷ?Y>Z˾#zQ c" M‹ISc~< &@0BH;S]zrΝ׻3ڱ~.P|~TM?r Q{H2t%@`^z )͛7 OxByWS__//8So_7xG[]/"BByv;4: 4Gz!@%@(4_^f͚j܎#~8;oߎ? W) P %Z ZQ lc )K(*oWu45U3}?~.[pôкlnݻwӬ߄1@` '{OIr Li@ >QwHvK '@/!RJL=ukT:u^ǿ^/8^_hкu@!*޽Gc1@(L@- hzX-mc@Y PVBe@`Aiʕ+k=߂ b5sr4J;`~۶m  1pYGzd>1@eG@]22 @uy5]z'tRr@iГ* PJ$!)C#_s~k׮Ψ}vvmI>9my7w~i L ybIs$1>@ @* He!S@ Igyf>WOnmGwN}rrpώ]7D $ȍС`@~vtI 0*F fHϿvƍ'pBVM3,{]ryy7߹sg]8_&@n|q+F'aRG@. RHJy^Z5]tQU~93Sm;q@)"oz'wJESiL]\>f~֭e:ڪ_ݛsGtCwaz PZeԃ]12KԽ mvs-ZT{͜93ۛݷwoMG{{|L:N.joӠ~. )\{Ep %w 8X, I!@`RsR@ ޮ]]WWx֮\Ɵ;o_]qr={۷G @7IA4& ='RH\jҚ5kj_:;:j4jO{rr}}( P-SQ^-FwJWK XWBA C@tf5={Uߞkl$塶ߟK|<@K@|Ńj2hn p5@ &4RK51UUU5]vŊju[[I~y6;f LMzt+p(Kֳ@d - C)'0Kt%Kj8Ztuvؿ&YSt]rr>l 5/ @`P`@AJ5Pb@`2 loVPSS~/~hQ6wν4Ӟݻ=ɾĜ@: (0'_*&W@ P)Wr@!D;tҥKkN>ZW&iO:Nt^ f8f_Ar%'KޗX,  PT$[6444z W껺ξ<"osS7?x 5 Pk^=eZ~;o=KqDI`N8ᄪ+WMVvjR`Bt\A@ 16[_Ki?ʋ^hkpZ5niiR}U[kkk[CŎc bPkSe P C-YqٮKc 32RJAӧW-YZQcWg`_|G?5n!L!@F@A8  4@ְ)  0Z eW͝;׵U7\AڢcZ *@oS 9aH XRAz1.H@ *ɏKOY_]__jPmҹO;}y  0YS0iUMe*L! ;@)%JBM3f~v5y.rp?#@i$~%74|. (BC 04@%e59sfֵ}}ݪX^g?#B3@8 @v\#SXP E@ T)Snd7jzz3<cʁ H]UzDf! 8K@z }RАqOZ\ n\I:nAS/SSl(~F%ǿQ7ư `\boLMlBa)# J/T]t?*/ r!giFM<.gs5B 0@Fc:s0]N @J@tE@k|#*. (B 0@_atl*mB ?\A@öZa\ ^> S"SDjviUȗFizL!@(=gRZ |w&RJ^$ ͐  @.5˝Ϋ!$Pz L,5A?!9  @`k!UD aA PhPWrA ]Zq ~ {P )F@Uj О(;Y@B]!b@ \i )oj3 @) P ;-` G "0I 8,-trX+ǿA7 tPW$rOP+Y@ ( H!R˔H CtiV @H!ؗa:f!2& e|:RJ`!r=ҿ?1A Rz^gg~tt_JM 1 0X H2RsSGL!@H/\Q:KMg|TAeL@_<xQ>z @\{Kg\@0+1@K5Jz)3/V =aկ7KNü6/4N<}FZ=BNAN* Osy{x}_X( 2@ - Fv!B7(O |fZJT2747mlҲ v씧3ۍk't |?t$ 0z=#| e&@ 0^ҁ/½Fo3x8Tcɀ |f\fOwj] @j`\ΚrQ_yyX` :K_?']XVNK,3 '`^6kOԻl{+/ 9/v-os~>4/-'_7 33Gj lo:(y~Z$[cxqOݵyޟzDߕje5GK6 Som ^쫚yYX` _#r B&ܨ_1T~ٶ3]Lszvbݖ!MK-i :U̟ r%wMFο=.dL7j N8}NI!P%AI#Y12#T%ܟou %'`]јFaɎϥH@ ["KA4sFfu=o4ا( ~YQ'@hx0 % A{_Dc?`Zvw֯ͷkq4v=߽䦣9Vb( :ҹpk@88$OG 0>WJo_jRP%M7YFAiw?ץF.o$n{hkξ `SOKn:x;U7נ5e5AtN ?zMq *[Bt0&~dLCGܿS(y_0 e9 ɟ*?ypzɁ ptoKv}O %x r<*THALLܤKpV[_HIߕ $O>[$=NFp*G@ Jɭ0@` pcD)#IIćOLGM@/|q~M=`H9(פ;$ (T]F 8$1~@IE!;W^M\ 0ItO D1LSQ}Xf ~@W~,}IAGJ3Ґz.4w|rPPZ`+%}1@` ypJ@`rNpjWB ЗSp/&RO/|^A$'Jn!$ e !./C(=g foS(}B_n i0y9WS;~yڴn韥* 2rgs8cK' ?Hcn  0u!p0uKl P[ϢC"k6z䱉0@x/!\@*/vW<HOV%N|sK;_>* ?1n ɭ%MEE\r+49cuA! 4\Ii# e/]ŭ*^/~rBfGv҃@\ %-nTU8ynuHbS<LC`|\gHͱG"Ͽ:,3,^UM7\L;Y 0~g"R=ZA٦XsK<(`xf98n#1A ʹI%ePmKzK@FK_oN,p_ y0PӢY @*\QP*EIAL*n&rA=TWJ!(, p<bxX@ .S>#8EK7ceJ@&wEp퉻[Z`; ԯY%=\ أTɯ|Eezy"@ Uwr29b:]3)s)!!r!J}tT uxceU,7)*E es(FMA{)-՛,~ߐ$-a*[KIK *g1M8J6<^GzJ (|"@$ ~^ȓ^fo=)i]۟\CB~A&M7¾lW6;0?f葪ld'6{ۛc~=IsyfvH(ѕM0/nK!.Qv YRYW +Gq~h(ut1L뮻98e` ڤ)'䫥L&nG4uydnp p69 Ѳoz[4/ЭM0Cc!.W+;b_?nFOunӣ;~Jk ]A`B| -}}d'HvxS [ SZytC*i ~^sK~CYa (wx <@IDAT.pRn {7Ϳ6, 0 C B+OIΛ_x.4`7c)$`O_J~̥*wr(5O|U;w> d.ᜮs2 /(}>yL[nyI__Jӥ|'YL&xOOGw&<5Wp+UJ+5:t k/\ҘrMKN+T7yM?h?IԞCA͇- L$7SӞuXӰ^TڋRJs<ۢlK6w, I{pgR_?NGRK:V$8uVӀ_,ZIS7)u)lؠ򸆸ҏYouG@/. 5wKMvD5\#Ic|nƵa]ɶ]rmfGc>8\׮^+8LI14N-1s5 # 8G|OtrA` B E*/?8!YRF@/+v]t8/k~y[Yv6+#7LZ%y$v=v[$져&SVn\[K/H>Ac~_]wwYJya.o:::o[h;W@G'iL 2I*)׃C7u )ـ@Y͠"d$OqѤgF/*>g:䖜˥&idGR.v5)hj)Cn@-8WKHҭ5J$lfͮ$.s_he©+>uҵR2У{^=W󁂐&uQ 2$$A$^0F;A) ^q!z?"zy쓗oG~MW+('4{|Ot0'IN37px-"}/Ҩ"}6p@˧i Fgi0fC ?Ci|`$ZK p& ݘ _"2lҿHqN?zK>LR&GI9j- BMWJOTM.AvL[ss_W,iiir/߸_WMVzw=\ݐU,l6hp6%>뮿g"Xt߯Ӥz^H8 (9 =Eq$ɡ2MKMA+#I\YԆUE75C4PJ+boq5ieajbmڴ9Lߟro/-C7Rux;OdL>Gr-^??Ҏl@ +gIGܢG|n%=Ixn9Vcp GmHߔ˒<ըvMGfw0/#X*fĺ<)4[VSS|y{^T]]&f_׿-?`C|u;`rd#'t?ᆿo DؠKZw⬞n8<6Y|ׁpͿby!P.jK' CÝhLT/]){v)( B?_AshΜ9х{qXS~o?@/^`;n׿/K;`${ο|Czyi_~jed";"03= 0 >v6AO`YяIw&~_Aޤ}-NYZ&JzT'gXw޹Ĩw4>F w[w;Q[n餾*å'{_q4 0ު >pT;?% gr%~elVCt=8m LђC؊MpuL G=4˅~o?AӧJ8PAsk%wy`@>;]?cƌٿs=yr_]Z*ީ{DkA ޭL8hIi mz(EXO29KnƀB`,e,ǰ/ 0qnԩ2qL^ =p=ҥүJE8YZ^ %֬Y͝;oA(޽;;]vÙҟHln\weαE!> : A4xYS 5\1--#ߟT3:ʗ~/ R+_~َMaE@opz۫94/J+V7}NҸ]*o:ag؁CE?O[E}<ȖB?W Pj~Lïu >'p/7Oώ}ŴفMy`Z?[;A4(+r)Fc*oxxZ3?iK[h@pU;'Hv^egqz4}zsj Mz(Qh"]ɁIK1Nߗ?7)jS#Ķ&me\F)dgrίhdWF> pG`!prrRȍ~<)YN-_%=Az@*kҟIT566FK.kݼ(s`~Z iGrP`̖FeӴH^Fh~׻J 0 >s>N='_j p@ӡtagEԒHYߜXf@ }M'N gs'3[Y\.iC2rȫjkmY5ѷeU2CS~Cу>=c]t^M)y\'JuҐe;PmoKF84:+\:,u9j<b@}LO ˘Gp[0Z龰ipm%ҍINywM|ܹQMSSԴhaTUWշDӧGgEuӣΎJ}{;:"zڥ>GZn}H壃rګjO1h-Y$n okk~KKJIIwJ{5jwFMt܊`8k>>z+^ CDR=Xڤv.00gzJ&m8iB p)ǫF+ *[ĦHcîLA@/zs `5sŰipuQzU]]4cŊhGF-+W˪Ur2^A~9 )V~j4룮t/wz}ϯuk}y$:UQTm۶-ڳgp 5m8p} AkkROe+m0h@lI-.K"+m-N ;a%`Rnr)DSW<[f)M>e)?];6=h`y]W< C5YrsDrH`|$XgώNܵkY j5ŷmWc{uklg^O>,v'2Qq+7FmrݜޯF,;vD56%F?====3b]ѬUvpH$픢Kz~ۧ5>l@ S^ =WY% =] 0 HO(/Z^~paE&.Z;,}-`Zq)G$wxTAj~ΙgD 9'Z~}4QVawOζMMrlb}8v wT\uښh橫т_BCXyUWW)N#:xP DqlK-/oڴuu K`x_7]exLl-nUg0I_jNuo.IHB )%eytx䚲 LCn^dh{`5#l^']-(y]IAgzjIONr'Sǣ/Ł]Tc~Eѣ>Z-U 駟6g õH}_Rd4!0 %яJ%>әk &xn;M5 $(KP N "~ ~SȏV L^OmSnǜ}RNZ.W7cFxwezsm l9QՀ>7&6%gu;vƃ&qގJu>3xў={uuuZ20"I]w-qh5jj8 H9USH2ZV:4)})|J|D2:)^f/QrO{v4y3%7Yʢy ӮzIُp TWQ"0u׾~~0?^f͚~=iӚ !n΋{ x^Rߖm1,wD_.+unT謩aƌ{N2h$JU>- K2t @kA"{@_R:[79M@y_?r_֨ߖ_*:%pkStde sw& rRps58)nfiͣxg?;Za~56s$j޺HBT3kVۿm +… ΝzI'eO;mMSCCC8V+?Xp_NQod`~DslK[zPP{Yݷwrʚ_yswѕIoEwk}S/.R$#@.0SyN˕NoVI)hO5_^/%HlX2U$(ey͋NzSuQ֣y/yEͺ겣YwVp[G~{-j^JL77O;|%מq755}o꘱_nSx.F]_@DIڡMZZ^w p.'ɨV` H@~z/؛;ǚC􀫄2Rkw>[?H~8~0Si욳gKJY8oyFѼΊUcמǕwMӗ(hڧO-w^v)Qѣj=oGv<+3ghllnm9d[ZNR:Tw50w1ڪ@72쇮(iLi5z>6r=!ٟ=lb:JzGhˁ[[0L9C L9MN=:7Y?f=&:t>=Իp?(ߐ^!QSAvJ OyJO~zԧQSorٿM4c˖@]] N5+ |0z?qGߏz;»sTҿ__wKIc}CU,_-Ū?yL mgEH29>7cK!hf>*D32ټVxx@oV)H;І^K븤/@?4zxϤ%1[9뚰I𬑊U* X7{͚h͋_-ULVèGf&` |xP˗G͋E3Wyf;ߍOIht[^'>K)4v#ϖc^3ǽUc PtCW0 qHS_vN?)k{m43]?t4qsgoVA7Tda)! L,e:ݏWlyl@nLWi Vyz汮)Yk΍_5Ι鏮j%n7G~x`%D=a5:U= QݴiQ_F+/G΁_X…QW(t9=aL_,g,_)PжcDv pYAiہۇ>jL)`Ҭ @nwd 'SIonTwAPM kFs,@R+I9ʅ4|crzHOݮec 󥿔_Kg3O>9ZgFk_h?_GPpuҨ1m@5veI ,f,[UȉKe$_X,sq7oKAjy˟@)R_jؖ, +ͪĭ=WMJBR EPdXpNZOF=7r=IlZ7vȝGVA?. (yDGщ_7E&ɱoRMCqSY3ι0嶣?Ѳre4CU谿40qf'REoꪫM/R('v=f}c>L%DTjnI[%35&9@5*mhpvjRB, Bx?{t)* ziB@ 2'0G#f|4&w޺uѺ?St_Z}wNdviʕHPk4ҧġ>lU76?+w p`EQ -^uuߟ8{IgDx)G靰y @<>'/Cĭr Fn`^i iX/(@ |^y_|}F "ilF'Jwp8ˏK%wVHvJbu--IxFtK_-(&Sw%)QA{k 0j}`C[QQNAow*q nuuriD{nٳ>F/Eb7(fn_7֭;7T+7^`@Տ5CBzJɻ`Er-JR{ؠ]}ut}sjVɡztWc:x Zuj?\v'oˢLoWد6;M`e 35bCQN-y.hl+`*b[-}vۨЯs}1]F8$wd0sC 13R]Qu`Cp t+O!P1GA%J%e.cS"L\za(tKZRztr™& /*9l-^9QxDݍe+2U۾?p9[;0<9j[oDrާvj43kӣlui8GwFKѡ* KDgqz߭:z{{gԘט @@<>LSu}iQ]ˌ }]m)+e]>.ÇsO7CTq7Я:1u`˨y_&G}mmeiϿdd?6Պv3ڹsW}9=د[-$kOj~qS(Ѓ]{]F]>EZpM]N?I;\wrOI$G ݪHڼyJfýO7p÷4 0$|;az]p륜ߛ¤ZlsܢJ%@J+-ܟ96=mgyC]ܩ+KXpKO)um5/*Z~}4cٲxtojwɩwS5}q.}"Ё5qڷnzԜ_x]AS sD-'o$_+,GgNmll>n/~h߾u&;Iߐ/AHݺ|я]ͫ_>A`"I.MŭvU35?\J9"8 bsy @E PBtQV`?Ռ[ML˗_<KWIfK%3/޸Q{>wq<}juɩz;;w>򗿎Z(Ы&vlFvezdW9qPq^zs\uJ8XmᏢ{ŨU̵ϋ4_e Fַ@G~Ӵ zIߑvI6~`DBdpGKI)5:#4\e,&`6R; T*ʻ(=ܼ96 rvRS9?% *KΕJ=7ZD$kO5 *w9=77iOh4-5AO{[T&s<3j^$#߿uq^ϟUC|mȔj?vvE萶H[^.]75u 8tvc}_?u -O~,ԧenytMG4 N! @}`չZ%Kr7,=N.z^˻}  cJ){/eV#wWmۿfv9g93] #7 S8LD57K,}_w8w?fhzJkiiNFrIeIlAPsMM;&6H5W@)<#w(D>uk= vBX|NA@6b6Lݯ&W<9 2ǀ j xRټy"Ύ AF | H[@0t(Hpd,j4<(p`<! kXs@(M b޿ ox&CFsbex& qiM.4-a̽B[@kchLνx?iBX06ID^)֌ OHd ,-_>3>@xx5J0pu7gÆ 3ZLZe-U6SO_jw?A QsKÞ|)R 냚ohv^sp h@v&?3警@ '#(PpJ.o9bQO}[(!)9e`1EFuM5Mk)[$(ʊMtVI%,9YtD@ 3@IGeGdY1J9[ \;8x1RŬɧzZNW}MZm> xNfϒzhTA>Yuukf]W;Kʄ'3X½ ~ ٸfY3pETTttyy9] _O/P@@Q\fz-zMvUᇅ RZ+BԠ)0`(Q  pM1>?Ϲ-\L88](nv8w/} 06Oe.fIK9$`Lr>L; 3KORke<㼢!2RHa:I9 r@|UqO`N ={t:dl۶ݒhGZ?uqׇ,0ܪ{ ]25!Oͭ5-- AO=LST :G< ،x囎6pV|\h"3P(I ܆aR(}i?xo/:p)ԧэy48FT`8jr 3p2.o_K|kAx_OmG{ =~dI7WBSkSbR_Y)&n\8>|Vxh5!`bǂ<>bN8fl6/ onn*0Z@?@B4f0cp|%K'|e4h wxMxⱨQ;'7 f-ɁMs؏R]P`5AgxlRY`'M,䂂Co0aWC?[@8+R|0 F76HHɓbDE"D1<3CBa)rW焙y}:()?ٴi\B=0 d*˕#F"-a=@D3+@gywz }=al~:XO;ZhJ]|R¥_P8,f(8gZ/y}Z0ASvԾO<^00U$a>2\>5L Q&I…2hE$͵OԜCd)dQF;ٿ-~m#Yvcǎl]LXMNNV?h%Oi%_{a'JѶ3B";WW3p(0 Pgx[XDq5"1~VtР)0(p'{\ dk{Q9s Kh}MrRZm qL׀QS.Wފ $m; (-oE_?iShL`7ɦޓ2m ::Jrrr$==uĈII6u0i\;=  YIZm@oASO=ݳ5DQw!KEgP:{b=~ܵ[$H!q %ud ~MIG455***KۇKe׀.%Z?O <4]BCC>Y|4h d~dc=k' 8Ё7xF4=?B}DkF5t Ǩlq([?zM&ӧ;@k$,>^MkAu gQ  |gvj!6VB'&H12~VBKή1_:88Hf8 ŋlo㸍4l]$xQM3l;ti i߈*;28 7oV۹CϠ;RiPR; {T]+M7 SC?t߀3ޙ#!|UW#T*:_k4 "Z+Ɖ@ *DA(|VDHĉ[X N)]iҁ@ iV| ?4.`< r7^~kp*5߸v!?,u0訴[ h Y M/̄49!#c eǰQ }{8 <3;w<=yz ~ Fx##dc\\[(_t+ AzhK2YŘ=^*Ͱ(@}y   1c4܋ۀ`csA,Pa5ku.tΞwHK?jvC+P ˃CNT]]<Ԡ)Я)^~}C/PD,M8A`qi14fΟگJ8!@(`q5nPIĀ ,sse 7Hƌȁwߕ:X.܆0pA`k=bFuldd"C?mw7Q/ݽ@;(@xt+0wA9c,$= WGΗ[y43τ}54ʅ~qI}ځ. n553~0+iPИI:U?KPhiIAS{hE} p# `29 @*F@K]ԕʰ{K)S^^nٳGLJP-Sr; OyiK ,^[ _OtHE2~x:tS@݃ҵK.huqub*F-PiZ.ҒƭU8Z { 4M4rqG5o*Q=u7t @seji ,y8ɿt^&ؐ!AS70K}> ;uZ8)I](&!vBe׫Ɂ+$X/ى8=|IAft v5 ~w\TK7o)VExmW\?ȋ4RKpQ0 (k4⛭_q=7V4G-e]@RzxVbw X6ޏ{sИz1V]7#YEsdԝw5=MP1fI^7P;ϾVJưB _('`F 0;vJ`NJyܬU0/@̊%Hvor|f&xLFl"-JJJd]K م[?:t;VrQN=&}b-tyvH{@^ GoN(@p,Tr_u &3u@ @ OW/kw2 뮕X5ۛ;Ztf0U[c.jʓ0p ˡ}$,u;v[&I(Iڴ ȗzX0sҢe1HA?a%Myylܸɴv\X C >%W& [ny 30@G4(m)0n7 w{)p&Lz_}T`B0wޠ쐑tZ5Jm P359@A`w-%-n̚]񀣀b9n#i>5-UߕUԹ@IDATK_U]-eph>].נ'L;RLH@:"@] iAʞZ 8 2ح?$>J Ll g$#XjUCqqt\D&;T]n k֬G :ւ@C[H)MءRNwEh [ @(AS@S`^\B&~~aS} ɿU)dI?V.4h x&i8Q&UwJ 4f** L oF@nm`m++ ̫K.!HLa7$2Ś+; P1޽[D]pQMB`7qn~K dD{3:УtsqKkqv b!4{ 0 |t>drud8*` ^OP ?]P(a )2[${\CAּ!]逦U}~uL*0 WjkkرR AAyyIEKxꔄ$ +ހC`E]\&<=rO! J,ϰT\:XlذAt>;ӀˁkK]SK,NB(j=PpNa )V+t +)g20M~O-P@QX2_j~;=q Zcj| G?"k-%-2'[lЈCL壏7񯁦A1d@PLq=2q`̺2w,ޝ}{(z"fIdoI5,d M"衻N8 \52~O?Ud9׬ܶO$ Е~ T oHx{akASR@ =< PMm,$,ϵ@['?OX=սqB8m%N{쐅 92$ OSgwCl0Al+KhKK:~,߁jHX8N` iFzkrx;~\t FZLw cΝ0? ɐv05w[g/͆Фk0[θXh-K`%@ NRI -PM Ǩo"(@m53fL@ wi O6{}@". 嶤NM*F2MHCk՝Uh tP vhrGEl`h1 ʘ%Q1]/ĠIPr.+W9Q8 (2'_ǎC>݋F_G kb+3[J6Mg(\|H˒ 1^ -0 D00(9/{0uĤO9z|qccBS.:`.~n+ 1$㍋5+Sd7HVx7Z<3d$!` P, pP_UU|]4 HAt?o-&&hASS،8d$Gq^=\+[-vU@ x4h h cq폁C33"bcO-aÄ'?Ujuإ}5:RhQ2dߕhNoiliOHT4[" (YM( }0*"9^*nABwĀpQwzsë,B`ۺa=944ktN`ϻ Q1?W<ޅO kډ&*_<4K ?Rui|=[࢒s|ɝ?~(fhѰQ pcyJK#gzk=ץfASƥ,+ߗӧ eP?{SCC$2/WR^$ּ<o PD-gMQ$`ʽ`"p֭[[f+@pDICXtœ>`6M?d >sc*ڬa(PD--xUf2k/^ 6B}sA>tU}&XAR̙So5 ~N 5*$_=>m]0^{Wi$qC6}*N -n3警@(19-p~&"<[R3+3ߌrͫd{pW֕GS^3 2?9K;N<@  9rd25P !=AP( bT{VXR13@Xz*$AOᕵ@Λ"_*Y7\+4s?vC fە tEؽ[*`mh͎ 5"VVV+貆n.}'6//-7ca@m)ͽ1 ZC MkԲD ,3Ս_IIIW^l9&D2ݳ* 8~);rL4=,Հ߁رc3"㑮 4€DL0JJw\i˄a(?x;íQ#ewɈ[nxQZ0cVCC k0al hbe833+ȏL(ѷ$YYcFK"|cǏHs$~di>wvgPYю M_8gav|4ҪRa5r*1%PRrLJK|{'z /QSSw'}Hk3O3A  fn9sv^W}KG@j{Y>mEeS(}jғ>sx Hl+FM~CO} j d 4Ȉ8yB| |#""XqA ym4YSe<?љ?vt]}P@DIy2舘60^kSWFZ\#9wa+%aoBLS[!enpBZmmOD.Z@gefOȵG!0=\p3%EoAbflF|(J)+;ٺm+V.u[tevYhu4:3NaiPR\\|n}vY@CWB:|~ˎ42 Ϻngg4aW@`Ss;MS2H--\!qjn0,c;.c!XS\O\1)NEi{9C鞑Eq}HpXiž OOꏟ#`K׭Wic߂S}.0W! `#ߡҊ@{AM3{P23SCKvQD@ }`lL1"(M<ܒ0c%M*[:2(9E`ZmfQ9 vc ֍2%}4ojOzE]Sg ܿd*9;BmR;jPj9WbkG`U:>#ќx&oA@κl\) d5s&Js 9hB @~#@?kÏ.Z(Zp .(r*-`Jԩ̥0~{={[0qq bo6EGDnd3c0;|76VS )tt#w;E.ʊ $'Ś19ƾ@ 1ZK"= z0GaǕ A./hh;y,f͖Qw)#nY,jGHۣJWݫLOm$A2u*^4[]ߊ  ɻcW@y| xNY:;Gp͡%e8(ƾRA |4OS >ނ@ ҝ|啿nO~~v=C R@+J=pWȒc.q1ql( ڳgye@@@S@ &4ixWf̚J?mW`rh˒!Fl/?p98Hf }BL^^}Ly I1Bc>d;4uf`t,缒:qd"> )jU@2dpf``Ȭٳ%iimish5 ^d4hkAB\GrssoS/_4ZbE3/>b2Y-q"kWl04]]6JнO9r1gGbwX9"@SK):6&͟U;7 {]Ṃ E_^Qys2Ѻ1t1Xufɇ6v}L|})}^䄣?Fۀ@=%Ζ##nIT*4_,=~3Bk8~ɱ+/ңZ̥f1DG- @VA<7W@b ;%IT e9^lA@@̝?^ kj* n#F Z ][R9ad!Pee~_uRZEU+[?ȷSo.Ne! qְWZ쮔>ׯ(px ^ :c]zzobb$4A-yH zB}4L-3 uȀG ;z(kjJ!Kw`̾s@.2tO2.;kgE@jW4tp7@s/H헅`! Gp,`i/||uiT#R],"6" >AiIW[7$#=-a14϶(,.]?Æ oZRӐ!\r@fW@P4))?M6J#j_z&&u-MipXǬ_faO@W G;Tx3_L*rĵ !RӓC?iCUU!RvKխB_ ;e ShE.821n\|Œmܹs vLhH u&347gq@o}Jx6ˀ$(#8ɘ5 P?j]j {T. '=c %A8޽[vlokQc>|G]7Km lP(asGGk -BS?H8 "Abo~3)G zpU-w?ׯr)|w/[u'0gNF. 7[[z.{eZ0!hDȭ&Vs+_ $ ~c;e:ͱzu%˶|5警@ P@ )> EGka7Q ?24i|*ʜ9slÆp:̿1bc|`' /Z$M"d|/?'Fڏ['^}M f"É1&Ak"nwX9]{ )'_%A`8 6'@2>yJ_̄ˆ9d)đ#I.Bџ) nik$[fUVVC'm ֮][Y\\4OͰrt6t@Pa" _"S!^+w|Bbc suuMо("pQ8 j;@w (@ 7j ߿c7~FW_~驧$-sIR 'cC{ۀ|GzpC`}BdZ ff _CR25e6^F;P kۥBY'X0!0Y0lQo\+ %;q_ANʁeϞRgՌ,'hV#& €˄PhlL 12HGLcI2\ܥV!+b0 sNI 'O(**F38cF_w+Ga@h9+ȳ˯:<V1= 32~Y%95!tW[+**I c__)~%n<@({ _rsE#9Q܍@n{ï ?i8?5'75N2\B^a`.>cLdĭ vj-(2÷4K3 ޷kwu Vܭta@'P_)-(oꝻ$}+;wwt}) 86adٲw.;=sy( c@P\\4',vM7~oQaSmx v[F)eeeL! Jw3sߝ|ne7765޵_iw_8Р)m to{~MSc `ȑc'MdHϔ028{墍v`gXPP ]wr-V"sO$yrVu \`R8t#05H0^nq^HWLF<(Ȋ";jLw!h c 1j:9G]VmPkꓲR74.F}mc䘜޸Xc@wP{髯V/+ < [y% .Z{ɓ'GBG"@SSXWZ[ţUwߺ>) hwk l { \uYdX;|ϸŜ> 9#[o~M7m|V4{5@ c81{0. 'JbXGwNn2d 1A{]?㓛?Ɠ'ajv||xI{LK BƂilv|fzGY ?nuuNMȾTXL1 5\kkkA#駟Sa| ֠)S hOɭ P`aIÆ Γ`n1F=3\M(> 5iv1󽆈d|cɝ7O"[s iw-=f60W+>L2[% djI[k}1%"5U1Xd _^?Q K]m 6[JA anROfd`hD?zэ˕ι7c>@ `|?S$,3Sce RQjnnիWI^5ot!fb+=`,z駟~5h 8P\P{롐q3CϺu0c%X1%@T/HH >ԺЏA.laB "SJLq5Y1E]TzAj \?6 #=L<~zkܛ?@\s4<ԁ ǵ}Ϻ@l< `XR8$M'K n%BwBI]0_B  )3&Mp_I;-n;#_=.\`Z#[ծ`^Xz}h{OХ. 7oA|q\sqqQʬYS?Nܹs`0'jժu.+'MЁNرn:2 Ża omll2$H@ >Ժͼ;oߚdJO8j`y5񸁌|3Vk hB)0&2^޷_΅3m WJzb%i:D!B૸,@ dlڃ4 w(G_gm4Õl|h"b@}.tC` 8X1r^ dr!`3M!3mePB Hx}}u͚<՗K;ٳfYWBf~t7,. ~9pLQQ9sD euƌi ׯ7꒮oXĺsFdDv&g ?v<ޝQhClLGn5퐃m)1 4h NOZ֍h 4csf(_nsD0~-h|?#}W~>`D:>K If{=gb \"N_injZ5>Xוȶ_ҐԜzDA[JK6v ‚ ̴`uEkCYY[AL/ `,( JSI`IgނkA*hJ DrlMW@-x4+kvhN<7ȁA N>eb'JMMMM͍0A#V [[s߮YƘs{Յ_\^\\4<ǙE GQ\v6HwZ*':lY4wp1 @#J`;S}fff5w #S5 ۜ\4Dՠ)= 5нהYSok5̟F]}U9YL#qqyP$ZÇo$U#DjW?8oA*!ߗ P W{'o ௾*AZBfה?*;wl_K?`o^/)E h /WW0x=i mwܜ*I)a[]l?kw49(O¤L>|EO{uz 䠙ǁN:_D_)ҧM)O<  {$k3L8נ]ۻ Ի zSRU-'$x6I`X0m nNG $111* h R{@Pz ` C\[8wxH;XIWY!V.YʭB%s1p 0[e9,0&V--=}{TDFF <{SXox⡰rYk9_rkBaLk>X(I ~h}0%v^}p蔡Гή"Xfdd[׭]SvPZZKjAIhݎͷޔao3+tF9w,r^l?GmY 0" r{"k ʰnZ1sѯg RS#)!=ۅqmZ4 ]`KSl3UbiE)M;c Ě+Fьp*PcP}>P[(}lQUqF43å& ): }ѷshYc***jChh^Fi0pn8No$""hg|Q3YBhr`4Xa 1ywQG9cvvM4U!fB/ta@YMoQ@ EY]o PW)`ıqSNFAŌB[w8t <4A+dƍ{Bڱ. pU ,p,k:2qwA B# SnhĴT!PLsS?]Gڿ0m}42Z5`ZO|4Hf  h`@+%&VW B]+9 '"f h@!G(;vH0謊!S@H1 k1&08ǂF-]J${ni>Yr6 D>Rk֬>kW-[x1|g =v,߄njG ,,'NJJJ1ʵ KAS+ڢ+Օj L7޸oTKLH2'㝷{ 1f*aH7$mTI@*:0k54,YB`ʩ,+? HVi޺U Jvͳv>Q`sPo:].`x_ʝ-J9qi,0`p;vX 1}( (̈́D ǜ1jH]JC(ʱ/q 0NccF\a9~nG < K-e= zYvbQ=y%?5$>-a۶m" Qo7kk%33=M:0s՗FY$ 4P߀ƹ'N41lРB7|mOγ,1 LE׿uK/Iֶ]KHE,mv}r5b62@IDATVkCÅQ=ߥAǼжlTJ#H՘n ӊ2->@DkvPY^S(KǠh``oB"b">,{ L>?x'%U AO=d@e,؂-$\jsNAv>H}{O|xxػ= pux2$ZriGӗc +++r„ qwo)-&sEyȑQéHxZIj?CGtI`>cˏcv7~/X@z5id}0eo"fzI͕th jg(k?lˑxuu W@ p7JK8"2 ]Y P VJxf(-s c@Ch{rwL,:Bh 8w)dzmnE(f@ C@B ,@'-,,nС߽ekq-k֒Qc- Sfߺzv |kՈm`qN'!HzS>I-RP* 4UTc)$* (p!z]`ܕiw`08fƔJN QFo=JJr״!l2iL~Q)Dp,t[om } 2U;wgc Kݺ-2va;RabÒ0M tN"E&*<- UAV dM0חrh0ha HZX"2zwȁ`ITY h0fV+|ΑjJTFr G|l)..f7[72'?nokn~k2?ͯA9ʤ`#2XA||NkWz1 `uAS`Pw4wIS&FU f1I;{cq؏ǢgܹcU\PuuTwck0EQ U|8 eԷ+,lƕ5;&|c=k׮9M`͚s̩UT tQ5M5]`P@;S{`Lǩ31㖜 J26|aVS/"/j d /(e! Ms8}w[/>Ȕ)SB_|Q^}_oN iz'O3'OJ`e bjhȸN0N'Nݛ( ynWc5qz9g VE)A-d`,1 "2#Ͼ*Eob ǂJ HHiUT}~wy_mCݾC G6:g7?x } |hF E3ܩ"ǂ lSeqz^.b] "oeo0{dze~ FĜ9E%ƅx5-g\s>aB{(Cx;52ZM)tqZ>Q@ D>}qP̙@^uqxpE ɲeZ}b{Еt (3<*`4k8zfA|Z*guhEpZL;Oi**N1dj`*> 3yɴR@@ASf?U}c o/l >@"Cn8 TY!-|K>#+.YK<\ɓS_ۡœxX0N"&7GSV.A7IjJ`eLG֮]k>z$0cQkeDj1̜9 p!cxpUH9֠ˁ۶mk6lXԘ1c "i|{޹:2zxKwQ]kJZiWb7 WzM@- $BKx)Zb`۸WIޥk[+˖VG3;sgΙ;wN?1Q!׬(0CNxBH$ MKnZ'3A ,{YY段o\Γ6L]޷m/RgOHQ >>Ok4G{)2%{dE/zs\gi:yX^4e鑡 hDkc^%t!{uq!I +vD> `^_~y~Qﺢ#R[R 1QBxs9. Pm߱S**7bѐ#[^3xޑx ߷/l (0Z>[ %Xk`2CYޕH~枙COSNM8 `Uaݺ孁g)]I@ΰ PDYfΜ0f%yOf.[ƉL23#PhkEKpZd  PX3.䑣FWBY}S2׽-y\gၰ ͛)OX Q HP0p~)y7%tC?!qUG\?]j܆"yKaVmAݻ$5f@`PWVucUJ6n`CZ(m9Dz,"~ Jrp"܊ "O۩rkN?4d ޷X(pƫ_ M58Ƴں5_mW<"@I!s*ύ㔞++AxTʹH爩?;u8T I;#!spE%g@5/d>Qh}5 f#łjI`0*֬Ypu1i 3RJVUWPQ±m1#q?b^Zvm X 9n1 t֛/.&|̇xa-`Xx,_[3ng"@ TP%hic;< [ʈ| ]d;vԦ/P4hIm[#q1!+@iE|mBK*YmSЩ*?OFnn-/*(#kXsΥ $5`LR@Uoˀ:h'Nҫ'@ bڹJn>3Cio,dXlxU)X@-YIK`LQ`X~DˠYÓFnJ)ch_B+KE.ZBk('IE1V߉0$ t!?@,R(Ǫ Oo ~TPRR (.u%0e98= k`?3} })'nH x9`-W㿓lhIQ )s" q9Ę-7@FZ3\Cq Z$YR @@"/zɓ.G G?тVY;EŸ`*ꫣ^b3R}q9#VS.Y9WC;[:fQd'?)@!U`iƏֻg?iY4>ގ%[$0 k0\gv[@\V:(E.[n!/ɰ$;1Z,Pn/zRukΧ* .ׁ&c9:g5hI}ZNE bRh%2_I k!27W. U"̷Pw v#VI8BXi^ :YRoGa}ԥa4**cĻ^e B8KR*ex4$# ky3gS ưsW[h 0d > /8aqüy`HM78Qz mooC%@UM D9m=&`4.H^  E)`oyբ@@Sbj"}ss4(`^^%iբ+뾥KpBh% bc< Z>?*t_O> ف""ŏ*(2?aS@a=;BB> hYw`2Bl8FqukH}خHz3?ޛ ,7cUPȓvťJlqJ)Kú.Ucq|0e*/{;P(K/psS ,#Dl ϡXZ#k_) WL)((CkԨQv*ʨh2lg.'8(ZUY]Um204A&km(eJ?lfu˳GFZbZvm=;JFWr$@둸o2I?v>KskM(뵬?;h@ V*VrX6 ̗CkJ\^۳}3Z !Ѕ5I# qm*)ZRJow@*(U` |(X 9Rn`K+(.j(ۺM"*.Q{gL+1T!qc$y$t /JF@ЪU !d5g )Æ.d"ysu*56!?@$+=,(P%PYRgMf]gx@@ʰx$1{ >i,JkA6{C@w0,3#]=,]kXҒ+dzN9CYوҀϔ9u=!P6}$)b\_iMH9a:6#?,<:ռU CEKXoLJO}}{ My b@#=<5Yјohb)5URcб-(4[?h$97ߨ-IwU9BJYdY-eƻ;#H8qPҐ<`i{t5+F,<#GO4)\\v\:D X5Is#=Gg] ("a m]}^ ~T,"\RV^ ϖKy9> 4 Sg߭YwtQ௸&Q:tH߸ճ{q깓u666s;c{Úp]wAWS{#ֲE 0bOdD20y}oQvDg̕sǵ;pm&S;K_@YSQjyr5h|cw;^ShrI[2Mu˸ͱ[_Qԅ݆LTPf@ US P'H!|{HN>K(}ES[TyJ6m%!K鏾u:1:(u P$cIg %تU00?+$,2»j+{+VHLNHHѣ{7&4wx檫(٧4|p"9oΏ@pt 0 atlptt~%T;<GuGp|Vr iƌ h)/=Qu?Y05K˂0v]'#LUNQHW}KŃZHVz[ ZnimmxIðD7AP9⁐!\ZL*!L3~BVA(H&`MOBpclk᫇;a[:=er@]'ux\ M`t0؅i exC2&4&J%z2$O*aPŀSvF̿7I8M[Zim˗i% qoC}oDR8|@ O3a}Oѩ'8+Q8^l7PF`l[*ȶkʔiΝp ,b20iӦM5D*(3D'=~Ƀ={3%TBRBYPA~X`Q5 ھX, tOdy-})}zLJ3ErrH=Sak>&IIA!Ľ1?ׅ|'R  Yʘ8Az͘Vq xHtߍK}VgvQO<.]̀Pru=!t]߷3هgTi3# *DDJ򸱒2a<zKXxV*㍷pG>ڡP/lPB@TqtV`> Fh>'`./rE'>*A LFH/0?O/aga/T'HLXG*|^ '/ ]x@~ue#C*qF^ gsmܴN֬]0 cjQ PgE@oѹ^fw2s NM&%(8A%v3~sX7ָnc'U/,6Zf DGd>" :7Wz~[$.TyA! ?I;BȻR{ +kGϳ]m B4-1*ɂ==;?qɆ\5G`1dX@9. Ysf(_ CHܠsLPSggJzY*\ /܅M]u ѳS5ϱo( C = XÕ- 42Jv~zW+oN"2ܧ,8 P` $yݛS @g-s@IK10~!4.TP$[=+KM)^N'VoO/ w% =C]/Gqt`<jP3Ba9*Xu׬YPmWCo\w??ǝYV3&-~@̆sߌ xcHիƎmc(ɣSO^BZS[#~Yяt,8~PQ-SRLk)@W0{p͌nj'ApoP-djOE変ʅL1E; tgkmZ`P,>auMYe P{aϖc؉_K;mug~ l ʨ;o!Ax#]b /)$ $z p ]c>̏SR.qb_._mI7m޼mGYYyQxuhw0h…]w]$ck&eMMlh4r5+ۛ|9N< wIeUD9׭]_aXhzxV- xTaQ (43Sbbb.CWL{IR<Q `8(P4?S06Zywk?&Sy쇵gMG'@!"+HW';d(\o=ki{V43|w=gm:0D"9Qڜy%B &@1˶oײ',Ʊӕwc9%c-~S{k+վHJ7oD.EknڹSs@xK{ _+ ,Y'J\K1 3k(p"/V޽=hժUb'@z с׬!z4 @ѣCj11q_#R3\I25Rgnf{n3׍+;Ƽo޴PKi"8X`Qx 9'oG)0O\c?ѽ{[pDxt66>c5OF@c.3g,@QNK7tu S2 @fooɠ-ѹ9jkCŅ 0]r_X݋F߽k(<}F'hUA}QBcՂ F_P(a~cL` $2c˾@WXIGK<UfцtGZ0?o0xPBxQ1?j. ųv#T q-c,a~"G=`Ic.= k2*z]~7bێuZ)4R- іy<b0>+KbYjc 9&?jm W9.vm9'$PPZ Hw}WGt']OEGia^EW7&+/w\sBɒZQH߆c&P~e9:BC$11I}ْ+W"pP%]^ &yx/me.󈤣X lݴ&r\nxu1{6j̛l{~*uC7[N*( 2w9(g wV]`B5Rs,Jx?s$לgГiSۢ6Tt2TPV٣^PR ?Lr/3rVsB\Gu0XxϽE~|8P@qQ#l>UMd)R'ˍ 6%< Lx駟zw8YήsGڰaCݕW^"Z%)¼ۚ gO(&k=W "$dPhʰ& ,۾C^4@~Xu2%5A@(:k2 P4{ɱߧ*cYX# w#y`7tbq+(-($88O<y͝;z޼ᄏiy%V)S&#AҀp/^j!Ye۳ w|0{ѫg/;yG-nVy\|%鑏>Ŕ8wMeVnտ_yL5]ژ"gJ; Zd {vktЁ1fH<sB&+"3zΰ2wʑ!ʲ|7*G8?KExwJ7Vߡ;T! ]?@DpN`|$Nqd])A!xlgRx4f ϕӴѣ$k*Jg`nxOO4ηF˟?xO?&״9s6@mڴ0!!A,-##Kd7^53Z`hZ~W8QVW_ c’Fz_f&Ok,ECl03+3r钥H Fo֮6Z9JKp֚)Gt¦A#nH ̢RL?:IrDv8POvro# {w13Q6zR[L c ⊐~}e(Jj OH8CQ5be22'LvƴAZt{Pw L?VX˶n2B0FU >Aq O _=$Pz|844,ׯC*G֬p s {>_>ԍ#ftw^mA6B*1(xt ,(+ЪĘӖA8S4c5.0?>͜9s*L);N *12g}n{E=yUv(J{#x̘1<)[^psGm`&6]v&pƬP4tY9̶Ң@PZf{٢" /bTpo1g?7jS3J07/V|;٘J}Hˀf[ci[&rweK/۩al1ޚLC|Nz q {uδ0]h;;+K?yN%Dn$iO{h7vN w~ӟqQ[QKxk@b{破_lh?ֿC6_r@{!Ѱ_/ LKE 0} QЄvGrmvh~ /#XS bfhK=V^H>LFJ? 5KnA8y}e`#1Y4,)4(`N8})Kտ?( J@V-8NI;\?N+kTnK/n_XۘGU/Ds+)@h2T5ӂ[@2; {0k߾}uyyy.\ > 'Tp%V)6y[ag䁩x ڽСCqotm X }q⤗g~x Ļw{%azVflV+1~?  'Dnn<B|z<tqlvM>p8>29ӦɰS$,&x|&g ^dGqQ99(}xdN*2l/&cxϪCI/;<{VeQ0=R1*8KR@5C8b{& F.1 t**R Oo-VP ^o0eg׳b՗WhV عS9"gh㠭a<#ŁOȾٟH0TD%!e[BXi)ںMKJ% ,`繃c! ʿI+ʪCKD^T !ekO=#):Z^縏xt:/m}sKkOҮ+VKo(ȧ~W)c0S@=cfIXÓ HCMf{k5)`)sȻ |$jh`o`*R <?ި&6 3uMҴSёa6Ojdh&F1ZO qrOΐ\7ayY'0_6˗gn|^g.,Dk[LI'JS9a)Nȧx$Ҋ|@֭$iDǃ91ƀKIY4b\I$ymU\JenB>V 'OԔVF| eO4 Ϣ"N/.--c8æfw5dؼZ0T )xذa jZM+>9W]W:|.oXr27,lPܰ~O8ѧ 73ˋ/O1ݡ$8F^՝@3((HR?my$DGjNyNn|B? 46!u"Du@9h՛}ѽ555gq<[ ǀ|v,O ./S2ƌcn~>OJAY׽w)?B jIpP`u oq 1i1bC?p 5H +~QO.ZT`k@>8!d1RV )IF~)SBt9|H@ Bwa(zSRā%{TUV8ESQ% l0 @r{J(L۶ -647hiLUˡ"fj4ih0k#cG-C$/p `)(ymPsF Ny( u birw6[YLPJ y EDsC* .H^<mLKp?nzOIMu 7'?ɵ;\'3NH-7VT!@ tr=t:oF%KL3 i߯yZшY<;A9$@`+fj%!ANld}K矗/$Q(XUV!˗Fm cUЇwe#Nb G2*C(zYP_UxHr w (anXM"ҶJ^^cxYl".V<~|ޝM\/R%p8`Ԕd*lS8;vȊd歂iA_*l7IqȕA94RG"ޭcQ۶Y0090@pK6d>VVm,A S @Wx\PńZ`Tf0v;%7/7Ͽj҇};b| ~/R hygqQkہYtO=f예\;?촘  h[}.ߞ| ܉Sć6Mw)unt rAP+ٸx#}  dYگ Kj%319u;d;dKȖAd~qe/@<Lv_uy찡CCsQ5?Zn/8%5ٍx~ͤ}1\qs F?GOCWCN?qAxγrpO2? L{CLm֤ZƎ[Z vJ-mm9aJ=Z 8j"sf}˖A$*ۏLv*@! uo}+s JC%lAP4’q `@;Ke5b/P/Ubn9vfO1Bbb1FX\~D ރ*p wSFU'{>TAS6̘>MA0t0&naG i 0?}zK)S p0Ѫ?p>LXGfG"3Gx]]iPxMկ~u7MQ|ji+1xg #SGvɅ^2ejk"2X @~:zz|g|ݍ3ƎHIF͈3@>3m(XVj/$AA(Ɍ/Q~ Cnܺ1<K~B y{R`%^sj>ut{6OMϽ;xzLpҊO"ssta_~%'h̸u֩29j8rDvfk>ɾ I:\;w͹@ n g&[ +Uyх!}֏rFxXBRiw(c (h8(y0T2ykߦ9dzϼV2'M?P*P_}ԃ`ôTn9rD6獖ڴq)<u#y#X4$TV@8{ lڵf5p* 1t`LRpuceCAf ڞ rSb BR2`h4#EM7YբN 5@ *@;gu/W+bb{xs FсR@b%.6N\pi6P$z"|(oO7b`-A>E9D`0v,eBm9!_Dgv:$Rg?|8vA|~8(h9OF?\/ԬYʤ\ˮO?1ܢq1yyJرnY%y$Pbq0{…M6u/} =P<VYugkl^j5˫{ˤTD[8ABP6T)DA_qL#<4c@28b9z.Ɓ'scQW#&1t6ϒ^Q5A7@-Ӂ09Vݷz멤\TPT=+]|1;qʰ/z% pJ^+ؗ.p ='ϵm6UTYOFOl |THoU_%OD}霺5+L`<9*N kR)@Y]8@v2laO <\L:^S4ՍӔ4N'11IbP*<yjeg{޹7:699UڝL[|しw-0 xaVw|N_)<s=yzCHpBK Xb?xJd53Z =st;!_]7#YT(=o5C1'̨s3D}»hѢ?+lur$N` *V:aeav݆ (`߰ʭ]sml٩8ɜ8V'='WNѥ$ 7 Y"1R~/L,K\ȧR E0dh–/Cύ QPE*03z<ڡW?tA-[! Up0!c=iON^$$`Βڒ#*"4WM PsEt޿Os7kZשx?z{XcV`9 _͌+/W!Ӑҹ1wók<:y/0קO߫əf\^W[z'~k!QxMqp>}(+@yZejmz.OaLϐ$f8zzW.\G@p_OS '^] {Μ%'B `Ԇ ƍt0MTx [ }JTv$aɧ'.y~47~c]ּ^wsBA/9)Y3G@A UA*Hu>}{E)܋b7 &? G,@<?w60ӳg3ǍbG84YZZG3 9K' N <8?M'1Zx剹YI'&L _^QBq,&ŋ4׀uC\ d |K$`? >+䊁sPX:?HnP^eO&= B34).E]H6Yo%{R cy*0=_|!!s@FKB H.oz_Q]"NjaLV!tϹʱy'*Pb ՂI@We l:Yx:Ŧ4<~<ۑp# !,h@fO'Z- ;٫<0:NЕi_^eqXrcQ 5())CdԄN5L?l>5&xUK%3V?Fn8u:%[7 ,m#h6lsʃ4/qSw%-5Hiy)(mG ~ zjѨTȄDϗ \4= 51!W2%>tR!$qt/^s87w/mフK9(zD2LdJ(@&/^a ~1oG!Ź|1b27$COrNU.zc'$7HݤM$B-& Lwn;?D" WRAA,- PUydʠCCD[*4?n Ǚ._ +WvO@SPr$+{mI0݁/  㒮 [`RCc6 qwy;~C6 p1$ v7lcA(:^T"tE]xCO0Y+$a#vSa?n/[}Aqarʣm9Xp)rsOq-< { BA*+#, ds9@ߘ 8 {Ƙߌ1,۸q\7=wa-=lm f7l* P!ywGєQGDwi˱{eɃ/v?^ۺ)0 1_p=wp .;26B^s8|:'=H`nsz6lfǴwCۘҸ'?v`,OKUTiB+p*_Sud\IU^2)1C! Ipַ$ bY<;_{]PcsیvŒstG<fuU6O/{( Ӈ:ֆdAA)rGOU\tV`nc`0ttag3= B-~ח7TBC:g D8 ONDt%=L` OeASʈJxW^BjBCz[d’ŕQx*4j hIJuV9] `e $;\`v{f57{Yf/vfd"1cOHퟭ6ƾ ԍ=.X]6ܖ-}~:-G-UmS׹t6N[3B AR@T }{;jes2 ;X2.;wgbY˗d_hR??'SapOK%KкZD`BuEU$نY>˱)q&ޠpXn"E_} >˗k8({RP"n9ݞ{6{Ȳ|.Ta(o AƢO&'!"AH2> ղnM˖k V %G*P09F耿 ܎~e̝'m6_cCZ#Wsޮ>[dk}m+hENy衇2ې|+2Eį[s-Aj B1 &IE&7K={H$^:hKbLWzvs;wH-̔oᆭ7xtܹEF u6?u| xp/;K&~.If9 d|f]Iiݤ5n /VjoAKw…r,Wu`{NcWFĉZ2GZ ZT\k3X> af9R xX0S@>}$Hq=OUz4av`(C9ŗRAX4<LzrbB&Zd .@ 3V*|cϐ!fJQR7` B*iR /.&/s']@2JV6@[(Bn pu@ Np;<455O؂1J&$ގS\ynW3tlO`17We y7wmcY%t'nܭòs(7ɛoSd7/6+?eQ8;֕J72]o(7֭`ஜ.FƱb<Kd#3졶e~B1a1C@~,ɯF)# ٌ1_3{rDXÜt+]uۚݳi֬Y9 cy[g@_EJ$G,$%P^fw:ЈH-GKJWfwqn@LIޗˑt'R {xrŲFB0M L3A8FE+ÆJjnļc xz4_* ί"?N~Q$=ay%d E".M+7a|F3 oF vKZ.}ZP$WhͱTv!401m\{> 6C JҢm (s+l(գs`8x*dѐϘω#" IP7NTgt:Vre>-K?UdS͟Nj'0n ֺ)˺B=6O5x {ue-67fhV +t{0'|,/X/d ccb-0NOO*`i9x=odC.P3ƄfLvxzcb@ ZqLfpe ɂBԙ^q=4ܜĐUBj$x6n6deswd)ve W%\n/LՙHVk&+CLLȄȖ풋{!DH=mqj\R9'Jk/aÆXhӃp߼.@ g* ``sG/ZYǒy߹<{BJuBn6 ]uw~玈rd?;wfūyt^D!OLX _ן${u' 䋍`` ؠ0a`b ҀL׀'ufKܓ VU]% #7)SN<`N@Vx-Tm /a'o7;g&㪫ŗHa`Q.Z l^L:GY7RgKWZUGF>_/,=aheFetՒk_x$&JEvs tQȼ `(ZL ! n"ZSOJaʞ^$a(LqT8zg?6UʜΖ(kYcA~` sLg\Nϖ2/X0j[pQc.ʼŋEk4I[8-AҵmfxfO-s' ؾc|tN)̥S3ݲrJ)2jʓGE2!2zy-|T,]Dvcd?֯9P{>p?ao)]{53///kk+~JKnV\/N!ߖ7|l2nXL2N0&pY '2/grvOZA(3`r@G3fPGCl >lm ctM']E8p\U2 w $grpҡvbU=ɱDJGn VUbgՕ>kF D;7$]t"0]lf||ˡ#ӺBk)Fb;VHHDs$hn(=|VLxTPsf 1#5)RܳW-ٌ! y].7@EA)ߖyFiJ1)TAWc<9 ej3%Q3Twtߢ+ FX- &ݩ.vz3(([Sȣ=*^S&8eTN]:=}?(Jgz F)X 3f 804))wxxIKK7Au7yrp'lPGͷHG"B;G)xO~=sD0JѸ!!,-XạqgW<11QB>1!Q{zC՗_2 ko yp,krpR 0d9ΥKVT ic2 |L|,8)pVe|ӑmVUA >w#cIW}c^)&׿q +|2tp6@~qr W>T N9Jٻk$SJ8u4 J.@r6+@NğYs>y'ۆ?ˍa`,0 p+[r&q9%Y~&t=:`X#~a\B C_'^D0Q9y2g3{Ѱ*0VȧʔX{Jp2B@-PDS(|ʠ`_">"4&0V{a]yUt2a.q.!jQBP0}c-8(gB' PdKnVF*lɻQ @X yaSZ`&K$mơ!i1&LHKO4igdg` Qٽ~׬Y-d{vBnӦˀ~$ 7Pˊzf%|H` QA޽uP*UWU3I3ۊ*a77t=6^7 ߿O| ;;rGxI-}"liOa0+zM#G )/3%1q< 30WWVqb wj9fFWhfuBq:ArnlO>de?R:е&9LP L&{s:]R|s~WmPx#I J/JkHEA(t$$ GWSb`4ڎƙ|.I6]vϛL}?hq%]/Cx@_~|R1@l`x* p'PQuC9… %+zgX!jFhXe"1XVks?LJ)5EP[=s0ʼnP-~Zz% w4j Ca ] b@Sם קշtf9r*Ղ!$2'Ƃ5x7CD2 ϲ`W@gMMP~<a\ޒ*UHE  0780Čp(:f'*>o$,~c'Mk)|Bր9mfoS=@lmMR"\_r4~_X~Kc¸n<*8E4MDžN,X7*s`h]5]eg߭`rQGkx)XÅr֍؞4L Z]yNV*w(%% vSVuÄ@c *`ha'_6Zp^3+'Ohx[IǺ‹GJdc~+)L2ѷY s '5S=*]qMzu뭷56N7~k0)@e0EJ.*j7_k/pWNs; ߑ]8fZ[/;A1Zpٲe} _26-15Mo[ʫh-2]wCf baRIS9\,) S]Trk%j5rկ6Dq56JRlrH}FP ӹ5 ͥ`{ p'?Ԓ`%'BdpXf^aA%Җ xGڡL0+<1d~dGTc7!7K'(:꟬:kB{eb=Dӓ\lqJU|E NXs_R21[zYb1E8!`/uqatgwG0{?@ i2A>}hlQ2\mS|SSV0&Tkq4ݷe=L56y?nM#̒5?Qp27`Q~R5^q7$<Bid]ҜIh+Ɯf)Wk}C59.4 @@ۥޕOq8"7+㉵̊cbAtv,CE#:e~͵ȎPd8\;z%BoMT]"2 $U'{ǂnHk<NO@B}2WIP'*}C>sM7\G8=[r-y{7Y+Z[!o*&'[|b3EE\~KֆƟS?rv[c ^S t5_.0 M &:1Լ '89?In5^gjc3iLSh %蛤߇_KDK+lHikRL>q7󆷘=B2. eûo}|@~u@q|J',Қ}3umB^7zԓnO";S]?XQ: @\みrL!gvmS`>Apffu. Zd#L3?5[Jb7 X,H6|;i{Tf=(Ľu+1,_*4Lh#enw.zZSKzXK} SΝ҈{|T|,83 /͕ʪ& xUy=]|)½zR7ĹF*@ 4r*vk֬q{[$8fn)<?5~Ƿf=m(f0#U'x'4Fwk@qB {횵j(t{h<ڽ *0>poZ k!"#@ʧ4+Qbn @?OTwwmN#aVB&!\?OlUSx?!yJI`  fh"3h<@a#eDqDZ !vk#OtI|6i)Yq hnڴ ;lr*2]ʉo<zRlTn3>D\wu_|}0zן{ CҀ[1w3z]~ÒCk|yanS 9~nues!HM.5k׸9s@kmkzUvWo.5"ӖQJ D gg)~0y߻'`~~kKx:SgAI|[ej_v숰_(b1h!O LѸuTGm+'"8)m6w dSڷ>sy354[ Oþ`lHBguݻv<6#Їq@OzƜK8NtJdfvJ򪤿ٜ9.&؊ʄ/=,"1T<(+caf@#my2Wws'MQ[`Aٳ4MkSĆ# ܫ] vnq\,xEB@̒*y\:#\é}7B4rԩO?jI]!imp'H跱%8^">h̓qC}}}of.NmJCR3 5mTGZٓtIj~B-X>ix-D5n={Ew6Υ%KL<9F!x $Y+ ?"xwA܇g/ _\U1k/vL@f=c@yS@ss7 n:m۶{ mʫ@H\fKK4̘1wUNȪʫ\gp`Ȝ|{5,kIba/"ӤH,! `x*n+xLxMKHaPX)_=RD W똃0.6k>qr7l؀T*ZMoQ:'lPMzy}+Mx$?,rλ;=9FzRY6\|[/Y7da엳%*\㛮b բB*M%%in)OS骫Lrd}#DtaU&s'Hd- NX?vEܲżC\C|v`IQ.͝*9^,Z$vnKk!ct*Ôhyy;%MA @|6~vo(x&"k =ት w6(~!(eP3+ 7mYP9T^M}ʯN8V =)S'XdkuEnC~=/Gg}To¼12! Nw_!h4>ַd8bQ@8r 9RoeG `SPęr6;_2Xd425M `HtGL{ yJ~FS5H*7?W^^+2&oZ<땤3N?@rm8c>`?T`0ÀC$2jk(GB2"ڣmԌmR=pAa8&[{ cՕ9TרV@Ssk.vFӟ ]5* sK?dJY!5j."͌1bIsRdI߼Y' D{',^Ze-j/vbno1oxtyBoэigo15΁6.kT{+k_nO)_* !y8~&0kفg߮<1vk%{6587yUo}em;n-{m{19})%[] Ġ~p!4 ϯȑӬ2CeYehßf{=Z7uT[/U{l L, ubǕ7Ļ*?iC~A~3j6plpgV{׽OY-Vt29%YfT+WAQ l4 J YRSNf,W'I!d,by~/]/"'~Ca7\A$PY9<O ֞?4v?,Yr![-':utLk3@#͑R8SbjZ(Q.Q]1 Drer4C2gtcRG=vlBBV)0ffd j#<px/5ԲvKdB@,Ov9."T1"!2l96LAe%$ݎr;xTs}eI*ɛ A?"\w+V%ʅ55\8}YWV'CLBM?5\}rr/Gp} 9HfLCROL+UKeB9 ۺ_aX3&S哝J`Hxo '~Cӈ ujwŬJL}yb :LW(AU LFثi1\1G .SX^ kE \D?V4EMu$j weK߃a/Qm;:`h&fR#{">TMv;qeH~`VI~#'Wɓ,Sc@ J5GĎ!WP -(\Wg\@]ֆb\p"-r`S*nbcc ~;2VCLx͛ )޽{Q=+RF\ӯu pǕcKi{f|9F WJ8}l5?k7:|ew:y ϕ(_! u ouaDŽL%L{A&{*Mo~O;HH'43g*yG%!!k1L'caaϮݮ]f&mbTasĸ˶dZ)S\h A`}Fyb17o9QtulzHW;quҲڳ۵J.C MODTH/^\5y\!x:4eyv"n噷}1 ӏ?ֱ] _Cfq$i̒5+ڎ>aa9_}z|#*1 x x}W3"/}x3s|R3@j1[ZA} c"K-A:޶O8AI !Fj@m|ٲ?ֈTYR5?,N;Fp(ߌy‐ @C8b'֞n53G)(s" N`C%4Ajכ6ordb^Ө';WxOe^s `#[Е9C?qe]), :nџ;wMf})IR$l>]*9Ln!I0 +e&鑳 eE-_4!q_$Wx[̦M(efP f@:sVhY @>3C^FvSvбiS]WZC ٞ( v0K\[p~ϸf1˺w{W4nʵ׺q,c)E{RoP^'^&! \M5”\p> 1aL14Z m]niN(Ĺ*P 5c %⢉ ~nBi6) HYA!^F, (r=vGXhE }&hNbps7} KO=G:1d_ i^mP#E035 PG YR3gL] f̞;R,&RaA@𲠍sg@V׮quJr}BE ZvߜjP= 3!P01y? #%} ZgY +sk9b.e9Z{ybpa ccs y36?TS.YLnP9}ݔti;z*iąxل_Dx}0n!s@ȃxO~W0QHb5a+cdD.ل)~l&0bPF)3w !@H;Bj\# u#3oT2;8FߨQCT풟Wxiտ W"ƘF 8K XE%/`2sС;Ӊ9:쒦~R{930iN3=M>Ph㯸\ ,\$"rob5tc A`9Xa6koKGS _) :9 Ə/YBk+Jkڵ32Ȫl9,U_jk~ыr D6V+UI|yDmݣ ٷz?Qv3`1PJIX.`"(ߘ=eb1ƍ+VElfNy%jEHNv~a9f㤛|\}Mok9 --ĪJuʢK1TXSNY b %I,EJuDߜJ%&Πڦ/vIAYL@(4Pa@ 0Q+6EpI9*O;909P!q(=[{>PGQ$t܂}͔(B |6v?Y ƭ* st'~H/;cԓۥ7Mh03(I,+IW}{n1dƉϗ]Ь}dd VH&˩N캶m7LZ0! QV@CPʷ̏X%sjItqh#={8j$]30`T10k2- 4 UPQnzWȉ(0\dw9Ww5D0n3qY|1`4@Xy'{OYU+ 05jǎ3\T/ۖ L hyANAʜAKv0`͡!ִg2YV60ck}X &Rp'( x#x=qS\  K捛nڴٿom v'[jf FF>1C,qlj!J$5mNQ"^*^k^)PW@xڐ}2w :ixEaJzUU@8<#1 r9axmDSO6LRg(58VU 67KalBLcKlL{EpF0' !fx`gb$^= u9WБ5rg+D.e5M1(h \wSOi>xbXxsz9 b̢>!ldYhVP~e3ֵ#//b1T{n⛯V13x7@Ε_9\Zd LկJYvf%--.-4m/\$dni˔ܱb /HYLL @^&7؝""ߟñ !kLݣ\a!\ W![0 t>RP%!de/]&@d A;1Li8q{\h-i嘿uF̛os]o\djS OBO!GVlRM~qꦊ6D=>Fr"?AlWXdaziZLV,ZhI IҌID"ΣǞ[cI`" . /uBI.8HZLwnze>Ӿakj95D8ĸNRWc $,q}Q9{+ϸ-gZH2+,ć pDN^-yHcp?mj} bRw]30e| *]meӧ! gAOm|ad+8p ?uZWcʗKqYyS|Z 0W9h܁ 1cXW ~rBa'0A92 n]5{5h.֟1q%(3//)^?g^-En۾ILYmnR4\51FD. Dڈd ơ5)i64yTYCP3Ν6(`97f@:u֦_װ`h݋iIPK-roe @*nRTI聍Z*(( ƝCx7.q>%vw˹YK7xEKA"TQCn?PxD#w G]sUn$ +/u}2I6՞@5Hl>$kb_ J}ףpI k.33Pl$Am[u"T.8ܵ½"c?hD`zjK3ח0Q잁a/ѯek# _TH?#@M 1:sk04F|$ W =~앚m~DvaSm[+NKIue63F&@ I&O,jPIFnuߕk߶-驨5M^ rēĀ|T & **m5'R h!\n2.JښLA6^vS/bD## e^V9{+o[A?0h0RBdچ2ْXSW es?B}'x.0NTʗOmg̀kq.P3$Je=J6F9Êyܼw[VLُ&Svp&Lvi.B&p 3w põVסuu&B6(9C雚K?V@Pe]Bh:)^ob~A׋ZmmLnj)nV2%|4"uH4sÎ@f &Rs!1`a`qk?<tn~{D@Cʾ?(2߈c+,o;7Q= nܐ:+=NRU,N 0{oŋqx2gܧR]kq*}H#ʤ%OPȚ1bҗCH:FwB󊕮H݊n-ܱӭ1dU=k|饮LvlY/0xP{"W.&~p Fie2?1GkmֺOm3NO, ͖R>5H'^r=Ә,{VO$%0uZ”st'&rg˼FH|4d64qtci' _>Ъ>*P^k$7vOZ=ih*k(iXb$ o.b^ ~މ@p`P=}`ح{]%WjzRX&|C>HvA "9-`#hx?cP.*VS8|>1|ȍ abd@f>֋p6']< <线qPq<3Dy !@7mWY1 <@́! 8;"yb ' P۷ czsyʿGyVofǢJsh0{vT5gMCv[R5Ev3~q7| .{350/fl?L A1)t#ND uC[1rO J?@-9Բj(b+ܘňNֳdKbd1 P-{>9;xi&җ\YgIW]j2l31x +[^I<pZ}|37sVFF8t\yrlő!~1yaz gpa`LdΌKBwPjD XO~D_DOffwߏէIk#8Q) E8gaY,!0 CBzn@;2 ?*ҌK4,zߑg&H&ӟ\JŽܛ廔Qʜfv)x)OGXjW$G"! /[+ŏ-\9m!> c=`8\SX2s]~@&]RK P>4nXÒ Ld"@"uVmmUpZ;w2BOA `@xȏNB9Eej鈁sq 8"ksU땗(^Q+ n?mdR8l{%/?qlω=z*=üDBSt=9mywneĊTz?]"Ոߥ=^]o TATo*sؗk[TU+8 ?>13RDw$L^eSW͘a`FtV$77v="wIecdxeZs-/p5zn-V$m@AֳdKB3a46,v/}{ys҆s NKcHW;Bݙ'd\Q)OQ[\ nPiLyi<3l߃$,CJ2((_5@!e$ϓ?A+IuPa6 1>9tN6 _mn Ыd.r<"Cer@[=at2YOL;@eGAa۹kwKJ7MpׯgKұfk|[ұ^YC|e hNuh>%%vԤ[7nt5yNP.] "b~h /_dFj5jS4CRUg?oٍ;l [}f-n r6\}pZ + `M%C?[9l,yfcrtޙ/;EbƠhFeN`#5]rLy`+JC4CHh9R(3c2W,FOτxmvG]?hi_3-`})jLa"! U! H3:7Z׍ @;1Ÿ2D]FgE2 '4xy|oް1P98T0!Y"31쮳GÛw۷Ovc*N̞&nM'Lt4m>Cjrv ;`7dC Q/dBWq#ubf\Sy 1Sx< 5izh"ƔZZZ7:(O;j׸";qYn )n_ft;# _̛ov74phW+UxO]j}R+N4!#&8D9g:}V;\޽Iw_-Ue.ޱYҍF T3`%.>G\%K,B!!ȁN?@_4:_v[=KuS\Z7XGOc, GHuYg)tBٞ-[ 3`ϸVy?Qu3.,R'Ou\=` i .8R"ia X9V9' ~P=53 Tp?C@7@! C%=`14Bx4sƐCF́U;:ք?!9M ZJ?1lfR'?5cZ9 Xt: @#%-p<`ɲo??P1= u5@v{du!ǐY:5ka HH@=WGMz09+A] H8MdcfR^#"f­F:~~u_ w^TJ_*7\oZظ} DO4!}kGe<\9Ŷeݺ%;8.K(06"_03N o+X޼#M4|1Ȟ=N V|((/3O3gY@[^15%qL;<9q1$;̚yJ싍j0^-.ߕs2?P~B9@j$E T|T߷oߠE拰ĘMqE 6¬ J@GnM،y_?&1$:3&Ly_ߨ{|6 77뱤z*g4`!!E@n$OA*W8ҫgNkXOb31lw/,>e!iGfH ! -NGBffq-x-h? ;rX,cLyԗhľ%:Qe=a&R͙3gĸ#ۺmOЙ_x4M\mAt`C /Ģv^k$H-\/R4[E2%gܯߥBmm@#@_뫞Z 9~qn}]gZzL}v*`L˗kW(_ h>9$:[AK&ՙ])ey{|פ3>IgQۙm+WnʕI3G9U4GFY>S6ﮯ/߯#&N0h BXO:mذZ˵fr\@/1:ޏ?/dk6_:COnk㦙k `x`YvHY  n BàŠW* 4ԸLƸ6Qx,E')P#%mEd l0ڻݾ}G[vC6xwG0㏛ͼZ˨ jJSW ϹnZvseo}0k`f HQqcFnxSݗvqGݎ;%\, sI зX۽{:=wNE*`67UcdFFDžЮ+e5 2#8ӟvIۻchh&l~c p8KLŷev=r(,T5]}u%s |^5 `镶^J2FHhq=3\ZVgNє`% s Ӓ 4͕NnC`Yk)/̇7&]yz ΦxQsL ߶=[I[m+ պ]Iyijq࡚c'MD;ޕ)_?+{Lr2] e*ĸ=/ć?_':On"@r󗍵r8EupS+r!A;`ݮE1B$ ߀u<;>g P׈t_^=0:aPXugf=ܴi9NZ^b-TH-[VXտyVE Lx@IDATGkddc9]rUfXD290ZyB`;Tw`ͫgh9ݚ4Q;b"c&w2gZ!\zi~G!ozA~^vޑGH3~j=מyC'!!0 ȵBZ/[Ƞ|si^bRT=VZ 2ie-4erXبdW,m$y?S0qRG uzv,VsKtw*8p eO*<)3_ܩp^,t'9s[o: ?<[SBNY֮] %ew-BjJᓵky|\/s|@>Γqcch% _[[<30i/[漢B T께~ n̸Z#qxKs$Dd2(}H3{dsHo}1]I5>BeܿPdw4Pk6YM]z=΀E)xE #'c={Iz%-iLz: ;kw G 6C"-Yr1wKﵶV= }{ޣ_:B#IOaV6BP6ok&HW&)=h4K@!@5"x&JxްFA[͸H[o|mҮO:<ۇ{8P}LОaKqɗ]_w+9f}-D=l O? IZ#[|l}oiK"^Pl^mm<x95\tQ0^'M?${d:a5Ȅa;)b?Ccޕ!YKb$?/+5Ӄ=s`e 3` *]vƄ=N<b1[\$ F1(UhUwiZ>OYfRqfNfNimsKDt}n@ J,xǻ%:(wqyyEA}$4ܣ x劕&ܪ()~C~\6B? s." iznw^{ML1?wx!,:KB9l W?_~A{cDsϋ/.WGecjf bfV )(?9>㩧r5Dcq .ݒ"G~msJu6(G%Rs"܉Ov9b<\ǮЌ7uQNAOnذA{Zѫpq;,4BfYgY-JY:$1 @5yנ-bJ 9L3x?Lx{XNh YV4YxW3^dzm^"=AT_ T~5FaбqI *M *e)SԲƩLK~i ?~%nL EhߎI:ʘu B#lշvHm@{Z*8HY 8qLWAUDQ$9-\D`Т--+E:ϕǟU0\ƌV8~rr4 @H佳ejy ӡdC=l\T ]sg1iND@H\f[Kʓ`{مrȁ] @9˖/7uzkp"#c"?~Ifp|!$6h!e5}B(D0hFW :Z`!To9W3zQ:(uBT's[nu`̀6ORBLQ[4m~pAtsNWuV[ZOuzIS gz+pH 7\^࣊PZmCB~UcOj1>kvޘ ;66#[_?Y`SNt7( èg!/` |8F7zgUhN|٭/]`2]->%ضTܯ#IiZX܎O.3D ER 2|=u1~<͑o<@3]"CH.D;x3w0\=lv-[ӵCpw㮽`q"ܔ+Mgw*Ah1-U+WwP%~ _*cnFXFͧ^'|MDU9v.ĉ x?H]O?g<0 YOa:^I{T8߼߀R>E3y&n$6MһWKZ'Fg|lJ0PŮ3[~c;Ғ>'}qNx&&x&a>KÀQ-f6-0bL;q>131R;P)^S%E*lHQO5{YEG }T d8kO94O[/vkB&zB5vi85kŮE„5/|Kr{_Nûlҷя~ԽCaHػqijOc4 B,C"sG矶|4mdf6pT&j1^~e&0 (!{%]55VZ%-͆{-koa=ގiz2,-vTw 8v~cT :): ^* )iFT6] T.9hhpǧzSZ)1[N{O/ Os4=Dx&G=(j!?jTD0S8]“$ 09?_|~gyk޽r&{˔і|\ oMO爠9{(rDXwɇFBI\ W 9L,4pj-$4Q {n (>]Z]?{@H8./g]T}a:ojbsd;X̴Df< ]iӠ[_`o~$ ? ߸+nwkr;? & ?6]iM9 -b|_PTX0eʔ\q|s K'M2a1e~C)>44Z8 ;+V^/W{0?g/So$v)a] M)hƹ|=\Cjp'-312YhFC^G3ϵS& uG?x-x_cSSy,DN,x,=O-qؕbLGQT*ρfctlۺ?o6s2j(ʈhѤ2!?@4 Q7 @_tμ&'0# =OvtIlW~{n@dR/͹y$dT7/+Ĺ M"9ٷ_ezֶS!m>BmJr>AZ YbXK:Y"AO&±-3JoW[֭skܿkOW6u8*qz|`6cI )<; !N< Ԁr5BH@Tz )`V%. hbe;s׮lV/%)>عsݤspvT88ScB)91͐m]/!0@l5kݲ}ݵ%.59nB#g#J pEY=(TKUeSgzxʌկ=o(&1 }Zc̖^M+WLÒ@@MRǟ̑ ʂuQQGc˵x=?Cc+Mzg*N]ǿحjB? pG{ۿC1\eB٬ͬ B,}'~͒K64?=Hީ):4_*]2-=gv^_r?~0ϋeFG[|Bepdgp \gvqurqv40Ɖ_̔p80WtD.W+aXq|"@+*.3Gˋ/,W/Yveqbj3iܠl}}6n8x嗚QlZ\$8~;6D[oJ<[D3 @FvVT`B% ^y/=Bn*\1@1?}ŰlcH`#K.Ot>&s#.&8 ;JG/x;05FqWu=V}+;G-R18l|D u'd@ axхi FH3:Zd^h98K Z9KT镐Fw&K߼@I-> y8[ ܭypf&`08CЇƅ'sFy{|v!ů/W8zƍn俺eZ?Zi5BVda>o~ß;A?*?4@HgY)/ھmG8C^v,j$peez洯X\rq=G384.3.0)44%ļ] "v:]1{g9TU\èSQUuێ yԭE3 $yʵxҷwӦ*"ƒy |饤 V(npS.YMOՌf 30$M1BO&Ju^11(WM !b#Wc~6__3GVo_kٰ!xɒ%sE` X :_xD@0#ˣN_"fzrGKq{pA F20^}eo*.-/g.n ?GCw*hn۶M橿PBe]߽g;:Ggǧ/=`]Ģ!^881i8вڭW^ZgK>|ont|,jqi&@^782ri%k1[y\|DHeu0P/;&![ر߸a~K6=3pbG~Hxs]\VU]9@WO⌆D#jEO<pیDN]2!'Ns| X1g tp1[Ĭx[vʕ+[rOq՘{n q< NX:ur$ezPS9*ƜM>7=$;(Hyb^{< )J!BrSn9p{wgfgs;A0(5ªo)ͥ-"^`,7]-yaנ&CJ믇ZCEZt1=`?x05vP`yIix85۶5R[jtajpPϛ/k&MCX7KM dӧ )m~U;O<5XӀ \V-+AXO3֯ې 0;ͷ(.j"0u RZ[" 3:ݝLtZt#I$ܤw &?s>PQpmHW0`#F▃E; sg9QzxK: w QHpx_ZLx zB @O"Z)!z?uJcroo>F[h=f9vs)]^׮fp)5PlRIi1=r sw$:\{ ?M^>) E>oҟ_Ǝ+o\0 >-p97sj L&m^\܃*n*!dغe[vttQw`4.}f"dUkT+6u5uިQ#t#xJiX"xw0j!oLH@1AZkv=xFXzn݀J1u90R=9_ 2%o==pp7X'NN ׷o_]-Y>9!5=~X9h@뱂m4hYcGh7F̣;sJ}pq٦Duf>0xYck5>k1m6r450>\SQ |w=^C25@ h0Fj`JBJAOD˰Ӧ˖wߓ~HZ-ݠBg>sr뭷*3\'.X@bcciT.:5ჁA\„>c-dҼe\( 9༃ դiٵs'ԋus˵^sg5jPN! 3J6& @ޓ~Y? Lǵ9J?RdsI?@DrkϬu™7\WrH=sx8CGOzD}=V>wߥ@ޖ<' 0H&"/_%|?2AUr/|=T+ % L"pSz]ɴl .p"}~.׭*k@4]̨#Z22}uƄɂP*nR3ke$zjG@8ES2,t&S\;w.}G[Ѱa#:/Q s z\sM tyseT?<?r(W HS!pNps30.ٔ^F/ES}$.A @||~ߜ(88YX' u2r^Ym0+A:bwY4!oN.Yc&`L1^Tؖ-~3&gQAH0+"^U2RhM9Q8}Fb?BҐ*WF@J0k@YQJ<>$-Z,|+̀{qfpׯD"/7_`M,tڃ[/YpQ!kW_-7x՗T{,(.HP1q->sgϾxAkjdXNnI*Ք4V}Nں^׺^g"1UͣpM O4ܣߋ'u9/\aR"ЧQo^^$IT7?.!L/P"H d XNK +W- AP6nښwN'aq*r@D=rPsWy\NЯˤ^U撦N9@8\ӲqT[L; mYq ܊oCoULKP } C Kv&aC1`_&͔s~TTπ,l(LZ=ZLa}!f16hߊyG7l5WA?}݊9,ǫ#,{}s^*65ϻ>/XȚ5xӍ PXTQّ\{k܅kpgJ@>qa'a!8ysLXrA kf(`G|ItSHbz0#֫S"־@r2ѓ ɇ ' +L۟-C˱+vgU˯'!%: 9i[QJui$u,|MLrCVIJ!Ka?{7ҕUGtrw› D3q@|/_^] "ML9b)K-h[U~&"g% n5x(m^ /" wԔ*$ߺE"|*+N\Q 7,۷/_΁UE5e1hYPm@**;'NLvZOk=2O^Apd,0CCZi@jTrRzM [61.gIoakҲ@Qq}p_f!!!HR/y&܌>;zN zr@y5ɠwpfoniOqrmM_ji8P^{ydl_~raQ@%-q3q/Hf͜Y{Ԑ)\y(& tG̘!Ε*g9Hs&.N+dJb?\N>>=zH{\fJˋ9̨@V`8ˆ֎#V^T^<);l*{>L 瓏-gHVsD8\ۀ@DXOK:,qv}oBvkkк([̓eB>@i|鹙 }v nԸ2C`tuZюsil=V?BЀ[GA_ϵ'UhT@E|ExٗB{<Ȟ;}˖- ~LKgyA$:Yݶu͛r-[_[Ci@1 H+N)ȣ>Mj##0(w5HAd0+SAxxG2G֮.G _vNJX5 Hᣚ T+3IEڪȈ-*]}nP`|S=0 98@'Aa7rnbOPh-Pp' 5;u4VeE@DvӛS$abސ( 2pVR>{y=j+yq i`+ (K/+ ***jj*aXF6Dfcy `\} \s&$]~ Hwb@ N%) !׺wi8BvTʧtsBѓ M`]VV@z v4g -=s0M@C,Ȝ˛|GłI1cdɈcwDկ/,r|XR_s sc刔j5(k%y9?N=?π75dVKD=Dɓ kp;X8wOHEG^x Λ/p"Hx]9\3 f Akr^̿uqͭ}:ȦMCw@NPof[6)Pl( A4\nݺL染NHT4N&Tj Zu5~Pֱ2 Y9S66"哻{YŰ ?P84TDj6}"^:M3kK%J`h@%ӹdAԗ˘M|(6£'%+}_|)'}a@R=RtO!AZ,Y6 &w!_])vt`j9/Zr1[쫗?D*h0* !nAksWWIw( Rr [px_ a .*Ý4]+9 `$￿0r+?'X]0j2Vlll&ڧƿ+W`"'n@Myؓif]MkqU Wwȴ pROD9|ZYS_5X]r(2P(>޿Owr382ӽ+>b\4 y ,/ꖧ*T\=+}[kr׳\Z[N疊?hp=2\E X׃U\gubbbkeX0D-Z$ JtɄpd+~t,i0ڱ[#Cb0%!({t7»#KwQ {>L2.*wZJGΊrgPW݈ն7 f{б.-T#pq*3b@ȣra$w^9~Zvڑp89ZZHTZ1- ŧyPKh|xhҤI`a&V7NzB u}N$d1WرcG6ڡpR} uWp>ڙi<*RSULFC57V׎Uap8#;sq2ܾʖd:HǶ^ ܼ@8hwK(83iHXݺ*ӵMȂ_!%ת7q^GAzjt9✞vAߗ'`N_~ /ȵ^{Q7;I|lzI]IoʮA`>7\}љ]A],1n6Ϭg}v×!xiJm,*KI  ܄>822ҁ| 7/lz")\98}++cs{$B~!-TaCU$q> f$2^8?N}?GRҤ>5͞L)r%Ŝ\@%?,Ƿb]0eA h5n.t0dcT!3)p·7< *>!"sо9s'7$&&F{9 .DF0S^t\0zZBhq@sݺ:K.{ի_uJRm@Ҿ$^\7vz'/hg8:(`~/Up`pIxBW_&^.  Bq`K&0AǶ1~ga=zJUbr%@:`$.[.y2er 1]A@IDATsW^)AФĕ:IN-ͷ={dŽm,΃q>ƿkײcRy qJ#-jϺ/wt `A8p  \o,J s^]+Yh JHɁ es2drpRI@_c >mwoE q9}U*O`z.;v 1VQ;w\! .|}0.|lI\ /61mڴ7oZZc J+omae.ԧ@Z z Ԗ|)s9Գ;w~lSC~a*ݯpؑjp\C5X@g~H=s8l~ek͛>V"C ^9d+pF9CC@H* =q%c #G/Y״n^# 1@MS@Vºϖ͡E8n{!(I @IRZNKKlɏ*L?^@GU?AzZFa2KuA7B+}k8 _|(511Km׍ML!WM9qAs j/XL ݥ M1Hb4va"4csd(`Z/BH,S^gkAUHePtLC O˄N-mtoClR!`'<}͛K׿GeN\4`ZǭǸt `q[ ](}#o8:}Ҡ^4>(`/>F&?QjBZ}}Nk ڲ>:u~.p#]i =f)0N9i=T\,  gd:aSEK` 5ު֏S!u;} &Tr5zuTA>UI>fVKWHrh:|JK/GN}8uZ.Lh|k(? (m/\ Hnݺ?/wy7T-͞=[>S9 [<^-e e 2=V{ cƍ{|I>\%Gɘ FLḥs̹gڵ=7\(WG}}}޺BoȺHBQAon2D˥]Z²LHӷp b,nR/]I^=L0Dm` deP sz;>D5[½pth?@>~"3߹G}Jn]:::=  J*wf?o[[]tYuyQFIӦ\J_[o7IB`B_{NKmnܸ2 ho׭> Wbxwu>@<1;5pCffӧ/T;?h Pk,9]G+ETwŊYqqqAv u`^6~2dn*ĆJYS?y e.ZH ~vCjb"WO?, 9]#n{E}o0? #AߧfGJfTP>S k3={BP_=g$#%iE \"7MMC)9&Ԅ*PJ0W}Vu„ KnFF].J:÷ ,o; *~ `Hs+\0L!TcG:>iwn !XYfPf flZ0({g͖ah?Y)lɒk\eU) rE#^OX x44VwPJK\aٲeq%ӧTFP<:R`i8tAZQLyWk],_\`Y[. 7pOq(CÔ_0_ESX8 HA0i,Ag~|㈘i>f4\ݼVsUR,35MnڌXEB`5$7Q-_!; \Wo?K׋+pa gTE&V;R 7<ЪW%@=6  \(8+O-+[vؖ-cJˑnuԩHtH罢~D?h;-,BP0]u\xuoֺϠpoav2mBUYe9@THM<$arxSPRPkpu,!;tl2Ev~VT?KsXŜ,>$oty`7 T:0ɹQQQH+Kf5ï  X]YY. @{C5zѢE3_{5 2/ (Y&`s3ñ~QzF鰕F[}^3z_e}L2y])-`p+FV`f6c$oܨ{g: b8|e6GNţbÇ5L!z=40)^ȺjL?PwÀdgF̴rpb_f'M(*_/VSGw s7 Q1o  Nw8-l2"'v-7tk G0ȦRa ,ВF:52 .׬A,PeoҰ(2n *km,2FG}t1c6oZ(y#(vQ !h pHhdɿfйXx]ǵq}Z;b]FDŽMWl`\Auq1@'`S/}bI?uJ#O(%g_M[`D.D1`^پ;z֛xgzcϧ,䅁!f< qg׾0G:vtp o-;2Ѐe"c@7f!F+0)  D̍JEoe/I2e jyy> g1w͝;Wy{Q ` TzOv;n+Kf[+ǯfq9}̺t /'N#-犸?s @!)Kh/ ~ȓ 5Sk\o;Lo]\}ӧ~b\Up?T563@ 34Q3H9̐qV p ={w s4e`-c>)|JB;|DCCZÆà6|׼zo|Y72ۥfN̿!x ]<VDi?"]50dCanqIZJV=z/9 \szH4h`LPl)1h^d @ŧF Պr 2wj]o-h_ףK-(Bɓ'{]`OrUM2C֯_y—1$^Zx2ݝVoZ*FyjpTp$d'm̀~2>i;q\a2ta0&_4H ##~MjpY?9/78ߤǷo3 */.05T|^t ,T-H!v[ "8wJWzM S.=t{fk(P(9DZٝ)+'N};>m۶rw˫*LLNN<)AJո8I?xQWur `|{֭Oх,ͬ2Yǭu]>KD쇃{7mڴ m TYxO .70KWhO\  =z˺k1] |aCΟ F+T*@'c >Z/=q@I,JNyS/2h*_2C[(U nǶnWݓ1>xXePZ1Z䇯pEJXD-*\XPDgZVeG!9x(#yGL3 Ljn=&7T+:`i_Ꚓr|HZZZTڵU?k ^j&]ou9o_ؖ!=MLL4 `p+++P͕H -8l2˦44զ @6A~#W!}_ZafDm ,N"XŋsL"۶A{̉9 f>hb~fqݣS_r̭4=NV,n|IcKbeAy P,~vKf͚wjuW6^1۠ZӋ֩~ h^RgQ.`u1͈2ŕ bq׭z<#% A3裏.@1(` RISB6lg̙bÒ|K3m1c}݆fz^3|ٽ{w.Rs ΥMwMÇ0oJI9Y!O N~qД[B1\a70C'$$~ +\0h2>('K}أ-kؿFOcC?})HWTDaa.ng Tr PxN1oO>ꝷ6蔱MBZK|+#̇Io%@=e}SB Otz] +mu{nbP/dl5w|x%nQ n<"jp9s9};&Ͱ\2d4_vmvbb"48ȧ?JÁmZ#̆K+z]/UfL)h,l#}mXd.1?TG/muA`'+%0}1@ש]$ISdا{eqoM)y%ɐTuK`BGY #3(|BwX0SpNiFTېV XC*-[%ן\m[ pm?pV|aسg@jɤhmAzrֺ>F|htG<#GsDT]l/&v.Lw}_i i xfzs뺯Y|euY}L&Ï )q??8ԈWv/̨{Znm2C1=kUN%vpjmiXSWQ"}%s ^RBL_ Z[Z\ !()C[ɡ+aDL4GA\@oa T4 =cT0{fRG7"(uឯBZb^>͕wR \]h㽯Dst rɗ+ޒ9|n]1}U_q^K%}} Z67޸A4ê XLA #s率Mpzzn_󺌮Syײ<}SO!` ̼ׄiO?wY |~}a@[]B<׀ÇKt*(',zS2OB{MK6ml}}[0_ _XӇ _~Q Zb)sZο;W&^ŢO8LdxiC(w9LcP7%iJPfo5JHaw2ּ#JKg74`I][ UEet1}KfJw-[֭y+ͭf.SֺukgZԩSzDQąFBqM} ۶m)( rz-ɵ>Vq2d$"2vݺuِE"~l@)@hZl  '} X2c hޤ5N&)@f0-c׿k5~1W9"2dϟ:,`e^~^Nԟ]/-,yuB!7i@hdb30?E$ܐ58Y CzQZ4MưL}W,-Ӣy܅>oi]i^ px9Qr @F/KW(p_XOs׆nlM4U7oѣޣx5Etש2|J`@2_K0ڃaXjjj4lgPAo}U?ZFk?5)'ig]bir UA3[(2`,P6܇-S51B'.D0;h m#}mX9`]E dI\ T:?_ {L2TB 9Zu-f01GEE1Ai`Ú5kfOL9@)<$ ` +/hԬ6 aow7˺;ƶ񇟏bibO_@cOBP}6Vk@ QvϘ!GV?nNNjj0liS:C50@zt_}-xC2RRJTnN `o*G\nN2K]92+I=-cAtX -,=%0 uBvX@Xԃ4&sq^Y_/V o31+Nj0_{ n==xSҔRi…\}jZiR@D/8.?SF׮]۴iqx]e.dyW_uYV"d;s=s= UC$=H[1,Q`ibzP[[/YW}i B 9qMfЀ)x pV8;FopedPD:G|1agc͚ * ]&[{OΜY`Ke "&o>xv޶]`ש}T3ȼT !C$ 5Qhխ(w*-$/Z4d@@`P$)@ ϛx$$%!7`7| _!)Bٳg8S-(h&b̯iR9)#H%@+'.hF!VCzo}^GH*(YժUs {i'FJje>$5} S1%%Uz0[2s[}\oy`o#rbgg CU mj$Q &B; *+F=ж0 ; (|`f1oKc,NT8'vOj*] XN ,jC\uȴdOtm2Ij X@"~c8 '!8 ?OTLfuPS)b(؁ap;A܁L'5$VmH6>Dj[.rP dKmBQsw}ݧғy^J%o#-x"o SOx~P YrLw^i~[uk=eTaVp-ߴB`#ѻwHc>{+>Jp`GO%'' 4Jʁ%`Ϲ>Zyc?jt2'k}K@&.rrj 蜈!ǷmLPV b~Ơm0 W> `Lq:>dVðx> WEv,?+'żV9Vc:B#(:~9P.n<9?~o=8 t$&tCPsx =Π8_`ky[-0:{NY P㟴H7mCVZ`qm YC}ׂ7h 8P;g<-npdaKʜ"Jރ,*I*-$&Gξ}(i - 2cwEM(w| -5:"d XlٲڪnjOBEvnݺ4Kg 喃[u_ey^uW?'?U&z-Wku%CM#3=y:A"f ղҢt4n4\f(@&H:;J,#۶CpTZ}cy kRn ?L!^69KD[[Q0`8}73қiT9sGT:q%Q&mnA"4 X֌nP' `s<1)D_̳r_ P}p)lW_}Jw22I ̯ɇ;9 B G駡 իW y"ݥ $B|G<޺oCg\ $9.]7ܱ_E{#d֑} >2uOMF?Ooݲ+mXz:RdQKiFKu)@+@] /-*6@,֩@"OAliR@3Ua u7y}O;ĵxbApZ@g@ 2% l%BS{oZ*6xM[+2:5ĝbi=ziyUR)P_3܀ksOVhڻf<*OEN=FB>tB@ UK(XbQl'Aj3r A)WA@a>sm譶u6mꀅ1 Bv1 B8'UiF?J@"ms`z*؟6uDց}^"A-i'4}6@٠Wh &6 dL0hɛ I\fͤNj3L8n)C&t®Om`hHׅ+\Hiy5b lăl`*p КN%0_=r%S#ɑ5kUaARcAo`~ccp-FgyF@dT(?C(e!)u'_͜-e 0p'DƳlV:ܹ*?d1 ׼je%JNHyo%\TrfƲAaqS׃>8&`0ws0ujVvJޘڏ~P+gӦM0!7p0hQD qrj!mެbPSKm oqqeTr `$Jw$fNNraB;y.YOzcse7OB`X ]D<9MԞ7DM'=x'w<(0WB7eVBQ~sC`V4M0A~i?~ @8ע?Pp  q MF/ILL yh Vߺy#}M~[w$LA@utYfӮ]eBboGƺ.ƍ;or׃ݖݲn,>溥 ԟ?@YIIIPH>@٧=0~6 5*I&.͆hZV1m A.yF Z{F0xŤzb}LuOOQ0hFbON']gּoP> Lnv<ڤ‚GEJԪU˓WepDtE>HTLd zr:sy¿VNB KjQ_]RǿnK`Nw)ɔ"P!dQ@[Qn@ˇ.Da\c6UmiPeB*{4o-*G1(0G2`tϞ.uB#U9s=239v~iqZ7*ͨ!ZI\\69=4**}`lw["5ȹ`~MJ>3[HKO?Ios VsS‵6]zy@eef`Fg("Ϝ93O>pqB3ihhƺuoLףGR"M4(n[!Dkib@E 0N`{c0Ў:8#ZLӦ` R h"`}{>%Rp+Z-/5&tؼys|q3p sXTl0f̘VUpR3gڼ 8+π`!@ -8?]FX 14ش2y]4dzBЊe4-[A͋ub/K |4ĉ;e|e۪OI믗Ԥ$ca SɷtI?qR#. ET Mo\8.Tpmd6l`G_beloo_+"?<#rs@@Zr` Z@wr<= [Hh&PqjvKa9n-YD㫁`HA )0?oj* (LK S|5?T71?ȋEc %>3-:/pI[˒lr=x/~ʼT*dnܸq_a5`ԄW:R+QӾ>l2l($>tm/ dY*6 ~}4BLȆR?66\zI:+S ~Νjz=۸>`((!fP\Wp5Uhġ.a]U_gtk @窫G ܓ`\scݞ)W*u9ۺeXSqrT7#%z L \Pq ?"_BkėalW3.5_ʌgdo߾=נPt'gZnotlxw 3.>lXX\,rr'* 1TC(ukוSOI|!uP? f_1H!K,ɀ o'$f?G;tl?a<;o(//>C۷t)%]@D4p p$08H@[ }13ozI.c `+MŠ@84 (~Q"<{"">iׅEq~,ŨUp0s bhg AN  =P=Cƃ춎3wb+"MO>,fiL"|U%hi1=5c / PAY9ERO,eAQ x7N@ #v4\~Ű m1K`lr|fcP H:t(FרQĉk!~5>!B*f da}{u]3\ߚ?6] @"/oe˲Ż  Zl߱ Ԟp> B fãK1u˗/&baC^ƚW?x@ρXf-9v2g}@׃>M'ѣiOm۶]6U>FCv?BdPLt>#9,x'SǶGm]W 9\7`$WlZ-HP,ءpJxRq*,fаI6)1/1 {kԷ$懾-p:yT9?;`6w,g4_/VXC{;\+;>D@󟊔v.]ȥpیVLBA̿dTXnƍhIA!̙#A%\v o H 4m;^רa|]真ף\0(>8kr0cwDA%j5ߠ `"f2sObw$3zt@+xx.`Jū:c,oeɃrstZS76߰>Ӈo?D]||TaxԀ/X908WCmUA߄UJd5p:4Wa?WQ}Z/Yqqq٨ |0L: +pØu8 .G#Gw6\CV/8pu-Si]Hn ZTb'sԁ2W0#)xaPD(@' Z5oT}JDd*8Zb lLϷSb-H0,ͯQr8|0Ar~ޟ!. ) DY {v7`jrj)S)!Ue'aOvv)|idZ+Ep@SF'^?ɔful~v=2?{jA9BW^ɸjt* 55M֯_۽fZg !@2Ь@+ C0Kb*㚛ko 8ϫտ34|@|><@JoG u)Y+`㦍@WLJ F_|LX2MȒ c\pp8QQÌ. D֑ǏzpsI&LG_kibŊL`I@hU8l R`qss8ÑrL⒓8}HoƆV4An~'jke[ w]%"&ZhOXR:aP$(`ᵒw=zz_o&Nò sn~{o0/O? UZCOZLqWK ڳo?y]ZEY.ZHgݙ&3/r7( o2fh2[7uvd*E#SR@CrJ|ēv^T)!@S_iڍ@FSW^fVΝ+ ,(F% `[jƊ;,,y`Uѫ?cc 7#T(p)G3 626BhI| jZ{HaA' D,yZBtNby`y`RRR}0n}gϞ}?#`r!PO #= pce :e8w,nUqr)?4 5rz.76#<|zLiR}6( W>/!b*ЌN׀Mi@IDAT} wMi]qԁ\-  3^+F4{ 'joivNN>5dJ'SߺU:}d K7)͛AsʬT/Bv[{0o>jҠo~$4% L~{T={圇(8z"ITR._3r)#6P(]2a.2TX? , O-Zlb^a*,P+);(QL!Cs6&<7 $]vyC o2F+5~5]]:^"ʶ^iEZǓF< 2,|ۧu^XhqAV̎(`1yxD,H8HŠ;1\0}9q@,!O)3?0&ŭ ,GCߢvUa99Y_8M4f:,U=-S(ddd؝u -T:'\L2Ȏ}QHj2BAJsȴN 0  I5bjJ3/ 1xf?{#rj>yNCƛs}dǧɺ^Bs]kbA$j.t4P#hkA$.ki:|Tomy@[3ݑ%Xr߮ fS(.l[ 8`WY#ۦMSsɁI'J6z6Z|\S\X1ߦ)SCδnZ)? GsaS{XJt¿(c1/^E=4_@HCöm[K6m5ؑAYFcDP.pwB*!g/&t˖-4tDǖrc aE `}8͎{9*cC~u;SYy0>ShBuuPbRbAkcà \pamTGUF#칳jRJc?F]re} wBae8HBSB[$;O|GnЭZV 'dhUqc-p/1@_mR)Ak$~5b@8`6`(`̏~A-Hǰ5ϫ$ω>re"}>d0iyUJ4i\,04D$l(CoR*,'Ryt{!.t3I$Cu;u}+Zf:Xԁ >+M3K*>1?T=!UAF|߾}GAZ\%`30mVZ22#+WY-{?S}`ϼ'$ R 7H_Zsɒwuq  >V0MI{׷@Q|?vmu E@dpI*n9P"]`y@.ˇa px>cȐ!!tա[\~U ](q+⇳c]#/\i#}Df@p7%gy/;?"ֿ6$(D x3nw@bccs~&u9WN׭[J<>ri_~J[ILV:o;?:M]?uԕ0sɆV?&]PO֮lON }$x%p[S{*}zK1c..G &}0`(w iޤ{i©t uzFD"adP+ЕOHՇLPx8A2@ !\Fx_~%ǟKXXT$,Zv[K"ýwDZ?ZRnyX(P rvr]@aO4IF̈]^ӧ4m7įYtbf2* Af qd:F?V7u\2nG'1"auʩ0+۶mw^FEIZ5! r(,s*[8bMz: #ރ3q*>l`w Y`#>3F5kf3+ev90݃͛@9(xcS Kw.JQR?OY8K78ӂ/ /Y>Κ/iĉʭxzzb^iE8VMx#+6EILhǏE?Exs?`HIkA ml'59at dB 9# Ý9{ԔԋEU,`B@~4haa23d2B|i`P" plqmQ@4?,Y$դjg4/HEQ_Z@תU+tٜ)A8 Du!hӨ"# 9'@,s)4Dɂ?4y?j+A@og, X2E{= w.+pO}_pZnӾ;w*K@"= .`j 0o~?>0?vO@i- 9-i%y7ؠW^FZ-HJ()yQywW*'QUe@"D >ߝ>'lg19$DFrzOow_}oy[ozzzzzz:TUWUoXaMPr8$$ffჄy9TkX5mˠS3_T6'fv 0$L.YVwcL;K;7` @}Bt#KZߒ)b;*- ~̈́u`?^‚$ @0Yt&/)W=׀{FJ9s˖/sn?Rb4gf$t:lȄkXK«c@  " [ɰa 5xc9B0q?X7B&W^{VONtByUrs~(W[zkkNDŽ&1t~ LK$ݢcV-ݩ8i@ gQUC%2;$ɧK0KЮ ?"hBOJ'쥱eE`'Mٮb~nƊ"l_Μy5|!Wݰk5*!Cqmv2m`嗹\*V2%\Կ|sk>HN f-9ƧZm^ڽ!?k+fTD{Mت\^ae>l }L$yG09fnKUJ42W y~.-#4.v 5 Q?\&+eNu~9:I]ߴ*8d'# .Y"l~X85f&30 kʎ^#8]@{i-M^y[J-)DB m5`@nI{{4ȳ t |X[sjU04<<&P&F&/1tMGyE^e\h,=/,XLlR@mib҄Q:$LhMPVZfi_9 iM`<Q=L^GM3 b{JMu`̧ʕ+رmyy3߯@| yE!ţF!A&"<:Y ,|CIœ?%)5g:ko#LlV/Bvj `kkq/ME-tv]chTq*k vr4$FTN{e}׾.b}׳/dPy~kNw,BjLiOASIG~W_};s\e z5i$%`.)nlD96a 8<<@3.S|Vۢ)(3JbRcwy4.-p"1$Ԙ^L8:ڒ)C>9i1'Ӣ:ھ}!:[7dȰf98{{ށ,8GmaR6>L0[Y`D <4! P{.d,.qb!-08JE$36yS8V_SX2e[.[޾rt6ġmbgl ;]ېz{$O%: {`m+ds;vRJо~̉aM?w⩿]J߹d Ab=&!5vbD7?f lwde2``B ]Σ1Y9|R a0ddӦt [DAZ_`IܫYr,Bl5B`i4|kѪ &~Ĵk$T-Kϱ񽖱!BS^˥2_2vc=:WͶL UOvmnÂ2a"w?@M? Pmc>4i-Re|8;F㼯70É4pY!^{ѓ""M_‡;̭?$x`7CE=m5kݜ9s=.ԉQG MY`k.^ӕ2Nuќa_,*h&H=LB韑JO_GnULZHe!?}XGqPÁe@SYYY&?É<,hI k$j{?>WBkZˌ_˖'h~t8Aɻwֵ`'~EN8 t<C?R װ!LP*PaĻh$6Uv!c")>QhQr5k(06XA*%`{- O=̣AAP kf"'zO2LLC{rMfZy0*;NYvKx6(W\i˄l_ 1o}ΕcǺW]i4xnWOOJw }.5eP%'Vx9hN޽ىUn,dXfۿ>> ӏMcoD.m',&!7DqOhO€OpL -ߖ66vz4,l0I>&OزB]Do?2e4 q2誣-"v[؎v"!#3E+%l%(ߢ o[-"dgW*!%-Ze{44xq7p㪥,t?"[[.nNI-:v: H3TwV R:-u2ޠԻp8=rԎ8n,``('>C6EcHbs 8 \\rӲk*SN_y?_6foW/Z'nlvHնNPbyC=!/c`Fme@ݵ]ڋ-栺ܹ+/ng5VA,5iLp.6Qie6ޯ7oxFJ C62znӽ\>OBuVZT#3 pҢYȀ@OxKq-\ 11@l $x6, jd5,m C窨5QUk`x͘hj]8 . x#-Rү_v0)'v= 9unk`AA|KOsoC&z$wymî5 '%ljM^3W]^Xdҽ_4_gP&i9˽'^̱xV1P&a8c3v`vްKm5?rN][?%0y< l:.?U;BR.^(hOE^>2Z+hXOc'N,W9 Dvm8.6gu &JЁc}̿:c^Em N' NB<, ėpso(cQᇒBysÐķ+kl34> 76_$8kSc:v/ qu^^-<<0Xq<=܋Tq$i'|^vk]x/zܾ5x?:ؠ) ' 1)E6;ܒɓ݁]˾F4 -COg"|ٮrnLg6ة]9;\y}j)nIn}XҒjkI?Kl2&&+H%%5=Uߺ2ZK`}[2Ɵ=HbV P˹cFH3NѿRߗt[hGPCaeEnJF* u 9c;|$Q_ lZ]"AD#F앓΂l>ڠEC y;X(_a{~ /nAA&-B ïwu-xG=lMXjv52Ap _īa}|U?s1gBbr t\$Is4|k4i< b_|Ո}g=ۧھ]a RK5+τ $D30o{'?#݀ .pnDv~]ؚ9b)Ԁ42haC]CqD"ZfQe V?C bXQEHIʯ4˙TyR?lO[ߴݭҊTcF0+gyz¦٥5K/1wH`jS GnN+7Jwh?"ѯX$ZXs0e)_|ѽKnuFQoVu||L-X=&[LVj)İnc§韸^}zk iX*ϖĢD ЖѪ?f3eh-Mn +-S$l(Lod:z 9e }`B8>pȾ0΋ `|tC#q58t!Huk`iv]P{dgȐ!$y,cb30_|PΉ_\Q8HT 2i[7C8W--]|O8NxaNaԩnqԵOw t-[ӪbdwZ>[B ܦϖɲ7t;BN;l_ֱBMŰ@u=P\60Fhe Liˊ"V*SL'-#;pYhO(ȠN~iF1@~}?&uډBN˜5g9̿L?Rb?"{Ǔ tyr_4ȍ˵=1#O`5.5kܝ_Ù Վl <$R)\~pլ3@"UIZ8c9P}z]G4DF-5Jk/|uݟWP!mngu"'c Þ 4Ώ.ߢ N jMTrƤFX#b4:!8זv>/VVVh%!$?BLN͗(+ R>=6Bz ֟mCpd/YE|\>4!W 9N W,F]~`0!Ex+_g>Y<_߭<^TI9oјtƿPi}p̣#§A,?VZ +wSj!vР}'r1SL+L-HM :hw]<_Wu)6G` QPdv#|-UNZ, {:|'ܪ%D}KxaF{6a٪$[I=1u2 VhvB"Z}' {"`^{Gq\{$,Hxp3VI?ݒ_v\|hӻ^3nt5*yQF+6F.D%?Z|}Fitpoa)5@H֢KgsC q1ܒO=jf ZCΕKWeNHŔԀ-*+rߊ|0cW`;gx 7%)暨h;i ɔxf7mT.KYޮkf[+3GϷ&U UGEF@z  я>9ꈄ_Ù]ua ϓ`hKjXȆNK.v px^K@l1_Sb$[6HL +*n&mg)C$1a˜dF\ZMLMmn][EY#x.j@@!/5z{rƼ)ʚ63*[K(u[yzȡ^\^?uueMxg܇<Ϭ S+GkM!m?C6 2,Nj⵾s4?b;Yt^73?&fr1ɝ聥x~mOB {SP|:i…j=]G[EAmV=hTΣyx!f4bhM5kH3N&fvy| 9m@V~۫:?/;|4 O?w3 Q' LuO| ݻcRCAm|߂xS @Ԥ-|-³hT s KWr:U:lE(@cB^ʴv٨6kZ>*|oLʶ.Lʫhfd~v`L,~;suuVW5t__A1o {4pM4X2HV(8FxsW:4<>pրA!Ne\΀gxxKZQSٍaVY!k 5GMԦӅ3>u;?O| ae*7'͢}D0* ' k?p oԠLM7*++ͱswkcE;)oR9BEZAQɦ6\>?t5LטoxR]p' xG>V> 7wp@j[Xg,.3ȾCX@:Ti_}U2綑MŬY~L_Ŷ'61ڎA|+h0Y$N7A~,TT7I7Do0]ԀxsQ 9>KUeO$Ws:1e`Ic.k^NM%g+o)( [J׿}#e\X<(Bnkup1~WDͱiz"_OC,| ’'c3fPP9/}5|[ruda'x";NMT<2 |S$ؕ {ћD ;_+!L6@_auI"+V= fFf4D  l_nlI Z3y' < 3!a1\Τys/:08\kƴ1r]Fcu9-#(0"nB3D3j^{= 폻ᄏZpÁri՞vGD mMB(iL!\" X3r* :"[ZtZ6k ţM vn#C]?h<;oժE+=*G8:sx0ԭ1V^EZ?E@=MH75YRI͠%Ÿ̠ѡi Mbg<|+=cqI/xޜ yOxEޗ@F{1J7?p-!}_5`vo^UO?ΫKÇ s>L^zk[YiYl9{b׀Ƨ2v9`jngW o3OUƤH:}mL {{9z1XM2j4پG]w|p݁g;a2 _.PK,q/;>m+1Gh$9IbbꠅkEm4^\=(/i? 0@ NGX-VdÄ@O.Ҷs ڱgȟKmdajψ& BA:`?W:gZ6]}~r>Ju h9g^;j!GܨiS_sVbh$ظGhn=V^+sy7xΒK%[wXC9t'i`; ߝ0ڹ… [A29O|8[Xn #XMz46,4]|8VژqFF550b:4m(k04Xc *b܎A-MeÆ ۏ_/[s knovL>M^(]Hv{D ,*7Xz (̩uGt/uRďm(GPb w 3$z)'[nq)]33ؼeJ{}l#șݘG;rNvd򔜿*0ۛ|$j5-Dg pٿ{3ޑ0z27m%A6bHPu[6s"4d?4 49±dPˀKSᚎQGF5+xԧWTbpa07 }Ds^5 M?@Nyj1oNSN'KM-_ֈAX>fZz_m'ֻo־߹I ,qyf&L0geV+% #`/B6j}SsCr?ɶ 4X9l18d+5A;jXnCjwKa\"y,#Kꋴ%`eeҵKE5-{5e%2 2ujG7+ 5MNe4hy<@x ?v^<^ i$a8۶NԆh01FSE 1[Xâ#v%VA 0aH)[Vx匞'*~n{ 4<ߤ$<#TBǓo]HCz^ҙ'' sHy1t+/rO<ѵL,6sVŌ3TxԨ?YL^7s]1=s2imfn=˭lI qO'8Gy!q䀖N7z?x"şka .t\h@Mp}ZX51P}O 0u*N#yY꣏$!~Cx0:zH @& ̙3u@ =?|;Ht#_~3glt%|==  F= 5.|/]8,^ dDj,🪜QLC_RT$ثMȐb7&KAksCLBZ2S8O/al&@"!.: z|Z˯40s=EiX0@Fp9a|$,fR!'o>'Jxp`V>ݢ_2dJ+[YڋgPFH9ysøܼ~~I'Rv/wj"pT_ڙ2x}vr帱D n:/*Ѽ֦;M>ﮘj^3 }c?4#! TE9%|*S"$W0O>O6qNj4rYwG0`ǹY%|WC1ý(-Dv߄GlB`kծ8 ОQ~OCɫkٱ -^1bD'W Z6'U~q4cA_'&=裎0 !ahrӕbO@@IDATFO}7@`Ui=|[ CJ7^x|_0OYR!ҋ4>v֖^xrmdS*a@ǹn=zGx1 §h, <AIAkȥ!s[=^bHU'XqZSrxz| 7>n"&n{hҿ#.ׄ_*IjB/13gGkΟ%e#; "j .Mֽosp!1DD5>{X{1D3Dyj0RoӘG'oz>u>u=ضz nU $7-[>VlTTs hɸq~~xj:t sX^njc; qNƍ_`{05D+jB ! !|%a*dO?uH3dcD`! VaF`y"Xo24i8}8LG G>׉y@*_{lG=W87iĘ0F~O $|B _: 4@᱕؟sa fT4Zycz>}W/ÞHp_Vr ORSS U-H(bT.y!؄D«yJ<{.(K˄#95cuu?7/ڃJkFzYb P{nInQuTSg6S$jockil*mGmeg#c\6qcl痋rUԚʻ40͠gKbc%<(&Lpb' ŋwDH QSY#, @wu'H7xs=nʔ)H07^ e9{[?{1%N! $ V;\-£:.B.\М¨sG~]-D#k״o6R~,"4(5N ,^qUAX1@`QoV{-+,LY h@~$Rk6Dq;% d! mɧkzRoVYYٌNVC uw: Ú׽W}ψ0D ;U m1uj ?:VW(Kg9(RQEv9]˶d3 ̨D8@khvBTȧZ}B*bV3'Y5 ᰿^ӑ1 H@m (-ٷ=G3 M$sh|#8G.$Ǫi*Ǟ&sUի|o2[x%!&wxtGLًhޥUVM_S]ћ=mS[J; !ϖ}:Jֶpu`e[e1L8 af=()asi;V~hlV< իSNM@MWdѣGa:={Ml Gmv45&`M? 22 w */+Eک V70UdE*µB7^zhh\VH?[`@ Z^ xK2q:{% fBB/3n+6,k&ڧ"k ؉L}syb_Y:.wʹ2qvn]۷JVvn6nc7K_ҵWc#}&[iu[~RREɧDɐ4sLmZOZ[Y,6b~y3`dž\+ ȏq̉mWGuX_]b K^Ci@m!CpT;؎:BO2?!n08U xSc&K(.f&OFf_cBlܰѭmVF~Jҁh+|ԯ%knS.d1hP׽9ީ3s០gtP8;őxL !W'p'RnȌܧ} Ekt\ # mh7DjA]Dcu TZ=>f\P;:U1bq V&ߪ?'d`ǎF3>D_7_LO\TaN`>n_qqhRD0E e ٌQ0s/xi״u+Y2q:DC훕}Dḵn HfSi\F]e;]nޓ]?ܶ#"2 4Κ9Mnk I#eR|[xaՔ~_6m??UbLo׈ 5@KZ~}u՛z<(N=6~`<ШgdɟauafDZ(6RV`, '; (+ &Fe/LTHV1ӗ(ovڱi[!UsyF7Ue_p]/ZŰ#0*ʎn?'O}?2y*7h~15Xw=LҬF4WW2$(dX'Svn1C{.afa0ʕ+諌)N-[yڙգmI!̣u޽INZʼ 15=c"m, 0~@ Gq~A1|nݺ (7DZQ^uV_CG&~ \, Z]oh8M B&ڠ&O׍sÉFpO39O~k`Iox?q Y>1޸Ww֙]P11"܊KWYɟJs1UTDd\G!‘sM!W^Y9wZ9_MΤ+N;՜l eoöuGvsxm\+}zS3_ֵ_[y` 3. >\y3̯u=k, 'O6!Gm>B&e רVof+sE5`ed9%X, GȻmxV % =< m^յW %cvqJ} ǟl)]{z8ri";7"!0`P#:Os}*v{ν&Gwc|% n7p6})VvPrb4Q5XjƧy!WbRzH{JPlY;2`xfҘaOz Ua?sLJ8ᨼ+Y@0,s}Ld7h\kMEq틨b0A iB?}$qf'@V|, !1!kⶊH'hCٟQ sͯn0aV~:thxl2 =L0~yr/7y-7XUG1( MnP='@SV5_K$*;6̔ |`Li{q%?!MWp^4].l{u]T>G}k´i$KY9/]*wnsϛ3^ݢKD}t6[̫jq mZJsuN+5F 1ݏ<+ ft-qCrN6ݶ&3Nbek;ݧݼ_2؏mƍg>}eN A***N)0 @0uT7]m/<;[؆Gzxx?c>Be`"k'ɍR> SlЂ!>(m$./V0lXM?WTɏD3 K/]K=gII3IQ$l(@VCC@#;x%[|2VǚPOU;gV ˳1++0$;|R7oSƹLқ ӱV>V[ӥf&ڊpWz+>< )g[1?̝8};:1J}sg;3乌WN%[bwgS ]LEPwdE:NVmᢶ{gqM<RbOR*j=_(4h3j!Sp%+|ppZ>:/B0@ A(FA2GӇM ~,yB`E4xl٦UށL%Ld y~qQ2zyTQz]Kc;4/ooq8 0 q@HMǟYRۏA5 &PA?.Ń]'#;OƹxT ~^8 (S &Q>Z# 6+|hطBa駟vO>#1װWݲoXlۻv haDU _Z̿kӐO<.S.[?\NQ^xtc%S^qyi08PsyhTO|aj.`0] A۾0Cb1~Z50@>l9VgC@s,L`>5yLT=v @+. 2וoș-&MT-9FHn1%3sc߿CDJXsU>1)d0 DXDP.nwDc4lk!YhԀlDjL\j[Wkm9&1LppEZ>`fw[}L`ۜaݤyylR r4-¯vzai `ܑ_x. 70OIukkg̰VZ %,6rk/gȈ5Fki&MMK%o~](0Guy@?S DΜ-bhwߵUFY1Ol~a |:fᗿ$<;L<H&gUtC515Q2E C)3T/ p$A-!MHFӲ<75Cs|hMG)>gWPW V@xOsX Ґ.H-pc K_Qjl@E]<Bcn?ACq$J4Q7wP&I_W&Ί HV ~“c a @?U{$5|u4A87X"}&/&S퀾j -7x;LJ*Ke8[NtC60֕5Ӷ|E+C}n-iO=)l^iwI?nlgvBw1h 4A瞓I5fd@vC1>{ % WbеrC6TaǏov=a^6o؊?9 ΈYgEc5^F6<#Us< 9kOZE̷V*{.pm4[ZhEqgʺL~l&ɟŸ${K5{u'+ W;q#Fp2 b2?Џ^?!L$f ]ruq/J%G||$jwO\ũAW^:HCi֎f٬ȋoA [}?cv9nuؕl;O2&W6 J >QvLNu3OO=\޵{;At9|bb.wy馛||lg0ޜ C~iL-hZ)Y`LG[YYg0/N^ŋ_}Ġy'Gz;vJ_19i|||eժD &:OM n77& Z\uU3j88ONp@}7,јroŁI+@ `&1\hI pI{v^?# ^Ǣ K_P` R04}7ʠ!z?.׃}5:rc AU۫cPVoJ"MnU&j_U7($SKiakA7BD 6o+&HOt΄kԃ?_lkR%ut8_+vI}mMN*oWP.ak&[IS9ʄf-nԪ?1+^Ե ycZ7?MKZOr{D/dRuVsrYgGV9|jg5c-`zjIjV&`T2exx7i/}l sVϗZa pF]|Gx]圦y^i=!?8`}ZaBTRHԔ].X](ip /~mw꩐1}s蘪)M<*++Ok X!?VX_zVIV怷RcBd_y4mJ.E@PCPgy"ְlaY0g5a_ֲÄ0mR~Y8D P6owjB6'0򊿻=- @*9znOTE%Z=PYh4 +R#kkeV`Gm뮻l%m|S M̖{׺۴tC\2րkbb.qc܌I]>ryX~ r.xR:0>*I5[~ֈ!6 1Eeŏ$#Ӻ~4X)mbNWdזoc#&U?UGH+}(-VYs=9hqե)~F0Z/Y7lhz1Z AIG| )z_>V}g,p˜/h@!^  `a/_QQ}ilF'@j X ui2c-kvKC% hJ30C{wAd~ww@{Uph/G!ɟozc0*[pY7Qb{笊L@80"*e P=N`UR%:nXd(M- LP;G3]ͣ.!5 w_勁XQQ>Gj' 7 T~Txp0`@Jn_y?t#€0䇌 9\d'Ҏ2hd^}x2&x8E7Ѕ$Oⱝ!OK+ce033WɞJ)X=)}xvw\%*EPj .$ر Ad#2Ae1"ݱ.Q>qoC iߗ#r,aQхh<,qe!R?[‡q2W9R+"D^h"B"C"ZStV|ϧ'W8џ\r),Bzo^$O"|! eF2#2jbfz ?VjSۧzVGHxk,EZʅ×^E@[ Jΐw5ۼEB/58X\F00Q۵kYTv:]7QU~+OKBQ9 2Z'#@̄=kA";jm65_@Ew/;S8*Ksƈ1S<`+|iG˗v_WS^s/ dif+}k.fkÅSjw@o1yNJ9skr pyں|宙Vv˥qv6[$|/h6ryˆl2}HOw+T^WƦ(Ú3h1dUYYi[zAQ@;0x?l p#GIB K&?ÊuoeG]OBE!/##蓱ZO={z BL›u󗣏>J)|%2(tPTAhmenցF AF FDo7 ӅN<T-ƚ, ?c ByS@Qo[ jRg*=%4:fj׉q}1Cjvu£˰co^  b3ʌ<#rԔXǥLzx ~{V s#>s***́j6s?K6:}(U ڂ T.aüy5%_9*$j4I[@.kaޫ1{On|)œ&glSu*^xфMhh&hl]ƞ{6Գ\p VT0W^{vD.B >0驖9M* XeJ B+.q1iWM:^+ ,UQr"8^coյKS^rd{C&TkzC>0<8 ٳMR5הO|d-T;:7_}HBw%Q\3{b}QzQ89w衇f(bp>1TGQ[ 5ߖgiE.tµ3RIŭib+B#GY^SrfZp} s. C }mϗI{%7.*lk QhV`ܚj5;-_;BSW`RU,ր65hXUf{i1 @,Mo?O 塗 {39C m*$7͟c*t^?y?|} W`J~oTG6 RZgKu.Ҧh3D|!׿nۿm雹-R~캇M[6QY[L.P̻jN-5>ߺAF?9$Qn9+O7gt?a;^Cu4x&iW:RxtPa;]aX,]9`\rF횲C2a}k$s6hcǚfkN<ppr(m |^yWЀJ ${e*?eD# `i$CQ Hi |㦍{kteiaѐ#C G 9o4Dbf{ؗsr!_F e;x "@8GU}?&+ؙ8vQ1O/ $Sz)'L {ٺU'l^s M*N=(ue\;^ovd~}!7C~(vȪ1hl}83_B6_-]lbxTZ(evn#ǨpQg 7TukTxp0*D섐6^<@D-l@.y0:aI (U7wһ>+\!$tCk@^BZ y.dV  ѧaDe4rAӂ ճ[h5ݲD=!(=0oQN΋?:nD_7#Hgi{!@% vD$]`ih"^!rܔ*B1l:K 0)ΦH53,mi<["  -~gS, ̿4|6"^38(7C¦&Z4iWw֙r8F Z M@oUݪ8ԯr a_8b,:N# x%u&48G}8#aB{&  G 7gޱ9_qe1A-O@:)C5Fe&!Pk__5X]fHʰ( >t͞NpH;LK˪;GNnSb7r-2ׯ_8S[Zn89B_[A}[c{@4pI&U"r-Gm6\Nrx_i4!@0ik]ա1 h~h#ޚ#>on|RA\  VS/`#%w6-f.w:ʼC4F*'~FPkgAcBz6BSP>j67xp, 0L)j*fY|&גO%V~چJ!Y*ŁΉ¸hP5]!ǵ =@q a{ YHC{Be/ u\_ygyHpkMLXЙ%Z˄O [+1NOyVUMx P|^jz}ݺmkG{~Ҙ}!1~%ik׃Lb J*++yg+LҾAsLzMע5My*ik3HGQR Q:{°!I`[c8q"gDie#hN; n_Qم07N9w]w4 /z+[y?Xqj+!iumc[.i-RnH7!ODv"Kr|m2cZA].ӸVONFWdU p }"ȫ0]`) Q3­BӞd,fo/eC<mH||4B%lH+Dn,lҞ PW[ܽ)K$ 2;D3o FVؘ7h{y>kt>}#qJgLu{Lk&)Gq>3ޟs+MArG<-IJ-:S* <80IR8tg?{}ksܑh,[~]vCʵtebtl@T`\%*;k;jh%f)I%zֻ}VZ+$:߿Z֖hT׋L+ܾ>;OGB0M/d|PfW4&гDs)SvPIn辆~n7m4R/NS1C;vt^oXNx [4O|(a\1QL ~kR^Voۄa-ž hfr_TN9r_8]"dv?~];m@؂!j?m Od^C%, Kg I[\ǽN{ 5@NLzp@:p=Ff*w~OHDZlQ($(M8:_A[6'ޕ7iPe0 OK7[0!_GV)rԇ>&Nh^pΪr.s`K/W]{1gxڐhy kųml K+`N0,kuqV]ykY\h"ՂDPTĮXPM,Dc4FM&6M&M6u1ŀ(*(" ^2 [3gi̙3'{&W`T@IDATӺeW"tdf믻׮[*&gyyƈrb튈z`4@>H \%a(Uַ%y(HcQk'=IMLy>~5 (bZ80(Jg/EaяYh.%yϓd@FU Vvg/Ά - |Ɔ2,wSLZ0^{`>%='7 kInWƷmP#Y(0ٍ3F2K:xfA| ~zqE1A EmK'}kځD].^>JRi~_U.FnxӶ^ Z%t5A;`w=g}舻}c[% ںjNꯓ5l^_{G?;{Ybםí>>oA6S&M`.@2 ;=$jN$Q_:hŸ'j iWefD1[hm7[`jq}ꃫ" DC/,%Bސ#{՗ j&HҞd] lݛ؟ a嬍-$ -Mf08nmD=GZGC i`:H'ߺacXf`2*DOqi@>%vXon<d LqzsaC<͆I+ŭrPzVn#tO#amOuJ<0B-I^6pCuuָǰXgxO<{4LfEʮb"B ΑBAxP?,&jz{;HTzٌnù&wO(5εX+",PsHy)^ knGIABFDt %$yS]H6oDފ32z).η˄nιrL4$ F` ~v!ɷ|Kz'H'{U|8ϋ#"[~IgG"4b~,GK1B*4~ 0.]a<"2.D* *|@ m; ]r9;LPX-/0 hnI&򹛿gaYcmG_7^ ̜񿡕 O6?d%foU@e] ѽ ;#}gd0}{˶9dma1@}% ?a{$yF3ìb7Ș(#aRٴS+{i>eQ by1&RnZ!1ةc~yrOqyN ?nO~kŶ!-?,C5k = ψ5}Dgqmd{-VDo+b]ήm{wՒ n?`$G?Àt0_sLk_UbWN0M:oij15A8*gQoT H&F>L̒ݸ@Vb q G}Y1tw}\O /fV{TQk`r{Z7r6p{!PN&MPL\ۡ)&l y L'Dl`$d$(0o~ӡ ivI+qv _t]}?o V(Bջ1j@1}`ŞG_;{}WS н['E>EWCu\S^iA9 Ƭ^t?DNI)ƪxjo!#fϞ e/_8r:E\1>\ _}1l .F?V?܌YJxoQz߅ \;_xpa!X);ޭBP$_` rYBÉgbG?mӱNK5rhW~>\cPгgf7K2-L.[I?4 O"- Z̷5*h[?5B̏lϛQZv ,BO2øIInrIq,|O\N#ʑ\Dx`Y甭nYR}>Ow@#+L:3 0MX3cMݾ_ҋzpwUM;켾j3VVG` O\+sYs'bDjk0qK?zF=XG_XO﨣D2g09;J6cv$11{7;O)'l'ƅL0k3J F_%1)}&k) %| GFD?i7a'\!P7.'Yvwźuk+x=^ q(OM,o34;f.pfϘm~xVNg> ôc)L eiETLj`4!wXrolp6f윕edf7RKc0qٓn640z&Jk08KSȴP8nPi. /8-lf}ֽ5iI4SL`T 3)JOUhXL5a|~C 6zĺU@O>ݻh#LX R[[lX,L[n)LKa`0<`e S/Yc-ǿRC$F3tݨz?5~ #[lvLoax. /. a騘 :(x]`IcK}޽$` C TWԗ"85bwq3f_36 wM6Q7xcgؿyPfRH+1o?7[gk=M@q+觕Hϸ }D\ٟ_C,?F8zU ^|EO$ms'#t]=@8qͳ&ft8>$F ÒPᏄ 3lTYШ50_='C@BʍVba-ڲ^ֲ$̆Phk5^UFʧ^)1`75|= !AgCkgL4OaeAXK7)HkPkhu6 KaG^Og X\>=c3h[zI$ܬcJ#=ߞw YN)f]]n&#S Y+R}焻fF_)rT}<>w܊( dlaP: ȑ⦕Rt}QwErvH̍6w~*C;h_Gw떅IҫP+?GAyo[k`>"ON"Me%;%sY׽Gw1a3dKm^M~3:0ٓLK#4 g`v3C\$a2@@\O؋o>,uc|ڶOb +Yi"T%*4qQ-_Cj[ ioY'>wO ;tO80|>0\1L!"B4°Oƌ oJq@az$P6@0*.P"3ޜE[n{{)m3̆v"r=#HpHϾV_55~w _URm\N1v+&X 'F'  SE+~0ސ{S:LW{@+dGD l8+*ɡ,btbAO;~ISLU~"^*RpSEUHx_F$a 尷B$3V !v zrGf_M,`]mF@80@Q(|?i6Q_Xj>utݶr"qm,rUI-* /GRfDUWޣ`b  8v²V%42vha 8Qοn_">s;؋֢>}K}/! ˧7ưCsdZФNb ~,,? W1 )&|K S* Ӊ=H:aE@kI9L#aw؟g+psF0`a8o s4{?~UZBmKS,UB xr]ivRͮ-~ lޫݥ" h-hBL؎]4|+(\_ BVۿ"}*c];Y͏E{U(XjW%F@>~Iwz 6}I'f$}$Ǭ/6 "qO`6}!Q&_JN\I6c1b0o6zŤمs}V:"qnl9I %6h'V}q]z;$a-+?BP.D [Pl]hDhs0eX@"OhzP@t7_`eL 3~>r e-J#L`X0ȡ.oNĚq93\j9D9f.0}2Y/4-3>5CP")?4o6\ؗ8;&<-|ְ= 1㷶{ysIX3qZq$4(`{.5O10 ?w1PץHB AJ ׋9[QVf'8Qk;r ڱYL&re].N^E,w_w׻QF_#B=zknk_rm_IwF^fր6 'YIS;~psugӦPODQwWkφ%_|R0L!_2DDˏ H13nOI]~ W F~?WʝnctO"_8B&Z[ c*a{ NHac|jIvnvtAERufijf1x0$Ng0$in嚖1,I~ T JVCMHk(G5#O]_9 i!6Y:[\is lfnfeZfZ8=:voA9J`]mCiJ6Pg(1 ISjA"{Rp`3x ,iRD/ ̄SN93QOxɄCX Jgk'w_5Y4Fmz]wi_([@D_k[@/iS.n% #%1~ n0NLwɻKuiN;m1#[@$ ?FuY/sR!;ɜoBL_3},ܸG G^/"/Ř GvB#̓_ʹl&f4 Û[00~&Lmfc1 Iz-^"_ ݀L'q=W9(}a"ZP(?[p+vEؤ4H#1|NKթ]W)x>Qz^ YNA$ Ɓ - 4LbE:Dbp[…@i>FgN2G}W oF;i#)'vud@2U٪P5695f@GY>ֵ~o[rLs;ꨣ?;?P7}qÈ#ı$[XW2){)r}IcoJ2BIQ˟5n(j?҅‹ 7%Pkv7ZxSdG=p v6 W~0[>tGonap=W\dkL ? X GAxnPeTΣ@=1;3OƭmvP> Z͒ -ofx$ #Lp[3-~r0sOg!W^C- ߳g$ʁBⲁ,\afA͂w UX3p1` @&r?:?n7(MTu2_w鶂a\zɁ΍ rTn!5qV3{ލo2ii̵O=[ wwPH\F$P^8dn1jv@zKq(Y;J_~e2 ճC}P'˽)GK2bV*Jp[aүژoBC9 ςcٌ4tdmt 0!|/ȽuM_Mm,MR-vl󙛖pʼnOl0$7'~c:OeK1 I@L ΃j;CS1xv}>3?(`g!jLNf>LʕF\P?~Ε.SG6KfL 0RR+of S1B$C5sj*vXxv &- kHV@<|3\H2p 뢋ܐK/qۊQv]k~ƛ`fqkax|A9XCߣOb汲tEG#Y1 ̎G{ktPN8U@?b |g;q}0Yg €80,B7 b|a:X3☛ h˴")#4C{=JMyuSY@[Gl|SsKފmI]@6;uAoc!.;묳ܑG33c҄+߻f7GݰvkU*rTn5FDgLwӥln-ҏ6N?t>xF}ѐ>vI JY#Y~0S+K_3W曅k055џb,C.¬&٪X50Q=,A8SWGɏEFw!+MIʦ,G ?>i%ذp5,̎i0͞ 5s [3 $ms7|f77;u2΅bH>߬RⴄU $)QV+t_WzwЬ*A3 cX\3 oдtB7_%0mIsh -=3<2 ̔mqʹ8700Zʮ_ft/&|C# kMn#D5͕=9DΝb1*wo⾱c# ),*߾o?vOvA]: v:dnv.1n16e$F)5p?ya oJⷿ?C?9R:yP7mKvQGhnϔWDtqzQWꭷܻlM[Uٿ*dc+)z_ N3$Pi½BP:0,M G U`ң 6@N,i)ٳaX SiacZ\ keg[lmq V-Ŭ2*%pj=;zրͤf'L_dťʼn `>lG$[XBa-f i tqRI/SbҴ#%/P P*@U wRG]vg 'rj8Hp^Y0`5HFRiF?@^| a\@"!u#:^|Ew]wI&y&XPbO]r *iyXfմZH֩ ܌1ϸ%MOGꫯ 5撖ԥOv,qC1$ _~S24/ "G#Бvc@x߄#ʤ ׅ bz9/ Y\`wYMIڅ<01^>$ܼ9~cCމ`n&xݒdnؓ0Iu}Rrȓx!:֢U@:_s+WfAlN@Ƞ+O40sT%YxL$dyX\s؄aЩ.LH״Z\63~%\̿n] ,"K9ΑsO2/( } ΕYĞBo_y4`ZaGh?c{_zA˪^97GܴFjqcRH:ӎNp.JHq@oUƍǔxv 2M-em>#vIEDZK)xWЫg VkvXa2ㄟrŸ h) e ߅o waa])iw^.W7d%,\<>ZXy0sgW.v1)Դ ϭ?_4s=O{N"nCI{k#=68MX-OY7?uR+ qvG>`⿥c ;\9\#~J DFDb"^,)&??To)}Mc;/Ϝ2q 34y~Œ܉,Uh^VB>9BzNk͂݀wc`I}޻֜FWܬl}^+#xuC܇-~?[8L,a c?$[sv cklJ# 7*6sy-Znhl\z777߰.KGlotv$)n3rLap33W?dzg3} .c iBo$b;[X?އ3(bzi/,t+ Ih 0Pg1M ɖ4'w$:S_"yH0~ ew/?H15 "J0IdfM*ۨ"VjC%K_{='e+TIxpF-`53Ų\'|^0>/ )6*;o '9h~֬]#`[]> s,}ޞ3KJ 3+Vi77[`#@t5"S#BPʆّ7=!_/%iF߇ ۓNc0$lRH'~bJrݒ-3s13 md@͟g3nIPWWHVr ےs ˖DpS%i'l@Sjح Goɵɞ ,Hbߒ+ /B4X[N?O=1DzRnًgeUSs3L[E͞׿O1ڭ֙4S,/R@PW!Fc> #[tYRӦL!0P\,\!o6>)јpvOҭj %4#57Q>ݧq)1 WE?;}W /B`fH+Y(5>Ax1ppP]*A'F[/eР=.Q!YiCq0 Ú[lښ9 ǍlnfܓLK3/v#cX 0GÖ`V«d 7Űo8nQ߻-O2IC{f6 1nn!wc3LYB׋3b*/K8q>).;JȻ+l*P(`.?`orE*]cC֮Ǹ݀q[x!nqTi}#H AO26$oy x†Bt!@K7) '=PwtfB*m1y>} <^ na?.ݪqүyև|ҽy&@ڹr5331LflIL3[`ZMŤq"$w}ӟ^~c{ 18okZn?\Jҫr-\nv| BDv=FB'R9sNBfX2@NM0hu [nnCa{ \zU>5-㕭4liv=$|{fƦ39v7|&qB&hXO%ͬI)GU@>Zt:"kWI؏jo$4ґ0IEH8ORKq#Mt438Vd@ 0L+[z/R䛔$/Аw?iMZx5~4kMfPZg~9 }3O\jd`vk/f^b%t0|v7%Lk~If?ؓ3-X ^&vQWZqk1Y\HͱBe;Ԝgqڴv=yu#e/.Nu'Mqt~n&kVK?@ʴWU 0ؕDzHvvܐz t#O_~xv8".c;رcwޗh7LP1M1wtKfig=nnX{iXhH *.1mv-08F]l:~'ꎱ>I10N7R89 ltbƕk sGJ h@^zz+Ĝ6]'T'!pP/O\ƭv"( я9CpB U;sXfZ|ՏoyXq ߶4;qBpIa,YB,3c 5I0i0J#@oO}4EzU@ejQ-Zqo^U fƝ"@v+0N˞}LsO2-|Bp[h?lӋz0-M{Ks.[ ./ b)g &bFoOw?ڬaQV۵s>w]'Nv?,Fn鐽\@t@>--֞K~  pvι /ebR- W }ꩧ<r1z+n!^:p(6+ Dx߇wܩe B?;s)oE_͛W6 !5N,n?Wfƫ rgwn?{'ɍ%ZC+O>q1:[+C}8y~BcBne2ӑ,-Cfem`Xc02ޑP4^vv|I,>pwj?'ˉ.@g tLS_%7٭VI\ᩏƐ\{[h!24V~6 6çIAu2rfƵma\vK+4-,=ǞLs&oi@nq²0xN^+1m:h%ZsuLڀvwyd4M nM +rF?'.w}pQXY 0g}y}tQ\_ϖ{nwEsg՟Tk][6}3/q[`oBɞ L;nXb }]r{`/>}1 Cn7j(Ϙ ڪWƫU _JMVA[R+q1X-US;;ʺ;N{3b{ ^&,4ղ7`bFA# ?/ OJW]-f}/n:-B*יml mF9$!g<3%[0${866yX̤a^ă`tPWi{` ! U@?߽,{oihfb؟ :9pv`glP9숡n(RQޖ~ pq>sLE Zt1M%y0 6"mnl|aP6:fcSNv)ĿNӦ]{ڵ}qnч:M+HY[]ƸNӧxug*>Ϫ;޴ph* fI<]8B "M;Hgi嬩R22PT>"T+ŸX믿6}])}>]}}aœCߤrk@m]/K$['kt3EQ~QGN;Ki ɟy9c4GR )f%k #ksbygy&QG Kq1TQB7S}'(yQ5&= 駻 P~2GNXƫejrBv d?ũS#T8O _ΕY:962kw+f#t…%Ga 僿]at Y>+seq PMp筟? DlmL=c` y]4FPo"c.3Y٬#ٳ/)/),7X~~lfO=ni<ǫ[:~>3mb&_ލĴgHΥt3'@IDATN{CB$ֻUz% H>W]QϺv/⿽Ɋ&>A!0P܇~$ !7i%v8 ?G+k+뮻܇ A9 \%/|g{+\OtCuMWARwSRUTm+JGL&Y< @"E΋BF훶P'8wN<6%_6M'] 0nݓ.fʣ:y:!\*TCњ>'|xa-G&Eȗa\Zg-M9BiCoT_]ί韛=JɌ~"@/U8\gү:t d Ӵ2CM҆H `ݯPe5ϭ;hym!Iv@1XH)dY؍!N?fhfxl63|GkH,%Jɣrh_0rH7H0hϩm)驹v{bS?Zcط3Nv<ԭKp`MJBj=(-#[o?{[޿g*N`"]ȭAk ?eF&@1M9Cƭ/_KWP «sjߊs+"g}CO;X30`qJ0ُP?o8?%Շ? ?~:JBB^be=4.K5n]Y(շ AoF~AȮm`_B<(|G /¤BB`c65Т`Ձ Ira1un/a~03ϙln63[za744д0K gf0f4)Ӆ*PW:f[v hĶ࠳+!f<b.uvYoYx.„mp ?'߁0'gd?R}3%jViz# e%!j=?ڴv;?ku? aby4ql7N/f9lz+^[F;zJo]n^q}~u[|n'V>Mv; ss"}ǔ)S<#\wdWWO&hC2o~5׸c=_D3n ˴MUt4N?wB5vB[iy;7Gv_uu$+2RAsLK/u'ON<Ж,}vDb意R KaWc40LRFs5eL/ώ?}e,Nb~ENj!7T|{UlRګSb<z,j+Lk_~]8HIXƫX\7Jx0ipG G fA.ٚ8Kyf Ҟ.3J/@,R^Uo -NiWSG,/vKr.Wп;X^̴w$ʃ_h癱O*[( b %v@WT~t?,S 䍆J㖧t4 O޹gK2s3K4MX>< T \lp-5otꩧzYoЙE}_7縣_>uGຍ(] oɗ]>z-[g܀:OE8,/VR desĝKS6g!$ߕAƘ v$Vs fMa'?{^"w} Ir*iK+nt 8Tez*;yo14|vء?M7]7j;-` (3%6ʛbjk~!?9G + 7|n Ѵwˋ# cƌ6&I4-@i|Nfw߷,\C(;"&'a79(VQ6͡=R~2+|IE`}edvx7ofa xF8n1 0NhÇf7$Ѝ8 ִ!fp- }1tl%р@E a]v\7ЃoL4^qmxiKnnv,]c]u:6mk٧ndAW-EDzv a'ednBذX }#cT@L0ʉ$ G}ԋj'E> ;r3Y}/v9ǵ׽UF@ Fÿ&XL|n^| a@R6ؽ-rI9h>,̟0Q31 GsL?@MM>Ӵi#>7ngӕOr~|,rˌA`K@¥+_Ƥ${“TREJ;e 9sCֳvk (Xd\ּTVVi#ky)nY'Q ֢ecҺZj$^Z`e4|-r[s7*þCKW}?x\-*hְ -0{+uZ?abb`pAңLff2XЎ[᳅79t [ IiY^60X:&a:~7*%~Jɣe;[(Y駟Py)];Sdkê]{m>]괻6p>[nn}$/,Sim-wo$mh-|<͵].=zZA2}1NDaص0Ϳ%!}6 a:03;c_җý4K/vV̛_b<+1Ǹ^?  -$>c1n;-cQ (;A<T 9u>u*.j~In$x? ܜjN,|[7B@& BUjFe'11lkuMM/-&eAawyJ&x ̂ݯ51` 4BX61:܈n%ea9paViiZfͽ\ҳu~Gsu@%CZ, *ʄm#cpMMMbc Kɟ& f|6̖^ 4hIzaOC473-=K1͍0fMVf`zCszF@wpaF%1X~#<+c6q|Tgۊh`'M:D@;1M"b?q2ĿQ4w}w|CJc[ag7Ϲ%p}xu?Vz>Nygs_'/`g[kCm;dgLwwЊ)4uф|䇊>lVvhXDݤ{u3!6H9 }E #30@=A|_V>@JQ9￿hCR_.=ԭչ1n^xYn%NzX㲾*1|&r6餪[MM;3܈#|tH`%|va:O8m0(-Xw8Aktlh}Ί:0`sSfr1Lo1(vɣ +};Qx1"B!D?_ґIr0DqFcxE{3kJ[Xg,Y3T[¹$Cn<&0]si}5w  (\Pde`e}y:hpby qXP/,-M:VΕⒷ1d, 5wgI- ߍ&pwd/@iG6ɷe=Hnsl,h<餓}+6:_e7︑^FITOv3f^|>7oe_^Oҕ,5>ky$%٣Rap_~AȎ{ahwB?.\* yc{ 3qf\;'|V8Ygc󗕍psFcڸYog<']잧%yYfں4|f6^ɑ&^D!|&Hfl N,piְ1g ;{V,tYؓ ls!;ל$-܉gfl9K7B7-?cqZ׻>$jKTTOzCZh=IbZ8o~Z }7KD]N3^||~R|E)ŵ_~^[<>ϭyGa"R ZP\cnE?\3XdB:9穹5cv:}Kr~#!4D"6F功)UW)L>hw]w^{YieRru骻o|>__~$̎ߒݩ"X_>ĿVWmnȑ;[{_Ls$H!o0PPdU)vy|`[AmXl 媔6bNANh\-NF\QuM.Bj}M9F:;&@%__Ž.}(Vi6~ǍjWDW^麋JQZs?^*}i; B;[6%X_1I%+F@(eWd6#XsbP/1=SMT-rq>T/I0@'lj^>%d|p0.z,wG1"p[:x/;wJu׻]zFinixޮط]y/FT{ m֭컫۠G6ꡮ6$ K]]V%C@VLba {~7\ac Rs%}9h~8j~ꩧC=r3"2N> w\GnQj%%2[o[s앆=Ksy~!!BIMѧ~_~e2@n`v&L05 {лYQ0;#@1K,DL WȐ| U(DN.GQ (ɪ垫@X9KŞ'0Vu|7\DڸQ_zgC^`5n6͇xLo>74{^N>{Sx<|0S,0v$Ӂ\ EEWEmAZ77~!`n3kֈR`eVM#7iR: b+s%11yB c`-=cN,,-GůO\̭b¶0l ;;h۹I#;|kn^rdx}6䂳ܒ}qO_uh~©Jrמnn@i`=( R$YA&^Ou{CilK]9ǏpiLߪ7c=D:LD1t/a.7s)0ȋv@e"/ ?+ =zWVwUKwtn]IezٗG )so\UP;GBJkJN8 =_ 3kmGsk88,$1c s$1^W:j31AF /$D_ JȚG @ d\!`&='|Rp9r pfvqo>c!aS9vx 1дq:7Hy'|6|na&+[-N:0O,@-2Mo2FTZc5w׀=^n>>;e;$f`6(P' -<ݿ|ḛ̡=_nRx+?~/&b!&񣁛6r=֖NJo^Efg{Ju)+\5ݾko93݊~Aܷq/-8f:anyzeGJ-O(J~L5JZi3u}o+S6.RauQk"':η]):󷮋ĆP;|^?"6v2 *i!.FtI*6~]e}]1qmRJCԾ\jNĽtCEGw(vurapAh#׈DLvŴ$0'r|ңc7= -?gvb,RbpI65s9mP|n3A݂F± ,B5&_!OX4!Vj~aY%tdmRH"L(|G!TE(ƒzl6δ9~0C{&|Ⱕ>fXN慽XZxY̦h/ݍE0ުP\ cи,4H!$XX[Q?5{FS:IX>S.ҌMua3g M[:aXcqFnl@xO-&ĬE[@QO6m9?tE:vx8Z굕vVj_ f7Gw7kuA̋HW\- m$ڿmon7Ɖu=fp箮Eͺnv]݂#u fk15uk zOjk~vbCZ!zP?}Nߎv#\fei~8m?яKѿb6[l)H{nUW^^]S"XnzھʩAؤS Z׉ʲN4p-nZs600hcuH xs?GK֙wb1(Fݱ" %I-Ԏ[ ijn;Rmg F%Bvx57BvluȒf݄ڙm̪(CpY) vh) s  g͍=16{o;P~CFO38aZp}YK2-=4lmfaJlt^{6w2B)X;ίҁhИ  Yvܖ3xu"Ht:u؞ԹXl<׎FOl'=ig.0\NI@\X\igˊ}'{e,Kܾ{ Ѷ=Ӽ7f`VDq ψҦ>[߯k> Z7C$PC]:Ξڬeȴ}{@_@|~-p=}6)**)ܢp $B[I"f%[! 8;0PZ߲~Tn0FC&$7pq!c!I$y裏Fg7W^{}wstun"zѤA:md5"R?0ՆkE?c3n%J['N?ty]̷Vn=6QJDc2ĝc {O^2;il6!0 RxF,213.$?!EJ[u)BC_>y%)L=g _k  0q- ӌӱ|,f m,@ׄU5.Ƚ|FP3N噝9ݤ%Ávue *0ca{J%ƈk`lЌg4-ի= u ;@qa|~x컕Z',bݾ#tm -rݔ!mrZ1vrfui嶛[.+b)&R.nރݢy=ƎwwVI`oЃgpm$NyOq\wǺΓ.:蠡J@B%GZ@@Za{スĉT6aoe agFx<)>|{ @^gM>!9'ݛoWs C\'w$1!F}r\7$g}3=*L^PoΧ]ctnK70{oi^AA?8ߏbIPL#gdi;Z|0M}7pOIgmFle9Oxp9VFz83_Oư~EJ bG: [*0^0z)V,!Sfˮ-}j#-lӜ?Os>;qplqrglZZnLs/$~:h5#*CU4E) iY{ݘ&@Wz"Q ̏hr̴H#pQ m uf/, zw|L(Y>F;X* 0J>V!8Wή&uR`~VbJ#Ӣz>]e+\QO q镨3Ovǭu6|): }G?75mOV ft[6:,veT)[|b$hGY |A9U~|W#}[اɛa 9rva@&xi7)oc9_8^"^3hJ}x|Kc[ 9Vv:Fzj'V߷xH9 F  FeZa8c;ny\)s`4F9t 7%EtyRwbH/Lp+tǽBlS&¿ SI_ &i)wv˜aafmn+eq̒ [Jo8IKw\Տ7ncnrgab֭u iڛC00N{63Wt 얖5$m eJ+l -t])-H !Ap[Ev?R3`,~bl, MKߗC}fͪ/)bi{ s'8"F2e8=^^.k)1҈Fs)_r$8<6o[:]?Lnk\'GF2<1fa @H36m&MotiC&% А){e 6`Os;Տ$'[G:ݿ~{ XkݶllЎ O{F V;bX!}ٚKgZvDlݸN'ߢ%睥ԩ?)Z:z'&3v9B18rK1$c/KUW]wkCe^.İEQ檟'¿訏گ++vNS rL2  s۪P"z]dYppԚLGSL)qKBSϝ5spJ3 ӉrA=pl bwJ\Wi͙~ E =$;}ZE`G[ yLR+5qs@*"}<WjtʕE)n`"xߣ\c1kU;%Ư@yZ'oÞm^Mo+Fzi@b?U eu:NATA_ f0I7 l>tt)Ez?(-$u<ژc0!aܵ!_d9Chw5fgqO9mΜ9!/>eԾ±; GE8s4tfnk( P. ӶH`Ps7c1ƲT.yP}]1~!~?q狄W /Ku>'|>CvH`-^8QMlK9Rk!6O hHaa{|l|-(yLϸH힮?7gz~I$8%_-@^yu!_(,t:"&=1cRA`m rx,, E{)Ipa60z[ @:ԅA,{v9, /RPϚ5x.5_ &˗]gv$k/222}xF~:V|öi6_9J\e}?N!IP'Ƀ&>uV*cm:mو'fFzRyn-G``Ѯ dXhn4`מqz&Wy~€,![ 1ȵ > ;ξc"إ =w} U>y]pd7j"(ƻY;cj#$Zod*oڦ mp]);e'O 0o@xp>Y³ӄBVH;06J{䫀WNkmP/]1e )vhc:\SO%w <_7~<'a{q7/_>3}3γvaW?dYy456&SFb}QJ$`1gG39iO2N Lt8ƻu|4U UOh$\p 6@)Sk5?ի*%(F˯dbq/8fG@ˆ484Z6jQn]u>aR[Sw"G:AJ5;|xiU>ʆ?[XzZڐ瞳Sߴ5i{Xےua5~G? ^oa{H A׈576ph]fm=K47]ӆ f{ -a1{ߗr'4omӼ ?-dGڷ #\Ț 9c&Ÿ5ׅ({Kx>A{#%$IQ){V3aOcN=qn>6ݏܓfzLc|-[9ކ^IC@mĀA]L`;0!]*C۳e{l&b0AA hz/{\GL?ݎagO \2 oy(ǔ Ӡ tKZ|uB Ƹ{4J/}rv `9h&2~6gj7TJ{Oo8kz8>QA \6G<0m̳m1UR>XaA?n6PQn xz9[r1MQ5uwœzc1ۚgo|4@2`qc_{Xa:n(!mP2Ǐ Pz?Q/˧><þvhQ|sw}ooߵ׷jx](3leu;&@|wCyLxZ/KQTJ?JYqp9XSuN1Ǔ|L{SWy6Af}i8֑+xآ|g}tIO<8kyxt.pk=w&Pmz'eoc8sq?3Eħ>;2u:pǰ+{}Ck5n'ϐhMShۓU*@CI,W$=;Z &\!LY)d}fR"àppNa&)9K7 :Kb0SN>]#ɔ=X!Ϳָ鵂QH3'i|qw{8)q.fnI/t ^@r,c 3-b xF% DQmM[&;q^yf rMO.ޤ,+# 'kwtRlےD \vea64>Z!)E;z+͕8ޑ]mOpE]V)΁#;MUJCOX7}lfn) $~&׿ xs_EG[B'NK͆<~6ym:}@;Y&n[&Nz+o'/vn `؍})qk{ t 70Th? EUUUA:hM-3ev~a^:i?fg7r> nW;n}W2)|m" ;_4L)b@7W/&k:~y$_~IP@^ D"91?JgK3g +C ԨM] 3\qzGx#j?do3bSp}fz~+&qf2c8I=Fk=dxǤO cOdK :ٛcañ@tXs ʁls;^B>hIH.kz8a `ld CxMBQһ T! \# >u' R*Bx2po(BC>>?C'l>RwԯN_wP@Mua{2m)A HYKueNa}E]xMWY 0pumUէK6_ iӦ5`x77h_vٵv1!< G" _]r%&W)G%R >P8s 2?2_\>35z>v뭷6$?lp?w>ms| 5{Cf?wK.ґhQ8YL*[̜WOh_ù¿=:E>(eXPqeBؽR e|o "υO7g s f"v$ ]gMTE Ih)| :?=$}5f}S;udg懰~#_z]KVgdN,]I`wb3K ŭ5JB!S G1hBjڧw J"|X Z;20n ӆͿ--Bӿ־To3fϙe )4=Mw즻[ķP yP+`CVQE){& Z8Tbnd8.6 xtHS0%.6kdk8^kG!4 vfqNK'rR.=MhCv?W7\xGʲ6̸vguݻf'$z]/I`WHvܾsVs°Tqv/J9e%&qVUU&(C?>wFLfz >aZ6 W2QN dX^{͙3^}pĄ>\˖kxO9唠g5$sM?؀1^2H q|HaPnIO>bЙ;l~ZOձg|:xO}n#4/>昔b$k0T}{hJM$Onj@!t1mY E%{ _&2d>Bb4c/ nfX#OZ_AD+*w:L6|𽗧k0Gq3N%7 1z>IcI5w{(xR3avkt0 >@';nGRa& 'ޟU\^>،g/7K:@8N`.I?/`x5f&͎~ ťxK4,JwS„ 3$0RNä m+GB&uhCkZt.?՗^jcv{ՎQ,Qp_mql:/3'l̝gWg{FcEVncz z3j>D :gOB |xޤ ptuu]tE!NR މ~ |+8>O8qi1![?2O!:TFڃ:Q UogN$;-0o]}25V~>j{uc$bTfpĐzPUi~J8S8LR_S׼)Y!Q.K*|N\xH-ja>|(8)I2oпnkҟTƠ9e*T>q4e3 er3v{Ϟ?7gzX7}o$~g,6P$Y. yݤ#bO +ܓw| d!‚ z3u |&qxtٵs{=u.0 gp鿐V@b%gB-3]nOӁIbO |(ʃb<1> {˭G֤OߠGDC 7I'[}! /_R2#2" }%نb.{yWЍLN`m}KB`՗w7nX elTLw,)+_- _Uye"3s١]صKlmҚ|ȃݦaЇ>o¼y±aQI=!L =ɏoI3äsӧO:B6Gw+馛B='a_Ԭ¿;Wg"@QA͜qA10(qAX҃3uAS|o`Ba 'aOKNd !@^e@bFik{0-`Ti <}宻j<ֵΘ:^J>1==dMpLkK6bh?OۮݵX'O9͑jp;zzUR -q#pj!;_FVP~7 _X0y"qB$2`-0|yJ)33 & pUB`5]07^>y8IJMc[e/s)^O#9)i:|C9۩dRUv̖js=l8ˏa=dpq3`T× d(,h >L{nó(sqb\ fkR?I {^nqC8Z7YOMĞ@pO_. TϮ~+_i5̑p"T;JdU7 7[eIS@>&YGCq~~AVHb|mݬhɧ̆yQ.cu}m;yjeٲBb)@q, >3--C s 1`26x7(~% @ 7I! 3!^wBc:c_v'/b``;pmi5A0i|я~$ NҾ+wk15lWm'f&-ݐ:e6$^&n׼b$a.~EXa*K|lM -3D|BaBfRlD`%/!_0>/DCτ. kA `.HR޴kK@GJgx&L(nƹ56nZ8L6{Ki֟)gcS1=_|tC@L!%0 ;i 0ϗ;wASO%tzYB,SA%/c^_^.ljy}13vx=~8C:=fkco,g9*EO_c5c^cT0ldV-؞1#\Dk1.\3YUU@zy!^C8  |}n>ПÝ߉B}s)SαB^H09` !x)B{YBE828>Ϯb ˄Ҝ0(&m!N^~6_D@x+0f'xMQ*$e~Lj bvX\a+'fxo L0o@mƏq*fե%LGYM^"1;W/#s x?{I$8͌4a==}>w֚k#f@W.W(x>ǀhn @t?7YYDa .x7Lep.gwwf* 0 |b^R2ٕ#)r|1ɲȘi-,{LI̜Ԗ[A;/}G963\ʙ)#. v3򂠋Lc75)Cs %vܭˬvDE޽ls׿٦ӧ OM]90څ'Iة_`A)fo'hF\ 'ͣ-|s3coTN`!FbôV6Oo=pF7c! vy I;\!!njQ Qaa Eq.GV:@x~baF4,8!33#keaVX+LG<2W>(A;.(dsXg¤q^"-q䟄8Llerlj6.'s:~mA.63km<[Nkb_qltX1= B).F]nPnpIw܏ݜ0t'h|Oy:gt} Yuڑ,@!x;pΛyJ_4V6MK{_=46xgl{حd@qH@#"\ bABXcqnݥPLzfX{ m]v+vdzVթP4Mտún_1ʴeI1n"(60QzJ =X!!<]=״59?{e=H ;,h+7l{o~Đ~)xƉADvmgg@z0Z&X>zᇄ쌯@tB~Y),`O—w 3{ |G$kQu={?xtON|<}73%ͯ<"_4S##_>hYhӥ J٦:ﯾc}ZwM8<ܤbJ)HpӅI¤ϱuh@hj0Igej2v{:ifZ)Aя-@BD@!َVq`B-uQ ko!)wo_BD)?9Hp|r6;(sՈ:#J\6Ӷ8t )1ڢo|ٶOo:;-zvwũSXFex>R_0跮OA`2qe$;Θޭ+W+RCѷz!&D? UNh!&-*g G lXBd3 =*__l#bQ)&ER5gL98{5s[%k$`l54+ưnOoO6i.)L-]qvQLG9~ɾ/8LW^y%HE"O Ɉefh{aqmGV>>$C_3fПA[SH=\_Ki/ošZ1{u\}|p ({LdEVm|pp0{WO-NoANӑd]:§f O^oyWxJK%8!0Y;L/ ֙i2bz^ɴb?'M$ݒϙ$q8iݿdx./n)S- ':wC,v'@\ fs0 taDŽb8O}b2>=s@^/e8v5kVQ^s'@voUr޺wG#Ns u^G6Aۻq ƭ6zvsf S4ʵ˗FD"ޯsHIP҇φg@p }ko>!a2N`p | >߼>vꪚvKB#cc8gqv ;@ݭ>+L'#5UzGBI-|BBx QWQ-`d\HIQP95~t3A >y`b?w p B%=[';i||E|.~Y\Iap\Ii#=?Ӄ{z&~.Q.q:jXP6'_wc3Ń)zI @;sʎ@]30olwOSSQp;Wb ^&cä@L ٙr-;"Yйei>3(;Ztm$CN `΀{h39!20IC.աȿR_ga-[,l|9umx@JȡQ3NhąVIDPStG uyaj 7C#ϖ7q&(€!LmܘJx[O LkBΚ *l179`o@֛vc'ג|I̟~2nx\7903 C:I)~&p EI.n⁃lӶJ]lP}V=֞}ltࠝ~\l2ۀ/[M˴:g;M|m29(,<ub;[MKl鶫() >\!O8qbC{@|smrI ϿK[X/wsA| u;{:uev4bٗb鶧m/ܢdvd%\ϑn&]~vs v /P&㘏aj/Y$ЙIyN-J0* '/03d mivn`#/Gsg/Jӏݍ`{lnM9=?/8e2 w-ͽG00+M:M,xt4tM4>9ۉC1{~x`'Ñj xW)/?=yvH*i"k@K镲+k22sm`UUl۽Tz;y.{^rB%vn}`h( mLvݦJ{t[ey. S,菌?t "?Sv|Iq2o޼. D{Hz5ԖV3ruA9'b鱕).0`Þc]w WY.^fl[OjCńe9Ler!0azA?IL0!YJo!jO>Hct[81p< G}z2J~W;.y>T3 y脜k~RF0G!b.P;L9ІRWO_I֒?x%* U f_M*S֚_s=yWs\؞ Gzq|=fp3n[>Hg]TL("DxK1˞Kڝ 5G:= 焿#a< P)9x > gy&HFz.i+MlU.J1FXJ/bbX^,[kC:=ۖu6MoR|TZpBPaʠrŊo DoI\s 0$48rmbl 800ʐ@nx6gL9!R]Jyi{&RC@[v͕g] %lH I!:kodG=Ik.+d1lW*^{BsXlE  9EWVyY10?}~U%sϩ|9&qo,Wc=|8Liyx.[2ˡpd4<)}wq E&łb63~1$~잱mG|d\w Ly ݡBHmkS =9Cj쬓wDwA[xxn'k %: mdr 7c18ob;vklQGʏ\a.:/Bf3[ĆEAsϳ56W׊kfi0vwO&s Q9NZ?[v @3IDKǼM7n\`9v҂e?ıY2Ҕ^FSz)mxٺ- }:xMpe_+# WJD%9_QʷA[υ qK orƿ#A)VuH kRgb|ʙ5C(G|run,\~nz87 ni "2N*d4m ϙL'3vGH vY3!b:ßᦻ{|vG8nMa}ğ"J*eq.3Xd >K-f쩭+R["=G.}֫weu~2{mЀv37*mnV`p"Ğ8㌠,^ ?Nķ14@N~Lpڵ@Q;QeY=f؎2?ZG.~[+l3Sl#OYYY+bxi,'Std~HPoC3O>w0 գ]o [{_G0GѣG@c~ډf${CjlÇY3ۅ9+רx_v:>t9jX~'?&d+00'SP58skn3-U~h=[~.g_KqnIz<2nq-)C( QmNXat6_;~nBM@9PDƹd]3 ;{Y2=Hfacxf=O"y4C074/N$2ӿަMypb ^kEqJA^/+f6[=;K{n]'LfgOM1~seM`Om;J B10Հ# jG |f΁b_ "(\C1!\rҏu>br{R~♶S2ŭҺv;f}خcmWmOY t3bm9Y´\ei.u{e:sk86@z`J20=&\3tv6%n㾟) A`̘1Bcά*߻z҆?j'g/KMxs4Λ7iWni{La@[Qvu`϶,e%:xi=9h;D78dc[;,@g֬YA`ѢE`JRWmxa^:g!:J着? t5Mƀ3ʐxlΜ9 Rm=wO|8d.\/3~}؏P<ڿ%< ۾(Ga#Vi8^_#kYoލF out8ޡ6;Vy2L[<{ʡ<Tslr)Cv8O61q&6pS`SC@')+SNb3vGTL@*Tw1>Y|ú8=y(P)+mYp0#LmLMͅ8|N});?b{yFFz۾vK vi'첓& ֝]w -'Ɯ$86ۇ'+߬+57?+IZ6zX\yk"/_C:mfǓqH[s0a%}e2${ߵn[b;FD{[=\=yXUX~b/uC` vCm5z1g(xM(c̖/}?":(sHŒ%Kb:9Չ+Džƅ  : I@>͑}x/@wVi_,|@;"X0CW8}WOI `8^% _eJiᏄgrh!2TGf:),SpvBC:L\n;90t)ޟsyݰU֜ yt?{LҎb\_:dpC {>=Yع۝@Œ;81Sŀb,O kzslu3j>Ya)x"mxY[ZNY Sn8jjݴVBl+޽3ؔcS{c p֮%kZw-].c u} ._}[WxYe}zNпG }فHAqR@RNH ٙ߯-u}^B,j -5G]%^!R Km)Sl~_ЎI1 ?&%ŀr~ ߒeT52HBu>ĸ@.W[?iӦHlܸ1\eG 2dHHm;bxarK``y?KEG"ywUc1&=*UG @!^OB'g:D>7eʣ-=s 4[ay1G-~Y4a7:e~?j𧧇pW &ge9 8d=/¸=[zv޽KPE ˡN@c hmjbp7_{+joݒq%wqonӌqw,񣈡~1Bg{=h6"H{@LSWg-[ǟ`3j5ۛ tU2]6k}xE1 ڳc8AooK 4,Tɸv0_zN{袋lٲe+މ|!}&y1I&5@7Av0 >jV3ʖ}ڛgr|M)m)l@U(o :~0Pz& j}uSNӦIQJ(00a9ӭ:@tym<\шm8\0⿛K>8|*/1ޱjcv%? |Kx&90Jhgջ-|YZxJ3UJ );p0%W$K#^!A0wx0|c uF׿- ρOzw>umaw><={63YvLs1xq t\l Mʸ:B$,wF' &{ ,(`=~p7L?{$;@' 1S)b4?aZN'Gs<2ُ$ u"ۂYve:_n3a{ľhX~@IDAT7FRzh])qw%njcTڎ]y7Q#N+Ю!6Cs>>S%[0{ zαvΌ,Ucv/Xd$5]bgnzIWmF+C`uٹ< ծ~D̥1w mb/HQaI$(6 @*;|@{:~ ߗ|SSWe_bԿmc\ytgm*D fg"dGhqB1B8Q-kI/V^%\ BoKJoSjb[fX%K֧2nuk kN_oeIͤ!O''r1d,&@EEL;;%C)X4 #LwHtn_5fWX[En7 x&u;v15"UIA(6LR)oFv¡kǍaFka [koWQMwWۖ]{sHq{Vi: qꂍ!CFG('І!mhAG_!Dnݺʐ"_%._6{Şy ON3ϓau6|)cx6皵ɶĉUJ!qt+\;n :*Y}Ew)$>X{8(x6Y&A?,?~C 0LQ>W`:/[C)x 0C(u۷Ww˯^etmcM=mM:nt`^ ) Ւ҇zf-prΗ ")A]MB)V,MaDHUiPX`@1d0ݫc{` $Is23[Vf5jŖ_d^[|'ZUHf=iٓH]wu;|~ܟ3ngOLOTA21;P)[~~G R3Ϟim~kCn{vi{짷m;oW صo:"pW D^8eZCG̙3 ^x!D# N\s&i;#H (ُݯQ8RE %>Yemkiu]1 8@== whL~tp B+HiKHsD nM-_Ҟzꩆux\dcD,UhjY$ ?ӯeUf [7 o)LΖvb9MDZ:O9y焷 y'EgT_#NxH~ú2tUEz}LOL-y]H=1nslf~-㗭<^b3xW7-^yGti3YS*xl# /t^3n>A4nܫ H G +mzwk|&R ڶ8eO㺪/UTvՎn/^g?&6iɀk}v+58 0wܠ8p>` |錀C/5+hI>c~ 9a_l?^>h]ncFٞQ#±]-ɀgm𔲒X|%҇ rUc\Ҽ*倡8Lӧ XmB3G`0z Kw5qmɭ4" v]w/$߿)z8BfyfuQF۫o~?#*/1 -\'Ld8TB ۟dȩY S_Y 8EaRAӐGSSj0} hN-8ӄtӄ9*r z!2UmϟB>|q8쬧n[ `;0* h۪$^ 8)Tnj$K)& ^$.$Mnzݓq=,Hg8MwfT4CF YxCk]81$OBP˥ =T8E{S*|3a4/VW=mSc䰬'i㴺@z7&k?%{~no.if ܳ kb3*BHU!2&rc/|G-Ӛafޝ- ¹{\wOg7=^lz;I6'TT\ClHCowTЯ®߸-gV;JۻV9`W``=2gm܊}RkgN.]u7V}ku6u.Mַ7LgaF;=Wǽ4G~[r$/q!LΡ#ǖd|w!L}!_TJX;]F{lc\78!뾙" W|Ж}Z<{r;حtl}>(.J GtpZ92Xix9L}-("7I_B]}(>yg7>"ɑ3J*ۧmʅpO$0DžYBAӚ:Q@AÐyJ H 5pƗȷ95sVT  ?lxNmLeV!PMf{b?H>gJ-n2O'3.Wk>`9b' 3OHz'FS= n|PCch)^KqZ}-R~)㦝r5~1`lUp$1 vq_uQ2lw0EQ#-i'c^d//Ӎc,#.fo=:gg(NI:`uW 74@?>B?A b[6 3>ul3 qe]\H jv7[kƌݵVu۽6Bݶ@Cޡ쀎\j nd]zڮƀ3 ]!,?PƘg'^&BuE0C= Sox;~m7|S|~H@PRs],~bGahx㍆}'fZRϼ-cbm?Uwpbx*͟U*[hKƼa,'nao% vz|τ+A!Q; ?6]R09ʢK{#k 'gH$O2psx0nw3 ?i>ϼ3b}SC>f h:3X%;o1 @0pEqla9=0qĪ6< AäKǒcD,;sN@5vha?[S'YWqNt1[fSi#Wd ?t^u6;]e{=0{LWQ}ߖk6\;v4\>!ZM]z\aۦ3ϴ'M1wcG&MgLʭ;lpgG VZ}uU 4a6+=zK;IrNy+PAv{/Ym{wٮqGt&0fԩ p|o mA$8QUUeǏG5I'WHh# a' ׆!n61b`⽘D#gO8Nl'~\oay= ^|"]mW'N+.`q\r(P]k`[X^}T4{=+{?A"j7{Ha}nggΘ"Gug={9٦m:.P<e>8!8*~DǎkUUUXi2פuWm=~XQm׿+9Y˾` <67Cl rtZ(\ܯc))^.a[4F>>jmSueeJn;\΂vk@Dtm0K^?FnzʿK싟e}KZmO7xvHک\\Ńb"WKD^ e4g4ЪG7 D'_/VL+k!+ԅ$ $!yBF5#e$*9N~ة,:B@4>[ Kؙ1TE޵AD3$1\*sW{f)G?Dl! 3 Ž ㄽ̎ 4IH4urxVxW R%yH`6?;Ounn t~!(\4lni0$a}2-dTzȡj>l ,@b }DtۃG?c:;QD`Y%\=Hx:[6;i U5/@7 a"Irl YrM#w£#52}]y>+H?-[zA%ղ7Io^^\[5Vosِm  ]W\qE :vzBpRZfpM!7$/_ k"Իu#lІ=γ^`;&.5Dw]e_Y`G澠7vG2!g<=HWn .8ceflɮf7=8v\ lS齃@sH^4y=3gfNMAUVޯ<{Z%2 jeS67Gmhk]0ҏT>=v> :Ȝ2 ~EB5>67">` Nνu/YmCN#]ܠ"~\Q_܏~X` @z:CfL9X˓U`˼:uk~ҺK=6Ԗ)+SLs%}ܦk!avh>'(ukL֡navɄ]TãkY6id?lylCˮw C`P8/'_k0ZIkxv79|{m!J ?tiڥ"YPd6ƌ Xp\47n?î$v^=SXfQyQQz(OHL0#;vxIFԁُ}3A:g$ҵCdrwףn8E2߬E6P(v礻|D^WSgwĕ8}0VH L"4hD|S&)Γz5./W*TRS'۰IEh|)@+KԎj\p >+Oj{ɦk>gIiu+eϸR( Cf:ɃѣTŠJ 4~')`v#Q @1/Oq H`(--uj! B9Cz̙o76)߾5fyRhzlm4J\FWzOfD>GGU=>0_1Ah!6Ȱf ju:f m*0c S=uIbV(GPBE;5Q'E-pz:@?x3Ϋh oַ??zKak/T=K5{hgxFq^zC!RELqt^oSϺTcļݛgav Cݫ|4 &l}'m8l @} y[Co8k7yd3f#<ѯ2/])ޢ<]wo^ΘS+2H !myqjUXM0%( 8T!;f3E1GS0x^Cu˖-sqIh3x#>ж ̳4+9Jz_+#@W>;9%O>'=gΓ).C Kd5sKU;;4N 3Mߛ:=c CR>twpT{ZaDĖ-[x3Hü?M d}Fi'Ok³>+3f8ɬL7VȄ33I~ݔfζXuz:n`:e\`Ozt;*g c9)};`]B'u>^y꟭u1#_4w} `jǤآ_Nߨd|dVxպH L\éWP,~Ϻ8D6鴬mxYVO41ߟm~D[_gu#S $1WǼI@GdqT;>*׾ertM*:N~E/ɏo",-a?Pxul$zd \8d??sdQgv!tD .pG%_Y찼aY̘%j?`N,.rb޸@^y~E sCk_xlڞ+V*:os꾫Cay:QwyHXz%%%:FG¼=%wj(QH٨j? / }J0;47kL<8"]W\N+8ҽc4Qc>3`Æ }0U(i=9ʸ3G-Z7bǏ??||ʣ>ڬX8sry2bH5L>wL;}kUVULyc/Yy;z9}P;Hf.nKQ"WEDnqu~cMUw:Xc `|[0P[G##|_Qjb}N[nM.|9 pĹ| .*rl .lx׼pawI]t]}z2JU93G* \]K%O~_ʟW^xh4RzgN-l& |Cn1pCN5O]wq^D q1y_{FCj0@ֈ>}c.!M@m5kGڧ;iR6*d\J~y{ٸc6\2L:45{_cٔ+uz,[H$AH,L6͝Ua}y"ͭâ 0@E¿K>]=_TZ;%%K[AjsZ!T?SA92KzivpPL?,P}^!3:RT9T:; N#f cEM;Dc1q#(E.?O?!|F,&!o"ח†g8,ɷ|gy"zn[h'~+Id;u0pRRRtb$58vyvrj0{'vKF)-W^$T%Pۯ;.{R%w8j#rR~P0]+c^~tTb_Zy|}2L=gFXVÙ~񇕉T :6"83zۡ߼y@<=KARnz:\wJfD;fhM2"p?t:k'p4~E_㋛d~["T7M]hg@u}aר6E&}J"u~`co'O~r(.ާ{oeSN@9enW3<_.1t40:? qw|Ev\tE(FTH;/<_wG*<6})\VO )#=rI,&NG jd pVeTJUgR>lCgtt^.eǟҭ]'?ꚡ(99ecdl(aǨe?՝ʶe⤳ T $\񪫯E6ynjbSq~rgu.5i~0ay6끀 h.L' w[YGLgitpy@41ǐ Xx/-- t\0Iq{dHi11#`HYUQ#B{%cȑ#6D'!:Pה5ƔUH.8W/ o"_n 9k˥heLV&{R6Pwh;z0 PV6|cZEʇRVzw1$yE&'ڗ,U`bϜS~kw5k%|J6`EsMy[F̯B4X1 NxWLF5]9ы={DGpBg8n$EOdgwb@_T+_8M[vYIu j#Wʛ;21wK45!$hkdGEr5;Osɇd d$'X8h^z@3B )``&(DvU‰ca7;fatv=(SSxur_t%S)(R]2w^z')ڬ骧z^C'J5Kzj1Bb\ sH wϓ-4x4[f`(s=)_i_ 0tPGWS^%FhgЯZv2Ӛ3j.BT '=[kTi /UM]0?Q)vئB} J~1˸Sn`@뮓o}[L䓿o)\& 5uc(sgM lZb$¬=Q=wiWKe&`?L:PuX\gm҂^z$1`ҧl߿b'k̳ z;fpx~C5\*2ѸΝ;9{V1TRT9rXE~?~;L_D30,,3dOT-T /<]莹"f _28BzY.=R0xF@1$0F à/flf}3dK*,c,n¨_s#Q@5dd`2VٹK;})L^ߪ*[Gg쩗穻N]wu0&{i{e8;gqLJQpܹs{鏏1Bfb,wggN 6)HqZSo_~G;hCޥûN$̀(Tȋ^\'Fy7k֬q;s<[nA3'OvV-=Y4\G2R|BCrZ~W \':KcWȴv '=3ilޑKV Li0~t^7I=0Nɸq܎J`s cѴTgFN h> )\L spX'u/(Qez4YRշþJ1  ĵj3eٿY}m~GK <^'?Zj $ofilT V Zz*w,Y`cjx&&­O?ltK7V=~䔑͞]RLfc#R mwYg!]~ wI/"1Z nŲeU]X>L)\;dࠁt3q/9~,-C6`5r[\X02PeTN?ָgv?R.4Fb0 .m$ ЅJvC\wYzREӵ 2fD)5 L.:o4gMs@5*1.eY.ҳHV11t+Xh]D >+<P@-gϞ.w (?ERÅ< Aݥ!Ku>*;[+KV9jTɲKl05LgJ iT|{Xぴ_#wp@@&< Q''801*- q2FZ~q[iҁ/A._*!UJ*CjuIl9mu QYy>C*ejuԅP;hEm W F-[n:CH]w9ŸH}zYlVTȩ'T0L i:/,5^AAx9eN*3P~T (YDŋz~ZT/ydB Ȏ &zG`cz]p\ 8 U`cJD9L'PqAJHQf}ǭ]֩`"}d(,8 `5"=pg|4YX=J~+V`+4|@\65Kj+XS˯(pnхN_x9\mb+d!`åS/yBeb"UW%4>r8)\(~hdP8d1hC B|O?, 9vQcf{ʔ)2bĈן;k+A띔sw[q򶧑 7\[Fi@Vf /t {LV1waٳB&GF¤y'[gi}*#h՞ʘan&:{dgf]8u)1GB/c?bIIlQRbQ v!8iGFD~,A8I50(oX>y,‘u& }KBIڥO gO/!$k'a2:TB;.%)w!P80d$E+Z[]T0U;0l'u-u# SGzui c@Lߋ6!bS2{1`nyd#??_u$X9D!tCC,}^ZS:3]-Cn@xBȒ!"35EBA1'Sϲ5yɮW)*П{9iAdȀ^qB:F ŋ;q']̙pVm+afib O*v@ ]gWUp*oT҅QdD?O\uKS FtRX'k҅z7)p]4r4Mp(_tK׾"۰e,F4Juwgqf,Im+-**I-fG'֒@y/'; ,q G*O2Ǝ=]k_8z,Y(%쿦]u!UU4C}'x 4]UOP}Å$8 .YH8rJ?naû >۵a(xm|k]iRVeW]+_L˭yZ%P7mϓ{crز3[Γa% k$7A./e6 q_~-o 1DMx Qs W^CvLH' Nѝ¾@G.ۧG:79;wKuWͻcfVj>BMAD~\c;`zU='62 \0ҳpAR3 hU: Iű,Uzwffhor,6f{<;I(ث R܉74Іv3 J-u3-X{=>rŢU̚5UЙ@3.thFxxM{T ]RRׅwR#!F0 ʚ _opp96_?>5?G2G9s#7~ )U۬ 3HypngxLhƪ<#n ,m)KRKMk]H|W"{a*聉k8RBȮA guLM<~4h^455.CQ*juxj-4-]{-e:!= ,1G'/ᙘNy,3OYN K-Y&WOrsR<>|L`8!>ַgɳ4*H`l::SboKWi|2/~"壆=:v;M+#]W3mw?I{ ٣*'-O'SpmcQTTRF-&͆ ܸ~kɒ%ᖂGUeQ1MxOPf!ej|\+`lZZǢ?@_{HfuF_/r$ FXGA !xWKPW5[;(9V-R } ,kWop5eONK.qn"uuzDj&߸?ݜNv24[hȗe:@YEKqAL=3\'-|=RNQcƉzQn!3C +U|5cW(]}j#WwGtGTw enJyRP%0V1O)+~,褶~o-c(իcyE <;іIUMJ*,8TaӞ#2&sb:T[ڰgɼAus}.XF8QN;-8%W^q*\9]@skLW=߃9Qxo= WWGծ>aov'ۯ>Ej?.)KRXKp `(@n)%(2%&}oo5;\o= х'[kn86nP 7C8+ct#H'?r~ߘ8%ց.I~'G@krXKm*nNg]B0%)8Sƙ }M>o~bc_ %n ʖů~_;eHb8ܯwV J)R g ]js]e_AY\(}tFz}t=Q(((pz#=)鉼C< m6Aݨ H8/0JΎ&[KJ%;]}:Nm|}}aXEvN\)ۮb1$ePHs[~+il#Ց̴[+%s8ME'1o8(o/Aȃcplߤ@gBx,!UEU]ꂕsDҗ$^{YyO;S-oZP)#E._+Y=J-n/7\-z\P% +υC_$NƀaV]AnlݥGBP Lt__z.l >Wf۠=Ew:3X¨q_v)6hǦ KGOmY`%OX_@I)ֵ麒 ">'@t|UGSkh{OS Ci) ~PvG2PNM0hI QgKq{'l}M#Ǽq Z$ Xc/2.>2}chp,|kzڦ޺'8;F5AFHz9׉{*))q>b*tՍ1}>@J)WXTֻAbߡiDA]yaϒ^}euWʖktV *07HAAø17xF0Vі`ƃR2>ГuQǬm1f-PfWuM=֋=a?ԴR0Ν+/RMh%G Mc'˷1Q7ưtYkM4~]Gn`u[3Ňk֖.?l];Gz玝N?b$'#x7[lǼ8Z}g/N"j @$ H`}*!|ڴk򂐌k[p{F[QvIO 79f<@pb){_VE:˹:ȷʖ*;:BAz)tء6f`|Xǁ:D̀(My@, Vw;"9FF(84ZS~f!͔̪r)=Bz9W>tط]KgHU?|]ze'0_*~x0bٜH}vw٥`Á9֠AwKc.=їp,Zu@JXYJ|9Ny` )r?uFS .) a%/d@S eڳFFaRZ@6'G8hܨҲVV];Ha❿VgZTHӏ2Yx-޽zycj1/*ɣ=f͆$tVB*:bj `Qבh&і,11ߟ).#"¶kmJ0ԋt%Xh}m As@D]ht~xwm\$ @_bxMkbَw{w^,37˓3:{Ju ߖ5 ^->Q_[&)H<0!a@OfCS' 3qN͏e8Q[~vy,~6珳0~`e}=F\K sܩ} [spu-dLUr; #U&A~/ v^0$vy˚p<"q￿ӳW-[;`q#~FY:TL"tRG[צ 3 \O4:m/ RiicA\XxƸ=dWgq;SW\qq IXskL|TZ~v~)釄QlKS-?ٹ[KfD$M7v#R6lp@36rцa0a @"C t [.f̘վ{t՛QeiL*Ҿ^نؗ("+C꿬n:L9RU'O[oU暄橫0!ֲ7>HG5_=hX3S԰Yѹ,q}i#EU^G\0 ˵] ./@CcaEb:l%m(8Cܴ9<t`G*g9RKea5Hxm|HqmynYS㜡.u_H˸⼽z a. 5:QRRKg2?FyrMpRBf@QYK7e0V6|)-_]n ,KふQq:6C[5INzM4q,+ UлSWo掵ZSꠌ /NFs=h/joKRKG'NfL~x;G##eA{MoK4a>ow>Uo~p:wi5|m& 1O7kq'34?㰵 :DZyf>}`8,׫7̈ճ^lE^9 y \=]uw@juGc6|e[@EÏ@js:B[o2mǏio@z(pkY8TYcq1j;ҏ`ҏ_ ͛t7>U-mۮ j[:2R]\ pL*8*9 #GF`Zib8F;$/T>\Xb  wwTtl)mND<:&f9$[o%oA ^8_H4J}Jzˬ-uW&^qN6uc@uxP򖧥,%_P,5`j1º6U—H,OV˦hæőxqLRb*<٫5CpY;)l~;Dc|I=ɓBKZ$`ޚ5;l_[#mRծ?ʘO~G5Cʠh VdeQ' T#ߨ>b8P0\>H`lj=P{ʲdB4= Nޮ7O@DÝ̘"1t0`;!W\1g :FVϲ`WJ_="}^zMrUNY~^cX{mٟ8t.l=-PLycnY30Gr2B v_=LwꩧO~g3;N!&TO)CͿ >Fgcя@khDߛ]d[a,ָxݷo.kWπ_mٚ8x~8#'⛔oڴYElb܄q9w}GCG=9OV`āv $?˙o% !kE~)T(;G%" DC,ۇ *6ax3'v&M5NۥdG滋PO5*'xQJm|Id;0D?RON@xBc(cS8pwޕ3f3URRPۼ3AJ#*Jk`*wXiRӥ'!+dH05BcFS e-|ŒvI.w": eر~W.¤J%jsIԘ^{5] 4>H-@2_[;9F@n#YRe^Y\k WW]-%w{nit3LEEjdYT3~G)}jfEf5K Ji\n4|BNvQ2@G'd ~=v)qhD6lXbկr.b_ e f̙=7Rfi,ab5Yxۢ!]Y\p0@w233DVtu `փƴ[r^=' n B&L9D!ySg Rub(]-ZOTâeG7˦rڨB)U5ijC4ޤʝңkl۝-[e:νdǞlYi,\/=5k>ϾY,uiң&'¨x:T45 >Lw8^ՆRջՒ,Q|uq5S23L԰.)ZAl _oUE<1{O/e(O%#G7/S>\Q&w?QvU;X뙦.LNȖ0B/{L}o5$lw}u]N%W[^x1M ۚ@E[5˸98Ufذjl~oߥ:USՀ:5+#^G|z2-:voaǤ5W6<;K\r-šwo w$-ݩ^l!|`'ۿ>p>udčlV$Ï\_L)u'xZ Ο|̺81 7o3 kKu^E$WEI!a.wD<Ƃ1RֱMZC!îGVGBꫯX YFXl@CC%tc@]H "3<##[)G~ծVÞΖ3NѝWgP) 5(3r[=c a҅SR2{Xso|9oS"k[~=re d?uL=e^OݥFuyKݓ֩;.nRO<ٝޖQS$LXcYumFoOW(kDS?ߴV!Ο'xkQ6T}| ٢i}#Xϓ+L}y)--CӥeyH?5rEC}HOpǟTO3m9a+r7g]N?C gdcf#/;c+ջ|<.Dt&~?b@ҐH3KW?HH k&Ff4yO<eL_RR"0؅F-B( H0c8_ۜFK~YP%V~@N]*-A\l0ll72Us U)93HFɬCȌyP>imh}-ac/h sgmS[N/R Z~:Sб% &J5k׍r*0݋lOb]6[`~/mwCekC@<rM_rQcbcO<عCn''*Mpv@ğ7Lݝ/ `)g_ݖ*rC..&cB 됓-]9 birєs'EE,QT>Xwm7^„5ߑPqs .טLS\_:ܺ$0^n[_-N6#stwȜCz&0ȱ6Z bW^y'-f!M8Onk卷+eƜJ,0p reh-9`ȔO9(CWJn ) O6ȑ-;eD@ؽ/K%J.5de:2~>GeT5`r;D1LL,S3TxH!Cᠰ(K:}ƇO~F Z>M%rϿ V+;^(e*Hi0&Zh=o xn`0FH ,X1 'HJ. .T IhNZ[ALcRgoFV͞[S'ҿ_m$&L|ʹ qJVPA R?:IO#V,,YYAs'@^UYӃ\}"-8_6a>n̟\񋟏(@=o2kkɄ g?r#>Y;n(5 4]UODhg該~%ѣ%K ;*戋YjD49{ٺ+S!gS;;?6UCȏňI}:azp׍%j}Y絛Y ~z]C;:-\Yg]mB7[\(dB!2'Ln+ s** amk|Bhtk-W~{G?`_w߼0##+V8b+N{.~jp]tk̈N^jg?Ewke˶he̚ tT~g8(y%*^ۚ{D7vsqݻcpl d-=3J Ͼ,٪^q2wL9O c~*.UwyytؿOҫniR6rS&󑮝%ZU,ڢ鿽2{ @u]$3O8k\<;ƒe5,II Tf)#?kXϘ1CVJh uZM83Z[q6;Yg-_H>+\[mYpV6L b^;jDOXhJK.sG-ԩ~=)lBۤ_~-Om*uTyL ?9&ׯ[ݹ˕NqkU9k}㈍aPBʂ겸p!_$m*KkoP0u !u*# .tRӟ$?ώ #R G?C%%%Ntȓa= aw%84lٳk2h>tJ97+^/}zsbNy+%1tމvg=J0Gf-$z&5$؋C 1ʮ4;6lp`Shd$h19`8-r珖Iwkt3醫䈪8~+sN_+E+VAhr%qpm!.1(+p!: ##ø@xo1O;`|܀1"A{ `;m^$_-z +'t$=;CJ;J>y"ZPځQ|`"('O*+[u1MPyP:#N-HCxfrO KRp \vR[wG3$qꖇ.B};\:@[Z/x8T^vVx?ݟF|O6`&hqO۷pRht H,߷w{Ě>iDu"<EHKJ/9HaQr&h*aR>#rɘ,#,Q"P_kwp<זf(UHP}:;JNMŴ՞Ok4]6`p;Pdk|;4={:gF؁Pj)t&@Ԣrdo-+˾=55U3u'XͥBz~5X-ȌwHar5;TVYT$ 3 w 'd:N~Gxv30x0v'2^(N ī 7i6{_ ~ݎwplUR43M8C xzd?Orv{Ir=R }gybX8p`\Qza( MNhR&]X2=m2}(aZ9,|r@T#{ϽK>\Q&wwB[( 1׾n#x%QR'3M3:iQQӠ ~_Ěԃ,xQ#5Xeپ0:ڋ7kPxjJdA^ k?W܅aop`0j~p:ה-5gNNeu} z,l ~Y9ω9i GTyᇋdҹbg| o}GbeqoCٴqSKǒ9y%=accLb;N . ӣأ#^d#\!ܟϐ*V~ ItaCjxBh` b)peю)GUBCB A0:A& B|hѱ; ֯LիE2@eݦZ绉'1joD~ XVۋF xfiJnm($3F<v9<1hl Y<4#cW?&:w=JL<?1j@IDATHW`uDc~qc=& .t >0puƘ40]A97!oos߂}䌡Ew-Q,/{ź;8eٲ^1. 06cLB !z/ ~@ PC1`i6)ƽKl|It#}ޛtQ;i@N}4xCTp|t!HyFN7MUOݺKݩ cȫXq?|Lw|@cޒ̵\0;II˥ЗKy)2>tHiegH%gc( XoUrtKẃ/{"9)RcO8M" ^ZƁ' :?}jU7AR`B0aџ#K3aP" F?Ogc]oOO?vB7¶T%lξv~ַg/e`Yv=NZ}Rjk7Hl]Di;r'^*XܼOt"{JIsM?Ⱦ]1N<}x&e}]_1I?:w؊3OBܼ`Ysp3 e/UKM@mkarp߼N}6>7QoTsMyl֬Yv뭷`3 ܁`d  ̚@ҽ:_޶@v*(1zw+>=:ب+ɩi튅*!%A q2}dUn՚mN*c"!O ǖ˧k]}9ˀQ-aoĉ{ OU>5{) rf\9iែ LNw9\;W_> Ӣ&5Ex|=aõe e_j}گ$CyW׿}CI I˸qPn'~;I ~4MMz0SP&9:&D Pl@WiϾi0浅D~(@4gk7/֌ihZ0Ð7o{v;78)Qt|I5!cu_C(3{Y*:֫{uV;3[o6.mQ'ݤ2,X q;挵>|ij:f40ȃlc S0A5 X 3qwX=uN#URex3lW dok_׎5Ю"vD[@e`ڶ+}+*,\l .A:6P@:eeeN?eV`,vM4 dM̕h7j7{Hd kB0;p rީ+-~bhJ`N8:CK\)pR·_iCE' CGvsUq$9կflsAM ɓ'یєE)ͻZmƁ{ UUOwQ]V2Q<wp` L|m4r(៚7nt=yosʫ>) GrɁ|vFңsZ\y@3.ɂ ?>v##2Keg߱矛nS<+dOwq^v^0S: };%ude9)1Ov$CCPGmA">/VyW N:8bGOn*'5.Z<_1a;2ߺ͛˰]nv6X7Я>qI7۰B#)Jy''чsvۋ֑f{;u"}O^/FAƳ/"fC`=G`4yCqٳg; p>(QāqĖ]xUR#=~|au,`u{BkW%xEwXJ^Pmm]خvJ׉28X|mc2Td3;'tk'xyOwyt08eD}0ySQr_DV֯غʒȃ$10uX`zp2g[ 5ظy)9w7GW>|x`"ϱ1V{{1Wo 4jD7_wu'?O4FI9|kM ۩%}~Mߞ>Nth{i+v'>qguCgG'[oIRFJN[&ON^)PСeVZV*cvʂl:"gClv+Ђ/x=0r8.l+|yE!,4Xv RT%Hm7kf'#D,9>}{:qkUuYnAq[?qw[..n7ޱ9W>=&iw }eH?.*v?iH,-_-lƎ >E!l{%0pg0fZd@z;"։4z?x&[sڝױpLnW{Q;eEF]}7;% VxU `}ن|j I tXz zTi\%l < ;xt (`B338n¾45w"9 *--u3k چSO֭c ${o/Ƈl`t2j%v$J h'bILog_eFf )/ܾ/EEE[iɱÉe|3ЦT`?pOoH$-Eu7UtyQbÏrڇZjsjԟ{?qk׮O< k쎛4}NVqg| RcK 2qY*}~}D9ؕǜ,^]dmW Ķ@Vjqf+D>9:{>6>7q;Q}qޓ K4K-cogU%OJЭ% 'y!l-ֽ[FW 0{^g7Bj͆qol{5 $&`0wٴF&qsUf~oMB?`wk%CløCmmҎb+ϝ6ocER;k_X ŎLLUn |}:s%+x:v 7i?./Hj Q_ל7{@npο曎EOY qqi% 7o9mV2o(%ND =mcy]ֻv:}~{t7[; ? gٟ qߙ+<09x:TA8%vH -Exum>Vzvl-mn7Ye UxD'ؚcw]})t;V)]N=CpT)lfqTQGe|? ݼ?~30А`/O'Bes8v;$-〒ퟯ:KBAأ׿n\p+eڂ6mp.6EPjh348C+;Lk%|S&õMO-$qe iE>%qޏ|HnI;_ y@^:/Wc\n]h2h2ι5 !2M6w%ރRkڈ6g<ی1/.@_}8Zbv8b~;:$wIiܵ^<4UZeR&sŽl*]@RTZ`$.wd|3rAwy~'#LN#g?QtN ]ul0]$_ }%ݿt܄0.=n=mg[ JlV+VV8z`-3q(kz`#E6_%_ѭĶ G ]sV^v$=?9պhɖ|<[qVأ c,(gd^_z؇dB@(ކ|U9kNϢ;H^k=L}抹a=;'@бVQXT_{uQa'I (\KmPXu1:1`VmA(RcX~p/[/v*6K~j]KOGQ-lnzt w6~6cNۯO^@l@0d #l=gDiӦCFYt3ˊ6Y/Yڛ:@{;1Cڜ~Q8$[do&?Ȇ[\{g`قO3+$NKH̜%#6n@cij7 y mgV.~OL62uֈF @j49(Ar5̼*Dk x }<: |:8$\ @l/l/ SUS1/ 6q < uZj|TGv!ܜb]I?>ܣr ԅa81jv r k9]vatd`H8.]~x&+L(@ӎ6ۜ݉ HJ18=@ lbqN,'SgRve笱}=߁(1^_yQq] Fɚ\`- WLV?1*J٪ mmG.m}zO:J-urOB\;o.^`6Pu<j`|-R;[pQ҂3['JXk*{:T`jJ: u`_hQVY'0XggQ֔s՜}Frsc,?S[c04ͶɃ%=d#2$$8OL C/8I5$T5>1! `dPÚfgoj=8-V4m;`"-f(ZrRqa8O Э>.l/.3ꘘH2*g;;+6p 4@4RZxBC0N6}`>0ʸ_k]ak;O6P#тbBH%`[M{u(eC$bvzt 52&\"*;Fg]`ĉ@`XK=B_jG()WkUGwFe1@^:_"fJ'XqPK< Ô݀j,(T''=@ρ}Rѯc6;L >TV-M K2 tZSF8V3t 1j1q|C-"Xgrtqۏ3}IAÉ;eK$Z \񔵰1d8|u }SH7 Vf'w>F [>}Iv\[Nwʧ^G %|&L3$̨V.Zsupz!s`oihG =g&s5AZ3z*T2;;[o~O=-uefc_3+a%~ } :]Ԋ~r .%nN4"#FY{߶2;p %=[b4+++sVӀ}gX#wwikAI=HzB|C^λ5pJ[֐r3/E =]^?G>׿q/GUyB;8sK_3H<'9X!>v4SS|LVno3vjڿ'=hHx@IHr 0 z H]ߧ#uL:3B9ʻ3 P&B]>{{~3D m;8 䃼l|+^̋}S;mʋ[m=?~$wy*;pSExgbH4|c;3F2gD|CM-K)-@6>r;C؆Ml;A6bXoe|Zӻ?W;ğfŝ0-v15vMQ"d)dg kZxAOH Κ#Y㑹t 4FG J>xu=P_Ufψ_Wg6)?H'C$c2{m5:bv1tamڋ'Á2jW|1j 5_ I'd XG%,g,J{l7k&0mɻ8m0j Ӗ0[!;b-t `D'5mF:"-w4sckL4/Y 4V+m9mMy@\L'J|g. 0 s . ww % %61[1IΟh<7W "s?>bGa>\}pzՄ9Qc6 l쭶zD*R{赟M}YNb[ג*pRe'ʎῆ$qԇ h`fސQ3̮ܶ,,%GYȆ #E>L7>| 9NܶB&H8;F8eC:]_> 2Vmehb7Deeo@ & f>{[֝tR n͙[m/f>Qi3f%+;sNN÷,+- % w<9XN; |+VԜK:P8NQjcEts[Uks_l׾bE gQi0,Ecs`?4/|%k1+VIMdoϻq:fٳ\oCc;ÜÔf<m>SO=erhܪ'?_|B@۝@F!y{یP?I8Y#u0 33mCRhG:/gd<g\: =Ҽ ` lIxbqx4"h.!;HEQ@1 ($,1ԩ~SƮ\)%U͘ǽeyԩڨQܱvqׯav#AP }A5;놆 ?{E@q]Nvqܩ.Lؖ**kS^75 {ꔺv$Ѳlܨ(`E.㎧d5a׈SKPY"b= +xnٚUPa%lMpm"s'[[$e̦Ok7Ƃ2&#wX*}esu'joG5e-Xc֗ G2r>g)1_ 1Wmٿij^`-;nMrbp I< 1TUl: %`` ~5}& _H]F3PQ3̰dtpU5 D5 sOѐxժlv-uT x?`MFu:50ؾ:@>. 0=.2(8 y?@xh>P5;~\|i1kذ!EeE/^nMvI좳z!_|988* p.8"߷o_7?|$\$pEj~W9 vb;^DۮCoN]iPagy@&mև\3Bwiz>UiGI'L6Th:D[&2p!&1E?-@~OtRt%qD=9+e4?ɿ$ϖ8{C|ʔ)ngi|fwβ2 2t_f֖ XZG*qh/][:^ ^ju-]CVٰ6tp{ sQYU`؛ujY4k泓2 ˅}t_|E7/>h:ph'{d&5`s2˶av'-pҞ,\,uX`ķtʀTj'smBƐ9Ӝ jJ|xw#7$+H o3 R [bt3`@u|=K T|3I齟 Ot?}3}_a^3jZYg#YVTUR ö́և|!Z nȪV$V:& \ DZ﷾> L&y"9S|r@٭d-9Ѽ LC@tpщ5y\}FD]Yhc084T6G*r`}nR9o>_^`>.d+jI.4`PUw  b=$vv`@z5 Tu20c` >H:MFN;N !6CT_[%kf ;dOPg|B5ĉ]y nłmK;edu*ҿ#׿bN,51%wk/c#t;묕7|qP$61DڷFK/c0íR/ʿ/I6 \>k~ O3$j2P}uO1O~r_3p*b#Il:{A4-Ncy@gyxX!0D6 r{CptuF nSPE"2|{*hls!G}Zy g*)}sy@8?R҃ͷ-lJJ8E}}]xBbt &A@؞j?\&];CȜׇp 75jM_LzpN$z^y;[FOR+C\|AS`tkLcua}32N yM"VΟ]w9 bQGy ^a+ 5G ;VZ+vMCVoT5N=x`[6 FсxNQI9$GZpTG׾M _rB>s_;͝*XbKY?}dQ2ؤga*If?O'[h0X `@u#)eIZl;q{wb<3 8k 8PT.9fD##Il! sKGֶZs-D%IY3<73xJͻMһ? 6xP& #r lNSd"gRMu{weXΦxqu1-g2{=>}#L@A4v,m DNCu(DRsu0@/d dF@ʤƖi_a;ؐЧR H( \vJ̿;FnEnT; :Y+p!R'h%Lew0C1t+Nq狵d=P6m[`<6 uZTxр9@IDATXw79dS*[-kf\%~f6 fKRrk%RX Lr)֯_?'ْ lW\qlКiOC) Kk) 6 ۤ=6SgbHvE0[$N1y߫0M<;Ź 1SI#zr0 K=q\x4\?yOO\#f%˃Asl ɻR*AA.iǩ*a-jHꅉXKdWtٚ52uL>`&x&wMCw`Inٳg\`GuT6Ϸf !r&LvNj/r qMLIC8l,ǘ1cwjnڵJ@.`d=v8JOP% ,#%r 11vW7>)9/&|@У`FD |r7vX'bu@|P3&Oc)ڝV/BgH/K/1L>խZcv IFj" kne,1oN!Q^=?ֹSD'ps16qD{'3g<:̜?S[9J5 zo~Cx+R?-?QX\Oa9*q.* LOлrhOFh]9 pm3ɃO508 ;iHa>SM*Sg%% Zt\a-n}7nn}7EG5%; XȻ)?\rA@w7(AB :^=z[:tA]c7#`?8Kw:cVhX~*Cg3:8zG;̭^!IkNIG% p1<򈓤@z&6Q ^|ŎᐶMBE?5{ fXc\+aK,T0pp[^~A[\`6b$ ~ Y$,W'teyT䢋.r^gWg;֍9}R ~i.fA 6 4۰1<]!dNF~IqN&2!1HH]dN5.$e}Ζf[S n'DVA 5ՠ~u!-8R=sr~}{5PM>OȤl+) k0{G}^u{W3tgi[wv2!.GđĀ4οKox 얖ƶOlnff TٲzFOatm؝uʪv20Xλ)}]vA +Bp" $LYY#8'M)8v=\ˤte`L`va#`/+;-Ko 2^VA Yt"90=:Udd r]wQ6 @ kOL5\ ~{X(hBǚ\s5Qy=8 ~P@5:Tf_1UE6՛w2wYݿ|g4颦Lxʩx'ONcʡ(}Zat.:?tiM62VҜ#Rk }7 |A&"b%Z>Hp1Q:85 |dnm_~ZkZ؟ps UvfN[a V[Al)Ç;u.d9CU֦ Uq̎;ڂsδ8傻:hęZ( rfI` \Q ?K~GFǂk1IS >pnX~rRZZjh1 xD}YǸǏU[ (Pw0duzOnoWcBm}H)M 0Ł=e/hD  ŧA& p+B7p^<%RR|y@r$Ca$׆w$ q!hMNqqSUnێ.BlydՆHbYp|p9 W  ;6YGG>Dx1&˙-r鼧022NW_ocW;bw|/>>xN]~QW+(`/~ VZ]rvgzکwv~} mU:Np-XݎzvgA3QVV2ʂ82q m5k,gyX {s%[\%u&IзOm -q-Xc%?K-8aBeL1"1‡$5γأJ= ׿}t1f&սQoF3e ?8%:D#v6#q&?[1=azesRnD@ M$p^5uE:5-ZqpbJ5}=`}&&ou f,JlG>/:Y !^2aKv8 _Gh>0ڌvZ~r(Ryfwjϙ3'襲C]#.3aɱ &Hf ݢLcu!XO`v!@AF6?)Oy:uc=#wm'į]t|fT vЈ^k?7f б ;g|gۯo-aZ%]DZ0Hai=XvY֙gIT &,f ֮]:,xq]>s~`w*L|]*oY0HeavIOj\h}̂!18_9smV]m䫶hS !N@ }Y d;Fcpti>_֨Z4:4@JkItClTW%mA? U#qÂdh9Θ'Dj3N E|H?/+Wt;=p5p[Ω`k/psq-1|U+ _Ylgz{ff}A kR 6dw)&fv53\/v6x@(ޙW>sZs# Z08B40ݛ w g-0ieo$/k>|Q rޝc/3N'zN&NH*-8`ކo 5O|ᾣǨڲf@Hqe}4|〯tߎ(`w Oj.p]S$@p؞IH^y_<'>zah6Pg2*B{b297,[Z@@)eCV=G Rj:e  ` oEEߥBk)Yȳ3T^@n"[F}uU#F8@o \>6 ݾtY%v"{mI;ioy[ ܯPؙkgCQ`']TRc;lҔ-qs}s=kI^-<|b=d$mʯ'L}]tNZ@x@f^j$h f8`.uJ-﯃YpƩ&Q*s,*Bh]t~ I ;.5ࡉKY+fioXNYj/'|8q[$-?Z |Eц _D?۬,y:*qH PRmr4d.HoL<hЬQ} py $޷f]ܹ# ;ҽ}3* tY!PuYpמa$33wSX% ?xf6L7*!_"LJ0 P DvFsaQ7[ +@\VVm{}vP$O޸t`{B:KVؒE"Jw{ۜȡ!AW*z~hd{J6cNH)'tV!K2x})M!L'e{\ ~{@$t \H>CW(?KdQ7 X''?*2UHBTTNmaEvk(}TJ!9s3b=%?W~s!@ x1Z B1wn-`bر֫W/GtÏk&h“X_$P a;vtGgo톝|vENΉ6m#wO]`˻ mS[;)Od^;d;.R7XtU-uV@]t) `9]`>8֒>1c[kI{5@XZ&CYp] &bMkYß4dEH =lN8P~2-ͮkZ?Yp:51VaP`矣X!Y-sa@ JxIl;__KGI'I|FHQJQzv<hЌBo6ӗ73P}~6~)KgX) bx͆ݰ@,5]m; 1 |IG򟕏G-Ɗ#/K3.I' 2e=sRv=oLw~'qd$>04[[tz'?_VqݻXbNsd`$aO~{ʞ}L@c_+B]* @Ngq#Gt9GqbG(=] iT(hw6[|6lp#G U 孮Apvnt~VeݺɲnvR9@:0aIG vm ivrp~.}ƄH  Z}6Y tGI_m1Sjv ~qZ&P[&xf Ղ?k$S5%t3p 78橗IW&4t؝fk"P}u0:$C{pWGۋ|w}܅gwUpRIl줨Pt6L I;U@p]ƥsX0K\{΀gGxC|u85PQD.IO04l7l9IdOr}1eҊjU[lEѡx.2 C 'l9 qZp}vx?G-ԉ#01.+LAH6רUhcFwj<^TȘߐv3c-\2O=>qqWR2X){F%g@`A(L &n6Xl4`$p…>Lւ s޵` 6l'T`K֑e5Mݵc>1mm|3<3U5_p>Ci:{6'I`O?+э ITZ樭;v8 n~P.W޵owK2%e0$AV%5Z?GD| +ez5O 5˫d=&0L!azT wqւ3:`QA@"tvе%Xޱ7-XpD &?J 9XMw7ʘ6^ޑQv`` (m0nU]ېwtj СC%TW|vcD *ϑB>u8(x(q~\jqW KU9i&6x Зiو<19,2MlCl HܨG }AR!8EH,tH%)DIs^|@'YF}ѐQ`Ѥo C(%˿(21B>Cr,Ss>y]---?ܽ0 2x7q0F"qtl~9bCp eݺ_~~ I 8G[d?@hXG j-z,Ms[)+[ezYE:gFa,yqk" n={tA^Q:1y@1QFguP{w1QhkNmcFS'v9OdXN}ٙ'?ݎ8?b '*mي]2(%X}L~ :`*ByJGz`1=[V r iTc֯_?%nv@3d`2)S"k[bf=łR 80K N>^0/5ů-$9Ep7?,e?d̂U0r@͸pjkb H`Irm;+qo%Z |S;`01Y=tݔW$=Hf:m  hzj/0x&5+9,Of0kLAi$m[G3=SWm@IpOaEW5[Fۘk)o/)9eD36m]x~}twxP5~8q۹3KDY_v H<`\xF;;)Nض}cr$K[l2v'8tQq0 7`2(ؿM8mݖ_7n?^aXT3سS a7l̙c91~_-ԟZBcovkpYg9A{0'ސx&&k5ۂDSvHj`Af܂o}9,Z.mf%2!,fY+\ ^]$5z,P6HkP13\BN u}~$#ݝ'H2Us*'ҪGhfrP||l3poqxQz|:דJ@]jnxjP=VvHiǷt^,e\pv|W fW/$y0QaSzQ-X.3.1vY*߆m`7}?K>'qf(sD`nd~>)Г[læ Pt;Nӿ6YON ,ЎlF,sO,;xy,jc?#j}0X Tp`ְNie-QX?`#zX ,Q:&_r&;NHڧ% |nf_ګ$Y ɂK@Fe!яZӡ ٳgn'_|}ca 7h# o%Ϩ&p iɀЁX !rkU0Wτ,[hLZ(n.S]3^z :@MWD]s]1 u Ź6#km̵^y=v=*9sV^mSNuGN4Iz93x85^xVEN@B|.48$uXohYz1w\~u3_xzg;flܩmޥM;o|glT*R~v_[v噗.ILk\j0y: ]thLs~Yk}䢏fCeU^~pG[8K fџv.\sD)is& oyެ|MۦLtΥl=b͙3G]V\Bt.:ɏ?‡\ӑ.4kC#Z=}k׮…gM1Xze|~$pDa9}^75R\KoP,Z !X# nwg+:zAE+&2y,˗ WZ|<ӦMa6=%k?ߘ'%VB{E u`yfn;hMW+'8&{g|ꅣ':Vy}%݃e"'(R\$.[HQ!9p 2ydgAd gAJػo$_%#o.h?]]4 HqA"%FTx-u i"Wr~VwB'W4 4+S i(`|p'Pc*1e?y3:!+a9"&ށs"=APŨLH`OE$0 E;`+f vC9Dωӳ?p \ugJ#_H;q=BPv#{\3 ?X ރ@zĶA1t>*l*s7@]ѣG˘1cVci*>ZUN*}*$Itoh6'CsGnu@Eӯ7xjy`R%ꦢR`rLNWLnx$aE d> (;p:X:} <y268,ԁSS:OJ)ҋt>}^]~͟?_1! `;x~:fKlqPVL;8.=.X̋"O<|̡|.]!sX:Ekq;ANm/+Ϡ#Kn7)|B滔B jua95yfߕ8zXثȇ",?!UE~WwքZ1kP-VTd UM n#BmS̋ քfyQ]H|=n_:Xb| ꂀ"Fda)'N6d"M)ґ5q̠Hjs$2"P C|o/l<Th yhƙˁB*\0 +bb̧"OOa3@u\miLZؤ3_w9& D)ٯ%ᐮLƒl ᆱ  HS>m pAk;gZg;k{(^\Bm"7*tTOڬgc]%Za2g6jG7+f"uXe+9zh3;Z9 a^&N8qGQl@bx@-|PhnZ+@%>8Y3#2u]Rã  8ȳWxց\L:UxUZS,N(Bn(@^EPytZV0L.:4hA4fz漭-@pUJ&彏7˪5[GV^x"y ̭.0k /Wc.p%Mrɔo( :\_vjܖI/w=OEP *(|RP\\?`YF3KεX0=; :[/"{ %.(XXdܻ"K5RbX8g = 8u]w||*ԝࣾZw)' =2 ~wkoS(̧םE;?qH9E-I,UTI(*K尀U'&dY>dC CJ6 bw\;΢Y2a")d}o:/ b H: ܉Z A]nc.?#4i^Fgi<?*X~d@tG@}Pf&+V;U*lGlR7'rMfMo?X}59ZyPeKZpHUV΢pphFo.vo E/Y)0YT]` Weyq*ehuvk?HfYU9CG8#?#I3g(5r 0 +ǃuE apE:#w^Ww˅-tH%д4Ф<̅b1wOR!~bsoV*c .'nQ&c%[ǧ/`ԩ[e;ݿw۶mRA^~ {kʱ꼆fU"B *Ekb$D b>:qպ%l[߇?]Y)τ$;PytE0yBt)pb#VzD'tVlrWCy}c淌-Ȼ(sw3C5 nYi6  M\pgˑg 1*37:JnbുN*3?m el^ԩ0pjD]"Q/Q}m,\]ȟ~F?ٮ7 PYUl(^@ U@tmpBXGXRRsӊj3խ[79"ws| EۧHACZg9g<ցF(a$;%䁹nRuqw}?܅VkU_Y 9`\<)i$6(w s˄>R@DŽݺ`^IsZP}dC `?1iAk*XXop] bR-<*##Ăr|x{U `Uq p3Y!{3(2&p&(3L w?(B.B#,ܚ9@$Syz0r#_; FPG҅I pʦthož2k՘yD^!$K8̞%0Zܾ p'+2(pڴi2fݍ}f~l;)E9hBB5@L"O2e>w1yZ'<޵SV򋑅ҬiwNW7_`!m>=9Ptz gwz$ɗ7mX#LvL-7o]:6S.\er&TZ;>q]߬Ydڵ~|`_UHg?EB7|ȣq5 Ey8Cr4Hߡ>۪CΑPPاoo}sK\30pd|j$>X{ dǸTT K^R= ¬ -ܱܮqN>*wC 6~̝3O7/y9:5dRlEgH@!Ǐsѕm3 hNGs*HS:Y\tpIHPZn]&Җف& #3ZʉGE0] o+,JTxfy"YrAÚ5yWO85m{)[dRk6"mvuzSK *N>{0aثfϘ3g^IE VkBb 8y -[,>p8㱂ؘ'3Z-O?>^䣾_@Æ T;X3tɖxdfϸ\9qJEaPuiH2*DB?[@Z@޴Ok)**&Dݣsjsie7wn w-TjaղeKUu]gYE Soͱ>K -K,e}hJ429+Ep`W_}^Kʿ *fPVO ܈i"QһO/.!2YqiJLy>$UU Ekn K-irUTk.?q [XÇ:{.]k>zͫy U)̫~'@*i(P /?bƹB첋.L*,<–B<&cC$)IWUo۶Lrf 19fpRv(nU$!tYG6߻*ا@~qr 9r؁MTͲLU"bYҋs=UY+lZ ]:Z[bg\+唑")1^!)ʺo]|M~5q jI1H(߫wO}FIgP8YkJp2UneYGZ#a 3bϴOj93_ a31Q!W ; @@ МDIe$䴓LYrX Vޑ oOT tB*Hh x?^pQBn(!gӹX#?g7“VEvͱ@ 鳷v(/<Цzw6ɫ;w0,σFP.7'ݻ4 oSб}C\-E~Xz1X 4Sn6Bҋ"t".MJBO 7~xS@f4CX ܦPI^r-x1$ xѐW8 #U~2M gMO qPWm|gTQ YHHMH I**p+#W^'o 58s2~g2B?7 9O֫܅ ɖ V>Qzˢd퀽w)yرc >}āwl;ЛxE~ ;Yxr'Px*hЪURIA=5ߟE vKeӏapr5erh~}p ?\: ψ/zW"%T᣾J0Ϊi&cq X[UY.c?͈%D TU$SGb<ʅB_:B s28&ԩ.A{LUwwf3ēy]ԇn!|Q 0H!W=rIkN:I9뮻z`چ࢜sH gc@\|r)pALtlgͫ! ڴii P Ck,>٬qKok`ڵ!e/​E˶;} 9:۳bv4O `E'H8p*H3~G(}#s1CMz`)Y ԫf] I,WqSQ"y)W^5ɫY׍Sú>CM֡ʸ_J!4Qap V^tNG^_6S6/' j2cVugџr@Fr5d/x\n8byuzc6ȫ6Ko[C_ܾ⽅7pm}+ (G&,ń}PP`9)>|x^+x%\W ouyUKT ܈da)D J]ŕ#f׿ a]Xs O@烑DSBʖa[X-ZGy?(ӛxſae퍅6W2{ =fH>%s,nG+h XkׄOJ[@Ûy?bgiO] 7PQ|NKԲ 4OR H ?EQU@7-Tc40-W~6Y܌+60*~;+PKŢQ"!*lO0#0OOnY-ɩDÐv#܊1#&B/z}qW<}?,ޔ9pV.>;8}:%Rߞ= # ȩX^W$Ly)RI%A1\ X7PiJ?Z'/U,6?@}9BU*CK8LFu8)"2sL`3ҽZ{d:2K,{Lp|c&Z4(Hx $5f}2>E|K4Wf5T?ah)p_hGY@on^L`؈0DbB*4t?TUgtgۮa"̏z^"xߺE#Ui䨣O>Y=z} pώY~DxwԤ;m-ZHXMy;#7``ᒭϧ3w/W_FTM,^ ;k o>)5}]v3f{'\]P`F)0`XV|2`h|-(,"OA)BH~EJWT)U TJ0ޔ"- o"3]c GVOO6mUBWOnj4K_fש J) U"sttREb8c7pv})DV܁TM_E(ln[: |L39-eϾHmlޜP,Yк?1cd]wZJrGAYGk?"BN3dd8[lӦtQT3: w]ҳ y\t2gt) W[X~#baܛ89ߕ Q_M$l(^.ttWQsT<eLYT"hڳn)c{]gQo$#?n|뭷9M-O.{)41g76*RIMGöO$ Z*,ܼ/Wh.ԗϾ*L¥dmektW-7?JdQKoX||q6H%B _ YaQ5 o߾c1TP>3@5sŞz) s3L:7y;ڠ6l۶t촳a?n`,g ~:K< PՕWqՐ*JyaAU$Q.J a*R>D1:40+fXfF6Ǩ|bq)X" ̝MYC Mip/;V/ 8ZsUX(><耻{t]@*-qS[ȦRzVU,~U l yo=Qo,rLnm?9P U~ⰸL>z]D)&#n i 8i۶Pb |u "$C_dXVFEeڷ;wGsvW&,*@%N2ߍz`U|0DB-L֭[%ĥڂIy8t9kC\ $4dhU#h?L~DfLYr8Jε)KjS% 3f:I8X:KNnݺ>'~Z.rw^'(665d'9p@&<ej_Wˣ}Mq_8 (A|>mۧ#v`ٹ}0dȻ5kCeê_[a'`)e ЈQMM$fcp8R)Jiբ>ϒ^f:cèp. uŹ+BSr?^F,jDP  h|7Ӻ^x!l 2D~߫9*BM*h 0k,y塇E`c:7wvo'];5kztmW^s*zV̡ -W_lZ|2DȠկʧ˧E@OqLMV8|~^h?t)ig"%#K'ЈЉ:ƽ)-Ȣ[|iBCwoڴa0QU0 +h0K1ng)!yRBrr#XSAPIl-oN׫VӨ3Q<8 88pOc9FQw[NR>H<͛u'S#?U^:ꨌ3W֔*3X4Dh>d1PT~7 `?^Fw@N/Vng^(z7Bh7r~B?hV6E +P1 M+kƥL'D+,kVg&="ԈM6ϫi}dF Q7@/P-x c Ы9fT_FE>at6 7"Z@8_7πoӧOW#F;S-v -Z?^0@oO7V> 6n(K,;c lݲ nGmQoXx<) lr˯No);֗˷6c H5t{1 VK -,X dJf<z^+P#.&&3d S7)RVc0w9(Mܡzy wv ϰv3XiUPD6 LiV;t9 \[7 *ڣ4i$ը̄߹Y죀[>= iJTYaBe]Bw o5=9Hu_ [(pYU9M  TЙ$5M$-9VH*O,a=*4lÔ7lŋAg݉mh )UO4IF-[=Sh۶Q9ڵky?4yP@a Lm[Yp̞=[ގ;fl^z2tc/n>No 8dP^9k׆+|l*/J'ʁJ 9YGh}sp2w}ڳVS?b?pbq&{u=( bNÁyN" $L:Uz: /vZR :CU 0棉5Q@%oHzy`u5{E2w{!6_6G3zGOF86nBgkP*z G"L3 2;tji3qjh+&v~ӶŌ(s&V##E;6qp, 6)oA Hi:/cYNᥗ^c_.W]upj!x tU<_ˬYԡ>Rj2s,~V^-|AeСC4sʧ_{"izj(I_H1Bn!GӢ1qD?@9{}aZ x))0A#3:I%J'9!*.MVӄ)cI۰V(pSN3? A3a;'QviP1Ͻl.jd)9 tܴg:uڣlڢysw-2f:)2ͿR46}ٸ*@yv޽tVEK^GȆ*6m$. $:7Нoہ2ws 6,];/'TSv{<묳/QBݿ-OAD[5Ð:")'{T>j`R:i'5Ț,\|n~7L>(~ʕu&iZMSn!NS\6fLCGU%p= (< d%w&<ǽcG̝)xclJ"N݀݁o1kוqQڭ4($vIw.tHS~ 7;(rXҥK-[fl^ǝȩ'4׳EE;M2xry䤣 *xD ӥ?kT ZF#fF>uɻ7QU8# *9)RJ\'R,#yuzNSn*fjBǼxkUcЍj%D.և6X'§`:` _pRm4?3/c Q3 6LG̙3u:TYRׯ/Bwo?9ꨣr֓۴BE˭ZWSYn`ie3KR R2Be>=`L74|քyFfe\[sI]\fN~-ފNG ) GDӣ`c~< -f Dd Ʒ#3Lt&o wsi㏫ic|}[ܙӧmV%iǤ|-_}.]:r@4l 5)5Wq 7țoOgـ:/A][R2 ++O)ĢY&_kHpw$7d܀]7+ I{Տ5ѡ.Y@\Lv(Z2 a)OUpy9,S\L4Ѕ"N0c |h Gj?> v/`c`3Cͣ4Q,ڷoThӣ?, " @'-ZvK#\py˰uG ۰,*7a>OޯZ>7ty4H(L2nM@m)8ʀ8t82ZԕgUg `b Ou|c"7NzѡÔx6X\8r~v>(u Y@z ~s9rq S<hOSÇˈ#䠃RӤg&z7:k޼y#(._?1 PSEM&u:RɷG@EൖHĝ4G\ʥ'+s]KLysE/.ƟvCoC6c.mEj(0[% 8,2y: G5axf%Čh;L:6so¯Akx @k;L~_频ymӦe8餓OB¦Q>LnyWaI^:M:[P+>ڰU-*@ddTP 94&' ąx..m6x 0ysRbM<)4Y.{$72; 01U;Ka`ָqc٭nq3pg'|@@xX Ffeޖ-{جY԰@D|)'/ȩ'>cO0O2R'9 Qhޝrm4!hک&(@7|gz-~<3z> ۷2rH=A/"+t4\>ۡwojTw}B>`~|G@U@LFft@/,%uY"eow[Ѳ|SֆS3"z[.)dv2IWy)l?*91i\8.R4W:9T+c%Ѻ.Z}Ӳ2'#1S;tXL. &{;DC=MƧL"ݺuSGrf!-DFINd]vwY6m;T '_S :/eŊұcGuHДd?͛}`~W'`]W(p>ڽ 8-egww;3@.ܹwB8̢ބʪ%-͚5S >ʲ yN(0hX!;Nfsںg[M@уy< px#.L=oݺ5.4y; Vvᄎ[R3֣"'O;S=Lͷ:_*I|Gԥ^jR H DJ. *'hF2*QhlB)p9:ܚNZG%&uۖ P> |} m{5ҥKܪ8Lr,ߣq`)@ L>>2[ buώ?]CUmȶe$a^FJ⤦sߐh FZbl2#&FFoޯ 8Ԇ%4H<pʱ+/_ϕ[\K-1~ӟ `5QR?0k֬67导Js?/%mP 2Vqby&[G*Ip)[keD!Yj+tX@4Y]uÈrc {0YS0T|=VXf8)l$*S_~ fgqL8Q֭[6RP{キ:<묳䨣R+*TzT2d;s:=z,|y-2цj)P DF@>+t82 Ly&NzөT{>ʹw>9,})[6CӜ=] |6G[x VI/rꚆ:yc07.[_^X9#S̜P *h7oڴi-;wN8@uX.Φi_wu׌k3N75/ZM͛@|5N(TX7n\o+Dܳ|(*9ł)okjN?1W](BW^yEw0tB5(PXX.ynN;X˷yuB|'n[1֥"r;ϐ*[,u:~ڶk+;u <g0OVpo| QhrܬO7彷YX ' Z0vԿwfR;h#w1PDi贕 9m$$vGmIo&NٛKR` x@ tLwWO~UpgΉ,K^ ]C=Td9RZl2H?ªwl2y'䣏> vBE/g6b[ Ԑ?9~hr!'O}>G.~QMOӑw^Sj .Mlø#'5T˕3{29}{$ #$ 2PxMȱ;Ѩ&f_iDŽ,k)fs,*m> \ #Ç˃>ghB o}W1;<%%%5 %l@IDATC9$؁Bߥ/XOjVȌQُb\JԈY#ʎ&nBra%Ɯʌo$7wek%SڰU-P 22BBsȸ,Ɉ%GM%IU4z,9|LhO6M$ {kիszƣ4&RjRWI%~<̏{͌^HG3ϔ/\>CM"?(0{޽?}3 6LϻW_~{<7_{~;R`)P̚]{EH}^8)riMb`ZY4V]=?uAAP vE]PN*B~Pݣ] R,Sĉeʔ)Nx:4 'B|o'hVK*QNˊN"S9nf\Ne5ȥSi-NLXflmȭ g^YAuDFajdAdh^VGakA&*(mM"u#R67;S'.(wu]rꩧc=& ,֡CosΑ .@t"k֬iv8=Fr̙3{1wӈk) DJ0b\H4Qd8auwRL4`S`m08 6&I(`-jSl\Xézŀ*ǓN*uB[J^iŴ$˱h& R#V]S]y RC… .S/\ҵkWehhٲnƍSEwy_@hŁ\q~[?_![R'P峙W5 ꈍЉ# 9! "S^WբgZO3!.C72Bu On^\~@2Y 1JYh6f5ff9I RYID:;ew9HDuM߿ GG3ƎGP|< [R [P+sEGdtG&UZxZ&^i,1mx)r: )V(0p3, ]#XxJǣN:9N7aF"tLYSY/d|50Px饗S<ЧOi:nS]hyJks} M:蠺0O O|c[ deÄ|iCԊDywb r+jSa҅d<^m),}GF[Wc"jER)*TiإIWVX0kOW4bNFf[ D^q/g?g-?̘1C69Յm۶B~@}ݧ&|̋7f||G@6)x!%DGJ"ēI̅rb҂5dz]Y}ܒMՀ]D5aQ::8*̸0(10 +';x'b;eܘqG `a(@ǀ<4}"@ t8o욤7Dk5dZ Pp'($ʝguYE $;*X+20WE'Ӏ(\R :~+..Oxx)0sL{9B `)V DBF|x)nwdxE;m8e ЌR ]O>#⿆ a70@ gUꐁ%11t& $04TǓjߥ8uV6 xCM2n$68M[ X &Ap@7a3ϔ!CH^v}(]ضmp B>`6ڿ>ڰU-,@|* {ڢ|hNH2%nmQb-L5:}Ekp [Ȁ ?VɜwG/--b.At,N 2ćњƉGR^h+=qoe`&Æa:x+u2`0~x[oާ q:=|G@(P^检)O^SJKC3v< ]Kk(4%p}@sſ7a l̚ϱRٶm[4XvlٲEMlhܨOTtNZ¥^DG1ȋi>C7eM}Raq3Gn,$@GEx+```@_|RRRUVҤI6pog-?ƾ `)f 5ZJNh/uѱ-+Eh+Rx*pgY?ķmu~F\.]5ptrJk5k[~k?fa|)poZ `ve%xqC<cInئ,,h =sw!P_+\N @;T<2mNd q @V)VKݴWLcD,b&yRQ8|w5f&Z\_Q=S\2&]x3FJl| x4!/72r}eRbnrܞ5d[R )РthPlhE{|o*jL <fzY'xK۴My(`byG̏7.ȫ-au|.tTwZ7W8y0C+^v*pp<2Px뭷Xȑ#e(p]v Ox=#<.&y\ł@H(P>NO{eDw\YL%r75H0F0iHĦ=''7m>SFHm`(|ry^x4_9@d|"ItZڣPR9]'U%Xi-idЬ L8{/p0.AZMH$|. BQ1:*DLyQҎw:؆Q: ,,>` O6˖-2a9K7ņȡ'LA}^vluK\QM\ $~(%K{L-cdO'&`ڻ_nʹxmwmPB'B)`9&xȻ7G4kD6Ok".)=B2Y3R;\73m`%ʹ |Ip1vp$P`?`@ǀp',rS۸o SOŋUtG !@^iʊ.zf5@AoY&ܴ$` !yl>yj5jfP`ˀd׹ H -o[se}qMq x{'-Vдk[%o`|nt4q~qFz:rB11¬*B Y ܽ"l ֭['G'ʩC VZ֧mf(**?jEy*':`)P(@RX~դxCqy/=,vPAFRQum\p~;yJs !Ulh #cMzouΥ(PrL/d"Si[&.s2*2\MÔ— P1_r Lي8}|X@,>  䱀{)S^xh)'bf͚51+nKY 7rdiĂ_y&%Te`ᅬZnH%MP(`u%d1";lk`cMXh.!+kU2&LX,q,R%N3Ȕ:&  ?wz-OOTgCN:{WU{|;CHA K=>\*R Ӟ>hO9ǧZ? {gtv7 _Brw&qiWCB6;:tJ%á{ eհ~3f?˻:0u?uo௖W8И߸uŋU7s„ Y:,塱4 = /cF-~ށSS9Ήqx @`D~S"- W,R4}K? .HN>sOEn!ټyX/߅O+)(8U-NFD*E| =~anݸU\U?OS;tu{p< }nu=6&om'k N9cƌ#޽;4Aڵ{Wxӓ>;TNڡ?j=za\5xNI$|EM+mۖ|+_IzP~5`:4pM+ms.l@ ՄTS*+d\e@$\>MW(zĦ;K;Ɇ 4PnɴN1&Q qzP*/~ SmHOfƿ^HfϞ=`S疮=uE=+f^W|JSҭog*J&_:. !?WU?&EMӪUO:lǝB}{_>U$E-: y3W$̍1-BfV &Uy7N{kNXfCۈ䲿S7 -jS>L`֬Y5M&u>M1 v,4=saƵb\\9]]kB82 .?-ު8IQ{ / 'xbM.;Wdո$xj} d >tdUq b1h:Q6t0;.0TʴSXTYz~V{肯+86Ǩճ/{Z ]Sϣܜԝ6Siozsj]5W-doi84XwWw3w}\ W@\v◊G(~G1OQo6u]#<ZoNjy5=lͮ;{B^!Iq|sJϢ{hYXNHq`N4M<;H?ݩ" ( ;T?5'+&Uvwy2/8#>}zî5N*{zA;ݿ3R>ϋ|?ou~xoPf8݆#Ԋ~O@Qy~_&O,[,<ϵ(¾(pNf;vS0¯ZHrTMZu=CgzSiCKv2Ng.B{qGH6ʦ&JYq~2 Ο @.'RXkUkJPcTYsUgT8Xyn&-COCR[y:9k_ryAe} կv(ܪbT/Nו֓$} pFj: N/DË@c>'WpR(.-,l֞愄gDMo)ީ8IQ8}t_ ⋓N8fl6?:Ps=\?S%3vӚlTuXBôZ=XjWqEt4\U.džUj?e}V; -KkSN۷2e kڵ'Nlf?䪪дsade^-4s `'wZEB(\>E͒r^ pE𖷼%tZ6َoNdݺu:;ԕ n~Ye\[~o>;Jq,ªe?JkG(j2E ]xe%¬`/EC Vzu6aqBtzO]AɚTZj*-প;R ud…F09 Nĵ#Q)W&#nq~q˓0upO)|z5K~vgğ߇z'Xzu},kzhUR t)K~]G zn]c{mU_ӿc@ś\E;+v)zP~]Z-L} cu:oc߬S'ǑZ\`hUV_0gwE#\4iR*U;ԟt;IXJJyW1S?$hn}:=?m?RVQ~6nܘx7;o޼/W^p =gΜ?ɽޛ~O?];_᧞ !@/Nzr㠑RXFنi+ִ5׈O㰖+O@Oe{7w&t ]K: :bn=y MQ5.'żչew9g}\t/cЂ6C:=_M ZCM2XM*.SLU4,w!yꩧM?wꩧJb_p+.]`\Owa$?߭ THMVX:Е^V''P\gm{*2dC <C/jOGG"6ZW6ӭHm @@>s9CN=stS)CLPgXvdOrX{+մ|lph5v ܋%K~-xIEH{ fߨuYՀ&?={lW]Igo=:&[#:j A/+&َ$KWLHq*F|h"eana:PG] Ts7i)yGRP&&}:?W|M_خ';PY\Gs#.,UqdTeH кn Aӻ8St=Li͚5՘o_Nec`7|ceŵ ;@`Mra[$Hi EtAI|_ٰ8|_z9O6g#`w3]qbthV ,#/n+Rg;腕fUxʔa4t3] JeѰ^>T5+^z7Rpg_㰯9~vb#ڠPSNQ|ZC9Cc}K^4oKc kVG5,t?'&$h?_S[A_{)~3D`\ |PW: #7X^ZYhn$̌7tZ縟|lݺ-v)ޥ#]⎥]~mvt=~-[lt暛7oMv1SͰ, fa_\Hܪƒl.5ܙ W_FqC ^I psXm[TPvv#]-x6W\yabqi7*djOn!Π鷢E-}\^ݰaf^N><~W]jfuОt~ɡ;9-fm~iΆAZ o{X%)-v?&pE <  C𿡖DnTe e2F~h5]~uAڻWu[*6|Z{Ѿ T/.VϿ(C٣1ou%JjkpfqY3 L8lZӊ0Z,9IN'g(ޣG-- 7oz}.7X@.>dn[yXdJ+e7^W0PX|~j:U6m沺'mf?riB:j;:꨹sU?<4kzHy^/b̊ZK?ex xp(QRLSоXq\EݺG7(lUڣ[ԜZ=az3ʣTRLˑ^#F+Nnç}AFy2WU?ݭt/hzFV!')uS%'+=̻|奚o_kl>n>#5LƼ y/EvSwG(&+T+xzՓï?\WB !PeVbwWv?ȍWzsʭR<=1cFSќk1'N|T-\jlep4{>uzzmX}9N@ؖ?W`,Ņ WVt~>)(U@7).w RY4cOU>u4alҵI[ Tڵ+ٹsgص:4Xvz]%5a?ƍWT&;|hժUݻw'{If͚nGs~74erQg甚X/OװrܢzCvxk>k~,>pR■pI'M~}QeP,U|h6 !~_[WD*8S.;Ydz# t~kɽ_E+=okvߚ5k6 Η?4g&[t.7O#z9M4iRh ߹_xd޼yɶm܄/\s8PZaY:K?+, cR.2FS F䎤T6S +܏_8A᜵WQoPS!&GH\gfC5O3G}t?OW^Ipeh'PYyO>Q-oQ؟4N&lWM^p O=P˗/_LWM:Y^H?DՄ َ܎>fiI1yX0tMuվv@̚q- ܩpO]U}s~0>Rr~~C<þMN9u2(l" KM|q-o/~a壏>:]s)g9Ywe~_Ƕhy(P_y_ԸpkwFJ7,[l^ϟ&s]/=ܳ#tgk~fG/2RO?$}IK]Г`ʕ+w?~u EGV<;Fƫs~P*US6m4p3Ϙbw>K5cƬ=WHt?ZY[c.X{mx3 4Vtj=QM/Qq:6f>]z$~Oq:;]f.*l( % ƚOO{-(Txk6!e˾{i]ܶTsbVYI6in?rfJOd^L'Ĺ  6j ZzM{sV˒3é0"O8ú%wuñy7+j_rYW%!PYPy6shJ xPwCSk:K7kL8!L^mP3-qp%@3$7os@@l7_Ѭ\u s!ol2ɒ׍éS$ }~PW(e-n@:7bPK̞I&9~EGC!X=j(p4jxhv Yb{otr˄g+W*,gϞu.\t'!Pu*NE@-7}ؑԐS5C 7RN{bM0e_fs ! */LS|J/$ vo4B9|Q}u'/Ztґ[@3vXV e[ oX/t:;΂3dq+4M~<>}sR6?X19  P/^oq8_:ٳ7'}}4aV>O׏dx]-4ibrqǮ}_58H5V͎ˎ+^?sԿQC\+ɨV*nבt8$otF}(Z)_@h>o+z7**L/kgrH}]V#T5-:q7rA35'"裏'W1e4SNXgs5}g=y[ IDAT^ ! AQ((F[bӪN; /o}[J:ՕL<9&F?LOK-H>owL6SlI*_us\3}~ @h:;/nοԲ)a݊e+P@@J_+|ʁý٣mWoEkia?9gϞd޽~79ɜsu\tw<\ DĮŋgN6O^(gYU%Xr!tAř ߕ~P#Y w޷ZBq% @@`3_ N={ߍTA[ .@hN6lذGttt2|<|dll!GDDT>vY@S Ƣ"XsǪ&),-AkBh qBhq=<^=/" _4x^/C%.D1'aA(B9s8 KZ!A@8?#I!Ȭog۶m7ffdhA$kBS?ַrG@12PyyyPh1~;_2*߂k $V` .F`k VZj׮]1**Je9`Ҧ7@k&{xء ׅ.y=_^>Ξu./j+=yqkV a-R@KA&AH_?_OZ(\@w+11q<ݺuС&ѻʅg^x.s =nV?|}==,K2?GACMT>7*)F/oָ - 8"W W 1oXW!A6" @m|RgW"90>}YG^x]v-7d>M'6ͤ6MH|tk[ye `,,(2*SB" >ZwHw)E= "8R7{zA5$}L|ސBH`kg ,S /Ӆ,4͏!Wm>C DALrݤ:S/G B`::.ֶoo2ssTwU`<wk<P# 5ǽ0'5z YH[- &ߘubp1pIOaYp^'~py*&-b@1WWD"~k'|,$x,x죓~1_~Z 6 `1f2kBւaC=cǏW'RSU*DZGPhH岤l.f" -%ses s!$]{ /9\ $xҾxºo=zOݺu 4щdK;rS>; {' &{z "sK҅>ET4p` `!A##҅ Ȑ!Cze>{n㈀NB=RRR4y$_&C(ETs@Hp[DpG#s1-}}H|>4O!N['Q8p@:xPE/9J^3U JWC@{$R #0KNıp惃]Io4'IA{c'NhE޽fG Sp¹`!AmmִiY#GŢ;>{7OO-zs ='IH U,\GC140C 5(5؅"9w.3·v)Izǯg: ߽kL1k?!70G=B@u# @u#.spPq9~x{Ǐp= t[=}s,&᭿ /zG$Yi< Q i}cƌK~ƴ{ZnާsEHF `"ѥ[lE@Wrw=ӛ7o>}ܸqDcZ_R ЃPܱCEL8s0Nŷ[B@! @A+➆GBIާ?@2{WH [VM %FS 0_ .E@)uN~=}˞>OS‡!YFěĝ0>-6B@JG[ d>օ8`sKi.8ּ̑pp19̴$ *"C2cV[y'Tцkp8ρJ10S!/A@> /y.FS;X.ξf֓ h.` yIj> v?x' `*T| 4qHqKrTN!/] H>C*$# 9ZI sN=Z2{4Sfo6B#@ŀ]Mĕ -`Z 8,JN`Qӝ.F͗=_Ef͗ȃJ&Bž‡=u` }`\@ nՀ u(2+P1ЇSXCz-UdD纲=`&bwO+xžOZP̞P !Z-Ћ^|Z :Q^AB~ڍ:_m/e>ٻy-=|(A._ s4>G} DFah `L qP=b!/=Cs_ 3҃(˧fczS ^ ,ELggA`M)| "Hg`*PB4\T` _Z>PS؃'s^Q!K&/Le ǵ}7/PE=r9_lk%>{4gS? k0j'Pm*ׂ#9V oV;{g7`!CP-E`RֆsN| ~ЅK:2pp2P+bgB(\X`Z؋%MlG)`!A.B"*[ =? OkU=]B.wBZAhhgOZHٷ}){B@e'my\k03C0@Ϩ9xGjCQ׏!ijb f^tx4!AD"C fFK$g^PAQ!Q>`Q/xl|mtc&y0!;>}?nIy3f̔ƽrwF*= px?%=F~Ԑᙅo~j-{tp ;W (e4,d'Ɖjq`6|of-/Xә3g.ZS5`8 F og Elrpz ~j]5gyYZCbuN>J9y<,f~(-\_aaѝFqa35k3 @ #>K"T.#kKvUx\R' hlO5&,P+\umĭ|uW8qyzv\8U)uj5 #0u F 2 ~٫pm"*sI`6M4/RD1q0 p)7o.=W=%RAEL4s@ HG?A `C!q#pp?{f׃k %W/S;JQGwoCO,;bWN"A%B8!ri"X_{C6EA)fTYQ8"ohHYG;\?sc vF2Mpl$l-0%cлoXPP18ؚ|8W5,=դxBiwsh0`7H*fݬR'kF9q[]0| c v; G*dfӣIp K?_uUAϿ>yϴi3 (000/`'sʈ53g6-4B#.lsx2|=12"{fOLngMϳ-x=v<6>44;<L!X[=Tt&L77o.ϦΙ3S͚5WwC͡ pIy"qWs={' wJȋ`ǁ{=c&P^G2钓UTTS5x\BB @)#`yiK؆TY>v]F`rˡT ~nP)kl&Bkӡ5w\ nrѨe"k,*fl}TP:* "Bԍ࣌EE@ge4{$Jj۶KcPJI)3e !)QѷeF^xt|Px<# M{^T%^6t"b4 KE(_;AAץj:zӪ oP)*@T^MEErD~_QO݊Ο?;hI~LDeN|k9q)Mm6ᛧy# @Y 嬀<^\HQᲇv4h4Se`lƖ-[c _N'Vpܹ k4a{l޼f̘MP-YvS=Cxj/^0 G;奏 /TCPCo 0ބ^gqx{إkhȑ\N.nh5 ssܴ>P"J|b/꩚]GWT:#G{^خ]!Ck>~quD7Bic @>b9rpPY)* Rڂ(.n۶|('E5E|Bhm|P ϱ~9v9 \[Gߋ&X^4O'= ;|X%[| $W-XR+e >!ȟuiG}L͝;1id+s:aƌm&!]$m ċoɹlempSpQR%[xn=~ d.DE#nH۰iN}Sɢ´aK)0-0S'`ߪ?~Je⚛_Y^pzƱ3f9tT!0oB}ݮ@nb]QŻ  wEfU4|MES~nF1}:fa*x!*W} Ј>Hn6fWԩ/nw2 ϡcBo®3ŸYj!.j e7Y|Vc>^[m?#eWm7B@Rpx\ nUvNyyV+hjy|5iu_=Es7 ->} egCkq_8 ^p=BzbccL_ߦhjX {O9"N9P馲J@.G:޺m`C@*\-)%j.BUn@^ zhpp>?vpm 6dHeZP0_U*,fUu޿Wq^0hj:ZUl6;iuBu~7߬6mCe- ;<5m͖?͛7kZg_}c P ه H9$V'PBՈE7* x >swesݵi?K? uen=ݦMSVE'7zUG4=~\m]Z{_Cu-XPŶoFs*~RI;BդIR)OFȨv0Z33fl/]چf7aΆ[`wkP$&Q<@ ABa>=۩1*9 lmؿשL3IA/g_E! 3/ *+ W@UB:4lw8*oetCepó>s]w}m 9mMݭOy؋J:^QM ٖn)1#'HxlmwM i`=6>UZ._Z?4T;G5C_@N޷_} t͂.B`H͇a/TJڹsRŸS e^8X myK(ǎG>XҰŦf fyhlIjE?j 3p . Ă;C^Mi0v]XUу/0mŪ8ΩƈnR}5*,1QXȒhXb)} Q`68Z1huԮN֪c D ,(j5fAs #qǎz駟)5,㏩xD͟?;z/VfPYY5u]\I;V+Eho`S}NF%Z!U!T!.̺'_bX |gAC| YMD `q|GVZ3s!N\S1 ` r`8UKᆱ6>_U k~O6'(ȗdzζisBJhsb(j!~=P\?TvWqlÑ 7s\>Hڱ{} n_{wV0O?3bC]閑7ܠXRpܑ-n?FPEGvVR5s޼9]# )hͤe~ls8VF~<SaGDT;jIjԒUHݺ;oo\ϿT>p5 0?BƸoQ1K b,;v8?C/0!l7pG4ǡMP΀%η3b*1Wq${ b=1p?~WRo>IÇޏ>կ#yC0_ut,#1'Z6"c>nwߥb+Ƿo3CRڄ}4.X !Fǎ:Tj{ ?QD?򫸨2T2U?-ceAkErhJ@ȧ,~A}cņ{(/_5G]k@4@uvK># > ?~j7R(UfUEgdb8 \b* %iӦqƥB c(@-_k ܍^7u3ͧ}"Gr#@'p hNn?nSplv]_?jґwsV}j0OH/WRE zgAJk `tV__MH=qB!.P|is u), "L~ڻwZ-Xgce`0.sL6)EAD{t2|!E3v &2>fD5p5IBv^_VE9Xxި6o٪;N>|ٽ{zE#5RC:vZ?g:ObL֭oTs\zxҥKs.l$|0}>JpX[`x?xJfϲ/l~)sVN*p&r톥U /?+x$2Kԅ >uڶUc^:u1j!`TA˃7_ۨO54#i߰N{enBPB7tˋ2Y&,@ >8OYopU0B`0hlE}Ba?El3\Fvbr\ddQlV'Ǡ44lPqT-+]@|e K̆Лz>>ׂπ>c>LE4N*X2:?*=uI؉ms;dU"@+L+.WVt*0>۶my;Xhhls. : %*MG5oќp`wZ|+;W&7j;wi¿ŸpOrq˫h}<̞]jUOӳG+ ~Ti QP7VGTS?h\g [Wӣ{r/u{Qa'@ j 72/>cOډra gsg ~p*- QK6cw'ϟ5f {錯d+S1GO,0/#==8)V9;ZG \4``ĦM)B1@Y>l_֢omބ ,}f}Es( ]\m]lRʮL_w/UpKM*6q<~?( ~ mKρTXZ,@Xѭ -X3 4a7\ X df" S,K+@U!\F-g:'OnʕifB>3hhf[%T{J!*uV} R][7_}Ҵ}{YzG_l56z!]PtY=@N[}*479B5F8@sͅ>_ke6kkc O\8:C11uT/mذ6[?A[Wp.(?fizc jP{8A?XfWX\k{8r𸰰?MPh/ |ŸI`(}|rZ@J $Dtֻe'=`8Zu>! Uvmʉʉ#|GxO#ݶ R\ߥ>h;ilwGk 9r!?LaO/s*[< u-߮\2Ł<-)-4l@-Rm٢ON^vҿjRPi]xoHHaԉƸ ]sHK߹{\I?vϡ/l~[_{U4;Q)/=MmĘ2{:QRXA[JDF$S=]NNn-9\fQ;w+p9 As*yuf khڿŋn~D_!_2:\G%סFt2M*8oݺŰo<6FA";H. @gƌO6M͞>Ep dŸZV)hY6c|6NWϗuN^xYq]u9~LmVۤPWW]˽4Y#K"Cꃨg! 3{dˤmsr.܏3aj4:p ؚ`^x uGd *U&eu+X֩|QtF HA>YrKrL\&dvAwuqZO*s͛KY,?H `Z&^wN1fđ%-{n6ޖPP$Zr S2BIK`C:65hxȕ-);>P '\L8BcǎQ=z(񹱸7Y+ٝ? ]EIB..Һbgϗ&۹ _}f𷥯#g| :x)[4o,b!sK-܆beoI%Q-N\ZۧOdQdpۗ{,f<8}򙟗JC&C_9F6OV~FDZyO$| N*[ 8*CREpBmV|3qQ'.E(!0aPqp@&uQXPOAH96@ /@֋n-ʅ͆X P;ԟ4ŕrB|Jz<_ gBDdVry%NkՉ77>jSN-ٳg.(ht`O??=؋XH.>5h9 }+-9f޿7~U’i"8pHꃘ>UEU!]ැb!_HȹwOŜ9O܀ .W% 3dg \rwFV\ a?g B8T:q4x0 SkZC4[Yd>g,secsv҃i\(I]@c88+ǣ]KĮa7n9}~$wÌֿ#H}6N}HN~C+LG/D\yS.ZY^ ?  l9Kmuq x<28`@;vT?Rmڼ o\hP~fl[S϶( ጓkOw4ǟ ,u j LSt_yYlwz{S?PEq'O}ڲÄ{mѲy(/Pruu׫W`>/OZסօ.L>}<O`yMBnmԆfQ=gT~pcĹ&z.S@]r iNm۪Og`C'(SaL:{0 PaܔlE\mR[`XG*äLsaKP9 loPp=i*XknpwÊq|)xB )!oX@ɉڱLL}'|rdҤIaQQQX"޿ϡpLnѪyҥ_e r8 .{DhR-oأwzB?;W3ՇaPR0@R6t*Ug؇y7 SYRubˇ{=s 56pP*pW޻{;s6wv-Փd2ЩC#CσBN" ㊠@ WMSWR>O Zˇ#CXz%lB0Oi (Mќ@IDATŐѬ筷U|d &|DcJým~￧#ͽ_G7@Sh|5z{^ #ǩAl[xOpb}yŵ8;Vj6j_/T¢Pf_Sr-`KSNƶ<|Ҏw` Qԉ}iii]Jql 7Q6#KTU*ٍ@8RU']נcξQZJk1_} !uZ:V[|rl~@Է6uZU FxF?C ڽGC#1:h?Aeb={U#q$0**aCg GHZc0- r8ր`~ѣ* :n@]1\1*͇S0ZX0Z'=G)qr֭4 `РQXb6n39IPa* MŸ;8We6 WY+BU׭+mp4.,N\9ML?rjn =|F+pr14Xo>\={3r_9 3,im.mmsgf_})W8*'WսJ( @>zݟ3c< Sǭeʲj%vóoc۹=m^:W LD8D].lYN_Za}HFB`u^p싡H(q% <Ӭ ذo_<0I4Gk֬YקO?ɼxYCpiӦ/DpRVxd[n08A7_4UT~8DuAC.jBuuc;Ŧ/#4SES ..^* Xhkbweb]~h߱_xQϠĪX<4߆J֙&|.h(3F tXT*s^y"+S g" @1~ S-ƏW1XQ2}vw);4 [g gc>6fxlMm SZA^v#F&$$'u-;G1p uRsT-jFu7G8ޫĥi oyP:pliz=nE![X\{LbQ>DmIm2g`?\IEJ3 }v*Xr>=pՕw+oPMV-b"dbUdr3S=)UI6-~^"}QF*LӾqhd6Ϙ1oysaCgp m2raMC͗^W a] (vk_;j = (Pm?nD.4۶kCN+p(?MtvZ/.lʫ`@=c'鱗ph* ! /=zc뒎ڨ<_ >(?zD_N)mKjD7O69#㇩<w°=Ͱ؝*1!^2Z妥ks`A"}Fu/4GpCSPUJЁ7m8r֭2Άf9sSO#$AI<$E$>`(fS U,;y'R2_5|.ĨcUX鰰*+!p.QB'Z?3s6CAd0oDm@)0'hm+!(+c%'2Y}ĉ*kE?{t ˘)~q]2U9ǎ\T(Y?.S!"&6Xe0q#B3-NYB> N?PHd6š KjOT/S(SSŁCg\Z w*@'ϨՄ+4'?7!9ݽ} KO>e{JQ oh Pnq؂ wy⧟ZxL ;#,>I[Ҡqbe+ 19tBe,&:tlRn)8_Ru#a ^)04lss}PuQuתXѨSSՄ?WoKCuK/uTbh *y\e/KUx$]`|:q|(~)ֳ߯?`uG_SF.UEԖ-&KJ}Y?OOm!?#1n7WI< ?JY},}[jr㤊-0|gABŹyƌD顷aT*fXC4Ӥ}̕Ŧ8h2e*lZܞVzb6m:F,>2Iߏ R vi _D(KNp%otan$~v gQ; |`wcpgJ5@nbVp~b< *ʃ{C:AjuU1]!YA-$I%]>^qS1v|@c(P5ȷR*Kż{V{s3aΧikz4GXFgʘ|MŴ(;G5&*{bMGVg^Coҙf ܭIbY6>}z>CR[*>xݻwcģ BVhUD<4u#<$8L?|i|yyܰabhq}2vFp RorBa}XG|yا* 2ZyTy j0<0p֌qVߦE>",Q9sKtts\0x%CeV( %o %S^O d{sl_lۤ_ ŎoR{ƝΩQ^O(p(ǟXT7NBbcj: "8qwuw!: {^=GbFE{;>P Ȅg{xDtBNDAz(}=z_@Аhp49Ć oB'T )2 +/Ćߔ+Q9JzphW&cw SU]z*Q8Xr3Nr΍@mv+ª2+ۯmtݻ`;X xXO R6b7|%)`Zrjb9ktP~}?kaOܒ ai >LKj"v[w{]`ݻw|tNʯ A زzM.+ Wj:r3[e pӥJ6Laؽ[El?gõEPY\! a.<0NnބN8{_9mb:FdW?#u`-Gƹǐƨ}T}?"Aw:l2>3x`015*f= 㷚!pVD#ԧch[T&ٮ.1 M%/횮_=oﴙ'vKFz<$P90Ç,\0Ow]ΉCf_{"9Y%OªP^1ޡ48Z V-+=UtxPY04ƳDi4UxNњxש<+ENnx#2 oBldSGov>V`5ܼ=v~Zv[muWOqI7Oξ) kf%Db_׆'x){|"q3i97Ӷ%ݧ= fF{0مi[6W.NSjkT@bs)z&TU+By@t^J?NKlB^O>Վy)r\3OoB$L{PhrsZwꏇۛ#i?SFec%P b^Ʃր@D ~5j6¤ 0}̙<\C/m)׸ =dΝ;7cO_sf[ f$J2[ZS6 ap9 I0\kր`|A ̗È9& u"zqQlyg@ִ{̏NP vJa?^toMAIpv;sh B/UU?V6~sV$cBDwܡv!֗_Rpj8` EEu7< |H@艟rLݿ4a(Q W9W(>h LpzX_`i&#e #Ӣp/NA>B U`Sھ_%j֬P6" ǖ-LmDE6GU88a#6Ď1+ˤuql"Rn,'K%كmv:W!vE ó W *\0|>`: Ri:> JrJJUj6(9>T8q>}z7o—@o X`,ʧi$M)ʤh*#M<*O t7ԛ,K5gUH|͆ǑIqERcVug 9e-0YSH|Ӫh9fˎ~w|=ʿ[2Ƽ| D\G#W/T8􋉉=T9VԎ_U{?inj\ Ot28s=lz&Ldj>Kbm,}D[o{=b_WEc ;~Wh؇`͛K'p!7>>FpXEj5p.@9 L,صk7{Ć`&S^E{KCL/i5^]/>A! xt 7p|8pŪL̿CJ/fj#.M,rǔ9`b`˱ o4~H:L>T =S>9}Ssƞm pǴÇ^'8F4ե^׮jr3^Uጳp1^{]c,y,#^Ϙͮz{k]g-2鶧 >C9C~X֨VU뻦ișB8x ՞{Itǒy@ =$>+*SV:C/S'Ĝ7c,\j N ֛ujP aQRJBc{8IT~r='ω￿2)HKQ=BXuާv*v (=ڽo>vU>w?^˜*RcJOyk8-h0r<|{~WU~B.@~=VS*ٱ88GVع3=]^ g̜9eBtɮp 3f̨WW]׬QajqR5 Q e3eƌ]ʱcj#4rڗ>JiEc]Qh˥Nθw:u-Ww_UNNNu;{V<ҒŊoa\@*j~c0X+og:ȵti{D5w(Bg՛zUiYP|$FFd>}QP&lBC $ * . HO$ds5eLPbv-Dgخb`Ps=p@^q;jx`, v'[ĢjK(W7՚&?}%)oҴ@uZ SMkwlt\|I  uH 77sޟ+]`P.;( xSc7>USQJ4`) _|Ҡ~ ڇِ#p9{ D0NA-@jI4'@ٽ7egQ)s fJ[Gj8j@2"%X[s>L"Hg@@z.)(/88POhxI1f~ u!sOaJ>)9ױKkAON&tXйH+ !/%V8 $NH QIr 0n'NJ >b$tߡ;e#6Yp8 XWD~ղeKK5~}Bb^øZ5 yUZ5k)&OT? & !RQ4m''?2e ,]p1… p#~)J @oKw߆ADz6/@]FvOkNo =!x.&= ( 2k L7|R #|^U #pdm|mwAɚ5!*ĪyHwU]ظQbCHVs1a  !aذ(W<'nȕacpij)!!.P ^A6C~$Alr k,}!)&VJ5n.#N ç{zɉA000TVO:riĞ:#Ub3 (NtU&#і% q{O͔>IR煲ZlVkx9qr~Re_\v2. peTHx tSK.\1? \ I~I"޶;e"dF1&Uwsg~.J@bSgj J0;0G7lr*wR kթӦʀ5?p+V+cj?d=#}+ )hEwEA1.1!~J[ օ "H^@qOvMDO&a\`-K3/ Ĭ#7H ?Ru#G˾>2D-ɭ3Z:2K+Y3F{~W֏;$/]|9QQXw&ἙMp`}'PYVB 'ΡMRq'u5k!@tia#fI:w0΃KvƳamO_$]ht(I~W[ږAZbZ)IP"ץG6]=DJ(]C* gN#VIPsiI|*t*cL3&e z0yT@N+5ܔ'tܽSMJ H#z b7ȟnm,tl7WJ2 J#m}Cc# g2m坷6%NNZ ]D# J }ͳsTű(m 8]iR]%dPH8Q"Wjfp9'DR,YϹ nKoMC-\1?H'ባO=*=!WV\Nڥ<7rțApL}>6klPOo+}aSv8~@d4>-xfq=gV6;L?摚ܒVCCG//wlQ`hX^]Y|b9d&'Zi0bPw _T^y`HZfMa2ЧzF͚*u/[hi1c &"@eӃPZP`1v"2dLX\Wb\ek/3(m(͎Y%פ'CO1b\>A R?1yLz:h=ڀ]~\W2ޛ+ae#9\ )w1$S6xI醴a? @N3X i iu#FɵTd, cPtjx %2<`0{eYy9+6cV6ҐlVz)z1c.8i3':pNARk9&c庺 kQ ?3%y%㕎6UXbmg_\/RJsq3,4 rUx\mj,s[~rӰQ_9qHᭅH|).fJd(L D°$P֭RwdΉZF .r jnntBna,QZm}]b `m 2RO+QDq?EREQ_&&& dc5#J :S$o=k#G6&R^\x5ڵ!y1 4kT]D >P!d (X5^95wyg 0ggCW^[~bqMv0hk =d5ݲwb"3>;T%X&?vd_iY>H=)a M?QO591!R' Iy=h9ݠ:2(>T㚲^5~~Ѩǒc{m,3SaGӒǨ]u`h"jgIT\68P81MɰOe툑r11\b|GDa iv&b}>Vs+"8ֿr[S$Ug#L"'F?+b17*!q菱Z0o#qb@#ȼ Jg@ r{5B;hir>c.?vW\Me(RN$a|~tԁ1.> Ea]Bpu׮|"|P(I@' Hh$!p+?M8d)H_!xPDN IB+EA[e;/, >4h O@ W^ &tjaKjS<Qah~(ZԈH@A:yEg(Vɣ1ln~8ګ6oBRgOu>`Nfu2l˨FGK@;@4rTJW4]>&==dhTg@5Fcܓ!UsFcMG7SkH:7C.X76y q ;MNGfurQSd]0`S5TND?Q)5LZ|jQ@5ϧhu8vrrr>{K=94 PXEHKD /Ju u"}%*D&_7 "|MAe 3j( k(ѕ8>N8wݔz-}[>=^#D؁,|#,=:E /H2>F{cF0YVl}"5 F2tAVn:%Mdt[ow݇R*,*߽3D7)}Gk`7@B 6LBZ}tw$~UƍU!vds|~K{.:sIΜdc.] PLIDUBc7cb`}!% 5< \ Uqtď.Pc@O\Fl68R$N gTHh0B6DH]JÇoR)I jb!1ꉐO."&T;O3ah´'א.NdyGɿW&:t(:Kp 5mbjϜ>4D7l\p#c@VO?&1rV'QEZ {.m8һkN"ˡ{twE]XT_Yx^i(X; @"S6U=T('-Y)վh`GΎ{zSB8wgKK6o t]0x2XGw)S$9AҤz0+?ƑUl~5E[C!.NZi[ǿRh<Xz#,_m qΩڕ`\;yqk1NϞ9`B'P>EP"ڧΜ>׹SPtAH Cl"mR{" O=2R XJɓRF,=Zzm GM/W`J,;-r=LC "@;Åw;Z[9dp'(.ǰmQ%F]wI(pCqjqlW6nW8?ZC^+ @Ō&P\?|D`at6x4$S$A5Da'qB0@H|99F!$e bf!u ED^J`1 ׭F<8)qJ LeO?_*?E5Q,3,6*=(%0%Fv@ vH?G`.&E`":gߒ~J[SȔ% eɖ'K r˚B"RݻI'@[Jk !wAJhX ]~mQ75r…alV;%Hmۺ=%XcNP; /]0^hw rQ`纯3{Jo%  #UeUCJO:&MV,_ ?/G7PJj@^ȑIѻxoq؛#G%F`@@O @jR,HPOLOkq* N0>];wC {Q^AbMe1 \[8yfA0 Zupl\bLިp\!E1l7d8#"! ==wfMg9!0Z Kw쨈̃'2bV?9ˡpk֬Iׇ3ϻロpld?c Z,59Zhq]n׾- i ~rd踮sN:qcL8 Ə3 8ļr2qA&P #Gg©s 5%z_N:#+>DگUP"1N}9(('NR%Ka7u_v:*H5"4X阵Anbɦʊ6ޅ4&NZ{V&8^hze*v*=/:A8x~k&.X +3*lj7$qJU7~THnԩw:uR~uDT@k:G;ia0F ӿ?WjZJu%\2tD,u'JB_FiЋ0/#| J(_oyرaaai:ep?kРA%)Nx$j2խWWs.]B dk2_%߂~ Ⱥgó9S+\)ۤTj֦HS #YZ*c0z\wEzYJu,/u_=g04#}IdxtĠHޓNy@e~,l۶-a7f4[zx8$۴TG^^rlNյj*G#+99:G.M`ԨQҥKgM5=%ypWQY|UEQMgxaKWJ^ U]"{NP8ucXG!C` ,ED CR;F{È/!v! i? kYkPH'81:<[(I={ G_kE5q*} ׽8Tp FH|KO")5 ɩTC9fWM~PuQOX#̜v{)-w}]בs+n:5B!EGW"b+&'*Woڣ\=tp}F'@lBR<k''9:dXjA%bbd(&ڳ{]DQڡ@1#?2ifbgnçm _ l~mZU-]vE 0xWIK{,|%d^=mY|wpx4޵{{." Rj֡1?F_zgB9,O>]v"A"PIO aÇ msi揈F *J`l ۞8xSP;06,Jnq<_@a&8qhAO/=3wޓ >OM_7?Lm&O6LO98+khCؤ2_bn4+#*A ~0/ 7;pd3~{-_*uJٯ$> 6|9B~kB`d6,0@, (EvC-ϳUC~wհJ})?. >XNܿ~3/\/Lt=:>2gq u Lk09u8%{Tl޼pD$ҥDH%Jmܰ嫢`x ɉrA(F**_֠ 9 }\gg%^ # g=~q+ 7tHs$0hU0,Q_I5242ߒDžF-;!A@ϭ['^lW0}2e<RnP`> 4[]K xW`ppb歲v$uv/U/TD _z-U$\PAو ]ty{'к>OkPT"  ×k8".e=P؇U_C`"I@!2!paڂEKYMAFK4[g[[ܖFƻn 3LH[/l$gI4SJ֮%5I|PJ-@<5v\ I )A?oě)GshZ܂\SФ ?#NUn@kyXJŊ][g_: 6g AG&^FC_pM/0PDU[OX9lQBBu )@T?ٷo Fg9V`>[%!'@߹d%V/ԇ9n qҡY?ŽaIv2/12LPzM.ZR$Srn!͡]Xn^T{x '` tCԼ?eǟH"·`5Rqf $p}MCxS,/'XD%QsȐGBkBR]}]qЕ;%؊,9r<* 3\PScǎJkL;4m0 Œc:O!#S\ 4 UjGQ,rQ \2p[ރպupǼq1/JH¤4@jY5`ְzϞ?#MqKd٘gJ4vS`|en9lH N XŎ|-V.l o3gמ_ڳćE !I7yO.]*]vط#g͚%GE}5sb(QJ Cϯy,T2;s*~<QIp/OC'`G'N+aԷ Dx;'ft.]b4:0Ց8 }3Cځ0^hG4_ ;]Ex$?~YtEg]UC]J/ ,3@~Cxz0"Hmױ~MBb*UW9O7A4׿,O8ݖyau7DbzQԅzW(+WG, V@@_ }D?n?$tQNRϠ_M`KFҪ➊`rR< 8$m "bX3檒$"ɶ??" /! Ju=/J; b1"x`2s E.{{>-9s樴gOSN 4:2sO0@`T7h]!E0{^TRBBB2 }cq! gzKSS\nB?^KG{cjW([|s18 ?zm}D)u;?\!;"py_LDQ0:sFE#@?f._C9n}9 :k g:~ i@H;"a?тϪyp b??._[rcpi*|M M.o&|J鷋lzRj FA0x0u_nߙ 3m0!<(HLqw#G`?.@D͠ځK; r˛S$ć˿"O}]T#5خd:d Y|O76_Rغ!ۀ!j={N仡T%?K?=2BUo?o^P3o-… i֭Rk6 ms~=ͤB˖El Y=9 MnVgnE۾3#E.Hk å3O+m=rb7*;~C̋¬{VZ[\;wt&0 POcq'F8blǎZB ߈ ,HG'>H@Bm24DxTpa4mPNf<.M@ȝmF;"wTEB"XGx0Cbo5E ף-e9lvk'$ȯBƝe!yn+ |H{nr+ECWj]踫FS\쿷ߑC␘VDVZv W^Fm^EF r_]B2RM6xއ3}-u7C&G?ay d3~7lXPP;_E7[{_"G,YD.]7Cq&y7ASC|d\\Ӧ*p q=狇ԼN'' {+Q{DD;#?|7wYi:ny v i[A=aVC{C[ A]0':tHHldsO[KEhƠˠ#TEF>ER֐ ]?39zuN?_?Η f8/sQ/? k%0[! H޽{a6 GAߍpdR7)<sK%I۟_z Z< {%9pU\ BgWZ6f$<.G@E5;͠пl9-m#Su s~? ;]%`ݓy%  $|;[sl]k i?~KA(E<,lV[:ߤvܙ O=F( l\'yP2Vj+#vQA?Y*n@$}_ݴ v'; }S&>0I/`)'Y"36su֩G5JlO6sz6.^\8=A9`]b^Ar=.3!$/Xl+~`!Kc|T,^X9/0%R%`7\ܼE Hɯ(0a>07d֐ ݰ^rd,/>:V~x Uj~|k jNorSk@j\ٵoڡ@s#(KɫH>}h,r064yF @yCbz:Ax %d> V჏ :^n C+12̷_(̏7_>(gLd|/L&}P"ݶC3̼f#b|D}f̐Y#S# e7V`9 ݃Q/Mb;ѿϭʙ+1;a=f-I  U0>?&t<}'Ǹܖ*߿4jh2$N\Et^|O9{!}_~j jr_:&j< \:RW^:?QwQOb7AvM6 eᠻ0|4Q.,rҀv0v7[Eʸ쥌7o+ oP%`/bq8,Gڵ#!pAN Wuހ|I/@pS@τo@9nEpy\/onӍĄe0 qJnqyp5#PڡlB֗%+ƎGzAŢǠXhYt(C}@CdĞRw·$cnBu:TBN Uh'`^iƄH^h5 WJO.ldM=Һ6Kj4R5 :S^e~#p\A븃[;3$ ~v">\dP_i'5jPCs_9|/u?uX w4!T+A"ʰ`@ Y̞ h)߼6DVE`{C9tv' AAr봩7X"AFBkq礈 q6D0 "=,BLYF#2š_~C/(p{)&Z"plHT];xPߒǂ` &9zܱ< \x:UFw`胮S_x"{Bjz U"wGّo5γ( F bz vE80@WpS~8ڠ { 쉸ֺ{֬_ ]*N9cGfZV-ʹH*`4dJzB]GoBgK.J2Prl*("C</ݽ{ww1}h+Hq'Wޅ]@0.ACRC/`d[4|H^ּN \ZpaFTђf'S}OF!# Țg/`Wfב S[׿ɣH]Wb]̑?& 6x$qsݷȟLyݮ"!eBjBHAa;gmd/BǏSN)-O)Q*ADdDFY("qwxc֭[ PB]NCQ`o t_?֪]NIabsjs?0Ax`xͩOsT8+e J3(vA ſjGqoyRkήN z#A. -siaN黿F?@ta/Җc\oCP*ڡ_NN* =ݨ=AK׫/e40pqZd\p7"Cs [.̬Gc\?˦wѭBF a]*G01X{AnE:ҷ| >~D%. /0 A8ν<7|"u /te],dՃuTL>tXqP>$8׮]DmQvv0Rt G c"OMIcVhue(zT@G)"v7WH 3pL%֬\~`i.-I ҹ!i~aYF]S!l }ۆ&dcI<#h~O3Īwlo|Ĵ!U!(tUnR Z~QȜXeKnبnn>>~ЬZhsaln#S zjR{bR2 iSɶE$o/#3t6mښQoGh$ stj'&$+We˶-"EJ AGҊTXu[0Z@n@iC *,_ƭ3z(O[QL6// qX {s`zdNJ,X2gcKPzg'Q{ޮRaŚJ׶"pjh 6sð#yWbaJm }!OTXo*;)U?)c6HCCz$P5Lv=ũK !bHq&%feU`[keXUls/p;x$tmTtR9awh&M R܆)`D_ׯ_tUN=9]|dKIc% !eƍPP9p]n&k;֍Nqˁq(K)jnF]6bD#ACUqY ٨k֬%e˔Ufàv=,B靹΁4t$AΓ6qw3E3A|a風-FA:XݩDVSS!v!]V pQ]׫޻x]Ncԁm I/k/l E $gaB| ?[A.qй ]ȟ6 eI!IE%K>1@ELJ#˺THjiHɓ'W+e ;x„ ƍ !CO bK*mPu\k߶W$I AVh@J._ gκ5%z;.U<Iqz{I$|#HĢu*Pq ]sĩgF},mx8i(-~ÇξhpH94qbB/A<$t"OnE,*ODP,ȝ~ [nM*"b$3D_CadfǸ%z54^odɠey.'4eb1'HES@5)"yQDK0{!B+aZ,88؍3)@Zjyٳ'&6t*+0|P[x$\|/\tנu(n.}18rT&XX 0Ft _?uʬ5^}U38/ \}(Dhidf2 *{ &;?t2`&SM-<֗y@bha'J'Z77?~$5%#CdIJ*l?F~;0lq1ZEO0־2l5u|#d-~"?1S.^OdT#tb@a}={vǘy2eʰG 0gڑ~Y{Z@?#)p!p?$fXHB$'&Oq_5wb7v%ORD^EłT>GhQ? IQm߱=|H=5G.jO짞zj@͚5= '_0 9y@~I)O(!+U#CӺ3=E%W_5; ^e (QSo{fJi䡇aVmè7_>3'w~RQ"}ɆaS?Uߠ;"Hvi^ ? ;>yˋ4#%GW7aXպφdáo< 셛L^ށD" AI(jbfeZ;Ճ2בz·F,_:^6/[ݻz\[}ںdv?|Ffծ}wbUGeq1/ɪ'%XQzFgxDe7W,o)>e8<Nx$Ox]A=CTE4 |ɸ67@IDAT0/ZK@oN׮0|+C ̫ +a>3=^GdF˰ .uO>#eJ{lKP*r&-C6 ŒG85pgѨv4ή2I92C#QIm{<$:ܚ=5Oc"+Z`d^@pr+∈;8 BB&<er|1} ַ%ƾ~_J@,gF<-wci~ "{RURGM:S-C}1"r43NEC'E#gCE 9_CwGudhϞQAyv7> fO> I%$eWgmjn|[5㐏<)I%/X֨)>0JўSӜd2`sH笯k^ﳎ*[$+a] 3 7@$`Zq5u}7$'\|7u J0.Xj"}B$OH gm+ݑ0*anhmj4#i潪PAmh@>װ&|-(܃bb"P}% ƀȮ,-´/](L49 fL߃7Dj\L- ;@xH2{ X>V>O/[;p ÛC}Ưƒ8</]!^a+]B-##ߟlڸE?*Ǟ`m=֏sKŒP)xc0rͬ~) %i͊ݦG"3IRܐWOWu= kޜrRdB3͡:p_9~ʨ!uE&.ԣ98?86tEn?,gZ80j8Ԕ3;ZxNGH=àoЃy{! nB.w}bSG?S矫gО HBW#spu~Yn]H!(GQ,!#"±>v84spX.z ,ǀԼ~p+p[JL ѡTf"t4q<Ab'80rg(eg ?!(ar_.o+^ 984Oį4UF$`נm[(Pǭ=TC9|<^jIUuQ//yZ7^&7P$KaȌ] >CBBT(Zw!PL~'@$\%b@Ӏ}T^øBZ1O.#W >uFَ`jc .BG\o5ʲNWP< z @h9s1YT߄IpWD.^Z@"5ĩY՛SL:!XĔ>$y"F>̑>:ny/11AyϠm\ Ӫd x0?g(v)cnr? ? R.mO 2`U ?s\?y2cE_!-`0yJ݃+,ٝ;CAZ> 6̈nrԗ6A;/2NU@ Y/3=0*'0DB5qf)Csn8,2& +9Ly WINyN$@juPWp($ܚ+, B\aI)݉ESHXO1m=ZF~P5Έܿ% }6|͉J~1wzPt)ru~sH; <e#'}݋dѠUly735#>Pf \-PAqNͯat@LVngaAЀe]! ~p!A} L~@d.8808X[gGɰޮR7b!l#WK~3)i3J'l,Σ:`}j}%G|*s-[`{ \h(\t8 |h{9nIdb]vV:_^$Pb I@90@;蒿_uڵ$F)xOG*}rKbBbא<) ^Nl>Uq N#tq FқkE mZoP-i! l3I06A`H?[M 0݃Z̅B +BY۔ z!9~e5]^J*D+? 0Dܣaߕ#Xi{‡q3"Se{lFcV'=t=:{F"7߲ih~:u$b`)9^;Ƞ r{ ~p[V?PA 1ca_Y >A1ΫUo(g?b[Fv J: Ns]?z: `Hwk61@yOIM! ܥ?q(8\pm.J߾}NSIH! 0e |bRԑѐ/tm~3& RA 'ÍޢmWO3bPdryRoWE2'&9^?|/fU,O̽|-V|KAT²JFxJf6'hU]kU)d('OTvf17M R￯I07 Cr E(܇4*Ҟd(ųA~7z?$ F(tE. {5'k31q?{*^p,o_ìQ7E.T1 Lȸ}lyPQdkMȄ oK3l<@"2)ݟd'5?1p%6@x1=% 4bfHO|(;7uqm_1vselD"0r/le#0ȑt w1ma_6S_CG?S CЧ\@#nfsz*߿5d> B\͑:Au/@29t/vٵ?m401'D[s]R`}}M؉Ǻ9FEH>@O}@ً%!\ 9?Hi$B%[w$F]q0;_K5B!iu eZ>0o^4 q,"9oj{z-+/:9 {#Yݣ-Z<ՄdjVN);|PKX<L@)>P!i@ J6g|Z[֑5$<1Gj3-HO,5p=i#HVa86pW"Tiy򅽭C1 {nI:J09꒯8+YU:Aq:(! KߪbjWgsKq\ >_aqZh56HwLz#އA?"TEdl :k\H}e&, YC5m8ȢL πa8qıB@KI.?˙ EsqC[7*3_}гȗ6Yg^8lMcM2+tKi#*8%q]$Yg/h}*?}[Mڧ Տ>2W+.l]AiXsC2`3 ~-Wfh˷ DA,je*SN Fu'0ɲ 7_Ҭt-g1⳺lt^Z65h1I鳟4WuFU0!J= kR%=Un!̷WBlW4Κ#N;w@fRZy_1yČN-\gg]T\5ϬiD-&ʃ#Dtϡ 88>p_5an1ĕ' 5w#!@j]\z! U2-[G$>`[Aӝ" ^5N^x>ʵt]m/;48.*ӕDL++ꇷ&sGU+s/~.!.7r?it+%Zi <s.R|W_my,/6J0@F"撀xIFdO}3YQ֌Ͽ g}DstL(}G(‹mf~];J0gޜ A~bj&bۡ9?J /ʞst럚1#R p./8uF0/\D/󒝈q.pk[߶B})(J[}h5%[ޠn|̶@v2˛,ƧV[Z'/s:^n{k=-LǘED0S/8<0ɴ󺧞bXquGD|}E9Mw^{m6UE,_=T{.z뭫,Jg%#=qE' ĿʒH%Z#I{t9ֲDY_/ğ_y]0i4ʱ"^Ꝉ.#Ra b/.wE@P' aA~zg.G‘dJs 橳ƹ2ۂ >P (#gʠC Th%Ŭ ϖэw[wrIG1㏷Gw&h2;A+Brw0<"fcr`!H壏t;,?ٲړ.9׋T&ZQǘ}S ucn34 R#Śd7%  ioFEZžkEmM5~",I-: f}]T//7WzwTDPD Ru$s@mYc4 j ЏzNZ }_ j.<&8&9Yjr? qޙ|Ҥ}2V=Z6>t>NF%*xHsMue%@yK(4ͪۻ{kg>54`ˇ>D9^V>$&HwuzL[im);[HzO[)_H=vM{mvL X7 קXaUGGj}j"}u+L?z<0(7ZoEx.pܾk}`^l}+KVP_/1zY#E/b08Gvn+|\.EB]0o{^RKi\yM:6c|?H'Y(R u 0,NjOc~R-ʪ1s` L Q1 i uHL pe8г{"@7|^D\.ʔ9P"JjzEu3?b﷔1(zPdK8En/_*]4)rS *)DŽ3H !vPL~kgjmwpKO/Uwd~#6{W҇0BCrnM>i~4q)4ojgLD VHb-d7{r =-xn ~Di߯25N y ^fXū.bվ-@&s+2&\{93Fc܃>h!CkRQx`{ꎷ&͚~‰A߻2ÏԨ"M͂&߃.OX 032_x/Wre\{P75ĐSVCH˘c[,#eHM}kcRk71æCuɦƣ.0$VK^q)b#DTeKٖ[n$;hvȸ}ϞdS7q|/v-v.CeK:-a[6QBS!N(ى!I3D 1NŜIqqL̂IceB_`Q}[.+~9KQ!pQtf*[Qc D"ug/l!V`!0vGȑ6KGb[k/]n֣_?[Z4*IpwO?mtrĨB!aϸr%,~Q]6Ys]? D gD |>3UD92 I#[XHU48@b?Gd\f Y7>J҆ ? c,A ?$xvdl2)pf~9U ɟkm 1w @h,72\FC! $a[n e fPaUm\գ6T7{@70| :0nD4&;[6`u( gc9Z>#VT/tԑŌdMu8{gՍ]w' ~%|_|IFBXљx d]BmyOv0όR2b^2`uԠ74 9I5Nww?Ӟʈ:/_[{4y<@3g2dY*zAl$#3(^16lgC8f.C@Ȟx .q5aN ^65X ې"_Jbl aG Y (8u8V߰OJ_'-~sѬp.||XZ]nc@ ^{`cd|8)= xĎUQ\$KaF?+z xazFD! vdP✩-S=π.AwcR^-2T&3788I@V 0Z; ϟ1)-CBvvOCGtG3i9&“iҞ|>0ܝƚ\ J&:B_xTqKZ ϕp;> F|ܴqVh2,f裏2LewV>g̿e`c1>Cb:AWc|]~*\wp^u0ӊf03 B-kzƍ^0'd'xc;3s7Hs7WxzDxq>A*|JSEC/e%qRѭeR;nxxװaÂ!Vz (&|=n[[3,Rz4tLrꇏeK[rڃ~LF c"n7D'F-c# lU1Pq`x 0s.ey@_gNg&V5~t $c@K@iWp]rU.~:i=/䯐D  f Ñ&^g~ @˘*ӗs0{U'|̘1ADL콲B$0c?c^O>d`0-\ٷ=}`pS^[hVåWC.(qWe37n9gf\8.st'ӅD?V-Rh+ +`Yi|G\ĝ2|{a%˞-MFpz!?H7 rev#.qAU)_q|rm>° Hn,!&{챇cYH1+]Tǭ64W>v__@'ѵ*X#bg?"^ZEJA"^:cً/;Ɛ~t !{$N@~SH e튙^![Drx!H,V܃; Yi))8/ 9@RKuqL 3_P0̈́V3~<?3K2e']/pd"+F}:u)Ź3+fBޔN^ '8x;8Ϫ4 5υ+#=Sz=*:wF37G衇Gt ӽw."BV(#y)lW`L_~yQ_%wÍlŽn"`o#eK[hs6{k/ :ʎmHx6j\yK je1f:GD|Ouw{{=Jϊ[WJbB4;tP>M`UI72iaP~EL1KF9LZWո@)x ?v   ɥ9qQwdE插~~;%iqO[4_ZnğABV^^+\ZXHEȖF~үlAo|\sN{#E?q>F;pn+0]2ؖ@1iFݔBKuK]4|)T(; Lǒc Q?Q1|#uhx#U h1i訕Wf+4kpZ ./l*=Xxyr!5]PwZo&Vcǎ|SZ0ck}2e?߾ǹ4xy#G b>HB O)SR ɤiG x.a;$R7~ XtYE^Ze䠕_T 0]i)+ѝehl?T죽]k8Qc6lJV~0%oFpOl|-`8 l?.cM[ _$c8}L0\{DYU9v Rs=ۀeO xZdp^2I{ >PÿUw7fٲ Hؾ/ VqIF!˘g2|- ~-ig]D@'N2f~PG=d#?q<a^&bo\ DR }ȷUGN nvc@ '2h;;p{.LK|qwZ>4B{saj]?*k~ѮN nҷeӖzEj@]ƒT?m^?Ա)&\VVV.aIkcf[9fxV^{mRU~2^^C̥<'~m樏||ɢ^V /(q}Hjf>udr |5y͂ypW stȑ! Bf1ZW/ .:B>"Thay5߄mh﷿u꼄o6qMCBa$59?IKiw?ŭO^hbf.K*4xğ[L+ (j"g>!ZN;h %:-acƌU?N >M!\79Wzf|%p}~I܍$SW{@`D?Lˆfg̜QI _3n*OxD; 7by_uzwIǻy}a0i@Fs!  I^4*\˚'l^K>9x[ 7Y. dOyM6 zLb*8ٞ6Fj?IwI'F d&W(Gi#6~@; C4C7dW^-wqsAc:_ПSl n|gv)я9wo;Q LƬi=_iEĉ}QW !oHn<4@@\l7 E=BH9o&atp7I>/ N(-(3N&ߙ|t'ݏiܭ!@US)37z wtCJ@}Z̘}W%@ CQE~p箇<;quy"Jl&6e}uA[uV癧`#Td ioLHPBs"6&y$2a16 d]|6>{1K"i᭶f;pb_; OtDC2"<4@EuX84[w0 @k#޿C@Hz۪E~C0 n =#=9@.s7{a>'.$\μX Do*?񑲚P ҡpt5+7h& o|1a4>Cy:OYq2r!xF N?518 ]ħߡs4X*BqOɀ9^ѮP?V+^tnξ:l?[{nng_VlqܩX_}M!aDsVH/䈫c@;ת/>{.}~A?4\;jf9e:-PCQu9~47#AZq$mw#x~>,^H c/!)ÀR.{Yqf@K~d\,ӱً[TJ:.#lC!-A%z,(?JxaUԗO:YZVpg[]9>἟r{xS:/g @V 0#!iq@)PĿ=ğI;r-&Ma) %3QzGYOswJg !$09!2߿ѕz7T9r-s=5&2n-s6ےaX`˱EZӬٴ)ٗGdVb믿"Z7aꢥ@IDAT20 cG W^y%W +Ͽ>&#IB7/Ew-𛘰95N8}A2qJ08؍5nKv(+EDJiLTv?OIUd+\}j:8\e h eʜ aZȎ#K}7 R1έ{|?Cl\ភq pZD$=K է OSPX%8ą"b H~ ;|NO>@\i=2yG&FSistL̹쟴q|-i# N^xG:W(2Vޱ^-3vk:搽Xirs[&uCl}?EW0\.1+\+OGT~NtCG5/袠UӤ>Zuֶ>V"zb@}0IWUJ\˪>m<{5c ?$5,p lz*f] W_x*BtWi<d/,N[Se)[>ՄS.B9?r|hd5Jɜ"OGf.2s<3}|^?NyXy8wLY 8@a782wEFahLVgxCFM0SNe!΁x`TЅj >O~2J~/O:?\>3ɟ7C04Ėg۱#Q(;vߍmŽt.l h#:ͷYGVa U ofpyt, ~WC; F>nkxubi*I'.Sr{v{8 1-lh0QFxQopa4!9<R˅z (v|ÚXi)~AVT2iX0?KS.2iQPH`rSnpٙ|f:5Xg^n f?~\ؽ)aqxHà`SyX[ag!)*,U1!RYiuˏooO?Zo_ys^5fİWׯxy2BH<0!ji;e+~F$aMaiS} |G/35Wz s< $>[)Ns.|)ЯB 'Ҍݖ*Dqa#ΪI8$0A$yN$paNݥ$cw7s'w>%*OGYr([2$ӕ}r iK.ѿ?&Ŷ#l[kӺw2M -Mzz<𠵘05kmotM&yXT'G԰1Rx@[e?.FqYZ0W aVxϳ:X'qT2PY(M$G|aAEf\C;t bJW2Δe_I4b0óƥ=ն4|*«Ѐِ@7!= kF~e}^aM = si㹗SI94EZtq靆xyS0?" ))K@evJ+KzJU[(pމLZ1%LكBLZ-r!m,SiU aiwaMF"3;v7d1{jkn}m.6}6"mb_ofdkɗ_)+,c+^|MYbЪbϖ鈚YK6}HBh +VӁEK/4Nؒe=OVkok/%de9$j!ƾ!nѠo %?~\jV.\׻{M`l ɘ' 5'\܄>M dHR_ܢ' ko0fUl|lWpm!L5FrUzd1?Rb*AշR0u$Z)Nob~?< <Śfn! '#:hc082Q>иAAr?Nrs0e%Ḡw?K^(qw1046*210b9Xc4&x]o+[ԓl~[>gm|uU?dOzOʬ6Q{l5TuDAs}@q뭷~kq|'L:{o0-|ׇtYsepVnn`׺S0}bSkyq$@ cF|h?h;_5⤊x`*{<) J} @ UVt pUӃ9|O "\J/-[=LX&d)Lb&/ kI>; %[\W}&?yNÐ8\i? ꞇXB{S[`CVLt"Չ4_U Ez\s hUd<;ҦI?x˜(kbΆ`f@*c[fER3LRl:ez hg_|re:)-kա٬K03\k731ZGbmGy?dI=ꐊS|O~4S-XC?\mN f9>yW>Q W4_dQkH[ڊjx>fMv}iF鏯/z뮐m>Av.̼i._ $Xɞ+s;\3mkH'${ϝlf۲7ߦ;4M1ml4O&fj3&kG׽p&6WVh30}~З G R[OqQ'ƚ [ ՅYS&k%?٦ڬw>*?LaQΗvK/ ,~;)q$i:n#o&lhz"wd+F>B΋2(((r_*,lH Kl 1Wf2qx.'u?ߘĻ?9sy&.3;('F= Q%e`$VO4`&-\#hk{y!6ΏǮx'~~<̀/C i85|"婧W^y%HMآЈ&S#a,Cs 容^mX\yPh#.<޺yͨ_l}VYBK0Ys! ~3l!`!:1 fڷ܂&KQ?ډ>iղ9^niuR]WjRmiI ˫Իc _u\U_JȶB?R~i]K] alŊΛi" u9O\an9~t(P(^в MW-]dOӈ ~PO ZX!/m> ަub#?S&=|H'~oSv!'gqmn+D)~7}Yg.` qG?6N<V:X{ =%wpWɱK.>~i-޾Q7y/CF&"~U_4fe\Mm2먠'_ w+ЅUa5_C QZD%}QDƊ1fs ?HP\5̧տf t̹@ȣ| "'<{2g9WCM5koq VQ.;BG#NwrGٞR&O…oK2# PSʺ@P/&*f f> ̷okfu`_VED6̟$泥n-cr/:I =$2',˖N;dةΕBW JMl %aH8W{ h{~#nCGf~wWGq5d swb%kfnr?~m*8+ɇRޔrwa$ETb?-­ k],dp%aBi0*Qh8/N 5zv2[}1&Л"*̹q>3sn,/7{4tN=_|B@n/+@='4`Lyfae]CÅҊXwj0}? \!m` &! { `7M7ݴm񾌭Яi@挸op[i~÷{a!f$M!9۞{Lq˵}I|4@/V:n=C޳-|Rn4|u}~+&|ZȪ_ShP"Y%f:L!: LMjS.ig | .'[r%l)#i$ Rw (h5Eʃ4[ [#|' ZGkO.t?.aɟ\/7(YLUO nL4&eE4T(d䝏~g&Om<$.TYB$θN \Ф|{EmZcnjM|e$><1Fe]'[89KmNF2,=p VwkUǿw>ҹrC4 C+1 83 0~Ա>މxI]Ejj&"pBW^V~%܏20hD|'VML*;7!/dp7Sf2nnglM酼6zWb#t-<^.WQD=7UK n"mM)I! o.r8<9 ;GRc ^iv>0 i|$sqy9 0\o/'/ϱ/P%TAĭO @{$ Ax<`!Q\:4~0F: ^o\~[\U8+KnfrxIAsYV;Jz\D[`Ͻ=9|qt(19LAG=e#ȧmOB`D eeeo*5_if^tq3m7o>>`}0r)Adu *2`CñAN}l$`$5+i~ džGqG<@}N'"Gp!O2҄S/~|8 f_uUa+gMV6նޟV!gi[5A } r=Oqq~ji jP/\ D# jP(Ku;(7Ϥ猟I @;W& ߝWa]vY ,iaUk1A$ᗱ1mӵ'wD*m1^b^uOҸ~^œzJh],4Yvvmy Uk–|5p]lED9d- } [07>^RRoF*@z Cԑ u<{O: Nw'H3U4`&yl߬'YBT&.8m;__M񬖿m^d B7"Ig!>#(`¿0a?'o!|F_IKR%)Ye<:’cX㮿gLG;&  B@hY!&@:80{.~\l={g] SBF`@$ 0Ƴ뮻VY%~!isiw?&4GczR6yjSoy3g޽f6L/[mP]1es]@t| a{Aah8}~* |#vwVaܤe0Ķn0Lr? +:;:.t) ݌m'i4p{o|k*qDM"G+Bx fϒfk&_!,K1]x0\0')e$i4̹Z,1g/3w.Xb0NK>Ͻ%qx{(ͳyv\V t6o—yy$ NѠib$pa+xɳwr'g4ԁ8gehSK 8#H)oaN y?w LbMٛ#.gl;bZ3uK]3=|G>`}u=ʌ?ȸN+Mұ'i==7s/yߌ7VW?,{cQ}*M[m- ~c>>R3(6#zw09 7 0fuz!CBo]am[9\s`vTCe ֻ!!K "!Hj4n >[%!%ʺ$>-jAWePV_8##qKi;a(ػx]lOѨiHc:P2 0M}O-ly^/x$J=3g8O9˫ bn5][ymޓkz2ݧ[s3{nooIHմ-"@Ty?iX(N( E@"dl߷w^j?mNϼrr;s57A w"[|g\ φo[auԩ|'Ŗ̓X|r[u2Ҟw}ck#)  %!xFwp^E > ]XBI` /X)")5-=%lI*ϭ"^D4 3:@:ɓOze_}͘1igoc4̹1tm ڗ~z!{.{n <&O.o`~&ǭ/ ]b|z4Xh0H8ʞߗ }L$9\eF8uXvmn@|36۴dاd e&w֔^km(JG~y!ĺr!xN(^x} `<8 %OXfѕC{UXu>C{`3Al^)l uiZ#G g#x4Ⱦ>PGf{baZ_5ZD&۸9FulP"2vf*mդ ̰_؉˜b,Pr$x$#U}/qQXEccQ=Hcinw&:Jc^$dKG{ BOC@˅ |(aF %'7ZK/dl ̭̖Ahk1[?pO4 or<-V[@j5?9&B46Le8 P,6w<ofKxeƖXoJsWx;`Ÿ-žs5?~S; [D멎wZg= ,sثےK̴uVvxtTvPx@p~ ϖLvVN?e p A7@1kğ|ek#w(aLG{R]t'1g`?aΙ}D򔵰+~7;xM섃+?aSۑmnZgqu(|0>F݄|D)~=l$+›_ 0\.U` SwM3"zf< B+܍ˈ!Mn$3[*EOMZTMhPG4oD|WΏ[|;R_4WA_’">iYϮMmދ.ig/ZK"m,7դKO>MQ ڗE.aEI8v\p6}fe),~a[vCm^S/Ufٝ\nKzzʹ6OC8iaN>0ri#'`M*C ,UW꾥";mhiiC*޲p!ĿLxyB~^SdGp{I,'h9º$z]I~ |́>kK,r]5w}N,%< =]]yܴV,SH]dE@a0xWdG>,;C}ࢃԉ4uI0X\@`[PhR%obUIosm: 0W;ZiofnMN=04\j6:?KaxbՐUtҌ-V;O}g{s_˭SO;: ]ʜ HgڜIS+~\ź q1O ո^7x=ӶZ+7cM5af7h3f١nn]X߼'{H칏̆EBĖӄҴcuCx0:na8‚?:eȰt c(GԐ[w$qOZyv  3<y=M /()@@ѳƐ{S .{ǥa{/W^cs|qƝ ݟ`V Qnf(gYUtn:6 ж-.o/^qT_.>at֛`hbCus롰vR(z'@Q>x-0QÊĶѼ6RfyܣZ`-F q:%}q1>X~)/7PL$"`clP|c&~@mN뮻Ra'Xk:9ωTG1nҖ\^D C{Bf»("*zd*QLN9>B6"?n$z}I~*ܣ^MŒ`sZalsvwDh{:\ -=?kV_ª*ޠ@Ҁ|y#=Złw|L@ci>8HX/q7Ҫiڶiu.$+XŚC&ذ#lη:n5 v^w;WH9v:kh_:[!fp|7i?囥wt2jwe`50h[ۑ/5Ѹl*vMYW%#eUI`vx\yoA:0 Wp/lijZ;pUdzXL.>-LXd)V!BfӅ)\RHX)d! E?-„oF}Ik6KS| aՏ\0;*$~1ɗc=_b)i>{$/d'OWbUFׇ-@ҩޠ5' "Q o/A o_"suN;udh〿քuirݤ#6G $Ԣ;޺=xqXKԓ3LBe|mFaR7 C[09ǚec3tYvڱΡRF=)bh7|7nnPfϼ3>/>QOf wwB6$/Z|-]0eT:u̜9CFd;/M̭ BD߲&ucI(OƽXSM ϼ>qm@cL@rp Ν;R:`w!*LLLtD,rpsԆ?.G* Rխ];?l])JN73lv$uf؎j~`4tgܒ]^}||p ӻw~p>OnakvNt9[Y3%_xM /ZO?靻Xoΰ{T¿ Ӿ2Y(l"7l7[&β\<|g-ʄlJ})[ET/&,@*a}Ik4SWÜs-pF_nv+  mHC(ߎyƽa^Vr= Kb Ua~jq K| Th蚚qq]5WbߏnaP,hw7@H\p bNU4GV|MHVYQ };kbnSy=ۻW\n_9@g'ͭ_>Ⱥ? "Fk׮a[#Jrs &!=#W6C Ʉi̠?X^ 4 €+"ğ}6lذ7ۿyv?"䙽D[nOz>ێ?oja_j *^SGBOO? {ch8 h/۴n5g7} ll/Wz$؄$PϑMVЅ2 ~K޽oYnZ\O[30@OG}tr&ϾNHG7<xCHS3Saޞ,AOw?[E뻀!jgJ!B6~)T:2QEB Cw!Ԝ|߂$y|6_P&Yb3VHӐ?SoŪx0K=w 4|S{쵻{;+H]xL[y&cοt1:Cmq* mtPݫa@8  3` V!> 'xZ̵2.ň9cqžO<ўy*hӺ]?Hwvn_[5F+9zam[ϳZ"6m:fsƶH]wy&swƎ[I>C;{g.x O?F!`}zQrg[ǞEF~a_OWlCu~7T#÷:v’!~fL?s,u?PDK}}G:ÝZ5/ k4Ru6K+pG!S@!g BK_*4!x`8qҷo`0)ϻB}̞?/+Y(?̝9WƵ>3dxי L,lI'X1r€﫥lTcUG:Vh Vh6Ye c~{U'ҁ;Tpw=wqg $E|`FAu⭊ ߾@4tN 7-(T禶آLfkҾIORڿYҺwf?H*֭ _FhY;YA[FIY=ߖ^z*-q-SO0qTP&ڷ5ݫYF5N8ÚMj_wNbSo-mYs]u;~t (zZ"b[ˈBǁ gAّ#H6xNKOV`~cumNO1H3j "~);D_PɄ#/ϵv, &텽l(*dtxUY"MHX0)|D \?䠶[M g ,>RSjØe<Ͽ f5{̂b3 s=z~,/e\wՅft+n5*g9cyjZjY"A99@G;LwJ;| C4Εca6dP€jp}]0g Im(w񁠠{dfCe8ZܣfwM#ub`MKbk}]EW5@>aNXE@LڲO~qO/x'%^v{xRLRK̜`/?}ZI@V U]h={4˫eAn;W#LJ Ü, =l&o@2oU6>F|@\_j?{ j@]s~Ҭp"~w;%B6AFEUqBF8d8p`?ܓI;^d4G9ӥ"i@n1s,.c;; x~pxޫXXb+V] AQP?T,H{7/{.$/].fv͛q'v|ĭщA4ʌɳzjQkc/$"  @D*{Jce1Jt[-eY ,!#H2{0N^Ѩ 'YCgs-8@خр('N(v&օQ֒_>l&?T>{]5GV[ 7ea쥃~zƦ% ̤4ch:8lذ-f!5`w~Oj굷da=^{;Tm9!œM+JqeMú>+ 2H<|,;i\h`cK_-fxj%єVMſ諒; cQvq*l)-:aъdz:eclI cd[o-0#AyX@@@@6BkiCoPb3/ؘI=>߸#wϷCzD~r^F;.$s:yhag8SjdQ*!PDQRuT|A2/h0ºp\K=KCY\0+'a_/kg.z?&v]xz2ha, 4m_}w\rFUٻ@>*@>`컋Z-d[X χt[guv_5%"x~hY+om:/=پkZjk^e]uW=PبvS{f,* R7v>`= s1WȜ #Tj#⟧H-~\Gtu{=:=52 @?[UNPdJ%# ӕW^yOQC">:* nS4zR$em0 [jp߰&k.@IDATOZ8&vw,+VZ#CxG:j\I!˪3f@;&e q_lmrUAB\;?y" bsS_/jb ,70̮cO͸ bD`ry,Oluȵ=,l۬c/o{V>Uڭ `fl{nX~Z,# r{B7JWmLjXZkzƝ]g+NuTn1ܤK]Uޖ?с-Ү.]af3+PwfA-V^>u(|_.}|A‡{ձޟP=?N݅T7ZFQ=zА耔$g; >b:^?}|6 kG]]w1|'%ȱ[?#QM< @P,n6uDstF0n>^.dc/%"̥EO $1&! 0=nݺ;<e\OSڊPss$vU,w<q=p3Sg{וEx!G˞6^k p)_-_v9J&@_w,u' ~Rod֑'o=7^ވ1~Yh$<MZ4nD0kײup! Zlp uT{>y sHy3@Һp/"}U3 :00?i5(ѤIL i+ԗ*+Wm\.w to##!o!SfM2s~̘hKoܸqfH(R+.pHPWGvuLbJ)ĶWWH,O>$xo-X{IP3r\QX ƖX-6S[MUwI'Fv`^9; L:䙫awF ϶{1ג%G+_ 1RV:0λo…~=#*ev1޻||VMK-Jh:D0gsXK\4xt~D:aR8w|7÷.g21& FXճgOŖ cXW+>K:UCWՒ/%VTsՇ˱-ѓ[Ȣd;5#ʕUeZ;:>{vViL=b$.68n2@kX󯨧 iHz6o{-2n34bOq\ !C1-Clʜ7 ="< `yc{^;(PkgP<<x`A`f1i | _cUo;&]4;VݢS^C5n`M@֛H=/Z/ܠDg5k\X"o&uɿx`stiIw8$рd5hgAo8rw޶y'QU: 4+' T^u/ӏ/Ş#Na_֕a#g䐝N;fюĪ +>ad>|mK~R,O˂RS/)E#~e$4cNJ9 5V}F_*BrݞTwr ʬۗ^z)iwr+`ƽMQaG;ӣh&9Z_o']Q}r" cXL_}]L%8qRBD]n71cfRAm80qv ߽H!󉏼#3~W,1x$%%PAfh#E? r}d#CTnCrjremn"BІRSmz|e"Sw`}vH8Mp!QYf4য়~˨&O<*a?f&Y*&]N:i-uqD R۬Uk}QԲW-+O=nOdU#CWݡP;@CA ]?sl''MDr2UID7*0)i߆2f.@5h2]ps&iڴ?ξsMĝ"3q%Xt̚y>P[jC@ ?kTz]~C3%HO]=;;]*Lb3W^y[euNMWwnߪU+4\^uURx;.975ۀl*ȍv U0X~*AkGOX4pFćV-Dvn NNRr1m_#}`hu6,SjeFLLK֩Sʽޣ"NI?ly~ĉvHxҺ8f꼴+okHdqO ̞/bO?z6C$ ytn yAcnz-O4>(t *߶0^{KE00 HX{G[v{Ȋɟ7.LΪX{v4٥ϭ K@ KH5hsGݗ>Jga_gsdrl{h5PS9FۥڐХKtRXq7gcT1Ht;e7[KnBh3k:}c92qwUro=8a)@r`\1?Uo:'~cs~Ʃy"-2`\[\XNgDVf'ǘ߇vۨs8,J]ju¿-e`4C}HwdwY( 4RڴiӴ+b~HyϣF2,',QOydI^/;mJ*GԖ;.z v#\b%9L0vDYR4C'g=mqƂI`mݡoc/+tO lc9@NY|o.]lOFR",Q#:$U-|s͕ŋKcIZtRE`lu|O?O341ė̚u{`2{:Ҧm{2o@l84g7WcuB!Bd:ABn@.2z AײtYˎ veFZxgL J; <0tfQfg|P>{ߢ\kk-WWS g\HWExy;YPߊtsa<;_\weŚ0`k6FSh7 СCm \ 0zoahJjPWd>TP$U@Oi~-W @{)gpb Lu&R[41@Kd5rV ~s!n9h>Nq`\`=QBԤYLUbIMcԮv{'a%how~#K7f/2qDiM+KN!#Mp)ݍ1u4D˕isͷޔÏgw4ϓgȷ|eZD1 zm9m6z۵]cڗ3k&Ѽy0ט/ dYE=l`7G&% ‰ʀxMudD>A&ZT1E,^NN:Z9rk4=?ŻO?h h 3foH9 ]ːl0GF|_[V͑VMH7u9rdJ=ju~3cAc1̪1 l"V;q0a;Ö0DGiPLbKGXΚb{?`?YS;ۊ ^,R 0'[9 :LXK(} mS S.,T)+Ͻ5rޯQ^TR>T\_ۉqʿZWIў25s`pjlA3AqƑ>/3soV2tPsuP|/#5ŋtmԭW[=lZ*EuQ>TU.q.ݳ AҀuo֬Yjٲet D979dg[3ٕVHͥN:j)l^3g-CY_9Jg^nEb `=Zc9h \zr!m~ٳqòre5e)2pXeἙ2s^yrk_UezMvM5SAp:ю~-ͧzHX>2dJ`T*G'w>LͲVj.N3dey6F]` O?m?%`pjrdv5ӎ5ejאIEui 3;#^1ȣFMԅ{[v8\~1TE9Br$k1꒦ye+>(ڢqjđG>ҨVUZ|s̕&:|!& &?s c@I_?u>gbm6\gd Ղ yT~ӕ.h 譴\i XDS|iHh/&&Z݂(Z ?-Fد.@4y bv=|LG_:+Tp$n@ie-"=uB#l@ohb%]ƭWߕ:UX-}ԑ]-K嫟kjZ+Uo9@p0-=``A"^Lpf6E2~o&\YRϟ_Q˂=d] d>ɆZq:BY#aH1X:!N hdVZIݨLҤd2D4U^p3bLF%%jֹr=稠v_2r&ScQ#2>|xvh^xᅠӱQP,ku;-fm fۑo sn+Uo z-[ {s{ øG2 .^?K3+<4[\]~\y5﨨& w&×D2Yl hԨ4l@ .s> >y?+˝ߓl`PD9si]>Ĥ7n\o{!X3Dk t`]M:-*sOW?E" {E˲AJ~l)K Gdڧe+l+ޭz˧"'֑9 ˒9R&Q bҽp R  ۀ ÅH_6}poe72ղ6UƟIm]s@,=zmYz+Zo}7uUE8@>5Iā~:1! fe t:h3`tM|1zltwdYG<׬RNʖTC?fZNZܡu5~A}n';ȡ[; B;6۴fώ v6߀snLV*-rBһtځ bΐj1<ſw fFwQnT\I{ҫeAI _T!L~vzj&KOT 25(H0;8SlU[f"FSUQWn0n2}9k?o ʈ_Z5[Nid(ZW@?;0jrU夋9ϑ}: S+`c,XCsrҺEh2^S9s~;-P'pc=5~F8GKَf/k7YG- Z-o|EEڪqH[-U+p{gG*SHpu 0MʩyeMV5ɑ{Փwk]GzE:v|ͦ3\5!V,gCԉZ!!"2k*0#n _JΝtqw HCp3t O>1:_'M]h+(AES4k0Y"B"e.b]-ɐ a[kȏH0}!pSUL ʖU9hyh1_|: 2 e]l:?$ϡogV89^k:ԬQF>{j)&իl2s׃-ZxQԟ5IWA)҆0w0Sk*?H/Y,7Qi)pY.2ۑϤjdΧk9WۑA] $ʆz%cfZd =İ}1B{Ì1V@|I:I+N+zAɾufI@4nzy˸qi{}klNHc?i /ƊG9p~;r>ptfUUwtPĹr\lꫯe;pLV4Ip =smՋօ1~9LAr䛱 Z~f=W:_)U20ld]eNCU:[)TjXWgqg8C\Jαˏp 3f.&f00~c*$;`isҺ29tgƫ/o{Vw7^_rѭ Ύ؄X>馛k , vB\xWs9xC$:@;_}IonDzB3* ?hK,Pi3;lkow u;G#}7Ӕ%-#4H) sޕ)SȪZF|kT/Ǖ5uT 233ӁP3d#0 6&i HLuȑ6P12HłVT\Bu r(U[(\5\'}_l!;^%7lbԩC15н*e\}@m4-ugXyxgTXRwl69>;&=Jr)_*׊g_AN!V/c=}ѦKLKv[x/(I ӓi`hѲPa'mRBfmԭ;=pA 䦼5cJZUXImjL1i#=3 @}x:AecܝE){0nmC,nЎ$j{fZۨkT3ӏ-MX[\N!N5 /_IJH0 Y#[wb͢ik.QBQ)j'V.*y!u2ofyFWej#A r ez$qR&Tk-Vbm$63a# `h/ vԳPiA `*lTCY5t]ΛD;%_L׎_S",&eBuH0\;$+b̂c`pWV^lmK[n1ш0^ >@ RE?"MnY'TmSgV>=Jj۷s*6t. ltRP!!81=ꨣL(F#6>f!\ `]&U;lRG d+HKX:Ôvqϕ\eB&>%9K$4u=vP㒺 Lԏ!F]cL88bX[8'2( /iQ_V1SJ+mF_0}]X>ycAP\<%)<$iA|g,WQq4M0mWљf = lߠk"NՃ\ge0@u#̶mQmAgĉ&&5G f&_tSvcoHF~E\׳j]+މk%H5U, L #@8 '@2+hDG?, 2P%4Jg%f[ P􆄮^d"ZHgEtv0.4|Ҿ}{o%q}PoĶB\vRIfD+t0@*D;v.ni&T72C7?P3%Zgl9%9'w[%\B6}&ǵL?E`kz5n&N%0\WJAᎶ~1RdO0}81o2@DP8pAlߣ{m<Ǫ TI#߿ܫP7ߊr o~xWՓ;$/0\0qjO#ah/p;_vJn Ei&vMat68m!@'Z00?ќWV>)i:Y0pC F}Z|34X5 l1b,D!b~B6k,zJ6lSeɫ6`#US_dlZ]F+?x7g:mzn B VŃYs7GHW͑?[-SK˦ߙVXhv {a%8p3-X䌋$wd Br/TB:ەTڪz*ƪ0J̘)r";KE*(,PO A(=t30')gUښݢ{uT;{mk1g9ϘMjW2HJUe=0|}} څIt%g`DnQ ӵ҈TK);rA|4ct]ȕU*ۀ'Є [@;L33 ?nPw <֩9/m(uE|3x/Zb'oeZ8YzPY9hOV˳ۍ0A`:SltFbE8mt,cJazgrӲNyPY-U>tҥ.cJhn켟%w x2j9j[R+,T =]P7N?d`e7ʂ{c'0Pf}{0 F?6ݕ簷͐xvNڱPVF x`N,fD|*ⲁU+Iľh@,Gl *O_<\(+rOSDԽ&ڶmwO}B2ٹs `q:vV}Պ :t!LϬ\|f`.d~y*Ң:UKў/Gr-LsP @[o+C{K1\x!!] GBj_^,{) ~xD?bw0r8pg䣍SFgh+2I؀άޭq@Nre˙;kPL@K+d G̟}ϥ@8pCqJ uuh2%N9֦@cua~AMeݦ2yZ9=L]QB,o%?^M \y}jҨq3`0@B0h̳dabQ}F4BvvT>9Q[oOȈO$toR=HO=B>x>ӥ.~{H葧Ԣ j(SпC Ӆ_D)EK"lJOhOܬgzaDdఝڌ_Mz@][|uA :iݿWl``uQ1{ Q 1 0`zJj=NO_=4; (z3 UXn:Fk0܂7|$;}Om(422dW=h]v\sBydr˷SQ+HzdzT}9sA?ZhdK͢hcruj촃.m[Ȗ{j. י~6F Ȣ I螻%$D=Y@} vp}.(@{m@ܸIc7+4j6+`>]\t\`Ԯc #zA,of)NjȺNDEܗ[?yq4 q޶-VdXyo< AЃz]hÈ6[iJ7Qg,9|O  oO)#^-'VEHƎh. o.ל_K=OVfȷgI jSt>v# xLOɰ)RfػuW;fH藱jHH%zt?MBUu-"E"^g Bh$JQV H`&C Łqⷆ茌PE覟znf ;^{͖Bbu5zƍe?eي<_\+_Fn&*ȕ<亨|yW^)}5 aY>0q{47:? BCCgBOS jC 2 yq%]ǁ4~Z4[CtФXj fWSϋ@c`wk _gr#E-DO)H 2= /(I2gϽr}O(S3|n+c#}%:v 0-I3( g=2v/o6e ơ\\ynM*/+='^>W'W^\j)p qڍղHXʾWX&{wW֬ǣhkٲbwWXW,F懁)m)Bub !U]䅗?uAݫ"J<{s~HU:甗~hV\(! M )<_^e5K/̃& F ^ݧa)OG EC2TkUb~yy#۔A @; 7A6`]֭Jq߹{zxϱY4mAPRyͶcDV,뵃A_\ A5 "Nmʋ)![M8(`y㩧#{YcR #>lS*; {He 6CD>bvʊfJSWɅc6؝'s N Rި3<*-ϵyM?mk>M˂A n8W],J̒4*Ě=,+5ҙ}MF!rf0t鲀[NR.P:ԋ0ږ.^$@ÞP:|],`ASL1e jP+SQVJ9صrS堽+MV<6A7첼- e?Ii ix9|p#lWƄBϿSSs%XҞ-Rǜ AoKۺk%1j{N~ͦzO"~ɅqZ3^=i~<u} þb`" wP)ME$$|,e ~MZrr#,$9թ91(̝"©zzUb&;J[:'&KA;]{裏DXĀmNAt5'=O.Сr*s'+WSTpfɲMr9e.3aeG B٫W/l`m'0a>~U7) [S@*>BEvSMO܉3$wKEPu ̂2%2lȴ^q-kVt2b+ ) MHAWxk&iyBW.tӵHNa4EZ،|akhd @};t4!zn _ۘQp.HPYݕVK+r|qqP <1 &?H@ԔG4q7.|MˤӞN`*z,c^|ze-"57  iҏ'|R.=bF^9}k IA qLB;!j`(RIAg_a]h.&_X]kx"[XZ5R J I[u#}M{Cةo߾|qg[Ν;3xyMyn#`z~\pa@=0rI" *EVt x]dnHxUTY- 5VB+7Sp7ڹers@Xs~9#GpU<=U )=sET]|1G>uԋmnd2E3`/L&kV=C{mD?YGl~FTCGuS+G<{HWNXEP-M>r/ U;?XyX]u}~~*ALZ4k`';mk(t:~7qT;_]RPA*+UsN.hdg\&A;XzJBw2=G8PO'$S.:%>&Qj7j'4:=P> LtkUTԷH%,Rn_lcꖱK&UC@CSpא2L 46-2),=.#ܾF xOuQ:طlR.qNG`f#m_bpL1.׉Z+_Z= tƿZ *O"pZ:~ r̡UIeJZ% gu;ܶm[6$01*xOB#P#S H4g2B~G/4p8\D|ƂTy+N|RVlJO`b$Ҥ"s 0ڒG0K(_17Q  F%/1^xvP.ҠhL)8ѭ[-ӈ{%qb5 Pie* NA~c}SV,N 1@kmp!Xƈ/2mQ6L`8-84{ B3y>|M Q)qOEٯTq?Md'R/:rO]dw!(롲{Ғ&ĵ=Wl?Ԋ4Uw: QFIƍQJt%lҤqr%҆? 0 _=a8T'5rg:MeS aMcJrcd3>d+dDxy57oF9r kkF|_l m??^y4oIx v{|wυ%SAíy.6 Ne SV*ƕkWOfˈoxʏXPQdDܗ@[4{%p` 3{ӵkW%o x8-y/@jVNk̑2ﯔvە>jLA3yFr5tG*~Qζ`~&=l(>5qp[cX( qk 9Ԃ׌F!T2{2,]:pze G"F`d*XEGR&P!A_C>m~_ ) $cر& vD}9j[tC-Q"׎$vknם!\W6s&q)l+H ς ",Yz FEö,GD/+&Յfҭds Y(Y<>D+9d-i׊PJ [-PXY֋~N0!J$oRx`c=l3 ?.Xm67)gQ?V>~p,k/4(L$?qZܾB:DyBS# 6@4ChG_Z{-?,Kx5-M@'R4T{{CL17D&CpA @e_auHj kݻ;ض5_bQ? hニcD0s̱1Yjɰ! (= 7iXVSA.uhRVƏl!O]O෿ *?SǩRUbkpY'&npw% \:B*x^Vb~Ǔ$ډ|a4dselHˑA @F>DM%?~xi߾|֊Fzpm&(%~wd؈2zz}A<Ko97yݫKupUA2K@8iV!5lh%d1Rٹm99y5m!+T`KV`jxAߠBM`@,h-&gQ!J/Rah {8 6n?~@wu;3—/_.w.&yIn1nK~o ę96=?3S6דo+Q}.&Z3 {а쁌, >ڠ HT=ziEYlg~'ESY~dJ5uewi"í'`#meTd?9;;YLA~zK `=atXEa`~w3o.pp8tңu#oKt{YŠ2\]PMKMQs萢R (9|anc!YL;TNmqrIQ5~K@hR̯lUP]uR7!(ad̙3~(%M?¼c=&G}08@W=z{xJ㳫YY=xJ?M.S|RK*@<K畣*=M0?/eh *B=&mI5j\|fd'Gf>eJ{O;gqi_%NгLRϡ.˚@Zɣw0>a:J%kߖ<Ѐ+D2  RL=tZs*p/![Q|W'C0N}~w(N嫆Rt.U5PyyN>hb4tUWEAL#' tI?MiDes(}?%6c 4ڻ/ y4;Zdaa}u֪HM t cVJ:0-'\%k(½<%,]23D"0>~ 7Hvd8fm+oLR++-)}H{ O(hp;Uhi"懻)n-:fQ5TC8#.H PUL%̯iߖ^U=FݡG)/SN]Jo{CEqqgrP %@F+lN6&KP+]Tlkaޜ(ur`Et&#/6sm2 䚁#H.Q77뮻 ͛L֭>_o :]/@*|y4цv%S}'/ǻESURR15WBCQȊyjqڿ pF,Vi+R&a?mu?pA/bKlZ,b(ܠ)(Wtr@#vHLGc*i´? weyъEG(`kedUwZ@d!Z/^V Kp7?ڮGP [M0 afguK83k|C-NOhgw-[Σ652 ;e"ן?K ңӅ.b̸53>ӋrVn/]'Sfd:CD#a3A萮\듭꺨-MIIvKq$5pl u $AC() pvdc!g[z9Tpڲ].):HϞ=3XQ<묳!˚J-B!J`&{8=ک0 $'t;!r^tUԝ.isHY:HoTwjS]xS !Z rHI~+zz򥗪lz{EmZ[uV'Lc_b";=`J:3PXWf`wnO^ltDk2{2YkQu _vZO5#90{R%:F?Du]Ls&Md ~5;w{F_Uz$ޔ|Fwp-<e"X3ȳ\njԕh7~_zq}y(t`@ڼ_b8'<2kb)lKiQe= .9`zT&Zh#^6?-.53pP;uHXj*?3T 4ym t\ 2,^QA]_u =fOdw6a%'-"0l0g}iIX&%=0=%$XHj"7 aZjq!$|J3oP~?*a% RX^Or؜ϑxU܄%ʗ.;(}*}R{`Q)k…y4;ҽ{wٴ &h, K)L^M&qQӖ/4ϑK.LJs%6 voGt,d+l+)e_J$pRhy wAW7#x AMr JS)|Z֩ꐝ'0q<~c;}zSN=Ocma%(ci\JzmKIaA@󠄦FwT|``fw&.ᑥ @  %*@ްH c[i5,jWw:˄aȑn֭[K>}v[.#ل)knK$Mt $.M{s̓6 &J0ITḄ$Kb|S!^I[o)={yL>Yd"'=9 4l?a,ʧ4E@ufT;' ԯ__t"/"3"-*5C}}I۶mM/R3/bJ2ݢrjh6 vJr3h'Ԕ8 OA VVSKnf4Y_5‰Uϥw++W.KYK@?u;uoAhAA<0 ܁Pv\4iDnfej00ǩ)^bwt_yFq (Dd)Yk ^zo+4Kh\|ɷJ?nHv}N*UWjU5Γ\"Ӱ1s`7.J}1*܌4}zwuOj ?8}0''Gf.m1 UT5j U%2c /dԨQ2ztR ԑXuqS ,RTܵ($LIT*'w~~g=W.{_6L宗:U붮U,'Q3հ8山]F&tZx_ʋΎ_ϦGNd8= 5;=bK~ŝ)(3gb~\XT|}rS?*l.HM%ToOT򹣾q_ خJz{h>Я_ޞfBWW;VjY"433JQex.eŕ5W?C}ƥrո,5+ӰB⛊nGЫXcg)3MY{4^m*OztNIX0\liYK,e~]=\۲eqH`_]{W+,8;*fZ:#Q?sӉQHjß]`nݠ_ʬ%ӑNlQ雇 ?SF'𚾒o<ȯ=r2Nb$M6:&'tt_[:S\{E.Qh̟ܗ2(\aÆi=V׬ݱyss7EuMҳlZ_Tm8П>PE oOV ICRI'&2;O6T̖::>8z===7J*uc=KO*OO*֥Wjb=6@ߖ/n.NOC\ѓl׺TdUsVs>sL' ?g%-s}VCjȮe~_ ao ԝT->cZjۯ;՝;wr~R-Zf ~?~g hհWzXlU zx: kMg2`q۴.MdؓtE$AMlM|M]s>u]VH>>?o ^? ?z B~<(=DM:9n,sA, /9!s8mkHu83cBG"9=6z) ywDN},\^]oj'q VsYic08DPNG  IHDR\rfsRGB@IDATx]`TEt:!zJM@T"6 Q+X)""T Mz5@@*o/޽܅Kr) L^}vΊp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jiy-i2}@ 8 o.xZiJ\-P@ ʖ-[a??^QܼuʕHs< 1uF[I@:/0h0_|=o`^.6B t+[lLٻ}T ˗͛*Zh ?__"&9(Go/]$W._(krLF*aZb 3 aGvn'\ GKifH{,(A%5qhZv3gsrЊ08P锪TK[ӦsΣ˕+W Cܹs'N'ĉri_X c0 HfqAZާt?۳]vcʔ)z@c$?⼋o #@O#_촀ig܆]-ZL*Ud5)SQvu9~ShZG #N?$nŸ\XJ'hrxQbg$=N.o]f͚30W#_v$F ܻ{6 :ܭﻎ[MB~)P7ʕI{=GyM.^'O=]-c57 vZ4ӻRŊ_fɜy՞$~lG)ȎSQiAoN171sgA|jِAʃոo\g= iEː_glhjXW55#0۽TXgG}.Hs-@iJ9͕. b k|g4<,LMi'cKOX[xjf5MR`"?FL`&܉r4ZPvRXBCջWZOS ^, Gx.d:94667 i"k[@{ ?~ l@=GJԹ :ek %Te1LkY F}@ѩ|a <h#]G7"?,qh,gЩtbgƻ?RYfA1KAj|3o|uO&tZ9)OR?}1e[Ǝ#7\ƌOplQ`4kF#F9YO9SAT^>6_dCSb~I->#Ь4H^D8cpdZ}|XTO*Z#>7h8sŁ83I 2; T&xK'~9so@x\#W!_vcǎA= iQRO㗦.)MЗEy4%a](Gߜ]v0t߁HIqt$eK^xg0>PKݾ-wq_,8T`oܹcZ1'Ç V?x 0^*\;)㻿uG7ׂS&t^a"P_ȟB[AN1JP©Cp+G LJgw%KDQRȓ'ojՖm۶ʸqeذ.=tHE %fx 9i3 :#?w;N_ hCAZƌk |T}ޜ+cFig~=F/D2\].5m*gΝMHS?$πm?< <9-'C%禥&,;8M S"%M{!!N0a4A߀4}YA:KѣEV?ڹ ‹I4FxeۨKƍmZ~9[* iX }"+Na @[VISQdA_J?'󁫀VO^yθq "~#Wva 6fTRC$/,ܶ! RI2I-(/x63y%aQhޣpCRKݑ: ,Oo KhO|?]^!ǎa'¯XƮT<~FbN>4l@~bW(؅1bipjin%-F{I'wR$*`'gN2铤0LT1?pai7!_>y](]vY=0?F`ޙ2Iھ}q@?p'$2kOLNV* P3i n9h9qK xzGrHGJl̉}.e$אAJ3"Ws 8Jo!>t//]A%ӺR-o޼iLK. PQ`1TƎ] 6Bj  ZfbFee4tMhp;yܠ7aжySԃ(oA7Hp!Pl3+W+uo~ -ǹLx~OߴJ Se4Y>m;DM(Tۭ04d8q??o[ nď)"JC*ioSf>}sZ kM; !!_BKqT6ϥvČ]fG# cPON=`܉p2r0)H_6CO iB0ϻtd 9 Z 3Ӫxl}} p0zJѸvV.caJD yKtm@.(1|8?u)A8_ =4S7M??9&GϚ-1 8=)شtT~4vZJixiAl![8W"s BGx3RG82r(VnGR3W4V+G, h'l||gI]8:Ao~NX.aU!,AD/H||^S֮]gR\ 5ZN3x?z;09RIycjСCeʊDS{C38~E-q{s^|QݾMJC9/=viQ:nFը.Ѱxg*)lLQ)AgU>Pd<~X4}>|Ο?/^-@ ?<4kezrO|FglY']5i".tJBF48$@;{/C ~5j8⟁7I~ov'2 &_-cx2i 7&IPhf;tH`>kr䐭Xhj;WCBB:'m~C޳sBa48:g!ō~ȨcXN@e:wT$^VÊDPJg1hQ'@9^ ,hnK?/??{᩷rF[\ZN.^+YJyDhWG|n? aDn-^\ܢt~ꈀ${XoQπw6$ik 2s<ÇDJ$JshYRfMjתs_َ?ڵTyX5kxu֙A! 0dA<(7nNs~wT MJ|x{|u}1ԣxJJB.+7h`r2p n7IkW9M @-< zm#G VNi 'FxB66nܰI͚u"tBHlƔ!5nt %^{M,bnߒ*U]|4'2[4t}ֹSΙt✒#bƍA$,9$?"~t''C Q&ovퟔÓR69d,\sMkܱ i PŊ͛A`RnÆW+(щȩS!K|秐4PTRL %0O* k$7O95[|yݩKɐNΙ#[ w}~Y.|l D$"[(;V|X"q-H|~pմ|P[N{/{׮]/Zm Po})Zx)O s/5a„ Rb;L~ l̟_MJ^J&IomhԳW&~pp|_ $O|ܻpQh0ۈ#5|~y:eZF =h\ss+HaWF\;.X`5= wj^LYdɏ4X ҁo)Q$?7%NNnݤ}-<#- 6r`OwDRRrDvH!By(m "a=(Rp(b DO8>7bpDE eСr,۵k+ի9 L u($ `P/Ω3Fxʕ(`$ #dݞ|*_rmy0&g㚵hڬG^1's@t3fb.4d% rXB 8z쌲Y!d}}.2ͬOu$ft:e_?&@'mGHsBؖF$srouSgHfM$GM?``j@G{üu]h޼aF~ըQÑ1 O6<=ի;azIg:J*,[4޽<'u_1ˤOw}Zq?ʣ#GO6'6ȋJAsU&S(W͈t0DZ~>7lk.̀/O)zODb2=S~${Ϝ"T G5ƒIpꐭR ss'.sA0?"_ ŋDo05tl޲M@ץ*O4$!HiXp\ǜeϊ6.> ^ӀًJ#` x/ uڵ:=QID:*U2%Kk=rJ2:k=:M͘YdS&#m1o޼у .sR>WM~6gsT>01f- :p@yI5Ν?ڮ[UV4ox͆*l,2o2Q@Ƴݓr:L sTܺqSN 8-$hPLmZkez^+ZDC+ 7r!JdY}Nǎ,:Bcx|m۶'2bI7͙dN˗ޱ4[w8NfM{z)b |Wy!4%Kdr6Ux5rx(썄$U1a92݋d|I2\#{ps6t4w?AD)*)Ez<'9س7δ=7GNE|` D_<r;BRPCs^CQcr|/_V844lhə-93wVo޼)o:?eV$w~۝3:*Yv9dIaYRSSǍ)} E(Wh^uhɤ?f\jEʦno_2ԩ8ϩW9Ht+KE ۰zR,1?'fk:t~fB}e_~!uQ.G@\&*Bfs:-/o OฒH+LQ,1Vu-ܲػGs@<[*RaNap)@}5D>o' _ V<,Qʳaߙzg)@*U*0dȻ8?dc 1'O @lFxn":H9?x $sz2}^{OlxEe% \sIYOH bÝsf=kv.;WO|fEǎIdˣGyӷ`@>FL ;тjj5G)@nT` jlۺ=bȑNO@!-Ůg2 DɒhQ %3g4 {:,]JK]D]֪v:I q,2'v~ $bP |z@Fb2C C:ŧ|̉،%]W׬>QRF4iX\Lu`AO>nݺw7nS:6%W?ot>n 1o%kqC"ݒ#ǎ?jK:Tj3ɵzzҤ A4gK.cbȕSc7. \cǏɠAoڹzim :p Yd׶wVV "n (!]p_F[."׉cGԂ/SXS@&I̥،Q.\ht[sŘ=ǣ$64%TfM!N]D(V&VFڗأѧy(-Bi.˟?s"?@RYr``䆏Why,F++~8abPXXxgצz`y9&{a7l2tC`/lh @t\~@Jgy "gI);K)=rˏߨJֽ񦜂MbجhXsn]Y,ߨjo|F)`.1A9%?ږ/F5(1|qdc} s4BO3sJ1D& ǖA֚x[2g;ӋZ·ANh0 ٲOGuB-o !(׬F`+8cאR8Z*\FHoB RpaI b |rUeFgʘ!dϚqTSSKZN[gX+  G;/MnO|b%+bn, vQv#w:(rתdb\_yב_[Dnݫ4^dƄ,!a߅xV@F&{u&9%a%$Hd.F` ʛO@Q>Onjs3 R)GL,֭.Ou6͂,76_FN^ #~E4V\Š!d˚?{[UG'=Z ݞiVftY2gf$ 4xRYF|F 9J0xRI-F3eȘ<'ب$5 Vnzu|%B&)@E={Khui)'!s_D.c \p6z $;}1r}74B1~6iD£1d\j%y0HsJ3Q1n\_p~4z3>bx<%pak(ϟ3]:K\(pv,{8Ȑyɯ;HfaVF{Y,Y ,P.^8$Jlj3^ru/^v"&Gk֟ HO˘)}fRPK "<~ @tJj <琍E"X/Ԯ]K," e Θ1|twi>af}8!lk`_0@>tPwQ][i1zۛSՆ+`;0븶dD9Rd Ar0F1ol 6G,rꀷ-λ_}kN; MխWxD09 ߄;,BSctˀ>^-.&9E`ap> lywgN߆}LbW>/@g)Ns-);RZUY OFL؆vޓ۩ ("BB#ByDj)$GOIhNj)<"Lݗ2PL+,ƱE֫'1ehk$2uĉ/{rrw}~zЮ :g,I.^s=u"a){YPD~g g%`aiRRG s9e-"sj@ YPR> ?(_ִPz|ߚuZ [ySr!o_߹s[Y8QP:9Pu³kA$"*B<9Bj00=w5_˗2\J//aK-yJ4XNP4 Dےv[^h(9n|;ƼJv}6xΑXjV9}nD\>#PqW [iLsY0%7a!-7GDhrl qNP͜!15P ekWd ]~c.e ֌XhGcRݺAOlxo 0M3A UL%; ܺuO"A]Á; pZR#pTH pۃ E˸N^xJ N9U0%5?4^;+/e#cjϗvy*;*˪sdf!.7x[p!j@FA-VP."#8 ~eV'ydU9QY--Vl,ߒL"zX"x-4+$ۊ慨|̍,GHd &}," @GE!;t`Sj0wRgȮH.C)Df*Onno `H 3rUťÔ)[kq#[Ƅ8f<\0{iw|dIDgNaMV\`z&SQ:;a)0&˖ yU |}2'sQCiR乮qhLhQHi`SSqG8 >+c* 1C7t]8'$x~ tى:ap|KޘМ>7v(>X,EvOoJ?@IrP<bܗ*6 w䯯b`v^oSn|+EOŠK rn,ŽZ>>{ ggVfg¦VhuMUHD5j h<`aVC5!_qP rĉX£RW"1%cfZ~txbڸi#/w79}4FJ=wwHׯ)E%L}$z߂.)OwϞ6n^D3â#A#%+ GCX]e"I '*N5B* 7,]G[0b?M78ˆ J?;=A4VYE8Ct1BAx@ۤ!:4\0O3Dxw% O"ǟXn<Pu|J?)+;Rrr f!x4%Dwb`t1;=}K㷀֭NN& ݲu TyyQ'2w|r^%ͷJ*|%.GLx\kc*CCGc2჏.c} ;aUx)a: qT7IgQ~g<| EQ)yAE{Pfՠ]Qθ]N@YI-gyVOwzKr-B|>Ϊ/]7ZmINrrR:4sϊhA9r& PF50eȐ^9l9 mo|kׯJݕu֐eK[t\5?j x8I9sVXxXrʦVIT|pa A1 Οw h+pyr`iNi<17V@A??xK*bYp>ذ9zY@ٔ 0+ "|l-Ņ1uNlLŋYc3I#^.o Ms/b,_ma"Ϟ9[~z>y xbn:X|!-r/SS#Y5Х}򷅋W1:K%l 5pԯҨ[&앾]2@g#7 `g6^1^Z~s4V|U+4t:ҕ:%a anF@O UnUdfz\#OUz5/M9@)D\2AaӵˡpW?a!HBO?f-XS#g,D)7"`_<5ܾB%1<4]s8˿.#GTh|w ;*,U+|ߪ.T7ܹKITce+6usD5G?`xOSغl͛7Qj)3IdÛ?nwY.m~u^I=":|B窀5UhLXܖQiiբu붨s%`,{7y$T4 /JʜgQ;#M!/mr?:uրp4)kJ({I',O-ދAUjK,{^u~,C@ۧOY^EY|&a 31^Ay4@N)J82gի7#?z6(@9 -a[$;@t~f"ETD>c Ǿ{[!70K+@":9Gx}X ķX'.0"i#^<טϩ>RO$$"m?`"~ GOA>p'sM@%15mk8N.HJO:uj h({ (s pz'c}.VN!VeA005Ŷ^õӠߖ>%xXa1 ln. 7^S.&5AJۅNIXF(X$+A(,2-s;}^:ޣD@:}8qzUN7;!`XQsWX^~ieZ6 DC?ŗ7:rb(ps;{iv=˾B:1h+߷yzѳ\5`\GਿfY50Ge8s+7O0dvi=HMS:cǎ`B49G$LQ[Ν; *WGü2?wYUzqT9}0Q~]GiҚV#<|Pkl@1@`Vmj@D3Wz aXs.SJh=wZ.e(f $~46 3M׉Wkҥ#(iHd>ty=te8>D@$9ͅ;VUS@jtF+W\Hqs|>C_7)>m<' $bD`F&EH s3PfRLp>gUE~EAcV[rb+ {zPC?,!#?Lx쇉'^3Տlik?~(iCY~0u Sax tsL6 ܌'LG/1r;r@s .?6;'˟o Kj֏j_ز9NdhʌVD4h҇ 9󫯾*|D]c^.崒&# gp[5ȧrCcjyL%2fr$n/u"H;ӦM?G|+$i_~UTYl.j)7ҏa ajtdj5)̚5VEuuj*/zۧGF6м6G17ǀq+HhԩEO@bUrlt  ! t?w5d( e>4QC#~\fj!dftl 26zzJCO?Mȃ^d~b'Ih%ZUsR*΃>thlij5 bv3!~9} "ja[;L9|rR0 g E$#߅r\FlGdt+^VJ T ΍ $X} l?B[ ןܑ#G4L`"( xk:vj6a„hɐ%ÌkFxǧ W%HJ߻WU^-p#N1W^0`@(KΜ%prtw=n7<@2Xͩ˹kT?׭Wq+N1!a |lYϽUsL^@yʻ?6ONb56mZNVp"#!#|Vֿ:] xm/ ~#3}{!x""گ_+"%mٳΟ+`o;Nd HXYتZb(TBFE.0KJ#[h'md1$C8"=|[+@}:QHabO?(Km6 ᧰k{M̌ LA_TN>~uc`VC>Ჾ{' A ~KԳS5j>n> w3g>`YaѼQrȑSl\h{Nj2 ,b9} P$~!GeJRJ3_!(JVfElTތMǴH |8Џ?)!%Ʋ/)ݣFn6Bl.lXoqAC]m=/ 9G[!o+aIs@ [I>'s=(9-X 8O(恨Yc|(dӏY&A?DDf @8oܸi`r}.'l9xӴ e@ &u3$cHOAuiOt>XEAzd  txdZD^#ӧ&ߢ7 Y{@m.>bQf;F^s7tr4YNT#wjal*ݩWঢd =_Ng(}X(řxB ݒXf)5;F(- aDM;p2{,~ƚni Im5k"E e(~?~WqB:";po؅]Tl7&cJa-Z(^Azn"*%XPa,r ڇwq#CY'am Wi"Hx*A@j~ 9dO24<@_:B98* 0_&x{v[oK=p`:Aci7/sSdvܾ$?>A߿Sq7v!kc7mz0ޯ7R@$?&%Ooep5 <(Fԍ@iOFw$H-zY*2ɬ=}tED in.j4V0!:r>G'!~ʌK1 =1&ƬzzO@%y;dь~( L#eTe 7'@y xqK8Aٝ3L #*Oq8¬GD's扼fiטzt(`z҉H @Q s] b GSRo(^`6th6oqc3hgcl;/51& [j`3=T͒s8-T5UM$ֳkƦ WRp)0`|0w7C^g RJ,;2bL>e2v?c\֟#q rq+!Y)) F0:c|!N:zt_[ʕk(N{-G32C2`r`kxa9 1QMmWȬ.]5<)QIcn {^gCJbzzD%6K3%>Tlfɘ(n޼\۷_yqz&AUn װ4jyP D7u$lm={ @]=z$1+22^w~B?ad}ӅT#D}[! IyCm]<pҐ#MBϣϓd |'tٶm8.雺0gfd*_#ŰfG3. ! E]3p?WĚ9qBu: |tݱ]7nd-ϊp#p9?pe`3G]r~2GCQ4:vLB` ;AgŻp[ 1H<9Oi[.s6lX,د,V ۃ>Xf-X鋰 1.H$)+3Gvryt#|y$q!hWcu ߠq2ĊDsJX)CeFS(xԮBvRЎ7) [0_- ޢOvN`#Pǐno5:NVppw`~ SAXÞsz^s7py,r0ҽp}L#  CXRD;oJtq 2]ӷا IhڋmF7#k5k֬F jKA y~ڻTj@¥"#6u#}3s1;n<J _VZ*+{cBEcғ!7?]bEIfͿ\+i?a(w_3mÍzSe-pH~XK'>&ap n][ Om'ڻDDWݓp6&j x= I@j%?VnCO{tf V~yOB)2i4%;3..P{jz.kVG yN#W=E@VýV95ufGRVfј7Pt.f"!s]-Tnef@s2^}O]*DB@L֝<"(wvz~O22HZPhH}ArtւPfRҋ"~|DV@_K9p!ќ8i $ȅ$#@= ɜX`YFnO#5`id'rzyf{aDId^k|1@8q,0%:)u.Q?GHl$ 1ˎeREN9گ^Z)YNB;^`̇}XZ<1a*ssC#0n8FEk2gNR~ͬ٩pj-O!I^( !1#_F1qD ,ˡ\ޅuͅpIȞHq(1L֪RI1Bb5gHynD:)iDqDc]5ZIjJbB5s=cQ}K}4F`^Hxؚ ZP_E?|ǍFf>F$}c*qqNβ1 di6b<n'N\o~&i}038-b}hum)‹Z/@#;hK<,R,=aJWϙ皡XYk! K .w( ƣhӑI lGs[0eKA8د߻ [K?\J/d>`? @ڲRX@Qu6i$O @3| Sо*(3r49/}4a`yN HWPWG^\?`\ea0|+y@0:!ƛ9F c^Ѥg99"ɱs ={lN#t/h Xx*}`d!t7}SÆTA4(LD@2sFkT}}^L#nc,?7o0cё.QUYJ6[ zY/lޒ-tZ"<7F,^ NI/ JA3!bNXwTFp/}25]@}xO#0Špm 3"#2|H-b{8>"Ǡwdߥ}hj-h݇@g_g!k:12[lsL(P p6+ a@*GkV³+A(lPɨW6Q1n:G3G4h`s^&gΓeqwJyuQMy.Ch[̔!bˍ(WrO7LaFCB3P`W^*/밃XҤۻz稴¾w$&~>xPB3 $N dŋRg0={V7eFO)(69Ś(]RYD;ؿ-úEtVӅGضG?q2+pټBK "HldikG}#7 +AJDy5`k^pyͳd>FW28,wgr9'el2*[VAÿ`S_p2 oDp,<:%Cׅi'#V-]0'3ws/@ɓDHscA<4އjl [5vFG2~0];4RE),]9с`:h2҅gc!̨ўʦՍ`=u.zD?1HlyTϧsVeʾ/ ͝KM쐲>cV mU_P?#(%$ZMz?<=9ҭ\ zn}~TQ  G (d*&؍u xa&v܅0h^a(Ôwwn@Dill~r>XHR7pho>1kTo>mf[k#>te̞F.Kp{CNn, )b5P$XA2 v G櫯)A\74+%a ` )tYP/b>4h^Zg/kuj{c6ɺ{ϱ#]L`}柑ii*JĂm֍ukv+&q!tg.(E;vR~"5ۋU^x( ֭n5{l'hR1PIiӞ4/{ow-$ d /o!B)B9XesOݟ^_kX(12O /G;:h I"גvlr0RN\Q7+D@#-1? F#$:[s^@7Q2p}hr _6).*K./ʉʅV=FfX#.*׌ g#{-+QG;,XoDk Ay[O){4כl޽{b&̀l+{8NVg<թgǐ` @ڵ[wY+GdF@&@ ٌzOA6&zd1  T- NH >,#: HZ|33&(k 9dz΀$2WYH%t xa K_zD@[آh4Sآh F5v{b% *XRD;}kn;wgΜ9s,_Jz@@OȠkDEu^":4o2CK|C6I4I}XÀ5~VH G[Rk*|X0aȼDs U~{MSY h+~t I+C+i&q ]1 0QI .QI@A-(D"t |?&5@hy./ Ay&>h43ZiPGʾ~k S쓓wݏ8&\rvPgD3aXLC3KFLI9h;/L՝.yS:k½/Nژ@VknSd[?^hyg+ίUˡ?/+BBR Px`]k~% ƾbgnMWto -|I9) ;)P}a@Z)bPaK||@(scW@jt*'#P%;w]wTj*~B \^:S+Ia '*OPTx*{.;>wl4u.q_kZ4iC˷޶ ~僆RY 1RQ`B*y|rtD`Jͳ~xhz8L=PQQ!uJ򂡪af4{ ˿Ĵ ]NF] +|F*J qBohs5a+Yu=Mߒ}tQH!vKv\. U>jg"` Jx$G S{@"VF[ZM<ҹ2֦LoMo0P:t[~i MJ"sMWO:eZ' rZkUK<ǫ`ူ5@KC0 oњŗ|,AGЀXZ7'we.t埬<%,RG~A!66,_\w n'LC^kvi8}COr?黋O7l}n 5}>|W/& FSt?Z Z*?-J yO "*L(A9+TCQd>evύmʴvدZYw٬/7%vm媀 pλlO>6T-j&mwe6ڋtRik~ M2#lǐ FCob@/\k$\SV[fzӏ]Q[סBZpv"[{aN Tc7 O{ԗGj?bKܕCUuO~ J#VBrBZdrФ7'd_t[A7ڷr9]k շg'M0_wf 1 bG(DK ~~^B- O7cIA `/_z^<_ E36H`[p OAiL1<H8IAOwBfgԖ,kMjoϭgMko )xciǧ 1â,ZfxGeԊ{udNm .Q5{}[MJ>P6k! /l ; 88{bl:2#-ổ+]|H}M+-p#@5cv0[x`!}},)n/jbF>Q&-m?/$/wJcؙYը< [la]*ح pKN{ .m&9a8ƶE6ӟ4iypOG 2+4r3xA*t͗_Ol杷ظ]kK[#u|b<(㧝]Ó(B'$OҬ6t C{.˩f6{v2(̾LMwhlﵪFυcHji,c Cplh?Tr<Ly~7PQ< z$~KZxdM=÷iB"MbdWʩk 6_`=:zhΧZ1 U䚇?衇\ho<4mRd]:M[=Oue}M6<rl{ͦ6r ߃; a `tHqxT WlM=Vʏ_:_que}[\&Zq$ 1# Oϖɓw>Z*' %c,ҭBy`v}pT;Z{F#LgeWR_0g 8l]|z cV-k/w]=ߒ/P!R\BwvaI بQc[ ϴ~GK~aB>Dy`K=p=WH/߮Uu.BV.JsZO5y [٭aZF7QND:&76V٩ʾBmf~-QӏO@Xjޟ$-)}ōtGlzw5‰Br3t!>Phh c'DPa8[_Jk /`6^J^.:mn;Օg/Ԗ»iRtʄ+}' wF9̙0?~xK:0<]}nX1(5"Nv]IE.fxpʩC4XXyfOC0b %` @}&x8L PF* (_j CE62 6kH*v|:,)n`8-QݝSf>@}Wl옿X7߲-oƦw-= XSa O/@xѶ_pyܫe_9]*iOTF7(Ud|/O҇:@ډLpOR|\F߭!Ȅ\/#9YZ \ލ;q 1,`:?& !R!XtܒbRڣgr*%!=a8`A@?Z@ A:5ZQµ !>"D셷Zۈ?Of{-Knn>vbkɻQ9 ` 4&IR[޹[MF@E[wPLePky0F??IL7|;N3go[fūq<1Us]CxZ6 r\V_  X3XMTSI >ރHK;;-n~=f-Nj-Y4/\ҵPz{Ä8\c Bd6+>O]q֥KBkSO9A[:߿ⷰu%]lޚش.SqQ,l*;41 [ ºz]5y 6Q7[h?F.EHtF@7GMH`tzt7ڏ_vg! BHвEfA0p CGO8gFbZ 26/>a{~y>oպ:uwGu߳qFt!Y .+ɼѨh&}`-[thC{AݺVKuIP2o6cSo ᨤHAt5絰C(X˦AWgL~|Ter ;EU2`ȐJhyKV܌: .Ve凯W6xϽ` qZ5@Y/ #t4(EK^#$о1Î/0IГ9.aez%hOLvYf;y纮@u~ӭuϾRl!{S_|1_۩n/(?O?UK鮵_ 2LƴV  3(_kq@U 0:klbJA^ֵ„%B{R{򥦶v4_koimY-щ8sx |7`ی#fKWI«m֡r>n>PEEs$BZFD/yp0^Ko ljC.S?!W0ZBhB̢r+I<,Fk`Bh]x9fj?WVVWzYrT7^z ,hT쑇wy/YG$; N`Qu_*͠M֮hmc*=j2 jfL{XiRYWy ΞUyfFF\[:7-mi}I4 t0cQ2,CWnm%V,Iա# m>Jd9$ݼN,[v۶vں߾0`-VB'TFF%tgekП ]}eAa8>+&ƽPGOZE'b4ۢŋm&?mշ[!7ztX]9IZYmba$ |tݙLK]K0Xf_E2G]Ǘ[ !ނ%T]h3hQh%/Z=Yz|MgkVo3mۋRA4~!B%u/+mɦ CYw IDAT|^l.]}GkmLֱMK~<{}Mr 5TEhOn1Pޢ"[FDd2HTeY;츃k% تUpc9cOhf+JHoպB-5x=J|BiCODeT0bs_ B[p z093]o/OhYͱ>p\A`|waȒLwgРAQ's]sWvzja]pLj({$Zr)t`u.JVQQ.Dc͚9|#q."T%=KKYO-ʃ*M%e:(Q+VWZi?\hٜyә ݼҦ^&uIEHx362vk$#mټ7n>gu_^:ѐTnmIHF!|# A z穤ep)E~ n'ɓdpcNE].2Qor 4t n喤r.@tL X ڣg6K.&9$k}.;@@L*|!w"]x[*.CС{\iI)]wjlSznоY\:ֺӊYo`P Ϡk(z!BA P7jW-ۃmnVCYydT_#f|e+3{\yzߧOcA|ᤓN:<c< G^ENdD+ H%BӜd/ w@m }@k(:-WፇjC~P}}yN)TыWzTT/0T|/Ha6IHtiκHԹD,vfwܥ)Nd+{  K!*=xÒ:h9 r]GdYi^m 6(ڗIh J*d*5q,(].l4RXpLC,tXny1TnsTj y8p$µ. Ng 50Q*߶Ul]^m`C'BdF]k-Z2ip͚uPDdպ > i;T_1k>i^ 'S -Y#kaG#@p2\V$1:vUU|Sz)#`YK0Vg&,kT~w|/l:QMBi_:+v]@ZFb%9[b;Ҕ6`/o''2j{~3F.r/V ]p jd{7+{۸ZYK97vt=QPt Tv\7FU/>eưygZ35cOK˴ѣG"aOC.(*ApMȡ͙h*/MŚՁ'u9. L-dp]MHk>XBJ-.tW˜KpP'f9L=V su׹{3*@@Ծ%ŲOE 5l@wgkZ6l;f̩e挍Y($?$>[*hc6#Vn͒=@)ުV3 }TCKG`'@K27~r{66֢U-lvN@ڭйhp瀲tɽqKodH&,]t [mg4OY$l N {d V;Vg'9 _Yy*T~ԩ=?Gy’ECyJEO(u]뉆kpťcC^h`4v l>CJaE^jMQbk` vi;5eGɮ+/ 9AO`K6 ">_k)|1/Cw bSBaꎿc1"@ o! 5DZ4+;XD]e+Y6%>yՖ $9xA qsPt"n>sz{5Bvp>Ͻd&T MV&X/d+ZAc4U=zmS4 mabJ>CA/_1IҲH?a}Yo9 wW{j*D#PBf.B?@@Q[[v4<;QojϾi= g͵'_fms Аg@o]fnƾZ{dhqo(o3 mn] Uw o-ry Qa .=_QRRUXx[;{##; ΅N?x/b RsY4wN5P'ԓc3fg SUR E3DŐ AǾMP+uM*gZȶV8ΌF@ #OD>{i(4H$R,6Ab;?l3]p0FNw<:cE v3:@4'&˿@٭ϚQ\^:se_= HAOyf/HJ> O#`E/g** xFưrgI:@pb H)¨}:0v=vk+4M[p6/-{ z{I)ƃ} ߱CrȲIʓt}5ڷKv0i ~)7ӼC0]Bz79<1?gp#]0}9<:--a%GrbFfd Q G#*ͭ&=?(^)wY<5!:ʔn-12. Mb¡F đ* 0]t^evy֧gN6vumYsho| #`3>"vԡ}ٟ7"9i\^`{`oտ(}_\Y:?f۵Va'@AikEu]C=o-݄ |6ώc}i>kKuO % (,B"Q2ݟ{ a/ ֓0aC K/9%T'uؙ*:OV헷Y`7^*G~ng4ڦK%?3v p@9r #7_Q 3ٲ-*'TP'N{ }k+[w-//o=$B 2yXmi 'Bt믉lp9?D ?!gO 'ƠDYxA'Jbs<8񴙫m;O1~?XuknXs5׸pXDj6kl8[ 1q3/& .kW4Z W =?w=Rm.A%Qz̢Bhr~t'Gs?Z^hj$@q䳘IĻnچ^8&Gܹ+pQ$lh3}gNUp5pZ#Pu2#pE}AUbQH6I><+/-d3O[rgjNvŖ3c(xf顉=F·]ڶfW==9uPj~ <*r\遐"x1D)6b_:ޘ9ڗTJ_ ay9>ZjLwF>HTvJT_1&U݄?&Q_8FJ8_ 4|p(ԏPy`ĵpޥy=rca_^ƺvwab]D#fLY BoͲZ{3h Yy_H'e+}yX74?]k-c4 F5tdk(Dg{L֞xn! H Ō="<\y)ʹhZ7\g/gWƾ+;9 2>_㍽[k @m9=?ז.u ddzTj2WөE&'>\r3F'c :kշW÷aeCF7ݜAߕy8Z@Fx9"B =(zm@c!}\ΎއJNkE{c@[o`:Dڛ|w!`;$)Owz7g^eiY'@-z* ݹ@ s+m+­`") i9`}y h d,F;"{p;ﺩBNjݨʭF*%J82Hcs-r $$xaBDtUQlsqJI(?PENaON`A'"ZJ@o` ؉o}#𘎱mV "jZ)qjZ=/gIs~JSfZ(_ӥ#":S/ּ=~C_4}0S~惏~ء'.cc (iN,fF&qv*s"'-|hzw̤DȹקOɤ4nTC]LT5*B"Vx۟ǩ ~0md[G y A :P|wVǬ9>faW%}?{ FD-w h%mŀG1Z# @m/xmuƈ(eDBx^rA2:AmTx? @>:mJK6-/(zm@&_@.äu@"oW\OSu4i!/سR0x؟0|Eo9DzGPsjT*<P˅Dyʔ).J1KtcCD1"FfwJ^t~ HxqqA¥kyn  Lwpzﶻ\RK|pTtnֱuŤa@Mr5|`eHFwG'-:pf3@4T-@u oMл;ׯuB0Z5h:r~:$5~6lJ`F` j<"qiso/R۷1=Pf.x$x1sMe PVj0p6cTd ) VI(9BxAknݪ,9R۔o>0@}`\L-}w3#?E}__̥YqÏh.z]ǣpkM:Qj^]g6)|YwaއP?uXe R? m@c!-J &eHSzv~_ᶬ5]kX *5}x^?^})qæ&Xꨏ?IK&ۄJ)T,Op"GlRt܊}dfşC:[nn?l,c@SO=eGqK 5:k\6evÀ;]c aGfB?ּ,yr54~9/lQ3MX]|gnshsxl^ أi\ P(`X߈|gtAax{2kU;AI'r@YTT, +$]n,Ko.f'SpPU|@05{$߹s&u=sgB$/近_D`^] 4,.f? Opя!B 3Jtpd&7|dLڦW`Uo'>)^?pc%rCT9xɧϟ?ZME-du u0+˦ln~yU&\KRq n H!֬VԠMt5*ZigIMZ@F9G]xdyyyWЮ]dVuYAY#dUd C,xJxOmLPVVז-](|"coGR?եK4wDH\ǣTkӦ9sW-JVh;Jz! Jb'KiU Il)U3uo^)c1?'`X';miW;-Y-rIg3gܦ 0]p߅A&ډ!@ 8FH#RH8K`Vju^G; N|\ݏzD ~ @ߝCq.>S`CP%;QL1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b ))PiQvIENDB`ic13DPNG  IHDR\rfsRGB@IDATx]`TEt:!zJM@T"6 Q+X)""T Mz5@@*o/޽܅Kr) L^}vΊp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jW Zp\-jiy-i2}@ 8 o.xZiJ\-P@ ʖ-[a??^QܼuʕHs< 1uF[I@:/0h0_|=o`^.6B t+[lLٻ}T ˗͛*Zh ?__"&9(Go/]$W._(krLF*aZb 3 aGvn'\ GKifH{,(A%5qhZv3gsrЊ08P锪TK[ӦsΣ˕+W Cܹs'N'ĉri_X c0 HfqAZާt?۳]vcʔ)z@c$?⼋o #@O#_촀ig܆]-ZL*Ud5)SQvu9~ShZG #N?$nŸ\XJ'hrxQbg$=N.o]f͚30W#_v$F ܻ{6 :ܭﻎ[MB~)P7ʕI{=GyM.^'O=]-c57 vZ4ӻRŊ_fɜy՞$~lG)ȎSQiAoN171sgA|jِAʃոo\g= iEː_glhjXW55#0۽TXgG}.Hs-@iJ9͕. b k|g4<,LMi'cKOX[xjf5MR`"?FL`&܉r4ZPvRXBCջWZOS ^, Gx.d:94667 i"k[@{ ?~ l@=GJԹ :ek %Te1LkY F}@ѩ|a <h#]G7"?,qh,gЩtbgƻ?RYfA1KAj|3o|uO&tZ9)OR?}1e[Ǝ#7\ƌOplQ`4kF#F9YO9SAT^>6_dCSb~I->#Ь4H^D8cpdZ}|XTO*Z#>7h8sŁ83I 2; T&xK'~9so@x\#W!_vcǎA= iQRO㗦.)MЗEy4%a](Gߜ]v0t߁HIqt$eK^xg0>PKݾ-wq_,8T`oܹcZ1'Ç V?x 0^*\;)㻿uG7ׂS&t^a"P_ȟB[AN1JP©Cp+G LJgw%KDQRȓ'ojՖm۶ʸqeذ.=tHE %fx 9i3 :#?w;N_ hCAZƌk |T}ޜ+cFig~=F/D2\].5m*gΝMHS?$πm?< <9-'C%禥&,;8M S"%M{!!N0a4A߀4}YA:KѣEV?ڹ ‹I4FxeۨKƍmZ~9[* iX }"+Na @[VISQdA_J?'󁫀VO^yθq "~#Wva 6fTRC$/,ܶ! RI2I-(/x63y%aQhޣpCRKݑ: ,Oo KhO|?]^!ǎa'¯XƮT<~FbN>4l@~bW(؅1bipjin%-F{I'wR$*`'gN2铤0LT1?pai7!_>y](]vY=0?F`ޙ2Iھ}q@?p'$2kOLNV* P3i n9h9qK xzGrHGJl̉}.e$אAJ3"Ws 8Jo!>t//]A%ӺR-o޼iLK. PQ`1TƎ] 6Bj  ZfbFee4tMhp;yܠ7aжySԃ(oA7Hp!Pl3+W+uo~ -ǹLx~OߴJ Se4Y>m;DM(Tۭ04d8q??o[ nď)"JC*ioSf>}sZ kM; !!_BKqT6ϥvČ]fG# cPON=`܉p2r0)H_6CO iB0ϻtd 9 Z 3Ӫxl}} p0zJѸvV.caJD yKtm@.(1|8?u)A8_ =4S7M??9&GϚ-1 8=)شtT~4vZJixiAl![8W"s BGx3RG82r(VnGR3W4V+G, h'l||gI]8:Ao~NX.aU!,AD/H||^S֮]gR\ 5ZN3x?z;09RIycjСCeʊDS{C38~E-q{s^|QݾMJC9/=viQ:nFը.Ѱxg*)lLQ)AgU>Pd<~X4}>|Ο?/^-@ ?<4kezrO|FglY']5i".tJBF48$@;{/C ~5j8⟁7I~ov'2 &_-cx2i 7&IPhf;tH`>kr䐭Xhj;WCBB:'m~C޳sBa48:g!ō~ȨcXN@e:wT$^VÊDPJg1hQ'@9^ ,hnK?/??{᩷rF[\ZN.^+YJyDhWG|n? aDn-^\ܢt~ꈀ${XoQπw6$ik 2s<ÇDJ$JshYRfMjתs_َ?ڵTyX5kxu֙A! 0dA<(7nNs~wT MJ|x{|u}1ԣxJJB.+7h`r2p n7IkW9M @-< zm#G VNi 'FxB66nܰI͚u"tBHlƔ!5nt %^{M,bnߒ*U]|4'2[4t}ֹSΙt✒#bƍA$,9$?"~t''C Q&ovퟔÓR69d,\sMkܱ i PŊ͛A`RnÆW+(щȩS!K|秐4PTRL %0O* k$7O95[|yݩKɐNΙ#[ w}~Y.|l D$"[(;V|X"q-H|~pմ|P[N{/{׮]/Zm Po})Zx)O s/5a„ Rb;L~ l̟_MJ^J&IomhԳW&~pp|_ $O|ܻpQh0ۈ#5|~y:eZF =h\ss+HaWF\;.X`5= wj^LYdɏ4X ҁo)Q$?7%NNnݤ}-<#- 6r`OwDRRrDvH!By(m "a=(Rp(b DO8>7bpDE eСr,۵k+ի9 L u($ `P/Ω3Fxʕ(`$ #dݞ|*_rmy0&g㚵hڬG^1's@t3fb.4d% rXB 8z쌲Y!d}}.2ͬOu$ft:e_?&@'mGHsBؖF$srouSgHfM$GM?``j@G{üu]h޼aF~ըQÑ1 O6<=ի;azIg:J*,[4޽<'u_1ˤOw}Zq?ʣ#GO6'6ȋJAsU&S(W͈t0DZ~>7lk.̀/O)zODb2=S~${Ϝ"T G5ƒIpꐭR ss'.sA0?"_ ŋDo05tl޲M@ץ*O4$!HiXp\ǜeϊ6.> ^ӀًJ#` x/ uڵ:=QID:*U2%Kk=rJ2:k=:M͘YdS&#m1o޼у .sR>WM~6gsT>01f- :p@yI5Ν?ڮ[UV4ox͆*l,2o2Q@Ƴݓr:L sTܺqSN 8-$hPLmZkez^+ZDC+ 7r!JdY}Nǎ,:Bcx|m۶'2bI7͙dN˗ޱ4[w8NfM{z)b |Wy!4%Kdr6Ux5rx(썄$U1a92݋d|I2\#{ps6t4w?AD)*)Ez<'9س7δ=7GNE|` D_<r;BRPCs^CQcr|/_V844lhə-93wVo޼)o:?eV$w~۝3:*Yv9dIaYRSSǍ)} E(Wh^uhɤ?f\jEʦno_2ԩ8ϩW9Ht+KE ۰zR,1?'fk:t~fB}e_~!uQ.G@\&*Bfs:-/o OฒH+LQ,1Vu-ܲػGs@<[*RaNap)@}5D>o' _ V<,Qʳaߙzg)@*U*0dȻ8?dc 1'O @lFxn":H9?x $sz2}^{OlxEe% \sIYOH bÝsf=kv.;WO|fEǎIdˣGyӷ`@>FL ;тjj5G)@nT` jlۺ=bȑNO@!-Ůg2 DɒhQ %3g4 {:,]JK]D]֪v:I q,2'v~ $bP |z@Fb2C C:ŧ|̉،%]W׬>QRF4iX\Lu`AO>nݺw7nS:6%W?ot>n 1o%kqC"ݒ#ǎ?jK:Tj3ɵzzҤ A4gK.cbȕSc7. \cǏɠAoڹzim :p Yd׶wVV "n (!]p_F[."׉cGԂ/SXS@&I̥،Q.\ht[sŘ=ǣ$64%TfM!N]D(V&VFڗأѧy(-Bi.˟?s"?@RYr``䆏Why,F++~8abPXXxgצz`y9&{a7l2tC`/lh @t\~@Jgy "gI);K)=rˏߨJֽ񦜂MbجhXsn]Y,ߨjo|F)`.1A9%?ږ/F5(1|qdc} s4BO3sJ1D& ǖA֚x[2g;ӋZ·ANh0 ٲOGuB-o !(׬F`+8cאR8Z*\FHoB RpaI b |rUeFgʘ!dϚqTSSKZN[gX+  G;/MnO|b%+bn, vQv#w:(rתdb\_yב_[Dnݫ4^dƄ,!a߅xV@F&{u&9%a%$Hd.F` ʛO@Q>Onjs3 R)GL,֭.Ou6͂,76_FN^ #~E4V\Š!d˚?{[UG'=Z ݞiVftY2gf$ 4xRYF|F 9J0xRI-F3eȘ<'ب$5 Vnzu|%B&)@E={Khui)'!s_D.c \p6z $;}1r}74B1~6iD£1d\j%y0HsJ3Q1n\_p~4z3>bx<%pak(ϟ3]:K\(pv,{8Ȑyɯ;HfaVF{Y,Y ,P.^8$Jlj3^ru/^v"&Gk֟ HO˘)}fRPK "<~ @tJj <琍E"X/Ԯ]K," e Θ1|twi>af}8!lk`_0@>tPwQ][i1zۛSՆ+`;0븶dD9Rd Ar0F1ol 6G,rꀷ-λ_}kN; MխWxD09 ߄;,BSctˀ>^-.&9E`ap> lywgN߆}LbW>/@g)Ns-);RZUY OFL؆vޓ۩ ("BB#ByDj)$GOIhNj)<"Lݗ2PL+,ƱE֫'1ehk$2uĉ/{rrw}~zЮ :g,I.^s=u"a){YPD~g g%`aiRRG s9e-"sj@ YPR> ?(_ִPz|ߚuZ [ySr!o_߹s[Y8QP:9Pu³kA$"*B<9Bj00=w5_˗2\J//aK-yJ4XNP4 Dےv[^h(9n|;ƼJv}6xΑXjV9}nD\>#PqW [iLsY0%7a!-7GDhrl qNP͜!15P ekWd ]~c.e ֌XhGcRݺAOlxo 0M3A UL%; ܺuO"A]Á; pZR#pTH pۃ E˸N^xJ N9U0%5?4^;+/e#cjϗvy*;*˪sdf!.7x[p!j@FA-VP."#8 ~eV'ydU9QY--Vl,ߒL"zX"x-4+$ۊ慨|̍,GHd &}," @GE!;t`Sj0wRgȮH.C)Df*Onno `H 3rUťÔ)[kq#[Ƅ8f<\0{iw|dIDgNaMV\`z&SQ:;a)0&˖ yU |}2'sQCiR乮qhLhQHi`SSqG8 >+c* 1C7t]8'$x~ tى:ap|KޘМ>7v(>X,EvOoJ?@IrP<bܗ*6 w䯯b`v^oSn|+EOŠK rn,ŽZ>>{ ggVfg¦VhuMUHD5j h<`aVC5!_qP rĉX£RW"1%cfZ~txbڸi#/w79}4FJ=wwHׯ)E%L}$z߂.)OwϞ6n^D3â#A#%+ GCX]e"I '*N5B* 7,]G[0b?M78ˆ J?;=A4VYE8Ct1BAx@ۤ!:4\0O3Dxw% O"ǟXn<Pu|J?)+;Rrr f!x4%Dwb`t1;=}K㷀֭NN& ݲu TyyQ'2w|r^%ͷJ*|%.GLx\kc*CCGc2჏.c} ;aUx)a: qT7IgQ~g<| EQ)yAE{Pfՠ]Qθ]N@YI-gyVOwzKr-B|>Ϊ/]7ZmINrrR:4sϊhA9r& PF50eȐ^9l9 mo|kׯJݕu֐eK[t\5?j x8I9sVXxXrʦVIT|pa A1 Οw h+pyr`iNi<17V@A??xK*bYp>ذ9zY@ٔ 0+ "|l-Ņ1uNlLŋYc3I#^.o Ms/b,_ma"Ϟ9[~z>y xbn:X|!-r/SS#Y5Х}򷅋W1:K%l 5pԯҨ[&앾]2@g#7 `g6^1^Z~s4V|U+4t:ҕ:%a anF@O UnUdfz\#OUz5/M9@)D\2AaӵˡpW?a!HBO?f-XS#g,D)7"`_<5ܾB%1<4]s8˿.#GTh|w ;*,U+|ߪ.T7ܹKITce+6usD5G?`xOSغl͛7Qj)3IdÛ?nwY.m~u^I=":|B窀5UhLXܖQiiբu붨s%`,{7y$T4 /JʜgQ;#M!/mr?:uրp4)kJ({I',O-ދAUjK,{^u~,C@ۧOY^EY|&a 31^Ay4@N)J82gի7#?z6(@9 -a[$;@t~f"ETD>c Ǿ{[!70K+@":9Gx}X ķX'.0"i#^<טϩ>RO$$"m?`"~ GOA>p'sM@%15mk8N.HJO:uj h({ (s pz'c}.VN!VeA005Ŷ^õӠߖ>%xXa1 ln. 7^S.&5AJۅNIXF(X$+A(,2-s;}^:ޣD@:}8qzUN7;!`XQsWX^~ieZ6 DC?ŗ7:rb(ps;{iv=˾B:1h+߷yzѳ\5`\GਿfY50Ge8s+7O0dvi=HMS:cǎ`B49G$LQ[Ν; *WGü2?wYUzqT9}0Q~]GiҚV#<|Pkl@1@`Vmj@D3Wz aXs.SJh=wZ.e(f $~46 3M׉Wkҥ#(iHd>ty=te8>D@$9ͅ;VUS@jtF+W\Hqs|>C_7)>m<' $bD`F&EH s3PfRLp>gUE~EAcV[rb+ {zPC?,!#?Lx쇉'^3Տlik?~(iCY~0u Sax tsL6 ܌'LG/1r;r@s .?6;'˟o Kj֏j_ز9NdhʌVD4h҇ 9󫯾*|D]c^.崒&# gp[5ȧrCcjyL%2fr$n/u"H;ӦM?G|+$i_~UTYl.j)7ҏa ajtdj5)̚5VEuuj*/zۧGF6м6G17ǀq+HhԩEO@bUrlt  ! t?w5d( e>4QC#~\fj!dftl 26zzJCO?Mȃ^d~b'Ih%ZUsR*΃>thlij5 bv3!~9} "ja[;L9|rR0 g E$#߅r\FlGdt+^VJ T ΍ $X} l?B[ ןܑ#G4L`"( xk:vj6a„hɐ%ÌkFxǧ W%HJ߻WU^-p#N1W^0`@(KΜ%prtw=n7<@2Xͩ˹kT?׭Wq+N1!a |lYϽUsL^@yʻ?6ONb56mZNVp"#!#|Vֿ:] xm/ ~#3}{!x""گ_+"%mٳΟ+`o;Nd HXYتZb(TBFE.0KJ#[h'md1$C8"=|[+@}:QHabO?(Km6 ᧰k{M̌ LA_TN>~uc`VC>Ჾ{' A ~KԳS5j>n> w3g>`YaѼQrȑSl\h{Nj2 ,b9} P$~!GeJRJ3_!(JVfElTތMǴH |8Џ?)!%Ʋ/)ݣFn6Bl.lXoqAC]m=/ 9G[!o+aIs@ [I>'s=(9-X 8O(恨Yc|(dӏY&A?DDf @8oܸi`r}.'l9xӴ e@ &u3$cHOAuiOt>XEAzd  txdZD^#ӧ&ߢ7 Y{@m.>bQf;F^s7tr4YNT#wjal*ݩWঢd =_Ng(}X(řxB ݒXf)5;F(- aDM;p2{,~ƚni Im5k"E e(~?~WqB:";po؅]Tl7&cJa-Z(^Azn"*%XPa,r ڇwq#CY'am Wi"Hx*A@j~ 9dO24<@_:B98* 0_&x{v[oK=p`:Aci7/sSdvܾ$?>A߿Sq7v!kc7mz0ޯ7R@$?&%Ooep5 <(Fԍ@iOFw$H-zY*2ɬ=}tED in.j4V0!:r>G'!~ʌK1 =1&ƬzzO@%y;dь~( L#eTe 7'@y xqK8Aٝ3L #*Oq8¬GD's扼fiטzt(`z҉H @Q s] b GSRo(^`6th6oqc3hgcl;/51& [j`3=T͒s8-T5UM$ֳkƦ WRp)0`|0w7C^g RJ,;2bL>e2v?c\֟#q rq+!Y)) F0:c|!N:zt_[ʕk(N{-G32C2`r`kxa9 1QMmWȬ.]5<)QIcn {^gCJbzzD%6K3%>Tlfɘ(n޼\۷_yqz&AUn װ4jyP D7u$lm={ @]=z$1+22^w~B?ad}ӅT#D}[! IyCm]<pҐ#MBϣϓd |'tٶm8.雺0gfd*_#ŰfG3. ! E]3p?WĚ9qBu: |tݱ]7nd-ϊp#p9?pe`3G]r~2GCQ4:vLB` ;AgŻp[ 1H<9Oi[.s6lX,د,V ۃ>Xf-X鋰 1.H$)+3Gvryt#|y$q!hWcu ߠq2ĊDsJX)CeFS(xԮBvRЎ7) [0_- ޢOvN`#Pǐno5:NVppw`~ SAXÞsz^s7py,r0ҽp}L#  CXRD;oJtq 2]ӷا IhڋmF7#k5k֬F jKA y~ڻTj@¥"#6u#}3s1;n<J _VZ*+{cBEcғ!7?]bEIfͿ\+i?a(w_3mÍzSe-pH~XK'>&ap n][ Om'ڻDDWݓp6&j x= I@j%?VnCO{tf V~yOB)2i4%;3..P{jz.kVG yN#W=E@VýV95ufGRVfј7Pt.f"!s]-Tnef@s2^}O]*DB@L֝<"(wvz~O22HZPhH}ArtւPfRҋ"~|DV@_K9p!ќ8i $ȅ$#@= ɜX`YFnO#5`id'rzyf{aDId^k|1@8q,0%:)u.Q?GHl$ 1ˎeREN9گ^Z)YNB;^`̇}XZ<1a*ssC#0n8FEk2gNR~ͬ٩pj-O!I^( !1#_F1qD ,ˡ\ޅuͅpIȞHq(1L֪RI1Bb5gHynD:)iDqDc]5ZIjJbB5s=cQ}K}4F`^Hxؚ ZP_E?|ǍFf>F$}c*qqNβ1 di6b<n'N\o~&i}038-b}hum)‹Z/@#;hK<,R,=aJWϙ皡XYk! K .w( ƣhӑI lGs[0eKA8د߻ [K?\J/d>`? @ڲRX@Qu6i$O @3| Sо*(3r49/}4a`yN HWPWG^\?`\ea0|+y@0:!ƛ9F c^Ѥg99"ɱs ={lN#t/h Xx*}`d!t7}SÆTA4(LD@2sFkT}}^L#nc,?7o0cё.QUYJ6[ zY/lޒ-tZ"<7F,^ NI/ JA3!bNXwTFp/}25]@}xO#0Špm 3"#2|H-b{8>"Ǡwdߥ}hj-h݇@g_g!k:12[lsL(P p6+ a@*GkV³+A(lPɨW6Q1n:G3G4h`s^&gΓeqwJyuQMy.Ch[̔!bˍ(WrO7LaFCB3P`W^*/밃XҤۻz稴¾w$&~>xPB3 $N dŋRg0={V7eFO)(69Ś(]RYD;ؿ-úEtVӅGضG?q2+pټBK "HldikG}#7 +AJDy5`k^pyͳd>FW28,wgr9'el2*[VAÿ`S_p2 oDp,<:%Cׅi'#V-]0'3ws/@ɓDHscA<4އjl [5vFG2~0];4RE),]9с`:h2҅gc!̨ўʦՍ`=u.zD?1HlyTϧsVeʾ/ ͝KM쐲>cV mU_P?#(%$ZMz?<=9ҭ\ zn}~TQ  G (d*&؍u xa&v܅0h^a(Ôwwn@Dill~r>XHR7pho>1kTo>mf[k#>te̞F.Kp{CNn, )b5P$XA2 v G櫯)A\74+%a ` )tYP/b>4h^Zg/kuj{c6ɺ{ϱ#]L`}柑ii*JĂm֍ukv+&q!tg.(E;vR~"5ۋU^x( ֭n5{l'hR1PIiӞ4/{ow-$ d /o!B)B9XesOݟ^_kX(12O /G;:h I"גvlr0RN\Q7+D@#-1? F#$:[s^@7Q2p}hr _6).*K./ʉʅV=FfX#.*׌ g#{-+QG;,XoDk Ay[O){4כl޽{b&̀l+{8NVg<թgǐ` @ڵ[wY+GdF@&@ ٌzOA6&zd1  T- NH >,#: HZ|33&(k 9dz΀$2WYH%t xa K_zD@[آh4Sآh F5v{b% *XRD;}kn;wgΜ9s,_Jz@@OȠkDEu^":4o2CK|C6I4I}XÀ5~VH G[Rk*|X0aȼDs U~{MSY h+~t I+C+i&q ]1 0QI .QI@A-(D"t |?&5@hy./ Ay&>h43ZiPGʾ~k S쓓wݏ8&\rvPgD3aXLC3KFLI9h;/L՝.yS:k½/Nژ@VknSd[?^hyg+ίUˡ?/+BBR Px`]k~% ƾbgnMWto -|I9) ;)P}a@Z)bPaK||@(scW@jt*'#P%;w]wTj*~B \^:S+Ia '*OPTx*{.;>wl4u.q_kZ4iC˷޶ ~僆RY 1RQ`B*y|rtD`Jͳ~xhz8L=PQQ!uJ򂡪af4{ ˿Ĵ ]NF] +|F*J qBohs5a+Yu=Mߒ}tQH!vKv\. U>jg"` Jx$G S{@"VF[ZM<ҹ2֦LoMo0P:t[~i MJ"sMWO:eZ' rZkUK<ǫ`ူ5@KC0 oњŗ|,AGЀXZ7'we.t埬<%,RG~A!66,_\w n'LC^kvi8}COr?黋O7l}n 5}>|W/& FSt?Z Z*?-J yO "*L(A9+TCQd>evύmʴvدZYw٬/7%vm媀 pλlO>6T-j&mwe6ڋtRik~ M2#lǐ FCob@/\k$\SV[fzӏ]Q[סBZpv"[{aN Tc7 O{ԗGj?bKܕCUuO~ J#VBrBZdrФ7'd_t[A7ڷr9]k շg'M0_wf 1 bG(DK ~~^B- O7cIA `/_z^<_ E36H`[p OAiL1<H8IAOwBfgԖ,kMjoϭgMko )xciǧ 1â,ZfxGeԊ{udNm .Q5{}[MJ>P6k! /l ; 88{bl:2#-ổ+]|H}M+-p#@5cv0[x`!}},)n/jbF>Q&-m?/$/wJcؙYը< [la]*ح pKN{ .m&9a8ƶE6ӟ4iypOG 2+4r3xA*t͗_Ol杷ظ]kK[#u|b<(㧝]Ó(B'$OҬ6t C{.˩f6{v2(̾LMwhlﵪFυcHji,c Cplh?Tr<Ly~7PQ< z$~KZxdM=÷iB"MbdWʩk 6_`=:zhΧZ1 U䚇?衇\ho<4mRd]:M[=Oue}M6<rl{ͦ6r ߃; a `tHqxT WlM=Vʏ_:_que}[\&Zq$ 1# Oϖɓw>Z*' %c,ҭBy`v}pT;Z{F#LgeWR_0g 8l]|z cV-k/w]=ߒ/P!R\BwvaI بQc[ ϴ~GK~aB>Dy`K=p=WH/߮Uu.BV.JsZO5y [٭aZF7QND:&76V٩ʾBmf~-QӏO@Xjޟ$-)}ōtGlzw5‰Br3t!>Phh c'DPa8[_Jk /`6^J^.:mn;Օg/Ԗ»iRtʄ+}' wF9̙0?~xK:0<]}nX1(5"Nv]IE.fxpʩC4XXyfOC0b %` @}&x8L PF* (_j CE62 6kH*v|:,)n`8-QݝSf>@}Wl옿X7߲-oƦw-= XSa O/@xѶ_pyܫe_9]*iOTF7(Ud|/O҇:@ډLpOR|\F߭!Ȅ\/#9YZ \ލ;q 1,`:?& !R!XtܒbRڣgr*%!=a8`A@?Z@ A:5ZQµ !>"D셷Zۈ?Of{-Knn>vbkɻQ9 ` 4&IR[޹[MF@E[wPLePky0F??IL7|;N3go[fūq<1Us]CxZ6 r\V_  X3XMTSI >ރHK;;-n~=f-Nj-Y4/\ҵPz{Ä8\c Bd6+>O]q֥KBkSO9A[:߿ⷰu%]lޚش.SqQ,l*;41 [ ºz]5y 6Q7[h?F.EHtF@7GMH`tzt7ڏ_vg! BHвEfA0p CGO8gFbZ 26/>a{~y>oպ:uwGu߳qFt!Y .+ɼѨh&}`-[thC{AݺVKuIP2o6cSo ᨤHAt5絰C(X˦AWgL~|Ter ;EU2`ȐJhyKV܌: .Ve凯W6xϽ` qZ5@Y/ #t4(EK^#$о1Î/0IГ9.aez%hOLvYf;y纮@u~ӭuϾRl!{S_|1_۩n/(?O?UK鮵_ 2LƴV  3(_kq@U 0:klbJA^ֵ„%B{R{򥦶v4_koimY-щ8sx |7`ی#fKWI«m֡r>n>PEEs$BZFD/yp0^Ko ljC.S?!W0ZBhB̢r+I<,Fk`Bh]x9fj?WVVWzYrT7^z ,hT쑇wy/YG$; N`Qu_*͠M֮hmc*=j2 jfL{XiRYWy ΞUyfFF\[:7-mi}I4 t0cQ2,CWnm%V,Iա# m>Jd9$ݼN,[v۶vں߾0`-VB'TFF%tgekП ]}eAa8>+&ƽPGOZE'b4ۢŋm&?mշ[!7ztX]9IZYmba$ |tݙLK]K0Xf_E2G]Ǘ[ !ނ%T]h3hQh%/Z=Yz|MgkVo3mۋRA4~!B%u/+mɦ CYw IDAT|^l.]}GkmLֱMK~<{}Mr 5TEhOn1Pޢ"[FDd2HTeY;츃k% تUpc9cOhf+JHoպB-5x=J|BiCODeT0bs_ B[p z093]o/OhYͱ>p\A`|waȒLwgРAQ's]sWvzja]pLj({$Zr)t`u.JVQQ.Dc͚9|#q."T%=KKYO-ʃ*M%e:(Q+VWZi?\hٜyә ݼҦ^&uIEHx362vk$#mټ7n>gu_^:ѐTnmIHF!|# A z穤ep)E~ n'ɓdpcNE].2Qor 4t n喤r.@tL X ڣg6K.&9$k}.;@@L*|!w"]x[*.CС{\iI)]wjlSznоY\:ֺӊYo`P Ϡk(z!BA P7jW-ۃmnVCYydT_#f|e+3{\yzߧOcA|ᤓN:<c< G^ENdD+ H%BӜd/ w@m }@k(:-WፇjC~P}}yN)TыWzTT/0T|/Ha6IHtiκHԹD,vfwܥ)Nd+{  K!*=xÒ:h9 r]GdYi^m 6(ڗIh J*d*5q,(].l4RXpLC,tXny1TnsTj y8p$µ. Ng 50Q*߶Ul]^m`C'BdF]k-Z2ip͚uPDdպ > i;T_1k>i^ 'S -Y#kaG#@p2\V$1:vUU|Sz)#`YK0Vg&,kT~w|/l:QMBi_:+v]@ZFb%9[b;Ҕ6`/o''2j{~3F.r/V ]p jd{7+{۸ZYK97vt=QPt Tv\7FU/>eưygZ35cOK˴ѣG"aOC.(*ApMȡ͙h*/MŚՁ'u9. L-dp]MHk>XBJ-.tW˜KpP'f9L=V su׹{3*@@Ծ%ŲOE 5l@wgkZ6l;f̩e挍Y($?$>[*hc6#Vn͒=@)ުV3 }TCKG`'@K27~r{66֢U-lvN@ڭйhp瀲tɽqKodH&,]t [mg4OY$l N {d V;Vg'9 _Yy*T~ԩ=?Gy’ECyJEO(u]뉆kpťcC^h`4v l>CJaE^jMQbk` vi;5eGɮ+/ 9AO`K6 ">_k)|1/Cw bSBaꎿc1"@ o! 5DZ4+;XD]e+Y6%>yՖ $9xA qsPt"n>sz{5Bvp>Ͻd&T MV&X/d+ZAc4U=zmS4 mabJ>CA/_1IҲH?a}Yo9 wW{j*D#PBf.B?@@Q[[v4<;QojϾi= g͵'_fms Аg@o]fnƾZ{dhqo(o3 mn] Uw o-ry Qa .=_QRRUXx[;{##; ΅N?x/b RsY4wN5P'ԓc3fg SUR E3DŐ AǾMP+uM*gZȶV8ΌF@ #OD>{i(4H$R,6Ab;?l3]p0FNw<:cE v3:@4'&˿@٭ϚQ\^:se_= HAOyf/HJ> O#`E/g** xFưrgI:@pb H)¨}:0v=vk+4M[p6/-{ z{I)ƃ} ߱CrȲIʓt}5ڷKv0i ~)7ӼC0]Bz79<1?gp#]0}9<:--a%GrbFfd Q G#*ͭ&=?(^)wY<5!:ʔn-12. Mb¡F đ* 0]t^evy֧gN6vumYsho| #`3>"vԡ}ٟ7"9i\^`{`oտ(}_\Y:?f۵Va'@AikEu]C=o-݄ |6ώc}i>kKuO % (,B"Q2ݟ{ a/ ֓0aC K/9%T'uؙ*:OV헷Y`7^*G~ng4ڦK%?3v p@9r #7_Q 3ٲ-*'TP'N{ }k+[w-//o=$B 2yXmi 'Bt믉lp9?D ?!gO 'ƠDYxA'Jbs<8񴙫m;O1~?XuknXs5׸pXDj6kl8[ 1q3/& .kW4Z W =?w=Rm.A%Qz̢Bhr~t'Gs?Z^hj$@q䳘IĻnچ^8&Gܹ+pQ$lh3}gNUp5pZ#Pu2#pE}AUbQH6I><+/-d3O[rgjNvŖ3c(xf顉=F·]ڶfW==9uPj~ <*r\遐"x1D)6b_:ޘ9ڗTJ_ ay9>ZjLwF>HTvJT_1&U݄?&Q_8FJ8_ 4|p(ԏPy`ĵpޥy=rca_^ƺvwab]D#fLY BoͲZ{3h Yy_H'e+}yX74?]k-c4 F5tdk(Dg{L֞xn! H Ō="<\y)ʹhZ7\g/gWƾ+;9 2>_㍽[k @m9=?ז.u ddzTj2WөE&'>\r3F'c :kշW÷aeCF7ݜAߕy8Z@Fx9"B =(zm@c!}\ΎއJNkE{c@[o`:Dڛ|w!`;$)Owz7g^eiY'@-z* ݹ@ s+m+­`") i9`}y h d,F;"{p;ﺩBNjݨʭF*%J82Hcs-r $$xaBDtUQlsqJI(?PENaON`A'"ZJ@o` ؉o}#𘎱mV "jZ)qjZ=/gIs~JSfZ(_ӥ#":S/ּ=~C_4}0S~惏~ء'.cc (iN,fF&qv*s"'-|hzw̤DȹקOɤ4nTC]LT5*B"Vx۟ǩ ~0md[G y A :P|wVǬ9>faW%}?{ FD-w h%mŀG1Z# @m/xmuƈ(eDBx^rA2:AmTx? @>:mJK6-/(zm@&_@.äu@"oW\OSu4i!/سR0x؟0|Eo9DzGPsjT*<P˅Dyʔ).J1KtcCD1"FfwJ^t~ HxqqA¥kyn  Lwpzﶻ\RK|pTtnֱuŤa@Mr5|`eHFwG'-:pf3@4T-@u oMл;ׯuB0Z5h:r~:$5~6lJ`F` j<"qiso/R۷1=Pf.x$x1sMe PVj0p6cTd ) VI(9BxAknݪ,9R۔o>0@}`\L-}w3#?E}__̥YqÏh.z]ǣpkM:Qj^]g6)|YwaއP?uXe R? m@c!-J &eHSzv~_ᶬ5]kX *5}x^?^})qæ&Xꨏ?IK&ۄJ)T,Op"GlRt܊}dfşC:[nn?l,c@SO=eGqK 5:k\6evÀ;]c aGfB?ּ,yr54~9/lQ3MX]|gnshsxl^ أi\ P(`X߈|gtAax{2kU;AI'r@YTT, +$]n,Ko.f'SpPU|@05{$߹s&u=sgB$/近_D`^] 4,.f? Opя!B 3Jtpd&7|dLڦW`Uo'>)^?pc%rCT9xɧϟ?ZME-du u0+˦ln~yU&\KRq n H!֬VԠMt5*ZigIMZ@F9G]xdyyyWЮ]dVuYAY#dUd C,xJxOmLPVVז-](|"coGR?եK4wDH\ǣTkӦ9sW-JVh;Jz! Jb'KiU Il)U3uo^)c1?'`X';miW;-Y-rIg3gܦ 0]p߅A&ډ!@ 8FH#RH8K`Vju^G; N|\ݏzD ~ @ߝCq.>S`CP%;QL1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b )S @L1b ))PiQvIENDB`ic11 PNG  IHDR szzsRGBIDATX VyPW " !ʭrT;bŻgmEtWg:kԫTVXpP-G$$$ѩgw;~Gg\OJJzfޫ2nByyH rt =<=zz|>S:e̡Syu5 nySP(lZ-opp044t7Zy2/DƎ͌0p [Aalm$wAnV\n7Ψ|f߼,'z[7IBWR:sɑ03`2 xEe ppwʏSW^.|ZYq(.nJZ-M++~k֭o(eS˝uu\߷A2 P;xNr,l&DuB4?6'ǭg_ N%5dC.,UNN[F׾) t񨽝*$4d%f>^ U66]ݶ-ƚ{z'b#685۷#FEmC'@ZR"]_X5;'H{|S5p\rX:U-;{(WUǃe <ġWp:rNiju?R\"CT3kABYYYffu7[(==37gDzJ.^Aqp]EGYNFލTGh+;wx7 +#Jϗ~$кv:K,9`˒>X>Ft <B=|8PWUz%#}p{;]Y bo%JKqɡi}H$n PAǀ1fLMBãR`c7\qZ(T;:bGUl/O3BD?<ϞK:1Zڍ͈8Ν;Gi6P7!&q*pGa3O`&?]vD& e-ʟ v؁1҈w62K׉%1416 @+0.؋@|9)6Yy ǗjET᧟ Sw~%)F176odٲeM{ >>C` L:hWG;m;wQ{l6CP(0`?+f+@__6kjj#4acp{  .dZg4,=5>j`Lp\$D&5]%53[iK0u֬YZ[[`!<ܼ8T__O908t{4~;9996((P@e~C'h(..nC2sB%&OL`%l./wOeEU;wh,M,J"e,rn^U$b=?IENDB`info bplist00X$versionX$objectsY$archiverT$topU$null WNS.keysZNS.objectsV$class TnameTiconZ$classnameX$classes\NSDictionaryXNSObject_NSKeyedArchiverTroot#-27=CJR]dfhjlnsx}il32x`G7+ W0  -3S??4k[SUcF 0TgR?h\X80чq0b^/K8-Q]a[>0[9 5`N*=J&\_WK&;@jGfZITIag69R&E`_a!zPna_[UN"^X]`WBQU^c0Y?dAk۪g:X``a*N 3V]a``TD:cѯR:i_`[5*;,efAӀͲP?P^_cDNU6jπ{tK1YaYT!hǽǣtZfDʟRzPn9̾Lؿވk?dAk۪g]rÄ=cѭS(x^b䜑OIҀͯRWޘ1i^|9ʀztKVǾdu~x. tZfE{8wtJ@?ǑV4?X?}t*2"@:޹~g}#2#w5 1Cp7O皾CdDB[6ԷrY;I6 1`ʹѻ`Q4>7 ATH344CGFB)5m<:7.xZG7+U- +29F.)tt0]F i賂óc#Їq(lVlQ=gtkHwקH{?֢.1@j kq>QzPl9˽L׾݇j?dAk۪g]rƒ=cѯP(x]b㛑OIӀͲOWݗ1h^|9π{tIUƽcu~x. tZfC8vpJ@>ƑV4?X>|蟃t)2"@7Æj{mR #2!w5 0Co6OڻaCdBBY4ٶqY;H4 1`о_Q4=5 ASH332CGFB'2m;:3.is32#xA) )a  FX[Diql4?Q<@SQGfi[9_9DaI?SY7tGcJ(DeP!kP\7YΠ_ `7|/Np˷˜btY:B CO좀2 2_'u?(UU i\qljry\3i[~ԀڛLt+Y䨾̓bI_[/OpʺrctY鹸7C DO쥀2 2_'u?(UQ iXmljry\3iIٛKt+Y㧾̃bI_ R/MpʥkMrasX7A CO1 2_%klog-0.9.2.9/elogclublog.cpp0000644000076700000620000003655013233376355013620 0ustar staff#include "elogclublog.h" #include #include #include #include //#include eLogClubLog::eLogClubLog() : QObject(0) { //qDebug() << "eLogClubLog::eLogClubLog" << endl; call= QString(); email = QString(); pass = QString(); api = "9467beee93377e82a276b0a777d388b5c933d044"; currentQSO = -1; useQSOStationCallsign = false; stationCallsign = QString(); //qDebug() << "eLogClubLog::eLogClubLog - END" << endl; } eLogClubLog::~eLogClubLog() { //qDebug() << "eLogClubLog::~eLogClubLog" << endl; } void eLogClubLog::slotQsoUploadFinished(QNetworkReply *data) { //qDebug() << "eLogClubLog::slotQsoUploadFinished" << endl; result = data->error(); //qDebug() << "eLogClubLog::slotQsoUploadFinished - Result = " << QString::number(result) << endl; const QByteArray sdata = data->readAll(); QString text = QString(); if (currentQSO>0) { emit actionReturnDownload(result, currentQSO); currentQSO = -1; } if (result == QNetworkReply::NoError) { text = "ClubLog: " + prepareToTranslate(sdata); //qDebug() << sdata; } else if (result == QNetworkReply::HostNotFoundError) { //qDebug() << "eLogClubLog::slotQsoUploadFinished - Result = Host Not found! = " << QString::number(result) << endl; text = "ClubLog: " + tr("Host not found!"); //TODO: Mark the previous QSO as not sent to clublog } else if (result == QNetworkReply::TimeoutError) { //qDebug() << "eLogClubLog::slotQsoUploadFinished - Result = Time out error! = " << QString::number(result) << endl; text = "ClubLog: " + tr("Timeout error!"); //TODO: Mark the previous QSO as not sent to clublog } else if (result == 202) { //qDebug() << "eLogClubLog::slotQsoUploadFinished - Result = Password Error! = " << QString::number(result) << endl; text = "ClubLog: " + tr("It seems to be a PASSWORD ERROR; check your password."); int ret = QMessageBox::warning(0, tr("KLog - ClubLog"), tr("It seems that your ClubLog password is not correct.") + "\n" + tr("Please check your password in the setup. ClubLog uploads will be disabled."), QMessageBox::Ok); emit disableClubLogAction(true); //TODO: Mark the previous QSO as not sent to clublog } else { //qDebug() << "eLogClubLog::slotQsoUploadFinished - Result = UNDEFINED = " << QString::number(result) << endl; text = "ClubLog: " + tr("Undefined error..."); //TODO: Mark the previous QSO as not sent to clublog } //qDebug() << "eLogClubLog::slotQsoUploadFinished - Result = " << QString::number(result) << endl; //emit done(); emit showMessage(text); } void eLogClubLog::slotFileUploadFinished(QNetworkReply *data) { //qDebug() << "eLogClubLog::slotFileUploadFinished" << endl; result = data->error(); //qDebug() << "eLogClubLog::slotFileUploadFinished - Result = " << QString::number(result) << endl; const QByteArray sdata = data->readAll(); QString text = QString(); if (result == QNetworkReply::NoError) { text = "ClubLog: " + prepareToTranslate(sdata); //qDebug() << "eLogClubLog::slotFileUploadFinished - Result = NoError = " << QString::number(result) << endl; //qDebug() << sdata; } else if (result == QNetworkReply::HostNotFoundError) { //qDebug() << "eLogClubLog::slotFileUploadFinished - Result = Host Not found! = " << QString::number(result) << endl; text = "ClubLog: " + tr("Host not found!"); } else if (result == QNetworkReply::TimeoutError) { //qDebug() << "eLogClubLog::slotFileUploadFinished - Result = Time out error! = " << QString::number(result) << endl; text = "ClubLog: " + tr("Timeout error!"); } else { //qDebug() << "eLogClubLog::slotFileUploadFinished - Result = UNDEFINED = " << QString::number(result) << endl; text = "ClubLog: " + tr("Undefined error..."); } //qDebug() << "eLogClubLog::slotFileUploadFinished - Result = " << QString::number(result) << endl; //emit done(); emit showMessage(text); } void eLogClubLog::downloadProgress(qint64 received, qint64 total) { //qDebug() << "eLogClubLog::downloadProgress: " << QString::number(received) << "/" << QString::number(total) << endl; //qDebug() << received << total; emit actionShowProgres(received, total); } void eLogClubLog::slotErrorManagement(QNetworkReply::NetworkError networkError) { //qDebug() << "eLogClubLog::slotErrorManagement: " << QString::number(networkError) << endl; result = networkError; if (result == QNetworkReply::NoError) { } else if (result == QNetworkReply::HostNotFoundError) { //qDebug() << "eLogClubLog::slotErrorManagement: Host not found" << endl; } else { //qDebug() << "eLogClubLog::slotErrorManagement: ERROR!" << endl; } //actionError(result); } int eLogClubLog::sendQSO(QStringList _qso) { //qDebug() << "eLogClubLog::sendQSO: " << call <<"/"<< email << "/" << pass << "/" << api << endl; //qDebug() << "eLogClubLog::sendQSO:: length = " << QString::number(_qso.length()) << endl; // First Data in the QStringList is the QSO id, not to be sent to clublog but used in the signal actionReturnDownload(const int _i, const int _qsoId); if (_qso.length()!=18) { return -1; } currentQSO = (_qso.at(0)).toInt(); _qso.removeFirst(); stationCallsign = QString(); if (useQSOStationCallsign) { stationCallsign = _qso.last(); } //qDebug() << "eLogClubLog::sendQSO (stationCallsign = " << _qso.last() << ")" << endl; _qso.removeLast(); QString qso = getClubLogAdif(_qso); //qDebug() << "eLogClubLog::sendQSO: " << qso << endl; return sendData(qso); } int eLogClubLog::sendData(const QString _q) { //qDebug() << "eLogClubLog::sendData: " << _q << endl; //Posiblemente tenga que usar una de estas: void QUrlQuery::addQueryItem(const QString & key, const QString & value) QUrl serviceUrl = QUrl("https://secure.clublog.org/realtime.php"); QByteArray postData; //QByteArray postData; /* QUrl params; params.addQueryItem("email",email); params.addQueryItem("password",pass); if ((useQSOStationCallsign) && (stationCallsign.length()>2)) { params.addQueryItem("callsign",stationCallsign); //qDebug() << "eLogClubLog::sendData - callsign 1: " << stationCallsign << endl; } else { params.addQueryItem("callsign",call); //qDebug() << "eLogClubLog::sendData - callsign 2: " << call << endl; } params.addQueryItem("api",api); params.addQueryItem("adif",_q); postData = params.encodedQuery(); */ QUrlQuery params; params.addQueryItem("email",email); params.addQueryItem("password",pass); if ((useQSOStationCallsign) && (stationCallsign.length()>2)) { params.addQueryItem("callsign",stationCallsign); //qDebug() << "eLogClubLog::sendData - callsign 1: " << stationCallsign << endl; } else { params.addQueryItem("callsign",call); //qDebug() << "eLogClubLog::sendData - callsign 2: " << call << endl; } params.addQueryItem("api",api); params.addQueryItem("adif",_q); postData = params.query(QUrl::FullyEncoded).toUtf8(); //postData = params.encodedQuery(); // Call the webservice QNetworkAccessManager *networkManager = new QNetworkAccessManager(this); QNetworkRequest request(serviceUrl); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotQsoUploadFinished(QNetworkReply*))); networkManager->post(request, postData); return -1; } QString eLogClubLog::getClubLogAdif(const QStringList _q) { //qDebug() << "eLogClubLog::getClubLogAdif: " << QString::number(_q.length()) << endl; // _qso must include 16 ordered fields than can be empty or contain data. This function builds the ADIF QSO /* http://clublog.freshdesk.com/support/solutions/articles/53202-which-adif-fields-does-club-log-use- ClubLog only accepts the following ADIF fields: •QSO_DATE •TIME_ON •QSLRDATE •QSLSDATE •CALL •OPERATOR •MODE •BAND •BAND_RX •FREQ •QSL_RCVD •LOTW_QSL_RCVD •QSL_SENT •DXCC •PROP_MODE •CREDIT_GRANTED */ if (_q.length()!=16) { return QString(); } QString qso, aux1; qso.clear(); aux1 = _q.at(0); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); qso = "" + aux1 + " "; } //qso = "" + _q.at(0) + " "; qso = qso + "" + _q.at(1) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 10" << endl; qso = qso + "" + _q.at(2) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 20" << endl; qso = qso + "" + _q.at(3) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 30" << endl; qso = qso + "" + _q.at(4) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 40" << endl; qso = qso + "" + _q.at(5) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 50" << endl; qso = qso + "" + _q.at(6) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 60" << endl; qso = qso + "" + _q.at(7) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 70" << endl; if ((_q.at(8)).length()> 2) { qso = qso + "" + _q.at(8) + " "; } if ((_q.at(9)).length()> 2) { qso = qso + "" + _q.at(9) + " "; } //qDebug() << "eLogClubLog::getClubLogAdif: 90" << endl; qso = qso + "" + _q.at(10) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 100" << endl; qso = qso + "" + _q.at(11) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 110" << endl; qso = qso + "" + _q.at(12) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 120" << endl; if ((_q.at(13)).toInt()> 0) { qso = qso + "" + _q.at(13) + " "; } //qDebug() << "eLogClubLog::getClubLogAdif: 130'" << endl; qso = qso + "" + _q.at(14) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 140" << endl; qso = qso + "" + _q.at(15) + " "; //qDebug() << "eLogClubLog::getClubLogAdif: 150" << endl; qso = qso + ""; ////qDebug() << "eLogClubLog:: - QSO: " << qso << endl; //qDebug() << "eLogClubLog::getClubLogAdif: 100" << endl; return qso; } void eLogClubLog::setCredentials(const QString _call, const QString _email, const QString _pass, const bool _useQSOStationCall) { //qDebug() << "eLogClubLog::setCredentials" << endl; call = _call; email = _email; pass = _pass; useQSOStationCallsign = _useQSOStationCall; } int eLogClubLog::deleteQSO(QStringList _qso) { //qDebug() << "eLogClubLog::deleteQSO: length = " << QString::number(_qso.length()) << endl; if (_qso.length()!=17) { return -1; } _qso.removeFirst(); //http://clublog.freshdesk.com/support/solutions/articles/54908-using-adif-to-update-or-delete-qsos //VP9NO2007090321330030MCWGH6UW QString replaceCall = "" + call + " " + ""; QString qso = getClubLogAdif(_qso); qso.replace("", replaceCall); //qDebug() << "eLogClubLog::deleteQSO: ready to send = " << qso << endl; return sendData(qso); } QString eLogClubLog::prepareToTranslate(const QString _m) { //qDebug() << "eLogClubLog:: = prepareToTranslate" << _m << endl; if (_m == "Callsign missing") { return tr("Callsign missing"); } else if (_m == "Invalid callsign") { return tr("Invalid callsign"); } else if (_m == "Skipping SWL callsign") { return tr("Skipping SWL callsign"); } else if (_m == "Callsign is your own call") { return tr("Callsign is your own call"); } else if (_m == "Invalid callsign with no DXCC mapping") { return tr("Invalid callsign with no DXCC mapping"); } else if (_m == "Updated QSO") { return tr("Updated QSO"); } else if (_m == "Invalid ADIF record") { return tr("Invalid ADIF record"); } else if (_m == "Missing ADIF record") { return tr("Missing ADIF record"); } else if (_m == "Test mode - parameters ok, no action taken") { return tr("Test mode - parameters ok, no action taken"); } else if (_m == "Excessive API Usage") { return tr("Excessive API Usage"); } else if (_m == "Internal Error") { return tr("Internal Error"); } else if (_m == "Rejected") { return tr("Rejected"); } else if (_m == "QSO Duplicate") { return tr("QSO Duplicate"); } else if (_m == "QSO Modified") { return tr("QSO Modified"); } else if (_m == "Missing Login") { return tr("Missing Login"); } else if (_m == "QSO OK") { return tr("QSO OK"); } else if (_m == "Upload denied") { return tr("Upload denied"); } else if (_m == "No callsign selected") { return tr("No callsign selected"); } else if (_m == "No match found") { return tr("No match found"); } else if (_m == "Dropped QSO") { return tr("Dropped QSO"); } else if (_m == "OK") { return tr("OK"); } else if (_m == "Login rejected") { return tr("Login rejected"); } else if (_m == "Upload denied") { return tr("Upload denied"); } else if (_m == "Rejected: Callsign is your own call") { return tr("Rejected: Callsign is your own call"); } else { return _m; } } int eLogClubLog::modifyQSO (QStringList _oldQSO, QStringList _newQSO) { int x = -1; x = deleteQSO(_oldQSO); x = sendQSO(_newQSO); return x; } klog-0.9.2.9/utilities.h0000644000076700000620000000607713233376355013003 0ustar staff#ifndef UTILITIES_H #define UTILITIES_H /*************************************************************************** utilities.h - description ------------------- begin : jun 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ /* This class implements general use utilities that can be used from any other class Anything that is not directly related with a class itself and could be used from different classes should be here */ #include #include #include #include class Utilities { public: Utilities(); ~Utilities(); int getProgresStepForDialog(int totalSteps); bool trueOrFalse(const QString _s); // reads a String and return true if s.upper()== TRUE :-) QString checkAndFixASCIIinADIF(const QString _data); QString getAgent(const QString _klogversion); //Devel or debug functions - Not adding any feature to the user void printQString(const QStringList _qs); QString getKLogDBFile(); //QString getKLogDatabaseFile(const QString _file); bool isDBFileExisting(); bool isDBFileExisting(const QString _file); QString getHomeDir(); QString getCfgFile(); QString getCTYFile(); void setVersion(const QString _v); QString getVersion(); double getVersionDouble(); QDate getDefaultDate(); bool isValidDate(const QDate _d); int getNormalizedDXCCValue(const int _dxcc); private: bool processConfigLine(const QString _line); QString getKLogDefaultDatabaseFile(); QString dbPath; QString softwareVersion; }; #endif // UTILITIES_H klog-0.9.2.9/gpl-3.0-standalone.html0000644000076700000620000011150513233376355014704 0ustar staff GNU General Public License v3.0 - GNU Project - Free Software Foundation (FSF)

GNU GENERAL PUBLIC LICENSE

Version 3, 29 June 2007

Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/>

Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble

The GNU General Public License is a free, copyleft license for software and other kinds of works.

The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.

To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.

For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.

Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.

Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS

0. Definitions.

“This License” refers to version 3 of the GNU General Public License.

“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.

“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.

To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.

A “covered work” means either the unmodified Program or a work based on the Program.

To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.

To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.

An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.

1. Source Code.

The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.

A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.

The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.

The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.

The Corresponding Source for a work in source code form is that same work.

2. Basic Permissions.

All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.

You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.

Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.

When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.

4. Conveying Verbatim Copies.

You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.

You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.

5. Conveying Modified Source Versions.

You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:

  • a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
  • b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
  • c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
  • d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.

A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

6. Conveying Non-Source Forms.

You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:

  • a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
  • b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
  • c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
  • d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
  • e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.

A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.

A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.

“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.

If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).

The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.

Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.

7. Additional Terms.

“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.

When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.

Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:

  • a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
  • b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
  • c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
  • d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
  • e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
  • f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.

All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.

If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.

Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.

8. Termination.

You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).

However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.

9. Acceptance Not Required for Having Copies.

You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.

10. Automatic Licensing of Downstream Recipients.

Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.

An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.

You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.

11. Patents.

A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.

A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.

Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.

If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.

A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.

Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

12. No Surrender of Others' Freedom.

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.

13. Use with the GNU Affero General Public License.

Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.

14. Revised Versions of this License.

The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.

If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.

15. Disclaimer of Warranty.

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. Limitation of Liability.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

17. Interpretation of Sections 15 and 16.

If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    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 3 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, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.

You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.

The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.

klog-0.9.2.9/database.h0000644000076700000620000002126513233376355012530 0ustar staff#ifndef DATABASE_H #define DATABASE_H /*************************************************************************** database.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "utilities.h" class QSqlRelationalTableModel; // Previous db update 0.011 const float DBVersionf = 0.012; // TODO: struct AwarddxccEntry { // Information to update the awarddxcc table; For other Award tables, the DXCC is just the ID of the award element QString dxcc; QString band; QString mode; QString status; QString logNumber; QString qsoID; }; struct AwarddxccEntryCheck { // Information to update the awarddxcc table; For other Award tables, the DXCC is just the ID of the award element QString dxcc; QString band; QString mode; QString status; QString logNumber; }; class DataBase { public: DataBase(const QString _parentClass, const QString _DBName); //DataBase(const QString _softVersion, bool inmemoryonly = false); DataBase(const QString _parentClass, const QString _softVersion, const QString _DBName); ~DataBase(); QString getSoftVersion(); QString getDBVersion(); QString getDBName(); bool createConnection(bool newDB=false); // If true that means that we are creating the DB, // not just connecting to an existing one. // That will be done in the default path bool reConnect(const QString _DBName); //bool setDir(const QString _dir); QStringList getColumnNamesFromTable(const QString _tableName); bool isValidBand (const QString b); bool isValidMode (const QString b, const bool _tmp=false); bool isValidBandNumber (const int b); bool isValidModeNumber (const int b); QString getBandNameFromNumber(const int _n); QString getModeNameFromNumber(const int _n, bool _tmp=false); QString getSubModeNameFromNumber(const int _n, bool _tmp=false); int getBandIdFromName(const QString b); int getModeIdFromName(const QString b); int getModeIdFromSubMode(const QString b); bool createBandModeMaps(); int getBandIDFromName2(const QString b); int getModeIDFromName2(const QString b); int getSubModeIDFromName2(const QString b); QString getBandNameFromID2(const int _i); QString getModeNameFromID2(const int _i); QString getSubModeNameFromID2(const int _i); int getBandIdFromFreq(const QString fr); //Freq should be in MHz bool isThisFreqInBand(const QString b, const QString fr); //Freq should be in MHz QString getFreqFromBandId(const int _i); int getLogTypeNumber(const QString _logType); QString getLogTypeName(const int _logType); bool unMarkAllQSO(); bool updateIfNeeded(); void compress(); bool updateTheEntityTableISONames(); bool updateTableLogs(); bool queryAddField(const QString _field, const QString value); //bool queryPrepare(); //bool queryExec(); bool queryPrepare(const QString _query); bool queryBind(const QString _field, const QString value); bool updateAwardDXCCTable(); bool updateAwardWAZTable(); int getNumberOfQsos(const int _logNumber); private: bool beginTransaction(); bool commitTransaction(); bool execQuery(const QString function, const QString stringQuery); bool createDataBase(); bool isTheDBCreated(); bool hasTheTableData(const QString _tableName); bool updateToLatest(); bool updateTo003(); // Updates the DB to 0.0.3 bool updateTo004(); bool updateTo005(); bool updateTo006(); bool updateTo007(); bool updateTo008(); bool updateTo009(); // Updates DB and add the Satellite tables bool updateTo010(); // Updates DB and recreates the supportedcontest table bool updateTo011(); // Updates DB and recreates Satellite data bool updateTableLog(const int _v); bool updateDBVersion(); bool createTheBandQuickReference(); bool createTheModeQuickReference(); //bool updateLog(); // Updates the log table bool recreateTableLog(); bool createTableLog(bool temp = false); // false creates the production DB. True a temporal one. bool createTableLogs(const bool real=true); // real = true creates the production DB. False a temporal one. bool createTableEntity(const bool NoTmp); bool updateTableEntity(); bool createTableClubLogStatus(); bool populateTableClubLogStatus(); bool createTableMode(const bool NoTmp); bool populateTableMode(const bool NoTmp); bool updateTheModeTableAndSyncLog(); bool createTableBand(const bool NoTmp); bool populateTableBand(const bool NoTmp); bool recreateTableBand(); bool recreateTableDXCC(); bool createTableAwardDXCC(); bool recreateTableWAZ(); bool createTableAwardWAZ(); bool recreateSatelliteData(); bool createTableSatellites(const bool NoTmp); bool populateTableSatellites(const bool NoTmp); bool recreatePropModes(); bool createTablePropModes(); bool populatePropagationModes(); bool recreateContestData(); bool recreateSupportedContest(); bool createTableContest(); bool createTableSupportedContest(); bool populateContestData(); bool populateTableSupportedContest(); bool howManyQSOsInLog(const int i); //void showError(); //bool moveFromModeIdToSubmodeId(); bool updateModeIdFromSubModeId(); bool updateBandIdTableLogToNewOnes(); bool updateBandIdTableAward(const int _db); bool updateModeIdTableAward(const int _db); void queryErrorManagement(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); bool created; float dbVersion; // The current version of the DB. May differ from latestReaded if we are updating the DB! QString dbConnectionName; QString softVersion; float latestReaded; // The latest version of DB readed in the DB itself //bool inMemoryOnly; // The DB is to be created in memory, no file support... Faster but less safe! //QDateTime date; QHash bandIDHash; QHash modeIDHash; QHash subModeIDHash; QHash IDBandHash; QHash IDModeHash; QHash IDSubModeHash; QHash freqBandIdHash; QMap bandQMap; QMap modeQMap; Utilities *util; QSqlDatabase db; QString dbDir, dbName; QStringList insertPreparedQueries, insertQueryFields; QSqlQuery preparedQuery; int constrid; // Just an id for the constructor to check who is being executed at one specific time signals: void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution }; #endif // DATABASE_H klog-0.9.2.9/infowidget.cpp0000644000076700000620000004572213233376355013462 0ustar staff#include "infowidget.h" InfoWidget::InfoWidget(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "InfoWidget::InfoWidget: " << endl; dataProxy = dp; awards = new Awards(dataProxy); //Just to know colors locator = new Locator(); world = new World(dataProxy); bandLabel1 = new QLabel; bandLabel2 = new QLabel; bandLabel3 = new QLabel; bandLabel4 = new QLabel; bandLabel5 = new QLabel; bandLabel6 = new QLabel; bandLabel7 = new QLabel; bandLabel8 = new QLabel; bandLabel9 = new QLabel; bandLabel10 = new QLabel; bandLabel11 = new QLabel; bandLabel12 = new QLabel; continentLabel = new QLabel; prefixLabel = new QLabel; cqzLabel = new QLabel; ituzLabel = new QLabel; gradShortLabel = new QLabel; distShortLabel = new QLabel; gradLongLabel = new QLabel; distLongLabel = new QLabel; distShortLabelN = new QLabel; distLongLabelN = new QLabel; imperialSystem=false; dxLocator.clear(); createUI(); clearBandLabels(); //qDebug() << "InfoWidget::InfoWidget: - END" << endl; } void InfoWidget::createUI() { bandLabel1->setText(tr("10M")); bandLabel2->setText(tr("15M")); bandLabel3->setText(tr("20M")); bandLabel4->setText(tr("40M")); bandLabel5->setText(tr("80M")); bandLabel6->setText(tr("160M")); bandLabel7->setText(tr("2M")); bandLabel8->setText(tr("6M")); bandLabel9->setText(tr("12M")); bandLabel10->setText(tr("17M")); bandLabel11->setText(tr("30M")); bandLabel12->setText(tr("70CM")); bandLabel1->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel2->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel3->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel4->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel5->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel6->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel7->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel8->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel9->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel10->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel11->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); bandLabel12->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *continentLabelN = new QLabel(tr("Continent")); continentLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); continentLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *prefixLabelN = new QLabel(tr("Prefix")); prefixLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); prefixLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *cqzLabelN = new QLabel(tr("CQ")); cqzLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); cqzLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *ituzLabelN = new QLabel(tr("ITU")); ituzLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); ituzLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *shortLabelN = new QLabel(tr("Short Path")); shortLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *longLabelN = new QLabel(tr("Long Path")); longLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *gradShortLabelN = new QLabel(tr("Degree")); gradShortLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); gradShortLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); distShortLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *gradLongLabelN = new QLabel(tr("Degree")); gradLongLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); gradLongLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); distShortLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); distLongLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); distLongLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QGridLayout *infoLayout1 = new QGridLayout; infoLayout1->addWidget(continentLabelN, 0, 0); infoLayout1->addWidget(continentLabel, 1, 0); infoLayout1->addWidget(prefixLabelN, 0, 1); infoLayout1->addWidget(prefixLabel, 1, 1); infoLayout1->addWidget(cqzLabelN, 0, 2); infoLayout1->addWidget(cqzLabel, 1, 2); infoLayout1->addWidget(ituzLabelN, 0, 3); infoLayout1->addWidget(ituzLabel, 1, 3); QGridLayout *shortPathLayout = new QGridLayout; shortPathLayout->addWidget(shortLabelN, 0, 0, 1, 0); shortPathLayout->addWidget(gradShortLabelN, 1, 0); shortPathLayout->addWidget(gradShortLabel, 1, 1); shortPathLayout->addWidget(distShortLabelN, 1, 2); shortPathLayout->addWidget(distShortLabel, 1, 3); QGridLayout *longPathLayout = new QGridLayout; longPathLayout->addWidget(longLabelN, 0, 0, 1, 0); longPathLayout->addWidget(gradLongLabelN, 1, 0); longPathLayout->addWidget(gradLongLabel, 1, 1); longPathLayout->addWidget(distLongLabelN, 1, 2); longPathLayout->addWidget(distLongLabel, 1, 3); QHBoxLayout * pathsLayout = new QHBoxLayout; pathsLayout->addLayout(shortPathLayout); pathsLayout->addLayout(longPathLayout); QGridLayout *bandsLayout = new QGridLayout; bandsLayout->addWidget(bandLabel1, 0, 0); bandsLayout->addWidget(bandLabel2, 0, 1); bandsLayout->addWidget(bandLabel3, 0, 2); bandsLayout->addWidget(bandLabel4, 0, 3); bandsLayout->addWidget(bandLabel5, 0, 4); bandsLayout->addWidget(bandLabel6, 0, 5); bandsLayout->addWidget(bandLabel7, 1, 0); bandsLayout->addWidget(bandLabel8, 1, 1); bandsLayout->addWidget(bandLabel9, 1, 2); bandsLayout->addWidget(bandLabel10, 1, 3); bandsLayout->addWidget(bandLabel11, 1, 4); bandsLayout->addWidget(bandLabel12, 1, 5); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(bandsLayout); mainLayout->addLayout(infoLayout1); mainLayout->addLayout(pathsLayout); #ifdef Q_OS_WIN continentLabel->setFrameShadow(QFrame::Raised); continentLabel->setFrameStyle(QFrame::StyledPanel); continentLabelN->setFrameShadow(QFrame::Raised); continentLabelN->setFrameStyle(QFrame::StyledPanel); prefixLabelN->setFrameShadow(QFrame::Raised); prefixLabelN->setFrameStyle(QFrame::StyledPanel); prefixLabel->setFrameShadow(QFrame::Raised); prefixLabel->setFrameStyle(QFrame::StyledPanel); cqzLabelN->setFrameShadow(QFrame::Raised); cqzLabelN->setFrameStyle(QFrame::StyledPanel); cqzLabel->setFrameShadow(QFrame::Raised); cqzLabel->setFrameStyle(QFrame::StyledPanel); ituzLabel->setFrameShadow(QFrame::Raised); ituzLabel->setFrameStyle(QFrame::StyledPanel); ituzLabelN->setFrameShadow(QFrame::Raised); ituzLabelN->setFrameStyle(QFrame::StyledPanel); shortLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); shortLabelN->setFrameShadow(QFrame::Raised); shortLabelN->setFrameStyle(QFrame::StyledPanel); longLabelN->setFrameShadow(QFrame::Raised); longLabelN->setFrameStyle(QFrame::StyledPanel); gradShortLabelN->setFrameShadow(QFrame::Raised); gradShortLabelN->setFrameStyle(QFrame::StyledPanel); gradShortLabel->setFrameShadow(QFrame::Raised); gradShortLabel->setFrameStyle(QFrame::StyledPanel); distShortLabelN->setFrameShadow(QFrame::Raised); distShortLabelN->setFrameStyle(QFrame::StyledPanel); distShortLabel->setFrameShadow(QFrame::Raised); distShortLabel->setFrameStyle(QFrame::StyledPanel); gradLongLabelN->setFrameShadow(QFrame::Raised); gradLongLabelN->setFrameStyle(QFrame::StyledPanel); gradLongLabel->setFrameShadow(QFrame::Raised); gradLongLabel->setFrameStyle(QFrame::StyledPanel); distLongLabelN->setFrameShadow(QFrame::Raised); distLongLabelN->setFrameStyle(QFrame::StyledPanel); distLongLabel->setFrameShadow(QFrame::Raised); distLongLabel->setFrameStyle(QFrame::StyledPanel); bandLabel1->setFrameShadow(QFrame::Raised); bandLabel1->setFrameStyle(QFrame::StyledPanel); bandLabel2->setFrameShadow(QFrame::Raised); bandLabel2->setFrameStyle(QFrame::StyledPanel); bandLabel3->setFrameShadow(QFrame::Raised); bandLabel3->setFrameStyle(QFrame::StyledPanel); bandLabel4->setFrameShadow(QFrame::Raised); bandLabel4->setFrameStyle(QFrame::StyledPanel); bandLabel5->setFrameShadow(QFrame::Raised); bandLabel5->setFrameStyle(QFrame::StyledPanel); bandLabel6->setFrameShadow(QFrame::Raised); bandLabel6->setFrameStyle(QFrame::StyledPanel); bandLabel7->setFrameShadow(QFrame::Raised); bandLabel7->setFrameStyle(QFrame::StyledPanel); bandLabel8->setFrameShadow(QFrame::Raised); bandLabel8->setFrameStyle(QFrame::StyledPanel); bandLabel9->setFrameShadow(QFrame::Raised); bandLabel9->setFrameStyle(QFrame::StyledPanel); bandLabel10->setFrameShadow(QFrame::Raised); bandLabel10->setFrameStyle(QFrame::StyledPanel); bandLabel11->setFrameShadow(QFrame::Raised); bandLabel11->setFrameStyle(QFrame::StyledPanel); bandLabel12->setFrameShadow(QFrame::Raised); bandLabel12->setFrameStyle(QFrame::StyledPanel); #else continentLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); continentLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); prefixLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); prefixLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); cqzLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); cqzLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); ituzLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); ituzLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); shortLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); longLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); gradShortLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); gradShortLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); distShortLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); distShortLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); gradLongLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); distLongLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); distLongLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); gradLongLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel1->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel2->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel3->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel4->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel5->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel6->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel7->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel8->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel9->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel10->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel11->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); bandLabel12->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); #endif setLayout(mainLayout); } void InfoWidget::clearBandLabels() { QString defaultColorName = (awards->getDefaultColor()).name(); bandLabel1->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel2->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel3->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel4->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel5->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel6->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel7->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel8->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel9->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel10->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel11->setStyleSheet("* { background-color: " + defaultColorName + "; }"); bandLabel12->setStyleSheet("* { background-color: " + defaultColorName + "; }"); } void InfoWidget::clearInfoFromLocators() { //qDebug() << "InfoWidget::clearInfoFromLocators" << endl; gradShortLabel->setText( "0" ); gradLongLabel->setText( "0" ); distShortLabel->setText( "0" ); distLongLabel->setText( "0" ); cqzLabel->setText("0"); ituzLabel->setText("0"); } void InfoWidget::clear() { continentLabel->setText("-"); prefixLabel->setText("-"); clearBandLabels(); clearInfoFromLocators(); } void InfoWidget::setColors (const QString _newOne, const QString _needed, const QString _worked, const QString _confirmed, const QString _default) { awards->setColors (_newOne, _needed, _worked, _confirmed, _default); } void InfoWidget::setCurrentLog(const int _log) { currentLog = _log; } void InfoWidget::setImperialSystem (const bool _imp) { imperialSystem = _imp; if (imperialSystem) { distShortLabelN->setText(tr("Miles")); distLongLabelN->setText(tr("Miles")); //distShortLabel->setText( QString::number( Km2Mile(imperialSystem, (distShortLabel->text()).toInt() )) ); //distLongLabel->setText( QString::number(Km2Mile(imperialSystem, (distLongLabel->text()).toInt()) ) ); } else { distShortLabelN->setText(tr("Km")); distLongLabelN->setText(tr("Km")); } } QString InfoWidget::getStyleColorToLabelFromBand(const QString _b, const QString _q) { // Receives band name, Entity number (as a String) //qDebug() << "InfoWidget::getStyleColorToLabelFromBand: " << _b << "/" << _q << endl; QStringList _qs; _qs.clear(); _qs << _q << QString::number(dataProxy->getIdFromBandName(_b)) << QString::number(-1) << QString::number(currentLog); //TODO: Check if we can know the mode and replace the -1 //qDebug() << "InfoWidget::getStyleColorToLabelFromBand (Band/background-color): " << _b << (awards->getQRZDXStatusColor(_qs)).name() << endl; return "* { background-color: " + (awards->getQRZDXStatusColor(_qs)).name() + "; }"; } //void InfoWidget::showInfo(const int _entity, const int _bandid, const int _modeid, const int _log) void InfoWidget::showInfo(const int _entity) { // Default values of _modeid & _log = -1 //qDebug() << "InfoWidget::showInfo: " << QString::number(_entity) << "/" << QString::number(_bandid) << "/"<< QString::number(_modeid) << "/" << QString::number(_log) << endl; //QColor getQRZDXStatusColor(const QStringList _qs); // Receives Entity, band, mode & log bandLabel1->setStyleSheet(getStyleColorToLabelFromBand(bandLabel1->text(), QString::number(_entity))); bandLabel2->setStyleSheet(getStyleColorToLabelFromBand(bandLabel2->text(), QString::number(_entity))); bandLabel3->setStyleSheet(getStyleColorToLabelFromBand(bandLabel3->text(), QString::number(_entity))); bandLabel4->setStyleSheet(getStyleColorToLabelFromBand(bandLabel4->text(), QString::number(_entity))); bandLabel5->setStyleSheet(getStyleColorToLabelFromBand(bandLabel5->text(), QString::number(_entity))); bandLabel6->setStyleSheet(getStyleColorToLabelFromBand(bandLabel6->text(), QString::number(_entity))); bandLabel7->setStyleSheet(getStyleColorToLabelFromBand(bandLabel7->text(), QString::number(_entity))); bandLabel8->setStyleSheet(getStyleColorToLabelFromBand(bandLabel8->text(), QString::number(_entity))); bandLabel9->setStyleSheet(getStyleColorToLabelFromBand(bandLabel9->text(), QString::number(_entity))); bandLabel10->setStyleSheet(getStyleColorToLabelFromBand(bandLabel10->text(), QString::number(_entity))); bandLabel11->setStyleSheet(getStyleColorToLabelFromBand(bandLabel11->text(), QString::number(_entity))); bandLabel12->setStyleSheet(getStyleColorToLabelFromBand(bandLabel12->text(), QString::number(_entity))); } void InfoWidget::showEntityInfo(const int _enti, int _cq, int _itu) { //qDebug() << "InfoWidget::showEntityInfo" << QString::number(_enti) << endl; if (_enti<=0) { return; } /* TO paint a flag of the Worked entity QString flagSt; flagSt.clear(); QString aux; aux = dataProxy->getISOName(_enti); if (aux.length()>1) { flagSt = ":/" + aux + ".png"; } else { flagSt.clear(); } flagSt = ":/flags/" + dataProxy->getISOName(_enti) + ".png"; flagIcon->setIcon(QIcon(flagSt)); */ //infoLabel2->setText(world->getEntityName(_enti)); continentLabel->setText( world->getContinentShortName(_enti) ); prefixLabel->setText( world->getEntityMainPrefix(_enti)); //if ( locator->isValidLocator((locatorLineEdit->text()).toUpper()) ) //{ // dxLocator = (locatorLineEdit->text()).toUpper(); //} //else //{ // dxLocator = world->getLocator(_enti); //} //showDistanceAndBearing (myLocator, dxLocator); int i = -1; if ((_cq>0) && (_cq<41)) { cqzLabel->setText( QString::number(_cq) ); } else { i = world->getEntityCqz(_enti); if( i > 0 ) { cqzLabel->setText( QString::number(i) ); } else { cqzLabel->setText("0"); } } if (_itu>0) { ituzLabel->setText( QString::number(_itu) ); } else { i = world->getEntityItuz(_enti); if ( i > 0 ) { ituzLabel->setText( QString::number(i) ); } else { ituzLabel->setText("0"); } } } void InfoWidget::showDistanceAndBearing(const QString _locLocal, const QString _locDX) {// Local / DX //qDebug() << "InfoWidget::showDistanceAndBearing: " << _locLocal << "/" << _locDX << endl; QString lloc = _locLocal.toUpper(); QString ldx = _locDX.toUpper(); if ( locator->isValidLocator(lloc) ) { if ( locator->isValidLocator(ldx) ) { dxLocator = ldx; int beam = locator->getBeamBetweenLocators(lloc, dxLocator); gradShortLabel->setText( QString::number(beam) ); if (beam >= 180) { gradLongLabel->setText( QString::number(beam -180 ) ); } else { gradLongLabel->setText( QString::number(beam + 180 ) ); } distShortLabel->setText( QString::number( locator->getDistanceBetweenLocators(lloc, dxLocator, imperialSystem) ) ); distLongLabel->setText( QString::number( 40000 - locator->getDistanceBetweenLocators(lloc, dxLocator, imperialSystem) ) ); } else { clearInfoFromLocators(); return; } } else { clearInfoFromLocators(); return ; } } void InfoWidget::setLocalLocator(const QString _loc) { if (locator->isValidLocator(_loc)) { localLocator = _loc; } } void InfoWidget::setDXLocator(const QString _loc) { if (locator->isValidLocator(_loc)) { dxLocator = _loc; } } klog-0.9.2.9/klog.rc0000644000076700000620000000007313233376355012067 0ustar staffIDI_ICON1 ICON DISCARDABLE "klog.ico" klog-0.9.2.9/mainwindowinputcomment.h0000644000076700000620000000440313233376355015576 0ustar staff#ifndef MAINWINDOWINPUTCOMMENT_H #define MAINWINDOWINPUTCOMMENT_H /*************************************************************************** mainwindowminputcomment.h - description ------------------- begin : ago 2016 copyright : (C) 2016 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implement the tab of the mainwindow that supports the Comment // #include #include class MainWindowInputComment : public QWidget { Q_OBJECT public: explicit MainWindowInputComment(QWidget *parent = 0); ~MainWindowInputComment(); void createUI(); void setData(const QString _comment); QString getComment(); void clear(); private: QString comment; QLineEdit *commentLineEdit; }; #endif // MAINWINDOWINPUTCOMMENT_H klog-0.9.2.9/downloadcty.h0000644000076700000620000000606313233376355013312 0ustar staff#ifndef DOWNLOADCTY_H #define DOWNLOADCTY_H /*************************************************************************** downloadcty.h - description ------------------- begin : feb 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include "utilities.h" class QSslError; class DownLoadCTY : public QObject { Q_OBJECT public: explicit DownLoadCTY(const QString _klogDir, const QString _klogVersion); ~DownLoadCTY(); int download(); private: Utilities *util; //void setTarget(const QString& t); bool saveToDisk(const QString &filename, QIODevice *data); QString saveFileName(const QUrl &url); QNetworkAccessManager *manager; QNetworkRequest *request; //QString target; int result; // enum QNetworkReply::NetworkError QString klogDir; QString urld; QUrl *url; private slots: void slotDownloadFinished(QNetworkReply* reply); void slotDownloadProgress(qint64 received, qint64 total); void slotErrorManagement(QNetworkReply::NetworkError networkError); signals: void actionReturnDownload(const int _i); void done(); void actionShowProgres(qint64 received, qint64 total); void actionError(const int _i); }; #endif // DOWNLOADCTY_H klog-0.9.2.9/TODO0000644000076700000620000004230413233376355011300 0ustar staffRC-BUGS: For next release: TODO: Create a function that runs the log adding a DXCC to any QSO without a DXCC. TODO: Import LOTW (MainWindow::slotADIFImport) TODO: Remove the Querys from void SetupPageLogs:: Working: TODO: ADD A TIP ON the DXCC tab stating Prefix, CQ, ITU & Bearing This is a kind of roadmap for KLog development. It is not fixed... new features may be prioritized or not added without any notice ;-) Feel free to request any roadmap change if you have any suggestion. TODO: To add the support to import/export the following ADIF fields that are already existing in DB AWARD_SUBMITTED AWARD_GRANTED DARC_DOK FISTS FISTS_CC GUEST_OP "hrdlog_qso_upload_date VARCHAR(10)," "hrdlog_qso_upload_status VARCHAR(1)," "my_antenna VARCHAR," "my_dxcc INTEGER, " "my_fists INTEGER, " "my_itu_zone INTEGER ," "my_postal_code VARCHAR ," "my_sota_ref VARCHAR, " "my_usaca_counties VARCHAR, " "my_vucc_grids VARCHAR, " "silent_key VARCHAR(1), " "region VARCHAR, " "qrzcom_qso_upload_date VARCHAR(10), " "qrzcom_qso_upload_status VARCHAR(1), " "skcc VARCHAR, " "sota_ref VARCHAR, " "uksmg INTEGER, " "usaca_counties VARCHAR, " "ve_prov VARCHAR, " "vucc_grids VARCHAR, " TODO: Add a warning or periodically ADIF export so data is backup TODO: Create a function to look for QSO without a DXCC and ask the user to confirm the DXCC. TODO: Isolate the QSO input tab and create a widget with it. TODO: Isolate the Main QRZ box and create a widget with it. TODO: Isolate the Awards tab and create a widget with it. TODO: Add an option to save the DXCluster data to a file (file based on name or so) TODO: Think if it is possible to create a function in the Widgets(i.e. MainWindowInputQSL) to read the data and enter it in the DB automatically when the user clicks on "enter" It would help to "isolate" it and make it more "independant" TODO: Review the color management in MainWindowInputOthers::setIOTA (and maybe others) (completewithPrevious of MainWindow) TODO: Check if in mainwindow (read formUI and modify the eQSL/LOTW REC/SENT values are correct TODO: If no QSL sent via or rec via are defined, KLog shows as direct? It should be bureau TODO: Add a cheking to the list of bureaus and propose the bureau for QSL via when there is an existing one and propose direct when no bureau is existing. (http://www.iaru.org/qsl-bureaus.html) TODO: Define band limits for CW/SSB/RTTY... so when a click on the cluster is done, the right mode is proposed. TODO: Add in the setup/Band/mode a combobox showing all the active band/modes so the user can select the default band/mode from that list. BUG: Potential bug Double click on a QSO in the log on the Mode/Band... you can modifify the value. As it is a double click, the QSO goes to edit and ... Check if: - Only selected modes can be shown there. - If double click on the log we only "quick modify" directly in the log, without editing. BUG: (TNX JL3OXR) The DB is not storing if the time is stored in UTC or local so that info is lost. If a user changes the configuration from time to time, the user will loose the real time when the QSO was made. Solution: - Consider the DB is only storing UTC QSO. - Read config from user (or simply ask) and convert all the DB to UTC if needed (only one time when new version is installed to upgrade the DB) Always: - When entering data from the UI, check the user config and store only UTC time. - TODO: Think how to show the data in the log or search box as data is stored in UTC and showed directly (specially log widget) - Solution: Maybe changing the header to UTC may solve this and provide the info to the user that UTC is being used for storage It may be weird for the user to see the log in UTC when working in local time... in the rest of the functions... TODO: void DXCCStatusWidget::slotRefreshButtonClicked()//TODO: Define a way to show the status of the selected log or all the logs in the DB BUG: Optimize the KLog start BUG: If logbook.dat is not existing but klogrc it is, KLog does not start. TODO: Add a tip on the DXCC Status showing some info: bearing, DXCC status (worked or not...) TODO: Add a link or action on DXCCStatus items to doubleclick and search the QSOs that provide such status. TODO: Show the flag of the worked QRZ on the top right,close to the Entity Name TODO: Add the flags to the DXCluster TODO: Click on an Entity name will select all the QSO of that Entity on the search box Debian: Time in UTC: (not to be fixed) https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=654325 BUG: Check the options that are marked in QSL when rightbutton. i.e.: Is myQSL sent marked as requested when it should be the DX-QSL? TODO GUI: To add the CQ/ITU box or make them editable TODO: checkIfNewBandOrMode() is not being used. Code should be removed... BUG: Clublog: void MainWindow::slotQRZReturnPressed() _x = elogClublog->deleteQSO(clublogPrevQSO); _x = elogClublog->sendQSO(dataProxy->getClubLogRealTimeFromId(modifyingQSO)) It runs so fast and not serialized that at the end sometimes the QSO is deleted but not created afterwards TODO: Add the possibility to the user to select from the setup a call to be used in clublog or use the one comming from the station callsign lineedit TODO: In slotQsoUploadFinished, if QSO is not uploaded. mark it as not uploaded in the log If qsoToEdit, nothing is modified and OK. (Clublog returns QSO DUPE) Again qsoToEdit, nothing is modified and OK (Clublogs returns QSO DROPPED, and QSO is dropped!) TODO: Check the values that clublog is returning to manage errors and show messages to the user TODO: To add the possibility to upload a modified QSO to clublog. TODO: If there is an error in password/username or whatever, disable clublog in KLog TODO: Upload a logfile to clublog // Ideas: https://code.google.com/p/datacod-qt-tools/source/browse/upcoder/uploader.h // https://code.google.com/p/datacod-qt-tools/source/browse/upcoder/uploader.cpp TODO: Define a maximum QSO upload rate to clublog to avoid excesive API usage. KLog 0.9.4 TODO: Some Entities are not recognized by ARRL (I, IG9, IT9 are the same ARRL id entities but different ones). Maybe I should not be working with ARRLid or maybe I should detect special ones and "id+10000" so >10000 ids are special ones. KLog 0.9.3 TODO: Support CQ WW SSB (Including Cabrillo Import/Export) TODO: Support CQ WW CW (Including Cabrillo Import/Export) KLog 0.9.4 TODO: Hamlib support (Linux). KLog 0.9.5 TODO: Support CQ WPX SSB (Including Cabrillo Import/Export) TODO: Support CQ WPX CW (Including Cabrillo Import/Export) KLog 0.9.6 WORLDEDITOR Dialog TODO: WorldEditor is not updated when the CTY.CSV file is updated TODO: World Editor: Create a way to add an entity. TODO: World Editor: Create a way to remove an entity. TODO: World Editor: Create a way to edit an entity. KLog 0.9.7 TODO: Integrate with www.clublog.org (http://www.clublog.org/docs/pages/viewpage.action?pageId=1638482) KLog 0.9.8 TODO: Integrate with eqsl.cc https://www.eqsl.cc/qslcard/ADIFContentSpecs.cfm KLog 0.9.9 TODO: Server to log all the QSO in real time (through the network) from N1MM http://n1mm.hamdocs.com/tiki-index.php?page=UDP+Broadcasts&structure=N1MM+Logger+Documentation KLog 0.9.10 TODO: Integrate with FLIGI real time logging (req by AA5VI) KLog 0.9.11 - Cluster release TODO: DXCluster: Add flags to the DXCluster widget TODO: DXCluster: UI: Modify the DX-Cluster tab to show the data in a table?: DX de/Freq/DX/Comment/Time/Loc TODO: DXCluster: Add the DXMarathon information to the spots TODO: DXCLuster: Create a band map (including a "to-be-worked") TODO: Working on the dxCluster: Tool to save the DXCluster in a file (for further analysis). KLog 0.9.12 TODO: Add the awards functionality (to manage awa files, TPEA, WAS, ...) KLog 0.9.13 TODO: Mobile interface. Create a mobile UI. TODO: Check if the data has been modified (only memory) and save the data! TODO BUG: When modifying allow deleting data (as in KLog 0.5.8) DONE BUG: Worked DXCC and WAZ are not updated until confirmed :-? TODO: When importing an ADIF file with several logs, create automatically the logs as detected. TODO: HelpHelpDialog TODO: HelpAboutDialog TODO: setuppagelogs.cpp TODO: Remove references to DataBase from all classes except DataProxySQLite TODO: DXCluster: Lines that are not a DX should not be in another color than default. TODO: Add a default DX Cluster server TODO: Make a tool to mark and export QSO from the right button. (i.e. To mark several QSO to print and export the ADIF file with just those QSO) TODO: Add all the Entity Info to the slotClear to clear everything. TODO: Add a list of previous QSO with the same station, if any. (Done in the search box) TODO: Create something like a void Awards::setAwardsOfAllQSO to read ALL QSO and set the Awards at once instead of adding one QSO per QSO KLOG TODO: TODO: To create a function tha runs the log and marks "N" if QSL has not been sent or received. TODO: Create a setup page to configure a default prop_mode per band (ie 6m = ES) TODO: CTY.DAT update TODO: Award tabs: center/bold tabs TODO: Add export to cabrillo to the logfile SETUP: TODO: Show progress when doing actions TODO: Open this file when opening TODO: DXCLuster: Show HF activity TODO: DXCLuster: Show WARC TODO: DXCLuster: Show VHUF TODO: DXCLuster: Show confirmed TODO: DXCLuster: Show SSB TODO: DXCLuster: Show CW TODO: DXCLuster: Show Ann/full TODO: DXCLuster: Show WCY TODO: DXCLuster: Show WWV TODO: DXCLuster: Double click on a spot, add it to log TODO: DXCLuster: Add Cluster servers DONE: TODO: Colors: Confirmed, Worked, Needed band, New, Default TODO: Require mandatory fields in all QSO TODO: Awards: Add Award TODO: Awards: Remove Award ===================== TODO: Sats: Create a way to update the list of supported satellites. Maybe another tab in the setup dialog as the World Editor TODO: Sats: https://www.eqsl.cc/qslcard/ADIFContentSpecs.cfm TODO: Sats: https://lotw.arrl.org/lotw/faq#sats TODO: Sat Modes: http://www.amsat.org/amsat/intro/sats_faq.html#RTFToC5 http://www.sckans.edu/~sireland/radio/amsat.html A - This mode requires a 2 meter SSB/CW transmitter and a 10 meter SSB/CW receiver and supports CW and voice. B - This mode requires a 70 cm SSB/CW transmitter and a 2 meter SSB/CW receiver and supports CW and voice. Some satellites also support RTTY and SSTV in this mode. J -> V Uplink and U downlink JA - This mode stands for J Analog and requires a 2 meter SSB/CW transmitter and a 70 cm SSB/CW receiver and supports CW, voice. JD - This mode stands for J Digital and requires a 2 meter FM transmitter and a 70 cm SSB/CW receiver and supports packet. K - This mode requires a 15 meter SSB/CW transmitter and a 10 meter SSB/CW receiver and supports CW and voice. This mode is unique in that it can be done with a simple HF rig. S - This mode requires a 70 cm SSB/CW transmitter and a 2.4 GHz SSB/CW receiver and supports CW and voice. Many people use a 2.4 GHz to 2 meter converter with a 2 meter SSB/CW receiver instead of buying a 2.4 GHz SSB/CW receiver. T - This mode requires a 15 meter SSB/CW transmitter and a 2 meter SSB/CW receiver and supports CW and voice. KT, KA, BS, Some satellites have dual modes that operate simultaneously. For example, AO-13 can operate in mode BS which means that it can do both mode B and mode S simultaneously. Other common dual modes are KT and KA. Mode V Mode U Mode U/V -> B TODO: Code a way to sort the bands/modes in the "setuppagebandsmodes.cpp TODO: Create an "updateKLog" class to manage all the release updates so there is a way to detect the version of KLog and upgrade the DB to the latest. TODO: The following fields may add information, even if the qsl has not been rcvd/sent B B TODO: showStatusOfDXCC should be executed when band change. TODO: Add color support: messages for slotQRZTextChanged TODO: SetupPageColors: Check the style in the buttons as the rounds are lost when I change the color!! TODO: MainWindow::processConfigLine: add support for the cluster data. TODO: Check when to connect the DXCluster and when no, it tries twice or more... TODO: Awards: make a function to calculate the total. TODO: Color support: Add needed, worked, confirmed, neutral colors to the configuration dialog. TODO: Color support: Support the bar when a QRZ is entered. TODO: Color support: Calculate a color for the log. TODO: World::getDXStatus: Calculate the algorithm to know the different status for a DXCC (confirmed, worked, confirmed in another band, ,...) TODO: World:: Maybe the color should be returned from the World class TODO: Check the readDataFromUI. QSO are not added when in contest. TODO: Check that New Log, Open, ... somewhere the log table is removed from the DB! TODO: The confirmed WAZ number is not properly calculated. TODO: GUI: Add in the input box a combobox to change the CQZ TODO: GUI: Add in the input box a combobox to change the ITUZ TODO: In CQWWSSB, when editing QSO the SRX, Points, multiplier, ... are not sent to the edit so after "OK", those data are lost. TODO: MainWindow::slotQsoDeleteFromLog: Add the CALL to the message before detele a QSO. TODO: Search GUI: add multi-selection QSO to do the same actions inmultiple QSO. TODO: When importing ADIF, update the logview sometimes... just to show the progress. TODO: When importing ADIF: Only shows the ProgresDialog when the number is low >1000 <14000 investigate TODO: Import Cabrillo TODO: To check how can I order the columns in the log or in the search QTableView. Now the order depends only on the order of the SQL table. TODO: When modifying a cell directly in the log, it is possible to select a mode/band that is not actually active in the configuration. TODO: Slot: If (only)eqsl/lotw is sent/rec, the QSL_RCVD_VIA should be E TODO: Code a Tool to get statistcs for the contests, some kind of post contest tool. http://www.qsl.net/3v4-002/Contests/2011%20CQ-WW-SSB%203V8SS/index.htm TODO: Be able to send scores to: http://www.cqcontest.ru/help/developers.jsp TODO: Create an update CTY.DAT without overwriting the current data. Just Adding and correcting (asking) if data is already there but different. TODO: Create an export CTY.DAT file to create a CTY.DAT file with ALL the data in the current "world". FILEMANAGER TODO: adifLogExportToFile: Count the marked QSO and adjust the numberOfQsos TODO: FileManager::adifReadLog: Optimize the dialog (maybe updating only each 100 or as in KLog) TODO: FileManager::adifReadLog: Add a semaphore/lock or similar to avoid running the same method twice or more at the same time... or at least the same file. It seems that now it "serializes" the import... TODO: Check that FileManager::adifLogExportToFile is exporting ALL the DB fields. TODO: FileManager::adifLogExportToFile code a progress dialog for exporting. TODO: When importing ADIF: Check if all the QSO have all the mandatory fields and warn the user if not. Optimization: The ADIF import is very slow. Optimization is recommended. IMPROVEMENT: Improve the result of the log printing. DONE: TODO: Working on the DB version update functions DONE: MainWindow::showAwards Remove "empty CQZ" when counting to avoid having 41 CQ zones DONE: Code the color configuration for status of an entity (needed/worked/confirmed). DONE: Color support: Calculate a color for the search results. DONE: Color support: Calculate a color for the DXCluster. DONE: TODO: Colors: Reconfigure the colors needs KLog to be restarted. DONE: Working on the dxCluster: Color support, identify the different kind of lines... DX de, normal spots, comments, ... DONE: Working on setAwardDXCC: When adding if a pair is already entered but we are going to add a confirmed status, modify it. DONE: Right click on log to show a to edit QSO. DONE: Right click on log to show a QSL received. DONE: Right click on log to remove a QSO. DONE: Right click on log to show a QSL sent. TODO: Right click on search to remove a QSO. DONE: Right click on search to show a QSL reception. DONE: Right click on search to show a QSL sent. DONE: Right click on search to show to edit QSO. DONE: Added a select/unselect all button to the search QSO tab. DONE: Search QSO to send DONE: Add a button to export to ADIF the content of searchResultsTreeWidget DONE: When importing ADIF, if the CQZ/ITUZ/DXCC is empty, calculate and add it. DONE: Not export ADIF fields if "N": DONE: Print the log. DONE: TODO: Time in UTC DONE: TODO: Log in real time DONE: Double click on cluster to select DONE: TODO: When double clicking on a DX-Spot, frequency should be also copied to inputbox DONE: TODO: When a DX-Spot is selected, the DX-Entity and status should be shown. DONE: TODO: DXCluster: Connect, disconnect and connect again does not work DONE: TODO: Add a field in Mainwindow to manage RX_PWR DONE: TODO: slotclearbuttons->Colors to default DONE: GUI: Add in the input box a combobox to change the DXCC klog-0.9.2.9/mainwindowinputothers.h0000644000076700000620000000632613233376355015446 0ustar staff#ifndef MAINWINDOWINPUTOTHERS_H #define MAINWINDOWINPUTOTHERS_H /*************************************************************************** mainwindowminputothers.h - description ------------------- begin : ago 2016 copyright : (C) 2016 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implement the tab of the mainwindow that supports the Others tab // #include #include #include "dataproxy.h" class MainWindowInputOthers : public QWidget { Q_OBJECT public: MainWindowInputOthers(DataProxy *dp, QWidget *parent = 0); ~MainWindowInputOthers(); void setEntitiesList(const QStringList _qs); void setEntity(const int _n); QString getEntityPrefix(); void setPropMode(const QString _qs); QString getPropModeFromComboBox(); void setIOTA(const QString _qs, const bool _black=true); QString getIOTA(); void setIOTAContinentFromEntity(const int _n); void setIOTAContinent(const QString _qs); bool isIOTAModified(); void clearIOTA(); void createUI(); void clear(); private slots: //void slotSetPropMode(const QString _p); // To receive the signal from the SAT widget and set "SAT" propagation mode, of needed. private: QString checkIfValidIOTA(const QString _tiota); //TODO: There is an equivalent function in the Awards class. I should use only one! DataProxy *dataProxy; QStringList entitiesList, propModeList; //QLabel *entityPrimLabel, *entitySecLabel, *iotaAwardLabel, *entityNameLabel, *propModeLabel; QComboBox *iotaContinentComboBox, *entityPrimDivComboBox, *entitySecDivComboBox, *entityNameComboBox, *propModeComboBox; QLineEdit *iotaNumberLineEdit; QPalette palRed, palBlack; }; #endif // MAINWINDOWINPUTOTHERS_H klog-0.9.2.9/klog.qrc0000644000076700000620000002120013233376355012243 0ustar staff img/klog_512x512.png img/klog_256x256.png img/klog_logo.png img/klog.ico flags/ad.png flags/ae.png flags/af.png flags/ag.png flags/ai.png flags/al.png flags/am.png flags/an.png flags/ao.png flags/ar.png flags/as.png flags/at.png flags/au.png flags/aw.png flags/ax.png flags/az.png flags/ba.png flags/bb.png flags/bd.png flags/be.png flags/bf.png flags/bg.png flags/bh.png flags/bi.png flags/bj.png flags/bm.png flags/bn.png flags/bo.png flags/bq.png flags/br.png flags/bs.png flags/bt.png flags/bv.png flags/bw.png flags/by.png flags/bz.png flags/ca.png flags/canary.png flags/cc.png flags/cd.png flags/cf.png flags/cg.png flags/ch.png flags/ci.png flags/ck.png flags/cl.png flags/cm.png flags/cn.png flags/co.png flags/cr.png flags/cs.png flags/cu.png flags/cv.png flags/cw.png flags/cx.png flags/cy.png flags/cz.png flags/de.png flags/dj.png flags/dk.png flags/dm.png flags/do.png flags/dz.png flags/ec.png flags/ee.png flags/eg.png flags/eh.png flags/england.png flags/er.png flags/es.png flags/et.png flags/europeanunion.png flags/fam.png flags/fi.png flags/fj.png flags/fk.png flags/fm.png flags/fo.png flags/fr.png flags/ga.png flags/gb.png flags/gd.png flags/ge.png flags/gf.png flags/gh.png flags/gi.png flags/gl.png flags/gm.png flags/gn.png flags/gp.png flags/gq.png flags/gr.png flags/gs.png flags/gt.png flags/gu.png flags/gw.png flags/gy.png flags/hk.png flags/hm.png flags/hn.png flags/hr.png flags/ht.png flags/hu.png flags/id.png flags/ie.png flags/il.png flags/in.png flags/io.png flags/iq.png flags/ir.png flags/is.png flags/it.png flags/jm.png flags/jo.png flags/jp.png flags/ke.png flags/kg.png flags/kh.png flags/ki.png flags/km.png flags/kn.png flags/kp.png flags/kr.png flags/kw.png flags/ky.png flags/kz.png flags/la.png flags/lb.png flags/lc.png flags/li.png flags/lk.png flags/lr.png flags/ls.png flags/lt.png flags/lu.png flags/lv.png flags/ly.png flags/ma.png flags/mc.png flags/md.png flags/me.png flags/mg.png flags/mh.png flags/mk.png flags/ml.png flags/mm.png flags/mn.png flags/mo.png flags/mp.png flags/mq.png flags/mr.png flags/ms.png flags/mt.png flags/mu.png flags/mv.png flags/mw.png flags/mx.png flags/my.png flags/mz.png flags/na.png flags/nc.png flags/ne.png flags/nf.png flags/ng.png flags/ni.png flags/nl.png flags/no.png flags/northernireland.png flags/np.png flags/nr.png flags/nu.png flags/nz.png flags/om.png flags/pa.png flags/pe.png flags/pf.png flags/pg.png flags/ph.png flags/pk.png flags/pl.png flags/pm.png flags/pn.png flags/pr.png flags/ps.png flags/pt.png flags/pw.png flags/py.png flags/qa.png flags/re.png flags/ro.png flags/rs.png flags/ru.png flags/rw.png flags/sa.png flags/sb.png flags/sc.png flags/scotland.png flags/sd.png flags/se.png flags/sg.png flags/sh.png flags/si.png flags/sj.png flags/sk.png flags/sl.png flags/sm.png flags/smh.png flags/sn.png flags/so.png flags/sr.png flags/ss.png flags/st.png flags/sv.png flags/sy.png flags/sz.png flags/tc.png flags/td.png flags/tf.png flags/tg.png flags/th.png flags/tj.png flags/tk.png flags/tl.png flags/tm.png flags/tn.png flags/to.png flags/tr.png flags/tt.png flags/tv.png flags/tw.png flags/tz.png flags/ua.png flags/ug.png flags/um.png flags/un.png flags/us.png flags/uy.png flags/uz.png flags/va.png flags/vc.png flags/ve.png flags/vg.png flags/vi.png flags/vn.png flags/vu.png flags/wales.png flags/wf.png flags/ws.png flags/ye.png flags/yt.png flags/za.png flags/zm.png flags/zw.png klog-0.9.2.9/mainwindowinputqsl.cpp0000644000076700000620000002561413233376355015275 0ustar staff/*************************************************************************** mainwindowinputqsl.cpp - description ------------------- begin : jun 2017 copyright : (C) 2017 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implement the tab of the mainwindow that supports the QSL options // #include "mainwindowinputqsl.h" MainWindowInputQSL::MainWindowInputQSL(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "MainWindowInputQSL::MainWindowInputQSL" << endl; util = new Utilities; qslSentComboBox = new QComboBox; qslRecComboBox = new QComboBox; qslSentViaComboBox = new QComboBox; qslRecViaComboBox = new QComboBox; qslSentQDateEdit = new QDateEdit; qslRecQDateEdit = new QDateEdit; qslViaLineEdit = new QLineEdit; qslmsgTextEdit = new QTextEdit; dataProxy = dp; createUI(); setDefaultData(); clear(); //qDebug() << "MainWindowInputQSL::MainWindowInputQSL - END" << endl; } MainWindowInputQSL::~MainWindowInputQSL(){} void MainWindowInputQSL::createUI() { // QSL Tab definition starts here qslSentQDateEdit->setDisplayFormat("dd/MM/yyyy"); qslRecQDateEdit->setDisplayFormat("dd/MM/yyyy"); QLabel *QSLSentLabelN = new QLabel(tr("QSL Sent")); QSLSentLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *QSLRecLabelN = new QLabel(tr("QSL Rec")); QSLRecLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *QSLViaLabelN = new QLabel(tr("QSL Via")); QSLViaLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *QSLMsgLabelN = new QLabel(tr("QSL Msg")); QSLMsgLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); qslSentComboBox->setToolTip(tr("Status of the QSL sending.")); qslRecComboBox->setToolTip(tr("Status of the QSL reception.")); qslSentViaComboBox->setToolTip(tr("QSL sending information.")); qslRecViaComboBox->setToolTip(tr("QSL reception information.")); qslSentQDateEdit->setToolTip(tr("Date of the QSL sending.")); qslRecQDateEdit->setToolTip(tr("Date of the QSL reception.")); qslmsgTextEdit->setToolTip(tr("Message of the QSL.")); qslViaLineEdit->setToolTip(tr("QSL via information.")); QGridLayout *QSLLayout = new QGridLayout; QSLLayout->addWidget(QSLSentLabelN, 0, 0); QSLLayout->addWidget(QSLRecLabelN, 1, 0); QSLLayout->addWidget(QSLViaLabelN, 2, 0); QSLLayout->addWidget(QSLMsgLabelN, 3, 0); QSLLayout->addWidget(qslSentComboBox, 0, 1); QSLLayout->addWidget(qslRecComboBox, 1, 1); QSLLayout->addWidget(qslViaLineEdit, 2, 1, 1, -1); QSLLayout->addWidget(qslmsgTextEdit, 3, 1, 1, -1); QSLLayout->addWidget(qslSentQDateEdit, 0, 2); QSLLayout->addWidget(qslRecQDateEdit, 1, 2); QSLLayout->addWidget(qslSentViaComboBox, 0, 3); QSLLayout->addWidget(qslRecViaComboBox, 1, 3); setLayout(QSLLayout); connect(qslViaLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotQSLViaTextChanged() ) ) ; connect(qslRecComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotQSLRecvComboBoxChanged() ) ) ; connect(qslSentComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotQSLSentComboBoxChanged() ) ) ; connect(qslViaLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQSLViaLineEditReturnPressed() ) ); } void MainWindowInputQSL::setDefaultData() { qslSentStatusList.clear(); qslRcvdStatusList.clear(); qslViaList.clear(); qslSentStatusList = dataProxy->getQSLSentList(); qslRcvdStatusList = dataProxy->getQSLRcvdList(); qslViaList = dataProxy->getQSLViaList(); qslSentComboBox->addItems(qslSentStatusList); qslRecComboBox->addItems(qslRcvdStatusList); qslRecViaComboBox->addItems(qslViaList); qslSentViaComboBox->addItems(qslViaList); qslSentQDateEdit->setDate(util->getDefaultDate()); qslRecQDateEdit->setDate(util->getDefaultDate()); } void MainWindowInputQSL::clear() { qslSentComboBox->setCurrentIndex(1); qslRecComboBox->setCurrentIndex(1); qslRecViaComboBox->setCurrentIndex(0); qslSentViaComboBox->setCurrentIndex(0); qslSentQDateEdit->setDate(util->getDefaultDate()); qslRecQDateEdit->setDate(util->getDefaultDate()); qslmsgTextEdit->clear(); qslViaLineEdit->clear(); } void MainWindowInputQSL::qslViaClear() { qslViaLineEdit->clear(); } QString MainWindowInputQSL::getQSLRecStatus() { QString _pm = QString(); _pm = (((qslRecComboBox->currentText()).split('-')).at(0)).simplified(); return _pm; } QString MainWindowInputQSL::getQSLSenStatus() { QString _pm = QString(); _pm = (((qslSentComboBox->currentText()).split('-')).at(0)).simplified(); return _pm; } QString MainWindowInputQSL::getSentVia() { QString _pm = QString(); _pm = (((qslSentViaComboBox->currentText()).split('-')).at(0)).simplified(); //qDebug() << "MainWindow::getSentVia: " << _pm << endl; return _pm; } QString MainWindowInputQSL::getRecVia() { QString _pm = QString(); _pm = (((qslRecViaComboBox->currentText()).split('-')).at(0)).simplified(); //qDebug() << "MainWindowInputQSL::getRecVia: " << _pm << endl; return _pm; } QString MainWindowInputQSL::getQSLVia() { return qslViaLineEdit->text(); } QString MainWindowInputQSL::getQSLMsg() { return qslmsgTextEdit->toPlainText(); } void MainWindowInputQSL::setQSLRecStatus(const QString _qs) { if(( qslRecComboBox->findText(_qs+" -", Qt::MatchStartsWith))>=0) { qslRecComboBox->setCurrentIndex( qslRecComboBox->findText(_qs+" -", Qt::MatchStartsWith)); } else { qslRecComboBox->setCurrentIndex(1); } } void MainWindowInputQSL::setQSLSenStatus(const QString _qs) { if(( qslSentComboBox->findText(_qs+" -", Qt::MatchStartsWith))>=0) { qslSentComboBox->setCurrentIndex( qslSentComboBox->findText(_qs+" -", Qt::MatchStartsWith)); } else { qslSentComboBox->setCurrentIndex(1); } } void MainWindowInputQSL::setQSLRecVia(const QString _qs) { if(( qslRecViaComboBox->findText(_qs+" -", Qt::MatchStartsWith))>=0) { qslRecViaComboBox->setCurrentIndex( qslRecViaComboBox->findText(_qs+" -", Qt::MatchStartsWith)); } else { qslRecViaComboBox->setCurrentIndex(0); // bureau by default } } void MainWindowInputQSL::setQSLSenVia(const QString _qs) { //qDebug() << "MainWindowInputQSL::setQSLSenVia: " << _qs << endl; if(( qslSentViaComboBox->findText(_qs+" -", Qt::MatchStartsWith))>=0) { qslSentViaComboBox->setCurrentIndex( qslSentViaComboBox->findText(_qs+" -", Qt::MatchStartsWith)); } else { qslSentViaComboBox->setCurrentIndex(0); // bureau by default } } void MainWindowInputQSL::setQSLVia(const QString _qs, QColor qColor) { palette.setColor(QPalette::Text, qColor); qslViaLineEdit->setPalette(palette); if (_qs.length()>0) { qslViaLineEdit->setText(_qs); } else { qslViaLineEdit->clear(); } } void MainWindowInputQSL::setQSLMsg(const QString _qs) { if (_qs.length()>0) { qslmsgTextEdit->setText(_qs); } else { qslmsgTextEdit->clear(); } } QDate MainWindowInputQSL::getQSLRecDate() { return qslRecQDateEdit->date(); } QDate MainWindowInputQSL::getQSLSenDate() { return qslSentQDateEdit->date(); } void MainWindowInputQSL::setQSLRecDate(const QDate _qs) { if (_qs.isValid()) { qslRecQDateEdit->setDate(_qs); } else { qslRecQDateEdit->clear(); } } void MainWindowInputQSL::setQSLSenDate(const QDate _qs) { if (_qs.isValid()) { qslSentQDateEdit->setDate(_qs); } else { qslSentQDateEdit->clear(); } } void MainWindowInputQSL::slotQSLViaTextChanged() { //qDebug() << "MainWindow::slotQSLViaTextChanged: " << qslViaLineEdit->text() << " / Length: " << QString::number((qslViaLineEdit->text()).size()) << endl; qslViaLineEdit->setText((qslViaLineEdit->text()).toUpper()); } void MainWindowInputQSL::slotQSLSentComboBoxChanged(){ int i = qslSentComboBox->currentIndex(); //{Y, N, R, I, V} //(QSLSDATE is only valid if QSL_SENT is Y-0, Q-3, or I-4) // Y-Yes = 0 // N-No = 1 // R-Requested = 2 // Q-Queued = 3 // I-Ignore = 4 switch (i) { case 0: qslSentQDateEdit->setEnabled(true); qslSentQDateEdit->setDate((QDateTime::currentDateTime()).date()); break; case 2: break; case 3: qslSentQDateEdit->setEnabled(true); break; case 4: qslSentQDateEdit->setEnabled(true); break; default: //NO qslSentQDateEdit->setEnabled(false); break; } } void MainWindowInputQSL::slotQSLRecvComboBoxChanged(){ int i = qslRecComboBox->currentIndex(); //{Y, N, R, I, V} //(QSLSDATE is only valid if QSL_SENT is Y-0, Q-3, or I-4) // Y-Yes = 0 // N-No = 1 // R-Requested = 2 // Q-Queued = 3 // I-Ignore = 4 switch (i) { case 0: qslRecQDateEdit->setEnabled(true); qslRecQDateEdit->setDate((QDateTime::currentDateTime()).date()); break; case 2: break; case 3: qslRecQDateEdit->setEnabled(true); break; case 4: qslRecQDateEdit->setEnabled(true); break; default: //NO qslRecQDateEdit->setEnabled(false); break; } } void MainWindowInputQSL::slotQSLViaLineEditReturnPressed() { emit returnPressed(); } klog-0.9.2.9/setuppagemisc.cpp0000644000076700000620000004572413233376355014176 0ustar staff/*************************************************************************** setuppagemisc.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include "setuppagemisc.h" //TODO: The defaultFileName QString can be removed and used the content of defaultFileNameLineEdit // instead. It is easy to change but the code would not be so clear... Think about this. :-) SetupPageMisc::SetupPageMisc(QWidget *parent) : QWidget(parent){ //qDebug() << "SetupPageMisc::SetupPageMisc" << endl; util = new Utilities; imperialCheckBox = new QCheckBox(tr("&Imperial system"), this); realTimeCheckbox = new QCheckBox(tr("&Log in real time"), this); UTCCheckbox = new QCheckBox(tr("&Time in UTC"), this); alwaysADIFCheckBox = new QCheckBox(tr("&Save ADIF on exit"), this); useDefaultName = new QCheckBox(tr("Use this &default filename"), this); sendQSLWhenRecCheckBox = new QCheckBox(tr("Mark &QSO to send QSL when QSL is received"), this); completeWithPreviousCheckBox = new QCheckBox(tr("Complete QSO with previous data")); showStationCallWhenSearchCheckBox = new QCheckBox(tr("Show the Station &Callsign used in the search box"), this); keepMyDataCheckBox = new QCheckBox(tr("&Reset to My Data for all QSOs"), this); checkNewVersionCheckBox = new QCheckBox(tr("&Check for new versions automatically"), this); provideCallCheckBox = new QCheckBox(tr("&Provide Info for statistics"), this); defaultFileNameLineEdit = new QLineEdit; dbPathLineEdit = new QLineEdit; fileNameButton = new QPushButton (tr("Browse")); dbPushButton = new QPushButton (tr("Browse")); moveDBPushButton = new QPushButton(tr("Move DB")); dbPathApplied = true; createUI(); createActions(); if (areDBPathChangesApplied()) { moveDBPushButton->setEnabled(false); } else { moveDBPushButton->setEnabled(true); } //qDebug() << "SetupPageMisc::SetupPageMisc - END" << endl; } SetupPageMisc::~SetupPageMisc(){ //qDebug() << "SetupPageMisc::~SetupPageMisc" << endl; } void SetupPageMisc::createUI() { palWrong.setColor(QPalette::Text, Qt::red); palRight.setColor(QPalette::Text, Qt::black); //TODO: To be removed when the defaultDir is saved in the config file #ifdef Q_OS_WIN //qDebug() << "WINDOWS DETECTED!" << endl; klogDir = util->getHomeDir(); // We create the \klog for the logs and data defaultFileName = klogDir+"/klog.adi"; #else //qDebug() << "NO WINDOWS DETECTED!" << endl; klogDir = util->getHomeDir(); // We create the ~/.klog for the logs and data defaultFileName = klogDir+"/klog.adi"; #endif dbDirNew = klogDir; // The new path where the DB is to be moved dbDirCurrent = dbDirNew; // The path where the DB is hosted defaultFileNameLineEdit->setReadOnly(false); defaultFileNameLineEdit->setText(defaultFileName); defaultFileNameLineEdit->setEnabled(false); dbPathLineEdit->setReadOnly(false); dbPathLineEdit->setText(dbDirCurrent); dbPathLineEdit->setEnabled(true); useDefaultName->setChecked(true); alwaysADIFCheckBox->setChecked(true); showStationCallWhenSearchCheckBox->setChecked(true); keepMyDataCheckBox->setChecked(true); completeWithPreviousCheckBox->setChecked(false); sendQSLWhenRecCheckBox->setToolTip(tr("QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours.")); showStationCallWhenSearchCheckBox->setToolTip(tr("The search box will show also the callsign on the air to do the QSO.")); keepMyDataCheckBox->setToolTip(tr("All the data from the My Data tab will be used or data from the previous QSO will be maintained.")); checkNewVersionCheckBox->setToolTip(tr("Check if there is a new release of KLog available every time you start KLog.")); provideCallCheckBox->setToolTip(tr("If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog.")); imperialCheckBox ->setToolTip(tr("Check it for Imperial system (Miles instead of Kilometres).")); realTimeCheckbox->setToolTip(tr("Select to use real time.")); UTCCheckbox->setToolTip(tr("Select to use UTC time.")); alwaysADIFCheckBox->setToolTip(tr("Select if you want to save to ADIF on exit.")); useDefaultName->setToolTip(tr("Select to use the following name for the logfile without being asked for it again.")); completeWithPreviousCheckBox->setToolTip(tr("Complete the current QSO with previous QSO data.")); defaultFileNameLineEdit->setToolTip(tr("This is the default file where ADIF data will be saved.")); dbPathLineEdit->setToolTip(tr("This is the directory where the database (logbook.dat) will be saved.")); fileNameButton->setToolTip(tr("Click to change the default ADIF file.")); dbPushButton->setToolTip(tr("Click to change the path of the database.")); moveDBPushButton->setToolTip(tr("Click to move the DB to the new directory.")); QHBoxLayout *fileLayout = new QHBoxLayout; fileLayout->addWidget(useDefaultName); fileLayout->addWidget(defaultFileNameLineEdit); fileLayout->addWidget(fileNameButton); defaultFileNameLineEdit->setEnabled(true); fileNameButton->setEnabled(true); QHBoxLayout *dbLayout = new QHBoxLayout; dbLayout->addWidget(dbPathLineEdit); dbLayout->addWidget(dbPushButton); dbLayout->addWidget(moveDBPushButton); UTCCheckbox->setChecked(true); realTimeCheckbox->setChecked(true); QGridLayout *mainLayou1 = new QGridLayout; mainLayou1->addLayout(fileLayout, 0, 0, 1, -1); mainLayou1->addLayout(dbLayout, 1, 0, 1, -1); mainLayou1->addWidget(alwaysADIFCheckBox, 2, 0, 1, 1); mainLayou1->addWidget(UTCCheckbox, 3, 0, 1, 1); mainLayou1->addWidget(realTimeCheckbox, 3, 1, 1, 1); mainLayou1->addWidget(imperialCheckBox, 4, 0, 1, 1); mainLayou1->addWidget(keepMyDataCheckBox, 5, 0, 1, 1); mainLayou1->addWidget(completeWithPreviousCheckBox, 5, 1, 1, 1); mainLayou1->addWidget(sendQSLWhenRecCheckBox,6, 0, 1, 1); mainLayou1->addWidget(showStationCallWhenSearchCheckBox, 6, 1, 1, 1); mainLayou1->addWidget(checkNewVersionCheckBox, 7, 0, 1, 1); mainLayou1->addWidget(provideCallCheckBox, 7, 1, 1, 1); setLayout(mainLayou1); } void SetupPageMisc::createActions(){ //void itemDoubleClicked ( QListWidgetItem * item ) connect(fileNameButton, SIGNAL(clicked () ), this, SLOT(slotOpenFileButtonClicked() ) ); connect(useDefaultName, SIGNAL(stateChanged (int) ), this, SLOT(slotUseDefaultButtonStateChanged(int) ) ); connect(defaultFileNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotDefaultFileNameLineEditChanged() ) ); connect(checkNewVersionCheckBox, SIGNAL(clicked () ), this, SLOT(slotcheckNewVersionCheckBoxClicked() ) ); connect(dbPushButton, SIGNAL(clicked () ), this, SLOT(slotDBButtonClicked() ) ); connect(dbPathLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotDBLineEditChanged() ) ); connect(moveDBPushButton, SIGNAL(clicked () ), this, SLOT(slotMoveDBButtonClicked() ) ); } QString SetupPageMisc::getRealTime(){ if (realTimeCheckbox->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setRealTime(const QString t){ //QString st = t; if ( (t.toUpper()) == "FALSE") { realTimeCheckbox->setChecked(false); } else { realTimeCheckbox->setChecked(true); } } QString SetupPageMisc::getUTCTime(){ if (UTCCheckbox->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setUTCTime(const QString t){ if ( (t.toUpper()) == "FALSE") { UTCCheckbox->setChecked(false); } else { UTCCheckbox->setChecked(true); } } QString SetupPageMisc::getAlwaysADIF() { if (alwaysADIFCheckBox->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setAlwaysADIF(const QString t) { // Defaul value is false if ( (t.toUpper()) == "TRUE") { alwaysADIFCheckBox->setChecked(true); } else { alwaysADIFCheckBox->setChecked(false); } } QString SetupPageMisc::getDefaultFileName() { return defaultFileName; } void SetupPageMisc::setDefaultFileName(const QString t) { //qDebug() << "SetupPageMisc::setDefaultFileName: " << t << endl; defaultFileName = t; defaultFileNameLineEdit->setText(defaultFileName); } void SetupPageMisc::slotOpenFileButtonClicked() { defaultFileName = QFileDialog::getOpenFileName(this, tr("Open File"), klogDir, "ADIF (*.adi)"); defaultFileNameLineEdit->setText(defaultFileName); } void SetupPageMisc::slotDefaultFileNameLineEditChanged() { //setDefaultFileName(); defaultFileName = defaultFileNameLineEdit->text(); } /* QString SetupPageMisc::getInMemory() { if (dbInMemory->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setInMemory(const QString t) { if ( (t.toUpper()) == "FALSE") { dbInMemory->setChecked(false); } else { dbInMemory->setChecked(true); } } */ QString SetupPageMisc::getUseDefaultName() { if (useDefaultName->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setUseDefaultName(const QString t) { if ( (t.toUpper()) == "FALSE") { useDefaultName->setChecked(false); } else { useDefaultName->setChecked(true); } } QString SetupPageMisc::getImperial() { if (imperialCheckBox->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setImperial(const QString t) { if ( (t.toUpper()) == "FALSE") { imperialCheckBox->setChecked(false); } else { imperialCheckBox->setChecked(true); } } void SetupPageMisc::slotUseDefaultButtonStateChanged(int state) { //qDebug() << "SetupPageMisc::slotUseDefaultButtonStateChanged" << endl; if (state) { defaultFileNameLineEdit->setEnabled(true); moveDBPushButton->setEnabled(true); } else { defaultFileNameLineEdit->setEnabled(false); moveDBPushButton->setEnabled(false); } } QString SetupPageMisc::getSendQSLWhenRec(){ if (sendQSLWhenRecCheckBox->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setSendQSLWhenRec(const QString t){ if ( (t.toUpper()) == "FALSE") { sendQSLWhenRecCheckBox->setChecked(false); } else { sendQSLWhenRecCheckBox->setChecked(true); } } QString SetupPageMisc::getShowStationCallSignInSearch() { if (showStationCallWhenSearchCheckBox->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setShowStationCallSignInSearch(const QString t) { if ( (t.toUpper()) == "FALSE") { showStationCallWhenSearchCheckBox->setChecked(false); } else { showStationCallWhenSearchCheckBox->setChecked(true); } } QString SetupPageMisc::getKeepMyData() { if (keepMyDataCheckBox->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setKeepMyData(const QString t) { if ( (t.toUpper()) == "FALSE") { keepMyDataCheckBox->setChecked(false); } else { keepMyDataCheckBox->setChecked(true); } } QString SetupPageMisc::getCompleteWithPrevious() { if (completeWithPreviousCheckBox->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setCompleteWithPrevious(const QString t) { if ( (t.toUpper()) == "FALSE") { completeWithPreviousCheckBox->setChecked(false); } else { completeWithPreviousCheckBox->setChecked(true); } } void SetupPageMisc::slotcheckNewVersionCheckBoxClicked() { if (checkNewVersionCheckBox->isChecked()) { provideCallCheckBox->setEnabled(true); } else { provideCallCheckBox->setEnabled(false); provideCallCheckBox->setChecked(false); } } QString SetupPageMisc::getCheckNewVersions() { if (checkNewVersionCheckBox->isChecked()) { return "True"; } else { return "False"; } } void SetupPageMisc::setCheckNewVersions(const QString t) { if ( (t.toUpper()) == "FALSE") { checkNewVersionCheckBox->setChecked(false); } else { checkNewVersionCheckBox->setChecked(true); } } QString SetupPageMisc::getReportInfo() { if (checkNewVersionCheckBox->isChecked()) { if (provideCallCheckBox->isChecked()) { return "True"; } else { return "False"; } } else { return "False"; } } void SetupPageMisc::setReportInfo(const QString t) { if ( (t.toUpper()) == "FALSE") { provideCallCheckBox->setChecked(false); } else { provideCallCheckBox->setChecked(true); } } QString SetupPageMisc::getDefaultDBPath() { return dbDirCurrent; } void SetupPageMisc::setUseDefaultDBPath(const QString t) { dbDirCurrent = t; dbPathLineEdit->setText(dbDirCurrent); } void SetupPageMisc::slotDBButtonClicked() { // QString dbDirBack = dbDir; QString dir = QFileDialog::getExistingDirectory(this, tr("Select Directory"), dbDirCurrent, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if (dir.length()>=1) { dbDirNew = dir; } dbPathLineEdit->setText(dbDirNew); if (dbDirCurrent == dbDirNew) { dbPathApplied = true; } else { dbPathApplied = false; moveDBPushButton->setEnabled(true); } //setUseDefaultDBPath(dbDirNew); } void SetupPageMisc::slotDBLineEditChanged() { //qDebug() << "SetupPageMisc::slotDBLineEditChanged: " << dbPathLineEdit->text() << endl; QString aux; aux = dbPathLineEdit->text(); if ( QFile::exists(aux) ) { dbPathLineEdit->setToolTip(tr("This is the directory where DB (logbook.dat) will be saved.")); dbPathLineEdit->setPalette(palRight); dbDirNew = dbPathLineEdit->text(); } else { dbPathLineEdit->setToolTip(tr("Please specify an existing directory where the database (logbook.dat) will be saved.")); dbPathLineEdit->setPalette(palWrong); } if (dbDirCurrent == dbDirNew) { dbPathApplied = true; moveDBPushButton->setEnabled(false); } else { dbPathApplied = false; moveDBPushButton->setEnabled(true); } } void SetupPageMisc::slotMoveDBButtonClicked() { QString source = dbDirCurrent + "/logbook.dat"; QString target = dbDirNew + "/logbook.dat"; QMessageBox msgBox; //qDebug() << "SetupPageMisc::slotMoveDBButtonClicked (source): " << source << endl; //qDebug() << "SetupPageMisc::slotMoveDBButtonClicked (target): " << target << endl; if ( QFile::exists(dbDirNew) ) { //dbDirCurrent //dbDir if (QFile::copy(source, target)) { dbDirCurrent = dbDirNew; if (QFile::remove(source)) { msgBox.setIcon(QMessageBox::Warning); msgBox.setText(tr("File moved")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); dbPathApplied = true; } else { msgBox.setIcon(QMessageBox::Warning); msgBox.setText(tr("File copied")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); dbPathApplied = true; } } else { msgBox.setIcon(QMessageBox::Warning); msgBox.setText(tr("File NOT copied")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); dbPathApplied = false; moveDBPushButton->setEnabled(true); } } else { msgBox.setIcon(QMessageBox::Warning); msgBox.setText(tr("The target directory does not exist. Please select an existing directory.")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); dbPathApplied = false; moveDBPushButton->setEnabled(true); } } bool SetupPageMisc::areDBPathChangesApplied() { return dbPathApplied; } klog-0.9.2.9/mainwindowsattab.cpp0000644000076700000620000005010713233376355014667 0ustar staff /*************************************************************************** mainwindowsattab.cpp - description ------------------- begin : Jul 2016 copyright : (C) 2016 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "mainwindowsattab.h" /* This class implements the Satellite TAB of the MainWindow */ MainWindowSatTab::MainWindowSatTab(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "MainWindowSatTab::MainWindowSatTab" << endl; satNameComboBox = new QComboBox; satNameLineEdit = new QLineEdit; satModeLineEdit = new QLineEdit; satDXLocatorLineEdit = new QLineEdit; satOtherLabel = new QLabel; satBandTXComboBox = new QComboBox; satBandRXComboBox = new QComboBox; txFreqSpinBox = new QDoubleSpinBox; rxFreqSpinBox = new QDoubleSpinBox; keepThisDataForNextQSORadiobutton = new QRadioButton; dataProxy = dp; locator = new Locator; createUI(); populateSatComboBox(); satNameLineEdit->setEnabled(false); satOtherLabel->setEnabled(false); setDefaultBands(); //TODO: Check how the bands are included not to create an inconsistence with the selected (in the setup) bands //qDebug() << "MainWindowSatTab::MainWindowSatTab - END" << endl; } MainWindowSatTab::~MainWindowSatTab(){} void MainWindowSatTab::createUI() { connect(satNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotSatNameTextChanged() ) ); connect(satModeLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotSatModeTextChanged() ) ); connect(satDXLocatorLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotSatDXLocTextChanged() ) ); connect(satNameComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotSatNameComboBoxChanged() ) ) ; connect(satBandRXComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotSatBandRXComboBoxChanged()) ) ; connect(satBandTXComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotSatBandTXComboBoxChanged()) ) ; connect(txFreqSpinBox, SIGNAL(valueChanged(double)), this, SLOT(slotSatFreqTXChanged()) ) ; connect(rxFreqSpinBox, SIGNAL(valueChanged(double)), this, SLOT(slotSatFreqRXChanged()) ) ; QLabel *keepLabel = new QLabel(); keepLabel->setText(tr("Keep this data")); keepLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); keepLabel->setToolTip(tr("Data entered in this tab will be copied into the next QSO")); keepThisDataForNextQSORadiobutton->setToolTip(tr("Data entered in this tab will be copied into the next QSO")); QString othersat = tr("Other - Sat not in the list"); QString aux; aux.clear(); aux = QString(tr("Name of the Satellite if not in the list. Select: \"")) + othersat + QString(tr("\" to enable this box. (format like AO-51)")); satNameLineEdit->setToolTip(aux); //satNameLineEdit->setToolTip(tr("Name of the Satellite if not in the list. Select Other Sat (format like AO-51)")); satModeLineEdit->setToolTip(tr("Satellite mode used")); satNameComboBox->setToolTip(tr("Select the satellite you are using")); satBandTXComboBox->setToolTip(tr("UpLink band")); satBandRXComboBox->setToolTip(tr("DownLink band")); satDXLocatorLineEdit->setToolTip(tr("Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab.")); QLabel *upLinkLabel = new QLabel(); upLinkLabel->setText(tr("UpLink")); upLinkLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *downLinkLabel = new QLabel(); downLinkLabel->setText(tr("DownLink")); downLinkLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *satNameLabel = new QLabel(); satNameLabel->setText(tr("Satellite")); satNameLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *satModeLabel = new QLabel(); satModeLabel->setText(tr("Mode")); satModeLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *satDXLocLabel = new QLabel(); satDXLocLabel->setText(tr("DX Locator")); satDXLocLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); //QLabel *satOtherLabel = new QLabel(); satOtherLabel->setText(tr("Other")); satOtherLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); txFreqSpinBox->setDecimals(3); txFreqSpinBox->setMaximum(9999); txFreqSpinBox->setSuffix(" " + tr("MHz")); rxFreqSpinBox->setDecimals(3); rxFreqSpinBox->setMaximum(9999); rxFreqSpinBox->setSuffix(" " + tr("MHz")); QHBoxLayout *keepLayout = new QHBoxLayout; keepLayout->addWidget(keepLabel); keepLayout->addWidget(keepThisDataForNextQSORadiobutton); QHBoxLayout *lastlineLayout = new QHBoxLayout; //lastlineLayout->addWidget(satModeLabel); lastlineLayout->addWidget(satModeLineEdit); lastlineLayout->addWidget(satDXLocLabel); lastlineLayout->addWidget(satDXLocatorLineEdit); QGridLayout *tabLayout = new QGridLayout; tabLayout->addWidget(satNameLabel,0,0); tabLayout->addWidget(upLinkLabel,1,0); tabLayout->addWidget(downLinkLabel,2,0); tabLayout->addWidget(satModeLabel,3,0); tabLayout->addLayout(lastlineLayout,3,1); tabLayout->addWidget(satNameComboBox,0,1); tabLayout->addWidget(satBandTXComboBox,1,1); tabLayout->addWidget(satBandRXComboBox,2,1); //tabLayout->addWidget(satModeLineEdit,3,1); //tabLayout->addWidget(satModeLineEdit,3,1,1,-1); tabLayout->addWidget(satNameLineEdit,0,2); tabLayout->addWidget(txFreqSpinBox,1,2); tabLayout->addWidget(rxFreqSpinBox,2,2); tabLayout->addLayout(keepLayout,3,2); setLayout(tabLayout); } void MainWindowSatTab::slotSatNameComboBoxChanged() { int i = satNameComboBox->currentIndex(); //qDebug() << "MainWindowSatTab::slotSatNameComboBoxChanged: " << QString::number(i) << endl; //QString _pm = (((satNameComboBox->currentText()).split(' ')).at(0)).simplified(); satNameLineEdit->clear(); if (i == 0) { emit setPropModeSat("Not"); satNameLineEdit->setEnabled(false); satOtherLabel->setEnabled(false); } else if(i == 1) { emit setPropModeSat("SAT"); satNameLineEdit->setEnabled(true); satOtherLabel->setEnabled(true); } else { emit setPropModeSat("SAT"); satNameLineEdit->setEnabled(false); satOtherLabel->setEnabled(false); setBandsOfSat(satNameComboBox->currentText()); } } void MainWindowSatTab::slotSatNameTextChanged() { //qDebug() << "MainWindowSatTab::slotSatNameTextChanged: " << satNameLineEdit->text() << endl; satNameLineEdit->setText((satNameLineEdit->text()).toUpper()); if ((satNameLineEdit->text()).length()>0) { emit setPropModeSat("SAT"); } else if ((satModeLineEdit->text()).length()<1) { emit setPropModeSat("Not"); } } void MainWindowSatTab::slotSatModeTextChanged() { //qDebug() << "MainWindowSatTab::slotSatModeTextChanged: " << satModeLineEdit->text() << endl; /* satModeLineEdit->setText((satModeLineEdit->text()).toUpper()); if ((satModeLineEdit->text()).length()>0) { emit setPropModeSat("SAT"); } else if ((satNameLineEdit->text()).length()<1) { emit setPropModeSat("Not"); } */ } void MainWindowSatTab::setLocator(const QString _t) { //qDebug() << "MainWindowSatTab::setLocator: " << _t << endl; satDXLocatorLineEdit->setText(_t.toUpper()); } void MainWindowSatTab::slotSatDXLocTextChanged() { //qDebug() << "MainWindowSatTab::slotSatDXLocTextChanged: " << satDXLocatorLineEdit->text() << endl; satDXLocatorLineEdit->setText((satDXLocatorLineEdit->text()).toUpper()); if ( locator->isValidLocator((satDXLocatorLineEdit->text()).toUpper()) ) { emit dxLocatorChanged((satDXLocatorLineEdit->text()).toUpper()); } else { return; } } QString MainWindowSatTab::getSatName() { // Sat name must follow the format CC-NN to make it compatible with LOTW // C = Character // N = Number /* QString satName; satName = satNameLineEdit->text(); //TODO: Check that the format is OK return satName; */ QString _pm = QString(); QString satName = QString(); //qDebug() << "MainWindowSatTab::getSatName:" << satNameComboBox->currentText() << endl; _pm = (((satNameComboBox->currentText()).split(' ')).at(0)).simplified(); //qDebug() << "MainWindowSatTab::satNameComboBox: " << _pm << endl; if (satNameComboBox->currentIndex() == 0) { return QString(); } else if(satNameComboBox->currentIndex() == 1) { satName = satNameLineEdit->text(); if (satName.length()>0) { return satName; } else { return QString(); } } else { return _pm; } } void MainWindowSatTab::setSatName(const QString _t) { //TODO: Check that the format is OK //qDebug() << "MainWindowSatTab::setSatName: " << _t << endl; //satNameLineEdit->setText(_t); if (getSatIndex(_t) > 0) { setSatelliteCombo(_t); } else { satNameComboBox->setCurrentIndex(1); satNameLineEdit->setText(_t); } } QString MainWindowSatTab::getSatMode() { return satModeLineEdit->text(); } void MainWindowSatTab::setSatMode(const QString _t) { //qDebug() << "MainWindowSatTab::setSatMode: " << _t << endl; if (_t == "-CLEAR-") { satModeLineEdit->clear(); } else { satModeLineEdit->setText(_t); } } bool MainWindowSatTab::getRepeatThis() { return keepThisDataForNextQSORadiobutton->isChecked(); } void MainWindowSatTab::setRepeatThis(const bool _t) { keepThisDataForNextQSORadiobutton->setChecked(_t); } void MainWindowSatTab::clear() { //qDebug() << "MainWindowSatTab::clear" << endl; if (keepThisDataForNextQSORadiobutton->isChecked()) { satDXLocatorLineEdit->clear(); return; } else { satModeLineEdit->clear(); satNameComboBox->setCurrentIndex(0); satNameLineEdit->clear(); //txFreqSpinBox->setValue(0); //rxFreqSpinBox->setValue(0); //satBandRXComboBox->setCurrentIndex(0); //satBandTXComboBox->setCurrentIndex(0); } } void MainWindowSatTab::populateSatComboBox() { //qDebug() << "MainWindowSatTab::populateSatComboBox: " << endl; QString nosat = tr("Not Sat QSO"); QString othersat = tr("Other - Sat not in the list"); satellitesList.clear(); satellitesList = dataProxy->getSatellitesList(); satellitesList.prepend(othersat); satellitesList.prepend("No-SAT - " + nosat); if (satellitesList.size()>1) { satNameComboBox->addItems(satellitesList); } else { //TODO: Check how to do it better... now I could simply remove the if satNameComboBox->addItems(satellitesList); } } void MainWindowSatTab::setSatelliteCombo(const QString _p) { //qDebug() << "MainWindowsatTab::setSatelliteCombo: " << _p << endl; QString aux = QString(); int indexC = getSatIndex(_p); //int indexC = satNameComboBox->findText(_p, Qt::MatchContains); //qDebug() << "MainWindowsatTab::setSatelliteCombo: N=" << QString::number(indexC) << endl; if (indexC>0) { satNameComboBox->setCurrentIndex(indexC); } else { satNameComboBox->setCurrentIndex(0); if (_p.length()>0) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); aux = tr("KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name.") + "\n\n"; msgBox.setText(aux + tr("The satellite you have in your QSO is: ") + _p + "\n\n" + tr("Please know that the satellite name will not be saved if it is not in the list so that information may be lost!")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: break; default: // should never be reached break; } } } } void MainWindowSatTab::setOtherSatName(const QString _t) { //qDebug() << "MainWindowsatTab::setOtherSatName: " << _t << endl; satNameLineEdit->setText(_t); } QString MainWindowSatTab::getOtherSatName() { return QString(); } int MainWindowSatTab::getSatIndex(const QString _p) { return satNameComboBox->findText(_p, Qt::MatchContains); } void MainWindowSatTab::addBands(QStringList _bands) { //qDebug() << "MainWindowSatTab::addBands: " << QString::number(_bands.length()) << endl; satBandRXComboBox->clear(); satBandTXComboBox->clear(); satBandTXComboBox->addItems(_bands); satBandRXComboBox->addItems(_bands); } void MainWindowSatTab::setDefaultBands() {//Defines the default bands for SAT communications: 10m/2m/70cm/23CM only if they exist on the selected bands //qDebug() << "MainWindowsatTab::setDefaultBands: " << endl; QStringList _b; _b.clear(); _b << "10M" << "2M" << "70CM" << "23CM"; satBandRXComboBox->addItems(_b); satBandTXComboBox->addItems(_b); } void MainWindowSatTab::slotSatBandRXComboBoxChanged() { //qDebug() << "MainWindowsatTab::slotSatBandRXComboBoxChanged" << endl; emit satBandRXChanged(satBandRXComboBox->currentText()); } void MainWindowSatTab::slotSatBandTXComboBoxChanged() { //qDebug() << "MainWindowsatTab::slotSatBandTXComboBoxChanged" << endl; emit satBandTXChanged(satBandTXComboBox->currentText()); } void MainWindowSatTab::slotSatFreqRXChanged() { QString _q; int v = dataProxy->getBandIdFromFreq(rxFreqSpinBox->value()); if (v<0) { return; } _q = dataProxy->getNameFromBandId (v); satBandRXComboBox->setCurrentIndex(satBandRXComboBox->findText(_q)); } void MainWindowSatTab::slotSatFreqTXChanged() { //qDebug() << "MainWindowsatTab::slotSatFreqTXChanged" << endl; QString _q; int v = dataProxy->getBandIdFromFreq(txFreqSpinBox->value()); if (v<0) { return; } _q = dataProxy->getNameFromBandId (v); satBandTXComboBox->setCurrentIndex(satBandTXComboBox->findText(_q)); } void MainWindowSatTab::setUpLink(const QString _t) { //qDebug() << "MainWindowsatTab::setUpLink: " << _t << endl; int index = satBandTXComboBox->findText(_t, Qt::MatchCaseSensitive); int indexRX; if (index>=0) { satBandTXComboBox->setCurrentIndex(index); //if ((dataProxy->isVHF(dataProxy->getIdFromBandName(_t))) && !(dataProxy->isUHF(dataProxy->getIdFromBandName(_t))) ) if ( dataProxy->getIdFromBandName("2M") == dataProxy->getIdFromBandName(_t) ) { //qDebug() << satNameComboBox->currentText() << endl; if (satNameComboBox->findText("AO-7 - AMSAT-OSCAT 7", Qt::MatchCaseSensitive)) { indexRX = satBandRXComboBox->findText("10M", Qt::MatchCaseSensitive); } else { indexRX = satBandRXComboBox->findText("70CM", Qt::MatchCaseSensitive); } satBandRXComboBox->setCurrentIndex(indexRX); } //else if(dataProxy->isUHF(dataProxy->getIdFromBandName(_t))) else if ( dataProxy->getIdFromBandName("70CM") == dataProxy->getIdFromBandName(_t) ) //else { indexRX = satBandRXComboBox->findText("2M", Qt::MatchCaseSensitive); satBandRXComboBox->setCurrentIndex(indexRX); } } } void MainWindowSatTab::setBandsOfSat(const QString _p) { // Until the data is in the DB, this function tries to solve data of active sats from: http://www.amsat.org/status/ //qDebug() << "MainWindowSatTab::setBandsOfSat: " << _p << " - Short: " << _p.section(' ', 0, 0) << endl; //"AO-7 - AMSAT-OSCAT 7" //2M/10M << 2M/70CM QString upLink; upLink.clear(); upLink = dataProxy->getSatelliteUplink(_p.section(' ', 0, 0)); QString downLink; downLink.clear(); downLink = dataProxy->getSatelliteDownlink(_p.section(' ', 0, 0)); //qDebug() << "MainWindowSatTab::setBandsOfSat upLink: " << upLink << endl; emit txFreqChanged(upLink); txFreqSpinBox->setValue(upLink.toDouble()); if (upLink.toDouble()>0) { QString upLinkBand = dataProxy->getBandNameFromFreq(upLink.toDouble()); int indexTX = satBandTXComboBox->findText(upLinkBand, Qt::MatchCaseSensitive); if (indexTX>0) { satBandTXComboBox->setCurrentIndex(indexTX); } else { addNewBand(upLinkBand); indexTX = satBandTXComboBox->findText(upLinkBand, Qt::MatchCaseSensitive); satBandTXComboBox->setCurrentIndex(indexTX); } } else { satBandTXComboBox->setCurrentIndex(0); } emit rxFreqChanged(downLink); rxFreqSpinBox->setValue(downLink.toDouble()); if (downLink.toDouble()>0) { QString downLinkBand = dataProxy->getBandNameFromFreq(downLink.toDouble()); int indexRX = satBandRXComboBox->findText(downLinkBand, Qt::MatchCaseSensitive); if (indexRX>0) { satBandRXComboBox->setCurrentIndex(indexRX); } else { addNewBand(downLinkBand); indexRX = satBandRXComboBox->findText(downLinkBand, Qt::MatchCaseSensitive); satBandRXComboBox->setCurrentIndex(indexRX); } } else { satBandRXComboBox->setCurrentIndex(0); } } void MainWindowSatTab::addNewBand(const QString _p) { //qDebug() << "MainWindowSatTab::addNewBand: " << _p << endl; if (dataProxy->getIdFromBandName(_p)<0) { //qDebug() << "MainWindowSatTab::addNewBand: Id: " << QString::number(dataProxy->getIdFromBandName(_p)) << endl; return; } QStringList bands; bands.clear(); //qDebug() << "MainWindowSatTab::addNewBand: RX Id: " << QString::number(satBandRXComboBox->count()) << endl; //qDebug() << "MainWindowSatTab::addNewBand: TX Id: " << QString::number(satBandTXComboBox->count()) << endl; for (int i = 0; i < satBandTXComboBox->count(); i++) { bands << satBandTXComboBox->itemText(i); for (int ii = 0; ii < satBandRXComboBox->count(); ii++) { bands << satBandRXComboBox->itemText(ii); } } bands << _p; //bands.removeDuplicates(); emit newBandsToBeAdded(bands); //addBands(bands); //qDebug() << "MainWindowSatTab::addNewBand: 2 RX Id: " << QString::number(satBandRXComboBox->count()) << endl; //qDebug() << "MainWindowSatTab::addNewBand: 2 TX Id: " << QString::number(satBandTXComboBox->count()) << endl; } klog-0.9.2.9/dataproxy.h0000644000076700000620000002576113233376355013004 0ustar staff#ifndef DATAPROXY_H #define DATAPROXY_H /*************************************************************************** dataproxy.h - description ------------------- begin : feb 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include class DataProxy : public QObject { Q_OBJECT public: DataProxy(); // DataProxy(const QStringList _qs); ~DataProxy(); virtual QString getSoftVersion(); virtual QString getDBVersion(); virtual bool reconnectDB(); virtual void createLogModel(); virtual void createLogPanel(); virtual bool haveAtLeastOneLog(); virtual QStringList getColumnNamesFromTableLog(); //UI functions virtual int getIdFromModeName(const QString& _modeName); virtual int getIdFromBandName(const QString& _bandName); virtual int getSubModeIdFromSubMode(const QString _subModeName); virtual int getModeIdFromSubModeId(const int _sm); virtual QString getNameFromBandId (const int _id); virtual QString getNameFromModeId (const int _id); virtual QString getNameFromSubModeId (const int _id); virtual QString getSubModeFromId (const int _id); virtual QString getNameFromSubMode (const QString _sm); // Checks if a submode is deprecated //TODO: Check if really needed //virtual QString getModeFromSubMode (const QString _sm); virtual bool isModeDeprecated (const QString _sm); virtual QString getFreqFromBandId(const int _id); virtual int getBandIdFromFreq(const double _n); virtual QString getBandNameFromFreq(const double _n); virtual double getLowLimitBandFromBandName(const QString _sm); virtual double getLowLimitBandFromBandId(const QString _sm); virtual bool isThisFreqInBand(const QString b, const QString fr); virtual bool isHF(const int _band); virtual bool isWARC(const int _band); virtual bool isVHF(const int _band); virtual bool isUHF(const int _band); virtual QStringList getBands(); virtual QStringList getModes(); virtual QStringList sortBandNamesBottonUp(const QStringList _qs); virtual QStringList getBandIDs(); virtual QStringList getModesIDs(); virtual QStringList getBandsInLog(const int _log); virtual QStringList getModesInLog(const int _log); virtual int getMostUsedBand(const int _log); virtual int getMostUsedMode(const int _log); virtual int getLastQSOid(); virtual bool clearLog(); virtual bool deleteQSO(const int _qsoId); virtual int isWorkedB4(const QString _qrz, const int _currentLog); virtual bool isThisQSODuplicated(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode); virtual int getDuplicatedQSOId(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode); virtual bool isDXCCConfirmed(const int _dxcc, const int _currentLog); virtual bool isQSLReceived(const int _qsoId); virtual bool isQSLSent(const int _qsoId); virtual bool qslSentViaDirect(const int _qsoId, const QString _updateDate); virtual bool qslSentViaBureau(const int _qsoId, const QString _updateDate); virtual bool qslSentAsRequested(const int _qsoId, const QString _updateDate); virtual bool qslRecAsRequested(const int _qsoId, const QString _updateDate); virtual bool qslRecViaBureau(const int _qsoId, const QString _updateDate); virtual bool qslRecViaBureau(const int _qsoId, const QString _updateDate, const bool _queueSentQSL); virtual bool qslRecViaDirect(const int _qsoId, const QString _updateDate); virtual bool qslRecViaDirect(const int _qsoId, const QString _updateDate, const bool _queueSentQSL); virtual bool setClubLogSent(const int _qsoId, const QString _st, const QString _updateDate); virtual int getBandFromId(const int _qsoId); virtual int getModeFromId(const int _qsoId); virtual int getDXCCFromId(const int _qsoId); virtual int getCQZFromId(const int _qsoId); virtual QString getCallFromId(const int _qsoId); virtual QStringList getClubLogRealTimeFromId(const int _qsoId); // Complete with previous virtual QString getNameFromQRZ(const QString _call); virtual QString getQTHFromQRZ(const QString _call); virtual QString getLocatorFromQRZ(const QString _call); virtual QString getIOTAFromQRZ(const QString _call); virtual QString getQSLViaFromQRZ(const QString _call); // /Complete with previous virtual bool updateAwardDXCC(); virtual bool updateAwardWAZ(); virtual int getContinentIdFromContinentShortName(const QString _n); virtual QString getContinentShortNameFromEntity(const int _n); virtual int getContinentIdFromEntity(const int _n); virtual QStringList getContinentShortNames(); virtual bool isValidContinentShortName(const QString _n); virtual int getCQzFromPrefix(const QString _p); virtual int getCQzFromEntity(const int _n); virtual int getITUzFromEntity(const int _n); virtual int getITUzFromPrefix(const QString _p); virtual QString getEntityNameFromId(const int _n); virtual QString getEntityMainPrefix(const int _entityN); virtual bool isNewCQz(int _c); virtual bool isNewEntity(int _e); virtual double getLongitudeFromEntity(const int _e); virtual double getLatitudeFromEntity(const int _e); virtual int getDXCCFromPrefix(const QString _p); virtual QString getEntityPrefixes(const int _enti); virtual QStringList getEntitiesNames(); virtual int getHowManyEntities(); virtual int getMaxEntityID(); virtual QStringList getOperatingYears(const int _currentLog); virtual void compressDB(); virtual bool unMarkAllQSO(); // Unmarks all the marked QSO virtual bool lotwSentQueue(const QString _updateDate, const int _currentLog); // Mark LOTW QSL SENT as Q (Queued) virtual bool lotwSentYes(const QString _updateDate, const int _currentLog, const QString _station); // Updat LOTW QSL SENT marked as Q as Y (Queued) virtual int getQSOonYear(const int _year, const int _logNumber); virtual int getDXCConYear(const int _year, const int _logNumber); virtual int getCQzonYear(const int _year, const int _logNumber); virtual bool newDXMarathon(const int _dxcc, const int _cq, const int _year, const int _logNumber); virtual QStringList getContestNames(); virtual QStringList getContestCat(const int _catn); virtual QStringList getContestOverlays(); virtual int getContestTypeN(const int _co, const int _catop, const int _catas, const int _catpo, const int _catba, const int _catov, const int _catmo); virtual QStringList getDataFromContestType(const int _n); virtual int getLogTypeNumber(const QString _logType); // Returns the number of the type of log name virtual QString getLogTypeName(const int _logType); // Returns the name of the type of log number virtual QString getLogTypeOfUserLog(const int _logN); // Returns the type of log of a specific log virtual int getLogNumberFromQSOId(const int _qsoId); // Returns the log where the QSO id was added virtual QStringList getBandNames(); virtual QStringList getPropModeList(); virtual QStringList getSatellitesList(); virtual QString getSatelliteUplink(const QString _sat); virtual QString getSatelliteDownlink(const QString _sat); virtual QStringList getQSLRcvdList(); virtual QStringList getQSLSentList(); virtual QStringList getClubLogStatusList(); virtual QStringList getQSLViaList(); virtual QStringList getValidCatOptions(const int _currentCat, const int _lowerCa); virtual bool fillEmptyDXCCInTheLog(); virtual int getHowManyQSOInLog(const int _log); virtual int getHowManyConfirmedQSLInLog(const int _log); virtual int getNumberOfManagedLogs(); virtual int getMaxLogNumber(); virtual QStringList getListOfManagedLogs(); virtual QString getStationCallSignFromLog(const int _log); virtual QStringList getStationCallSignsFromLog(const int _log); virtual QString getOperatorsFromLog(const int _log); virtual QString getCommentsFromLog(const int _log); virtual QString getLogDateFromLog(const int _log); virtual QString getLogTypeNFromLog(const int _log); virtual bool addNewLog (const QStringList _qs); virtual bool doesThisLogExist(const int _log); virtual bool updateISONames(); // Update the entities ISO names for the flags virtual QString getISOName(const int _n); virtual void getFoundInLog(const QString _txt, const int _log=-1); virtual bool setDXCCAwardStatus(const int _qsoId); virtual bool setWAZAwardStatus(const int _qsoId); //virtual bool queryPrepare(const QString _query); //virtual bool queryBind(const QString _field, const QString value); //virtual bool queryExec(); /* virtual bool isMultiplier(const QStringList _qs); virtual int getQSOPoints(const QStringList _qs); virtual bool saveFileToSend(const QString& _fileName); virtual int getTotalScore(); virtual int getMultipliers(); virtual int getPoints(); */ private: virtual QStringList sortBandIdBottonUp(const QStringList _qs); //virtual QStringList getColumnNamesFromTable(const QString _tableName); // int points; // int multipliers; signals: void qsoFound(const QStringList _qs); // Each: QString with format: Fieldname:value }; #endif // DATAPROXY_H klog-0.9.2.9/aboutdialog.h0000644000076700000620000000411413233376355013250 0ustar staff#ifndef ABOUTDIALOG_H #define ABOUTDIALOG_H /*************************************************************************** aboutdialog.h - description ------------------- begin : feb 2017 copyright : (C) 2017 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ class QEvent; #include #include class AboutDialog : public QDialog { Q_OBJECT public: explicit AboutDialog(const QString tversion, QWidget *parent = 0); ~AboutDialog(); bool event(QEvent *event); private: QTabWidget *tabw; QWidget *tab1, *tab2, *tab3, *tab4; }; #endif // ABOUTDIALOG_H klog-0.9.2.9/infowidget.h0000644000076700000620000000662513233376355013126 0ustar staff#ifndef INFOWIDGET_H #define INFOWIDGET_H /*************************************************************************** infowidget.h - description ------------------- begin : ago 2017 copyright : (C) 2017 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implement the Info widget where the band, bearing, CQ & ITU zones.... are shown // #include #include #include "locator.h" #include "awards.h" #include "world.h" #include "dataproxy.h" #include "dataproxy_sqlite.h" class InfoWidget : public QWidget { Q_OBJECT public: InfoWidget(DataProxy *dp, QWidget *parent = 0); void createUI(); void clear(); void setCurrentLog(const int _log); void setColors (const QString _newOne, const QString _needed, const QString _worked, const QString _confirmed, const QString _default); void setImperialSystem (const bool _imp); void showInfo(const int _entity); void showDistanceAndBearing(const QString _locLocal, const QString _loc2); void showEntityInfo(const int _enti, int _cq=-1, int _itu=-1); void setLocalLocator(const QString _loc); //MAYBE NOT NEEDED void setDXLocator(const QString _loc); //MAYBE NOT NEEDED private: void clearBandLabels(); void clearInfoFromLocators(); QString getStyleColorToLabelFromBand(const QString _b, const QString _q); QLabel *bandLabel1, *bandLabel2, *bandLabel3, *bandLabel4; QLabel *bandLabel5, *bandLabel6, *bandLabel7, *bandLabel8; QLabel *bandLabel9, *bandLabel10, *bandLabel11, *bandLabel12; QLabel *continentLabel, *prefixLabel, *cqzLabel, *ituzLabel; QLabel *gradShortLabel, *distShortLabel; QLabel *gradLongLabel, *distLongLabel; QLabel *distShortLabelN; QLabel *distLongLabelN; Awards *awards; DataProxy *dataProxy; Locator *locator; World *world; int currentLog; bool imperialSystem; QString dxLocator, localLocator; }; #endif // INFOWIDGET_H klog-0.9.2.9/dataproxy_sqlite.h0000644000076700000620000002406513233376355014361 0ustar staff#ifndef DATAPROXY_SQLITE_H #define DATAPROXY_SQLITE_H /*************************************************************************** dataproxy_sqlite.h - description ------------------- begin : feb 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include //#include #include "dataproxy.h" #include "database.h" class DataProxy_SQLite : public DataProxy { Q_OBJECT public: DataProxy_SQLite(const QString _softVersion, const QString _parentFunction); ~DataProxy_SQLite(); QString getSoftVersion(); QString getDBVersion(); bool reconnectDB(); void createLogModel(); void createLogPanel(); bool haveAtLeastOneLog(); QStringList getColumnNamesFromTableLog(); int getIdFromModeName(const QString& _modeName); int getIdFromBandName(const QString& _bandName); int getSubModeIdFromSubMode(const QString _subModeName); int getModeIdFromSubModeId(const int _sm); QStringList getBands(); QStringList getModes(); QStringList sortBandNamesBottonUp(const QStringList _qs); QStringList getBandIDs(); QStringList getModesIDs(); QStringList getBandsInLog(const int _log); QStringList getModesInLog(const int _log); int getMostUsedBand(const int _log); int getMostUsedMode(const int _log); QString getNameFromBandId (const int _id); QString getNameFromModeId (const int _id); QString getNameFromSubModeId (const int _id); QString getSubModeFromId (const int _id); QString getNameFromSubMode (const QString _sm); // Checks if a submode is deprecated TODO: CHeck if really needed //QString getNameFromSubMode (const QString _sm); // DEPRECATED bool isModeDeprecated (const QString _sm); QString getFreqFromBandId(const int _id); int getBandIdFromFreq(const double _n); QString getBandNameFromFreq(const double _n); double getLowLimitBandFromBandName(const QString _sm); double getLowLimitBandFromBandId(const QString _sm); bool isThisFreqInBand(const QString b, const QString fr); int getLastQSOid(); bool deleteQSO(const int _qsoId); int isWorkedB4(const QString _qrz, const int _currentLog); bool isThisQSODuplicated(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode); int getDuplicatedQSOId(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode); bool isDXCCConfirmed(const int _dxcc, const int _currentLog); bool isQSLReceived(const int _qsoId); bool isQSLSent(const int _qsoId); bool qslSentViaDirect(const int _qsoId, const QString _updateDate); bool qslSentViaBureau(const int _qsoId, const QString _updateDate); bool qslRecViaBureau(const int _qsoId, const QString _updateDate); bool qslRecViaBureau(const int _qsoId, const QString _updateDate, const bool _queueSentQSL); bool qslRecViaDirect(const int _qsoId, const QString _updateDate); bool qslRecViaDirect(const int _qsoId, const QString _updateDate, const bool _queueSentQSL); bool qslSentAsRequested(const int _qsoId, const QString _updateDate); bool qslRecAsRequested(const int _qsoId, const QString _updateDate); bool setClubLogSent(const int _qsoId, const QString _st, const QString _updateDate); bool isHF(const int _band); bool isWARC(const int _band); bool isVHF(const int _band); bool isUHF(const int _band); int getBandFromId(const int _qsoId); int getModeFromId(const int _qsoId); int getDXCCFromId(const int _qsoId); int getCQZFromId(const int _qsoId); QString getCallFromId(const int _qsoId); QStringList getClubLogRealTimeFromId(const int _qsoId); // Complete with previous QString getNameFromQRZ(const QString _call); QString getQTHFromQRZ(const QString _call); QString getLocatorFromQRZ(const QString _call); QString getIOTAFromQRZ(const QString _call); QString getQSLViaFromQRZ(const QString _call); // /Complete with previous bool updateAwardDXCC(); bool updateAwardWAZ(); //LOTW int getContinentIdFromContinentShortName(const QString _n); QString getContinentShortNameFromEntity(const int _n); int getContinentIdFromEntity(const int _n); QStringList getContinentShortNames(); bool isValidContinentShortName(const QString _n); int getCQzFromPrefix(const QString _p); int getCQzFromEntity(const int _n); int getITUzFromEntity(const int _n); int getITUzFromPrefix(const QString _p); QString getEntityNameFromId(const int _n); QString getEntityMainPrefix(const int _entityN); bool isNewCQz(int _c); bool isNewEntity(int _e); double getLongitudeFromEntity(const int _e); double getLatitudeFromEntity(const int _e); int getDXCCFromPrefix(const QString _p); QString getEntityPrefixes(const int _enti); QStringList getEntitiesNames(); int getHowManyEntities(); int getMaxEntityID(); QStringList getOperatingYears(const int _currentLog); void compressDB(); bool unMarkAllQSO(); // Unmarks all the marked QSO bool lotwSentQueue(const QString _updateDate, const int _currentLog); // Mark LOTW QSL SENT as Q (Queued) bool lotwSentYes(const QString _updateDate, const int _currentLog, const QString _station); // Update LOTW QSL SENT marked as Q as Y (Queued) bool clearLog(); int getQSOonYear(const int _year, const int _logNumber); int getDXCConYear(const int _year, const int _logNumber); int getCQzonYear(const int _year, const int _logNumber); bool newDXMarathon(const int _dxcc, const int _cq, const int _year, const int _logNumber); QStringList getContestNames(); QStringList getContestCat(const int _catn); QStringList getContestOverlays(); int getContestTypeN(const int _co, const int _catop, const int _catas, const int _catpo, const int _catba, const int _catov, const int _catmo); QStringList getDataFromContestType(const int _n); int getLogTypeNumber(const QString _logType); QString getLogTypeName(const int _logType); QString getLogTypeOfUserLog(const int _logN); int getLogNumberFromQSOId(const int _qsoId); QStringList getBandNames(); QStringList getPropModeList(); QStringList getSatellitesList(); QString getSatelliteUplink(const QString _sat); QString getSatelliteDownlink(const QString _sat); QStringList getQSLRcvdList(); QStringList getQSLSentList(); QStringList getClubLogStatusList(); QStringList getQSLViaList(); QStringList getValidCatOptions(const int _currentCat, const int _lowerCa); bool fillEmptyDXCCInTheLog(); int getHowManyQSOInLog(const int _log); int getHowManyConfirmedQSLInLog(const int _log); int getNumberOfManagedLogs(); QStringList getListOfManagedLogs(); int getMaxLogNumber(); QString getStationCallSignFromLog(const int _log); QStringList getStationCallSignsFromLog(const int _log); QString getOperatorsFromLog(const int _log); QString getCommentsFromLog(const int _log); QString getLogDateFromLog(const int _log); QString getLogTypeNFromLog(const int _log); bool addNewLog (const QStringList _qs); bool doesThisLogExist(const int _log); bool updateISONames(); // Update the entities ISO names for the flags QString getISOName(const int _n); bool setDXCCAwardStatus(const int _qsoId); bool setWAZAwardStatus(const int _qsoId); void getFoundInLog(const QString _txt, const int _log=-1); //bool queryPrepare(const QString _query); //bool queryBind(const QString _field, const QString value); //bool queryExec(); private: bool dbCreated; DataBase *db; QStringList sortBandIdBottonUp(const QStringList _qs); double getFreqFromRange(QString _fr); //May even receive: 145.900-146.00 and should return the mid in the range (145.950) QStringList getColumnNamesFromTable(const QString _tableName); int getPrefixId(const QString _qrz); QString changeSlashAndFindPrefix(const QString _qrz); bool searching; int executionN; Utilities *util; //QSqlQuery preparedQuery; //QSqlRelationalTableModel *logModel; signals: void qsoFound(const QStringList _qs); // Each: QString with format: Fieldname:value void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution }; #endif // DATAPROXY_SQLITE_H klog-0.9.2.9/setuppagelogsnew.cpp0000644000076700000620000010064113233376355014707 0ustar staff/*************************************************************************** setuppagelogsnew.h - description ------------------- begin : feb 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implements the Dialog to add a new log // #include "setuppagelogsnew.h" SetupPageLogsNew::SetupPageLogsNew(DataProxy *dp, QWidget *parent) { //qDebug() << "SetupPageLogsNew::SetupPageLogsNew" << endl; dataProxy = dp; editing = false; checking = false; bCass = false; bCOp = false; bCMo = false; bCPo = false; bCBa = false; bCOv = false; bCTy = false; logData.clear(); stationCallsignFilled = false; operatorsFilled = true; stationCallsign = QString(); operators = QString(); comment = QString(); dateString = QString(); typeContest = 0; contestCatMode = 0; contestCatOperators = 0; contestCatAssisted = 0; contestCatPower = 0; contestCatBands = 0; contestBands = 0; contestCatOverlay = 0; typeContestSelected = 0; typeConteststr = QString(); stationCallsignLineEdit = new QLineEdit; operatorsLineEdit = new QLineEdit; dateEdit = new QDateEdit; dateEdit->setDate(QDate::currentDate ()); commentLineEdit = new QLineEdit; typeComboBox = new QComboBox; contestCatModeComboBox = new QComboBox; contestCatOperatorsComboBox = new QComboBox; contestCatAssistedComboBox = new QComboBox; contestCatPowerComboBox = new QComboBox; contestCatBandsComboBox = new QComboBox; contestBandsComboBox = new QComboBox; contestCatOverlayComboBox = new QComboBox; contestCatModeComboBox = new QComboBox; catAsLabel = new QLabel(); typeLabel = new QLabel(); catOpLabel = new QLabel(); catModeLabel = new QLabel(); catPowerLabel = new QLabel(); catBandsLabel = new QLabel(); overlayLabel = new QLabel(); validCats = new QLabel(); dateLabel = new QLabel(tr("&Date")); stationCallsignLabel = new QLabel(tr("&Station Callsign")); operatorsLabel = new QLabel(tr("&Operators")); commentLabel = new QLabel(tr("Comm&ent")); okButton = new QPushButton(tr("&Ok"), this); cancelButton = new QPushButton(tr("&Cancel"), this); createWidget(); okButton->setEnabled(false); //qDebug() << "SetupPageLogsNew::SetupPageLogsNew - END" << endl; } void SetupPageLogsNew::clear() { stationCallsignLineEdit->clear(); operatorsLineEdit->clear(); dateEdit->setDate(QDate::currentDate ()); typeComboBox->setCurrentIndex(0); contestCatModeComboBox->setCurrentIndex(0); contestCatOperatorsComboBox->setCurrentIndex(0); contestCatAssistedComboBox->setCurrentIndex(0); contestCatPowerComboBox->setCurrentIndex(0); contestCatBandsComboBox->setCurrentIndex(0); contestBandsComboBox->setCurrentIndex(0); contestCatOverlayComboBox->setCurrentIndex(0); contestCatModeComboBox->setCurrentIndex(0); typeContest = 0; contestCatMode = 0; contestCatOperators = 0; contestCatAssisted = 0; contestCatPower = 0; contestCatBands = 0; contestBands = 0; contestCatOverlay = 0; typeContestSelected = 0; } void SetupPageLogsNew::createWidget() { //qDebug() << "SetupPageLogsNew::createWidget" << endl; stationCallsignLabel->setWordWrap(true); operatorsLabel->setWordWrap(true); commentLabel->setWordWrap(true); dateLabel->setBuddy(dateEdit); stationCallsignLabel->setBuddy(stationCallsignLineEdit); operatorsLabel->setBuddy(operatorsLineEdit); commentLabel->setBuddy(commentLineEdit); catAsLabel->setBuddy(contestCatAssistedComboBox); typeLabel->setBuddy(typeComboBox); catOpLabel->setBuddy(contestCatOperatorsComboBox); catModeLabel->setBuddy(contestCatModeComboBox); catPowerLabel->setBuddy(contestCatPowerComboBox); catBandsLabel->setBuddy(contestCatBandsComboBox); overlayLabel->setBuddy(contestCatOverlayComboBox); validCats->setText(tr("Select categories")); validCats->setWordWrap(true); stationCallsignLineEdit->setToolTip(tr("Callsign used for this log")); operatorsLineEdit->setToolTip(tr("Comma separated list of operators: callsign1, callsign2")); dateEdit->setToolTip(tr("Start date of this log")); commentLineEdit->setToolTip(tr("Add a comment about this log")); typeLabel->setText(tr("&Type of Operation")); typeLabel->setWordWrap(true); //nameLabel->setWordWrap(true); dateLabel->setWordWrap(true); typeComboBox->setToolTip(tr("Select the kind of operation for this log")); QStringList _qs; _qs.clear(); _qs.append(dataProxy->getContestNames()); typeComboBox->addItems(_qs); //qDebug() << "SetupPageLogsNew::createWidget - contestNames: " << _qs.at(0) << endl; catModeLabel->setText(tr("&Mode Category")); catModeLabel->setWordWrap(true); contestCatModeComboBox->setToolTip(tr("Select the mode category")); _qs.clear(); _qs.append(dataProxy->getContestCat(6)); contestCatModeComboBox->addItems(_qs); //QLabel *catOpLabel = new QLabel(tr("Operators Category")); catOpLabel->setText(tr("O&perators Category")); catOpLabel->setWordWrap(true); contestCatOperatorsComboBox->setToolTip(tr("Select the operators category")); _qs.clear(); _qs.append(dataProxy->getContestCat(1)); contestCatOperatorsComboBox->addItems(_qs); catAsLabel->setText(tr("&Assisted Category")); catOpLabel->setWordWrap(true); contestCatAssistedComboBox->setToolTip(tr("Select the assisted category")); _qs.clear(); _qs.append(dataProxy->getContestCat(2)); contestCatAssistedComboBox->addItems(_qs); //QLabel *catPowerLabel = new QLabel(tr("Power Category")); catPowerLabel->setText(tr("Po&wer Category")); catPowerLabel->setWordWrap(true); contestCatPowerComboBox->setToolTip(tr("Select the power category")); _qs.clear(); _qs.append(dataProxy->getContestCat(3)); contestCatPowerComboBox->addItems(_qs); //QLabel *catBandsLabel = new QLabel(tr("Bands Category")); catBandsLabel->setText(tr("&Bands Category")); catBandsLabel->setWordWrap(true); contestCatBandsComboBox->setToolTip(tr("Select the bands category")); _qs.clear(); _qs.append(dataProxy->getContestCat(4)); contestCatBandsComboBox->addItems(_qs); overlayLabel->setText(tr("O&verlay")); overlayLabel->setWordWrap(true); contestCatOverlayComboBox->setToolTip(tr("Select the Overlay category")); _qs.clear(); _qs.append(dataProxy->getContestOverlays()); contestCatOverlayComboBox->addItems(_qs); connect(stationCallsignLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotStationCallSignTextChanged() ) ); connect(operatorsLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotOperatorsTextChanged() ) ); connect(typeComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotTypeComboBoxChanged() ) ) ; connect(contestCatModeComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatModeComboBoxChanged() ) ) ; connect(contestCatAssistedComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatAssistedComboBoxChanged() ) ) ; connect(contestCatOperatorsComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatOperatorsComboBoxChanged() ) ) ; connect(contestCatPowerComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatPowerComboBoxChanged() ) ) ; connect(contestCatBandsComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatBandsComboBoxChanged() ) ) ; connect(contestCatOverlayComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatOverlayComboBoxChanged() ) ) ; //connect(typeComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotTypeComboBoxChanged() ) ) ; //connect(contestCatModeComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatModeComboBoxChanged() ) ) ; //connect(contestCatAssistedComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatAssistedComboBoxChanged() ) ) ; //connect(contestCatOperatorsComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatOperatorsComboBoxChanged() ) ) ; //connect(contestCatPowerComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatPowerComboBoxChanged() ) ) ; //connect(contestCatBandsComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatBandsComboBoxChanged() ) ) ; //connect(contestCatOverlayComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatOverlayComboBoxChanged() ) ) ; connect(contestBandsComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotBandsComboBoxChanged() ) ) ; //connect(contestCatModeComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatModeComboBoxChanged() ) ) ; connect(okButton,SIGNAL(clicked()), this, SLOT(slotOKButtonClicked() ) ); connect(cancelButton, SIGNAL(clicked()), this, SLOT(slotCancelButtonClicked() ) ); QGridLayout *callsLayout = new QGridLayout; // Widget, row, column callsLayout->addWidget(stationCallsignLabel, 0, 0); callsLayout->addWidget(stationCallsignLineEdit, 0, 1); callsLayout->addWidget(dateLabel, 1, 0); callsLayout->addWidget(dateEdit, 1, 1); callsLayout->addWidget(operatorsLabel, 2, 0); callsLayout->addWidget(operatorsLineEdit, 2, 1); callsLayout->addWidget(commentLabel, 3, 0); callsLayout->addWidget(commentLineEdit, 3, 1); /* callsLayout->addWidget(typeLabel, 3, 0); callsLayout->addWidget(typeComboBox, 3, 1); callsLayout->addWidget(catModeLabel, 4, 0); callsLayout->addWidget(contestCatModeComboBox, 4, 1); callsLayout->addWidget(catOpLabel, 5, 0); callsLayout->addWidget(contestCatOperatorsComboBox, 5, 1); callsLayout->addWidget(catAsLabel, 6, 0); callsLayout->addWidget(contestCatAssistedComboBox, 6, 1); callsLayout->addWidget(catPowerLabel, 7, 0); callsLayout->addWidget(contestCatPowerComboBox, 7, 1); callsLayout->addWidget(catBandsLabel, 8, 0); callsLayout->addWidget(contestCatBandsComboBox, 8, 1); callsLayout->addWidget(contestBandsComboBox, 8, 2); callsLayout->addWidget(overlayLabel, 10, 0); callsLayout->addWidget(contestCatOverlayComboBox, 10, 1); */ QHBoxLayout *buttonsLayout = new QHBoxLayout; //buttonsLayout->addWidget(validCats); buttonsLayout->addSpacerItem(new QSpacerItem(10,0,QSizePolicy::Expanding,QSizePolicy::Maximum)); buttonsLayout->addWidget(okButton); buttonsLayout->addWidget(cancelButton); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(callsLayout); mainLayout->addLayout(buttonsLayout); setLayout(mainLayout); clear(); //page->setLayout(callsLayout); } void SetupPageLogsNew::slotOperatorsTextChanged() { //qDebug() << "SetupPageLogsNew::slotOperatorsTextChanged" << endl; // connect(stationCallsignLineEdit, SIGNAL(textChanged(QString)), this, SLOT( ) ); if ((operatorsLineEdit->text()).length()<1) { return; } int cursorP = operatorsLineEdit->cursorPosition(); QString currentQrz = operatorsLineEdit->text(); if ((currentQrz.at(cursorP-1)).isSpace()) { currentQrz = currentQrz.remove(cursorP-1, 1); cursorP--; operatorsLineEdit->setText(currentQrz); } operatorsLineEdit->setText(((operatorsLineEdit->text())).simplified()); operatorsLineEdit->setText((operatorsLineEdit->text()).toUpper()); operatorsLineEdit->setCursorPosition(cursorP); if (currentQrz.length()>=3) {//TODO: Add a check of the format (comma separated) operatorsFilled= true; } } void SetupPageLogsNew::slotStationCallSignTextChanged() { //qDebug() << "SetupPageLogsNew::slotStationCallSignTextChanged" << endl; // connect(stationCallsignLineEdit, SIGNAL(textChanged(QString)), this, SLOT( ) ); if ((stationCallsignLineEdit->text()).length()<1) { showNOK(); return; } int cursorP = stationCallsignLineEdit->cursorPosition(); QString currentQrz = stationCallsignLineEdit->text(); if ((currentQrz.at(cursorP-1)).isSpace()) { currentQrz = currentQrz.remove(cursorP-1, 1); cursorP--; stationCallsignLineEdit->setText(currentQrz); } stationCallsignLineEdit->setText(((stationCallsignLineEdit->text())).simplified()); stationCallsignLineEdit->setText((stationCallsignLineEdit->text()).toUpper()); stationCallsignLineEdit->setCursorPosition(cursorP); if (currentQrz.length()>=3) { stationCallsignFilled = true; } showOK(); } void SetupPageLogsNew::slotTypeComboBoxChanged() { //qDebug() << "SetupPageLogsNew::slotTypeComboBoxChanged" << endl; // connect(typeComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotTypeComboBoxChanged() ) ) ; contestCatMode = contestCatModeComboBox->currentIndex(); contestCatBands = contestCatBandsComboBox->currentIndex(); contestCatPower = contestCatPowerComboBox->currentIndex(); contestCatOperators = contestCatOperatorsComboBox->currentIndex(); contestCatAssisted = contestCatAssistedComboBox->currentIndex(); typeContestSelected = typeComboBox->currentIndex(); contestCatOverlay= contestCatOverlayComboBox->currentIndex(); typeContest = getSelectedTypeContest(); if (typeContest < 0) { typeLabel->setStyleSheet("QLabel {color : red; }"); validCats->setText(tr("Categories not OK")); validCats->setStyleSheet("QLabel {color : red; }"); okButton->setEnabled(false); } else { typeLabel->setStyleSheet("QLabel {color : black; }"); showOK(); } } void SetupPageLogsNew::slotCatAssistedComboBoxChanged() { //qDebug() << "SetupPageLogs:slotCatAssistedComboBoxChanged: " << QString::number(contestCatAssistedComboBox->currentIndex()) << endl; //connect(contestCatAssistedComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatAssistedComboBoxChanged() ) ) ; contestCatMode = contestCatModeComboBox->currentIndex(); contestCatBands = contestCatBandsComboBox->currentIndex(); contestCatPower = contestCatPowerComboBox->currentIndex(); contestCatOperators = contestCatOperatorsComboBox->currentIndex(); contestCatAssisted = contestCatAssistedComboBox->currentIndex(); typeContestSelected = typeComboBox->currentIndex(); contestCatOverlay= contestCatOverlayComboBox->currentIndex(); typeContest = getSelectedTypeContest(); if (typeContest < 0) { catAsLabel->setStyleSheet("QLabel {color : red; }"); showNOK(); } else { catAsLabel->setStyleSheet("QLabel {color : black; }"); showOK(); } } void SetupPageLogsNew::slotCatOperatorsComboBoxChanged() { //qDebug() << "SetupPageLogsNew::slotCatOperatorsComboBoxChanged(): " << QString::number(contestCatOperatorsComboBox->currentIndex()) << endl; contestCatMode = contestCatModeComboBox->currentIndex(); contestCatBands = contestCatBandsComboBox->currentIndex(); contestCatPower = contestCatPowerComboBox->currentIndex(); contestCatOperators = contestCatOperatorsComboBox->currentIndex(); contestCatAssisted = contestCatAssistedComboBox->currentIndex(); typeContestSelected = typeComboBox->currentIndex(); contestCatOverlay= contestCatOverlayComboBox->currentIndex(); typeContest = getSelectedTypeContest(); if (typeContest < 0) { catOpLabel->setStyleSheet("QLabel {color : red; }"); showNOK(); } else { catOpLabel->setStyleSheet("QLabel {color : black; }"); showOK(); } } void SetupPageLogsNew::slotCatPowerComboBoxChanged() { //qDebug() << "SetupPageLogsNew::slotCatPowerComboBoxChanged(): " << QString::number(contestCatPowerComboBox->currentIndex()) << endl; //connect(contestCatPowerComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatPowerComboBoxChanged() ) ) ; contestCatMode = contestCatModeComboBox->currentIndex(); contestCatBands = contestCatBandsComboBox->currentIndex(); contestCatPower = contestCatPowerComboBox->currentIndex(); contestCatOperators = contestCatOperatorsComboBox->currentIndex(); contestCatAssisted = contestCatAssistedComboBox->currentIndex(); typeContestSelected = typeComboBox->currentIndex(); contestCatOverlay= contestCatOverlayComboBox->currentIndex(); typeContest = getSelectedTypeContest(); if (typeContest < 0) { catPowerLabel->setStyleSheet("QLabel {color : red; }"); showNOK(); } else { catPowerLabel->setStyleSheet("QLabel {color : black; }"); showOK(); } } void SetupPageLogsNew::slotCatBandsComboBoxChanged() { //qDebug() << "SetupPageLogsNew::slotCatBandsComboBoxChanged(): " << QString::number(contestCatBandsComboBox->currentIndex()) << endl; //connect(contestCatBandsComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotCatBandsComboBoxChanged() ) ) ; contestCatMode = contestCatModeComboBox->currentIndex(); contestCatBands = contestCatBandsComboBox->currentIndex(); contestCatPower = contestCatPowerComboBox->currentIndex(); contestCatOperators = contestCatOperatorsComboBox->currentIndex(); contestCatAssisted = contestCatAssistedComboBox->currentIndex(); typeContestSelected = typeComboBox->currentIndex(); contestCatOverlay= contestCatOverlayComboBox->currentIndex(); typeContest = getSelectedTypeContest(); if (typeContest < 0) { catBandsLabel->setStyleSheet("QLabel {color : red; }"); showNOK(); } else { catBandsLabel->setStyleSheet("QLabel {color : black; }"); showOK(); } } void SetupPageLogsNew::slotBandsComboBoxChanged() { //qDebug() << "SetupPageLogsNew::slotBandsComboBoxChanged(): " << QString::number(contestBandsComboBox->currentIndex()) << endl; //connect(contestBandsComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotBandsComboBoxChanged() ) ) ; } void SetupPageLogsNew::slotCatOverlayComboBoxChanged() { //qDebug() << "SetupPageLogsNew::slotCatOverlayComboBoxChanged(): " << QString::number(contestCatOverlayComboBox->currentIndex()) << endl; contestCatMode = contestCatModeComboBox->currentIndex(); contestCatBands = contestCatBandsComboBox->currentIndex(); contestCatPower = contestCatPowerComboBox->currentIndex(); contestCatOperators = contestCatOperatorsComboBox->currentIndex(); contestCatAssisted = contestCatAssistedComboBox->currentIndex(); typeContestSelected = typeComboBox->currentIndex(); contestCatOverlay= contestCatOverlayComboBox->currentIndex(); typeContest = getSelectedTypeContest(); //qDebug() << "SetupPageLogsNew::slotCatOverlayComboBoxChanged(): typeContest = " << QString::number(typeContest) << endl; if (typeContest < 0) { overlayLabel->setStyleSheet("QLabel {color : red; }"); showNOK(); } else { overlayLabel->setStyleSheet("QLabel {color : black; }"); showOK(); } } void SetupPageLogsNew::slotCatModeComboBoxChanged() { //qDebug() << "SetupPageLogsNew::slotCatModeComboBoxChanged(): " << QString::number(contestCatModeComboBox->currentIndex()) << endl; contestCatMode = contestCatModeComboBox->currentIndex(); contestCatBands = contestCatBandsComboBox->currentIndex(); contestCatPower = contestCatPowerComboBox->currentIndex(); contestCatOperators = contestCatOperatorsComboBox->currentIndex(); contestCatAssisted = contestCatAssistedComboBox->currentIndex(); typeContestSelected = typeComboBox->currentIndex(); contestCatOverlay= contestCatOverlayComboBox->currentIndex(); typeContest = getSelectedTypeContest(); //qDebug() << "SetupPageLogsNew::slotCatModeComboBoxChanged(): " << QString::number(typeContest) << endl; if (typeContest < 0) { catModeLabel->setStyleSheet("QLabel {color : red; }"); showNOK(); } else { catModeLabel->setStyleSheet("QLabel {color : black; }"); showOK(); } } void SetupPageLogsNew::slotOKButtonClicked() { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked" << endl; stationCallsign = stationCallsignLineEdit->text(); if (stationCallsign.length()<3) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("You need to enter a valid QRZ in the Station Callsign box.\nThe log will not be opened.")); msgBox.exec(); return; } operators = operatorsLineEdit->text(); //TODO: Check if operators is really including a comma separated list of QRZ comment = commentLineEdit->text(); dateString = dateEdit->date().toString("yyyy/MM/dd"); //typeContest, contestCatOperators, contestCatAssisted, contestCatPower, //contestCatBands, contestCatOverlay, contestCatMode if (typeComboBox->isEnabled()) { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked ENA: type" << endl; typeContestSelected = typeComboBox->currentIndex(); typeConteststr = typeComboBox->currentText(); } else { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked NOT ENA: type" << endl; typeContestSelected = 0; typeConteststr = QString(); } if (contestCatModeComboBox->isEnabled()) { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked ENA: mode" << endl; contestCatMode = contestCatModeComboBox->currentIndex(); } else { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked NOT ENA: mode" << endl; contestCatMode = 0; } if (contestCatOperatorsComboBox->isEnabled()) { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked ENA: oper" << endl; contestCatOperators = contestCatOperatorsComboBox->currentIndex(); } else { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked NOT ENA: oper" << endl; contestCatOperators = 0; } if (contestCatAssistedComboBox->isEnabled()) { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked ENA: ass" << endl; contestCatAssisted = contestCatAssistedComboBox->currentIndex(); } else { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked NOT ENA: ass" << endl; contestCatAssisted = 0; } if (contestCatPowerComboBox->isEnabled()) { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked ENA: pwr" << endl; contestCatPower = contestCatPowerComboBox->currentIndex(); //qDebug() << "SetupPageLogsNew::slotOkButtonClicked ENA: pwr - " << contestCatPowerComboBox->currentText() << endl; } else { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked NOT ENA: pwr" << endl; contestCatPower = 0; } if (contestCatBandsComboBox->isEnabled()) { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked ENA: Cbands" << endl; contestCatBands = contestCatBandsComboBox->currentIndex(); } else { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked NOT ENA: Cbands" << endl; contestCatBands = 0; } if (contestBandsComboBox->isEnabled()) { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked ENA: bands" << endl; contestBands = contestBandsComboBox->currentIndex(); } else { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked NOT ENA: bands" << endl; contestBands = 0; } if (contestCatOverlayComboBox->isEnabled()) { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked ENA: over" << endl; contestCatOverlay = contestCatOverlayComboBox->currentIndex(); } else { //qDebug() << "SetupPageLogsNew::slotOkButtonClicked NOT ENA: over" << endl; contestCatOverlay = 0; } //typeContest, contestCatOperators, contestCatAssisted, contestCatPower, //contestCatBands, contestCatOverlay, contestCatMode typeContest = getSelectedTypeContest(); if (typeContest < 0) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("You selected an invalid combination.\nThe log will not be opened.")); msgBox.exec(); } else { gatherAndSend(); close(); } } void SetupPageLogsNew::gatherAndSend() { //qDebug() << "SetupPageLogsNew::gatherAndSend: " << typeConteststr << endl; // The following lines will be removed once more contest types have been added contestCatMode = contestCatModeComboBox->currentIndex(); contestCatBands = contestCatBandsComboBox->currentIndex(); contestCatPower = contestCatPowerComboBox->currentIndex(); contestCatOperators = contestCatOperatorsComboBox->currentIndex(); contestCatAssisted = contestCatAssistedComboBox->currentIndex(); typeContestSelected = typeComboBox->currentIndex(); contestCatOverlay = contestCatOverlayComboBox->currentIndex(); typeContest = getSelectedTypeContest(); // The previous lines will be removed once more contest types have been added logData.clear(); logData << stationCallsign << operators << comment << dateString << typeConteststr << QString::number(contestCatMode) << QString::number(contestCatOperators) << QString::number(contestCatAssisted) << QString::number(contestCatPower) << QString::number(contestCatBands) << QString::number(contestBands) << QString::number(contestCatOverlay) << QString::number(typeContest); if (editing) { logData << "1"; editing = false; } else { logData << "0"; } //logData << QString::number(typeContest) // Update the SetupPageLogs::slotAnalyzeNewLogData if you add or remove any field (Today 12) //for (int i=0;igetValidCatOptions(_currentCat, _higherCat); return QStringList(); } void SetupPageLogsNew::setStationCallSign(const QString _st) { stationCallsign = _st; stationCallsignLineEdit->setText(stationCallsign.toUpper()); } void SetupPageLogsNew::setOperators(const QString _st) { operators = _st; operatorsLineEdit->setText(operators.toUpper()); } void SetupPageLogsNew::setComment(const QString _st) { comment = _st; commentLineEdit->setText(comment.toUpper()); } void SetupPageLogsNew::setDateString(const QString _st) { dateString = _st; dateEdit->setDate(QDate::fromString(dateString, "yyyy/MM/dd")); } void SetupPageLogsNew::setType(const QString _st) { typeConteststr = _st; //typeConteststr = typeComboBox->currentText(); typeComboBox->setCurrentIndex(typeComboBox->findText(typeConteststr, Qt::MatchExactly)); //findText ( const QString & text, Qt::MatchFlags flags = static_cast ( Qt::MatchExactly | Qt::MatchCaseSensitive ) ) const } void SetupPageLogsNew::setCMode(const int _n) { contestCatMode = _n; contestCatModeComboBox->setCurrentIndex(contestCatMode); } void SetupPageLogsNew::setCOperators(const int _n) { contestCatOperators = _n; contestCatOperatorsComboBox->setCurrentIndex(contestCatOperators); } void SetupPageLogsNew::setCAssisted(const int _n) { contestCatAssisted = _n; contestCatAssistedComboBox->setCurrentIndex(contestCatAssisted); } void SetupPageLogsNew::setCPower(const int _n) { contestCatPower = _n; contestCatPowerComboBox->setCurrentIndex(contestCatPower); } void SetupPageLogsNew::setCBands(const int _n) { contestCatBands = _n; contestCatBandsComboBox->setCurrentIndex(contestCatBands); } void SetupPageLogsNew::setBands(const int _n) { contestBands = _n; contestBandsComboBox->setCurrentIndex(contestBands); } void SetupPageLogsNew::setCOverlay(const int _n) { contestCatOverlay = _n; contestCatOverlayComboBox->setCurrentIndex(contestCatOverlay); } void SetupPageLogsNew::setEditing(const bool b) { editing = b; if (!editing) { clear(); } } int SetupPageLogsNew::getSelectedTypeContest() { //qDebug() << "SetupPageLogsNew::getSelectedTypeContest: " << endl; //is/contest/catoperator/catassisted/catpower/catband/catoverlay/catmode int i = dataProxy->getContestTypeN(typeContestSelected, contestCatOperators, contestCatAssisted, contestCatPower, contestCatBands, contestCatOverlay, contestCatMode); //qDebug() << "SetupPageLogsNew::getSelectedTypeContest: " << QString::number(i) << endl; return i; } void SetupPageLogsNew::setTypeN(const int _n) { //qDebug() << "SetupPageLogsNew::setTypeN: " << QString::number(_n) << endl; typeContestSelected = _n; fillWithType(typeContestSelected); } void SetupPageLogsNew::fillWithType(const int _n) { //qDebug() << "SetupPageLogsNew::fillWithType - n = " << QString::number(_n) << endl; typeContestSelected = _n; QStringList contestData; contestData << dataProxy->getDataFromContestType(_n); //qDebug() << "SetupPageLogsNew::fillWithType-1 (length = " << QString::number(contestData.length()) << ")" << endl; if (contestData.length()== 8) { //qDebug() << "SetupPageLogsNew::fillWithType-2" << endl; setCOperators ((contestData.at(1)).toInt()); setCAssisted ((contestData.at(2)).toInt()); setCPower ((contestData.at(3)).toInt()); setCOverlay ((contestData.at(4)).toInt()); setCMode ((contestData.at(5)).toInt()); setType(contestData.at(6)); setCBands((contestData.at(7)).toInt()); //qDebug() << "SetupPageLogsNew::fillWithType: " << contestData.at(6) << endl; } else { //qDebug() << "SetupPageLogsNew::fillWithType-3" << endl; return; } } void SetupPageLogsNew::updateAllCats() { //qDebug() << "SetupPageLogsNew::updateAllCats" << endl; contestCatMode = contestCatModeComboBox->currentIndex(); contestCatBands = contestCatBandsComboBox->currentIndex(); contestCatPower = contestCatPowerComboBox->currentIndex(); contestCatOperators = contestCatOperatorsComboBox->currentIndex(); contestCatAssisted = contestCatAssistedComboBox->currentIndex(); typeContestSelected = typeComboBox->currentIndex(); contestCatOverlay= contestCatOverlayComboBox->currentIndex(); typeContest = getSelectedTypeContest(); } void SetupPageLogsNew::showOK() { validCats->setText(tr("Categories OK")); validCats->setStyleSheet("QLabel {color : black; }"); okButton->setEnabled(true); } void SetupPageLogsNew::showNOK() { validCats->setText(tr("Categories not OK")); validCats->setStyleSheet("QLabel {color : red; }"); okButton->setEnabled(false); } klog-0.9.2.9/mainwindowinputeqsl.cpp0000644000076700000620000004034013233376355015433 0ustar staff#include "mainwindowinputeqsl.h" MainWindowInputEQSL::MainWindowInputEQSL(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "MainWindowInputEQSL::MainWindowInputEQSL" << endl; util = new Utilities; qslSentStatusList.clear(); qslRcvdStatusList.clear(); clubLogStatusList.clear(); dataProxy = dp; qslSentStatusList = dataProxy->getQSLSentList(); qslRcvdStatusList = dataProxy->getQSLRcvdList(); clubLogStatusList = dataProxy->getClubLogStatusList(); eqslSentComboBox = new QComboBox; eqslRecComboBox = new QComboBox; lotwSentComboBox = new QComboBox; lotwRecComboBox = new QComboBox; clublogComboBox = new QComboBox; eqslSentQDateEdit = new QDateEdit; eqslRecQDateEdit = new QDateEdit; lotwSentQDateEdit = new QDateEdit; lotwRecQDateEdit = new QDateEdit; clublogQDateEdit = new QDateEdit; eqslSentQDateEdit->setDisplayFormat("dd/MM/yyyy"); eqslRecQDateEdit->setDisplayFormat("dd/MM/yyyy"); lotwSentQDateEdit->setDisplayFormat("dd/MM/yyyy"); lotwRecQDateEdit->setDisplayFormat("dd/MM/yyyy"); clublogQDateEdit->setDisplayFormat("dd/MM/yyyy"); createUI(); setDefaultData(); clear(); //qDebug() << "MainWindowInputEQSL::MainWindowInputEQSL - END" << endl; } void MainWindowInputEQSL::createUI() { clublogQDateEdit->setToolTip(tr("Date of the ClubLog upload.")); eqslSentQDateEdit->setToolTip(tr("Date of the eQSL sending.")); eqslRecQDateEdit->setToolTip(tr("Date of the eQSL reception.")); lotwSentQDateEdit->setToolTip(tr("Date of the LoTW sending.")); lotwRecQDateEdit->setToolTip(tr("Date of the LoTW reception.")); clublogComboBox->setToolTip(tr("Status on ClubLog.")); eqslSentComboBox->setToolTip(tr("Status of the eQSL sending.")); eqslRecComboBox->setToolTip(tr("Status of the eQSL reception.")); lotwSentComboBox->setToolTip(tr("Status of the LoTW sending.")); lotwRecComboBox->setToolTip(tr("Status of the LoTW reception.")); // eQSL Tab definition starts here QLabel *clublogLabelN = new QLabel(tr("ClubLog")); clublogLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *eQSLSentLabelN = new QLabel(tr("eQSL Sent")); eQSLSentLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *eQSLRecLabelN = new QLabel(tr("eQSL Rec")); eQSLRecLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *lotWSentLabelN = new QLabel(tr("LoTW Sent")); lotWSentLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *lotWRecLabelN = new QLabel(tr("LoTW Rec")); lotWRecLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); /* QHBoxLayout *eqslSentLayout = new QHBoxLayout; eqslSentLayout->addWidget(eqslSentComboBox); eqslSentLayout->addWidget(eqslSentQDateEdit); QHBoxLayout *eqslRecLayout = new QHBoxLayout; eqslRecLayout->addWidget(eqslRecComboBox); eqslRecLayout->addWidget(eqslRecQDateEdit); QHBoxLayout *lotwSentLayout = new QHBoxLayout; lotwSentLayout->addWidget(lotwSentComboBox); lotwSentLayout->addWidget(lotwSentQDateEdit); QHBoxLayout *lotwRecLayout = new QHBoxLayout; lotwRecLayout->addWidget(lotwRecComboBox); lotwRecLayout->addWidget(lotwRecQDateEdit); QFormLayout *eqslInputTabWidgetLayout = new QFormLayout; eqslInputTabWidgetLayout->addRow(eQSLSentLabelN, eqslSentLayout); eqslInputTabWidgetLayout->addRow(eQSLRecLabelN, eqslRecLayout); eqslInputTabWidgetLayout->addRow(lotWSentLabelN, lotwSentLayout); eqslInputTabWidgetLayout->addRow(lotWRecLabelN, lotwRecLayout); */ QGridLayout *eqslInputTabWidgetLayout = new QGridLayout; eqslInputTabWidgetLayout->addWidget(clublogLabelN, 0, 0); eqslInputTabWidgetLayout->addWidget(eQSLSentLabelN, 1, 0); eqslInputTabWidgetLayout->addWidget(eQSLRecLabelN, 2, 0); eqslInputTabWidgetLayout->addWidget(lotWSentLabelN, 3, 0); eqslInputTabWidgetLayout->addWidget(lotWRecLabelN, 4, 0); eqslInputTabWidgetLayout->addWidget(clublogComboBox, 0, 1); eqslInputTabWidgetLayout->addWidget(eqslSentComboBox, 1, 1); eqslInputTabWidgetLayout->addWidget(eqslRecComboBox, 2, 1); eqslInputTabWidgetLayout->addWidget(lotwSentComboBox, 3, 1); eqslInputTabWidgetLayout->addWidget(lotwRecComboBox, 4, 1); eqslInputTabWidgetLayout->addWidget(clublogQDateEdit, 0, 2); eqslInputTabWidgetLayout->addWidget(eqslSentQDateEdit, 1, 2); eqslInputTabWidgetLayout->addWidget(eqslRecQDateEdit, 2, 2); eqslInputTabWidgetLayout->addWidget(lotwSentQDateEdit, 3, 2); eqslInputTabWidgetLayout->addWidget(lotwRecQDateEdit, 4, 2); setLayout(eqslInputTabWidgetLayout); connect(clublogComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotClubLogComboBoxChanged() ) ) ; connect(eqslSentComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(sloteQSLSentComboBoxChanged() ) ) ; connect(eqslRecComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(sloteQSLRecvComboBoxChanged() ) ) ; connect(lotwSentComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotLotwSentComboBoxChanged() ) ) ; connect(lotwRecComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotLotwRecvComboBoxChanged() ) ) ; //dxUpLeftTab->addTab(eqslInputTabWidget, tr("eQSL")); } void MainWindowInputEQSL::setDefaultData() { //qsAux << tr("Y-Yes") << tr("N-No") << tr("R-Requested") << tr("I-Ignore") << tr("V-Validated"); //eqslRecComboBox->addItems(qsAux); //lotwRecComboBox->addItems(qsAux); eqslRecComboBox->addItems(qslRcvdStatusList); lotwRecComboBox->addItems(qslRcvdStatusList); //qsAux.clear(); //qsAux << tr("Y-Yes") << tr("N-No") << tr("R-Requested") << tr("Q-Queued") << tr("I-Ignore"); //eqslSentComboBox->addItems(qsAux); //lotwSentComboBox->addItems(qsAux); eqslSentComboBox->addItems(qslSentStatusList); lotwSentComboBox->addItems(qslSentStatusList); //QStringList qsAux; //qsAux.clear(); //qsAux << tr("Y-Uploaded") << tr("N-Do not upload") << tr("M-Modified"); clublogComboBox->addItems(clubLogStatusList); } void MainWindowInputEQSL::clear() { //qDebug() << "MainWindowInputEQSL::clear" << endl; clublogComboBox->setCurrentIndex(1); // Do not upload eqslSentComboBox->setCurrentIndex(1); eqslRecComboBox->setCurrentIndex(1); lotwSentComboBox->setCurrentIndex(1); lotwRecComboBox->setCurrentIndex(1); //dateEdit->setDate(QDate::fromString(aux1, "yyyy/MM/dd")); //QString date; //date = "18000101"; //eqslSentQDateEdit->setDate(QDate::fromString(date, "yyyyMMdd")); //eqslRecQDateEdit->setDate(QDate::fromString(date, "yyyyMMdd")); //lotwSentQDateEdit->setDate(QDate::fromString(date, "yyyyMMdd")); //lotwRecQDateEdit->setDate(QDate::fromString(date, "yyyyMMdd")); //clublogQDateEdit->setDate(QDate::fromString(date, "yyyyMMdd")); eqslSentQDateEdit->setDate(util->getDefaultDate()); eqslRecQDateEdit->setDate(util->getDefaultDate()); lotwSentQDateEdit->setDate(util->getDefaultDate()); lotwRecQDateEdit->setDate(util->getDefaultDate()); clublogQDateEdit->setDate(util->getDefaultDate()); } QString MainWindowInputEQSL::getClubLogStatus() { QString _pm = QString(); //qDebug() << "MainWindowInputEQSL::getClubLogStatus:" << clublogComboBox->currentText() << endl; _pm = (((clublogComboBox->currentText()).split('-')).at(0)).simplified(); //qDebug() << "MainWindowInputEQSL::getClubLogStatus: " << _pm << endl; //if (_pm == "Not") //{ // return QString(); //} return _pm; } QString MainWindowInputEQSL::getEQSLRecStatus() { QString _pm = QString(); //qDebug() << "MainWindowInputEQSL::getEQSLRecStatus:" << eqslRecComboBox->currentText() << endl; _pm = (((eqslRecComboBox->currentText()).split('-')).at(0)).simplified(); //qDebug() << "MainWindowInputEQSL::getEQSLRecStatus: " << _pm << endl; //if (_pm == "Not") //{ // return QString(); //} return _pm; } QString MainWindowInputEQSL::getEQSLSenStatus() { QString _pm = QString(); //qDebug() << "MainWindowInputEQSL::getEQSLSenStatus:" << eqslSentComboBox->currentText() << endl; _pm = (((eqslSentComboBox->currentText()).split('-')).at(0)).simplified(); //qDebug() << "MainWindowInputEQSL::getEQSLSenStatus: " << _pm << endl; //if (_pm == "Not") //{ // return QString(); //} return _pm; } QString MainWindowInputEQSL::getLOTWRecStatus() { QString _pm = QString(); //qDebug() << "MainWindowInputEQSL::getLOTWRecStatus:" << lotwRecComboBox->currentText() << endl; _pm = (((lotwRecComboBox->currentText()).split('-')).at(0)).simplified(); //qDebug() << "MainWindowInputEQSL::getLOTWRecStatus: " << _pm << endl; //if (_pm == "Not") //{ // return QString(); //} return _pm; } QString MainWindowInputEQSL::getLOTWSenStatus() { QString _pm = QString(); //qDebug() << "MainWindowInputEQSL::getLOTWSenStatus:" << lotwSentComboBox->currentText() << endl; _pm = (((lotwSentComboBox->currentText()).split('-')).at(0)).simplified(); //qDebug() << "MainWindowInputEQSL::getLOTWSenStatus: " << _pm << endl; //if (_pm == "Not") //{ // return QString(); //} return _pm; } void MainWindowInputEQSL::setClubLogStatus(const QString _qs) { //qDebug() << "MainWindowInputEQSL::setClubLogStatus: " << _qs << endl; if(( clublogComboBox->findText(_qs+" -", Qt::MatchStartsWith))>=0) { clublogComboBox->setCurrentIndex( clublogComboBox->findText(_qs+" -", Qt::MatchStartsWith)); } else { clublogComboBox->setCurrentIndex(1); } } void MainWindowInputEQSL::setEQSLRecStatus(const QString _qs) { //qDebug() << "MainWindowInputEQSL::setEQSLRecStatus: " << _qs << endl; if(( eqslRecComboBox->findText(_qs+" -", Qt::MatchStartsWith))>=0) { eqslRecComboBox->setCurrentIndex( eqslRecComboBox->findText(_qs+" -", Qt::MatchStartsWith)); } else { eqslRecComboBox->setCurrentIndex(1); } } void MainWindowInputEQSL::setEQSLSenStatus(const QString _qs) { //qDebug() << "MainWindowInputEQSL::setEQSLSenStatus: #" << _qs+" -" << endl; if(( eqslSentComboBox->findText(_qs, Qt::MatchStartsWith))>=0) { eqslSentComboBox->setCurrentIndex( eqslSentComboBox->findText(_qs, Qt::MatchStartsWith)); } else { //qDebug() << "MainWindowInputEQSL::setEQSLSenStatus: NOT found" << endl; eqslSentComboBox->setCurrentIndex(1); } } void MainWindowInputEQSL::setLOTWRecStatus(const QString _qs) { //qDebug() << "MainWindowInputEQSL::setLOTWRecStatus: " << _qs << endl; if(( lotwRecComboBox->findText(_qs+" -", Qt::MatchStartsWith))>=0) { lotwRecComboBox->setCurrentIndex( lotwRecComboBox->findText(_qs+" -", Qt::MatchStartsWith)); } else { lotwRecComboBox->setCurrentIndex(1); } } void MainWindowInputEQSL::setLOTWSenStatus(const QString _qs) { //qDebug() << "MainWindowInputEQSL::setLOTWSenStatus: " << _qs << endl; if(( lotwSentComboBox->findText(_qs+" -", Qt::MatchStartsWith))>=0) { lotwSentComboBox->setCurrentIndex( lotwSentComboBox->findText(_qs+" -", Qt::MatchStartsWith)); } else { lotwSentComboBox->setCurrentIndex(1); } } void MainWindowInputEQSL::slotLotwRecvComboBoxChanged(){ //qDebug() << "MainWindowInputEQSL::slotLotwRecvComboBoxChanged" << endl; //QSLRDATE (only valid if QSL_RCVD is Y-0, I-3, or V-4) //Y-Yes-0 //N-No-1 //R-Requested-2 //I-Ignore-3 //V-Verified-4 int i = lotwRecComboBox->currentIndex(); switch (i) { case 0: lotwRecQDateEdit->setEnabled(true); lotwRecQDateEdit->setDate((QDateTime::currentDateTime()).date()); break; case 2: break; case 3: lotwRecQDateEdit->setEnabled(true); break; case 4: lotwRecQDateEdit->setEnabled(true); break; default: //NO lotwRecQDateEdit->setEnabled(false); break; } } void MainWindowInputEQSL::slotLotwSentComboBoxChanged(){ //qDebug() << "MainWindowInputEQSL::slotLotwSentComboBoxChanged" << endl; int i = lotwSentComboBox->currentIndex(); //{Y, N, R, I, V} //(QSLSDATE is only valid if QSL_SENT is Y-0, Q-3, or I-4) // Y-Yes = 0 // N-No = 1 // R-Requested = 2 // Q-Queued = 3 // I-Ignore = 4 switch (i) { case 0: lotwSentQDateEdit->setEnabled(true); lotwSentQDateEdit->setDate((QDateTime::currentDateTime()).date()); break; case 2: break; case 3: lotwSentQDateEdit->setEnabled(true); break; case 4: lotwSentQDateEdit->setEnabled(true); break; default: //NO lotwSentQDateEdit->setEnabled(false); break; } } void MainWindowInputEQSL::sloteQSLRecvComboBoxChanged(){ //qDebug() << "MainWindowInputEQSL::sloteQSLRecvComboBoxChanged" << endl; //QSLRDATE (only valid if QSL_RCVD is Y-0, I-3, or V-4) //Y-Yes-0 //N-No-1 //R-Requested-2 //I-Ignore-3 //V-Verified-4 int i = eqslRecComboBox->currentIndex(); switch (i) { case 0: eqslRecQDateEdit->setEnabled(true); eqslRecQDateEdit->setDate((QDateTime::currentDateTime()).date()); break; case 2: break; case 3: eqslRecQDateEdit->setEnabled(true); break; case 4: eqslRecQDateEdit->setEnabled(true); break; default: //NO eqslRecQDateEdit->setEnabled(false); break; } } void MainWindowInputEQSL::sloteQSLSentComboBoxChanged(){ //qDebug() << "MainWindowInputEQSL::sloteQSLSentComboBoxChanged" << endl; int i = eqslSentComboBox->currentIndex(); //{Y, N, R, I, V} //(QSLSDATE is only valid if QSL_SENT is Y-0, Q-3, or I-4) // Y-Yes = 0 // N-No = 1 // R-Requested = 2 // Q-Queued = 3 // I-Ignore = 4 switch (i) { case 0: eqslSentQDateEdit->setEnabled(true); eqslSentQDateEdit->setDate((QDateTime::currentDateTime()).date()); break; case 2: break; case 3: eqslSentQDateEdit->setEnabled(true); break; case 4: eqslSentQDateEdit->setEnabled(true); break; default: //NO eqslSentQDateEdit->setEnabled(false); break; } } void MainWindowInputEQSL::slotClubLogComboBoxChanged() { int i = clublogComboBox->currentIndex(); //{Y, N, M} // Y-Yes = 0 // N-No = 1 // M-Modified = 2 switch (i) { case 0: clublogQDateEdit->setEnabled(true); clublogQDateEdit->setDate((QDateTime::currentDateTime()).date()); break; case 2: clublogQDateEdit->setEnabled(true); clublogQDateEdit->setDate((QDateTime::currentDateTime()).date()); break; default: //NO clublogQDateEdit->setEnabled(false); break; } } void MainWindowInputEQSL::setClubLogDate(const QDate _qs) { if (_qs.isValid()) { clublogQDateEdit->setDate(_qs); } else { clublogQDateEdit->clear(); } } void MainWindowInputEQSL::setEQSLRecDate(const QDate _qs) { if (_qs.isValid()) { eqslRecQDateEdit->setDate(_qs); } else { eqslRecQDateEdit->clear(); } } void MainWindowInputEQSL::setEQSLSenDate(const QDate _qs) { if (_qs.isValid()) { eqslSentQDateEdit->setDate(_qs); } else { eqslSentQDateEdit->clear(); } } void MainWindowInputEQSL::setLOTWRecDate(const QDate _qs) { if (_qs.isValid()) { lotwRecQDateEdit->setDate(_qs); } else { lotwRecQDateEdit->clear(); } } void MainWindowInputEQSL::setLOTWSenDate(const QDate _qs) { if (_qs.isValid()) { lotwSentQDateEdit->setDate(_qs); } else { lotwSentQDateEdit->clear(); } } QDate MainWindowInputEQSL::getClubLogDate() { return clublogQDateEdit->date(); } QDate MainWindowInputEQSL::getEQSLRecDate() { return eqslRecQDateEdit->date(); } QDate MainWindowInputEQSL::getEQSLSenDate() { return eqslSentQDateEdit->date(); } QDate MainWindowInputEQSL::getLOTWRecDate() { return lotwRecQDateEdit->date(); } QDate MainWindowInputEQSL::getLOTWSenDate() { return lotwSentQDateEdit->date(); } klog-0.9.2.9/aboutdialog.cpp0000644000076700000620000002166313237613021013577 0ustar staff#include "aboutdialog.h" //#include //#include "coreicons.h" //#include //#include //#include //#include //#include //#include //#include #include #include #include #include #include //#include AboutDialog::AboutDialog(const QString tversion, QWidget *parent) : QDialog(parent) { //qDebug() << "AboutDialog::AboutDialog" << endl; QPixmap pixmap(":/img/klog_256x256.png"); setWindowTitle(tr("About KLog")); setWindowFlags(windowFlags() & Qt::WindowContextHelpButtonHint); QGridLayout *layout = new QGridLayout(this); layout->setSizeConstraint(QLayout::SetFixedSize); const QString br = QLatin1String("
"); const QString description = "

KLog " + tversion + "

" +tr("By") + " EA4TV - 2002-2018


" + tr("KLog is a free logbook for hamradio operators.") +"

" + tr("Please know that this is an BETA release and it may contain many bugs.
Backup your data before using this software!") + "


" + tr("KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing.") + "

" + tr("Please provide your review in KLog's eHam review page:") + "
" + "http://www.eham.net/reviews/detail/3118

" + tr("Find more information and the latest release at") + "
http://www.klog.xyz

" + tr("Author") + ": Jaime Robles, EA4TV
jaime@robles.es"; QLabel *copyRightLabel = new QLabel(description); copyRightLabel->setWordWrap(true); copyRightLabel->setOpenExternalLinks(true); copyRightLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); QPushButton *closeButton = buttonBox->button(QDialogButtonBox::Close); buttonBox->addButton(closeButton, QDialogButtonBox::ButtonRole(QDialogButtonBox::RejectRole | QDialogButtonBox::AcceptRole)); connect(buttonBox , &QDialogButtonBox::rejected, this, &QDialog::reject); QLabel *logoLabel = new QLabel; logoLabel->setPixmap(pixmap); QLabel *logoLabel2 = new QLabel; logoLabel2->setPixmap(pixmap); QLabel *logoLabel3 = new QLabel; logoLabel3->setPixmap(pixmap); QLabel *logoLabel4 = new QLabel; logoLabel4->setPixmap(pixmap); QString author1 = QString("Jaime Robles") + QString("EA4TV") + "(2002-" + tr("today") +")" +tr("Main developer") + ""; QString author2 = QString("Akihiro Koda") + QString("JL3OXR") + "(2016-2017)"; QString author3 = QString("Andrew Goldie") + QString("ZL2ACG") + "(2009-2010)"; QString authorText = tr("KLog is developed by a very small team and you are invited to join!") + "

" + tr("If you want to provide support you are welcome to join the") + " " + tr("KLog development mailing list") + ""+ tr("!") + "

" + tr("You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog."); QString authors = "

" + tr("Authors") + "


" + authorText + "
" + author1 + author2 + author3 + "
"; QString translator1 = QString("Catalan") + QString("Josep Ma. Ferrer") + QString("KDE Catalan translation team"); QString translator2 = QString("Croatian") + QString("Kristijan Conkas") + QString("M0NKC"); QString translator3 = QString("Finnish") + QString("Kristjan Lorents") + QString("Debian translation team"); QString translator4 = QString("Danish") + QString("Joe Hansen") + QString("Danish Debian translation team"); QString translator5 = QString("Italian") + QString("Simona Pisano") + QString("IU5HIU"); QString translator6 = QString("Japanese") + QString("Akihiro Koda") + QString("JL3OXR"); QString translator7 = QString("Polish") + QString("Piotr Ludwig") + QString("LA7RRA"); QString translator8 = QString("Spanish") + QString("Jaime Robles") + QString("EA4TV"); QString translatorsText = tr("Translators bring KLog into your language. They are really an important part of the KLog development team.") + "

" + tr("If KLog is still not in your language and you want to help us, you are welcome to contact us through the") + " " + tr("KLog development mailing list") + "" + tr("!"); QString translators = "

" + tr("Translators") + "


" + translatorsText + "
" + translator1 + translator2 + translator3 + translator4 + translator5 + translator6 + translator7 + translator8 + "
"; QLabel *authorsLabel = new QLabel(authors); authorsLabel->setWordWrap(true); authorsLabel->setOpenExternalLinks(true); authorsLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); QLabel *translatorsLabel = new QLabel(translators); translatorsLabel->setWordWrap(true); translatorsLabel->setOpenExternalLinks(true); translatorsLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); QString privacy = "

" + tr("Privacy advisory") + "


" + tr("KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs") + "

" + tr("At present, the data that is provided is the following:") + "
  • " + tr("Callsign") + "
  • " + tr("KLog version") + "
  • " + tr("Operating system") + "


" + tr("Be aware that you can enable/disable this feature from the Misc tab in the Setup page") + "."; QLabel *privacyLabel = new QLabel(privacy); privacyLabel->setWordWrap(true); privacyLabel->setOpenExternalLinks(true); privacyLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); tab1 = new QWidget; tab2 = new QWidget; tab3 = new QWidget; tab4 = new QWidget; QGridLayout *layout1 = new QGridLayout; layout1->addWidget(logoLabel , 0, 0, 1, 1); layout1->addWidget(copyRightLabel, 0, 1, 4, 4); layout1->addWidget(buttonBox, 4, 0, 1, 5); tab1->setLayout(layout1); QGridLayout *layout2 = new QGridLayout; layout2->addWidget(logoLabel2 , 0, 0, 1, 1); layout2->addWidget(authorsLabel, 0, 1, 4, 4); //layout2->addWidget(buttonBox, 4, 0, 1, 5); tab2->setLayout(layout2); QGridLayout *layout3 = new QGridLayout; layout3->addWidget(logoLabel3 , 0, 0, 1, 1); layout3->addWidget(translatorsLabel, 0, 1, 4, 4); tab3->setLayout(layout3); QGridLayout *layout4 = new QGridLayout; layout4->addWidget(logoLabel4 , 0, 0, 1, 1); layout4->addWidget(privacyLabel, 0, 1, 4, 4); tab4->setLayout(layout4); tabw = new QTabWidget; tabw->addTab(tab1, tr("KLog")); tabw->addTab(tab2, tr("Authors")); tabw->addTab(tab3, tr("Translators")); tabw->addTab(tab4, tr("Privacy")); layout->addWidget(tabw); setLayout(layout); //qDebug() << "AboutDialog::AboutDialog - END" << endl; } AboutDialog::~AboutDialog() { } bool AboutDialog::event(QEvent *event) { if (event->type() == QEvent::ShortcutOverride) { QKeyEvent *ke = static_cast(event); if (ke->key() == Qt::Key_Escape && !ke->modifiers()) { ke->accept(); return true; } } return QDialog::event(event); } klog-0.9.2.9/setuppagebandmode.h0000644000076700000620000000140713233376355014447 0ustar staff#ifndef SETUPPAGEBANDMODE_H #define SETUPPAGEBANDMODE_H #include #include #include #include #include "dataproxy.h" class SetupPageBandMode : public QWidget { Q_OBJECT public: SetupPageBandMode(DataProxy *dp, QWidget *parent=0); ~SetupPageBandMode(); QString getBands(); // 10m, 12m, 15m QString getModes(); //ssb, CW void setActiveBands(QStringList q); void setActiveModes(QStringList q); signals: public slots: private: void addBands(QStringList _b); // read the available bands from the DB void addModes(QStringList _b); // read the available modes from the DB QListWidget *bandsListWidget, *modesListWidget; DataProxy *dataProxy; }; #endif // SETUPPAGEBANDMODE_H klog-0.9.2.9/startwizard.h0000644000076700000620000001154413233376355013341 0ustar staff#ifndef STARTWIZARD_H #define STARTWIZARD_H /*************************************************************************** startwizard.h - description ------------------- begin : feb 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include //#include #include #include #include #include #include "downloadcty.h" class FileOrMemoryPage; class CTYPage; class StartWizard : public QWizard { Q_OBJECT public: enum { Page_Intro, Page_Lic, Page_Mem, Page_CTY }; StartWizard(const QString _klogDir, const QString _softVersion, QWidget *parent = 0); void setVersion(QString tversion); //~StartWizard(); protected: private slots: void slotCancelWizard(); void slotRunInMemory(bool checked); void slotButtonFinishedClicked(); private: FileOrMemoryPage *fileOrMemoryPage; CTYPage *ctyPage; QString version; bool inMemory; QString klogDir; }; class IntroPage : public QWizardPage { Q_OBJECT public: IntroPage(QWidget *parent = 0); int nextId() const; private: QLabel *topLabel; QTextEdit *welcomeBrowser; }; class LicPage : public QWizardPage { Q_OBJECT public: LicPage(QWidget *parent = 0); void setNextButtonActive(const bool _active); int nextId() const; private: QLabel *topLabel; QTextEdit *licenseBrowser; QCheckBox *aceptLicCheckBox; }; /* class FileOrMemoryPage : public QWizardPage { Q_OBJECT public: FileOrMemoryPage(QWidget *parent = 0); int nextId() const; //int nextId() const; private slots: void slotRunningModeSelectedFile(bool checked); void slotRunningModeSelectedMemory(bool checked); signals: void exeInMemory(const bool mem); private: bool downloadCTYFile(); QLabel *topLabel; QRadioButton *memoryRadioButton; QRadioButton *fileRadioButton; bool runInMemory; }; */ class CTYPage : public QWizardPage { Q_OBJECT public: CTYPage(const QString _klogDir, const QString _version, QWidget *parent = 0); void updateProgress (qint64 v,qint64 t); private slots: /* void slotCTYCheckButtonTogled(int state); void slotDownloadCTY(bool checked); void slotDownloadFinished(); void slotValueReturnedFromDownload(int value); void slotDownloadButtonClicked(); */ void slotUpdateDownloadProgress(qint64 received, qint64 total); void slotDownloadButtonClicked(); void slotIgnoreDownloadButtonClicked(); void slotDownloadFinished(const int ret); void slotDownloadError(const int ret); signals: void downloadTheFileSignal(const bool mem); private: bool prepareTheDownload(); bool doTheDownload(); //bool isComplete(); bool downloadCTYFile, CTYFileDownloaded; int downloadValueResult; //QString klogDir; int total; //bool completed; DownLoadCTY *dl; QLabel *topLabel; QTextEdit *ctyBrowser; QCheckBox *downloadCTYCheckBox; QProgressBar *progressBar; QPushButton *downloadButton, *ignoreDownloadButton; QCheckBox *hiddenCheckBox; }; #endif // STARTWIZARD_H klog-0.9.2.9/translations/0000755000076700000620000000000013237613362013322 5ustar staffklog-0.9.2.9/translations/klog_template.ts0000644000076700000620000052371013233376355016535 0ustar staff AboutDialog About KLog By KLog is a free logbook for hamradio operators. Please know that this is an BETA release and it may contain many bugs.<br>Backup your data before using this software! KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing. Please provide your review in KLog's eHam review page: Find more information and the latest release at Author today Main developer KLog is developed by a very small team and you are invited to join! If you want to provide support you are welcome to join the KLog development mailing list ! You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog. Authors Translators bring KLog into your language. They are really an important part of the KLog development team. If KLog is still not in your language and you want to help us, you are welcome to contact us through the Translators Privacy advisory KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs At present, the data that is provided is the following: Callsign KLog version Operating system Be aware that you can enable/disable this feature from the Misc tab in the Setup page KLog Privacy CTYPage Country data download KLog needs country data... &Download &Ignore Country data needed KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information. You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do. Click on Download to download now. KLog I can't find the host. Please check your network and try again Do you want to try again? DXCCStatusWidget Update ID Entity DXClusterWidget Click on Connect to connect to the DX-Cluster server Connect Clear Click on connect to connect to the DX-Cluster Trying to connect to the server KLog DXCluster The host was not found. Please check: - your network connection; - the host name and port settings. The connection was refused by the peer. Make sure the DXCluster server is running, and check that the host name and port settings are correct. The following error occurred: %1. Connected to server KLog message Enter your callsign to connect to the cluster: Enter your password to connect to the cluster: (Just hit enter for no password) Disconnect Not logged on, you may need to enter your callsign again. Enter here the commands to be sent to the DX-Cluster server Connection closed by the server Send DataProxy_SQLite Software version in DB is null No query failed KLog DXCC All QSOs have been updated with a DXCC. DownLoadCTY Download of cty.csv failed with the following error code: Download of cty.csv done. There is already a cty.csv file in the folder but it will be replaced with the new one. Could not open for writing. FileManager The log that you have selected contains more than just one station callsign. Please select the station callsing you want to export the log from: Station Callsign: Define Station Callsign You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: No station callsign has been selected and therefore no log will be exported Writing ADIF file... Abort writing Exporting LoTW ADIF file... QSO: Writing ADIF file... QSO: You have canceled the file export. The file will be removed and no data will be exported. Do you still want to cancel? Writing Cabrillo file... KLog: Cabrillo Log Export not implemented I am sorry but the Cabrillo Export To File feature has still not been implemented. Reading LoTW file... Abort reading There is more than one log in this logfile. All logs will be imported into the current log. Do you want to continue? Importing ADIF file... You have cancelled the file import. The file will be removed and no data will be imported. It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported) Reading ADIF file... This QSO is not including the minimum data to consider a QSO as valid!. Please edit the ADIF file and make sure that it include at least: and This QSO had: - The band missing and the following call: - The call missing but was done at this time: - The mode missing and the following call: - The date missing and the following call: - The time missing and the following call: Do you want to continue with the current file? KLog: Not all required data found! This log seems to lack of RST-TX information. Click on Yes to add a default 59 to all QSO with a similar problem. If you select NO, the QSO may not be imported. KLog: No RST TX found! This log seems to lack of RST-RX information. KLog: No RST RX found! InfoWidget 10M 15M 20M 40M 80M 160M 2M 6M 12M 17M 30M 70CM Continent Prefix CQ ITU Short Path Long Path Degree Miles Km IntroPage Welcome to KLog! Welcome to KLog! - brought to you under the terms of the GPL! Welcome to KLog This looks like it's the first time you've run KLog on this computer. KLog is a free hamradio logging program that can run on Linux macOS and Windows. It is designed to provide general purpose, DX and contest logging. It supports QSL management, import and export of ADIF and Cabrillo file formats and many other features... Before you can start using KLog, you will be asked to: Acknowledge to the terms of the license. Download the DX entities information. Enter your callsign, CQ zone, etc. and main configuration. Enjoy KLog and contact the development team if you have any suggestions! LicPage KLog License information Welcome to KLog!- brought to you under the terms of the GPL! Acknowledge Be aware that KLog is free software. LogModel Date Time QRZ Band Mode RSTtx RSTrx Comment LogWindow QSL Send QSL Rcvd &Delete Delete a QSO &Edit QSO Edit this QSO Via &bureau Send this QSL via bureau D&irect Send this QSL via direct Via bureau QSL &received via bureau Direct QSL received via direc&t You have requested to delete this QSO. Are you sure? MainWindow Recalculate Click to recalculate the award status Starting KLog &Add &Clear Status bar... DX Entity &Log Window &Score Window Watts MHz KLog Ready An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: You have selected an entity: that is different from the KLog proposed entity: Click on the prefix of the correct entity or Cancel to edit the QSO again. Click on the prefix of the right entity or Cancel to correct. QRZ of the QSO TX RST RX RST TX Exchange RX Exchange Band of the QSO Mode of the QSO Date of the QSO Time of the QSO Add the QSO to the log Clear the box Input RSTrx RSTtx QRZ STX SRX NEW MULT Invalid characters used in the QRZ Ready... The logfile has been modified. Do you want to save your changes? &File &New... &Open... &Import from ADIF... Import an ADIF file into the current log. &Save As... Export the current log to an ADIF logfile. Export ALL the QSOs into one ADIF file, merging QSOs from all the logs. Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program). Export to ADIF... Export all logs to ADIF... Export Requested QSL to ADIF... Export ADIF for LoTW... Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW! &Print Log... Print your log. KLog folder Opens the data folder of KLog. E&xit &Tools Fill in QSO data Go through the log reusing previous QSOs to fill missing information in other QSOs. Fill in DXCC data Go through the log filling QSOs without a DXCC defined. QSL tools... &Find QSO to QSL Shows QSOs for which you should send your QSL and request the DX QSL. Find My-QSLs pending to send Shows the QSOs with pending requests to send QSLs. You should keep this queue empty! &Find DX-QSLs pending to receive Shows the DX-QSL that has been requested or QSLs has been sent with no answer. &Find requested pending to receive Shows the DX-QSL that has been requested. LoTW tools... Queue all QSL to be sent of this log Mark all non sent QSOs in this log as queued to be uploaded. Queue all QSL to be sent Mark all non sent QSOs as queued to be uploaded. Mark as sent all queued QSO of this log Mark all queued QSOs in this log as sent to LoTW. Mark all queued QSO as sent Mark all queued QSOs as sent to LoTW. &Update cty.csv For updated DX-Entity data, update cty.csv. &Setup &Setup... &Help Check updates... &About... About Qt... KLog LoTW All pending QSO of this log has been marked as queued for LoTW! Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW. There was a problem to mark all pending QSO of this log as queued for LoTW! All pending QSO has been marked as queued for LoTW! The log that you have selected contains more than just one station callsign. Please select the station callsing you want to mark as sent to LoTW: Station Callsign: Define Station Callsign You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: No station callsign has been selected and therefore no log will be marked All queued QSO of this log has been marked as sent for LoTW! There was a problem to mark all queued QSO of this log as sent for LoTW! All queued QSO has been marked as sent to LoTW! There was a problem to mark all queued QSO of this log as sent to LoTW! About... KLog update checking result Congratulations! You already have the latest version. Nothing has been saved. You have to select a valid file type. Save File ADIF file Cabrillo files Any file You can find the KLog data folder here: DUPE The selected log is not existing or it is still empty. Click Yes and KLog will open an empty log. Click No and KLog will select another log with data. You can modify the config file accordingly, if needed. It seems that there are no QSO in the database. If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help. TX Frequency in MHz. RX Frequency in MHz. Power used by the DX. Logging operator's callsign. Callsign used over the air. My QTH locator. Name of the DX. QTH of the DX. Locator of the DX. QRZ of the QSO. TX RST. RX RST. TX Exchange. RX Exchange. Band of the QSO. Mode of the QSO. Date of the QSO. Time of the QSO. Add the QSO to the log. Clears the QSO entry. Number of confirmed DXCC entities. Number of worked DXCC entities. Number of confirmed WAZ zones. Number of worked WAZ zones. Number of confirmed local references. Number of worked local references. Number of confirmed QSOs. Number of worked QSOs. Number of QSOs worked on the selected year. Number of DXCC worked on the selected year. Number of CQ Zones worked on the selected year. Score for the DXMarathon on the selected year. Select the year you want to check. Status of the DX entity. Name of the DX entity. Name QTH Locator Power(rx) RST(tx) RST(rx) Freq TX Freq RX QSO QSL eQSL Comment Others My Data Satellite QSOs DXCC CQ Score DX-Marathon Info Award Confirmed Worked WAZ Local Awards Search Log DX-Cluster Save ADIF File LoTW logfile has been properly exported! Remember to: Before uploading: sign the LoTW log; and After uploading: mark as sent all the queued QSO (LoTW Tools). There was no QSO to be exported. If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as: Q - Queued There was an error while exporting the LoTW. The log has not been exported! Save Cabrillo File Cabrillo (*.log) Open File &Modify -- - Needed for DXMarathon Filling QSOs... Abort filling Filling QSOs... QSO: Number Date Time Band Mode Print Log Printing the log... Abort printing Printing the log... QSO: An unexpected error ocurred!! If the problem persists, please contact the developers for analysis: Error in function Error code Error text Failed query Do you want to keep showing errors? MainWindowInputComment Add a comment for this QSO MainWindowInputEQSL Date of the ClubLog upload. Date of the eQSL sending. Date of the eQSL reception. Date of the LoTW sending. Date of the LoTW reception. Status on ClubLog. Status of the eQSL sending. Status of the eQSL reception. Status of the LoTW sending. Status of the LoTW reception. ClubLog eQSL Sent eQSL Rec LoTW Sent LoTW Rec MainWindowInputOthers Primary Div Secondary Div IOTA Entity Propagation mode Select the primary division for this QSO Select the secondary division for this QSO Select the entity for this QSO Select the propagation mode for this QSO Select the IOTA continent for this QSO Select the IOTA reference number for this QSO Not Identified Not - Not Identified MainWindowInputQSL QSL Sent QSL Rec QSL Via QSL Msg Status of the QSL sending. Status of the QSL reception. QSL sending information. QSL reception information. Date of the QSL sending. Date of the QSL reception. Message of the QSL. QSL via information. MainWindowMyDataTab Watt Keep this data Data entered in this tab will be copied into the next QSO Power used for the QSO in watts Logging operator's callsign Callsign used over the air My QTH locator Power Operator Station Callsign My Locator MainWindowSatTab Keep this data Data entered in this tab will be copied into the next QSO Other - Sat not in the list Name of the Satellite if not in the list. Select: " " to enable this box. (format like AO-51) Satellite mode used Select the satellite you are using UpLink band DownLink band Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab. UpLink DownLink Satellite Mode DX Locator Other MHz Not Sat QSO KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name. The satellite you have in your QSO is: Please know that the satellite name will not be saved if it is not in the list so that information may be lost! QObject New One, work it! Needed, work it! Worked but not confirmed Confirmed Not identified Database Error KLog DB needs to be upgraded. Do you want to upgrade it now? If DB is not upgraded KLog may not work properly. KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you. KLog: Enter Station callsign Enter the station callsign used in this log Station Callsign All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK. Updating mode information... Abort updating QSO: Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel? Updating bands information... Updating bands information in %1 status... Progress: Updating mode information in %1 status... Updating DXCC award information... Updating DXCC Award information... Updating WAZ award information... Updating DXCC information... Install wizard was canceled before completing... Do you want to remove the KLog dir from your disk? Your KLog dir has been removed Thank you for running KLog! I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk. Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk. Remember that your KLog dir is on your system... SearchWidget &Clear &Export Highlighted &Select All &Search All Clear the searches. Export the search result to an ADIF file. Select/Unselect all the QSOs shown. Search in the log. Search in all logs. Enter the QRZ to search for. Search results. QRZ Date/Time Band Mode QSL Sent QSL Rcvd Station Callsign ID &Clear selection Save File QSL Send &Delete Delete a QSO &Edit QSO Edit this QSO Via &bureau Send this QSL via bureau D&irect Send this QSL via direct &Request my QSL Mark my QSL as requested Via Direct && mark DX QSL as requested Send this QSL via direct & mark DX QSL as requested Via Bureau && mark DX QSL as requested Send this QSL via bureau & mark DX QSL as requested &Request the QSL Mark the QSL as requested Via bureau && mark my QSL as requested QSL received via bureau & mark my QSL as requested Via bureau QSL received via bureau Direc&t && mark as my QSL requested QSL received via direct & mark my QSL as requested Direc&t QSL received via direct You have requested to delete the QSO with: Are you sure? Needed QSO to send the QSL My QSL requested to be sent DX QSL pending to be received SetupDialog My Data Bands/Modes DX-Cluster Colors Misc World Editor Logs ClubLog Cancel OK Config Dialog User data D&X-Cluster You need to enter at least one log in the Logs tab. World DB has not been moved to new path Go to the Misc tab and click on Move DB or the DB will not be moved to the new location. You need to enter at least a valid QRZ. User tab and enter valid QRZ. You have not selected the kind of log you want. You will be redirected to the Log tab. Please add and select the kind of log you want to use. SetupEntityDialog Entity Name of the Entity CQ CQ zone ITU ITU zone Latitude Longitude of the Entity Longitude UTC Local time difference to UTC Main prefix Main prefix of the entity ARRL ID Prefixes Comma separated possible prefixes, e.g. EA1, EA2, ... Date of the deletion Deleted Cancel OK Entity Dialog SetupPageBandMode Bands Modes SetupPageClubLog &Callsign ClubLog &password ClubLog &email Enter the email you used to register in ClubLog. Enter the callsign you used to register in ClubLog. Enter your password in ClubLog. &Send QSOs in real time &Activate ClubLog Use QSO Station &Callsign Send each QSO to ClubLog in real time, as they are added (or modified) in KLog Starts the ClubLog support in KLog Use the Station Callsign defined in each QSO instead of the one defined here SetupPageColors New One Needed in this band Worked in this band Confirmed in this band Default Choose a color SetupPageDxCluster Add Delete Show &HF spots Show V/&UHF spots Show W&ARC spots Show &worked spots Show &confirmed spots Show ANN/&FULL messages Show WW&V messages Show WC&Y messages DX Spots Messages KLog: Add a DXCluster server Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default: SetupPageLogs &New &Edit &Remove Add a new log Edit the selected log Remove the selected log Select the log you want to open KLog Do you really want to remove this log? All the QSOs from this log will be also deleted... Log has not been removed. (#3) Log has not been removed. (#2) Log has not been removed. (#1) ID Date Station Callsign Operators Comments Type An error has occurred showing the following error code: KLog - SetupPageLogs SetupPageLogsNew &Date &Station Callsign &Operators Comm&ent &Ok &Cancel Select categories Callsign used for this log Comma separated list of operators: callsign1, callsign2 Start date of this log Add a comment about this log &Type of Operation Select the kind of operation for this log &Mode Category Select the mode category O&perators Category Select the operators category &Assisted Category Select the assisted category Po&wer Category Select the power category &Bands Category Select the bands category O&verlay Select the Overlay category Categories not OK You need to enter a valid QRZ in the Station Callsign box. The log will not be opened. You selected an invalid combination. The log will not be opened. Categories OK SetupPageMisc &Imperial system &Log in real time &Time in UTC &Save ADIF on exit Use this &default filename Mark &QSO to send QSL when QSL is received Complete QSO with previous data Show the Station &Callsign used in the search box &Reset to My Data for all QSOs &Check for new versions automatically &Provide Info for statistics Browse Move DB QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours. The search box will show also the callsign on the air to do the QSO. All the data from the My Data tab will be used or data from the previous QSO will be maintained. Check if there is a new release of KLog available every time you start KLog. If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog. Check it for Imperial system (Miles instead of Kilometres). Select to use real time. Select to use UTC time. Select if you want to save to ADIF on exit. Select to use the following name for the logfile without being asked for it again. Complete the current QSO with previous QSO data. This is the default file where ADIF data will be saved. This is the directory where the database (logbook.dat) will be saved. Click to change the default ADIF file. Click to change the path of the database. Click to move the DB to the new directory. Open File Select Directory This is the directory where DB (logbook.dat) will be saved. Please specify an existing directory where the database (logbook.dat) will be saved. File moved File copied File NOT copied The target directory does not exist. Please select an existing directory. SetupPageUserDataPage &Personal data Station &data Enter your name Enter your address - 1st line Enter your address - 2nd line Enter your address - 3rd line Enter your address - 4th line Enter your city Enter your zip code Enter your province or state Enter your country &Name &Address Cit&y &Zip Code Pro&v/State Countr&y Enter your information for rig Enter your information for antenna Enter your power information &Rig 1 R&ig 2 Ri&g 3 Antenna &1 Antenna &2 Antenna &3 Po&wer Enter the station callsign that will be used for logging Enter the operators (comma separated if more than one). Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign. &QRZ &Operators &CQ Zone &ITU Zone &Locator &Locator (not valid) SetupPageWorldEditor An entities information file (cty.csv) has been detected in your KLog folder and will be loaded. No entities information file (cty.csv) has been detected in your KLog folder. KLog will not be able to show entities information. Prefix Entity ARRL ID Continent CQ Zone ITU Zone UTC Latitude Longitude Deleted Since Date To Date Open File BigCTY (*.csv) Entities information has been updated. Entities information has not been updated. ShowErrorDialog KLog Message SoftwareUpdateDialog Ok KLog update Congratulations! Your KLog has been updated. You already have the latest version. StartWizard KLog - The free hamradio logging program Quit Setup Setup is not complete yet. Are you sure you want to quit setup? World Entity Continent Reading cty.csv... Abort reading eLogClubLog Host not found! Timeout error! It seems to be a PASSWORD ERROR; check your password. KLog - ClubLog It seems that your ClubLog password is not correct. Please check your password in the setup. ClubLog uploads will be disabled. Undefined error... Callsign missing Invalid callsign Skipping SWL callsign Callsign is your own call Invalid callsign with no DXCC mapping Updated QSO Invalid ADIF record Missing ADIF record Test mode - parameters ok, no action taken Excessive API Usage Internal Error Rejected QSO Duplicate QSO Modified Missing Login QSO OK Upload denied No callsign selected No match found Dropped QSO OK Login rejected Rejected: Callsign is your own call klog-0.9.2.9/translations/klog_fi.ts0000644000076700000620000046330313233376355015321 0ustar staff AboutDialog About KLog Tietoja KLogista By Tekijä KLog is a free logbook for hamradio operators. KLog on ilmainen päiväkirja radioamatööreille. Please know that this is an BETA release and it may contain many bugs.<br>Backup your data before using this software! Huomaa, että tämä on BETA-julkaisu ja se saattaa sisältää monia vikoja. <br>Varmuuskopioi omat tiedstot ennen tämän ohjelmiston käyttämistä! KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing. KLog on tehty kokonaan uudelleen versiosta 0.6.2:sta, jotta voisimme tarjota järjestelmäriippumattoman sovelluksen, joka toimii tärkeimmissä käyttöjärjestelmissä (Linux, MacOS ja Windows), sekä uusia toimintoja, joita KLog ei aiemmin tarjonnut. Please provide your review in KLog's eHam review page: Anna arvostelusi KLogin eHam -arvostelusivulla: Find more information and the latest release at Lisätietoja ja viimeisin ohjelmistoversio löytyy osoitteesta Author Tekijä today tänään Main developer Pääkehittäjä KLog is developed by a very small team and you are invited to join! KLogia kehittää erittäin pieni ryhmä ihmisiä ja sinut on kutsuttu mukaan! If you want to provide support you are welcome to join the Jos haluat antaa tukesi, olet tervetullut liittymään KLog development mailing list KLog kehitystiimin postituslistaan ! ! You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog. Voit auttaa meitä myös lähettämällä virheilmoituksia tai ohjelmointiapua, ideoita tai mitä vain, mikä mielestäsi voisi parantaa KLogia. Authors Tekijät Translators bring KLog into your language. They are really an important part of the KLog development team. Kääntäjät tuovat KLogin kielellesi, ja he ovat todella tärkeä osa KLog-kehitystiimiä. If KLog is still not in your language and you want to help us, you are welcome to contact us through the Mikäli KLogia ei vielä ole omalla kielelläsi ja haluat auttaa meitä, olet tervetullut ottamaan yhteyttä meihin Translators Kääntäjät Privacy advisory Tietosuojakäytäntö KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs KLog-kehittäjät ovat sisällyttäneet ominaisuuden, joka raportoi joitakin käyttäjätietoja KLog-palvelimelle, jonka ainoana tarkoituksena on tunnistaa asennetut versiot, jotta kehityksessä osataan keskittyä oikeaan suuntaan, käyttäjien tarpeet huomioiden At present, the data that is provided is the following: Tällä hetkellä toimitettavat tiedot ovat seuraavat: Callsign Kutsutunnus KLog version KLog versio Operating system Käyttöjärjestelmä Be aware that you can enable/disable this feature from the Misc tab in the Setup page Huomaa, että voit ottaa tämän ominaisuuden käyttöön tai poistaa sen käytöstä, Sekalaiset -välilehdellä, Asetussivulla KLog KLog Privacy Tietosuoja CTYPage Country data download Maakohtaisten tietojen lataus KLog needs country data... KLog tarvitsee maakohtaiset tiedot... &Download &Lataa &Ignore &Ohita Country data needed Maakohtaiset tiedot tarvitaan KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information. KLog käyttää cty.csv-tiedostoa osoitteesta http://www.country-files.com/ saadakseen DXCC tiedot. You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do. Sinun on ladattava cty.csv-tiedosto, jos haluat, että KLog näyttää sinulle maat, lokaattorit, ... tekemillesi QSO:ille. Click on Download to download now. Napsauta Lataa ladataksesi nyt. KLog KLog I can't find the host. Please check your network and try again Do you want to try again? En löydä palvelinta. Tarkista verkko ja yritä uudelleen Haluatko yrittää uudelleen? DXCCStatusWidget Update Päivitä ID ID Entity Yksikkö DXClusterWidget Click on Connect to connect to the DX-Cluster server Napsauta Yhdistä, kun haluat muodostaa yhteyden DX-klusteripalvelimeen Connect Yhdistä Clear Tyhjennä Click on connect to connect to the DX-Cluster Napsauta yhdistä, muodostaaksesi yhteyden DX-klusteriin Trying to connect to the server Muodostetaan yhteyttä palvelimeen KLog DXCluster KLog DXKlusteri The host was not found. Please check: Isäntää ei löytynyt. Tarkista: - your network connection; - the host name and port settings. - verkkoyhteytesi; - isäntänimi ja porttiasetukset. The connection was refused by the peer. Make sure the DXCluster server is running, and check that the host name and port settings are correct. Yhteys vertaisverkkoon evättiin. Varmista, että DX Klusteripalvelin on käynnissä ja tarkista, että isäntänimi ja porttiasetukset ovat oikein. The following error occurred: %1. Tapahtui seuraava virhe: %1. Connected to server Yhdistetty palvelimeen KLog message KLog viesti Enter your callsign to connect to the cluster: Syötä kutsutunnuksesi liittyäksesi klusteriin: Enter your password to connect to the cluster: (Just hit enter for no password) Syötä salasanasi yhteyden muodostamiseksi klusteriin: (Paina enter, jättääksesi salasanan tyhjäksi) Disconnect Katkaise yhteys Not logged on, you may need to enter your callsign again. Et ole kirjautunut sisään, sinun on ehkä annettava kutsutunnuksesi uudelleen. Enter here the commands to be sent to the DX-Cluster server Anna tähän komennot, jotka lähetetään DX-klusteripalvelimelle Connection closed by the server Palvelin katkaisi yhteyden Send Lähetä DataProxy_SQLite Software version in DB is null Ohjelmistoversio Tietokannassa on tyhjä No query failed Kyselyt onnistuivat KLog DXCC KLog DXCC All QSOs have been updated with a DXCC. Kaikki QSO:t on päivitetty DXCC:llä. DownLoadCTY Download of cty.csv failed with the following error code: cty.csv:n lataus epäonnistui virhekoodilla: Download of cty.csv done. cty.csv:n lataus valmis. There is already a cty.csv file in the folder but it will be replaced with the new one. Kansiossa on jo cty.csv-tiedosto, mutta se korvataan uudella. Could not open Ei voitu avata for writing. kirjoittamista varten. FileManager The log that you have selected contains more than just one station callsign. Valitsemasi loki sisältää enemmän kuin vain yhden aseman kutsutunnuksen. Please select the station callsing you want to export the log from: Valitse aseman kutsutunnus, jonka lokin haluat viedä: Station Callsign: Aseman Kutsutunnus: Define Station Callsign Määritä aseman kutsutunnus You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here. Et ole valinnut kutsutunnusta. KLog vie QSO:t ilman asetettua aseman kutsutunnusta ja ne, kutsulla jonka syötät tähän. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Syötä tässä lokissa käytettävä aseman kutsutunnus, tai jätä se tyhjäksi QSO:lle ilman määritettyä aseman kutsutunnusta: Writing ADIF file... Kirjoitetaan ADIF -tiedostoa... Abort writing Keskeytä kirjoitus Exporting LoTW ADIF file... LoTW ADIF -tiedoston vienti... Writing ADIF file... QSO: Kirjoitetaan ADIF -tiedostoon... QSO: You have canceled the file export. The file will be removed and no data will be exported. Olet peruuttanut tiedoston viennin. Tiedosto poistetaan, eikä tietoja viedä. Do you still want to cancel? Haluatko varmasti peruuttaa? Writing Cabrillo file... KirjoitetaanCabrillo -tiedostoa... KLog: Cabrillo Log Export not implemented KLog: Cabrillo-lokin Vientiä ei ole toteutettu I am sorry but the Cabrillo Export To File feature has still not been implemented. Olen pahoillani, mutta Cabrillo Vienti tiedostoon -ominaisuutta ei ole vieläkään toteutettu. Reading LoTW file... Luetaan LoTW -tiedostoa... There are more than one log in this logfile. All logs will be imported in the current log. Do you want to continue? Tässä lokitiedostossa on useampi kuin yksi loki. Kaikki lokit tuodaan nykyiseen lokiin. Haluatko jatkaa? Importing ADIF file... QSO: Tuodaan ADIF -tiedostoa... QSO: You have cancelled the file export. The file will be removed and no data will be exported. Do you still want to cancel? Olet peruuttanut tiedostonviennin. Tiedosto poistetaan eikä tietoja ole viety. Haluatko varmasti peruuttaa? - The band missing and the following call: - Taajuusalue puuttuu ja seuraava kutsu: - The call missing but was done at this time: - Kutsu puuttuu mutta toteutettiin tällä kertaa: - The mode missing and the following call: - Tila puuttuu ja seuraava kutsu: - The date missing and the following call: - Päiväys puuttuu ja seuraava kutsu: - The time missing and the following call: - Aika puuttuu ja seuraava kutsu: Reading ADIF file... Luetaan ADIF -tiedostoa... Abort reading Keskeytä lukeminen QSO: QSO: No station callsign has been selected and therefore no log will be exported Aseman kutsutunnusta ei ole valittu, joten lokia ei viedä There is more than one log in this logfile. All logs will be imported into the current log. Do you want to continue? Importing ADIF file... It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported) You have cancelled the file import. The file will be removed and no data will be imported. This QSO is not including the minimum data to consider a QSO as valid!. Tämä QSO ei sisällä vähimmäistietoja, jotta QSO:ta voidaan pitää oikeana! Please edit the ADIF file and make sure that it include at least: Muokkaa ADIF -tiedostoa ja varmista, että se sisältää ainakin: and ja This QSO had: Tässä QSO:ssa oli: Do you want to continue with the current file? Haluatko jatkaa nykyisen tiedoston kanssa? KLog: Not all required data found! KLog: kaikkia vaadittavia tietoja ei löydetty! This log seems to lack of RST-TX information. Tästä lokista näyttää puuttuvan RST-TX-tieto. Click on Yes to add a default 59 to all QSO with a similar problem. Napsauta Kyllä, jos haluat lisätä oletusarvon 59 kaikille QSO:ille, joilla on vastaava ongelma. If you select NO, the QSO may not be imported. Jos valitset EI, QSO:ta ei ehkä tuoda. KLog: No RST TX found! KLog: RST TX:ää ei löydy! This log seems to lack of RST-RX information. Tästä lokista näyttää puuttuvan RST-RX-tieto. KLog: No RST RX found! KLog: RST RX:ää ei löydy! InfoWidget 10M 10M 15M 15M 20M 20M 40M 40M 80M 80M 160M 160M 2M 2M 6M 6M 12M 12M 17M 17M 30M 30M 70CM 70CM Continent Manner Prefix Etuliite CQ CQ ITU ITU Short Path Lyhyt reitti Long Path Pitkä reitti Degree Grad Suuntima Miles Mailia Km Km IntroPage Welcome to KLog! Tervetuloa KLog:iin! Welcome to KLog! - brought to you under the terms of the GPL! Tervetuloa KLog:iin! - tuotu sinulle GPL:n ehtojen mukaisesti! Welcome to KLog Tervetuloa Klog:iin This looks like it's the first time you've run KLog on this computer. Näyttää siltä, että käynnistit KLog:in ensimmäistä kertaa tällä tietokoneella. KLog is a free hamradio logging program that can run on Linux macOS and Windows. KLog on ilmainen lokikirjaohjelma radioamatööreille, joka toimii Linux:ssa macOS:ssa ja Windowsissa. It is designed to provide general purpose, DX and contest logging. Se on suunniteltu tarjoamaan yleistä, sekä DX ja kilpailu -lokin pitoa. It supports QSL management, import and export of ADIF Se tarjoaa QSL hallintaa, sekä ADIF tuontia ja vientiä and Cabrillo file formats and many other features... ja Cabrillo -tiedostomuotoja, sekä paljon muita ominaisuuksia... Before you can start using KLog, you will be asked to: Ennen kuin voit aloittaa KLog:in käytön, sinua pyydetään: Acknowledge to the terms of the license. Hyväksymään lisenssin ehdot. Download the DX entities information. Lataamaan DX-yksiköiden tiedot. Enter your callsign, CQ zone, etc. and main configuration. Antamaan kutsutunnuksesi, CQ vyöhykeesi, jne. sekä pääkokoonpano. Enjoy KLog and contact the development team if you have any suggestions! Nauttimaan KLogista ja ottamaan yhteyttä kehitystiimiin, jos sinulla on ehdotuksia! LicPage KLog License information KLogin käyttöoikeustiedot Welcome to KLog!- brought to you under the terms of the GPL! Tervetuloa KLog:iin! - tuotu sinulle GPL:n ehtojen mukaisesti! Acknowledge Hyväksy Be aware that KLog is free software. Huomioi, että KLog on ilmainen ohjelmisto. LogModel Date Päivämäärä Time Aika QRZ QRZ Band Taajuusalue Mode Moodi RSTtx RSTtx RSTrx RSTrx Comment Kommentti LogWindow QSL Send QSL Lähetys QSL Rcvd QSL Vastaanotettu &Delete &Poista Delete a QSO Poista QSO &Edit QSO &Muokkaa QSO:ta Edit this QSO Muokkaa tätä QSO:ta Via &bureau &Bureau:n kautta Send this QSL via bureau Lähetä tämä QSO bureau:n kautta D&irect D&irect Send this QSL via direct Lähetä tämä QSO Direct:in kautta Via bureau Bureau:n kautta QSL &received via bureau QSL &vastaanotettu bureau:n kautta Direct Direct QSL received via direc&t QSL vastaanotettu Direc&t:in kautta You have requested to delete this QSO. Olet pyytänyt poistamaan tämän QSO:n. Are you sure? Oletko varma? MainWindow Recalculate Laske uudelleen Click to recalculate the award status Napsauta laskeaksesi uudelleen palkinto tilanne Starting KLog Käynnistetään KLog &Add &Lisää &Clear T&yhjennä Status bar... Tilapalkki... DX Entity DX Yksikkö &Log Window &Loki ikkuna &Score Window Pi&steytysikkuna Watts Wattia MHz MHz KLog KLog Ready Valmis An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: Tapahtui odottamaton virhe, kun yritit lisätä QSO:n lokiin. Jos ongelma jatkuu, ota yhteyttä kehittäjään analyysiä varten: You have selected an entity: Olet valinnut yksikön: that is different from the KLog proposed entity: joka eroaa KLog:in ehdotetusta kokoonpanosta: Click on the prefix of the correct entity or Cancel to edit the QSO again. Napsauta oikean yksikön etuliitettä tai Peruuta, jos haluat muokata QSO:ta uudelleen. Click on the prefix of the right entity or Cancel to correct. Napsauta oikean yksikön etuliitettä tai paina Peruuta korjataksesi. QRZ of the QSO QSO:n QRZ TX RST TX RST RX RST RX RST TX Exchange TX Exchange RX Exchange RX Exchange Band of the QSO QSO:n taajuusalue Mode of the QSO QSO:n moodi Date of the QSO QSO:n päivämäärä Time of the QSO QSO:n aika Add the QSO to the log Lisää QSO lokiin Clear the box Tyhjennä laatikko Input Syöttö RSTrx RSTrx RSTtx RSTtx QRZ QRZ STX STX SRX SRX NEW MULT NEW MULT Invalid characters used in the QRZ Virheellisiä merkkejä käytetty QRZ:ssa Ready... Valmis... The logfile has been modified. Do you want to save your changes? The logfile has been modified. Do you want to save your changes? &File &Tiedosto &New... &Uusi... &Open... &Avaa... &Import from ADIF... Tu&o ADIF -tiedostosta... &Save As... Tallenna &nimellä... &Export to ADIF... &Vie ADIF -tiedostoon... &Export all logs to ADIF... Vie &kaikki lokit ADIF -tiedostoon... Export ALL the QSOs into one ADIF file, merging QSOs from all the logs. Vie kaikki QSO:t yhteen ADIF -tiedostoon, yhdistäen QSO:t kaikista lokeista. &Export Requested QSL to ADIF... Vie &pyydetty QSL ADIF -tiedostoon... &Export ADIF for LoTW... Vie ADIF LoTW:iä varten... Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW! Vie ADIF-tiedosto lähetettäväksi LoTW:iin. Muista kirjata se TQSL:lla ennen lataamista LoTW:iin! &Print Log... Tulosta Loki... KLog folder KLog -kansio E&xit Ulo&s &Tools Työkalut Fill in QSO data Täytä QSO:n tiedot QSL tools... QSL työkalut... &Find QSO to QSL &Etsi QSO QSL:lle Find My-QSLs pending to send Etsi Minun QSL:t jotka odottavat lähetystä Shows the QSOs with pending requests to send QSLs. You should keep this queue empty! Näyttää QSO:t joilla on odottavia pyyntöjä lähettää QSL:iä. tämä jono tulisi pitää tyhjänä! &Find DX-QSLs pending to receive &Etsi DX-QSL:t jotka odottavat vastaanottoa &Find requested pending to receive &Etsi vastaanottoa odottavat Import an ADIF file into the current log. Tuo ADIF -tiedosto nykyiseen lokiin. Export to ADIF... Export the current log to an ADIF logfile. Vie nykyinen loki ADIF lokitiedostoon. Export all logs to ADIF... Export Requested QSL to ADIF... Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program). Vie kaikki QSO:t joilla on QSL pyyntöjä, ADIF tiedostoon (esim. tuodaksesi ne QSL tagin tulostus ohjelmaan). Export ADIF for LoTW... Print your log. Tulosta lokisi. Opens the data folder of KLog. Avaa KLog:in tallennuskansion. Go through the log reusing previous QSOs to fill missing information in other QSOs. Käy loki läpi käyttäen edellisiä QSO:ita täyttämään puuttuvat tiedot muissa QSO:issa. Fill in DXCC data Täytä DXCC tiedot Go through the log filling QSOs without a DXCC defined. Käy loki läpi täyttäen QSO:t joihin ei ole määritelty DXCC:tä. Shows QSOs for which you should send your QSL and request the DX QSL. Näyttää QSO:t joita varten sinun tulisi lähettää QSL ja pyytää DX QSL:ää. Shows the DX-QSL that has been requested or QSLs has been sent with no answer. Näyttää DX-QSL:t jotka on pyydetty, tai QSL:t on lähetetty ilman vastausta. Shows the DX-QSL that has been requested. Näyttää DX-QSL:n jota on pyydetty. LoTW tools... LoTW työkalut... Queue all QSO of this log Aseta jonoon kaikki tämän lokin QSO:t Mark all non sent QSOs in this log as queued to be uploaded. Merkitse kaikki tässä lokissa olevat lähettämättömät QSO:t lähetysjonoon. Queue all QSO Aseta jonoon kaikki QSO:t Queue all QSL to be sent of this log Queue all QSL to be sent Mark all non sent QSOs as queued to be uploaded. Merkitse kaikki lähettämättömät QSO:t lähetysjonoon. Mark as sent all queued QSO of this log Merkitse kaikki tämän lokin jonossa olevat QSO:t lähetetyiksi Mark all queued QSOs in this log as sent to LoTW. Merkitse kaikki tämän lokin jonossa olevat QSO:t lähetetyiksi LoTW:iin. Mark all queued QSO as sent Merkitse kaikki jonossa olevat QSO:t lähetetyiksi Mark all queued QSOs as sent to LoTW. Merkitse kaikki jonossa olevat QSO:t lähetetyiksi LoTW:iin. &Update cty.csv &Päivitä cty.csv For updated DX-Entity data, update cty.csv. Päivitettyjä DX-yksikkö tietoja varten, päivitä cty.csv. &Setup &Asetukset &Setup... &Asetukset &Help &Ohjeet Check updates... Tarkista päivitykset... &About... &Tietoja About Qt... Tietoja QT:stä KLog LoTW KLog LoTW All pending QSO of this log has been marked as queued for LoTW! Kaikki tämän lokin odottavat QSO:t on merkattu jonoon LOTW:iä varten! Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW. There was a problem to mark all pending QSO of this log as queued for LoTW! Odottavien QSO:iden merkinnässä jonoon LoTW:iä varten, ilmeni ongelma! All pending QSO has been marked as queued for LoTW! Kaikki odottavat QSO:t on merkattu jonoon LOTW:iä varten! The log that you have selected contains more than just one station callsign. Valitsemasi loki sisältää enemmän kuin vain yhden aseman kutsutunnuksen. Please select the station callsing you want to mark as sent to LoTW: Station Callsign: Aseman Kutsutunnus: Define Station Callsign Määritä aseman kutsutunnus You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Syötä tässä lokissa käytettävä aseman kutsutunnus, tai jätä se tyhjäksi QSO:lle ilman määritettyä aseman kutsutunnusta: No station callsign has been selected and therefore no log will be marked All queued QSO of this log has been marked as sent for LoTW! Kaikki tämän lokin jonossa olevat QSO:t on merkattu lähetetyiksi LOTW:iin! There was a problem to mark all queued QSO of this log as sent for LoTW! Kaikkien QSO:iden merkinnässä lähetetyiksi LoTW:iin, ilmeni ongelma! All queued QSO has been marked as sent to LoTW! Kaikki jonossa olevat QSO:t on merkattu lähetetyiksi LoTW:iin! There was a problem to mark all queued QSO of this log as sent to LoTW! Kaikkien jonossa olevien QSO:iden merkinnässä lähetetyiksi LoTW:iin, ilmeni ongelma! About... Tietoja... KLog update checking result KLog päivityksen tarkastuksen tulos Congratulations! Onnittelut! You already have the latest version. Sinulla on jo viimeisin versio. Nothing has been saved. You have to select a valid file type. Mitään ei ole tallennettu. Sinun täytyy valita oikea tiedostotyyppi. Save File Tallenna Tiedosto ADIF file ADIF -tiedosto Cabrillo files Cabrillo -tiedostot Any file Kaikki tiedostot You can find the KLog data folder here: KLog talletuskansio löytyy täältä: DUPE DUPE The selected log is not existing or it is still empty. Valittua lokia ei ole, tai se on vielä tyhjä. Click Yes and KLog will open an empty log. Napsauta Kyllä ja KLog avaa tyhjän lokin. Click No and KLog will select another log with data. Napsauta Ei ja KLog valitsee toisen lokin jossa on tietoja. You can modify the config file accordingly, if needed. Voit muokata config -tiedostoa jos tarvitaan. It seems that there are no QSO in the database. Näyttää siltä ettei tietokannassa ole QSO:ta. If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help. Jos olet varma että tietokannassa on QSO:ita ja KLog ei löydä niitä, voit ottaa yhteyttä kehittäjiin (Katso, Tietoja KLogista) apua varten. TX Frequency in MHz. TX Taajuus MHz:inä. RX Frequency in MHz. RX Taajuus MHz:inä. Power used by the DX. DX:n käyttämä virta. Logging operator's callsign. Lokinpitäjän kutsutunnus. Callsign used over the air. Lähetyksissä käytetty kutsutunnus. My QTH locator. Minun QTH lokaattori. Name of the DX. DX:n nimi. QTH of the DX. DX:n QTH. Locator of the DX. DX:n lokaattori. QRZ of the QSO. QSO:n QRZ. TX RST. TX RST. RX RST. RX RST. TX Exchange. TX Exchange. RX Exchange. RX Exchange. Band of the QSO. QSO:n taajuusalue. Mode of the QSO. QSO:n moodi. Date of the QSO. QSO:n päivämäärä. Time of the QSO. QSO:n aika. Add the QSO to the log. Lisää QSO lokiin. Clears the QSO entry. Poistaa QSO merkinnän. Number of confirmed DXCC entities. Vahvistettujen DXCC yksiköiden määrä. Number of worked DXCC entities. Työstettyjen DXCC yksiköiden määrä. Number of confirmed WAZ zones. Vahvistettujen WAZ vyöhykkeiden määrä. Number of worked WAZ zones. Työstettyjen WAZ vyöhykkeiden määrä. Number of confirmed local references. Vahvistettujen paikallisten referenssien määrä. Number of worked local references. Työstettyjen paikallisten referenssien määrä. Number of confirmed QSOs. Vahvistettujen QSO:iden määrä. Number of worked QSOs. Työstettyjen QSO:iden määrä. Number of QSOs worked on the selected year. Työstettyjen QSO:iden määrä, valittuna vuonna. Number of DXCC worked on the selected year. Työstettyjen DXCC:iden määrä, valittuna vuonna. Number of CQ Zones worked on the selected year. Työstettyjen CQ vyöhykkeiden määrä, valittuna vuonna. Score for the DXMarathon on the selected year. DXMarathon pisteet, valittuna vuonna. Select the year you want to check. Valitse vuosi jonka haluat nähdä. Status of the DX entity. DX yksikön tila. Name of the DX entity. DX yksikön nimi. Name Nimi QTH QTH Locator Lokaattori Power(rx) Teho(rx) RST(tx) RST(tx) RST(rx) RST(rx) Freq TX TX Taajuus Freq RX RX Taajuus QSO QSO QSL QSL eQSL eQSL Comment Kommentti Others Muut My Data Minun tiedot Satellite Satelliitti QSOs QSO:t DXCC DXCC CQ CQ Score Pisteet DX-Marathon DX-Maratoni Info Info Award Palkinto Confirmed Vahvistettu Worked Työstetty WAZ WAZ Local Paikallinen Awards Palkinnot Search Etsi Log Loki DX-Cluster DX-Klusteri Save ADIF File Tallenna ADIF -tiedosto LoTW logfile has been properly exported! LoTW lokitiedosto on viety onnistuneesti! Remember to: Before uploading: sign the LoTW log; and After uploading: mark as sent all the queued QSO (LoTW Tools). Remember to sign the LoTW log before you upload it! Muista kirjata LoTW loki ennen lähetystä! There was no QSO to be exported. Vietäviä QSO:ita ei ollut. If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as: Jos uskot, että joitakin QSO:ita olisi pitänyt viedä, etsi niitä ja varmista, että eQSL LoTW QSL lähetetty laatikko on merkitty seuraavasti: Q - Queued J - Jonossa There was an error while exporting the LoTW. The log has not been exported! LotW viennissä tapahtui virhe. Lokin vienti epäonnistui! Save Cabrillo File Tallenna Cabrillo Tiedosto Cabrillo (*.log) Cabrillo (*.log) Open File Avaa Tiedosto &Modify &Muokkaa -- -- - Needed for DXMarathon - Tarvitaan DXMarathon:iin Filling QSOs... Täyttää QSO:t... Abort filling Keskeytä täyttäminen Filling QSOs... QSO: Täyttää QSO:ita... QSO: Number Numero Date Päivämäärä Time Aika Band Taajuusalue Mode Tila Print Log Tulosta loki Printing the log... Tulostetaan lokia... Abort printing Keskeytä tulostus Printing the log... QSO: Tulostetaan lokia... QSO: An unexpected error ocurred!! Odottamaton virhe tapahtui!! If the problem persists, please contact the developers Jos ongelma jatkuu, ota yhteyttä kehitystiimiin for analysis: analysointia varten: Error in function Virhe funktiossa Error code Virhekoodi Error text Virheteksti Failed query Epäonnistunut kysely Do you want to keep showing errors? Haluatko jatkaa virheiden näyttämistä? MainWindowInputComment Add a comment for this QSO Lisää kommentti tälle QSO:lle MainWindowInputEQSL Date of the ClubLog upload. ClubLog:in lähetyksen päivämäärä. Date of the eQSL sending. eQSL lähetyksen päivämäärä. Date of the eQSL reception. eQSL:n vastaanoton päivämäärä. Date of the LoTW sending. LoTW:n lähetyksen päivämäärä. Date of the LoTW reception. LoTW vastaanoton päivämäärä. Status of the LoTW sending. LoTW lähetyksren tila. Status of the LoTW reception. LoTW vastaanoton tila. LoTW Sent LoTW lähetetty LoTW Rec LoTW Vastaanotto Status on ClubLog. ClubLog:n tilanne. Status of the eQSL sending. eQSL lähetyksen tilanne. Status of the eQSL reception. eQSL vastaanoton tilanne. ClubLog ClubLog eQSL Sent eQSL Sent eQSL Rec eQSL Vastaanotto MainWindowInputOthers Primary Div Ensisijainen hallinnollinen alue Secondary Div Toissijainen hallinnollinen alue IOTA IOTA Entity Yksikkö Propagation mode Etenemismoodi Select the primary division for this QSO Valitse ensisijainen hallinnollinen alue tälle QSO:lle Select the secondary division for this QSO Valitse toissijainen hallinnollinen alue tälle QSO:lle Select the entity for this QSO Valitse yksikkö tälle QSO:lle Select the propagation mode for this QSO Valitse etenemismoodi tälle QSO:lle Select the IOTA continent for this QSO Valitse IOTA -manner tälle QSO:lle Select the IOTA reference number for this QSO Valitse IOTA -referenssinumero tälle QSO:lle Not Identified Ei tunnistettu Not - Not Identified Ei - Ei tunnistettu MainWindowInputQSL QSL Sent QSL lähetetty QSL Rec QSL Vastaanotto QSL Via QSL -kautta QSL Msg QSL Viesti Status of the QSL sending. QSL lähetyksen tila. Status of the QSL reception. QSL vastaanoton tila. QSL sending information. QSL lähetyksen tiedot. QSL reception information. QSL vastaanoton tiedot. Date of the QSL sending. QSL lähetyksen päivämäärä. Date of the QSL reception. QSL vastaanoton päivämäärä. Message of the QSL. QSL:n viesti. QSL via information. QSL -kautta tieto. MainWindowMyDataTab Watt Wattia Keep this data Säilytä nämä tiedot Data entered in this tab will be copied into the next QSO Tähän kenttään syötetyt tiedot kopioidaan seuraavaan QSO:n Power used for the QSO in watts QSO:n käytetty teho watteina Logging operator's callsign Lokinpitäjän kutsutunnus. Callsign used over the air Lähetyksessä käytetty kutsutunnus My QTH locator Minun QTH lokaattori Power Teho Operator Operaattori Station Callsign Aseman kutsutunnus My Locator Minun lokaattori MainWindowSatTab Keep this data Säilytä nämä tiedot Data entered in this tab will be copied into the next QSO Tähän välilehteen syötetyt tiedot kopioidaan seuraavaan QSO:n Other - Sat not in the list Muut - Satelliitti ei ole listalla Name of the Satellite if not in the list. Select: " Satelliitin nimi, jos ei listalla. Valitse: " " to enable this box. (format like AO-51) " aktivoidaksesi tämän. (Muotoile kuten: AO-51) Satellite mode used Satelliitti tila käytössä Select the satellite you are using Valitse käytettävä satelliitti UpLink band Lähetyslinkin taajuusalue DownLink band Vastaanottolinkin taajuusalue Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab. UpLink Lähetyslinkki DownLink Vastaanottolinkki Satellite Satelliitti Mode Tila DX Locator Other Muuta MHz MHz Not Sat QSO Ei Satelliitti QSO KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name. KLog on havainnut satelliitin nimen, jota se ei tunnista. Jos sen tulisi sen sijaan käyttää jotain tunnettujen satelliittien nimistä sen sijaan, valitse se luettelosta. Vaihtoehtoisesti, voit ottaa yhteyttä kehitystiimiin lisätäksesi uuden satelliitin nimen. The satellite you have in your QSO is: QSO:ssa oleva satelliitti on: Please know that the satellite name will not be saved if it is not in the list so that information may be lost! Huomaa, että satelliitin nimi ei tallennu, jos se ei ole listalla, joten satelliitin tiedot voivat kadota! QObject New One, work it! Uusi, työstä se! Needed, work it! Tarvitaan, työstä se! Worked but not confirmed Työstetty, mutta ei vahvistettu Confirmed Vahvistettu Not identified Ei tunnistettu Database Error Tietokantavirhe KLog DB needs to be upgraded. KLog tietokanta pitää päivittää uudempaan. Do you want to upgrade it now? Haluatko päivittää uudempaan nyt? If DB is not upgraded KLog may not work properly. Jos tietokantaa ei päivitetä, KLog ei välttämättä toimi oikein. KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you. KLog on havainnut aikaisemman lokin tietokannassa. Kaikki tiedot siirretään juuri luotuun DX tyyppiseen lokiin. KLog: Enter Station callsign KLog: Syötä aseman kutsutunnus Enter the station callsign used in this log Syötä tässä lokissa käytetty aseman kutsutunnus Station Callsign Aseman kutsutunnus All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK. Kaikki tiedot siirrettiin oikein. Sinun pitäisi nyt mennä Asetukset-> Lisäasetukset-> Lokit tarkistaaksesi, että kaikki on OK. Updating mode information... Päivitetään tilatietoja... Abort updating Keskeytä päivittäminen QSO: QSO: Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel? Tämän päivityksen peruuttaminen aiheuttaa epäjohdonmukaisuuksia ja mahdollisen tietojen menettämisen. Haluatko silti peruuttaa? Updating bands information... Päivitetään taajuusalue tiedot... Updating bands information in %1 status... Päivitetään taajuusalue tiedot %1 tila... Progress: Eteneminen: Updating mode information in %1 status... Päivitetään tilatiedot %1 tila... Updating DXCC award information... Päivitetään DXCC palkinto tiedot... Updating DXCC Award information... Päivitetään DXCC palkinto tiedot... Updating WAZ award information... Päivitetään WAZ palkintotiedot... Install wizard was canceled before completing... Asennusohjelma keskeytettiin ennen valmistumista... Do you want to remove the KLog dir from your disk? Haluatko poistaa KLog -kansion kiintolevyltä? Your KLog dir has been removed KLog -kansio on poistettu Thank you for running KLog! Kiitos KLogin käyttämisestä! I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk. En voinut poistaa KLog -kansiota. Sinun tulee tehdä se manuaalisesti, jos haluat poistaa sen kiintolevyltä. Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk. KLog -kansiota ei voitu poistaa. Sinun tulee tehdä se manuaalisesti, jos haluat poistaa sen kiintolevyltä. Remember that your KLog dir is on your system... Muista että KLog -kansio on kiintolevyllä... Updating DXCC information... Päivitetään DXCC tiedot... SearchWidget &Clear T&yhjennä &Export Highlighted &Vie Korostetut &Select All Valitse &kaikki &Search &Etsi All Kaikki Clear the searches. Tyhjennä etsinnät Export the search result to an ADIF file. Vie etsinnän tulokset ADIF -tiedostoon. Select/Unselect all the QSOs shown. Valitse/Poista valinnasta kaikki näkyvillä olevat QSO:t. Search in the log. Etsi lokista. Search in all logs. Etsi kaikista lokeista. Enter the QRZ to search for. Syötä etsittävä QRZ. Search results. Etsinnän tulokset. QRZ QRZ Date/Time Päivämäärä/aika Band Taajuusalue Mode Moodi QSL Sent QSL Lähetetty QSL Rcvd QSL Vastaanotettu Station Callsign Aseman kutsutunnus ID ID &Clear selection T&yhjennä valinta Save File Tallenna tiedosto QSL Send QSL lähetys &Delete &Poista Delete a QSO Poista QSO &Edit QSO &Muokkaa QSO:ta Edit this QSO Muokkaa tätä QSO:ta Via &bureau &bureau:n kautta Send this QSL via bureau Lähetä tämä QSL bureau:n kautta D&irect D&irect Send this QSL via direct Lähetä tämä QSL direct:in kautta &Request my QSL Pyy&dä minun QSL Mark my QSL as requested Merkitse minun QSL pyydetyksi Via Direct && mark DX QSL as requested Direct:in kautta && merkitse DX QSL pyydetyksi Send this QSL via direct & mark DX QSL as requested Lähetä tämä QSL direct:in kautta & merkitse DX QSL pyydetyksi Via Bureau && mark DX QSL as requested Bureau:n kautta && merkitse DX QSL pyydetyksi Send this QSL via bureau & mark DX QSL as requested Lähetä tämä QSL bureau:n kautta & merkitse DX QSL pyydetyksi &Request the QSL Pyydä QSL Mark the QSL as requested Merkitse QSL pyydetyksi Via bureau && mark my QSL as requested Bureau:n kautta && merkitse minun QSL pyydetyksi QSL received via bureau & mark my QSL as requested QSL vastaanotettu bureau:n kautta & merkitse minun QSL pyydetyksi Via bureau Bureau:n kautta QSL received via bureau QSL vastaanotettu bureau:n kautta Direc&t && mark as my QSL requested Direc&t && merkitse minun QSL pyydetyksi QSL received via direct & mark my QSL as requested QSL vastaanotettu direct:in kautta & merkitse minun QSL pyydetyksi Direc&t Direc&t QSL received via direct QSL vastaanotettu direct:in kautta You have requested to delete the QSO with: Olet pyytänyt poistamaan QSO:n joissa on: Are you sure? Oletko varma? Needed QSO to send the QSL Tarvittava QSO, QSL:n lähetystä varten My QSL requested to be sent QSL pyydetty lähetettäväksi DX QSL pending to be received DX QSL odottaa vastaanottoa SetupDialog My Data Minun Tiedot Bands/Modes Taajuusalueet/Moodit DX-Cluster DX-Klusteri Colors Värit Misc Sekalaiset World Editor Maailma Editori Logs Lokit ClubLog ClubLog Cancel Peru OK OK Config Dialog Asetusvalikko User data Käyttäjätiedot D&X-Cluster D&X-Klusteri You need to enter at least one log in the Logs tab. Ainakin yksi loki on syötettävä Lokit -välilehdellä. World Maailma DB has not been moved to new path Tietokantaa ei ole siirretty Go to the Mene Misc tab Sekalaiset -välilehdelle and click on Ja klikkaa Move DB Siirrä tietokanta or the DB will not be moved to the new location. tai tietokantaa ei siirretä. You need to enter at least a valid QRZ. Ainakin olemassaoleva QRZ on syötettävä. User tab Käyttäjä -välilehdelle and enter valid QRZ. ja syötä olemassaoleva QRZ. You have not selected the kind of log you want. Et ole valinnut minkälaisen lokin haluat. You will be redirected to the Log tab. Please add and select the kind of log you want to use. Sinut ohjataan lokit -välilehdelle. Lisää, ja valitse millaista lokia haluat käyttää. SetupEntityDialog Entity Yksikkö Name of the Entity Yksikön nimi CQ CQ CQ zone CQ vyöhyke ITU ITU ITU zone ITU vyöhyke Latitude Leveysaste Longitude of the Entity Yksikön pituusaste Longitude Pituusaste UTC UTC Local time difference to UTC Paikallinen aikaero UTC:hen Main prefix Ensisijainen etuliite Main prefix of the entity Yksikön ensisijainen etuliite ARRL ID ARRL ID Prefixes Etuliitteet Comma separated possible prefixes, e.g. EA1, EA2, ... Mahdolliset etuliitteet, pilkulla eroteltuina, esim. OH1, OH2, ... Date of the deletion Poistamisen päivämäärä Deleted Poistettu Cancel Peru OK OK Entity Dialog Yksikköasetukset SetupPageBandMode Bands Taajuusalueet Modes Moodit SetupPageClubLog &Callsign &Kutsutunnus ClubLog &password ClubLog &salasana ClubLog &email ClubLog s&ähköposti Enter the email you used to register in ClubLog. Syötä sähköposti jota käytit ClubLog:in rekisteröitymiseen. Enter the callsign you used to register in ClubLog. Syötä kutsutunnus jota käytit ClubLog:in rekisteröitymiseen. Enter your password in ClubLog. Syötä ClubLog salasanasi. &Send QSOs in real time &Lähetä QSO:t reaaliajassa &Activate ClubLog &Aktivoi ClubLog Use QSO Station &Callsign Käytä QSO Aseman Kutsutunnusta Send each QSO to ClubLog in real time, as they are added (or modified) in KLog Lähetä jokainen QSO ClubLog:iin reaaliajassa, samalla kun ne lisätään (tai niitä muokataan) KLog:issa Starts the ClubLog support in KLog Käynnistää ClubLog -tuen KLog:issa Use the Station Callsign defined in each QSO instead of the one defined here Käytä jokaisessa QSO:ssa määritettyä aseman kutsutunnusta, tässä määritetyn sijaan SetupPageColors New One Uusi Needed in this band Tarvittu tällä taajuussalueella Worked in this band Työstetty tällä taajuusalueella Confirmed in this band Vahvistettu tällä taajuusalueella Default Oletus Choose a color Valitse väri SetupPageDxCluster Add Lisää Delete Poista Show &HF spots Näytä &HF Spotit Show V/&UHF spots Näytä V/&UHF spotit Show W&ARC spots Näytä W&ARC spotit Show &worked spots Näytä &työstetyt spotit Show &confirmed spots Näytä &vahvistetut spotit Show ANN/&FULL messages Näytä ANN/&FULL viestit Show WW&V messages Näytä WW&V viestit Show WC&Y messages Näytä WC&Y viestit DX Spots DX Spotit Messages Viestit KLog: Add a DXCluster server KLog: Lisää DX-Klusteripalvelin Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default: Lisää osoite ja :portti Esimerkiksi: dxfun.com:8000 Jos porttia ei syötetä, Käytetään oletusarvoa 41112: SetupPageLogs &New &Uusi &Edit &Muokkaa &Remove &Poista Add a new log Lisää uusi loki Edit the selected log Muokkaa valittua lokia Remove the selected log Poista valittu loki Select the log you want to open Valitse loki jonka haluat avata KLog KLog Do you really want to remove this log? Haluatko varmasti poistaa tämän lokin? All the QSOs from this log will be also deleted... Lokista poistetaan myös kaikki QSO:t... Log has not been removed. (#3) Lokia ei ole poistettu (#3) Log has not been removed. (#2) Lokia ei ole poistettu (#2) Log has not been removed. (#1) Lokia ei ole poistettu (#1) ID ID Date Päivämäärä Station Callsign Aseman kutsutunnus Operators Operaattorit Comments Kommentit Type Tyyppi An error has occurred showing the following error code: On tapahtunut virhe seuraavalla koodilla: KLog - SetupPageLogs KLog - Lokisivujen asetus SetupPageLogsNew &Date P&äivämäärä &Station Callsign A&seman kutsutunnus &Operators Ope&raattorit Comm&ent Komm&entti &Ok &Ok &Cancel Peru Select categories Valitse kategoriat Callsign used for this log Tässä lokissa käytettävä asematunnus Comma separated list of operators: callsign1, callsign2 Pilkulla eroteltu lista operaattoreista: kutsutunnus1, kutsutunnus2 Start date of this log Tämän lokin alkamispäivämäärä Add a comment about this log Lisää kommentti tästä lokista &Type of Operation &Toiminnan tyyppi Select the kind of operation for this log Valitse toiminnan tyyppi tätä lokia varten &Mode Category &Moodi kategoria Select the mode category Valitse moodi kategoria O&perators Category Operaattorit kategoria Select the operators category Valitse operaattorit kategoria &Assisted Category Avustettu kategoria Select the assisted category Valitse avustettu kategoria Po&wer Category Teho kategoria Select the power category Valitse teho kategoria &Bands Category Taajuusalue kategoria Select the bands category Valitse taajuusalue kategoria O&verlay Yleisnäkymä Select the Overlay category Valitse yleisnäkym kategoria Categories not OK Kategoriat ok You need to enter a valid QRZ in the Station Callsign box. The log will not be opened. Aseman kutsutunnus lokeroon tulee syöttää toimiva QRZ. Lokia ei avata. You selected an invalid combination. The log will not be opened. Valitsit väärän yhdistelmän. Lokia ei avata. Categories OK Kategoriat OK SetupPageMisc &Imperial system &Empiirinen järjestelmä &Log in real time &Kirjaa lokiin reaaliajassa &Time in UTC UTC &Aika &Save ADIF on exit &Tallenna ADIF kun ohjelma suljetaan Use this &default filename Käytä tätä &oletus tiedostonimeä Mark &QSO to send QSL when QSL is received Merkitse &QSO läheettämään QSL kun QSL on vastaanotettu Complete QSO with previous data Täydennä QSO edellisillä tiedoilla Show the Station &Callsign used in the search box Näytä hakukentässä käytetty &Asematunnus &Reset to My Data for all QSOs &Palauta minun tiedot kaikkiin QSO:ihin &Check for new versions automatically &Tarkista automaattisesti uusien versioiden varalta &Provide Info for statistics &Jaa tietoja tilastointia varten Browse Selaa Move DB Siirrä tietokanta QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours. QSO:t merkataan QSL:n lähetystä odottaviksi, jos DX QSL on saapunut, etkä ole lähettänyt omaasi. The search box will show also the callsign on the air to do the QSO. Etsintälokero näyttää kutsussa olevan kutsutunnuksen tehdäkseen QSO:n. All the data from the My Data tab will be used or data from the previous QSO will be maintained. Kaikki tiedot Minun Tiedot -välilehdeltä käytetään, tai tiedot edellisestä QSO:sta Säilytetään. Check if there is a new release of KLog available every time you start KLog. Tarkista KLog päivitysten varalta joka käynnistyskerralla. If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog. Jos päivityksien tarkistus on valittu, KLog lähettää kehitystiimille kutsutunnuksesi, KLog version, sekä Käyttöjärjestelmän tiedot, KLogin kehitystä varten. Check it for Imperial system (Miles instead of Kilometres). Valitse empiiristä järjestelmää varten (Mailit, kilometrien sijaan). Select to use real time. Valitse käyttääksesi oikeaa aikaa. Select to use UTC time. Valitse käyttääksesi UTC -aikaa Select if you want to save to ADIF on exit. Valitse jos haluat tallentaa ADIF-tiedostoon kun ohjelma suljetaan. Select to use the following name for the logfile without being asked for it again. Valitse käyttääksesi seuraavaa lokitiedoston nimeä ilman että sitä kysytään joka kerta. Complete the current QSO with previous QSO data. Täydennä nykyinen QSO edellisen QSO:n tiedoilla. This is the default file where ADIF data will be saved. Tämä on oletustiedosto johon ADIF tiedot tallennetaan. This is the directory where the database (logbook.dat) will be saved. Tämä on kansio johon tietokanta (logbook.dat) tallennetaan. Click to change the default ADIF file. Napsauta vaihtaaksesi oletus ADIF -tiedostoa. Click to change the path of the database. Napsauta vaihtaaksesi tietokannan sijainti. Click to move the DB to the new directory. Napsauta Siirtääksesi tietokanta uuteen kansioon. Open File Avaa tiedosto Select Directory Valitse Kansio This is the directory where DB (logbook.dat) will be saved. Tämä on kansio johon tietokanta (logbook.dat) tallennetaan. Please specify an existing directory where the database (logbook.dat) will be saved. Määritä olemassaoleva kansio johon tietokanta (lokbook.dat) tallennetaan. File moved Tiedosto on siirretty File copied Tiedosto on kopioitu File NOT copied Tiedostoa EI ole kopioitu The target directory does not exist. Please select an existing directory. Kohdekansiota ei ole olemassa. Valitse olemassaoleva kansio. SetupPageUserDataPage &Personal data &Henkilökohtaiset tiedot Station &data Aseman &tiedot Enter your name Syötä nimesi Enter your address - 1st line Syötä osoitteesi - 1. rivi Enter your address - 2nd line Syötä osoitteesi - 2. rivi Enter your address - 3rd line Syötä osoitteesi - 3. rivi Enter your address - 4th line Syötä osoitteesi - 4. rivi Enter your city Syötä kaupunki Enter your zip code Syötä postinumero Enter your province or state Syötä maakunta Enter your country Syötä maa &Name &Nimi &Address &Osoite Cit&y &Kaupunki &Zip Code &Postinumero Pro&v/State Maak&unta Countr&y &Maa Enter your information for rig Syötä laitekokoonpanosi tiedot Enter your information for antenna Syötä antennitiedot Enter your power information Syötä virtalähteen tiedot &Rig 1 Kokoonpano 1 R&ig 2 Kokoonpano 2 Ri&g 3 Kokoonpano 3 Antenna &1 Antenni &1 Antenna &2 Antenni &2 Antenna &3 Antenni &3 Po&wer Vi&rtalähde Enter the station callsign that will be used for logging Syötä asematunnus jota käytetään lokissa Enter the operators (comma separated if more than one). Syötä operaattorit (pilkulla eroteltuina jos useita). Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign. Syötä aseman lokaattori. Vaihtoehtoisesti KLog voi käyttää arvioitua lokaattoria kutsutunnuksesi perusteella. &QRZ &QRZ &Operators &Operaattorit &CQ Zone &CQ Alue &ITU Zone &ITU Alue &Locator &Lokaattori &Locator (not valid) Lokaattori (virheellinen) SetupPageWorldEditor An entities information file (cty.csv) has been detected in your KLog folder and will be loaded. KLog kansiostasi löytyy yksikkötiedot -tiedosto (cty.csv)joka ladataan. No entities information file (cty.csv) has been detected in your KLog folder. KLog kansiostasi ei löydy yksikkötiedot -tiedostoa (cty.csv). KLog will not be able to show entities information. KLog ei pysty näyttämään yksikkötietoja. Prefix Etuliite Entity Yksikkö ARRL ID ARRL ID Continent Manner CQ Zone CQ Vyöhyke ITU Zone ITU Vyöhyke UTC UTC Latitude Leveysaste Longitude Pituusaste Deleted Poistettu Since Date Lähtien päivämäärästä To Date Päivämäärään asti Open File Avaa Tiedosto BigCTY (*.csv) BigCTY (*.csv) Entities information has been updated. Yksikkötiedot on päivitetty. Entities information has not been updated. Yksikkötietoja ei ole päivitetty. ShowErrorDialog KLog Message KLog viesti SoftwareUpdateDialog Ok Ok KLog update KLog päivitys Congratulations! Onnittelut! Your KLog has been updated. KLog on päivitetty. You already have the latest version. Sinulla on jo viimeisin versio. StartWizard KLog - The free hamradio logging program KLog - Ilmainen amatööriradio kirjausohjelma Quit Setup Lopeta asennus Setup is not complete yet. Are you sure you want to quit setup? Asennus ei ole vielä valmis. Oletko varma että haluat lopettaa? World Entity Yksikkö Continent Manner Reading cty.csv... Luetaan cty.csv... Abort reading Keskeytä luku eLogClubLog Host not found! Isäntää ei löydy! Timeout error! Aikakatkaisu virhe! It seems to be a PASSWORD ERROR; check your password. Virhe näyttää olevan PASSWORD ERROR; tarkista salasanasi. KLog - ClubLog KLog - ClubLog It seems that your ClubLog password is not correct. Näyttää siltä että ClubLog salasanasi on väärä. Please check your password in the setup. ClubLog uploads will be disabled. Tarkista salasanasi asetuksista. ClubLog päivitykset eivät ole käytössä. Undefined error... Määrittelemätön virhe... Callsign missing Kutsutunnus puuttuu Invalid callsign Väärä kutsutunnus Skipping SWL callsign Ohitetaan SWL kutsutunnus Callsign is your own call Kutsutunnus on oma kutsusi Invalid callsign with no DXCC mapping Virheellinen kutsutunnus, ilman DXCC kartoitusta Updated QSO QSO päivitetty Invalid ADIF record Virheellinen ADIF tieto Missing ADIF record Puuttuva ADIF tieto Test mode - parameters ok, no action taken Testitila - parametrit ok, toimintoja ei tehty Excessive API Usage Liiallinen API:n käyttö Internal Error Sisäinen Virhe Rejected Hylätty QSO Duplicate QSO Duplikaatti QSO Modified QSO muokattu Missing Login Puuttuva sisäänkirjaus QSO OK QSO OK Upload denied Lataus kielletty No callsign selected Ei valittua kutsutunnusta No match found Vastaavuutta ei löytynyt Dropped QSO Pudotettu QSO OK OK Login rejected Sisäänkirjautuminen evätty Rejected: Callsign is your own call Hylätty: Kutsutunnus on oma kutsusi klog-0.9.2.9/translations/klog_ca.ts0000644000076700000620000056470013233376355015311 0ustar staff AboutDialog About KLog Quant al KLog You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog. També ens podeu ajudar enviant informes d'error o col·laboracions petites de codi, idees o el que penseu que podria millorar el KLog. Authors Autors By Per Please know that this is an BETA release and it may contain many bugs.<br>Backup your data before using this software! Tingueu present que aquesta és un llançament BETA i podria contenir algun error.<br>Feu una còpia de seguretat abans d'usar aquest programari! Author Autor KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing. El KLog s'ha reescrit completament a partir de la 0.6.2 per ser capaç de proporcionar una aplicació multiplataforma que s'executa en els sistemes operatius principals (Linux, macOS i Windows) i proporciona funcionalitats noves que el KLog no feia. KLog is a free logbook for hamradio operators. El KLog és un registre lliure per a operadors de radioafició. Please provide your review in KLog's eHam review page: Si us plau, proporcioneu comentaris a la pàgina de revisions del KLog a eHam: today avui Main developer Desenvolupador principal KLog is developed by a very small team and you are invited to join! El KLog està desenvolupat per un equip molt petit i esteu convidat a unir-vos-hi! KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs Els desenvolupadors del KLog han inclòs una funcionalitat que informa de vàries dades d'usuari al servidor del KLog amb l'únic propòsit d'identificat el nombre de versions instal·lades, per enfocar el desenvolupament cap a una direcció o una altre tenint en compte les necessitats dels usuaris At present, the data that is provided is the following: Actualment, les dades proporcionades són les següents: Be aware that you can enable/disable this feature from the Misc tab in the Setup page Tingueu present que podeu activar/desactivar aquesta funcionalitat des de la pestanya Varis a la pestanya de configuració Translators bring KLog into your language. They are really an important part of the KLog development team. Els traductors adapten el KLog al vostre idioma. Són una part important de l'equip de desenvolupament del KLog. Find more information and the latest release at Podeu trobar més informació i l'últim llançament a If you want to provide support you are welcome to join the Si voleu col·laborar, sou benvingut a unir-vos a KLog development mailing list la llista de correu del desenvolupament del KLog ! ! If KLog is still not in your language and you want to help us, you are welcome to contact us through the Si el KLog encara no és en el vostre idioma i voleu ajudar-nos, sou benvingut a contactar-nos a través dewelcome to contact us through the Translators Traductors Privacy advisory Avís de privadesa Callsign Indicatiu KLog version Versió del KLog Operating system Sistema operatiu KLog KLog Privacy Privadesa CTYPage Country data download Baixa les dades de països KLog needs country data... El KLog necessita dades de països... &Download &Baixa &Ignore &Ignora Country data needed Cal les dades de països KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information. El KLog usa el fitxer «cty.csv» de http://www.country-files.com/ per obtenir la informació DXCC. You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do. Cal baixar el fitxer «cty.csv» si voleu que el KLog mostri els països, localitzadors, ... dels QSO que feu. Click on Download to download now. Cliqueu a Baixa per baixar ara. KLog KLog I can't find the host. Please check your network and try again Do you want to try again? No s'ha pogut trobar la màquina. Reviseu la configuració de xarxa i proveu de nou Voleu tornar-ho a intentar? DXCCStatusWidget Update Actualitza ID ID Entity Entitat DXClusterWidget Connect Connecta Clear Neteja Click on connect to connect to the DX-Cluster Cliqueu a Connecta per connectar al DX-Cluster KLog DXCluster Kontest DXCluster DXCluster del KLog Click on Connect to connect to the DX-Cluster server Cliqueu a Connecta per connectar al servidor de DX-Cluster Trying to connect to the server S'intenta connectar amb el servidor The connection was refused by the peer. Make sure the DXCluster server is running, and check that the host name and port settings are correct. La connexió ha estat rebutjada pel servidor. Assegureu-vos que el servidor de DXCluster està executant-se i comproveu que el nom de la màquina i el port siguin correctes. The following error occurred: %1. Ha ocorregut el següent error: %1. Connected to server Connectat al servidor KLog message Kontest message Missatge del KLog Enter your callsign to connect to the cluster: Introduïu el vostre indicatiu per connectar al clúster: Enter your password to connect to the cluster: (Just hit enter for no password) Introduïu la contrasenya per connectar al clúster: (premeu retorn si no hi ha contrasenya) Not logged on, you may need to enter your callsign again. No esteu connectat, cal tornar a introduir el vostre indicatiu un altre cop. Disconnect Desconnecta The host was not found. Please check: No s'ha trobat la màquina. Comproveu: - your network connection; - the host name and port settings. - la connexió de xarxa; - la configuració del nom de màquina i el port. Enter here the commands to be sent to the DX-Cluster server Introduïu aquí les ordres a enviar al servidor de DX-Cluster Connection closed by the server Connexió tancada pel servidor Send Envia DataProxy_SQLite Software version in DB is null La versió del programari a la BD és nul No query failed No ha fallat cap consulta KLog DXCC DXCC del KLog All QSOs have been updated with a DXCC. Tots els QSO s'han actualitzat amb un DXCC. DownLoadCTY Download of cty.csv failed with the following error code: La baixada del «cty.csv» ha fallat amb el codi d'error següent: Download of cty.csv done. La baixada de «cty.csv» ha finalitzat. There is already a cty.csv file in the folder but it will be replaced with the new one. Ja hi ha un fitxer «cty.csv» a la carpeta, però se substituirà pel nou. Could not open No s'ha pogut obrir for writing. per escriptura. FileManager Reading ADIF file... S'està llegint el fitxer ADIF... Abort reading Interromp la lectura The log that you have selected contains more than just one station callsign. El registre que heu seleccionat conté més d'un indicatiu d'estació. Please select the station callsing you want to export the log from: Seleccioneu l'indicatiu d'estació pel que voleu exportar el registre: Station Callsign: Indicatiu d'estació: Define Station Callsign Defineix l'indicatiu d'estació You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here. No heu seleccionat cap indicatiu. El KLog exportarà els QSO sense cap indicatiu d'estació definit i aquells amb l'indicatiu que introduïu aquí. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Introduïu l'indicatiu emprat en aquest registre o deixeu-ho buit pels QSO sense indicatiu d'estació definit: Writing ADIF file... Escrivint el fitxer ADIF... Abort writing Interromp l'escriptura Exporting LoTW ADIF file... S'està exportant el fitxer LoTW ADIF... Writing ADIF file... QSO: S'està escrivint el fitxer ADIF... QSO: Reading LoTW file... S'està llegint el fitxer LoTW... There are more than one log in this logfile. All logs will be imported in the current log. Do you want to continue? Hi ha més d'un registre en aquest fitxer de registre. S'importaran tots els registres del registre actual. Voleu continuar? Importing ADIF file... QSO: S'està important el fitxer ADIF... QSO: You have cancelled the file export. The file will be removed and no data will be exported. Do you still want to cancel? Heu cancel·lat l'exportació del fitxer. El fitxer s'eliminarà i no s'exportarà cap dada. Encara voleu cancel·lar? Do you want to continue with the current file? Voleu continuar amb el fitxer actual? This log seems to lack of RST-TX information. Sembla que aquest registre li manca informació de RST-TX. Click on Yes to add a default 59 to all QSO with a similar problem. Cliqueu a Sí per afegir un 59 per defecte a tots els QSO amb un problema semblant. If you select NO, the QSO may not be imported. Si seleccioneu No, el QSO pot no importar-se. This log seems to lack of RST-RX information. Sembla que aquest registre li manca informació de RST-RX. - The band missing and the following call: - Manca la banda i l'indicatiu següent: - The call missing but was done at this time: - Manca l'indicatiu però s'ha fet a hores d'ara: - The mode missing and the following call: - Manca el mode i l'indicatiu següent: - The date missing and the following call: - Manca la data i l'indicatiu següent: - The time missing and the following call: - Manca l'hora i l'indicatiu següent: You have canceled the file export. The file will be removed and no data will be exported. Heu cancel·lat l'exportació del fitxer. El fitxer s'eliminarà i no s'exportarà cap dada. Do you still want to cancel? Encara voleu cancel·lar? QSO: QSO: No station callsign has been selected and therefore no log will be exported No s'ha seleccionat cap indicatiu, i per tant no s'exportarà cap registre Writing Cabrillo file... S'està escrivint el fitxer Cabrillo... KLog: Cabrillo Log Export not implemented Kontest: Cabrillo Log Export not implemented KLog: L'exportació del registre en format Cabrillo no està implementada I am sorry but the Cabrillo Export To File feature has still not been implemented. Ho sentim però la funció d'exportar Cabrillo encara no està implementada. There is more than one log in this logfile. All logs will be imported into the current log. Do you want to continue? Importing ADIF file... It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported) You have cancelled the file import. The file will be removed and no data will be imported. This QSO is not including the minimum data to consider a QSO as valid!. Aquest QSO no inclou les dades mínimes per a considerar-se un QSO vàlid! Please edit the ADIF file and make sure that it include at least: Editeu el fitxer ADIF i assegureu-vos que inclou, com a mínim: and i This QSO had: Aquest QSO té: KLog: Not all required data found! KLog: No s'han trobat totes les dades necessàries! KLog: No RST TX found! KLog: No s'ha trobat RST TX! KLog: No RST RX found! KLog: No s'ha trobat RST RX! InfoWidget 10M 10M 15M 15M 20M 20M 40M 40M 80M 80M 160M 160M 2M 2M 6M 6M 12M 12M 17M 17M 30M 30M 70CM 70CM Continent Continent Prefix Prefix CQ CQ ITU ITU Short Path Camí curt Long Path Camí llarg Degree Grad Grad Miles Milles Km Km IntroPage Welcome to KLog! Welcome to Kontest! Benvingut al KLog! Welcome to KLog! - brought to you under the terms of the GPL! Benvingut al KLog! - Distribuït sota els termes de la GPL! Welcome to KLog Benvingut al KLog This looks like it's the first time you've run KLog on this computer. Sembla que aquesta és la primera vegada que s'executa el KLog en aquest ordinador. KLog is a free hamradio logging program that can run on Linux macOS and Windows. El KLog és un programa lliure d'enregistrament de radioafició que es pot executar en el Linux, MacOS i Windows. It is designed to provide general purpose, DX and contest logging. Està dissenyat per proporcionar enregistrament de propòsit general, DX i concurs. It supports QSL management, import and export of ADIF Permet la gestió de QSL, importació i exportació de formats and Cabrillo file formats and many other features... de fitxer ADIF i Cabrillo, i moltes altres funcionalitats... Before you can start using KLog, you will be asked to: Abans de començar a usar el KLog, us demanarem: Acknowledge to the terms of the license. Reconeixement dels termes de la llicència. Download the DX entities information. Baixada de la informació de les entitats DX. Enter your callsign, CQ zone, etc. and main configuration. Introduïu el vostre identificador, zona CQ, etc. i configuració principal. Enjoy KLog and contact the development team if you have any suggestions! Gaudiu del KLog i contacteu amb l'equip de desenvolupament si teniu qualsevol suggeriment! LicPage KLog License information Informació de la llicència del KLog Welcome to KLog!- brought to you under the terms of the GPL! Benvingut al KLog! - Distribuït sota els termes de la GPL! Acknowledge Reconeixement Be aware that KLog is free software. Tingueu present que el KLog és programari lliure. LogModel Date Data Time Hora QRZ QRZ Band Banda Mode Mode RSTtx RSTtx RSTrx RSTrx Comment Comentari LogWindow QSL Send QSL enviada QSL Rcvd QSL rebuda &Delete &Suprimeix Delete a QSO Suprimeix un QSO &Edit QSO &Edita QSO Edit this QSO Edita aquest QSO Via &bureau Via &bureau Send this QSL via bureau Envia aquesta QSL via bureau D&irect D&irecta Send this QSL via direct Envia aquesta QSL via directa Via bureau Via bureau QSL &received via bureau QSL &rebuda via bureau Direct Directa QSL received via direc&t QSL rebuda via direc&ta You have requested to delete this QSO. Heu sol·licitat suprimir aquest QSO. Are you sure? Esteu segur? MainWindow &Clear &Neteja Recalculate Recalcula Click to recalculate the award status Cliqueu per recalcular l'estat dels diplomes Starting KLog Starting Kontest Iniciant KLog &Add &Afegeix Status bar... Barra d'estat... DX Entity Entitat DX &Log Window Finestra de registre &Score Window Fine&stra de puntuació MHz MHz An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: Ha ocorregut un error inesperat en intentar afegir el QSO al registre. Si el problema persisteix, contacteu amb el desenvolupador per a la seva anàlisi: You have selected an entity: Heu seleccionat una entitat: that is different from the KLog proposed entity: que és diferent de l'entitat proposada pel KLog: Import an ADIF file into the current log. Importa un fitxer ADIF dins el registre actual. Export the current log to an ADIF logfile. Exporta el registre actual a un fitxer de registre ADIF. Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program). Exporta tots els QSO sol·licitant QSL a un fitxer ADIF (p. ex. per importar-los a un programa d'impressió d'etiquetes QSL). &Export ADIF for LoTW... &Exporta ADIF per a LoTW... Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW! Exporta un fitxer ADIF per enviar a LoTW. Recordeu signar-lo amb TQSL abans de pujar-lo a LoTW! Print your log. Imprimeix el registre. Opens the data folder of KLog. Obre la carpeta de dades del KLog. Go through the log reusing previous QSOs to fill missing information in other QSOs. Explora el registre reutilitzant els QSO previs per omplir la informació que manca en altres QSO. Fill in DXCC data Omple les dades DXCC Go through the log filling QSOs without a DXCC defined. Explora el registre omplint els QSO sense cap DXCC definit. QSL tools... Eines QSL... Shows QSOs for which you should send your QSL and request the DX QSL. Mostra els QSO pels que cal enviar la vostra QSL i sol·licitar la QSL DX. Shows the DX-QSL that has been requested or QSLs has been sent with no answer. Mostra les DX-QSL que s'han sol·licitat o les QSL que s'han enviat sense resposta. Shows the DX-QSL that has been requested. Mostra les DX-QSL que s'han sol·licitat. LoTW tools... Eines LoTW... Mark all non sent QSOs in this log as queued to be uploaded. Marca tots els QSO no enviats en aquest registre com a posats en cua per a ser pujats. Mark all non sent QSOs as queued to be uploaded. Marca tots els QSO no enviats com a posats en cua per a ser pujats. Mark as sent all queued QSO of this log Marca com a enviats tots els QSO d'aquest registre Mark all queued QSOs in this log as sent to LoTW. Marca tots els QSO posats en cua d'aquest registre com a enviats al LoTW. Mark all queued QSO as sent Marca tots els QSO posats en cua com a enviats For updated DX-Entity data, update cty.csv. Per a dades DX-Entity actualitzades, actualitzeu el «cty.csv». KLog LoTW KLog LoTW All pending QSO of this log has been marked as queued for LoTW! Tots els QSO pendents d'aquest registre s'han marcat com a posats en cua pel LoTW! There was a problem to mark all pending QSO of this log as queued for LoTW! Hi ha hagut un problema en marcar tots els QSO pendents d'aquest registre com a posats en cua pel LoTW! All pending QSO has been marked as queued for LoTW! Tots els QSO pendents s'han marcat com a posats en cua pel LoTW! All queued QSO of this log has been marked as sent for LoTW! Tots els QSO posats en cua d'aquest registre s'han marcat com a enviats pel LoTW! There was a problem to mark all queued QSO of this log as sent for LoTW! Hi ha hagut un problema en marcar tots els QSO posats en cua d'aquest registre com a enviats pel LoTW! The log that you have selected contains more than just one station callsign. El registre que heu seleccionat conté més d'un indicatiu d'estació. Export to ADIF... Export all logs to ADIF... Export Requested QSL to ADIF... Export ADIF for LoTW... Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW. Ara podeu anar al menú Fitxer per exportar el fitxer LoTW ADIF i pujar-lo a LoTW. Please select the station callsing you want to mark as sent to LoTW: Seleccioneu l'indicatiu d'estació que voleu marcar com a enviat a LoTW: Station Callsign: Indicatiu d'estació: Define Station Callsign Defineix l'indicatiu d'estació You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here. No heu seleccionat cap indicatiu. El KLog marcarà els QSO sense cap indicatiu d'estació definit i aquells amb l'indicatiu que introduïu aquí. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Introduïu l'indicatiu emprat en aquest registre o deixeu-ho buit pels QSO sense indicatiu d'estació definit: No station callsign has been selected and therefore no log will be marked No s'ha seleccionat cap indicatiu, i per tant no es marcarà cap registre All queued QSO has been marked as sent to LoTW! Tots els QSO posats en cua s'han marcat com a enviats al LoTW! There was a problem to mark all queued QSO of this log as sent to LoTW! Hi ha hagut un problema en marcar tots els QSO posats en cua d'aquest registre com a enviats al LoTW! ADIF file Fitxer ADIF Cabrillo files Fitxers Cabrillo Any file Qualsevol fitxer The selected log is not existing or it is still empty. El registre seleccionat no existeix o encara és buit. Click Yes and KLog will open an empty log. Cliqueu Sí i el KLog obrirà un registre buit. Click No and KLog will select another log with data. Cliqueu No i el KLog seleccionarà un altre registre amb dades. You can modify the config file accordingly, if needed. D'acord amb això, podeu modificar el fitxer «config», si cal. TX Frequency in MHz. Freqüència de TX en MHz. RX Frequency in MHz. Freqüència de RX en MHz. Power used by the DX. Potència usada pel DX. Logging operator's callsign. Indicatiu de l'operador del registre. Callsign used over the air. Indicatiu usat a l'aire. My QTH locator. El meu localitzador QTH. Name of the DX. Nom del DX. QTH of the DX. QTH del DX. Locator of the DX. Localitzador del DX. QRZ of the QSO. QRZ del QSO. TX RST. RST TX. RX RST. RST RX. TX Exchange. Intercanvi TX. RX Exchange. Intercanvi RX. Band of the QSO. Banda del QSO. Mode of the QSO. Mode del QSO. Date of the QSO. Data del QSO. Time of the QSO. Hora del QSO. Add the QSO to the log. Afegeix el QSO al registre. Clears the QSO entry. Neteja l'entrada QSO. Number of confirmed DXCC entities. Nombre d'entitats DXCC confirmades. Number of worked DXCC entities. Nombre d'entitats DXCC treballades. Number of confirmed WAZ zones. Nombre de zones WAZ confirmades. Number of worked WAZ zones. Nombre de zones WAZ treballades. Number of confirmed local references. Nombre de referències locals confirmades. Number of worked local references. Nombre de referències locals treballades. Number of confirmed QSOs. Nombre de QSO confirmats. Number of worked QSOs. Nombre de QSO treballats. Number of DXCC worked on the selected year. Nombre de DXCC treballats durant l'any seleccionat. Number of CQ Zones worked on the selected year. Nombre de zones CQ treballades durant l'any seleccionat. Score for the DXMarathon on the selected year. Puntuació per al DXMarathon durant l'any seleccionat. Select the year you want to check. Seleccioneu l'any que voleu comprovar. Status of the DX entity. Estat de l'entitat DX. Name of the DX entity. Nom de l'entitat DX. Log Registre An unexpected error ocurred!! Hi ha hagut un error inesperat!! If the problem persists, please contact the developers Si el problema persisteix, contacteu amb els desenvolupadors for analysis: per a l'anàlisi: Error in function Error a la funció Error code Codi d'error Error text Text de l'error Failed query Ha fallat la consulta Do you want to keep showing errors? Voleu mantenir la visualització dels errors? QRZ QRZ Band Banda Mode Mode Date Data Time Hora SRX SRX RSTtx RSTtx STX STX RSTrx RSTrx QRZ of the QSO QRZ del QSO TX RST RST TX RX RST RST RX TX Exchange Intercanvi TX RX Exchange Intercanvi RX Band of the QSO Banda del QSO Mode of the QSO Mode del QSO Date of the QSO Data del QSO Time of the QSO Hora del QSO Add the QSO to the log Afegeix el QSO al registre Input Entrada Watts watts Ready Preparat Click on the prefix of the correct entity or Cancel to edit the QSO again. Cliqueu al prefix de l'entitat correcta o Cancel·la per tornar a editar el QSO. Clear the box Neteja la casella NEW MULT NOU MULT Ready... Preparat... Save File Desa el fitxer The logfile has been modified. Do you want to save your changes? S'ha modificat el registre. Voleu desar els canvis? &File &Fitxer &New... &Nou... &Open... &Obre... &Save As... &Desa com a... Export ALL the QSOs into one ADIF file, merging QSOs from all the logs. Exporta TOTS els QSO dins un fitxer ADIF, barrejant els QSO de tots els registres. &Print Log... &Imprimeix un registre... E&xit S&urt &Tools &Eines &Export to ADIF... &Exporta a ADIF... &Import from ADIF... &Importa des d'ADIF... &Find QSO to QSL &Cerca QSO a QSL Queue all QSL to be sent of this log Posa a la cua totes les QSL a enviar d'aquest registre Queue all QSL to be sent Posa a la cua totes les QSL a enviar Mark all queued QSOs as sent to LoTW. Marca tots els QSO posats en cua com a enviats al LoTW. &Setup &Configuració &Setup... &Configuració... &Help &Ajuda &About... &Quant a... DUPE DUPLICAT It seems that there are no QSO in the database. Sembla que no hi ha cap QSO a la base de dades. If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help. Si esteu segur que la base de dades conté QSO i el KLog no és capaç de trobar-los, contacteu amb els desenvolupadors (vegeu Quant al KLog) per sol·licitar ajuda. Number of QSOs worked on the selected year. Nombre de QSO treballats durant l'any seleccionat. Power(rx) Potència (rx) RST(tx) RST (tx) RST(rx) RST(rx) QSO QSO QSL QSL eQSL eQSL Satellite Satèl·lit LoTW logfile has been properly exported! El fitxer de registre LoTW s'ha exportat adequadament! Remember to: Recordeu: Before uploading: sign the LoTW log; and Abans de la pujada: signeu el registre LoTW; i After uploading: mark as sent all the queued QSO (LoTW Tools). Després de la pujada: marca com a enviats tots els QSO en la cau (eines LoTW). There was no QSO to be exported. No hi ha cap QSO a exportar. If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as: Si penseu que s'haurien d'haver exportat alguns QSO, cerqueu-los i assegureu-vos que la casella d'enviament eQSL LoTW QSL està marcada amb: Q - Queued Q - A la cua There was an error while exporting the LoTW. The log has not been exported! S'ha produït un error en exportar el LoTW. No s'ha exportat el registre! -- -- - Needed for DXMarathon - Necessari per DXMarathon Others Altres Click on the prefix of the right entity or Cancel to correct. Cliqueu al prefix de l'entitat correcta o Cancel·la per corregir. KLog folder Carpeta del KLog KLog update checking result Resultat de la comprovació d'actualitzacions del KLog You can find the KLog data folder here: Podeu trobar la carpeta de dades del KLog aquí: Name Nom QTH QTH Locator Localitzador My Data Les meves dades CQ CQ Info Info Award Diploma KLog KLog &Export Requested QSL to ADIF... &Exporta a ADIF les QSL requerides... Shows the QSOs with pending requests to send QSLs. You should keep this queue empty! Mostra els QSO amb sol·licituds pendents d'enviar QSL. Cal mantenir buida aquesta cua! Check updates... Comprova les actualitzacions... About Qt... Quant a les Qt... About... Quant a... Nothing has been saved. You have to select a valid file type. No s'ha guardat res. Cal seleccionar un tipus de fitxer vàlid. Freq TX Freq TX Freq RX Freq RX Confirmed Confirmats Worked Treballats DXCC DXCC &Export all logs to ADIF... &Exporta tots els registres a ADIF... Score Puntuació DX-Marathon DX-Marathon WAZ WAZ Local Local QSOs QSO Awards Diplomes Search Cerca DX-Cluster DX-Cluster Save ADIF File Desa el fitxer ADIF Save Cabrillo File Desa el fitxer Cabrillo Cabrillo (*.log) Cabrillo (*.log) Open File Obre fitxer &Modify &Modifica Filling QSOs... Omplint els QSO... Abort filling Interromp l'ompliment Filling QSOs... QSO: Ompliment dels QSO... QSO: Number Nombre Comment Comentari Invalid characters used in the QRZ Caràcters no vàlids usats en el QRZ Fill in QSO data Omple les dades QSO Find My-QSLs pending to send Cerca les meves QSL pendents d'enviar &Find DX-QSLs pending to receive &Cerca DX-QSL pendents de rebre &Find requested pending to receive &Cerca sol·licituds pendents de rebre &Update cty.csv &Actualitza el «cty.csv» Congratulations! Enhorabona! You already have the latest version. Ja teniu la versió més recent. Print Log Imprimeix el registre Printing the log... S'està imprimint el registre... Abort printing Interromp la impressió Printing the log... QSO: S'està imprimint el registre... QSO: MainWindowInputComment Add a comment for this QSO Afegeix un comentari a aquest QSO MainWindowInputEQSL Date of the ClubLog upload. Data de la pujada al ClubLog. Date of the eQSL sending. Data de l'enviament de l'eQSL. Date of the eQSL reception. Data de la recepció de l'eQSL. Date of the LoTW sending. Data de l'enviament del LoTW. Date of the LoTW reception. Data de la recepció del LoTW. Status of the LoTW sending. Estat de l'enviament del LoTW. Status of the LoTW reception. Estat de la recepció del LoTW. LoTW Sent LoTW enviat LoTW Rec LoTW rebut Status on ClubLog. Estat al ClubLog. Status of the eQSL sending. Estat de l'enviament de l'eQSL. Status of the eQSL reception. Estat de la recepció de l'eQSL. ClubLog ClubLog eQSL Sent eQSL enviat eQSL Rec eQSL rebut MainWindowInputOthers Primary Div Div principal Secondary Div Div secundària IOTA IOTA Entity Entitat Propagation mode Mode de propagació Select the primary division for this QSO Seleccioneu la divisió principal d'aquest QSO Select the secondary division for this QSO Seleccioneu la divisió secundària d'aquest QSO Select the entity for this QSO Seleccioneu l'entitat d'aquest QSO Select the propagation mode for this QSO Seleccioneu el mode de propagació d'aquest QSO Select the IOTA continent for this QSO Seleccioneu el continent IOTA d'aquest QSO Select the IOTA reference number for this QSO Seleccioneu el número de referència IOTA d'aquest QSO Not Identified No identificat Not - Not Identified Not - No identificat MainWindowInputQSL QSL Sent QSL enviada QSL Rec QSL rebuda QSL Via QSL via QSL Msg Missatge QSL Status of the QSL sending. Estat de l'enviament de la QSL. Status of the QSL reception. Estat de la recepció de la QSL. QSL sending information. Informació d'enviament de la QSL. QSL reception information. Informació de recepció de la QSL. Date of the QSL sending. Data de l'enviament de la QSL. Date of the QSL reception. Data de la recepció de la QSL. Message of the QSL. Missatge de la QSL. QSL via information. QSL via informació. MainWindowMyDataTab Watt Watt Keep this data Mantén aquestes dades Data entered in this tab will be copied into the next QSO Les dades introduïdes en aquesta pestanya es copiaran al QSO següent Power used for the QSO in watts Potència usada pel QSO en watts Logging operator's callsign Indicatiu de l'operador del registre Callsign used over the air Indicatiu usat a l'aire My QTH locator El meu localitzador QTH Power Potència Operator Operador Station Callsign Indicatiu de l'estació My Locator El meu localitzador MainWindowSatTab Keep this data Mantén aquestes dades Data entered in this tab will be copied into the next QSO Les dades introduïdes en aquesta pestanya es copiaran al QSO següent Satellite mode used Mode de satèl·lit emprat Select the satellite you are using Seleccioneu el satèl·lit que esteu usant UpLink band Banda de pujada DownLink band Banda de baixada Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab. Localitzador de l'estació DX. Aquesta casella se sincronitzarà amb la casella del localitzador de la pestanya QSO. UpLink Pujada DownLink Baixada Satellite Satèl·lit Mode Mode DX Locator Localitzador DX Other Altres MHz MHz Not Sat QSO QSO sense satèl·lit KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name. El KLog ha detectat un nom de satèl·lit que no reconeix. En el seu lloc, caldria usar un dels noms coneguts de satèl·lit. Seleccioneu-lo de la llista. Alternativament, contacteu amb l'equip de desenvolupament per afegir el nom nou de satèl·lit. Please know that the satellite name will not be saved if it is not in the list so that information may be lost! Sapigueu que el nom del satèl·lit no es desarà si no és a la llista, per tant, aquesta informació es podria perdre! Other - Sat not in the list Altres - El satèl·lit no és a la llista Name of the Satellite if not in the list. Select: " Nom del satèl·lit si no és a la llista. Seleccioneu: « " to enable this box. (format like AO-51) » per activar aquesta casella. (format com AO-51) The satellite you have in your QSO is: El satèl·lit que hi ha al QSO és: QObject Database Error Error de base de dades KLog DB needs to be upgraded. La BD del KLog necessita actualitzar-se. Do you want to upgrade it now? La voleu actualitzar ara? If DB is not upgraded KLog may not work properly. Si la BD no s'actualitza, el KLog podria no funcionar adequadament. KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you. El KLog ha detectat un registre anterior a la BD. Es migraran totes les dades a un registre de tipus DX creat de nou. KLog: Enter Station callsign KLog: Introduïu l'indicatiu de l'estació Enter the station callsign used in this log Introduïu l'indicatiu emprat en aquest registre Station Callsign Indicatiu de l'estació All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK. Totes les dades s'han migrat correctament. Ara hauríeu d'anar a Configuració->Preferències->Registres per comprovar que tot és correcte. QSO: QSO: Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel? La cancel·lació d'aquesta actualització provocarà inconsistència de dades i possiblement pèrdua de dades. Encara voleu cancel·lar? Progress: Progrés: Updating DXCC award information... S'està actualitzant la informació dels diplomes DXCC... Updating DXCC Award information... S'està actualitzant la informació dels diplomes DXCC... Updating WAZ award information... S'està actualitzant la informació dels diplomes WAZ... Updating mode information... Actualitzant informació del mode... Abort updating Interromp l'actualització Updating bands information... Actualitzant informació de bandes... Updating bands information in %1 status... Actualitzant informació de bandes en %1... Updating mode information in %1 status... Actualitzant informació dels modes en %1... New One, work it! nNew One, work it! Un de nou, treballeu-ho! Needed, work it! Necessari, treballeu-ho! Worked but not confirmed Treballat però no confirmat Confirmed Confirmat Not identified No identificat Install wizard was canceled before completing... L'assistent d'instal·lació s'ha cancel·lat abans de finalitzar... Do you want to remove the KLog dir from your disk? Voleu eliminar el directori del KLog del disc? Your KLog dir has been removed S'ha eliminat el directori del KLog I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk. No s'ha pogut eliminar el directori del KLog. Caldria fer-ho manualment si el voleu eliminar del disc dur. Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk. No s'ha pogut eliminar el directori del KLog. Caldria fer-ho manualment si el voleu eliminar del disc dur. Remember that your KLog dir is on your system... Recordeu que el directori del KLog és al vostre sistema... Thank you for running KLog! Moltes gràcies per usar el KLog! Updating DXCC information... S'està actualitzant la informació DXCC... SearchWidget &Clear &Neteja &Select All &Selecciona-ho tot &Search &Cerca All Tot &Export Highlighted &Exporta els ressaltats Clear the searches. Neteja les cerques. Export the search result to an ADIF file. Exporta el resultat de la cerca a un fitxer ADIF. Select/Unselect all the QSOs shown. Selecciona/Desselecciona tots els QSO mostrats. Search in the log. Cerca al registre. Search in all logs. Cerca a tots els registres. Enter the QRZ to search for. Introduïu el QRZ a cercar. Search results. Resultats de la cerca. QRZ QRZ Date/Time Data/hora Band Banda Mode Mode QSL Sent QSL enviada QSL Rcvd QSL rebuda Station Callsign Indicatiu d'estació ID ID &Clear selection &Neteja la selecció Save File Desa fitxer QSL Send QSL enviada &Delete &Suprimeix Delete a QSO Suprimeix un QSO &Edit QSO &Edita QSO Edit this QSO Edita aquest QSO Via &bureau Via &bureau Send this QSL via bureau Envia aquesta QSL via bureau D&irect D&irecta Send this QSL via direct Envia aquesta QSL via directa &Request my QSL &Sol·licita la meva QSL Mark my QSL as requested Marca la meva QSL com a sol·licitada Via Direct && mark DX QSL as requested Via directa i marca la QSL DX com a sol·licitada Send this QSL via direct & mark DX QSL as requested Envia aquesta QSL via directa i marca la QSL DX com sol·licitada Via Bureau && mark DX QSL as requested Via bureau i marca la QSL DX com a sol·licitada Send this QSL via bureau & mark DX QSL as requested Envia aquesta QSL via bureau i marca la QSL DX com a sol·licitada &Request the QSL &Sol·licita la QSL Mark the QSL as requested Marca la QSL com a sol·licitada Via bureau && mark my QSL as requested Via bureau i marcar la meva QSL com a sol·licitada QSL received via bureau & mark my QSL as requested QSL rebuda via bureau i marca la meva QSL com a sol·licitada Via bureau Via bureau QSL received via bureau QSL rebuda via bureau Direc&t && mark as my QSL requested Direc&ta i marca-la com a QSL sol·licitada QSL received via direct & mark my QSL as requested QSL rebuda via directa i marca la meva QSL com a sol·licitada Direc&t Direc&ta QSL received via direct QSL rebuda via directa You have requested to delete the QSO with: Heu sol·licitat suprimir el QSO amb: Are you sure? Esteu segur? Needed QSO to send the QSL QSO necessari per enviar la QSL My QSL requested to be sent La meva QSL sol·licitada per enviar DX QSL pending to be received QSL del DX pendent de rebre SetupDialog User data Dades de l'usuari Bands/Modes Bandes/modes My Data Les meves dades DX-Cluster DX-Cluster Colors Colors Misc Varis World Editor Editor mundial ClubLog ClubLog Cancel Cancel·la OK D'acord Config Dialog Diàleg de configuració D&X-Cluster D&X-Cluster You need to enter at least one log in the Logs tab. Com a mínim cal introduir un registre a la pestanya Registres. Misc tab Pestanya varis and click on i feu clic a Move DB Mou la BD or the DB will not be moved to the new location. o la BD no es mourà a la ubicació nova. You need to enter at least a valid QRZ. Com a mínim cal introduir un QRZ vàlid. You will be redirected to the Log tab. Please add and select the kind of log you want to use. Sereu redirigit a la pestanya Registre. Afegiu i seleccioneu la classe de registre que voleu usar. Go to the Vés a DB has not been moved to new path La BD no s'ha mogut al camí nou User tab Pestanya d'usuari and enter valid QRZ. i introduïu un QRZ vàlid. You have not selected the kind of log you want. No heu seleccionat la classe de registre que voleu. Logs Registres World Mundial SetupEntityDialog Entity Entitat Name of the Entity Nom de l'entitat CQ CQ CQ zone Zona CQ ITU ITU ITU zone Zona ITU Latitude Latitud Longitude of the Entity Longitud de l'entitat Longitude Longitud UTC UTC Local time difference to UTC Diferència de l'hora local amb la UTC Main prefix Prefix principal Main prefix of the entity Prefix principal de l'entitat ARRL ID ARRL ID Comma separated possible prefixes, e.g. EA1, EA2, ... Prefixos possibles separats per comes, p. ex. EA1, EA2, ... Prefixes Prefixos Date of the deletion Data de la supressió Deleted Suprimit Cancel Cancel·la OK D'acord Entity Dialog Diàleg d'entitat SetupPageBandMode Bands Bandes Modes Modes SetupPageClubLog &Callsign Indi&catiu ClubLog &password Contra&senya del ClubLog ClubLog &email Corr&eu electrònic del ClubLog Enter the email you used to register in ClubLog. Introduïu el correu electrònic usat per registrar-se al ClubLog. Enter the callsign you used to register in ClubLog. Introduïu l'indicatiu usat per registrar-se al ClubLog. Enter your password in ClubLog. Introduïu la vostra contrasenya al ClubLog. &Send QSOs in real time &Envia els QSO en temps real &Activate ClubLog &Activa el ClubLog Use QSO Station &Callsign Usar indi&catiu de l'estació del QSO Send each QSO to ClubLog in real time, as they are added (or modified) in KLog Enviar cada QSO a ClubLog en temps real, segons es van afegint (o modificant) al KLog Starts the ClubLog support in KLog Inicia el suport del ClubLog al KLog Use the Station Callsign defined in each QSO instead of the one defined here Usa l'indicatiu d'estació definit a cada QSO en lloc del definit aquí SetupPageColors New One Un de nou Needed in this band Necessari en aquesta banda Worked in this band Treballat en aquesta banda Confirmed in this band Confirmed Confirmat en aquesta banda Default Predeterminat Choose a color Escolliu un color SetupPageDxCluster Add Afegeix Delete Suprimeix Show &HF spots Show HF spots Mostra els avisos en &HF Show V/&UHF spots Show V/UHF spots Mostra els avisos en V/&UHF Show W&ARC spots Show WARC spots Mostra els avisos en W&ARC Show &worked spots Show worked spots Mostra els a&visos treballats Show &confirmed spots Show confirmed spots Mostra els avisos &confirmats Show ANN/&FULL messages Show ANN/FULL messages Mostra els missatges ANN/&FULL Show WW&V messages Show WWV messages Mostra els missatges WW&V Show WC&Y messages Show WCY messages Mostra els missatges WC&Y DX Spots Avisos DX Messages Missatges KLog: Add a DXCluster server Kontest: Add a DXCluster server KLog: Afegeix un servidor DXCluster Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default: Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default.: Afegeix l'adreça seguida de :port Exemple: dxfun.com:8000 Si no s'especifica port, s'usarà 41112 de forma predeterminada: SetupPageLogs Type Tipus &New New &Nou &Edit &Edita &Remove &Elimina Add a new log Afegeix un registre nou Select the log you want to open Seleccioneu el registre que voleu obrir KLog KLog Do you really want to remove this log? Esteu segur que voleu eliminar aquest registre? All the QSOs from this log will be also deleted... També s'eliminaran tots els QSO d'aquest registre... Operators Operadors An error has occurred showing the following error code: Hi ha hagut un error en mostrar el codi d'error següent: Log has not been removed. (#3) No s'ha eliminat el registre. (#3) Log has not been removed. (#2) No s'ha eliminat el registre. (#2) Log has not been removed. (#1) No s'ha eliminat el registre. (#1) KLog - SetupPageLogs KLog - SetupPageLogs Edit the selected log Edita el registre seleccionat Remove the selected log Elimina el registre seleccionat ID ID Station Callsign Indicatiu de l'estació Comments Comentaris Date Data SetupPageLogsNew &Ok D'ac&ord &Cancel &Cancel·la Select categories Seleccioneu les categories Callsign used for this log Indicatiu emprat per aquest registre Comma separated list of operators: callsign1, callsign2 Llista separada per comes dels operadors: indicatiu1, indicatiu2 Start date of this log Data d'inici d'aquest registre Add a comment about this log Afegeixi un comentari per aquest registre Select the kind of operation for this log Seleccioneu la classe d'operació per aquest registre Select the mode category Seleccioneu la categoria del mode Select the operators category Seleccioneu la categoria dels operadors Select the assisted category Seleccioneu la categoria d'assistit Select the power category Seleccioneu la categoria de potència Select the bands category Seleccioneu la categoria de bandes &Date &Data &Station Callsign Indicatiu d'e&stació &Operators &Operadors Comm&ent Com&entari &Type of Operation &Tipus d'operació &Mode Category Categoria de &mode O&perators Category Categoria d'o&peradors &Assisted Category Categoria d'&assistit Po&wer Category Categoria de &potència &Bands Category Categoria de &bandes O&verlay S&uperposició Select the Overlay category Seleccioneu la categoria de superposició Categories not OK Categories no correctes You need to enter a valid QRZ in the Station Callsign box. The log will not be opened. You need to enter a valid QRZ in the Station Callsign box The log will not be opened. Cal introduir un QRZ vàlid a la casella d'indicatiu d'estació. El registre no s'obrirà. You selected an invalid combination. The log will not be opened. You selected an invalid combination The log will not be opened. Heu seleccionat una combinació no vàlida. El registre no s'obrirà. Categories OK Categories correctes SetupPageMisc &Imperial system Imperial system Sistema &imperial &Log in real time Log in real time &Registre en temps real &Time in UTC Time in UTC Hora en U&TC &Save ADIF on exit Save ADIF on exit De&sa l'ADIF en sortir Use this &default filename Use this default filename Usa aquest nom de fitxer pre&determinat Mark &QSO to send QSL when QSL is received Mark QSO to send QSL when QSL is received Marca el &QSO per enviar QSL quan es rebi la QSL Complete QSO with previous data Completa QSO amb dades prèvies &Reset to My Data for all QSOs &Restaura les meves dades a tots els QSO Move DB Mou la BD If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog. Si s'ha seleccionat la comprovació de versió nova, el KLog enviarà al desenvolupador el vostre indicatiu, la versió del KLog i el sistema operatiu per ajudar a millorar el KLog. Select to use the following name for the logfile without being asked for it again. Seleccioneu l'ús del nom següent com a fitxer de registre sense tornar-ho a preguntar. This is the default file where ADIF data will be saved. Aquests és el fitxer predeterminat a on es desaran les dades ADIF. This is the directory where the database (logbook.dat) will be saved. Aquest és el directori a on es desarà la base de dades (logbook.dat). Click to change the path of the database. Cliqueu per canviar el camí a la base de dades. Please specify an existing directory where the database (logbook.dat) will be saved. Especifiqueu un directori existent a on es desarà la base de dades (logbook.dat). This is the directory where DB (logbook.dat) will be saved. Aquest és el directori a on es desarà la BD (logbook.dat). Click to change the default ADIF file. Cliqueu per canviar el fitxer ADIF predeterminat. Click to move the DB to the new directory. Cliqueu per moure la BD a un directori nou. Select Directory Selecció de directori File moved S'ha mogut el fitxer File copied S'ha copiat el fitxer File NOT copied NO s'ha copiat el fitxer The target directory does not exist. Please select an existing directory. El directori de destinació no existeix. Seleccioneu un directori existent. The search box will show also the callsign on the air to do the QSO. El quadre de cerca mostrarà també l'indicatiu a l'aire emprat per fer el QSO. Show the Station &Callsign used in the search box Mostra l'indi&catiu d'estació usat al quadre de cerca All the data from the My Data tab will be used or data from the previous QSO will be maintained. S'empraran totes les dades de la pestanya Les meves dades o bé es mantindran les dades del QSO anterior. &Check for new versions automatically &Comprova automàticament si hi ha versions noves QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours. Els QSO es marcaran com a pendents d'enviar una QSL si rebeu el DX QSL i no heu enviat el vostre. Check if there is a new release of KLog available every time you start KLog. Comprova si hi ha un llançament nou disponible del KLog cada vegada que s'iniciï el KLog. &Provide Info for statistics &Proporciona informació per a estadístiques Check it for Imperial system (Miles instead of Kilometres). Activeu-ho pel sistema imperial (milles en lloc de quilòmetres). Select to use real time. Seleccioneu-ho per emprar temps real. Select to use UTC time. Seleccioneu-ho per emprar l'hora UTC. Select if you want to save to ADIF on exit. Seleccioneu si voleu desar a l'ADIF en sortir. Complete the current QSO with previous QSO data. Completa el QSO actual amb dades de QSO anteriors. Browse Explora Open File Obre fitxer SetupPageUserDataPage &Personal data Personal data Dades &personals Station &data Station data &Dades de l'estació Enter your name Introduïu el vostre nom Enter your address - 1st line Introduïu la vostra adreça - 1a línia Enter your address - 2nd line Enter your address - 2nd line Introduïu la vostra adreça - 2a línia Enter your address - 3rd line Introduïu la vostra adreça - 3a línia Enter your address - 4th line Introduïu la vostra adreça - 4a línia Enter your city Introduïu la vostra ciutat Enter your zip code Introduïu el vostre codi postal Enter your province or state Introduïu la província o l'estat Enter your country Introduïu el vostre país &Name Name &Nom &Address Address &Adreça Cit&y City Ci&utat &Zip Code Zip Code Codi &postal Pro&v/State Prov/State Pro&v/Estat Countr&y Country Paí&s Enter your information for rig Introduïu la informació de l'equip Enter your information for antenna Introduïu la informació de l'antena Enter your power information Introduïu la informació de la potència &Rig 1 &Equip 1 R&ig 2 E&quip 2 Ri&g 3 Eq&uip 3 Antenna &1 Antena &1 Antenna &2 Antena &2 Antenna &3 Antena &3 Po&wer Po&tència Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign. Introduïu l'indicatiu de la vostra estació. Alternativament, el KLog pot usar un indicatiu aproximat a partir del vostre indicatiu. &QRZ &QRZ &Operators &Operadors &CQ Zone Zona &CQ &ITU Zone Zona &ITU &Locator &Localitzador &Locator (not valid) &Localitzador (no vàlid) Enter the station callsign that will be used for logging Introduïu l'indicatiu de l'estació que serà usat pel registre Enter the operators (comma separated if more than one). Introduïu els operadors (separats per comes si hi ha més d'un). SetupPageWorldEditor KLog will not be able to show entities information. El KLog no serà capaç de mostra la informació de les entitats. Prefix Prefix Entity Entitat An entities information file (cty.csv) has been detected in your KLog folder and will be loaded. S'ha detectat un fitxer d'informació d'entitats (cty.csv) a la carpeta del KLog i es carregarà. No entities information file (cty.csv) has been detected in your KLog folder. No s'ha detectat cap fitxer d'informació d'entitats (cty.csv) a la carpeta del KLog. ARRL ID ARRL ID Continent Continent CQ Zone Zona CQ ITU Zone Zona ITU UTC UTC Latitude Latitud Longitude Longitud Deleted Suprimit Since Date Des de la data To Date Fins a la data Open File Obre fitxer BigCTY (*.csv) BigCTY (*.csv) Entities information has been updated. S'ha actualitzat la informació de les entitats. Entities information has not been updated. No s'ha actualitzat la informació de les entitats. ShowErrorDialog KLog Message Missatge del KLog SoftwareUpdateDialog Ok D'acord KLog update Actualització del KLog Congratulations! Enhorabona! Your KLog has been updated. S'ha actualitzat el KLog. You already have the latest version. Ja teniu la versió més recent. StartWizard KLog - The free hamradio logging program KLog - El programa lliure d'enregistrament de radioafició Quit Setup Surt de la configuració Setup is not complete yet. Are you sure you want to quit setup? La configuració encara no està completa. Esteu segur que voleu sortir de la configuració? World Entity Entitat Continent Continent Abort reading Interromp la lectura Reading cty.csv... S'està llegint el «cty.csv»... eLogClubLog Host not found! No s'ha trobat la màquina! Timeout error! Error de temps excedit! KLog - ClubLog KLog - clublog KLog - ClubLog Undefined error... Error no definit... Callsign missing Manca l'indicatiu Invalid callsign Indicatiu no vàlid Skipping SWL callsign S'omet l'indicatiu SWL Callsign is your own call Callsign is your ow call L'indicatiu és el vostre propi indicatiu Invalid callsign with no DXCC mapping Indicatiu no vàlid sense correspondència amb DXCC Updated QSO QSO actualitzat Invalid ADIF record Enregistrament ADIF no vàlid Missing ADIF record Manca enregistrament ADIF Test mode - parameters ok, no action taken Mode Test - paràmetres correctes, sense acció It seems to be a PASSWORD ERROR; check your password. Sembla que hi ha una ERROR DE CONTRASENYA; comproveu la vostra contrasenya. It seems that your ClubLog password is not correct. Sembla que la vostra contrasenya del ClubLog no és correcta. Please check your password in the setup. ClubLog uploads will be disabled. Si us plau, comproveu la vostra contrasenya a la configuració. Les pujades al ClubLog es desactivaran. Excessive API Usage Ús excessiu de l'API Internal Error Error intern Rejected Rebutjat QSO Duplicate QSO duplicat QSO Modified QSO modificat Missing Login Manca inici de sessió QSO OK QSO OK Upload denied Pujada denegada No callsign selected No s'ha seleccionat cap indicatiu No match found Cap coincidència Dropped QSO QSO eliminat OK OK Login rejected S'ha rebutjat l'inici de sessió Rejected: Callsign is your own call Rebutjat: L'indicatiu és el vostre propi indicatiu klog-0.9.2.9/translations/klog_pl.ts0000644000076700000620000054260713233376355015343 0ustar staff AboutDialog About KLog O progrmie By Przez KLog is a free logbook for hamradio operators. KLog jest darmowym programem logującym dla krótkofalowców. Please know that this is an BETA release and it may contain many bugs.<br>Backup your data before using this software! Proszę zwrócić uwagę że jest to wersja BETA wydanie może zawierać liczne błędy.<br> Proszę wykonać kopię zapasową przed użyciem tego programu! KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing. KLOG został całkowicie przepisany rozpoczynając od wersji 0.6.2 tak aby była możliwość pracy na wielu systemach operacyjnych ( Linux, macOS & Windows ) Zawiera również nowe funkcje którch KLOG nie było we wcześniejszych wydaniach. Please provide your review in KLog's eHam review page: Proszę o napisanie opini na tema KLog na stronie eHam: Find more information and the latest release at Aby dowiedzieć się więcej oraz najnowsze wydania na If you want to provide support you are welcome to join the Jeśli chciałbyś pomóc to serdecznie zapraszamy do KLog development mailing list Lista mailingowa KLog ! ! If KLog is still not in your language and you want to help us, you are welcome to contact us through the Jeśli KLog nadal nie jest w Twoim języku i chciałbyć pomóc w tworzeniu to serdecznie prosimy o kontakt przez You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog. Możesz również pomóc przesyłając błędy programu oraz swoje pomysły lub cokolwiek co pomogło by w poprawie KLog. KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs Twórcy programy KLog umieścili w kodzie programu możliwość przesyłanie niewielkich ilości danych użytkownika na serwery KLog informujące o ilości zainstalowanych wersji,ma to pomóc twórcy programu w rozwijaniu i przystosowaniu oprogramowania do wymagań użytkowników At present, the data that is provided is the following: W tym momęcie, dane dostarczone zawierają: Be aware that you can enable/disable this feature from the Misc tab in the Setup page Proszę zauważyć że istnieje możliwość wyłączenie \ włączenie tej funkcji w zakładce Inne w menu głównym Author Autor today dzisiaj Main developer Główny twórca KLog is developed by a very small team and you are invited to join! KLOG Jest tworzony przez bardzo małe grono entuzjastów. Dołącz do nas! Authors Autorzy Translators bring KLog into your language. They are really an important part of the KLog development team. Tłumacze przełożli KLOG na Twój język. Tłumacze są naprawdę ważną częścią grupy rozwojowej KLOG. Translators Tłumacze Privacy advisory Postanowienia prawne Callsign Znak wywoławczy KLog version Wersja KLog Operating system System operacyjny KLog Klog Privacy Prywatność CTYPage Country data download Lista krajów została pobran KLog needs country data... Klog wymga danych państwa... &Download &Pobieranie &Ignore &Ignorownie Country data needed Wymagana lista krajów KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information. Klog korzysta z pliku CSV.CTY który można pobrać ze strony http://www.country-files.com/. You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do. Wymagane jest pobranie pliku CSV.CTY aby Klog mógł podawać dane państ oraz lokator, ...QSO które prowadzisz. Click on Download to download now. Proszę nacisnąć Pobierz aby zacząć pobieranie. KLog Klog I can't find the host. Please check your network and try again Do you want to try again? Nie mogę odnaleźć host. Proszę sprawdzić swoje połączenie sieciowe oraz spróbować ponownie Czy chciałbyś spróbować ponownie? DXCCStatusWidget Update Aktualizacja ID ID Entity Jednostka DXClusterWidget Click on Connect to connect to the DX-Cluster server Naciśnij Połącz aby połączyć z DX-Cluterem Connect Połącz Clear Wyczyść Click on connect to connect to the DX-Cluster Naciśnij na Połącz aby połączyć z DX-Cluster Trying to connect to the server Próba nawiązania połączenia z serwerem KLog DXCluster Klog DX Cluster The host was not found. Please check: - your network connection; - the host name and port settings. The connection was refused by the peer. Make sure the DXCluster server is running, and check that the host name and port settings are correct. Połączenie zostało odrzucone przez peer Upewnij się że DX Cluster jest włączony oraz sprawdź czy ustawienia są prawidłowe. The following error occurred: %1. Pojawił się pewien błąd:%1. Connected to server Połączono z serwerem KLog message Wiadomość KLog Enter your callsign to connect to the cluster: Wprowadź swój znak aby połączyć się z clusterem: Enter your password to connect to the cluster: (Just hit enter for no password) Wprowadź swoje hasło aby połączyć się z Clusterem: ( Naciśnij Enter aby połączyć bez hasła ) Disconnect Rozłącz Not logged on, you may need to enter your callsign again. Nie zalogowano, być może konieczne będzie wpisać Twój znak ponownie. Enter here the commands to be sent to the DX-Cluster server Wprowadź swoje hasło aby połączyć się z DX- Clusterem: ( Naciśnij Enter aby połączyć bez hasła ) Connection closed by the server Połączenie zamknięte przez serwer Send Wyślij DataProxy_SQLite Software version in DB is null No query failed KLog DXCC All QSOs have been updated with a DXCC. DownLoadCTY Download of cty.csv failed with the following error code: Pobieranie pliku CTY.CSV zakończone z błędem o kodzie: Download of cty.csv done. Pobieranie pliku CTY.CSV ukończone. There is already a cty.csv file in the folder but it will be replaced with the new one. Plik CTY.CSV już znajduje się w folderze ale zostnie on zastąpiony nowym. Could not open Nie można otworzyć for writing. do zapisu. FileManager Writing ADIF file... Zapisywanie pliku ADIF... Abort writing Przerwij zapisywanie Writing ADIF file... QSO: Zapisywanie pliku ADIF... QSO: You have canceled the file export. The file will be removed and no data will be exported. Eksport pliku zosał anulowany. Plik zostanie usunięty oraz żadne dane wyeksportowane. Do you still want to cancel? Czy nadal chcesz anulować? QSO: QSO: This QSO had: To QSO miało: Do you want to continue with the current file? Czy nadal chcesz kontynuować z obecnym plikiem? The log that you have selected contains more than just one station callsign. Please select the station callsing you want to export the log from: Station Callsign: Define Station Callsign You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: No station callsign has been selected and therefore no log will be exported Exporting LoTW ADIF file... Writing Cabrillo file... Zapisywanie pliki Cabrillo... KLog: Cabrillo Log Export not implemented KLog: Eksport Logu do formatu Cabrillo nie jest jeszcze możliwy I am sorry but the Cabrillo Export To File feature has still not been implemented. Bardzo mi przykro ale eksport pliku do formatu Cabrillo nie został jeszcze wdrożony. Reading LoTW file... Reading ADIF file... Wczytywanie pliku ADIF... This QSO is not including the minimum data to consider a QSO as valid!. Please edit the ADIF file and make sure that it include at least: and This log seems to lack of RST-TX information. Click on Yes to add a default 59 to all QSO with a similar problem. If you select NO, the QSO may not be imported. This log seems to lack of RST-RX information. Abort reading Przerwij wczytywanie There is more than one log in this logfile. All logs will be imported into the current log. Do you want to continue? Importing ADIF file... You have cancelled the file import. The file will be removed and no data will be imported. It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported) - The band missing and the following call: - The call missing but was done at this time: - The mode missing and the following call: - The date missing and the following call: - The time missing and the following call: KLog: Not all required data found! KLog: Nie wszystkie wymagane dane zostały znalezione! KLog: No RST TX found! Klog: Nie znaleziono RST-TX! KLog: No RST RX found! Klog: Nie znaleziono odebranych raportów RST-RX! InfoWidget 10M 10M 15M 15M 20M 20M 40M 40M 80M 80M 160M 160M 2M 2M 6M 6M 12M 12M 17M 17M 30M 30M 70CM 70CM Continent Kontynent Prefix Prefiks CQ CQ ITU ITU Short Path Krótka droga Long Path Długa droga Degree Grad Stopień Miles Mile Km Km IntroPage Welcome to KLog! Witamy w KLog! Welcome to KLog! - brought to you under the terms of the GPL! Witamy w KLog! - Napisanym pod licęcją GPL! Welcome to KLog Witaj w KLog This looks like it's the first time you've run KLog on this computer. Wygląda na to że to pierwszy raz kiedy korzystasz z KLog na tym komputerze. KLog is a free hamradio logging program that can run on Linux macOS and Windows. KLog jest darmowym programem logującym dla radioamatorów który może pracować pod systemami Linux, macOS oraz Windows. It is designed to provide general purpose, DX and contest logging. Został stworzony do codziennej pracy, DX oraz w zawodach. It supports QSL management, import and export of ADIF Posiada możlowość zarządzania kartami QSL, import oraz eksport z oraz do ADIF and Cabrillo file formats and many other features... oraz format Cabrill and wiele innych funkcji... Before you can start using KLog, you will be asked to: Zanim zaczniesz korzystać z KLog, będziesz poproszony o: Acknowledge to the terms of the license. Informacje dotyczące warunków licencji. Download the DX entities information. Pobierz Informacje o jednostakach DX. Enter your callsign, CQ zone, etc. and main configuration. Podaj swój znak wywoławczy, Strefę CQ, oraz inne przy konfiguracji główniej. Enjoy KLog and contact the development team if you have any suggestions! Korzystaj z KLog oraz z twóracmi programu jeśli masz jakieś sugestje! LicPage KLog License information KLog informacje na temat licęcji Welcome to KLog!- brought to you under the terms of the GPL! Witaj w KLog! -Napisany pod licencją GPL! Acknowledge Acknowledge Be aware that KLog is free software. Pamiętaj o tym że KLog jest oprogramowaniem darmowym. LogModel Date Data Time Czas QRZ QRZ Band Pasmo Mode Emisja RSTtx RSTtx RSTrx RSTrx Comment Komentarz LogWindow QSL Send QSL wysłane QSL Rcvd QSL Otrzymane &Delete &Delete Delete a QSO Usuń QSO &Edit QSO &Edit QSO Edit this QSO Edytuj QSO Via &bureau Via &bureau Send this QSL via bureau Wyśłij QSL przez biuro D&irect D&irect Send this QSL via direct Wyślij QSL direktem Via bureau Przez biuro QSL &received via bureau QSL &received via bureau Direct Direct QSL received via direc&t QSL odebrane przez direct&t You have requested to delete this QSO. To QSO zaostało zaznaczone do usnunięcia. Are you sure? Czy jesteś pewien? MainWindow Recalculate Przeliczanie Click to recalculate the award status Proszę nacisnąć aby przeliczuć status dyplomów Starting KLog Uruchamianie KLog &Add &Add &Clear &Clear Status bar... Pasek stanu... DX Entity Jednostka DX &Log Window &Log Window &Score Window &Score Window MHz MHz KLog Klog Ready Gotów An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: Wystąpił niespodziewany błąd w czasie zapisywana QSO do Logu. Jeśli problem nadal będzie się powtarzał, proszę o kontak z twóracmi programu: You have selected an entity: Zaznaczyłeś jednostkę: that is different from the KLog proposed entity: ta jednostka jest inna niż KLog zaproponowa: Click on the prefix of the right entity or Cancel to correct. Proszę naciśniej na prefix właściwej jednostki lub Porzuć aby poprawić. QRZ of the QSO QRZ of the QSO TX RST TX RST RX RST RX RST TX Exchange TX Exchage RX Exchange RX Exchanege Band of the QSO Pasmo QSO Mode of the QSO Emisja QSO Date of the QSO Data QSO Time of the QSO Czas QSO Add the QSO to the log Dodaj to QSO do logu Input Wprowadź RSTrx RSTrx RSTtx QRZ QRZ STX STX SRX SRX NEW MULT Nowy mnożnik Ready... Gotów... The logfile has been modified. Do you want to save your changes? Plik logu został zmodyfikowany. Czy chcesz zapisać zmiany? &File &File &New... &New... &Open... &Open... &Import from ADIF... &Import from ADIF... Import an ADIF file into the current log. &Save As... &Save As... &Export to ADIF... &Export to ADIF... &Export all logs to ADIF... &Export all logs to ADIF... &Export Requested QSL to ADIF... &Export Requested QSL to ADIF... Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW! &Print Log... &Print Log... KLog folder Katalog KLog E&xit E&xit &Tools &Tools QSL tools... &Find QSO to QSL &Find QSO to QSL LoTW tools... Mark all non sent QSOs in this log as queued to be uploaded. Mark all non sent QSOs as queued to be uploaded. Mark as sent all queued QSO of this log Mark all queued QSOs in this log as sent to LoTW. Mark all queued QSO as sent For updated DX-Entity data, update cty.csv. &Setup &Setup &Setup... &Setup... &Help &Help Check updates... Sprawdź czy są aktualizacje... &About... &About... About Qt... O Qt... KLog LoTW All pending QSO of this log has been marked as queued for LoTW! There was a problem to mark all pending QSO of this log as queued for LoTW! All pending QSO has been marked as queued for LoTW! All queued QSO of this log has been marked as sent for LoTW! There was a problem to mark all queued QSO of this log as sent for LoTW! The log that you have selected contains more than just one station callsign. Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW. Please select the station callsing you want to mark as sent to LoTW: Station Callsign: Define Station Callsign You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: No station callsign has been selected and therefore no log will be marked All queued QSO has been marked as sent to LoTW! There was a problem to mark all queued QSO of this log as sent to LoTW! About... O... KLog update checking result Wyniki sprawdzania aktualizacji KLog Congratulations! Gratulacje! You already have the latest version. Już posiadasz najnowszą wersję. Nothing has been saved. You have to select a valid file type. Nic nie zostało zapisane. Musisz wybrać odpowiedni format pliku. Save File Zapisz Plik It seems that there are no QSO in the database. If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help. LoTW logfile has been properly exported! Remember to: Before uploading: sign the LoTW log; and After uploading: mark as sent all the queued QSO (LoTW Tools). There was no QSO to be exported. If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as: Q - Queued There was an error while exporting the LoTW. The log has not been exported! An unexpected error ocurred!! If the problem persists, please contact the developers for analysis: Error in function Error code Error text Failed query Do you want to keep showing errors? You can find the KLog data folder here: Moższ znaleźć folder KLog tutaj: Export to ADIF... Export all logs to ADIF... Export Requested QSL to ADIF... Export ADIF for LoTW... DUPE DUPE The selected log is not existing or it is still empty. Click Yes and KLog will open an empty log. Click No and KLog will select another log with data. You can modify the config file accordingly, if needed. TX Frequency in MHz. Częstotliwość TX w MHz Częstoliwość TX w MHz. RX Frequency in MHz. Częstotliwość RX w MHz. Power used by the DX. Moc używana przez DX. Logging operator's callsign. Logowanie znaku operatora. Callsign used over the air. Znak używan. My QTH locator. Mój QTH Lokator. Name of the DX. Imie. QTH of the DX. QTH. Locator of the DX. Lokator.stacji DX. QRZ of the QSO. QRZ of the QSO. TX RST. TX RST. RX RST. RX RST. TX Exchange. TX Wymiana. RX Exchange. RX Wymiana. Band of the QSO. Pasmo. Mode of the QSO. Emisja. Date of the QSO. Data QSO. Time of the QSO. Czas QSO. Add the QSO to the log. Dodaj QSO do Logu. Clears the QSO entry. Czyści wpisy QSO. Number of confirmed DXCC entities. Liczba potwierdzonych jednostek DXCC. Number of worked DXCC entities. Liczba zrobionych jednostek DXCC. Number of confirmed WAZ zones. Liczba potwierdzonych stref WAZ. Number of worked WAZ zones. Liczba zrobionych stref WAZ. Number of confirmed local references. Number of confirmed local references. Number of worked local references. Number of worked local references. Number of confirmed QSOs. Liczba potwierdzonych QSO. Number of worked QSOs. Liczba QSO nie potwierdzonych. Number of DXCC worked on the selected year. Liczba zrobionych DXCC w zaznaczonym roku. Number of CQ Zones worked on the selected year. Liczba stref CQ zrobionych w zaznaczonym roku. Score for the DXMarathon on the selected year. Wynik DXMarathon w zaznaczonym roku. Select the year you want to check. Zaznacz rok który chciałbyś sprawdzić. Status of the DX entity. Wynik DXCC. Name of the DX entity. Nazwa jednostki DX. Info Info Export ALL the QSOs into one ADIF file, merging QSOs from all the logs. Eksport WSZYSTKICH QSO do jednego pliku ADIF, łącząc ze sobą wszystkie logi. Fill in QSO data Wypełnij dane QSO Find My-QSLs pending to send Znajdź moje QSL oczekujące na wysłanie &Find DX-QSLs pending to receive &Find DX QSLs pending to recive &Find requested pending to receive &Find Requested pending to recive Name Imię QTH QTH Locator Lokator Power(rx) Moc(rx) RST(tx) RST(tx) RST(rx) RST(rx) Freq TX QRG TX Freq RX QRG RX QSO QSO QSL QSL eQSL eQSL Comment Komentarz Others Inne My Data Moje dane Satellite Satelity CQ CQ DXCC DXCC Watts Waty Click on the prefix of the correct entity or Cancel to edit the QSO again. Naciśnij na odpowiedni prefiks jednostki DXCC lub Anuluj edycje QSO. Clear the box Wyczyść wszystko Invalid characters used in the QRZ Nieprawidłowe znaki użyte w polu QRZ Shows the QSOs with pending requests to send QSLs. You should keep this queue empty! Pokazuje QSO które oczekują na wysłanie Twojej kart QSL. Tu powinno być pusto! &Update cty.csv &Update cty.csv ADIF file Cabrillo files Any file Score Wynik DX-Marathon DX-Maraton Award Dyplom Confirmed Potwierdzone Worked Zrobiony WAZ WAZ Local Lokal QSOs QSOs Export the current log to an ADIF logfile. Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program). Print your log. Opens the data folder of KLog. Go through the log reusing previous QSOs to fill missing information in other QSOs. Fill in DXCC data Go through the log filling QSOs without a DXCC defined. Shows QSOs for which you should send your QSL and request the DX QSL. Shows the DX-QSL that has been requested or QSLs has been sent with no answer. Shows the DX-QSL that has been requested. Queue all QSL to be sent of this log Queue all QSL to be sent Mark all queued QSOs as sent to LoTW. Number of QSOs worked on the selected year. Liczba QSO wykonana w danym roku. Awards Dyplomy Search Wyszukiwanie Log Log DX-Cluster DX-Cluster Save ADIF File Zapisz plik ADIF Save Cabrillo File Zapisz plik Cabrillo Cabrillo (*.log) Cabrillo (*.log) Open File Otwórz plik &Modify &Modify -- -- - Needed for DXMarathon - Wymagany do DX Maratonu Filling QSOs... Wypełnianie QSOs... Abort filling Przerwij wypełnianie Filling QSOs... QSO: Wypełnianie QSOs... QSO: Number Numer Date Data Time Czas Band Pasmo Mode Emisja Print Log Drukuj Log Printing the log... Drukowanie logu... Abort printing Przerwij drukowanie Printing the log... QSO: Drukowanie logu... QSO: MainWindowInputComment Add a comment for this QSO Dodaj komentarz do tego QSO MainWindowInputEQSL Date of the ClubLog upload. Data aktualizacji ClubLog. Date of the eQSL sending. Data wysłania eQSL. Date of the eQSL reception. Data otrzymania eQSL. Date of the LoTW sending. Date of the LoTW reception. Status of the LoTW sending. Status of the LoTW reception. LoTW Sent LoTW Rec Status on ClubLog. Status ClubLog. Status of the eQSL sending. Status wysłania eQSL. Status of the eQSL reception. Status otrzymywanych eQSL. ClubLog ClubLog eQSL Sent eQSL Wysłane eQSL Rec eQSL Otrzymane MainWindowInputOthers Primary Div Primary Div Secondary Div Secondary Div IOTA IOTA Entity Jednostka Propagation mode Typ propagacji Select the primary division for this QSO Select the primary division for this QSO Select the secondary division for this QSO Select the secondary division for this QSO Select the entity for this QSO Zaznacz jednostkę dla tego QSO Select the propagation mode for this QSO Zaznacz typ propagacji dla tego QSO Select the IOTA continent for this QSO Zaznacz IOTA dla tego QSO Select the IOTA reference number for this QSO Zaznacz numer IOTA dla tego QSO Not Identified Not - Not Identified MainWindowInputQSL QSL Sent QSL wysłane QSL Rec QSL Otrzymane QSL Via QSL Via QSL Msg QSL Msg Status of the QSL sending. Stan wysłanych kart QSL. Status of the QSL reception. Stan kart QSL otrzymanych. QSL sending information. Informacje dotyczące wysyłania QSL. QSL reception information. Informacje dostyczące odebranej karty QSL. Date of the QSL sending. Data wysłania karty QSL. Date of the QSL reception. Data otrzymania karty QSL. Message of the QSL. Informacje o QSL. QSL via information. Info o sposobie wysłania QSL. MainWindowMyDataTab Watt Wat Keep this data Zachowaj te dane Data entered in this tab will be copied into the next QSO Dane podane w tej zakładce zostaną skopiowane do następnego QSO Power used for the QSO in watts Moc używana podczas tego QSO w watach Logging operator's callsign Logowanie znaku operatora Callsign used over the air Znak z którego korzystamy My QTH locator Mój QTH lokator Power Moc Operator Operator Station Callsign Znak stacji My Locator Mój lokator MainWindowSatTab Keep this data Zachowaj te dane Data entered in this tab will be copied into the next QSO Dane podane w tej zakładce zostaną skopiowane do następnego QSO Other - Sat not in the list Inne - Satelita nie jest na liście Name of the Satellite if not in the list. Select: " Nazwa satelity nie znajduje się na liście. Wybierz:" " to enable this box. (format like AO-51) "aby uruchomić to okno. ( format np AO51) Satellite mode used Sposób emisji przy pracy SAT Select the satellite you are using Zaznacz satelitę z którego korzystasz UpLink band Pasmo UpLink DownLink band Pasmo DownLink Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab. UpLink UpLink DownLink DownLink Satellite Satelita Mode Emisja DX Locator Other Inne MHz MHz Not Sat QSO QSO nie przez SAT KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name. KLog wykrył nazwę satelity która nie została rozpoznana. Jeśli chcesz użyć jednej ze znanych zamiast tej, proszę wybrać ją z listy. Ewentualnie, proszę o kontak z twórcami programu aby satelita mógł zostać do listy w kolejnych wydaniach. Please know that the satellite name will not be saved if it is not in the list so that information may be lost! Proszę zauważyć że nazwa satelity nie zostanie zapisana jeśli nie jest nia liście więc informacje mogą zostać utracone! The satellite you have in your QSO is: Satelita w Twoim QSO to: QObject New One, work it! New One, work it! Needed, work it! Potrzebny, zrób QSO! Worked but not confirmed Zrobione, ale nie potwierdzone Confirmed Potwierdzone Not identified Nie zidetyfikowany Database Error Błąd bazy dancyh KLog DB needs to be upgraded. Baza danych KLog musi zostać zaktualizowana. KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you. KLog wykrył poprzedni LOG w bazie dancy. Wszystkie dane zostaną dla Ciebie zaimportowane do nowo utworzonego Logu. KLog: Enter Station callsign KLog: Wprowadź znak stacji Enter the station callsign used in this log Wprowadź znak używany w KLog Station Callsign Znak Stacji All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK. Wszystkie dane zostały zaimportowane poprawnie. Przejdź do Ustawień >Właściwości>Logi do sprawdzenia czy wszystko jest OK. QSO: QSO: Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel? Przerwanie tej aktualizjacji może grozić utratą danych, Czy napewno chcesz przerwać? Progress: Postęp: Updating DXCC award information... Updating DXCC Award information... Updating WAZ award information... Updating mode information... Updating mode information... Do you want to upgrade it now? Czy chcesz aktualizować teraz? If DB is not upgraded KLog may not work properly. Jeśli DB nie zostanie zauktualizowana KLog może nie działać poprawnie. Abort updating Przerwij aktualizowanie Updating bands information... Aktualizowanie informacjo o pasmach... Updating bands information in %1 status... Updating bands information in %1 status... Updating mode information in %1 status... Updating mode information in %1 status... Install wizard was canceled before completing... Proces aktualizacji został przerwany przed zakończeniem... Do you want to remove the KLog dir from your disk? Czy chcesz usunąć katalog KLoog ze sswojego dysku? Your KLog dir has been removed Katalog KLog został usunięty I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk. Usunięcie katalogu KLog było nie możliwe. Powinieneś zrobić to manualnie jeśli aby katalog KLog został całkowicie usunięty. Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk. Katalog KLog nie został usunięty. Aby usunąć ten katalog z dysku powinieneś usunąć go ręcznie. Remember that your KLog dir is on your system... Pamiętaj że katalog Klo jest w zainstalowany na Twoim systemie... Thank you for running KLog! Dziękujemy za korzystanie z KLog! Updating DXCC information... SearchWidget &Clear &Clear &Select All &Select All &Search &Search All Wszystko &Export Highlighted &Export Highlighted Clear the searches. Wyczyść wyszukiwanie. Export the search result to an ADIF file. Wyeksportuj wyniki wyszukiwania do pliku ADIF. Select/Unselect all the QSOs shown. Zaznacz/Odznacz wszystkie wyświetlone QSO. Search in the log. Przeszukaj log. Search in all logs. Przeszukaj we wszystkich logach. Enter the QRZ to search for. Wprowadź znak aby wyszukać. Search results. Przeszukaj wyniki. QRZ QRZ Date/Time Data/Czas Band Pasmo Mode Emisja QSL Sent QSL Wysłane QSL Rcvd QSL Otrzymane Station Callsign Znak stacji ID ID &Clear selection &Clear selection Save File Zapisz plik QSL Send QSL Wysłane &Delete &Delete Delete a QSO Usuń QSO &Edit QSO &Edit QSO Edit this QSO Edytuj to QSO Via &bureau Via &bureau Send this QSL via bureau Wyślij to QSL przez biuro D&irect D&irect Send this QSL via direct Wyślij to QSL direktem &Request my QSL &Request my QSL Mark my QSL as requested Zaznacz moje QSL jako oczekiwane Via Direct && mark DX QSL as requested Via Direct && mark DX QSL as requested Send this QSL via direct & mark DX QSL as requested Wyślij to QSL direktem oraz oznacz QSL jako oczekiwane Via Bureau && mark DX QSL as requested Przez biuro oraz zaznacz DX QSL jako oczekiwane Send this QSL via bureau & mark DX QSL as requested Wyślij to QSL przez biuro oraz zaznacz DX QSL jako oczekiwane &Request the QSL &Request the QSL Mark the QSL as requested Zaznacz to QSL jako oczekiwane Via bureau && mark my QSL as requested Via biuro oraz zaznacz moje QSL jako oczekiwane QSL received via bureau & mark my QSL as requested QSL otrzymane przez biuro oraz zaznacz QSL jako oczekiwane Via bureau Via biuro QSL received via bureau QSL otrzymane via biuro Direc&t && mark as my QSL requested Direc&t && mark as my QSL requested QSL received via direct & mark my QSL as requested QSL otrzymane direktem oraz zaznacz moje QSL jako oczekiwane Direc&t Direc&t QSL received via direct QSL otrzymane direktem You have requested to delete the QSO with: Zamierzasz usunąć to QSO z: Are you sure? Czy jesteś pewien? Needed QSO to send the QSL QSO wymagne aby wysłać QSL My QSL requested to be sent Moje QSL jako oczekiwane DX QSL pending to be received DX QSL jako oczekjące SetupDialog My Data Moje dane Bands/Modes Pasma/Emisje DX-Cluster DX-Klaster Colors Kolory Misc Inne World Editor Edycja Znaków Logs Logi ClubLog ClubLog Cancel Anuluj OK OK Config Dialog Okno konfiguracji User data Dane użytkownika D&X-Cluster D&X-Cluster DB has not been moved to new path DB nie została przeniesiona w nowe miejsce or the DB will not be moved to the new location. lub DB nie zostanie przeniesiona w nowe miejsce. You will be redirected to the Log tab. Please add and select the kind of log you want to use. Zstaniesz przekierowany do zakłdki Log. Proszę wybrać z którego logu chcesz obecnie korzystać. World Świat You need to enter at least one log in the Logs tab. Wymagane jest abyś dodał przynajmniej jeden Log w zakładce Log. Go to the Przejdź do Misc tab Zakładka Inne and click on i naćiśnij Move DB Przenieś DB You need to enter at least a valid QRZ. Wmagane jest wprowadzenie przynajmniej jednego aktualnego znaku. User tab Zakładka użytkownika and enter valid QRZ. i podaj aktualny znak. You have not selected the kind of log you want. Nie zanaczono żadnego logu. SetupEntityDialog Entity Jednostka Name of the Entity Nazwa Jednostki CQ CQ CQ zone Strefa CQ ITU ITU ITU zone Strefa ITU Latitude Szerokość Longitude of the Entity Szerokość geograficzna jednostki Longitude Szerokość UTC UTC Local time difference to UTC Różnica czasu lokalnego do czsu UTC Main prefix Główny Prefiks Main prefix of the entity Główny prefix Jednoski ARRL ID ARRL ID Comma separated possible prefixes, e.g. EA1, EA2, ... Prefixy oddzielpone przecinkiem Np EA1, EA2, ... Prefixes Prefiksy Date of the deletion Data usunięcia Deleted Usunięty Cancel Anuluj OK OKOK Entity Dialog Opis Jednostki SetupPageBandMode Bands Pasma Modes Emisje SetupPageClubLog &Callsign &Callsign ClubLog &password ClubLog &password ClubLog &email ClubLog &email Enter the email you used to register in ClubLog. Wprowadź e-mail którego użyłeś podczas rejestracji w ClubLog. Enter the callsign you used to register in ClubLog. Wprowadź znak który podałeś podczas rejestracji w ClubLog. Enter your password in ClubLog. Wprowadź swoje hasło do ClubLog. &Send QSOs in real time &Send QSO in real time &Activate ClubLog &Active ClubLog Use QSO Station &Callsign Użyj znaku stacji &Callsign Send each QSO to ClubLog in real time, as they are added (or modified) in KLog Wysyłaj każde QSO w czasie rzeczywistym do ClubLog które były wprowadzone lub zmienione do KLog Starts the ClubLog support in KLog Rozpocznij kożystanie z ClobLog w KLog Use the Station Callsign defined in each QSO instead of the one defined here Wykorzystaj zdefiniowany Znak Stacji w każdym QSO zamiast definiować je tutaj SetupPageColors New One Nowy kraj Needed in this band Potrzebny na tym paśmie Worked in this band Zrobiony na tym paśmie Confirmed in this band Potwierdzony na tym paśmie Default Domyślny Choose a color Wybierz kolor SetupPageDxCluster Add Dodaj Delete Usuń Show &HF spots Pokaż &HF spots Show V/&UHF spots Pokaż V/&UHF spots Show W&ARC spots Pokaż W&ARC spots Show &worked spots Pkaż &worked spots Show &confirmed spots Pokaż &confirmed spots Show ANN/&FULL messages Pokaż ANN/&FULL messages Show WW&V messages Pokaż WW&V messages Show WC&Y messages Pokaż WC&Y messages DX Spots DX spot Messages Wiadomość KLog: Add a DXCluster server KLog: Dodaj server DXCluster Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default: Proszę podać adres razem z numerem :portu Na przykład: dxfun.com:8000 Jeśli numer portu nie zostanie podany, port 41112 zostanie użyty jako domyślny: SetupPageLogs &New &New &Edit &Edit &Remove &Remove Add a new log Dodaj nowy Log Edit the selected log Edytuj wybrany Log Remove the selected log Usuń wybrany Log Select the log you want to open Proszę zanaczyć Log który chesz otworzyć KLog Klog Log has not been removed. (#3) Log nie został usunięty. (#3) Do you really want to remove this log? Czy na pewno chcesz usunąć ten Log? All the QSOs from this log will be also deleted... Wszystkie QSO z tego Logu zostaną usunięte... Log has not been removed. (#2) Log nie został usunięty. (#2) Log has not been removed. (#1) Log nie został usunięty. (#1) ID ID Date Data Station Callsign Znak stacji Operators Comments Komentarz Type Rodzaj An error has occurred showing the following error code: Wystąpił błąd o wskazanym kodzie błędu: KLog - SetupPageLogs Klog -SetupPageLogs SetupPageLogsNew &Date &Date &Station Callsign &Satation Callsign &Operators &Operators Comm&ent Comm&ent &Ok &OK &Cancel &Cancel Select categories Zaznacz kategorie Callsign used for this log Znaki wywoławcze użyte w tym Logu Comma separated list of operators: callsign1, callsign2 Lista operatorów oddzielona przecinkiem: Znak Sacji1, Znak Stacji2 Start date of this log Data początkowa tego Logu Add a comment about this log Dodaj komentarz do tego Logu &Type of Operation &Type of Operation Select the kind of operation for this log Zaznacz rodzaj aktywnośći dla tego Logu &Mode Category &Mode Category Select the mode category Zaznacz rodzaj emisji O&perators Category O&perators Category Select the operators category Zanzacz rodzaj operartorów &Assisted Category &Assisted Category Select the assisted category Zaznacz kategorię wspomagania Po&wer Category Po&wer Category Select the power category Zaznacz kategorię mocy &Bands Category &Bands Category Select the bands category Znaznacz kategorię pasm O&verlay O&verlay Select the Overlay category Zaznacz kategorię Overlay Categories not OK Kategorie nie poprawne You need to enter a valid QRZ in the Station Callsign box. The log will not be opened. Wpisz aktualny znak QRZ w polu Znak Stacji. Log nie zostanie otwarty. You selected an invalid combination. The log will not be opened. Nie odpowiednie zostawienie zostało wybrane. Log nie zostanie otwarty. Categories OK Kategorie OK SetupPageMisc &Imperial system &Imperial system &Log in real time &Log in real time &Time in UTC &Time in UTC &Save ADIF on exit &Save ADIF on exit Use this &default filename Use this &default filname Mark &QSO to send QSL when QSL is received Mark &QSO to send QSL when QSL is recived Complete QSO with previous data Uzupełnij QSO ze wcześniejszymi danymi Show the Station &Callsign used in the search box Show the Station &Callsign used in the search box &Reset to My Data for all QSOs &Reset to My Data for all QSOs QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours. QSO zostanie oznaczone jako oczekujące QSL jeśli otrzymasz kartę QSL a Twoja jeszcze nie została wysłana. If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog. Jeśli nowa wersja zosyanie wybrana wówczas KLog wyśle do twórców programy używaną wersję KLog oraz system operacyjny na którym KLog został zainstalowany, w celu ulepszenia KLog. Select to use the following name for the logfile without being asked for it again. Proszę zaznaczyć wybrnaną nazwę pliku aby nie być ponownie pytany o jego nazwę. This is the default file where ADIF data will be saved. To jest domyślna nazwa pliku w którym ADIF zostanie zapisany. Please specify an existing directory where the database (logbook.dat) will be saved. Proszę wybrać istniejący katalog w którym baza danych programu ( logbook.dat) zostanie zapisana. &Check for new versions automatically &Check for new version automaticlly &Provide Info for statistics &Provide info for statistics Browse Przeglądaj Move DB Przenieś DB The search box will show also the callsign on the air to do the QSO. W polu wyszukiwania zostanie wskazany również znak stacji pracującej z którą można zrobić QSO. All the data from the My Data tab will be used or data from the previous QSO will be maintained. Zostaną wykorzystane wszystkie dane zapisane w zakładce Moje Dane lub dane z poprzednich QSO zostaną zaktualizowane. Check if there is a new release of KLog available every time you start KLog. Sprawdź czy są dostępne nowe wydania KLog każdorazowno kiedy KLog jest uruchamiany. Check it for Imperial system (Miles instead of Kilometres). Zaznacz aby wybrać system Imperialny ( Mile zamiast Kilometrów ). Select to use real time. Zaznacz aby pracować w czasie rzeczywistym. Select to use UTC time. Zaznacz aby użyć czasu UTC. Select if you want to save to ADIF on exit. Zaznacz aby zapisać do ADIF przy wyjściu z programu. Complete the current QSO with previous QSO data. Uzupełnij obecne QSO danymi z poprzednich QSO. This is the directory where the database (logbook.dat) will be saved. To jest katalog w którym baza danych ( logbook.dat) zostanie zapisana. Click to change the path of the database. Kliknij aby zmienić miejsce w którym baza danych zostanie zapisana. This is the directory where DB (logbook.dat) will be saved. To jest katalog w którym DB ( logbook.dat ) zostanie zapisana. Click to change the default ADIF file. Kliknij aby zmienić domyślny plik ADIF. Click to move the DB to the new directory. Kliknij aby przenieść DB do nowego katalogu. Open File Otwórz plik Select Directory Zaznacz Katalog File moved Plik przeniesiony File copied Plik skopiowany File NOT copied Plik NIE skopiowany The target directory does not exist. Please select an existing directory. Katalog docelowy nie istnieje . Proszę wybrać istniejący katalog. SetupPageUserDataPage &Personal data &Personal data Station &data Station &data Enter your name Wpisz swoje imie Enter your address - 1st line Wpisz swój adres - Pierwsza linja Enter your address - 2nd line Wpisz swój adres - Druga linja Enter your address - 3rd line Wpisz swój adres - Trzecia linja Enter your address - 4th line Wpisz swój adres - Czwarta linja Enter your city Nazwa miasta Enter your zip code Kod pocztowy Enter your province or state Nazwa gminy lub województwa Enter your country Twój kraj &Name &Name &Address &Address Cit&y Cit&y &Zip Code &Zip Code Pro&v/State Pro&v/State Countr&y Countr&y Enter your information for rig Wpisz informacje o swoim radiu Enter your information for antenna Wpisz informacje o swojej antenie Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign. Wpisz lokator swojej stacji. Alternatywnie KLog może skorzystać z przybliżonej lokalizacji bazując na Twoim znaku wywoławczym. Enter your power information Wpisz moc z jakiej korzystasz &Rig 1 &Rig 1 R&ig 2 R&ig 2 Ri&g 3 Ri&g 3 Antenna &1 Antenna &1 Antenna &2 Antenna &2 Antenna &3 Antenna &3 Po&wer Po&wer Enter the station callsign that will be used for logging Wprowadź znak stcji z którego będziesz korzystał podczas logowania Enter the operators (comma separated if more than one). Wpisz operatorów ( skorzystaj z przecinka jeśli więcej niż jeden ). &QRZ &QRZ &Operators &Operators &CQ Zone &CQ Zone &ITU Zone &ITU Zone &Locator &Locator &Locator (not valid) &Locator (not valid) SetupPageWorldEditor An entities information file (cty.csv) has been detected in your KLog folder and will be loaded. Plik z informacjami jednostek DXCC ( cty.csv ) został wykryty w katalogu KLog i zostanie on wczytany. No entities information file (cty.csv) has been detected in your KLog folder. Plik z jednostkami DXCC nie został wykryty ( cty.csv) w folderze KLog. KLog will not be able to show entities information. KLog nie będzie mógł pokazać informacji jednostek DXCC. Prefix Prefix Entity Jednostka ARRL ID ARRL ID Continent Kontynent CQ Zone Strefa CQ ITU Zone Strefa ITU UTC UTC Latitude Szerokość geograficzna Longitude Długość geograficzna Deleted Usunięty Since Date Od daty To Date Do daty Open File Otwórz plik BigCTY (*.csv) BigCTY (*.csv) Entities information has been updated. Informacje o jednostkach DXCC zostały zaktualizowane. Entities information has not been updated. Informacje o jednostkach DXCC nie zostały zaktualizowane. ShowErrorDialog KLog Message SoftwareUpdateDialog Ok OK KLog update Aktualizacja KLog Congratulations! Gratulacje! Your KLog has been updated. Twój KLog został zaktualizowany. You already have the latest version. Już posiadasz najnowszą wersję. StartWizard KLog - The free hamradio logging program KLog - Darmowy program logujący dla krótkofalowców Quit Setup Opuść Ustawienia Setup is not complete yet. Are you sure you want to quit setup? Ustawienia nie zostały jeszcze ukończone. Czy jesteś pewien że chcesz opuścić ustawienia? World Entity Jednostka Continent Kontynent Reading cty.csv... Wczytywanie cty.csv... Abort reading Przerwij wczytywanie eLogClubLog Host not found! Host nie został odnaleziony! Timeout error! Przekroczony został limit czasu! KLog - ClubLog Klog -ClubLog Undefined error... Niezidenfikowany błąd... Callsign missing Brak znaku wywoławczego Invalid callsign Niepoprawny znak wywoławczy Skipping SWL callsign Opuszczanie znaków wywołaczych stacji nasłuchowych SWL Callsign is your own call Znka wywoławczy jest Twoim własnym znakiem Invalid callsign with no DXCC mapping Niepoprawny znak wywoławczy brak w spisie DXCC Updated QSO QSO Zaktualizowane Invalid ADIF record Niepoprawny zapis ADIF Missing ADIF record Brakujący wpis ADIF Test mode - parameters ok, no action taken Tryb testujący -Parametry OK, brak akcji It seems to be a PASSWORD ERROR; check your password. Wygląda na BŁĘDNE HASŁOOR; sprwdź hasło. It seems that your ClubLog password is not correct. Wygląda na to że Twoje hasło do ClubLog jest nie poprawne. Please check your password in the setup. ClubLog uploads will be disabled. Proszę sprawdź hasło w ustawieniach. Aktualizajcja ClubLog będzie wyłączona. Excessive API Usage Znaczne użcie API Internal Error Błąd wewnętrzny Rejected Odrzucony QSO Duplicate QSO zduplikowane QSO Modified QSO Zmodyfikowane Missing Login Brakujący Login QSO OK QSO OK Upload denied Przesyłanie odrzucone No callsign selected Znak wywoławczy nie zaznaczony No match found Nie znaleziono poasujących elemętów Dropped QSO QSO Opuszczone OK OK Login rejected Logowanie odrzucone Rejected: Callsign is your own call Odrzucone: Znak wywoławczy jest Twoim własnym znakiem klog-0.9.2.9/translations/klog_es.ts0000644000076700000620000056217413233376355015340 0ustar staff AboutDialog About KLog Acerca de KLog Authors Autores By Por Please know that this is an BETA release and it may contain many bugs.<br>Backup your data before using this software! Por favor, tenga en cuenta que esta es una versión BETA que puede tener muchos errores.<br>¡Haga copia de seguridad de sus datos antesde usar este programa! Author Autor KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing. KLog fue reescrito completamente en su versión 0.6.2 para hacerlo multiplataforma de forma que pudiera ejecutarse en los sistemas operativos principales (Linux, macOS & Windows) y proveer funcionalidades nuevas que aun no se proveían. KLog is a free logbook for hamradio operators. KLog es un software libre de log para radioaficionados. Please provide your review in KLog's eHam review page: Por favor, escribe tu crítica en la página de críticas de eHam: Find more information and the latest release at Más información y la última versión en If you want to provide support you are welcome to join the Si quieres colaborar eres bienvenido a unirte a KLog development mailing list la lista de desarrollo de KLog ! ! If KLog is still not in your language and you want to help us, you are welcome to contact us through the Si KLog aun no está en su idioma y quiere ayudarnos, es bienvenido a contactar con nosotros a través de la today hoy Main developer Desarrollador principal KLog is developed by a very small team and you are invited to join! ¡KLog está desarrollado por un equipo muy pequeño y estás invitado a unirte! You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog. Puedes ayudarnos reportando errores o pequeñas contribuciones de código, ideas o cualquier otra cosa que creas que pueda mejorar KLog. KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs Los desarrolladores de KLog han incluido una función que reporta algunos datos del usuario al servidor de KLog con el único objetivo de saber el número de versiones instaladas y poder centrar el desarrollo en una u otra dirección en función de las necesidades de los usuarios. At present, the data that is provided is the following: Hoy, los datos que se proporcionan son los siguientes: Be aware that you can enable/disable this feature from the Misc tab in the Setup page Sepa que puede habilitar/deshabilitar esta función en la pestaña de Varios de la página de configuración Translators bring KLog into your language. They are really an important part of the KLog development team. Los traductores traen KLog a tu idioma. Son una parte realmente importante del equipo de desarrollo de KLog. Translators Traductores Privacy advisory Aviso de privacidad Callsign Indicativo KLog version Versión de KLog Operating system Sistema operativo KLog KLog Privacy Privacidad CTYPage Country data download Descargar datos de entidades KLog needs country data... KLog necesita datos de las entidades ... &Download &Descargar &Ignore &Ignorar Country data needed Información de entidades KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information. KLog usa el fichero cty.csv (de http://www.country-files.com/) para obtener la información del DXCC. You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do. Necesita descargar el cty.csv si quiere que KLog muestre información de entidad, locator, ... de los QSO que haga. Click on Download to download now. Pulse en Descargar para descargar ahora. KLog KLog I can't find the host. Please check your network and try again Do you want to try again? No se pudo encontrar la máaquina. Revise su configuración de red y pruebe de nuevo ¿Quiere volverlo a intentar? DXCCStatusWidget Update Actualizar ID ID Entity Entidad DXClusterWidget Connect Conectar Clear Limpiar Click on connect to connect to the DX-Cluster Pulse en conectar para conectar al DX-Cluster KLog DXCluster Kontest DXCluster DXCluster de KLog Click on Connect to connect to the DX-Cluster server Pulse en Conectar para conectar al servidor de DX-Cluster Trying to connect to the server Intentando conectar con el servidor The connection was refused by the peer. Make sure the DXCluster server is running, and check that the host name and port settings are correct. La conexióon fue rechazada por el servidor. Asegúrese de que el servidor de DXCluster estáa ejecutáandose y compruebe el nombre de máquina y puerto. The following error occurred: %1. El siguiente error ha tenido lugar: %1. Connected to server Conectado al servidor KLog message Kontest message Mensaje de KLog Enter your callsign to connect to the cluster: Introduzca su indicativo para conectar al cluster: Enter your password to connect to the cluster: (Just hit enter for no password) Introduzca su contraseña para conectar al cluster: (pulse enter si no hay contraseña) Not logged on, you may need to enter your callsign again. No identificado, puede introducir su contraseña de nuevo. Disconnect Desconectar The host was not found. Please check: No se ha encontrado el servidor. Por favor revise: - your network connection; - the host name and port settings. - la conexión de red; - el nombre de máquina y puerto. Enter here the commands to be sent to the DX-Cluster server Introduzca aquí los comandos a enviar al servidor de DX-Cluster Connection closed by the server Conexión cerrada por el servidor Send Enviar DataProxy_SQLite Software version in DB is null La versión de software de la BBDD es nulo No query failed No falló ninguna query KLog DXCC KLog DXCC All QSOs have been updated with a DXCC. Se ha añadido el DXCC a todos los QSOs. DownLoadCTY Download of cty.csv failed with the following error code: La descarga de cty.csv falló con el siguiente código de error: Download of cty.csv done. Descarga de CTY.CSV finalizada. There is already a cty.csv file in the folder but it will be replaced with the new one. Ya hay un cty.csv en la carpeta pero será reemplazado por el nuevo. Could not open No pudo abrirse for writing. para escribir. FileManager Reading ADIF file... Leyendo fichero ADIF... Abort reading Cancelar lectura The log that you have selected contains more than just one station callsign. El log que ha seleccionado contiene más de un sólo indicativo de estación. Please select the station callsing you want to export the log from: Por favor seleccione el indicativo de estación del que quiere exportar el log: Station Callsign: Indicativo de la estación: Define Station Callsign Definir indicativo de estación You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here. No ha seleccionado indicativo. KLog exportará los QSOs sin un indicativo de estación definido y aquellos con el indicativo que está seleccionando aquí. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Introduzca el indicativo de estación para usar en este log o déjelo vacío para poner un QSO sin un indicativo de estación definido: Writing ADIF file... Escribiendo fichero ADIF... Abort writing Cancelar escritura Exporting LoTW ADIF file... Exportando fichero ADIF de LoTW... Writing ADIF file... QSO: Escribiendo fichero ADIF ... QSO: Writing Cabrillo file... Escribiendo fichero Cabrillo ... KLog: Cabrillo Log Export not implemented Kontest: Cabrillo Log Export not implemented KLog: La exportación de log en en formato Cabrillo no está implementada I am sorry but the Cabrillo Export To File feature has still not been implemented. Lo sentimos pero la función de Exportar Cabrillo aun no está implementada. Reading LoTW file... Leyendo fichero LoTW... There are more than one log in this logfile. All logs will be imported in the current log. Do you want to continue? Hay más de un log en este fichero. Todos los logs se importarán al log actual. ¿Quiere continuar? Importing ADIF file... QSO: Importando fichero ADIF... QSO: You have cancelled the file export. The file will be removed and no data will be exported. Do you still want to cancel? Ha cancelado la exportación del fichero. El fichero se eliminará y no se exportará ningún dato. ¿Quiere cancelar? Do you want to continue with the current file? ¿Quiere continuar con elfichero actual? This log seems to lack of RST-TX information. Este log parece que no tiene la información de RST-TX. Click on Yes to add a default 59 to all QSO with a similar problem. Pulse en Si para añadir 59 de forma predeterminada a todoslos QSO con un problema similar. If you select NO, the QSO may not be imported. Si selecciona No, el QSO puede no ser importado. This log seems to lack of RST-RX information. Este log parece que no tiene la información de RST-RX. - The band missing and the following call: - La banda inexistente pero el siguiente indicativo: - The call missing but was done at this time: - El indicativo inexistente pero la siguiente hora: - The mode missing and the following call: - El modo inexistente pero el siguiente indicativo: - The date missing and the following call: - La fecha inexistente pero el siguiente indicativo: - The time missing and the following call: - La hora inexistente pero el siguiente indicativo: You have canceled the file export. The file will be removed and no data will be exported. Has cancellado la exportación del fichero. El fichero se eliminará y no se exportará ningún dato. Do you still want to cancel? ¿Aun quiere cancelar? QSO: QSO: No station callsign has been selected and therefore no log will be exported No se ha seleccionado indicativo de estación por lo que no se exportará ningún log There is more than one log in this logfile. Hay más de un log en este fichero. All logs will be imported into the current log. Todos los logs se importarán en el log actual. Do you want to continue? ¿Quiere continuar? Importing ADIF file... Importando fichero ADIF... You have cancelled the file import. The file will be removed and no data will be imported. Has cancelado la importación del fichero. El fichero se eliminará y no se importará ningún dato. It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported) Parece que hay algunos QSO duplicados en el fichero ADIF que está importando. ¿Quiere continuar? (los QSO duplicados no se importarán) An unexpected error ocurred while importing. Please send this code to the developer for analysis: Ha ocurrido un error inesperado al importar. Por favor, envía este códido a los desarrolladores para que lo analicen: An error ocurred while importing. No data will be imported. Please send this code to the developer for analysis: Ha ocurrido un errot al importar. No se importarán datos. Por favor envíe este código a los desarrolladores para que lo analicen: This QSO is not including the minimum data to consider a QSO as valid!. ¡Este QSO no incluye la información mínima para considerarse un QSO válido! Please edit the ADIF file and make sure that it include at least: Por favor, edite el fichero ADIF y asegúrese de que incluye al menos: and y This QSO had: Este QSO tenía: KLog: Not all required data found! KLog: ¡No se encontraron todos los datos necesarios! KLog: No RST TX found! KLog: ¡No se encontró RST TX! KLog: No RST RX found! KLog: ¡No se encontró RST RX! InfoWidget 10M 10M 15M 15M 20M 20M 40M 40M 80M 80M 160M 160M 2M 2M 6M 6M 12M 12M 17M 17M 30M 30M 70CM 70Cm Continent Continente Prefix Prefijo CQ CQ ITU ITU Short Path Salto corto Long Path Salto largo Degree Grados Grad Grad Miles Millas Km Km IntroPage Welcome to KLog! Welcome to Kontest! ¡Bienvenido a KLog! Welcome to KLog! - brought to you under the terms of the GPL! ¡Bienvenido a KLog - disponible gracias a los términos de la GPL! Welcome to KLog Bienvenido a KLog This looks like it's the first time you've run KLog on this computer. Parece que es la primera vez que ejecuta KLog en este ordenador. KLog is a free hamradio logging program that can run on Linux macOS and Windows. KLog es un programa libre de log de radioaficionados que puede correr en Linux, macOS y Windows. It is designed to provide general purpose, DX and contest logging. Está diseñado para proveer de log de propósito general, DX y concursos. It supports QSL management, import and export of ADIF Soporta gestión de QSL, importa y exporta formato ADIF and Cabrillo file formats and many other features... y Cabrillo y otras otras muchas funcionalidades... Before you can start using KLog, you will be asked to: Antes de empezar a usar KLog, se le pedirá que: Acknowledge to the terms of the license. Conocer los térmimos de la licencia. Download the DX entities information. Descargar los datos de entidades DX. Enter your callsign, CQ zone, etc. and main configuration. Introduzca el indicativo, zona CQ, etc y la configuración principal. Enjoy KLog and contact the development team if you have any suggestions! ¡Disfrute de KLog y contacte con el equipo de desarrollo si tiene alguna sugerencia! LicPage KLog License information Información de licencia de KLog Welcome to KLog!- brought to you under the terms of the GPL! ¡Bienvenido a KLog - disponible gracias a los términos de la GPL! Acknowledge Aceptar Be aware that KLog is free software. Sepa que KLog es software libre LogModel Date Fecha Time Hora QRZ QRZ Band Banda Mode Modo RSTtx RSTtx RSTrx RSTrx Comment Comentario LogWindow QSL Send Enviar QSL QSL Rcvd QSL Recibida &Delete &Borrar Delete a QSO Borrar un QSO &Edit QSO &Editar QSO Edit this QSO Edita este QSO Via &bureau Vía &bureau Send this QSL via bureau Envía esta QSL vía bureau D&irect D&irecta Send this QSL via direct Envía esta QSL vía directa Via bureau Vía bureau QSL &received via bureau QSL &recibida vía bureau Direct Directa QSL received via direc&t QSL recibida vía direc&ta You have requested to delete this QSO. Ha solicitado eliminar este QSO. Are you sure? ¿Está seguro? MainWindow &Clear &Limpiar Recalculate Recalcular Click to recalculate the award status Pulse para recalcular el estado de los diplomas Starting KLog Starting Kontest Iniciando KLog &Add &Añadir Status bar... Barra de estado ... DX Entity Entidad DX &Log Window Ventana de &Log &Score Window Ventana de &Puntuación MHz MHz An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: Ha ocurrido un error inesperado al intentar añadir el QSO a log. Si el problema persiste, contacte con el desarrollador para su análisis: Log Log QRZ QRZ Band Banda Mode Modo Date Fecha Time Hora SRX SRX You have selected an entity: Ha seleccionado una entidad: Click on the prefix of the correct entity or Cancel to edit the QSO again. Pulsa en el prefijo de la entidad correcta o Cancelar para editar el QSO de nuevo. Clear the box Limpia el cuadro RSTtx RSTtx STX STX RSTrx RSTrx QRZ of the QSO QRZ del QSO TX RST RST TX RX RST RST RX TX Exchange Intercambio TX RX Exchange Intercambio RX Band of the QSO Banda del QSO Mode of the QSO Modo del QSO Date of the QSO Fecha del QSO Time of the QSO Hora del QSO Add the QSO to the log Añadir QSO al log Input Entrada Watts Vatios Ready Listo NEW MULT NUEVO MULT Ready... Listo... Save File Guardar fichero The logfile has been modified. Do you want to save your changes? El log se ha modificado. ¿Quiere guardar los cambios? &File &Fichero &New... &Nuevo ... &Open... &Abrir ... &Save As... &Guardar como ... Export ALL the QSOs into one ADIF file, merging QSOs from all the logs. Exportar TODOS los QSO de TODOS los logs al mismo fichero, mezclándolos en el mismo. &Print Log... &Imprimir log ... E&xit &Salir &Tools &Herramientas &Export to ADIF... &Exportar ADIF ... Invalid characters used in the QRZ Caracteres no válidos en el QRZ &Import from ADIF... &Importar ADIF ... Export to ADIF... Exportar a ADIF... Export all logs to ADIF... Exportar a ADIF todos los logs... Export Requested QSL to ADIF... Exportar a ADIF QSL requeridas... Export ADIF for LoTW... Exportar ADIF para LoTW... &Find QSO to QSL Buscar QSO a enviar &QSL Queue all QSL to be sent of this log Encola todas las QSL a enviar de este log Queue all QSL to be sent Encola todas las QSL a enviar Mark all queued QSOs as sent to LoTW. Marca todos los QSOs de la cola como enviados a LoTW. For updated DX-Entity data, update cty.csv. Para obtener datos actualizados de entidades DX, actualice el cty.csv. &Setup &Configurar &Setup... &Configurar... &Help &Ayuda &About... &Acerca de... Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW. Ahora se puede ir al menú Fichero para exportar el fichero ADIF de LoTW y subirlo a LoTW. The log that you have selected contains more than just one station callsign. El log que ha seleccionado contiene más de un sólo indicativo de estación. Please select the station callsing you want to mark as sent to LoTW: Por favor, seleccione el indicativo de estación del que quiere marcar como enviados a LoTW: Station Callsign: Indicativo de la estación: Define Station Callsign Definir indicativo de estación You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here. No ha seleccionado inficativo. KLog marcará todos los QSOs sin un indicativo de estación definido con el indicativo que añada aquí. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Introduzca el indicativo de estación para usar en este log o déjelo vacío para poner un QSO sin un indicativo de estación definido: No station callsign has been selected and therefore no log will be marked No se ha introducido indicativo de estación y no se marcará ningún log DUPE DUPLICADO It seems that there are no QSO in the database. Parece que no hay QSO en la base de datos. If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help. Si está seguro de que la base de datos contiene QSO y KLog no es capaz de encontrarlos, contacte con los desarrolladores para más ayuda (Acerca de KLog). Number of QSOs worked on the selected year. QSOs trabajados en el año seleccionado. Power(rx) Potencia (rx) RST(tx) RST(tx) RST(rx) RST(rx) QSO QSO QSL QSL eQSL eQSL Satellite Satélite LoTW logfile has been properly exported! El log de LoTW se ha exportado correctamente. There was no QSO to be exported. No se encontró ningún QSO a exportar. If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as: Si piensa que algún QSO debería haber sido exportado, por favor búsquelo y asegúrese de que el cuadro de el envío de eQSL LoTW QSL está marcado: Q - Queued Q - En cola There was an error while exporting the LoTW. The log has not been exported! Hubo un error al exportar el fichero LoTW. El log no se ha exportado. -- -- - Needed for DXMarathon - Necesitado para DXMarathon Others Otros KLog folder Carpeta de KLog KLog update checking result Resultado de proceso de ccomprobación de actualizaciones You can find the KLog data folder here: Puede encontrar la carpeta de KLog aquí: Name Nombre QTH QTH Locator Locator My Data Mis datos CQ CQ Info Info Award Diploma KLog KLog Click on the prefix of the right entity or Cancel to correct. Pulsa en el prefijo de la entidad adecuada o Cancelar para corregir. &Export Requested QSL to ADIF... &Exportar a ADIF QSL requeridas... Fill in QSO data Rellenar datos de QSO Find My-QSLs pending to send Buscar QSLs pendientes de enviar Shows the QSOs with pending requests to send QSLs. You should keep this queue empty! Muestra los QSO con solicitudes de QSL. ¡Debería mantener esto vacío! About Qt... Acerca de Qt... About... Acerca de ... Nothing has been saved. You have to select a valid file type. No se ha guardado nada. Debe especificar un tipo de fichero válido. Freq TX Freq TX Freq RX Freq RX Confirmed Confirmados Worked Trabajados DXCC DXCC &Export all logs to ADIF... &Exportar a ADIF todos los logs... &Find DX-QSLs pending to receive B&uscar QSL DX pendientes de recibir that is different from the KLog proposed entity: que es diferente a la que KLog propone: Import an ADIF file into the current log. Importa un fichero ADIF al log actual. Export the current log to an ADIF logfile. Exporta el log actual a un fichero ADIF. Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program). Exporta todas las peticiones de QSL a un fichero ADIF (para, p.e. importarlo a un programa de impresión de tarjetas QSL). &Export ADIF for LoTW... &Exportar ADIF para LoTW... Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW! Exporta el fichero ADIF para enviar a LoTW. Recuerda firmarlo conTQSL antes de subirlo a LoTW. Print your log. Imprime el log. Opens the data folder of KLog. Abre la carpeta de datos de KLog. Go through the log reusing previous QSOs to fill missing information in other QSOs. Recorre el log reusando QSOs anteriores para rellenar datos de otros QSOs. Fill in DXCC data Completar info DXCC Go through the log filling QSOs without a DXCC defined. Recorre el log completando los QSO que no tienen la entidad DXCC definido. QSL tools... Herramientas de QSL... Shows QSOs for which you should send your QSL and request the DX QSL. Muestra los QSOs a los que debería enviar su QSL y solicitar la QSL DX. Shows the DX-QSL that has been requested or QSLs has been sent with no answer. Muestra las QSL DX que han sido solicitadas o las QSLs que han sido enviadas sin respuesta. &Find requested pending to receive Bu&scar QSL DX solicitadas pendientes de recibir Shows the DX-QSL that has been requested. Muestra las QSL DX que han sido solicitadas. LoTW tools... Herramientas LoTW... Mark all non sent QSOs in this log as queued to be uploaded. Marca todos los QSO no enviados de este log como en cola para ser subidos. Mark all non sent QSOs as queued to be uploaded. Marca todos los QSO no enviados de este log como en cola para ser subidos. Mark as sent all queued QSO of this log Marcar como enviados todos los QSO de este log Mark all queued QSOs in this log as sent to LoTW. Marca todos los QSOs de la cola de este log como enviados a LoTW. Mark all queued QSO as sent Marcar todos los QSO de la cola como enviados &Update cty.csv Act&ualizar cty.csv KLog LoTW KLog LoTW All pending QSO of this log has been marked as queued for LoTW! Todos los QSO pendientes del log se han añadido a la cola de LoTW. There was a problem to mark all pending QSO of this log as queued for LoTW! Hubo un problema al añadir todos los QSO pendientes del log a la cola de LoTW All pending QSO has been marked as queued for LoTW! Todos los QSO pendientes se han añadido a la cola de LoTW. All queued QSO of this log has been marked as sent for LoTW! Todos los QSO de la cola de este log se han marcado como enviados a LoTW. There was a problem to mark all queued QSO of this log as sent for LoTW! Hubo un problema al marcar como enviados los QSO de la cola de envío de LoTW. All queued QSO has been marked as sent to LoTW! Todos los QSO de la cola se han marcados como enviados a LoTW. There was a problem to mark all queued QSO of this log as sent to LoTW! Hubo un problema al marcar como enviados los QSO de de la cola de envío de LoTW de este log. Congratulations! ¡Enhorabuena! You already have the latest version. Ya cuenta con la última versión. ADIF file Ficheros ADIF Cabrillo files Ficheros Cabrillo Any file Cualquier fichero The selected log is not existing or it is still empty. El log seleccionado no existe o está vacío. Click Yes and KLog will open an empty log. Pulse en Si y KLog abrirá un log vacío. Click No and KLog will select another log with data. Pulse en No y KLog seleccionará otro log con datos. You can modify the config file accordingly, if needed. Puede modificar el fichero de configuración, si es necesario. TX Frequency in MHz. Frecuencia de TX en MHz. RX Frequency in MHz. Frecuencia de RX en MHz. Power used by the DX. Potencia usada por el DX. Logging operator's callsign. Indicativo del operador. Callsign used over the air. Indicativo usado en el aire. My QTH locator. Mi QTH locator. Name of the DX. Nombre del DX. QTH of the DX. QTH del DX. Locator of the DX. Locator del DX. QRZ of the QSO. QRZ del QSO. TX RST. RST TX. RX RST. RST RX. TX Exchange. Intercambio TX. RX Exchange. Intercambio RX. Band of the QSO. Banda del QSO. Mode of the QSO. Modo del QSO. Date of the QSO. Fecha del QSO. Time of the QSO. Hora del QSO. Add the QSO to the log. Añadir QSO al log. Clears the QSO entry. Limpia la entrada de QSO. Number of confirmed DXCC entities. Número de entidades DXCC confirmadas. Number of worked DXCC entities. Número de entidades DXCC trabajadas. Number of confirmed WAZ zones. Número de zonas WAZ confirmadas. Number of worked WAZ zones. Número de zonas WAZ trabajadas. Number of confirmed local references. Número de referencias locales confirmadas. Number of worked local references. Número de referencias locales trabajadas. Number of confirmed QSOs. Número de QSO confirmados. Number of worked QSOs. Número de QSO trabajados. Number of DXCC worked on the selected year. Número de DXCC trabajados en el año seleccionado. Number of CQ Zones worked on the selected year. Número zonas CQ trabajadas en el año seleccionado. Score for the DXMarathon on the selected year. Puntuación para el DXMarathon del año seleccionado. Select the year you want to check. Seleccione el año que quiere comprobar. Status of the DX entity. Estado de la entidad DX. Name of the DX entity. Nombre de la entidad DX. Score Puntuación DX-Marathon DX-Marathon WAZ WAZ Local Local An unexpected error ocurred!! ¡Ha ocurrido un error inesperado! If the problem persists, please contact the developers Si el problema persiste, contacte con los desarrolladores for analysis: para que lo analicen: Error in function Error en la funcion Error code Código de error Error text Texto del error Failed query Query fallida Do you want to keep showing errors? ¿Quiere seguir mostrando los errores? QSOs QSOs Awards Diplomas Search Buscar DX-Cluster DX-Cluster Save ADIF File Guardar fichero ADIF Remember to: Recuerde: Before uploading: sign the LoTW log; and Antes de enviar: firmar el log de LoTW; y After uploading: mark as sent all the queued QSO (LoTW Tools). Después de enviar: marcar como enviados todos los QSO en cola (Herramientas LoTW). Save Cabrillo File Guardar fichero Cabrillo Cabrillo (*.log) Cabrillo (*.log) Open File Abrir fichero &Modify &Modificar Filling QSOs... Rellenando QSOs... Abort filling Cancelar rellenado Filling QSOs... QSO: Rellenando QSOs... QSO: Number Número Comment Comentario Check updates... Comprobar actualizaciones... Print Log Imprimir log Printing the log... Imprimiendo el log... Abort printing Cancelar impresión Printing the log... QSO: Imprimiendo el log ...QSO: MainWindowInputComment Add a comment for this QSO Añadir un comentario a este QSO MainWindowInputEQSL Date of the ClubLog upload. Dato del envío a ClubLog. Date of the eQSL sending. Fecha del envío de eQSL. Date of the eQSL reception. Fecha de la recepción de eQSL. Date of the LoTW sending. Fecha del envío de LoTW. Date of the LoTW reception. Fecha de la recepción de LoTW. Status of the LoTW sending. Estado del envío de LoTW. Status of the LoTW reception. Estado de la recepción de LoTW. LoTW Sent Envío LoTW LoTW Rec Recepción LoTW Status on ClubLog. Estado en ClubLog. Status of the eQSL sending. Estado de envío de eQSL. Status of the eQSL reception. Estado de recepción de eQSL. ClubLog ClubLog eQSL Sent Envío eQSL eQSL Rec Recepción eQSL MainWindowInputOthers Primary Div Div principal Secondary Div Div secundaria IOTA IOTA Entity Entidad Propagation mode Modo de propagación Select the primary division for this QSO Seleccione la división principal de este QSO Select the secondary division for this QSO Seleccione la división secundaria de este QSO Select the entity for this QSO Seleccione la entidad para este QSO Select the propagation mode for this QSO Seleccione el modo de propagación para este QSO Select the IOTA continent for this QSO Seleccione el continente IOTA para este QSO Select the IOTA reference number for this QSO Seleccione la referencia IOTA para este QSO Not Identified Sin identificar Not - Not Identified No - Sin identificar MainWindowInputQSL QSL Sent QSL Enviada QSL Rec QSL Rec QSL Via QSL Vía QSL Msg Msj QSL Status of the QSL sending. Estado del envío de QSL. Status of the QSL reception. Estado de la recepción de QSL. QSL sending information. Información de envío de QSL. QSL reception information. Información de recepción de QSL. Date of the QSL sending. Fecha del envío de QSL. Date of the QSL reception. Fecha de recepción de QSL. Message of the QSL. Mensaje de la QSL. QSL via information. Información de QSL via. MainWindowMyDataTab Watt Vatio Keep this data Mantener estos datos Data entered in this tab will be copied into the next QSO Los datos introducidos en esta pestaña se copiarán al siguiente QSO Power used for the QSO in watts Potencia usada para el QSO en vatios Logging operator's callsign Indicativo del operador Callsign used over the air Indicativo usado en el aire My QTH locator Mi QTH locator Power Potencia Operator Operador Station Callsign Indicativo de la estación My Locator Mi locator MainWindowSatTab Keep this data Mantener estos datos Data entered in this tab will be copied into the next QSO Los datos introducidos en esta pestaña se copiarán al siguiente QSO Satellite mode used Modo del satélite usado Select the satellite you are using Seleccione el satélite que está usando UpLink band Banda de subida. DownLink band Banda de bajada. Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab. Locator de la estación DX. Este cuadro se sincronizará con el cuadro de Locator en la pestaña QSO. UpLink Subida DownLink Bajada Satellite Satélite Mode Modo DX Locator Locator DX Other Otro MHz MHz Not Sat QSO QSO sin satélite KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name. KLog ha detectado un nombre de satélite no reconocido. Si debería ser uno de los satélites conocidos, por favor seleccionelo de la lista. Alternativamente puede contactar con el equipo de desarrollo para que añadan el nuevo nombre de satélite. Please know that the satellite name will not be saved if it is not in the list so that information may be lost! ¡Tenga en cuenta que el nombre del satélite no se guardará si no está en la lista y puede perder esa información! Other - Sat not in the list Otro - Satélite no en la lista Name of the Satellite if not in the list. Select: " El nombre del satélite no está en la lista. Seleccione: " " to enable this box. (format like AO-51) " para habilitar este cuadro. (formato como AO-51) The satellite you have in your QSO is: El satélite que tiene en su QSO es: QObject Database Error Error de base de datos KLog DB needs to be upgraded. La BD de KLog necesita actualizarse. Do you want to upgrade it now? ¿Quiere actualizar ahora? If DB is not upgraded KLog may not work properly. Si no actualiza la base de datos es posible que KLog no funcione correctamente. KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you. KLog ha detectado un log anterior en la BD. Todos los datos serán migrados a un log tipo DX creado para usted. KLog: Enter Station callsign KLog: Introduzca indicativo Enter the station callsign used in this log Introduzca el indicativo usado en este log Station Callsign Indicativo de la estación All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK. Todos los datos se han migrado de forma correcta. Ahora debería ir a Preferencias->Logs para compribar que todo está OK. QSO: QSO: Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel? Cancelar esta actualización causará inconsistencia de datos y posible pérdida de datos. ¿Quiere cancelar? Progress: Progreso: Updating DXCC award information... Actualizand la información del diploma DXCC... Updating DXCC Award information... Actualizando la información del diploma DXCC... Updating WAZ award information... Actualizando la información del diploma WAZ... Updating mode information... Actualizando información de modo... Abort updating Cancelar actualización Updating bands information... Actualizando información de bandas... Updating bands information in %1 status... Actualizando información de bandas en %1... Updating mode information in %1 status... Actualizando información de modos en %1... New One, work it! nNew One, work it! ¡Nuevo, trabájelo! Needed, work it! ¡Necesitado, trabájelo! Worked but not confirmed Trabajado pero no confirmado Confirmed Confirmado Not identified No identificado Install wizard was canceled before completing... El asistente de instalación fué cancelado antes de terminar... Do you want to remove the KLog dir from your disk? ¿Quiere eliminar la carpeta de KLog de su disco? Your KLog dir has been removed Su directorio de KLog ha sido eliminado I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk. No se pudo eliminar su directorio de KLog. Debería eliminarlo manualmente si no lo quiere en su disco duro. Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk. No se pudo eliminar su directorio de KLog. Debería eliminarlo manualmente si no lo quiere en su disco duro. Remember that your KLog dir is on your system... Recuerde que la carpeta de KLog está en su sistema... Thank you for running KLog! ¡Gracias por usar KLog! Updating DXCC information... Actualizando información DXCC... SearchWidget &Clear &Limpiar &Select All &Seleccionar todos &Search Bu&scar All Todos &Export Highlighted &Exportar marcados Clear the searches. Limpiar búsquedas. Export the search result to an ADIF file. Exporta el resultado de la búsqueda a un fichero ADIF. Select/Unselect all the QSOs shown. Selecione/Deseleccione todos los QSOs mostrados. Search in the log. Buscar en el log. Search in all logs. Buscar en todos los logs. Enter the QRZ to search for. Introduzca el QRZ a buscar. Search results. Resultados de la búsqueda. QRZ QRZ Date/Time Fecha/Hora Band Banda Mode Modo QSL Sent QSL Enviada QSL Rcvd QSL Recibida Station Callsign Indicativo de la estación ID ID &Clear selection &Limpiar selección Save File Guardar fichero QSL Send Enviar QSL &Delete &Borrar Delete a QSO Borrar un QSO &Edit QSO &Editar QSO Edit this QSO Editar este QSO Via &bureau Vía &bureau Send this QSL via bureau Envia esta QSL vía bureau D&irect D&irecta Send this QSL via direct Envía esta QSL vía directa &Request my QSL &Requerir mi QSL Mark my QSL as requested Marcar mi QSL como requerida Via Direct && mark DX QSL as requested Vía directa y marcar QSL DX como solicitada Send this QSL via direct & mark DX QSL as requested Enviar esta QSL vía directa y marcar QSL DX como solicitada Via Bureau && mark DX QSL as requested Vía Bureau y marcar QSL DX como solicitada Send this QSL via bureau & mark DX QSL as requested Enviar esta QSL vía bureau y marcar QSL DX como solicitada &Request the QSL &Requerir la QSL Mark the QSL as requested Marcar la QSL como requerida Via bureau && mark my QSL as requested Vía bureau y marcar mi QSL como requerida QSL received via bureau & mark my QSL as requested QSL recibida vía bureau y marcar mi QSL como solicitada Via bureau Vía bureau QSL received via bureau QSL recibida vía bureau Direc&t && mark as my QSL requested Direc&ta y marcar mi QSL como requerida QSL received via direct & mark my QSL as requested QSL recibida vía directa y marcar mi QSL como requerida Direc&t Direc&ta QSL received via direct QSL recibida vía directa You have requested to delete the QSO with: Ha solicitado eliminar el QSO con: Are you sure? ¿Está seguro? Needed QSO to send the QSL QSO al que es necesario enviar la QSL My QSL requested to be sent Se ha solicitado el envío de mi QSL DX QSL pending to be received QSL del DX pendiente de recibir SetupDialog User data Datos de usuario Bands/Modes Bandas/modos My Data Mis datos DX-Cluster DX-Cluster Colors Colores Misc Varios World Editor Editor de entidades ClubLog ClubLog Cancel Cancelar OK OK Config Dialog Configuración D&X-Cluster D&X-Cluster You need to enter at least one log in the Logs tab. Debe introducir al menos un log en la pestaña de Logs. Misc tab pestaña Varios and click on y pulsar en Move DB mover BBDD or the DB will not be moved to the new location. o la BBDD no se moverá a la nueva ubicación. You need to enter at least a valid QRZ. Debe introducir un QRZ válido. Go to the Ir a la DB has not been moved to new path la BBDD no se ha movido a la nueva ubicación User tab Pestaña Usuario and enter valid QRZ. e introduzca un QRZ válido. You have not selected the kind of log you want. No ha seleccionado el tipo de log que quiere. You will be redirected to the Log tab. Please add and select the kind of log you want to use. Será redirigido a la pestaña de Log. Añada y seleccione el tipo de log que quiere usar. Logs Logs World Entidades SetupEntityDialog Entity Entidad Name of the Entity Nombre de la entidad CQ CQ CQ zone Zona CQ ITU ITU ITU zone Zona ITU Latitude Latitud Longitude of the Entity Longitud de la entidad Longitude Longitud UTC UTC Local time difference to UTC Diferencia de la hora local con UTC Main prefix Prefijo Main prefix of the entity Prefijo principal de la entidad ARRL ID ARRL ID Comma separated possible prefixes, e.g. EA1, EA2, ... Lista separada por comas de prefijos posibles. Ej. EA1, EA2, ... Prefixes Prefijos Date of the deletion Fecha de eliminación Deleted Eliminado Cancel Cancelar OK Ok Entity Dialog Entidad SetupPageBandMode Bands Bandas Modes Modos SetupPageClubLog &Callsign Indi&cativo ClubLog &password Contrase&ña ClubLog &email Correo &electrónico Enter the email you used to register in ClubLog. Introduzca el correo-e que usó para registrarse en ClubLog. Enter the callsign you used to register in ClubLog. Introduzca el indicativo que usó para registrarse en ClubLog. Enter your password in ClubLog. Introduzca su contraseña de ClubLog. &Send QSOs in real time &Enviar QSOs en tiempo real &Activate ClubLog &Activar ClubLog Use QSO Station &Callsign Usar indicativo de esta&ción del QSO Send each QSO to ClubLog in real time, as they are added (or modified) in KLog Enviar cada QSO a ClubLog en tiempo real, según se van añadiendo (o modificando) en KLog Starts the ClubLog support in KLog Inicia el soporte de ClubLog en KLog Use the Station Callsign defined in each QSO instead of the one defined here Usa en cada QSO el indicativo de estación definido en vez del definido aquí. SetupPageColors New One Nuevo Needed in this band Necesitado en esta banda Worked in this band Trabajado en esta banda Confirmed in this band Confirmed Confirmado en esta banda Default Predeterminado Choose a color Elija un color SetupPageDxCluster Add Añadir Delete Borrar Show &HF spots Show HF spots Mostrar avisos en I&HF Show V/&UHF spots Show V/UHF spots Mostrar avisos en V/&UHF Show W&ARC spots Show WARC spots Mostrar avisos en W&ARC Show &worked spots Show worked spots Mostrar a&visos trabajados Show &confirmed spots Show confirmed spots Mostrar avisos &confirmados Show ANN/&FULL messages Show ANN/FULL messages Mostrar mensajes ANN/&FULL Show WW&V messages Show WWV messages Mostrar mensajes &WWV Show WC&Y messages Show WCY messages Mostrar mensajes WC&Y DX Spots Avisos DX Messages Mensajes KLog: Add a DXCluster server Kontest: Add a DXCluster server KLog: Añadir servidor DX-Cluster Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default: Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default.: Añade la dirección seguida de :puerto Ejemplo: dxfun.com:8000 Si no se especifica puerto se usará 41112 de forma predeterminada: SetupPageLogs Type Tipo &New New &Nuevo &Edit &Editar &Remove Elimina&r Add a new log Añadir nuevo log Select the log you want to open Seleccione el log a abrir KLog KLog Do you really want to remove this log? ¿Realmente quiere eliminar este log? All the QSOs from this log will be also deleted... Todos los QSOs de este log también se eliminarán... Operators Operadores An error has occurred showing the following error code: Ha ocurrido un error que muestra el siguiente código de error: Log has not been removed. (#3) Log no eliminado (#3) Log has not been removed. (#2) Log no eliminado (#2) Log has not been removed. (#1) Log no eliminado (#1) KLog - SetupPageLogs KLog - SetupPageLogs Edit the selected log Editar el log selecionado Remove the selected log Eliminar el log seleccionado ID ID Station Callsign Indicativo de la estación Comments Comentarios Date Fecha SetupPageLogsNew &Ok &Ok &Cancel &Cancelar Select categories Seleccione categorías Callsign used for this log Indicativo usado para este log Comma separated list of operators: callsign1, callsign2 Lista separada por comas de los operadores: indicativo1, indicativo2 Start date of this log Fecha de inicio de este log Add a comment about this log Añada un comentario para este log Select the kind of operation for this log Seleccione el tipo de operación para este log Select the mode category Seleccione la categoría de modo Select the operators category Seleccione la categoría de operadores Select the assisted category Seleccione la categoría de asistido Select the power category Seleccione la categoría de potencia Select the bands category Seleccione la categoría de bandas &Date &Fecha &Station Callsign &Indicativo Estación &Operators &Operadores Comm&ent Com&entario &Type of Operation &Tipo de Operación &Mode Category &Modo operación O&perators Category Categoría O&peradores &Assisted Category Categoría &Asistido Po&wer Category Categoría &Potencia &Bands Category Categoría &Bandas O&verlay O&verlay Select the Overlay category Seleccione la categoría de overlay Categories not OK Categorías no OK You need to enter a valid QRZ in the Station Callsign box. The log will not be opened. You need to enter a valid QRZ in the Station Callsign box The log will not be opened. Necesita introducir un indicativo válido en el cuadro de Indicativo. El log no se abrirá. You selected an invalid combination. The log will not be opened. You selected an invalid combination The log will not be opened. Ha seleccionado una categoría no válida. El log no se abrirá. Categories OK Categorías OK SetupPageMisc &Imperial system Imperial system Sistema &imperial &Log in real time Log in real time &Log en tiempo real &Time in UTC Time in UTC Hora en U&TC &Save ADIF on exit Save ADIF on exit Guardar ADIF al &salir Use this &default filename Use this default filename Usar este fichero &de forma predeterminada Mark &QSO to send QSL when QSL is received Mark QSO to send QSL when QSL is received Marcar como &QSL por enviar cuando se recibe la QSL Complete QSO with previous data Completar QSO con datos anteriores &Reset to My Data for all QSOs &Reiniciar Mis Datos en todos los QSO Move DB Mover BBDD If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog. Si se selecciona el comprobar nuevas versiones, KLog enviará al desarrollador el indicativo, la versión de KLog y el sistema operativo para ayudar a mejorar KLog. Select to use the following name for the logfile without being asked for it again. Seleccione para usar el siguiente nombre de fichero y que no se le pregunte más. This is the default file where ADIF data will be saved. Este es el nombre de fichero predeterminado donde se guardará el fichero ADIF. This is the directory where the database (logbook.dat) will be saved. Este es el directorio donde la base de datos (logbook.dat) se guardará. Click to change the path of the database. Pulse para cambiar la ubicación de la base de datos. Please specify an existing directory where the database (logbook.dat) will be saved. Por favor, especifique un directorio existente donde la base de datos (logbook.dat) se almacenará. This is the directory where DB (logbook.dat) will be saved. Este es el directorio donde la base de datos (logbook.dat) se guardará. Click to change the default ADIF file. Pulse para cambiar el nombre predeterminado del fichero ADIF. Click to move the DB to the new directory. Pulse para mover la BBDD al nuevo directorio. Select Directory Seleccionar directorio File moved Archivo movido File copied Archivo copiado File NOT copied Archivo NO copiado The target directory does not exist. Please select an existing directory. El directorio destino no existe. Por favor, seleccione un directorio existente. The search box will show also the callsign on the air to do the QSO. El cuadro de búsqueda mostraráa también el indicativo usado para hacer el QSO. Show the Station &Callsign used in the search box Mostrar indicativo usado en el &cuadro de búsqueda All the data from the My Data tab will be used or data from the previous QSO will be maintained. Todos los datos de la pestaña Mis Datos se usarán o bien se usarán datos del QSO anterior. &Check for new versions automatically &Comprobar si hay nuevas versiones automáticamente QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours. Los QSO se marcarán como pendientes de enviar si se recibe la tarjeta del DX y no ha enviado la suya. Check if there is a new release of KLog available every time you start KLog. Comprueba si hay una nueva versión de KLog disponible cada vez que inicia KLog. &Provide Info for statistics &Proporcionar datos para estadísticas Check it for Imperial system (Miles instead of Kilometres). Marcar si quiere usar sistema imperial (Millas en vez de Kilómetros). Select to use real time. Seleccione para usar tiempo real. Select to use UTC time. Seleccione para usar UTC. Select if you want to save to ADIF on exit. Seleccione si quiere guardar en ADIF al salir. Complete the current QSO with previous QSO data. Completar el QSO actual con datos de QSO anteriores. Browse Buscar Open File Abrir fichero SetupPageUserDataPage &Personal data Personal data Datos &personales Station &data Station data &Datos de la estación Enter your name Introduzca su nombre Enter your address - 1st line Introduzca su dirección - 1ª línea Enter your address - 2nd line Enter your address - 2nd line Introduzca su dirección - 2ª línea Enter your address - 3rd line Introduzca su dirección - 3ª línea Enter your address - 4th line Introduzca su dirección - 4ª línea Enter your city Introduzca su ciudad Enter your zip code Introduzca su código postal Enter your province or state Introduzca su provincia o estado Enter your country Introduzca su país &Name Name &Nombre &Address Address &Dirección Cit&y City Ci&udad &Zip Code Zip Code Código &postal Pro&v/State Prov/State Pro&v/Estado Countr&y Country Paí&s Enter your information for rig Introduzca la información de su equipo/radio Enter your information for antenna Introduzca la información de su antena Enter your power information Introduzca información sobre su potencia &Rig 1 &Equipo 1 R&ig 2 E&quipo 2 Ri&g 3 Eq&uipo 3 Antenna &1 Antena &1 Antenna &2 Antena &2 Antenna &3 Antena &3 Po&wer Po&tencia Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign. Introduzca el locator de su estación. De forma alternativa, KLog puede proporcionarle uno aproximado basado en su indicativo. &QRZ &QRZ &Operators &Operadores &CQ Zone Zona &CQ &ITU Zone Zona &ITU &Locator &Locator &Locator (not valid) &Locator (no válido) Enter the station callsign that will be used for logging Introduzca el indicativo de la estación que será usado para el log Enter the operators (comma separated if more than one). Introduzca los operadores (separados por comas si hay más de uno). SetupPageWorldEditor KLog will not be able to show entities information. KLog no podrá mostrar información de entidades. Prefix Prefijo Entity Entidad An entities information file (cty.csv) has been detected in your KLog folder and will be loaded. Se ha detectado un fichero de información de entidades (cty.csv) en su carpeta de KLog y se utilizará. No entities information file (cty.csv) has been detected in your KLog folder. No se ha detectado en su carpeta de KLog ningún fichero de información de entidades (cty.csv). ARRL ID ARRL ID Continent Continente CQ Zone Zona CQ ITU Zone Zona ITU UTC UTC Latitude Latitud Longitude Longitud Deleted Eliminado Since Date Desde fecha To Date Hasta fecha Open File Abrir fichero BigCTY (*.csv) BigCTY (*.csv) Entities information has been updated. La información de entidades ha sido actualizada. Entities information has not been updated. La información de entidades no ha sido actualizada. ShowErrorDialog KLog Message Mensaje de KLog SoftwareUpdateDialog Ok Ok KLog update Actualización de KLog Congratulations! ¡Enhorabuena! Your KLog has been updated. Su KLog ha sido actualizado. You already have the latest version. Ya cuenta con la última versión. StartWizard KLog - The free hamradio logging program KLog - El programa libre de log de radioaficionados Quit Setup Salir Setup is not complete yet. Are you sure you want to quit setup? La configuración no está completa. ¿Está seguro de querer salir de la configuración? World Entity Entidad Continent Continente Abort reading Cancelar lectura Reading cty.csv... Leyendo cty.csv... eLogClubLog Host not found! ¡Máquina no encontrada! Timeout error! ¡Error de tiempo excedido! KLog - ClubLog KLog - clublog KLog - ClubLog Undefined error... Error no definido... Callsign missing Falta indicativo Invalid callsign Indicativo no válido Skipping SWL callsign Saltando indicativo SWL Callsign is your own call Callsign is your ow call El indicativo es su propio indicativo Invalid callsign with no DXCC mapping Indicativo no válido sin correspondencia con DXCC Updated QSO QSO actualizado Invalid ADIF record Registro ADIF no válido Missing ADIF record Falta registro ADIF Test mode - parameters ok, no action taken Modo Test - parámetros OK, sin acción It seems to be a PASSWORD ERROR; check your password. Parece haber un error de contraseña, revísela. It seems that your ClubLog password is not correct. Parece que su contraseña de ClubLog no es correcta. Please check your password in the setup. ClubLog uploads will be disabled. Revise su contraseña en las preferencias. Se deshabilitará la sincronización con ClubLog. Excessive API Usage Uso excesivo de API Internal Error Error interno Rejected Rechazado QSO Duplicate QSO duplicado QSO Modified QSO modificado Missing Login Falta login QSO OK QSO OK Upload denied Subida rechazada No callsign selected No se seleccionó indicativo No match found Sin coincidencia Dropped QSO QSO eliminado OK OK Login rejected Login rechazado Rejected: Callsign is your own call Rechazado: El indicativo es su propio indicativo klog-0.9.2.9/translations/klog_it.ts0000644000076700000620000055413213233376355015340 0ustar staff AboutDialog About KLog About KLog You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog. Per aiutare puoi comunicare bug, fornire nuovo codice, idee o suggerimenti o qualsiasi altra cosa possa migliorare KLog. Authors Autori By Da Please know that this is an BETA release and it may contain many bugs.<br>Backup your data before using this software! Per favore tieni conto che questa è una versione BETA e pertanto può contenere molti bug.<br>Copia i tuoi dati prima di usare questo software! Author Autore KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing. Dalla versione 0.6.2 KLog è stato completamente riscritto per poter funzionare su tutti i principali sistemi operativi (Linux, MacOS & Windows) oltre che nuove funzioni. KLog is a free logbook for hamradio operators. KLog è un software libero per radioamatori. Please provide your review in KLog's eHam review page: Per favore scrivi un tuo contributo sulla pagina commenti di KLog: today oggi Main developer Sviluppatore Senior KLog is developed by a very small team and you are invited to join! Klog è sviluppato da un esiguo numero di programmatori e tu sei invitato a partecipare! KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs Gli sviluppatori di KLog hanno inserito una funzione che trasmette alcuni dati utente al server di KLog con la sola finalità di contare le versioni effettivamente installate, per sviluppare KLog in modo più funzionale alle esigenze degli utenti At present, the data that is provided is the following: Correntemente, i dati forniti sono i seguenti: Be aware that you can enable/disable this feature from the Misc tab in the Setup page Tieni presente che puoi sempre abilitare/disabilitare questa funzione dalla tab Misc (Altro) della pagina di impostazioni Translators bring KLog into your language. They are really an important part of the KLog development team. I traduttori realizzano una versione KLog specifica per la tua lingua. Sono pertanto una parte importante della squadra di sviluppo di KLog. Find more information and the latest release at Cerca ulteriori informazioni e l'ultima versione presso If you want to provide support you are welcome to join the Se vuoi essere di aiuto sei benvenuto e puoi unirti alla KLog development mailing list Mailing list di sviluppo di KLog ! ! If KLog is still not in your language and you want to help us, you are welcome to contact us through the Se KLog non è ancora disponibile nella tua lingua e vuoi essere di aiuto, sei benvenuto e puoi contattarci tramite Translators Traduttori Privacy advisory Nota sul trattamento dei dati personali Callsign Nominativo KLog version Versione KLog Operating system Sistema operativo KLog KLog Privacy Privacy CTYPage Country data download Scarico dati Country KLog needs country data... KLog ha bisogno di informazioni sui Country... &Download &Scarica &Ignore &Ignora Country data needed Dati Country richiesti KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information. KLog usa il file cty.cvs disponibile su http://www.country-files.com/ per acquisire le informazioni DXCC. You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do. E' necessario scaricare il file cty.cvs se vuoi che KLog mostri countries, locator, ... relativi al QSO avvvenuto. Click on Download to download now. Clicca su Scarica per avviare lo scarico. KLog KLog I can't find the host. Please check your network and try again Do you want to try again? Non riesco a raggiungere l'host. Per favore verifica la tua conenssione di rete e riprova Vuoi fare un ulteriore tentativo? DXCCStatusWidget Update Aggiornamento ID ID Entity Collegamento DXClusterWidget Click on Connect to connect to the DX-Cluster server Clicca su Connetti per collegarti al server DX-Cluter Connect Connetti Clear Pulisce Click on connect to connect to the DX-Cluster Clicca su Connetti per colelgarti al DX-Cluster Trying to connect to the server Tentativo di connessione al server in corso KLog DXCluster KLog DXCluster The host was not found. Please check: Server host non trovato. Per favore verifica: - your network connection; - the host name and port settings. - la tua configurazione di rete; - il nome del server ed il numero di porta configurato. The connection was refused by the peer. Make sure the DXCluster server is running, and check that the host name and port settings are correct. La conenssione è stata rifiutata lato server. Accertati che il server DXCluster sia in funzione, e controlla che il nome del server host e l'impostazione delle porte sia corretto. The following error occurred: %1. Errore appena rilevato: %1. Connected to server Connesso al server KLog message Messaggio KLog Enter your callsign to connect to the cluster: Inserisci il nominativo di conenssione al cluster: Enter your password to connect to the cluster: (Just hit enter for no password) Inserisci la password di connessione al cluster: (direttamente Invio per nessuna password) Disconnect Scollega Not logged on, you may need to enter your callsign again. Non collegato, forse devi inserire di nuono il nominativo. Enter here the commands to be sent to the DX-Cluster server Scrivi direttamente i comandi da trasmettere al server DX-Cluster Connection closed by the server Collegamento chiuso dal server Send Trasmetti DataProxy_SQLite Software version in DB is null Versione software nel DB vuota No query failed Nessuna query fallita KLog DXCC KLog-DXCC All QSOs have been updated with a DXCC. Tutti i QSO sono stati aggiornati su DXCC. DownLoadCTY Download of cty.csv failed with the following error code: Lo scarico di cty.csv è fallito generando il seguente codice errore: Download of cty.csv done. Scarico di cty.cvs completo. There is already a cty.csv file in the folder but it will be replaced with the new one. E' già presente un file cty.cvs nella cartella ma sarà sovrascritto dal nuovo. Could not open Impossibile aprire for writing. in scrittura. FileManager Writing ADIF file... File ADIF in scrittura... Abort writing Scrittura annullata Writing ADIF file... QSO: File ADIF in scrittura... QSO: You have canceled the file export. The file will be removed and no data will be exported. Hai annullato l'operazione di export. Il file sarà rimosso e nessun dato sarà esportato. Do you still want to cancel? Sei sicuro di voler annullare l'operazione? QSO: QSO: The log that you have selected contains more than just one station callsign. Il log scelto contiene più nominativi di stazione. Please select the station callsing you want to export the log from: Per favore scegli il nominativo di stazione che vuoi esportare dal log: Station Callsign: Nominativo di stazione: Define Station Callsign Imposta il nominativo di stazione You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here. Non hai scelto il nominativo di stazione. KLog esporterà I QSO senza un nominativo di stazione definito ed con il nominatativo qua indicato. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Scegli il nominativo di stazione di questo log o lascialo vuoto per i QSO senza nominativo definito: Exporting LoTW ADIF file... Exportazione file LOTW ADIF... Writing Cabrillo file... File Cabrilo in scrittura... KLog: Cabrillo Log Export not implemented KLog: funzione di export di Log su Cabrillo non implementata I am sorry but the Cabrillo Export To File feature has still not been implemented. Spiacente, ma la funzione di esport del log su file Cabrillo non è stata ancora implementata. Reading LoTW file... Lettura file LoTW... There are more than one log in this logfile. All logs will be imported in the current log. Do you want to continue? Questo file di log contiene più di un singolo log. Se proseguo tutti i log saranno importati. Vuoi continuare? Reading ADIF file... File ADIF in lettura... Importing ADIF file... QSO: Importazione file ADIF... QSO: You have cancelled the file export. The file will be removed and no data will be exported. Do you still want to cancel? Calcellazione file di esport. Se prosegui il file sarà eliminato e nessun dato sarà esportato. Vuoi davvero effettuare l'eliminazione? This QSO is not including the minimum data to consider a QSO as valid!. Questo QSO non contiene le informazioni minime necessarie per essere considerato un QSO valido!. Please edit the ADIF file and make sure that it include at least: Per favore modifica il file ADIF ed inserisci al suo interno almeno: and e This QSO had: Questo QSO aveva: Abort reading Annullamento lettura No station callsign has been selected and therefore no log will be exported Non hai scelto un nominativo di stazione e perciò nessun log sarà esportato There is more than one log in this logfile. All logs will be imported into the current log. Do you want to continue? Importing ADIF file... You have cancelled the file import. The file will be removed and no data will be imported. It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported) - The band missing and the following call: - La banda non è indicata ed il seguente nominativo: - The call missing but was done at this time: - Il nominativo non è indicato ma è stato effettuato all'ora: - The mode missing and the following call: - Il modo operativo non è indicato e il seguente nominativo: - The date missing and the following call: - La data non è indicata ed il seguente nominativo: - The time missing and the following call: - L'ora non è indicata ed ils eguente nominativo: Do you want to continue with the current file? Vuoi poroseguire sul seguente file? KLog: Not all required data found! KLOg: Dati necessari mancanti! This log seems to lack of RST-TX information. Questo log sembra non contenere informazioni RTS-TX. Click on Yes to add a default 59 to all QSO with a similar problem. Clicca su Sì per aggiungere un 59 come default a tutti i QSO con un problema simile. If you select NO, the QSO may not be imported. Se scegli NO, il QSO non sarà importato. KLog: No RST TX found! KLog: Non trovato RST TX! This log seems to lack of RST-RX information. Questo log sembra non contenere informazioni RST-RX. KLog: No RST RX found! KLog: Non trovato RST TX! InfoWidget 10M 10m 15M 15m 20M 20m 40M 40m 80M 80m 160M 160m 2M 2m 6M 6m 12M 12m 17M 17m 30M 30m 70CM 70cm Continent Contienente Prefix Prefisso CQ CQ ITU ITU Short Path Percorso breve Long Path Percorso lungo Degree Grad Gradi Miles Miglia Km Km IntroPage Welcome to KLog! Benvenuto/a su KLog! Welcome to KLog! - brought to you under the terms of the GPL! Benvenuto su KLog! -acquisito sotto i termini della licenza GPL! Welcome to KLog Benvenuto su KLog This looks like it's the first time you've run KLog on this computer. Sembra questa sia la prima volta tu stia eseguendo KLog su questo computer. KLog is a free hamradio logging program that can run on Linux macOS and Windows. KLog è un software libero per radioamatori di memorizzazione log che gira su Linux MacOS e Windows. It is designed to provide general purpose, DX and contest logging. E' progettato per un uso generico, DX e log di contest. It supports QSL management, import and export of ADIF Supporta l'amministrazione di QSL, importa ed esporta in formato ADIF and Cabrillo file formats and many other features... ed il formato Cabrillo e molte altre caratteristiche... Before you can start using KLog, you will be asked to: Prima che tu possa iniziare ad usare KLog, ti è richiesto di: Acknowledge to the terms of the license. Conferma i termini di uso della licenza. Download the DX entities information. Scarica le informazioni DX. Enter your callsign, CQ zone, etc. and main configuration. Inserisci il tuo nominativo, zona CQ, ecc. e configura le impostazioni principali. Enjoy KLog and contact the development team if you have any suggestions! Divertiti usando KLog e contatta liberamente lo staff di sviluppo per ogni suggerimento! LicPage KLog License information KLog inofmrazioni sulla licenza Welcome to KLog!- brought to you under the terms of the GPL! Benvenuto si KLog!- acquisito sotto il termini della licenza GPL! Acknowledge Conferma Be aware that KLog is free software. Attenzione che KLog è software libero. LogModel Date Data Time Ora QRZ QRZ Band Banda Mode Modo RSTtx RSTtx RSTrx RSTrx Comment Commento LogWindow QSL Send Trasmetti QSL QSL Rcvd Ricevi QSL &Delete &Cancella Delete a QSO Cancella un QSO &Edit QSO &Modifica QSO Edit this QSO Modifica questo QSO Via &bureau Via &bureau Send this QSL via bureau Trasmetti questa QSL via bureau D&irect D&iretta Send this QSL via direct Trasmetti questa QSL via diretta Via bureau Via bureau QSL &received via bureau QSL &ricevuta via bureau Direct Diretta QSL received via direc&t QSL ricevuta cia diret&ta You have requested to delete this QSO. Hai richiesto di cancellare questo QSO. Are you sure? Sei sicuro? MainWindow &Clear &Pulisce Recalculate Ricalcola Click to recalculate the award status Clicca per ricalcolare the award status Starting KLog Avvio KLog &Add &Aggiunge Status bar... Barra di stato... DX Entity DX Entity &Log Window Finestra &Log &Score Window Finestra &Punteggi MHz MHz KLog KLog Ready Pronto An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: Si è verificato un errore inaspettato durante il tentativo di aggiunta del QSL al tuo log.Se il problema continua, per favore contatta gli sviluppatori per ulteriori analisi: Click on the prefix of the right entity or Cancel to correct. Clicca sul prefisso del collegamento a destra o Cancella per correggere. Log Log QRZ QRZ Band Banda Mode Modo Date Data Time Ora RSTtx RSTtx RSTrx RSTrx Comment Commento QRZ of the QSO QRZ del QSO You have selected an entity: Hai selezionato il commegamento: that is different from the KLog proposed entity: questo è diverso dal collegamento proposto da KLog: TX RST TX RST RX RST RX RST TX Exchange TX Echange RX Exchange RX Echange Band of the QSO Banda del QSO Mode of the QSO Modo del QSO Date of the QSO Data del QSO Time of the QSO Ora del QSO Add the QSO to the log Aggiunge il QSO al log Input Input STX STX SRX SRX NEW MULT NEW MULT Ready... Pronto... Import an ADIF file into the current log. Importa un file ADIF all'interno del log corrente. Export the current log to an ADIF logfile. Esporta il log corrente su un file log ADIF. Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program). Esporta tutti i QSO che richiedono una QSL su file ADIF (ad esempio per importare su un programma di stampa QSL). &Export ADIF for LoTW... &EsportaADIF per LoTW... Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW! Esporta un file ADIF da trasferire a LoTW. Ricorda anche di firmarlo con TQSL prima di trasferirlo a LoTW! Print your log. Stampa il tuo log. Opens the data folder of KLog. Apre la cartalla dati di KLog. Go through the log reusing previous QSOs to fill missing information in other QSOs. Procedi riutilizzando i dati del precedente QSO sul log per completare le informazioni mancanti in altri QSO. Fill in DXCC data Completa sui dati DXCC Go through the log filling QSOs without a DXCC defined. Procedi riempiendo i QSO del log senza DXCC definito. QSL tools... Strumenti QSL... Shows QSOs for which you should send your QSL and request the DX QSL. Mostra i QSO per i quali è stata richiesta la QSL e richiedi la QSL del DX. Shows the DX-QSL that has been requested or QSLs has been sent with no answer. Mostra le QSL DX richieste oppure le QSL spedite ma senza ancora risposta. Shows the DX-QSL that has been requested. Mostra le QSL DX richieste. LoTW tools... Strumenti per LoTW... Mark all non sent QSOs in this log as queued to be uploaded. Marca tutti i QSO nel log come accodati per essere trasmessi. Mark all non sent QSOs as queued to be uploaded. Marca tutti i QSO non ancora trasmessi accodandoli per essere trasmessi. Mark as sent all queued QSO of this log Marca come già trasmessi tutti i QSOdi questo log in coda Mark all queued QSOs in this log as sent to LoTW. Marca tutti i QSO del log in coda come strasmessi verso LoTW. Mark all queued QSO as sent Marca tutti i QSO in coda come trasmessi For updated DX-Entity data, update cty.csv. Per le voci DX corrette, aggiorna cty.csv. KLog LoTW KLog LoTW All pending QSO of this log has been marked as queued for LoTW! Tutti i QSO del log sospesi stati marcati come accodati per LoTW! There was a problem to mark all pending QSO of this log as queued for LoTW! C'è stato un problema nel marcare tutti i QSOdel log sospesi per accodarli per LoTW! All pending QSO has been marked as queued for LoTW! Tutti i QSO sospesi sono stati marcati per essere messi in coda per LoTW! All queued QSO of this log has been marked as sent for LoTW! Tutti i QSO del log in coda sono stati marcati come trasmessi verso LoTW! There was a problem to mark all queued QSO of this log as sent for LoTW! C'è stato un problema durante l'operazione di marcatura di tutti i QSO di questo log in coda come trasmessi verso LowTW! The log that you have selected contains more than just one station callsign. Il log scelto contiene più nominativi di stazione. Export to ADIF... Export all logs to ADIF... Export Requested QSL to ADIF... Export ADIF for LoTW... Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW. Please select the station callsing you want to mark as sent to LoTW: Station Callsign: Nominativo di stazione: Define Station Callsign Imposta il nominativo di stazione You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Scegli il nominativo di stazione di questo log o lascialo vuoto per i QSO senza nominativo definito: No station callsign has been selected and therefore no log will be marked All queued QSO has been marked as sent to LoTW! Tutti i QSO sono stati marcati come trasmessi verso LoTW! There was a problem to mark all queued QSO of this log as sent to LoTW! C'è stato un problema durante l'operazione di marcatura di tutti i QSO di questo log come trasmessi verso LowTW! Save File Salva File ADIF file File ADIF Cabrillo files Files Cabrillo Any file Tutti i file The selected log is not existing or it is still empty. Il log scelto non esiste oppure è ancora vuoto. Click Yes and KLog will open an empty log. Clicca su Sì e Klog aprirà un nuovo log vuoto. Click No and KLog will select another log with data. Clocca su No e KLog sceglierà un altro log non vuoto. You can modify the config file accordingly, if needed. Puoi correggere il file di configurazione, se necessario. TX Frequency in MHz. Frequenza TX in MHz. RX Frequency in MHz. Frequenza RX in MHz. Power used by the DX. Potenza usata dal DX. Logging operator's callsign. Logging nominativo dell'operatore. Callsign used over the air. Nominativo usato via etere. My QTH locator. Locator del mio QTH. Name of the DX. Nome del DX. QTH of the DX. QTX del DX. Locator of the DX. Locator del DX. QRZ of the QSO. QRZ del QSO. TX RST. TX RST. RX RST. RX RST. TX Exchange. TX Echange. RX Exchange. RX Echange. Band of the QSO. Banda del QSO. Mode of the QSO. Modo del QSO. Date of the QSO. Data del QSO. Time of the QSO. Ora del QSO. Add the QSO to the log. Aggiunge il SQL al log. Clears the QSO entry. Pulisce tutti i campi del QSO. Number of confirmed DXCC entities. Numero di collegamenti DXCC confermati. Number of worked DXCC entities. Numero di collegamento DXCC lavorati. Number of confirmed WAZ zones. Numero di zone WAZ confermate. Number of worked WAZ zones. Numero di zone WAZ lavorate. Number of confirmed local references. Numero di riferimenti locali confermati. Number of worked local references. Numero di riferimenti locali lavorari. Number of confirmed QSOs. Numero di QSO confermati. Number of worked QSOs. Numero di QSO lavorati. Number of QSOs worked on the selected year. Numero di QSOs lavorati durante l'anno scelto. Number of DXCC worked on the selected year. Numero di DXCC lavorati durante l'anno scelto. Number of CQ Zones worked on the selected year. Numero di zone CQ lavorate durante l'anno scelto. Score for the DXMarathon on the selected year. Punteggio nella maratona DX per l'anno scelto. Select the year you want to check. Scegli l'anno che vuoi controllare. Status of the DX entity. Stato del collegamento DX. Name of the DX entity. Nome del collegamento DX. An unexpected error ocurred!! Un errore imprevisto si è verificato!! If the problem persists, please contact the developers Se il problema persiste, per favore contatta gli sviluppatori for analysis: per analisi: Error in function Errore nella funzione Error code Codice di errore Error text Testo descrittivo dell'errore Failed query Richiesta fallita Do you want to keep showing errors? Vuoi mantenere visibili gli errori? The logfile has been modified. Do you want to save your changes? Il file di log è stato modificato. Vuoi salvare i cambiamenti? &File &File &New... &Nuovo... KLog folder Cartella KLog &Open... &Apre... &Save As... &Salva Come... &Print Log... &Stampa Log... E&xit E&sce &Tools &Strumenti &Export to ADIF... &Esporta su ADIF... &Export all logs to ADIF... &Esporta tutti i log su ADIF... &Import from ADIF... &Importa da ADIF... &Find QSO to QSL &Cerca QSO su QSL &Export Requested QSL to ADIF... &Esporta QSL richieste su ADIF... Export ALL the QSOs into one ADIF file, merging QSOs from all the logs. Esporta TUTTI i QSO si un file ADIF,fondendo i QSO da tutti i log. Fill in QSO data Completa tutti i dati del QSL Find My-QSLs pending to send Cerca le mie QSL in attesa di trasmissione &Find DX-QSLs pending to receive &Cerca le QSL DX ancora da ricevere &Find requested pending to receive &Cerca le QSL richieste in attesa di ricezione Queue all QSL to be sent of this log Queue all QSL to be sent Mark all queued QSOs as sent to LoTW. Marca tutti i QSO in coda per essere trasmessi verso LoTW. &Setup &Configurazione &Setup... &Configurazione... &Help &Aiuto Check updates... Controlla aggiornamenti... &About... &About... About Qt... About Qt... About... About... KLog update checking result KLog aggiorna risultati di controllo Congratulations! Congratulazioni! You already have the latest version. Stai usando già la versione più recente. Nothing has been saved. You have to select a valid file type. Nessun dato salvato. Devi scegliere un tipo di file valido. You can find the KLog data folder here: La cartella data di KLog si trova su: DUPE DUPLICA It seems that there are no QSO in the database. Il database sembra non contenere alcun QSO. If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help. Se sei sicuro che il datbase contenga QSO anche se KLog non riesce a riconoscerli, per favore contatta gli sviluppatori (vedi la pagina About di KLog) per supporto. Name Nome QTH QTH Locator Locator Power(rx) Potenza(rx) RST(tx) RST(tx) RST(rx) RST(rx) Freq TX Frequenza TX Freq RX Frequenza RX QSO QSO QSL QSL eQSL eQSL Others Altro My Data Miei dati Satellite Satellite CQ CQ DXCC DXCC Watts Watt Click on the prefix of the correct entity or Cancel to edit the QSO again. Clicca sul prefisso del collegamento o su Cancella per ritornare a modificare i dati del QSO. Clear the box Pulisce il box Invalid characters used in the QRZ Caratteri non validi usati nel campo QRZ Shows the QSOs with pending requests to send QSLs. You should keep this queue empty! Mostra i QSO con richieste di invio QSL in attesa. Questo elenco dovrebbe essere sempre vuoto! &Update cty.csv &Aggiorna cty.csv Score Punteggio DX-Marathon Maratona DX Info Informazioni Award Premi Confirmed confermate Worked Lavorato WAZ WAZ Local Locale QSOs QSO Awards Premi Search Cerca DX-Cluster DX-Cluster Save ADIF File Salva file ADIF LoTW logfile has been properly exported! Il file di log LoTW è stato correttamente esportato! Remember to: Ricorda a: Before uploading: sign the LoTW log; and Prima di trasmettere: firma il log LoTW; e After uploading: mark as sent all the queued QSO (LoTW Tools). Dopo la trasmissione: marca come trasmessi tutti i QSO in coda (Strumenti LoTW). There was no QSO to be exported. Non ci sono QSO da esportare. If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as: Se pensi che specifici QSO debbano essere esportati, per favore controllali bene e verifica che il check-box eQSL LoTW QSL sia marcato come: Q - Queued Q - In coda There was an error while exporting the LoTW. The log has not been exported! C'è stato un errore durante l'export del LoTW. Il log non è stato esportato! Save Cabrillo File Salva file Cabrillo Cabrillo (*.log) Cabrillo (*.log) Open File Apre File &Modify &Modifica -- -- - Needed for DXMarathon - Necessario per maratone DX Filling QSOs... Completamento QSO... Abort filling Abort filling Filling QSOs... QSO: Filling QSO... QSO: Number Numero Print Log Stampa Log Printing the log... Log in stampa... Abort printing Annulla stampa Printing the log... QSO: Stampa del log... QSO: MainWindowInputComment Add a comment for this QSO Aggiunge un commento a questo QSO MainWindowInputEQSL Date of the ClubLog upload. Data del Clublog scaricata. Date of the eQSL sending. Date of the eQSL sending. Date of the eQSL reception. Date of the eQSL reception. Date of the LoTW sending. Data della trasmissione LoTW. Date of the LoTW reception. Data della ricezione LoTW. Status of the LoTW sending. Stato della trasmissione LoTW. Status of the LoTW reception. Stato della ricezione LoTW. LoTW Sent Trasmissione LoTW LoTW Rec Registrazione LoTW Status on ClubLog. Stato su ClubLog. Status of the eQSL sending. Stato della spedizione delle eQSL. Status of the eQSL reception. Stato della ricezione di eQSL. ClubLog ClubLog eQSL Sent Invio eQSL eQSL Rec Registrazione eQSL MainWindowInputOthers Primary Div Primary Div Secondary Div Secondary Div IOTA IOTA Entity Collegamento Propagation mode Modo di propagazione Select the primary division for this QSO Seleziona la primary division di questo QSO Select the secondary division for this QSO Seleziona la secondary division di questo QSO Select the entity for this QSO Seleziona il collegamento di questo QSO Select the propagation mode for this QSO Seleziona il modo di propagazione di questo QSO Select the IOTA continent for this QSO Seleziona il continente IOTA di questo QSO Select the IOTA reference number for this QSO Seleziona il numero di riferimento IOTA di questo QSO Not Identified Non identificato Not - Not Identified No - Non identificato MainWindowInputQSL QSL Sent Invio QSL QSL Rec QSL Rec QSL Via QSL Via QSL Msg QSL Message Status of the QSL sending. Stato QSL in trasmissione. Status of the QSL reception. Stato QSL in ricezione. QSL sending information. Informazioni invio QSL. QSL reception information. Informazioni ricezione QSL. Date of the QSL sending. Data invio QSL. Date of the QSL reception. Data ricezione QSL. Message of the QSL. Messaggio sulla QSL. QSL via information. Informazioni su Via QSL. MainWindowMyDataTab Watt Watt Keep this data Mantieni questa data Data entered in this tab will be copied into the next QSO La data inserita in questa tab sarà usata per il prossimo QSO Power used for the QSO in watts Potenza usata per il QSL in watt Logging operator's callsign Logging nominativo dell'operatore Callsign used over the air Nominativo usato via etere My QTH locator Locator del mio QTH Power Potenza Operator Operatore Station Callsign Nominativo di stazione My Locator Il mio Locator MainWindowSatTab Keep this data Mantieni questa data Data entered in this tab will be copied into the next QSO La data usata in questa tab sarà usata per il prossimo QSO Satellite mode used Usata. modalità satellite Select the satellite you are using Seleziona il satellite che stai usando UpLink band Banda uplink DownLink band Banda downlink Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab. UpLink Uplink DownLink Downlink Satellite Satellite Mode Modo DX Locator Other Altro MHz MHz Not Sat QSO QSO non satellitare KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name. KLog ha trovato un nome di satellite non riconosciuto. Se hai bisogno di usare un nome di satellite conosciuto invece, selezionalo dalla lista. In alternativa, per favore contatta lo staff di sviluppo per aggiungere il nuovo nome di satellite. Please know that the satellite name will not be saved if it is not in the list so that information may be lost! Teni gentilmente presente che il nome del satellite non sarà salvato se assente dalla lista così quest'informazione andrà persa! Other - Sat not in the list Altro - Satellite assente dalla lista Name of the Satellite if not in the list. Select: " Nome del satellite assente dalla lista. Seleziona: " " to enable this box. (format like AO-51) " per abilitare questo box. (formato come AO-51) The satellite you have in your QSO is: Il satellite del tuo QSO è: QObject New One, work it! Nuovo, work it! Needed, work it! Necessario, work it! Worked but not confirmed Lavorato ma non confermato Confirmed Confermato Not identified Non identificato Database Error Errore nel database KLog DB needs to be upgraded. Il DB KLog deve essere aggiornato. KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you. KLog ha rilevato un precedente log nel DB. Tutti i dati saranno copiati su un nuovolog tipo DX per te. KLog: Enter Station callsign KLog: Inserisci nominativo di stazione Enter the station callsign used in this log Inserisci il nominativo di stazione usato in questo log Station Callsign Nominativo di stazione All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK. Tutti i dati sono stati copiati correttamente. Adesso dovresti andare su Configurazione > Preferenze >Logs per controllare che sia tutto OK. QSO: QSO: Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel? Annullare questo aggiornamento può causare inconsistenza dei dati caricati e perdite di dati. Ancora vuoi effettuare l'annullamento? Progress: Progresso: Updating DXCC award information... Aggiornamento imformazioni award DXCC... Updating DXCC Award information... Aggiornamento infomrazioni award DXCC... Updating WAZ award information... Aggiornamento informazioni award WAZ... Updating mode information... Aggiornamento informazioni modi... Do you want to upgrade it now? Vuoi effettuare l'aggiornamento adesso? If DB is not upgraded KLog may not work properly. Se il DB non è aggiornato KLog potrebbe non funzionare correttamente. Abort updating Annulla aggiornamento Updating bands information... Aggiornamento informazione bande... Updating bands information in %1 status... Aggiornamento informazione bande %1 stato... Updating mode information in %1 status... Aggiornamento informazioni modi %1 stato... Install wizard was canceled before completing... Il wizard di installazione è stato annullato prima di aver completato l'operazione... Do you want to remove the KLog dir from your disk? Vuoi rimuovere la cartella KLog dal tuo disco? Your KLog dir has been removed La tua cartella di KLog è stata eliminata I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk. Non sono riuscito ad eliminare la tua cartella KLog. Dovrai eliminarla a mano dal tuo hard disk. Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk. Non sono riuscito a rimuovere la cartella di KLog. Dovrai eliminarla a mano dal disco. Remember that your KLog dir is on your system... Ricorda che la cartella di KLog è sul tuo sistema... Thank you for running KLog! Grazie per aver usato KLog! Updating DXCC information... Aggiornamento informazioni DXCC... SearchWidget &Clear &Pulisce &Select All &Seleziona Tutto &Search &Cerca All Tutto &Export Highlighted &Esporta elementi evidenziati Clear the searches. Cancella le ricerche. Export the search result to an ADIF file. Esporta i risultati della ricerca su un file ADIF. Select/Unselect all the QSOs shown. Seleziona/deleseziona tutti i QSO mostrati. Search in the log. Cerca nel log. Search in all logs. Cerca in tutti i logs. Enter the QRZ to search for. Inserisci il QRZ da cercare. Search results. Risultati della ricerca. QRZ QRZ Date/Time Data/Ora Band Banda Mode Modo QSL Sent QSL inviata QSL Rcvd QSL ricevuta Station Callsign Nominativo di stazione ID ID &Clear selection &Pulisce selezione Save File Salva File QSL Send Invia QSL &Delete &Cancella Delete a QSO Cancella un QSO &Edit QSO &Modifica QSO Edit this QSO Modifica questo QSO Via &bureau Via &bureau Send this QSL via bureau Invia questa QSL via bureau D&irect D&iretta Send this QSL via direct Invia questa QSL via diretta &Request my QSL &Richiedi la mia QSL Mark my QSL as requested Segna la mia QSL come richiesta Via Direct && mark DX QSL as requested Via Diretta && segna QSL DX come richiesta Send this QSL via direct & mark DX QSL as requested Invia questa QSL via diretta & segna QSL DX come richiesta Via Bureau && mark DX QSL as requested Via bureau && segna QSL DX come richiesta Send this QSL via bureau & mark DX QSL as requested Invia questa QSL via bureau & segna QSL DX come richiesta &Request the QSL &Richiedi la QSL Mark the QSL as requested Segna la QSL come richiesta Via bureau && mark my QSL as requested Via bureau && segna la mia QSL come richiesta QSL received via bureau & mark my QSL as requested QSL rcievuta via bureau & segna la mia QSL come richiesta Via bureau Via bureau QSL received via bureau QSL ricevuta via bureau Direc&t && mark as my QSL requested Diret&ta && segna come richiesta la mia QSL QSL received via direct & mark my QSL as requested QSL ricevuta via diretta & segna la mia QSL come richiesta Direc&t Diret&ta QSL received via direct QSL ricevuta via diretta You have requested to delete the QSO with: Hai richiesto di cancellare questo QSO con: Are you sure? Sei sicuro? Needed QSO to send the QSL QSO che hanno bisogno to inviare la QSL My QSL requested to be sent La mia richiesta di QSL da inviare DX QSL pending to be received QSL DX in attesa di essere ricevuta SetupDialog My Data Dati personali Bands/Modes Bande/modi DX-Cluster DX-CLuster Colors Colori Misc Altro World Editor World Editor Logs Logs ClubLog ClubLog Cancel Annulla OK OK Config Dialog Pagina di configurazione User data Dati utente D&X-Cluster D&X-Cluster You need to enter at least one log in the Logs tab. E' necessario caricare almeno un log nella tab configurazione logs. World World Misc tab Tab configurazione altro and click on e cliccare su Move DB Sposta-DB or the DB will not be moved to the new location. oppure il DB non sarà sopostato alla nuova locazione. You need to enter at least a valid QRZ. E' necessario che tu inserisca almeno un corretto QRZ. You will be redirected to the Log tab. Please add and select the kind of log you want to use. Sarai portato sulla tab di impostazione log. Per favore aggiungi e scegli il tipo di log che vuoi utilizzare. Go to the Go to the DB has not been moved to new path DB non è stato spostato alla nuova path User tab Tab impostazioni utente and enter valid QRZ. ed inserisci un valido QRZ. You have not selected the kind of log you want. Non hai scelto il tipo di log che vuoi usare. SetupEntityDialog Entity Collegamento Name of the Entity Nome del collegamento CQ CQ CQ zone zona CQ ITU ITU ITU zone zona ITU Latitude latitudine Longitude of the Entity Longitudine del collegamento Longitude Longitudine UTC UTC Local time difference to UTC Differenza da tempo locale a UTC Main prefix Prefisso principale Main prefix of the entity Prefisso principale del collegamento ARRL ID ARRL ID Comma separated possible prefixes, e.g. EA1, EA2, ... Virgole separano possibili prefissi, es. EA1,EA2, ... Prefixes Prefissi Date of the deletion Data di cancellazione Deleted Cancellato Cancel Cancella OK OK Entity Dialog Maschera collegamento SetupPageBandMode Bands Bande Modes Modi SetupPageClubLog &Callsign &Nominativo ClubLog &password ClobLog &password ClubLog &email ClubLog &email Enter the email you used to register in ClubLog. Inserisci l'email che hai usato per registrarti a ClubLog. Enter the callsign you used to register in ClubLog. Inserisci il nominativo che hai usato per registrarti a ClubLog. Enter your password in ClubLog. Inserisci la tua password per ClubLog. &Send QSOs in real time &Invia QSO in tempo reale &Activate ClubLog &Attiva ClubLog Use QSO Station &Callsign Usa stazione QSO &Nominativo Send each QSO to ClubLog in real time, as they are added (or modified) in KLog Invia ogni QSO a ClubLog in tempo reale, appena aggiunti (o modificati) su KLog Starts the ClubLog support in KLog Avvia il servizio ClubLog su KLog Use the Station Callsign defined in each QSO instead of the one defined here Usa il nominativo di stazione definito in ogni QSL invece di quello qui riportato SetupPageColors New One Nuovo Needed in this band Necessario in questa banda Worked in this band Lavorato in questa banda Confirmed in this band Comfermato in questa banda Default Default Choose a color Scegli un colore SetupPageDxCluster Add Aggiungi Delete Cancella Show &HF spots Mostra &HF spots Show V/&UHF spots Mostra V/&UHF spots Show W&ARC spots Mostra W&ARC spots Show &worked spots Mostra spots &lavorati Show &confirmed spots Mostra spot &confermati Show ANN/&FULL messages Mostra ANN/&TUTTI i messaggi Show WW&V messages Mostra messaggi WW&V Show WC&Y messages Mostra messaggi WC&Y DX Spots DX Spots Messages Messaggi KLog: Add a DXCluster server KLog: Aggiungi un server DXCluster Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default: Aggiungi l'indirizzo seguito da :porta Esempio: dxfun.com:8000 Se la porta non è specificata, 41112 sarà usato di default: SetupPageLogs &New &Nuovo &Edit &Modifica &Remove &Elimina Add a new log Aggiunge un nuovo log Edit the selected log Modifica il log selezionato Remove the selected log Elimina il log selezionato Select the log you want to open Scegli il log che desideri aprire KLog KLog Log has not been removed. (#3) Il Log non è stato rimosso. (#3) Do you really want to remove this log? Davvero vuoi eliminare questo log? All the QSOs from this log will be also deleted... Anche tutti i QSO di questo log saranno eliminati... Log has not been removed. (#2) Il Log non è stato rimosso. (#2) Log has not been removed. (#1) Il Log non è stato rimosso. (#1) ID ID Date Data Station Callsign Nominativo di stazione Operators Operatori Comments Commenti Type Tipo An error has occurred showing the following error code: Si è verificato un errore che riporta il seguente codice di errore: KLog - SetupPageLogs KLog - Pagina setup Logs SetupPageLogsNew &Date &Data &Station Callsign &Nominativo di stazione &Operators &Operatori Comm&ent Comm&enta &Ok &Ok &Cancel &Annulla Select categories Seleziona categoria Callsign used for this log Nominativo usato per questo log Comma separated list of operators: callsign1, callsign2 Lista degli operatori separati da virgola: nome1, nome2 Start date of this log Data di inizio di questo log Add a comment about this log Aggiunge un commento relativo a questo log &Type of Operation &Tipo di operazione Select the kind of operation for this log Scegli il tipo di operazione di questo log &Mode Category Categoria &Modo Select the mode category Scegli la categoria di modo O&perators Category Categoria o&peratori Select the operators category Scegli la categoria degli operatori &Assisted Category Categoria &Assisted Select the assisted category Scegli la categoria assisted Po&wer Category Categoria Po&tenza Select the power category Scegli la categoria di potenza &Bands Category Categoria &Bande Select the bands category Scegli la categoria delel bande O&verlay O&verlay Select the Overlay category Scegli la categoria overlay Categories not OK Categorie non OK You need to enter a valid QRZ in the Station Callsign box. The log will not be opened. E' necessario che tu isnerisca un valido QRZ nella pagina di configurazione del bnominativo di stazione. Il log non sarà aperto. You selected an invalid combination. The log will not be opened. Hai scelto una combinazione non valida. Il log non sarà aperto. Categories OK Categorie OK SetupPageMisc &Imperial system Sistema &Imperiale &Log in real time &Log in tempo reale &Time in UTC &Ora in UTC &Save ADIF on exit &Salva ADIF all'uscita Use this &default filename Usa questo nome di file per &default Mark &QSO to send QSL when QSL is received Segna il &QSO per inviare QSL quando una QSL è ricevuta Complete QSO with previous data Completa i dati del QSO con dati precedenti Show the Station &Callsign used in the search box Mostra il &nominativo di stazione caricato nella pagina di ricerca The search box will show also the callsign on the air to do the QSO. La pagina di ricerca mostra anche il nominativo usato durante il QSO. All the data from the My Data tab will be used or data from the previous QSO will be maintained. Tutti i dati nella pagina configurazione personale saranno usato oppure saranno mantenuti i dati del precedente QSO. &Check for new versions automatically &Controlla automaticamente nuove versioni Check if there is a new release of KLog available every time you start KLog. Controlla se è diosponibile una nuova versione di KLog ogni volta che tu avvii KLog. &Provide Info for statistics &Fornisci informazioni per statistiche Move DB Sposta DB Check it for Imperial system (Miles instead of Kilometres). Controlla esso per il sistema Imperiale (Miglia invece di Kilometri). Select to use real time. Scegli di usare ora reale. Select to use UTC time. Scegli di usare ora UTC. Select if you want to save to ADIF on exit. Scegli se vuoi salvare su formato ADIF all'uscita. Complete the current QSO with previous QSO data. Completa il QSO corrente con i dati del precedente QSO. This is the directory where DB (logbook.dat) will be saved. Questa è la cartella dove DB (logbook.dat) sarà salvato. Click to change the default ADIF file. Clicca per cambiare il file ADIF di default. Click to move the DB to the new directory. Clicca per spostare il DB su una nuova cartella. Select Directory Scegli la cartella File moved File spostato File copied File copiato File NOT copied File NON copiato The target directory does not exist. Please select an existing directory. La cartella di destinazione non esiste. Per favore scegli una cartella valida. Browse Browse &Reset to My Data for all QSOs &Reimposta ai miei dati su tutti i QSO QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours. Il QSO sarà marcato come in attesadi inviare una QSL se ricevi la QSL DX senza aver inviato la tua. If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog. Se il controllo di nuova versione è attivato, KLog trasmetterà allo sviluppatore il tuo nominativo, la versione di KLog & il sistema operativo coem strumento per aiutare a migliorare KLog. Select to use the following name for the logfile without being asked for it again. Scegli il seguente nome per il file di log senza che ti venga chiesto di nuovo. This is the default file where ADIF data will be saved. Questo è il file di default dove i dati ADIF saranno salvati. This is the directory where the database (logbook.dat) will be saved. Questa è la cartella dove il database (logbook.dat) sarà salvato. Click to change the path of the database. Clicca per cambiare la path del database. Open File Apre File Please specify an existing directory where the database (logbook.dat) will be saved. Per favore indica una cartella valida dove il database (logbook.dat) sarà salvato. SetupPageUserDataPage &Personal data Dati &Personali Station &data &Data Stazione Enter your name Inserisci il tuo nome Enter your address - 1st line Inserisci il tuo indirizzo -1a linea Enter your address - 2nd line Inserisci il tuo indirizzo -2a linea Enter your address - 3rd line Inserisci il tuo indirizzo -3a linea Enter your address - 4th line Inserisci il tuo indirizzo -4a linea Enter your city Inserisci la tua città Enter your zip code Inserisci il tuo CAP Enter your province or state Inserisci la pronvincia o lo stato Enter your country Inserisci il tuo country &Name &Nome &Address &Indirizzo Cit&y Cit&tà &Zip Code &Cap Pro&v/State Pro&v/Stato Countr&y Countr&y Enter your information for rig Inserisci informazioni per rig Enter your information for antenna Inserisci informazioni sulla tua antenna Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign. Inserisci il locator della tua stazione. In alternativa, KLog è in grado di usare un locator approssimativo ricavato dal tuo nominativo. Enter your power information Inserisci informazioni sulla potenza usata &Rig 1 &Impianto 1 R&ig 2 &Impianto 1 Ri&g 3 &Impianto 1 Antenna &1 Antenna &1 Antenna &2 Antenna &2 Antenna &3 Antenna &3 Po&wer Po&tenza Enter the station callsign that will be used for logging Inserisci il nominativo di chiamata da usare per il log Enter the operators (comma separated if more than one). Inserisci gli operatori (separati da virgola se più di uno). &QRZ &QRZ &Operators &Operatori &CQ Zone &CQ zona &ITU Zone &ITU zona &Locator &Locator &Locator (not valid) &Locator (non valido) SetupPageWorldEditor An entities information file (cty.csv) has been detected in your KLog folder and will be loaded. Un file di informazioni collegamenti (cty.csv) è stato trovato nella cartella di KLog e sarà caricato. No entities information file (cty.csv) has been detected in your KLog folder. Nessun file di informazioni di collegamenti (cty.cvs) è stato trovato nella cartalla di KLog. KLog will not be able to show entities information. KLog non sarà in grado di mostrare le informazioni di collegamento. Prefix Prefisso Entity Collegamento ARRL ID ARRL ID Continent Continente CQ Zone CQ zona ITU Zone ITU zona UTC UTC Latitude Latidudine Longitude Longitudine Deleted Eliminato Since Date Dalla data To Date Alla data Open File Apre File BigCTY (*.csv) BigCTY (*.csv) Entities information has been updated. Informazioni collegamento aggiornate. Entities information has not been updated. Informazioni collegamento non aggiornate. ShowErrorDialog KLog Message Messaggio KLog SoftwareUpdateDialog Ok Ok KLog update Aggiornamento KLog Congratulations! congratulazioni! Your KLog has been updated. KLog è stato aggiornato. You already have the latest version. Stai già usando la versione più recente. StartWizard KLog - The free hamradio logging program KLog.- Un software libero di annotazione dei collegamento Quit Setup Esce dalla configurazione Setup is not complete yet. Are you sure you want to quit setup? Configurazione non ancora completa. Sei sicuro di voler uscire dalla configurazione? World Entity Collegamento Continent continente Abort reading Annulla lettura Reading cty.csv... Lettura cty.cvs... eLogClubLog Host not found! Host non trovato! Timeout error! Errore di Timeout! It seems to be a PASSWORD ERROR; check your password. Si è verificato un ERRORE DI PASSWORD; controlla la tua password. KLog - ClubLog KLog - ClubLog Undefined error... Errore indefinito... Callsign missing Nominativo di chiamata assente Invalid callsign Nominativo di stazione non valido Skipping SWL callsign Salto nominativo SWL Callsign is your own call Callsign is you own call Invalid callsign with no DXCC mapping Nominativo di stazione non valido con nessuna localizzazione DXCC Updated QSO Trasferito QSO Invalid ADIF record Record ADIF non valido Missing ADIF record Record ADIF mancante Test mode - parameters ok, no action taken Modalità test parametri ok, nessuna azione intrapresa It seems that your ClubLog password is not correct. Sembra la tua password ClubLog non sia corretta. Please check your password in the setup. ClubLog uploads will be disabled. Per favore controlla la tua password nella configurazione. Il caricamento su ClubLog non sarà attivo. Excessive API Usage Eccessivo uso delle API Internal Error Errore Interno Rejected Rifiutato QSO Duplicate QSO Duplicato QSO Modified QSO Modificato Missing Login Login mancante QSO OK QSO OK Upload denied Trasferimento rifiutato No callsign selected Nessun nominativo selezionato No match found Nessuna corrispondenza trovata Dropped QSO QSO interrotto OK OK Login rejected Login rifiutato Rejected: Callsign is your own call Rifiutato: Nominativo is your own call klog-0.9.2.9/translations/klog_ja.ts0000644000076700000620000057103613233376355015320 0ustar staff AboutDialog About KLog KLogについて You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog. バグレポートやちょっとしたコードを書いて送ってくれたり、他にもアイデアとか KLog をよりよくするとあなたが思うことを何でも送ってくれることで手助けとなります. If you want to provide support you are welcome to join the サポートしていただけるなら、次のメーリングリストに参加してください. KLog development mailing list KLog 開発者メーリングリスト ! 歓迎します! Authors 作者 If KLog is still not in your language and you want to help us, you are welcome to contact us through the まだ KLog があなたの言語に翻訳されておらず、翻訳をお手伝いいただけるなら、次のメーリングリストを通じてご連絡ください. By Please know that this is an BETA release and it may contain many bugs.<br>Backup your data before using this software! このリリースはまだベータバージョンで、多くのバグを含んでいる可能性があります.<br>このソフトウェアを使い始める前に、まずデータのバックアップを取ってください! Author 作者 KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing. KLogは主要なオペレーティングシステム (Linux mac OS & Windows)上でクロスプラットフォーム実行が可能なように、また以前のKLogに備わっていなかった新機能を提供するために、バージョン0.6.2以降、大幅に書き換えられました. KLog is a free logbook for hamradio operators. KLogはアマチュア無線家のためのフリーなログソフトです. Please provide your review in KLog's eHam review page: eHamのレビューページにKLogのレビューをぜひ投稿してください: Find more information and the latest release at より詳しい情報や、最新のリリースは以下の場所で入手できます.<br> today 現在 Main developer メイン開発者 KLog is developed by a very small team and you are invited to join! KLogはとても小さなチームによって開発されており、あなたの参加が望まれています! KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs ユーザーの需要を考慮した開発の方向性を定めるために、どのバージョンがどれくらいインストールされたかを知るという目的に限定してユーザー情報をKLogサーバーに送信する機能が取り込まれました. At present, the data that is provided is the following: 今のところ、提供いただく情報は以下のものです: Be aware that you can enable/disable this feature from the Misc tab in the Setup page この機能は「設定」ページの「その他」タブで、有効・無効を切り替えることができます Translators bring KLog into your language. They are really an important part of the KLog development team. 翻訳者はKLogをあなたの言語で使えるようにします. 翻訳者はKLog開発チームの中でもとりわけ重要な役割を担います. Translators 翻訳者 Privacy advisory プライバシーについての勧告 Callsign コールサイン KLog version KLogのバージョン Operating system OSの情報 KLog Privacy プライバシー CTYPage Country data download エンティティーデータのダウンロード KLog needs country data... KLogではエンティティーデータを利用します... &Download ダウンロード(&D) &Ignore 無視(&I) Country data needed エンティティデータが必要です KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information. KLogはDXCC情報取得のため、http://www.country-files.com/ で配布される cty.csv ファイルを利用します. You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do. あなたが交信したQSOのエンティティやグリッドロケーターを表示させるには、cty.csvファイルをダウンロードする必要があります. Click on Download to download now. ダウンロードを開始するために、「ダウンロード」ボタンをクリックしてください. KLog I can't find the host. Please check your network and try again Do you want to try again? 接続先が見つかりません. ネットワーク接続を確認して、再度トライしてみてください. もう一度行いますか? DXCCStatusWidget Update 更新 ID Entity エンティティ DXClusterWidget Click on Connect to connect to the DX-Cluster server 接続ボタンをクリックするとDXクラスターに接続します。 Connect 接続 Clear クリア Click on connect to connect to the DX-Cluster 接続ボタンをクリックするとDXクラスターに接続します。 Trying to connect to the server サーバーに接続しています KLog DXCluster KLog DXクラスター The connection was refused by the peer. Make sure the DXCluster server is running, and check that the host name and port settings are correct. 接続できませんでした。DXクラスターが稼働していることを確かめてください。また、ホスト名、ポート番号の設定が正しいことを確認してください。 The following error occurred: %1. 次のエラーが発生しました: %1 Connected to server サーバーに接続しました。 KLog message KLog メッセージ Enter your callsign to connect to the cluster: DXクラスターに接続するためのコールサインを入力してください: Enter your password to connect to the cluster: (Just hit enter for no password) DXクラスターに接続するためのパスワードを入力してください。 (カラのパスワードについてはエンターだけ押してください。) Not logged on, you may need to enter your callsign again. ログオンしていません. もう一度、コールサインを入力してみてください. Disconnect 切断 The host was not found. Please check: - your network connection; - the host name and port settings. Enter here the commands to be sent to the DX-Cluster server DXクラスターに送信するコマンドをここに入力します。 Connection closed by the server サーバーによって接続が切られました。 Send 送信 DataProxy_SQLite Software version in DB is null No query failed KLog DXCC All QSOs have been updated with a DXCC. DownLoadCTY Download of cty.csv failed with the following error code: cty.csv のダウンロード、失敗. エラーコード: Download of cty.csv done. cty.csv のダウンロード、完了. There is already a cty.csv file in the folder but it will be replaced with the new one. フォルダーにすでに cty.csv ファイルがありますが、最新のもので置き換えます. Could not open 次のファイルを開けません: for writing. (書き込み用) FileManager Writing ADIF file... ADIFファイルを書き込んでいます... Abort writing 書込みの中止 Writing ADIF file... QSO: ADIFファイルを書き込んでいます... QSO: Writing Cabrillo file... Cabrilloファイルを書き込んでいます... KLog: Cabrillo Log Export not implemented KLog: Cabrillo Log Exportは未実装 I am sorry but the Cabrillo Export To File feature has still not been implemented. 申し訳ありません. Cabrillo形式ログのエクスポート機能はまだ実装されていません. You have canceled the file export. The file will be removed and no data will be exported. ファイルのエクスポートが中断されました. 出力先のファイルは削除され、データはエクスポートされません. No station callsign has been selected and therefore no log will be exported Do you still want to cancel? 本当に中止しますか? QSO: Reading ADIF file... ADIFファイルを読みこんでいます... Abort reading 読込みの中止 The log that you have selected contains more than just one station callsign. Please select the station callsing you want to export the log from: Station Callsign: Define Station Callsign You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Exporting LoTW ADIF file... Reading LoTW file... This QSO is not including the minimum data to consider a QSO as valid!. Please edit the ADIF file and make sure that it include at least: and This QSO had: Do you want to continue with the current file? This log seems to lack of RST-TX information. Click on Yes to add a default 59 to all QSO with a similar problem. If you select NO, the QSO may not be imported. This log seems to lack of RST-RX information. - The band missing and the following call: There is more than one log in this logfile. All logs will be imported into the current log. Do you want to continue? Importing ADIF file... You have cancelled the file import. The file will be removed and no data will be imported. It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported) - The call missing but was done at this time: - The mode missing and the following call: - The date missing and the following call: - The time missing and the following call: KLog: Not all required data found! KLog; データの不足が見つかりました! KLog: No RST TX found! KLog: RST TXが見つかりません! KLog: No RST RX found! KLog: RST RXが見つかりません! InfoWidget 10M 15M 20M 40M 80M 160M 2M 6M 12M 17M 30M 70CM Continent 大陸名 Prefix プリフィクス CQ ITU Short Path ショートパス Long Path ロングパス Degree Grad 方位 Miles マイル Km IntroPage Welcome to KLog! KLogにようこそ! Welcome to KLog! - brought to you under the terms of the GPL! ようこそ、KLogに! - GPL条項にもとづいてお届けします! Welcome to KLog KLog にようこそ <html><head> <title>KLogにようこそ</title> </head><body> <p>このコンピューターでKLogを実行するのは初めてのようです.</p> <p>KLogは、Linux, mac OSやWindowsで実行可能なフリーなアマチュア無線用ロギングソフトウェアです. DXやコンテストでのロギングなど、一般的な使用方法でお使いいただけるようデザインされています.</p> <p>ADIF形式やCabrillo形式でのデータのインポート、エクスポート、またQSLカードの管理など、多くの機能をサポートしています.</p> <p>KLogをスタートする前に、以下の質問にお答えください. <ul> <li>ライセンス条項への同意</li> <li>KLogの実行方法の設定</li> <li>コールサイン、CQゾーン、その他、多くの設定項目</li> </ul> </p> <p>KLogをお楽しみください. ご提案などがあれば、開発チームにご連絡ください.</p> <p><h3>73 de EA4TV</h3></p> </body></html> This looks like it's the first time you've run KLog on this computer. このコンピューターでKLogを実行するのは初めてのようです. KLog is a free hamradio logging program that can run on Linux macOS and Windows. KLogは、Linux, mac OSやWindowsで実行可能なフリーなアマチュア無線用ロギングソフトウェアです. It is designed to provide general purpose, DX and contest logging. DXやコンテストでのロギングなど、汎用な使い方ができるようデザインされています. It supports QSL management, import and export of ADIF ADIF形式やCabrillo形式でのデータのインポート、エクスポート、 and Cabrillo file formats and many other features... またQSLカードの管理など、多くの機能をサポートしています... Before you can start using KLog, you will be asked to: KLogを使い始める前に、以下の質問にお答えください: Acknowledge to the terms of the license. ライセンス条項への同意. Download the DX entities information. ライセンス条項への同意 Enter your callsign, CQ zone, etc. and main configuration. コールサイン、CQゾーン、その他、多くの設定項目 Enjoy KLog and contact the development team if you have any suggestions! KLogをお楽しみください. ご提案などがあれば、開発チームにご連絡ください! LicPage KLog License information KLogライセンス情報 Welcome to KLog!- brought to you under the terms of the GPL! ようこそ、KLogに! - GPL条項にもとづいてお届けします! Acknowledge 同意します Be aware that KLog is free software. KLogはフリーソフトウェアです. LogModel Date 日付 Time 時刻 QRZ コールサイン Band バンド Mode モード RSTtx 送信RST RSTrx 受信RST Comment コメント LogWindow QSL Send QSLカードの送付 QSL Rcvd QSL受領状況 &Delete 削除(&D) Delete a QSO QSOのレコードを削除します &Edit QSO QSOの編集(&E) Edit this QSO QSOのレコードを編集します Via &bureau ビューロー経由(&b) Send this QSL via bureau QSLカードをビューロー経由で送ります D&irect ダイレクト(&i) Send this QSL via direct QSLカードをダイレクトで送ります Via bureau ビューロー経由 QSL &received via bureau QSLカードをビューロー経由で受け取りました。(&r) Direct ダイレクト QSL received via direc&t QSLカードをダイレクトで受け取りました。(&t) You have requested to delete this QSO. このQSOを削除しようとしています。 Are you sure? 本当に削除しますか? MainWindow &Clear クリア(&C) Recalculate 再計算 Click to recalculate the award status クリックするとアワードの現在の集計を再計算します Starting KLog KLogを起動しています &Add 追加(&A) Status bar... ステータスバー... DX Entity DXエンティティ &Log Window ログウィンドウ(&L) &Score Window スコアウィンドウ(&S) MHz KLog Ready An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: ログにQSOデータを追加中に予期しないエラーが発生しました. 問題が何度も起こるようであれば、原因究明のため開発者に連絡をお願いします: Log ログ QRZ コールサイン Band バンド Mode モード Date 日付 Time 時刻 RSTtx 送信RST You have selected an entity: 次のエンティティが指定されています: that is different from the KLog proposed entity: しかし、これは KLog が推定したエンティティと異なります: RSTrx 受信RST Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW! Print your log. Opens the data folder of KLog. Go through the log reusing previous QSOs to fill missing information in other QSOs. Fill in DXCC data Go through the log filling QSOs without a DXCC defined. QSL tools... Shows QSOs for which you should send your QSL and request the DX QSL. &Find DX-QSLs pending to receive 相手のQSLカードをまだ受領していないQSOを検索(&F) Shows the DX-QSL that has been requested or QSLs has been sent with no answer. &Find requested pending to receive 相手のQSLカードをまだ受領しておらずリクエストとマークしたQSOを検索(&F) Shows the DX-QSL that has been requested. LoTW tools... Mark all non sent QSOs in this log as queued to be uploaded. Mark all non sent QSOs as queued to be uploaded. Mark as sent all queued QSO of this log Mark all queued QSOs in this log as sent to LoTW. Mark all queued QSO as sent KLog LoTW All pending QSO of this log has been marked as queued for LoTW! There was a problem to mark all pending QSO of this log as queued for LoTW! All pending QSO has been marked as queued for LoTW! All queued QSO of this log has been marked as sent for LoTW! There was a problem to mark all queued QSO of this log as sent for LoTW! The log that you have selected contains more than just one station callsign. Export to ADIF... Export all logs to ADIF... Export Requested QSL to ADIF... Export ADIF for LoTW... Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW. Please select the station callsing you want to mark as sent to LoTW: Station Callsign: Define Station Callsign You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: No station callsign has been selected and therefore no log will be marked All queued QSO has been marked as sent to LoTW! There was a problem to mark all queued QSO of this log as sent to LoTW! Congratulations! おめでとうございます! You already have the latest version. 最新のバージョンを入手しました. ADIF file Cabrillo files Any file The selected log is not existing or it is still empty. Click Yes and KLog will open an empty log. Click No and KLog will select another log with data. You can modify the config file accordingly, if needed. TX Frequency in MHz. 送信周波数をMHzの単位で表示 RX Frequency in MHz. 受信周波数をMHzの単位で表示 Power used by the DX. 相手局が用いた送信出力 Logging operator's callsign. ログを記入したオペレーターのコールサイン Callsign used over the air. 交信に用いたコールサイン My QTH locator. 自局QTHのグリッドロケーター Name of the DX. 相手局の名前 QTH of the DX. 相手局のQTH Locator of the DX. 相手局のグリッドロケーター QRZ of the QSO. 相手局のコールサイン TX RST. 相手局に送ったRST RX RST. 相手局から送られてきたRST TX Exchange. 相手局に送ったコンテストナンバー RX Exchange. 相手局から送られてきたコンテストナンバー Band of the QSO. このQSOのバンド Mode of the QSO. このQSOのモード Date of the QSO. このQSOの日付 Time of the QSO. このQSOの時刻 Add the QSO to the log. このQSOをログに追加します. Clears the QSO entry. 入力内容をクリアします. Number of confirmed DXCC entities. コンファームしたDXエンティティの数 Number of worked DXCC entities. 交信したDXCCエンティティの数 Number of confirmed WAZ zones. コンファームしたWAZゾーンの数 Number of worked WAZ zones. 交信したWAZゾーンの数 Number of confirmed local references. Number of worked local references. Number of confirmed QSOs. コンファームしたQSOの数 Number of worked QSOs. 交信したQSOの数 Number of DXCC worked on the selected year. 選択した年に交信したDXCCエンティティの数 Number of CQ Zones worked on the selected year. 選択した年に交信したCQゾーンの数 Score for the DXMarathon on the selected year. 選択した年のDXマラソンのスコア Select the year you want to check. 確認したい年を選択してください. Status of the DX entity. DXエンティティの状況 Name of the DX entity. DXエンティティの名称 Comment コメント An unexpected error ocurred!! If the problem persists, please contact the developers for analysis: Error in function Error code Error text Failed query Do you want to keep showing errors? QRZ of the QSO 相手局のコールサイン Watts W TX RST 相手局に送ったRST RX RST 相手局から送られてきたRST TX Exchange 相手局に送ったコンテストナンバー RX Exchange 相手局から送られてきたコンテストナンバー Band of the QSO このQSOのバンド Mode of the QSO このQSOのモード Date of the QSO このQSOの日付 Time of the QSO このQSOの時刻 Add the QSO to the log このQSOをログに追加します Input 入力 STX SRX NEW MULT Ready... Save File ファイルに保存 The logfile has been modified. Do you want to save your changes? ログファイルの内容は変更されています。 変更結果を保存しますか? &File ファイル(&F) &New... 新規...(&N) KLog folder KLogフォルダー &Open... 開く...(&O) &Save As... 名前を付けて保存...(&S) &Print Log... ログを印刷...(&P) E&xit 終了(&x) &Tools ツール(&T) &Export to ADIF... ADIF形式にエクスポート...(&E) &Export all logs to ADIF... すべてのログをADIF形式にエクスポート...(&E) &Import from ADIF... ADIF形式からインポート...(&I) &Find QSO to QSL QSLカードの必要なQSOを検索(&F) KLog update checking result KLogの更新チェックの結果 You can find the KLog data folder here: KLog 用データフォルダーはこちらです; Name 名前 QTH Locator グリッドロケーター -- - Needed for DXMarathon - DXマラソンのために必要 &Export Requested QSL to ADIF... QSLカードがリクエストされているQSOをADIFにエクスポート...(&E) Click on the prefix of the right entity or Cancel to correct. 正しい方のエンティティのプリッフィックスをクリックしてください。または修正をキャンセルしてください。 &Setup 設定(&S) &Setup... 設定...(&S) &Help ヘルプ(&H) &About... このプログラムについて...(&A) About Qt... Qtについて... About... このプログラムについて... Nothing has been saved. You have to select a valid file type. 保存は実行されません。適切なファイル形式を指定してください。 DUPE Click on the prefix of the correct entity or Cancel to edit the QSO again. 正しい方のエンティティのプリッフィックスをクリックしてください. または修正をキャンセルしてください. Clear the box 入力内容をクリアします Invalid characters used in the QRZ コールサインの入力欄に正しくない文字が入力されています Export ALL the QSOs into one ADIF file, merging QSOs from all the logs. すべてのQSOレコードをひとつのADIFファイルにエクスポートします. すべてのログファイルのQSOレコードがマージされます. Fill in QSO data QSOデータの埋め込み Find My-QSLs pending to send 自分のQSLカードをまだ送付していないQSOを検索 Shows the QSOs with pending requests to send QSLs. You should keep this queue empty! QSLカードがリクエストされていて、まだ発送していないQSOを表示します. この項目はカラになるように努めましょうね! &Update cty.csv cty.csv を更新(&U) For updated DX-Entity data, update cty.csv. Check updates... 更新のチェック... Number of QSOs worked on the selected year. 選択した年の交信数 Power(rx) 相手局の出力 RST(tx) RST(送信) RST(rx) RST(受信) Freq TX 送信周波数 Freq RX 受信周波数 QSO QSL eQSL Others その他 My Data 自局のデータ Satellite サテライト通信 CQ DXCC Score スコア DX-Marathon DXマラソン Info 情報 Award アワード Confirmed コンファーム済 Worked 交信済 WAZ Local QSOs QSO総数 Import an ADIF file into the current log. Export the current log to an ADIF logfile. Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program). Queue all QSL to be sent of this log Queue all QSL to be sent Mark all queued QSOs as sent to LoTW. It seems that there are no QSO in the database. If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help. Awards アワード Search 検索 DX-Cluster DXクラスター Save ADIF File ADIFファイルに保存 LoTW logfile has been properly exported! Remember to: Before uploading: sign the LoTW log; and After uploading: mark as sent all the queued QSO (LoTW Tools). There was no QSO to be exported. If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as: Q - Queued There was an error while exporting the LoTW. The log has not been exported! Save Cabrillo File Cabrilloファイルに保存 Cabrillo (*.log) Open File ファイルを開く &Modify 変更(&M) Filling QSOs... QSOデータを埋込んでいます... Abort filling 埋込みの中止 Filling QSOs... QSO: QSOデータを埋込んでいます... QSO: Number 番号 Print Log ログの印刷 Printing the log... ログを印刷しています… Abort printing 印刷の中止 Printing the log... QSO: ログを印刷しています… QSO: MainWindowInputComment Add a comment for this QSO このQSOの備考を入力してください MainWindowInputEQSL Date of the ClubLog upload. ClubLogにアップロードした日付 Date of the eQSL sending. eQSLを送付した日付 Date of the eQSL reception. eQSLを受領した日付 Date of the LoTW sending. Date of the LoTW reception. Status of the LoTW sending. Status of the LoTW reception. LoTW Sent LoTW Rec Status on ClubLog. ClubLogの状況 Status of the eQSL sending. eQSLの送付状況 Status of the eQSL reception. eQSLの受領状況 ClubLog eQSL Sent eQSL送付 eQSL Rec eQSL受領 MainWindowInputOthers Primary Div Secondary Div IOTA Entity エンティティ Propagation mode 伝播モード Select the primary division for this QSO このQSO相手局のPrimary Divisionを選択してください Select the secondary division for this QSO このQSO相手局のSecondary Divisionを選択してください Select the entity for this QSO このQSO相手局のエンティティを選択してください Select the propagation mode for this QSO このQSOの伝播モードを選択してください Select the IOTA continent for this QSO このQSO相手局のIOTA大陸略称を選択してください Select the IOTA reference number for this QSO このQSO相手局のIOTAリファレンス番号を選択してください Not Identified 不明 Not - Not Identified Not - 不明 MainWindowInputQSL QSL Sent QSL送付 QSL Rec QSL受領 QSL Via QSL Msg Status of the QSL sending. QSLカードの送付状況 Status of the QSL reception. QSLカードの受領状況 QSL sending information. QSLカードの送付先の情報 QSL reception information. QSLカードの受領元の情報 Date of the QSL sending. QSLカードを送付した日付 Date of the QSL reception. QSLカードを受領した日付 Message of the QSL. QSLカードのメッセージ QSL via information. QSLカード経由先などの情報 MainWindowMyDataTab Watt W Keep this data このデータを保持 Data entered in this tab will be copied into the next QSO このタブに入力されたデータは次の交信にもコピーされます Power used for the QSO in watts QSOに用いた送信出力をワットの単位で表示 Logging operator's callsign ログを記入したオペレーターのコールサイン Callsign used over the air 交信に用いたコールサイン My QTH locator 自局QTHのグリッドロケーター Power 送信出力 Operator オペレーター Station Callsign 無線局のコールサイン My Locator 自局のグリッドロケーター MainWindowSatTab Keep this data このデータを保持 Data entered in this tab will be copied into the next QSO このタブに入力されたデータは次の交信にもコピーされます Satellite mode used 使用した衛星通信のモード Select the satellite you are using 使用している衛星を選択してください UpLink band アップリンクのバンド DownLink band ダウンリンクのバンド Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab. UpLink アップリンク DownLink ダウンリンク Satellite サテライト通信 Mode モード DX Locator Other その他 MHz Not Sat QSO 衛星QSOではない KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name. 識別不可能な衛星の名称が入力されているのを発見しました. 別の名称でも呼ばれており、その名称がリストにあるならば、その名称を使ってください. もしくは開発チームにこの新しい衛星の名称を加えるよう連絡してください. Please know that the satellite name will not be saved if it is not in the list so that information may be lost! リストにない衛星の名称は保存できません. したがって情報が失われてしまうことをご承知おきください! Other - Sat not in the list その他、リストにない衛星 Name of the Satellite if not in the list. Select: " リストに衛星の名前がない場合、" " to enable this box. (format like AO-51) "を選択して、この入力ボックスを有効にしてください。 (入力例:AO-51) The satellite you have in your QSO is: QSO情報に記録された衛星の名称は以下のものです: QObject Database Error データベース エラー KLog DB needs to be upgraded. KLog DBを更新する必要があります. Do you want to upgrade it now? いま更新しますか? If DB is not upgraded KLog may not work properly. DBを更新しないとKLogは正しく動作しない可能性があります. KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you. DBの中に以前のバージョンのログを発見しました。すべてのデータを新しく作成されるDXタイプのログに移行します。 KLog: Enter Station callsign KLog: 無線局のコールサインを入力してください Enter the station callsign used in this log このログで使用する無線局のコールサインを入力してください Station Callsign 無線局のコールサイン All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK. すべてのデータが正しく移行できました. メニューのSetup->Preferences->Logsから、問題ないことを確認してください. QSO: Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel? 更新を中止するとデータに矛盾が生じたり、データが失われる可能性があります.  更新を中止しますか? Progress: 進捗状況: Updating DXCC award information... Updating DXCC Award information... Updating WAZ award information... Updating mode information... モードの情報を更新しています... Abort updating 更新の中止 Updating bands information... バンドの情報を更新しています... Updating bands information in %1 status... %1 用のバンドの情報を更新しています... Updating mode information in %1 status... %1 用のモードの情報を更新しています... New One, work it! New Oneです. 交信すべし! Needed, work it! 交信すべし! Worked but not confirmed 交信済だけど未コンファーム Confirmed コンファーム済 Not identified 不明 Install wizard was canceled before completing... インストールウィザードは操作完了前に中断されました... Do you want to remove the KLog dir from your disk? KLog ディレクトリーをディスクドライブから削除しますか? Your KLog dir has been removed KLog ディレクトリは削除されました I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk. KLog ディレクトリーが削除できませんでした. ハードディスクから削除したい場合は手動で削除してください. Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk. KLog ディレクトリーが削除できませんでした. ハードディスクから削除したい場合は手動で削除してください. Remember that your KLog dir is on your system... KLog ディレクトリーはシステム中に残ったままです... Thank you for running KLog! KLogを使用してくださりありがとうございます! Updating DXCC information... SearchWidget &Clear クリア(&C) &Select All すべて選択(&S) &Search 検索(&S) All すべてのログ &Export Highlighted 選択した項目をエクスポート(&E) Clear the searches. 検索結果をクリアします. Export the search result to an ADIF file. 検索結果をADIFファイルにエクスポートします. Select/Unselect all the QSOs shown. 表示されたQSOすべてを選択・選択解除します. Search in the log. ログを検索します. Search in all logs. すべてのログを検索します. Enter the QRZ to search for. 検索するコールサインを入力してください. Search results. 検索結果. QRZ コールサイン Date/Time 日付/時刻 Band バンド Mode モード QSL Sent QSL送付 QSL Rcvd QSL受領状況 Station Callsign 無線局のコールサイン ID &Clear selection 選択をクリア(&C) Save File ファイルに保存 QSL Send QSLカードの送付 &Delete 削除(&D) Delete a QSO QSOのレコードを削除します &Edit QSO QSOの編集(&E) Edit this QSO QSOのレコードを編集します Via &bureau ビューロー経由(&b) Send this QSL via bureau QSLカードをビューロー経由で送ります D&irect ダイレクト(&i) Send this QSL via direct QSLカードをダイレクトで送ります &Request my QSL 自分のQSLカードがリクエストされた (&R) Mark my QSL as requested QSLカードがリクエストされているとマークします Via Direct && mark DX QSL as requested ダイレクトで送付、相手局にリクエスト Send this QSL via direct & mark DX QSL as requested QSLカードをダイレクトで送ったこと、および相手のQSLカードにリクエストのマークをします Via Bureau && mark DX QSL as requested ビューロー経由で送付、相手局にリクエスト Send this QSL via bureau & mark DX QSL as requested QSLカードをビューロー経由で送ったこと、および相手のQSLカードにリクエストのマークをします &Request the QSL QSLカードがリクエストされた (&R) Mark the QSL as requested QSLカードがリクエストされていることをマークします Via bureau && mark my QSL as requested ビューロー経由で受領 && 自分のQSLはリクエスト QSL received via bureau & mark my QSL as requested QSLカードをビューロー経由で受け取ったこと、および自分のQSLカードがリクエストされていることをマークします Via bureau ビューロー経由 QSL received via bureau QSLカードをビューロー経由で受け取りました Direc&t && mark as my QSL requested ダイレクトを受領、QSLカードがリクエストされた (&t) QSL received via direct & mark my QSL as requested QSLカードをダイレクトで受け取ったこと、および自分のQSLカードがリクエストされていることをマークします Direc&t ダイレクト(&t) QSL received via direct QSLカードをダイレクトで受け取りました You have requested to delete the QSO with: 次の局とのQSOを削除しようとしています: Are you sure? 本当に削除しますか? Needed QSO to send the QSL QSLカード送付の必要があるQSO My QSL requested to be sent 自分のQSLカードがリクエストされている DX QSL pending to be received 相手局のQSLカードをまだ受け取っていない SetupDialog My Data 自局の情報 Bands/Modes バンドとモード DX-Cluster DXクラスター Colors 表示色 Misc その他 World Editor ワールドエディター Logs ログ ClubLog Cancel キャンセル OK Config Dialog 設定 User data ユーザー情報 D&X-Cluster D&Xクラスター You need to enter at least one log in the Logs tab. 「ログ」タブで少なくともひとつログを入力してください. World ワールド Misc tab 「その他」タブ and click on 次のボタンをクリックしてください Move DB 「DBを移動」 You need to enter at least a valid QRZ. 少なくともひとつ適切なコールサインを入力してください. Go to the 次のタブに行き、 DB has not been moved to new path DBは新しいパスに移動されていません or the DB will not be moved to the new location. そうしなければ、DBは新しいパスに移動されません. User tab 「ユーザー情報」タブ and enter valid QRZ. に移動し、適切なコールサインを入力してください. You have not selected the kind of log you want. ログの種類が選択されていません. You will be redirected to the Log tab. Please add and select the kind of log you want to use. この後、「ログ」タブに誘導されます. 使用したいログの種類を選択・追加してください. SetupEntityDialog Entity エンティティ Name of the Entity エンティティの名称 CQ CQ zone CQゾーン ITU ITU zone ITUゾーン Latitude 緯度 Longitude of the Entity エンティティの経度 Longitude 経度 UTC Local time difference to UTC ローカル時刻とUTCとの差 Main prefix 主なプリフィクス Main prefix of the entity エンティティの主要なプリフィクス ARRL ID Comma separated possible prefixes, e.g. EA1, EA2, ... その他の使用される可能性のあるプリフィクスをコンマで区切って入力. 例 JA1, JA2,... Prefixes その他のプリフィクス Date of the deletion 消滅した日付 Deleted 消滅 Cancel キャンセル OK Entity Dialog エンティティ設定ウィンドウ SetupPageBandMode Bands バンド Modes モード SetupPageClubLog &Callsign コールサイン(&C) ClubLog &password ClubLogパスワード(&p) ClubLog &email ClubLog &email Enter the email you used to register in ClubLog. ClubLogに登録したemailを入力してください. Enter the callsign you used to register in ClubLog. ClubLogに登録したコールサインを入力してください. Enter your password in ClubLog. ClubLogのパスワードを入力してください. &Send QSOs in real time QSOデータをリアルタイムで送信(&S) &Activate ClubLog ClubLogサポート機能を使う(&A) Use QSO Station &Callsign QSOの際のコールサインを使用(&C) Send each QSO to ClubLog in real time, as they are added (or modified) in KLog KLogにQSOデータを追加(または訂正)するたび、ClubLogにリアルタイムで送信します Starts the ClubLog support in KLog KLogのClubLogサポート機能をONにします Use the Station Callsign defined in each QSO instead of the one defined here ここで設定したコールサインではなく、それぞれのQSOの際に用いた無線局のコールサインを使用します SetupPageColors New One Needed in this band このバンドで未交信 Worked in this band このバンドで交信済 Confirmed in this band このバンドでコンファーム済 Default デフォルト Choose a color 色の選択 SetupPageDxCluster Add 追加 Delete 削除 Show &HF spots Show HF spots &HFスポット情報を表示 Show V/&UHF spots Show V/UHF spots V/&UHFスポット情報を表示 Show W&ARC spots Show WARC spots W&ARCスポット情報を表示 Show &worked spots Show worked spots 交信済のスポット情報を表示(&w) Show &confirmed spots Show confirmed spots コンファーム済のスポット情報を表示(&c) Show ANN/&FULL messages Show ANN/FULL messages ANN/&FULLメッセージを表示 Show WW&V messages Show WWV messages WW&Vメッセージを表示 Show WC&Y messages Show WCY messages WC&Yメッセージを表示 DX Spots DXスポット Messages メッセージ KLog: Add a DXCluster server KLog: DXクラスターサーバーを追加 Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default: アドレスとポート番号を指定 例: dxfun.com: 8000 ポート番号の指定がないときは、デフォルトで41112を使用 SetupPageLogs &New New 新規ログ(&N) &Edit 編集(&E) &Remove 削除(&R) Add a new log 新しくログを追加 Edit the selected log 選択したログを編集 Remove the selected log 選択したログを削除 Select the log you want to open 開きたいログを選択してください KLog Do you really want to remove this log? このログを本当に削除しますか? All the QSOs from this log will be also deleted... このログに含まれるすべてのQSOデータが削除されます... Operators An error has occurred showing the following error code: 次のエラーコードが発生しました: Log has not been removed. (#3) ログが削除されませんでした(#3) Log has not been removed. (#2) ログが削除されませんでした(#2) Log has not been removed. (#1) ログが削除されませんでした(#1) KLog - SetupPageLogs Date 日付 ID Station Callsign 無線局のコールサイン Comments コメント Type タイプ SetupPageLogsNew &Ok &Cancel キャンセル(&C) Select categories カテゴリーの選択 Callsign used for this log このログで交信に用いたコールサイン Comma separated list of operators: callsign1, callsign2 コンマで区切られたオペレーターのリスト: callsign1, callsign2 Start date of this log このログの開始の日付 Add a comment about this log このログにコメントを追加します Select the kind of operation for this log このログの運用のタイプを選択してください Select the mode category モードのカテゴリーを選択してください Select the operators category オペレーターのカテゴリーを選択してください Select the assisted category アシストのカテゴリーを選択してください Select the power category 送信出力のカテゴリーを選択してください Select the bands category バンドのカテゴリーを選択してください &Date 日付(&D) &Station Callsign 無線局のコールサイン(&S) &Operators オペレーター(&O) Comm&ent コメント(&e) &Type of Operation 運用のタイプ(&T) &Mode Category モードカテゴリー(&M) O&perators Category オペレーターカテゴリー(&p) &Assisted Category アシステッドカテゴリー(&A) Po&wer Category 送信出力カテゴリー(&w) &Bands Category バンドカテゴリー(&B) O&verlay オーバーレイ(&v) Select the Overlay category オーバーレイカテゴリーを選択してください Categories not OK 不適切なカテゴリー選択 You need to enter a valid QRZ in the Station Callsign box. The log will not be opened. 無線局のコールサイン欄に適切なコールサインを入力してください。 ログは作成されません。 You selected an invalid combination. The log will not be opened. 適切な組み合わせが選択されていません。 ログは作成されません。 Categories OK 適切なカテゴリー選択 SetupPageMisc &Imperial system Imperial system インチ・ヤード表記(&I) &Log in real time Log in real time 現在時刻でログを記録(&L) &Time in UTC Time in UTC 時刻のUTC表記(&T) &Save ADIF on exit Save ADIF on exit 終了時にADIFを保存(&S) Use this &default filename Use this default filename 次のデフォルトのファイル名を使用(&d) Mark &QSO to send QSL when QSL is received Mark QSO to send QSL when QSL is received &QSLカード受領時に発送にマークする Complete QSO with previous data 以前のデータを使ってQSOの項目を埋める Select to use the following name for the logfile without being asked for it again. ログファイルには次のファイル名を用い、以後、尋ねられないようにするには、チェックをいれてください. This is the default file where ADIF data will be saved. ADIF形式でファイルを保存するときのデフォルトのファイル名. Please specify an existing directory where the database (logbook.dat) will be saved. データベース (logbook.dat) が保存される既存のディレクトリーを指定してください. The search box will show also the callsign on the air to do the QSO. 検索結果にそのQSOのときに使用したコールサインもあわせて表示します All the data from the My Data tab will be used or data from the previous QSO will be maintained. チェックすれば自局のデータ欄の情報で上書きします。チェックしなければ直前のQSOのときの情報を保持します。 If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog. 新しいバージョンのチェックを選択している場合、KLogは改良の手助けとなる情報(コールサイン、KLogのバージョン、OSの種類)を開発者に送信します. Check it for Imperial system (Miles instead of Kilometres). インチ・ヤード表記(キロメートルのかわりにマイル)を使いたいときはチェックをいれてください Show the Station &Callsign used in the search box 検索結果に使用した無線局のコールサインも表示する(&C) &Check for new versions automatically 新しいバージョンを自動でチェックする (&C) QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours. 相手局のQSLカードを受領して、かつ自分のQSLカードを送付していなければ、QSLカードの送付待ちとしてマークをします. Check if there is a new release of KLog available every time you start KLog. KLogの起動時に新しいバージョンがリリースされているかをチェックします. &Provide Info for statistics 統計情報を提供する (&P) &Reset to My Data for all QSOs すべてQSOに自局のデータを設定(&R) Move DB DBを移動 Select to use real time. 現在時刻のログ記入を行う場合、チェックをいれてください Select to use UTC time. 時刻のUTC表記を行う場合、チェックを入れてください Select if you want to save to ADIF on exit. 終了時にADIF形式で保存したい場合、チェックをいれてください Complete the current QSO with previous QSO data. 現在のQSOの各項目を埋めるのに、以前のQSOのデータを使用します. This is the directory where the database (logbook.dat) will be saved. このディレクトリーにデータベース (logbook.dat) が保存されます. Click to change the path of the database. データベースのパスを変更するにはクリック. This is the directory where DB (logbook.dat) will be saved. このディレクトリーにDB (logbook.dat) が保存されます. Click to change the default ADIF file. デフォルトのADIFファイルを変更するにはクリックしてください. Click to move the DB to the new directory. DBを新しいディレクトリーに移動するにはクリックしてください. Select Directory ディレクトリーを選択 File moved ファイルを移動しました File copied ファイルをコピーしました File NOT copied ファイルがコピーされませんでした The target directory does not exist. Please select an existing directory. 移動先のディレクトリーが存在しません. 既存のディレクトリーを指定してください. Browse 参照 Open File ファイルを開く SetupPageUserDataPage &Personal data Personal data 個人の情報(&P) Station &data Station data 無線局の情報(&d) Enter your name 名前を入力してください Enter your address - 1st line 住所を入力してください (1行目) Enter your address - 2nd line Enter your address - 2nd line 住所を入力してください (2行目) Enter your address - 3rd line 住所を入力してください (3行目) Enter your address - 4th line 住所を入力してください (4行目) Enter your city 市町村名を入力してください Enter your zip code 郵便番号を入力してください Enter your province or state 厳密にはProv/Stateじゃないですけど 都道府県名を入力してください Enter your country 国名を入力してください &Name Name 名前(&N) &Address Address 住所(&A) Cit&y City 市町村(&y) &Zip Code Zip Code 郵便番号(&Z) Pro&v/State Prov/State 厳密にはProv/Stateじゃないですけど 都道府県(&v) Countr&y Country 国(&y) Enter your information for rig リグの情報を入力してください Enter your information for antenna アンテナの情報を入力してください Enter your power information 送信出力の情報を入力してください &Rig 1 リグ 1(&R) R&ig 2 リグ 2(&i) Ri&g 3 リグ 3(&g) Antenna &1 アンテナ &1 Antenna &2 アンテナ &2 Antenna &3 アンテナ &3 Po&wer 送信出力(&w) Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign. 自局のグリッドロケーターを入力してください. 入力されなければKLogはコールサインの情報をもとにグリッドロケーターを推測して表示します. &QRZ コールサイン(&Q) &Operators オペレーター(&O) &CQ Zone CQゾーン(&C) &ITU Zone ITUゾーン(&I) &Locator グリッドロケーター(&L) &Locator (not valid) グリッドロケーター(不適合)(&L) Enter the station callsign that will be used for logging ロギングで使う自局のコールサインを入力してください。 Enter the operators (comma separated if more than one). オペレーター名を入力してください。(複数の場合はコンマで区切って入力してください。) SetupPageWorldEditor An entities information file (cty.csv) has been detected in your KLog folder and will be loaded. DXCC情報取得のファイル (cty.csv) がKLogフォルダーに見つかりました. ファイルをロードします. No entities information file (cty.csv) has been detected in your KLog folder. DXCC情報取得のファイル (cty.csv) がKLogフォルダーに見つかりません. KLog will not be able to show entities information. KLogはDXCC情報の表示ができません. Prefix プリフィクス Entity エンティティ ARRL ID Continent 大陸名 CQ Zone CQゾーン ITU Zone ITUゾーン UTC Latitude 緯度 Longitude 経度 Deleted 消滅 Since Date 交信有効期間はじめ To Date 交信有効期間おわり Open File ファイルを開く BigCTY (*.csv) Entities information has been updated. DXCC情報が更新されました. Entities information has not been updated. DXCC情報が更新されませんでした. ShowErrorDialog KLog Message SoftwareUpdateDialog Ok KLog update KLogの更新 Congratulations! おめでとうございます! Your KLog has been updated. お使いの KLog は更新されました. You already have the latest version. 最新のバージョンを入手しました. StartWizard KLog - The free hamradio logging program フリーなアマチュア無線用ログソフト KLog Quit Setup 設定の中止 Setup is not complete yet. Are you sure you want to quit setup? 設定は完了していません。本当に設定を中止しますか? World Entity エンティティ Continent 大陸名 Abort reading 読込みの中止 Reading cty.csv... cty.csvを読みこんでいます… eLogClubLog Host not found! ホストが見つかりません! Timeout error! タイムアウトエラー! KLog - ClubLog Undefined error... 未定義のエラー... Callsign missing コールサインがない Invalid callsign 正しくないコールサイン Skipping SWL callsign SWLナンバーをスキップ Callsign is your own call コールサインが自分自身のコールサイン Invalid callsign with no DXCC mapping DXCCで割り当てされていないコールサイン Updated QSO 更新されたQSO Invalid ADIF record 正しくないADIFレコード Missing ADIF record ADIFレコードがない Test mode - parameters ok, no action taken テストモード - パラメータはOK.、動作は行われません It seems to be a PASSWORD ERROR; check your password. パスワードがエラーのようです. パスワードを再確認してください. It seems that your ClubLog password is not correct. ClubLogのパスワードが正しく設定されていないようです Please check your password in the setup. ClubLog uploads will be disabled. パスワード設定を再確認してください. ClubLogアップロード機能は停止します. Excessive API Usage API呼び出しが過剰 Internal Error 内部エラー Rejected 拒否 QSO Duplicate QSOが重複 QSO Modified QSO内容が変更 Missing Login ログインしていない QSO OK Upload denied アップロードが拒否 No callsign selected コールサインが選択されていない No match found 一致するものが見つからない Dropped QSO OK Login rejected ログインが拒否 Rejected: Callsign is your own call 拒否: コールサインが自分自身のコールサイン klog-0.9.2.9/translations/klog_hr.ts0000644000076700000620000055664413233376355015347 0ustar staff AboutDialog About KLog O KLogu You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog. Također nam možete pomoći šaljući izvješća o greškama ili malih doprinosa u programskom kodu ili bilo što što mislite da može unaprijediti KLog. If you want to provide support you are welcome to join the Ako želite podržati dobrodošli ste pridružiti se KLog development mailing list This is the infinitive form. If this is to be concatenated to the "if you want to provide support..." string, the last word should say "listi" instead of "lista". KLog razvoj mailing lista ! ! Authors Autori If KLog is still not in your language and you want to help us, you are welcome to contact us through the Ako KLog još nije na vašem jeziku i želite nam pomoći, dobrodošli ste javiti nam se kroz By Od Please know that this is an BETA release and it may contain many bugs.<br>Backup your data before using this software! Molim primite na znanje da je ovo BETA inačica i da može imati puno programskih grešaka.<br>Napravite sigurnosnu kopiju vaših podataka prije korištenja ovog softvera! Author Autor KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing. KLog je bio u potpunosti iznova napisan u inačici 0.6.2 kako bi postao višeplatformska aplikacija koja se izvršava na glavnim operacijskim sustavima (Linux, macOS i Windows) i pružio funkcionalnost koju KLog nije pružao. KLog is a free logbook for hamradio operators. KLog je slobodna dnevnička aplikacija za radio-amatere operatere. Please provide your review in KLog's eHam review page: Molimo ocijenite KLog na eHamovoj stranici za ocjene: Find more information and the latest release at Potražite više informacija i najnoviju inačicu na today danas Main developer Glavni razvijatelj programa KLog is developed by a very small team and you are invited to join! Klog razvija vrlo mali tim i pozvani ste da se pridružite! KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs KLog razvijatelji programskog koda razvili su opciju koja šalje neke korisničke podatke na KLogov poslužitelj kojima je osnovna svrha identificiranje broja instaliranih inačica, kako bi razvoj mogao biti usmjeren u jednom ili drugom smijeru, uzevši u obzir korisnikove potrebe At present, the data that is provided is the following: Trenutno, podatci koji se šalju su: Be aware that you can enable/disable this feature from the Misc tab in the Setup page Budite svjesni da možete omogućiti/onemogućiti ovu funkcionalnost na kartici Razno u stranici Postavke Translators bring KLog into your language. They are really an important part of the KLog development team. Prevoditelji donose KLog u vaš jezik. Oni su važan dio tima koji razvija KLog. Translators Prevoditelji Privacy advisory Upozorenje o privatnosti Callsign Pozivni znak KLog version Inačica KLoga Operating system Operacijski sustav KLog KLog Privacy Privatnost CTYPage Country data download Preuzmi podatke o zemljama KLog needs country data... KLog treba podatke o zemljama... &Download &Preuzmi &Ignore &Zanemari Country data needed Potrebni su potaci o zemljama KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information. KLog koristi cty.csv datoteku s http://www.country-files.com/ za dobivanje DXCC informacije. You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do. Trebate preuzeti cty.csv datoteku ako želite da vam KLog prikaže zemlje, lokator,...QSOa koje radite. Click on Download to download now. Kliknite na Preuzmi za trenutno preuzimanje. KLog KLog I can't find the host. Please check your network and try again Do you want to try again? Ne mogu naći stroj. Molim provjerite mrežu i pokušajte ponovo Želite li probati ponovo? DXCCStatusWidget Update Ažuriraj ID ID Entity Entitet DXClusterWidget Connect Spoji Clear Izbriši Click on connect to connect to the DX-Cluster Kliknite spoji za spajanje na DX-Cluster Trying to connect to the server Pokušavam se spojiti na poslužitelj KLog DXCluster Kontest DXCluster KLog DXCluster Click on Connect to connect to the DX-Cluster server Kliknite Spoji za spajanje na DX-Cluster poslužitelj The connection was refused by the peer. Make sure the DXCluster server is running, and check that the host name and port settings are correct. Stroj odbija spajanje. Osigurajte da DXCluster poslužitelj radi i provjerite jesu li ime stroja i port ispravni. The following error occurred: %1. Dogodila se greška: %1. Connected to server Spojen na poslužitelj KLog message Kontest message Poruka KLoga Enter your callsign to connect to the cluster: Unesite pozivni znak za spajanje na klaster: Enter your password to connect to the cluster: (Just hit enter for no password) Unesite zaporku za spajanje na klaster: (samo Enter ako nemate zaporke) Not logged on, you may need to enter your callsign again. Niste prijavljeni, možda ćete trebati ponovo unijeti svoj pozivni znak. Disconnect Odspoji The host was not found. Please check: Poslužitelj nije pronađen. Molim provjerite: - your network connection; - the host name and port settings. - vaš spoj na mrežu; - ime poslužitelja i port. Enter here the commands to be sent to the DX-Cluster server Unesite naredbu za poslati DX-Clusteru Connection closed by the server Poslužitelj je prekinuo vezu Send Pošalji DataProxy_SQLite Software version in DB is null Inačica softvera u bazi je null No query failed Niti jedan upit nije neuspio KLog DXCC KLog DXCC All QSOs have been updated with a DXCC. Svi QSOi su ažurirani sa DXCC. DownLoadCTY Download of cty.csv failed with the following error code: Preuzimanje cty.csv je neuspjelo s kodom greške: Download of cty.csv done. Preuzimanje cty.csv završeno. There is already a cty.csv file in the folder but it will be replaced with the new one. Postojeća cty.csv datoteka u mapi bit će zamijenjena s novom. Could not open Ne mogu otvoriti for writing. za pisanje. FileManager Reading ADIF file... Čitam ADIF datoteku... Abort reading Prekini čitanje The log that you have selected contains more than just one station callsign. Dnevnik koji ste izabrali sadrži više od jednog pozivnog znaka. Please select the station callsing you want to export the log from: Molim izaberite pozivni znak postaje za koju želite izvesti dnevnik: Station Callsign: Pozivni znak postaje: Define Station Callsign If this sentence ought to be read as imperative, the first word should say "Odredite" Odrediti pozivni znak postaje You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here. Niste izabrali pozivni znak. Klog će izvesti QSOe bez definiranog pozivnog znaka postaje i one s pozivnim znakom unešenim ovdje. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Unesite pozivni znak za ovaj dnevnik ili ga ostavite praznim za QSO bez definiranog pozivnog znaka postaje: Writing ADIF file... Zapisujem ADIF datoteku... Abort writing Prekini pisanje Exporting LoTW ADIF file... Izvozim LoTW ADIF datoteku... Writing ADIF file... QSO: Zapisujem ADIF datoteku ... QSO: Reading LoTW file... Čitam LoTW datoteku... There are more than one log in this logfile. All logs will be imported in the current log. Do you want to continue? Postoji više od jednog dnevnika u ovoj datoteci. Svi dnevnici bit će uvezeni u trenutan dnevnik. Želite li nastaviti? Importing ADIF file... QSO: Uvozim ADIF datoteku... QSO: You have cancelled the file export. The file will be removed and no data will be exported. Do you still want to cancel? Prekinuli ste izvoz datoteke. Datoteka će biti izbrisana i podatci neće biti izvezeni. Želite li još uvijek prekinuti? Do you want to continue with the current file? Želite li nastaviti s trenutnom datotekom? This log seems to lack of RST-TX information. Izgleda da u ovoj datoteci nedostaje RST-TX informacija. Click on Yes to add a default 59 to all QSO with a similar problem. Kliknite na Da kako bi primjenili uobičajeni 59 na sve QSOe sa sličnim problemom. If you select NO, the QSO may not be imported. Ako izaberete Ne, QSO možda neće biti uvezen. This log seems to lack of RST-RX information. Izgleda da u ovoj datoteci nedostaje RST-RX informacija. - The band missing and the following call: - Frekvencijski pojas nedostaje i sljedeći pozivni znak: - The call missing but was done at this time: - Pozivni znak nedostaje ali je urađen sada: - The mode missing and the following call: - Način rada nedostaje i sljedeći pozivni znak: - The date missing and the following call: - Datum nedostaje i sljedeći pozivni znak: - The time missing and the following call: - Vrijeme nedostaje i sljedeći pozivni znak: You have canceled the file export. The file will be removed and no data will be exported. Prekinuli ste izvoz datoteke. Datoteka će biti izbrisana i podatci neće biti izvezeni. Do you still want to cancel? Želite li još uvijek prekinuti? QSO: QSO: No station callsign has been selected and therefore no log will be exported Niti jedan pozivni znak nije izabran i kao takav niti jedan dnevnik neće biti izvezen Writing Cabrillo file... Zapisujem Cabrillo datoteku... KLog: Cabrillo Log Export not implemented Kontest: Cabrillo Log Export not implemented KLog: Izvoz dnevnika u Cabrillo format nije implementiran I am sorry but the Cabrillo Export To File feature has still not been implemented. Na žalost izvoz Cabrillo dnevnika u datoteku još nije implementiran. There is more than one log in this logfile. All logs will be imported into the current log. Do you want to continue? Importing ADIF file... You have cancelled the file import. The file will be removed and no data will be imported. It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported) This QSO is not including the minimum data to consider a QSO as valid!. Ovaj QSO ne sadrži minimalne podatke za valjan QSO!. Please edit the ADIF file and make sure that it include at least: Molim uredite ADIF datoteku tako da uključuje barem: and i This QSO had: Ovaj QSO je imao: KLog: Not all required data found! KLog: Nisu pronađeni svi obavezni podatci! KLog: No RST TX found! KLog: Nije nađen RST TX! KLog: No RST RX found! KLog: Nije nađen RST RX! InfoWidget 10M 10M 15M 15M 20M 20M 40M 40M 80M 80M 160M 160M 2M 2M 6M 6M 12M 12M 17M 17M 30M 30M 70CM 70Cm Continent Kontinent Prefix Prefiks CQ CQ ITU ITU Short Path Kratki put Long Path Dugi put Degree Grad Is this "grad" as in "deg/rad/grad"? Grad Miles Milje Km Km IntroPage Welcome to KLog! Welcome to Kontest! Dobrodošli u KLog! Welcome to KLog! - brought to you under the terms of the GPL! Dobrodošli u KLog! - vama pružen pod odredbama GPLa! Welcome to KLog Dobrodošli u KLog This looks like it's the first time you've run KLog on this computer. Izgleda da je ovo prvi put da ste pokrenuli KLog na ovom računalu. KLog is a free hamradio logging program that can run on Linux macOS and Windows. KLog je slobodan radioamaterski dnevnički program koji se može izvršavati na Linuxu maOSu i Windowsu. It is designed to provide general purpose, DX and contest logging. Namijenjen je općenitom, DX i zapisivanju kontesta. It supports QSL management, import and export of ADIF Podržava baratanje QSLima, uvoz i izvoz ADIF and Cabrillo file formats and many other features... i Cabrilo datotečnih formata i mnoge druge funkcije... Before you can start using KLog, you will be asked to: Prije nego počnete koristiti KLog bit ćete upitani da: Acknowledge to the terms of the license. Prihvatite uvjete licence. Download the DX entities information. Preuzmete listu DX entiteta. Enter your callsign, CQ zone, etc. and main configuration. Unesete vaš pozivni znak, CQ zonu, itd. i glavnu konfiguraciju. Enjoy KLog and contact the development team if you have any suggestions! Uživajte u KLogu i javite se razvojnom timu ako imate kakvih prijedloga! LicPage KLog License information KLog podatci o licenci Welcome to KLog!- brought to you under the terms of the GPL! Dobrodošli u KLog! - vama pružen pod odredbama GPLa! Acknowledge Prihvati Be aware that KLog is free software. Uzmite u obzir da je KLog slobodan softver. LogModel Date Datum Time Vrijeme QRZ QRZ Band Pojas Mode Način rada RSTtx RSTtx RSTrx RSTrx Comment Komentar LogWindow QSL Send QSL Poslana QSL Rcvd QSL Primljena &Delete Iz&briši Delete a QSO Izbriši QSO &Edit QSO &Uredi QSO Edit this QSO Uredi ovaj QSO Via &bureau Preko &biroa Send this QSL via bureau Pošalji ovu QSL preko ureda D&irect &Izravno Send this QSL via direct Pošalji ovu QSL izravno Via bureau Preko biroa QSL &received via bureau QSL p&rimljena preko biroa Direct Izravno QSL received via direc&t QSL primljena &izravno You have requested to delete this QSO. Zatražili ste brisanje ovog QSOa. Are you sure? Jeste li sigurni? MainWindow &Clear &Izbriši Recalculate Preračunaj Click to recalculate the award status Kliknite za preračunavanje statusa nagrada Starting KLog Starting Kontest Započinjem KLog &Add Dod&aj Status bar... Statusna traka ... DX Entity DX Entitet &Log Window Prozor &dnevnika &Score Window Prozor &Bodovanja MHz MHz An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: Neočekivana greška dogodila se prilikom dodavanja QSOa u vaš dnevnik. Ako problem potraje, molim kontaktirati razvijatelja programa za analizu: You have selected an entity: Izabrali ste entitet: that is different from the KLog proposed entity: koji se razlikuje od onog kojeg je predložio KLog: Import an ADIF file into the current log. Uvezi ADIF datoteku u trenutni dnevnik. Export the current log to an ADIF logfile. Izvesti trenutni dnevnik u ADIF datoteku. Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program). Izvezi sve QSOe koji traže QSLe u ADIF datoteku (npr. za uvažanje u program za ispit QSL naljepnica). &Export ADIF for LoTW... &Izvezi ADIF za LoTW... Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW! Izvezite ADIF datoteku za slanje u LoTW. Sjetite se da je potpišete sa TQSLom prije slanja na LoTW! Print your log. Ispišite dnevnik. Opens the data folder of KLog. Otvara mapu s Klog podatcima. Go through the log reusing previous QSOs to fill missing information in other QSOs. Idi kroz dnevnik koristeći prijašnje QSOe za popunjavanje nedostajućih podataka u drugim QSOima. Fill in DXCC data Popuni DXCC podatke Go through the log filling QSOs without a DXCC defined. Idi kroz dnevnik popunjavajući QSOe bez definiranog DXCCa. QSL tools... QSL alati... Shows QSOs for which you should send your QSL and request the DX QSL. Prikazuje QSOe za koje trebate poslati QSL i zatražiti DX QSL. Shows the DX-QSL that has been requested or QSLs has been sent with no answer. Prikazuje DX-QSL koji je bio zatražen ili QSLe koji su bili poslani bez odgovora. Shows the DX-QSL that has been requested. Pokazuje DX-QSL koji je bio zatražen. LoTW tools... LoTW alati... Mark all non sent QSOs in this log as queued to be uploaded. Označi sve neposlane QSOe u ovom dnevniku kao u redu za učitavanje. Mark all non sent QSOs as queued to be uploaded. Označi sve neposlane QSOe kao u redu za učitavanje. Mark as sent all queued QSO of this log Označi kao poslane sve QSOe u ovom dnevniku koji su u redu Mark all queued QSOs in this log as sent to LoTW. Označi sve QSOe koji su u redu u ovom dnevniku kao poslane u LoTW. Mark all queued QSO as sent Označi sve QSOe u redu kao poslane For updated DX-Entity data, update cty.csv. Za osvježene podatke o DX entitetima, osvježi cty.csv. KLog LoTW KLog LoTW All pending QSO of this log has been marked as queued for LoTW! Svi neriješeni QSOi u ovom dnevniku označeni su kao u redu za LoTW! There was a problem to mark all pending QSO of this log as queued for LoTW! Dogodio se problem prilikom označavanja svih neriješenih QSOa u ovom dnevniku kao u redu za LoTW! All pending QSO has been marked as queued for LoTW! Svi neriješeni QSOi označeni su kao u redu za LoTW! All queued QSO of this log has been marked as sent for LoTW! Svi neriješeni QSOi u ovom dnevniku označeni su kao poslani u LoTW! There was a problem to mark all queued QSO of this log as sent for LoTW! Dogodio se problem prilikom označavanja svih QSOa u redu u ovom dnevniku kao poslanih u LoTW! The log that you have selected contains more than just one station callsign. Dnevnik koji ste izabrali sadrži više od jednog pozivnog znaka. Export to ADIF... Export all logs to ADIF... Export Requested QSL to ADIF... Export ADIF for LoTW... Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW. Please select the station callsing you want to mark as sent to LoTW: Station Callsign: Pozivni znak postaje: Define Station Callsign Odrediti pozivni znak postaje You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: Unesite pozivni znak za ovaj dnevnik ili ga ostavite praznim za QSO bez definiranog pozivnog znaka postaje: No station callsign has been selected and therefore no log will be marked All queued QSO has been marked as sent to LoTW! Svi QSOi u redu označeni su kao poslani u LoTW! There was a problem to mark all queued QSO of this log as sent to LoTW! Dogodio se problem prilikom označavanja svih QSOa u redu u ovom dnevniku kao poslanih u LoTW! ADIF file ADIF datoteka Cabrillo files Cabrillo datoteke Any file Bilo koja datoteka The selected log is not existing or it is still empty. Izabrani dnevnik ne postoji ili je još uvijek prazan. Click Yes and KLog will open an empty log. Kliknite Da i KLog će otvoriti prazan dnevnik. Click No and KLog will select another log with data. Kliknite Ne i KLog će izabrati drugi dnevnik s podatcima. You can modify the config file accordingly, if needed. Možete proizvoljno urediti konfiguracijsku datoteku, ako bude potrebno. TX Frequency in MHz. TX frekvencija u MHz. RX Frequency in MHz. RX frekvencija u MHz. Power used by the DX. Snaga koju je koristio DX. Logging operator's callsign. Snimam operaterov pozivni znak. Callsign used over the air. Pozivni znak korišten u eteru. My QTH locator. Moj QTH lokator. Name of the DX. DXovo ime. QTH of the DX. DXov QTH. Locator of the DX. DXov lokator. QRZ of the QSO. QRZ QSOa. TX RST. TX RST. RX RST. RX RST. TX Exchange. TX Izmjena. RX Exchange. RX Izmjena. Band of the QSO. Frekvencijski pojas QSOa. Mode of the QSO. Način rada QSOa. Date of the QSO. Datum QSOa. Time of the QSO. Vrijeme QSOa. Add the QSO to the log. Dodaj QSO u dnevnik. Clears the QSO entry. Čisti QSO unos. Number of confirmed DXCC entities. Broj potvrđenih DXCC entiteta. Number of worked DXCC entities. Broj rađenih DXCC entiteta. Number of confirmed WAZ zones. Broj potvrđenih WAZ zona. Number of worked WAZ zones. Broj rađenih WAZ zona. Number of confirmed local references. Broj potvrđenih lokalnih referenci. Number of worked local references. Broj rađenih lokalnih referenci. Number of confirmed QSOs. Broj potvrđenih QSOa. Number of worked QSOs. Broj rađenih QSOa. Number of DXCC worked on the selected year. Broj DXCCa urađenih u izabranoj godini. Number of CQ Zones worked on the selected year. Broj CQ zona urađenih u izabranoj godini. Score for the DXMarathon on the selected year. Broj bodova za DXMarathon u izabranoj godini. Select the year you want to check. Izaberite godinu koju želite provjeriti. Status of the DX entity. Status DX entiteta. Name of the DX entity. Ime DX entiteta. Log Dnevnik An unexpected error ocurred!! Nastupila je neočekivana greška!! If the problem persists, please contact the developers Ako se problem nastavi, molim kontaktirajte razvijatelje programa for analysis: za analizu: Error in function Greška u funkciji Error code Kod greške Error text Tekst greške Failed query Neuspio upit Do you want to keep showing errors? Želite li vidjeti daljnje greške? QRZ QRZ Band Pojas Mode Način rada Date Datum Time Vrijeme SRX SRX RSTtx RSTtx STX STX RSTrx RSTrx QRZ of the QSO QRZ QSOa TX RST RST TX RX RST RST RX TX Exchange TX Izmjena RX Exchange RX Izmjena Band of the QSO Pojas QSOa Mode of the QSO Način rada QSOa Date of the QSO Datum QSOa Time of the QSO Vrijeme QSOa Add the QSO to the log Dodaj QSO u dnevnik Input Unos Ready Spremno NEW MULT NOVI MULT Ready... Spremno... Save File Spremi Datoteku The logfile has been modified. Do you want to save your changes? Dnevnik je bio izmijenjen. Želite li snimiti promjene? &File &Datoteka &New... &Novo ... &Open... &Otvori... &Save As... &Spremi kao... &Print Log... &Ispiši dnevnik ... E&xit I&zađi &Tools &Alati &Export to ADIF... &Izvezi u ADIF ... &Import from ADIF... &Uvezi iz ADIFa... &Find QSO to QSL Nađi QSO za &QSL &Setup &Postavke &Setup... &Postavke... &Help &Pomoć &About... &O programu... DUPE DUPLIKAT Power(rx) Snaga (rx) RST(tx) RST(tx) RST(rx) RST(rx) QSO QSO QSL QSL eQSL eQSL Satellite Satelit -- -- - Needed for DXMarathon - Potrebno za DXMarathon Others Drugi Click on the prefix of the right entity or Cancel to correct. Kliknite na prefiks ispravnog entiteta ili Poništi za ispravku. KLog folder KLog mapa KLog update checking result KLog nadogradnja provjerava rezultat You can find the KLog data folder here: Klog podatke možete naći u mapi: My Data Moji podaci CQ CQ Info Podaci Award Priznanje KLog KLog &Export Requested QSL to ADIF... Izv&ezi tražene QSLe u ADIF... &Find DX-QSLs pending to receive Nađi DX QSLe koje nisu primljene &Find requested pending to receive Nađi zatražene koje nisu primljene Check updates... Provjeri za nadogradnje... About Qt... O Qt... About... O ... Congratulations! Čestitke! You already have the latest version. Već imate najnoviju inačicu. Nothing has been saved. You have to select a valid file type. Ništa nije bilo pohranjeno. Morate izabrati ispravnu vrstu datoteke. Freq TX TX frekv Freq RX RX frekv Confirmed Potvrđeno Worked Rađeno DXCC DXCC &Export all logs to ADIF... Izv&esti sve dnevnike u ADIF... Name Ime QTH Locator Lokator Score Postignuto DX-Marathon DX-Marathon WAZ WAZ Local Lokalno QSOs QSOa Awards Priznanja Search Traži DX-Cluster DX-Cluster Save ADIF File Spremi ADIF Datoteku Save Cabrillo File Spremi Cabrillo Datoteku Cabrillo (*.log) Cabrillo (*.log) Open File Otvori datoteku &Modify Pro&mijeni Filling QSOs... Punim QSOe... Abort filling Prekini punjenje Filling QSOs... QSO: Punim QSOe... QSO: Number Broj Comment Komentar Watts Wata Click on the prefix of the correct entity or Cancel to edit the QSO again. Kliknite na prefiks ispravnog entiteta ili Poništi za ponovo uređivanje QSOa. Clear the box Očisti polje Invalid characters used in the QRZ Nevaljali znakovi korišteni za QRZ Export ALL the QSOs into one ADIF file, merging QSOs from all the logs. Izvezi SVE QSOe u jednu ADIF datoteku, stapajući QSOe iz svih dnevnika. Fill in QSO data Popuni podatke QSOa Find My-QSLs pending to send Nađi moje QSLke koje su neriješene za slanje Shows the QSOs with pending requests to send QSLs. You should keep this queue empty! Prikazuje QSOe sa neriješenim zahtjevima za slanje QSLki. Nastojte ovaj red držati praznim! Queue all QSL to be sent of this log Queue all QSL to be sent Mark all queued QSOs as sent to LoTW. Označi sve QSOe koji su u redu kao poslane u LoTW. &Update cty.csv Až&uriraj cty.csv It seems that there are no QSO in the database. Izgleda da nema niti jednog QSOa u bazi podataka. If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help. Ako ste sigurni da baza podataka sadrži QSOe i KLog ih ne može naći, molim kontaktirajte razvijatelje programa (vidite O Klogu) za pomoć. Number of QSOs worked on the selected year. Broj QSOa odrađenih u izabranoj godini. LoTW logfile has been properly exported! LoTW dnevnička datoteka je ispravno izvezena! Remember to: Prisjetite se da: Before uploading: sign the LoTW log; and Prije učitavanja: potpišite LoTW dnevnik; i After uploading: mark as sent all the queued QSO (LoTW Tools). Poslije učitavanja: označite kao poslane sve QSOe u redu (LoTW Alati). There was no QSO to be exported. Nema QSOa za izvoz. If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as: Ako mislite da su neki QSOi trebali biti izvezeni, molim potražite ih i provjerite da je eQSL LoTW QSL poslana kućica označena kao: Q - Queued If this "Q" is a single-letter label, perhaps a more appropriate Croatian translation would start with "R" (for "U Redu") Q - U redu There was an error while exporting the LoTW. The log has not been exported! Dogodila se greška prilikom LoTW izvoza. Dnevnik nije bio izvezen! Print Log Ispiši dnevnik Printing the log... Ispisujem dnevnik... Abort printing Prekini ispisivanje Printing the log... QSO: Ispisujem dnevnik...QSO: MainWindowInputComment Add a comment for this QSO Dodaj komentar za ovaj QSO MainWindowInputEQSL Date of the ClubLog upload. Datum ClubLog učitavanja. Date of the eQSL sending. Datum slanja eQSLa. Date of the eQSL reception. Datum prijema eQSLa. Date of the LoTW sending. Datum slanja LoTWa. Date of the LoTW reception. Datum prijema LoTWa. Status of the LoTW sending. Status slanja LOTWa. Status of the LoTW reception. Status prijema LoTWa. LoTW Sent LoTW Posl LoTW Rec LoTW Prim Status on ClubLog. Status u ClubLogu. Status of the eQSL sending. Status eQSL slanja. Status of the eQSL reception. Status eQSL prijema. ClubLog ClubLog eQSL Sent eQSL poslana eQSL Rec eQSL primljena MainWindowInputOthers Primary Div Primarni Pod Secondary Div Sekundarni Pod IOTA IOTA Entity Entitet Propagation mode Propagacijski mod Select the primary division for this QSO Izaberite primarnu podjelu za ovaj QSO Select the secondary division for this QSO Izaberite sekundarnu podjelu za ovaj QSO Select the entity for this QSO Izaberite entitet za ovaj QSO Select the propagation mode for this QSO Izaberite propagacijski mod za ovaj QSO Select the IOTA continent for this QSO Izaberite IOTA kontinent za ovaj QSO Select the IOTA reference number for this QSO Izaberite IOTA referentni broj za ovaj QSO Not Identified Nije identificiran Not - Not Identified Nije - Nije identificiran MainWindowInputQSL QSL Sent QSL Poslana QSL Rec QSL Prim QSL Via QSL Preko QSL Msg QSL Por Status of the QSL sending. Status slanja QSLa. Status of the QSL reception. Status prijema QSLa. QSL sending information. Informacija slanja QSLa. QSL reception information. Informacija prijema QSLa. Date of the QSL sending. Datum slannja QSLa. Date of the QSL reception. Datum prijema QSLa. Message of the QSL. QSL poruka. QSL via information. QSL preko podatci. MainWindowMyDataTab Watt Wat Keep this data Spremiti ove podatke Data entered in this tab will be copied into the next QSO Podaci unešeni u ovu karticu bit će kopirani u sljedeći QSO Power used for the QSO in watts Snaga korištena za QSO u Watima Logging operator's callsign Snimam operaterov pozivni znak Callsign used over the air Pozivni znak korišten u eteru My QTH locator Moj QTH lokator Power Snaga Operator Operater Station Callsign Pozivni znak postaje My Locator Moj lokator MainWindowSatTab Keep this data Spremiti ove podatke Data entered in this tab will be copied into the next QSO Podaci unešeni u ovu karticu bit će kopirani u sljedeći QSO Other - Sat not in the list Drugo - Satelit nije na listi Name of the Satellite if not in the list. Select: " Ime satelita ako ga nema na listi. Izaberite: " " to enable this box. (format like AO-51) " da bi omogućili ovu kućicu (format kao AO-51) Satellite mode used Korišten satelitski način rada Select the satellite you are using Izaberite satelit koji koristite UpLink band UpLink pojas DownLink band DownLink pojas Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab. UpLink UpLink DownLink DownLink Satellite Satelit Mode Način rada DX Locator Other Drugo MHz MHz Not Sat QSO Nije satelitski QSO KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name. KLog je otkrio satelit čije ime ne poznaje. Ako je riječ o nekom od poznatih satelita, molim izaberite ga s liste. Inače, molim kontaktirajte razvojni tim da dodaju ime novog satelita. Please know that the satellite name will not be saved if it is not in the list so that information may be lost! Uočite da ime satelita neće biti spremljeno ako nije na listi pa će tako doći do gubitka podataka! The satellite you have in your QSO is: Satelit kojeg imate u QSOu je: QObject Database Error Greška baze podataka KLog DB needs to be upgraded. Klog baza treba se nadograditi. Do you want to upgrade it now? Želite li nadograditi sada? If DB is not upgraded KLog may not work properly. Ako baza podataka nije nadograđena KLog možda neće ispravno raditi. KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you. KLog je otkrio prijašnji dnevnik u bazi. Svi podaci bit će prenešeni u novi dnevnik DX tipa. KLog: Enter Station callsign KLog: Unesite pozivni znak postaje Enter the station callsign used in this log Unesite pozivni znak koji će biti korišten u ovom dnevniku Station Callsign Pozivni znak postaje All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK. Svi podatci su ispravno prenešeni. Idite u Postavljanje->Postavke->Dnevnici i provjerite da je sve u redu. QSO: QSO: Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel? Prekid ove nadogradnje proizvest će nekonzistentne podatke i mogući gubitak podataka. Želite li još uvijek prekinuti? Progress: Napredak: Updating DXCC award information... Ažuriram podatke o DXCC nagradama... Updating DXCC Award information... Ažuriram podatke o DXCC nagradama... Updating WAZ award information... Ažuriram podatke o WAZ nagradama... Updating mode information... Ažuriram podatke o načinu rada... Abort updating Prekini ažuriranje Updating bands information... Ažuriram podatke o frekvencijskim pojasevima... Updating bands information in %1 status... Ažuriram podatke o frekvencijskim pojasevima za %1 status... Updating mode information in %1 status... Ažuriram podatke o načinu rada za %1 status... New One, work it! nNew One, work it! Novi, odradite! Needed, work it! Treba, odradite! Worked but not confirmed Rađen ali nije potvrđen Confirmed Potvrđeno Not identified Nije identificiran Install wizard was canceled before completing... Instalacijski čarobnjak prekinut je prije kraja... Do you want to remove the KLog dir from your disk? Želite li izbrisati KLog mapu s vašeg diska? Your KLog dir has been removed Vaša KLog mapa je uklonjena I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk. Nisam mogao ukloniti vašu KLog mapu. Izbrišite je ručno ako je želite ukloniti s vašeg čvrstog diska. Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk. Vaša KLog mapa nije mogla biti izbrisana. Učinite to ručno ako je želite ukloniti s vašeg čvrstog diska. Remember that your KLog dir is on your system... Podsjetite se da je vaša KLog mapa na vašem sustavu... Thank you for running KLog! Hvala što koristite KLog! Updating DXCC information... Ažuriram DXCC podatke... SearchWidget &Clear &Izbriši &Select All Označi &sve &Search &Traži All Svi &Export Highlighted Izv&ezi označeno Clear the searches. Očisti potrage. Export the search result to an ADIF file. Izvezi rezultat potraga u ADIF datoteku. Select/Unselect all the QSOs shown. Označi/neoznači sve prikazane QSOe. Search in the log. Traži u dnevniku. Search in all logs. Traži u svim dnevnicima. Enter the QRZ to search for. Unesite QRZ za traženje. Search results. Rezultati potrage. QRZ QRZ Date/Time Datum/Vrijeme Band Pojas Mode Način rada QSL Sent QSL Poslana QSL Rcvd QSL Primljena Station Callsign Pozivni znak postaje ID ID &Clear selection &Izbriši selekciju Save File Spremi Datoteku QSL Send Pošalji QSL &Delete Iz&briši Delete a QSO Izbriši QSO &Edit QSO &Uredi QSO Edit this QSO Uredi ovaj QSO Via &bureau Preko &biroa Send this QSL via bureau Pošalji ovu QSL preko ureda D&irect &Izravno Send this QSL via direct Pošalji ovu QSL izravno &Request my QSL Za&traži moju QSL Mark my QSL as requested Označi moju QSL kao zatraženu Via Direct && mark DX QSL as requested Izravno i označi DX QSL kao zatraženu Send this QSL via direct & mark DX QSL as requested Pošalji ovu QSL izravno i označi DX QSL kao zatraženu Via Bureau && mark DX QSL as requested Preko ureda i označi DX QSL kao zatraženu Send this QSL via bureau & mark DX QSL as requested Pošalji ovu QSL izravno i označi DX QSL kao zatraženu &Request the QSL Za&traži QSL Mark the QSL as requested Označi QSL zatraženom Via bureau && mark my QSL as requested Preko biroa i označi moju QSL kao zatraženu QSL received via bureau & mark my QSL as requested QSL primljena izravno i označi moju QSL kao zatraženu Via bureau Preko biroa QSL received via bureau QSL primljena preko biroa Direc&t && mark as my QSL requested &Izravno & označi moju QSL zatraženom QSL received via direct & mark my QSL as requested QSL primljena izravno i označi moju QSL kao zatraženu Direc&t &Izravno QSL received via direct QSL primljena izravno You have requested to delete the QSO with: Zatražili ste brisanje QSOa sa: Are you sure? Jeste li sigurni? Needed QSO to send the QSL QSO za koji treba poslati QSL My QSL requested to be sent Moj QSL zatražen za slanje DX QSL pending to be received Prijem DX QSLa neodlučen SetupDialog User data Korisnički podaci Bands/Modes Frekvencijski pojasevi/Načini rada My Data Moji podaci DX-Cluster DX-Cluster Colors Boje Misc Razno World Editor Urednik svijeta ClubLog ClubLog Cancel Poništi OK OK Config Dialog Postavke D&X-Cluster D&X-Cluster You need to enter at least one log in the Logs tab. Trebate unijeti barem jedan dnevnik na kartici Dnevnici. Misc tab kartica Razno and click on i kliknite na Move DB Makni bazu podataka or the DB will not be moved to the new location. ili baza podataka neće biti maknuta na novu lokaciju. You need to enter at least a valid QRZ. Trebate unijeti barem važeći QRZ. Go to the Idi na DB has not been moved to new path baza podataka nije bila maknuta na novu lokaciju User tab Korisnička kartica and enter valid QRZ. i unesite ispravan QRZ. You have not selected the kind of log you want. Niste izabrali kakvu vrstu dnevnika želite. You will be redirected to the Log tab. Please add and select the kind of log you want to use. Bit ćete preusmjereni na karticu Dnevnici. Izaberite vrstu dnevnika kakvu želite koristiti. Logs Dnevnici World Svijet SetupEntityDialog Entity Entitet Name of the Entity Ime entiteta CQ CQ CQ zone CQ zona ITU ITU ITU zone ITU Zona Latitude Zemljopisna širina Longitude of the Entity Zemljopisna dužina entiteta Longitude Zemljopisna dužina UTC UTC Local time difference to UTC Razlika između lokalnog vremena i UTC Main prefix Glavni prefiks Main prefix of the entity Glavni prefiks entiteta ARRL ID ARRL ID Comma separated possible prefixes, e.g. EA1, EA2, ... Mogući prefiksi odvojeni zarezom, npr. EA1, EA2, ... Prefixes Prefiksi Date of the deletion Datum brisanja Deleted Izbrisan Cancel Poništi OK Ok Entity Dialog Dialog entiteta SetupPageBandMode Bands Frekvencijski pojasevi Modes Načini rada SetupPageClubLog &Callsign Pozivni &znak ClubLog &password ClubLog za&porka ClubLog &email ClubLog &email Enter the email you used to register in ClubLog. Unesite e-mail s kojim ste registrirani u ClubLogu. Enter the callsign you used to register in ClubLog. Unesite pozivni znak s kojim ste registrirani u ClubLogu. Enter your password in ClubLog. Unesite zaporku za ClubLog. &Send QSOs in real time Šalji QSOe u &stvarom vremenu &Activate ClubLog &Aktiviraj ClubLog Use QSO Station &Callsign Koristi &pozivni znak QSO postaje Send each QSO to ClubLog in real time, as they are added (or modified) in KLog Šalji svaki QSO u ClubLog u stvarnom vremenu, kako su dodani (ili mijenjani) u KLogu Starts the ClubLog support in KLog Pokreće ClubLog podršku u KLogu Use the Station Callsign defined in each QSO instead of the one defined here Koristi pozivni znak postaje postavljen u svakom QSOu umjesto postavljenog ovdje SetupPageColors New One Novi Needed in this band Potrebno na ovom frekvencijskom pojasu Worked in this band Rađen na ovom frekvencijskom pojasu Confirmed in this band Confirmed Potvrđeno na ovom frekvencijskom pojasu Default Zadano Choose a color Izaberite boju SetupPageDxCluster Add Dodaj Delete Izbriši Show &HF spots Show HF spots Prikazati &HF zapažanja Show V/&UHF spots Show V/UHF spots Prikazati V/&UHF zapažanja Show W&ARC spots Show WARC spots Prikazati W&ARC zapažanja Show &worked spots Show worked spots Prikazati od&rađena zapažanja Show &confirmed spots Show confirmed spots Prikazati p&otvrđena zapažanja Show ANN/&FULL messages Show ANN/FULL messages Prikazati ANN/&FULL poruke Show WW&V messages Show WWV messages Prikatati &WWV poruke Show WC&Y messages Show WCY messages Prikazati WC&Y poruke DX Spots DX zapažanja Messages Poruke KLog: Add a DXCluster server Kontest: Add a DXCluster server KLog: Dodaj DX-Cluster poslužitelj Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default: Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default.: Dodaj adresu iza koje je :port Primjer: dxfun.com:8000 Ako ne dodate port, 41112 se podrazumijeva: SetupPageLogs Type Vrsta &New New &Novo &Edit Ur&edi &Remove Izb&risati Add a new log Dodati novi dnevnik Select the log you want to open Izaberite dnevnik koji želite otvoriti KLog KLog Do you really want to remove this log? Želite li zaista ukloniti ovaj dnevnik? All the QSOs from this log will be also deleted... Svi QSOi iz ovog dnevnika će također biti izbrisani... Operators Operateri An error has occurred showing the following error code: Nastupila je greška sa sljedećim kodom: Log has not been removed. (#3) Dnevnik nije bio izbrisan (#3) Log has not been removed. (#2) Dnevnik nije bio izbrisan (#2) Log has not been removed. (#1) Dnevnik nije bio izbrisan (#1) KLog - SetupPageLogs KLog - SetupPageLogs Edit the selected log Uredi izabrani dnevnik Remove the selected log Izbriši izabrani dnevnik ID ID Station Callsign Pozivni znak postaje Comments Komentari Date Datum SetupPageLogsNew &Ok &Ok &Cancel &Poništi Select categories Izaberite kategorije Callsign used for this log Pozivni znak korišten za ovaj dnevnik Comma separated list of operators: callsign1, callsign2 Lista operatera odvojenih zarezom: pozivni1, pozivni2 Start date of this log Datum početka ovog dnevnika Add a comment about this log Dodaj komentar za ovaj dnevnik Select the kind of operation for this log Izaberite operaciju za ovaj dnevnik Select the mode category Izaberite kategoriju načina rada Select the operators category Izaberite kategoriju operatera Select the assisted category Izaberite potpomognutu kategoriju Select the power category Izaberite kategoriju snage Select the bands category Izaberite kategoriju frekvencijskih pojaseva &Date &Datum &Station Callsign Pozivni znak po&staje &Operators &Operateri Comm&ent Kom&entar &Type of Operation Vrs&ta operacije &Mode Category Način &rada O&perators Category Kategorija O&peratera &Assisted Category Potpomognut&a kategorija Po&wer Category Kategorija &Snage &Bands Category Kategorija načina rada O&verlay Prekri&vač Select the Overlay category Izaberite kategotiju prekrivača Categories not OK Kategorije nisu OK You need to enter a valid QRZ in the Station Callsign box. The log will not be opened. You need to enter a valid QRZ in the Station Callsign box The log will not be opened. Trebate unijeti važeći QRZ u kućicu Pozivni znak postaje. Dnevnik neće biti otvoren. You selected an invalid combination. The log will not be opened. You selected an invalid combination The log will not be opened. Izabrali ste nevažeću kombinaciju. Dnevnik neće biti otvoren. Categories OK Kategorije su OK SetupPageMisc &Imperial system Imperial system &Imperialni sustav &Log in real time Log in real time &Dnevnik u stvarnom vremenu &Time in UTC Time in UTC Vrijeme u U&TC &Save ADIF on exit Save ADIF on exit &Spremi ADIF Datoteku pri izlasku Use this &default filename Use this default filename Koristi ovu &podrazumijevanu datoteku Mark &QSO to send QSL when QSL is received Mark QSO to send QSL when QSL is received Označi &QSO za slanje QSL kad je QSL primljena Complete QSO with previous data Popuni QSO prijašnjim podacima &Reset to My Data for all QSOs Ponovo namjesti Moje Podatke za sve QSOe Move DB Makni bazu podataka If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog. Ako je označena provjera nove inačice, KLog će poslati razvijatelju vaš pozivni znak, inačicu KLoga i operacijski sustav kako bi pomogao u poboljšavanju KLoga. Select to use the following name for the logfile without being asked for it again. Označite za korištenje sljedećeg imena za dnevničku datoteku bez da ste za to ponovo upitani. This is the default file where ADIF data will be saved. Ovo je zadana datoteka u koju će se spremati ADIF podatci. This is the directory where the database (logbook.dat) will be saved. Ovo je mapa u koju će se spremiti baza podataka (logbook.dat). Click to change the path of the database. Kliknite za promjenu putanje baze podataka. Please specify an existing directory where the database (logbook.dat) will be saved. Molim odaberite postojeću mapu gdje će baza podataka (logbook.dat) biti spremljena. This is the directory where DB (logbook.dat) will be saved. Ovo je mapa u koju će baza podataka (logbook.dat) biti spremljena. Click to change the default ADIF file. Kliknite za promjenu zadane ADIF datoteke. Click to move the DB to the new directory. Kliknite za micanje baze podataka u novu mapu. Select Directory Izaberite mapu File moved Datoteka maknuta File copied Datoteka kopirana File NOT copied Datoteka NIJE kopirana The target directory does not exist. Please select an existing directory. Ciljna mapa ne postoji. Molim izaberite postojeću mapu. The search box will show also the callsign on the air to do the QSO. Ova kućica za pretraživanje će vam također pokazati pozivni znak u eteru za QSO. Show the Station &Callsign used in the search box Pokazati pozivni znakl &postaju korištenu u kućici za pretraživanje All the data from the My Data tab will be used or data from the previous QSO will be maintained. Svi podaci sa kartice Moji Podaci će biti korišteni ili sačuvaj podatje prijašnjih QSOa. &Check for new versions automatically &Provjeri za nove verzije automatski QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours. QSOi će biti označeni kao neriješeni za slanje QSLke ako primite DX QSLku a niste poslali vašu. Check if there is a new release of KLog available every time you start KLog. Provjeri je li dostupna nova inačica KLoga svaki put kad pokreneš KLog. &Provide Info for statistics &Pruži podatke za statistiku Check it for Imperial system (Miles instead of Kilometres). Označiti za Imperijalni sustav (milje umjesto kilometara) Marcar si quiere usar sistema imperial (Millas en vez de Kilómetros). Select to use real time. Označite da koristite stvarno vrijeme. Select to use UTC time. Izaberite za korištenje UTC vremena. Select if you want to save to ADIF on exit. Označite ako želite snimiti u ADIF formatu prije izlaska. Complete the current QSO with previous QSO data. Popuni trenutni QSO podacima prijašnjeg QSOa. Browse Razgledavanje Open File Otvori datoteku SetupPageUserDataPage &Personal data Personal data Osobni &podatci Station &data Station data Podatci &postaje Enter your name Unesite vaše ime Enter your address - 1st line Unesite vašu adresu - 1. red Enter your address - 2nd line Enter your address - 2nd line Unesite vašu adresu - 2. red Enter your address - 3rd line Unesite vašu adresu - 3. red Enter your address - 4th line Unesite vašu adresu - 4. red Enter your city Unesite vaš grad Enter your zip code Unesite vaš poštanski kod Enter your province or state Unesite vašu županiju ili regiju Enter your country Unesite vašu državu &Name Name &Ime &Address Address &Adresa Cit&y City &Grad &Zip Code Zip Code &Poštanski kod Pro&v/State Prov/State Županija/&Regija Countr&y Country &Zemlja Enter your information for rig Unesite podatke o vašoj postaji Enter your information for antenna Unesite podatke o vašoj anteni Enter your power information Unesite podatke za vašu snagu &Rig 1 &Radio uređaj 1 R&ig 2 R&adio uređaj 2 Ri&g 3 Ra&dio uređaj 3 Antenna &1 Antena &1 Antenna &2 Antena &2 Antenna &3 Antena &3 Po&wer &Snaga Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign. Unesite lokator vaše postaje. Alternativno, KLog može koristiti približan lokator na osnovu vašeg pozivnog znaka. &QRZ &QRZ &Operators &Operatori &CQ Zone &CQ Zona &ITU Zone &ITU Zona &Locator &Lokator &Locator (not valid) &Lokator (neispravan) Enter the station callsign that will be used for logging Unesite pozivni znak koji će biti korišten za zapisivanje dnevnika Enter the operators (comma separated if more than one). Unesite operatere (odvojene zarezom ako je više od jednog). SetupPageWorldEditor KLog will not be able to show entities information. KLog neće moći prikazati podatke o entitetima. Prefix Prefiks Entity Entitet An entities information file (cty.csv) has been detected in your KLog folder and will be loaded. Datoteka s podatcima o entitetima (cty.csv) pronađena u vašoj KLog mapi bit će učitana. No entities information file (cty.csv) has been detected in your KLog folder. Datoteka s podatcima o entitetima (cty.csv) ne postoji u vašoj KLog mapi. ARRL ID ARRL ID Continent Kontinent CQ Zone CQ Zona ITU Zone ITU Zona UTC UTC Latitude Širina Longitude Dužina Deleted Izbrisano Since Date Od datuma To Date Do datuma Open File Otvori datoteku BigCTY (*.csv) VelikiCTY (*.csv) Entities information has been updated. Podaci o entitetima su ažurirani. Entities information has not been updated. Podaci o entitetima nisu ažurirani. ShowErrorDialog KLog Message KLog poruka SoftwareUpdateDialog Ok Ok KLog update KLog nadogradnja Congratulations! Čestitke! Your KLog has been updated. Vaš KLog je ažuriran. You already have the latest version. Već imate najnoviju inačicu. StartWizard KLog - The free hamradio logging program KLog - slobodna dnevnička aplikacija za radio-amatere Quit Setup Izađi iz postavljanja Setup is not complete yet. Are you sure you want to quit setup? Postavljanje nije završeno. Jeste li sigurni da želite izaći iz postavljanja? World Entity Entitet Continent Kontinent Abort reading Prekini čitanje Reading cty.csv... Čitam cty.csv... eLogClubLog Host not found! Stroj nije nađen! Timeout error! Greška prekoračenja vremena! KLog - ClubLog KLog - clublog KLog - ClubLog Undefined error... Nedefinirana pogreška... Callsign missing Nedostaje pozivni znak Invalid callsign Nevaljali pozivni znak Skipping SWL callsign Preskačem SWL pozivni znak Callsign is your own call Callsign is your ow call Pozivni znak je vaš vlastiti pozivni znak Invalid callsign with no DXCC mapping Nevaljali pozivni znak bez DXCC veze Updated QSO QSO ažuriran Invalid ADIF record Nevaljali ADIF zapis Missing ADIF record Nedostajeći ADIF zapis Test mode - parameters ok, no action taken Test način rada - parametri su u redu, nikakva akcija nije poduzeta It seems to be a PASSWORD ERROR; check your password. Izgleda kao problem s lozinkom; provjerite vašu lozinku. It seems that your ClubLog password is not correct. Izgleda da vaša ClubLog lozinka nije ispravna. Please check your password in the setup. ClubLog uploads will be disabled. Molim provjerite lozinku u postavkama. ClubLog učitavanja će biti onemogućena. Excessive API Usage Prekomjereno korištenje APIa Internal Error Interna pogreška Rejected I am not sure about the context, this is the masculine version of "rejected" Odbačen QSO Duplicate Duplicirani QSO QSO Modified QSO ažuriran Missing Login Nedostaje Login QSO OK QSO OK Upload denied Snimanje podataka na poslužitelj odbijeno No callsign selected Niti jedan pozivni znak nije označen No match found Ništa podudarajuće nije nađeno Dropped QSO Ispušten QSO OK OK Login rejected Login odbijen Rejected: Callsign is your own call Odbijeno: pozivni znak je vaš vlastiti pozivni znak klog-0.9.2.9/translations/klog.pot0000644000076700000620000024650413233376355015021 0ustar staffmsgid "" msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Qt-Contexts: true\n" #: ../aboutdialog.cpp:28 msgctxt "AboutDialog|" msgid "About KLog" msgstr "" #: ../aboutdialog.cpp:35 msgctxt "AboutDialog|" msgid "By" msgstr "" #: ../aboutdialog.cpp:37 msgctxt "AboutDialog|" msgid "KLog is a free logbook for hamradio operators." msgstr "" #: ../aboutdialog.cpp:38 msgctxt "AboutDialog|" msgid "" "Please know that this is an BETA release and it may contain many " "bugs.
Backup your data before using this software!" msgstr "" #: ../aboutdialog.cpp:40 msgctxt "AboutDialog|" msgid "" "KLog has been fully rewritten from the 0.6.2 to be able to provide a " "cross-platform application that runs in the main operating systems (Linux, " "macOS & Windows) and provide new functionalities that KLog was not providing." msgstr "" #: ../aboutdialog.cpp:42 msgctxt "AboutDialog|" msgid "Please provide your review in KLog's eHam review page:" msgstr "" #: ../aboutdialog.cpp:45 msgctxt "AboutDialog|" msgid "Find more information and the latest release at" msgstr "" #: ../aboutdialog.cpp:46 msgctxt "AboutDialog|" msgid "Author" msgstr "" #: ../aboutdialog.cpp:69 msgctxt "AboutDialog|" msgid "today" msgstr "" #: ../aboutdialog.cpp:69 msgctxt "AboutDialog|" msgid "Main developer" msgstr "" #: ../aboutdialog.cpp:73 msgctxt "AboutDialog|" msgid "KLog is developed by a very small team and you are invited to join!" msgstr "" #: ../aboutdialog.cpp:73 msgctxt "AboutDialog|" msgid "If you want to provide support you are welcome to join the" msgstr "" #: ../aboutdialog.cpp:73 ../aboutdialog.cpp:86 msgctxt "AboutDialog|" msgid "KLog development mailing list" msgstr "" #: ../aboutdialog.cpp:73 ../aboutdialog.cpp:86 msgctxt "AboutDialog|" msgid "!" msgstr "" #: ../aboutdialog.cpp:73 msgctxt "AboutDialog|" msgid "" "You can also help us by sending bug reports or small code contributions, " "ideas or whatever you think may improve KLog." msgstr "" #: ../aboutdialog.cpp:74 ../aboutdialog.cpp:144 msgctxt "AboutDialog|" msgid "Authors" msgstr "" #: ../aboutdialog.cpp:86 msgctxt "AboutDialog|" msgid "" "Translators bring KLog into your language. They are really an important part " "of the KLog development team." msgstr "" #: ../aboutdialog.cpp:86 msgctxt "AboutDialog|" msgid "" "If KLog is still not in your language and you want to help us, you are " "welcome to contact us through the" msgstr "" #: ../aboutdialog.cpp:87 ../aboutdialog.cpp:145 msgctxt "AboutDialog|" msgid "Translators" msgstr "" #: ../aboutdialog.cpp:99 msgctxt "AboutDialog|" msgid "Privacy advisory" msgstr "" #: ../aboutdialog.cpp:100 msgctxt "AboutDialog|" msgid "" "KLog developers have included a feature that reports some user data to the " "KLog server with the sole purpose of identifying the number of installed " "versions, to focus development in one direction or another taking into " "account user's needs" msgstr "" #: ../aboutdialog.cpp:101 msgctxt "AboutDialog|" msgid "At present, the data that is provided is the following:" msgstr "" #: ../aboutdialog.cpp:102 msgctxt "AboutDialog|" msgid "Callsign" msgstr "" #: ../aboutdialog.cpp:102 msgctxt "AboutDialog|" msgid "KLog version" msgstr "" #: ../aboutdialog.cpp:102 msgctxt "AboutDialog|" msgid "Operating system" msgstr "" #: ../aboutdialog.cpp:103 msgctxt "AboutDialog|" msgid "" "Be aware that you can enable/disable this feature from the Misc tab in the " "Setup page" msgstr "" #: ../aboutdialog.cpp:143 msgctxt "AboutDialog|" msgid "KLog" msgstr "" #: ../aboutdialog.cpp:146 msgctxt "AboutDialog|" msgid "Privacy" msgstr "" #: ../startwizard.cpp:914 msgctxt "CTYPage|" msgid "Country data download" msgstr "" #: ../startwizard.cpp:917 msgctxt "CTYPage|" msgid "KLog needs country data..." msgstr "" #: ../startwizard.cpp:922 msgctxt "CTYPage|" msgid "&Download" msgstr "" #: ../startwizard.cpp:923 msgctxt "CTYPage|" msgid "&Ignore" msgstr "" #: ../startwizard.cpp:942 msgctxt "CTYPage|" msgid "Country data needed" msgstr "" #: ../startwizard.cpp:945 msgctxt "CTYPage|" msgid "" "KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC " "information." msgstr "" #: ../startwizard.cpp:947 msgctxt "CTYPage|" msgid "" "You need to download the cty.csv file if you want KLog to show you the " "countries, locator, ... of the QSOs you do." msgstr "" #: ../startwizard.cpp:949 msgctxt "CTYPage|" msgid "Click on Download to download now." msgstr "" #: ../startwizard.cpp:1025 msgctxt "CTYPage|" msgid "KLog" msgstr "" #: ../startwizard.cpp:1026 msgctxt "CTYPage|" msgid "" "I can't find the host. Please check your network and try again\n" "Do you want to try again?" msgstr "" #: ../dxccstatuswidget.cpp:54 msgctxt "DXCCStatusWidget|" msgid "Update" msgstr "" #: ../dxccstatuswidget.cpp:283 msgctxt "DXCCStatusWidget|" msgid "ID" msgstr "" #: ../dxccstatuswidget.cpp:283 msgctxt "DXCCStatusWidget|" msgid "Entity" msgstr "" #: ../dxcluster.cpp:70 ../dxcluster.cpp:527 msgctxt "DXClusterWidget|" msgid "Click on Connect to connect to the DX-Cluster server" msgstr "" #: ../dxcluster.cpp:74 ../dxcluster.cpp:525 msgctxt "DXClusterWidget|" msgid "Connect" msgstr "" #: ../dxcluster.cpp:75 ../dxcluster.cpp:504 ../dxcluster.cpp:583 #: ../dxcluster.cpp:588 msgctxt "DXClusterWidget|" msgid "Clear" msgstr "" #: ../dxcluster.cpp:150 msgctxt "DXClusterWidget|" msgid "Click on connect to connect to the DX-Cluster" msgstr "" #: ../dxcluster.cpp:209 msgctxt "DXClusterWidget|" msgid "Trying to connect to the server" msgstr "" #: ../dxcluster.cpp:220 ../dxcluster.cpp:226 ../dxcluster.cpp:233 msgctxt "DXClusterWidget|" msgid "KLog DXCluster" msgstr "" #: ../dxcluster.cpp:221 msgctxt "DXClusterWidget|" msgid "The host was not found. Please check:" msgstr "" #: ../dxcluster.cpp:222 msgctxt "DXClusterWidget|" msgid "" "- your network connection;\n" "- the host name and port settings." msgstr "" #: ../dxcluster.cpp:227 msgctxt "DXClusterWidget|" msgid "" "The connection was refused by the peer. Make sure the DXCluster server is " "running, and check that the host name and port settings are correct." msgstr "" #: ../dxcluster.cpp:234 #, qt-format msgctxt "DXClusterWidget|" msgid "The following error occurred: %1." msgstr "" #: ../dxcluster.cpp:477 msgctxt "DXClusterWidget|" msgid "Connected to server" msgstr "" #: ../dxcluster.cpp:490 ../dxcluster.cpp:494 ../dxcluster.cpp:498 msgctxt "DXClusterWidget|" msgid "KLog message" msgstr "" #: ../dxcluster.cpp:490 ../dxcluster.cpp:494 msgctxt "DXClusterWidget|" msgid "Enter your callsign to connect to the cluster:" msgstr "" #: ../dxcluster.cpp:498 msgctxt "DXClusterWidget|" msgid "" "Enter your password to connect to the cluster:\n" "(Just hit enter for no password)" msgstr "" #: ../dxcluster.cpp:503 ../dxcluster.cpp:582 msgctxt "DXClusterWidget|" msgid "Disconnect" msgstr "" #: ../dxcluster.cpp:507 msgctxt "DXClusterWidget|" msgid "Not logged on, you may need to enter your callsign again." msgstr "" #: ../dxcluster.cpp:511 msgctxt "DXClusterWidget|" msgid "Enter here the commands to be sent to the DX-Cluster server" msgstr "" #: ../dxcluster.cpp:521 msgctxt "DXClusterWidget|" msgid "Connection closed by the server" msgstr "" #: ../dxcluster.cpp:587 msgctxt "DXClusterWidget|" msgid "Send" msgstr "" #: ../dataproxy_sqlite.cpp:74 msgctxt "DataProxy_SQLite|" msgid "Software version in DB is null" msgstr "" #: ../dataproxy_sqlite.cpp:74 msgctxt "DataProxy_SQLite|" msgid "No query failed" msgstr "" #: ../dataproxy_sqlite.cpp:3957 msgctxt "DataProxy_SQLite|" msgid "KLog DXCC" msgstr "" #: ../dataproxy_sqlite.cpp:3958 msgctxt "DataProxy_SQLite|" msgid "All QSOs have been updated with a DXCC." msgstr "" #: ../downloadcty.cpp:64 msgctxt "DownLoadCTY|" msgid "Download of cty.csv failed with the following error code: " msgstr "" #: ../downloadcty.cpp:76 msgctxt "DownLoadCTY|" msgid "Download of cty.csv done." msgstr "" #: ../downloadcty.cpp:147 msgctxt "DownLoadCTY|" msgid "" "There is already a cty.csv file in the folder but it will be replaced with " "the new one." msgstr "" #: ../downloadcty.cpp:177 msgctxt "DownLoadCTY|" msgid "Could not open " msgstr "" #: ../downloadcty.cpp:177 msgctxt "DownLoadCTY|" msgid " for writing." msgstr "" #: ../filemanager.cpp:201 msgctxt "FileManager|" msgid "" "The log that you have selected contains more than just one station callsign." msgstr "" #: ../filemanager.cpp:201 msgctxt "FileManager|" msgid "Please select the station callsing you want to export the log from:" msgstr "" #: ../filemanager.cpp:204 msgctxt "FileManager|" msgid "Station Callsign:" msgstr "" #: ../filemanager.cpp:213 msgctxt "FileManager|" msgid "Define Station Callsign" msgstr "" #: ../filemanager.cpp:214 msgctxt "FileManager|" msgid "" "You have selected no callsign. KLog will export QSOs without a station " "callsign defined and those with the call you are entering here." msgstr "" #: ../filemanager.cpp:214 msgctxt "FileManager|" msgid "" "Enter the station callsign to use for this log or leave it empty for QSO " "without station callsign defined:" msgstr "" #: ../filemanager.cpp:226 msgctxt "FileManager|" msgid "" "No station callsign has been selected and therefore no log will be exported" msgstr "" #: ../filemanager.cpp:251 ../filemanager.cpp:571 msgctxt "FileManager|" msgid "Writing ADIF file..." msgstr "" #: ../filemanager.cpp:251 ../filemanager.cpp:571 ../filemanager.cpp:2778 msgctxt "FileManager|" msgid "Abort writing" msgstr "" #: ../filemanager.cpp:442 msgctxt "FileManager|" msgid "Exporting LoTW ADIF file..." msgstr "" #: ../filemanager.cpp:442 ../filemanager.cpp:3587 msgctxt "FileManager|" msgid " QSO: " msgstr "" #: ../filemanager.cpp:2621 msgctxt "FileManager|" msgid "" "Writing ADIF file...\n" " QSO: " msgstr "" #: ../filemanager.cpp:2629 msgctxt "FileManager|" msgid "" "You have canceled the file export. The file will be removed and no data will " "be exported." msgstr "" #: ../filemanager.cpp:2629 ../filemanager.cpp:3753 msgctxt "FileManager|" msgid "Do you still want to cancel?" msgstr "" #: ../filemanager.cpp:2778 msgctxt "FileManager|" msgid "Writing Cabrillo file..." msgstr "" #: ../filemanager.cpp:2962 msgctxt "FileManager|" msgid "KLog: Cabrillo Log Export not implemented" msgstr "" #: ../filemanager.cpp:2963 msgctxt "FileManager|" msgid "" "I am sorry but the Cabrillo Export To File feature has still not been " "implemented." msgstr "" #: ../filemanager.cpp:3095 msgctxt "FileManager|" msgid "Reading LoTW file..." msgstr "" #: ../filemanager.cpp:3095 ../filemanager.cpp:3381 msgctxt "FileManager|" msgid "Abort reading" msgstr "" #: ../filemanager.cpp:3334 msgctxt "FileManager|" msgid "There is more than one log in this logfile." msgstr "" #: ../filemanager.cpp:3334 msgctxt "FileManager|" msgid "All logs will be imported into the current log." msgstr "" #: ../filemanager.cpp:3334 msgctxt "FileManager|" msgid "Do you want to continue?" msgstr "" #: ../filemanager.cpp:3587 msgctxt "FileManager|" msgid "Importing ADIF file..." msgstr "" #: ../filemanager.cpp:3753 msgctxt "FileManager|" msgid "" "You have cancelled the file import. The file will be removed and no data " "will be imported." msgstr "" #: ../filemanager.cpp:3614 msgctxt "FileManager|" msgid "" "It seems that there are some duplicated QSOs in the ADIF file you are " "importing. Do you want to continue? (Duped QSOs will not be imported)" msgstr "" #: ../filemanager.cpp:3381 msgctxt "FileManager|" msgid "Reading ADIF file..." msgstr "" #: ../filemanager.cpp:4759 msgctxt "FileManager|" msgid "This QSO is not including the minimum data to consider a QSO as valid!." msgstr "" #: ../filemanager.cpp:4759 msgctxt "FileManager|" msgid "Please edit the ADIF file and make sure that it include at least:" msgstr "" #: ../filemanager.cpp:4759 msgctxt "FileManager|" msgid "and" msgstr "" #: ../filemanager.cpp:4759 msgctxt "FileManager|" msgid "This QSO had:" msgstr "" #: ../filemanager.cpp:4763 msgctxt "FileManager|" msgid " - The band missing and the following call: " msgstr "" #: ../filemanager.cpp:4768 msgctxt "FileManager|" msgid " - The call missing but was done at this time: " msgstr "" #: ../filemanager.cpp:4773 msgctxt "FileManager|" msgid " - The mode missing and the following call: " msgstr "" #: ../filemanager.cpp:4778 msgctxt "FileManager|" msgid " - The date missing and the following call: " msgstr "" #: ../filemanager.cpp:4783 msgctxt "FileManager|" msgid " - The time missing and the following call: " msgstr "" #: ../filemanager.cpp:4788 msgctxt "FileManager|" msgid "Do you want to continue with the current file?" msgstr "" #: ../filemanager.cpp:4792 msgctxt "FileManager|" msgid "KLog: Not all required data found!" msgstr "" #: ../filemanager.cpp:4816 msgctxt "FileManager|" msgid "This log seems to lack of RST-TX information." msgstr "" #: ../filemanager.cpp:4816 ../filemanager.cpp:4838 msgctxt "FileManager|" msgid "Click on Yes to add a default 59 to all QSO with a similar problem." msgstr "" #: ../filemanager.cpp:4816 ../filemanager.cpp:4838 msgctxt "FileManager|" msgid "If you select NO, the QSO may not be imported." msgstr "" #: ../filemanager.cpp:4817 msgctxt "FileManager|" msgid "KLog: No RST TX found!" msgstr "" #: ../filemanager.cpp:4838 msgctxt "FileManager|" msgid "This log seems to lack of RST-RX information." msgstr "" #: ../filemanager.cpp:4840 msgctxt "FileManager|" msgid "KLog: No RST RX found!" msgstr "" #: ../infowidget.cpp:48 msgctxt "InfoWidget|" msgid "10M" msgstr "" #: ../infowidget.cpp:49 msgctxt "InfoWidget|" msgid "15M" msgstr "" #: ../infowidget.cpp:50 msgctxt "InfoWidget|" msgid "20M" msgstr "" #: ../infowidget.cpp:51 msgctxt "InfoWidget|" msgid "40M" msgstr "" #: ../infowidget.cpp:52 msgctxt "InfoWidget|" msgid "80M" msgstr "" #: ../infowidget.cpp:53 msgctxt "InfoWidget|" msgid "160M" msgstr "" #: ../infowidget.cpp:54 msgctxt "InfoWidget|" msgid "2M" msgstr "" #: ../infowidget.cpp:55 msgctxt "InfoWidget|" msgid "6M" msgstr "" #: ../infowidget.cpp:56 msgctxt "InfoWidget|" msgid "12M" msgstr "" #: ../infowidget.cpp:57 msgctxt "InfoWidget|" msgid "17M" msgstr "" #: ../infowidget.cpp:58 msgctxt "InfoWidget|" msgid "30M" msgstr "" #: ../infowidget.cpp:59 msgctxt "InfoWidget|" msgid "70CM" msgstr "" #: ../infowidget.cpp:74 msgctxt "InfoWidget|" msgid "Continent" msgstr "" #: ../infowidget.cpp:78 msgctxt "InfoWidget|" msgid "Prefix" msgstr "" #: ../infowidget.cpp:82 msgctxt "InfoWidget|" msgid "CQ" msgstr "" #: ../infowidget.cpp:86 msgctxt "InfoWidget|" msgid "ITU" msgstr "" #: ../infowidget.cpp:90 msgctxt "InfoWidget|" msgid "Short Path" msgstr "" #: ../infowidget.cpp:93 msgctxt "InfoWidget|" msgid "Long Path" msgstr "" #: ../infowidget.cpp:96 ../infowidget.cpp:101 msgctxt "InfoWidget|" msgid "Degree" msgstr "" #: ../infowidget.cpp:314 ../infowidget.cpp:315 msgctxt "InfoWidget|" msgid "Miles" msgstr "" #: ../infowidget.cpp:321 ../infowidget.cpp:322 msgctxt "InfoWidget|" msgid "Km" msgstr "" #: ../startwizard.cpp:141 msgctxt "IntroPage|" msgid "Welcome to KLog!" msgstr "" #: ../startwizard.cpp:143 msgctxt "IntroPage|" msgid "Welcome to KLog! - brought to you under the terms of the GPL!" msgstr "" #: ../startwizard.cpp:151 msgctxt "IntroPage|" msgid "Welcome to KLog" msgstr "" #: ../startwizard.cpp:152 msgctxt "IntroPage|" msgid "This looks like it's the first time you've run KLog on this computer." msgstr "" #: ../startwizard.cpp:153 msgctxt "IntroPage|" msgid "" "KLog is a free hamradio logging program that can run on Linux macOS and " "Windows." msgstr "" #: ../startwizard.cpp:154 msgctxt "IntroPage|" msgid "It is designed to provide general purpose, DX and contest logging." msgstr "" #: ../startwizard.cpp:155 msgctxt "IntroPage|" msgid "It supports QSL management, import and export of ADIF " msgstr "" #: ../startwizard.cpp:156 msgctxt "IntroPage|" msgid "and Cabrillo file formats and many other features..." msgstr "" #: ../startwizard.cpp:157 msgctxt "IntroPage|" msgid "Before you can start using KLog, you will be asked to:" msgstr "" #: ../startwizard.cpp:158 msgctxt "IntroPage|" msgid "Acknowledge to the terms of the license." msgstr "" #: ../startwizard.cpp:159 msgctxt "IntroPage|" msgid "Download the DX entities information." msgstr "" #: ../startwizard.cpp:160 msgctxt "IntroPage|" msgid "Enter your callsign, CQ zone, etc. and main configuration." msgstr "" #: ../startwizard.cpp:161 msgctxt "IntroPage|" msgid "" "Enjoy KLog and contact the development team if you have any suggestions!" msgstr "" #: ../startwizard.cpp:182 msgctxt "LicPage|" msgid "KLog License information" msgstr "" #: ../startwizard.cpp:185 msgctxt "LicPage|" msgid "Welcome to KLog!- brought to you under the terms of the GPL!" msgstr "" #: ../startwizard.cpp:826 msgctxt "LicPage|" msgid "Acknowledge" msgstr "" #: ../startwizard.cpp:827 msgctxt "LicPage|" msgid "Be aware that KLog is free software." msgstr "" #: ../logmodel.cpp:105 msgctxt "LogModel|" msgid "Date" msgstr "" #: ../logmodel.cpp:108 msgctxt "LogModel|" msgid "Time" msgstr "" #: ../logmodel.cpp:111 msgctxt "LogModel|" msgid "QRZ" msgstr "" #: ../logmodel.cpp:114 msgctxt "LogModel|" msgid "Band" msgstr "" #: ../logmodel.cpp:117 msgctxt "LogModel|" msgid "Mode" msgstr "" #: ../logmodel.cpp:120 msgctxt "LogModel|" msgid "RSTtx" msgstr "" #: ../logmodel.cpp:123 msgctxt "LogModel|" msgid "RSTrx" msgstr "" #: ../logmodel.cpp:126 msgctxt "LogModel|" msgid "Comment" msgstr "" #: ../logwindow.cpp:211 msgctxt "LogWindow|" msgid "QSL Send" msgstr "" #: ../logwindow.cpp:223 msgctxt "LogWindow|" msgid "QSL Rcvd" msgstr "" #: ../logwindow.cpp:280 msgctxt "LogWindow|" msgid "&Delete" msgstr "" #: ../logwindow.cpp:282 msgctxt "LogWindow|" msgid "Delete a QSO" msgstr "" #: ../logwindow.cpp:285 msgctxt "LogWindow|" msgid "&Edit QSO" msgstr "" #: ../logwindow.cpp:287 msgctxt "LogWindow|" msgid "Edit this QSO" msgstr "" #: ../logwindow.cpp:290 msgctxt "LogWindow|" msgid "Via &bureau" msgstr "" #: ../logwindow.cpp:292 msgctxt "LogWindow|" msgid "Send this QSL via bureau" msgstr "" #: ../logwindow.cpp:295 msgctxt "LogWindow|" msgid "D&irect" msgstr "" #: ../logwindow.cpp:297 msgctxt "LogWindow|" msgid "Send this QSL via direct" msgstr "" #: ../logwindow.cpp:300 msgctxt "LogWindow|" msgid "Via bureau" msgstr "" #: ../logwindow.cpp:302 msgctxt "LogWindow|" msgid "QSL &received via bureau" msgstr "" #: ../logwindow.cpp:305 msgctxt "LogWindow|" msgid "Direct" msgstr "" #: ../logwindow.cpp:307 msgctxt "LogWindow|" msgid "QSL received via direc&t" msgstr "" #: ../logwindow.cpp:388 msgctxt "LogWindow|" msgid "You have requested to delete this QSO." msgstr "" #: ../logwindow.cpp:389 msgctxt "LogWindow|" msgid "Are you sure?" msgstr "" #: ../mainwindow.cpp:194 msgctxt "MainWindow|" msgid "Recalculate" msgstr "" #: ../mainwindow.cpp:195 msgctxt "MainWindow|" msgid "Click to recalculate the award status" msgstr "" #: ../mainwindow.cpp:224 msgctxt "MainWindow|" msgid "Starting KLog" msgstr "" #: ../mainwindow.cpp:315 ../mainwindow.cpp:915 ../mainwindow.cpp:3085 msgctxt "MainWindow|" msgid "&Add" msgstr "" #: ../mainwindow.cpp:318 msgctxt "MainWindow|" msgid "&Clear" msgstr "" #: ../mainwindow.cpp:321 msgctxt "MainWindow|" msgid "Status bar..." msgstr "" #: ../mainwindow.cpp:322 msgctxt "MainWindow|" msgid "DX Entity" msgstr "" #: ../mainwindow.cpp:325 msgctxt "MainWindow|" msgid "&Log Window" msgstr "" #: ../mainwindow.cpp:326 msgctxt "MainWindow|" msgid "&Score Window" msgstr "" #: ../mainwindow.cpp:340 msgctxt "MainWindow|" msgid "Watts" msgstr "" #: ../mainwindow.cpp:345 ../mainwindow.cpp:350 msgctxt "MainWindow|" msgid "MHz" msgstr "" #: ../mainwindow.cpp:434 ../mainwindow.cpp:3278 ../mainwindow.cpp:3987 msgctxt "MainWindow|" msgid "KLog" msgstr "" #: ../mainwindow.cpp:643 msgctxt "MainWindow|" msgid "Ready" msgstr "" #: ../mainwindow.cpp:804 msgctxt "MainWindow|" msgid "" "An unexpected error ocurred when trying to add the QSO to your log. If the " "problem persists, please contact the developer for analysis: " msgstr "" #: ../mainwindow.cpp:1008 ../mainwindow.cpp:1723 msgctxt "MainWindow|" msgid "You have selected an entity:" msgstr "" #: ../mainwindow.cpp:1008 ../mainwindow.cpp:1723 msgctxt "MainWindow|" msgid "that is different from the KLog proposed entity:" msgstr "" #: ../mainwindow.cpp:1009 msgctxt "MainWindow|" msgid "" "Click on the prefix of the correct entity or Cancel to edit the QSO again." msgstr "" #: ../mainwindow.cpp:1724 msgctxt "MainWindow|" msgid "Click on the prefix of the right entity or Cancel to correct." msgstr "" #: ../mainwindow.cpp:2383 msgctxt "MainWindow|" msgid "QRZ of the QSO" msgstr "" #: ../mainwindow.cpp:2384 msgctxt "MainWindow|" msgid "TX RST" msgstr "" #: ../mainwindow.cpp:2385 msgctxt "MainWindow|" msgid "RX RST" msgstr "" #: ../mainwindow.cpp:2386 msgctxt "MainWindow|" msgid "TX Exchange" msgstr "" #: ../mainwindow.cpp:2387 msgctxt "MainWindow|" msgid "RX Exchange" msgstr "" #: ../mainwindow.cpp:2388 msgctxt "MainWindow|" msgid "Band of the QSO" msgstr "" #: ../mainwindow.cpp:2389 msgctxt "MainWindow|" msgid "Mode of the QSO" msgstr "" #: ../mainwindow.cpp:2390 msgctxt "MainWindow|" msgid "Date of the QSO" msgstr "" #: ../mainwindow.cpp:2391 msgctxt "MainWindow|" msgid "Time of the QSO" msgstr "" #: ../mainwindow.cpp:2394 msgctxt "MainWindow|" msgid "Add the QSO to the log" msgstr "" #: ../mainwindow.cpp:2396 msgctxt "MainWindow|" msgid "Clear the box" msgstr "" #: ../mainwindow.cpp:2398 msgctxt "MainWindow|" msgid "Input" msgstr "" #: ../mainwindow.cpp:2411 ../mainwindow.cpp:6900 msgctxt "MainWindow|" msgid "RSTrx" msgstr "" #: ../mainwindow.cpp:2418 ../mainwindow.cpp:6898 msgctxt "MainWindow|" msgid "RSTtx" msgstr "" #: ../mainwindow.cpp:2427 ../mainwindow.cpp:3154 ../mainwindow.cpp:3160 #: ../mainwindow.cpp:4567 ../mainwindow.cpp:5590 ../mainwindow.cpp:6896 msgctxt "MainWindow|" msgid "QRZ" msgstr "" #: ../mainwindow.cpp:2434 msgctxt "MainWindow|" msgid "STX" msgstr "" #: ../mainwindow.cpp:2441 msgctxt "MainWindow|" msgid "SRX" msgstr "" #: ../mainwindow.cpp:2733 msgctxt "MainWindow|" msgid "NEW MULT" msgstr "" #: ../mainwindow.cpp:2830 msgctxt "MainWindow|" msgid "Invalid characters used in the QRZ" msgstr "" #: ../mainwindow.cpp:2972 msgctxt "MainWindow|" msgid "Ready..." msgstr "" #: ../mainwindow.cpp:3279 msgctxt "MainWindow|" msgid "" "The logfile has been modified.\n" "Do you want to save your changes?" msgstr "" #: ../mainwindow.cpp:3306 msgctxt "MainWindow|" msgid "&File" msgstr "" #: ../mainwindow.cpp:3308 msgctxt "MainWindow|" msgid "&New..." msgstr "" #: ../mainwindow.cpp:3313 msgctxt "MainWindow|" msgid "&Open..." msgstr "" #: ../mainwindow.cpp:3318 msgctxt "MainWindow|" msgid "&Import from ADIF..." msgstr "" #: ../mainwindow.cpp:3321 msgctxt "MainWindow|" msgid "Import an ADIF file into the current log." msgstr "" #: ../mainwindow.cpp:3330 msgctxt "MainWindow|" msgid "&Save As..." msgstr "" #: ../mainwindow.cpp:3341 msgctxt "MainWindow|" msgid "Export the current log to an ADIF logfile." msgstr "" #: ../mainwindow.cpp:3347 msgctxt "MainWindow|" msgid "Export ALL the QSOs into one ADIF file, merging QSOs from all the logs." msgstr "" #: ../mainwindow.cpp:3352 msgctxt "MainWindow|" msgid "" "Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a " "QSL tag printing program)." msgstr "" #: ../mainwindow.cpp:3337 msgctxt "MainWindow|" msgid "Export to ADIF..." msgstr "" #: ../mainwindow.cpp:3343 msgctxt "MainWindow|" msgid "Export all logs to ADIF..." msgstr "" #: ../mainwindow.cpp:3349 msgctxt "MainWindow|" msgid "Export Requested QSL to ADIF..." msgstr "" #: ../mainwindow.cpp:3354 msgctxt "MainWindow|" msgid "Export ADIF for LoTW..." msgstr "" #: ../mainwindow.cpp:3357 msgctxt "MainWindow|" msgid "" "Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before " "uploading to LoTW!" msgstr "" #: ../mainwindow.cpp:3361 msgctxt "MainWindow|" msgid "&Print Log..." msgstr "" #: ../mainwindow.cpp:3364 msgctxt "MainWindow|" msgid "Print your log." msgstr "" #: ../mainwindow.cpp:3369 msgctxt "MainWindow|" msgid "KLog folder" msgstr "" #: ../mainwindow.cpp:3371 msgctxt "MainWindow|" msgid "Opens the data folder of KLog." msgstr "" #: ../mainwindow.cpp:3376 msgctxt "MainWindow|" msgid "E&xit" msgstr "" #: ../mainwindow.cpp:3382 msgctxt "MainWindow|" msgid "&Tools" msgstr "" #: ../mainwindow.cpp:3384 msgctxt "MainWindow|" msgid "Fill in QSO data" msgstr "" #: ../mainwindow.cpp:3388 msgctxt "MainWindow|" msgid "" "Go through the log reusing previous QSOs to fill missing information in " "other QSOs." msgstr "" #: ../mainwindow.cpp:3390 msgctxt "MainWindow|" msgid "Fill in DXCC data" msgstr "" #: ../mainwindow.cpp:3393 msgctxt "MainWindow|" msgid "Go through the log filling QSOs without a DXCC defined." msgstr "" #: ../mainwindow.cpp:3399 msgctxt "MainWindow|" msgid "QSL tools..." msgstr "" #: ../mainwindow.cpp:3406 msgctxt "MainWindow|" msgid "&Find QSO to QSL" msgstr "" #: ../mainwindow.cpp:3409 msgctxt "MainWindow|" msgid "Shows QSOs for which you should send your QSL and request the DX QSL." msgstr "" #: ../mainwindow.cpp:3411 msgctxt "MainWindow|" msgid "Find My-QSLs pending to send" msgstr "" #: ../mainwindow.cpp:3415 msgctxt "MainWindow|" msgid "" "Shows the QSOs with pending requests to send QSLs. You should keep this " "queue empty!" msgstr "" #: ../mainwindow.cpp:3417 msgctxt "MainWindow|" msgid "&Find DX-QSLs pending to receive" msgstr "" #: ../mainwindow.cpp:3420 msgctxt "MainWindow|" msgid "" "Shows the DX-QSL that has been requested or QSLs has been sent with no " "answer." msgstr "" #: ../mainwindow.cpp:3422 msgctxt "MainWindow|" msgid "&Find requested pending to receive" msgstr "" #: ../mainwindow.cpp:3425 msgctxt "MainWindow|" msgid "Shows the DX-QSL that has been requested." msgstr "" #: ../mainwindow.cpp:3428 msgctxt "MainWindow|" msgid "LoTW tools..." msgstr "" #: ../mainwindow.cpp:3430 msgctxt "MainWindow|" msgid "Queue all QSL to be sent of this log" msgstr "" #: ../mainwindow.cpp:3433 msgctxt "MainWindow|" msgid "Mark all non sent QSOs in this log as queued to be uploaded." msgstr "" #: ../mainwindow.cpp:3435 msgctxt "MainWindow|" msgid "Queue all QSL to be sent" msgstr "" #: ../mainwindow.cpp:3438 msgctxt "MainWindow|" msgid "Mark all non sent QSOs as queued to be uploaded." msgstr "" #: ../mainwindow.cpp:3442 msgctxt "MainWindow|" msgid "Mark as sent all queued QSO of this log" msgstr "" #: ../mainwindow.cpp:3445 msgctxt "MainWindow|" msgid "Mark all queued QSOs in this log as sent to LoTW." msgstr "" #: ../mainwindow.cpp:3447 msgctxt "MainWindow|" msgid "Mark all queued QSO as sent" msgstr "" #: ../mainwindow.cpp:3450 msgctxt "MainWindow|" msgid "Mark all queued QSOs as sent to LoTW." msgstr "" #: ../mainwindow.cpp:3455 msgctxt "MainWindow|" msgid "&Update cty.csv" msgstr "" #: ../mainwindow.cpp:3459 msgctxt "MainWindow|" msgid "For updated DX-Entity data, update cty.csv." msgstr "" #: ../mainwindow.cpp:3464 msgctxt "MainWindow|" msgid "&Setup" msgstr "" #: ../mainwindow.cpp:3466 msgctxt "MainWindow|" msgid "&Setup..." msgstr "" #: ../mainwindow.cpp:3472 msgctxt "MainWindow|" msgid "&Help" msgstr "" #: ../mainwindow.cpp:3474 msgctxt "MainWindow|" msgid "Check updates..." msgstr "" #: ../mainwindow.cpp:3479 msgctxt "MainWindow|" msgid "&About..." msgstr "" #: ../mainwindow.cpp:3484 msgctxt "MainWindow|" msgid "About Qt..." msgstr "" #: ../mainwindow.cpp:3522 ../mainwindow.cpp:3531 ../mainwindow.cpp:3545 #: ../mainwindow.cpp:3553 ../mainwindow.cpp:3627 ../mainwindow.cpp:3635 #: ../mainwindow.cpp:3653 ../mainwindow.cpp:3661 msgctxt "MainWindow|" msgid "KLog LoTW" msgstr "" #: ../mainwindow.cpp:3523 msgctxt "MainWindow|" msgid "All pending QSO of this log has been marked as queued for LoTW!" msgstr "" #: ../mainwindow.cpp:3523 ../mainwindow.cpp:3546 msgctxt "MainWindow|" msgid "" "Now you can go to the File menu to export the LoTW ADIF file and upload it " "to LoTW." msgstr "" #: ../mainwindow.cpp:3532 ../mainwindow.cpp:3554 msgctxt "MainWindow|" msgid "" "There was a problem to mark all pending QSO of this log as queued for LoTW!" msgstr "" #: ../mainwindow.cpp:3546 msgctxt "MainWindow|" msgid "All pending QSO has been marked as queued for LoTW!" msgstr "" #: ../mainwindow.cpp:3573 msgctxt "MainWindow|" msgid "" "The log that you have selected contains more than just one station callsign." msgstr "" #: ../mainwindow.cpp:3573 msgctxt "MainWindow|" msgid "Please select the station callsing you want to mark as sent to LoTW:" msgstr "" #: ../mainwindow.cpp:3576 msgctxt "MainWindow|" msgid "Station Callsign:" msgstr "" #: ../mainwindow.cpp:3585 msgctxt "MainWindow|" msgid "Define Station Callsign" msgstr "" #: ../mainwindow.cpp:3586 msgctxt "MainWindow|" msgid "" "You have selected no callsign. KLog will mark QSOs without a station " "callsign defined and those with the call you are entering here." msgstr "" #: ../mainwindow.cpp:3586 msgctxt "MainWindow|" msgid "" "Enter the station callsign to use for this log or leave it empty for QSO " "without station callsign defined:" msgstr "" #: ../mainwindow.cpp:3599 msgctxt "MainWindow|" msgid "" "No station callsign has been selected and therefore no log will be marked" msgstr "" #: ../mainwindow.cpp:3628 msgctxt "MainWindow|" msgid "All queued QSO of this log has been marked as sent for LoTW!" msgstr "" #: ../mainwindow.cpp:3636 msgctxt "MainWindow|" msgid "" "There was a problem to mark all queued QSO of this log as sent for LoTW!" msgstr "" #: ../mainwindow.cpp:3654 msgctxt "MainWindow|" msgid "All queued QSO has been marked as sent to LoTW!" msgstr "" #: ../mainwindow.cpp:3662 msgctxt "MainWindow|" msgid "There was a problem to mark all queued QSO of this log as sent to LoTW!" msgstr "" #: ../mainwindow.cpp:3671 msgctxt "MainWindow|" msgid "About..." msgstr "" #: ../mainwindow.cpp:3727 msgctxt "MainWindow|" msgid "KLog update checking result" msgstr "" #: ../mainwindow.cpp:3728 msgctxt "MainWindow|" msgid "Congratulations!" msgstr "" #: ../mainwindow.cpp:3728 msgctxt "MainWindow|" msgid "You already have the latest version." msgstr "" #: ../mainwindow.cpp:3873 ../mainwindow.cpp:3923 msgctxt "MainWindow|" msgid "Nothing has been saved. You have to select a valid file type." msgstr "" #: ../mainwindow.cpp:3901 msgctxt "MainWindow|" msgid "Save File" msgstr "" #: ../mainwindow.cpp:3903 msgctxt "MainWindow|" msgid "ADIF file" msgstr "" #: ../mainwindow.cpp:3903 msgctxt "MainWindow|" msgid "Cabrillo files" msgstr "" #: ../mainwindow.cpp:3903 msgctxt "MainWindow|" msgid "Any file" msgstr "" #: ../mainwindow.cpp:3980 msgctxt "MainWindow|" msgid "You can find the KLog data folder here: " msgstr "" #: ../mainwindow.cpp:4563 msgctxt "MainWindow|" msgid "DUPE" msgstr "" #: ../mainwindow.cpp:4907 msgctxt "MainWindow|" msgid "The selected log is not existing or it is still empty." msgstr "" #: ../mainwindow.cpp:4907 msgctxt "MainWindow|" msgid "Click Yes and KLog will open an empty log." msgstr "" #: ../mainwindow.cpp:4908 msgctxt "MainWindow|" msgid "Click No and KLog will select another log with data." msgstr "" #: ../mainwindow.cpp:4909 msgctxt "MainWindow|" msgid "You can modify the config file accordingly, if needed." msgstr "" #: ../mainwindow.cpp:4945 msgctxt "MainWindow|" msgid "It seems that there are no QSO in the database." msgstr "" #: ../mainwindow.cpp:4945 msgctxt "MainWindow|" msgid "" "If you are sure that the database contains QSOs and KLog is not able to find " "them, please contact the developers (see About KLog) for help." msgstr "" #: ../mainwindow.cpp:5233 msgctxt "MainWindow|" msgid "TX Frequency in MHz." msgstr "" #: ../mainwindow.cpp:5234 msgctxt "MainWindow|" msgid "RX Frequency in MHz." msgstr "" #: ../mainwindow.cpp:5236 msgctxt "MainWindow|" msgid "Power used by the DX." msgstr "" #: ../mainwindow.cpp:5237 msgctxt "MainWindow|" msgid "Logging operator's callsign." msgstr "" #: ../mainwindow.cpp:5238 msgctxt "MainWindow|" msgid "Callsign used over the air." msgstr "" #: ../mainwindow.cpp:5239 msgctxt "MainWindow|" msgid "My QTH locator." msgstr "" #: ../mainwindow.cpp:5240 msgctxt "MainWindow|" msgid "Name of the DX." msgstr "" #: ../mainwindow.cpp:5241 msgctxt "MainWindow|" msgid "QTH of the DX." msgstr "" #: ../mainwindow.cpp:5242 msgctxt "MainWindow|" msgid "Locator of the DX." msgstr "" #: ../mainwindow.cpp:5244 msgctxt "MainWindow|" msgid "QRZ of the QSO." msgstr "" #: ../mainwindow.cpp:5245 msgctxt "MainWindow|" msgid "TX RST." msgstr "" #: ../mainwindow.cpp:5246 msgctxt "MainWindow|" msgid "RX RST." msgstr "" #: ../mainwindow.cpp:5247 msgctxt "MainWindow|" msgid "TX Exchange." msgstr "" #: ../mainwindow.cpp:5248 msgctxt "MainWindow|" msgid "RX Exchange." msgstr "" #: ../mainwindow.cpp:5249 msgctxt "MainWindow|" msgid "Band of the QSO." msgstr "" #: ../mainwindow.cpp:5250 msgctxt "MainWindow|" msgid "Mode of the QSO." msgstr "" #: ../mainwindow.cpp:5251 msgctxt "MainWindow|" msgid "Date of the QSO." msgstr "" #: ../mainwindow.cpp:5252 msgctxt "MainWindow|" msgid "Time of the QSO." msgstr "" #: ../mainwindow.cpp:5255 msgctxt "MainWindow|" msgid "Add the QSO to the log." msgstr "" #: ../mainwindow.cpp:5257 msgctxt "MainWindow|" msgid "Clears the QSO entry." msgstr "" #: ../mainwindow.cpp:5282 msgctxt "MainWindow|" msgid "Number of confirmed DXCC entities." msgstr "" #: ../mainwindow.cpp:5283 msgctxt "MainWindow|" msgid "Number of worked DXCC entities." msgstr "" #: ../mainwindow.cpp:5284 msgctxt "MainWindow|" msgid "Number of confirmed WAZ zones." msgstr "" #: ../mainwindow.cpp:5285 msgctxt "MainWindow|" msgid "Number of worked WAZ zones." msgstr "" #: ../mainwindow.cpp:5286 msgctxt "MainWindow|" msgid "Number of confirmed local references." msgstr "" #: ../mainwindow.cpp:5287 msgctxt "MainWindow|" msgid "Number of worked local references." msgstr "" #: ../mainwindow.cpp:5288 msgctxt "MainWindow|" msgid "Number of confirmed QSOs." msgstr "" #: ../mainwindow.cpp:5289 msgctxt "MainWindow|" msgid "Number of worked QSOs." msgstr "" #: ../mainwindow.cpp:5290 msgctxt "MainWindow|" msgid "Number of QSOs worked on the selected year." msgstr "" #: ../mainwindow.cpp:5291 msgctxt "MainWindow|" msgid "Number of DXCC worked on the selected year." msgstr "" #: ../mainwindow.cpp:5292 msgctxt "MainWindow|" msgid "Number of CQ Zones worked on the selected year." msgstr "" #: ../mainwindow.cpp:5293 msgctxt "MainWindow|" msgid "Score for the DXMarathon on the selected year." msgstr "" #: ../mainwindow.cpp:5294 msgctxt "MainWindow|" msgid "Select the year you want to check." msgstr "" #: ../mainwindow.cpp:5296 msgctxt "MainWindow|" msgid "Status of the DX entity." msgstr "" #: ../mainwindow.cpp:5297 msgctxt "MainWindow|" msgid "Name of the DX entity." msgstr "" #: ../mainwindow.cpp:5322 msgctxt "MainWindow|" msgid "Name" msgstr "" #: ../mainwindow.cpp:5326 msgctxt "MainWindow|" msgid "QTH" msgstr "" #: ../mainwindow.cpp:5329 msgctxt "MainWindow|" msgid "Locator" msgstr "" #: ../mainwindow.cpp:5332 msgctxt "MainWindow|" msgid "Power(rx)" msgstr "" #: ../mainwindow.cpp:5336 msgctxt "MainWindow|" msgid "RST(tx)" msgstr "" #: ../mainwindow.cpp:5339 msgctxt "MainWindow|" msgid "RST(rx)" msgstr "" #: ../mainwindow.cpp:5372 msgctxt "MainWindow|" msgid "Freq TX" msgstr "" #: ../mainwindow.cpp:5374 msgctxt "MainWindow|" msgid "Freq RX" msgstr "" #: ../mainwindow.cpp:5448 msgctxt "MainWindow|" msgid "QSO" msgstr "" #: ../mainwindow.cpp:5565 msgctxt "MainWindow|" msgid "QSL" msgstr "" #: ../mainwindow.cpp:5566 msgctxt "MainWindow|" msgid "eQSL" msgstr "" #: ../mainwindow.cpp:5567 ../mainwindow.cpp:6906 msgctxt "MainWindow|" msgid "Comment" msgstr "" #: ../mainwindow.cpp:5570 msgctxt "MainWindow|" msgid "Others" msgstr "" #: ../mainwindow.cpp:5572 msgctxt "MainWindow|" msgid "My Data" msgstr "" #: ../mainwindow.cpp:5573 msgctxt "MainWindow|" msgid "Satellite" msgstr "" #: ../mainwindow.cpp:5627 ../mainwindow.cpp:5663 msgctxt "MainWindow|" msgid "QSOs" msgstr "" #: ../mainwindow.cpp:5628 ../mainwindow.cpp:5654 ../mainwindow.cpp:5710 msgctxt "MainWindow|" msgid "DXCC" msgstr "" #: ../mainwindow.cpp:5629 msgctxt "MainWindow|" msgid "CQ" msgstr "" #: ../mainwindow.cpp:5630 msgctxt "MainWindow|" msgid "Score" msgstr "" #: ../mainwindow.cpp:5631 msgctxt "MainWindow|" msgid "DX-Marathon" msgstr "" #: ../mainwindow.cpp:5640 msgctxt "MainWindow|" msgid "Info" msgstr "" #: ../mainwindow.cpp:5645 msgctxt "MainWindow|" msgid "Award" msgstr "" #: ../mainwindow.cpp:5648 msgctxt "MainWindow|" msgid "Confirmed" msgstr "" #: ../mainwindow.cpp:5651 msgctxt "MainWindow|" msgid "Worked" msgstr "" #: ../mainwindow.cpp:5657 msgctxt "MainWindow|" msgid "WAZ" msgstr "" #: ../mainwindow.cpp:5660 msgctxt "MainWindow|" msgid "Local" msgstr "" #: ../mainwindow.cpp:5704 msgctxt "MainWindow|" msgid "Awards" msgstr "" #: ../mainwindow.cpp:5705 msgctxt "MainWindow|" msgid "Search" msgstr "" #: ../mainwindow.cpp:5707 msgctxt "MainWindow|" msgid "Log" msgstr "" #: ../mainwindow.cpp:5709 msgctxt "MainWindow|" msgid "DX-Cluster" msgstr "" #: ../mainwindow.cpp:5805 ../mainwindow.cpp:5816 ../mainwindow.cpp:5890 #: ../mainwindow.cpp:5900 msgctxt "MainWindow|" msgid "Save ADIF File" msgstr "" #: ../mainwindow.cpp:5826 msgctxt "MainWindow|" msgid "LoTW logfile has been properly exported!" msgstr "" #: ../mainwindow.cpp:5826 msgctxt "MainWindow|" msgid "Remember to:" msgstr "" #: ../mainwindow.cpp:5826 msgctxt "MainWindow|" msgid "Before uploading: sign the LoTW log; and" msgstr "" #: ../mainwindow.cpp:5826 msgctxt "MainWindow|" msgid "After uploading: mark as sent all the queued QSO (LoTW Tools)." msgstr "" #: ../mainwindow.cpp:5847 msgctxt "MainWindow|" msgid "There was no QSO to be exported." msgstr "" #: ../mainwindow.cpp:5847 msgctxt "MainWindow|" msgid "" "If you think that some QSO should have been exported, please look for them " "and ensure that the eQSL LoTW QSL sent box is marked as:" msgstr "" #: ../mainwindow.cpp:5847 msgctxt "MainWindow|" msgid "Q - Queued" msgstr "" #: ../mainwindow.cpp:5868 msgctxt "MainWindow|" msgid "" "There was an error while exporting the LoTW. The log has not been exported!" msgstr "" #: ../mainwindow.cpp:5914 msgctxt "MainWindow|" msgid "Save Cabrillo File" msgstr "" #: ../mainwindow.cpp:5916 msgctxt "MainWindow|" msgid "Cabrillo (*.log)" msgstr "" #: ../mainwindow.cpp:5925 ../mainwindow.cpp:5949 msgctxt "MainWindow|" msgid "Open File" msgstr "" #: ../mainwindow.cpp:6045 msgctxt "MainWindow|" msgid "&Modify" msgstr "" #: ../mainwindow.cpp:6580 msgctxt "MainWindow|" msgid "--" msgstr "" #: ../mainwindow.cpp:6605 msgctxt "MainWindow|" msgid " - Needed for DXMarathon" msgstr "" #: ../mainwindow.cpp:6712 msgctxt "MainWindow|" msgid "Filling QSOs..." msgstr "" #: ../mainwindow.cpp:6712 msgctxt "MainWindow|" msgid "Abort filling" msgstr "" #: ../mainwindow.cpp:6830 msgctxt "MainWindow|" msgid "" "Filling QSOs...\n" " QSO: " msgstr "" #: ../mainwindow.cpp:6890 msgctxt "MainWindow|" msgid "Number" msgstr "" #: ../mainwindow.cpp:6892 msgctxt "MainWindow|" msgid "Date" msgstr "" #: ../mainwindow.cpp:6894 msgctxt "MainWindow|" msgid "Time" msgstr "" #: ../mainwindow.cpp:6902 msgctxt "MainWindow|" msgid "Band" msgstr "" #: ../mainwindow.cpp:6904 msgctxt "MainWindow|" msgid "Mode" msgstr "" #: ../mainwindow.cpp:6919 msgctxt "MainWindow|" msgid "Print Log" msgstr "" #: ../mainwindow.cpp:6924 msgctxt "MainWindow|" msgid "Printing the log..." msgstr "" #: ../mainwindow.cpp:6924 msgctxt "MainWindow|" msgid "Abort printing" msgstr "" #: ../mainwindow.cpp:6939 ../mainwindow.cpp:6954 msgctxt "MainWindow|" msgid "" "Printing the log...\n" " QSO: " msgstr "" #: ../mainwindow.cpp:7531 msgctxt "MainWindow|" msgid "An unexpected error ocurred!!" msgstr "" #: ../mainwindow.cpp:7531 msgctxt "MainWindow|" msgid "If the problem persists, please contact the developers" msgstr "" #: ../mainwindow.cpp:7531 msgctxt "MainWindow|" msgid "for analysis:" msgstr "" #: ../mainwindow.cpp:7533 msgctxt "MainWindow|" msgid "Error in function" msgstr "" #: ../mainwindow.cpp:7534 msgctxt "MainWindow|" msgid "Error code" msgstr "" #: ../mainwindow.cpp:7535 msgctxt "MainWindow|" msgid "Error text" msgstr "" #: ../mainwindow.cpp:7536 msgctxt "MainWindow|" msgid "Failed query" msgstr "" #: ../mainwindow.cpp:7547 msgctxt "MainWindow|" msgid "Do you want to keep showing errors?" msgstr "" #: ../mainwindowinputcomment.cpp:46 msgctxt "MainWindowInputComment|" msgid "Add a comment for this QSO" msgstr "" #: ../mainwindowinputeqsl.cpp:44 msgctxt "MainWindowInputEQSL|" msgid "Date of the ClubLog upload." msgstr "" #: ../mainwindowinputeqsl.cpp:45 msgctxt "MainWindowInputEQSL|" msgid "Date of the eQSL sending." msgstr "" #: ../mainwindowinputeqsl.cpp:46 msgctxt "MainWindowInputEQSL|" msgid "Date of the eQSL reception." msgstr "" #: ../mainwindowinputeqsl.cpp:47 msgctxt "MainWindowInputEQSL|" msgid "Date of the LoTW sending." msgstr "" #: ../mainwindowinputeqsl.cpp:48 msgctxt "MainWindowInputEQSL|" msgid "Date of the LoTW reception." msgstr "" #: ../mainwindowinputeqsl.cpp:50 msgctxt "MainWindowInputEQSL|" msgid "Status on ClubLog." msgstr "" #: ../mainwindowinputeqsl.cpp:51 msgctxt "MainWindowInputEQSL|" msgid "Status of the eQSL sending." msgstr "" #: ../mainwindowinputeqsl.cpp:52 msgctxt "MainWindowInputEQSL|" msgid "Status of the eQSL reception." msgstr "" #: ../mainwindowinputeqsl.cpp:53 msgctxt "MainWindowInputEQSL|" msgid "Status of the LoTW sending." msgstr "" #: ../mainwindowinputeqsl.cpp:54 msgctxt "MainWindowInputEQSL|" msgid "Status of the LoTW reception." msgstr "" #: ../mainwindowinputeqsl.cpp:58 msgctxt "MainWindowInputEQSL|" msgid "ClubLog" msgstr "" #: ../mainwindowinputeqsl.cpp:61 msgctxt "MainWindowInputEQSL|" msgid "eQSL Sent" msgstr "" #: ../mainwindowinputeqsl.cpp:64 msgctxt "MainWindowInputEQSL|" msgid "eQSL Rec" msgstr "" #: ../mainwindowinputeqsl.cpp:67 msgctxt "MainWindowInputEQSL|" msgid "LoTW Sent" msgstr "" #: ../mainwindowinputeqsl.cpp:70 msgctxt "MainWindowInputEQSL|" msgid "LoTW Rec" msgstr "" #: ../mainwindowinputothers.cpp:66 msgctxt "MainWindowInputOthers|" msgid "Primary Div" msgstr "" #: ../mainwindowinputothers.cpp:67 msgctxt "MainWindowInputOthers|" msgid "Secondary Div" msgstr "" #: ../mainwindowinputothers.cpp:68 msgctxt "MainWindowInputOthers|" msgid "IOTA" msgstr "" #: ../mainwindowinputothers.cpp:69 msgctxt "MainWindowInputOthers|" msgid "Entity" msgstr "" #: ../mainwindowinputothers.cpp:70 msgctxt "MainWindowInputOthers|" msgid "Propagation mode" msgstr "" #: ../mainwindowinputothers.cpp:78 msgctxt "MainWindowInputOthers|" msgid "Select the primary division for this QSO" msgstr "" #: ../mainwindowinputothers.cpp:79 msgctxt "MainWindowInputOthers|" msgid "Select the secondary division for this QSO" msgstr "" #: ../mainwindowinputothers.cpp:80 msgctxt "MainWindowInputOthers|" msgid "Select the entity for this QSO" msgstr "" #: ../mainwindowinputothers.cpp:81 msgctxt "MainWindowInputOthers|" msgid "Select the propagation mode for this QSO" msgstr "" #: ../mainwindowinputothers.cpp:82 msgctxt "MainWindowInputOthers|" msgid "Select the IOTA continent for this QSO" msgstr "" #: ../mainwindowinputothers.cpp:83 msgctxt "MainWindowInputOthers|" msgid "Select the IOTA reference number for this QSO" msgstr "" #: ../mainwindowinputothers.cpp:108 ../mainwindowinputothers.cpp:150 msgctxt "MainWindowInputOthers|" msgid "Not Identified" msgstr "" #: ../mainwindowinputothers.cpp:114 msgctxt "MainWindowInputOthers|" msgid "Not - Not Identified" msgstr "" #: ../mainwindowinputqsl.cpp:66 msgctxt "MainWindowInputQSL|" msgid "QSL Sent" msgstr "" #: ../mainwindowinputqsl.cpp:69 msgctxt "MainWindowInputQSL|" msgid "QSL Rec" msgstr "" #: ../mainwindowinputqsl.cpp:72 msgctxt "MainWindowInputQSL|" msgid "QSL Via" msgstr "" #: ../mainwindowinputqsl.cpp:75 msgctxt "MainWindowInputQSL|" msgid "QSL Msg" msgstr "" #: ../mainwindowinputqsl.cpp:78 msgctxt "MainWindowInputQSL|" msgid "Status of the QSL sending." msgstr "" #: ../mainwindowinputqsl.cpp:79 msgctxt "MainWindowInputQSL|" msgid "Status of the QSL reception." msgstr "" #: ../mainwindowinputqsl.cpp:80 msgctxt "MainWindowInputQSL|" msgid "QSL sending information." msgstr "" #: ../mainwindowinputqsl.cpp:81 msgctxt "MainWindowInputQSL|" msgid "QSL reception information." msgstr "" #: ../mainwindowinputqsl.cpp:83 msgctxt "MainWindowInputQSL|" msgid "Date of the QSL sending." msgstr "" #: ../mainwindowinputqsl.cpp:84 msgctxt "MainWindowInputQSL|" msgid "Date of the QSL reception." msgstr "" #: ../mainwindowinputqsl.cpp:85 msgctxt "MainWindowInputQSL|" msgid "Message of the QSL." msgstr "" #: ../mainwindowinputqsl.cpp:86 msgctxt "MainWindowInputQSL|" msgid "QSL via information." msgstr "" #: ../mainwindowmydatatab.cpp:61 msgctxt "MainWindowMyDataTab|" msgid "Watt" msgstr "" #: ../mainwindowmydatatab.cpp:64 msgctxt "MainWindowMyDataTab|" msgid "Keep this data" msgstr "" #: ../mainwindowmydatatab.cpp:66 ../mainwindowmydatatab.cpp:68 msgctxt "MainWindowMyDataTab|" msgid "Data entered in this tab will be copied into the next QSO" msgstr "" #: ../mainwindowmydatatab.cpp:70 msgctxt "MainWindowMyDataTab|" msgid "Power used for the QSO in watts" msgstr "" #: ../mainwindowmydatatab.cpp:71 msgctxt "MainWindowMyDataTab|" msgid "Logging operator's callsign" msgstr "" #: ../mainwindowmydatatab.cpp:72 msgctxt "MainWindowMyDataTab|" msgid "Callsign used over the air" msgstr "" #: ../mainwindowmydatatab.cpp:73 msgctxt "MainWindowMyDataTab|" msgid "My QTH locator" msgstr "" #: ../mainwindowmydatatab.cpp:75 msgctxt "MainWindowMyDataTab|" msgid "Power" msgstr "" #: ../mainwindowmydatatab.cpp:78 msgctxt "MainWindowMyDataTab|" msgid "Operator" msgstr "" #: ../mainwindowmydatatab.cpp:80 msgctxt "MainWindowMyDataTab|" msgid "Station Callsign" msgstr "" #: ../mainwindowmydatatab.cpp:83 msgctxt "MainWindowMyDataTab|" msgid "My Locator" msgstr "" #: ../mainwindowsattab.cpp:78 msgctxt "MainWindowSatTab|" msgid "Keep this data" msgstr "" #: ../mainwindowsattab.cpp:80 ../mainwindowsattab.cpp:82 msgctxt "MainWindowSatTab|" msgid "Data entered in this tab will be copied into the next QSO" msgstr "" #: ../mainwindowsattab.cpp:83 ../mainwindowsattab.cpp:367 msgctxt "MainWindowSatTab|" msgid "Other - Sat not in the list" msgstr "" #: ../mainwindowsattab.cpp:86 msgctxt "MainWindowSatTab|" msgid "Name of the Satellite if not in the list. Select: \"" msgstr "" #: ../mainwindowsattab.cpp:86 msgctxt "MainWindowSatTab|" msgid "\" to enable this box. (format like AO-51)" msgstr "" #: ../mainwindowsattab.cpp:89 msgctxt "MainWindowSatTab|" msgid "Satellite mode used" msgstr "" #: ../mainwindowsattab.cpp:90 msgctxt "MainWindowSatTab|" msgid "Select the satellite you are using" msgstr "" #: ../mainwindowsattab.cpp:91 msgctxt "MainWindowSatTab|" msgid "UpLink band" msgstr "" #: ../mainwindowsattab.cpp:92 msgctxt "MainWindowSatTab|" msgid "DownLink band" msgstr "" #: ../mainwindowsattab.cpp:93 msgctxt "MainWindowSatTab|" msgid "" "Locator of the DX station. This box will is syncronized with the Locator box " "in the QSO tab." msgstr "" #: ../mainwindowsattab.cpp:96 msgctxt "MainWindowSatTab|" msgid "UpLink" msgstr "" #: ../mainwindowsattab.cpp:100 msgctxt "MainWindowSatTab|" msgid "DownLink" msgstr "" #: ../mainwindowsattab.cpp:104 msgctxt "MainWindowSatTab|" msgid "Satellite" msgstr "" #: ../mainwindowsattab.cpp:108 msgctxt "MainWindowSatTab|" msgid "Mode" msgstr "" #: ../mainwindowsattab.cpp:112 msgctxt "MainWindowSatTab|" msgid "DX Locator" msgstr "" #: ../mainwindowsattab.cpp:117 msgctxt "MainWindowSatTab|" msgid "Other" msgstr "" #: ../mainwindowsattab.cpp:123 ../mainwindowsattab.cpp:127 msgctxt "MainWindowSatTab|" msgid "MHz" msgstr "" #: ../mainwindowsattab.cpp:366 msgctxt "MainWindowSatTab|" msgid "Not Sat QSO" msgstr "" #: ../mainwindowsattab.cpp:403 msgctxt "MainWindowSatTab|" msgid "" "KLog has detected a satellite name that it does not recognise. If it should " "use one of the names of known satellites instead, please select it from the " "list. Alternatively, please contact the development team to add the new " "satellite name." msgstr "" #: ../mainwindowsattab.cpp:404 msgctxt "MainWindowSatTab|" msgid "The satellite you have in your QSO is: " msgstr "" #: ../mainwindowsattab.cpp:404 msgctxt "MainWindowSatTab|" msgid "" "Please know that the satellite name will not be saved if it is not in the " "list so that information may be lost!" msgstr "" #: ../awards.cpp:664 msgctxt "QObject|" msgid "New One, work it!" msgstr "" #: ../awards.cpp:668 ../awards.cpp:672 ../awards.cpp:678 ../awards.cpp:681 #: ../awards.cpp:684 ../awards.cpp:687 ../awards.cpp:693 ../awards.cpp:699 msgctxt "QObject|" msgid "Needed, work it!" msgstr "" #: ../awards.cpp:675 ../awards.cpp:690 ../awards.cpp:696 ../awards.cpp:702 msgctxt "QObject|" msgid "Worked but not confirmed" msgstr "" #: ../awards.cpp:705 msgctxt "QObject|" msgid "Confirmed" msgstr "" #: ../awards.cpp:709 msgctxt "QObject|" msgid "Not identified" msgstr "" #: ../database.cpp:271 ../database.cpp:310 msgctxt "QObject|" msgid "Database Error" msgstr "" #: ../database.cpp:1447 msgctxt "QObject|" msgid "KLog DB needs to be upgraded." msgstr "" #: ../database.cpp:1448 msgctxt "QObject|" msgid "Do you want to upgrade it now?" msgstr "" #: ../database.cpp:1448 msgctxt "QObject|" msgid "If DB is not upgraded KLog may not work properly." msgstr "" #: ../database.cpp:2032 msgctxt "QObject|" msgid "" "KLog has detected a previous log in the DB. All data will be migrated to a " "newly created DX type log for you." msgstr "" #: ../database.cpp:2050 msgctxt "QObject|" msgid "KLog: Enter Station callsign" msgstr "" #: ../database.cpp:2051 msgctxt "QObject|" msgid "Enter the station callsign used in this log" msgstr "" #: ../database.cpp:2052 msgctxt "QObject|" msgid "Station Callsign" msgstr "" #: ../database.cpp:2103 msgctxt "QObject|" msgid "" "All the data was migrated correctly. You should now go to " "Setup->Preferences->Logs to check that everything is OK." msgstr "" #: ../database.cpp:3352 ../database.cpp:3373 msgctxt "QObject|" msgid "Updating mode information..." msgstr "" #: ../database.cpp:3352 ../database.cpp:3537 ../database.cpp:3734 #: ../database.cpp:3935 ../database.cpp:6614 ../database.cpp:6837 #: ../dataproxy_sqlite.cpp:3901 msgctxt "QObject|" msgid "Abort updating" msgstr "" #: ../database.cpp:3373 ../database.cpp:3556 ../database.cpp:6706 #: ../database.cpp:6929 ../dataproxy_sqlite.cpp:3942 msgctxt "QObject|" msgid "QSO: " msgstr "" #: ../database.cpp:3448 ../database.cpp:3625 ../database.cpp:3826 #: ../database.cpp:4034 msgctxt "QObject|" msgid "" "Canceling this update will cause data inconsistencies and possibly data " "loss. Do you still want to cancel?" msgstr "" #: ../database.cpp:3537 ../database.cpp:3556 ../database.cpp:3756 #: ../database.cpp:3958 msgctxt "QObject|" msgid "Updating bands information..." msgstr "" #: ../database.cpp:3732 #, qt-format msgctxt "QObject|" msgid "Updating bands information in %1 status..." msgstr "" #: ../database.cpp:3756 ../database.cpp:3958 msgctxt "QObject|" msgid "Progress: " msgstr "" #: ../database.cpp:3933 #, qt-format msgctxt "QObject|" msgid "Updating mode information in %1 status..." msgstr "" #: ../database.cpp:6614 msgctxt "QObject|" msgid "Updating DXCC award information..." msgstr "" #: ../database.cpp:6706 ../database.cpp:6929 ../dataproxy_sqlite.cpp:3942 msgctxt "QObject|" msgid "Updating DXCC Award information..." msgstr "" #: ../database.cpp:6837 msgctxt "QObject|" msgid "Updating WAZ award information..." msgstr "" #: ../dataproxy_sqlite.cpp:3901 msgctxt "QObject|" msgid "Updating DXCC information..." msgstr "" #: ../main.cpp:268 msgctxt "QObject|" msgid "Install wizard was canceled before completing..." msgstr "" #: ../main.cpp:269 msgctxt "QObject|" msgid "Do you want to remove the KLog dir from your disk?" msgstr "" #: ../main.cpp:282 msgctxt "QObject|" msgid "Your KLog dir has been removed" msgstr "" #: ../main.cpp:282 ../main.cpp:288 ../main.cpp:295 ../main.cpp:301 msgctxt "QObject|" msgid "Thank you for running KLog!" msgstr "" #: ../main.cpp:288 msgctxt "QObject|" msgid "" "I could not remove your KLog dir. You should do it manually if you want it " "removed from your hard disk." msgstr "" #: ../main.cpp:295 msgctxt "QObject|" msgid "" "Your KLog dir could not be removed. You should do it manually if you want it " "removed from your hard disk." msgstr "" #: ../main.cpp:301 msgctxt "QObject|" msgid "Remember that your KLog dir is on your system..." msgstr "" #: ../searchwidget.cpp:26 msgctxt "SearchWidget|" msgid "&Clear" msgstr "" #: ../searchwidget.cpp:27 msgctxt "SearchWidget|" msgid "&Export Highlighted" msgstr "" #: ../searchwidget.cpp:28 ../searchwidget.cpp:398 ../searchwidget.cpp:430 msgctxt "SearchWidget|" msgid "&Select All" msgstr "" #: ../searchwidget.cpp:29 msgctxt "SearchWidget|" msgid "&Search" msgstr "" #: ../searchwidget.cpp:30 msgctxt "SearchWidget|" msgid "All" msgstr "" #: ../searchwidget.cpp:69 msgctxt "SearchWidget|" msgid "Clear the searches." msgstr "" #: ../searchwidget.cpp:70 msgctxt "SearchWidget|" msgid "Export the search result to an ADIF file." msgstr "" #: ../searchwidget.cpp:71 msgctxt "SearchWidget|" msgid "Select/Unselect all the QSOs shown." msgstr "" #: ../searchwidget.cpp:72 msgctxt "SearchWidget|" msgid "Search in the log." msgstr "" #: ../searchwidget.cpp:73 msgctxt "SearchWidget|" msgid "Search in all logs." msgstr "" #: ../searchwidget.cpp:74 msgctxt "SearchWidget|" msgid "Enter the QRZ to search for." msgstr "" #: ../searchwidget.cpp:75 msgctxt "SearchWidget|" msgid "Search results." msgstr "" #: ../searchwidget.cpp:81 ../searchwidget.cpp:86 msgctxt "SearchWidget|" msgid "QRZ" msgstr "" #: ../searchwidget.cpp:81 ../searchwidget.cpp:86 msgctxt "SearchWidget|" msgid "Date/Time" msgstr "" #: ../searchwidget.cpp:81 ../searchwidget.cpp:86 msgctxt "SearchWidget|" msgid "Band" msgstr "" #: ../searchwidget.cpp:81 ../searchwidget.cpp:86 msgctxt "SearchWidget|" msgid "Mode" msgstr "" #: ../searchwidget.cpp:81 ../searchwidget.cpp:86 msgctxt "SearchWidget|" msgid "QSL Sent" msgstr "" #: ../searchwidget.cpp:81 ../searchwidget.cpp:86 ../searchwidget.cpp:608 msgctxt "SearchWidget|" msgid "QSL Rcvd" msgstr "" #: ../searchwidget.cpp:81 msgctxt "SearchWidget|" msgid "Station Callsign" msgstr "" #: ../searchwidget.cpp:81 ../searchwidget.cpp:86 msgctxt "SearchWidget|" msgid "ID" msgstr "" #: ../searchwidget.cpp:406 ../searchwidget.cpp:425 msgctxt "SearchWidget|" msgid "&Clear selection" msgstr "" #: ../searchwidget.cpp:500 msgctxt "SearchWidget|" msgid "Save File" msgstr "" #: ../searchwidget.cpp:583 msgctxt "SearchWidget|" msgid "QSL Send" msgstr "" #: ../searchwidget.cpp:642 msgctxt "SearchWidget|" msgid "&Delete" msgstr "" #: ../searchwidget.cpp:644 msgctxt "SearchWidget|" msgid "Delete a QSO" msgstr "" #: ../searchwidget.cpp:647 msgctxt "SearchWidget|" msgid "&Edit QSO" msgstr "" #: ../searchwidget.cpp:649 msgctxt "SearchWidget|" msgid "Edit this QSO" msgstr "" #: ../searchwidget.cpp:652 msgctxt "SearchWidget|" msgid "Via &bureau" msgstr "" #: ../searchwidget.cpp:654 msgctxt "SearchWidget|" msgid "Send this QSL via bureau" msgstr "" #: ../searchwidget.cpp:657 msgctxt "SearchWidget|" msgid "D&irect" msgstr "" #: ../searchwidget.cpp:659 msgctxt "SearchWidget|" msgid "Send this QSL via direct" msgstr "" #: ../searchwidget.cpp:662 msgctxt "SearchWidget|" msgid "&Request my QSL" msgstr "" #: ../searchwidget.cpp:664 msgctxt "SearchWidget|" msgid "Mark my QSL as requested" msgstr "" #: ../searchwidget.cpp:667 msgctxt "SearchWidget|" msgid "Via Direct && mark DX QSL as requested" msgstr "" #: ../searchwidget.cpp:668 msgctxt "SearchWidget|" msgid "Send this QSL via direct & mark DX QSL as requested" msgstr "" #: ../searchwidget.cpp:671 msgctxt "SearchWidget|" msgid "Via Bureau && mark DX QSL as requested" msgstr "" #: ../searchwidget.cpp:672 msgctxt "SearchWidget|" msgid "Send this QSL via bureau & mark DX QSL as requested" msgstr "" #: ../searchwidget.cpp:676 msgctxt "SearchWidget|" msgid "&Request the QSL" msgstr "" #: ../searchwidget.cpp:678 msgctxt "SearchWidget|" msgid "Mark the QSL as requested" msgstr "" #: ../searchwidget.cpp:682 msgctxt "SearchWidget|" msgid "Via bureau && mark my QSL as requested" msgstr "" #: ../searchwidget.cpp:683 msgctxt "SearchWidget|" msgid "QSL received via bureau & mark my QSL as requested" msgstr "" #: ../searchwidget.cpp:686 msgctxt "SearchWidget|" msgid "Via bureau" msgstr "" #: ../searchwidget.cpp:687 msgctxt "SearchWidget|" msgid "QSL received via bureau" msgstr "" #: ../searchwidget.cpp:691 msgctxt "SearchWidget|" msgid "Direc&t && mark as my QSL requested" msgstr "" #: ../searchwidget.cpp:692 msgctxt "SearchWidget|" msgid "QSL received via direct & mark my QSL as requested" msgstr "" #: ../searchwidget.cpp:695 msgctxt "SearchWidget|" msgid "Direc&t" msgstr "" #: ../searchwidget.cpp:696 msgctxt "SearchWidget|" msgid "QSL received via direct" msgstr "" #: ../searchwidget.cpp:924 msgctxt "SearchWidget|" msgid "You have requested to delete the QSO with:" msgstr "" #: ../searchwidget.cpp:929 msgctxt "SearchWidget|" msgid "Are you sure?" msgstr "" #: ../searchwidget.cpp:992 msgctxt "SearchWidget|" msgid "Needed QSO to send the QSL" msgstr "" #: ../searchwidget.cpp:1000 msgctxt "SearchWidget|" msgid "My QSL requested to be sent" msgstr "" #: ../searchwidget.cpp:1005 ../searchwidget.cpp:1010 msgctxt "SearchWidget|" msgid "DX QSL pending to be received" msgstr "" #: ../setupdialog.cpp:86 msgctxt "SetupDialog|" msgid "My Data" msgstr "" #: ../setupdialog.cpp:87 ../setupdialog.cpp:159 ../setupdialog.cpp:313 msgctxt "SetupDialog|" msgid "Bands/Modes" msgstr "" #: ../setupdialog.cpp:88 ../setupdialog.cpp:319 msgctxt "SetupDialog|" msgid "DX-Cluster" msgstr "" #: ../setupdialog.cpp:89 ../setupdialog.cpp:161 ../setupdialog.cpp:325 msgctxt "SetupDialog|" msgid "Colors" msgstr "" #: ../setupdialog.cpp:90 ../setupdialog.cpp:162 ../setupdialog.cpp:331 msgctxt "SetupDialog|" msgid "Misc" msgstr "" #: ../setupdialog.cpp:91 ../setupdialog.cpp:163 msgctxt "SetupDialog|" msgid "World Editor" msgstr "" #: ../setupdialog.cpp:92 ../setupdialog.cpp:164 ../setupdialog.cpp:307 msgctxt "SetupDialog|" msgid "Logs" msgstr "" #: ../setupdialog.cpp:93 ../setupdialog.cpp:165 msgctxt "SetupDialog|" msgid "ClubLog" msgstr "" #: ../setupdialog.cpp:95 ../setupdialog.cpp:169 msgctxt "SetupDialog|" msgid "Cancel" msgstr "" #: ../setupdialog.cpp:96 ../setupdialog.cpp:170 msgctxt "SetupDialog|" msgid "OK" msgstr "" #: ../setupdialog.cpp:119 ../setupdialog.cpp:190 msgctxt "SetupDialog|" msgid "Config Dialog" msgstr "" #: ../setupdialog.cpp:158 ../setupdialog.cpp:301 msgctxt "SetupDialog|" msgid "User data" msgstr "" #: ../setupdialog.cpp:160 msgctxt "SetupDialog|" msgid "D&X-Cluster" msgstr "" #: ../setupdialog.cpp:285 msgctxt "SetupDialog|" msgid "You need to enter at least one log in the Logs tab." msgstr "" #: ../setupdialog.cpp:337 msgctxt "SetupDialog|" msgid "World" msgstr "" #: ../setupdialog.cpp:366 msgctxt "SetupDialog|" msgid "DB has not been moved to new path" msgstr "" #: ../setupdialog.cpp:367 ../setupdialog.cpp:376 msgctxt "SetupDialog|" msgid "Go to the" msgstr "" #: ../setupdialog.cpp:367 msgctxt "SetupDialog|" msgid "Misc tab" msgstr "" #: ../setupdialog.cpp:367 msgctxt "SetupDialog|" msgid "and click on" msgstr "" #: ../setupdialog.cpp:367 msgctxt "SetupDialog|" msgid "Move DB" msgstr "" #: ../setupdialog.cpp:367 msgctxt "SetupDialog|" msgid "or the DB will not be moved to the new location." msgstr "" #: ../setupdialog.cpp:375 msgctxt "SetupDialog|" msgid "You need to enter at least a valid QRZ." msgstr "" #: ../setupdialog.cpp:376 msgctxt "SetupDialog|" msgid "User tab" msgstr "" #: ../setupdialog.cpp:376 msgctxt "SetupDialog|" msgid "and enter valid QRZ." msgstr "" #: ../setupdialog.cpp:387 msgctxt "SetupDialog|" msgid "You have not selected the kind of log you want." msgstr "" #: ../setupdialog.cpp:388 msgctxt "SetupDialog|" msgid "" "You will be redirected to the Log tab.\n" "Please add and select the kind of log you want to use." msgstr "" #: ../setupentitydialog.cpp:69 msgctxt "SetupEntityDialog|" msgid "Entity" msgstr "" #: ../setupentitydialog.cpp:71 msgctxt "SetupEntityDialog|" msgid "Name of the Entity" msgstr "" #: ../setupentitydialog.cpp:73 msgctxt "SetupEntityDialog|" msgid "CQ" msgstr "" #: ../setupentitydialog.cpp:75 msgctxt "SetupEntityDialog|" msgid "CQ zone" msgstr "" #: ../setupentitydialog.cpp:77 msgctxt "SetupEntityDialog|" msgid "ITU" msgstr "" #: ../setupentitydialog.cpp:79 msgctxt "SetupEntityDialog|" msgid "ITU zone" msgstr "" #: ../setupentitydialog.cpp:85 msgctxt "SetupEntityDialog|" msgid "Latitude" msgstr "" #: ../setupentitydialog.cpp:87 ../setupentitydialog.cpp:91 msgctxt "SetupEntityDialog|" msgid "Longitude of the Entity" msgstr "" #: ../setupentitydialog.cpp:89 msgctxt "SetupEntityDialog|" msgid "Longitude" msgstr "" #: ../setupentitydialog.cpp:93 msgctxt "SetupEntityDialog|" msgid "UTC" msgstr "" #: ../setupentitydialog.cpp:95 msgctxt "SetupEntityDialog|" msgid "Local time difference to UTC" msgstr "" #: ../setupentitydialog.cpp:97 msgctxt "SetupEntityDialog|" msgid "Main prefix" msgstr "" #: ../setupentitydialog.cpp:99 msgctxt "SetupEntityDialog|" msgid "Main prefix of the entity" msgstr "" #: ../setupentitydialog.cpp:103 ../setupentitydialog.cpp:105 msgctxt "SetupEntityDialog|" msgid "ARRL ID" msgstr "" #: ../setupentitydialog.cpp:111 msgctxt "SetupEntityDialog|" msgid "Prefixes" msgstr "" #: ../setupentitydialog.cpp:113 msgctxt "SetupEntityDialog|" msgid "Comma separated possible prefixes, e.g. EA1, EA2, ..." msgstr "" #: ../setupentitydialog.cpp:116 msgctxt "SetupEntityDialog|" msgid "Date of the deletion" msgstr "" #: ../setupentitydialog.cpp:118 msgctxt "SetupEntityDialog|" msgid "Deleted" msgstr "" #: ../setupentitydialog.cpp:120 msgctxt "SetupEntityDialog|" msgid "Cancel" msgstr "" #: ../setupentitydialog.cpp:121 msgctxt "SetupEntityDialog|" msgid "OK" msgstr "" #: ../setupentitydialog.cpp:209 msgctxt "SetupEntityDialog|" msgid "Entity Dialog" msgstr "" #: ../setuppagebandmode.cpp:16 msgctxt "SetupPageBandMode|" msgid "Bands" msgstr "" #: ../setuppagebandmode.cpp:20 msgctxt "SetupPageBandMode|" msgid "Modes" msgstr "" #: ../setuppageclublog.cpp:45 msgctxt "SetupPageClubLog|" msgid "&Callsign" msgstr "" #: ../setuppageclublog.cpp:46 msgctxt "SetupPageClubLog|" msgid "ClubLog &password" msgstr "" #: ../setuppageclublog.cpp:47 msgctxt "SetupPageClubLog|" msgid "ClubLog &email" msgstr "" #: ../setuppageclublog.cpp:53 msgctxt "SetupPageClubLog|" msgid "Enter the email you used to register in ClubLog." msgstr "" #: ../setuppageclublog.cpp:54 msgctxt "SetupPageClubLog|" msgid "Enter the callsign you used to register in ClubLog." msgstr "" #: ../setuppageclublog.cpp:55 msgctxt "SetupPageClubLog|" msgid "Enter your password in ClubLog." msgstr "" #: ../setuppageclublog.cpp:60 msgctxt "SetupPageClubLog|" msgid "&Send QSOs in real time" msgstr "" #: ../setuppageclublog.cpp:61 msgctxt "SetupPageClubLog|" msgid "&Activate ClubLog" msgstr "" #: ../setuppageclublog.cpp:62 msgctxt "SetupPageClubLog|" msgid "Use QSO Station &Callsign" msgstr "" #: ../setuppageclublog.cpp:63 msgctxt "SetupPageClubLog|" msgid "" "Send each QSO to ClubLog in real time, as they are added (or modified) in " "KLog" msgstr "" #: ../setuppageclublog.cpp:64 msgctxt "SetupPageClubLog|" msgid "Starts the ClubLog support in KLog" msgstr "" #: ../setuppageclublog.cpp:65 msgctxt "SetupPageClubLog|" msgid "" "Use the Station Callsign defined in each QSO instead of the one defined here" msgstr "" #: ../setuppagecolors.cpp:42 msgctxt "SetupPageColors|" msgid "New One" msgstr "" #: ../setuppagecolors.cpp:43 msgctxt "SetupPageColors|" msgid "Needed in this band" msgstr "" #: ../setuppagecolors.cpp:44 msgctxt "SetupPageColors|" msgid "Worked in this band" msgstr "" #: ../setuppagecolors.cpp:45 msgctxt "SetupPageColors|" msgid "Confirmed in this band" msgstr "" #: ../setuppagecolors.cpp:46 msgctxt "SetupPageColors|" msgid "Default" msgstr "" #: ../setuppagecolors.cpp:131 msgctxt "SetupPageColors|" msgid "Choose a color" msgstr "" #: ../setuppagedxcluster.cpp:74 msgctxt "SetupPageDxCluster|" msgid "Add" msgstr "" #: ../setuppagedxcluster.cpp:75 msgctxt "SetupPageDxCluster|" msgid "Delete" msgstr "" #: ../setuppagedxcluster.cpp:77 msgctxt "SetupPageDxCluster|" msgid "Show &HF spots" msgstr "" #: ../setuppagedxcluster.cpp:78 msgctxt "SetupPageDxCluster|" msgid "Show V/&UHF spots" msgstr "" #: ../setuppagedxcluster.cpp:79 msgctxt "SetupPageDxCluster|" msgid "Show W&ARC spots" msgstr "" #: ../setuppagedxcluster.cpp:80 msgctxt "SetupPageDxCluster|" msgid "Show &worked spots" msgstr "" #: ../setuppagedxcluster.cpp:81 msgctxt "SetupPageDxCluster|" msgid "Show &confirmed spots" msgstr "" #: ../setuppagedxcluster.cpp:82 msgctxt "SetupPageDxCluster|" msgid "Show ANN/&FULL messages" msgstr "" #: ../setuppagedxcluster.cpp:83 msgctxt "SetupPageDxCluster|" msgid "Show WW&V messages" msgstr "" #: ../setuppagedxcluster.cpp:84 msgctxt "SetupPageDxCluster|" msgid "Show WC&Y messages" msgstr "" #: ../setuppagedxcluster.cpp:86 msgctxt "SetupPageDxCluster|" msgid "DX Spots" msgstr "" #: ../setuppagedxcluster.cpp:98 msgctxt "SetupPageDxCluster|" msgid "Messages" msgstr "" #: ../setuppagedxcluster.cpp:156 msgctxt "SetupPageDxCluster|" msgid "KLog: Add a DXCluster server" msgstr "" #: ../setuppagedxcluster.cpp:157 msgctxt "SetupPageDxCluster|" msgid "" "Add the address followed by the :port\n" "Example: dxfun.com:8000\n" "If no port is specified, 41112 will be used by default:" msgstr "" #: ../setuppagelogs.cpp:70 msgctxt "SetupPageLogs|" msgid "&New" msgstr "" #: ../setuppagelogs.cpp:71 msgctxt "SetupPageLogs|" msgid "&Edit" msgstr "" #: ../setuppagelogs.cpp:72 msgctxt "SetupPageLogs|" msgid "&Remove" msgstr "" #: ../setuppagelogs.cpp:75 msgctxt "SetupPageLogs|" msgid "Add a new log" msgstr "" #: ../setuppagelogs.cpp:79 msgctxt "SetupPageLogs|" msgid "Edit the selected log" msgstr "" #: ../setuppagelogs.cpp:80 msgctxt "SetupPageLogs|" msgid "Remove the selected log" msgstr "" #: ../setuppagelogs.cpp:82 msgctxt "SetupPageLogs|" msgid "Select the log you want to open" msgstr "" #: ../setuppagelogs.cpp:219 msgctxt "SetupPageLogs|" msgid "KLog" msgstr "" #: ../setuppagelogs.cpp:220 msgctxt "SetupPageLogs|" msgid "Do you really want to remove this log?" msgstr "" #: ../setuppagelogs.cpp:221 msgctxt "SetupPageLogs|" msgid "All the QSOs from this log will be also deleted..." msgstr "" #: ../setuppagelogs.cpp:253 msgctxt "SetupPageLogs|" msgid "Log has not been removed. (#3)" msgstr "" #: ../setuppagelogs.cpp:260 msgctxt "SetupPageLogs|" msgid "Log has not been removed. (#2)" msgstr "" #: ../setuppagelogs.cpp:267 msgctxt "SetupPageLogs|" msgid "Log has not been removed. (#1)" msgstr "" #: ../setuppagelogs.cpp:327 msgctxt "SetupPageLogs|" msgid "ID" msgstr "" #: ../setuppagelogs.cpp:330 msgctxt "SetupPageLogs|" msgid "Date" msgstr "" #: ../setuppagelogs.cpp:333 msgctxt "SetupPageLogs|" msgid "Station Callsign" msgstr "" #: ../setuppagelogs.cpp:336 msgctxt "SetupPageLogs|" msgid "Operators" msgstr "" #: ../setuppagelogs.cpp:339 msgctxt "SetupPageLogs|" msgid "Comments" msgstr "" #: ../setuppagelogs.cpp:342 msgctxt "SetupPageLogs|" msgid "Type" msgstr "" #: ../setuppagelogs.cpp:649 msgctxt "SetupPageLogs|" msgid "An error has occurred showing the following error code:" msgstr "" #: ../setuppagelogs.cpp:652 msgctxt "SetupPageLogs|" msgid "KLog - SetupPageLogs" msgstr "" #: ../setuppagelogsnew.cpp:92 msgctxt "SetupPageLogsNew|" msgid "&Date" msgstr "" #: ../setuppagelogsnew.cpp:93 msgctxt "SetupPageLogsNew|" msgid "&Station Callsign" msgstr "" #: ../setuppagelogsnew.cpp:94 msgctxt "SetupPageLogsNew|" msgid "&Operators" msgstr "" #: ../setuppagelogsnew.cpp:95 msgctxt "SetupPageLogsNew|" msgid "Comm&ent" msgstr "" #: ../setuppagelogsnew.cpp:97 msgctxt "SetupPageLogsNew|" msgid "&Ok" msgstr "" #: ../setuppagelogsnew.cpp:98 msgctxt "SetupPageLogsNew|" msgid "&Cancel" msgstr "" #: ../setuppagelogsnew.cpp:155 msgctxt "SetupPageLogsNew|" msgid "Select categories" msgstr "" #: ../setuppagelogsnew.cpp:159 msgctxt "SetupPageLogsNew|" msgid "Callsign used for this log" msgstr "" #: ../setuppagelogsnew.cpp:160 msgctxt "SetupPageLogsNew|" msgid "Comma separated list of operators: callsign1, callsign2" msgstr "" #: ../setuppagelogsnew.cpp:162 msgctxt "SetupPageLogsNew|" msgid "Start date of this log" msgstr "" #: ../setuppagelogsnew.cpp:163 msgctxt "SetupPageLogsNew|" msgid "Add a comment about this log" msgstr "" #: ../setuppagelogsnew.cpp:165 msgctxt "SetupPageLogsNew|" msgid "&Type of Operation" msgstr "" #: ../setuppagelogsnew.cpp:172 msgctxt "SetupPageLogsNew|" msgid "Select the kind of operation for this log" msgstr "" #: ../setuppagelogsnew.cpp:179 msgctxt "SetupPageLogsNew|" msgid "&Mode Category" msgstr "" #: ../setuppagelogsnew.cpp:181 msgctxt "SetupPageLogsNew|" msgid "Select the mode category" msgstr "" #: ../setuppagelogsnew.cpp:187 msgctxt "SetupPageLogsNew|" msgid "O&perators Category" msgstr "" #: ../setuppagelogsnew.cpp:189 msgctxt "SetupPageLogsNew|" msgid "Select the operators category" msgstr "" #: ../setuppagelogsnew.cpp:194 msgctxt "SetupPageLogsNew|" msgid "&Assisted Category" msgstr "" #: ../setuppagelogsnew.cpp:196 msgctxt "SetupPageLogsNew|" msgid "Select the assisted category" msgstr "" #: ../setuppagelogsnew.cpp:202 msgctxt "SetupPageLogsNew|" msgid "Po&wer Category" msgstr "" #: ../setuppagelogsnew.cpp:204 msgctxt "SetupPageLogsNew|" msgid "Select the power category" msgstr "" #: ../setuppagelogsnew.cpp:210 msgctxt "SetupPageLogsNew|" msgid "&Bands Category" msgstr "" #: ../setuppagelogsnew.cpp:212 msgctxt "SetupPageLogsNew|" msgid "Select the bands category" msgstr "" #: ../setuppagelogsnew.cpp:217 msgctxt "SetupPageLogsNew|" msgid "O&verlay" msgstr "" #: ../setuppagelogsnew.cpp:219 msgctxt "SetupPageLogsNew|" msgid "Select the Overlay category" msgstr "" #: ../setuppagelogsnew.cpp:380 ../setuppagelogsnew.cpp:936 msgctxt "SetupPageLogsNew|" msgid "Categories not OK" msgstr "" #: ../setuppagelogsnew.cpp:577 msgctxt "SetupPageLogsNew|" msgid "" "You need to enter a valid QRZ in the Station Callsign box.\n" "The log will not be opened." msgstr "" #: ../setuppagelogsnew.cpp:688 msgctxt "SetupPageLogsNew|" msgid "" "You selected an invalid combination.\n" "The log will not be opened." msgstr "" #: ../setuppagelogsnew.cpp:928 msgctxt "SetupPageLogsNew|" msgid "Categories OK" msgstr "" #: ../setuppagemisc.cpp:38 msgctxt "SetupPageMisc|" msgid "&Imperial system" msgstr "" #: ../setuppagemisc.cpp:39 msgctxt "SetupPageMisc|" msgid "&Log in real time" msgstr "" #: ../setuppagemisc.cpp:40 msgctxt "SetupPageMisc|" msgid "&Time in UTC" msgstr "" #: ../setuppagemisc.cpp:41 msgctxt "SetupPageMisc|" msgid "&Save ADIF on exit" msgstr "" #: ../setuppagemisc.cpp:42 msgctxt "SetupPageMisc|" msgid "Use this &default filename" msgstr "" #: ../setuppagemisc.cpp:43 msgctxt "SetupPageMisc|" msgid "Mark &QSO to send QSL when QSL is received" msgstr "" #: ../setuppagemisc.cpp:44 msgctxt "SetupPageMisc|" msgid "Complete QSO with previous data" msgstr "" #: ../setuppagemisc.cpp:45 msgctxt "SetupPageMisc|" msgid "Show the Station &Callsign used in the search box" msgstr "" #: ../setuppagemisc.cpp:46 msgctxt "SetupPageMisc|" msgid "&Reset to My Data for all QSOs" msgstr "" #: ../setuppagemisc.cpp:47 msgctxt "SetupPageMisc|" msgid "&Check for new versions automatically" msgstr "" #: ../setuppagemisc.cpp:48 msgctxt "SetupPageMisc|" msgid "&Provide Info for statistics" msgstr "" #: ../setuppagemisc.cpp:53 ../setuppagemisc.cpp:54 msgctxt "SetupPageMisc|" msgid "Browse" msgstr "" #: ../setuppagemisc.cpp:55 msgctxt "SetupPageMisc|" msgid "Move DB" msgstr "" #: ../setuppagemisc.cpp:110 msgctxt "SetupPageMisc|" msgid "" "QSOs will be marked as pending to send a QSL if you receive the DX QSL and " "have not sent yours." msgstr "" #: ../setuppagemisc.cpp:111 msgctxt "SetupPageMisc|" msgid "The search box will show also the callsign on the air to do the QSO." msgstr "" #: ../setuppagemisc.cpp:112 msgctxt "SetupPageMisc|" msgid "" "All the data from the My Data tab will be used or data from the previous QSO " "will be maintained." msgstr "" #: ../setuppagemisc.cpp:113 msgctxt "SetupPageMisc|" msgid "" "Check if there is a new release of KLog available every time you start KLog." msgstr "" #: ../setuppagemisc.cpp:114 msgctxt "SetupPageMisc|" msgid "" "If new version checking is selected, KLog will send the developer your " "callsign, KLog version & Operating system to help in improving KLog." msgstr "" #: ../setuppagemisc.cpp:115 msgctxt "SetupPageMisc|" msgid "Check it for Imperial system (Miles instead of Kilometres)." msgstr "" #: ../setuppagemisc.cpp:116 msgctxt "SetupPageMisc|" msgid "Select to use real time." msgstr "" #: ../setuppagemisc.cpp:117 msgctxt "SetupPageMisc|" msgid "Select to use UTC time." msgstr "" #: ../setuppagemisc.cpp:118 msgctxt "SetupPageMisc|" msgid "Select if you want to save to ADIF on exit." msgstr "" #: ../setuppagemisc.cpp:119 msgctxt "SetupPageMisc|" msgid "" "Select to use the following name for the logfile without being asked for it " "again." msgstr "" #: ../setuppagemisc.cpp:120 msgctxt "SetupPageMisc|" msgid "Complete the current QSO with previous QSO data." msgstr "" #: ../setuppagemisc.cpp:121 msgctxt "SetupPageMisc|" msgid "This is the default file where ADIF data will be saved." msgstr "" #: ../setuppagemisc.cpp:122 msgctxt "SetupPageMisc|" msgid "This is the directory where the database (logbook.dat) will be saved." msgstr "" #: ../setuppagemisc.cpp:123 msgctxt "SetupPageMisc|" msgid "Click to change the default ADIF file." msgstr "" #: ../setuppagemisc.cpp:124 msgctxt "SetupPageMisc|" msgid "Click to change the path of the database." msgstr "" #: ../setuppagemisc.cpp:125 msgctxt "SetupPageMisc|" msgid "Click to move the DB to the new directory." msgstr "" #: ../setuppagemisc.cpp:264 msgctxt "SetupPageMisc|" msgid "Open File" msgstr "" #: ../setuppagemisc.cpp:563 msgctxt "SetupPageMisc|" msgid "Select Directory" msgstr "" #: ../setuppagemisc.cpp:594 msgctxt "SetupPageMisc|" msgid "This is the directory where DB (logbook.dat) will be saved." msgstr "" #: ../setuppagemisc.cpp:600 msgctxt "SetupPageMisc|" msgid "" "Please specify an existing directory where the database (logbook.dat) will " "be saved." msgstr "" #: ../setuppagemisc.cpp:635 msgctxt "SetupPageMisc|" msgid "File moved" msgstr "" #: ../setuppagemisc.cpp:645 msgctxt "SetupPageMisc|" msgid "File copied" msgstr "" #: ../setuppagemisc.cpp:655 msgctxt "SetupPageMisc|" msgid "File NOT copied" msgstr "" #: ../setuppagemisc.cpp:668 msgctxt "SetupPageMisc|" msgid "" "The target directory does not exist. Please select an existing directory." msgstr "" #: ../setuppageuserdata.cpp:40 msgctxt "SetupPageUserDataPage|" msgid "&Personal data" msgstr "" #: ../setuppageuserdata.cpp:41 msgctxt "SetupPageUserDataPage|" msgid "Station &data" msgstr "" #: ../setuppageuserdata.cpp:70 msgctxt "SetupPageUserDataPage|" msgid "Enter your name" msgstr "" #: ../setuppageuserdata.cpp:71 msgctxt "SetupPageUserDataPage|" msgid "Enter your address - 1st line" msgstr "" #: ../setuppageuserdata.cpp:72 msgctxt "SetupPageUserDataPage|" msgid "Enter your address - 2nd line" msgstr "" #: ../setuppageuserdata.cpp:73 msgctxt "SetupPageUserDataPage|" msgid "Enter your address - 3rd line" msgstr "" #: ../setuppageuserdata.cpp:74 msgctxt "SetupPageUserDataPage|" msgid "Enter your address - 4th line" msgstr "" #: ../setuppageuserdata.cpp:75 msgctxt "SetupPageUserDataPage|" msgid "Enter your city" msgstr "" #: ../setuppageuserdata.cpp:76 msgctxt "SetupPageUserDataPage|" msgid "Enter your zip code" msgstr "" #: ../setuppageuserdata.cpp:77 msgctxt "SetupPageUserDataPage|" msgid "Enter your province or state" msgstr "" #: ../setuppageuserdata.cpp:78 msgctxt "SetupPageUserDataPage|" msgid "Enter your country" msgstr "" #: ../setuppageuserdata.cpp:80 msgctxt "SetupPageUserDataPage|" msgid "&Name" msgstr "" #: ../setuppageuserdata.cpp:81 msgctxt "SetupPageUserDataPage|" msgid "&Address" msgstr "" #: ../setuppageuserdata.cpp:82 msgctxt "SetupPageUserDataPage|" msgid "Cit&y" msgstr "" #: ../setuppageuserdata.cpp:83 msgctxt "SetupPageUserDataPage|" msgid "&Zip Code" msgstr "" #: ../setuppageuserdata.cpp:84 msgctxt "SetupPageUserDataPage|" msgid "Pro&v/State" msgstr "" #: ../setuppageuserdata.cpp:85 msgctxt "SetupPageUserDataPage|" msgid "Countr&y" msgstr "" #: ../setuppageuserdata.cpp:139 ../setuppageuserdata.cpp:140 #: ../setuppageuserdata.cpp:141 msgctxt "SetupPageUserDataPage|" msgid "Enter your information for rig" msgstr "" #: ../setuppageuserdata.cpp:142 ../setuppageuserdata.cpp:143 #: ../setuppageuserdata.cpp:144 msgctxt "SetupPageUserDataPage|" msgid "Enter your information for antenna" msgstr "" #: ../setuppageuserdata.cpp:145 msgctxt "SetupPageUserDataPage|" msgid "Enter your power information" msgstr "" #: ../setuppageuserdata.cpp:147 msgctxt "SetupPageUserDataPage|" msgid "&Rig 1" msgstr "" #: ../setuppageuserdata.cpp:148 msgctxt "SetupPageUserDataPage|" msgid "R&ig 2" msgstr "" #: ../setuppageuserdata.cpp:149 msgctxt "SetupPageUserDataPage|" msgid "Ri&g 3" msgstr "" #: ../setuppageuserdata.cpp:150 msgctxt "SetupPageUserDataPage|" msgid "Antenna &1" msgstr "" #: ../setuppageuserdata.cpp:151 msgctxt "SetupPageUserDataPage|" msgid "Antenna &2" msgstr "" #: ../setuppageuserdata.cpp:152 msgctxt "SetupPageUserDataPage|" msgid "Antenna &3" msgstr "" #: ../setuppageuserdata.cpp:153 msgctxt "SetupPageUserDataPage|" msgid "Po&wer" msgstr "" #: ../setuppageuserdata.cpp:186 msgctxt "SetupPageUserDataPage|" msgid "Enter the station callsign that will be used for logging" msgstr "" #: ../setuppageuserdata.cpp:187 msgctxt "SetupPageUserDataPage|" msgid "Enter the operators (comma separated if more than one)." msgstr "" #: ../setuppageuserdata.cpp:188 msgctxt "SetupPageUserDataPage|" msgid "" "Enter the locator of your station. Alternatively, KLog can use an " "approximate locator based on your callsign." msgstr "" #: ../setuppageuserdata.cpp:191 msgctxt "SetupPageUserDataPage|" msgid "&QRZ" msgstr "" #: ../setuppageuserdata.cpp:192 msgctxt "SetupPageUserDataPage|" msgid "&Operators" msgstr "" #: ../setuppageuserdata.cpp:193 msgctxt "SetupPageUserDataPage|" msgid "&CQ Zone" msgstr "" #: ../setuppageuserdata.cpp:194 msgctxt "SetupPageUserDataPage|" msgid "&ITU Zone" msgstr "" #: ../setuppageuserdata.cpp:195 ../setuppageuserdata.cpp:373 msgctxt "SetupPageUserDataPage|" msgid "&Locator" msgstr "" #: ../setuppageuserdata.cpp:369 msgctxt "SetupPageUserDataPage|" msgid "&Locator (not valid)" msgstr "" #: ../setuppageworldeditor.cpp:88 msgctxt "SetupPageWorldEditor|" msgid "" "An entities information file (cty.csv) has been detected in your KLog folder " "and will be loaded." msgstr "" #: ../setuppageworldeditor.cpp:97 msgctxt "SetupPageWorldEditor|" msgid "" "No entities information file (cty.csv) has been detected in your KLog folder." msgstr "" #: ../setuppageworldeditor.cpp:98 msgctxt "SetupPageWorldEditor|" msgid "KLog will not be able to show entities information." msgstr "" #: ../setuppageworldeditor.cpp:184 msgctxt "SetupPageWorldEditor|" msgid "Prefix" msgstr "" #: ../setuppageworldeditor.cpp:186 msgctxt "SetupPageWorldEditor|" msgid "Entity" msgstr "" #: ../setuppageworldeditor.cpp:188 msgctxt "SetupPageWorldEditor|" msgid "ARRL ID" msgstr "" #: ../setuppageworldeditor.cpp:190 msgctxt "SetupPageWorldEditor|" msgid "Continent" msgstr "" #: ../setuppageworldeditor.cpp:192 msgctxt "SetupPageWorldEditor|" msgid "CQ Zone" msgstr "" #: ../setuppageworldeditor.cpp:194 msgctxt "SetupPageWorldEditor|" msgid "ITU Zone" msgstr "" #: ../setuppageworldeditor.cpp:196 msgctxt "SetupPageWorldEditor|" msgid "UTC" msgstr "" #: ../setuppageworldeditor.cpp:198 msgctxt "SetupPageWorldEditor|" msgid "Latitude" msgstr "" #: ../setuppageworldeditor.cpp:200 msgctxt "SetupPageWorldEditor|" msgid "Longitude" msgstr "" #: ../setuppageworldeditor.cpp:203 msgctxt "SetupPageWorldEditor|" msgid "Deleted" msgstr "" #: ../setuppageworldeditor.cpp:206 msgctxt "SetupPageWorldEditor|" msgid "Since Date" msgstr "" #: ../setuppageworldeditor.cpp:208 msgctxt "SetupPageWorldEditor|" msgid "To Date" msgstr "" #: ../setuppageworldeditor.cpp:305 msgctxt "SetupPageWorldEditor|" msgid "Open File" msgstr "" #: ../setuppageworldeditor.cpp:305 msgctxt "SetupPageWorldEditor|" msgid "BigCTY (*.csv)" msgstr "" #: ../setuppageworldeditor.cpp:314 msgctxt "SetupPageWorldEditor|" msgid "Entities information has been updated." msgstr "" #: ../setuppageworldeditor.cpp:320 msgctxt "SetupPageWorldEditor|" msgid "Entities information has not been updated." msgstr "" #: ../showerrordialog.cpp:9 msgctxt "ShowErrorDialog|" msgid "KLog Message" msgstr "" #: ../softwareupdatedialog.cpp:17 msgctxt "SoftwareUpdateDialog|" msgid "Ok" msgstr "" #: ../softwareupdatedialog.cpp:35 msgctxt "SoftwareUpdateDialog|" msgid "KLog update" msgstr "" #: ../softwareupdatedialog.cpp:53 msgctxt "SoftwareUpdateDialog|" msgid "Congratulations!" msgstr "" #: ../softwareupdatedialog.cpp:53 msgctxt "SoftwareUpdateDialog|" msgid "Your KLog has been updated." msgstr "" #: ../softwareupdatedialog.cpp:53 msgctxt "SoftwareUpdateDialog|" msgid "You already have the latest version." msgstr "" #: ../startwizard.cpp:42 msgctxt "StartWizard|" msgid "KLog - The free hamradio logging program" msgstr "" #: ../startwizard.cpp:68 msgctxt "StartWizard|" msgid "Quit Setup" msgstr "" #: ../startwizard.cpp:68 msgctxt "StartWizard|" msgid "Setup is not complete yet. Are you sure you want to quit setup?" msgstr "" #: ../world.cpp:171 msgctxt "World|" msgid "Entity" msgstr "" #: ../world.cpp:172 msgctxt "World|" msgid "Continent" msgstr "" #: ../world.cpp:1205 msgctxt "World|" msgid "Reading cty.csv..." msgstr "" #: ../world.cpp:1205 msgctxt "World|" msgid "Abort reading" msgstr "" #: ../elogclublog.cpp:58 ../elogclublog.cpp:118 msgctxt "eLogClubLog|" msgid "Host not found!" msgstr "" #: ../elogclublog.cpp:64 ../elogclublog.cpp:123 msgctxt "eLogClubLog|" msgid "Timeout error!" msgstr "" #: ../elogclublog.cpp:70 msgctxt "eLogClubLog|" msgid "It seems to be a PASSWORD ERROR; check your password." msgstr "" #: ../elogclublog.cpp:72 msgctxt "eLogClubLog|" msgid "KLog - ClubLog" msgstr "" #: ../elogclublog.cpp:73 msgctxt "eLogClubLog|" msgid "It seems that your ClubLog password is not correct." msgstr "" #: ../elogclublog.cpp:74 msgctxt "eLogClubLog|" msgid "" "Please check your password in the setup. ClubLog uploads will be disabled." msgstr "" #: ../elogclublog.cpp:84 ../elogclublog.cpp:128 msgctxt "eLogClubLog|" msgid "Undefined error..." msgstr "" #: ../elogclublog.cpp:391 msgctxt "eLogClubLog|" msgid "Callsign missing" msgstr "" #: ../elogclublog.cpp:395 msgctxt "eLogClubLog|" msgid "Invalid callsign" msgstr "" #: ../elogclublog.cpp:399 msgctxt "eLogClubLog|" msgid "Skipping SWL callsign" msgstr "" #: ../elogclublog.cpp:403 msgctxt "eLogClubLog|" msgid "Callsign is your own call" msgstr "" #: ../elogclublog.cpp:407 msgctxt "eLogClubLog|" msgid "Invalid callsign with no DXCC mapping" msgstr "" #: ../elogclublog.cpp:411 msgctxt "eLogClubLog|" msgid "Updated QSO" msgstr "" #: ../elogclublog.cpp:415 msgctxt "eLogClubLog|" msgid "Invalid ADIF record" msgstr "" #: ../elogclublog.cpp:419 msgctxt "eLogClubLog|" msgid "Missing ADIF record" msgstr "" #: ../elogclublog.cpp:423 msgctxt "eLogClubLog|" msgid "Test mode - parameters ok, no action taken" msgstr "" #: ../elogclublog.cpp:427 msgctxt "eLogClubLog|" msgid "Excessive API Usage" msgstr "" #: ../elogclublog.cpp:431 msgctxt "eLogClubLog|" msgid "Internal Error" msgstr "" #: ../elogclublog.cpp:435 msgctxt "eLogClubLog|" msgid "Rejected" msgstr "" #: ../elogclublog.cpp:439 msgctxt "eLogClubLog|" msgid "QSO Duplicate" msgstr "" #: ../elogclublog.cpp:443 msgctxt "eLogClubLog|" msgid "QSO Modified" msgstr "" #: ../elogclublog.cpp:447 msgctxt "eLogClubLog|" msgid "Missing Login" msgstr "" #: ../elogclublog.cpp:451 msgctxt "eLogClubLog|" msgid "QSO OK" msgstr "" #: ../elogclublog.cpp:455 ../elogclublog.cpp:479 msgctxt "eLogClubLog|" msgid "Upload denied" msgstr "" #: ../elogclublog.cpp:459 msgctxt "eLogClubLog|" msgid "No callsign selected" msgstr "" #: ../elogclublog.cpp:463 msgctxt "eLogClubLog|" msgid "No match found" msgstr "" #: ../elogclublog.cpp:467 msgctxt "eLogClubLog|" msgid "Dropped QSO" msgstr "" #: ../elogclublog.cpp:471 msgctxt "eLogClubLog|" msgid "OK" msgstr "" #: ../elogclublog.cpp:475 msgctxt "eLogClubLog|" msgid "Login rejected" msgstr "" #: ../elogclublog.cpp:483 msgctxt "eLogClubLog|" msgid "Rejected: Callsign is your own call" msgstr "" klog-0.9.2.9/translations/klog_da.ts0000644000076700000620000052373113233376355015311 0ustar staff AboutDialog About KLog By KLog is a free logbook for hamradio operators. Please know that this is an BETA release and it may contain many bugs.<br>Backup your data before using this software! KLog has been fully rewritten from the 0.6.2 to be able to provide a cross-platform application that runs in the main operating systems (Linux, macOS & Windows) and provide new functionalities that KLog was not providing. Please provide your review in KLog's eHam review page: Find more information and the latest release at Author today Main developer KLog is developed by a very small team and you are invited to join! If you want to provide support you are welcome to join the KLog development mailing list ! You can also help us by sending bug reports or small code contributions, ideas or whatever you think may improve KLog. Authors Translators bring KLog into your language. They are really an important part of the KLog development team. If KLog is still not in your language and you want to help us, you are welcome to contact us through the Translators Privacy advisory KLog developers have included a feature that reports some user data to the KLog server with the sole purpose of identifying the number of installed versions, to focus development in one direction or another taking into account user's needs At present, the data that is provided is the following: Callsign KLog version Operating system Be aware that you can enable/disable this feature from the Misc tab in the Setup page KLog Privacy CTYPage Country data download KLog needs country data... &Download &Ignore Country data needed KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information. You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do. Click on Download to download now. KLog I can't find the host. Please check your network and try again Do you want to try again? DXCCStatusWidget Update ID Entity DXClusterWidget Click on Connect to connect to the DX-Cluster server Connect Clear Click on connect to connect to the DX-Cluster Trying to connect to the server KLog DXCluster The host was not found. Please check: - your network connection; - the host name and port settings. The connection was refused by the peer. Make sure the DXCluster server is running, and check that the host name and port settings are correct. The following error occurred: %1. Connected to server KLog message Enter your callsign to connect to the cluster: Enter your password to connect to the cluster: (Just hit enter for no password) Disconnect Not logged on, you may need to enter your callsign again. Enter here the commands to be sent to the DX-Cluster server Connection closed by the server Send DataProxy_SQLite Software version in DB is null No query failed KLog DXCC All QSOs have been updated with a DXCC. DownLoadCTY Download of cty.csv failed with the following error code: Download of cty.csv done. There is already a cty.csv file in the folder but it will be replaced with the new one. Could not open for writing. FileManager The log that you have selected contains more than just one station callsign. Please select the station callsing you want to export the log from: Station Callsign: Define Station Callsign You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: No station callsign has been selected and therefore no log will be exported Writing ADIF file... Abort writing Exporting LoTW ADIF file... QSO: Writing ADIF file... QSO: You have canceled the file export. The file will be removed and no data will be exported. Do you still want to cancel? Writing Cabrillo file... KLog: Cabrillo Log Export not implemented I am sorry but the Cabrillo Export To File feature has still not been implemented. Reading LoTW file... Abort reading There is more than one log in this logfile. All logs will be imported into the current log. Do you want to continue? Reading ADIF file... Importing ADIF file... It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported) You have cancelled the file import. The file will be removed and no data will be imported. This QSO is not including the minimum data to consider a QSO as valid!. Please edit the ADIF file and make sure that it include at least: and This QSO had: - The band missing and the following call: - The call missing but was done at this time: - The mode missing and the following call: - The date missing and the following call: - The time missing and the following call: Do you want to continue with the current file? KLog: Not all required data found! This log seems to lack of RST-TX information. Click on Yes to add a default 59 to all QSO with a similar problem. If you select NO, the QSO may not be imported. KLog: No RST TX found! This log seems to lack of RST-RX information. KLog: No RST RX found! InfoWidget 10M 15M 20M 40M 80M 160M 2M 6M 12M 17M 30M 70CM Continent Prefix CQ ITU Short Path Long Path Degree Miles Km IntroPage Welcome to KLog! Welcome to KLog! - brought to you under the terms of the GPL! Welcome to KLog This looks like it's the first time you've run KLog on this computer. KLog is a free hamradio logging program that can run on Linux macOS and Windows. It is designed to provide general purpose, DX and contest logging. It supports QSL management, import and export of ADIF and Cabrillo file formats and many other features... Before you can start using KLog, you will be asked to: Acknowledge to the terms of the license. Download the DX entities information. Enter your callsign, CQ zone, etc. and main configuration. Enjoy KLog and contact the development team if you have any suggestions! LicPage KLog License information Welcome to KLog!- brought to you under the terms of the GPL! Acknowledge Be aware that KLog is free software. LogModel Date Time QRZ Band Mode RSTtx RSTrx Comment LogWindow QSL Send QSL Rcvd &Delete Delete a QSO &Edit QSO Edit this QSO Via &bureau Send this QSL via bureau D&irect Send this QSL via direct Via bureau QSL &received via bureau Direct QSL received via direc&t You have requested to delete this QSO. Are you sure? MainWindow Recalculate Click to recalculate the award status Starting KLog &Add &Clear Status bar... DX Entity &Log Window &Score Window Watts MHz KLog Ready An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: You have selected an entity: that is different from the KLog proposed entity: Click on the prefix of the correct entity or Cancel to edit the QSO again. Click on the prefix of the right entity or Cancel to correct. QRZ of the QSO TX RST RX RST TX Exchange RX Exchange Band of the QSO Mode of the QSO Date of the QSO Time of the QSO Add the QSO to the log Clear the box Input RSTrx RSTtx QRZ STX SRX NEW MULT Invalid characters used in the QRZ Ready... The logfile has been modified. Do you want to save your changes? &File &New... &Open... &Import from ADIF... Import an ADIF file into the current log. &Save As... Export to ADIF... Export the current log to an ADIF logfile. Export all logs to ADIF... Export ALL the QSOs into one ADIF file, merging QSOs from all the logs. Export Requested QSL to ADIF... Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program). Export ADIF for LoTW... Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW! &Print Log... Print your log. KLog folder Opens the data folder of KLog. E&xit &Tools Fill in QSO data Go through the log reusing previous QSOs to fill missing information in other QSOs. Fill in DXCC data Go through the log filling QSOs without a DXCC defined. QSL tools... &Find QSO to QSL Shows QSOs for which you should send your QSL and request the DX QSL. Find My-QSLs pending to send Shows the QSOs with pending requests to send QSLs. You should keep this queue empty! &Find DX-QSLs pending to receive Shows the DX-QSL that has been requested or QSLs has been sent with no answer. &Find requested pending to receive Shows the DX-QSL that has been requested. LoTW tools... Queue all QSL to be sent of this log Mark all non sent QSOs in this log as queued to be uploaded. Queue all QSL to be sent Mark all non sent QSOs as queued to be uploaded. Mark as sent all queued QSO of this log Mark all queued QSOs in this log as sent to LoTW. Mark all queued QSO as sent Mark all queued QSOs as sent to LoTW. &Update cty.csv For updated DX-Entity data, update cty.csv. &Setup &Setup... &Help Check updates... &About... About Qt... KLog LoTW All pending QSO of this log has been marked as queued for LoTW! Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW. There was a problem to mark all pending QSO of this log as queued for LoTW! All pending QSO has been marked as queued for LoTW! The log that you have selected contains more than just one station callsign. Please select the station callsing you want to mark as sent to LoTW: Station Callsign: Define Station Callsign You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here. Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined: No station callsign has been selected and therefore no log will be marked All queued QSO of this log has been marked as sent for LoTW! There was a problem to mark all queued QSO of this log as sent for LoTW! All queued QSO has been marked as sent to LoTW! There was a problem to mark all queued QSO of this log as sent to LoTW! About... KLog update checking result Congratulations! You already have the latest version. Nothing has been saved. You have to select a valid file type. Save File ADIF file Cabrillo files Any file You can find the KLog data folder here: DUPE The selected log is not existing or it is still empty. Click Yes and KLog will open an empty log. Click No and KLog will select another log with data. You can modify the config file accordingly, if needed. It seems that there are no QSO in the database. If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help. TX Frequency in MHz. RX Frequency in MHz. Power used by the DX. Logging operator's callsign. Callsign used over the air. My QTH locator. Name of the DX. QTH of the DX. Locator of the DX. QRZ of the QSO. TX RST. RX RST. TX Exchange. RX Exchange. Band of the QSO. Mode of the QSO. Date of the QSO. Time of the QSO. Add the QSO to the log. Clears the QSO entry. Number of confirmed DXCC entities. Number of worked DXCC entities. Number of confirmed WAZ zones. Number of worked WAZ zones. Number of confirmed local references. Number of worked local references. Number of confirmed QSOs. Number of worked QSOs. Number of QSOs worked on the selected year. Number of DXCC worked on the selected year. Number of CQ Zones worked on the selected year. Score for the DXMarathon on the selected year. Select the year you want to check. Status of the DX entity. Name of the DX entity. Name QTH Locator Power(rx) RST(tx) RST(rx) Freq TX Freq RX QSO QSL eQSL Comment Others My Data Satellite QSOs DXCC CQ Score DX-Marathon Info Award Confirmed Worked WAZ Local Awards Search Log DX-Cluster Save ADIF File LoTW logfile has been properly exported! Remember to: Before uploading: sign the LoTW log; and After uploading: mark as sent all the queued QSO (LoTW Tools). There was no QSO to be exported. If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as: Q - Queued There was an error while exporting the LoTW. The log has not been exported! Save Cabrillo File Cabrillo (*.log) Open File &Modify -- - Needed for DXMarathon Filling QSOs... Abort filling Filling QSOs... QSO: Number Date Time Band Mode Print Log Printing the log... Abort printing Printing the log... QSO: An unexpected error ocurred!! If the problem persists, please contact the developers for analysis: Error in function Error code Error text Failed query Do you want to keep showing errors? MainWindowInputComment Add a comment for this QSO MainWindowInputEQSL Date of the ClubLog upload. Date of the eQSL sending. Date of the eQSL reception. Date of the LoTW sending. Date of the LoTW reception. Status on ClubLog. Status of the eQSL sending. Status of the eQSL reception. Status of the LoTW sending. Status of the LoTW reception. ClubLog eQSL Sent eQSL Rec LoTW Sent LoTW Rec MainWindowInputOthers Primary Div Secondary Div IOTA Entity Propagation mode Select the primary division for this QSO Select the secondary division for this QSO Select the entity for this QSO Select the propagation mode for this QSO Select the IOTA continent for this QSO Select the IOTA reference number for this QSO Not Identified Not - Not Identified MainWindowInputQSL QSL Sent QSL Rec QSL Via QSL Msg Status of the QSL sending. Status of the QSL reception. QSL sending information. QSL reception information. Date of the QSL sending. Date of the QSL reception. Message of the QSL. QSL via information. MainWindowMyDataTab Watt Keep this data Data entered in this tab will be copied into the next QSO Power used for the QSO in watts Logging operator's callsign Callsign used over the air My QTH locator Power Operator Station Callsign My Locator MainWindowSatTab Keep this data Data entered in this tab will be copied into the next QSO Other - Sat not in the list Name of the Satellite if not in the list. Select: " " to enable this box. (format like AO-51) Satellite mode used Select the satellite you are using UpLink band DownLink band Locator of the DX station. This box will is syncronized with the Locator box in the QSO tab. UpLink DownLink Satellite Mode DX Locator Other MHz Not Sat QSO KLog has detected a satellite name that it does not recognise. If it should use one of the names of known satellites instead, please select it from the list. Alternatively, please contact the development team to add the new satellite name. The satellite you have in your QSO is: Please know that the satellite name will not be saved if it is not in the list so that information may be lost! QObject New One, work it! Needed, work it! Worked but not confirmed Confirmed Not identified Database Error KLog DB needs to be upgraded. Do you want to upgrade it now? If DB is not upgraded KLog may not work properly. KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you. KLog: Enter Station callsign Enter the station callsign used in this log Station Callsign All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK. Updating mode information... Abort updating QSO: Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel? Updating bands information... Updating bands information in %1 status... Progress: Updating mode information in %1 status... Updating DXCC award information... Updating DXCC Award information... Updating WAZ award information... Updating DXCC information... Install wizard was canceled before completing... Do you want to remove the KLog dir from your disk? Your KLog dir has been removed Thank you for running KLog! I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk. Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk. Remember that your KLog dir is on your system... SearchWidget &Clear &Export Highlighted &Select All &Search All Clear the searches. Export the search result to an ADIF file. Select/Unselect all the QSOs shown. Search in the log. Search in all logs. Enter the QRZ to search for. Search results. QRZ Date/Time Band Mode QSL Sent QSL Rcvd Station Callsign ID &Clear selection Save File QSL Send &Delete Delete a QSO &Edit QSO Edit this QSO Via &bureau Send this QSL via bureau D&irect Send this QSL via direct &Request my QSL Mark my QSL as requested Via Direct && mark DX QSL as requested Send this QSL via direct & mark DX QSL as requested Via Bureau && mark DX QSL as requested Send this QSL via bureau & mark DX QSL as requested &Request the QSL Mark the QSL as requested Via bureau && mark my QSL as requested QSL received via bureau & mark my QSL as requested Via bureau QSL received via bureau Direc&t && mark as my QSL requested QSL received via direct & mark my QSL as requested Direc&t QSL received via direct You have requested to delete the QSO with: Are you sure? Needed QSO to send the QSL My QSL requested to be sent DX QSL pending to be received SetupDialog My Data Bands/Modes DX-Cluster Colors Misc World Editor Logs ClubLog Cancel OK Config Dialog User data D&X-Cluster You need to enter at least one log in the Logs tab. World DB has not been moved to new path Go to the Misc tab and click on Move DB or the DB will not be moved to the new location. You need to enter at least a valid QRZ. User tab and enter valid QRZ. You have not selected the kind of log you want. You will be redirected to the Log tab. Please add and select the kind of log you want to use. SetupEntityDialog Entity Name of the Entity CQ CQ zone ITU ITU zone Latitude Longitude of the Entity Longitude UTC Local time difference to UTC Main prefix Main prefix of the entity ARRL ID Prefixes Comma separated possible prefixes, e.g. EA1, EA2, ... Date of the deletion Deleted Cancel OK Entity Dialog SetupPageBandMode Bands Modes SetupPageClubLog &Callsign ClubLog &password ClubLog &email Enter the email you used to register in ClubLog. Enter the callsign you used to register in ClubLog. Enter your password in ClubLog. &Send QSOs in real time &Activate ClubLog Use QSO Station &Callsign Send each QSO to ClubLog in real time, as they are added (or modified) in KLog Starts the ClubLog support in KLog Use the Station Callsign defined in each QSO instead of the one defined here SetupPageColors New One Needed in this band Worked in this band Confirmed in this band Default Choose a color SetupPageDxCluster Add Delete Show &HF spots Show V/&UHF spots Show W&ARC spots Show &worked spots Show &confirmed spots Show ANN/&FULL messages Show WW&V messages Show WC&Y messages DX Spots Messages KLog: Add a DXCluster server Add the address followed by the :port Example: dxfun.com:8000 If no port is specified, 41112 will be used by default: SetupPageLogs &New &Edit &Remove Add a new log Edit the selected log Remove the selected log Select the log you want to open KLog Do you really want to remove this log? All the QSOs from this log will be also deleted... Log has not been removed. (#3) Log has not been removed. (#2) Log has not been removed. (#1) ID Date Station Callsign Operators Comments Type An error has occurred showing the following error code: KLog - SetupPageLogs SetupPageLogsNew &Date &Station Callsign &Operators Comm&ent &Ok &Cancel Select categories Callsign used for this log Comma separated list of operators: callsign1, callsign2 Start date of this log Add a comment about this log &Type of Operation Select the kind of operation for this log &Mode Category Select the mode category O&perators Category Select the operators category &Assisted Category Select the assisted category Po&wer Category Select the power category &Bands Category Select the bands category O&verlay Select the Overlay category Categories not OK You need to enter a valid QRZ in the Station Callsign box. The log will not be opened. You selected an invalid combination. The log will not be opened. Categories OK SetupPageMisc &Imperial system &Log in real time &Time in UTC &Save ADIF on exit Use this &default filename Mark &QSO to send QSL when QSL is received Complete QSO with previous data Show the Station &Callsign used in the search box &Reset to My Data for all QSOs &Check for new versions automatically &Provide Info for statistics Browse Move DB QSOs will be marked as pending to send a QSL if you receive the DX QSL and have not sent yours. The search box will show also the callsign on the air to do the QSO. All the data from the My Data tab will be used or data from the previous QSO will be maintained. Check if there is a new release of KLog available every time you start KLog. If new version checking is selected, KLog will send the developer your callsign, KLog version & Operating system to help in improving KLog. Check it for Imperial system (Miles instead of Kilometres). Select to use real time. Select to use UTC time. Select if you want to save to ADIF on exit. Select to use the following name for the logfile without being asked for it again. Complete the current QSO with previous QSO data. This is the default file where ADIF data will be saved. This is the directory where the database (logbook.dat) will be saved. Click to change the default ADIF file. Click to change the path of the database. Click to move the DB to the new directory. Open File Select Directory This is the directory where DB (logbook.dat) will be saved. Please specify an existing directory where the database (logbook.dat) will be saved. File moved File copied File NOT copied The target directory does not exist. Please select an existing directory. SetupPageUserDataPage &Personal data Station &data Enter your name Enter your address - 1st line Enter your address - 2nd line Enter your address - 3rd line Enter your address - 4th line Enter your city Enter your zip code Enter your province or state Enter your country &Name &Address Cit&y &Zip Code Pro&v/State Countr&y Enter your information for rig Enter your information for antenna Enter your power information &Rig 1 R&ig 2 Ri&g 3 Antenna &1 Antenna &2 Antenna &3 Po&wer Enter the station callsign that will be used for logging Enter the operators (comma separated if more than one). Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign. &QRZ &Operators &CQ Zone &ITU Zone &Locator &Locator (not valid) SetupPageWorldEditor An entities information file (cty.csv) has been detected in your KLog folder and will be loaded. No entities information file (cty.csv) has been detected in your KLog folder. KLog will not be able to show entities information. Prefix Entity ARRL ID Continent CQ Zone ITU Zone UTC Latitude Longitude Deleted Since Date To Date Open File BigCTY (*.csv) Entities information has been updated. Entities information has not been updated. ShowErrorDialog KLog Message SoftwareUpdateDialog Ok KLog update Congratulations! Your KLog has been updated. You already have the latest version. StartWizard KLog - The free hamradio logging program Quit Setup Setup is not complete yet. Are you sure you want to quit setup? World Entity Continent Reading cty.csv... Abort reading eLogClubLog Host not found! Timeout error! It seems to be a PASSWORD ERROR; check your password. KLog - ClubLog It seems that your ClubLog password is not correct. Please check your password in the setup. ClubLog uploads will be disabled. Undefined error... Callsign missing Invalid callsign Skipping SWL callsign Callsign is your own call Invalid callsign with no DXCC mapping Updated QSO Invalid ADIF record Missing ADIF record Test mode - parameters ok, no action taken Excessive API Usage Internal Error Rejected QSO Duplicate QSO Modified Missing Login QSO OK Upload denied No callsign selected No match found Dropped QSO OK Login rejected Rejected: Callsign is your own call klog-0.9.2.9/locator.h0000644000076700000620000000636013233376355012426 0ustar staff/*************************************************************************** locator.h - description ------------------- begin : vie feb 7 2003 copyright : (C) 2003 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #ifndef LOCATOR_H #define LOCATOR_H #include #include const double PI = 3.141592654; //http://en.wikipedia.org/wiki/Pi const bool LATITUDE = false; const bool LONGITUDE = true; const double EARTH_RADIUS = 6371; //http://en.wikipedia.org/wiki/Earth_radius const bool RADIAN = 180.0/PI; const double DEG_TO_RAD = PI/180.0; const double KM_IN_A_MILE = 1.609344; class Locator{ public: Locator(); ~Locator(); bool isValidLocator(const QString& tlocator); double getLat(const QString& tlocator); double getLon(const QString& tlocator); QString getLocator(const double lon1, const double lat1) const; int getBeam(const double lon1, const double lat1, const double lon2, const double lat2); int getBeamBetweenLocators (const QString& tlocator1, const QString& tlocator2); int getDistance(const double lon1, const double lat1, const double lon2, const double lat2, const bool _imperialSystem); int getDistanceBetweenLocators (const QString& tlocator1, const QString& tlocator2, const bool _imperialSystem); //int getDistanceMilles(const double lon1, const double lat1, const double lon2, const double lat2); void degTodms(const double deg); double dmsTodeg (int deg, int min, int sec); bool checkCoords(const double lon1, const double lat1); private: //bool valid; QString myLocator; QString testLocator; QString otherLocator; QChar theChar; //double my_lon, my_lat, other_lon, other_lat, beam, testNumb; int ideg, imin, isec; }; #endif klog-0.9.2.9/awarddxmarathon.cpp0000644000076700000620000000577613237613050014502 0ustar staff/*************************************************************************** awarddxmarathon.cpp - description ------------------- begin : feb 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "awarddxmarathon.h" //#include DXMarathon::DXMarathon(DataProxy *dp) { //qDebug() << "DXMarathon::DXMarathon" << endl; dataProxy = dp; //qDebug() << "DXMarathon::DXMarathon - END" << endl; } int DXMarathon::getDXMarathonQSO(const int _year, const int _logNumber) { //qDebug() << "DXMarathon::getDXMarathonQSO: " << QString::number(_year) << endl; return dataProxy->getQSOonYear(_year, _logNumber); } int DXMarathon::getDXMarathonDXCC(const int _year, const int _logNumber) { //qDebug() << "DXMarathon::getDXMarathonDXCC: " << QString::number(_year) << endl; return dataProxy->getDXCConYear(_year, _logNumber); } int DXMarathon::getDXMarathonCQ(const int _year, const int _logNumber) { //qDebug() << "DXMarathon::getDXMarathonCQ: " << QString::number(_year) << endl; return dataProxy->getCQzonYear(_year, _logNumber); } int DXMarathon::getDXMarathonScore(const int _year, const int _logNumber) { //qDebug() << "DXMarathon::getDXMarathonScore: " << QString::number(_year) << endl; return ( getDXMarathonDXCC(_year, _logNumber) + getDXMarathonCQ(_year, _logNumber)); } bool DXMarathon::neededForDXMarathon(const int _dxcc, const int _cq, const int _year, const int _logNumber) { return dataProxy->newDXMarathon(_dxcc, _cq, _year, _logNumber); } klog-0.9.2.9/awards.h0000644000076700000620000001614113233376355012242 0ustar staff#ifndef AWARDS_H #define AWARDS_H /*************************************************************************** awards.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include // For the "tr" function #include #include #include #include #include #include #include #include #include #include #include "world.h" #include "awarddxmarathon.h" #include "dataproxy.h" #include "utilities.h" class QProgressDialog; class Awards : public QObject { Q_OBJECT //friend class World; public: Awards(DataProxy *dp); ~Awards(); void setAwards(const int _qsoId); void setAwards(const int _dxcc, const int _waz, const int _band, const int _mode, const int _workedOrConfirmed, const int _logNumber, const int _qsoId); /* _workedOrConfirmed = 0 Set as Worked _workedOrConfirmed = 1 Set as Confirmed */ void setManageModes(const bool _manageModes=false); // Defines if the mode is to be taken into account when calculating an award void recalculateAwards(); //void recalculateDXCC(const int _logNumber); //void setAwards(const int _qsoId, bool modify); int getDXCCWorked(const int _logNumber); int getDXCCConfirmed(const int _logNumber); int getWAZWorked(const int _logNumber); int getWAZConfirmed(const int _logNumber); int getQSOsInLog(const int _logNumber); bool getIsDXCCConfirmed(const int _dxcc, const int _logNumber); bool isThisSpotConfirmed(const QStringList _qs); QString checkIfValidIOTA(const QString _tiota); //TODO: There is an equivalent function in the MainWindowInputOthers class. I should use only one! int getEntityDXStatus (const int _enti, const int _bandid, int _modeid = -1, int _log = -1); int getDXStatus (const QStringList _qs); QString getDXStatusString (const int _status); // Needs to be called with the output of getDXStatus QString getDXCCStatusBand(const int _dxcc, const int _band, const int _logNumber=0); // Returns -, W or C (Not worked, worked, Confirmed) void setColors (const QString _newOne, const QString _needed, const QString _worked, const QString _confirmed, const QString _default); QColor getQRZDXStatusColor(const QStringList _qs); // Receives Entity, band, mode & log QColor getDefaultColor(); int getDXMarathonQSO(const int _year, const int _logNumber); int getDXMarathonDXCC(const int _year, const int _logNumber); int getDXMarathonCQ(const int _year, const int _logNumber); int getDXMarathonScore(const int _year, const int _logNumber); bool isDXMarathonNeed(const int _dxcc, const int _cq, const int _year, const int _logNumber); // Receives: QStringList _qs; //_qs << QRZ << BandId << lognumber; /* 0 - New one. 1 - Worked but not confirmed: New one in this band. 2 - Worked but not confirmed: Worked in this band. 3 - Confirmed: New one in this band. 4 - Confirmed: Worked in this band. 5 - Confirmed: Confirmed in this band. 6 - Default: Not applicable */ private: void setAwardDXCC(const int _qsoId); //bool setAwardDXCC(const int _dxcc, const int _band, const int _mode, const QString _workedOrConfirmed, const int _logNumber, const int _qsoId); int setAwardDXCCst(const int _dxcc, const int _band, const int _mode, const bool _confirmed, const int _logNumber, const int _qsoId); int setAwardDXCCConfirmed(const int _band, const int _mode, const int _dxcc, const int _newQSOid); // Changes the status of a DXCC from worked to confirmed int setDXCCToQSO(const int _dxcc, const int _qsoid); // Defines the DXCC in a QSO int setCQToQSO(const int _cqz, const int _qsoid); // Defines the CQ zone in a QSO int dxccStatusBandMode(const int _ent, const int _band, const int _mode, const int _logNumber, bool _checkingMode); //-1 error / 0 Not worked / 1 worked / 2 confirmed int dxccStatus(const int _ent, const int _logNumber); //-1 error / 0 Not worked / 1 worked / 2 confirmed /* _confirmed = 0 Set as Worked _cConfirmed = 1 Set as Confirmed */ /**/ int dxccStatusBand(const int _ent, const int band, const int _logNumber); //-1 error / 0 Not worked / 1 worked / 2 confirmed int dxccStatusMode(const int _ent, const int band, const int _logNumber); //-1 error / 0 Not worked / 1 worked / 2 confirmed /**/ void setAwardWAZ(const int _qsoId); //bool setAwardWAZ(const int _cqz, const int _band, const int _mode, const QString _workedOrConfirmed, const int _logNumber, const int _qsoId); int setAwardWAZst(const int _cqz, const int _band, const int _mode, const bool _confirmed, const int _logNumber, const int _qsoId); /* _confirmed = 0 Set as Worked _confirmed = 1 Set as Confirmed */ //int getProgresStepForDialog(int totalSteps); QColor newOneColor; // QColor neededColor; // QColor workedColor; // QColor confirmedColor; // QColor defaultColor; World *world; DataProxy *dataProxy; DXMarathon *dxMarathon; Utilities *util; typedef QMultiHash DXStatus; DXStatus dxccWorked, dxccConfirmed, wazWorked, wazConfirmed; bool manageModes; signals: void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution void awardDXCCUpdated(); }; #endif // AWARDS_H klog-0.9.2.9/locator.cpp0000644000076700000620000002630213233376355012757 0ustar staff/*************************************************************************** locator.cpp - description ------------------- begin : vie feb 7 2003 copyright : (C) 2003 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "locator.h" #include Locator::Locator(){ ideg = 0; imin = 0; isec = 0; } Locator::~Locator(){ } bool Locator::isValidLocator(const QString& tlocator){ /* -------------- Subroutine ----------------------- Check valid locator (VALID: AA00AA -> RR99XX Input : char *locator = 4 or 6 characters word wide locator. returned value == -1 No error. (Valid locator). returned value == 0 Error. (Invalid locator). Note: also string "END" is considered a valid locator, but returned value is -2. ------------------------------------------------- */ //qDebug() << "Locator::isValidLocator: " << tlocator << endl; int lenght_of_locator; testLocator ="A"; testLocator = tlocator.toUpper(); lenght_of_locator = testLocator.length(); if (lenght_of_locator == 4){ testLocator = testLocator +"LM"; lenght_of_locator = 6; } if (lenght_of_locator != 6) { return false; }else{ theChar = testLocator.at(0); if (!theChar.isLetter()){ //First letter is not a valid letter return false; } if ((theChar<'A') && (theChar>'R') ){ //First letter is not a valid letter return false; } theChar = testLocator.at(1); if (!theChar.isLetter()){ //Second letter is not a valid letter return false; } if ((theChar<'A') && (theChar>'R') ){ //Second letter is not a valid letter return false; } theChar = testLocator.at(2); if (!theChar.isDigit()){ //Second letter is not a number return false; } theChar = testLocator.at(3); if (!theChar.isDigit()){ //Second letter is not a number return false; } theChar = testLocator.at(4); if (!theChar.isLetter()){ //First letter is not a valid letter return false; } if ((theChar<'A') && (theChar>'X') ){ //First letter is not a valid letter return false; } theChar = testLocator.at(5); if (!theChar.isLetter()){ //Second letter is not a valid letter return false; } if ((theChar<'A') && (theChar>'X') ){ //Second letter is not a valid letter return false; } } return true; } double Locator::getLat(const QString& tlocator){ //qDebug() << "Locator::getLat: " << tlocator; if (!isValidLocator(tlocator)) { return 0.0; } if (tlocator.length() == 2) { return (((tlocator.at(1)).toLatin1() - 65) * 10) - 90; } if (tlocator.length() == 4) { return (((tlocator.at(1)).toLatin1() - 65) * 10) + ((tlocator.at(3)).toLatin1() - 48) - 90; } else if (tlocator.length()== 6) { return (((tlocator.at(1)).toLatin1() - 65) * 10) + ((tlocator.at(3)).toLatin1() - 48) + (((tlocator.at(5)).toLatin1() - 65 + 0.5) / 24) - 90; } else { return 0.0; } } double Locator::getLon(const QString& tlocator) { //qDebug() << "Locator::getLon: " << tlocator; if (!isValidLocator(tlocator)) { return 0.0; } if (tlocator.length() == 2) { return (((tlocator.at(0)).toLatin1() - 65) * 20) - 180; } if (tlocator.length() == 4) { return (((tlocator.at(0)).toLatin1() - 65) * 20) + (((tlocator.at(2)).toLatin1() - 48) * 2) - 180; } else if (tlocator.length()== 6) { return (((tlocator.at(0)).toLatin1() - 65) * 20) + (((tlocator.at(2)).toLatin1() - 48) * 2) + (((tlocator.at(4)).toLatin1() - 65 + 0.5) / 12) - 180; } else { return 0.0; } } int Locator::getBeam(const double lon1, const double lat1, const double lon2, const double lat2){ double lon_a,lat_a,lon_b,lat_b, bearing; //qDebug() << "Locator::getBeam1: " << QString::number(lon1) << "/" << QString::number(lat1) << endl; //qDebug() << "Locator::getBeam2: " << QString::number(lon2) << "/" << QString::number(lat2) << endl; lon_a=lon1*PI/180; // Convert degrees to radians lat_a=lat1*PI/180; lon_b=lon2*PI/180; lat_b=lat2*PI/180; //earing_Distance( double lon_a, double lat_a, /* Lon/Lat of point A */ // double lon_b, double lat_b, /* Lon/Lat of point B */ // double *bearing, double *distance )/* From A to B */ //{ double gc_arc, cos_gc_arc, /* Great circle arc A to B */ cos_bearing, sin_bearing, /* cos/sin of bearing A to B */ lon_diff; /* Difference in longitude of B from A */ /* Longitude differnce of B from A */ lon_diff = lon_b - lon_a; /* Calculate great circle distance A to B */ cos_gc_arc = cos(lon_diff)*cos(lat_a)*cos(lat_b) + sin(lat_a)*sin(lat_b); gc_arc = acos( cos_gc_arc ); /* Distance in km */ // *distance = eradius * gc_arc; /* Calculate bearing A to B */ cos_bearing = sin(lat_b) - sin(lat_a) * cos_gc_arc; sin_bearing = sin(lon_diff) * cos(lat_a) * cos(lat_b); bearing = atan2(sin_bearing, cos_bearing); /* Correct negative (anticlockwise) bearings */ if( bearing < 0.0 ) { bearing = (2*PI) + bearing; } bearing = 360 - (180/PI*bearing); bearing = 360 - bearing; //qDebug() << "Locator::getBeam: " << QString::number(bearing) << endl; /* Convert to degrees */ return (int)bearing; } int Locator::getDistance(const double lon1, const double lat1, const double lon2, const double lat2, const bool _imperialSystem){ //http://en.wikipedia.org/wiki/Haversine_formula //qDebug() << "Locator::getDistanceKilometres: MyPos("<< QString::number(lon1) << "/" // << QString::number(lat1) << ") - DxPos(" << QString::number(lon2) << "/" << QString::number(lat2) << ")" << endl; double lo1,la1,lo2,la2; // TODO: Is it needed to check if the longitude and latitude are correct and/or between the magins? // if (!( (checkCoords(lon1, lat1) ) && (checkCoords(lon2, lat2)) )) // return 0; lo1=lon1* DEG_TO_RAD; // Convert degrees to radians la1=lat1* DEG_TO_RAD; lo2=lon2* DEG_TO_RAD; la2=lat2* DEG_TO_RAD; if (!_imperialSystem){ //qDebug() << "Locator::getDistance (Km): " << QString::number((int)(acos(cos(la1)*cos(lo1)*cos(la2)*cos(lo2)+cos(la1)*sin(lo1)*cos(la2)*sin(lo2)+sin(la1)*sin(la2)) * EARTH_RADIUS)) << endl; return (int)(acos(cos(la1)*cos(lo1)*cos(la2)*cos(lo2)+cos(la1)*sin(lo1)*cos(la2)*sin(lo2)+sin(la1)*sin(la2)) * EARTH_RADIUS); }else{ // In milles //qDebug() << "Locator::getDistance (Milles): " << QString::number(((int)(acos(cos(la1)*cos(lo1)*cos(la2)*cos(lo2)+cos(la1)*sin(lo1)*cos(la2)*sin(lo2)+sin(la1)*sin(la2)) * EARTH_RADIUS))* 0.62137) << endl; return ((int)(acos(cos(la1)*cos(lo1)*cos(la2)*cos(lo2)+cos(la1)*sin(lo1)*cos(la2)*sin(lo2)+sin(la1)*sin(la2)) * EARTH_RADIUS)) * 0.62137; } } bool Locator::checkCoords(const double lon1, const double lat1){ //qDebug() << "Locator::checkCoords" ; // Checks if a coordinates is correct. if ((lat1 > 90.0 || lat1 < -90.0) && (lon1 > 180.0 || lon1 < -180.0)){ return true; }else{ return false; } } QString Locator::getLocator(const double lon1, const double lat1) const{ /* -------------- Subroutine ----------------------- Calculate locator from longitude and latitude Input : lon = Longitude in decimal degrees (+ = West; - = East). lat = Latitude in decimal degrees (+ = North; - = South). Output: locator = 6 characters world wide locator. ------------------------------------------------- */ //qDebug() << "Locator::getLocator: (" << QString::number(lon1) << "/" << QString::number(lat1) << ")" << endl; QString locat = ""; //NO locator double lo, la; int alo,bla,clo,dla,elo,fla; lo=(-lon1+180)/20; la = (lat1+90)/10; alo=(int)floor(lo); bla=(int)floor(la); lo=(lo-(double)alo)*10; la=(la-(double)bla)*10; clo = (int)floor(lo); dla = (int)floor(la); elo = (int)floor((lo-(double)clo)*24); fla = (int)floor((la-(double)dla)*24); //TODO: Test if locators are calculated correctly. // generation function has been changed because of the QT4 migration locat = locat + QChar(alo+'A'); locat = locat + QChar(bla+'A'); locat = locat + QChar(clo+'0'); locat = locat + QChar(dla+'0'); locat = locat + QChar(elo+'A'); locat = locat + QChar(fla+'A'); // locat.at(0)=QChar(alo+'A'); // locat.at(1)=QChar(bla+'A'); // locat.at(2)=QChar(clo+'0'); // locat.at(3)=QChar(dla+'0'); // locat.at(4)=QChar(elo+'A'); // locat.at(5)=QChar(fla+'A'); return locat; } void Locator::degTodms(const double deg){ double temp; double ddeg; ddeg = 0; ddeg += 1.0/7200.0; /* Round-up to 0.5 sec */ ideg = (int)ddeg; temp = ( deg - (double)ideg ) * 60.0; imin = (int)temp; temp = ( temp - (double)imin ) * 60.0; isec = (int)(temp); } double Locator::dmsTodeg (int deg, int min, int sec){ return (double)deg + (double)min/60.0 + (double)sec/3600.0; } int Locator::getBeamBetweenLocators (const QString& tlocator1, const QString& tlocator2) { //qDebug() << "Locator::getBeamBetweenLocators: " << tlocator1 << "/" << tlocator2 << endl; if ( !(isValidLocator(tlocator1) && isValidLocator(tlocator2) ) ) { return -1; } else { double lon1 = getLon(tlocator1); double lon2 = getLon(tlocator2); double lat1 = getLat(tlocator1); double lat2 = getLat(tlocator2); return getBeam(lon1, lat1, lon2, lat2); } } int Locator::getDistanceBetweenLocators (const QString& tlocator1, const QString& tlocator2, const bool _imperialSystem) { if ( !(isValidLocator(tlocator1) && isValidLocator(tlocator2) ) ) { return -1; } else { double lon1 = getLon(tlocator1); double lon2 = getLon(tlocator2); double lat1 = getLat(tlocator1); double lat2 = getLat(tlocator2); return getDistance(lon1, lat1, lon2, lat2, _imperialSystem); //return getBeam(lon1, lat1, lon2, lat2); } } klog-0.9.2.9/mainwindowmydatatab.h0000644000076700000620000000706213233376355015026 0ustar staff#ifndef MAINWINDOWMYDATATAB_H #define MAINWINDOWMYDATATAB_H /*************************************************************************** mainwindowmydatatab.h - description ------------------- begin : jul 2016 copyright : (C) 2016 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implement the tab of the mainwindow that supports MY DATA // #include #include //#include "dataproxy.h" //#include "dataproxy_sqlite.h" class MainWindowMyDataTab : public QWidget { Q_OBJECT public: explicit MainWindowMyDataTab(QWidget *parent = 0); ~MainWindowMyDataTab(); void createUI(); void setData(const double _power, const QString _stationQRZ, const QString _operator, const QString _myLocator); void setSetupMyPower(const double _power); void setSetupOperator(const QString _op); void setSetupStationQRZ(const QString _op); void setSetupMyLocator(const QString _op); void setMyPower(const double _power); double getMyPower(); //double getLastPower(); void setOperator(const QString _op); QString getOperator(); //QString getLastOperator(); void setStationQRZ(const QString _op); QString getStationQRZ(); //QString getLastStationQRZ(); void setMyLocator(const QString _op); QString getMyLocator(); //QString getLastMyLocator(); void show(); //Shows the values into the widget void clear(const bool _keepMyData); private: //void setLastOperator(const QString _op); //void setLastStationQRZ(const QString _op); //void setLastMyLocator(const QString _op); //void setLastPower(const double _power); QDoubleSpinBox *myPowerSpinBox; QString stationQRZ, operatorQRZ, myLocator; //Not changed during normal operations. They come from the configuration QString lastOperatorQRZ, lastStationQRZ, lastMyLocator; // Change dinamically during execution double myPower, lastPower; QLineEdit *operatorLineEdit, *stationCallSignLineEdit, *myLocatorLineEdit; QRadioButton *keepThisDataForNextQSORadiobutton; }; #endif // MAINWINDOWMYDATATAB_H klog-0.9.2.9/contest.h0000644000076700000620000000466613233376355012451 0ustar staff#ifndef CONTEST_H #define CONTEST_H /*************************************************************************** contest.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include #include class Contest : public QObject { Q_OBJECT public: Contest(); Contest(const QStringList _qs); ~Contest(); virtual bool isMultiplier(const QStringList _qs); virtual int getQSOPoints(const QStringList _qs); virtual bool saveFileToSend(const QString& _fileName); virtual int getTotalScore(); virtual int getMultipliers(); virtual int getPoints(); private: int points; int multipliers; int constrid; // Just an id for the constructor to check who is being executed at one specific time }; #endif // CONTEST_H klog-0.9.2.9/setuppageclublog.cpp0000644000076700000620000001772413233376355014671 0ustar staff/*************************************************************************** setuppageclublog.cpp - description ------------------- begin : apt 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include "setuppageclublog.h" SetupPageClubLog::SetupPageClubLog(QWidget *parent) : QWidget(parent) { //qDebug() << "SetupPageClubLog::SetupPageClubLog" << endl; clubLogActive = false; call = QString(); email = QString(); pass = QString(); emailLineEdit = new QLineEdit; callLineEdit = new QLineEdit; passwordLineEdit = new QLineEdit; callLabel = new QLabel(tr("&Callsign")); passwordLabel = new QLabel(tr("ClubLog &password")); emailLabel = new QLabel(tr("ClubLog &email")); callLabel->setBuddy(callLineEdit); passwordLabel->setBuddy(passwordLineEdit); emailLabel->setBuddy(emailLineEdit); emailLineEdit->setToolTip(tr("Enter the email you used to register in ClubLog.")); callLineEdit->setToolTip(tr("Enter the callsign you used to register in ClubLog.")); passwordLineEdit->setToolTip(tr("Enter your password in ClubLog.")); //passwordLineEdit->setEchoMode(QLineEdit::PasswordEchoOnEdit); sendInRealTimeCheckBox = new QCheckBox(tr("&Send QSOs in real time"), this); clubLogActiveCheckBox = new QCheckBox(tr("&Activate ClubLog"), this); useQSOStationCallCheckBox = new QCheckBox(tr("Use QSO Station &Callsign"), this); sendInRealTimeCheckBox->setToolTip(tr("Send each QSO to ClubLog in real time, as they are added (or modified) in KLog")); clubLogActiveCheckBox->setToolTip(tr("Starts the ClubLog support in KLog")); useQSOStationCallCheckBox->setToolTip(tr("Use the Station Callsign defined in each QSO instead of the one defined here")); QHBoxLayout *callSLayout = new QHBoxLayout; callSLayout->addWidget(callLineEdit); callSLayout->addWidget(useQSOStationCallCheckBox); QGridLayout *glayout = new QGridLayout; glayout->addWidget(callLabel, 0, 0); glayout->addWidget(emailLabel, 1, 0); glayout->addWidget(passwordLabel, 2, 0); glayout->addLayout(callSLayout, 0, 1); //glayout->addWidget(callLineEdit, 0, 1); glayout->addWidget(emailLineEdit, 1, 1); glayout->addWidget(passwordLineEdit, 2, 1); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(clubLogActiveCheckBox); layout->addLayout(glayout); layout->addWidget(sendInRealTimeCheckBox); setLayout(layout); //connect(newOneColorButton, SIGNAL(clicked()), this, SLOT(slotNewOneColorButtonClicked()) ); connect(clubLogActiveCheckBox, SIGNAL(toggled(bool) ), this, SLOT(slotClubLogActive(bool))); connect(useQSOStationCallCheckBox, SIGNAL(toggled(bool) ), this, SLOT(slotUseStationCall(bool))); //connect(sendInRealTimeCheckBox, SIGNAL(toggled(bool) ), this, SLOT(slotClubLogActive(bool))); slotClubLogActive(clubLogActive); //qDebug() << "SetupPageClubLog::SetupPageClubLog - END" << endl; } SetupPageClubLog::~SetupPageClubLog() { } void SetupPageClubLog::setEmail(const QString c) { emailLineEdit->setText(c); } void SetupPageClubLog::setPassword(const QString c) { passwordLineEdit->setText(c); } void SetupPageClubLog::setCallsign(const QString c) { callLineEdit->setText(c.toUpper()); } QString SetupPageClubLog::getEmail() { return (emailLineEdit->text()); } QString SetupPageClubLog::getPassword() { return passwordLineEdit->text(); } QString SetupPageClubLog::getCallsign() { return (callLineEdit->text()).toUpper(); } QString SetupPageClubLog::getUseQSOStationCallsign() { if (useQSOStationCallCheckBox->isChecked() ) { return "True"; } else { return "False"; } } void SetupPageClubLog::setUseStationCall(const QString _s) { if ( (_s.toUpper()) == "FALSE") { useQSOStationCallCheckBox->setChecked(false); } else { useQSOStationCallCheckBox->setChecked(true); } } QString SetupPageClubLog::getClubLog() { if (clubLogActiveCheckBox->isChecked() ) { return "True"; } else { return "False"; } } void SetupPageClubLog::setClubLog(const QString _s) { if ( (_s.toUpper()) == "FALSE") { clubLogActive = false; clubLogActiveCheckBox->setChecked(false); } else { clubLogActive = true; clubLogActiveCheckBox->setChecked(true); } } void SetupPageClubLog::slotUseStationCall(bool _s) { //qDebug() << "SetupPageClubLog::slotUseStationCall" << endl; if (useQSOStationCallCheckBox->isChecked()) { callLineEdit->setEnabled(false); callLabel->setEnabled(false); } else { callLineEdit->setEnabled(true); callLabel->setEnabled(true); } } void SetupPageClubLog::slotClubLogActive(bool _s) { //qDebug() << "SetupPageClubLog::slotClubLogActive" << endl; if (_s) { //qDebug() << "SetupPageClubLog::slotClubLogActive TRUE" << endl; callLabel->setEnabled(true); emailLabel->setEnabled(true); passwordLabel->setEnabled(true); callLineEdit->setEnabled(true); emailLineEdit->setEnabled(true); passwordLineEdit->setEnabled(true); sendInRealTimeCheckBox->setEnabled(true); useQSOStationCallCheckBox->setEnabled(true); clubLogActive = true; } else { //qDebug() << "SetupPageClubLog::slotClubLogActive FALSE" << endl; callLabel->setEnabled(false); emailLabel->setEnabled(false); passwordLabel->setEnabled(false); callLineEdit->setEnabled(false); emailLineEdit->setEnabled(false); passwordLineEdit->setEnabled(false); sendInRealTimeCheckBox->setEnabled(false); useQSOStationCallCheckBox->setEnabled(false); clubLogActive = false; } } void SetupPageClubLog::setClubLogRealTime(const QString _s) { if ( (_s.toUpper()) == "FALSE") { sendInRealTimeCheckBox->setChecked(false); } else { sendInRealTimeCheckBox->setChecked(true); } } QString SetupPageClubLog::getClubLogRealTime() { if (sendInRealTimeCheckBox->isChecked()) { return "True"; } else { return "False"; } //return sendInRealTimeCheckBox->isChecked(); } klog-0.9.2.9/dataproxy.cpp0000644000076700000620000003243313237613113013317 0ustar staff/*************************************************************************** dataproxy.cpp - description ------------------- begin : sept 2014 copyright : (C) 2014 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include "dataproxy.h" DataProxy::DataProxy() { //qDebug() << "DataProxy::DataProxy" << endl; } DataProxy::~DataProxy() { } QString DataProxy::getSoftVersion() { return QString(); } bool DataProxy::reconnectDB() { return false; } QString DataProxy::getDBVersion() { return QString(); } void DataProxy::createLogModel(){} void DataProxy::createLogPanel(){} bool DataProxy::haveAtLeastOneLog(){return true;} //QStringList DataProxy::getColumnNamesFromTable(const QString _tableName){return QStringList();} QStringList DataProxy::getColumnNamesFromTableLog(){return QStringList();} bool DataProxy::setDXCCAwardStatus(const int _qsoId){return false;} bool DataProxy::setWAZAwardStatus(const int _qsoId){return false;} int DataProxy::getIdFromModeName(const QString& _modeName) { return -1; } int DataProxy::getIdFromBandName(const QString& _bandName) { return -1; } int DataProxy::getSubModeIdFromSubMode(const QString _subModeName) { return -1; } int DataProxy::getModeIdFromSubModeId(const int _sm) { return -1; } bool DataProxy::isModeDeprecated (const QString _sm) { return false; } QString DataProxy::getNameFromBandId (const int _id) { return ""; } QString DataProxy::getNameFromModeId (const int _id) { return ""; } QString DataProxy::getNameFromSubModeId (const int _id) { return ""; } QString DataProxy::getSubModeFromId (const int _id) { return QString(); } QString DataProxy::getNameFromSubMode (const QString _sm) { return ""; } QString DataProxy::getFreqFromBandId(const int _id) { return ""; } int DataProxy::getBandIdFromFreq(const double _n) { return -1; } QString DataProxy::getBandNameFromFreq(const double _n) { return QString(); } double DataProxy::getLowLimitBandFromBandName(const QString _sm) { return -1.0; } double DataProxy::getLowLimitBandFromBandId(const QString _sm) { return -1.0; } bool DataProxy::isThisFreqInBand(const QString b, const QString fr) { return false; } QStringList DataProxy::getBands() { return QStringList(); } QStringList DataProxy::getModes() { return QStringList(); } QStringList DataProxy::sortBandNamesBottonUp(const QStringList _qs) { return QStringList(); } QStringList DataProxy::sortBandIdBottonUp(const QStringList _qs) { return QStringList(); } QStringList DataProxy::getBandIDs() { return QStringList(); } QStringList DataProxy::getModesIDs() { return QStringList(); } QStringList DataProxy::getBandsInLog(const int _log) { return QStringList(); } QStringList DataProxy::getModesInLog(const int _log) { return QStringList(); } int DataProxy::getMostUsedBand(const int _log) { return -1; } int DataProxy::getMostUsedMode(const int _log) { return -1; } int DataProxy::getLastQSOid() { return -1; } bool DataProxy::clearLog() { return false; } bool DataProxy::qslSentViaDirect(const int _qsoId, const QString _updateDate) { return false; } bool DataProxy::qslSentViaBureau(const int _qsoId, const QString _updateDate) { return false; } bool DataProxy::qslRecViaBureau(const int _qsoId, const QString _updateDate) { return false; } bool DataProxy::qslRecViaBureau(const int _qsoId, const QString _updateDate, const bool _queueSentQSL) { return false; } bool DataProxy::qslRecViaDirect(const int _qsoId, const QString _updateDate, const bool _queueSentQSL) { return false; } bool DataProxy::qslRecViaDirect(const int _qsoId, const QString _updateDate) { return false; } bool DataProxy::qslSentAsRequested(const int _qsoId, const QString _updateDate) { return false; } bool DataProxy::qslRecAsRequested(const int _qsoId, const QString _updateDate) { return false; } bool DataProxy::setClubLogSent(const int _qsoId, const QString _st, const QString _updateDate) { return false; } bool DataProxy::isQSLReceived(const int _qsoId) { return false; } bool DataProxy::isQSLSent(const int _qsoId) { return false; } int DataProxy::getBandFromId(const int _qsoId) { return -1; } int DataProxy::getModeFromId(const int _qsoId) { return -1; } int DataProxy::getDXCCFromId(const int _qsoId) { return -1; } int DataProxy::getCQZFromId(const int _qsoId) { return -1; } QString DataProxy::getCallFromId(const int _qsoId) { return ""; } QStringList DataProxy::getClubLogRealTimeFromId(const int _qsoId) { return QStringList(); } QString DataProxy::getNameFromQRZ(const QString _call) { return QString(); } QString DataProxy::getQTHFromQRZ(const QString _call) { return QString(); } QString DataProxy::getLocatorFromQRZ(const QString _call) { return QString(); } QString DataProxy::getIOTAFromQRZ(const QString _call) { return QString(); } QString DataProxy::getQSLViaFromQRZ(const QString _call) { return QString(); } bool DataProxy::updateAwardDXCC() { return false; } bool DataProxy::updateAwardWAZ() { return false; } bool DataProxy::deleteQSO(const int _qsoId) { return false; } int DataProxy::isWorkedB4(const QString _qrz, const int _currentLog) { return -1; } bool DataProxy::isThisQSODuplicated(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode) { return false; } int DataProxy::getDuplicatedQSOId(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode) { return -1; } bool DataProxy::isDXCCConfirmed(const int _dxcc, const int _currentLog) { return false; } bool DataProxy::isHF(const int _band) { return false; } bool DataProxy::isWARC(const int _band) { return false; } bool DataProxy::isVHF(const int _band) { return false; } bool DataProxy::isUHF(const int _band) { return false; } QStringList DataProxy::getOperatingYears(const int _currentLog) { return QStringList(); } void DataProxy::compressDB() { } bool DataProxy::unMarkAllQSO() { return false; } bool DataProxy::lotwSentQueue(const QString _updateDate, const int _currentLog) {// Mark LOTW QSL SENT as Q (Queued) return false; } bool DataProxy::lotwSentYes(const QString _updateDate, const int _currentLog, const QString _station) { return false; } int DataProxy::getQSOonYear(const int _year, const int _logNumber) { return -1; } int DataProxy::getDXCConYear(const int _year, const int _logNumber) { return -1; } int DataProxy::getCQzonYear(const int _year, const int _logNumber) { return -1; } bool DataProxy::newDXMarathon(const int _dxcc, const int _cq, const int _year, const int _logNumber) { return false; } QStringList DataProxy::getContestNames() { return QStringList(); } QStringList DataProxy::getContestCat(const int _catn){ return QStringList(); } QStringList DataProxy::getContestOverlays() { return QStringList(); } QStringList DataProxy::getBandNames(){ return QStringList(); } QStringList DataProxy::getPropModeList() { return QStringList(); } QStringList DataProxy::getSatellitesList() { return QStringList(); } QString DataProxy::getSatelliteUplink(const QString _sat) { return QString(); } QString DataProxy::getSatelliteDownlink(const QString _sat) { return QString(); } QStringList DataProxy::getQSLRcvdList() { return QStringList(); } QStringList DataProxy::getQSLSentList() { return QStringList(); } QStringList DataProxy::getClubLogStatusList() { return QStringList(); } QStringList DataProxy::getQSLViaList() { return QStringList(); } QStringList DataProxy::getValidCatOptions(const int _currentCat, const int _lowerCa) { return QStringList(); } int DataProxy::getNumberOfManagedLogs() { return -1; } int DataProxy::getMaxLogNumber() { return -1; } QStringList DataProxy::getListOfManagedLogs() { return QStringList(); } QString DataProxy::getStationCallSignFromLog(const int _log) { return QString(); } QStringList DataProxy::getStationCallSignsFromLog(const int _log) { return QStringList(); } QString DataProxy::getOperatorsFromLog(const int _log) { return QString(); } QString DataProxy::getCommentsFromLog(const int _log) { return QString(); } QString DataProxy::getLogDateFromLog(const int _log) { return QString(); } QString DataProxy::getLogTypeNFromLog(const int _log) { return QString(); } int DataProxy::getContestTypeN(const int _co, const int _catop, const int _catas, const int _catpo, const int _catba, const int _catov, const int _catmo) { return -1; } QStringList DataProxy::getDataFromContestType(const int _n) { return QStringList(); } int DataProxy::getLogTypeNumber(const QString _logType) { return -1; } QString DataProxy::getLogTypeName(const int _logType) { return QString(); } QString DataProxy::getLogTypeOfUserLog(const int _logN) { return QString(); } int DataProxy::getLogNumberFromQSOId(const int _qsoId) { return -1; } bool DataProxy::fillEmptyDXCCInTheLog() { return false; } int DataProxy::getHowManyQSOInLog(const int _log) { return 0; } int DataProxy::getHowManyConfirmedQSLInLog(const int _log) { return 0; } bool DataProxy::addNewLog (const QStringList _qs) { return false; } bool DataProxy::doesThisLogExist(const int _log) { return false; } int DataProxy::getContinentIdFromContinentShortName(const QString _n) { return -1; } QString DataProxy::getContinentShortNameFromEntity(const int _n) { return QString(); } int DataProxy::getContinentIdFromEntity(const int _n) { return -1; } QStringList DataProxy::getContinentShortNames() { return QStringList(); } bool DataProxy::isValidContinentShortName(const QString _n) { return false; } int DataProxy::getCQzFromPrefix(const QString _p) { return -1; } int DataProxy::getITUzFromPrefix(const QString _p) { return -1; } int DataProxy::getCQzFromEntity(const int _n) { return -1; } int DataProxy::getITUzFromEntity(const int _n) { return -1; } QString DataProxy::getEntityNameFromId(const int _n) { return QString(); } QString DataProxy::getEntityMainPrefix(const int _entityN) { return QString(); } int DataProxy::getDXCCFromPrefix(const QString _p) { return -1; } bool DataProxy::isNewCQz(int _c) { return false; } bool DataProxy::isNewEntity(int _e) { return false; } double DataProxy::getLongitudeFromEntity(const int _e) { return 0.0; } double DataProxy::getLatitudeFromEntity(const int _e) { return 0.0; } QString DataProxy::getEntityPrefixes(const int _enti) { return QString(); } QStringList DataProxy::getEntitiesNames() { return QStringList(); } int DataProxy::getHowManyEntities() { return -1; } int DataProxy::getMaxEntityID() { return -1; } bool DataProxy::updateISONames() { return false; } QString DataProxy::getISOName(const int _n) { return QString(); } void DataProxy::getFoundInLog(const QString _txt, const int _log) { //return false; } /* bool DataProxy::queryPrepare(const QString _query) { return false; } bool DataProxy::queryBind(const QString _field, const QString value) { return false; } bool DataProxy::queryExec() { return false; } */ klog-0.9.2.9/logmodel.h0000644000076700000620000000517613237612641012564 0ustar staff#ifndef LOGMODEL_H #define LOGMODEL_H /*************************************************************************** logmodel.h - description ------------------- begin : june 2017 copyright : (C) 2017 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include #include #include #include #include "dataproxy.h" class LogModel : public QSqlRelationalTableModel { Q_OBJECT public: LogModel(DataProxy *dp, QObject *parent); void createlogModel(const int _i); private: void setColumnsToDX(); //QSqlRelationalTableModel *logModel; DataProxy *dataProxy; signals: void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution }; #endif // LOGMODEL_H /* class MyModel : public QAbstractTableModel { Q_OBJECT public: MyModel(QObject *parent); int rowCount(const QModelIndex &parent = QModelIndex()) const ; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; }; */ klog-0.9.2.9/mainwindowmydatatab.cpp0000644000076700000620000002205313233376355015356 0ustar staff/*************************************************************************** mainwindowmydatatab.cpp - description ------------------- begin : Jul 2016 copyright : (C) 2016 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "mainwindowmydatatab.h" MainWindowMyDataTab::MainWindowMyDataTab(QWidget *parent) : QWidget(parent) { //qDebug() << "MainWindowMyDataTab::MainWindowMyDataTab" << endl; myPowerSpinBox = new QDoubleSpinBox; operatorLineEdit = new QLineEdit; stationCallSignLineEdit = new QLineEdit; myLocatorLineEdit = new QLineEdit; keepThisDataForNextQSORadiobutton = new QRadioButton; lastOperatorQRZ = QString(); // Last QRZ used by the user, will remain if the button is checked and removed if not lastStationQRZ = QString(); // Last QRZ used by the user, will remain if the button is checked and removed if not lastMyLocator = QString(); // Last locator used by the user, will remain if the button is checked and removed if not stationQRZ = QString(); // Defined in the configuration by the user, will be used if the user configured so in the setup operatorQRZ = QString(); // Defined in the configuration by the user, will be used if the user configured so in the setup myLocator = QString(); // Defined in the configuration by the user, will be used if the user configured so in the setup createUI(); myPower = 0; lastPower = 0; //qDebug() << "MainWindowMyDataTab::MainWindowMyDataTab - END" << endl; } MainWindowMyDataTab::~MainWindowMyDataTab(){} void MainWindowMyDataTab::createUI() { myPowerSpinBox->setDecimals(2); myPowerSpinBox->setMaximum(9999); myPowerSpinBox->setSuffix(" " + tr("Watt")); QLabel *keepLabel = new QLabel(); keepLabel->setText(tr("Keep this data")); keepLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); keepLabel->setToolTip(tr("Data entered in this tab will be copied into the next QSO")); keepThisDataForNextQSORadiobutton->setToolTip(tr("Data entered in this tab will be copied into the next QSO")); myPowerSpinBox->setToolTip(tr("Power used for the QSO in watts")); operatorLineEdit->setToolTip(tr("Logging operator's callsign")); stationCallSignLineEdit->setToolTip(tr("Callsign used over the air")); myLocatorLineEdit->setToolTip(tr("My QTH locator")); QLabel *myPowerSpinBoxLabelN = new QLabel(tr("Power")); myPowerSpinBoxLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *operatorLabelN = new QLabel(tr("Operator")); operatorLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *stationCallSignLabelN = new QLabel(tr("Station Callsign")); stationCallSignLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *myLocatorLabelN = new QLabel(tr("My Locator")); myLocatorLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QGridLayout *myDataInputTabWidgetLayout = new QGridLayout; myDataInputTabWidgetLayout->addWidget(myPowerSpinBoxLabelN, 0, 0); myDataInputTabWidgetLayout->addWidget(operatorLabelN, 1, 0); myDataInputTabWidgetLayout->addWidget(stationCallSignLabelN, 2, 0); myDataInputTabWidgetLayout->addWidget(myLocatorLabelN, 3, 0); myDataInputTabWidgetLayout->addWidget(myPowerSpinBox, 0, 1); myDataInputTabWidgetLayout->addWidget(operatorLineEdit, 1, 1); myDataInputTabWidgetLayout->addWidget(stationCallSignLineEdit, 2, 1); myDataInputTabWidgetLayout->addWidget(myLocatorLineEdit, 3, 1); myDataInputTabWidgetLayout->addWidget(keepLabel, 4, 1); myDataInputTabWidgetLayout->addWidget(keepThisDataForNextQSORadiobutton, 4, 2); setLayout(myDataInputTabWidgetLayout); //myDataInputTabWidget->setLayout(myDataInputTabWidgetLayout); // i = dxUpLeftTab->addTab(myDataInputTabWidget, tr("My Data")); //connect(stationCallSignLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); } void MainWindowMyDataTab::clear(const bool _keepMyData) { // _keepMyData comes from the setup if (_keepMyData) { //qDebug() << "MainWindowMyDataTab::clear: TRUE" << endl; } else { //qDebug() << "MainWindowMyDataTab::clear: FALSE" << endl; } if (keepThisDataForNextQSORadiobutton->isChecked()) { myPowerSpinBox->setValue(lastPower); operatorLineEdit->setText(lastOperatorQRZ.toUpper()); stationCallSignLineEdit->setText(lastStationQRZ.toUpper()); myLocatorLineEdit->setText(lastMyLocator); } else { if (_keepMyData) { myPowerSpinBox->setValue(myPower); operatorLineEdit->setText(operatorQRZ.toUpper()); stationCallSignLineEdit->setText(stationQRZ.toUpper()); myLocatorLineEdit->setText(myLocator); } else { myPowerSpinBox->setValue(0); operatorLineEdit->clear(); stationCallSignLineEdit->clear(); myLocatorLineEdit->clear(); } } } void MainWindowMyDataTab::show() { //qDebug() << "MainWindowMyDataTab::show: " << QString::number(myPower) << "/" << operatorQRZ << "/" << stationQRZ << "/" << myLocator << endl; myPowerSpinBox->setValue(myPower); operatorLineEdit->setText(operatorQRZ); stationCallSignLineEdit->setText(stationQRZ); myLocatorLineEdit->setText(myLocator); } void MainWindowMyDataTab::setSetupMyPower(const double _power) { myPower = _power; } void MainWindowMyDataTab::setSetupOperator(const QString _op) { operatorQRZ = _op.toUpper(); } void MainWindowMyDataTab::setSetupStationQRZ(const QString _op) { stationQRZ = _op.toUpper(); } void MainWindowMyDataTab::setSetupMyLocator(const QString _op) { myLocator = _op.toUpper(); } void MainWindowMyDataTab::setMyPower(const double _power) { //qDebug() << "MainWindowMyDataTab::setMyPower: " << QString::number(_power) << endl; myPowerSpinBox->setValue(_power); } double MainWindowMyDataTab::getMyPower() { if (myPowerSpinBox->value() > 0) { lastPower = myPowerSpinBox->value(); return lastPower; } else { return 0.0; } //return myPowerSpinBox->value(); } void MainWindowMyDataTab::setOperator(const QString _op) { //qDebug() << "MainWindowMyDataTab::setOperator: " << _op << endl; operatorLineEdit->setText(_op); } QString MainWindowMyDataTab::getOperator() { lastOperatorQRZ = (operatorLineEdit->text()).toUpper(); return lastOperatorQRZ; } void MainWindowMyDataTab::setStationQRZ(const QString _op) { //qDebug() << "MainWindowMyDataTab::setStationQRZ: " << _op << endl; stationCallSignLineEdit->setText(_op); } QString MainWindowMyDataTab::getStationQRZ() { lastStationQRZ = (stationCallSignLineEdit->text()).toUpper(); return lastStationQRZ.toUpper(); } void MainWindowMyDataTab::setMyLocator(const QString _op) { myLocatorLineEdit->setText(_op); } QString MainWindowMyDataTab::getMyLocator() { lastMyLocator = (myLocatorLineEdit->text()).toUpper(); return lastMyLocator.toUpper(); } void MainWindowMyDataTab::setData(const double _power, const QString _stationQRZ, const QString _operator, const QString _myLocator) { if (_power > 0.0) { myPower = _power; } else { myPower = 0; } if (_stationQRZ.length()>0) { stationQRZ = _stationQRZ; } else { stationQRZ = QString(); } if (_operator.length()>0) { operatorQRZ = _operator; } else { operatorQRZ = QString(); } if (_myLocator.length()>0) { myLocator = _myLocator; } else { myLocator = QString(); } } klog-0.9.2.9/setuppageclublog.h0000644000076700000620000000553613233376355014334 0ustar staff#ifndef SETUPPAGECLUBLOG_H #define SETUPPAGECLUBLOG_H /*************************************************************************** setuppclublog.h - description ------------------- begin : apt 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include class SetupPageClubLog : public QWidget { Q_OBJECT public: SetupPageClubLog(QWidget *parent=0); ~SetupPageClubLog(); void setEmail(const QString c); void setPassword(const QString c); void setCallsign(const QString c); void setClubLog(const QString _s); void setClubLogRealTime(const QString _s); void setUseStationCall(const QString _s); QString getEmail(); QString getPassword(); QString getCallsign(); QString getClubLog(); QString getClubLogRealTime(); QString getUseQSOStationCallsign(); private slots: void slotClubLogActive(bool _s); void slotUseStationCall(bool _s); private: //QString defaultFileName; QCheckBox *sendInRealTimeCheckBox, *clubLogActiveCheckBox, *useQSOStationCallCheckBox; QLineEdit *passwordLineEdit, *emailLineEdit, *callLineEdit; QString call, email, pass; QLabel *callLabel, *passwordLabel, *emailLabel; bool clubLogActive; //QPushButton *fileNameButton; }; #endif // SETUPPAGECOLORS_H klog-0.9.2.9/setupentitydialog.cpp0000644000076700000620000004172613233376355015100 0ustar staff/*************************************************************************** setupentitydialog.cpp - description ------------------- begin : sept 2012 copyright : (C) 2012 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "setupentitydialog.h" //#include /* This class calls all the othet "Setup..." to manage the configuration */ SetupEntityDialog::SetupEntityDialog(){ //qDebug() << "SetupEntityDialog::SetupEntityDialog: " << endl; //QPalette::ColorRole QWidget::foregroundRole () const; //QPalette::ColorRole //paletteOrig = new QPalette; //paletteWrong = new QPalette; //paletteWrong.setColor(QPalette::Normal, QPalette::WindowText, Qt::red); //paletteWrong = new QPalette(); //*paletteWrong->setColor(QPalette::WindowText, Qt::red); //paletteWrong.setColor(QPalette::WindowText, color.setNamedColor("red")); palw.setColor(QPalette::Text, Qt::red); //pal.setColor(QPalette::Text, Qt::black); entityData.clear(); entityBool = false; mainPrefixBool = false; cqBool = false; ituBool = false; contBool = false; latBool = false; lonBool = false; utcBool = false; arrlidBool = false; delBool = false; delDateBool = false; prefBool = false; //qDebug() << "SetupEntityDialog::SetupEntityDialog - 0" << endl; QLabel *entityLabel = new QLabel(tr("Entity")); entityLineEdit = new QLineEdit; entityLineEdit->setToolTip(tr("Name of the Entity")); QLabel *cqLabel = new QLabel(tr("CQ")); cqLineEdit = new QLineEdit; cqLineEdit->setToolTip(tr("CQ zone")); QLabel *ituLabel = new QLabel(tr("ITU")); ituLineEdit = new QLineEdit; ituLineEdit->setToolTip(tr("ITU zone")); //QLabel *contLabel = new QLabel(tr("Continent")); //contLineEdit = new QLineEdit; //contLineEdit->setToolTip(tr("Continent of the Entity")); QLabel *latLabel = new QLabel(tr("Latitude")); latLineEdit = new QLineEdit; latLineEdit->setToolTip(tr("Longitude of the Entity")); QLabel *lonLabel = new QLabel(tr("Longitude")); lonLineEdit = new QLineEdit; lonLineEdit->setToolTip(tr("Longitude of the Entity")); QLabel *utcLabel = new QLabel(tr("UTC")); utcLineEdit = new QLineEdit; utcLineEdit->setToolTip(tr("Local time difference to UTC")); QLabel *mprefLabel = new QLabel(tr("Main prefix")); mprefLineEdit = new QLineEdit; mprefLineEdit->setToolTip(tr("Main prefix of the entity")); //qDebug() << "SetupEntityDialog::SetupEntityDialog - 1" << endl; QLabel *arrlidLabel = new QLabel(tr("ARRL ID")); arrlidLineEdit = new QLineEdit; arrlidLineEdit->setToolTip(tr("ARRL ID")); //QLabel *deletedLabel = new QLabel(tr("Deleted")); //deletedLineEdit = new QLineEdit; //deletedLineEdit->setToolTip(tr("Mark if the entity is deleted")); QLabel *prefLabel = new QLabel(tr("Prefixes")); prefLineEdit = new QLineEdit; prefLineEdit->setToolTip(tr("Comma separated possible prefixes, e.g. EA1, EA2, ...")); delQDateEdit = new QDateEdit; delQDateEdit->setToolTip(tr("Date of the deletion")); delRbutton = new QRadioButton(tr("Deleted"), this); QPushButton *closeButton = new QPushButton(tr("Cancel")); QPushButton *okButton = new QPushButton(tr("OK")); //qDebug() << "SetupEntityDialog::SetupEntityDialog - 2" << endl; /* connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); connect(okButton, SIGNAL(clicked()), this, SLOT(slotOkButtonClicked())); connect(entityLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckEntity() ) ); connect(mprefLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckMainprefix() ) ); connect(cqLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckCQz() ) ); connect(ituLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckITUz() ) ); connect(contLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckContinent() ) ); connect(latLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckLatitude() ) ); connect(lonLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckLongitude() ) ); connect(utcLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckUTC() ) ); connect(arrlidLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckARRLid() ) ); connect(delRbutton, SIGNAL(checked), this, SLOT(slotCheckDeleted() ) ); connect(delQDateEdit, SIGNAL(dateChanged), this, SLOT(slotCheckDeletedDate() ) ); connect(prefLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotCheckPrefixes() ) ); */ //qDebug() << "SetupEntityDialog::SetupEntityDialog - 3" << endl; QVBoxLayout *cqLayout = new QVBoxLayout; cqLayout->addWidget(cqLabel); cqLayout->addWidget(cqLineEdit); QVBoxLayout *ituLayout = new QVBoxLayout; ituLayout->addWidget(ituLabel); ituLayout->addWidget(ituLineEdit); QVBoxLayout *latLayout = new QVBoxLayout; latLayout->addWidget(latLabel); latLayout->addWidget(latLineEdit); QVBoxLayout *lonLayout = new QVBoxLayout; lonLayout->addWidget(lonLabel); lonLayout->addWidget(lonLineEdit); QHBoxLayout *posLayout = new QHBoxLayout; posLayout->addLayout(cqLayout); posLayout->addLayout(ituLayout); posLayout->addLayout(latLayout); posLayout->addLayout(lonLayout); QVBoxLayout *utcLayout = new QVBoxLayout; utcLayout->addWidget(utcLabel); utcLayout->addWidget(utcLineEdit); QVBoxLayout *arrlidLayout = new QVBoxLayout; arrlidLayout->addWidget(arrlidLabel); arrlidLayout->addWidget(arrlidLineEdit); QVBoxLayout *delLayout = new QVBoxLayout; delLayout->addWidget(delRbutton); delLayout->addWidget(delQDateEdit); QHBoxLayout *thirdLayout = new QHBoxLayout; thirdLayout->addLayout(utcLayout); thirdLayout->addLayout(arrlidLayout); thirdLayout->addLayout(delLayout); QVBoxLayout *prefLayout = new QVBoxLayout; prefLayout->addWidget(prefLabel); prefLayout->addWidget(prefLineEdit); QGridLayout *dataLayout = new QGridLayout; dataLayout->addWidget(entityLabel, 0, 0); dataLayout->addWidget(entityLineEdit, 1, 0); dataLayout->addWidget(mprefLabel, 0, 1); dataLayout->addWidget(mprefLineEdit, 1, 1); dataLayout->addLayout(posLayout, 2, 0, 2, -1); dataLayout->addLayout(thirdLayout, 4, 0, 4, -1); dataLayout->addLayout(prefLayout, 8, 0, 8, -1); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addStretch(1); buttonsLayout->addWidget(okButton); buttonsLayout->addWidget(closeButton); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(dataLayout); mainLayout->addStretch(1); mainLayout->addSpacing(12); mainLayout->addLayout(buttonsLayout); //qDebug() << "SetupEntityDialog::SetupEntityDialog - 3" << endl; setLayout(mainLayout); setWindowTitle(tr("Entity Dialog")); pal = lonLineEdit->palette(); //qDebug() << "SetupEntityDialog::SetupEntityDialog: END" << endl; } SetupEntityDialog::~SetupEntityDialog() { //qDebug() << "SetupEntityDialog::~SetupEntityDialog " << endl; } void SetupEntityDialog::slotOkButtonClicked() { //qDebug() << "SetupEntityDialog::slotOkButtonClicked " << endl; QStringList ql; ql.clear(); if (entityBool && mainPrefixBool && cqBool && ituBool && contBool && latBool && lonBool && utcBool && arrlidBool && delBool && delDateBool && prefBool) { ql << checkEntity(); ql << checkMainprefix(); ql << checkContinent(); ql << checkCQz(); ql << checkITUz(); ql << checkLatitude(); ql << checkLongitude(); ql << checkUTC(); ql << checkARRLid(); ql << checkDeleted(); //ql << checkDeletedDate(); ql << checkPrefixes(); emit entityAdded(ql); accept(); } else { reject(); } reject(); } QString SetupEntityDialog::checkContinent() { //qDebug() << "SetupEntityDialog::checkContinent" << endl; if(contBool) { return contLineEdit->text(); } else { return ""; } return ""; } QString SetupEntityDialog::checkEntity() { //qDebug() << "SetupEntityDialog::checkEntity" << endl; if(entityBool) { return entityLineEdit->text(); } else { return ""; } return ""; } QString SetupEntityDialog::checkMainprefix() { //qDebug() << "SetupEntityDialog::checkMainprefix" << endl; if(mainPrefixBool) { return mprefLineEdit->text(); } else { return ""; } return ""; } QString SetupEntityDialog::checkCQz() { //qDebug() << "SetupEntityDialog::checkCQz" << endl; if(cqBool) { return cqLineEdit->text(); } else { return ""; } return ""; } QString SetupEntityDialog::checkITUz() { //qDebug() << "SetupEntityDialog::checkITUz" << endl; if(ituBool) { return ituLineEdit->text(); } else { return ""; } return ""; } QString SetupEntityDialog::checkLatitude() { //qDebug() << "SetupEntityDialog::checkLatitude" << endl; if(latBool) { return latLineEdit->text(); } else { return ""; } return ""; } QString SetupEntityDialog::checkLongitude() { //qDebug() << "SetupEntityDialog::checkLongitude" << endl; if(lonBool) { return lonLineEdit->text(); } else { return ""; } return ""; } QString SetupEntityDialog::checkUTC() { //qDebug() << "SetupEntityDialog::checkUTC" << endl; if(utcBool) { return utcLineEdit->text(); } else { return ""; } return ""; } QString SetupEntityDialog::checkARRLid() { //qDebug() << "SetupEntityDialog::checkARRLid" << endl; if(arrlidBool) { return arrlidLineEdit->text(); } else { return ""; } return ""; } QString SetupEntityDialog::checkDeleted() { //qDebug() << "SetupEntityDialog::checkDeleted" << endl; if(delBool) { return "Y"; } else { return "N"; } return ""; } QString SetupEntityDialog::checkDeletedDate() { //qDebug() << "SetupEntityDialog::checkDeletedDate" << endl; if(delDateBool) { return "00/00/0000"; } else { return ""; } return ""; } QString SetupEntityDialog::checkPrefixes() { //qDebug() << "SetupEntityDialog::checkPrefixes" << endl; if(prefBool) { return prefLineEdit->text(); } else { return ""; } return ""; } void SetupEntityDialog::slotCancelButtonClicked() { //qDebug() << "SetupEntityDialog::slotCancelButtonClicked " << endl; reject(); } void SetupEntityDialog::slotCheckEntity() { //qDebug() << "SetupEntityDialog::slotCheckEntity " << endl; QString aux; aux = entityLineEdit->text(); if (aux.length()>2) { entityBool = true; entityLineEdit->setPalette(pal); } else { entityBool = false; entityLineEdit->setPalette(palw); } } void SetupEntityDialog::slotCheckMainprefix() { //qDebug() << "SetupEntityDialog::slotCheckMainprefix" << endl; QString aux; aux = mprefLineEdit->text(); if (aux.length()>0) { mprefLineEdit->setPalette(pal); mainPrefixBool = true; } else { mainPrefixBool = false; mprefLineEdit->setPalette(palw); } } void SetupEntityDialog::slotCheckCQz() { //qDebug() << "SetupEntityDialog::slotCheckCQz" << endl; QString aux; aux = cqLineEdit->text(); if (aux.length()>0) { cqBool = true; cqLineEdit->setPalette(pal); } else { cqBool = false; cqLineEdit->setPalette(palw); } } void SetupEntityDialog::slotCheckITUz() { //qDebug() << "SetupEntityDialog::slotCheckITUz" << endl; QString aux; aux = ituLineEdit->text(); if (aux.length()>0) { ituBool = true; ituLineEdit->setPalette(pal); } else { ituBool = false; ituLineEdit->setPalette(palw); } } void SetupEntityDialog::slotCheckContinent() { //qDebug() << "SetupEntityDialog::slotCheckContinent" << endl; QString aux; aux = contLineEdit->text(); if (aux.length()>2) { contBool = true; contLineEdit->setPalette(pal); } else { contBool = false; contLineEdit->setPalette(palw); } } void SetupEntityDialog::slotCheckLatitude() { //qDebug() << "SetupEntityDialog::slotCheckLatitude" << endl; QString aux; aux = latLineEdit->text(); if (aux.length()>0) { latBool = true; latLineEdit->setPalette(pal); } else { latBool = false; latLineEdit->setPalette(palw); } } void SetupEntityDialog::slotCheckLongitude() { //qDebug() << "SetupEntityDialog::slotCheckLongitude" << endl; QString aux; aux = lonLineEdit->text(); if (aux.length()>3) { //lonLineEdit->setPalette(*paletteOrig); lonBool = true; lonLineEdit->setPalette(pal); } else { //lonLineEdit->setForegroundRole(QPalette::WindowText); lonLineEdit->setPalette(palw); //lonLineEdit->setPalette(*paletteWrong); lonBool = false; } } void SetupEntityDialog::slotCheckUTC() { //qDebug() << "SetupEntityDialog::slotCheckUTC" << endl; QString aux; aux = utcLineEdit->text(); if (aux.length()>0) { utcBool = true; utcLineEdit->setPalette(pal); } else { utcBool = false; utcLineEdit->setPalette(palw); } } void SetupEntityDialog::slotCheckARRLid() { //qDebug() << "SetupEntityDialog::slotCheckARRLid" << endl; QString aux; aux = arrlidLineEdit->text(); // int n = aux.toInt(); if (aux.length()>0) { arrlidBool = false; arrlidLineEdit->setPalette(pal); } else { arrlidBool = false; arrlidLineEdit->setPalette(palw); } } void SetupEntityDialog::slotCheckDeleted() { //qDebug() << "SetupEntityDialog::slotCheckDeleted" << endl; if (delRbutton->isChecked()) { delBool = true; } else { delBool = false; } } void SetupEntityDialog::slotCheckDeletedDate() { //qDebug() << "SetupEntityDialog::slotCheckDeletedDate" << endl; delDateBool = false; //arrlidLineEdit->setPalette(palw); } void SetupEntityDialog::slotCheckPrefixes() { //qDebug() << "SetupEntityDialog::slotCheckPrefixes" << endl; QString aux; aux = prefLineEdit->text(); aux = aux.simplified(); QStringList list = aux.split(",", QString::SkipEmptyParts); if (aux.length()>0) { prefBool = true; prefLineEdit->setPalette(pal); //"EA1, EA2, EA3" } else { prefBool = false; prefLineEdit->setPalette(palw); } } klog-0.9.2.9/setuppagemisc.h0000644000076700000620000001034713233376355013634 0ustar staff#ifndef SETUPPAGEMISC_H #define SETUPPAGEMISC_H /*************************************************************************** setuppagemisc.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include #include "utilities.h" class SetupPageMisc : public QWidget { Q_OBJECT public: SetupPageMisc(QWidget *parent=0); ~SetupPageMisc(); QString getRealTime(); void setRealTime(const QString t); QString getUTCTime(); void setUTCTime(const QString t); QString getAlwaysADIF(); void setAlwaysADIF(const QString t); QString getDefaultFileName(); void setUseDefaultName(const QString t); QString getDefaultDBPath(); void setUseDefaultDBPath(const QString t); QString getUseDefaultName(); void setDefaultFileName(const QString t); //QString getInMemory(); //void setInMemory(const QString t); QString getImperial(); void setImperial(const QString t); QString getSendQSLWhenRec(); void setSendQSLWhenRec(const QString t); QString getShowStationCallSignInSearch(); void setShowStationCallSignInSearch(const QString t); QString getKeepMyData(); void setKeepMyData(const QString t); QString getCompleteWithPrevious(); void setCompleteWithPrevious(const QString t); QString getCheckNewVersions(); void setCheckNewVersions(const QString t); QString getReportInfo(); void setReportInfo(const QString t); bool areDBPathChangesApplied(); private slots: void slotOpenFileButtonClicked(); void slotUseDefaultButtonStateChanged(int state); //void slotdefaultFileNameChanged(); void slotDefaultFileNameLineEditChanged(); void slotcheckNewVersionCheckBoxClicked(); void slotDBButtonClicked(); void slotDBLineEditChanged(); void slotMoveDBButtonClicked(); private: void createActions(); void createUI(); Utilities *util; QCheckBox *realTimeCheckbox, *UTCCheckbox, *alwaysADIFCheckBox, *useDefaultName, *completeWithPreviousCheckBox; QCheckBox *imperialCheckBox, *sendQSLWhenRecCheckBox, *showStationCallWhenSearchCheckBox, *keepMyDataCheckBox; QCheckBox *checkNewVersionCheckBox, *provideCallCheckBox; QString defaultFileName; QLineEdit *defaultFileNameLineEdit, *dbPathLineEdit; QPushButton *fileNameButton, *dbPushButton, *moveDBPushButton; QString klogDir, dbDirNew, dbDirCurrent; //TODO: To be removed when the defaultDir is saved in the config file QPalette palRight, palWrong; // To paint Text in red or black(normal) bool dbPathApplied; //QWidget *bandsWidget; }; #endif // SETUPPAGEMISC_H klog-0.9.2.9/filemanager.cpp0000644000076700000620000071211713233376355013574 0ustar staff/*************************************************************************** filemanager.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "filemanager.h" //#include FileManager::FileManager(DataProxy *dp) { //qDebug() << "FileManager::FileManager()-1" << endl; constrid = 1; dataProxy = dp; util = new Utilities; klogVersion = util->getVersion(); db = new DataBase(Q_FUNC_INFO, klogVersion, util->getKLogDBFile()); ignoreUnknownAlways = false; world = new World(dataProxy); awards = new Awards(dataProxy); //dataProxyPrepared = new DataProxy_SQLite(klogVersion); noMoreQso = false; hashLogs.clear(); //qDebug() << "FileManager::FileManager()-1 - END" << endl; } /* FileManager::FileManager(DataProxy *dp, const QString _klogDir) { //qDebug() << "FileManager::FileManager()-2: Dir" << _klogDir << endl; dataProxy = dp; db = new DataBase(0); util = new Utilities; ignoreUnknownAlways = false; world = new World(dataProxy, klogDir); awards = new Awards(dataProxy); klogVersion = util->getVersion(); dataProxyPrepared = new DataProxy_SQLite(klogVersion); noMoreQso = false; hashLogs.clear(); klogDir = util->getHomeDir(); } */ FileManager::FileManager(DataProxy *dp, const QString _klogDir, const QString _softVersion) //FileManager::FileManager(const QString _klogDir, const QString _softVersion, DataBase _db) { //qDebug() << "FileManager::FileManager()-3: Dir(2)" << _klogDir << endl; constrid = 2; dataProxy = dp; util = new Utilities; util->setVersion(klogVersion); db = new DataBase(Q_FUNC_INFO, klogVersion, util->getKLogDBFile()); klogVersion = _softVersion; //dataProxyPrepared = new DataProxy_SQLite(klogVersion); klogDir = _klogDir; ignoreUnknownAlways = false; world = new World(dataProxy, klogDir); awards = new Awards(dataProxy); noMoreQso = false; hashLogs.clear(); //qDebug() << "FileManager::FileManager()-3: Dir(2) - END" << endl; } FileManager::~FileManager() { } bool FileManager::checkADIFValidFormat(const QStringList _qs) { QStringList qs = _qs; if (qs.size()!= 2) { //qDebug() << "FileManager::checkADIFValidFormat-0 (not two) " << endl; return false; } QString q0 = qs.at(0); QString q1 = qs.at(1); //qDebug() << "FileManager::checkADIFValidFormat: " << qs.at(0) << endl; //qDebug() << "FileManager::checkADIFValidFormat: " << qs.at(1) << endl; int len = 0; int i = (qs.at(0)).count(":"); if (i == 2) { // DATE:8:D / 20141020 len = (q0.section(':', 1, 1)).toInt(); } else if (i == 1) { // DATE:8 / 20141020 len = (q0.section(':', 1, 1)).toInt(); } else { //qDebug() << "FileManager::checkADIFValidFormat-1 " << endl; return false; } //i = (qs.at(0)).indexOf(":"); //i = (qs.at(0)).length() - i -1; //qDebug() << "i = " << QString::number(i) << "/" << qs.at(0) << endl; //len = ( (qs.at(0)).right(i)).toInt(); //qDebug() << "len = " << QString::number(len) << endl; if ( (q1).length() != len ) { //qDebug() << "FileManager::checkADIFValidFormat-2: " << (qs.at(1)) << " - " << QString::number((qs.at(1)).length()) << "/" << QString::number(len) << endl; return false; } if (len <= 0) { //qDebug() << "FileManager::checkADIFValidFormat-3 " << endl; return false; } //qDebug() << "FileManager::checkADIFValidFormat-4 (true)" << endl; return true; } bool FileManager::adifLogExport(const QString& _fileName, const int _logN) { //qDebug() << "FileManager::adifLogExport" << endl; return adifLogExportToFile(_fileName, _logN, false, false, false); } int FileManager::adifLoTWLogExport(const QString& _fileName, const int _logN) { //qDebug() << "FileManager::adifLoTWLogExport: " << _fileName << endl; if (!dataProxy->doesThisLogExist(_logN)) { //qDebug() << "FileManager::adifLoTWLogExport - The log does not exist" << endl; return -1; } QFile file(_fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return -2; QString stationCallToUse = QString(); QStringList stationCallSigns; stationCallSigns.clear(); stationCallSigns << "NONE"; stationCallSigns << dataProxy->getStationCallSignsFromLog(_logN); //bool callsignTyped = false; if (stationCallSigns.length()>1) { QString msg = QString(tr("The log that you have selected contains more than just one station callsign.") + "\n\n" + tr("Please select the station callsing you want to export the log from:")); bool ok; stationCallToUse = QInputDialog::getItem(this, tr("Station Callsign:"), msg, stationCallSigns, 0, false, &ok); if (ok && !stationCallToUse.isEmpty()) { //qDebug() << "FileManager::adifLoTWLogExport: StatioNCallsign: " << stationCallToUse << endl; } else { stationCallToUse = (QInputDialog::getText(this, tr("Define Station Callsign"), tr("You have selected no callsign. KLog will export QSOs without a station callsign defined and those with the call you are entering here.") + "\n\n" + tr("Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined:"), QLineEdit::Normal, "", &ok)).toUpper(); if (ok) { //callsignTyped = true; } else { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); QString aux = QString(tr("No station callsign has been selected and therefore no log will be exported") ); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: // Ok was clicked return -3; break; default: // should never be reached break; } } } } QTextStream out(&file); int numberOfQsos = dataProxy->getHowManyQSOInLog(_logN); int step = util->getProgresStepForDialog(numberOfQsos); int i = 0; QProgressDialog progress(tr("Writing ADIF file..."), tr("Abort writing"), 0, numberOfQsos, this); progress.setMaximum(numberOfQsos); progress.setWindowModality(Qt::ApplicationModal); out << "ADIF v3.0.7 Export from KLog\nhttp://www.klog.xyz/klog\n" << klogVersion << "\nKLOG" << endl; out << "" << QString::number(numberOfQsos) << endl; QDateTime dateTime = (QDateTime::currentDateTime()).toUTC(); out << "" << dateTime.toString("yyyyMMdd-hhmm") << endl; out << "" << endl; QString queryString = QString("SELECT call, freq, bandid, band_rx, freq_rx, modeid, qso_date, time_on, prop_mode, sat_name, lotw_qsl_sent, station_callsign FROM log WHERE lognumber='%1'").arg(_logN); QSqlQuery query; bool sqlOK = query.exec(queryString); //qDebug() << "FileManager::adifLoTWLogExport: " << query.lastQuery() << endl; if (!sqlOK) { //qDebug() << "FileManager::adifLoTWLogExport: Query Error" << endl; emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return -4; } QSqlRecord rec = query.record(); int nameCol; QString aux, aux2; QString bandst, bandrxst; bool propsat; while ( (query.next())) { //qDebug() << "FileManager::adifLoTWLogExport: Start of While" << endl; if (query.isValid()) { nameCol = rec.indexOf("station_callsign"); aux = (query.value(nameCol)).toString(); if ( ( (stationCallToUse == "NONE") && (aux.length() <3) ) || (aux == stationCallToUse) ) { // We are only exporting the QSO from the appropriate station callsign or with empty stationcallsigns but we will add the one entered by the user. nameCol = rec.indexOf("lotw_qsl_sent"); aux = (query.value(nameCol)).toString(); if (aux == "Q") { //qDebug() << "FileManager::adifLoTWLogExport: Start of isValid" << endl; propsat = false; // Reset the QSO in case it is a Satellite QSO nameCol = rec.indexOf("call"); aux = (query.value(nameCol)).toString(); aux = util->checkAndFixASCIIinADIF(aux); //qDebug() << "FileManager::adifLoTWLogExport: " << QString::number(nameCol) << "/" << aux1 << endl; if (aux.length()>0) { out << "" << aux<< " "; } //qDebug() << "FileManager::adifLoTWLogExport: CALL" << endl; nameCol = rec.indexOf("qso_date"); aux = (query.value(nameCol)).toString(); aux = util->checkAndFixASCIIinADIF(aux); if ((aux.length()) == 10){ aux.remove(QChar('-'), Qt::CaseInsensitive); aux.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux << " "; } } nameCol = rec.indexOf("time_on"); aux = (query.value(nameCol)).toString(); aux = util->checkAndFixASCIIinADIF(aux); //qDebug() << "FileManager::adifLoTWLogExportToFile-time_on: " << aux1 << endl; if ( ((aux.length()) == 5) || ((aux.length()) == 8) ){ aux.remove(QChar(':'), Qt::CaseInsensitive); out << "" << aux << " "; } nameCol = rec.indexOf("bandid"); aux = (query.value(nameCol)).toString(); //qDebug() << "FileManager::adifLoTWLogExportToFile-Band-1: " << aux << endl; aux = util->checkAndFixASCIIinADIF(aux); //qDebug() << "FileManager::adifLoTWLogExportToFile-Band-2: " << aux << endl; //aux = db->getBandNameFromID2(aux.toInt()); aux = dataProxy->getNameFromBandId(aux.toInt()); //qDebug() << "FileManager::adifLoTWLogExportToFile-Band-3: " << aux << endl; if (dataProxy->getIdFromBandName(aux)>=0) { out << "" << aux << " "; bandst = aux; } nameCol = rec.indexOf("band_rx"); aux = (query.value(nameCol)).toString(); aux = util->checkAndFixASCIIinADIF(aux); aux = dataProxy->getNameFromBandId(aux.toInt()); if ( dataProxy->getIdFromBandName(aux)>=0) { out << "" << aux << " "; QString bandrxst = aux; } //qDebug() << "FileManager::adifLoTWLogExport: BAND_RX" << endl; nameCol = rec.indexOf("modeid"); aux = (query.value(nameCol)).toString(); aux = util->checkAndFixASCIIinADIF(aux); // get SubModeId to check if it is the same or not from modeid aux2 = dataProxy->getSubModeFromId(aux.toInt()); //aux = db->getModeNameFromID2(aux.toInt()); aux = dataProxy->getNameFromSubMode(aux2); //qDebug() << "FileManager::adifLoTWLogExportToFile - MODE aux2: " << aux2 << endl; //qDebug() << "FileManager::adifLoTWLogExportToFile - MODE aux: " << aux << endl; if ((aux.length()>1) && (dataProxy->getIdFromModeName(aux)>=0)) { //haveMode = true; out << "" << aux << " "; } if ((aux != aux2) && (aux.length()>1) && (dataProxy->getSubModeIdFromSubMode(aux2)>=0) ) { //haveMode = true; out << "" << aux2 << " "; } //qDebug() << "FileManager::adifLoTWLogExport: SUBMODE: " << aux2 << endl; nameCol = rec.indexOf("freq"); aux = (query.value(nameCol)).toString(); //qDebug() << "FileManager::adifLoTWLogExportToFile FREQ1: " << aux1 << endl; aux = util->checkAndFixASCIIinADIF(aux); if ((aux.length())>0){ //TODO: Check if the Band is correctly defined. BAND Wins and freq is lost if not correct if (dataProxy->getBandIdFromFreq(aux.toDouble()) == dataProxy->getIdFromBandName(bandst)) //if (db->isThisFreqInBand(bandst, aux)) { out << "" << aux << " "; } } //qDebug() << "FileManager::adifLoTWLogExport: FREQ" << endl; nameCol = rec.indexOf("freq_rx"); aux = (query.value(nameCol)).toString(); aux = util->checkAndFixASCIIinADIF(aux); if ((aux.length())>0){ //TODO: Check if the Band is correctly defined. BAND Wins and freq is lost if not correct if (dataProxy->getBandIdFromFreq(aux.toDouble()) == dataProxy->getIdFromBandName(bandrxst)) //if (db->isThisFreqInBand(bandrxst, aux)) { out << "" << aux << " "; } } //qDebug() << "FileManager::adifLoTWLogExport: FREQ_RX" << endl; nameCol = rec.indexOf("prop_mode"); aux = (query.value(nameCol)).toString(); aux = util->checkAndFixASCIIinADIF(aux); if ((aux.length())>1){ out << "" << aux << " "; if (aux == "SAT") { propsat = true; } } //qDebug() << "FileManager::adifLoTWLogExport: PROP_MODE" << endl; nameCol = rec.indexOf("sat_name"); aux = (query.value(nameCol)).toString(); aux = util->checkAndFixASCIIinADIF(aux); if ((aux.length())>0){ out << "" << aux << " "; if (!propsat) { out << "SAT "; } } //qDebug() << "FileManager::adifLoTWLogExport: SAT_NAME" << endl; out << " " << endl; i++; if (( (i % step ) == 0) ) { // To update the speed I will only show the progress once each X QSOs //qDebug() << "FileManager::adifLoTWLogExport: MOD 0 - i = " << QString::number(i) << endl; aux = tr("Exporting LoTW ADIF file...") + "\n" + tr(" QSO: ") + QString::number(i) + "/" + QString::number(numberOfQsos); progress.setLabelText(aux); progress.setValue(i); } else { //qDebug() << "FileManager::adifLoTWLogExport: Mod: "<< QString::number(i) << " mod " << QString::number(step) << " = " << QString::number(i % step) << endl; } } } } //qDebug() << "FileManager::adifLoTWLogExport: End Of Valid" << endl; } //qDebug() << "FileManager::adifLoTWLogExport: End of While " << endl; return i; } bool FileManager::adifLogExportToFile(const QString& _fileName, const int _logN, bool justMarked, bool _qslRequested , bool _lotw) { // If _logN = 0, then we will export ALL the logs. //qDebug() << "FileManager::adifLogExportToFile: " << _fileName << endl; bool exportJustMarkedQSO = justMarked; //bool marked = false; bool exportOnlyQSLRequested = _qslRequested; //bool haveMode = false; noMoreQso = false; QFile file(_fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return false; QTextStream out(&file); QString aux1, aux2, queryString, bandst, bandrxst; // bandst & bandrxst are to check if the band is properly defined int nameCol = 0; QSqlQuery query1; int numberOfQsos = 0; int currentQso = 0; //bool noMoreQso = false; int step = 1; bool propsat=false; // Just to check if we have added the prop_mode needed by LOTW when SAT QSO //bool bandOK = false; // Just to check if the band is properly defined bool exportAll = false; if (_logN <=0) { exportAll = true; } else { exportAll = false; } bandst = QString(); bandrxst = QString(); if (exportJustMarkedQSO) { //TODO: Count the marked QSO and adjust the numberOfQsos numberOfQsos = 0; QSqlQuery query; if (exportAll) { queryString = QString("SELECT marked FROM log"); } else { queryString = QString("SELECT marked FROM log WHERE lognumber='%1'").arg(_logN); } bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } QSqlRecord rec = query.record(); while ( (query.next())) { if (query.isValid()) { nameCol = rec.indexOf("marked"); aux1 = (query.value(nameCol)).toString(); if (aux1 == "X") { numberOfQsos++; } else { } } else { } } //qDebug() << "FileManager::adifLogExportToFile - numberOfQsos = " << QString::number(numberOfQsos)<< endl; } else { if (exportAll) { aux1 = "SELECT count(id) FROM log"; } else { aux1 = QString("SELECT count(id) FROM log WHERE lognumber='%1'").arg(_logN); } bool sqlOK = query1.exec(aux1); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number(), query1.lastQuery()); } query1.next(); if (query1.isValid()) { numberOfQsos = (query1.value(0)).toInt(); } //qDebug() << "FileManager::adifLogExportToFile - numberOfQsos = " << QString::number(numberOfQsos)<< endl; } //qDebug() << "FileManager::adifLogExportToFile END - numberOfQsos = " << QString::number(numberOfQsos) << endl; step = util->getProgresStepForDialog(numberOfQsos); //step = getProgresStepForDialog(numberOfQsos); QProgressDialog progress(tr("Writing ADIF file..."), tr("Abort writing"), 0, numberOfQsos, this); progress.setMaximum(numberOfQsos); progress.setWindowModality(Qt::ApplicationModal); out << "ADIF v3.0.7 Export from KLog\nhttp://www.klog.xyz/klog\n" << klogVersion << "\nKLOG" << endl; out << "" << QString::number(numberOfQsos) << endl; QDateTime dateTime = (QDateTime::currentDateTime()).toUTC(); out << "" << dateTime.toString("yyyyMMdd-hhmm") << endl; out << "" << endl; if (exportAll) { queryString = QString("SELECT * FROM log"); } else { queryString = QString("SELECT * FROM log WHERE lognumber='%1'").arg(_logN); } QSqlQuery query; bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } //QSqlQuery query("SELECT * FROM log"); QSqlRecord rec = query.record(); //qDebug() << "FileManager::adifLogExportToFile - before the While" << endl; while ( (query.next()) && (!noMoreQso) ) { //marked = false; if (query.isValid()) { if (exportJustMarkedQSO == true) { nameCol = rec.indexOf("marked"); aux1 = (query.value(nameCol)).toString(); if (aux1 == "X") { //qDebug() << "FileManager::adifLogExportToFile: MARKED: " << aux1 << endl; currentQso++; nameCol = rec.indexOf("call"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile: " << QString::number(nameCol) << "/" << aux1 << endl; if (aux1.length()>0) { out << "" << aux1<< " "; } nameCol = rec.indexOf("qso_date"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qso_date_off"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("time_on"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile-time_on: " << aux1 << endl; if ( ((aux1.length()) == 5) || ((aux1.length()) == 8) ){ aux1.remove(QChar(':'), Qt::CaseInsensitive); out << "" << aux1 << " "; } nameCol = rec.indexOf("time_off"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile: time_off-682" << QString::number(nameCol) << "/" << aux1 << endl; if ( ((aux1.length()) == 5) || ((aux1.length()) == 8) ){ aux1.remove(QChar(':'), Qt::CaseInsensitive); out << "" << aux1 << " "; //qDebug() << "FileManager::adifLogExportToFile: time_off exported-682" << endl; } nameCol = rec.indexOf("bandid"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "FileManager::adifLogExportToFile: bandid1: " << aux1 << endl; aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile: bandid2: " << aux1 << endl; aux1 = dataProxy->getNameFromBandId(aux1.toInt()); //aux1 = db->getBandNameFromID2(aux1.toInt()); //qDebug() << "FileManager::adifLogExportToFile: bandid3: " << aux1 << endl; if (dataProxy->getIdFromBandName(aux1)>=0) { out << "" << aux1 << " "; bandst = aux1; } nameCol = rec.indexOf("band_rx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( (0 < aux1.toInt()) && (aux1.toInt() < 30) && (aux1.length()>0) && (dataProxy->getIdFromBandName(aux1)>=0)) { aux1 = dataProxy->getNameFromBandId(aux1.toInt()); //aux1 = db->getBandNameFromID2(aux1.toInt()); out << "" << aux1 << " "; bandrxst = aux1; } nameCol = rec.indexOf("modeid"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); // get SubModeId to check if it is the same or not from modeid aux2 = dataProxy->getSubModeFromId(aux1.toInt()); aux1 = dataProxy->getNameFromModeId(aux1.toInt()); //aux1 = db->getModeNameFromID2(aux1.toInt()); //qDebug() << "FileManager::adifLogExportToFile - MODE aux2: " << aux2 << endl; //qDebug() << "FileManager::adifLogExportToFile - MODE aux1: " << aux1 << endl; if ((aux1.length()>1) && (dataProxy->getIdFromModeName(aux1)>=0)) { //haveMode = true; out << "" << aux1 << " "; } if ((aux1 != aux2) && (aux2.length()>1) && (dataProxy->getSubModeIdFromSubMode(aux2)>=0) ) { //haveMode = true; out << "" << aux2 << " "; } nameCol = rec.indexOf("srx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0) { out << "" << aux1 << " "; } nameCol = rec.indexOf("srx_string"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("stx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("stx_string"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("cqz"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())>0) && (0 < aux1.toInt()) && (aux1.toInt() < CQZones+1) ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ituz"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())>0) && (0 < aux1.toInt()) && (aux1.toInt() < ITUZones+1) ){ out << "" << aux1 << " "; } //qDebug() << "FileManager::adifLogExportToFile: DXCC - Now..." << endl; nameCol = rec.indexOf("dxcc"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; //qDebug() << "FileManager::adifLogExportToFile: DXCC " << aux1 << endl; } //qDebug() << "FileManager::adifLogExportToFile: DXCC - Exported!" << endl; nameCol = rec.indexOf("address"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("age"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("cnty"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("comment"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("a_index"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ant_az"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ant_el"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ant_path"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("arrl_sect"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("checkcontest"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("class"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("cont"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("contacted_op"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("contest_id"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("points"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("multiplier"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("transmitterid"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("country"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("credit_submitted"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("credit_granted"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("distance"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("dark_doc"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("eq_call"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("email"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ if (aux1.contains("@") && (aux1.contains("."))) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("eqsl_qslrdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("eqsl_qslsdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("eqsl_qsl_rcvd"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && (aux1!="N") ) { out << "" << aux1 << " "; } nameCol = rec.indexOf("eqsl_qsl_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && (aux1!="N") ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("fists"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("fists_cc"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("force_init"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("freq"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "FileManager::adifLogExportToFile FREQ1: " << aux1 << endl; aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile FREQ1.1: " << aux1 << endl; if ((aux1.length())>0){ //TODO: Check if the Band is correctly defined. BAND Wins and freq is lost if not correct if (dataProxy->getBandIdFromFreq(aux1.toDouble()) == dataProxy->getIdFromBandName(bandst)) //if (db->isThisFreqInBand(bandst, aux1)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("freq_rx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ //TODO: Check if the Band is correctly defined. BAND Wins and freq is lost if not correct if (dataProxy->getBandIdFromFreq(aux1.toDouble()) == dataProxy->getIdFromBandName(bandrxst)) //if (db->isThisFreqInBand(bandrxst, aux1)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("guest_op"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("hrdlog_qso_upload_date"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("hrdlog_qso_upload_status"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && ((aux1!="Y") || (aux1!="N") || (aux1!="M")) ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("gridsquare"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_gridsquare"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_antenna"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_dxcc"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_fists"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("iota"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile (IOTA): " << aux1 << endl; if (((aux1.length())>=4) && ((aux1.length())<=6)){ //if ((aux1.length())==6){ out << "" << aux1 << " "; } nameCol = rec.indexOf("iota_island_id"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile (IOTA_ID): " << aux1 << endl; if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_iota"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if (((aux1.length())>=4) && ((aux1.length())<=6)){ //if ((aux1.length())==6){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_iota_island_id"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("k_index"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_itu_zone"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("lat"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("lon"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_lat"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_lon"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("lotw_qslrdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("lotw_qslsdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("lotw_qsl_rcvd"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && (aux1!="N") ) { out << "" << aux1 << " "; } nameCol = rec.indexOf("lotw_qsl_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && (aux1!="N") ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("clublog_qso_upload_date"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("clublog_qso_upload_status"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && ((aux1!="Y") || (aux1!="N") || (aux1!="M")) ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qrzcom_qso_upload_date"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qrzcom_qso_upload_status"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && ((aux1!="Y") || (aux1!="N") || (aux1!="M")) ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("max_bursts"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ms_shower"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_city"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_cnty"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_country"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_cq_zone"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_name"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("name"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("operator"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("station_callsign"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("owner_callsign"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_postal_code"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_rig"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_sig"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_sota_ref"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_postal_code"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_state"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("state"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_street"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("notes"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ aux1.replace("\n", "---"); out << "" << aux1 << " "; } nameCol = rec.indexOf("nr_bursts"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("nr_pings"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("pfx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("precedence"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("public_key"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qslmsg"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qslrdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qslsdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qsl_rcvd"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if (((aux1.length())==1) && (aux1!="N") ){ out << "" << aux1 << " "; nameCol = rec.indexOf("qsl_rcvd_via"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())==1){ out << "" << aux1 << " "; } } nameCol = rec.indexOf("qsl_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if (((aux1.length())==1) && (aux1!="N") ){ out << "" << aux1 << " "; nameCol = rec.indexOf("qsl_sent_via"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())==1) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qsl_via"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qso_complete"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qso_random"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qth"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("rst_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("rst_rcvd"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("region"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("rig"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("rx_pwr"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if (((aux1.length())>0) && (aux1.toDouble()>0) ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("tx_pwr"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())>0) && (aux1.toDouble()>0)) { out << "" << aux1 << " "; } nameCol = rec.indexOf("prop_mode"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>1){ out << "" << aux1 << " "; propsat = true; } nameCol = rec.indexOf("sat_mode"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("sat_name"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; if (!propsat) { out << "SAT "; } } nameCol = rec.indexOf("sfi"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("sig"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("sig_info"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("silent_key"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("skcc"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("sota_ref"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("state"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("swl"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ten_ten"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ten_ten"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("uksmg"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ve_prov"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_usaca_counties"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("usaca_counties"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("vucc_grids"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_vucc_grids"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("web"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } if (exportAll) { nameCol = rec.indexOf("lognumber"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } } out << " " << endl; } else { //qDebug() << "FileManager::adifLogExportToFile: NOT MARKED" << endl; //marked = false; // Find something that bypass the while without breaking it all } } else { if(exportOnlyQSLRequested) { nameCol = rec.indexOf("qsl_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( aux1 !="R" ) { goto EndOfWhile; } } currentQso++; nameCol = rec.indexOf("call"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile: " << QString::number(nameCol) << "/" << aux1 << endl; if (aux1.length()>0) { out << "" << aux1 << " "; } //qDebug() << "FileManager::adifLogExportToFile before 30 " << endl; nameCol = rec.indexOf("qso_date"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qso_date_off"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } //qDebug() << "FileManager::adifLogExportToFile before 50 " << endl; nameCol = rec.indexOf("time_on"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile-time_on: " << aux1 << endl; if ( ((aux1.length()) == 5) || ((aux1.length()) == 8) ){ aux1.remove(QChar(':'), Qt::CaseInsensitive); out << "" << aux1 << " "; } nameCol = rec.indexOf("time_off"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile: time_off-1489" << QString::number(nameCol) << "/" << aux1 << endl; if ( ((aux1.length()) == 5) || ((aux1.length()) == 8) ){ aux1.remove(QChar(':'), Qt::CaseInsensitive); out << "" << aux1 << " "; //qDebug() << "FileManager::adifLogExportToFile: time_off-1489-exported" << endl; } nameCol = rec.indexOf("bandid"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "FileManager::adifLogExportToFile: bandid21: " << aux1 << endl; aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile: bandid22: " << aux1 << endl; //aux1 = db->getBandNameFromID2(aux1.toInt()); aux1 = dataProxy->getNameFromBandId(aux1.toInt()); //qDebug() << "FileManager::adifLogExportToFile: bandid23: " << aux1 << endl; //TODO: If the DB has some blank fields (bandid or whatever, they will be exported as "-1" so not valid. // Check how to avoid exporting wrong data. if (dataProxy->getIdFromBandName(aux1)>=0) { out << "" << aux1 << " "; bandst = aux1; } nameCol = rec.indexOf("band_rx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); qDebug() << "FileManager::adifLogExportToFile before 60 " << endl; if ( (0 < aux1.toInt()) && (aux1.toInt() < 30) && (aux1.length()>0) && (dataProxy->getIdFromBandName(aux1)>=0) ) { //aux1 = db->getBandNameFromID2(aux1.toInt()); aux1 = dataProxy->getNameFromBandId(aux1.toInt()); out << "" << aux1 << " "; bandrxst = aux1; /*queryString = QString("SELECT name FROM band WHERE id='%1'").arg(aux1); query1.exec(queryString); query1.next(); if (query1.isValid()) { aux1 = (query1.value(0)).toString(); out << "" << aux1 << " "; } */ } nameCol = rec.indexOf("modeid"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); // get SubModeId to check if it is the same or not from modeid aux2 = dataProxy->getSubModeFromId(aux1.toInt()); aux1 = dataProxy->getNameFromSubMode(aux2); //aux1 = db->getModeNameFromID2(aux1.toInt()); //qDebug() << "FileManager::adifLogExportToFile - MODE2 aux2: " << aux2 << endl; //qDebug() << "FileManager::adifLogExportToFile - MODE2 aux1: " << aux1 << endl; if ((aux1.length()>1) && (dataProxy->getIdFromModeName(aux1)>=0)) { out << "" << aux1 << " "; //haveMode = true; } if ((aux1 != aux2) && (aux2.length()>1) && (dataProxy->getSubModeIdFromSubMode(aux2)>=0)) { //haveMode = true; out << "" << aux2 << " "; } qDebug() << "FileManager::adifLogExportToFile before 70 " << endl; nameCol = rec.indexOf("srx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("srx_string"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("stx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("stx_string"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("cqz"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())>0) && (0 < aux1.toInt()) && (aux1.toInt() < CQZones+1) ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ituz"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())>0) && (0 < aux1.toInt()) && (aux1.toInt() < ITUZones+1) ){ out << "" << aux1 << " "; } //qDebug() << "FileManager::adifLogExportToFile - DXCC to be exported: " << endl; nameCol = rec.indexOf("dxcc"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile - DXCC: " << aux1 << endl; //if ((aux1.length())>0){ if ( ((aux1.length())>0) && (0 < aux1.toInt()) && (aux1.toInt() < DXCCEntities + 5) ){ out << "" << aux1 << " "; //qDebug() << "FileManager::adifLogExportToFile - DXCC in the if" << endl; } //qDebug() << "FileManager::adifLogExportToFile - DXCC alreadyexported: " << endl; nameCol = rec.indexOf("address"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } qDebug() << "FileManager::adifLogExportToFile before 80 " << endl; nameCol = rec.indexOf("age"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("cnty"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("comment"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("a_index"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ant_az"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ant_el"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ant_path"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } qDebug() << "FileManager::adifLogExportToFile before 90 " << endl; nameCol = rec.indexOf("arrl_sect"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("checkcontest"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("class"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("cont"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("contacted_op"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("contest_id"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("points"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("multiplier"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("transmitterid"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } //qDebug() << "FileManager::adifLogExportToFile before 100 " << endl; nameCol = rec.indexOf("country"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("credit_submitted"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("credit_granted"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("distance"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("dark_doc"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("eq_call"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("email"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0) { if (aux1.contains("@") && (aux1.contains("."))) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("eqsl_qslrdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("eqsl_qslsdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } //qDebug() << "FileManager::adifLogExportToFile before eqsl_qsl_rcvd: " << endl; nameCol = rec.indexOf("eqsl_qsl_rcvd"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && (aux1!="N") ) { out << "" << aux1 << " "; } //qDebug() << "FileManager::adifLogExportToFile before eqsl_qsl_sent: " << endl; nameCol = rec.indexOf("eqsl_qsl_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && (aux1!="N") ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("fists"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("fists_cc"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } //qDebug() << "FileManager::adifLogExportToFile before force_init: " << endl; nameCol = rec.indexOf("force_init"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } //qDebug() << "FileManager::adifLogExportToFile before freq: " << endl; nameCol = rec.indexOf("freq"); //qDebug() << "FileManager::adifLogExportToFile before freq: nameCol: " << QString::number(nameCol) << endl; aux1 = (query.value(nameCol)).toString(); //qDebug() << "FileManager::adifLogExportToFile FREQ2: " << aux1 << endl; aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile FREQ2.1: " << aux1 << endl; if ((aux1.length())>0){ if (dataProxy->getBandIdFromFreq(aux1.toDouble()) == dataProxy->getIdFromBandName(bandst)) //if (db->isThisFreqInBand(bandst, aux1)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("freq_rx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ if (dataProxy->getBandIdFromFreq(aux1.toDouble()) == dataProxy->getIdFromBandName(bandst)) //if (db->isThisFreqInBand(bandst, aux1)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("guest_op"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("hrdlog_qso_upload_date"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("hrdlog_qso_upload_status"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && ((aux1!="Y") || (aux1!="N") || (aux1!="M")) ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("gridsquare"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_gridsquare"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_antenna"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("iota"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile (IOTA2): " << aux1 << endl; if (((aux1.length())>=4) && ((aux1.length())<=6)){ //if ((aux1.length())==6){ out << "" << aux1 << " "; } nameCol = rec.indexOf("iota_island_id"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile (IOTA_ID2): " << aux1 << endl; if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_iota"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if (((aux1.length())>=4) && ((aux1.length())<=6)){ //if ((aux1.length())==6){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_iota_island_id"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("k_index"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_itu_zone"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("lat"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("lon"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_lat"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_lon"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("lotw_qslrdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("lotw_qslsdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("lotw_qsl_rcvd"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && (aux1!="N") ) { out << "" << aux1 << " "; } nameCol = rec.indexOf("lotw_qsl_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && (aux1!="N") ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("clublog_qso_upload_date"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("clublog_qso_upload_status"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && ((aux1!="Y") || (aux1!="N") || (aux1!="M")) ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qrzcom_qso_upload_status"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qrzcom_qso_upload_status"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())==1) && ((aux1!="Y") || (aux1!="N") || (aux1!="M")) ){ out << "" << aux1 << " "; } nameCol = rec.indexOf("max_bursts"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ms_shower"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_city"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_cnty"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_country"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_cq_zone"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_name"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("name"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("operator"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("station_callsign"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("owner_callsign"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_postal_code"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_rig"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_sig"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_sig_info"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_state"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("state"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_street"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("notes"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("nr_bursts"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("nr_pings"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("pfx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("precedence"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("prop_mode"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>1){ out << "" << aux1 << " "; } nameCol = rec.indexOf("public_key"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qslmsg"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qslrdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qslsdate"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qsl_rcvd"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if (((aux1.length())==1) && (aux1!="N") ){ out << "" << aux1 << " "; nameCol = rec.indexOf("qsl_rcvd_via"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())==1){ out << "" << aux1 << " "; } } nameCol = rec.indexOf("qsl_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if (((aux1.length())==1) && (aux1!="N") ){ out << "" << aux1 << " "; nameCol = rec.indexOf("qsl_sent_via"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())==1) { out << "" << aux1 << " "; } } nameCol = rec.indexOf("qsl_via"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qso_complete"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qso_random"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("qth"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("rst_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("rst_rcvd"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("region"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("rig"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("rx_pwr"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if (((aux1.length())>0) && (aux1.toDouble()>0)){ out << "" << aux1 << " "; } nameCol = rec.indexOf("tx_pwr"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( ((aux1.length())>0) && (aux1.toDouble()>0)) { out << "" << aux1 << " "; } nameCol = rec.indexOf("sat_mode"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("sat_name"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("sfi"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("sig"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("sig_info"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("silent_key"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("skcc"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("sota_ref"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("state"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("swl"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ten_ten"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("uksmg"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("ve_prov"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_usaca_counties"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("usaca_counties"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("vucc_grids"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("my_vucc_grids"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } nameCol = rec.indexOf("web"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } if (exportAll) { nameCol = rec.indexOf("lognumber"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } } out << " " << endl; using namespace std; EndOfWhile: ; } if (( (currentQso % step )== 0) ) { // To update the speed I will only show the progress once each X QSOs aux1 = tr("Writing ADIF file...\n QSO: ") + QString::number(currentQso) + "/" + QString::number(numberOfQsos); progress.setLabelText(aux1); progress.setValue(currentQso); } if ( progress.wasCanceled() ) { QMessageBox msgBox; QString aux = QString(tr("You have canceled the file export. The file will be removed and no data will be exported.") + "\n" + tr("Do you still want to cancel?")); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked noMoreQso = true; break; case QMessageBox::No: // No Save was clicked break; default: // should never be reached break; } } else {} } // Closes the isValid else {} } //Closes the While //qDebug() << "FileManager::adifLogExportToFile - after the While" << endl; progress.setValue(numberOfQsos); if (noMoreQso) { //TODO: Remove the file (_fileName) file.remove(); return true; } else { return false; } return true; } bool FileManager::cabrilloLogExport(const QString& _fileName, const QString _contestType, const int logNconst) { //qDebug() << "FileManager::cabrilloLogExport" << endl; return cabrilloLogExportToFile(_fileName, logNconst); } bool FileManager::cabrilloLogExportCQWWToFile(const QString& _fileName, const int logNconst) { //qDebug() << "FileManager::cabrilloLogExportCQWWToFile" << _fileName, endl; /* START-OF-LOG: ARRL-SECTION: CALLSIGN: N6TW CATEGORY: SINGLE-OP ALL LOW CLAIMED-SCORE: CLUB: CONTEST: CQ-WW-SSB NAME: ADDRESS: ADDRESS: OPERATORS: [required for multi-op stations] SOAPBOX: [add lines if needed] SOAPBOX: QSO: 3799 PH 2000-11-26 0711 N6TW 59 03 K9QZO 59 04 0 QSO: 14256 PH 2000-11-26 0711 N6TW 59 03 P29AS 59 28 0 QSO: 21250 PH 2000-11-26 0711 N6TW 59 03 4S7TWG 59 22 0 QSO: 28530 PH 2000-11-26 0711 N6TW 59 03 JT1FAX 59 23 0 QSO: 7250 PH 2000-11-26 0711 N6TW 59 03 WA6MIC 59 03 0 END-OF-LOG: This is a template for the QSO portion of the log. --------info sent------- -------info rcvd-------- QSO: freq mo date time call rst exch call rst exch t QSO: ***** ** yyyy-mm-dd nnnn ************* nnn ****** ************* nnn ****** n QSO: 3799 PH 2000-11-26 0711 N6TW 59 03 JT1Z 59 23 0 000000000111111111122222222223333333333444444444455555555556666666666777777777788 123456789012345678901234567890123456789012345678901234567890123456789012345678901 Official Categories This is the list of categories the robot will accept. This will assure we get your category correct and avoid the errors of previous years CATEGORY: SINGLE-OP ALL HIGH CATEGORY: SINGLE-OP 160M HIGH CATEGORY: SINGLE-OP 80M HIGH CATEGORY: SINGLE-OP 40M HIGH CATEGORY: SINGLE-OP 20M HIGH CATEGORY: SINGLE-OP 15M HIGH CATEGORY: SINGLE-OP 10M HIGH CATEGORY: SINGLE-OP ALL LOW CATEGORY: SINGLE-OP 160M LOW CATEGORY: SINGLE-OP 80M LOW CATEGORY: SINGLE-OP 40M LOW CATEGORY: SINGLE-OP 20M LOW CATEGORY: SINGLE-OP 15M LOW CATEGORY: SINGLE-OP 10M LOW CATEGORY: SINGLE-OP ALL QRP CATEGORY: SINGLE-OP 160M QRP CATEGORY: SINGLE-OP 80M QRP CATEGORY: SINGLE-OP 40M QRP CATEGORY: SINGLE-OP 20M QRP CATEGORY: SINGLE-OP 15M QRP CATEGORY: SINGLE-OP 10M QRP CATEGORY: SINGLE-OP-ASSISTED ALL CATEGORY: SINGLE-OP-ASSISTED 160M CATEGORY: SINGLE-OP-ASSISTED 80M CATEGORY: SINGLE-OP-ASSISTED 40M CATEGORY: SINGLE-OP-ASSISTED 20M CATEGORY: SINGLE-OP-ASSISTED 15M CATEGORY: SINGLE-OP-ASSISTED 10M CATEGORY: MULTI-ONE CATEGORY: MULTI-TWO CATEGORY: MULTI-MULTI CATEGORY: CHECKLOG */ QFile file(_fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return false; QTextStream out(&file); QString aux1, queryString; int nameCol = 0; QSqlQuery query, query1; int numberOfQsos = 0; int currentQso = 0; int currentLog = logNconst; noMoreQso = false; queryString = QString("SELECT count(id) FROM log WHERE lognumber='%1'").arg(currentLog); bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } query.next(); if (query.isValid()) { numberOfQsos = (query.value(0)).toInt(); } QProgressDialog progress(tr("Writing Cabrillo file..."), tr("Abort writing"), 0, numberOfQsos, this); progress.setMaximum(numberOfQsos); progress.setWindowModality(Qt::WindowModal); out << "START-OF-LOG:" << endl; out << "ARRL-SECTION: " << endl; out << "CALLSIGN:" << endl; out << "CATEGORY:" << endl; out << "CLAIMED-SCORE:" << endl; out << "CLUB: " << endl; out << "CONTEST:" << endl; out << "NAME: " << endl; out << "ADDRESS:" << endl; out << "ADDRESS:" << endl; out << "ADDRESS:" << endl; out << "ADDRESS:" << endl; out << "OPERATORS:" << endl; out << "SOAPBOX:" << endl; out << "SOAPBOX:" << endl; out << "SOAPBOX:" << endl; out << "SOAPBOX:" << endl; //TODO: When the software supports several log, this should be taken into account in the following query. queryString = "SELECT freq, bandid, modeid, qso_date, time_on, station_callsign, rst_sent, rst_rcvd, call, stx FROM log"; sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } QSqlRecord rec = query.record(); while ( (query.next()) && (!noMoreQso) ) { if (query.isValid()) { /* This is a template for the QSO portion of the log. --------info sent------- -------info rcvd-------- QSO: freq mo date time call rst exch call rst exch t QSO: ***** ** yyyy-mm-dd nnnn ************* nnn ****** ************* nnn ****** n QSO: 3799 PH 2000-11-26 0711 N6TW 59 03 JT1Z 59 23 0 000000000111111111122222222223333333333444444444455555555556666666666777777777788 123456789012345678901234567890123456789012345678901234567890123456789012345678901 */ currentQso++; out << "QSO: " << endl; nameCol = rec.indexOf("freq"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << aux1.rightJustified(5, ' ', true) << " "; } else // if we dont have the freq but the band { nameCol = rec.indexOf("bandid"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); queryString = QString("SELECT cabrillo FROM band WHERE id='%1'").arg(aux1); sqlOK = query1.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number(), query1.lastQuery()); } query1.next(); if (query1.isValid()) { aux1 = (query1.value(0)).toString(); out << aux1.rightJustified(5, ' ', true) << " "; } else { // if we dont even have the band, we add the freq "00000" out << "00000" << " "; } } nameCol = rec.indexOf("modeid"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); queryString = QString("SELECT cabrillo FROM mode WHERE id='%1'").arg(aux1); sqlOK = query1.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number(), query1.lastQuery()); } query1.next(); if (query1.isValid()) { aux1 = (query1.value(0)).toString(); out << aux1 << " "; } else { out << "NO" << " "; } nameCol = rec.indexOf("qso_date"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length()) == 10){ aux1.remove(QChar('-'), Qt::CaseInsensitive); aux1.remove(QChar('/'), Qt::CaseInsensitive); QDate date = QDate::fromString(aux1, "yyyyMMdd"); if (util->isValidDate(date)) { out << aux1 << " "; } else { out << "0000-00-00" << " "; } } nameCol = rec.indexOf("time_on"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); //qDebug() << "FileManager::adifLogExportToFile-time_on: " << aux1 << endl; if ( ((aux1.length()) == 5) || ((aux1.length()) == 8) ){ aux1.remove(QChar(':'), Qt::CaseInsensitive); //out << aux1.resize(2) << " "; } else { out << "0000" << " "; } nameCol = rec.indexOf("station_callsign"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ( (0 <= aux1.length()) && (aux1.length() <= 14) ) { out << aux1.rightJustified(13, ' ', true) << " "; } else { out << QString("NOCAL").rightJustified(13, ' ', true) << " "; } nameCol = rec.indexOf("rst_sent"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << aux1.rightJustified(3, ' ', true) << " "; } nameCol = rec.indexOf("call"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((0 <= aux1.length()) && (aux1.length() <= 14) ) { out << aux1.rightJustified(13, ' ', true) << " "; } else { out << QString("NOCAL").rightJustified(13, ' ', true) << " "; } nameCol = rec.indexOf("rst_rcvd"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << aux1.rightJustified(3, ' ', true) << " "; } nameCol = rec.indexOf("stx"); aux1 = (query.value(nameCol)).toString(); aux1 = util->checkAndFixASCIIinADIF(aux1); if ((aux1.length())>0){ out << "" << aux1 << " "; } } else { } } // END OF WHILE out << "END-OF-LOG:" << endl; file.close(); return true; } bool FileManager::cabrilloLogExportToFile(const QString& _fileName, const int logNconst) { //qDebug() << "FileManager::cabrilloLogExportToFile" << endl; QString fn = _fileName; //TODO: Message "You must select a proper file format QMessageBox msgBox; msgBox.setWindowTitle(tr("KLog: Cabrillo Log Export not implemented")); msgBox.setText(tr("I am sorry but the Cabrillo Export To File feature has still not been implemented.")); msgBox.exec(); return false; } bool FileManager::printQs(const QStringList _line) //bool FileManager::printQs(const QString _q, const QStringList _line) { QStringList qs = _line; for (int i = 0; i'); //qDebug() << "FileManager::adifCheckMoreThanOneLog: data.0: " << data.at(0) << endl; //qDebug() << "FileManager::adifCheckMoreThanOneLog: data.1: " << data.at(1) << endl; if (firstLog) { log1 = (data.at(1)).toInt(); firstLog = false; } else { if (log1 == (data.at(1)).toInt()) {} else { file.close(); return true; } } } } } } //qDebug() << "FileManager::adifCheckMoreThanOneLog: JUST ONE!" << aux << endl; file.close(); return false; } */ bool FileManager::adifLoTWReadLog(const QString& tfileName) { //qDebug() << "FileManager::adifLoTWReadLog: " << tfileName << endl; QString fileName = tfileName; QFile file( fileName ); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //qDebug() << "FileManager::adifLoTWReadLog File not found" << fileName << endl; return false; } QStringList fields, qsToPass; bool hasEOH = false; int numberOfQsos = 0; int numberOfQsosLoWTHeader = 0; QString line = QString(); QString auxString = QString(); QString aux = QString(); qint64 pos; //Position in the file bool inHeader = true; pos = file.pos(); fields.clear(); qsToPass.clear(); //int step = 1; while ( !file.atEnd() ) { line = (file.readLine()).toUpper(); numberOfQsos = numberOfQsos + line.count("EOR>"); if ((line.count("")>0) && (!hasEOH)) { hasEOH = true; } numberOfQsosLoWTHeader = numberOfQsosLoWTHeader + line.count(""); } //847 //qDebug() << "FileManager::adifLoTWReadLog QSOs found: " << QString::number(numberOfQsos) << endl; QProgressDialog progress(tr("Reading LoTW file..."), tr("Abort reading"), 0, numberOfQsos, this); progress.setWindowModality(Qt::ApplicationModal); progress.setVisible(true); progress.setValue(0); progress.setMaximum(numberOfQsos); //step = util->getProgresStepForDialog(numberOfQsos); //qDebug() << "FileManager::adifLoTWReadLog (STEP)/Number: " << QString::number(step) << "/" << QString::number(numberOfQsos) << endl; //qDebug() << "FileManager::adifLoTWReadLog (number & step: " << QString::number(numberOfQsos % step) << endl; file.seek(pos); /* Optional header information may be included before the actual data in the file. To include optional header info, the first character of the file must be something other than <. Any amount of header info of any value except may be included. The header info must be terminated with . Any number of characters of any value except < may follow . The first < after is the start of the first field of the first data record in the file. */ //qDebug() << "FileManager::adifLoTWReadLog: Going to read the HEADER" << endl; //Read HEADER line = file.readLine().trimmed().toUpper(); //qDebug() << "FileManager::adifLoTWReadLog: " << line << endl; if ( (!(line.startsWith('<'))) && (inHeader) ) { // The file has a header if (line.contains("")) // To check if the first line contains the EOR but not alone in the line. { inHeader = false; } line.clear(); // We should finish the if with real data in "line" or a clear one. while ( inHeader && hasEOH) { line = file.readLine().trimmed().toUpper(); if (line.contains("")) { inHeader = false; line.clear(); //TODO: Maybe this clearing deletes a line that may have data... } } pos = file.pos(); } else if (!(line.startsWith('<'))) { // The file does not have any header. // Reading the first QSO... /* Cases: 1.- One big line with several QSO 2.- One QSO uses several lines. - THIS IS USUALLY THE CASE FOR LOTW 3.- Last line of one QSO includes data of the next one */ inHeader = true; while (inHeader) { pos = file.pos(); line = file.readLine().trimmed().toUpper(); if ( (line.startsWith('<')) ) { inHeader = false; line.clear(); //TODO: Maybe this clearing deletes a line that may have data... } } } file.seek(pos); //START reading QSO data... //qDebug() << "FileManager::adifLoTWReadLog: QSO data reading started..." << endl; while ((!noMoreQso) ) { if (!file.atEnd()) { line.clear(); line.append(file.readLine().trimmed().toUpper()); if (line.contains("")) { noMoreQso = true; } //line.append(file.readLine().toUpper()); // TODO: Check if we should remove extra spaces,tabs and so on... //qDebug() << "FileManager::adifLoTWReadLog-line:" << line << endl; fields << line.split("<", QString::SkipEmptyParts); /* DL4ZAA 15M 21.31700 SSB PHONE 20150329 112900 Y 20170910 */ qsToPass.clear(); auxString.clear(); foreach (aux, fields) { aux = aux.trimmed(); if ( (aux.contains('>')) && (auxString.length() > 0) ) { qsToPass.last() = qsToPass.last() + auxString; //qDebug() << "FileManager::adifLoTWReadLog Modified in qsToPass: " << qsToPass.last() << endl; //qsToPass << aux.trimmed(); //qDebug() << "FileManager::adifLoTWReadLog Added to qsToPass: " << aux.trimmed() << endl; auxString.clear(); } else if (( aux.contains('>')) && (auxString.length() <= 0) ) { qsToPass << aux.trimmed(); } else { auxString = auxString + "-" + aux.trimmed(); //qDebug() << "FileManager::adifLoTWReadLog auxString: " << auxString << endl; } //qDebug() << "FileManager::adifLoTWReadLog fields: " << aux << endl; } if (auxString.length()>0) { //qDebug() << "FileManager::adifLoTWReadLog auxString2: " << auxString << endl; qsToPass.last() = qsToPass.last() + auxString.trimmed(); } //qDebug() << "FileManager::adifLoTWReadLog END fields" << endl; //qDebug() << "FileManager::adifLoTWReadLog Mod: " << qsToPass.join("/") << endl; //qDebug() << "FileManager::adifLoTWReadLog END2 fields" << endl; fields = qsToPass; if (fields.contains("EOR>")) // We are going to add a QSO to the log... prepare the Query! { //qDebug() << "FileManager::adifLoTWReadLog: START of QSO "<< endl; //dataProxy->isThisQSODuplicated() //int getDuplicatedQSOId(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode); QString str, _call, _date, _time, _band, _mode; QString field; foreach (str, fields) { field = readAdifField(str).at(0); if (field == "CALL") { } else if (field == "QSO_DATE") { } else if (field == "TIME_ON") {} else if (field == "BAND") {} else if (field == "MODE") {} else {} //qDebug() << "FileManager::adifLoTWReadLog: " << str << endl; } //qDebug() << "FileManager::adifLoTWReadLog: END of QSO "<< endl; fields.clear(); } // END of if (fields.contains("EOR>")) // We are going to add a QSO to the log... ! else { if (file.atEnd()) { noMoreQso = true; } //qDebug() << "FileManager::adifLoTWReadLog: fields DOES NOT contains EOR>" << endl; } } } return true; } bool FileManager::adifReadLog(const QString& tfileName, const int logN) { //qDebug() << "FileManager::adifReadLog:" << tfileName << endl; //int n = 0; //QSqlDatabase db = QSqlDatabase::database(); //int maxLogs = dataProxy->getNumberOfManagedLogs(); // To manage several logs bool sqlOK = true; QStringList queries = QStringList(); queries.clear(); QSqlQuery query; QStringList fields, qsToPass, qsAux; QStringList currentQSOfields = QStringList(); fields.clear(); qsToPass.clear(); qsAux.clear(); QString fieldToAnalyze = QString(); QString fileName = tfileName; QString line = QString(); QString aux = QString(); QString auxString = QString(); QString _band = QString(); bool inHeader = true; bool EOR = false; noMoreQso = false; bool preparedQBool = false; qint64 pos; //Position in the file int i = 0; //Aunxiliar variable int numberOfQsos = 0; int step = 1; int errorCode = -1; int qsosInTransaction = 0; bool ignoreErrorCode19 = false; QFile file( fileName ); //bool moreThanOneLog = adifCheckMoreThanOneLog(file); int howManyLogs = howManyLogsInFile(file); fillHashLog(file); //I am creating several logs when importing a file //We need to fill the hashLog to process then in processLog bool keepLogsInFile = false; //qDebug() << "FileManager::adifReadLog: Logs: " << QString::number(howManyLogs) << endl; if (howManyLogs>1) { QMessageBox msgBox; aux = QString(tr("There is more than one log in this logfile.") + "\n" + tr("All logs will be imported into the current log.") + "\n" + tr("Do you want to continue?")); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked //qDebug() << "FileManager::adifReadLog: clicked YES" << endl; keepLogsInFile = true; break; case QMessageBox::No: // No Save was clicked //qDebug() << "FileManager::adifReadLog: clicked NO" << endl; keepLogsInFile = false; return false; break; default: // should never be reached keepLogsInFile = false; return false; //qDebug() << "FileManager::adifReadLog: default" << endl; break; } } if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //qDebug() << "FileManager::adifReadLog File not found" << fileName << endl; return false; } bool hasEOH = false; pos = file.pos(); while ( !file.atEnd() ) { line = (file.readLine()).toUpper(); numberOfQsos = numberOfQsos + line.count("EOR>"); if ((line.count("")>0) && (!hasEOH)) { hasEOH = true; } } //qDebug() << "FileManager::adifReadLog QSOs found: " << QString::number(numberOfQsos) << endl; QProgressDialog progress(tr("Reading ADIF file..."), tr("Abort reading"), 0, numberOfQsos, this); /*progress.setWindowModality(Qt::WindowModal);*/ progress.setWindowModality(Qt::ApplicationModal); progress.setVisible(true); progress.setValue(0); progress.setMaximum(numberOfQsos); step = util->getProgresStepForDialog(numberOfQsos); //step = getProgresStepForDialog(numberOfQsos); //qDebug() << "FileManager::adifReadLog (STEP)/Number: " << QString::number(step) << "/" << QString::number(numberOfQsos) << endl; //qDebug() << "FileManager::adifReadLog (number & step: " << QString::number(numberOfQsos % step) << endl; file.seek(pos); /* Optional header information may be included before the actual data in the file. To include optional header info, the first character of the file must be something other than <. Any amount of header info of any value except may be included. The header info must be terminated with . Any number of characters of any value except < may follow . The first < after is the start of the first field of the first data record in the file. */ //qDebug() << "FileManager::adifReadLog: Going to read the HEADER" << endl; //Read HEADER line = file.readLine().trimmed().toUpper(); //qDebug() << "FileManager::adifReadLog: " << line << endl; if ( (!(line.startsWith('<'))) && (inHeader) ) { // The file has a header if (line.contains("")) // To check if the first line contains the EOR but not alone in the line. { inHeader = false; } line.clear(); // We should finish the if with real data in "line" or a clear one. while ( inHeader && hasEOH) { line = file.readLine().trimmed().toUpper(); if (line.contains("")) { inHeader = false; line.clear(); //TODO: Maybe this clearing deletes a line that may have data... } } pos = file.pos(); } else if (!(line.startsWith('<'))) { // The file does not have any header. // Reading the first QSO... /* Cases: 1.- One big line with several QSO 2.- One QSO uses several lines. 3.- Last line of one QSO includes data of the next one */ inHeader = true; while (inHeader) { pos = file.pos(); line = file.readLine().trimmed().toUpper(); if ( (line.startsWith('<')) ) { inHeader = false; line.clear(); //TODO: Maybe this clearing deletes a line that may have data... } } } file.seek(pos); // START reading QSO data... //qDebug() << "FileManager::adifReadLog: QSO data reading started..." << endl; preparedQuery.prepare( "INSERT INTO log (call, qso_date, bandid, modeid, time_on, time_off, srx, stx, srx_string, stx_string, qso_date_off, band_rx, rst_sent, rst_rcvd, cqz, ituz, dxcc, address, age, cnty, comment, a_index, ant_az, ant_el, ant_path, arrl_sect, checkcontest, class, contacted_op, contest_id, country, credit_submitted, credit_granted, distance, eq_call, email, eqsl_qslrdate, eqsl_qslsdate, eqsl_qsl_rcvd, eqsl_qsl_sent, force_init, freq, freq_rx, gridsquare, my_gridsquare, iota, iota_island_id, my_iota, my_iota_island_id, k_index, lat, lon, my_lat, my_lon, lotw_qslrdate, lotw_qslsdate, lotw_qsl_rcvd, lotw_qsl_sent, clublog_qso_upload_date, clublog_qso_upload_status, max_bursts, ms_shower, my_city, my_cnty, my_country, my_cq_zone, my_name, name, operator, station_callsign, owner_callsign, my_rig, my_sig, my_sig_info, my_state, state, my_street, notes, nr_bursts, nr_pings, pfx, precedence, prop_mode, public_key, qslmsg, qslrdate, qslsdate, qsl_rcvd, qsl_sent, qsl_rcvd_via, qsl_sent_via, qsl_via, qso_complete, qso_random, qth, rx_pwr, tx_pwr, sat_mode, sat_name, sfi, sig, swl, ten_ten, web, points, multiplier, lognumber) VALUES (:call, :qso_date, :bandid, :modeid, :time_on, :time_off, :srx, :stx, :srx_string, :stx_string, :qso_date_off, :band_rx, :rst_sent, :rst_rcvd, :cqz, :ituz, :dxcc, :address, :age, :cnty, :comment, :a_index, :ant_az, :ant_el, :ant_path, :arrl_sect, :checkcontest, :class, :contacted_op, :contest_id, :country, :credit_submitted, :credit_granted, :distance, :eq_call, :email, :eqsl_qslrdate, :eqsl_qslsdate, :eqsl_qsl_rcvd, :eqsl_qsl_sent, :force_init, :freq, :freq_rx, :gridsquare, :my_gridsquare, :iota, :iota_island_id, :my_iota, :my_iota_island_id, :k_index, :lat, :lon, :my_lat, :my_lon, :lotw_qslrdate, :lotw_qslsdate, :lotw_qsl_rcvd, :lotw_qsl_sent, :clublog_qso_upload_date, :clublog_qso_upload_status, :max_bursts, :ms_shower, :my_city, :my_cnty, :my_country, :my_cq_zone, :my_name, :name, :operator, :station_callsign, :owner_callsign, :my_rig, :my_sig, :my_sig_info, :my_state, :state, :my_street, :notes, :nr_bursts, :nr_pings, :pfx, :precedence, :prop_mode, :public_key, :qslmsg, :qslrdate, :qslsdate, :qsl_rcvd, :qsl_sent, :qsl_rcvd_via, :qsl_sent_via, :qsl_via, :qso_complete, :qso_random, :qth, :rx_pwr, :tx_pwr, :sat_mode, :sat_name, :sfi, :sig, :swl, :ten_ten, :web, :points, :multiplier, :lognumber)" ); /* if (db.transaction()) { //qDebug() << "FileManager::adifReadLog: Transaction Opened" << endl; } else { //qDebug() << "FileManager::adifReadLog: Transaction NOT Opened" << endl; } */ //file.seek(pos); fields.clear(); // while ( (!file.atEnd() ) && (!noMoreQso) && (sqlOK)) while ((!noMoreQso) && (sqlOK)) { if (!file.atEnd()) { line.clear(); line.append(file.readLine().trimmed().toUpper()); //line.append(file.readLine().toUpper()); // TODO: Check if we should remove extra spaces,tabs and so on... //qDebug() << "FileManager::adifReadLog-line:" << line << endl; //fields.clear(); //TODO: Check if I should clear fields... I think I should not because I could loose data if a line contains data after an fields << line.split("<", QString::SkipEmptyParts); } //TODO: Check what happens //qDebug() << "FileManager::adifReadLog START fields" << endl; qsToPass.clear(); auxString.clear(); foreach (aux, fields) { aux = aux.trimmed(); if ( (aux.contains('>')) && (auxString.length() > 0) ) { //qsToPass << auxString + aux; qsToPass.last() = qsToPass.last() + auxString; //qDebug() << "FileManager::adifReadLog Modified in qsToPass: " << qsToPass.last() << endl; qsToPass << aux.trimmed(); //qDebug() << "FileManager::adifReadLog Added to qsToPass: " << aux.trimmed() << endl; auxString.clear(); } else if (( aux.contains('>')) && (auxString.length() <= 0) ) { qsToPass << aux.trimmed(); } else { auxString = auxString + "-" + aux.trimmed(); //qDebug() << "FileManager::adifReadLog auxString: " << auxString << endl; } //qDebug() << "FileManager::adifReadLog fields: " << aux << endl; } //qDebug() << "FileManager::adifReadLog-W-1" << endl; if (auxString.length()>0) { //qDebug() << "FileManager::adifReadLog auxString2: " << auxString << endl; qsToPass.last() = qsToPass.last() + auxString.trimmed(); } //qDebug() << "FileManager::adifReadLog END fields" << endl; //qDebug() << "FileManager::adifReadLog Mod: " << qsToPass.join("/") << endl; //qDebug() << "FileManager::adifReadLog END2 fields" << endl; fields = qsToPass; if (fields.contains("EOR>")) // We are going to add a QSO to the log... prepare the Query! { //qDebug() << "FileManager::adifReadLog: fields contains EOR>" << endl; preparedQuery.bindValue( ":lognumber", logN); while ( (!EOR) && (!fields.isEmpty()) ) { //qDebug() << "FileManager::adifReadLog-W-2" << endl; fieldToAnalyze = (fields.takeFirst()).trimmed(); if ( fieldToAnalyze.contains("EOR>") ) { //qDebug() << "FileManager::adifReadLog-W-2.1" << endl; currentQSOfields << fieldToAnalyze; //preparedQBool = processQsoReadingADIF(currentQSOfields, logN, keepLogsInFile, hashLogs); preparedQBool = processQsoReadingADIF(currentQSOfields, logN, keepLogsInFile); if (preparedQBool) { //qDebug() << "FileManager::adifReadLog: preparedQBool = true" << endl; } else { //qDebug() << "FileManager::adifReadLog: preparedQBool = false" << endl; } } else { //qDebug() << "FileManager::adifReadLog: Not contains EOR" << endl; if ((!fieldToAnalyze.contains('>')) && (currentQSOfields.length()>0)) { //qDebug() << "FileManager::adifReadLog: Contains > & currentsQSOfields.length>0" << endl; auxString = currentQSOfields.at(currentQSOfields.length()-1); auxString = auxString + "\n" + fieldToAnalyze; //currentQSOfields.at(currentQSOfields.length()) = auxString; fieldToAnalyze = auxString; } currentQSOfields << fieldToAnalyze; EOR = false; } } sqlOK = preparedQuery.exec(); //qDebug() << "FileManager::adifReadLog: executedQuery1: " << preparedQuery.executedQuery() << endl; //qDebug() << "FileManager::adifReadLog: executedQuery2: " << preparedQuery.executedQuery() << endl; //qDebug() << "FileManager::adifReadLog: LastQuery2: " << preparedQuery.lastQuery() << endl; if (( (i % step ) == 0) ) { // To update the speed I will only show the progress once each X QSOs //qDebug() << "FileManager::adifReadLog: MOD 0 - i = " << QString::number(i) << endl; aux = tr("Importing ADIF file...") + "\n" + tr(" QSO: ") + QString::number(i) + "/" + QString::number(numberOfQsos); progress.setLabelText(aux); progress.setValue(i); } else { //qDebug() << "FileManager::adifReadLog: Mod: "<< QString::number(i) << " mod " << QString::number(step) << " = " << QString::number(i % step) << endl; } if (sqlOK) { //qDebug() << "FileManager::adifReadLog: (1) in While sqlOK (QSO added) = TRUE" << endl; } else { errorCode = preparedQuery.lastError().number(); //qDebug() << "FileManager::adifReadLog: QSO DUPE" << endl; //qDebug() << "FileManager::adifReadLog: (1) LastQuery: " << preparedQuery.lastQuery() << endl; //qDebug() << "FileManager::adifReadLog: (1) LastError-data: " << preparedQuery.lastError().databaseText() << endl; //qDebug() << "FileManager::adifReadLog: (1) LastError-driver: " << preparedQuery.lastError().driverText() << endl; //qDebug() << "FileManager::adifReadLog: (1) LastError-n: " << QString::number(preparedQuery.lastError().number() ) << endl; if ((errorCode == 19) && (!ignoreErrorCode19)) { // There are some repeated QSO QMessageBox msgBox; aux = tr("It seems that there are some duplicated QSOs in the ADIF file you are importing. Do you want to continue? (Duped QSOs will not be imported)"); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked //qDebug() << "FileManager::adifReadLog: (1) clicked YES" << endl; sqlOK = true; break; case QMessageBox::YesToAll: // Yes was clicked //qDebug() << "FileManager::adifReadLog: (1) clicked YES to ALL" << endl; ignoreErrorCode19 = true; sqlOK = true; break; case QMessageBox::No: // No Save was clicked //qDebug() << "FileManager::adifReadLog: (1) clicked NO" << endl; sqlOK = false; break; default: // should never be reached sqlOK = true; //qDebug() << "FileManager::adifReadLog: (1) default" << endl; break; } //; } else if((errorCode == 19) && (ignoreErrorCode19)) { sqlOK = true; //qDebug() << "FileManager::adifReadLog: errorCode=19 && ignoreErrorCode19" << endl; } else { //qDebug() << "FileManager::adifReadLog: (2) LastQuery: " << preparedQuery.lastQuery() << endl; //qDebug() << "FileManager::adifReadLog: (2) LastError-data: " << preparedQuery.lastError().databaseText() << endl; //qDebug() << "FileManager::adifReadLog: (2) LastError-driver: " << preparedQuery.lastError().driverText() << endl; //qDebug() << "FileManager::adifReadLog: (2) LastError-n: " << QString::number(preparedQuery.lastError().number() ) << endl; emit queryError( Q_FUNC_INFO, preparedQuery.lastError().databaseText(), preparedQuery.lastError().number(), preparedQuery.lastQuery()); noMoreQso = true; /* QMessageBox msgBox; aux = tr("An unexpected error ocurred while importing. Please send this code to the developer for analysis: "); msgBox.setText(aux + "FM-1 #" + QString::number(errorCode) ); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: // Yes was clicked //sqlOK = false; //qDebug() << "FileManager::adifReadLog: (2) I have just set sqlOK=False (1)" << endl; noMoreQso = true; return; break; default: // should never be reached //sqlOK = false; //qDebug() << "FileManager::adifReadLog: (2) I have just set sqlOK=False (2)" << endl; break; } */ } } /* //qDebug() << "FileManager::adifReadLog: qsosInTransaction: " << QString::number(qsosInTransaction) << endl; if ((qsosInTransaction>=step*10) && (qsosInTransaction>200) ) { qsosInTransaction = 0; if (db.commit()) { //qDebug() << "FileManager::adifReadLog: MIDcommit OK: " << QString::number(i) << endl; if (db.transaction()) { //qDebug() << "FileManager::adifReadLog: MIDTransaction Opened" << endl; } else { //qDebug() << "FileManager::adifReadLog: MIDTransaction NOT Opened" << endl; } } else { //qDebug() << "FileManager::adifReadLog: MIDcommit NOK: " << QString::number(i) << endl; errorCode = preparedQuery.lastError().number(); QMessageBox msgBox; aux = tr("An error ocurred while importing. No data will be imported. Please send this code to the developer for analysis: "); msgBox.setText(aux + "FM-2 #" + QString::number(errorCode)); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: // Yes was clicked sqlOK = false; noMoreQso = true; //qDebug() << "FileManager::adifReadLog: I have just set sqlOK=False (3)" << endl; break; default: // should never be reached sqlOK = false; //qDebug() << "FileManager::adifReadLog: I have just set sqlOK=False (4)" << endl; break; } if (db.rollback()) { //qDebug() << "FileManager::adifReadLog: MIDcommit NOK: Rolledback" << endl; } else { //TODO: Check the error if db.rollback returns false //qDebug() << "FileManager::adifReadLog: MIDcommit NOK: Roleback returned FALSE¿?" << endl; } } } else { qsosInTransaction++; } */ if ( progress.wasCanceled() ) { QMessageBox msgBox; aux = QString(tr("You have cancelled the file import. The file will be removed and no data will be imported.") + "\n" + tr("Do you still want to cancel?")); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked noMoreQso = true; break; case QMessageBox::No: // No Save was clicked break; default: // should never be reached break; } } currentQSOfields.clear(); queryPreparation(logN); // to clear Values //progress.setValue(i); i++; } // END of if (fields.contains("EOR>")) // We are going to add a QSO to the log... ! else { if (file.atEnd()) { noMoreQso = true; } //qDebug() << "FileManager::adifReadLog: fields DOES NOT contains EOR>" << endl; } //TODO: Check how to stop the importing process } // END OF WHILE if (noMoreQso) { //qDebug() << "FileManager::adifReadLog: noMoreQso = true" << endl; progress.setValue(numberOfQsos); } else { //qDebug() << "FileManager::adifReadLog: noMoreQso = false" << endl; } if (sqlOK) { //qDebug() << "FileManager::adifReadLog: sqlOK = true" << endl; } else { //qDebug() << "FileManager::adifReadLog: sqlOK = false" << endl; } if (sqlOK) { /* if (db.commit()) { //qDebug() << "FileManager::adifReadLog: Last commit OK" << endl; } else { errorCode = preparedQuery.lastError().number(); QMessageBox msgBox; aux = tr("An error ocurred while importing. No data will be imported. Please send this code to the developer for analysis: "); msgBox.setText(aux + "FM-3 #" + QString::number(errorCode)); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: // Yes was clicked sqlOK = false; //qDebug() << "FileManager::adifReadLog: I have just set sqlOK=False (5)" << endl; break; default: // should never be reached sqlOK = false; //qDebug() << "FileManager::adifReadLog: I have just set sqlOK=False (6)" << endl; break; } if (db.rollback()) { } else { //TODO: Check the error if db.rollback returns false } } */ } else { //qDebug() << "FileManager::adifReadLog: sqlOK = NOK" << endl; } progress.setValue(numberOfQsos); //qDebug() << "FileManager::adifReadLog END " << endl; return true; } bool FileManager::processQsoReadingADIF(const QStringList _line, const int logNumber, const bool _keepLogsInFile) //bool FileManager::processQsoReadingADIF(const QStringList _line, const int logNumber, const bool _keepLogsInFile, QHash &_logs) { //qDebug() << "FileManager::processQsoReadingADIF: log: " << QString::number(logNumber) << endl; //qDebug() << "FileManager::processQsoReadingADIF: log: " << _line.at(0) << endl; //qDebug() << "FileManager::processQsoReadingADIF: " << _line.join("/") << endl; //QHash &hashLogs = _logs; //QFile &file = _f; //bool keepLogsInF;// = _keepLogsInFile; //TODO: Check if needed or remove it completely. This line is just to remove a warning int i = -1; QDate date; QTime time; QStringList qs = _line; QStringList oneField; QString field, data; QSqlQuery query; //confirmed = 0; // 0 means worked, 1 means confirmed QString queryString, stringFields, stringData; //int lastId; //int dxcc = 0; //int cqz = 0; //int ituz = 0; //int i; // Aux value QString aux; // Aux string QString aux2, aux3; QString qrzCall = ""; QString submode = QString(); bool bandRXDef = false; int bandi = -1; int bandrxi = -1; bool rstRXr = false; bool rstTXr = false; //KLog does not understand (and will not import) a QSO without these fields bool haveCall = false; bool haveBand = false; bool haveMode = false; bool haveSubMode = false; bool haveTime = false; bool haveDate = false; //bool ret; //int lenght = 0; //int currentLog = logNumber; //qDebug() << "FileManager::processQsoReadingADIF" << QString::number(qs.size()) << "/" << QString::number(logNumber) << endl; //TODO: To remove the next line, it was just to measure the time it takes. ignoreUnknownAlways = true; QString str; //preparedQuery.bindValue( ":confirmed", '0' ); //qDebug() << "FileManager::processQsoReadingADIF: Entering the foreach" << endl; foreach (str, qs) { //qDebug() << "FileManager::processQsoReadingADIF: " << str << endl; if ( !( (str.contains(":")) && (str.contains(">")) ) ) { //qDebug() << "FileManager::processQsoReadingADIF: NOT (contains : and >): " << str << endl; } else { //qDebug() << "FileManager::processQsoReadingADIF: (contains : and >): " << str << endl; oneField = str.split(">", QString::SkipEmptyParts); //qDebug() << "FileManager::processQsoReadingADIF: (oneField)" << oneField << endl; if (checkADIFValidFormat(oneField)) { i = (qs.at(0)).count(":"); field = (oneField.at(0)).trimmed(); // Needs to be cleared FIELD:4:D data = (oneField.at(1)).trimmed(); data = util->checkAndFixASCIIinADIF(data); if (i == 2) { // DATE:8:D / 20141020 //lenght = (field.section(':', 1, 1)).toInt(); field = field.section(':', 0, 0); } else if (i == 1) { // DATE:8 / 20141020 //lenght = (field.section(':', 1, 1)).toInt(); field = field.section(':', 0, 0); } else { //qDebug() << "FileManager::checkADIFValidFormat-1 " << endl; //return false; } //field = oneField.at(0).trimmed(); //data = oneField.at(1).trimmed(); //lenght = field.indexOf(":"); //field = field.left(lenght); //qDebug() << "FileManager::processQsoReadingADIF (field/data): " << field << "/" << data << endl; if (field == "CALL") { qrzCall = data; preparedQuery.bindValue( ":call", qrzCall ); haveCall = true; //qDebug() << "FileManager::processQsoReadingADIF-CALL:" << data << endl; } else if (field == "QSO_DATE") { //qDebug() << "FileManager::processQsoReadingADIF-QSO_DATE:" << data << endl; preparedQuery.bindValue( ":qso_date", (date.fromString(data, "yyyyMMdd")).toString("yyyy/MM/dd") ); haveDate = true; } else if (field == "BAND") { //preparedQuery.bindValue( ":bandid", data ); i = dataProxy->getIdFromBandName(data); //i = db->getBandIDFromName2(data); if (i>=0) { preparedQuery.bindValue( ":bandid", QString::number(i) ); haveBand = true; bandi = i; //qDebug() << "FileManager::processQsoReadingADIF-Band: " << data << "/" << QString::number(i) << endl; } else { //qDebug() << "FileManager::processQsoReadingADIF-Band - Wrong band: " << data << "/" << QString::number(i) << endl; } /* queryString = QString("SELECT id FROM band WHERE name ='%1'").arg(data); query.exec(queryString); query.next(); if (query.isValid()) { preparedQuery.bindValue( ":bandid", query.value(0).toInt() ); //qDebug() << "FileManager::bprocessQsoReadingADIF-Band: " << data << endl; } */ } else if (field == "MODE") { i = dataProxy->getSubModeIdFromSubMode(data); // get modeid if (i>=0) { { if (!haveSubMode) { preparedQuery.bindValue( ":modeid", QString::number(i) ); haveMode = true; haveSubMode = true; } } } } else if (field == "SUBMODE") { i = dataProxy->getSubModeIdFromSubMode(data); if (i>=0) { preparedQuery.bindValue( ":modeid", QString::number(i) ); preparedQuery.bindValue( ":submode", QString::number(i) ); haveSubMode = true; haveMode=true; //submode = data; } } else if (field == "SRX") { preparedQuery.bindValue( ":srx", data ); //qDebug() << "FileManager::bprocessQsoReadingADIF-srx: " << data << endl; } else if (field == "STX") { preparedQuery.bindValue( ":stx", data ); //qDebug() << "FileManager::bprocessQsoReadingADIF-stx: " << data << endl; } else if (field == "TIME_ON") { if (data.length() == 4) { data = data + "00"; } preparedQuery.bindValue( ":time_on", (time.fromString(data,"hhmmss")).toString("hh:mm:ss") ); haveTime = true; aux3 = (time.fromString(data,"hhmmss")).toString("hh:mm:ss"); //qDebug() << "FileManager::bprocessQsoReadingADIF-time_on: " << (time.fromString(data,"hhmmss")).toString("hh:mm:ss") << endl; } else if (field == "QSO_DATE_OFF") { preparedQuery.bindValue( ":qso_date_off", (date.fromString(data, "yyyyMMdd")).toString("yyyy/MM/dd") ); } else if (field == "BAND_RX") { i = dataProxy->getIdFromBandName(data); //i = db->getBandIDFromName2(data); if (i>=0) { preparedQuery.bindValue( ":band_rx", QString::number(i) ); bandRXDef = true; bandrxi = i; } /* queryString = QString("SELECT id FROM band WHERE name ='%1'").arg(data); query.exec(queryString); query.next(); if (query.isValid()) { preparedQuery.bindValue( ":band_rx", query.value(0).toInt() ); } */ } else if (field == "TIME_OFF") { if (data.length() == 4) { data = data + "00"; } preparedQuery.bindValue( ":time_off", (time.fromString(data,"hhmmss")).toString("hh:mm:ss") ); } else if (field == "RST_SENT") { preparedQuery.bindValue( ":rst_sent", data ); rstTXr = true; } else if (field == "RST_RCVD") { //qDebug() << "FileManager::bprocessQsoReadingADIF-rst_rcvd: " << data << endl; preparedQuery.bindValue( ":rst_rcvd", data ); rstRXr = true; } else if (field == "SRX_STRING") { preparedQuery.bindValue( ":srx_string", data ); } else if (field == "STX_STRING") { preparedQuery.bindValue( ":stx_string", data ); } else if (field == "CQZ") { preparedQuery.bindValue( ":cqz", data ); //cqz = data.toInt(); } else if (field == "ITUZ") { preparedQuery.bindValue( ":ituz", data ); //ituz = data.toInt(); } else if (field == "DXCC") { //dxcc = data.toInt(); preparedQuery.bindValue( ":dxcc", data ); } else if (field == "ADDRESS") { preparedQuery.bindValue( ":address", data ); } else if (field == "AGE") { preparedQuery.bindValue( ":age", data ); } else if (field == "CNTY") { preparedQuery.bindValue( ":cnty", data ); } else if (field == "COMMENT") { preparedQuery.bindValue( ":comment", data ); } else if (field == "A_INDEX") { preparedQuery.bindValue( ":a_index", data ); } else if (field == "ANT_AZ") { preparedQuery.bindValue( ":ant_az", data ); } else if (field == "ANT_EL") { preparedQuery.bindValue( ":ant_el", data ); } else if (field == "ANT_PATH") { preparedQuery.bindValue( ":ant_path", data ); } else if (field == "ARRL_SECT") { preparedQuery.bindValue( ":arrl_sect", data ); } else if (field == "AWARD_GRANTED") { preparedQuery.bindValue( ":award_granted", data ); } else if (field == "AWARD_SUBMITTED") { preparedQuery.bindValue( ":award_submitted", data ); } else if (field == "CHECKCONTEST") { preparedQuery.bindValue( ":checkcontest", data ); } else if (field == "CLASS") { preparedQuery.bindValue( ":class", data ); } else if (field == "CONT") { preparedQuery.bindValue( ":cont", data ); } else if (field == "CONTACTED_OP") { preparedQuery.bindValue( ":contacted_op", data ); } else if (field == "CONTEST_ID") { preparedQuery.bindValue( ":contest_id", data ); } else if (field == "COUNTRY") { preparedQuery.bindValue( ":country", data ); } else if (field == "CREDIT_SUBMITTED") { preparedQuery.bindValue( ":credit_submitted", data ); } else if (field == "CREDIT_GRANTED") { preparedQuery.bindValue( ":credit_granted", data ); } else if (field == "DISTANCE") { preparedQuery.bindValue( ":distance", data ); } else if (field == "DARK_DOK") { preparedQuery.bindValue( ":dark_dok", data ); } else if (field == "EQ_CALL") { preparedQuery.bindValue( ":eq_call", data ); } else if (field == "EMAIL") { if (data.contains("@") && (data.contains("."))) { preparedQuery.bindValue( ":email", data ); } } else if (field == "EQSL_QSLRDATE") { preparedQuery.bindValue( ":eqsl_qslrdate", (date.fromString(data, "yyyyMMdd")).toString("yyyy/MM/dd") ); } else if (field == "EQSL_QSLSDATE") { preparedQuery.bindValue( ":eqsl_qslsdate", (date.fromString(data, "yyyyMMdd")).toString("yyyy/MM/dd") ); } else if (field == "EQSL_QSL_RCVD") { preparedQuery.bindValue( ":eqsl_qsl_rcvd", data ); } else if (field == "EQSL_QSL_SENT") { preparedQuery.bindValue( ":eqsl_qsl_sent", data ); } else if (field == "FISTS") { preparedQuery.bindValue( ":fists", data ); } else if (field == "FISTS_CC") { preparedQuery.bindValue( ":fists_cc", data ); } else if (field == "FORCE_INIT") { preparedQuery.bindValue( ":force_init", data ); } else if (field == "FREQ") { //qDebug() << "FileManager::processQsoReadingADIF -FREQ: " << QString::number(data.toDouble()) << endl; preparedQuery.bindValue( ":freq", data); if (haveBand) { if (dataProxy->getBandIdFromFreq(data.toDouble()) == bandi) //if (db->isThisFreqInBand(db->getBandNameFromNumber(bandi), data)) { preparedQuery.bindValue( ":freq", data); } else { // IF band is defined but not the same than freq, Band wins } } else { preparedQuery.bindValue( ":freq", data); i = dataProxy->getBandIdFromFreq(data.toDouble()); if (i>=0) { preparedQuery.bindValue( ":bandid", QString::number(i) ); haveBand = true; //qDebug() << "FileManager::processQsoReadingADIF-Band: " << data << "/" << QString::number(i) << endl; } } } else if (field == "FREQ_RX") { //haveBand = true; //bandi = i; //i = db->getBandIDFromName2(data); if (bandRXDef) { if (dataProxy->getBandIdFromFreq(data.toDouble()) == bandrxi) //if (db->isThisFreqInBand(db->getBandNameFromNumber(bandrxi), data)) { preparedQuery.bindValue( ":freq_rx", data); } else { // IF band is defined but not the same than freq, Band wins } } else { preparedQuery.bindValue( ":freq_rx", data); } } else if (field == "GRIDSQUARE") { preparedQuery.bindValue( ":gridsquare", data ); } else if (field == "GUEST_OP") { preparedQuery.bindValue( ":guest_op", data ); } else if (field == "HRDLOG_QSO_UPLOAD_DATE") { preparedQuery.bindValue( ":hrd_qso_upload_date", data ); } else if (field == "HRDLOG_QSO_UPLOAD_STATUS") { preparedQuery.bindValue( ":hrd_qso_upload_status", data ); } else if (field == "MY_GRIDSQUARE") { preparedQuery.bindValue( ":my_gridsquare", data ); } else if (field == "MY_ANTENNA") { preparedQuery.bindValue( ":my_antenna", data ); } else if (field == "IOTA") { //qDebug() << "FileManager::processQsoReadingADIF (IOTA): " << data << endl; data = awards->checkIfValidIOTA(data); /* if (data.length()==4) //EU-1 { data.insert(3, "00"); } else if (data.length()==5) //EU-01 { data.insert(3, "0"); } */ if (data.length() == 6) { preparedQuery.bindValue( ":iota", data ); } } else if (field == "IOTA_ISLAND_ID") { preparedQuery.bindValue( ":iota_island_id", data ); } else if (field == "MY_IOTA") { /* if (data.length()==4) //EU-1 { data.insert(3, "00"); } else if (data.length()==5) //EU-01 { data.insert(3, "0"); } */ data = awards->checkIfValidIOTA(data); if (data.length() == 6) { preparedQuery.bindValue( ":my_iota", data ); } } else if (field == "MY_DXCC") { preparedQuery.bindValue( ":my_dxcc", data ); } else if (field == "MY_FISTS") { preparedQuery.bindValue( ":my_fists", data ); } else if (field == "MY_IOTA_ISLAND_ID") { preparedQuery.bindValue( ":my_iota_island_id", data ); } else if (field == "K_INDEX") { preparedQuery.bindValue( ":k_index", data ); } else if (field == "LAT") { preparedQuery.bindValue( ":lat", data ); } else if (field == "LON") { preparedQuery.bindValue( ":lon", data ); } else if (field == "MY_LAT") { preparedQuery.bindValue( ":my_lat", data ); } else if (field == "MY_LON") { preparedQuery.bindValue( ":my_lon", data ); } else if (field == "MY_ITU_ZONE") { preparedQuery.bindValue( ":my_itu_zone", data ); } else if (field == "MY_POSTAL_CODE") { preparedQuery.bindValue( ":my_postal_code", data ); } else if (field == "LOTW_QSLRDATE") { preparedQuery.bindValue( ":lotw_qslrdate", (date.fromString(data, "yyyyMMdd")).toString("yyyy/MM/dd") ); } else if (field == "LOTW_QSLSDATE") { preparedQuery.bindValue( ":lotw_qslsdate", (date.fromString(data, "yyyyMMdd")).toString("yyyy/MM/dd") ); } else if (field == "LOTW_QSL_RCVD") { preparedQuery.bindValue( ":lotw_qsl_rcvd", data ); } else if (field == "LOTW_QSL_SENT") { preparedQuery.bindValue( ":lotw_qsl_sent", data ); } else if (field == "CLUBLOG_QSO_UPLOAD_DATE") { preparedQuery.bindValue( ":clublog_qso_upload_date", (date.fromString(data, "yyyyMMdd")).toString("yyyy/MM/dd") ); } else if (field == "CLUBLOG_QSO_UPLOAD_STATUS") { preparedQuery.bindValue( ":clublog_qso_upload_status", data ); } else if (field == "MAX_BURSTS") { preparedQuery.bindValue( ":max_bursts", data ); } else if (field == "MS_SHOWER") { preparedQuery.bindValue( ":ms_shower", data ); } else if (field == "MY_CITY") { preparedQuery.bindValue( ":my_city", data ); } else if (field == "MY_CNTY") { preparedQuery.bindValue( ":my_cnty", data ); } else if (field == "MY_COUNTRY") { preparedQuery.bindValue( ":my_country", data ); } else if (field == "MY_CQ_ZONE") { preparedQuery.bindValue( ":my_cq_zone", data ); } else if (field == "MY_NAME") { preparedQuery.bindValue( ":my_name", data ); } else if (field == "NAME") { preparedQuery.bindValue( ":name", data ); } else if (field == "OPERATOR") { preparedQuery.bindValue( ":operator", data ); } else if (field == "STATION_CALLSIGN") { preparedQuery.bindValue( ":station_callsign", data ); } else if (field == "OWNER_CALLSIGN") { preparedQuery.bindValue( ":owner_callsign", data ); } else if (field == "MY_RIG") { preparedQuery.bindValue( ":my_rig", data ); } else if (field == "MY_SIG") { preparedQuery.bindValue( ":my_sig", data ); } else if (field == "MY_SIG_INFO") { preparedQuery.bindValue( ":my_sig_info", data ); } else if (field == "MY_SOTA_REF") { preparedQuery.bindValue( ":my_sota_ref", data ); } else if (field == "MY_STATE") { preparedQuery.bindValue( ":my_state", data ); } else if (field == "STATE") { preparedQuery.bindValue( ":state", data ); } else if (field == "MY_STREET") { preparedQuery.bindValue( ":my_street", data ); } else if (field == "MY_USACA_COUNTIES") { preparedQuery.bindValue( ":my_usaca_counties", data ); } else if (field == "MY_VUCC_GRIDS") { preparedQuery.bindValue( ":my_vucc_grids", data ); } else if (field == "NOTES") { preparedQuery.bindValue( ":notes", data ); } else if (field == "NR_BURSTS") { preparedQuery.bindValue( ":nr_bursts", data ); } else if (field == "NR_PINGS") { preparedQuery.bindValue( ":nr_pings", data ); } else if (field == "PFX") { preparedQuery.bindValue( ":pfx", data ); } else if (field == "PRECEDENCE") { preparedQuery.bindValue( ":precedence", data ); } else if (field == "PROP_MODE") { preparedQuery.bindValue( ":prop_mode", data ); } else if (field == "PUBLIC_KEY") { preparedQuery.bindValue( ":public_key", data ); } else if (field == "QRZCOM_QSO_UPLOAD_DATE") { preparedQuery.bindValue( ":qrzcom_qso_upload_date", data ); } else if (field == "QRZCOM_QSO_UPLOAD_STATUS") { preparedQuery.bindValue( ":qrzcom_qso_upload_status", data ); } else if (field == "QSLMSG") { preparedQuery.bindValue( ":qslmsg", data ); } else if (field == "QSLRDATE") { preparedQuery.bindValue( ":qslrdate", (date.fromString(data, "yyyyMMdd")).toString("yyyy/MM/dd") ); } else if (field == "QSLSDATE") { preparedQuery.bindValue( ":qslsdate", (date.fromString(data, "yyyyMMdd")).toString("yyyy/MM/dd") ); } else if (field == "QSL_RCVD") { preparedQuery.bindValue( ":qsl_rcvd", data ); //preparedQuery.bindValue( ":confirmed", '1' ); } else if (field == "QSL_SENT") { preparedQuery.bindValue( ":qsl_sent", data ); } else if (field == "QSL_RCVD_VIA") { preparedQuery.bindValue( ":qsl_rcvd_via", data ); } else if (field == "QSL_SENT_VIA") { preparedQuery.bindValue( ":qsl_sent_via", data ); } else if (field == "QSL_VIA") { //qDebug() << "FileManager::bprocessQsoReadingADIF-QSL_VIA: " << data << endl; if (data == "BUREAU") // This comprobation is to "correct" old logs, mainly from KLog // comming from older ADIF files { preparedQuery.bindValue( ":qsl_sent_via", "B" ); } else if ( (data == "B") || (data == "D") || (data == "E") )// M Deprecated value from ADIF 304 { preparedQuery.bindValue( ":qsl_via", data ); } else { // If values are not valid, are not imported. //TODO: Send an error to the user to show that there was an invalid field } } else if (field == "QSO_COMPLETE") { preparedQuery.bindValue( ":qso_complete", data ); } else if (field == "QSO_RANDOM") { preparedQuery.bindValue( ":qso_random", data ); } else if (field == "QTH") { preparedQuery.bindValue( ":qth", data ); } else if (field == "REGION") { preparedQuery.bindValue( ":region", data ); } else if (field == "RIG") { preparedQuery.bindValue( ":rig", data ); } else if (field == "RX_PWR") { //qDebug() << "FileManager::bprocessQsoReadingADIF-rx_pwr: " << data << endl; preparedQuery.bindValue( ":rx_pwr", data); } else if (field == "TX_PWR") { //qDebug() << "FileManager::bprocessQsoReadingADIF-tx_pwr: " << data << endl; preparedQuery.bindValue( ":tx_pwr", data); } else if (field == "SAT_MODE") { preparedQuery.bindValue( ":sat_mode", data ); } else if (field == "SAT_NAME") { preparedQuery.bindValue( ":sat_name", data ); } else if (field == "SFI") { preparedQuery.bindValue( ":sfi", data ); } else if (field == "SIG") { preparedQuery.bindValue( ":sig", data ); } else if (field == "SIG_INFO") { preparedQuery.bindValue( ":sig_info", data ); } else if (field == "SILENT_KEY") { preparedQuery.bindValue( ":silent_key", data ); } else if (field == "SKCC") { preparedQuery.bindValue( ":skcc", data ); } else if (field == "SOTA_REF") { preparedQuery.bindValue( ":sota_ref", data ); } else if (field == "STATE") { preparedQuery.bindValue( ":state", data ); } else if (field == "SUBMODE") { preparedQuery.bindValue( ":submode", data ); } else if (field == "SWL") { preparedQuery.bindValue( ":swl", data ); } else if (field == "TEN_TEN") { preparedQuery.bindValue( ":ten_ten", data ); } else if (field == "UKSMG") { preparedQuery.bindValue( ":uksmg", data ); } else if (field == "USACA_COUNTIES") { preparedQuery.bindValue( ":usaca_counties", data ); } else if (field == "VE_PROV") { preparedQuery.bindValue( ":ve_prov", data ); } else if (field == "VUCC_GRIDS") { preparedQuery.bindValue( ":vucc_grids", data ); } else if (field == "WEB") { preparedQuery.bindValue( ":web", data ); } else if (field == "APP_KLOG_POINTS") //Importing own ADIF fields { preparedQuery.bindValue( ":points", data ); } else if (field == "APP_KLOG_MULTIPLIER") //Importing own ADIF fields { preparedQuery.bindValue( ":multiplier", data ); } else if (field == "APP_KLOG_TRX") //Importing own ADIF fields { preparedQuery.bindValue( ":transmiterid", data ); } else if (field == "APP_KLOG_LOGN") //Lognumber in a multiple-log file { //TODO: Think about how to import a file with different logs //isThisQSODuplicated(const QString _qrz, const QString _date, const QString _time, const int _band, const int _mode) } else if (field == "APP_N1MM_POINTS") //Importing from N1MM { preparedQuery.bindValue( ":points", data ); } else { } } else { //qDebug() << "FileManager::processQsoReadingADIF (field) CheckAdif FALSE: " << field << endl; } } } //preparedQuery.bindValue( ":lognumber", i); //qDebug() << "FileManager::processQsoReadingADIF: logNumber: " << QString::number(logNumber) << endl; // if ((haveSubMode) && (!haveMode)) // { // We can guess the mode from a submode! // preparedQuery.bindValue( ":mode", dataProxy->getIdFromModeName(dataProxy->getModeFromSubMode(submode)) ); // haveMode = true; // } if (!(haveBand && haveCall && haveMode && haveTime && haveDate )) { aux2 = tr ("This QSO is not including the minimum data to consider a QSO as valid!.") + "\n\n\n" + tr("Please edit the ADIF file and make sure that it include at least:") + "\n\nCALL, QSO_DATE, TIME_ON, BAND "+ tr("and") +" MODE.\n\n" + tr("This QSO had:") + "\n"; if (!haveBand) { aux2 = aux2 + tr(" - The band missing and the following call: ") + qrzCall + ".\n"; //aux2 = "Band missing " + qrzCall + " "; } if (!haveCall) { aux2 = aux2 + tr(" - The call missing but was done at this time: ") + aux3 + ".\n"; //aux2 = "Call missing " + aux3 + " "; } if (!haveMode) { aux2 = aux2 + tr(" - The mode missing and the following call: ") + qrzCall + ".\n"; //aux2 = "Mode missing " + qrzCall + " "; } if (!haveDate) { aux2 = aux2 + tr(" - The date missing and the following call: ") + qrzCall + ".\n"; //aux2 = "Date missing " + qrzCall + " "; } if (!haveTime) { aux2 = aux2 + tr(" - The time missing and the following call: ") + qrzCall + ".\n"; //aux2 = "Time missing " + qrzCall + " "; } aux2 = aux2 + "\n\n" + tr("Do you want to continue with the current file?"); //qDebug() << "FileManager::processQsoReadingADIF - Missing fields: " << aux2 << endl; QMessageBox msgBox; msgBox.setWindowTitle(tr("KLog: Not all required data found!")); msgBox.setText(aux2); msgBox.setStandardButtons(QMessageBox::Yes|QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Cancel); msgBox.setIcon(QMessageBox::Warning); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked break; case QMessageBox::Cancel: noMoreQso = true; break; default: // should never be reached break; } } if ((!rstTXr) && (!rstTXDefault)) { QMessageBox msgBox; aux = tr("This log seems to lack of RST-TX information.") + "\n\n" + tr("Click on Yes to add a default 59 to all QSO with a similar problem.") + "\n\n" + tr("If you select NO, the QSO may not be imported."); msgBox.setWindowTitle(tr("KLog: No RST TX found!")); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); msgBox.setIcon(QMessageBox::Warning); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked rstTXDefault = true; break; default: // should never be reached rstTXDefault = false; break; } } if ((!rstRXr) && (!rstRXDefault)) { QMessageBox msgBox; aux = tr("This log seems to lack of RST-RX information.") + "\n\n" + tr("Click on Yes to add a default 59 to all QSO with a similar problem.") + "\n\n" + tr("If you select NO, the QSO may not be imported."); msgBox.setText(aux); msgBox.setWindowTitle(tr("KLog: No RST RX found!")); msgBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); msgBox.setIcon(QMessageBox::Warning); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked rstRXDefault = true; break; default: // should never be reached rstRXDefault = false; break; } } if ((!rstTXr) && (rstTXDefault)) { preparedQuery.bindValue( ":rst_sent", "59" ); } if ((!rstRXr) && (rstRXDefault)) { preparedQuery.bindValue( ":rst_rcvd", "59" ); } preparedQuery.bindValue( ":lognumber", QString::number(logNumber)); return true; } void FileManager::queryPreparation(const int _logN) { //qDebug() << "FileManager::queryPreparation log: " << QString::number(_logN) << endl; //Prepares the query, ALL fields to default except lognumber, as may change... QStringList columns; columns.clear(); columns << dataProxy->getColumnNamesFromTableLog(); if (columns.size()<2) { //qDebug() << "FileManager::queryPreparation: <2 " << endl; return; } for (int i=0;i'); //qDebug() << "FileManager::howManyLogsInFile: data.0: " << data.at(0) << endl; //qDebug() << "FileManager::howManyLogsInFile: data.1: " << data.at(1) << endl; if (logs.contains(data.at(1))) { } else { logs.append(data.at(1)); } } } } else if (line.contains("EOR")) { atLeastOneLog = true; } else { } } //qDebug() << "FileManager::howManyLogsInFile: JUST ONE!" << aux << endl; file.close(); if ( (logs.size()<2) && atLeastOneLog ) { return 1; } return logs.size(); } bool FileManager::fillHashLog(QFile &_f) { //qDebug() << "FileManager::fillHashLog:" << endl; //hashLogs //1.- Run the log and fill hashLogs //2.- Run the file and continue the log series to be able to translate the files log into our own log hashLogs.clear(); QStringList qs; qs.clear(); qs << dataProxy->getListOfManagedLogs(); int i = 0; for (i=0;i'); //qDebug() << "FileManager::howManyLogsInFile: data.0: " << data.at(0) << endl; //qDebug() << "FileManager::howManyLogsInFile: data.1: " << data.at(1) << endl; if (logs.contains(QString::number(data.at(1).toInt()+10000))) { } else { logs.append(QString::number(data.at(1).toInt()+10000)); } } } } else if (line.contains("EOR")) { //atLeastOneLog = true; } else { } } file.close(); return logs; } void FileManager::setVersion(const QString _version) { util->setVersion(_version); } QStringList FileManager::readAdifField (const QString _field) { // This function receives a QString with an ADIF field and returns a QString with the following format: // ADIF-tag, value // If the QString is not an ADIF tag, it returns a clear QStringList. // We are expecting the ADIF format: // D // Data /* //qDebug() << "FileManager::readAdifField: " << _field << endl; QStringList result; result.clear(); if (!((_field.startsWith("<")) && (_field.contains(":")) && (_field.contains(">")))) { //qDebug() << "FileManager::readAdifField: NOT (contains : and >): " << str << endl; return QStringList(); } // Now we have the data in the result[1] result = _field.split(">", QString::SkipEmptyParts); QString aux = result.at(0); QString data = result.at(1); QString type = QString(); int length = -1; QString fname = QString(); if ( !((aux.endsWith(">")) && !(aux.contains(":"))) ) { return QStringList(); } int i = aux.count(":"); if (i == 1) { lenght = (aux.section(':', 1, 1)).toInt(); fname = aux.section(':', 0, 0); } else if (i == 2) { lenght = (aux.section(':', 1, 1)).toInt(); fname = aux.section(':', 0, 0); type = aux.section(':', 2, 2); } else { //qDebug() << "FileManager::readAdifField: NO proper format(1): " << str << endl; return QStringList(); } if (length<1) { //qDebug() << "FileManager::readAdifField: NO proper format(2): " << str << endl; return QStringList(); } // Now data is splitted in the appropriate variables. We start checking format! result.at(0) = fname; if (fname == "QSO_DATE") { QDate date; date.fromString(data, "yyyyMMdd"); if (date.isValid()) { result.at(1) = data; return result; } else { //qDebug() << "FileManager::readAdifField: NO proper format(date): " << str << endl; return QStringList(); } } else if (fname == "TIME_ON") { QTime time; if (data.length() == 4) { data = data + "00"; } time.fromString(data,"hhmmss"); if (time.isValid()) { result.at(1) = data; return result; } else { //qDebug() << "FileManager::readAdifField: NO proper format(time): " << str << endl; return QStringList(); } } else if (fname == "BAND") { if (dataProxy->getIdFromBandName(data)>0) { result.at(1) = data; return result; } else { //qDebug() << "FileManager::readAdifField: NO proper data(BAND): " << str << endl; return QStringList(); } } else if (fname == "MODE") { if (dataProxy->getSubModeIdFromSubMode(data)>0) { result.at(1) = data; return result; } else { //qDebug() << "FileManager::readAdifField: NO proper data(BAND): " << str << endl; return QStringList(); } } else if (fname == "QSL_RCVD") { } else if (fname == "QSLRDATE") { QDate date; date.fromString(data, "yyyyMMdd"); if (date.isValid()) { result.at(1) = data; return result; } else { //qDebug() << "FileManager::readAdifField: NO proper format(qslrdate): " << str << endl; return QStringList(); } } else { //qDebug() << "FileManager::readAdifField: NO Field found: " << str << endl; return QStringList(); } //qDebug() << "FileManager::readAdifField: NO Field found-2: " << str << endl; */ return QStringList(); } QString FileManager::prepareStringLog() { //qDebug() << "FileManager::prepareStringLog: " << endl; QStringList columns; columns.clear(); columns << dataProxy->getColumnNamesFromTableLog(); if (columns.size()<2) { //qDebug() << "FileManager::prepareStringLog: <2 " << endl; return QString(); } QString queryFields, queryValues; queryFields.clear(); queryValues.clear(); for (int i=0;i. * * * *****************************************************************************/ //#include #include #include #include #include #include #include #include #include #include #include #include "locator.h" #include "dataproxy.h" //#include "awards.h" class QStringList; enum { Entity_Name = 1, Entity_Continent = 2 }; class World : public QWidget { //friend class Awards; Q_OBJECT public: World(DataProxy *dp); World(DataProxy *dp, const QString _klogDir); World(DataProxy *dp, const QString _klogDir, const QString _kontestVer); ~World(); bool create(const QString _worldFile); bool recreate(const QString _worldFile); QString getQRZEntityName(const QString _qrz); QString getEntityName(const int _entityN); QString getQRZEntityMainPrefix(const QString _qrz); QString getEntityMainPrefix(const int _entityN); QString getQRZContinentNumber(const QString _qrz); // Returns the continent id number int getContinentNumber(const int _enti); // Returns the continent id number QString getQRZContinentShortName(const QString _qrz); // Returns the continent shortName (EU, AF, ...) QString getContinentShortName(const int _enti); QString getQRZLocator(const QString _qrz); // Returns the entity locator QString getLocator(const int _entityN); // Returns the entity locator double getQRZLongitude(const QString _qrz); // Returns the longitude of the Entity double getLongitude(const int _enti); // Returns the longitude of the Entity double getQRZLatitude(const QString _qrz); // Returns the latitude of the Entity double getLatitude(const int _enti); // Returns the latitude of the Entity int getEntityCqz(const int _enti); int getQRZCqz(const QString _qrz); //int getPrefixCQz(const QString _p); int getQRZItuz(const QString _qrz); int getEntityItuz(const int _enti); int getQRZARRLId(const QString _qrz); //Returns the ARRL id of the Entity from a QRZ & Returns -1 if not found. bool isNewCQz(const int _cqz); bool isNewEntity(const int _entityN); //int getBandIdFromFreq(const QString fr); QString getQRZEntityPrefixes(const QString _qrz); QString getEntityPrefixes(const int _enti); bool checkQRZValidFormat(const QString _qrz); QStringList getEntitiesNames(); int getHowManyEntities(); private slots: private: //void identifyOS(); int getPrefixId(const QString _qrz); //bool readCTYDAT(); bool readCTYCSV(const QString _worldFile); QStringList processLine(const QString _line); QStringList processLineP(const QString _line, const int _processingEntity); void createWorldModel(); QStringList readZones(const QString &pref, const int _cq, const int _itu); QString changeSlashAndFindPrefix(const QString _qrz); // Changes the \ into / and find the country prefix int progressBarPosition; bool created; QString klogDir, kontestVersion; int cqz, ituz, numberOfEntities; QString entityName; QString currentPrefix; // Used in the progressBar bool ret; QStringList list, prefixAndZones; QString continentName, prefix; int continentId; double lat, lon, utc; //QString line; //bool readingDataOfAnEntity; int nullValue; QSqlRelationalTableModel *worldModel; //QProgressBar *progressBar; Locator *locator; DataProxy *dataProxy; int constrid; // Just an id for the constructor to check who is being executed at one specific time //Awards *awards; //FLAGS //QString flagsDir; //FLAGS-END signals: //void qsoFound(const QStringList _qs); // Each: QString with format: Fieldname:value void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution }; #endif // WORLD_H klog-0.9.2.9/showerrordialog.h0000644000076700000620000000424713233376355014177 0ustar staff#ifndef SHOWERRORDIALOG_H #define SHOWERRORDIALOG_H /*************************************************************************** showerrordialog.h - description ------------------- begin : oct 2017 copyright : (C) 2017 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include class ShowErrorDialog: public QDialog { Q_OBJECT public: ShowErrorDialog(); ~ShowErrorDialog(); void setText(const QString txt); private slots: void slotAcceptButtonClicked(); private: void keyPressEvent(QKeyEvent *event); QTextBrowser *textBrowser; QString text; QLabel *txtLabel; }; #endif // SHOWERRORDIALOG_H klog-0.9.2.9/mainwindowsattab.h0000644000076700000620000001002713233376355014331 0ustar staff#ifndef MAINWINDOWSATTAB_H #define MAINWINDOWSATTAB_H /*************************************************************************** mainwindowsattab.h - description ------------------- begin : jan 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implement the tab of the mainwindow that supports Satellites // #include #include #include "dataproxy.h" #include "locator.h" class MainWindowSatTab : public QWidget { Q_OBJECT public: explicit MainWindowSatTab(DataProxy *dp, QWidget *parent = 0); ~MainWindowSatTab(); QString getSatName(); void setSatName(const QString _t); void setOtherSatName(const QString _t); QString getOtherSatName(); QString getSatMode(); void setSatMode(const QString _t); bool getRepeatThis(); void setRepeatThis(const bool _t); void addBands(QStringList _bands); void setDefaultBands(); //Defines the default bands for SAT communications: 10m/2m/70cm/23CM only if they exist on the selected bands void setUpLink(const QString _t); void setLocator(const QString _t); void clear(); signals: void setPropModeSat(const QString _p); void satBandTXChanged(const QString _p); void satBandRXChanged(const QString _p); void newBandsToBeAdded(const QStringList _p); void txFreqChanged(const QString _p); void rxFreqChanged(const QString _p); void dxLocatorChanged(const QString _p); private slots: void slotSatNameTextChanged(); void slotSatModeTextChanged(); void slotSatDXLocTextChanged(); void slotSatNameComboBoxChanged(); void slotSatBandRXComboBoxChanged(); void slotSatBandTXComboBoxChanged(); void slotSatFreqRXChanged(); void slotSatFreqTXChanged(); private: void createUI(); void populateSatComboBox(); void setSatelliteCombo(const QString _p); int getSatIndex(const QString _p); void setBandsOfSat(const QString _p); void addNewBand(const QString _p); QLineEdit *satNameLineEdit; QLineEdit *satModeLineEdit; QLineEdit *satDXLocatorLineEdit; QLabel *satOtherLabel; QRadioButton *keepThisDataForNextQSORadiobutton; //QComboBox *satNameComboBox; //QPushButton *satNamePushButon; //QComboBox *satNameComboBox, *satModeComboBox; QComboBox *satNameComboBox; QComboBox *satBandTXComboBox, *satBandRXComboBox; QStringList satNames, satModes; QStringList satellitesList; QDoubleSpinBox *txFreqSpinBox, *rxFreqSpinBox; DataProxy *dataProxy; Locator *locator; }; #endif // MAINWINDOWSATTAB_H klog-0.9.2.9/setuppagecolors.cpp0000644000076700000620000001720213233376355014532 0ustar staff/*************************************************************************** setuppagecolors.cpp - description ------------------- begin : nov 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include "setuppagecolors.h" SetupPageColors::SetupPageColors(QWidget *parent) : QWidget(parent) { //qDebug() << "SetupPageColors::SetupPageColors" << endl; newOneColorButton = new QPushButton; neededColorButton = new QPushButton; workedColorButton = new QPushButton; confirmedColorButton = new QPushButton; defaultColorButton = new QPushButton; newOneColorButton->setText(tr("New One")); neededColorButton->setText(tr("Needed in this band")); workedColorButton->setText(tr("Worked in this band")); confirmedColorButton->setText(tr("Confirmed in this band")); defaultColorButton->setText(tr("Default")); newOneColorButton->setAutoFillBackground ( true ); QVBoxLayout *buttonsLayout = new QVBoxLayout; buttonsLayout->addWidget(newOneColorButton); buttonsLayout->addWidget(neededColorButton); buttonsLayout->addWidget(workedColorButton); buttonsLayout->addWidget(confirmedColorButton); buttonsLayout->addWidget(defaultColorButton); setLayout(buttonsLayout); connect(newOneColorButton, SIGNAL(clicked()), this, SLOT(slotNewOneColorButtonClicked()) ); connect(neededColorButton, SIGNAL(clicked()), this, SLOT(slotNeededColorButtonClicked()) ); connect(workedColorButton, SIGNAL(clicked()), this, SLOT(slotWorkedColorButtonClicked()) ); connect(confirmedColorButton, SIGNAL(clicked()), this, SLOT(slotConfirmedColorButtonClicked()) ); connect(defaultColorButton, SIGNAL(clicked()), this, SLOT(slotDefaultColorButtonClicked()) ); setNewOneColor("#FF0000"); setNeededColor("#FF8C00"); setWorkedColor("#FFD700"); setConfirmedColor("#32CD32"); setDefaultColor("#00BFFF"); //qDebug() << "SetupPageColors::SetupPageColors - END" << endl; } SetupPageColors::~SetupPageColors() {; } void SetupPageColors::slotNewOneColorButtonClicked() { //qDebug() << "SetupPageColors::slotNewOneColorButtonClicked " << endl; QString style = "* { background-color: "; style = style + (giveColor(newOneColorButton->palette().color(QPalette::Button))).name(); style = style + "; }"; newOneColorButton->setStyleSheet(style); } void SetupPageColors::slotNeededColorButtonClicked () { //qDebug() << "SetupPageColors::slotNeededColorButtonClicked " << endl; QString style = "* { background-color: "; style = style + (giveColor(neededColorButton->palette().color(QPalette::Button))).name(); style = style + "; }"; neededColorButton->setStyleSheet(style); } void SetupPageColors::slotWorkedColorButtonClicked () { //qDebug() << "SetupPageColors::slotWorkedColorButtonClicked " << endl; QString style = "* { background-color: "; style = style + (giveColor(workedColorButton->palette().color(QPalette::Button))).name(); style = style + "; }"; workedColorButton->setStyleSheet(style); } void SetupPageColors::slotConfirmedColorButtonClicked () { //qDebug() << "SetupPageColors::slotNeededColorButtonClicked " << endl; QString style = "* { background-color: "; style = style + (giveColor(confirmedColorButton->palette().color(QPalette::Button))).name(); style = style + "; }"; confirmedColorButton->setStyleSheet(style); } void SetupPageColors::slotDefaultColorButtonClicked() { //qDebug() << "SetupPageColors::slotDefaultColorButtonClicked " << endl; QString style = "* { background-color: "; style = style + (giveColor(defaultColorButton->palette().color(QPalette::Button))).name(); style = style + "; }"; defaultColorButton->setStyleSheet(style); } QColor SetupPageColors::giveColor (QColor c) { // Receives the actual color, shows the user a color picker and returns the color that the user selects. QColor colorb; color = c; colorb = color; color = QColorDialog::getColor (color, this, tr("Choose a color")); if (color.isValid ()) { //qDebug() << "SetupPageColors::giveColor valid color: " << color.name() << endl; return color; } else { //qDebug() << "SetupPageColors::giveColor NOT valid color" << endl; return colorb; } } QString SetupPageColors::getNewOneColor() { //qDebug() << "SetupPageColors::getNewOneColor: " << (newOneColorButton->palette().color(QPalette::Button)).name() << endl; return (newOneColorButton->palette().color(QPalette::Button)).name(); } QString SetupPageColors::getNeededColor() { return (neededColorButton->palette().color(QPalette::Button)).name(); } QString SetupPageColors::getWorkedColor() { return (workedColorButton->palette().color(QPalette::Button)).name(); } QString SetupPageColors::getConfirmedColor() { return (confirmedColorButton->palette().color(QPalette::Button)).name(); } QString SetupPageColors::getDefaultColor() { return (defaultColorButton->palette().color(QPalette::Button)).name(); } void SetupPageColors::setNewOneColor(const QString c) { QString style = "* { background-color: "; style = style + c; style = style + "; }"; newOneColorButton->setStyleSheet(style); } void SetupPageColors::setNeededColor(const QString c) { QString style = "* { background-color: "; style = style + c; style = style + "; }"; neededColorButton->setStyleSheet(style); } void SetupPageColors::setWorkedColor(const QString c) { QString style = "* { background-color: "; style = style + c; style = style + "; }"; workedColorButton->setStyleSheet(style); } void SetupPageColors::setConfirmedColor(const QString c) { QString style = "* { background-color: "; style = style + c; style = style + "; }"; confirmedColorButton->setStyleSheet(style); } void SetupPageColors::setDefaultColor(const QString c) { QString style = "* { background-color: "; style = style + c; style = style + "; }"; defaultColorButton->setStyleSheet(style); } klog-0.9.2.9/COPYING0000644000076700000620000010451313233376355011644 0ustar staff GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . klog-0.9.2.9/logwindow.h0000644000076700000620000001054013233376355012767 0ustar staff#ifndef LOGWINDOW_H #define LOGWINDOW_H /*************************************************************************** logwindow.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include //#include #include #include #include #include #include #include "dataproxy.h" #include "logmodel.h" #include "awards.h" #include "dxccstatuswidget.h" #include "elogclublog.h" class LogWindow : public QWidget { Q_OBJECT public: explicit LogWindow(DataProxy *dp, QWidget *parent = 0); ~LogWindow(); void createlogPanel(const int _currentLog); void clear(); void refresh(); void setCurrentLog(const int _currentLog); void qslSentViaBureau(const int _qsoId); //Maybe this could be defined as private and call it with an action, if needed. void qslRecViaBureau(const int _qsoId); //Maybe this could be defined as private and call it with an action, if needed. void qslRecViaDirect(const int _qsoId); bool isQSLReceived(const int _qsoId); bool isQSLSent(const int _qsoId); signals: void actionQSODoubleClicked(const int _qsoid); void updateAwards(); void updateSearchText(); //void qsoFound(const QStringList _qs); // Each: QString with format: Fieldname:value void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution private slots: void slotDoubleClickLog(const QModelIndex & index); void slotRighButtonFromLog(const QPoint& pos); void slotQSLSentViaBureauFromLog(); void slotQSLSentViaDirectFromLog(); void slotQSLRecViaDirectFromLog(); void slotQSLRecViaBureauFromLog(); void slotQsoDeleteFromLog(); void slotQSOToEditFromLog(); void slotQueryErrorManagement(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); private: void createUI(); void createActionsCommon(); void createActions(); void deleteQSO(const int _qsoID); void righButtonFromLogMenu(const int trow); void showMenuRightButtonFromLogCreateActions(); void setDefaultData(); void setColumnsToDX(); DataProxy *dataProxy; LogModel *logModel; Awards *awards; DXCCStatusWidget *dxccStatusWidget; eLogClubLog *elogClublog; QTableView *logView; QLabel *logLabel; QAction *delQSOFromLogAct; QAction *qsoToEditFromLogAct; QAction *qslSentViaBureauFromLogAct; QAction *qslSentViaDirectFromLogAct; QAction *qslRecViaBureauFromLogAct; QAction *qslRecViaDirectFromLogAct; int currentLog; }; #endif // LOGWINDOW_H klog-0.9.2.9/main.cpp0000644000076700000620000003565513233376355012253 0ustar staff /* This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include //#include #include #include #include //#include #include "startwizard.h" #include "mainwindow.h" #include "utilities.h" int main(int argc, char *argv[]) { QString version = "0.9.2.9" ; QDir d1 = QDir(); Utilities util = Utilities(); QStringList arguments; QTextStream cout(stdout); QApplication app(argc, argv); QString iconSt; iconSt = ":/img/klog.ico"; QIcon KLogIcon(iconSt); QApplication::setWindowIcon(KLogIcon); //QApplication app(argc, argv); app.setApplicationName(QString("KLog")); app.setApplicationVersion(QString(version)); // Now we check if the user is executing from the command line arguments.clear(); arguments << app.arguments(); if (arguments.length()>1) { if (arguments.contains("-h")) { cout << "Usage: klog [OPTION]... [FILE]..." << endl; cout << "Options:" << endl; cout << " -? Display this help" << endl; cout << " -h Display this help" << endl; cout << " -v Display program version" << endl; //cout << " -e Export Adif file " << endl; } else if (arguments.contains("-?")) { cout << "Usage: klog [OPTION]... [FILE]..." << endl; cout << "Options:" << endl; cout << " -? Display this help" << endl; cout << " -h Display this help" << endl; cout << " -v Display program version" << endl; } else if (arguments.contains("-v")) { cout << "Version: KLog-" << app.applicationVersion() << endl; } else { cout << "Usage: klog [OPTION]... [FILE]..." << endl; cout << "Options:" << endl; cout << " -? Display this help" << endl; cout << " -h Display this help" << endl; cout << " -v Display program version" << endl; } app.quit(); return 0; } //qDebug() << "KLog Main: Start of translation activities: "<< (QTime::currentTime()).toString("HH:mm:ss") << endl; //qDebug() << "KLog Main: Detected language: " << (QLocale::system().name()).left(2) << ".qm" << endl; // Translations begin QTranslator qtTranslator; qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); app.installTranslator(&qtTranslator); QTranslator myappTranslator; bool missingTranslation = false; //QString msgOSFilePath = QString(); // The OS depending part of the message to be printed if no translation is found. #if defined(Q_OS_WIN) //qDebug() << "KLog WIN " << endl; if (QFile::exists(QCoreApplication::applicationDirPath() + "/translations/klog_" + (QLocale::system().name()).left(2) + ".qm") ) { myappTranslator.load(QCoreApplication::applicationDirPath() + "/translations/klog_" + (QLocale::system().name()).left(2) + ".qm"); } else if (QFile::exists(QDir::homePath()+"/klog/klog_" + (QLocale::system().name()).left(2)+ ".qm") ) { myappTranslator.load(QDir::homePath()+"/klog/klog_" + (QLocale::system().name())); } else if (((QLocale::system().name()).left(2)) == "en") { // If language is English, it will execute without showing message } else { missingTranslation = true; //msgOSFilePath = QCoreApplication::applicationDirPath() + "/translations/" ; } #elif defined(Q_OS_OSX) //qDebug() << "KLog OSX " << endl; if (QFile::exists(QCoreApplication::applicationDirPath() + "/translations/klog_" + (QLocale::system().name()).left(2) + ".qm") ) { myappTranslator.load(QCoreApplication::applicationDirPath() + "/translations/klog_" + (QLocale::system().name()).left(2) + ".qm"); } else if (((QLocale::system().name()).left(2)) == "en") { // If language is English, it will execute without showing message } else { missingTranslation = true; //msgOSFilePath = QCoreApplication::applicationDirPath() + "/translations/" ; } #else //qDebug() << "KLog OTHER OS: " << (QLocale::system()).name() << endl; if (QFile::exists("klog_" + (QLocale::system().name()).left(2) + ".qm") ) { myappTranslator.load("klog_" + (QLocale::system().name()).left(2)); } else if (QFile::exists("/usr/share/klog/translations/klog_" + (QLocale::system().name()).left(2) + ".qm") ) { //qDebug() << "KLog OTHER -2: " << "/usr/share/klog/klog_" + (QLocale::system().name()).left(2) << endl; myappTranslator.load("/usr/share/klog/translations/klog_" + (QLocale::system().name())); } else if (QFile::exists(QCoreApplication::applicationDirPath() + "/translations/klog_" + (QLocale::system().name()).left(2) + ".qm")) { //qDebug() << "KLog OTHER -3: " << QCoreApplication::applicationDirPath() + "/translations/klog_" + (QLocale::system().name()).left(2) << endl; myappTranslator.load(QCoreApplication::applicationDirPath() + "/translations/klog_" + (QLocale::system().name())); } else if (((QLocale::system().name()).left(2)) == "en") { // If language is English, it will execute without showing message } else { missingTranslation = true; //sgOSFilePath = QCoreApplication::applicationDirPath() + "/translations/" ; } #endif if (missingTranslation) { //qDebug() << "KLog Main: Translation missing! " << endl; QMessageBox msgBox; QString urlTranslate = QString(); urlTranslate = "

TRANSLATE

"; QString msg = QString(); msgBox.setWindowTitle("KLog"); msgBox.setIcon(QMessageBox::Warning); msgBox.setTextFormat(Qt::RichText); msg = QString("No translation files for your language have been found so KLog will be shown in English.

") + QString("If you have the klog_") + (QLocale::system().name()).left(2) + QString(".qm file for your language, you can copy it into the ") + QCoreApplication::applicationDirPath() + "/translations/" + QString("folder and restart KLog.

If you want to help to translate KLog into your language, please contact the author.

") + urlTranslate; msgBox.setText(msg); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); } //qDebug() << "KLog Main-1" << (QTime::currentTime()).toString("HH:mm:ss") << endl; app.installTranslator(&myappTranslator); //qDebug() << "KLog Main: End of translation activities: "<< (QTime::currentTime()).toString("HH:mm:ss") << endl; // Traslations end QString configFileName, klogDir; klogDir = util.getHomeDir(); configFileName = util.getCfgFile(); //qDebug() << "KLog Main-10" << endl; //qDebug() << "KLog Main: Setting klog dir: " << (QTime::currentTime()).toString("HH:mm:ss")<< endl;; if (!QDir::setCurrent (klogDir) ) { //qDebug() << "MAIN: KLogDir does not exist.... creating " << endl; if (d1.mkdir(klogDir)) { if (QDir::setCurrent (klogDir) ) { //qDebug() << "MAIN: KLogDir has just been created and pointed " << endl; } else { //qDebug() << "MAIN: KLogDir has just been created and pointed FAILED! " << endl; } } else { //qDebug() << "MAIN: KLogDir can not be created?? " << endl; } } else { //qDebug() << "MAIN: KLogDir already existed!! " << endl; } //qDebug() << "KLog Main: Setting klog dir - finished: " << (QTime::currentTime()).toString("HH:mm:ss") << endl; //qDebug() << "KLog Main: Setting config file: " << (QTime::currentTime()).toString("HH:mm:ss") << endl; if(!QFile::exists(configFileName)) { //qDebug() << "MAIN: Starting wizard... " << endl; StartWizard *wizard = new StartWizard(klogDir, version); wizard->setModal(true); int inMemory = wizard->exec(); //qDebug() << "MAIN: Wizard inMemory: " << QString::number(inMemory) << endl; if (inMemory == 1) { //qDebug() << "MAIN: Wizard accepted " << QString::number(inMemory) << " ... Will run in Memory " << endl; MainWindow mw(klogDir, version); mw.show(); return app.exec(); } else if (inMemory == 2) { //qDebug() << "MAIN: Wizard accepted " << QString::number(inMemory) << " ... Will run in file " << endl; MainWindow mw(klogDir, version); mw.show(); return app.exec(); } else { //qDebug() << "MAIN: Wizard cancelled " << QString::number(inMemory) << " ... should close " << endl; QMessageBox msgBox; msgBox.setText(QObject::tr("Install wizard was canceled before completing...")); msgBox.setInformativeText(QObject::tr("Do you want to remove the KLog dir from your disk?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No ); msgBox.setDefaultButton(QMessageBox::Yes); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: if (QDir::setCurrent (QDir::homePath()) ) { if (d1.remove(klogDir)) { QMessageBox msgBox; msgBox.setText(QObject::tr("Your KLog dir has been removed") +"\n\n" + QObject::tr("Thank you for running KLog!")); msgBox.exec(); } else { QMessageBox msgBox; msgBox.setText(QObject::tr("I could not remove your KLog dir. You should do it manually if you want it removed from your hard disk.") +"\n\n" + QObject::tr("Thank you for running KLog!")); msgBox.exec(); } } else { QMessageBox msgBox; msgBox.setText(QObject::tr("Your KLog dir could not be removed. You should do it manually if you want it removed from your hard disk.") +"\n\n" + QObject::tr("Thank you for running KLog!")); msgBox.exec(); } break; case QMessageBox::No: QMessageBox msgBox; msgBox.setText(QObject::tr("Remember that your KLog dir is on your system...") + "\n\n" + QObject::tr("Thank you for running KLog!")); msgBox.exec(); break; } return 0; } } else { //qDebug() << "Main: Start of DB Activities" << endl; DataBase *db = new DataBase(Q_FUNC_INFO, version, util.getKLogDBFile()); //qDebug() << "Main: After Start of DB Activities" << endl; if (!db->createConnection()) { //qDebug() << "Main: Conection not created" << endl; return -1; // Exits with an error; no DB has been created } else { db->updateIfNeeded(); // Check if we need to update the DB //qDebug() << "Main: DB Updated" << endl; } db->~DataBase(); //qDebug() << "Main: End of DB Activities" << endl; //qDebug() << "KLog Main-50" << (QTime::currentTime()).toString("HH:mm:ss") << endl; QPixmap pixmap(":img/klog_512x512.png"); //qDebug() << "KLog Main-51" << (QTime::currentTime()).toString("HH:mm:ss") << endl; QSplashScreen splash(pixmap); //qDebug() << "KLog Main-52" << (QTime::currentTime()).toString("HH:mm:ss") << endl; splash.show(); //qDebug() << "KLog Main-100" << (QTime::currentTime()).toString("HH:mm:ss") << endl; MainWindow mw(klogDir, version); //qDebug() << "KLog Main-101" << (QTime::currentTime()).toString("HH:mm:ss") << endl; mw.show(); //qDebug() << "KLog Main-101.5" << (QTime::currentTime()).toString("HH:mm:ss") << endl; splash.finish(&mw); //qDebug() << "KLog Main-102" << (QTime::currentTime()).toString("HH:mm:ss") << endl; return app.exec(); //qDebug() << "KLog Main-103" << (QTime::currentTime()).toString("HH:mm:ss") << endl; } //qDebug() << "KLog Main-END: " << (QTime::currentTime()).toString("HH:mm:ss") << endl; //return app.exec(); } klog-0.9.2.9/setuppageworldeditor.h0000644000076700000620000000615513233376355015241 0ustar staff#ifndef SETUPPAGEWORLDEDITOR_H #define SETUPPAGEWORLDEDITOR_H /*************************************************************************** setuppageworldeditor.h - description ------------------- begin : jun 2012 copyright : (C) 2012 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include #include #include #include "world.h" #include "dataproxy.h" #include "setupentitydialog.h" #include "utilities.h" enum { WORLD_DXCCid = 0, WORLD_Nameid = 1, WORLD_MainPrefix = 2, WORLD_CQZ = 3, WORLD_ITUZ = 4, WORLD_Cont = 5 }; class SetupPageWorldEditor : public QWidget { Q_OBJECT public: SetupPageWorldEditor(DataProxy *dp, QWidget *parent=0); ~SetupPageWorldEditor(); private slots: void slotAddButtonClicked(); void slotDelButtonClicked(); void slotEditButtonClicked(); void slotDoubleClickEntity( const QModelIndex & index); void slotAnalyzeEntityAddedSignal(const QStringList _qs); void slotImportWorldButtonClicked(); private: World *world; Utilities *util; DataProxy *dataProxy; void createWorldPanel(); void createWorldModel(); void createActions(); bool isWorldEmpty(); QSqlRelationalTableModel *worldModel; QWidget *worldPanel; QTableView *worldView; QTreeWidget *searchResultsTreeWidget; QPushButton *addEntityPushButton, *delEntityPushButton, *editEntityPushButton, *exportWorldPushButton, *loadWorldPushButton; SetupEntityDialog *setupEntityDialog; }; #endif // SETUPPAGEWORLDEDITOR_H klog-0.9.2.9/contest_cqwwdxssb.h0000644000076700000620000001033213233376355014541 0ustar staff#ifndef CONTESTCQWWDXSSB_H #define CONTESTCQWWDXSSB_H /*************************************************************************** contestcqwwdxssb.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include #include #include #include #include #include "contest.h" class ContestCQWWDXSSB : public Contest { public: ContestCQWWDXSSB(); ContestCQWWDXSSB(const QStringList _qs); ~ContestCQWWDXSSB(); bool isMultiplier(const QStringList _qs); // Receives: QStringList _qs; //_qs << DX-Entity << DXCQz << DX-band; int getQSOPoints(const QStringList _qs); // Receives: QStringList _qs; //_qs << DX-Entity << DX-Continent bool saveFileToSend(const QString& _fileName); int getTotalScore(); int getMultipliers(); int getPoints(); // NA in the constructor is North America for scoring purposes signals: void queryError(QString functionFailed, QString errorCodeS, int errorCodeN); // To alert about any failed query execution private: QString myEntity, myCQz, myContinent, NA, thiscontest, mycategory, arrlSection, stationQrz, claimedScore, name, address, operators, soapbox, club, createdby; bool isValidCQz(const QString _cqz); bool isValidEntity(const QString _ent); int constrid; // Just an id for the constructor to check who is being executed at one specific time }; /* V. MULTIPLIER: Two types of multiplier will be used. A multiplier of one (1) for each different zone contacted on each band. A multiplier of one (1) for each different country contacted on each band. Stations are permitted to contact their own country and zone for multiplier credit. The CQ Zone Map, DXCC country list, WAE country list, and WAC boundaries are standards. Maritime mobile stations count only for a zone multiplier. VI. POINTS: Contacts between stations on different continents are worth three (3) points. Contacts between stations on the same continent but different countries, one (1) point. Exception: For North American stations only, contacts between stations within the North American boundaries count two (2) points. Contacts between stations in the same country are permitted for zone or country multiplier credit but have zero (0) point value. VII. SCORING: All stations: the final score is the result of the total QSO points multiplied by the sum of your zone and country multipliers. Example: 1000 QSO points 100 multiplier (30 Zones + 70 Countries) = 100,000 (final score). */ #endif // CONTESTCQWWDXSSB_H klog-0.9.2.9/searchwidget.cpp0000644000076700000620000012604213233376355013767 0ustar staff#include "searchwidget.h" SearchWidget::SearchWidget(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "SearchWidget::SearchWidget" << endl; searchBoxLineEdit = new QLineEdit; dataProxy = dp; awards = new Awards(dataProxy); util = new Utilities; filemanager = new FileManager(dataProxy); world = new World(dataProxy); currentLog = -1; //qDebug() << "SearchWidget::SearchWidget: 00092" << endl; searchResultsTreeWidget = new QTreeWidget; searchResultsTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); searchResultsTreeWidget->setSortingEnabled(true); //searchResultsTreeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); searchResultsTreeWidget->setSelectionMode(QAbstractItemView::MultiSelection); searchResultsTreeWidget->setMouseTracking(true); searchBoxClearButton = new QPushButton(tr("&Clear"), this); searchBoxExportButton = new QPushButton(tr("&Export Highlighted"), this); searchBoxSelectAllButton = new QPushButton(tr("&Select All"), this); searchBoxReSearchButton = new QPushButton(tr("&Search"), this); searchAllRadioButton = new QRadioButton (tr("All"), this); stationCallSignShownInSearch = true; clear(); createUI(); //qDebug() << "SearchWidget::SearchWidget - END" << endl; } SearchWidget::~SearchWidget() { } void SearchWidget::clear() { searchBoxLineEdit->clear(); searchResultsTreeWidget->clear(); qslingNeeded = false; searchSelectAllClicked = false; } void SearchWidget::setShowCallInSearch(const bool _sh) { stationCallSignShownInSearch = _sh; } void SearchWidget::setColors (const QString _newOne, const QString _needed, const QString _worked, const QString _confirmed, const QString _default) { awards->setColors (_newOne, _needed, _worked, _confirmed, _default); } void SearchWidget::setVersion (const QString _version) { filemanager->setVersion(_version); } void SearchWidget::createUI() { searchBoxClearButton->setToolTip(tr("Clear the searches.")); searchBoxExportButton->setToolTip(tr("Export the search result to an ADIF file.")); searchBoxSelectAllButton->setToolTip(tr("Select/Unselect all the QSOs shown.")); searchBoxReSearchButton->setToolTip(tr("Search in the log.")); searchAllRadioButton->setToolTip(tr("Search in all logs.")); searchBoxLineEdit->setToolTip(tr("Enter the QRZ to search for.")); searchResultsTreeWidget->setToolTip(tr("Search results.")); QStringList labels; if (stationCallSignShownInSearch) { labels << tr("QRZ") << tr("Date/Time") << tr("Band") << tr("Mode") << tr("QSL Sent") << tr("QSL Rcvd") << tr("Station Callsign") << tr("ID") ; searchResultsTreeWidget->setColumnCount(8); } else { labels << tr("QRZ") << tr("Date/Time") << tr("Band") << tr("Mode") << tr("QSL Sent") << tr("QSL Rcvd") << tr("ID") ; searchResultsTreeWidget->setColumnCount(7); } searchResultsTreeWidget->setHeaderLabels(labels); //QTreeWidgetItem *item = new QTreeWidgetItem(searchResultsTreeWidget); (searchResultsTreeWidget->header())->resizeSections(QHeaderView::ResizeToContents); searchResultsTreeWidget->clear(); //searchResultsTreeWidget->collapseAll(); searchResultsTreeWidget->setSortingEnabled(true); //searchResultsTreeWidget->setItemsExpandable(false); QHBoxLayout *dxUpRightSearchTopLayout = new QHBoxLayout; dxUpRightSearchTopLayout->addWidget(searchBoxLineEdit); dxUpRightSearchTopLayout->addWidget(searchAllRadioButton); QHBoxLayout *dxUpRightButtonsLayout = new QHBoxLayout; dxUpRightButtonsLayout->addWidget(searchBoxReSearchButton); dxUpRightButtonsLayout->addWidget(searchBoxClearButton); dxUpRightButtonsLayout->addWidget(searchBoxSelectAllButton); dxUpRightButtonsLayout->addWidget(searchBoxExportButton); QVBoxLayout *dxUpRightSearchTabLayout = new QVBoxLayout; dxUpRightSearchTabLayout->addLayout(dxUpRightSearchTopLayout); dxUpRightSearchTabLayout->addLayout(dxUpRightButtonsLayout); dxUpRightSearchTabLayout->addWidget(searchResultsTreeWidget); setLayout(dxUpRightSearchTabLayout); //connect(dataProxy, SIGNAL(qsoFound(QStringList)), this, SLOT(slotQsoFound(QStringList)) ); connect(searchBoxLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotSearchBoxTextChanged() ) ); connect(searchBoxExportButton, SIGNAL(clicked()), this, SLOT(slotSearchExportButtonClicked() ) ); connect(searchBoxClearButton, SIGNAL(clicked()), this, SLOT(slotSearchClearButtonClicked() ) ); connect(searchBoxReSearchButton, SIGNAL(clicked()), this, SLOT(slotSearchBoxReSearchButtonClicked() ) ); connect(searchBoxSelectAllButton, SIGNAL(clicked()), this, SLOT(slotSearchBoxSelectAllButtonClicked() ) ); connect(searchResultsTreeWidget, SIGNAL(itemSelectionChanged( ) ), this, SLOT(slotSearchBoxSelectionChanged( ) ) ); connect(searchResultsTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(slotDoubleClickSearch(QTreeWidgetItem *, int))); connect(searchResultsTreeWidget, SIGNAL(customContextMenuRequested( const QPoint& ) ), this, SLOT(slotRighButtonSearch( const QPoint& ) ) ); } void SearchWidget::slotDoubleClickSearch(QTreeWidgetItem * item, int) { //qDebug() << "SearchWidget::slotDoubleClickSearch" << endl; int number = -1; if (item){ if (stationCallSignShownInSearch) { number = (item->text(7)).toInt(); } else { number = (item->text(6)).toInt(); } actionQSODoubleClicked(number); } else {} } void SearchWidget::slotSearchBoxTextChanged() { //qDebug() << "SearchWidget::slotSearchBoxTextChanged: " << searchBoxLineEdit->text() << endl; QString _id, _call, _dateTime, _band, _bandid, _mode, _qsltx, _qslrx, _stationcallsign, _dxcc; QStringList q; bool searchAll = searchAllRadioButton->isChecked(); int i = -1; int cursorP = searchBoxLineEdit->cursorPosition(); searchBoxLineEdit->setText((searchBoxLineEdit->text()).toUpper()); if ((searchBoxLineEdit->text()).length() < 2) { searchResultsTreeWidget->clear(); return; } searchResultsTreeWidget->clear(); qslingNeeded = false; // If I am searching I am not longer looking for QSO to QSL QString theCall = searchBoxLineEdit->text(); QSqlQuery query; QString queryString, aux; aux.clear(); if ((theCall.startsWith("1")) || (theCall.startsWith("2"))) { // Fix a bug (or my knowledge of SQLite) to search Strings begining with 1 or 2 // sqlite does not understand statements like SELECT call FROM log WHERE call LIKE '%1A%' aux = theCall + "%"; } else { aux = "%" + theCall + "%"; } if (searchAll) { queryString = QString("SELECT call, qso_date, time_on, bandid, modeid, dxcc, qsl_rcvd, qsl_sent, station_callsign, id FROM log WHERE call LIKE '%1'").arg(aux); } else { queryString = QString("SELECT call, qso_date, time_on, bandid, modeid, dxcc, qsl_rcvd, qsl_sent, station_callsign, id FROM log WHERE call LIKE '%1' AND lognumber='%2'").arg(aux).arg(currentLog); } aux.clear(); //qDebug() << "SearchWidget::slotSearchBoxTextChanged: queryString" << queryString << endl; bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } QSqlRecord rec = query.record(); int nameCol = -1; //qDebug() << "SearchWidget::slotSearchBoxTextChanged: queryString EXECUTED!" << endl; QColor color; //QSqlRecord rec = query.record(); QFont font; font.setBold(true); while (query.next()) { if (query.isValid()) { nameCol = rec.indexOf("call"); _call= (query.value(nameCol)).toString(); //nameCol = rec.indexOf("call"); //_call= (query.value(0)).toString(); nameCol = rec.indexOf("qso_date"); _dateTime = (query.value(nameCol)).toString(); //_dateTime = (query.value(1)).toString(); nameCol = rec.indexOf("time_on"); _dateTime = _dateTime + "-" +(query.value(nameCol)).toString(); //_dateTime = _dateTime + "-" +(query.value(2)).toString(); nameCol = rec.indexOf("bandid"); _bandid = (query.value(nameCol)).toString(); //qDebug() << "SearchWidget::slotSearchBoxTextChanged: band: " << QString::number((query.value(3)).toInt()) << endl; _band = dataProxy->getNameFromBandId(_bandid.toInt()); //qDebug() << "SearchWidget::slotSearchBoxTextChanged: _band: " << _band << endl; nameCol = rec.indexOf("modeid"); //qDebug() << "SearchWidget::slotSearchBoxTextChanged: mode: " << QString::number((query.value(nameCol)).toInt()) << endl; //_mode = dataProxy->getNameFromModeId((query.value(4)).toInt()); _mode = dataProxy->getNameFromSubModeId((query.value(nameCol)).toInt()); nameCol = rec.indexOf("dxcc"); _dxcc= (query.value(nameCol)).toString(); nameCol = rec.indexOf("qsl_rcvd"); _qsltx = (query.value(nameCol)).toString(); if (_qsltx.length()<1) { _qsltx = "N"; } nameCol = rec.indexOf("qsl_sent"); _qslrx = (query.value(nameCol)).toString(); if (_qslrx.length()<1) { _qslrx = "N"; } if (stationCallSignShownInSearch) { nameCol = rec.indexOf("station_callsign"); _stationcallsign = (query.value(nameCol)).toString(); //if (_stationcallsign.length()<3) //{ // _stationcallsign = stationQRZ; //} nameCol = rec.indexOf("id"); _id = (query.value(nameCol)).toString(); } else { nameCol = rec.indexOf("id"); _id = (query.value(nameCol)).toString(); } q.clear(); q << _dxcc << _bandid << _mode << QString::number(currentLog); //QColor color = Qt::red; //color = Qt::red; //TODO: Optimize the awards->getQRZDXStatusColor because is TOO slow color = awards->getQRZDXStatusColor(q); //_mode = dataProxy->getSubModeFromId(_mode.toInt()); //_mode = db->getModeNameFromNumber(_mode.toInt()); /* awards.getQRZDXStatusColor(const QStringList _qs); // Receives: QStringList _qs; //_qs << QRZ << BandId << lognumber; */ QTreeWidgetItem *item = new QTreeWidgetItem(searchResultsTreeWidget); i = world->getQRZARRLId(_call); aux = world->getEntityName(i) + " - CQ: " + QString::number(world->getEntityCqz(i)); item->setToolTip(0, aux); item->setToolTip(1, aux); item->setToolTip(2, aux); item->setToolTip(3, aux); item->setToolTip(4, aux); item->setToolTip(5, aux); item->setToolTip(6, aux); //item->setToolTip(0, world->getQRZEntityName(_call)); item->setText(0, _call); item->setFont(0, font); item->setText(1, _dateTime); item->setText(2, _band); //qDebug() << "SearchWidget::slotSearchBoxTextChanged: mode(c) : " << _mode << endl; item->setText(3, _mode); item->setText(4, _qslrx); item->setText(5, _qsltx); if (stationCallSignShownInSearch) { item->setText(6, _stationcallsign); item->setText(7, _id); item->setToolTip(7, aux); } else { item->setText(6, _id); } item->setForeground(0, QBrush(color)); } // Closes if next.isValid } // Closes While (searchResultsTreeWidget->header())->resizeSections(QHeaderView::ResizeToContents); /* if (((theCall.at(cursorP-1)).isSpace()) && (cursorP>1)) { ->setText(theCall.remove(cursorP-1, 1)); cursorP--; } */ searchBoxLineEdit->setCursorPosition(cursorP); /* // The following is a new implementation. It is still not used because it is toooo slow. int cursorP = searchBoxLineEdit->cursorPosition(); bool searchAll = searchAllRadioButton->isChecked(); int logToSearch = -1; if (searchAllRadioButton->isChecked()) { } else { logToSearch = currentLog; } searchBoxLineEdit->setText((searchBoxLineEdit->text()).toUpper()); if ((searchBoxLineEdit->text()).length() < 2) { searchResultsTreeWidget->clear(); return; } searchResultsTreeWidget->clear(); dataProxy->getFoundInLog(searchBoxLineEdit->text(), logToSearch ); searchBoxLineEdit->setCursorPosition(cursorP); */ } void SearchWidget::setCurrentLog(const int _log) { currentLog = _log; } void SearchWidget::slotSearchClearButtonClicked() { //qDebug() << "SearchWidget::slotSearchClearButtonClicked: " << endl; searchResultsTreeWidget->clear(); searchBoxLineEdit->clear(); searchSelectAllClicked = false; qslingNeeded = false; } void SearchWidget::slotSearchBoxSelectAllButtonClicked() { //qDebug() << "SearchWidget::slotSearchBoxSelectAllButtonClicked: " << endl; if (searchSelectAllClicked) { //qDebug() << "SearchWidget::slotSearchBoxSelectAllButtonClicked: UN-SELECTING" << endl; searchSelectAllClicked = false; searchResultsTreeWidget->clearSelection(); searchBoxSelectAllButton->setText(tr("&Select All")); } else { //qDebug() << "SearchWidget::slotSearchBoxSelectAllButtonClicked: SELECTING" << endl; searchSelectAllClicked = true; searchResultsTreeWidget->selectAll(); searchBoxSelectAllButton->setText(tr("&Clear selection")); } } void SearchWidget::slotSearchBoxReSearchButtonClicked() { //qDebug() << "SearchWidget::slotSearchBoxReSearchButtonClicked: " << endl; slotSearchBoxTextChanged(); } void SearchWidget::slotSearchBoxSelectionChanged() {// Detects when a selection has been done in the search box and changes // The button to clear selection //qDebug() << "SearchWidget::slotSearchBoxSelectionChanged: " << endl; if ((searchResultsTreeWidget->selectedItems()).size() > 0 ) { searchBoxSelectAllButton->setText(tr("&Clear selection")); searchSelectAllClicked = true; } else { searchBoxSelectAllButton->setText(tr("&Select All")); searchSelectAllClicked = false; } } void SearchWidget::slotSearchExportButtonClicked() { //qDebug() << "SearchWidget::slotSearchExportButtonClicked: " << endl; // MARK QSOs // SAVE MARKED QSOs TO FILE // UNMARK QSOs bool itemsSelected = false; int _qsoId = 0; int i = 0; QString stringQuery; QSqlQuery query; QTreeWidgetItem *item = searchResultsTreeWidget->topLevelItem(i); bool sqlOK; while (i <= searchResultsTreeWidget->topLevelItemCount() ) { item = searchResultsTreeWidget->topLevelItem(i); if (item == 0) { i = searchResultsTreeWidget->topLevelItemCount() + 1; //qDebug() << "SearchWidget::slotSearchExportButtonClicked: ITEM = 0" << endl; } else { if (stationCallSignShownInSearch) { _qsoId = ((item)->text(7)).toInt(); } else { _qsoId = ((item)->text(6)).toInt(); } if ((item)->isSelected()) { stringQuery = QString("UPDATE log SET marked = 'X' WHERE id='%1'").arg(_qsoId); sqlOK = query.exec(stringQuery); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } itemsSelected = true; //TODO: Prepare this while/query execution i++; //qDebug() << "SearchWidget::slotSearchExportButtonClicked: ITEM MARKED: " << QString::number(_qsoId) << endl; } else { stringQuery = QString("UPDATE log SET marked = 'N' WHERE id='%1'").arg(_qsoId); sqlOK = query.exec(stringQuery); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } //TODO: Prepare this while/query execution i++; //qDebug() << "SearchWidget::slotSearchExportButtonClicked: ITEM NOT MARKED: " << QString::number(_qsoId) << endl; } } } if (itemsSelected) { //qDebug() << "SearchWidget::slotSearchExportButtonClicked: to Ask filename" << endl; QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), util->getHomeDir(), "ADIF (*.adi *.adif)"); filemanager->adifLogExportMarked(fileName); //qDebug() << "SearchWidget::slotSearchExportButtonClicked: to call save file" << endl; dataProxy->unMarkAllQSO(); } else { //No items were selected } //qDebug() << "SearchWidget::slotSearchExportButtonClicked: unmarking..." << endl; } void SearchWidget::slotRighButtonSearch(const QPoint& pos) { //qDebug() << "SearchWidget::slotRighButtonSearch" << endl; QTreeWidgetItem *item = searchResultsTreeWidget->itemAt(pos); int _qsoID = 0; if (item) { //qDebug() << "SearchWidget::slotRighButtonSearch ITEM=true" << endl; // 6 is the column in the searchResultsTreeWidget where the id is saved if (stationCallSignShownInSearch) { //qDebug() << "SearchWidget::slotRighButtonSearch stationCallSignShownInSearch = true" << endl; _qsoID = ((item)->text(7)).toInt(); //qDebug() << "SearchWidget::slotRighButtonSearch QSO1: " << QString::number(_qsoID) << endl; } else { //qDebug() << "SearchWidget::slotRighButtonSearch stationCallSignShownInSearch = false" << endl; _qsoID = ((item)->text(6)).toInt(); //qDebug() << "SearchWidget::slotRighButtonSearch QSO2: " << QString::number(_qsoID) << endl; } //qDebug() << "SearchWidget::slotRighButtonSearch QSO: " << QString::number(_qsoID) << endl; showMenuRightButtonSearchCreateActions(); //qDebug() << "SearchWidget::slotRighButtonSearch -05" << endl; righButtonSearchMenu(_qsoID); //qDebug() << "SearchWidget::slotRighButtonSearch -06" << endl; }else { //qDebug() << "SearchWidget::slotRighButtonSearch ITEM=false" << endl; return; } //qDebug() << "SearchWidget::slotRighButtonSearch: " << QString::number(_qsoID) << endl; } void SearchWidget::righButtonSearchMenu(const int trow) { //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: " << QString::number(trow) << endl; bool qslReceived = dataProxy->isQSLReceived(trow); bool qslSent = dataProxy->isQSLSent(trow); QMenu menu(this); menu.addAction(delQSOFromSearchAct); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -03" << endl; delQSOFromSearchAct->setData(trow); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -04" << endl; menu.addAction(qsoToEditFromSearchAct); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -05" << endl; qsoToEditFromSearchAct->setData(trow); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -06" << endl; menu.addSeparator(); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -07" << endl; if (qslSent) { //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSLSent" << endl; } else { //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Sent" << endl; QMenu *menuSentQsl = menu.addMenu(tr("QSL Send")); menuSentQsl->addAction(qslSentViaBureauFromSearchAct); menuSentQsl->addAction(qslSentViaDirectFromSearchAct); menuSentQsl->addAction(qslSentRequestedAct); if (!qslReceived) { menuSentQsl->addAction(qslSentViaBureauMarkRcvReqFromSearchAct); menuSentQsl->addAction(qslSentViaDirectMarkRcvReqFromSearchAct); qslSentViaBureauMarkRcvReqFromSearchAct->setData(trow); qslSentViaDirectMarkRcvReqFromSearchAct->setData(trow); } qslSentViaBureauFromSearchAct->setData(trow); qslSentViaDirectFromSearchAct->setData(trow); qslSentRequestedAct->setData(trow); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -end qsl not sent" << endl; } if (qslReceived) { //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSLRec" << endl; } else { //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec" << endl; QMenu *menuRecQsl = menu.addMenu(tr("QSL Rcvd")); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 01" << endl; menuRecQsl->addAction(qslRecViaBureauFromSearchAct); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 02" << endl; menuRecQsl->addAction(qslRecViaBureauMarkReqFromSearchAct); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 03" << endl; menuRecQsl->addAction(qslRecViaDirectFromSearchAct); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 04" << endl; menuRecQsl->addAction(qslRecViaDirectMarkReqFromSearchAct); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 05" << endl; menuRecQsl->addAction(qslRecRequestedAct); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 06" << endl; qslRecViaBureauFromSearchAct->setData(trow); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 07" << endl; qslRecViaBureauMarkReqFromSearchAct->setData(trow); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 08" << endl; qslRecViaDirectFromSearchAct->setData(trow); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 09" << endl; qslRecViaDirectMarkReqFromSearchAct->setData(trow); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -QSL Not Rec - 10" << endl; qslRecRequestedAct->setData(trow); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -end qsl not rec" << endl; } //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -end qsl" << endl; menu.exec(QCursor::pos()); //qDebug() << "SearchWidget::slotshowRighButtonSearchMenu: -END" << endl; } void SearchWidget::showMenuRightButtonSearchCreateActions() { //qDebug() << "SearchWidget::showMenuRightButtonSearchCreateActions" << endl; delQSOFromSearchAct = new QAction(tr("&Delete"), this); delQSOFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_D); delQSOFromSearchAct->setStatusTip(tr("Delete a QSO")); connect(delQSOFromSearchAct, SIGNAL(triggered()), this, SLOT(slotQsoDeleteFromSearch())); qsoToEditFromSearchAct = new QAction(tr("&Edit QSO"), this); qsoToEditFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_E); qsoToEditFromSearchAct->setStatusTip(tr("Edit this QSO")); connect(qsoToEditFromSearchAct, SIGNAL(triggered()), this, SLOT(slotQSOToEditFromSearch())); qslSentViaBureauFromSearchAct = new QAction(tr("Via &bureau"), this); qslSentViaBureauFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_B); qslSentViaBureauFromSearchAct->setStatusTip(tr("Send this QSL via bureau")); connect(qslSentViaBureauFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaBureauFromSearch() )); qslSentViaDirectFromSearchAct = new QAction(tr("D&irect"), this); qslSentViaDirectFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_I); qslSentViaDirectFromSearchAct->setStatusTip(tr("Send this QSL via direct")); connect(qslSentViaDirectFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaDirectFromSearch() )); qslSentRequestedAct = new QAction(tr("&Request my QSL"), this); qslSentRequestedAct->setShortcut(Qt::CTRL + Qt::Key_R); qslSentRequestedAct->setStatusTip(tr("Mark my QSL as requested")); connect(qslSentRequestedAct, SIGNAL(triggered()), this, SLOT( slotQSLSentMarkAsRequested() )); qslSentViaDirectMarkRcvReqFromSearchAct = new QAction(tr("Via Direct && mark DX QSL as requested"), this); qslSentViaDirectMarkRcvReqFromSearchAct->setStatusTip(tr("Send this QSL via direct & mark DX QSL as requested")); connect(qslSentViaDirectMarkRcvReqFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaDirectMarkDXReqFromSearch() )); qslSentViaBureauMarkRcvReqFromSearchAct = new QAction(tr("Via Bureau && mark DX QSL as requested"), this); qslSentViaBureauMarkRcvReqFromSearchAct->setStatusTip(tr("Send this QSL via bureau & mark DX QSL as requested")); connect(qslSentViaBureauMarkRcvReqFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaBureuMarkDXReqFromSearch() )); qslRecRequestedAct = new QAction(tr("&Request the QSL"), this); //qslSentRequestedAct->setShortcut(Qt::CTRL + Qt::Key_R); qslRecRequestedAct->setStatusTip(tr("Mark the QSL as requested")); connect(qslRecRequestedAct, SIGNAL(triggered()), this, SLOT( slotQSLRecMarkAsRequested() )); qslRecViaBureauMarkReqFromSearchAct = new QAction(tr("Via bureau && mark my QSL as requested"), this); qslRecViaBureauMarkReqFromSearchAct->setStatusTip(tr("QSL received via bureau & mark my QSL as requested")); connect(qslRecViaBureauMarkReqFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaBureauMarkReqFromSearch() )); qslRecViaBureauFromSearchAct = new QAction(tr("Via bureau"), this); qslRecViaBureauFromSearchAct->setStatusTip(tr("QSL received via bureau")); //qslRecViaBureauFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_R); connect(qslRecViaBureauFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaBureauFromSearch() )); qslRecViaDirectMarkReqFromSearchAct = new QAction(tr("Direc&t && mark as my QSL requested"), this); qslRecViaDirectMarkReqFromSearchAct->setStatusTip(tr("QSL received via direct & mark my QSL as requested")); connect(qslRecViaDirectMarkReqFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaDirectMarkReqFromSearch() )); qslRecViaDirectFromSearchAct = new QAction(tr("Direc&t"), this); qslRecViaBureauFromSearchAct->setStatusTip(tr("QSL received via direct")); //qslRecViaDirectFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_T); connect(qslRecViaDirectFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaDirectFromSearch() )); } void SearchWidget::slotQSLSentViaBureuMarkDXReqFromSearch() { //qDebug() << "slotQSLSentViaBureuMarkDXReqFromSearch: " << (qslSentViaBureauMarkRcvReqFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaBureauMarkRcvReqFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslSentViaBureauMarkRcvReqFromSearchAct->data()).toInt(); dataProxy->qslSentViaBureau(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); dataProxy->qslRecAsRequested(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } // Mark Sent, Bureau, date, update log. } void SearchWidget::slotQSLSentViaDirectMarkDXReqFromSearch() { //qDebug() << "slotQSLSentViaDirectMarkDXReqFromSearch: " << (qslSentViaDirectMarkRcvReqFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaDirectMarkRcvReqFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslSentViaDirectMarkRcvReqFromSearchAct->data()).toInt(); dataProxy->qslSentViaDirect(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); dataProxy->qslRecAsRequested(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } // Mark Sent, Bureau, date, update log. } void SearchWidget::slotQSLSentViaBureauFromSearch() { // //qDebug() << "SearchWidget::slotQSLSentViaBureauFromSearch: " << (qslSentViaBureauFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaBureauFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslSentViaBureauFromSearchAct->data()).toInt(); dataProxy->qslSentViaBureau(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); //logWindow->qslSentViaBureau(_qsoId); //qslSentViaBureau(_qsoId); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void SearchWidget::slotQSLSentViaDirectFromSearch() { //qDebug() << "SearchWidget::slotQSLSentViaDirectFromSearch: " << (qslSentViaDirectFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = ((qslSentViaDirectFromSearchAct->data()).toInt()); dataProxy->qslSentViaDirect(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } //qslSentViaDirect(_qsoId); } void SearchWidget::slotQSLSentMarkAsRequested() { // bool qslSentAsRequested(const int _qsoId, const QString _updateDate); int _qsoId = (qslSentRequestedAct->data()).toInt(); dataProxy->qslSentAsRequested(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void SearchWidget::slotQSLRecMarkAsRequested() { int _qsoId = (qslRecRequestedAct->data()).toInt(); dataProxy->qslRecAsRequested(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void SearchWidget::slotQSLRecViaBureauFromSearch() { //qDebug() << "SearchWidget::slotQSLRecViaBureauFromLog: " << "- Id = " << QString::number( ((logModel->index( ( (qslRecViaBureauFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslRecViaBureauFromSearchAct->data()).toInt(); //logWindow->qslRecViaBureau(_qsoId); dataProxy->qslRecViaBureau(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void SearchWidget::slotQSLRecViaBureauMarkReqFromSearch() { //qDebug() << "SearchWidget::slotQSLRecViaBureauMarkReqFromLog: " << "- Id = " << QString::number( ((logModel->index( ( (qslRecViaBureauFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslRecViaBureauMarkReqFromSearchAct->data()).toInt(); qslRecViaBureauMarkReq(_qsoId); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void SearchWidget::slotQSLRecViaDirectFromSearch() { //qDebug() << "SearchWidget::slotQSLRecViaDirectFromLog: " << (qslRecViaDirectFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslRecViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslRecViaDirectFromSearchAct->data()).toInt(); //logWindow->qslRecViaDirect(_qsoId); dataProxy->qslRecViaDirect(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } // Mark Sent, Bureau, date, update log. } void SearchWidget::slotQSLRecViaDirectMarkReqFromSearch() { //qDebug() << "SearchWidget::slotQSLRecViaDirectFromLog: " << (qslRecViaDirectFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslRecViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslRecViaDirectMarkReqFromSearchAct->data()).toInt(); qslRecViaDirectMarkReq(_qsoId); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } // Mark Sent, Bureau, date, update log. } void SearchWidget::qslRecViaBureauMarkReq(const int _qsoId) { // //qDebug() << "SearchWidget::qslRecViaBureau: " << QString::number(_qsoId) << "/" << (QDate::currentDate()).toString("yyyy/MM/dd") << endl; //setAwards(const int _dxcc, const int _waz, const int _band, const int _mode, const int _workedOrConfirmed); dataProxy->qslRecViaBureau(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd"), true); //awards->setAwards(_qsoId); //Update the DXCC award status //emit logRefresh(); emit updateAwards(); } void SearchWidget::qslRecViaDirectMarkReq(const int _qsoId) { //qDebug() << "SearchWidget::qslRecViaDirect: " << QString::number(_qsoId) << endl; dataProxy->qslRecViaDirect(_qsoId, (QDate::currentDate()).toString("yyyy/MM/dd"), true); //awards->setAwards(_qsoId); //setAwards(const int _dxcc, const int _waz, const int _band, const int _mode, const int _workedOrConfirmed); emit updateAwards(); } void SearchWidget::slotQSOToEditFromSearch() { //qDebug() << "slotQSOToEditFromSearch: " << (qsoToEditFromSearchAct->data()).toString() << endl; actionQSODoubleClicked((qsoToEditFromSearchAct->data()).toInt()); } void SearchWidget::slotQsoDeleteFromSearch() { //qDebug() << "SearchWidget::slotQsoDeleteFromSearch: " << (delQSOFromSearchAct->data()).toString() << endl; int QSOid = (delQSOFromSearchAct->data()).toInt(); //int x = -1; QString _qrz = dataProxy->getCallFromId(QSOid); if (_qrz.length()>=3) { QString message = QString(tr("You have requested to delete the QSO with:") + (" %1")).arg(_qrz); QMessageBox msgBox; msgBox.setIcon(QMessageBox::Question); msgBox.setText(message); msgBox.setInformativeText(tr("Are you sure?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: if(dataProxy->deleteQSO(QSOid)) { emit actionQSODelete(QSOid); emit logRefresh(); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } //dxccStatusWidget->refresh(); //awards->recalculateAwards(); emit updateAwards(); } else { //TODO: The QSO could not be removed... } break; case QMessageBox::No: // No was clicked break; default: // should never be reached break; } } else { // TODO: The QSO to be removed was not found in the log } } void SearchWidget::slotToolSearchQSL(const int actionQSL) { //qDebug() << "SearchWidget::slotToolSearchQSL: " << QString::number(actionQSL) << " - LogNumber: " << QString::number(currentLog) << endl; // 2 means QSL_RCVD = 'R' QString stringQuery = QString(); QString message = QString(); QString aux = QString(); int i = -1; switch (actionQSL) { case 0://void searchToolNeededQSLToSend(); //aux = QString("SELECT count(id) FROM log WHERE lognumber='%1'").arg(currentLog); //qDebug() << "SearchWidget::slotToolSearchQSL: CASE 0" << endl; stringQuery = QString("SELECT call, qso_date, time_on, bandid, modeid, qsl_sent, qsl_rcvd, station_callsign, log.id FROM log JOIN awarddxcc ON awarddxcc.qsoid=log.id WHERE awarddxcc.confirmed='0' AND log.qsl_sent!='Y' AND log.qsl_sent!='Q' AND log.qsl_sent!='R' AND log.lognumber='%1'").arg(currentLog); message = tr("Needed QSO to send the QSL"); qslingNeeded = true; requestBeingShown(); //dxUpRightTab->setCurrentIndex(2); break; case 1: //qDebug() << "SearchWidget::slotToolSearchQSL: CASE 1" << endl; stringQuery = QString("SELECT call, qso_date, time_on, bandid, modeid, qsl_sent, qsl_rcvd, dxcc, station_callsign, id FROM log WHERE qsl_sent=='R' AND lognumber='%1'").arg(currentLog); message = tr("My QSL requested to be sent"); break; case 2://void slotToolSearchNeededQSLPendingToReceive(); //qDebug() << "SearchWidget::slotToolSearchQSL: CASE 2" << endl; stringQuery = QString("SELECT call, qso_date, time_on, bandid, modeid, qsl_sent, qsl_rcvd, dxcc, station_callsign, log.id FROM log WHERE lognumber='%1' AND ( (qsl_sent='Y' AND qsl_rcvd!='Y' AND qsl_rcvd!='I') OR qsl_rcvd='R')").arg(currentLog); message = tr("DX QSL pending to be received"); break; case 3://void slotToolSearchNeededQSLRequested() //qDebug() << "SearchWidget::slotToolSearchQSL: CASE 3" << endl; stringQuery = QString("SELECT call, qso_date, time_on, bandid, modeid, qsl_sent, qsl_rcvd, dxcc, station_callsign, log.id FROM log WHERE lognumber='%1' AND qsl_rcvd='R'").arg(currentLog); message = tr("DX QSL pending to be received"); break; default: //qDebug() << "SearchWidget::slotToolSearchQSL: CASE DEFAULT" << endl; // should never be reached return; break; } int nameCol = -1; QString _call, _dateTime, _band, _mode, _freq, _qsltx, _qslrx, _id, _stationcallsign, _dxcc; QFont font; font.setBold(true); QColor color; QStringList q; searchResultsTreeWidget->clear(); QSqlQuery query(stringQuery); QSqlRecord rec = query.record(); if (!query.exec()) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "SearchWidget::slotToolSearchQSL: Query ERROR" << endl; //TODO: Control the error!! } else { emit toStatusBar(message); // updating the status bar while(query.next()) { if (query.isValid()) { QTreeWidgetItem *item = new QTreeWidgetItem(searchResultsTreeWidget); //aux = world->getQRZEntityName(_call); i = world->getQRZARRLId(_call); aux = world->getEntityName(i) + " - CQ: " + QString::number(world->getEntityCqz(i)); item->setToolTip(0, aux); item->setToolTip(1, aux); item->setToolTip(2, aux); item->setToolTip(3, aux); item->setToolTip(4, aux); item->setToolTip(5, aux); item->setToolTip(6, aux); nameCol = rec.indexOf("call"); _call= (query.value(nameCol)).toString(); nameCol = rec.indexOf("qso_date"); _dateTime = (query.value(nameCol)).toString(); nameCol = rec.indexOf("time_on"); _dateTime = _dateTime + "-" +(query.value(nameCol)).toString(); nameCol = rec.indexOf("bandid"); _freq = (query.value(nameCol)).toString(); _band = dataProxy->getNameFromBandId(_freq.toInt()); //_band = db->getBandNameFromNumber( _freq.toInt() ); nameCol = rec.indexOf("modeid"); _mode = dataProxy->getSubModeFromId((query.value(nameCol)).toInt()); nameCol = rec.indexOf("dxcc"); _dxcc= (query.value(nameCol)).toString(); //qDebug() << "SearchWidget::slotToolSearchQSL: Mode: " << _mode << endl; //qDebug() << "SearchWidget::slotToolSearchQSL: mode " << QString::number((query.value(nameCol)).toInt()) << endl; nameCol = rec.indexOf("qsl_sent"); _qsltx = (query.value(nameCol)).toString(); if (_qsltx.length()<1) { _qsltx = "N"; } nameCol = rec.indexOf("qsl_rcvd"); _qslrx = (query.value(nameCol)).toString(); if (_qslrx.length()<1) { _qslrx = "N"; } if (stationCallSignShownInSearch) { //qDebug() << "SearchWidget::slotToolSearchQSL: stationCallSign "<< endl; nameCol = rec.indexOf("station_callsign"); if (((query.value(nameCol)).toString()).length()>=3) { _stationcallsign = (query.value(nameCol)).toString(); } else { _stationcallsign.clear(); } } nameCol = rec.indexOf("id"); _id= (query.value(nameCol)).toString(); q.clear(); q << _dxcc << _freq << _mode << QString::number(currentLog); color = awards->getQRZDXStatusColor(q); item->setText(0, _call); item->setText(1, _dateTime); item->setText(2, _band); item->setText(3, _mode); item->setText(4, _qsltx); item->setText(5, _qslrx); if (stationCallSignShownInSearch) { item->setText(6, _stationcallsign); item->setText(7, _id); item->setToolTip(7, aux); } else { item->setText(6, _id); } item->setForeground(0, QBrush(color)); } else { //TODO: Check what is happening here! } } //qslingNeeded = true; requestBeingShown(); //dxUpRightTab->setCurrentIndex(2); } } void SearchWidget::searchToolNeededQSLToSend() { //qDebug() << "SearchWidget::slotToolSearchQSLToSend - TO PREPARE THE QUERY and optimize the function" << endl; slotToolSearchQSL(0); } void SearchWidget::slotToolSearchRequestedQSLToSend() { //qDebug() << "SearchWidget::slotToolSearchRequestedQSLToSend" << endl; slotToolSearchQSL(1); } void SearchWidget::slotToolSearchNeededQSLPendingToReceive() { //qDebug() << "SearchWidget::slotToolSearchNeededQSLPendingToReceive " << endl; // QSL RCVD requested or // QSL Sent Y and qsl_rcvd!=Y AND qsl_rcvd!=I //select call from log where (qsl_sent='Y' and qsl_rcvd!='Y' and qsl_rcvd!='I') OR //QString stringQuery = QString("SELECT call FROM log where (qsl_sent='Y' AND qsl_rcvd!='Y' AND qsl_rcvd!='I') OR qsl_rcvd='R'"); slotToolSearchQSL(2); } void SearchWidget::slotToolSearchNeededQSLRequested() { // Requested DX QSL slotToolSearchQSL(3); } klog-0.9.2.9/softwareupdatedialog.h0000644000076700000620000000435313233376355015200 0ustar staff#ifndef SOFTWAREUPDATEDIALOG_H #define SOFTWAREUPDATEDIALOG_H /*************************************************************************** softwareupdatedialog.h - description ------------------- begin : feb 2017 copyright : (C) 2017 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include class SoftwareUpdateDialog: public QDialog { Q_OBJECT public: SoftwareUpdateDialog(); ~SoftwareUpdateDialog(); void setVersion(const QString tversion, const bool updateNeeded); private slots: void slotAcceptButtonClicked(); private: void keyPressEvent(QKeyEvent *event); QTextBrowser *textBrowser; QString text; QString _version; }; #endif // SOFTWAREUPDATEDIALOG_H klog-0.9.2.9/world.cpp0000644000076700000620000013211313233376355012441 0ustar staff/*************************************************************************** world.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "world.h" /* QHash worldPrefixes; To insert a (key, value) pair into the hash, you can use operator[](): hash["EA"] = 130; hash["EA6"] = 131; hash["EA8"] = 132; */ World::World(DataProxy *dp) { //qDebug() << "World::World(0)" << endl; constrid = 1; worldModel = new QSqlRelationalTableModel(this); numberOfEntities = 0; progressBarPosition = 0; klogDir = ""; kontestVersion = ""; locator = new Locator(); created = false; dataProxy = dp; //awards = new Awards(); //qDebug() << "World::World(0) - END" << endl; } World::World(DataProxy *dp, const QString _klogDir) { //qDebug() << "World::World(1): Dir" << _klogDir << endl; constrid = 2; klogDir = _klogDir; kontestVersion = ""; worldModel = new QSqlRelationalTableModel(this); numberOfEntities = 0; progressBarPosition = 0; created = false; //flagsDir=":/flags/"; locator = new Locator(); dataProxy = dp; //qDebug() << "World::World(1): - END" << endl; } World::World(DataProxy *dp, const QString _klogDir, const QString _kontestVer) { //qDebug() << "World::World(2): Dir" << _klogDir << endl; constrid = 3; klogDir = _klogDir; kontestVersion = _kontestVer; worldModel = new QSqlRelationalTableModel(this); //qDebug() << "World::World(2): 1" << endl; numberOfEntities = 0; progressBarPosition = 0; created = false; //appDir = QString(); //flagsDir=":/flags/"; //qDebug() << "World::World(2): 2" << endl; locator = new Locator(); //qDebug() << "World::World(2): 3" << endl; dataProxy = dp; //qDebug() << "World::World(2): - END" << endl; } World::~World() { //qDebug() << "World::~World" << endl; } bool World::recreate(const QString _worldFile) { //qDebug() << "World::recreate: " << _worldFile << endl; QSqlQuery query; if (query.exec("DELETE FROM entity")) { //qDebug() << "World::recreate: EMPTY entity" << endl; if (query.exec("DELETE FROM prefixesofentity")) { //qDebug() << "World::recreate: EMPTY prefixesofentity" << endl; return create(_worldFile); } else {//TODO: Manage the query error //qDebug() << "World::recreate: FAILED TO EMPTY prefixesofentity" << endl; emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return false; } } else {//TODO: Manage the query error //qDebug() << "World::recreate: FAILED TO EMPTY entity" << endl; emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return false; } //qDebug() << "World::recreate: END..." << endl; return false; } bool World::create(const QString _worldFile) { //qDebug() << "World::create: " << _worldFile << endl; //klogDir = _worldFile; //qDebug() << "World::create: 2 " << klogDir << endl; if (readCTYCSV(_worldFile)) { created = true; //qDebug() << "World::create: TRUE" << endl; }else { created = false; //qDebug() << "World::create: FALSE" << endl; } if (created) { //dataProxy->updateISONames(); if (dataProxy->updateISONames()) { //qDebug() << "World::create: updateISONames TRUE" << endl; } else { //qDebug() << "World::create: updateISONames FALSE" << endl; } } //qDebug() << "World::create: END" << endl; return created; } void World::createWorldModel() { worldModel->setTable("entity"); worldModel->setRelation(Entity_Continent, QSqlRelation("continent", "id", "shortname")); worldModel->setSort(Entity_Name, Qt::AscendingOrder); worldModel->setHeaderData(Entity_Name, Qt::Horizontal, tr("Entity")); worldModel->setHeaderData(Entity_Continent, Qt::Horizontal, tr("Continent")); worldModel->select(); } QStringList World::processLine(const QString _line) { //qDebug() << "World::processLine: received: " << _line << endl; //QString queryString; QStringList aa; QString line; line = (_line).simplified(); if ((line).count('\'')) // Replaces ' by _ //The error comes from "Cote d'Ivoire" that breaks the SQL { line.replace(QChar('\''), QChar('_')); } //qDebug() << "World::processLine: Received: " << line << endl; //QSqlQuery query1; nullValue=-1; if ( (line.count(':') == 8 ) ) // First line of an Entity { //United States: 05: 08: NA: 43.00: 87.90: 5.0: K: //qDebug() << "World::processLine first: " << line << endl; numberOfEntities++; list.clear(); list << line.split(':'); entityName = list[0]; cqz = list[1].toInt(); ituz = list[2].toInt(); continentName = (list[3]).simplified(); continentId=-1; lat = list[4].toDouble(); lon = list[5].toDouble(); utc = ((list[6]).simplified()).toDouble(); prefix = list[7]; currentPrefix = prefix; continentId = dataProxy->getContinentIdFromContinentShortName(continentName); //queryString = "SELECT id FROM continent WHERE shortname=='" + continentName + "'"; //query1.exec(queryString); //query1.next(); //if (query1.isValid()) //{ // continentId = (query1.value(0)).toInt(); //} //qDebug() << "World::processLine Query: " << queryString << endl; //qDebug() << "World::processLine Query - Read/continenId: " << continentName << "/" << QString::number(continentId) << endl; //queryString = QString("INSERT INTO entity (id, name, cqz, ituz, continent, latitude, longitude, utc, dxcc, mainprefix) VALUES (NULL,'%1','%2','%3','%4','%5','%6','%7','%8','%9');\n").arg(entityName).arg(cqz).arg(ituz).arg(QString::number(continentId)).arg(lat).arg(lon).arg(utc).arg(numberOfEntities).arg(prefix); aa << entityName << QString::number(cqz) << QString::number(ituz) <getCQzFromEntity(currentEntity); _ituz = dataProxy->getITUzFromEntity(currentEntity); line = line.remove(';'); if (line.count(',') == 0) // Only one prefix in the final line { prefixAndZones = readZones(line, _cqz, _ituz); //aa.clear(); aa << prefixAndZones.at(0) << QString::number(currentEntity) << prefixAndZones.at(1) << prefixAndZones.at(2); //qDebug() << "World::processLineP Query (only one final): " << queryString << endl; //readZones returns a QStringList: prefix, CQz, ITUz //Returns QStringList: prefix << dxcc << cqz << ituz OR CurrentEntity as a number return aa; } else // More than just one prefix in the final line { //qDebug() << "World::processLineP Query (MORE one final)(line):" << line << endl; _list.clear(); _list << line.split(','); aa.clear(); //queryString.clear(); for (int i = 0; i < _list.size(); ++i) { // PROCESS THE LINE //qDebug() << "World::processLineP LastLine prefixes" << _list.at(i) << endl; //readZones returns a QStringList: prefix, CQz, ITUz prefixAndZones = readZones(_list.at(i), _cqz, _ituz); //aa.clear(); aa << prefixAndZones.at(0) << QString::number(currentEntity) << prefixAndZones.at(1) << prefixAndZones.at(2); //return aa; } //qDebug() << "World::processLineP: END" <getCQzFromEntity(currentEntity); _ituz = dataProxy->getITUzFromEntity(currentEntity); if (line.endsWith(',')) { line.chop(1); } if ((line.split(',')).size() == 1) // Only one prefix in the middle line { // Not usual, added this check for sanity reasons only //qDebug() << "World::processLine Query: (only one middle) " << endl; line = line.remove(','); prefixAndZones = readZones(line, _cqz, _ituz); aa.clear(); aa << prefixAndZones.at(0) << QString::number(currentEntity) << prefixAndZones.at(1) << prefixAndZones.at(2); //qDebug() << "World::processLine Query (only one final): " << queryString << endl; return aa; } else { //qDebug() << "World::processLine Query: (MORE than one middle) " << endl; list.clear(); list << line.split(','); //queryString.clear(); aa.clear(); for (int i = 0; i < list.size(); ++i) { // PROCESS THE LINE prefixAndZones = readZones(list[i], _cqz, _ituz); aa << prefixAndZones.at(0) << QString::number(currentEntity) << prefixAndZones.at(1) << prefixAndZones.at(2); //ret = query.exec(queryString); } //qDebug() << "World::processLine Query: " << queryString << endl; } } //aa.clear(); return aa; } QStringList World::readZones (const QString &pref, const int _cq, const int _itu) { //Returns a QStringList: prefix, CQz, ITUz //qDebug() << "World::readZones: (" << pref << "/" << QString::number(_cq) <<"/" << QString::number(_itu)<< ")" << endl; QStringList result; int cq = _cq; int itu = _itu; QString azone; QString aux = pref; if (aux.startsWith("=")){ aux = aux.remove(0,1); } if(aux.count('[')==1) // Check if has special CQz { //qDebug() << "World::readZones DETECTED [ !!!!" << endl; azone = (aux.midRef(aux.indexOf('[')+1)).toString(); //qDebug() << "World::readZones (ITU)-1: " << aux << " right of " << QString::number(aux.indexOf('[')) << " = " << azone << endl; itu = (azone.left(azone.indexOf(']'))).toInt(); //qDebug() << "World::readZones (ITU)-2: " << azone.left(azone.indexOf(']')) << endl; aux = aux.left(aux.indexOf('[')); //qDebug() << "World::readZones (ITU): " << pref << "/" << QString::number(itu) << "/" << aux << endl; } if(aux.count('(')==1) // Check if has special CQz { //qDebug() << "World::readZones DETECTED ( !!!!" << endl; azone = (aux.midRef(aux.indexOf('(')+1)).toString(); cq = (azone.left(azone.indexOf(')'))).toInt(); aux = aux.left(aux.indexOf('(')); //qDebug() << "World::readZones (CQ): " << pref << "/" << QString::number(cq) << "/" << aux << endl; } //qDebug() << "World::readZones (Pref/CQ/ITU): " << pref << "= " << aux <<"/" << QString::number(cq) << "/" << QString::number(itu) << endl; result << aux << QString::number(cq) << QString::number(itu); //qDebug() << "World::readZones (Pref/CQ/ITU): " << result << endl; return result; } int World::getPrefixId(const QString _qrz) { //qDebug() << "World::getPrefixId: -" << _qrz <<"-" << endl; //TODO: Instead of going from long to short, identify prefixes from the begining: // character(may be number) + number if (_qrz.length() < 1) { return -1; } int entityID = 0; QString aux = changeSlashAndFindPrefix((_qrz).toUpper()); while ((entityID <= 0) && (aux.length()>=1) ) { entityID = dataProxy->getDXCCFromPrefix(aux); //qDebug() << "World::getPrefixId: in the while" << aux << " = " << QString::number(entityID) << endl; if (entityID<=0) { aux.chop(1); } } //qDebug() << "World::getPrefixId: " << _qrz << QString::number(entityID) << endl; return entityID; } QString World::getQRZEntityName(const QString _qrz) { //qDebug() << "World::getQRZEntityName: " << _qrz << endl; if (_qrz.length() < 1 ) { return ""; } //QString queryString; //QSqlQuery query; int prefixIDNumber = getPrefixId(_qrz); return getEntityName(prefixIDNumber); /* queryString = "SELECT dxcc FROM prefixesofentity WHERE id=='" + QString::number(prefixIDNumber) +"'"; //qDebug() << "World::getQRZEntityName: queryString-1: " << queryString << endl; query.exec(queryString); query.next(); if (query.isValid()) { prefixIDNumber = (query.value(0)).toInt(); } else { prefixIDNumber = -1; } //qDebug() << "World::getQRZEntityName: " <<_qrz << " = " << (query.value(0)).toString() << endl; queryString = "SELECT name FROM entity WHERE dxcc=='" + QString::number(prefixIDNumber) +"'"; //qDebug() << "World::getQRZEntityName: queryString-2: " << queryString << endl; query.exec(queryString); query.next(); //qDebug() << "World::getQRZEntityName end: " << _qrz << " = " << (query.value(0)).toString() << endl; if (query.isValid()){ return (query.value(0)).toString(); }else{ return ""; } return ""; */ } QString World::getEntityName(const int _entityN) { int prefixIDNumber = _entityN; if (prefixIDNumber<=0) { return ""; } return dataProxy->getEntityNameFromId(prefixIDNumber); /* QString queryString; QSqlQuery query; queryString = QString("SELECT name FROM entity WHERE (mainprefix NOT LIKE '*%') AND dxcc='%1'").arg(prefixIDNumber); //queryString = "SELECT name FROM entity WHERE dxcc=='" + QString::number(prefixIDNumber) +"'"; //qDebug() << "World::getEntityName: queryString-2: " << queryString << endl; query.exec(queryString); query.next(); if (query.isValid()){ return (query.value(0)).toString(); }else{ return ""; } return ""; */ } int World::getQRZCqz(const QString _qrz) { //qDebug() << "World::getQRZCqz: " << _qrz << endl; if (_qrz.length() < 1 ) { return -1; } int i = -1; QString aux = _qrz; while ((i <= 0) && (aux.length()>=1) ) { i = dataProxy->getCQzFromPrefix(aux); if (i<=0) { aux.chop(1); } } return i; //int prefixIdNumber = getPrefixId(_qrz); //return getEntityCqz(prefixIdNumber); } int World::getQRZItuz(const QString _qrz) { //qDebug() << "World::getQRZItuz: " << _qrz << endl; if (_qrz.length() < 1 ) { return -1; } int i = -1; QString aux = _qrz; while ((i <= 0) && (aux.length()>=1) ) { i = dataProxy->getITUzFromPrefix(aux); if (i<=0) { aux.chop(1); } } return i; } int World::getEntityCqz(const int _enti) { if (_enti < 1 ) { return -1; } return dataProxy->getCQzFromEntity(_enti); /* QSqlQuery query; QString queryString; //queryString = QString("SELECT cqz FROM prefixesofentity WHERE (mainprefix NOT LIKE '*%') AND dxcc='%1'").arg(prefixIDNumber); queryString = "SELECT cqz FROM prefixesofentity WHERE dxcc=='" + QString::number(_enti) +"'"; query.exec(queryString); query.next(); //qDebug() << "World::getEntityCqz: " << QString::number(_enti) << " = " << (query.value(0)).toInt() << endl; if (query.isValid()){ return (query.value(0)).toInt(); }else{ return -1; } return -1; */ } int World::getEntityItuz(const int _enti) { if (_enti < 1 ) { return -1; } return dataProxy->getITUzFromEntity(_enti); /* QSqlQuery query; QString queryString; queryString = "SELECT ituz FROM prefixesofentity WHERE dxcc=='" + QString::number(_enti) +"'"; query.exec(queryString); query.next(); //qDebug() << "World::getEntityItuz: " << QString::number(_enti) << " = " << (query.value(0)).toInt() << endl; if (query.isValid()){ return (query.value(0)).toInt(); }else{ return -1; } return -1; */ } int World::getQRZARRLId(const QString _qrz) { //qDebug() << "World::getQRZARRLId" << _qrz << endl; if (_qrz.length() < 1 ) { return -1; } int prefixIdNumber = getPrefixId(_qrz); return prefixIdNumber; } QString World::getQRZEntityMainPrefix(const QString _qrz) { if (_qrz.length() < 1 ) { return ""; } int i = getQRZARRLId(_qrz); return getEntityMainPrefix(i); //QString queryString; //QSqlQuery query; /* queryString = "SELECT mainprefix FROM entity WHERE dxcc=='" + QString::number(i) +"'"; if (!query.exec(queryString)) { return ""; } else { query.next(); //qDebug() << "World::getQRZEntityMainPrefix(id/qrz): " << QString::number(i) << "/" <<_qrz << " = " << (query.value(0)).toString() << endl; if (query.isValid()){ return (query.value(0)).toString(); } else { return ""; } } return ""; */ } QString World::getEntityMainPrefix(const int _entityN) { if (_entityN <= 0 ) { return ""; } return dataProxy->getEntityMainPrefix(_entityN); /* QString queryString; QSqlQuery query; queryString = QString("SELECT mainprefix FROM entity WHERE (mainprefix NOT LIKE '*%') AND dxcc='%1'").arg(_entityN); //queryString = "SELECT mainprefix FROM entity WHERE dxcc=='" + QString::number(_entityN) +"'"; if (!query.exec(queryString)) { return ""; } else { query.next(); if (query.isValid()){ return (query.value(0)).toString(); }else{ return ""; } } return ""; */ } bool World::isNewCQz(const int _cqz) { return dataProxy->isNewCQz(_cqz); /* QString queryString; QSqlQuery query; queryString = "SELECT id FROM log WHERE cqz=='" + QString::number(_cqz) +"'"; if (!query.exec(queryString)) { return false; } else { query.next(); if (query.isValid()){ return true; }else{ return false; } } return false; */ } bool World::isNewEntity(const int _entityN) { if (_entityN <= 0) { return false; } return dataProxy->isNewEntity(_entityN); /* QString queryString; QSqlQuery query; queryString = "SELECT id FROM log WHERE dxcc=='" + QString::number(_entityN) +"'"; if (!query.exec(queryString)) { return false; } else { query.next(); if (query.isValid()){ return true; }else{ return false; } } return false; */ } QString World::getQRZContinentShortName(const QString _qrz) { //qDebug() << "World::getQRZContinentShortName: " << _qrz << endl; //QString continentNumber = getQRZContinentNumber (_qrz); return getContinentShortName (getQRZARRLId(_qrz)); } QString World::getContinentShortName(const int _enti) { //qDebug() << "World::getQRZContinentShortName: " << QString::number(_enti) << endl; //QString continentNumber = QString::number(_enti); if ( _enti < 0 ) { return "--"; } QString a = dataProxy->getContinentShortNameFromEntity(_enti); if (a.length()!=2) { return "--"; } else { return a; } /* QString queryString; QSqlQuery query; queryString = QString("SELECT continent FROM entity WHERE (mainprefix NOT LIKE '*%') AND dxcc='%1'").arg(_enti); //queryString = "SELECT continent FROM entity WHERE dxcc=='" + continentNumber +"'"; if (!query.exec(queryString)) { return "--"; } else { query.next(); if ( !(query.isValid()) ) { //qDebug() << "World::getQRZContinentShortName: NO VALID" << endl; return "--"; }else{ //qDebug() << "World::getQRZContinentShortName: VALID" << endl; return (query.value(0)).toString(); } } return "--"; */ } QString World::getQRZContinentNumber(const QString _qrz) { //qDebug() << "World::getQRZContinentNumber: " << _qrz << endl; int i = getQRZARRLId(_qrz); return QString::number(getContinentNumber(i)); /* QString a; QString queryString; QSqlQuery query; queryString = QString("SELECT continent FROM entity WHERE (mainprefix NOT LIKE '*%') AND dxcc='%1'").arg(i); //queryString = "SELECT continent FROM entity WHERE dxcc=='" + QString::number(i) +"'"; if (!query.exec(queryString)) { return "-1"; } else { query.next(); if ( !(query.isValid()) ) { //qDebug() << "World::getQRZContinentNumber(qrz/i/Cont): NO VALID" << endl; return "-1"; }else{ //qDebug() << "World::getQRZContinentNumber(qrz/i/Cont): VALID" << endl; a = (query.value(0)).toString(); } //qDebug() << "World::getQRZContinentNumber(qrz/i/Cont): " <<_qrz << "/" << QString::number(i) << "/" << a << endl; return a; } return "-1"; */ } int World::getContinentNumber(const int _enti) { //qDebug() << "World::getQRZContinentNumber: " << QString::number(_enti) << endl; if (_enti <= 0) { return -1; } return dataProxy->getContinentIdFromEntity(_enti); /* int a = -1; QString queryString; QSqlQuery query; int i = _enti; queryString = QString("SELECT continent FROM entity WHERE (mainprefix NOT LIKE '*%') AND dxcc='%1'").arg(i); //queryString = "SELECT continent FROM entity WHERE dxcc=='" + QString::number(i) +"'"; if (!query.exec(queryString)) { return -1; } else { query.next(); if ( !(query.isValid()) ) { return -1; }else{ a = (query.value(0)).toInt(); queryString = "SELECT id FROM continent where shortname=='" + query.value(0).toString() + "'"; if (query.exec(queryString)) { query.next(); if(query.isValid()) { return query.value(0).toInt(); } else { // Value not valid return -1; } } else { // Error in the query return -1; } } return a; } return -1; */ } double World::getQRZLongitude(const QString _qrz) { int i = getQRZARRLId(_qrz); return dataProxy->getLongitudeFromEntity(i); /* QString queryString; QSqlQuery query; queryString = "SELECT longitude FROM entity WHERE dxcc=='" + QString::number(i) +"'"; if (!query.exec(queryString)) { return 0.0; } else { query.next(); if ( !(query.isValid()) ) { //qDebug() << "World::getQRZLongitude: NO VALID" << endl; return 0.0; }else{ //qDebug() << "World::getQRZLongitude: VALID" << endl; return (query.value(0)).toDouble(); } } return 0.0; */ } double World::getLongitude(const int _enti) { if (_enti <= 0) { return 0.0; } return dataProxy->getLongitudeFromEntity(_enti); /* QString queryString; QSqlQuery query; int i = _enti; queryString = "SELECT longitude FROM entity WHERE dxcc=='" + QString::number(i) +"'"; if (!query.exec(queryString)) { return 0.0; } else { query.next(); if ( !(query.isValid()) ) { //qDebug() << "World::getQRZLongitude: NO VALID" << endl; return 0.0; }else{ //qDebug() << "World::getQRZLongitude: VALID" << endl; return (query.value(0)).toDouble(); } } return 0.0; */ } double World::getQRZLatitude(const QString _qrz) { int i = getQRZARRLId(_qrz); return dataProxy->getLatitudeFromEntity(i); /* QString queryString; QSqlQuery query; queryString = "SELECT latitude FROM entity WHERE dxcc=='" + QString::number(i) +"'"; if (!query.exec(queryString)) { return 0.0; } else { query.next(); if ( !(query.isValid()) ) { //qDebug() << "World::getQRZLatitud: NO VALID" << endl; return 0.0; }else{ //qDebug() << "World::getQRZLatitud: VALID" << endl; return (query.value(0)).toDouble(); } } return 0.0; */ } double World::getLatitude(const int _enti) { if (_enti <= 0) { return 0.0; } return dataProxy->getLatitudeFromEntity(_enti); /* QString queryString; QSqlQuery query; int i = _enti; queryString = "SELECT latitude FROM entity WHERE dxcc=='" + QString::number(i) +"'"; if (!query.exec(queryString)) { return 0.0; } else { query.next(); if ( !(query.isValid()) ) { //qDebug() << "World::getQRZLatitud: NO VALID" << endl; return 0.0; }else{ //qDebug() << "World::getQRZLatitud: VALID" << endl; return (query.value(0)).toDouble(); } } return 0.0; */ } QString World::getQRZLocator(const QString _qrz) { if (_qrz.length() < 1) { return ""; } return locator->getLocator(getQRZLongitude(_qrz), getQRZLatitude(_qrz)); } QString World::getLocator(const int _enti) { if (_enti <= 0) { return ""; } return locator->getLocator(getLongitude(_enti), getLatitude(_enti)); } /* int World::getBandIdFromFreq(const QString fr) { //qDebug() << "World::getBandIdFromFreq: " << fr << endl; //Freq should be in MHz QSqlQuery query; QString queryString = QString("SELECT id FROM band WHERE lower <= '%1' and upper >= '%2'").arg(fr).arg(fr); //qDebug() << "World::getBandIdFromFreq query: " << queryString << endl; if (!query.exec(queryString)) { return -1; } else { query.next(); int b=-1; if (query.isValid()) { b = (query.value(0)).toInt(); //qDebug() << "World::getBandIdFromFreq value: " << QString::number(b) << endl; //return (query.value(0)).toInt(); return b; } else { //qDebug() << "World::getBandIdFromFreq value not valid!!" << endl; return -1; } } return -1; } */ QString World::getQRZEntityPrefixes(const QString _qrz) { int i = getQRZARRLId(_qrz); return dataProxy->getEntityMainPrefix(i); /* QString result; result = ""; QString queryString; QSqlQuery query; queryString = "SELECT prefix FROM prefixesofentity WHERE dxcc=='" + QString::number(i) +"'"; if (!query.exec(queryString)) { return ""; } else { while ( (query.next())) { if (query.isValid()) { result = result + ", " + (query.value(0)).toString(); } else { } } if (result.length() < 1) { return result; } else { result = result.remove(0,2); return result; } } return ""; */ } bool World::readCTYCSV(const QString _worldFile) { //qDebug() << "World::readCTYCSV(): " << _worldFile << endl; QString tq; tq.clear(); QString entityNumber; entityNumber = "-1"; QString fileName; qint64 beginingOfFile; int numberOfLines = 0; int errorCode = -1; //int ii = 0; //bool ret; QFile file( _worldFile ); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //qDebug() << "World::readCTYCSV() File not found: END FALSE" << fileName << endl; return false; } else { //qDebug() << "World::readCTYCSV() File found: " << fileName << endl; } beginingOfFile = file.pos(); while (!file.atEnd()) { if ( (file.readLine()).contains(';') ) { numberOfEntities++; } numberOfLines++; } //qDebug() << "World::readCTYCSV() - numberOfEntities: " << QString::number(numberOfEntities) << endl; // The file is readed twice: 1: Main entity data; 2: prefixes. // Starts with main data: file.seek(beginingOfFile); progressBarPosition = 0; QProgressDialog progress(tr("Reading cty.csv..."), tr("Abort reading"), 0, numberOfLines, this); progress.setWindowModality(Qt::ApplicationModal); numberOfEntities = 0; // Reset this variable to reuse it and assign the "dxcc" to the entities (temp solution) QSqlQuery query; QSqlQuery queryP; query.prepare("INSERT INTO entity (id, name, cqz, ituz, continent, latitude, longitude, utc, dxcc, mainprefix)" "VALUES (?, ?,?, ?, ?, ?, ?, ?, ?, ?)"); queryP.prepare("INSERT INTO prefixesofentity (id, prefix, dxcc, cqz, ituz) VALUES (?, ?, ?, ?, ?)"); QSqlDatabase::database().transaction(); QStringList stringList, stringListPrefixes, stringListProcessedPrefix; int entN; entN = -1; while (!file.atEnd()) { progress.setValue(progressBarPosition); progressBarPosition++; if (progress.wasCanceled()) break; stringList.clear(); stringListPrefixes.clear(); // // 9Y,Trinidad & Tobago,90,SA,9,11,10.38,61.28,4.0,9Y 9Z; // 5A,Libya,436,AF,34,38,27.20,-16.60,-2.0,5A; // MainPref / Name / dxcc / Cont / CQ / ITU / LAT / LON / -UTC / prefixes // 0 1 2 3 4 5 6 7 8 9 tq = file.readLine(); //qDebug() << "World::readCTYCSV(): Line: " << tq << endl; tq = tq.simplified(); //qDebug() << "World::readCTYCSV(): Line simplified: " << tq << endl; tq = tq.trimmed(); //qDebug() << "World::readCTYCSV(): Line trimmed: " << tq << endl; tq.remove(QChar(';'), Qt::CaseInsensitive); //qDebug() << "World::readCTYCSV(): Line without ;: " << tq << endl; stringList << tq.split(','); //qDebug() << "World::readCTYCSV(): Line stringList-0: " << stringList.at(0) << endl; if (( stringList.at(0)).contains(QChar('*'), Qt::CaseInsensitive)) { entN = -1; entN = (stringList.at(2)).toInt() + 1000; while ( (dataProxy->getEntityMainPrefix(entN)).size()>0 ) { //qDebug() << "World::readCTYCSV() entN: " << QString::number(entN) << endl; //qDebug() << "World::readCTYCSV() dataProxy->getEntityMainPrefix: " << QString::number(entN) << endl; entN = entN + 1000; } entityNumber = QString::number(entN); } else { entityNumber = stringList.at(2); } if (stringList.size()>=8 ) { //(id, name, cqz, ituz, continent, latitude, longitude, utc, dxcc, mainprefix) query.addBindValue(QVariant(QVariant::Int)); query.addBindValue(stringList.at(1)); // name query.addBindValue(stringList.at(4)); // CQ query.addBindValue(stringList.at(5)); // ITU query.addBindValue(stringList.at(3)); // Cont query.addBindValue(stringList.at(6)); // Lat query.addBindValue(stringList.at(7)); // Lon query.addBindValue(stringList.at(8)); // UTC //query.addBindValue(stringList.at(2)); // dxcc query.addBindValue(entityNumber); // dxcc query.addBindValue(stringList.at(0)); // Mainprefix //qDebug() << "World::readCTYCSV(): Entity name: " << stringList.at(1) << endl; //qDebug() << "World::readCTYCSV(): Entity cqz: " << stringList.at(4) << endl; //qDebug() << "World::readCTYCSV(): Entity ituz: " << stringList.at(5) << endl; //qDebug() << "World::readCTYCSV(): Entity cont: " << stringList.at(3) << endl; //qDebug() << "World::readCTYCSV(): Entity lat: " << stringList.at(6) << endl; //qDebug() << "World::readCTYCSV(): Entity lon: " << stringList.at(7) << endl; //qDebug() << "World::readCTYCSV(): Entity UTC: " << stringList.at(8) << endl; //qDebug() << "World::readCTYCSV(): Entity ARRL: " << stringList.at(2) << endl; //qDebug() << "World::readCTYCSV(): Entity Pref: " << stringList.at(0) << endl; if (query.exec()) { //qDebug() << "World::readCTYDAT(): Entity data added" << endl; } else if (errorCode == 19) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); errorCode = query.lastError().number(); //qDebug() << "World::readCTYCSV(): Entity data NOT added" << endl; //qDebug() << "World::readCTYCSV(): LastQuery: " << query.lastQuery() << endl; //qDebug() << "World::readCTYCSV(): LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "World::readCTYCSV(): LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "World::readCTYCSV(): LastError-n: " << QString::number(query.lastError().number() ) << endl; } if (stringList.size()>8) { tq = stringList.at(9); stringListPrefixes << tq.split(' '); tq = stringListPrefixes.last(); QString prefAux = QString(); for (int i = 0; i < stringListPrefixes.size(); ++i) { prefAux = stringListPrefixes.at(i); //queryP.prepare("INSERT INTO prefixesofentity (id, prefix, dxcc, cqz, ituz) VALUES (?, ?, ?, ?, ?)"); // 0 1 2 3 4 // (id, prefix, dxcc, cqz, ituz) //qDebug() << "World::readCTYCSV(): Prefix: " << stringListPrefixes.at(i) << endl; queryP.addBindValue(QVariant(QVariant::Int)); //readZones (const QString &pref, const int _cq, const int _itu) //Returns a QStringList: prefix, CQz, ITUz stringListProcessedPrefix.clear(); stringListProcessedPrefix << readZones(prefAux, (stringList.at(4)).toInt(), (stringList.at(5)).toInt()); if (prefAux.at(0)=='=') { //TODO: Maybe there is a better way to identify exact calls instead of prefixes , identified with a = before he call. prefAux.remove(0,1); } //queryP.addBindValue(prefAux); queryP.addBindValue(stringListProcessedPrefix.at(0)); //queryP.addBindValue(stringList.at(2)); //queryP.addBindValue(stringList.at(4)); //queryP.addBindValue(stringList.at(5)); //queryP.addBindValue(stringList.at(2)); queryP.addBindValue(entityNumber); queryP.addBindValue(stringListProcessedPrefix.at(1)); queryP.addBindValue(stringListProcessedPrefix.at(2)); if (queryP.exec()) { //qDebug() << "World::readCTYCSV(): Prefix added: " << stringListPrefixes.at(i) << endl; } else if (errorCode == 19) {} else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); errorCode = query.lastError().number(); //qDebug() << "World::readCTYCSV(): Prefix data NOT added" << endl; //qDebug() << "World::readCTYCSV(): Prefix LastQuery: " << query.lastQuery() << endl; //qDebug() << "World::readCTYCSV(): Prefix LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "World::readCTYCSV(): Prefix LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "World::readCTYCSV(): Prefix LastError-n: " << QString::number(query.lastError().number() ) << endl; } } } } //qDebug() << "World::readCTYCSV() tq: " << tq << endl; progress.setLabelText("Reading cty.csv ... \nNow reading " + currentPrefix + " data"); //qDebug() << "World::readCTYCSV() - progressBarPosition: " << QString::number(progressBarPosition) << endl; } QSqlDatabase::database().commit(); progress.setValue(numberOfLines); if (created) { dataProxy->updateISONames(); } //qDebug() << "World::readCTYCSV() END TRUE " << endl; return true; } QString World::changeSlashAndFindPrefix(const QString _qrz) { //qDebug() << "World::changeSlashAndFindPrefix: -" << _qrz <<"-" << endl; int iaux1, iaux2; QString aux = _qrz.toUpper(); if ((aux).count('\\')) // Replaces \ by / to ease operation. { aux.replace(QChar('\\'), QChar('/')); } else { return aux; } if (aux.count('/')) // / found! Checking different options { if (aux.endsWith("/") ) { // We look for calls ending in slash "/" or "\" aux.remove(aux.length()-1,1); } iaux1 = aux.indexOf('/'); //qDebug() << "World::changeSlashAndFindPrefix: Slash found at: " << QString::number(iaux1) << endl; iaux2 = (aux.length())- iaux1; // iaux2 is the length of the second part if (iaux2 < 0){ iaux2 = -iaux2; } if ( iaux1 < iaux2 ) { //Like in F/EA4TV, we can simply take the first part as the prefix aux = aux.left(iaux1); } else { aux = aux.right(iaux2 -1); } } return aux; } bool World::checkQRZValidFormat(const QString _qrz) { //qDebug() << "World::checkQRZValidFormat: -" << _qrz <<"-" << endl; QString aux = changeSlashAndFindPrefix(_qrz.toUpper()); if (aux.length()<3) { return false; } // The format of a Call is defined here: // http://en.wikipedia.org/wiki/ITU_prefix_%28amateur_stations%29 //bool prefixEnded = false; //int callLength = _qrz.length(); int sepPos = 0; int barPos = aux.indexOf('/'); QString prefix = QString(); QString suffix = QString(); QString separator = QString(); // If barPos > 0 we have a complex call like F/EA4TV QCharRef c = aux[aux.length()-1]; if ( c.isDigit() && (barPos<=0) ) { return false; } prefix = prefix + aux.at(0); if ( ( aux.at(1) ).isDigit() ) { // W3 A6 if ((aux.at(2)).isDigit() ) { // A60 prefix = prefix + aux.at(1); separator = aux.at(2); sepPos = 2; } else { // W3A separator = aux.at(1); sepPos = 1; } } else { // EA 3D 2M if ((aux.at(2)).isDigit() ) { // EA0 prefix = prefix + aux.at(1); separator = aux.at(2); sepPos = 2; } else { // 3DA if (aux.length() < 4) { prefix = prefix + aux.at(2); return false; } if ((aux.at(3)).isDigit()) { // 3DA0 prefix = prefix + aux.at(1); prefix = prefix + aux.at(2); separator = aux.at(3); sepPos = 3; if (aux.length() < 5) { // 3DA0 prefix = prefix + aux.at(3); return false; } } else { return false; } } } for (int i = sepPos+1; i < aux.length(); i++) { suffix = suffix + aux.at(i); } //qDebug() << "World::checkQRZValidFormat: Prefix = " << prefix << endl; //qDebug() << "World::checkQRZValidFormat: Separator = " << separator << endl; //qDebug() << "World::checkQRZValidFormat: Suffix = " << suffix << endl; //qDebug() << "World::checkQRZValidFormat: Call = " << prefix+separator+suffix << endl; return true; } QStringList World::getEntitiesNames() { //qDebug() << "World::getEntitiesNames" << endl; return dataProxy->getEntitiesNames(); } int World::getHowManyEntities() { return dataProxy->getHowManyEntities(); } klog-0.9.2.9/setupdialog.h0000644000076700000620000001240613233376355013301 0ustar staff#ifndef SETUPDIALOG_H #define SETUPDIALOG_H /*************************************************************************** setupdialog.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include #include "setuppageuserdata.h" #include "setuppagebandmode.h" #include "setuppagemisc.h" #include "setuppagedxcluster.h" #include "setuppagecolors.h" #include "setuppagelogs.h" #include "setuppageworldeditor.h" #include "setuppageclublog.h" #include "utilities.h" #include "locator.h" class QListWidget; class QListWidgetItem; class QStackedWidget; class SetupDialog : public QDialog { Q_OBJECT public: SetupDialog(DataProxy *dp, const bool _firstTime=true); SetupDialog(DataProxy *dp, const QString _configFile, const QString _softwareVersion, const int _page=0, const bool _firstTime = true); ~SetupDialog(); void setData(const QString _configFile, const QString _softwareVersion, const int _page, const bool _firstTime=true); void setClubLogActive(const bool _b); void checkIfNewBandOrMode(); public slots: signals: void exitSignal(const int status); // 1 = OK, -1 = NOK, 2 = Cancel clicked void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution //void newLogRequested(const bool _s); // true show new log private slots: void changePage(QListWidgetItem *current, QListWidgetItem *previous); void slotReadConfigData(); void slotOkButtonClicked(); void slotCancelButtonClicked(); void slotAnalyzeNewLogData(const QStringList _qs); // We receive the station callsign and operators from the logs tab void slotSetStationCallSign(const QString _p); // We receive te station callsign from the userData tab to fill the new log void slotSetOperators(const QString _p); // We receive te station operators from the userData tab to fill the new log void slotQueryErrorManagement(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); private: void setConfigFile(const QString _configFile); void setSoftVersion(const QString _softwareVersion); void setConfigured(const bool _configured); void setPage(const int _page); void connectActions(); void createIcons(); bool processConfigLine(const QString _line); void setDefaults(); void readActiveBands (const QString actives); void readActiveModes (const QString actives); bool isValidBand (const QString b); bool isValidMode (const QString b); QString checkAndFixASCIIinADIF(const QString _data); bool haveAtleastOneLog(); bool firstTime; // To know if we are calling it from the Start wizard or not bool nolog; // If there is no log being managed QString dxClusterServerToUse; QStringList dxClusterServers; QTabWidget *tabWidget; int logsPageTabN; QListWidget *contentsWidget; QStackedWidget *pagesWidget; SetupPageUserDataPage *userDataPage; SetupPageBandMode *bandModePage; SetupPageDxCluster *dxClusterPage; SetupPageMisc *miscPage; SetupPageColors *colorsPage; SetupPageLogs *logsPage; SetupPageWorldEditor *worldEditorPage; SetupPageClubLog *clubLogPage; int pageRequested; // The page on the Dialog that is requested to be shown when you call it //QString klogDir; QString configFileName, version; QStringList bands, modes; Locator *locator; DataProxy *dataProxy; Utilities *util; int constrid; // Just an id for the constructor to check who is being executed at one specific time }; #endif // SETUPDIALOG_H klog-0.9.2.9/mainwindow.cpp0000644000076700000620000102665513233376355013504 0ustar staff/*************************************************************************** mainwindow.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include #include #include #include "database.h" #include "mainwindow.h" //#include MainWindow::MainWindow(const QString _klogDir, const QString tversion) { //qDebug() << "MainWindow::MainWindow: "<< _klogDir << " Ver: " << tversion << endl; //qDebug() << "MainWindow::MainWindow: Con func: "<< Q_FUNC_INFO << endl; QTime start; start = QTime::currentTime(); //qDebug() << "MainWindow::MainWindow: "<< (QTime::currentTime()).toString("hhmmsszzz")<< endl; showErrorDialog = new ShowErrorDialog(); upAndRunning = false; // To define some actions that can only be run when starting the software //connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(slotDownloadFinished(QNetworkReply*))); // To download cty.csv //flagIcon = new QPushButton; // To paint a flag of the worked entity // softwareVersion = tversion; itIsANewversion = false; dataProxy = new DataProxy_SQLite(softwareVersion, Q_FUNC_INFO); doc = new QTextDocument; util = new Utilities; needToEnd = false; cleaning = false; qrzAutoChanging = false; dxclusterServerToConnect = "dxfun.com"; dxclusterServerPort = 8000; contestMode = "DX"; defaultADIFLogFile = "klog.adi"; klogDir = _klogDir; InValidCharsInPrevCall = false; //stationCallSignShownInSearch = true; checkNewVersions = true; reportInfo = false; configured = false; modify = false; noMoreErrorShown = false; qslingNeeded = false; // When clicking on Find QSO to QSL manageMode = false; selectedYear = 0; defaultMode = 0; defaultBand = 0; //qDebug() << "MainWindow::MainWindow: 1 - currentMode: " << QString::number(currentMode) << endl; currentMode = 1; //qDebug() << "MainWindow::MainWindow: 2 - currentMode: " << QString::number(currentMode) << endl; currentModeShown = currentMode; currentBand = 0; currentBandShown = currentBand; currentLog = 1; points = 0; multipliers = 0; qsoPoints = 0; qsoMultiplier = 0; operatorQRZ = ""; stationQRZ = ""; mainQRZ = ""; myLocator = ""; dxLocator =""; myPower = 0.0; //lastPower = myPower; //lastOperatorQRZ = operatorQRZ; //lastStationQRZ = stationQRZ; //lastMyLocator = myLocator; //qDebug() << "MainWindow::MainWindow: 0007" << endl; //entitiesList.clear(); //propModeList.clear(); currentEntity = -1; // To optimize the calls to different world methods if the entity does not change. Used in slotQRZTextChanged previousEntity = -1;// To optimize the calls to different world methods if the entity does not change. realTime=true; UTCTime=true; keepMyData=true; completeWithPrevious=false; completedWithPreviousQTH=false; completedWithPreviousLocator=false; completedWithPreviousName=false; completedWithPreviousIOTA=false; completedWithPreviousQSLVia=false; alwaysADIF=false; useDefaultLogFileName=false; needToSave=false; qrzSmallModDontCalculate=false; imperialSystem=false; sendQSLWhenRec = true; dxClusterShowHF=true; dxClusterShowVHF=true; dxClusterShowWARC=true; dxClusterShowWorked=true; dxClusterShowConfirmed=true; dxClusterShowAnn=true; dxClusterShowWWV=true; dxClusterShowWCY=true; keepSatPage = false; //qDebug() << "MainWindow::MainWindow: 0008" << endl; clublogActive = false; clublogRealTime = false; clublogUser = QString(); clublogPass = QString(); clublogEmail = QString(); /* db = new DataBase(Q_FUNC_INFO, softwareVersion, util->getKLogDBFile()); if (!db->createConnection()) { //qDebug() << "MainWindow::MainWindow: Conection not created" << endl; return; } else { //db->updateIfNeeded(); // Check if we need to update the DB //qDebug() << "MainWindow::MainWindow: DB updated was checked here" << endl; } */ elogClublog = new eLogClubLog(); clublogAnswer = -1; defaultColor.setNamedColor("slategrey"); neededColor.setNamedColor("yellow"); workedColor.setNamedColor("blue"); confirmedColor.setNamedColor("red"); newOneColor.setNamedColor("green"); //Default band/modes bands << "10M" << "15M" << "20M" << "40M" << "80M" << "160M"; modes << "SSB" << "CW" << "RTTY"; dxccStatusWidget = new DXCCStatusWidget(dataProxy); logWindow = new LogWindow(dataProxy, this); connect(logWindow, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); searchWidget = new SearchWidget (dataProxy, this); connect(searchWidget, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); infoWidget = new InfoWidget(dataProxy, this); //qDebug() << "MainWindow::MainWindow: 0009" << endl; //helpHelpDialog = new HelpHelpDialog(softwareVersion); //qDebug() << "MainWindow::MainWindow: 00091" << endl; //helpAboutDialog = new HelpAboutDialog(softwareVersion); aboutDialog = new AboutDialog(softwareVersion); //qDebug() << "MainWindow::MainWindow: 0010" << endl; recalculateAwardsButton = new QPushButton(tr("Recalculate"), this); recalculateAwardsButton->setToolTip(tr("Click to recalculate the award status")); scoreTextEdit = new QTextEdit; //distShortLabelN = new QLabel; //distLongLabelN = new QLabel; configFileName = util->getCfgFile(); ctyDatFile = util->getCTYFile(); downloadcty = new DownLoadCTY(klogDir, softwareVersion); connect( downloadcty, SIGNAL(done()), this, SLOT(slotWorldReload()) ); //qDebug() << "MainWindow::MainWindow: logbook: " << QString(util->getKLogDBFile()) << endl; //qDebug() << "MainWindow::MainWindow: Before existing Data" << endl; bool existingData = QFile::exists(util->getKLogDBFile()); //qDebug() << "MainWindow::MainWindow: After existing Data" << endl; if (existingData) { //qDebug() << "MainWindow::MainWindow: existing data" << endl; //configured= false; } else { //qDebug() << "MainWindow::MainWindow: NOT existing data" << endl; } statusBarMessage = tr("Starting KLog"); if (!QDir::setCurrent ( klogDir )){ QDir d1(klogDir); if (d1.mkdir(klogDir)) { QDir::setCurrent ( klogDir ); } } //qDebug() << "MainWindow::MainWindow: 3" << endl; DBinMemory = false; //db = new DataBase(softwareVersion, DBinMemory); //qDebug() << "MainWindow::MainWindow: 4" << endl; world = new World(dataProxy, klogDir, softwareVersion); connect(world, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); if (!existingData) { //qDebug() << "MainWindow::MainWindow: !existingData" << endl; world->create(ctyDatFile); //entitiesList = world->getEntitiesNames(); //createData(); }else { //qDebug() << "MainWindow::MainWindow: existingData" << endl; } //qDebug() << "MainWindow::MainWindow: proxy to be created" << endl; connect(dataProxy, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); connect(this, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); //qDebug() << "MainWindow::MainWindow: setupDialog to be created" << endl; //setupDialog = new SetupDialog(!configured); setupDialog = new SetupDialog(dataProxy, configFileName, softwareVersion, 0, !configured); connect(setupDialog, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); //qDebug() << "MainWindow::MainWindow: satTabWidget to be created" << endl; satTabWidget = new MainWindowSatTab(dataProxy); connect(satTabWidget, SIGNAL(newBandsToBeAdded(QStringList)), this, SLOT(slotDefineNewBands(QStringList)) ); connect(satTabWidget, SIGNAL(rxFreqChanged(QString)), this, SLOT(slotChangeRXFreq(QString)) ); connect(satTabWidget, SIGNAL(txFreqChanged(QString)), this, SLOT(slotChangeTXFreq(QString)) ); connect(satTabWidget, SIGNAL(dxLocatorChanged(QString)), this, SLOT(slotUpdateLocator(QString)) ); myDataTabWidget = new MainWindowMyDataTab(); commentTabWidget = new MainWindowInputComment(); othersTabWidget = new MainWindowInputOthers(dataProxy); eQSLTabWidget = new MainWindowInputEQSL(dataProxy); QSLTabWidget = new MainWindowInputQSL(dataProxy); //qDebug() << "MainWindow::MainWindow: fileManager to be created" << endl; //filemanager = new FileManager(klogDir, softwareVersion, *db); //qDebug() << "MainWindow::MainWindow: locator to be created" << endl; locator = new Locator(); //qDebug() << "MainWindow::MainWindow: awards to be created" << endl; //qDebug() << "MainWindow::MainWindow: awards already created" << endl; mainWidget = new QWidget(this); setCentralWidget(mainWidget); //qDebug() << "MainWindow::MainWindow: 8" << endl; dateTime = new QDateTime(); selectedYear = (dateTime->currentDateTime()).date().year(); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(slotUpdateTime()) ); timer->start(1000); previousQrz = ""; qrzLineEdit = new QLineEdit; nameLineEdit = new QLineEdit; qthLineEdit = new QLineEdit; locatorLineEdit = new QLineEdit; rstTXLineEdit = new QLineEdit; rstRXLineEdit = new QLineEdit; STXLineEdit = new QLineEdit; SRXLineEdit = new QLineEdit; bandComboBox = new QComboBox; modeComboBox = new QComboBox; dateEdit = new QDateEdit; dateEdit->setDisplayFormat("dd/MM/yyyy"); timeEdit = new QTimeEdit; OKButton = new QPushButton(tr("&Add"), this); //spotItButton = new QPushButton(tr("&Spot"), this); //spotItButton->setEnabled(false); clearButton = new QPushButton(tr("&Clear"), this); // UI DX infoLabel1 = new QLabel(tr("Status bar...")); infoLabel2 = new QLabel(tr("DX Entity")); //logPanel = new QWidget; loggWinAct = new QAction(tr("&Log Window"), this); scoreeWinAct = new QAction(tr("&Score Window"), this); scoreWindow = new QWidget; operatorLineEdit = new QLineEdit; stationCallSignLineEdit = new QLineEdit; myLocatorLineEdit = new QLineEdit; //myPowerSpinBox = new QDoubleSpinBox; //myPowerSpinBox->setDecimals(2); //myPowerSpinBox->setMaximum(9999); rxPowerSpinBox = new QDoubleSpinBox; rxPowerSpinBox->setDecimals(2); rxPowerSpinBox->setMaximum(9999); rxPowerSpinBox->setSuffix(" " + tr("Watts")); txFreqSpinBox = new QDoubleSpinBox; txFreqSpinBox->setDecimals(3); txFreqSpinBox->setMaximum(9999); txFreqSpinBox->setSuffix(" " + tr("MHz")); rxFreqSpinBox = new QDoubleSpinBox; rxFreqSpinBox->setDecimals(3); rxFreqSpinBox->setMaximum(9999); rxFreqSpinBox->setSuffix(" " + tr("MHz")); dxccConfirmedQLCDNumber = new QLCDNumber; dxccWorkedQLCDNumber = new QLCDNumber; wazConfirmedQLCDNumber = new QLCDNumber; wazWorkedQLCDNumber = new QLCDNumber; localConfirmedQLCDNumber = new QLCDNumber; localWorkedQLCDNumber = new QLCDNumber; qsoConfirmedQLCDNumber = new QLCDNumber; qsoWorkedQLCDNumber = new QLCDNumber; dxMarathonQSOLCDNumber = new QLCDNumber; dxMarathonDXCCQLCDNumber = new QLCDNumber; dxMarathonCQQLCDNumber = new QLCDNumber; dxMarathonPointsQLCDNumber = new QLCDNumber; operatingYearsComboBox = new QComboBox; qsoWorkedQLCDNumber->setDigitCount(7); qsoConfirmedQLCDNumber->setDigitCount(7); // Check date & time and set them in the UI at the begining dateTime->currentDateTime(); dateEdit->setDate((dateTime->currentDateTime()).date()); timeEdit->setTime((dateTime->currentDateTime()).time()); //Search tab //searchBoxLineEdit = new QLineEdit; // UI DX // CLUSTER //qDebug() << "MainWindow::MainWindow: dxclusterwidget to be created" << endl; dxClusterWidget = new DXClusterWidget(dataProxy, dxclusterServerToConnect , dxclusterServerPort, this); // palRed.setColor(QPalette::Text, Qt::red); palBlack.setColor(QPalette::Text, Qt::black); awards = new Awards(dataProxy); awards->setManageModes(manageMode); // //************************************************** //createDXClusterUI(); connect( setupDialog, SIGNAL(exitSignal(int)), this, SLOT(slotExitFromSlotDialog(int)) ); //qDebug() << "MainWindow::MainWindow: readconfigdata" << endl; readConfigData(); if (itIsANewversion) { slotSetup(); } //qDebug() << "MainWindow::MainWindow: after readconfigdata" << endl; if (needToEnd) { //QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); //db->compress(); //qDebug() << "MainWindow::MainWindow: 12.5" << endl; exit(0); } //qDebug() << "MainWindow::MainWindow: UI to be created" << endl; logWindow->createlogPanel(currentLog); createUI(); //createSearchResultsPanel(); loggWinAct->setShortcut(Qt::CTRL + Qt::Key_L); connect(loggWinAct, SIGNAL(triggered()), this, SLOT(slotLogWinShow())); //logPanel->addAction(loggWinAct); //logPanel->addAction(scoreeWinAct); scoreeWinAct->setShortcut(Qt::CTRL + Qt::Key_P); connect(scoreeWinAct, SIGNAL(triggered()), this, SLOT(slotScoreWinShow())); scoreWindow->addAction(scoreeWinAct); scoreWindow->addAction(loggWinAct); createScorePanel(); setWindowTitle(tr("KLog")); //qDebug() << "MainWindow::MainWindow: 16" << endl; if (dataProxy->getNumberOfManagedLogs()<1) { //qDebug() << "MainWindow::MainWindow: 16.1" << endl; slotSetup(6); //qDebug() << "MainWindow::MainWindow: 16.2" << endl; } //qDebug() << "MainWindow::MainWindow: 17" << endl; checkIfNewBandOrMode(); //qDebug() << "MainWindow::MainWindow: 18" << endl; if (contestMode == "DX") { //qDebug() << "MainWindow::MainWindow: DX! 18.3" << endl; if (dataProxy->getLastQSOid()<=1) { //qDebug() << "MainWindow::MainWindow: 18.4" << endl; operatingYearsComboBox->addItem(QString::number(selectedYear)); } else { //qDebug() << "MainWindow::MainWindow: 18.5 - currentLog: " << QString::number(currentLog) << endl; operatingYearsComboBox->addItems(dataProxy->getOperatingYears(currentLog)); //qDebug() << "MainWindow::MainWindow: 18.5.1 - currentLog: " << QString::number(currentLog) << endl; QStringList a; a.clear(); a << dataProxy->getOperatingYears(currentLog); //qDebug() << "MainWindow::MainWindow: 18.5.1.1 - currentLog: " << QString::number(currentLog) << endl; if (!a.isEmpty()) { //qDebug() << "MainWindow::MainWindow: 18.5.1.2 - currentLog: " << QString::number(currentLog) << endl; operatingYearsComboBox->setCurrentIndex(operatingYearsComboBox->findText(a.last(), Qt::MatchCaseSensitive)); //qDebug() << "MainWindow::MainWindow: 18.5.1.3 - currentLog: " << QString::number(currentLog) << endl; } //qDebug() << "MainWindow::MainWindow: 18.5.2" << endl; } //qDebug() << "MainWindow::MainWindow: 18.6." << endl; //awards->recalculateAwards(); //qDebug() << "MainWindow::MainWindow: 18.8" << endl; showAwards(); //qDebug() << "MainWindow::MainWindow: 18.9" << endl; dxClusterWidget->setCurrentLog(currentLog); //qDebug() << "MainWindow::MainWindow: 18.10" << endl; } else if ((contestMode == "CQ-WW-SSB") || (contestMode == "CQ-WW-CW")) {} else { //TODO: Check how to do DX if nothing happens without duplicating code. //qDebug() << "MainWindow::MainWindow: DX! 18.3" << endl; if (dataProxy->getLastQSOid()<=1) { //qDebug() << "MainWindow::MainWindow: 18.4" << endl; operatingYearsComboBox->addItem(QString::number(selectedYear)); } else { //qDebug() << "MainWindow::MainWindow: 18.5 - currentLog: " << QString::number(currentLog) << endl; operatingYearsComboBox->addItems(dataProxy->getOperatingYears(currentLog)); //qDebug() << "MainWindow::MainWindow: 18.5.1 - currentLog: " << QString::number(currentLog) << endl; operatingYearsComboBox->setCurrentIndex(operatingYearsComboBox->findText((dataProxy->getOperatingYears(currentLog)).last(), Qt::MatchCaseSensitive)); //qDebug() << "MainWindow::MainWindow: 18.5.2" << endl; } //qDebug() << "MainWindow::MainWindow: 18.6." << endl; //qDebug() << "MainWindow::MainWindow: 18.7" << endl; awards->recalculateAwards(); //qDebug() << "MainWindow::MainWindow: 18.8" << endl; showAwards(); //qDebug() << "MainWindow::MainWindow: 18.9" << endl; dxClusterWidget->setCurrentLog(currentLog); //qDebug() << "MainWindow::MainWindow: 18.10" << endl; } //qDebug() << "MainWindow::MainWindow: 19" << endl; currentBandShown = dataProxy->getIdFromBandName(bandComboBox->currentText()); currentModeShown = dataProxy->getIdFromModeName(modeComboBox->currentText()); currentBand = currentBandShown; currentMode = currentModeShown; //qDebug() << "MainWindow::MainWindow: 20 - currentMode: " << QString::number(currentMode) << endl; //qDebug() << "MainWindow::MainWindow: 21 - currentBand: " << QString::number(currentBand) << endl; //qDebug() << "MainWindow::MainWindow: 21.1 - currentModeShown: " << QString::number(currentModeShown) << endl; //qDebug() << "MainWindow::MainWindow: 21.2 - currentBandShown: " << QString::number(currentBandShown) << endl; slotClearButtonClicked(); upAndRunning = true; //qDebug() << "MainWindow::MainWindow: "<< (QTime::currentTime()).toString("hhmmsszzz")<< endl; //qDebug() << "MainWindow::MainWindow: Software update to be created" << endl; softUpdate = new SoftwareUpdate(softwareVersion); //connect(softUpdate, SIGNAL(updateNeededSignal(bool)), this, SLOT(slotShowSoftUpdateResults(bool) ) ); callingUpdate = false; // to control whether the update is mannually launched or at the begining //qDebug() << "MainWindow::MainWindow: calling Software update..." << endl; if (checkNewVersions) {//reportInfo if (reportInfo) { softUpdate->addCall(stationQRZ); } softUpdate->needToUpdate(); } connect(awards, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); connect(awards, SIGNAL(awardDXCCUpdated()), this, SLOT(slotRefreshDXCCWidget()) ); filemanager = new FileManager(dataProxy, klogDir, softwareVersion); connect(filemanager, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); //qDebug() << "MainWindow::MainWindow: END" << endl; } MainWindow::~MainWindow() { /* doc->~QTextDocument(); recalculateAwardsButton->~QPushButton(); scoreTextEdit->~QTextEdit(); mainWidget->~QWidget(); dateTime->~QDateTime(); timer->~QTimer(); qrzLineEdit->~QLineEdit(); nameLineEdit->~QLineEdit(); qthLineEdit->~QLineEdit(); locatorLineEdit->~QLineEdit(); rstTXLineEdit->~QLineEdit(); rstRXLineEdit->~QLineEdit(); STXLineEdit->~QLineEdit(); SRXLineEdit->~QLineEdit(); bandComboBox->~QComboBox(); modeComboBox->~QComboBox(); dateEdit->~QDateEdit(); timeEdit->~QTimeEdit(); OKButton->~QPushButton(); clearButton->~QPushButton(); infoLabel1->~QLabel(); infoLabel2->~QLabel(); loggWinAct->~QAction(); scoreeWinAct->~QAction(); scoreWindow->~QWidget(); operatorLineEdit->~QLineEdit(); stationCallSignLineEdit->~QLineEdit(); myLocatorLineEdit->~QLineEdit(); rxPowerSpinBox->~QDoubleSpinBox(); txFreqSpinBox->~QDoubleSpinBox(); rxFreqSpinBox->~QDoubleSpinBox(); dxccConfirmedQLCDNumber->~QLCDNumber(); dxccWorkedQLCDNumber->~QLCDNumber(); wazConfirmedQLCDNumber->~QLCDNumber(); wazWorkedQLCDNumber->~QLCDNumber(); localConfirmedQLCDNumber->~QLCDNumber(); localWorkedQLCDNumber->~QLCDNumber(); qsoConfirmedQLCDNumber->~QLCDNumber(); qsoWorkedQLCDNumber->~QLCDNumber(); dxMarathonQSOLCDNumber->~QLCDNumber(); dxMarathonDXCCQLCDNumber->~QLCDNumber(); dxMarathonCQQLCDNumber->~QLCDNumber(); dxMarathonPointsQLCDNumber->~QLCDNumber(); operatingYearsComboBox->~QComboBox(); showErrorDialog->~ShowErrorDialog(); dataProxy->~DataProxy(); db->~DataBase(); util->~Utilities(); elogClublog->~eLogClubLog(); dxccStatusWidget->~DXCCStatusWidget(); logWindow->~LogWindow(); searchWidget->~SearchWidget(); aboutDialog->~AboutDialog(); infoWidget->~QWidget(); downloadcty->~DownLoadCTY(); world->~World(); setupDialog->~SetupDialog(); satTabWidget->~MainWindowSatTab(); myDataTabWidget->~MainWindowMyDataTab(); commentTabWidget->~MainWindowInputComment(); othersTabWidget->~MainWindowInputOthers(); eQSLTabWidget->~QWidget(); QSLTabWidget->~MainWindowInputQSL(); filemanager->~FileManager(); locator->~Locator(); awards->~Awards(); dxClusterWidget->~DXClusterWidget(); softUpdate->~SoftwareUpdate(); */ } void MainWindow::createStatusBar() { statusBar()->showMessage(tr("Ready")); } void MainWindow::createUI() { //qDebug() << "MainWindow::createUI" << endl; createStatusBar(); if (contestMode == "CQ-WW-SSB") { createUIDX(); createActionsCommon(); createActionsDX(); createMenusCommon(); } else if ( (contestMode == "CQ-WW-SSB") || (contestMode == "CQ-WW-CW") ) { createUICQWW(); createActionsCommon(); createActionsCQWW(); createMenusCommon(); createMenusCQWW(); } else { // This is DX. Depending on how KLog evolves I could remove the DX from the first place and leave this only. createUIDX(); createActionsCommon(); createActionsDX(); createMenusCommon(); } } void MainWindow::slotModeComboBoxChanged() { //qDebug() << "MainWindow::slotModeComboBoxChanged: " << QString::number(modeComboBox->currentIndex()) << endl; //qDebug() << "MainWindow::slotModeComboBoxChanged: " << modeComboBox->currentText() << endl; /* int i; i = dataProxy->getSubModeIdFromSubMode(modeComboBox->currentText()); if (i>=0) { //qDebug() << "MainWindow::MainWindow: 5 - currentMode: " << QString::number(currentMode) << endl; currentMode = i; //qDebug() << "MainWindow::MainWindow: 6 - currentMode: " << QString::number(currentMode) << endl; } //qDebug() << "MainWindow::slotModeComboBoxChanged: i: " << QString::number(i) << endl; */ //qDebug() << "MainWindow::slotModeComboBoxChanged: currentMode: " << QString::number(currentMode) << endl; //qDebug() << "MainWindow::slotModeComboBoxChanged: " << QString::number(modeComboBox->currentIndex()) << "/" << QString::number(currentMode) << endl; currentBandShown = dataProxy->getIdFromBandName(bandComboBox->currentText()); currentModeShown = dataProxy->getIdFromModeName(modeComboBox->currentText()); currentBand = currentBandShown; //qDebug() << "MainWindow::MainWindow: 7 - currentMode: " << QString::number(currentMode) << endl; currentMode = currentModeShown; //qDebug() << "MainWindow::MainWindow: 8 - currentMode: " << QString::number(currentMode) << endl; //qDebug() << "MainWindow::MainWindow: 8.1 - currentBand: " << QString::number(currentBand) << endl; //qDebug() << "MainWindow::MainWindow: 8.2 - currentModeShown: " << QString::number(currentModeShown) << endl; //qDebug() << "MainWindow::MainWindow: 8.3 - currentBandShown: " << QString::number(currentBandShown) << endl; //currentBandShown = bandComboBox->currentIndex(); //currentModeShown = modeComboBox->currentIndex(); checkIfWorkedB4(currentQrz); QStringList _qs; //for the showStatusOfDXCC(const QStringList _qs) _qs.clear(); _qs << QString::number(currentEntity) << QString::number(currentBandShown) << QString::number(currentModeShown) << QString::number(currentLog); showStatusOfDXCC(_qs); //qDebug() << "MainWindow::slotModeComboBoxChanged2: " << modeComboBox->currentText() << endl; } void MainWindow::slotBandComboBoxChanged(){ //qDebug() << "MainWindow::slotBandComboBoxChanged: " << QString::number(bandComboBox->currentIndex()) << endl; /* int i; i = dataProxy->getIdFromBandName(bandComboBox->currentText()); if (i>=0) { currentBand = i; //txFreqSpinBox->setValue(dataProxy->getFreqFromBandId(i)); } */ //qDebug() << "MainWindow::slotBandComboBoxChanged: " << QString::number(bandComboBox->currentIndex()) << "/" << QString::number(currentBand) << endl; currentBandShown = dataProxy->getIdFromBandName(bandComboBox->currentText()); currentModeShown = dataProxy->getIdFromModeName(modeComboBox->currentText()); currentBand = currentBandShown; //qDebug() << "MainWindow::MainWindow: 9 - currentMode: " << QString::number(currentMode) << endl; currentMode = currentModeShown; //qDebug() << "MainWindow::MainWindow: 9 - currentMode: " << QString::number(currentMode) << endl; //qDebug() << "MainWindow::MainWindow: 9.1 - currentMode: " << QString::number(currentMode) << endl; //qDebug() << "MainWindow::MainWindow: 9.2 - currentBand: " << QString::number(currentBand) << endl; //qDebug() << "MainWindow::MainWindow: 9.3 - currentModeShown: " << QString::number(currentModeShown) << endl; //qDebug() << "MainWindow::MainWindow: 9.4 - currentBandShown: " << QString::number(currentBandShown) << endl; //qDebug() << "MainWindow::MainWindow: Going to update the UpLink with: " << bandComboBox->currentText() << endl; satTabWidget->setUpLink(bandComboBox->currentText()); //currentModeShown = modeComboBox->currentIndex(); checkIfWorkedB4(currentQrz); QStringList _qs; //for the showStatusOfDXCC(const QStringList _qs) _qs.clear(); _qs << QString::number(currentEntity) << QString::number(currentBandShown) << QString::number(currentModeShown) << QString::number(currentLog); showStatusOfDXCC(_qs); } void MainWindow::slotQRZReturnPressed() { //qDebug() << "MainWindow::slotQRZReturnPressed: " << qrzLineEdit->text() << " - " << QString::number(bandComboBox->currentIndex()) << "/" << QString::number(modeComboBox->currentIndex()) << endl; //int newId = -1; int lastId = -1; int errorCode = 0; QString aux; //int _x; //for clublog management //bool ret = false; QString tqrz = qrzLineEdit->text(); //currentMode = modeComboBox->currentIndex(); //currentBandShown = bandComboBox->currentIndex(); slotBandComboBoxChanged(); slotModeComboBoxChanged(); // Just to prepare or some tasks before reading DATA from UI if (contestMode == "CQ-WW-SSB") { if ((SRXLineEdit->text()).toInt() < 1 ){ return; } } else { } //http://www.sqlite.org/autoinc.html // NULL = is the keyword for the autoincrement to generate next value QSqlQuery query; QString queryString = readDataFromUI(); //qDebug() << "MainWindow::slotQRZReturnPressed: queryString: " << queryString << endl; if (queryString != "NULL") { if (!query.exec(queryString)) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); //qDebug() << "MainWindow::slotQRZReturnPressed: Query ERROR: (queryString): " << queryString << endl; errorCode = query.lastError().number(); QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); aux = tr("An unexpected error ocurred when trying to add the QSO to your log. If the problem persists, please contact the developer for analysis: "); msgBox.setText(aux + "MW-1#" + QString::number(errorCode)); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: break; default: // should never be reached break; } return; } else { query.finish(); //TODO: To move the following lines to this part to properly manage the query result!! //ret = true; //qDebug() << "MainWindow::slotQRZReturnPressed: QSO Added! " << endl; needToSave = true; if (modify) { //qDebug() << "MainWindow::slotQRZReturnPressed: Modifying! " << endl; if(modifyingQSO>0) { awards->setAwards(modifyingQSO); if ((clublogActive) & (clublogRealTime)) { //qDebug() << "MainWindow::slotQRZReturnPressed: (Modifiying ClubLog) Lastid: "<< QString::number(lastId) << endl; // Delete QSO in CLubLog elogClublog->deleteQSO(clublogPrevQSO); // Add modified QSO in ClubLog elogClublog->sendQSO(dataProxy->getClubLogRealTimeFromId(modifyingQSO)); } else { //qDebug() << "MainWindow::slotQRZReturnPressed: (No ClubLog) Lastid: "<< QString::number(lastId) << endl; } } // CHECK WHAT WAS THE QSOID to add the awards, if needed awards->setAwards(modifyingQSO); //Update the DXCC award status } else { //qDebug() << "MainWindow::slotQRZReturnPressed: Not Modifying " << endl; lastId = dataProxy->getLastQSOid(); if (lastId>=0) { //qDebug() << "MainWindow::slotQRZReturnPressed: Lastid: "<< QString::number(lastId) << endl; awards->setAwards(lastId); //Update the DXCC award status // Send to CLUBLOG if enabled if (clublogActive) { //qDebug() << "MainWindow::slotQRZReturnPressed: clublogActive TRUE" << endl; } else { //qDebug() << "MainWindow::slotQRZReturnPressed: clublogActive FALSE" << endl; } if (clublogRealTime) { //qDebug() << "MainWindow::slotQRZReturnPressed: clublogRealTime TRUE" << endl; } else { //qDebug() << "MainWindow::slotQRZReturnPressed: clublogRealTime FALSE" << endl; } if ((clublogActive) & (clublogRealTime)) { //qDebug() << "MainWindow::slotQRZReturnPressed: (Sending ClubLog) Lastid: "<< QString::number(lastId) << endl; elogClublog->sendQSO(dataProxy->getClubLogRealTimeFromId(lastId)); } else { //qDebug() << "MainWindow::slotQRZReturnPressed: (No ClubLog) Lastid: "<< QString::number(lastId) << endl; } // } } //slotShowAwards(); logWindow->refresh(); dxccStatusWidget->refresh(); slotClearButtonClicked(); } } else // The QUERY string is NULL { return; //qDebug() << "MainWindow::slotQRZReturnPressed: queryString-NULL: " << queryString << endl; } modify = false; modifyingQSO = -1; OKButton->setText(tr("&Add")); } QString MainWindow::readDataFromUI() { //qDebug() << "MainWindow::readDataFromUI: " << endl; QString tqrz = (qrzLineEdit->text()).toUpper(); if (tqrz.length()<3) { return "NULL"; } if (contestMode == "DX") { if (modify) { return readDataFromUIDXModifying(); } else { return readDataFromUIDX(); } } else if (contestMode == "CQ-WW-SSB") {} else { if (modify) { return readDataFromUIDXModifying(); } else { return readDataFromUIDX(); } } //qDebug() << "MainWindow::readDataFromUI: END" << endl; return "NULL"; } QString MainWindow::readDataFromUIDX() { /* If you make any change here, please update also readDataFromUIDXModifying to keep data integrity! */ //qDebug() << "MainWindow::readDataFromUIDX:" << endl; QString tqrz = (qrzLineEdit->text()).toUpper(); if (tqrz.length()<3) { return "NULL"; } QString stringQuery = "NULL"; QString aux1, aux2, stringFields, stringData; //QString aux, aux2; int tband = currentBand; int tmode = currentMode; QString tdate = (dateEdit->date()).toString("yyyy/MM/dd"); QString ttime = (timeEdit->time()).toString("hh:mm:ss"); QString trsttx = rstTXLineEdit->text(); QString trstrx = rstRXLineEdit->text(); int dxcc = world->getQRZARRLId(tqrz); //int dxcc2 = getDXCCFromComboBox(); int dxcc2 = world->getQRZARRLId(othersTabWidget->getEntityPrefix()); //qDebug() << "MainWindow::readDataFromUIDX - DXCC: " << QString::number(dxcc) << endl; //qDebug() << "MainWindow::readDataFromUIDX - DXCC2: " << QString::number(dxcc2) << endl; dxcc = util->getNormalizedDXCCValue(dxcc); dxcc2 = util->getNormalizedDXCCValue(dxcc2); if (dxcc!=dxcc2) { QString dxccn1 = world->getEntityName(dxcc); dxccn1 = dxccn1 + " - " + world->getEntityMainPrefix(dxcc); QString dxccn2 = world->getEntityName(dxcc2); dxccn2 = dxccn2 + " - " + world->getEntityMainPrefix(dxcc2); QPushButton *button2 = new QPushButton(this); QPushButton *button1 = new QPushButton(this); button1->setText(world->getEntityMainPrefix(dxcc)); button2->setText(world->getEntityMainPrefix(dxcc2)); int ret; QMessageBox msgBox; msgBox.setText( tr("You have selected an entity:") + "\n\n"+"- "+dxccn2+"\n\n"+tr("that is different from the KLog proposed entity:") + "\n\n"+ "- "+dxccn1+"\n\n" +tr("Click on the prefix of the correct entity or Cancel to edit the QSO again.")); msgBox.addButton(button2, QMessageBox::AcceptRole); msgBox.addButton(button1, QMessageBox::ActionRole); msgBox.addButton(QMessageBox::Cancel); ret = msgBox.exec(); if (ret == QMessageBox::AcceptRole) { dxcc = dxcc2; } else if (ret == QMessageBox::Cancel) { return "NULL"; } else {} } int cqz = world->getEntityCqz(dxcc); int ituz = world->getEntityItuz(dxcc); aux1 = nameLineEdit->text(); if (aux1.length()>1) { stringFields = stringFields + ", name"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = (locatorLineEdit->text()).toUpper(); if ( locator->isValidLocator(aux1) ) { stringFields = stringFields + ", gridsquare"; stringData = stringData + ", '" + aux1 + "'"; } if ( (txFreqSpinBox->value()) > 0 ) { aux1 = QString::number(txFreqSpinBox->value()); if (dataProxy->isThisFreqInBand(dataProxy->getNameFromBandId(tband), aux1) ) { stringFields = stringFields + ", freq"; stringData = stringData + ", '" + aux1 + "'"; //qDebug() << "MainWindow::readDataFromUIDX: FREQ & BAND OK" << endl; } else { //qDebug() << "MainWindow::readDataFromUIDX: FREQ & BAND NOK" << endl; } } if ( (rxFreqSpinBox->value()) > 0 ) { aux1 = QString::number(rxFreqSpinBox->value()); stringFields = stringFields + ", freq_rx"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = qthLineEdit->text(); if (aux1.length()>2) { stringFields = stringFields + ", qth"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = myDataTabWidget->getOperator(); //aux1 = operatorLineEdit->text(); if (aux1.length()>2) { //lastOperatorQRZ = aux1.toUpper(); stringFields = stringFields + ", operator"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = myDataTabWidget->getStationQRZ(); //aux1 = (stationCallSignLineEdit->text()).toUpper(); if (aux1.length()>2) { //lastStationQRZ = aux1.toUpper(); stringFields = stringFields + ", station_callsign"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = myDataTabWidget->getMyLocator(); //aux1 = myLocatorLineEdit->text(); if (aux1.length()>2) { //lastMyLocator = aux1.toUpper(); stringFields = stringFields + ", my_gridsquare"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = commentTabWidget->getComment(); //aux1 = commentLineEdit->text(); if (aux1.length()>0) { stringFields = stringFields + ", comment"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = QSLTabWidget->getQSLMsg(); //aux1 = qslmsgTextEdit->toPlainText(); if (aux1.length()>0) { stringFields = stringFields + ", qslmsg"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = QString::number(dxcc); if (aux1.length()>0) { stringFields = stringFields + ", dxcc"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = QString::number(cqz); if (aux1.length()>0) { stringFields = stringFields + ", cqz"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = QString::number(ituz); if (aux1.length()>0) { stringFields = stringFields + ", ituz"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = QSLTabWidget->getQSLVia(); //aux1 = qslViaLineEdit->text(); if (aux1.length()>3) { stringFields = stringFields + ", qsl_via"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = QString::number(myDataTabWidget->getMyPower()); if ((aux1.toDouble())>0.0) { //lastPower = aux1.toDouble(); stringFields = stringFields + ", tx_pwr"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = QString::number(rxPowerSpinBox->value()); if ((aux1.toDouble())>0.0) { stringFields = stringFields + ", rx_pwr"; stringData = stringData + ", '" + aux1 + "'"; } aux1 = othersTabWidget->getIOTA(); //qDebug() << "MainWindow::readDataFromUIDX: IOTA: " << aux1 << endl; if (aux1.length() == 6) // EU-001 { //qDebug() << "MainWindow::readDataFromUIDX: IOTA to be saved" << endl; stringFields = stringFields + ", iota"; stringData = stringData + ", '" + aux1 + "'"; } else { //qDebug() << "MainWindow::readDataFromUIDX: IOTA NOT to be saved! Lenght="<text(); if ( (aux1.toInt()) > 0 ) { aux2 = iotaContinentComboBox->currentText() + "-" + aux1; aux1 = awards->checkIfValidIOTA(aux2); //qDebug() << "MainWindow::readDataFromUIDX: pre-IOTA-CheckIfValidIOTA-1: " << aux2 << endl; //qDebug() << "MainWindow::readDataFromUIDX: post-IOTA-CheckIfValidIOTA-2: " << aux1 << endl; if (aux1.length() == 6) // EU-001 { //qDebug() << "MainWindow::readDataFromUIDX: IOTA to be saved!" << endl; stringFields = stringFields + ", iota"; stringData = stringData + ", '" + aux1 + "'"; } else { //qDebug() << "MainWindow::readDataFromUIDX: IOTA NOT to be saved! Lenght="<getSatName(); //We are assuming that the SAT_NAME is always well provided. If it is blank, then no SAT QSO //qDebug() << "MainWindow::readDataFromUIDX: SAT1 " << aux1 << endl; //stringFields = stringFields + ", sat_name"; //stringData = stringData + ", '" + aux1 + "'"; if (aux1.length()>0) { stringFields = stringFields + ", sat_name"; stringData = stringData + ", '" + aux1 + "'"; } // aux1 = satTabWidget->getSatMode(); aux1 = satTabWidget->getSatMode(); // We are assuming that the SAT_MODE is always well provided. If it is blank, then no SAT QSO //stringFields = stringFields + ", sat_mode"; //stringData = stringData + ", '" + aux1 + "'"; if (aux1.length()>0) { stringFields = stringFields + ", sat_mode"; stringData = stringData + ", '" + aux1 + "'"; } keepSatPage = satTabWidget->getRepeatThis(); aux1 = othersTabWidget->getPropModeFromComboBox(); if ((aux1.length()>0) && (aux1 != "Not")) { stringFields = stringFields + ", prop_mode"; stringData = stringData + ", '" + aux1 + "'"; } //CLUBLOG aux1 = eQSLTabWidget->getClubLogStatus(); //Y, N, M if (aux1 == "Y") { stringFields = stringFields + ", clublog_qso_upload_status"; stringData = stringData + ", 'Y'"; stringFields = stringFields + ", clublog_qso_upload_date"; stringData = stringData + ", '" + (eQSLTabWidget->getClubLogDate()).toString("yyyy/MM/dd") + "'"; } else if (aux1 == "N") { stringFields = stringFields + ", clublog_qso_upload_status"; stringData = stringData + ", 'N'"; } else if (aux1 == "M") { stringFields = stringFields + ", clublog_qso_upload_status"; stringData = stringData + ", 'M'"; stringFields = stringFields + ", clublog_qso_upload_date"; stringData = stringData + ", '" + (eQSLTabWidget->getClubLogDate()).toString("yyyy/MM/dd") + "'"; } else //TODO: This should be equivalent to N? { stringFields = stringFields + ", clublog_qso_upload_status"; stringData = stringData + ", 'N'"; } //CLUBLOG aux1 = eQSLTabWidget->getEQSLSenStatus(); if (aux1 == "Y") { stringFields = stringFields + ", eqsl_qsl_sent"; stringData = stringData + ", 'Y'"; stringFields = stringFields + ", eqsl_qslsdate"; stringData = stringData + ", '" + (eQSLTabWidget->getEQSLSenDate()).toString("yyyy/MM/dd") + "'"; } else if (aux1 == "R") { stringFields = stringFields + ", eqsl_qsl_sent"; stringData = stringData + ", 'R'"; } else if (aux1 == "Q") { stringFields = stringFields + ", eqsl_qsl_sent"; stringData = stringData + ", 'Q'"; stringFields = stringFields + ", eqsl_qslsdate"; stringData = stringData + ", '" + (eQSLTabWidget->getEQSLSenDate()).toString("yyyy/MM/dd") + "'"; } else if (aux1 == "I") { stringFields = stringFields + ", eqsl_qsl_sent"; stringData = stringData + ", 'I'"; stringFields = stringFields + ", eqsl_qslsdate"; stringData = stringData + ", '" + (eQSLTabWidget->getEQSLSenDate()).toString("yyyy/MM/dd") + "'"; } else // N { stringFields = stringFields + ", eqsl_qsl_sent"; stringData = stringData + ", 'N'"; } aux1 = eQSLTabWidget->getEQSLRecStatus(); if (aux1 == "Y") { stringFields = stringFields + ", eqsl_qsl_rcvd"; stringData = stringData + ", 'Y'"; stringFields = stringFields + ", eqsl_qslrdate"; stringData = stringData + ", '" + (eQSLTabWidget->getEQSLRecDate()).toString("yyyy/MM/dd") + "'"; } else if (aux1 == "R") { stringFields = stringFields + ", eqsl_qsl_rcvd"; stringData = stringData + ", 'R'"; } else if (aux1 == "Q") { stringFields = stringFields + ", eqsl_qsl_rcvd"; stringData = stringData + ", 'Q'"; stringFields = stringFields + ", eqsl_qslrdate"; stringData = stringData + ", '" + (eQSLTabWidget->getEQSLRecDate()).toString("yyyy/MM/dd") + "'"; } else if (aux1 == "I") { stringFields = stringFields + ", eqsl_qsl_rcvd"; stringData = stringData + ", 'I'"; stringFields = stringFields + ", eqsl_qslrdate"; stringData = stringData + ", '" + (eQSLTabWidget->getEQSLRecDate()).toString("yyyy/MM/dd") + "'"; } else { stringFields = stringFields + ", eqsl_qsl_rcvd"; stringData = stringData + ", 'N'"; } // LOTW-SENT aux1 = eQSLTabWidget->getLOTWSenStatus(); if (aux1 == "Y") { stringFields = stringFields + ", lotw_qsl_sent"; stringData = stringData + ", 'Y'"; stringFields = stringFields + ", lotw_qslsdate"; stringData = stringData + ", '" + (eQSLTabWidget->getLOTWSenDate()).toString("yyyy/MM/dd") + "'"; } else if (aux1 == "R") { stringFields = stringFields + ", lotw_qsl_sent"; stringData = stringData + ", 'R'"; } else if (aux1 == "Q") { stringFields = stringFields + ", lotw_qsl_sent"; stringData = stringData + ", 'Q'"; stringFields = stringFields + ", lotw_qslsdate"; stringData = stringData + ", '" + (eQSLTabWidget->getLOTWSenDate()).toString("yyyy/MM/dd") + "'"; } else if (aux1 == "I") { stringFields = stringFields + ", lotw_qsl_sent"; stringData = stringData + ", 'I'"; stringFields = stringFields + ", lotw_qslsdate"; stringData = stringData + ", '" + (eQSLTabWidget->getLOTWSenDate()).toString("yyyy/MM/dd") + "'"; } else { stringFields = stringFields + ", lotw_qsl_sent"; stringData = stringData + ", 'N'"; } // LOTW-RECEPTION //LOTW_QSLRDATE: (only valid if LOTW_RCVD is Y, I, or V) aux1 = eQSLTabWidget->getLOTWRecStatus(); if (aux1 == "Y") { stringFields = stringFields + ", lotw_qsl_rcvd"; stringData = stringData + ", 'Y'"; stringFields = stringFields + ", lotw_qslrdate"; stringData = stringData + ", '" + (eQSLTabWidget->getLOTWRecDate()).toString("yyyy/MM/dd") + "'"; } else if (aux1 == "R") { stringFields = stringFields + ", lotw_qsl_rcvd"; stringData = stringData + ", 'R'"; } else if (aux1 == "V") { stringFields = stringFields + ", lotw_qsl_rcvd"; stringData = stringData + ", 'V'"; stringFields = stringFields + ", lotw_qslrdate"; stringData = stringData + ", '" + (eQSLTabWidget->getLOTWRecDate()).toString("yyyy/MM/dd") + "'"; } else if (aux1 == "I") { stringFields = stringFields + ", lotw_qsl_rcvd"; stringData = stringData + ", 'I'"; stringFields = stringFields + ", lotw_qslrdate"; stringData = stringData + ", '" + (eQSLTabWidget->getLOTWRecDate()).toString("yyyy/MM/dd") + "'"; } else { stringFields = stringFields + ", lotw_qsl_rcvd"; stringData = stringData + ", 'N'"; } //QSLTABWidget // QSL SENT: Y/N/R/Q/I // QSL_VIA: B/D/E/M aux1 = QSLTabWidget->getQSLSenStatus(); aux2 = QSLTabWidget->getSentVia(); //qDebug() << "MainWindow::readDataFromUIDX: aux1: " << aux1 << " / aux2: " << aux2 << endl; //TODO: the aux2 switch is repeated and could be improved if (aux1=="Y") { stringFields = stringFields + ", qsl_sent"; stringData = stringData + ", 'Y'"; stringFields = stringFields + ", qslsdate"; stringData = stringData + ", '" + (QSLTabWidget->getQSLSenDate()).toString("yyyy/MM/dd") + "'"; stringFields = stringFields + ", qsl_sent_via"; if (aux2 == "D") { stringData = stringData + ", 'D'"; } else if (aux2 == "E") { stringData = stringData + ", 'E'"; } else if (aux2 == "M") { stringData = stringData + ", 'M'"; } else { stringData = stringData + ", 'B'"; } } else if (aux1 == "R") { stringFields = stringFields + ", qsl_sent"; stringData = stringData + ", 'R'"; stringFields = stringFields + ", qsl_sent_via"; if (aux2 == "D") { stringData = stringData + ", 'D'"; } else if (aux2 == "E") { stringData = stringData + ", 'E'"; } else if (aux2 == "M") { stringData = stringData + ", 'M'"; } else { stringData = stringData + ", 'B'"; } } else if (aux1 == "Q") { stringFields = stringFields + ", qsl_sent"; stringData = stringData + ", 'Q'"; stringFields = stringFields + ", qslsdate"; stringData = stringData + ", '" + (QSLTabWidget->getQSLSenDate()).toString("yyyy/MM/dd") + "'"; stringFields = stringFields + ", qsl_sent_via"; if (aux2 == "D") { stringData = stringData + ", 'D'"; } else if (aux2 == "E") { stringData = stringData + ", 'E'"; } else if (aux2 == "M") { stringData = stringData + ", 'M'"; } else { stringData = stringData + ", 'B'"; } } else if (aux1 == "I") { stringFields = stringFields + ", qsl_sent"; stringData = stringData + ", 'I'"; stringFields = stringFields + ", qslsdate"; stringData = stringData + ", '" + (QSLTabWidget->getQSLSenDate()).toString("yyyy/MM/dd") + "'"; stringFields = stringFields + ", qsl_sent_via"; if (aux2 == "D") { stringData = stringData + ", 'D'"; } else if (aux2 == "E") { stringData = stringData + ", 'E'"; } else if (aux2 == "M") { stringData = stringData + ", 'M'"; } else { stringData = stringData + ", 'B'"; } } else { stringFields = stringFields + ", qsl_sent"; stringData = stringData + ", 'N'"; stringFields = stringFields + ", qsl_sent_via"; stringData = stringData + ", 'B'"; } // QSL RECEPTION //i = qslRecComboBox->currentIndex(); //ii = qslRecViaComboBox->currentIndex(); aux1 = QSLTabWidget->getQSLRecStatus(); // Y/N/R/I/V aux2 = QSLTabWidget->getRecVia(); // B/D/E/M if (aux1 == "Y") { stringFields = stringFields + ", qsl_rcvd"; stringData = stringData + ", 'Y'"; stringFields = stringFields + ", qslrdate"; stringData = stringData + ", '" + (QSLTabWidget->getQSLRecDate()).toString("yyyy/MM/dd") + "'"; stringFields = stringFields + ", confirmed"; stringData = stringData + ", '1'"; stringFields = stringFields + ", qsl_rcvd_via"; if (aux2 == "D") { stringData = stringData + ", 'D'"; } else if (aux2 == "E") { stringData = stringData + ", 'E'"; } else if (aux2 == "M") { stringData = stringData + ", 'M'"; } else { stringData = stringData + ", 'B'"; } } else if (aux1 =="R") { stringFields = stringFields + ", qsl_rcvd"; stringData = stringData + ", 'R'"; //stringFields = stringFields + ", confirmed"; //stringData = stringData + ", '0'"; stringFields = stringFields + ", qsl_rcvd_via"; if (aux2=="D") { stringData = stringData + ", 'D'"; } else if (aux2=="E") { stringData = stringData + ", 'E'"; } else if (aux2=="M") { stringData = stringData + ", 'M'"; } else { stringData = stringData + ", 'B'"; } } else if (aux1=="I") { stringFields = stringFields + ", qsl_rcvd"; stringData = stringData + ", 'I'"; stringFields = stringFields + ", qslrdate"; stringData = stringData + ", '" + (QSLTabWidget->getQSLRecDate()).toString("yyyy/MM/dd") + "'"; //stringFields = stringFields + ", confirmed"; //stringData = stringData + ", '0'"; stringFields = stringFields + ", qsl_rcvd_via"; if (aux2=="D") { stringData = stringData + ", 'D'"; } else if (aux2=="E") { stringData = stringData + ", 'E'"; } else if (aux2=="M") { stringData = stringData + ", 'M'"; } else { stringData = stringData + ", 'B'"; } } else if (aux1=="V") { stringFields = stringFields + ", qsl_rcvd"; stringData = stringData + ", 'V'"; stringFields = stringFields + ", qslrdate"; stringData = stringData + ", '" + (QSLTabWidget->getQSLRecDate()).toString("yyyy/MM/dd") + "'"; //TODO: Check if the QSL has been received or not as this "V" could mask a received QSL as a Worked (0) //stringFields = stringFields + ", confirmed"; //stringData = stringData + ", '0'"; stringFields = stringFields + ", qsl_rcvd_via"; if (aux2=="D") { stringData = stringData + ", 'D'"; } else if (aux2=="E") { stringData = stringData + ", 'E'"; } else if (aux2=="M") { stringData = stringData + ", 'M'"; } else { stringData = stringData + ", 'B'"; } } else { stringFields = stringFields + ", qsl_rcvd"; stringData = stringData + ", 'N'"; stringFields = stringFields + ", qsl_rcvd_via"; stringData = stringData + ", 'B'"; } // The data reading finish here. Now, we prepare the data to insert into the DB if (stringFields.startsWith(", ") ) { stringFields.remove(0,2); } stringFields += ", call, bandid, modeid, qso_date, time_on, lognumber, rst_sent, rst_rcvd"; if (stringFields.startsWith(", ") ) { stringFields.remove(0,2); } if (stringData.startsWith(", ") ) { stringData.remove(0,1); } stringData.remove(0,1); stringData += QString(", '%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8'").arg(tqrz).arg(tband).arg(tmode).arg(tdate).arg(ttime).arg(QString::number(currentLog)).arg(trsttx).arg(trstrx); if (stringData.startsWith(", ") ) { stringData.remove(0,2); } stringQuery = "INSERT INTO log (" + stringFields + ") values (" + stringData +")" ; return stringQuery; } QString MainWindow::readDataFromUIDXModifying() { //qDebug() << "MainWindow::readDataFromUIDXModifying:" << endl; /* UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition]; */ QString tqrz = (qrzLineEdit->text()).toUpper(); if (tqrz.length()<3) { return "NULL"; } QString stringQuery = "NULL"; QString aux1, aux2; //QString aux, aux2; int tband = currentBand; int tmode = currentMode; QString tdate = (dateEdit->date()).toString("yyyy/MM/dd"); QString ttime = (timeEdit->time()).toString("hh:mm:ss"); QString trsttx = rstTXLineEdit->text(); QString trstrx = rstRXLineEdit->text(); int dxcc = world->getQRZARRLId(tqrz); int cqz = world->getEntityCqz(dxcc); int ituz = world->getEntityItuz(dxcc); /**/ //int dxcc2 = getDXCCFromComboBox(); int dxcc2 = world->getQRZARRLId(othersTabWidget->getEntityPrefix()); //qDebug() << "MainWindow::readDataFromUIDXModifying - DXCC: " << QString::number(dxcc) << endl; //qDebug() << "MainWindow::readDataFromUIDXModifying- DXCC2: " << QString::number(dxcc2) << endl; dxcc = util->getNormalizedDXCCValue(dxcc); dxcc2 = util->getNormalizedDXCCValue(dxcc2); if (dxcc!=dxcc2) { QString dxccn1 = world->getEntityName(dxcc); dxccn1 = dxccn1 + " - " + world->getEntityMainPrefix(dxcc); QString dxccn2 = world->getEntityName(dxcc2); dxccn2 = dxccn2 + " - " + world->getEntityMainPrefix(dxcc2); QPushButton *button2 = new QPushButton(this); QPushButton *button1 = new QPushButton(this); button1->setText(world->getEntityMainPrefix(dxcc)); button2->setText(world->getEntityMainPrefix(dxcc2)); int ret; QMessageBox msgBox; msgBox.setText( tr("You have selected an entity:") + "\n\n"+"- "+dxccn2+"\n\n"+tr("that is different from the KLog proposed entity:") + "\n\n- "+dxccn1+"\n\n" +tr("Click on the prefix of the right entity or Cancel to correct.")); msgBox.addButton(button2, QMessageBox::AcceptRole); msgBox.addButton(button1, QMessageBox::ActionRole); msgBox.addButton(QMessageBox::Cancel); ret = msgBox.exec(); if (ret == QMessageBox::AcceptRole) { dxcc = dxcc2; } else if (ret == QMessageBox::Cancel) { return "NULL"; } else {} } /**/ QString updateString = "UPDATE log SET call = '" + tqrz + "', bandid = '" + QString::number(tband) + "', modeid = '" + QString::number(tmode) + "', qso_date = '" + tdate + "', time_on = '" + ttime + "', rst_sent = '" + trsttx + "', rst_rcvd = '" + trstrx + "', lognumber = '" + QString::number(currentLog) + "', "; aux1 = nameLineEdit->text(); if (aux1.length()>1) { updateString = updateString + "name = '"; updateString = updateString + aux1 + "', "; } aux1 = (locatorLineEdit->text()).toUpper(); if ( locator->isValidLocator(aux1) ) { updateString = updateString + "gridsquare = '"; updateString = updateString + aux1 + "', "; } if ( (txFreqSpinBox->value()) > 0 ) { aux1 = QString::number(txFreqSpinBox->value()); if (dataProxy->isThisFreqInBand(dataProxy->getNameFromBandId(tband), aux1) ) //if (db->isThisFreqInBand(db->getBandNameFromID2(tband), aux1) ) { updateString = updateString + "freq = '"; updateString = updateString + aux1 + "', "; } else { } } if ( (rxFreqSpinBox->value()) > 0 ) { aux1 = QString::number(rxFreqSpinBox->value()); updateString = updateString + "freq_rx = '"; updateString = updateString + aux1 + "', "; } aux1 = qthLineEdit->text(); if (aux1.length()>2) { updateString = updateString + "qth = '"; updateString = updateString + aux1 + "', "; } aux1 = myDataTabWidget->getOperator(); //aux1 = operatorLineEdit->text(); if (aux1.length()>2) { updateString = updateString + "operator = '"; updateString = updateString + aux1 + "', "; } aux1 = myDataTabWidget->getStationQRZ(); //aux1 = (stationCallSignLineEdit->text()).toUpper(); if (aux1.length()>2) { updateString = updateString + "station_callsign = '"; updateString = updateString + aux1 + "', "; } aux1 = myDataTabWidget->getMyLocator(); //aux1 = myLocatorLineEdit->text(); if (aux1.length()>2) { updateString = updateString + "my_gridsquare = '"; updateString = updateString + aux1 + "', "; } aux1 = commentTabWidget->getComment(); //aux1 = commentLineEdit->text(); if (aux1.length()>0) { updateString = updateString + "comment = '"; updateString = updateString + aux1 + "', "; } aux1 = QSLTabWidget->getQSLMsg(); //aux1 = qslmsgTextEdit->toPlainText(); if (aux1.length()>0) { updateString = updateString + "qslmsg = '"; updateString = updateString + aux1 + "', "; } aux1 = QString::number(dxcc); //qDebug() << "MainWindow::readDataFromUIDXModifying: DXCC=" << aux1 << endl; if (aux1.length()>0) { updateString = updateString + "dxcc = '"; updateString = updateString + aux1 + "', "; //qDebug() << "MainWindow::readDataFromUIDXModifying: Saving DXCC=" << aux1 << endl; } aux1 = QString::number(cqz); if (aux1.length()>0) { updateString = updateString + "cqz = '"; updateString = updateString + aux1 + "', "; } aux1 = QString::number(ituz); if (aux1.length()>0) { updateString = updateString + "ituz = '"; updateString = updateString + aux1 + "', "; } aux1 = QSLTabWidget->getQSLVia(); //aux1 = qslViaLineEdit->text(); if (aux1.length()>3) { updateString = updateString + "qsl_via = '"; updateString = updateString + aux1 + "', "; } //aux1 = QString::number(myPowerSpinBox->value()); aux1 = QString::number(myDataTabWidget->getMyPower()); if ((aux1.toDouble())>0.0) { updateString = updateString + "tx_pwr = '"; updateString = updateString + aux1 + "', "; } aux1 = QString::number(rxPowerSpinBox->value()); if ((aux1.toDouble())>0.0) { updateString = updateString + "rx_pwr = '"; updateString = updateString + aux1 + "', "; } aux1 = othersTabWidget->getIOTA(); //qDebug() << "MainWindow::readDataFromUIDX: Modifyng IOTA: " << aux1 << endl; if (aux1.length() == 6) // EU-001 { //qDebug() << "MainWindow::readDataFromUIDX: Modifyng IOTA to be saved! " << endl; updateString = updateString + "iota = '"; updateString = updateString + aux1 + "', "; } else { //qDebug() << "MainWindow::readDataFromUIDX: Modifyng IOTA NOT to be saved! Lenght="<getSatName(); //We are assuming that the SAT_NAME is always well provided. If it is blank, then no SAT QSO //qDebug() << "MainWindow::readDataFromUIDX: SAT2 modif " << aux1 << endl; //updateString = updateString + "sat_name = '"; //updateString = updateString + aux1 + "', "; if (aux1.length()>0) { updateString = updateString + "sat_name = '"; updateString = updateString + aux1 + "', "; } aux1 = satTabWidget->getSatMode(); // We are assuming that the SAT_MODE is always well provided. If it is blank, then no SAT QSO if (aux1.length()>0) { updateString = updateString + "sat_mode = '"; updateString = updateString + aux1 + "', "; } aux1 = othersTabWidget->getPropModeFromComboBox(); //aux1 = getPropModeFromComboBox(); //qDebug() << "MainWindow::readDataFromUIDX: PropMode: " << aux1 << endl; if ((aux1.length()>0) && (aux1 != "Not")) { //qDebug() << "MainWindow::readDataFromUIDX: PropMode(1): " << aux1 << endl; updateString = updateString + "prop_mode = '"; updateString = updateString + aux1 + "', "; } else if ((aux1.length()==0) || (aux1 == "Not")) { //qDebug() << "MainWindow::readDataFromUIDX: PropMode(2): " << aux1 << endl; updateString = updateString + "prop_mode = '',"; //updateString = updateString + aux1 + "', "; } else { //qDebug() << "MainWindow::readDataFromUIDX: PropMode(3): " << aux1 << endl; } //CLUBLOG aux1 = eQSLTabWidget->getClubLogStatus(); //Y, N, M if (aux1 == "Y") { updateString = updateString + "clublog_qso_upload_status = 'Y', "; updateString = updateString + "clublog_qso_upload_date = '" + (eQSLTabWidget->getClubLogDate()).toString("yyyy/MM/dd") + "', "; } else if (aux1 == "N") { updateString = updateString + "clublog_qso_upload_status = 'N', "; } else if (aux1 == "M") { updateString = updateString + "clublog_qso_upload_status = 'M', "; updateString = updateString + "clublog_qso_upload_date = '" + (eQSLTabWidget->getClubLogDate()).toString("yyyy/MM/dd") + "', "; } else //TODO: This should be equivalent to N? { updateString = updateString + "clublog_qso_upload_status = 'N', "; } //CLUBLOG // EQSL-SENT aux1 = eQSLTabWidget->getEQSLSenStatus(); if (aux1 == "Y") { updateString = updateString + "eqsl_qsl_sent = 'Y', "; updateString = updateString + "eqsl_qslsdate = '" + (eQSLTabWidget->getEQSLSenDate()).toString("yyyy/MM/dd") + "', "; } else if (aux1 == "R") { updateString = updateString + "eqsl_qsl_sent = 'R', "; } else if (aux1 == "Q") { updateString = updateString + "eqsl_qsl_sent = 'Q', "; updateString = updateString + "eqsl_qslsdate = '" + (eQSLTabWidget->getEQSLSenDate()).toString("yyyy/MM/dd") + "', "; } else if (aux1 == "I") { updateString = updateString + "eqsl_qsl_sent = 'I', "; updateString = updateString + "eqsl_qslsdate = '" + (eQSLTabWidget->getEQSLSenDate()).toString("yyyy/MM/dd") + "', "; } else // N { updateString = updateString + "eqsl_qsl_sent = 'N', "; } // EQSL-RECEPTION aux1 = eQSLTabWidget->getEQSLRecStatus(); if (aux1 == "Y") { updateString = updateString + "eqsl_qsl_rcvd = 'Y', "; updateString = updateString + "eqsl_qslrdate = '" + (eQSLTabWidget->getEQSLRecDate()).toString("yyyy/MM/dd") + "', "; } else if (aux1 == "R") { updateString = updateString + "eqsl_qsl_rcvd = 'R', "; } else if (aux1 == "I") { updateString = updateString + "eqsl_qsl_rcvd = 'I', "; } else if (aux1 == "V") { updateString = updateString + "eqsl_qsl_rcvd = 'V', "; updateString = updateString + "eqsl_qslrdate = '" + (eQSLTabWidget->getEQSLRecDate()).toString("yyyy/MM/dd") + "', "; } else { updateString = updateString + "eqsl_qsl_rcvd = 'N', "; } // LOTW-SENT aux1 = eQSLTabWidget->getLOTWSenStatus(); if (aux1 == "Y") { updateString = updateString + "lotw_qsl_sent = 'Y', "; updateString = updateString + "lotw_qslsdate = '" + (eQSLTabWidget->getLOTWSenDate()).toString("yyyy/MM/dd") + "', "; } else if (aux1 == "R") { updateString = updateString + "lotw_qsl_sent = 'R', "; } else if (aux1 == "Q") { updateString = updateString + "lotw_qsl_sent = 'Q', "; updateString = updateString + "lotw_qslsdate = '" + (eQSLTabWidget->getLOTWSenDate()).toString("yyyy/MM/dd") + "', "; } else if (aux1 == "I") { updateString = updateString + "lotw_qsl_sent = 'I', "; updateString = updateString + "lotw_qslsdate = '" + (eQSLTabWidget->getLOTWSenDate()).toString("yyyy/MM/dd") + "', "; } else { updateString = updateString + "lotw_qsl_sent = 'N', "; } // LOTW-RECEPTION //LOTW_QSLRDATE: (only valid if LOTW_RCVD is Y, I, or V) aux1 = eQSLTabWidget->getLOTWRecStatus(); if (aux1 == "Y") { updateString = updateString + "lotw_qsl_rcvd = 'Y', "; updateString = updateString + "lotw_qslrdate = '" + (eQSLTabWidget->getLOTWRecDate()).toString("yyyy/MM/dd") + "', "; } else if (aux1 == "R") { updateString = updateString + "lotw_qsl_rcvd = 'R', "; } else if (aux1 == "V") { updateString = updateString + "lotw_qsl_rcvd = 'V', "; updateString = updateString + "lotw_qslrdate = '" + (eQSLTabWidget->getLOTWRecDate()).toString("yyyy/MM/dd") + "', "; } else if (aux1 == "I") { updateString = updateString + "lotw_qsl_rcvd = 'I', "; updateString = updateString + "lotw_qslrdate = '" + (eQSLTabWidget->getLOTWRecDate()).toString("yyyy/MM/dd") + "', "; } else { updateString = updateString + "lotw_qsl_rcvd = 'N', "; } // QSL SENT //qsAux << tr("Y-Yes") << tr("N-No") << tr("R-Requested") << tr("Q-Queued") << tr("I-Ignore"); //int i = qslSentComboBox->currentIndex(); //int ii = qslSentViaComboBox->currentIndex(); aux1 = QSLTabWidget->getQSLSenStatus(); aux2 = QSLTabWidget->getSentVia(); //qDebug() << "MainWindow::readDataFromUIDXModifying: aux1: " << aux1 << " / aux2: " << aux2 << endl; if (aux1 == "Y") { updateString = updateString + "qsl_sent = 'Y', "; updateString = updateString + "qslsdate = '" + (QSLTabWidget->getQSLSenDate()).toString("yyyy/MM/dd") + "', "; if (aux2 == "D") { updateString = updateString + "qsl_sent_via = 'D', "; } else if (aux2 == "E") { updateString = updateString + "qsl_sent_via = 'E', "; } else if (aux2 == "M") { updateString = updateString + "qsl_sent_via = 'M', "; } else { updateString = updateString + "qsl_sent_via = 'B', "; } } else if (aux1 == "R") { updateString = updateString + "qsl_sent = 'R', "; //updateString = updateString + "qslsdate = '" + (QSLTabWidget->getQSLSenDate()).toString("yyyy/MM/dd") + "', "; if (aux2 == "D") { updateString = updateString + "qsl_sent_via = 'D', "; } else if (aux2 == "E") { updateString = updateString + "qsl_sent_via = 'E', "; } else if (aux2 == "M") { updateString = updateString + "qsl_sent_via = 'M', "; } else { updateString = updateString + "qsl_sent_via = 'B', "; } } else if (aux1 == "Q") { updateString = updateString + "qsl_sent = 'Q', "; updateString = updateString + "qslsdate = '" + (QSLTabWidget->getQSLSenDate()).toString("yyyy/MM/dd") + "', "; if (aux2 == "D") { updateString = updateString + "qsl_sent_via = 'D', "; } else if (aux2 == "E") { updateString = updateString + "qsl_sent_via = 'E', "; } else if (aux2 == "M") { updateString = updateString + "qsl_sent_via = 'M', "; } else { updateString = updateString + "qsl_sent_via = 'B', "; } } else if (aux1 == "I") { updateString = updateString + "qsl_sent = 'I', "; updateString = updateString + "qslsdate = '" + (QSLTabWidget->getQSLSenDate()).toString("yyyy/MM/dd") + "', "; if (aux2 == "D") { updateString = updateString + "qsl_sent_via = 'D', "; } else if (aux2 == "E") { updateString = updateString + "qsl_sent_via = 'E', "; } else if (aux2 == "M") { updateString = updateString + "qsl_sent_via = 'M', "; } else { updateString = updateString + "qsl_sent_via = 'B', "; } } else { updateString = updateString + "qsl_sent = 'N', "; updateString = updateString + "qsl_sent_via = 'B', "; } // QSL RECEPTION //i = qslRecComboBox->currentIndex(); //ii = qslRecViaComboBox->currentIndex(); aux1 = QSLTabWidget->getQSLRecStatus(); aux2 = QSLTabWidget->getRecVia(); if (aux1 == "Y") { updateString = updateString + "qsl_rcvd = 'Y', "; updateString = updateString + "qslrdate = '" + (QSLTabWidget->getQSLRecDate()).toString("yyyy/MM/dd") + "', "; //updateString = updateString + "confirmed = '1', "; if (aux2 == "D") { updateString = updateString + "qsl_rcvd_via = 'D', "; } else if (aux2 == "E") { updateString = updateString + "qsl_rcvd_via = 'E', "; } else if (aux2 == "M") { updateString = updateString + "qsl_rcvd_via = 'M', "; } else { updateString = updateString + "qsl_rcvd_via = 'B', "; } } else if (aux1 == "R") { //QSL received date //(only valid if QSL_RCVD is Y, I, or V) updateString = updateString + "qsl_rcvd = 'R', "; //updateString = updateString + "confirmed = '0', "; if (aux2 == "D") { updateString = updateString + "qsl_rcvd_via = 'D', "; } else if (aux2 == "E") { updateString = updateString + "qsl_rcvd_via = 'E', "; } else if (aux2 == "M") { updateString = updateString + "qsl_rcvd_via = 'M', "; } else { updateString = updateString + "qsl_rcvd_via = 'B', "; } } else if (aux1 == "I") { //QSL received date //(only valid if QSL_RCVD is Y, I, or V) updateString = updateString + "qsl_rcvd = 'I', "; updateString = updateString + "qslrdate = '" + (QSLTabWidget->getQSLRecDate()).toString("yyyy/MM/dd") + "', "; //updateString = updateString + "confirmed = '0', "; if (aux2 == "D") { updateString = updateString + "qsl_rcvd_via = 'D', "; } else if (aux2 == "E") { updateString = updateString + "qsl_rcvd_via = 'E', "; } else if (aux2 == "M") { updateString = updateString + "qsl_rcvd_via = 'M', "; } else { updateString = updateString + "qsl_rcvd_via = 'B', "; } } else if (aux1 == "V") { //QSL received date //(only valid if QSL_RCVD is Y, I, or V) updateString = updateString + "qsl_rcvd = 'V', "; updateString = updateString + "qslrdate = '" + (QSLTabWidget->getQSLRecDate()).toString("yyyy/MM/dd") + "', "; //updateString = updateString + "confirmed = '1', "; if (aux2 == "D") { updateString = updateString + "qsl_rcvd_via = 'D', "; } else if (aux2 == "E") { updateString = updateString + "qsl_rcvd_via = 'E', "; } else if (aux2 == "M") { updateString = updateString + "qsl_rcvd_via = 'M', "; } else { updateString = updateString + "qsl_rcvd_via = 'B', "; } } else { updateString = updateString + "qsl_rcvd = 'N', "; updateString = updateString + "qsl_rcvd_via = 'B', "; } keepSatPage = satTabWidget->getRepeatThis(); // The data reading finish here. Now, we prepare the data to insert into the DB if ( updateString.endsWith(", ") ) { updateString.chop(2); } //stringQuery = "INSERT INTO log (" + stringFields + ") values (" + stringData +")" ; // updateString = "UPDATE log SET call = '" + tqrz + "', bandid = '" + QString::number(tband) + "', modeid = '" + QString::number(tmode) + "', qso_date = '" + tdate + "', time_on = '" + ttime + "', lognumber = '" + QString::number(currentLog) + "', " + updateString; stringQuery = updateString + " WHERE id = " + "'" + QString::number(modifyingQSO) + "'"; //qDebug() << "MainWindow::readDataFromUIDXModifying: queryCreated: " << stringQuery << endl; return stringQuery; } /* void MainWindow::createSearchResultsPanel() { searchBoxClearButton->setToolTip(tr("Clear the searchs")); searchBoxExportButton->setToolTip(tr("Export the search result to an ADIF file")); searchBoxSelectAllButton->setToolTip(tr("Select/Unselect all the QSO of the box")); searchBoxReSearchButton->setToolTip(tr("Search in the log")); searchAllRadioButton->setToolTip(tr("Search in all logs")); searchBoxLineEdit->setToolTip(tr("Enter the QRZ to search")); searchResultsTreeWidget->setToolTip(tr("Search results")); QStringList labels; if (stationCallSignShownInSearch) { labels << tr("QRZ") << tr("Date/Time") << tr("Band") << tr("Mode") << tr("QSL Sent") << tr("QSL Rcvd") << tr("Station Callsign") << tr("Id") ; searchResultsTreeWidget->setColumnCount(8); } else { labels << tr("QRZ") << tr("Date/Time") << tr("Band") << tr("Mode") << tr("QSL Sent") << tr("QSL Rcvd") << tr("Id") ; searchResultsTreeWidget->setColumnCount(7); } searchResultsTreeWidget->setHeaderLabels(labels); //QTreeWidgetItem *item = new QTreeWidgetItem(searchResultsTreeWidget); (searchResultsTreeWidget->header())->resizeSections(QHeaderView::ResizeToContents); searchResultsTreeWidget->clear(); //searchResultsTreeWidget->collapseAll(); searchResultsTreeWidget->setSortingEnabled(true); //searchResultsTreeWidget->setItemsExpandable(false); switch (contestMode) { case CQ_WW_SSB: break; case CQ_WW_CW: break; default: break; } } */ void MainWindow::createScorePanel() { QVBoxLayout *scoreLayout = new QVBoxLayout; scoreLayout->addWidget(scoreTextEdit); scoreTextEdit->setPlainText("Test TEXT"); scoreWindow->setLayout(scoreLayout); } void MainWindow::createUICQWW() { //qDebug() << "MainWindow::createUICQWW" << endl; /* QSqlQuery query("SELECT name FROM band"); while (query.next()) { bands << query.value(0).toString(); } QSqlQuery query1("SELECT name FROM mode"); while (query1.next()) { modes << query1.value(0).toString(); } */ //bands << "10M" << "15M" << "20M" << "40M" << "80M" << "160M"; //modes << "SSB" << "CW" << "RTTY"; bandComboBox->addItems(bands); //qDebug() << "MainWindow::createUICQWW - 1-" << QString::number(modes.count()) << endl; modeComboBox->addItems(modes); qrzLineEdit->setToolTip(tr("QRZ of the QSO")); rstTXLineEdit->setToolTip(tr("TX RST")); rstRXLineEdit->setToolTip(tr("RX RST")); STXLineEdit->setToolTip(tr("TX Exchange")); SRXLineEdit->setToolTip(tr("RX Exchange")); bandComboBox->setToolTip(tr("Band of the QSO")); modeComboBox->setToolTip(tr("Mode of the QSO")); dateEdit->setToolTip(tr("Date of the QSO")); timeEdit->setToolTip(tr("Time of the QSO")); //statusBar->setToolTip(tr("Misc information")); //qsoStatusBar->setToolTip(tr("QSO information")); OKButton->setToolTip(tr("Add the QSO to the log")); //spotItButton->setToolTip(tr("Spots this QSO to the DX Cluster")); clearButton->setToolTip(tr("Clear the box")); gridGroupBox = new QGroupBox(tr("Input")); QGridLayout *layout = new QGridLayout; //slotUpdateStatusBar(tr("Ready")); //updateQSOStatusBar(tr("Ready")); rstTXLineEdit->setInputMask("#990"); rstRXLineEdit->setInputMask("#990"); rstTXLineEdit->setText("59"); rstRXLineEdit->setText("59"); rstTXLineEdit->setMaxLength(3); rstRXLineEdit->setMaxLength(3); QGroupBox *RSTrxgroupBox = new QGroupBox(tr("RSTrx")); RSTrxgroupBox->setFlat(true); QVBoxLayout *RSTrxvbox = new QVBoxLayout; RSTrxvbox->addWidget(rstRXLineEdit); RSTrxvbox->addStretch(1); RSTrxgroupBox->setLayout(RSTrxvbox); QGroupBox *RSTtxgroupBox = new QGroupBox(tr("RSTtx")); RSTtxgroupBox->setFlat(true); QVBoxLayout *RSTtxvbox = new QVBoxLayout; RSTtxvbox->addWidget(rstTXLineEdit); RSTtxvbox->addStretch(1); RSTtxgroupBox->setLayout(RSTtxvbox); //QGroupBox *qrzgroupBox = new QGroupBox(tr("QRZ")); qrzgroupBox = new QGroupBox(tr("QRZ")); qrzgroupBox->setFlat(true); QVBoxLayout *qrzvbox = new QVBoxLayout; qrzvbox->addWidget(qrzLineEdit); qrzvbox->addStretch(1); qrzgroupBox->setLayout(qrzvbox); QGroupBox *stxgroupBox = new QGroupBox(tr("STX")); stxgroupBox->setFlat(true); QVBoxLayout *stxvbox = new QVBoxLayout; stxvbox->addWidget(STXLineEdit); stxvbox->addStretch(1); stxgroupBox->setLayout(stxvbox); QGroupBox *srxgroupBox = new QGroupBox(tr("SRX")); srxgroupBox->setFlat(true); QVBoxLayout *srxvbox = new QVBoxLayout; srxvbox->addWidget(SRXLineEdit); srxvbox->addStretch(1); srxgroupBox->setLayout(srxvbox); QHBoxLayout *RSTLayout = new QHBoxLayout; RSTLayout->addWidget(RSTtxgroupBox); RSTLayout->addWidget(RSTrxgroupBox); RSTLayout->addWidget(stxgroupBox); RSTLayout->addWidget(srxgroupBox); QHBoxLayout *TimeLayout = new QHBoxLayout; TimeLayout->addWidget(dateEdit); TimeLayout->addWidget(timeEdit); QHBoxLayout *BandModeLayout = new QHBoxLayout; BandModeLayout->addWidget(bandComboBox); BandModeLayout->addWidget(modeComboBox); //QHBoxLayout *statusBarLayout = new QHBoxLayout; //statusBarLayout->addWidget(statusBar); //statusBarLayout->addWidget(qsoStatusBar); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addWidget(OKButton); //buttonsLayout->addWidget(spotItButton); buttonsLayout->addWidget(clearButton); QDateTimeEdit *dateEdit = new QDateTimeEdit(QDate::currentDate()); dateEdit->setDisplayFormat("yyyy/MM/dd"); timeEdit->setDisplayFormat("HH:mm:ss"); layout->addWidget(qrzgroupBox, 1, 0); layout->addLayout(RSTLayout, 1, 1); layout->addLayout(TimeLayout, 2, 0); layout->addLayout(BandModeLayout, 2, 1); layout->addLayout(buttonsLayout,3, 1); //layout->addLayout(statusBarLayout, 4, 0, 2 , -1); gridGroupBox->setLayout(layout); gridGroupBox->resize(gridGroupBox->minimumSize()); mainWidget->setLayout(layout); } void MainWindow::slotOKButtonClicked(){ //qDebug() << "MainWindow::slotOKButtonClicked: " << endl; slotQRZReturnPressed(); } void MainWindow::createActionsCommon(){ // Functional widgets connections //TODO: Reimplement the possibility to enter a QSO with enter inthe following widgets: //connect(qslViaLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); // Return pressed = QSO ENTRY connect(qrzLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(SRXLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(STXLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(rstTXLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(rstRXLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(operatorLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(stationCallSignLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(myLocatorLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(locatorLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(qthLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(nameLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(locatorLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotLocatorTextChanged() ) ); connect(myLocatorLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotMyLocatorTextChanged() ) ); connect(txFreqSpinBox, SIGNAL(valueChanged(double)), this, SLOT(slotFreqTXChanged()) ) ; connect(rxFreqSpinBox, SIGNAL(valueChanged(double)), this, SLOT(slotFreqRXChanged()) ) ; //connect(bandComboBox, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); //connect(dateEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); //connect(timeEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); //Actions to pass the focus between QRZ / SRX connect(qrzLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotQRZTextChanged() ) ); connect(SRXLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotSRXTextChanged() ) ); connect(STXLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotSTXTextChanged() ) ); connect(rstTXLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotrstTXTextChanged() ) ); connect(rstRXLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotrstRXTextChanged() ) ); //connect(qslViaLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotQSLViaTextChanged() ) ); connect(bandComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotBandComboBoxChanged() ) ) ; connect(modeComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotModeComboBoxChanged() ) ) ; //Buttons Actions connect(OKButton, SIGNAL(clicked()), this, SLOT(slotOKButtonClicked() ) ); //connect(spotItButton, SIGNAL(clicked()), this, SLOT(slotSpotItButtonClicked() ) ); connect(clearButton, SIGNAL(clicked()), this, SLOT(slotClearButtonClicked() ) ); // SEARCH BOX VIEW //connect(searchBoxLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotSearchBoxTextChanged() ) ); //connect(searchAllRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotSearchBoxSelectAllButtonClicked() ) ); //connect(searchResultsTreeWidget, SIGNAL(customContextMenuRequested( const QPoint& ) ), this, SLOT(slotRighButtonSearch( const QPoint& ) ) ); //connect(searchResultsTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(slotDoubleClickSearch(QTreeWidgetItem *, int))); //connect(searchResultsTreeWidget, SIGNAL(itemSelectionChanged( ) ), this, SLOT(slotSearchBoxSelectionChanged( ) ) ); //connect(searchBoxExportButton, SIGNAL(clicked()), this, SLOT(slotSearchExportButtonClicked() ) ); //connect(searchBoxClearButton, SIGNAL(clicked()), this, SLOT(slotSearchClearButtonClicked() ) ); //connect(searchBoxSelectAllButton, SIGNAL(clicked()), this, SLOT(slotSearchBoxSelectAllButtonClicked() ) ); //connect(searchBoxReSearchButton, SIGNAL(clicked()), this, SLOT(slotSearchBoxReSearchButtonClicked() ) ); connect(operatingYearsComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotOperatingYearComboBoxChanged() ) ) ; connect(recalculateAwardsButton, SIGNAL(clicked()), this, SLOT(slotRecalculateAwardsButtonClicked() ) ); // LOGVIEW connect(logWindow, SIGNAL(actionQSODoubleClicked ( int ) ), this, SLOT(slotDoubleClickLog( const int ) ) ); connect(logWindow, SIGNAL(updateAwards() ), this, SLOT(slotShowAwards() ) ); connect(logWindow, SIGNAL(updateSearchText()), this, SLOT(slotSearchBoxTextChanged() ) ); //When a QSO is deleted //CLUSTER //void clusterSpotToLog(const QStringList _qs); //SIGNAL dxspotclicked(const QStringList _qs) connect(dxClusterWidget, SIGNAL(dxspotclicked(QStringList)), this, SLOT(slotAnalyzeDxClusterSignal(QStringList) ) ); // CLUBLOG connect (elogClublog, SIGNAL (showMessage(QString)), this, SLOT (slotElogClubLogShowMessage(QString))); connect (elogClublog, SIGNAL (actionReturnDownload(int, int)), this, SLOT (slotElogClubLogProcessAnswer(int, int))); connect (elogClublog, SIGNAL (disableClubLogAction(bool)), this, SLOT (slotElogClubLogDisable(bool))); // SATELLITE TAB connect (satTabWidget, SIGNAL (satBandTXChanged(QString)), this, SLOT (slotSatBandTXComboBoxChanged(QString))); // QSL TAB connect(QSLTabWidget, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed()) ); // SEARCH TAB connect(searchWidget, SIGNAL(actionQSODoubleClicked ( int ) ), this, SLOT(slotDoubleClickLog( const int ) ) ); connect(searchWidget, SIGNAL(updateAwards() ), this, SLOT(slotShowAwards() ) ); connect(searchWidget, SIGNAL(logRefresh() ), this, SLOT(slotLogRefresh() ) ); connect(searchWidget, SIGNAL(toStatusBar(QString) ), this, SLOT(slotUpdateStatusBar(QString) ) ); connect(searchWidget, SIGNAL(requestBeingShown() ), this, SLOT(slotShowSearchWidget() ) ); connect(searchWidget, SIGNAL(actionQSODelete( int ) ), this, SLOT(slotQSODelete(int) ) ); } void MainWindow::slotSearchBoxTextChanged() { searchWidget->slotSearchBoxTextChanged(); } void MainWindow::slotQSODelete(const int _id) { elogClublog->deleteQSO(dataProxy->getClubLogRealTimeFromId(_id)); //awards->recalculateAwards(); } void MainWindow::slotShowSearchWidget() { //dxUpRightTab->addTab(searchWidget, tr("Search")); dxUpRightTab->setCurrentIndex(dxUpRightTab->indexOf(searchWidget)); } void MainWindow::slotLogRefresh() { logWindow->refresh(); } void MainWindow::slotElogClubLogDisable(const bool _b) { //qDebug() << "MainWindow::slotElogClubLogDisable: " << endl; if (_b) { clublogActive = false; setupDialog->setClubLogActive(false); } else { clublogActive = true; setupDialog->setClubLogActive(true); } //TODO: Disable clublog in the klogrc file //bool FileManager::modifySetupFile(const QString& _filename, const QString _field, const QString _value) filemanager->modifySetupFile(configFileName, "ClubLogActive", "False"); } void MainWindow::slotElogClubLogShowMessage(const QString _s) { //qDebug() << "MainWindow::slotElogClubLogShowMessage: " << _s << endl; slotUpdateStatusBar(_s); } void MainWindow::slotElogClubLogProcessAnswer(const int _i, const int _qID) { //qDebug() << "MainWindow::slotElogClubLogProcessAnswer: " <setClubLogSent(_qID, "Y", (eQSLTabWidget->getClubLogDate()).toString("yyyy/MM/dd")); } else { dataProxy->setClubLogSent(_qID, "M", (eQSLTabWidget->getClubLogDate()).toString("yyyy/MM/dd")); } } void MainWindow::slotRecalculateAwardsButtonClicked() { //qDebug() << "MainWindow::recalculateAwardsButtonClicked: " << endl; awards->recalculateAwards(); showAwards(); } void MainWindow::slotExitFromSlotDialog(const int exitID) { //qDebug() << "MainWindow::slotExitFromSlotDialog: " << QString::number(exitID) << endl; if (exitID == 2) { needToEnd = true; close(); } } void MainWindow::createActionsCQWW(){ // Functional widgets connections } void MainWindow::createActionsDX(){ // Functional widgets connections connect(nameLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(qthLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); connect(locatorLineEdit, SIGNAL(returnPressed()), this, SLOT(slotQRZReturnPressed() ) ); //connect(iotaContinentComboBox, SIGNAL(activated ( int)), this, SLOT(slotIOTAComboBoxChanged() ) ) ; //QSL Actions //connect(qslSentComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotQSLSentComboBoxChanged() ) ) ; //connect(qslRecComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotQSLRecvComboBoxChanged() ) ) ; //TODO REMOVE EQSL //connect(eqslSentComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(sloteQSLSentComboBoxChanged() ) ) ; //connect(eqslRecComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(sloteQSLRecvComboBoxChanged() ) ) ; //connect(lotwSentComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotLotwSentComboBoxChanged() ) ) ; //connect(lotwRecComboBox, SIGNAL(currentIndexChanged ( int)), this, SLOT(slotLotwRecvComboBoxChanged() ) ) ; connect(satTabWidget, SIGNAL(setPropModeSat(QString)), this, SLOT(slotSetPropMode(QString)) ) ; } bool MainWindow::checkContest(){ //qDebug() << "MainWindow::checkContest: " << contestMode << endl; //contestNames << "No-Contest" <<"CQ-WW-DX-SSB" << "CQ-WW-DX-CW" << "CQ-WPX-SSB" << "CQ-WPX-CW"; QStringList qs; qs.clear(); QString qsoStatus, aux; int currentEntity = world->getQRZARRLId(currentQrz); int tband = 1 + bandComboBox->currentIndex(); //int tmode = 1 + modeComboBox->currentIndex(); if (contestMode == "DX") {} else if (contestMode == "CQ-WW-SSB") { //qDebug() << "MainWindow::checkContest: CQ-WW-SSB:" << QString::number(currentEntity) << "/" << SRXLineEdit->text() << "/" << QString::number(tband) << endl; if ( currentEntity < 1) { return false; } //Multiplier: qs << DX-Entity << DXCQz << DX-band; qs << QString::number(currentEntity) << SRXLineEdit->text() << QString::number(tband); if (contest->isMultiplier(qs)){ qrzgroupBox->setTitle(tr("NEW MULT")); //qsoStatus = tr("MULT"); aux = " + (M + "; qsoMultiplier = 1; }else{ //qsoStatus = tr("NO MULT"); aux.clear(); qsoMultiplier = 0; } // Points: //_qs << DX-Entity << DX-Continent qs.clear(); qs << QString::number(currentEntity) << QString::number(world->getContinentNumber(currentEntity)); qsoPoints = contest->getQSOPoints(qs); if (aux == " + (M + ") { qsoStatus = "Total: " + QString::number(contest->getTotalScore()) + aux + QString::number(qsoPoints) + " points)"; // qsoStatus + " / " + QString::number(qsoPoints) + tr(" points"); } else { qsoStatus = "Total: " + QString::number(contest->getTotalScore()) + " ( " + QString::number(qsoPoints) + " points)"; // qsoStatus + " / " + QString::number(qsoPoints) + tr(" points"); } //qDebug() << "MainWindow::checkContest Points: " << QString::number(contest->getQSOPoints(qs)) << endl; //qDebug() << "MainWindow::checkContest Continent: " << world->getQRZContinentNumber(qrzLineEdit->text()) << endl; } else {} slotUpdateStatusBar(qsoStatus); //statusBar()->showMessage(qsoStatus); //updateQSOStatusBar(qsoStatus); return false; } /* void MainWindow::slotQSLViaTextChanged() { //qDebug() << "MainWindow::slotQSLViaTextChanged: " << qslViaLineEdit->text() << " / Length: " << QString::number((qslViaLineEdit->text()).size()) << endl; qslViaLineEdit->setText((qslViaLineEdit->text()).toUpper()); } */ bool MainWindow::validCharactersInCall(const QString _qrz) { for (int i = 0; i<_qrz.size();i++) { if (!( ((_qrz.at(i)).isLetterOrNumber()) || (_qrz.at(i)=='\\') || (_qrz.at(i)=='/') )) { return false; } } return true; } void MainWindow::slotQRZTextChanged() { //qDebug()<< "MainWindow::slotQRZTextChanged: " << qrzLineEdit->text() << " / Length: " << QString::number((qrzLineEdit->text()).size()) << "###### START ######" << endl; qrzLineEdit->setText((qrzLineEdit->text()).toUpper()); if (cleaning) { //qDebug()<< "MainWindow::slotQRZTextChanged: Cleaning" << endl; return; } if (qrzAutoChanging) { //qDebug()<< "MainWindow::slotQRZTextChanged: qrzAutoChanging" << endl; qrzAutoChanging = false; return; } qrzAutoChanging = true; int cursorP = qrzLineEdit->cursorPosition(); if ( (qrzLineEdit->text()).endsWith(' ') ) {/*Remove the space and moves the focus to SRX to write the RX exchange*/ previousQrz = (qrzLineEdit->text()).simplified(); qrzLineEdit->setText(previousQrz); SRXLineEdit->setFocus(); //qDebug()<< "MainWindow::slotQRZTextChanged: Space detected" << endl; } //qDebug()<< "MainWindow::slotQRZTextChanged: Simplifiying & Capitalizing" << endl; qrzLineEdit->setText(((qrzLineEdit->text())).simplified()); qrzLineEdit->setText((qrzLineEdit->text()).remove(" ")); //qrzLineEdit->setText((qrzLineEdit->text()).toUpper()); if (!validCharactersInCall(qrzLineEdit->text())) { infoLabel1->setText(tr("Invalid characters used in the QRZ")); InValidCharsInPrevCall = true; return; } if (((qrzLineEdit->text()).length() < 1)) { // If QRZ box is blank, Information labels should be cleared. infoLabel1->clear(); infoLabel2->clear(); slotClearButtonClicked(); return; } if ((modify) || ((qrzLineEdit->text()).length() < 1) || (qrzSmallModDontCalculate)) { //qDebug() << "MainWindow::slotQRZTextChanged: MODIFY or Lenght < 1" << endl; qrzSmallModDontCalculate=false; return; } qrzSmallModDontCalculate = true; // A kind of flag to prevent multiple calls to this method. //int i; int dx_CQz = -1; int dxE_CQz = -1; int dx_ITUz = -1; int dxE_ITUz = -1; currentQrz = qrzLineEdit->text(); if ((currentQrz).count('\\')){ // Replaces \ by / to ease operation. currentQrz.replace(QChar('\\'), QChar('/')); qrzLineEdit->setText(currentQrz); } currentQrz = qrzLineEdit->text(); if (cursorP>currentQrz.length()) {// A Space that has been removed without updating the cursor //qDebug()<< "MainWindow::slotQRZTextChanged: cursorP > currentQRZ.length" << endl; } else { if ((currentQrz.at(cursorP-1)).isSpace()) { previousQrz = currentQrz.remove(cursorP-1, 1); cursorP--; qrzLineEdit->setText(previousQrz); } } currentQrz = qrzLineEdit->text(); currentEntity = world->getQRZARRLId(currentQrz); //selectCorrectComboBoxEntity(currentEntity); //qDebug() << "MainWindow::slotQRZTextChanged: " << QString::number(currentEntity) << endl; othersTabWidget->setEntity(currentEntity); //qDebug() << "MainWindow::slotQRZTextChanged: DXCC/ISOname: " << QString::number(currentEntity) << "/" << dataProxy->getISOName(currentEntity) << endl; //qDebug() << "MainWindow::slotQRZTextChanged: Entity: " << QString::number(currentEntity) << endl; dxE_CQz = world->getEntityCqz(currentEntity); dx_CQz = world->getQRZCqz(currentQrz); dx_ITUz = world->getQRZItuz(currentQrz); dxE_ITUz = world->getEntityItuz(currentEntity); //qDebug()<< "MainWindow::slotQRZTextChanged: CQ: " << QString::number(dx_CQz) << endl; //qDebug()<< "MainWindow::slotQRZTextChanged: CQe: " << QString::number(dxE_CQz) << endl; //qDebug()<< "MainWindow::slotQRZTextChanged: ITU: " << QString::number(dx_ITUz) << endl; //qDebug()<< "MainWindow::slotQRZTextChanged: ITUe: " << QString::number(dxE_ITUz) << endl; if (dx_CQz == dxE_CQz) { dx_CQz = dxE_CQz; } if (dx_ITUz == dxE_ITUz) { dx_ITUz = dxE_ITUz; } QStringList _qs; //for the showStatusOfDXCC(const QStringList _qs) _qs.clear(); _qs << QString::number(currentEntity) << QString::number(currentBand) << QString::number(currentMode) << QString::number(currentLog); if ( locator->isValidLocator((locatorLineEdit->text()).toUpper()) ) { dxLocator = (locatorLineEdit->text()).toUpper(); } else { dxLocator = world->getLocator(currentEntity); } // NOW ONLY SPECIFIC ACTIONS DEPENDING ON THE RUNNING MODE if (contestMode == "DX") { //qDebug() << "MainWindow::slotQRZTextChanged: Default:" << endl; //qDebug() << "MainWindow::slotQRZTextChanged: - current/previous" << QString::number(currentEntity) << "/" << QString::number(previousEntity) << endl; if ( (currentEntity != previousEntity) || ((infoLabel2->text()).length() < 1) || (InValidCharsInPrevCall) || (dx_CQz != dxE_CQz) || (dx_ITUz != dxE_ITUz)) { //qDebug() << "MainWindow::slotQRZTextChanged: currentEntity=" << QString::number(currentEntity) << "/previousEntity=" << QString::number(previousEntity) << endl; previousEntity = currentEntity; InValidCharsInPrevCall = false; infoLabel2->setText(world->getEntityName(currentEntity)); infoWidget->showEntityInfo(currentEntity, dx_CQz, dx_ITUz); infoWidget->showDistanceAndBearing(myLocator, dxLocator); showStatusOfDXCC(_qs); showDXMarathonNeeded(currentEntity, dx_CQz, dateEdit->date().year(), currentLog); othersTabWidget->setIOTAContinentFromEntity(currentEntity); } else if ((dx_CQz == dxE_CQz) || (dx_ITUz = dxE_ITUz)) { infoLabel2->setText(world->getEntityName(currentEntity)); infoWidget->showEntityInfo(currentEntity, dx_CQz, dx_ITUz); } else { //qDebug() << "MainWindow::slotQRZTextChanged: Default: else" << endl; } } else if (contestMode == "CQ-WW-SSB") { //qDebug() << "MainWindow::slotQRZTextChanged: CQ-WW-SSB:" << endl; STXLineEdit->setText(QString::number(my_CQz)); // My Own CQZ if (dx_CQz > 0) { //if(QString::number(world->getQRZCqz(qrzLineEdit->text())) > 0 ){ SRXLineEdit->setText(QString::number(dx_CQz)); }else{ //qDebug() << "MainWindow::checkContest CQZ < 0"<< endl; } if (currentEntity>0){ slotUpdateStatusBar(world->getEntityName(currentEntity) + " - CQ: " + QString::number(dx_CQz) + " - ITU: " + QString::number(dx_ITUz)); } else { slotUpdateStatusBar(tr("Ready...")); } checkIfWorkedB4(currentQrz); // Has the QSO id if worked before checkContest(); } else { //qDebug() << "MainWindow::slotQRZTextChanged: Default:" << endl; //qDebug() << "MainWindow::slotQRZTextChanged: - current/previous" << QString::number(currentEntity) << "/" << QString::number(previousEntity) << endl; if ( (currentEntity != previousEntity) || ((infoLabel2->text()).length() < 1) || (InValidCharsInPrevCall) || (dx_CQz != dxE_CQz) || (dx_ITUz != dxE_ITUz)) { //qDebug() << "MainWindow::slotQRZTextChanged: currentEntity=" << QString::number(currentEntity) << "/previousEntity=" << QString::number(previousEntity) << endl; previousEntity = currentEntity; InValidCharsInPrevCall = false; infoLabel2->setText(world->getEntityName(currentEntity)); infoWidget->showEntityInfo(currentEntity, dx_CQz, dx_ITUz); infoWidget->showDistanceAndBearing(myLocator, dxLocator); showStatusOfDXCC(_qs); showDXMarathonNeeded(currentEntity, dx_CQz, dateEdit->date().year(), currentLog); othersTabWidget->setIOTAContinentFromEntity(currentEntity); } else if ((dx_CQz == dxE_CQz) || (dx_ITUz = dxE_ITUz)) { infoLabel2->setText(world->getEntityName(currentEntity)); infoWidget->showEntityInfo(currentEntity, dx_CQz, dx_ITUz); } else { //qDebug() << "MainWindow::slotQRZTextChanged: Default: else" << endl; } } qrzSmallModDontCalculate = false; // If the text has not been modified in this method qrzLineEdit->setCursorPosition(cursorP); completeWithPreviousQSO(currentQrz); qrzAutoChanging = false; //qDebug() << "MainWindow::slotQRZTextChanged: END" << endl; } void MainWindow::slotQRZSpacePressed() { //qDebug() << "MainWindow::slotQRZSpacePressed: " << endl; } void MainWindow::slotSRXTextChanged() { //qDebug() << "MainWindow::slotSRXTextChanged: " << SRXLineEdit->text() << endl; srx = SRXLineEdit->text(); //int i = srx.size(); if ( srx.endsWith(' ') ) { /*Remove the space and moves the focus to QRZ*/ srx = srx.simplified(); SRXLineEdit->setText(srx); qrzLineEdit->setFocus(Qt::OtherFocusReason); } } void MainWindow::slotSTXTextChanged() { //qDebug() << "MainWindow::slotSTXTextChanged: " << STXLineEdit->text() << endl; stx = STXLineEdit->text(); //int i = stx.size(); if ( stx.endsWith(' ') ) { /*Remove the space and moves the focus to QRZ*/ stx = stx.simplified(); STXLineEdit->setText(stx); SRXLineEdit->setFocus(Qt::OtherFocusReason); } } void MainWindow::slotrstTXTextChanged() { } void MainWindow::slotrstRXTextChanged() { } void MainWindow::slotSpotItButtonClicked() { if (!dxClusterWidget->isConnected()) { return; } } void MainWindow::slotClearButtonClicked() { //qDebug() << "MainWindow::slotClearButtonClicked - START" << endl; //qDebug() << "MainWindow::slotClearButtonClicked: " << modeComboBox->currentText() << endl; cleaning = true; modify = false; OKButton->setText(tr("&Add")); modifyingQSO = -1; qrzLineEdit->clear(); qrzLineEdit->setFocus(Qt::OtherFocusReason); rstTXLineEdit->setText("59"); rstRXLineEdit->setText("59"); qthLineEdit->clear(); //qDebug() << "MainWindow::slotClearButtonClicked: - band: " << QString::number(currentBand) << endl; //qDebug() << "MainWindow::slotClearButtonClicked: - mode: " << QString::number(currentMode) << endl; //qDebug() << "MainWindow::slotClearButtonClicked: - defaultMode: " << QString::number(defaultMode) << endl; if (currentBand < 0) { currentBand = defaultBand; } bandComboBox->setCurrentIndex(bandComboBox->findText(dataProxy->getNameFromBandId(currentBand), Qt::MatchCaseSensitive)); //qDebug() << "MainWindow::MainWindow: 12 - currentMode: " << QString::number(currentMode) << endl; if (currentMode < 0) { currentMode = defaultMode; } modeComboBox->setCurrentIndex(modeComboBox->findText(dataProxy->getSubModeFromId(currentMode), Qt::MatchCaseSensitive)); //modeComboBox->setCurrentIndex(modeComboBox->findText(dataProxy->getNameFromSubModeId(currentMode))); qsoPoints = 0; qsoMultiplier = 0; clublogAnswer = -1; clublogPrevQSO.clear(); if (contestMode == "DX") { SRXLineEdit->setText("59"); STXLineEdit->setText("59"); nameLineEdit->clear(); locatorLineEdit->clear(); //txFreqSpinBox->setValue(0); //rxFreqSpinBox->setValue(0); //freqQLCDNumber->display(0); //notesTextEdit->clear(); commentTabWidget->clear(); //commentLineEdit->clear(); infoLabel1->clear(); infoLabel2->clear(); //rxPowerSpinBox->setValue(0); eQSLTabWidget->clear(); QSLTabWidget->clear(); othersTabWidget->clear(); satTabWidget->clear(); myDataTabWidget->clear(keepMyData); infoWidget->clear(); } else if (contestMode == "CQ-WW-SSB") { SRXLineEdit->clear(); STXLineEdit->setText( QString::number( world->getQRZCqz(stationQRZ) ) ); qrzgroupBox->setTitle(tr("QRZ")); } else if (contestMode == "CQ-WW-CW") { SRXLineEdit->clear(); STXLineEdit->setText( QString::number( world->getQRZCqz(stationQRZ) ) ); qrzgroupBox->setTitle(tr("QRZ")); } else { SRXLineEdit->setText("59"); STXLineEdit->setText("59"); nameLineEdit->clear(); locatorLineEdit->clear(); txFreqSpinBox->setValue(0); rxFreqSpinBox->setValue(0); //freqQLCDNumber->display(0); //notesTextEdit->clear(); commentTabWidget->clear(); //commentLineEdit->clear(); infoLabel1->clear(); infoLabel2->clear(); rxPowerSpinBox->setValue(0); eQSLTabWidget->clear(); QSLTabWidget->clear(); othersTabWidget->clear(); satTabWidget->clear(); myDataTabWidget->clear(keepMyData); infoWidget->clear(); } statusBar()->clearMessage(); cleaning = false; //qDebug() << "MainWindow::slotClearButtonClicked: " << modeComboBox->currentText() << endl; //qDebug() << "MainWindow::slotClearButtonClicked - currentMode = " << QString::number(currentMode) << endl; //qDebug() << "MainWindow::slotClearButtonClicked - END" << endl; } /* void MainWindow::clearBandLabels() { bandLabel1->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel2->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel3->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel4->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel5->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel6->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel7->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel8->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel9->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel10->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel11->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); bandLabel12->setStyleSheet("* { background-color: " + defaultColor.name() + "; }"); } */ void MainWindow::slotRefreshDXCCWidget() { dxccStatusWidget->slotRefreshButtonClicked(); } void MainWindow::slotUpdateTime() { // //qDebug() << "MainWindow::slotUpdateTime: " << (dateTime->currentDateTime()).toString("yyyy-MM-dd - hh:mm:ss") << endl; // ((dateTime->currentDateTimeUtc()).date()).toString() //(dateTime->currentDateTime()).date() dateTime->currentDateTime(); if ( (!modify) && (realTime) ) { //dateTime->currentDateTime(); dateEdit->setDate((dateTime->currentDateTime()).date()); if (UTCTime) { timeEdit->setTime((dateTime->currentDateTime().toUTC()).time()); } else { timeEdit->setTime((dateTime->currentDateTime()).time()); } } } void MainWindow::closeEvent(QCloseEvent *event) { //qDebug() << "MainWindow::closeEvent" << endl; if (maybeSave()) { dataProxy->unMarkAllQSO(); //slotFileClose(); dataProxy->compressDB(); //db->compress(); event->accept(); } else { event->ignore(); } } bool MainWindow::maybeSave() { //qDebug() << "MainWindow::maybeSave" << endl; if ((alwaysADIF) || (DBinMemory) ) { if (needToSave) { QMessageBox::StandardButton ret; ret = QMessageBox::warning(this, tr("KLog"), tr("The logfile has been modified.\n" "Do you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); if (ret == QMessageBox::Save) { if (useDefaultLogFileName) { return saveFile(defaultADIFLogFile); } else { return saveFileAs(); } } else if (ret == QMessageBox::Cancel) return false; } } return true; } void MainWindow::createMenusCommon() { //qDebug() << "MainWindow::createMenusCommon" << endl; fileMenu = menuBar()->addMenu(tr("&File")); openAct = new QAction(tr("&New..."), this); fileMenu->addAction(openAct); //openAct->setShortcut(Qt::CTRL + Qt::Key_N); connect(openAct, SIGNAL(triggered()), this, SLOT(newFile())); openAct = new QAction(tr("&Open..."), this); fileMenu->addAction(openAct); openAct->setShortcut(Qt::CTRL + Qt::Key_O); connect(openAct, SIGNAL(triggered()), this, SLOT(openFile())); ADIFImport = new QAction(tr("&Import from ADIF..."), this); fileMenu->addAction(ADIFImport); connect(ADIFImport, SIGNAL(triggered()), this, SLOT(slotADIFImport())); ADIFImport->setToolTip(tr("Import an ADIF file into the current log.")); //LoTWImport = new QAction(tr("&Import from LoTW..."), this); //fileMenu->addAction(LoTWImport); //connect(LoTWImport, SIGNAL(triggered()), this, SLOT(slotLoTWImport())); //LoTWImport->setToolTip(tr("Import an LoTW file into the current log")); fileMenu->addSeparator(); saveAct = new QAction(tr("&Save As..."), this); fileMenu->addAction(saveAct); saveAct->setShortcut(Qt::CTRL + Qt::Key_S); connect(saveAct, SIGNAL(triggered()), this, SLOT(saveFileAs())); fileMenu->addSeparator(); ADIFExport = new QAction(tr("Export to ADIF..."), this); fileMenu->addAction(ADIFExport); //ADIFExport->setMenuRole(QAction::ApplicationSpecificRole); connect(ADIFExport, SIGNAL(triggered()), this, SLOT(slotADIFExport())); ADIFExport->setToolTip(tr("Export the current log to an ADIF logfile.")); ADIFExportAll = new QAction(tr("Export all logs to ADIF..."), this); fileMenu->addAction(ADIFExportAll); //ADIFExport->setMenuRole(QAction::ApplicationSpecificRole); connect(ADIFExportAll, SIGNAL(triggered()), this, SLOT(slotADIFExportAll())); ADIFExportAll->setToolTip(tr("Export ALL the QSOs into one ADIF file, merging QSOs from all the logs.")); ReqQSLExport = new QAction(tr("Export Requested QSL to ADIF..."), this); fileMenu->addAction(ReqQSLExport); connect(ReqQSLExport, SIGNAL(triggered()), this, SLOT(slotRQSLExport())); ReqQSLExport->setToolTip(tr("Export all QSOs requesting QSLs to an ADIF file (e.g. to import it into a QSL tag printing program).")); LoTWExport = new QAction(tr("Export ADIF for LoTW..."), this); fileMenu->addAction(LoTWExport); connect(LoTWExport, SIGNAL(triggered()), this, SLOT(slotLoTWExport())); LoTWExport->setToolTip(tr("Export an ADIF file to be sent to LoTW. Remember to sign it with TQSL before uploading to LoTW!")); fileMenu->addSeparator(); printLogAct = new QAction(tr("&Print Log..."), this); fileMenu->addAction(printLogAct); printLogAct->setShortcut(Qt::CTRL + Qt::Key_P); printLogAct->setToolTip(tr("Print your log.")); connect(printLogAct, SIGNAL(triggered()), this, SLOT(slotFilePrint())); fileMenu->addSeparator(); klogFolderAct = new QAction(tr("KLog folder"), this); fileMenu->addAction(klogFolderAct); printLogAct->setToolTip(tr("Opens the data folder of KLog.")); connect(klogFolderAct, SIGNAL(triggered()), this, SLOT(slotOpenKLogFolder())); fileMenu->addSeparator(); exitAct = new QAction(tr("E&xit"), this); fileMenu->addAction(exitAct); exitAct->setMenuRole(QAction::QuitRole); exitAct->setShortcut(Qt::CTRL + Qt::Key_X); connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); toolMenu = menuBar()->addMenu(tr("&Tools")); fillQsoAct = new QAction(tr("Fill in QSO data"), this); toolMenu->addAction(fillQsoAct); //fillQsoAct->setMenuRole(QAction::ApplicationSpecificRole); connect(fillQsoAct, SIGNAL(triggered()), this, SLOT(fillQSOData())); fillQsoAct->setToolTip(tr("Go through the log reusing previous QSOs to fill missing information in other QSOs.")); fillDXCCAct = new QAction(tr("Fill in DXCC data"), this); toolMenu->addAction(fillDXCCAct); connect(fillDXCCAct, SIGNAL(triggered()), this, SLOT(slotFillEmptyDXCCInTheLog())); fillDXCCAct->setToolTip(tr("Go through the log filling QSOs without a DXCC defined.")); toolMenu->addSeparator(); qslToolMenu = toolMenu->addMenu(tr("QSL tools...")); //findQSO2QSLAct = new QAction(tr("&Find QSO to QSL"), this); //toolMenu->addAction(findQSO2QSLAct); //connect(findQSO2QSLAct, SIGNAL(triggered()), this, SLOT(slotSearchToolNeededQSLToSend())); //findQSO2QSLAct->setToolTip(tr("Shows QSOs for which you should send your QSL and request the DX QSL")); findQSO2QSLAct = new QAction(tr("&Find QSO to QSL"), this); qslToolMenu->addAction(findQSO2QSLAct); connect(findQSO2QSLAct, SIGNAL(triggered()), this, SLOT(slotSearchToolNeededQSLToSend())); findQSO2QSLAct->setToolTip(tr("Shows QSOs for which you should send your QSL and request the DX QSL.")); findRequestedQSLAct = new QAction(tr("Find My-QSLs pending to send"), this); qslToolMenu->addAction(findRequestedQSLAct); //findQSO2QSLAct->setMenuRole(QAction::ApplicationSpecificRole); connect(findRequestedQSLAct, SIGNAL(triggered()), this, SLOT(slotToolSearchRequestedQSLToSend())); findRequestedQSLAct->setToolTip(tr("Shows the QSOs with pending requests to send QSLs. You should keep this queue empty!")); findQSLPendingToReceiveAct = new QAction(tr("&Find DX-QSLs pending to receive"), this); qslToolMenu->addAction(findQSLPendingToReceiveAct); connect(findQSLPendingToReceiveAct, SIGNAL(triggered()), this, SLOT(slotToolSearchNeededQSLPendingToReceive())); findQSLPendingToReceiveAct->setToolTip(tr("Shows the DX-QSL that has been requested or QSLs has been sent with no answer.")); findQSLDXRequestedAct = new QAction(tr("&Find requested pending to receive"), this); qslToolMenu->addAction(findQSLDXRequestedAct); connect(findQSLDXRequestedAct, SIGNAL(triggered()), this, SLOT(slotToolSearchNeededQSLRequested())); findQSLDXRequestedAct->setToolTip(tr("Shows the DX-QSL that has been requested.")); toolMenu->addSeparator(); lotwToolMenu = toolMenu->addMenu(tr("LoTW tools...")); lotwMarkSentQueuedThisLogAct = new QAction(tr("Queue all QSL to be sent of this log"), this); lotwToolMenu->addAction(lotwMarkSentQueuedThisLogAct); connect(lotwMarkSentQueuedThisLogAct, SIGNAL(triggered()), this, SLOT(slotToolLoTWMarkAllQueuedThisLog())); lotwMarkSentQueuedThisLogAct->setToolTip(tr("Mark all non sent QSOs in this log as queued to be uploaded.")); lotwMarkSentQueuedAct = new QAction(tr("Queue all QSL to be sent"), this); lotwToolMenu ->addAction(lotwMarkSentQueuedAct); connect(lotwMarkSentQueuedAct, SIGNAL(triggered()), this, SLOT(slotToolLoTWMarkAllQueued())); lotwMarkSentQueuedAct->setToolTip(tr("Mark all non sent QSOs as queued to be uploaded.")); lotwToolMenu->addSeparator(); lotwMarkSentYesThisLogAct = new QAction(tr("Mark as sent all queued QSO of this log"), this); lotwToolMenu->addAction(lotwMarkSentYesThisLogAct); connect(lotwMarkSentYesThisLogAct, SIGNAL(triggered()), this, SLOT(slotToolLoTWMarkAllYesThisLog())); lotwMarkSentYesThisLogAct->setToolTip(tr("Mark all queued QSOs in this log as sent to LoTW.")); lotwMarkSentYesAct = new QAction(tr("Mark all queued QSO as sent"), this); lotwToolMenu ->addAction(lotwMarkSentYesAct); connect(lotwMarkSentYesAct, SIGNAL(triggered()), this, SLOT(slotToolLoTWMarkAllYes())); lotwMarkSentYesAct->setToolTip(tr("Mark all queued QSOs as sent to LoTW.")); toolMenu->addSeparator(); downloadCTYAct = new QAction (tr("&Update cty.csv"), this); toolMenu->addAction(downloadCTYAct); //downloadCTYAct->setMenuRole(QAction::ApplicationSpecificRole); connect(downloadCTYAct, SIGNAL(triggered()), this, SLOT(slotUpdateCTYDAT())); downloadCTYAct->setToolTip(tr("For updated DX-Entity data, update cty.csv.")); toolMenu->addSeparator(); setupMenu = menuBar()->addMenu(tr("&Setup")); setupAct = new QAction(tr("&Setup..."), this); setupMenu->addAction(setupAct); setupAct->setMenuRole(QAction::PreferencesRole); connect(setupAct, SIGNAL(triggered()), this, SLOT(slotSetup())); //TODO: To be added once the help dialog has been implemented helpMenu = menuBar()->addMenu(tr("&Help")); updateAct = new QAction(tr("Check updates..."), this); helpMenu->addAction(updateAct); updateAct->setMenuRole(QAction::ApplicationSpecificRole); connect(updateAct, SIGNAL(triggered()), this, SLOT(slotHelpCheckUpdatesAction())); aboutAct = new QAction(tr("&About..."), this); helpMenu->addAction(aboutAct); aboutAct->setMenuRole(QAction::AboutRole); connect(aboutAct, SIGNAL(triggered()), this, SLOT(slotHelpAboutAction())); aboutQtAct = new QAction(tr("About Qt..."), this); helpMenu->addAction(aboutQtAct); aboutQtAct->setMenuRole(QAction::AboutQtRole); connect(aboutQtAct, SIGNAL(triggered()), this, SLOT(slotAboutQt())); } void MainWindow::slotSearchToolNeededQSLToSend() { searchWidget->searchToolNeededQSLToSend(); } void MainWindow::slotToolSearchRequestedQSLToSend() { searchWidget->slotToolSearchRequestedQSLToSend(); } void MainWindow::slotToolSearchNeededQSLPendingToReceive() { searchWidget->slotToolSearchNeededQSLPendingToReceive(); } void MainWindow::slotToolSearchNeededQSLRequested() { searchWidget->slotToolSearchNeededQSLRequested(); } void MainWindow::slotToolLoTWMarkAllQueuedThisLog() { //qDebug() << "MainWindow::slotToolLoTWMarkAllQueuedThisLog" << endl; QString tdate = (dateEdit->date()).toString("yyyy/MM/dd"); if(dataProxy->lotwSentQueue(tdate, currentLog)) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setWindowTitle(tr("KLog LoTW")); msgBox.setText(tr("All pending QSO of this log has been marked as queued for LoTW!") + "\n\n" + tr("Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW.")); msgBox.exec(); } else { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(tr("KLog LoTW")); msgBox.setText(tr("There was a problem to mark all pending QSO of this log as queued for LoTW!") ); msgBox.exec(); } } void MainWindow::slotToolLoTWMarkAllQueued() { //qDebug() << "MainWindow::slotToolLoTWMarkAllQueued" << endl; QString tdate = (dateEdit->date()).toString("yyyy/MM/dd"); if (dataProxy->lotwSentQueue(tdate, -1)) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setWindowTitle(tr("KLog LoTW")); msgBox.setText(tr("All pending QSO has been marked as queued for LoTW!") + "\n\n" + tr("Now you can go to the File menu to export the LoTW ADIF file and upload it to LoTW.")); msgBox.exec(); } else { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(tr("KLog LoTW")); msgBox.setText(tr("There was a problem to mark all pending QSO of this log as queued for LoTW!") ); msgBox.exec(); } } QString MainWindow::selectStationCallsign() { QString stationCallToUse = QString(); QStringList stationCallSigns; stationCallSigns.clear(); stationCallSigns << "NONE"; stationCallSigns << dataProxy->getStationCallSignsFromLog(-1); //bool callsignTyped = false; if (stationCallSigns.length()>1) { QString msg = QString(tr("The log that you have selected contains more than just one station callsign.") + "\n\n" + tr("Please select the station callsing you want to mark as sent to LoTW:")); bool ok; stationCallToUse = QInputDialog::getItem(this, tr("Station Callsign:"), msg, stationCallSigns, 0, false, &ok); if (ok && !stationCallToUse.isEmpty()) { return stationCallToUse; } else { stationCallToUse = (QInputDialog::getText(this, tr("Define Station Callsign"), tr("You have selected no callsign. KLog will mark QSOs without a station callsign defined and those with the call you are entering here.") + "\n\n" + tr("Enter the station callsign to use for this log or leave it empty for QSO without station callsign defined:"), QLineEdit::Normal, "", &ok)).toUpper(); if (ok) { //callsignTyped = true; return stationCallToUse; } else { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); QString aux = QString(tr("No station callsign has been selected and therefore no log will be marked") ); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: // Ok was clicked //return ; break; default: // should never be reached break; } } } } return QString(); } void MainWindow::slotToolLoTWMarkAllYesThisLog() { //qDebug() << "MainWindow::slotToolLoTWMarkAllYesThisLog" << endl; QString tdate = (dateEdit->date()).toString("yyyy/MM/dd"); if(dataProxy->lotwSentYes(tdate, currentLog, "ALL")) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setWindowTitle(tr("KLog LoTW")); msgBox.setText(tr("All queued QSO of this log has been marked as sent for LoTW!") ); msgBox.exec(); } else { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(tr("KLog LoTW")); msgBox.setText(tr("There was a problem to mark all queued QSO of this log as sent for LoTW!") ); msgBox.exec(); } } void MainWindow::slotToolLoTWMarkAllYes() { //qDebug() << "MainWindow::slotToolLoTWMarkAllYes" << endl; QString stationCallToUse = selectStationCallsign(); QString tdate = (dateEdit->date()).toString("yyyy/MM/dd"); if (dataProxy->lotwSentYes(tdate, -1, stationCallToUse)) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setWindowTitle(tr("KLog LoTW")); msgBox.setText(tr("All queued QSO has been marked as sent to LoTW!") ); msgBox.exec(); } else { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(tr("KLog LoTW")); msgBox.setText(tr("There was a problem to mark all queued QSO of this log as sent to LoTW!") ); msgBox.exec(); } } void MainWindow::slotAboutQt() { //qDebug() << "MainWindow::slotAboutQt" << endl; QMessageBox::aboutQt(this,tr("About...")); } /* void MainWindow::slotHelpHelpAction() { //qDebug() << "MainWindow::slotHelpHelpAction" << endl; //helpHelpDialog->exec(); //aboutDialog->exec(); } */ void MainWindow::slotHelpAboutAction() { //qDebug() << "MainWindow::slotHelpAboutAction " << endl; // QMessageBox::about(this, tr("About KLog"), // tr("KLog " // "Find the last release at http://jaime.robles.es/klog.")); aboutDialog->exec(); //helpAboutDialog->exec(); } void MainWindow::slotHelpCheckUpdatesAction() { //qDebug() << "MainWindow::slotHelpCheckUpdatesAction" << endl; callingUpdate = true; softUpdate->addCall(stationQRZ); softUpdate->needToUpdate(true); //callingUpdate = false; } void MainWindow::slotShowSoftUpdateResults(const bool _b) { //qDebug() << "MainWindow::slotShowSoftUpdateResults: " << endl; if (_b == true) { //qDebug() << "MainWindow::slotShowSoftUpdateResults _b = TRUE " << endl; } else { //qDebug() << "MainWindow::slotShowSoftUpdateResults _b = FALSE " << endl; } if (callingUpdate == true) { if (_b == false) { //qDebug() << "MainWindow::slotShowSoftUpdateResults: UPDATE NOT NEEDED" << endl; QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setWindowTitle(tr("KLog update checking result")); msgBox.setText(tr("Congratulations!") + "\n\n" + tr("You already have the latest version.")); msgBox.exec(); } else { //qDebug() << "MainWindow::slotShowSoftUpdateResults: UPDATE NEEDED" << endl; } } callingUpdate = false; } void MainWindow::createMenusCQWW() { //qDebug() << "MainWindow::createMenusCQWW" << endl; /* logWinAct = new QAction(tr("&Log Window"), this); logWinAct->setCheckable(true); logWinAct->setShortcut(Qt::CTRL + Qt::Key_L); viewMenu->addAction(logWinAct); connect(logWinAct, SIGNAL(triggered()), this, SLOT(slotLogWinShow())); scoreWinAct = new QAction(tr("&Points Window"), this); scoreWinAct->setCheckable(true); scoreWinAct->setShortcut(Qt::CTRL + Qt::Key_P); viewMenu->addAction(scoreWinAct); connect(scoreWinAct, SIGNAL(triggered()), this, SLOT(slotScoreWinShow())); CabrilloExport = new QAction(tr("&Export to Cabrillo..."), this); toolMenu->addAction(CabrilloExport); connect(CabrilloExport, SIGNAL(triggered()), this, SLOT(slotCabrilloExport())); */ } void MainWindow::slotLogWinShow() { //qDebug() << "MainWindow::slotLogWinShow: " << endl; if (!(logWindow->isVisible()) ) { logWinAct->setChecked ( true ); logWindow->show(); }else { logWinAct->setChecked ( false ); logWindow->hide(); } } void MainWindow::slotScoreWinShow() { //qDebug() << "MainWindow::slotScoreWinShow: " << endl; if (!(scoreWindow->isVisible()) ) { scoreWinAct->setChecked ( true ); scoreWindow->show(); }else { scoreWinAct->setChecked ( false ); scoreWindow->hide(); } } void MainWindow::slotSetup(const int _page) { //qDebug() << "MainWindow::slotSetup - 01" << endl; itIsANewversion = false; if (!needToEnd) { setupDialog->setData(configFileName, softwareVersion, _page, !configured); setupDialog->exec(); //qDebug() << "MainWindow::slotSetup - JUst after setupDialog->exec" << endl; if (needToEnd) { return; } else { //qDebug() << "MainWindow::slotSetup - Just before readConfigData" << endl; readConfigData(); //qDebug() << "MainWindow::slotSetup - Just after readConfigData" << endl; } //qDebug() << "MainWindow::MainWindow: logmodel to be created-2" << endl; logWindow->createlogPanel(currentLog); //qDebug() << "MainWindow::MainWindow: logmodel has been created-2" << endl; } defineStationCallsign(); //qDebug() << "MainWindow::MainWindow: before db->reConnect" << endl; dataProxy->reconnectDB(); //db->reConnect(); //qDebug() << "MainWindow::MainWindow: after db->reConnect" << endl; } void MainWindow::openFile() { int lastLog = currentLog; slotSetup(6); if (lastLog == currentLog) { // It seems that the user didn't really want a new log return; } logWindow->refresh(); } bool MainWindow::saveFile(const QString _fileName) { //qDebug() << "MainWindow::saveFile: " << _fileName << endl; QString fileName = _fileName; if (fileName.endsWith(".adi", Qt::CaseInsensitive)) { //qDebug() << "MainWindow::saveFile: 1" << endl; needToSave = !(filemanager->adifLogExport(fileName, currentLog)); } else if (fileName.endsWith(".log", Qt::CaseInsensitive)) { //qDebug() << "MainWindow::saveFile: 2" << endl; needToSave = !(filemanager->cabrilloLogExport(fileName, contestMode, currentLog)); //contest->saveFileToSend(fileName); } else { //qDebug() << "MainWindow::saveFile: 3" << endl; //TODO: Message "You must select a proper file format QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("Nothing has been saved. You have to select a valid file type.")); msgBox.exec(); return false; } //qDebug() << "MainWindow::saveFile: 4" << endl; return needToSave; } bool MainWindow::saveFileAs() { //qDebug() << "MainWindow::saveFileAs" << endl; //QFileDialog dialog(this); QStringList filters; filters << "ADIF files (*.adi *.adif)" << "Cabrillo files (*.log)" << "Any files (*)"; // dialog.setNameFilters(filters); /* QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "/home/jana/untitled.png", tr("Images (*.png *.xpm *.jpg)")); */ // klogDir+"/"+defaultADIFLogFile, QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), util->getHomeDir(), tr("ADIF file") + "(*.adi *.adif);;" + tr("Cabrillo files") + "(*.log);;" + tr("Any file") + "(*.*)"); if ( (fileName.endsWith(".adi", Qt::CaseInsensitive)) || (fileName.endsWith(".log", Qt::CaseInsensitive)) ) { useDefaultLogFileName = true; defaultADIFLogFile = fileName; return saveFile(fileName); } else if (fileName.length()==0) { // The user clicked on cancel, no msg to be shown return false; } else { //TODO: Message "You must select a proper file format QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("Nothing has been saved. You have to select a valid file type.")); msgBox.exec(); return false; } return false; } void MainWindow::newFile() { //qDebug() << "MainWindow::newFile" << endl; //TODO: Ask for a confirmation to the user //TODO: Clean the DB & query.exec("VACUUM"); int lastLog = currentLog; slotSetup(6); if (lastLog == currentLog) { // It seems that the user didn't really want a new log return; } points = 0; multipliers = 0; qsoPoints = 0; qsoMultiplier = 0; logWindow->refresh(); slotClearButtonClicked(); searchWidget->clear(); //searchResultsTreeWidget->clear(); /* if (dataProxy->clearLog()) { } else { //TODO: An error to create a new file has ocurred. Manage it! } */ } bool MainWindow::slotOpenKLogFolder() { //qDebug() << "MainWindow::slotOpenKLogFolder: " << configFileName << endl; //configFileName = klogDir+"/klogrc.cfg"; QString _aux = "" ; QString _text = tr("You can find the KLog data folder here: ") + _aux; /* int ret = QMessageBox::information(this, tr("KLog"), _text, QMessageBox::Ok, QMessageBox::Ok); */ QMessageBox::information(this, tr("KLog"), _text, QMessageBox::Ok, QMessageBox::Ok); //qDebug() << "MainWindow::slotOpenKLogFolder: END" << endl; return true; } void MainWindow::slotUpdateStatusBar(const QString statusm) { //qDebug() << "MainWindow::slotUpdateStatusBar: " << statusm << endl; statusBar()->showMessage(statusm, 2000); } bool MainWindow::readCtyFile() { return false; } void MainWindow::slotDoubleClickLog(const int _qsoID) { //qDebug() << "MainWindow::slotDoubleClickLog: QSOid: " << QString::number(_qsoID) << endl; //int row = _qsoID.row(); //qsoToEdit((logModel->index(row, 0)).data(0).toInt()); qsoToEdit(_qsoID); //TODO: To be added to the logWindow and create an action that emist the QSO id to be edited } /* void MainWindow::slotDoubleClickSearch(QTreeWidgetItem * item, int) { //qDebug() << "MainWindow::slotDoubleClickSearch" << endl; int number = -1; if (item){ if (stationCallSignShownInSearch) { number = (item->text(7)).toInt(); } else { number = (item->text(6)).toInt(); } qsoToEdit(number); } else {} } */ /* void MainWindow::slotRighButtonSearch(const QPoint& pos) { //qDebug() << "MainWindow::slotRighButtonSearch" << endl; QTreeWidgetItem *item = searchResultsTreeWidget->itemAt(pos); int _qsoID = 0; if (item) { //qDebug() << "MainWindow::slotRighButtonSearch ITEM=true" << endl; // 6 is the column in the searchResultsTreeWidget where the id is saved if (stationCallSignShownInSearch) { //qDebug() << "MainWindow::slotRighButtonSearch stationCallSignShownInSearch = true" << endl; _qsoID = ((item)->text(7)).toInt(); //qDebug() << "MainWindow::slotRighButtonSearch QSO1: " << QString::number(_qsoID) << endl; } else { //qDebug() << "MainWindow::slotRighButtonSearch stationCallSignShownInSearch = false" << endl; _qsoID = ((item)->text(6)).toInt(); //qDebug() << "MainWindow::slotRighButtonSearch QSO2: " << QString::number(_qsoID) << endl; } //qDebug() << "MainWindow::slotRighButtonSearch QSO: " << QString::number(_qsoID) << endl; showMenuRightButtonSearchCreateActions(); //qDebug() << "MainWindow::slotRighButtonSearch -05" << endl; righButtonSearchMenu(_qsoID); //qDebug() << "MainWindow::slotRighButtonSearch -06" << endl; }else { //qDebug() << "MainWindow::slotRighButtonSearch ITEM=false" << endl; return; } //qDebug() << "MainWindow::slotRighButtonSearch: " << QString::number(_qsoID) << endl; } */ /* void MainWindow::righButtonSearchMenu(const int trow) { //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: " << QString::number(trow) << endl; bool qslReceived = logWindow->isQSLReceived(trow); bool qslSent = logWindow->isQSLSent(trow); QMenu menu(this); menu.addAction(delQSOFromSearchAct); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -03" << endl; delQSOFromSearchAct->setData(trow); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -04" << endl; menu.addAction(qsoToEditFromSearchAct); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -05" << endl; qsoToEditFromSearchAct->setData(trow); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -06" << endl; menu.addSeparator(); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -07" << endl; if (qslSent) { //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSLSent" << endl; } else { //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Sent" << endl; QMenu *menuSentQsl = menu.addMenu(tr("QSL Send")); menuSentQsl->addAction(qslSentViaBureauFromSearchAct); menuSentQsl->addAction(qslSentViaDirectFromSearchAct); menuSentQsl->addAction(qslSentRequestedAct); if (!qslReceived) { menuSentQsl->addAction(qslSentViaBureauMarkRcvReqFromSearchAct); menuSentQsl->addAction(qslSentViaDirectMarkRcvReqFromSearchAct); qslSentViaBureauMarkRcvReqFromSearchAct->setData(trow); qslSentViaDirectMarkRcvReqFromSearchAct->setData(trow); } qslSentViaBureauFromSearchAct->setData(trow); qslSentViaDirectFromSearchAct->setData(trow); qslSentRequestedAct->setData(trow); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -end qsl not sent" << endl; } if (qslReceived) { //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSLRec" << endl; } else { //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec" << endl; QMenu *menuRecQsl = menu.addMenu(tr("QSL Rcvd")); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 01" << endl; menuRecQsl->addAction(qslRecViaBureauFromSearchAct); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 02" << endl; menuRecQsl->addAction(qslRecViaBureauMarkReqFromSearchAct); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 03" << endl; menuRecQsl->addAction(qslRecViaDirectFromSearchAct); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 04" << endl; menuRecQsl->addAction(qslRecViaDirectMarkReqFromSearchAct); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 05" << endl; menuRecQsl->addAction(qslRecRequestedAct); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 06" << endl; qslRecViaBureauFromSearchAct->setData(trow); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 07" << endl; qslRecViaBureauMarkReqFromSearchAct->setData(trow); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 08" << endl; qslRecViaDirectFromSearchAct->setData(trow); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 09" << endl; qslRecViaDirectMarkReqFromSearchAct->setData(trow); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -QSL Not Rec - 10" << endl; qslRecRequestedAct->setData(trow); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -end qsl not rec" << endl; } //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -end qsl" << endl; menu.exec(QCursor::pos()); //qDebug() << "MainWindow::slotshowRighButtonSearchMenu: -END" << endl; } void MainWindow::showMenuRightButtonSearchCreateActions() { //qDebug() << "MainWindow::showMenuRightButtonSearchCreateActions" << endl; delQSOFromSearchAct = new QAction(tr("&Delete"), this); delQSOFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_D); delQSOFromSearchAct->setStatusTip(tr("Delete a QSO")); connect(delQSOFromSearchAct, SIGNAL(triggered()), this, SLOT(slotQsoDeleteFromSearch())); qsoToEditFromSearchAct = new QAction(tr("&Edit QSO"), this); qsoToEditFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_E); qsoToEditFromSearchAct->setStatusTip(tr("Edit this QSO")); connect(qsoToEditFromSearchAct, SIGNAL(triggered()), this, SLOT(slotQSOToEditFromSearch())); qslSentViaBureauFromSearchAct = new QAction(tr("Via &bureau"), this); qslSentViaBureauFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_B); qslSentViaBureauFromSearchAct->setStatusTip(tr("Send this QSL via bureau")); connect(qslSentViaBureauFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaBureauFromSearch() )); qslSentViaDirectFromSearchAct = new QAction(tr("D&irect"), this); qslSentViaDirectFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_I); qslSentViaDirectFromSearchAct->setStatusTip(tr("Send this QSL via direct")); connect(qslSentViaDirectFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaDirectFromSearch() )); qslSentRequestedAct = new QAction(tr("&Request my QSL"), this); qslSentRequestedAct->setShortcut(Qt::CTRL + Qt::Key_R); qslSentRequestedAct->setStatusTip(tr("Mark my QSL as requested")); connect(qslSentRequestedAct, SIGNAL(triggered()), this, SLOT( slotQSLSentMarkAsRequested() )); qslSentViaDirectMarkRcvReqFromSearchAct = new QAction(tr("Via Direct && mark DX QSL as requested"), this); qslSentViaDirectMarkRcvReqFromSearchAct->setStatusTip(tr("Send this QSL via direct & mark DX QSL as requested")); connect(qslSentViaDirectMarkRcvReqFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaDirectMarkDXReqFromSearch() )); qslSentViaBureauMarkRcvReqFromSearchAct = new QAction(tr("Via Bureau && mark DX QSL as requested"), this); qslSentViaBureauMarkRcvReqFromSearchAct->setStatusTip(tr("Send this QSL via bureau & mark DX QSL as requested")); connect(qslSentViaBureauMarkRcvReqFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLSentViaBureuMarkDXReqFromSearch() )); qslRecRequestedAct = new QAction(tr("&Request the QSL"), this); qslRecRequestedAct->setStatusTip(tr("Mark the QSL as requested")); connect(qslRecRequestedAct, SIGNAL(triggered()), this, SLOT( slotQSLRecMarkAsRequested() )); qslRecViaBureauMarkReqFromSearchAct = new QAction(tr("Via bureau && mark my QSL as requested"), this); qslRecViaBureauMarkReqFromSearchAct->setStatusTip(tr("QSL received via bureau & mark my QSL as requested")); connect(qslRecViaBureauMarkReqFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaBureauMarkReqFromSearch() )); qslRecViaBureauFromSearchAct = new QAction(tr("Via bureau"), this); qslRecViaBureauFromSearchAct->setStatusTip(tr("QSL received via bureau")); //qslRecViaBureauFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_R); connect(qslRecViaBureauFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaBureauFromSearch() )); qslRecViaDirectMarkReqFromSearchAct = new QAction(tr("Direc&t && mark as my QSL requested"), this); qslRecViaDirectMarkReqFromSearchAct->setStatusTip(tr("QSL received via direct & mark my QSL as requested")); connect(qslRecViaDirectMarkReqFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaDirectMarkReqFromSearch() )); qslRecViaDirectFromSearchAct = new QAction(tr("Direc&t"), this); qslRecViaBureauFromSearchAct->setStatusTip(tr("QSL received via direct")); //qslRecViaDirectFromSearchAct->setShortcut(Qt::CTRL + Qt::Key_T); connect(qslRecViaDirectFromSearchAct, SIGNAL(triggered()), this, SLOT( slotQSLRecViaDirectFromSearch() )); } void MainWindow::slotQSLSentViaBureuMarkDXReqFromSearch() { //qDebug() << "slotQSLSentViaBureuMarkDXReqFromSearch: " << (qslSentViaBureauMarkRcvReqFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaBureauMarkRcvReqFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslSentViaBureauMarkRcvReqFromSearchAct->data()).toInt(); dataProxy->qslSentViaBureau(_qsoId, (dateTime->currentDateTime()).toString("yyyy/MM/dd")); dataProxy->qslRecAsRequested(_qsoId, (dateTime->currentDateTime()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } // Mark Sent, Bureau, date, update log. } void MainWindow::slotQSLSentViaDirectMarkDXReqFromSearch() { //qDebug() << "slotQSLSentViaDirectMarkDXReqFromSearch: " << (qslSentViaDirectMarkRcvReqFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaDirectMarkRcvReqFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslSentViaDirectMarkRcvReqFromSearchAct->data()).toInt(); dataProxy->qslSentViaDirect(_qsoId, (dateTime->currentDateTime()).toString("yyyy/MM/dd")); dataProxy->qslRecAsRequested(_qsoId, (dateTime->currentDateTime()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } // Mark Sent, Bureau, date, update log. } void MainWindow::slotQSLSentViaBureauFromSearch() { // //qDebug() << "MainWindow::slotQSLSentViaBureauFromSearch: " << (qslSentViaBureauFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaBureauFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslSentViaBureauFromSearchAct->data()).toInt(); logWindow->qslSentViaBureau(_qsoId); //qslSentViaBureau(_qsoId); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void MainWindow::slotQSLSentViaDirectFromSearch() { //qDebug() << "MainWindow::slotQSLSentViaDirectFromSearch: " << (qslSentViaDirectFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslSentViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = ((qslSentViaDirectFromSearchAct->data()).toInt()); dataProxy->qslSentViaDirect(_qsoId, (dateTime->currentDateTime()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } //qslSentViaDirect(_qsoId); } void MainWindow::slotQSLSentMarkAsRequested() { // bool qslSentAsRequested(const int _qsoId, const QString _updateDate); int _qsoId = (qslSentRequestedAct->data()).toInt(); dataProxy->qslSentAsRequested(_qsoId, (dateTime->currentDateTime()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void MainWindow::slotQSLRecMarkAsRequested() { int _qsoId = (qslRecRequestedAct->data()).toInt(); dataProxy->qslRecAsRequested(_qsoId, (dateTime->currentDateTime()).toString("yyyy/MM/dd")); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void MainWindow::slotQSLRecViaBureauFromSearch() { //qDebug() << "MainWindow::slotQSLRecViaBureauFromLog: " << "- Id = " << QString::number( ((logModel->index( ( (qslRecViaBureauFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslRecViaBureauFromSearchAct->data()).toInt(); logWindow->qslRecViaBureau(_qsoId); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void MainWindow::slotQSLRecViaBureauMarkReqFromSearch() { //qDebug() << "MainWindow::slotQSLRecViaBureauMarkReqFromLog: " << "- Id = " << QString::number( ((logModel->index( ( (qslRecViaBureauFromSearchAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslRecViaBureauMarkReqFromSearchAct->data()).toInt(); qslRecViaBureauMarkReq(_qsoId); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } } void MainWindow::slotQSLRecViaDirectFromSearch() { //qDebug() << "MainWindow::slotQSLRecViaDirectFromLog: " << (qslRecViaDirectFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslRecViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslRecViaDirectFromSearchAct->data()).toInt(); logWindow->qslRecViaDirect(_qsoId); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } // Mark Sent, Bureau, date, update log. } void MainWindow::slotQSLRecViaDirectMarkReqFromSearch() { //qDebug() << "MainWindow::slotQSLRecViaDirectFromLog: " << (qslRecViaDirectFromSearchAct->data()).toString() << " - Id = " << QString::number( ((logModel->index( ( (qslRecViaDirectFromLogAct->data()).toInt() ) , 0)).data(0).toInt()) ) << endl; int _qsoId = (qslRecViaDirectMarkReqFromSearchAct->data()).toInt(); qslRecViaDirectMarkReq(_qsoId); if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } // Mark Sent, Bureau, date, update log. } void MainWindow::qslRecViaBureauMarkReq(const int _qsoId) { // //qDebug() << "MainWindow::qslRecViaBureau: " << QString::number(_qsoId) << "/" << (dateTime->currentDateTime()).toString("yyyy/MM/dd") << endl; //setAwards(const int _dxcc, const int _waz, const int _band, const int _mode, const int _workedOrConfirmed); dataProxy->qslRecViaBureau(_qsoId, (dateTime->currentDateTime()).toString("yyyy/MM/dd"), true); awards->setAwards(_qsoId); //Update the DXCC award status logWindow->refresh(); showAwards(); } void MainWindow::qslRecViaDirectMarkReq(const int _qsoId) { //qDebug() << "MainWindow::qslRecViaDirect: " << QString::number(_qsoId) << endl; dataProxy->qslRecViaDirect(_qsoId, (dateTime->currentDateTime()).toString("yyyy/MM/dd"), true); awards->setAwards(_qsoId); //setAwards(const int _dxcc, const int _waz, const int _band, const int _mode, const int _workedOrConfirmed); logWindow->refresh(); showAwards(); } */ /* void MainWindow::slotQSOToEditFromSearch() { //qDebug() << "slotQSOToEditFromSearch: " << (qsoToEditFromSearchAct->data()).toString() << endl; qsoToEdit((qsoToEditFromSearchAct->data()).toInt()); } void MainWindow::slotQsoDeleteFromSearch() { //qDebug() << "MainWindow::slotQsoDeleteFromSearch: " << (delQSOFromSearchAct->data()).toString() << endl; int QSOid = (delQSOFromSearchAct->data()).toInt(); //int x = -1; QString _qrz = dataProxy->getCallFromId(QSOid); if (_qrz.length()>=3) { QString message = QString(tr("You have requested to delete the QSO with: %1")).arg(_qrz); QMessageBox msgBox; msgBox.setIcon(QMessageBox::Question); msgBox.setText(message); msgBox.setInformativeText(tr("Are you sure?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: elogClublog->deleteQSO(dataProxy->getClubLogRealTimeFromId(QSOid)); if(dataProxy->deleteQSO(QSOid)) { if(qslingNeeded) { searchToolNeededQSLToSend(); } else { slotSearchBoxTextChanged(); } slotShowAwards(); //dxccStatusWidget->refresh(); //awards->recalculateAwards(); //logWindow->refresh(); //showAwards(); } else { //TODO: The QSO could not be removed... } break; case QMessageBox::No: // No was clicked break; default: // should never be reached break; } } else { // TODO: The QSO to be removed was not found in the log } } */ void MainWindow::keyPressEvent(QKeyEvent *event){ /* if (!isStarted || isPaused || curPiece.shape() == NoShape) { QFrame::keyPressEvent(event); return; } */ switch (event->key()) { case Qt::Key_Return: // ENTER PRESSED //slotQRZReturnPressed(); break; case Qt::Key_Enter: // ENTER PRESSED // slotQRZReturnPressed(); break; default: //QFrame::keyPressEvent(event); ; } } void MainWindow::checkIfWorkedB4(const QString _qrz) { //qDebug() << "MainWindow::checkIfWorkedB4: " << _qrz << endl; int i = dataProxy->isWorkedB4(_qrz, currentLog); // Gets the QSO id if worked before if (contestMode == "DX") {} else if (contestMode == "CQ-WW-SSB") { if (i>=0) { qrzgroupBox->setTitle(tr("DUPE")); } else { qrzgroupBox->setTitle(tr("QRZ")); } } else {} } void MainWindow::readConfigData() { //qDebug() << "MainWindow::readConfigData - 01" << endl; if (needToEnd) { return; } QFile file(configFileName); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){ //qDebug() << "MainWindow::readConfigData: File not found" << configFileName << endl; if (configured) { //qDebug() << "MainWindow::readConfigData: configured = true" << endl; } else { //qDebug() << "MainWindow::readConfigDataw: configured = false" << endl; } slotSetup(); return; } while (!file.atEnd()) { QByteArray line = file.readLine(); processConfigLine(line); } //qDebug() << "MainWindow::readConfigData: After processConfigLine " << endl; defineStationCallsign(); //qDebug() << "MainWindow::readConfigData: " << defaultADIFLogFile << endl; if ((useDefaultLogFileName) && (defaultADIFLogFile.length()>0)) { useDefaultLogFileName = true; } else { useDefaultLogFileName = false; } infoWidget->setImperialSystem(imperialSystem); /* if (imperialSystem) { distShortLabelN->setText(tr("Miles")); distLongLabelN->setText(tr("Miles")); //distShortLabel->setText( QString::number( Km2Mile(imperialSystem, (distShortLabel->text()).toInt() )) ); //distLongLabel->setText( QString::number(Km2Mile(imperialSystem, (distLongLabel->text()).toInt()) ) ); } else { distShortLabelN->setText(tr("Km")); distLongLabelN->setText(tr("Km")); } */ infoLabel2->setText(world->getEntityName(currentEntity)); infoWidget->showEntityInfo(currentEntity); //lastPower = myPower; //lastOperatorQRZ = operatorQRZ; //lastStationQRZ = stationQRZ; //lastMyLocator = myLocator; configured = true; awards->setColors (newOneColor.name(), neededColor.name(), workedColor.name(), confirmedColor.name(), defaultColor.name()); dxClusterWidget->setColors (newOneColor.name(), neededColor.name(), workedColor.name(), confirmedColor.name(), defaultColor.name()); dxClusterWidget->setDXClusterSpotConfig(dxClusterShowHF, dxClusterShowVHF, dxClusterShowWARC, dxClusterShowWorked, dxClusterShowConfirmed, dxClusterShowAnn, dxClusterShowWWV, dxClusterShowWCY ); dxClusterWidget->setMyQRZ(stationQRZ); initialContestModeConfiguration(); if (upAndRunning) { // Next actions will not be executed in the first run slotClearButtonClicked(); //createSearchResultsPanel(); } // I need to init the CLUBLOG if (clublogActive) { elogClublog->setCredentials(clublogUser, clublogEmail, clublogPass, false); } else { } //qDebug() << "MainWindow::readConfigData: calling checkIfNewBandOrMode" << endl; checkIfNewBandOrMode(); //qDebug() << "MainWindow::readConfigData: 100" << endl; util->setVersion(softwareVersion); //qDebug() << "MainWindow::readConfigData: 101" << endl; searchWidget->setVersion(softwareVersion); //qDebug() << "MainWindow::readConfigData: 102" << endl; searchWidget->setCurrentLog(currentLog); //qDebug() << "MainWindow::readConfigData: 103" << endl; infoWidget->setCurrentLog(currentLog); //qDebug() << "MainWindow::readConfigData: 104" << endl; searchWidget->setColors (newOneColor.name(), neededColor.name(), workedColor.name(), confirmedColor.name(), defaultColor.name()); infoWidget->setColors(newOneColor.name(), neededColor.name(), workedColor.name(), confirmedColor.name(), defaultColor.name()); //qDebug() << "MainWindow::readConfigData - END" << endl; } bool MainWindow::processConfigLine(const QString _line){ //qDebug() << "MainWindow::processConfigLine: " << _line << endl; int _logWithMoreQSOs = 0; // At the end, if the this variable is >0 the Selectedlog will have to be changed in the file. QString line = _line.simplified(); //line.simplified(); QString aux; QStringList values = line.split("=", QString::SkipEmptyParts); if (line.startsWith('#')){ //qDebug() << "MainWindow::processConfigLine: notes Line!" << endl; return true; } if (!( (line.contains('=')) && (line.contains(';')))){ //qDebug() << "MainWindow::processConfigLine: Wrong Line!" << endl; return false; } QString field = (values.at(0)).toUpper(); QString value = values.at(1); int endValue = value.indexOf(';'); if (endValue>-1){ value = value.left(value.length() - (value.length() - endValue)); } if (field == "CALLSIGN"){ mainQRZ = value; }else if (field=="CQZ"){ my_CQz = value.toInt(); }else if (field=="ITUZ"){ my_ITUz = value.toInt(); }else if (field=="CONTEST"){ //qDebug() << "MainWindow::processConfigLine: CONTEST: " << endl; contestMode = value; }else if (field=="MODES"){ //qDebug() << "MainWindow::processConfigLine: modes1: " << value << endl; readActiveModes(value.split(", ", QString::SkipEmptyParts)); //qDebug() << "MainWindow::processConfigLine: modes2: " << value << endl; }else if (field=="BANDS"){ //qDebug() << "MainWindow::processConfigLine: BANDS: " << value << endl; readActiveBands(value.split(", ", QString::SkipEmptyParts)); }else if (field=="REALTIME"){ //qDebug() << "MainWindow::processConfigLine: REALTIME: " << value.toUpper() << endl; realTime = util->trueOrFalse(value); } else if (field=="INMEMORY") { //qDebug() << "MainWindow::processConfigLine: INMEMORY: " << value.toUpper() << endl; DBinMemory = util->trueOrFalse(value); } else if (field =="DXCLUSTERSERVERTOUSE"){ aux = value; //dxfun.com:8000 if (aux.contains(':')) { dxclusterServerToConnect = (aux.split(':', QString::SkipEmptyParts)).at(0); dxclusterServerPort = ((aux.split(':', QString::SkipEmptyParts)).at(1)).toInt(); } if ((dxclusterServerToConnect.length()< 3) || (dxclusterServerPort <= 0)) { dxclusterServerToConnect = "dxfun.com"; dxclusterServerPort = 8000; } dxClusterWidget->setDXClusterServer(dxclusterServerToConnect, dxclusterServerPort); } else if(field=="POWER") { if (value.toDouble()>0.0) { myPower = value.toDouble(); } } else if (field=="USEDEFAULTNAME") { useDefaultLogFileName = util->trueOrFalse(value); } else if (field=="IMPERIALSYSTEM") { imperialSystem = util->trueOrFalse(value); } else if (field=="SENDQSLWHENREC") { sendQSLWhenRec = util->trueOrFalse(value); } else if (field=="SHOWCALLSIGNINSEARCH") { searchWidget->setShowCallInSearch(util->trueOrFalse(value)); //stationCallSignShownInSearch = util->trueOrFalse(value); } else if (field=="CHECKNEWVERSIONS"){ checkNewVersions = util->trueOrFalse(value); } else if (field=="PROVIDEINFO"){ reportInfo = util->trueOrFalse(value); } else if (field=="ALWAYSADIF") { alwaysADIF = util->trueOrFalse(value); } else if (field=="UTCTIME") { //qDebug() << "MainWindow::processConfigLine: UTCTIME: " << value.toUpper() <trueOrFalse(value); } else if (field=="KEEPMYDATA") { keepMyData = util->trueOrFalse(value); } else if (field=="COMPLETEWITHPREVIOUS") { completeWithPrevious = util->trueOrFalse(value); } else if (field=="DXCLUSTERSHOWHF") { dxClusterShowHF = util->trueOrFalse(value); } else if (field=="DXCLUSTERSHOWVHF") { dxClusterShowVHF = util->trueOrFalse(value); } else if (field=="DXCLUSTERSHOWWARC") { dxClusterShowWARC = util->trueOrFalse(value); } else if (field=="DXCLUSTERSHOWWORKED") { dxClusterShowWorked = util->trueOrFalse(value); } else if (field=="DXCLUSTERSHOWCONFIRMED") { dxClusterShowConfirmed = util->trueOrFalse(value); } else if (field=="DXCLUSTERSHOWANN") { dxClusterShowAnn = util->trueOrFalse(value); } else if (field=="DXCLUSTERSHOWWWV") { dxClusterShowWWV = util->trueOrFalse(value); } else if (field=="DXCLUSTERSHOWWCY") { dxClusterShowWCY = util->trueOrFalse(value); } else if (field=="DEFAULTADIFFILE") { defaultADIFLogFile = value.toLower(); //qDebug() << "MainWindow::processConfigLine: " << defaultADIFLogFile << endl; } else if (field=="STATIONLOCATOR") { if ( locator->isValidLocator(value) ) { myLocator = value.toUpper(); } } else if(field=="NEWONECOLOR") { newOneColor.setNamedColor(value); } else if(field=="NEEDEDCOLOR") { neededColor.setNamedColor(value); } else if(field=="WORKEDCOLOR") { workedColor.setNamedColor(value); } else if(field=="CONFIRMEDCOLOR") { confirmedColor.setNamedColor(value); } else if(field=="DEFAULTCOLOR") { defaultColor.setNamedColor(value); } else if(field=="SELECTEDLOG") { currentLog = value.toInt(); //qDebug() << "MainWindow::processConfigLine: currentLog - SelectedLog: " << QString::number(currentLog) << endl; if ( ((dataProxy->doesThisLogExist(currentLog)) && (dataProxy->getHowManyQSOInLog(currentLog) > 0)) ) { //qDebug() << "MainWindow::processConfigLine: currentLog - Log with QSO - SelectedLog: " << QString::number(currentLog) << endl; } else { int _howManyQSOMax = -1; // NUmber of QSO of the log with more QSO int _howManyQSOMaxT = 0; // Number of QSO in ine specific log QStringList logs = QStringList(); //qDebug() << "MainWindow::processConfigLine: currentLog - Log without QSO - SelectedLog: " << QString::number(currentLog) << endl; QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); QString aux = tr("The selected log is not existing or it is still empty.") + "\n\n" + tr("Click Yes and KLog will open an empty log.") + "\n" + tr("Click No and KLog will select another log with data.") + "\n\n" + tr("You can modify the config file accordingly, if needed."); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: break; case QMessageBox::No: logs << dataProxy->getListOfManagedLogs(); //qDebug() << "MainWindow::processConfigLine: logs: " << QString::number(logs.size()) << endl; for (int i = 0;igetHowManyQSOInLog(i); //qDebug() << "MainWindow::processConfigLine: SelectedLog-x: " << QString::number(i) << " - QSOs: " << QString::number(_howManyQSOMaxT) << endl; if (_howManyQSOMax < _howManyQSOMaxT) { //qDebug() << "MainWindow::processConfigLine: Found log with more QSO: " << logs.at(i) << endl; _howManyQSOMax = _howManyQSOMaxT; _logWithMoreQSOs = (logs.at(i)).toInt(); } } if (_logWithMoreQSOs>0) { currentLog = _logWithMoreQSOs; filemanager->modifySetupFile(configFileName, "SelectedLog", QString::number(currentLog)); } else { msgBox.setIcon(QMessageBox::Critical); QString aux = tr("It seems that there are no QSO in the database.") + "\n\n" + tr("If you are sure that the database contains QSOs and KLog is not able to find them, please contact the developers (see About KLog) for help."); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: break; default: // should never be reached break; } } break; default: // should never be reached break; } } dxClusterWidget->setCurrentLog(currentLog); dxccStatusWidget->setCurrentLog(currentLog); //qDebug() << "MainWindow::processConfigLine: currentLog: " << value << endl; } else if(field=="CLUBLOGACTIVE") { //qDebug() << "MainWindow::processConfigLine: clublogActive: " << value << endl; clublogActive = util->trueOrFalse(value); } else if(field=="CLUBLOGREALTIME") { //qDebug() << "MainWindow::processConfigLine: clublogRealTime: " << value << endl; clublogRealTime = util->trueOrFalse(value); } else if(field=="CLUBLOGCALL") { clublogUser = value; } else if(field=="CLUBLOGPASS") { clublogPass = value; } else if(field=="CLUBLOGEMAIL") { clublogEmail = value; } else if(field=="VERSION") { if (softwareVersion!=value) { itIsANewversion = true; } } else { //qDebug() << "MainWindow::processConfigLine: NONE: " << endl; } // Lines are: Option = value; return true; } /********************************************************************* ********************************************************************** ********************************************************************** ********************************************************************** ********************************************************************** ********************************************************************** ********************************************************************** **********************************************************************/ void MainWindow::checkIfNewBandOrMode() {//Checks the log to see if there is a QSO with a band/mode //that is not currently selected as active //qDebug() << "MainWindow::checkIfNewBandOrMode" << endl; setupDialog->checkIfNewBandOrMode(); // Update the Setup dialog with new bands or modes //qDebug() << "MainWindow::checkIfNewBandOrMode after setupDialog" << endl; //qDebug() << "MainWindow::checkIfNewBandOrMode - bands: " << endl; //util->printQString(bands); //qDebug() << "MainWindow::checkIfNewBandOrMode - modes: " << endl; //util->printQString(modes); QStringList bandsInLog = dataProxy->getBandsInLog(currentLog); //qDebug() << "MainWindow::checkIfNewBandOrMode - bandsInLog-1: " << endl; //util->printQString(bandsInLog); //qDebug() << "MainWindow::checkIfNewBandOrMode - bandsInLog-2: " << endl; QStringList modesInLog = dataProxy->getModesInLog(currentLog); //qDebug() << "MainWindow::checkIfNewBandOrMode - modesInLog: " << endl; //util->printQString(modesInLog); QStringList qsTemp; qsTemp.clear(); bands << bandsInLog; qsTemp << dataProxy->sortBandNamesBottonUp(bands); bands.clear(); bands << qsTemp; modes << modesInLog; modes.removeDuplicates(); //if (modesInLog.length()>0) //{ // modes.clear(); // modes << modesInLog; //} /* if (bands.length()<1) { //Default band/modes bands << "10M" << "15M" << "20M" << "40M" << "80M" << "160M"; modes << "SSB" << "CW" << "RTTY"; } */ //qDebug() << "MainWindow::checkIfNewBandOrMode - bands -" << QString::number(bands.length()) << endl; bandComboBox->clear(); bandComboBox->addItems(bands); satTabWidget->addBands(bands); //qDebug() << "MainWindow::checkIfNewBandOrMode - modes -" << QString::number(modes.length()) << endl; modeComboBox->clear(); //qDebug() << "MainWindow::checkIfNewBandOrMode - 1-" << QString::number(modeComboBox->count()) << endl; modeComboBox->addItems(modes); //qDebug() << "MainWindow::checkIfNewBandOrMode - 2-" << QString::number(modeComboBox->count()) << endl; //qDebug() << "MainWindow::checkIfNewBandOrMode - CurrentBand/CurrentBandShown: " << QString::number(currentBand) << "/" << QString::number(currentBandShown) << endl; dxccStatusWidget->setBands(bands); //qDebug() << "MainWindow::checkIfNewBandOrMode - bands2: " << endl; // util->printQString(bands); //qDebug() << "MainWindow::checkIfNewBandOrMode - modes2: " << endl; // util->printQString(modes); //qDebug() << "MainWindow::checkIfNewBandOrMode END" << endl; } void MainWindow::slotDefineNewBands (const QStringList _bands) { //qDebug() << "MainWindow::defineNewBands: " << endl; QStringList qsTemp; qsTemp.clear(); //qsTemp << _bands; //qsTemp.removeDuplicates(); qsTemp << dataProxy->sortBandNamesBottonUp(_bands); bands.clear(); bands << qsTemp; bandComboBox->clear(); bandComboBox->addItems(bands); satTabWidget->addBands(bands); } void MainWindow::readActiveBands (const QStringList actives) { // Checks a "10m, 12m" QString, checks if they are valid bands and import to the // bands used in the program //qDebug() << "MainWindow::readActiveBands: " << endl; //util->printQString(actives); QString aux; bool atLeastOne = false; //QStringList values = actives; //QStringList values = actives.split(", ", QString::SkipEmptyParts); for (int i = 0; i < actives.size() ; i++) { if (dataProxy->getIdFromBandName(actives.at(i)) < 0) //if (db->isValidBand(actives.at(i))) { if (!atLeastOne) { //qDebug() << "MainWindow::readActiveBands (at least One!): " << actives.at(i) << endl; atLeastOne = true; bands.clear(); } aux = actives.at(i); if (aux.length()>0) { bands << aux; } //bands << actives.at(i); //qDebug() << "MainWindow::readActiveBands: " << actives.at(i) << endl; } } bands.removeDuplicates(); //qDebug() << "MainWindow::readActiveBands - END" << endl; } void MainWindow::readActiveModes (const QStringList actives) { //qDebug() << "MainWindow::readActiveModes: " << actives << endl; //qDebug() << "MainWindow::readActiveModes: start" << endl; for (int i = 0;igetIdFromModeName(actives.at(i)) > 0) //if (db->isValidMode(actives.at(i), false)) { if (!atLeastOne) { atLeastOne = true; //modes.clear(); } aux = actives.at(i); if (aux.length()>0) { modes << aux; } // modes << actives.at(i); } } modes.removeDuplicates(); modes.sort(); //qDebug() << "MainWindow::readActiveModes: end" << endl; for (int i = 0;iaddItems(continents); iotaNumberLineEdit = new QLineEdit; iotaNumberLineEdit->setInputMask("000"); iotaNumberLineEdit->setText("000"); */ //bands << "10M" << "15M" << "20M" << "40M" << "80M" << "160M"; //modes << "SSB" << "CW" << "RTTY"; bandComboBox->addItems(bands); //qDebug() << "MainWindow::createUIDX - 1-" << QString::number(modes.count()) << endl; modeComboBox->addItems(modes); txFreqSpinBox->setToolTip(tr("TX Frequency in MHz.")); rxFreqSpinBox->setToolTip(tr("RX Frequency in MHz.")); //myPowerSpinBox->setToolTip(tr("Power used for the QSO in watts")); rxPowerSpinBox->setToolTip(tr("Power used by the DX.")); operatorLineEdit->setToolTip(tr("Logging operator's callsign.")); stationCallSignLineEdit->setToolTip(tr("Callsign used over the air.")); myLocatorLineEdit->setToolTip(tr("My QTH locator.")); nameLineEdit->setToolTip(tr("Name of the DX.")); qthLineEdit->setToolTip(tr("QTH of the DX.")); locatorLineEdit->setToolTip(tr("Locator of the DX.")); //freqQLCDNumber->setToolTip(tr("Frequency of the QSO")); qrzLineEdit->setToolTip(tr("QRZ of the QSO.")); rstTXLineEdit->setToolTip(tr("TX RST.")); rstRXLineEdit->setToolTip(tr("RX RST.")); STXLineEdit->setToolTip(tr("TX Exchange.")); SRXLineEdit->setToolTip(tr("RX Exchange.")); bandComboBox->setToolTip(tr("Band of the QSO.")); modeComboBox->setToolTip(tr("Mode of the QSO.")); dateEdit->setToolTip(tr("Date of the QSO.")); timeEdit->setToolTip(tr("Time of the QSO.")); //statusBar->setToolTip(tr("Misc information")); //qsoStatusBar->setToolTip(tr("QSO information")); OKButton->setToolTip(tr("Add the QSO to the log.")); //spotItButton->setToolTip(tr("Spots this QSO to the DX Cluster - This function is still not implemented")); clearButton->setToolTip(tr("Clears the QSO entry.")); //TODO REMOVE eQSL /* clublogComboBox->setToolTip(tr("Status on ClubLog")); eqslSentComboBox->setToolTip(tr("Status of the eQSL sending")); eqslRecComboBox->setToolTip(tr("Status of the eQSL reception")); lotwSentComboBox->setToolTip(tr("Status of the LotW sending")); lotwRecComboBox->setToolTip(tr("Status of the LotW reception")); clublogQDateEdit->setToolTip(tr("Date of the ClubLog upload")); eqslSentQDateEdit->setToolTip(tr("Date of the eQSL sending")); eqslRecQDateEdit->setToolTip(tr("Date of the eQSL reception")); lotwSentQDateEdit->setToolTip(tr("Date of the LotW sending")); lotwRecQDateEdit->setToolTip(tr("Date of the LotW reception")); qslSentComboBox->setToolTip(tr("Status of the QSL sending")); qslRecComboBox->setToolTip(tr("Status of the QSL reception")); qslSentViaComboBox->setToolTip(tr("QSL sending information")); qslRecViaComboBox->setToolTip(tr("QSL reception information")); qslSentQDateEdit->setToolTip(tr("Date of the QSL sending")); qslRecQDateEdit->setToolTip(tr("Date of the QSL reception")); qslmsgTextEdit->setToolTip(tr("Message of the QSL")); qslViaLineEdit->setToolTip(tr("QSL via information")); */ dxccConfirmedQLCDNumber->setToolTip(tr("Number of confirmed DXCC entities.")); dxccWorkedQLCDNumber->setToolTip(tr("Number of worked DXCC entities.")); wazConfirmedQLCDNumber->setToolTip(tr("Number of confirmed WAZ zones.")); wazWorkedQLCDNumber->setToolTip(tr("Number of worked WAZ zones.")); localConfirmedQLCDNumber->setToolTip(tr("Number of confirmed local references.")); localWorkedQLCDNumber->setToolTip(tr("Number of worked local references.")); qsoConfirmedQLCDNumber->setToolTip(tr("Number of confirmed QSOs.")); qsoWorkedQLCDNumber->setToolTip(tr("Number of worked QSOs.")); dxMarathonQSOLCDNumber->setToolTip(tr("Number of QSOs worked on the selected year.")); dxMarathonDXCCQLCDNumber->setToolTip(tr("Number of DXCC worked on the selected year.")); dxMarathonCQQLCDNumber->setToolTip(tr("Number of CQ Zones worked on the selected year.")); dxMarathonPointsQLCDNumber->setToolTip(tr("Score for the DXMarathon on the selected year.")); operatingYearsComboBox->setToolTip(tr("Select the year you want to check.")); infoLabel1->setToolTip(tr("Status of the DX entity.")); infoLabel2->setToolTip(tr("Name of the DX entity.")); //entityPrimDivComboBox->setToolTip(tr("Select the primary division for this QSO")); //entitySecDivComboBox->setToolTip(tr("Select the secondary division for this QSO")); //entityNameComboBox->setToolTip(tr("Select the propagation mode for this current QSO")); //propModeComboBox->setToolTip(tr("Select the propagation mode for this current QSO")); //QGridLayout *layout = new QGridLayout; dxUpLeftInputFrame = new QFrame; //dxUpRightOutputFrame = new QFrame; //dxUpRightOutputFrame->setFrameShadow(QFrame::Raised); //dxUpRightOutputFrame->setFrameStyle(QFrame::StyledPanel); dxUpLeftTab = new QTabWidget; dxUpRightTab = new QTabWidget; dxBottonTab = new QTabWidget; dxUpLeftTab->setTabPosition(QTabWidget::North); dxUpRightTab->setTabPosition(QTabWidget::South); QWidget *qsoInputTabWidget = new QWidget; //QFormLayout *qsoInputTabWidgetLayout = new QFormLayout; QLabel *nameLabel = new QLabel(qsoInputTabWidget); nameLabel->setText(tr("Name")); nameLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *qthLabel = new QLabel(qsoInputTabWidget); qthLabel->setText(tr("QTH")); qthLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *locLabel = new QLabel(qsoInputTabWidget); locLabel->setText(tr("Locator")); locLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *rxPowerSpinBoxLabelN = new QLabel(tr("Power(rx)")); rxPowerSpinBoxLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *rstTxLabelN = new QLabel(tr("RST(tx)")); rstTxLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *rstRxLabelN = new QLabel(tr("RST(rx)")); rstRxLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); rstTXLineEdit->setInputMask("#990"); rstRXLineEdit->setInputMask("#990"); rstTXLineEdit->setText("59"); rstRXLineEdit->setText("59"); rstTXLineEdit->setMaxLength(3); rstRXLineEdit->setMaxLength(3); //rstTXLineEdit->setFixedWidth(30); //rstRXLineEdit->setFixedWidth(30); QGridLayout *RSTLayout = new QGridLayout; RSTLayout->addWidget(rstTxLabelN, 0, 0); RSTLayout->addWidget(rstTXLineEdit, 1, 0); RSTLayout->addWidget(rstRxLabelN, 0, 1); RSTLayout->addWidget(rstRXLineEdit, 1, 1); //QLabel *spacerLabel = new QLabel(tr("SPACERQTH")); QHBoxLayout *qthHLayout = new QHBoxLayout; qthHLayout->addWidget(qthLabel); //qthHLayout->addSpacerItem(new QSpacerItem(50,1)); //qthHLayout->addWidget(spacerLabel); QVBoxLayout *qthLayout = new QVBoxLayout; qthLayout->addLayout(qthHLayout); qthLayout->addWidget(qthLineEdit); QVBoxLayout *rstQTHLayout = new QVBoxLayout; rstQTHLayout->addLayout(RSTLayout); rstQTHLayout->addLayout(qthLayout); QLabel *txfreqLabelN = new QLabel(tr("Freq TX")); txfreqLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *rxfreqLabelN = new QLabel(tr("Freq RX")); rxfreqLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QGridLayout *freqLayout = new QGridLayout; freqLayout->addWidget(txfreqLabelN, 0, 0); freqLayout->addWidget(rxfreqLabelN, 0, 1); freqLayout->addWidget(txFreqSpinBox, 1, 0); freqLayout->addWidget(rxFreqSpinBox, 1, 1); QVBoxLayout *locVLayout = new QVBoxLayout; locVLayout->addWidget(locLabel); locVLayout->addWidget(locatorLineEdit); //QLabel *spacerLocLabel = new QLabel(tr("SPACERLoc")); QHBoxLayout *locLayout = new QHBoxLayout; //locLayout->addSpacerItem(new QSpacerItem(50,1)); //locLayout->addWidget(spacerLocLabel); locLayout->addLayout(locVLayout); QVBoxLayout *freqLocLayout = new QVBoxLayout; freqLocLayout->addLayout(freqLayout); freqLocLayout->addLayout(locLayout); QHBoxLayout *rstfreqLayout = new QHBoxLayout; rstfreqLayout->addLayout(rstQTHLayout); rstfreqLayout->addLayout(freqLocLayout); QVBoxLayout *rxPowerLayout = new QVBoxLayout; rxPowerLayout->addWidget(rxPowerSpinBoxLabelN); rxPowerLayout->addWidget(rxPowerSpinBox); //QLabel *spacerNameLabel = new QLabel(tr("SPACERName")); QHBoxLayout *nameHLayout = new QHBoxLayout; nameHLayout->addWidget(nameLabel); //nameHLayout->addSpacerItem(new QSpacerItem(50,1)); //nameHLayout->addWidget(spacerNameLabel ); QVBoxLayout *nameLayout = new QVBoxLayout; nameLayout->addLayout(nameHLayout); nameLayout->addWidget(nameLineEdit); QVBoxLayout *rxPwrLayout = new QVBoxLayout; rxPwrLayout->addWidget(rxPowerSpinBoxLabelN); rxPwrLayout->addWidget(rxPowerSpinBox); //QLabel *spacerHBottomLabel = new QLabel(tr("SPACERHBottom")); QHBoxLayout *namePwrHLayout = new QHBoxLayout; namePwrHLayout->addLayout(nameLayout); //namePwrHLayout->addSpacerItem(new QSpacerItem(50,1)); //namePwrHLayout->addWidget(spacerHBottomLabel); namePwrHLayout->addLayout(rxPwrLayout); //QLabel *spacerBottomLabel = new QLabel(tr("SPACERBottom")); QVBoxLayout *namePwrLayout = new QVBoxLayout; //namePwrLayout->addSpacerItem(new QSpacerItem(1,50)); //namePwrLayout->addWidget(spacerBottomLabel); namePwrLayout->addLayout(namePwrHLayout); QVBoxLayout *qsoInputTabWidgetMainLayout = new QVBoxLayout; qsoInputTabWidgetMainLayout->addLayout(rstfreqLayout); qsoInputTabWidgetMainLayout->addLayout(namePwrLayout); qsoInputTabWidget->setLayout(qsoInputTabWidgetMainLayout); //QWidget *qslInputTabWidget = new QWidget; //QWidget *eqslInputTabWidget = new QWidget; //QWidget *commentInputTabWidget = new QWidget; //QWidget *othersInputTabWidget = new QWidget; //QWidget *myDataInputTabWidget = new QWidget; dxUpLeftTab->addTab(qsoInputTabWidget, tr("QSO")); // QSL Tab definition starts here //QLabel *QSLSentLabelN = new QLabel(tr("QSL Sent")); //QSLSentLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); //QLabel *QSLRecLabelN = new QLabel(tr("QSL Rec")); //QSLRecLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); //QLabel *QSLViaLabelN = new QLabel(tr("QSL Via")); //QSLViaLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); /* entityNameComboBox = new QComboBox;entitiesList if (entitiesList.size()>1) { entitiesList.prepend("00-Not Identified (000)"); entityNameComboBox->addItems(entitiesList); } if (propModeList.size()>1) { propModeList.prepend("00 - Not - Not Identified"); propModeComboBox->addItems(propModeList); } QGridLayout *QSLLayout = new QGridLayout; QSLLayout->addWidget(QSLSentLabelN, 0, 0); QSLLayout->addWidget(QSLRecLabelN, 1, 0); QSLLayout->addWidget(QSLViaLabelN, 2, 0); QSLLayout->addWidget(qslSentComboBox, 0, 1); QSLLayout->addWidget(qslRecComboBox, 1, 1); QSLLayout->addWidget(qslViaLineEdit, 2, 1, 1, -1); QSLLayout->addWidget(qslSentQDateEdit, 0, 2); QSLLayout->addWidget(qslRecQDateEdit, 1, 2); QSLLayout->addWidget(qslSentViaComboBox, 0, 3); QSLLayout->addWidget(qslRecViaComboBox, 1, 3); qslInputTabWidget->setLayout(QSLLayout); */ /* // eQSL Tab definition starts here QLabel *clublogLabelN = new QLabel(tr("ClubLog")); clublogLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *eQSLSentLabelN = new QLabel(tr("eQSL Sent")); eQSLSentLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *eQSLRecLabelN = new QLabel(tr("eQSL Rec")); eQSLRecLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *lotWSentLabelN = new QLabel(tr("LotW Sent")); lotWSentLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QLabel *lotWRecLabelN = new QLabel(tr("LotW Rec")); lotWRecLabelN->setAlignment(Qt::AlignVCenter| Qt::AlignRight); QHBoxLayout *eqslSentLayout = new QHBoxLayout; eqslSentLayout->addWidget(eqslSentComboBox); eqslSentLayout->addWidget(eqslSentQDateEdit); QHBoxLayout *eqslRecLayout = new QHBoxLayout; eqslRecLayout->addWidget(eqslRecComboBox); eqslRecLayout->addWidget(eqslRecQDateEdit); QHBoxLayout *lotwSentLayout = new QHBoxLayout; lotwSentLayout->addWidget(lotwSentComboBox); lotwSentLayout->addWidget(lotwSentQDateEdit); QHBoxLayout *lotwRecLayout = new QHBoxLayout; lotwRecLayout->addWidget(lotwRecComboBox); lotwRecLayout->addWidget(lotwRecQDateEdit); QFormLayout *eqslInputTabWidgetLayout = new QFormLayout; eqslInputTabWidgetLayout->addRow(eQSLSentLabelN, eqslSentLayout); eqslInputTabWidgetLayout->addRow(eQSLRecLabelN, eqslRecLayout); eqslInputTabWidgetLayout->addRow(lotWSentLabelN, lotwSentLayout); eqslInputTabWidgetLayout->addRow(lotWRecLabelN, lotwRecLayout); */ /* QGridLayout *eqslInputTabWidgetLayout = new QGridLayout; eqslInputTabWidgetLayout->addWidget(clublogLabelN, 0, 0); eqslInputTabWidgetLayout->addWidget(eQSLSentLabelN, 1, 0); eqslInputTabWidgetLayout->addWidget(eQSLRecLabelN, 2, 0); eqslInputTabWidgetLayout->addWidget(lotWSentLabelN, 3, 0); eqslInputTabWidgetLayout->addWidget(lotWRecLabelN, 4, 0); eqslInputTabWidgetLayout->addWidget(clublogComboBox, 0, 1); eqslInputTabWidgetLayout->addWidget(eqslSentComboBox, 1, 1); eqslInputTabWidgetLayout->addWidget(eqslRecComboBox, 2, 1); eqslInputTabWidgetLayout->addWidget(lotwSentComboBox, 3, 1); eqslInputTabWidgetLayout->addWidget(lotwRecComboBox, 4, 1); eqslInputTabWidgetLayout->addWidget(clublogQDateEdit, 0, 2); eqslInputTabWidgetLayout->addWidget(eqslSentQDateEdit, 1, 2); eqslInputTabWidgetLayout->addWidget(eqslRecQDateEdit, 2, 2); eqslInputTabWidgetLayout->addWidget(lotwSentQDateEdit, 3, 2); eqslInputTabWidgetLayout->addWidget(lotwRecQDateEdit, 4, 2); eqslInputTabWidget->setLayout(eqslInputTabWidgetLayout); dxUpLeftTab->addTab(eqslInputTabWidget, tr("eQSL-old")); */ /* // NOTES tab starts here QGridLayout *notesInputTabWidgetLayout = new QGridLayout; notesInputTabWidgetLayout->addWidget(notesTextEdit, 0, 0); notesInputTabWidget->setLayout(notesInputTabWidgetLayout); i = dxUpLeftTab->addTab(notesInputTabWidget, tr("Notes")); */ //dxUpLeftTab->addTab(qslInputTabWidget, tr("QSL")); dxUpLeftTab->addTab(QSLTabWidget, tr("QSL")); dxUpLeftTab->addTab(eQSLTabWidget, tr("eQSL")); dxUpLeftTab->addTab(commentTabWidget, tr("Comment")); othersTabWidget->setEntitiesList(world->getEntitiesNames()); dxUpLeftTab->addTab(othersTabWidget, tr("Others")); dxUpLeftTab->addTab(myDataTabWidget, tr("My Data")); dxUpLeftTab->addTab(satTabWidget, tr("Satellite")); QHBoxLayout *TimeLayout = new QHBoxLayout; TimeLayout->addWidget(dateEdit); TimeLayout->addWidget(timeEdit); QHBoxLayout *BandModeLayout = new QHBoxLayout; BandModeLayout->addWidget(bandComboBox); BandModeLayout->addWidget(modeComboBox); QHBoxLayout *QrzBandModeLayout = new QHBoxLayout; QrzBandModeLayout->addWidget(qrzLineEdit); QrzBandModeLayout->addLayout(BandModeLayout); qrzgroupBox = new QGroupBox(tr("QRZ")); qrzgroupBox->setFlat(true); QVBoxLayout *qrzvbox = new QVBoxLayout; qrzvbox->addLayout(QrzBandModeLayout); qrzvbox->addStretch(1); qrzgroupBox->setLayout(qrzvbox); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addWidget(OKButton); buttonsLayout->addWidget(clearButton); QDateTimeEdit *dateEdit = new QDateTimeEdit(QDate::currentDate()); dateEdit->setDisplayFormat("yyyy/MM/dd"); timeEdit->setDisplayFormat("HH:mm:ss"); QGridLayout *dxUpLeftInputFrameLayout = new QGridLayout; dxUpLeftInputFrameLayout->addWidget(qrzgroupBox, 0, 0, 1, 0); dxUpLeftInputFrameLayout->addLayout(TimeLayout, 1, 0); dxUpLeftInputFrameLayout->addLayout(buttonsLayout,1, 1); dxUpLeftInputFrame->setLayout(dxUpLeftInputFrameLayout); QSplitter *upLeftSplitter = new QSplitter (this); upLeftSplitter->addWidget(dxUpLeftInputFrame); upLeftSplitter->addWidget(dxUpLeftTab); upLeftSplitter->setOrientation(Qt::Vertical); QVBoxLayout *dxUpRightFixLayout = new QVBoxLayout; dxUpRightFixLayout->addWidget(infoLabel1); dxUpRightFixLayout->addWidget(infoLabel2); infoLabel1->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); infoLabel2->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *dxMarathonTopQSOsLabelN = new QLabel(tr("QSOs")); QLabel *dxMarathonTopDXCCLabelN = new QLabel(tr("DXCC")); QLabel *dxMarathonTopCQLabelN = new QLabel(tr("CQ")); QLabel *dxMarathonTopScoreLabelN = new QLabel(tr("Score")); QLabel *dxMarathonLabelN = new QLabel(tr("DX-Marathon")); dxMarathonTopQSOsLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); dxMarathonTopDXCCLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); dxMarathonTopCQLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); dxMarathonTopScoreLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); dxMarathonLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); dxUpRightTab->addTab(infoWidget, tr("Info")); QWidget *awardsTabWidget = new QWidget; QLabel *awardLabelN = new QLabel(tr("Award")); awardLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); QLabel *confirmedLabelN = new QLabel(tr("Confirmed")); confirmedLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); QLabel *workedLabelN = new QLabel(tr("Worked")); workedLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); QLabel *dxccLabelN = new QLabel(tr("DXCC")); dxccLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); QLabel *wazLabelN = new QLabel(tr("WAZ")); wazLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); QLabel *localLabelN = new QLabel(tr("Local")); localLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); QLabel *qsoNLabelN = new QLabel(tr("QSOs")); qsoNLabelN->setAlignment(Qt::AlignVCenter | Qt::AlignCenter); QGridLayout *dxMarathonDLayout = new QGridLayout; dxMarathonDLayout->addWidget(dxMarathonTopQSOsLabelN, 0, 0); dxMarathonDLayout->addWidget(dxMarathonTopDXCCLabelN, 0, 1); dxMarathonDLayout->addWidget(dxMarathonTopCQLabelN, 0, 2); dxMarathonDLayout->addWidget(dxMarathonTopScoreLabelN, 0, 3); dxMarathonDLayout->addWidget(dxMarathonQSOLCDNumber, 1, 0); dxMarathonDLayout->addWidget(dxMarathonDXCCQLCDNumber, 1, 1); dxMarathonDLayout->addWidget(dxMarathonCQQLCDNumber, 1, 2); dxMarathonDLayout->addWidget(dxMarathonPointsQLCDNumber, 1, 3); QVBoxLayout *dxMarathonTLayout = new QVBoxLayout; dxMarathonTLayout->addWidget(dxMarathonLabelN); dxMarathonTLayout->addWidget(operatingYearsComboBox); QGridLayout *dxUpRightAwardsTabLayout = new QGridLayout; dxUpRightAwardsTabLayout->addWidget(awardLabelN, 0, 0); dxUpRightAwardsTabLayout->addWidget(workedLabelN, 0, 1); dxUpRightAwardsTabLayout->addWidget(confirmedLabelN, 0, 2); dxUpRightAwardsTabLayout->addWidget(dxccLabelN, 1, 0); dxUpRightAwardsTabLayout->addWidget(dxccWorkedQLCDNumber, 1, 1); dxUpRightAwardsTabLayout->addWidget(dxccConfirmedQLCDNumber, 1, 2); dxUpRightAwardsTabLayout->addWidget(wazLabelN, 2, 0); dxUpRightAwardsTabLayout->addWidget(wazWorkedQLCDNumber, 2, 1); dxUpRightAwardsTabLayout->addWidget(wazConfirmedQLCDNumber, 2, 2); dxUpRightAwardsTabLayout->addWidget(localLabelN, 3, 0); dxUpRightAwardsTabLayout->addWidget(localWorkedQLCDNumber, 3, 1); dxUpRightAwardsTabLayout->addWidget(localConfirmedQLCDNumber, 3, 2); dxUpRightAwardsTabLayout->addWidget(qsoNLabelN, 4, 0); dxUpRightAwardsTabLayout->addWidget(qsoWorkedQLCDNumber, 4, 1); dxUpRightAwardsTabLayout->addWidget(qsoConfirmedQLCDNumber, 4, 2); dxUpRightAwardsTabLayout->addLayout(dxMarathonTLayout, 5, 0); dxUpRightAwardsTabLayout->addLayout(dxMarathonDLayout, 5, 1, 1, -1); dxUpRightAwardsTabLayout->addWidget(recalculateAwardsButton, 6, 1); awardsTabWidget->setLayout(dxUpRightAwardsTabLayout); dxUpRightTab->addTab(awardsTabWidget, tr("Awards")); dxUpRightTab->addTab(searchWidget, tr("Search")); dxBottonTab->addTab(logWindow, tr("Log")); dxBottonTab->addTab(dxClusterWidget, tr("DX-Cluster")); dxBottonTab->addTab(dxccStatusWidget, tr("DXCC")); QVBoxLayout *dxUpRightLayout = new QVBoxLayout; dxUpRightLayout->addLayout(dxUpRightFixLayout); dxUpRightLayout->addWidget(dxUpRightTab); QWidget *upRightWidget = new QWidget; upRightWidget->setLayout(dxUpRightLayout); QSplitter *upSplitter = new QSplitter (this); upSplitter->addWidget(upLeftSplitter); upSplitter->addWidget(upRightWidget); QSplitter *splitter = new QSplitter(this); splitter->addWidget(upSplitter); splitter->addWidget(dxBottonTab); splitter->setOrientation(Qt::Vertical); QHBoxLayout *mLayout = new QHBoxLayout; mLayout->addWidget(splitter); mainWidget->setLayout(mLayout); //qDebug() << "MainWindow::createUIDX - OS DETECTION" << endl; #ifdef Q_OS_WIN //qDebug() << "MainWindow::createUIDX - WINDOWS DETECTED!" << endl; dxUpLeftInputFrame->setFrameShadow(QFrame::Raised); dxUpLeftInputFrame->setFrameStyle(QFrame::StyledPanel); qsoNLabelN->setFrameShadow(QFrame::Raised); qsoNLabelN->setFrameStyle(QFrame::StyledPanel); wazLabelN->setFrameShadow(QFrame::Raised); wazLabelN->setFrameStyle(QFrame::StyledPanel); localLabelN->setFrameShadow(QFrame::Raised); localLabelN->setFrameStyle(QFrame::StyledPanel); dxccLabelN->setFrameShadow(QFrame::Raised); dxccLabelN->setFrameStyle(QFrame::StyledPanel); workedLabelN->setFrameShadow(QFrame::Raised); workedLabelN->setFrameStyle(QFrame::StyledPanel); confirmedLabelN->setFrameShadow(QFrame::Raised); confirmedLabelN->setFrameStyle(QFrame::StyledPanel); awardLabelN->setFrameShadow(QFrame::Raised); awardLabelN->setFrameStyle(QFrame::StyledPanel); dxMarathonTopQSOsLabelN->setFrameShadow(QFrame::Raised); dxMarathonTopDXCCLabelN->setFrameShadow(QFrame::Raised); dxMarathonTopCQLabelN->setFrameShadow(QFrame::Raised); dxMarathonTopScoreLabelN->setFrameShadow(QFrame::Raised); dxMarathonLabelN->setFrameShadow(QFrame::Raised); dxMarathonTopQSOsLabelN->setFrameStyle(QFrame::StyledPanel); dxMarathonTopDXCCLabelN->setFrameStyle(QFrame::StyledPanel); dxMarathonTopCQLabelN->setFrameStyle(QFrame::StyledPanel); dxMarathonTopScoreLabelN->setFrameStyle(QFrame::StyledPanel); dxMarathonLabelN->setFrameStyle(QFrame::StyledPanel); infoLabel1->setFrameShadow(QFrame::Raised); infoLabel1->setFrameStyle(QFrame::StyledPanel); infoLabel2->setFrameShadow(QFrame::Raised); infoLabel2->setFrameStyle(QFrame::StyledPanel); #else //qDebug() << "MainWindow::createUIDX - NO WINDOWS DETECTED!" << endl; dxUpLeftInputFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); localLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); qsoNLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); wazLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); dxccLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); workedLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); confirmedLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); awardLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); dxMarathonTopQSOsLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); dxMarathonTopDXCCLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); dxMarathonTopCQLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); dxMarathonTopScoreLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); dxMarathonLabelN->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); infoLabel1->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); infoLabel2->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); #endif } void MainWindow::slotADIFExport(){ //qDebug() << "MainWindow::slotADIFExport " << endl; QString fileName = QFileDialog::getSaveFileName(this, tr("Save ADIF File"), util->getHomeDir(), "ADIF (*.adi *.adif)"); filemanager->adifLogExport(fileName, currentLog); } void MainWindow::slotLoTWExport(){ //qDebug() << "MainWindow::slotLoTWExport " << endl; QString aux; QString fileName = QFileDialog::getSaveFileName(this, tr("Save ADIF File"), util->getHomeDir(), "ADIF (*.adi *.adif)"); int exportedQSO = filemanager->adifLoTWLogExport(fileName, currentLog) ; //qDebug() << "MainWindow::slotLoTWExport - exported: " << QString::number(exportedQSO) << endl; if (exportedQSO > 0) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); aux = tr("LoTW logfile has been properly exported!") + "\n\n" + tr("Remember to:") + "\n\n-" + tr("Before uploading: sign the LoTW log; and") + "\n-" + tr("After uploading: mark as sent all the queued QSO (LoTW Tools)."); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Ok ); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: break; default: // should never be reached break; } } else if (exportedQSO == 0) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); aux = tr("There was no QSO to be exported.") + "\n\n" + tr("If you think that some QSO should have been exported, please look for them and ensure that the eQSL LoTW QSL sent box is marked as:") + "\n\n " + tr("Q - Queued") + "." ; msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Ok ); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: break; default: // should never be reached break; } } else { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); aux = tr("There was an error while exporting the LoTW. The log has not been exported!"); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Ok ); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: break; default: // should never be reached break; } } } void MainWindow::slotADIFExportAll(){ //qDebug() << "MainWindow::slotADIFExportAll " << endl; QString fileName = QFileDialog::getSaveFileName(this, tr("Save ADIF File"), util->getHomeDir(), "ADIF (*.adi *.adif)"); filemanager->adifLogExport(fileName, 0); } void MainWindow::slotRQSLExport() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save ADIF File"), util->getHomeDir(), "ADIF (*.adi *.adif)"); filemanager->adifReqQSLExport(fileName); } void MainWindow::slotCabrilloExport() { //qDebug() << "MainWindow::slotCabrilloExport " << endl; QString fileName = QFileDialog::getSaveFileName(this, tr("Save Cabrillo File"), util->getHomeDir(), tr("Cabrillo (*.log)")); contest->saveFileToSend(fileName); } void MainWindow::slotLoTWImport(){ //qDebug() << "MainWindow::slotLoTWImport " << endl; QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), util->getHomeDir(), "ADIF (*.adi *.adif)"); if (fileName.isNull()) { } else { //qDebug() << "MainWindow::slotLoTWImport -1" << endl; filemanager->adifLoTWReadLog(fileName); //qDebug() << "MainWindow::slotLoTWImport -2" << endl; logWindow->refresh(); //qDebug() << "MainWindow::slotLoTWImport -3" << endl; //checkIfNewBandOrMode(); //qDebug() << "MainWindow::slotLoTWImport -4" << endl; } //qDebug() << "MainWindow::slotLoTWImport-END" << endl; } void MainWindow::slotADIFImport(){ //qDebug() << "MainWindow::slotADIFImport " << endl; QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), util->getHomeDir(), "ADIF (*.adi *.adif)"); if (fileName.isNull()) { } else { //qDebug() << "MainWindow::slotADIFImport -1" << endl; filemanager->adifReadLog(fileName, currentLog); updateQSLRecAndSent(); //qDebug() << "MainWindow::slotADIFImport -2" << endl; logWindow->refresh(); //qDebug() << "MainWindow::slotADIFImport -3" << endl; checkIfNewBandOrMode(); //qDebug() << "MainWindow::slotADIFImport -4" << endl; if (contestMode == "DX") { operatingYearsComboBox->addItems(dataProxy->getOperatingYears(currentLog)); slotShowAwards(); } else if (contestMode == "CQ-WW-SSB") {} else { operatingYearsComboBox->addItems(dataProxy->getOperatingYears(currentLog)); slotShowAwards(); } //qDebug() << "MainWindow::slotADIFImport-7" << endl; } //qDebug() << "MainWindow::slotADIFImport-END" << endl; } void MainWindow::initialContestModeConfiguration() { //qDebug() << "MainWindow::initialContestModeConfiguration: - 0" << endl; if (!configured){ //qDebug() << "MainWindow::initialContestModeConfiguration: - 01" << endl; slotSetup(); //qDebug() << "MainWindow::initialContestModeConfiguration: - 02" << endl; return; } //qDebug() << "MainWindow::initialContestModeConfiguration: - 03" << endl; QSqlQuery query; QStringList contestQS; //qDebug() << "MainWindow::initialContestModeConfiguration: - 04" << endl; if (contestMode == "DX") { defaultMode = dataProxy->getMostUsedMode(currentLog); defaultBand = dataProxy->getMostUsedBand(currentLog); } else if (contestMode == "CQ-WW-SSB") { //qDebug() << "MainWindow::initialContestModeConfiguration: - 05" << endl; defaultMode = dataProxy->getIdFromModeName("SSB"); SRXLineEdit->setInputMask("09"); STXLineEdit->setInputMask("09"); contestQS << QString::number(world->getQRZARRLId(stationQRZ)) << QString::number(world->getQRZCqz(stationQRZ)) << world->getQRZContinentNumber(stationQRZ) << world->getQRZContinentNumber("K"); contest = new ContestCQWWDXSSB(contestQS); } else if (contestMode == "CQ-WW-CW") { SRXLineEdit->setInputMask("09"); STXLineEdit->setInputMask("09"); contestQS << QString::number(world->getQRZARRLId(stationQRZ)) << QString::number(world->getQRZCqz(stationQRZ)) << world->getQRZContinentNumber(stationQRZ) << world->getQRZContinentNumber("K"); } else { defaultMode = dataProxy->getMostUsedMode(currentLog); defaultBand = dataProxy->getMostUsedBand(currentLog); } } void MainWindow::qsoToEdit (const int _qso) { //qDebug() << "MainWindow::qsoToEdit: " << QString::number(_qso) << endl; int nameCol; QString aux1; double testValueDouble; // Variable just to test if the value is in the appropriate range modify = true; modifyingQSO = _qso; OKButton->setText(tr("&Modify")); //TODO: Optimize the following query. Maybe the * is not needed. QString stringQuery = QString("SELECT * FROM log WHERE id ='%1' AND lognumber='%2'").arg(_qso).arg(currentLog); //qDebug() << "MainWindow::qsoToEdit: " << stringQuery << endl; QSqlQuery query(stringQuery); bool sqlOK = query.exec(); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } query.next(); if (query.isValid()) { if ((clublogActive) && (clublogRealTime)) { clublogPrevQSO = dataProxy->getClubLogRealTimeFromId(_qso); } QSqlRecord rec = query.record(); // ADD THE DATA THAT IS PRESENT IN ALL THE MODES nameCol = rec.indexOf("call"); aux1 = (query.value(nameCol)).toString(); qrzLineEdit->setText(aux1); currentQrz = aux1; currentEntity = world->getQRZARRLId(currentQrz); //qDebug() << "MainWindow::qsoToEdit - currentEntity " << QString::number(currentEntity) << endl; nameCol = rec.indexOf("qso_date"); aux1 = (query.value(nameCol)).toString(); dateEdit->setDate(QDate::fromString(aux1, "yyyy/MM/dd")); nameCol = rec.indexOf("time_on"); aux1 = (query.value(nameCol)).toString(); timeEdit->setTime(QTime::fromString(aux1, "hh:mm:ss")); nameCol = rec.indexOf("bandid"); aux1 = (query.value(nameCol)).toString(); stringQuery = QString("SELECT name FROM band WHERE id ='%1'").arg(aux1); QSqlQuery queryAux(stringQuery); sqlOK = queryAux.exec(); if (!sqlOK) { emit queryError(Q_FUNC_INFO, queryAux.lastError().databaseText(), queryAux.lastError().number(), queryAux.lastQuery()); } queryAux.next(); if (queryAux.isValid()) { aux1 = (queryAux.value(0)).toString(); //qDebug() << "MainWindow::qsoToEdit - bandid-1 " << aux1 << endl; bandComboBox->setCurrentIndex(bandComboBox->findText(aux1, Qt::MatchCaseSensitive)); } else { //qDebug() << "MainWindow::qsoToEdit - bandid-NO " << endl; bandComboBox->setCurrentIndex(bandComboBox->findText(dataProxy->getNameFromBandId(defaultBand), Qt::MatchCaseSensitive)); //bandComboBox->setCurrentIndex(defaultBand); } //qDebug() << "MainWindow::qsoToEdit: Check mode " << endl; nameCol = rec.indexOf("modeid"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "MainWindow::qsoToEdit: (aux1)-1: " << aux1 << endl; stringQuery = QString("SELECT submode FROM mode WHERE id ='%1'").arg(aux1); sqlOK = queryAux.exec(stringQuery); if (!sqlOK) { emit queryError(Q_FUNC_INFO, queryAux.lastError().databaseText(), queryAux.lastError().number(), queryAux.lastQuery()); } queryAux.next(); if (queryAux.isValid()) { aux1 = (queryAux.value(0)).toString(); //qDebug() << "MainWindow::qsoToEdit: Mode query valid: -" << aux1 << "-Length: " << QString::number(aux1.length()) << endl; if (modeComboBox->findText(aux1, Qt::MatchCaseSensitive)>=0) { //qDebug() << "MainWindow::qsoToEdit: Mode in the Combobox: " << aux1 << " - Result: " << QString::number(modeComboBox->findText(aux1)) << endl; modeComboBox->setCurrentIndex(modeComboBox->findText(aux1, Qt::MatchCaseSensitive)); } else { //TODO: Add this mode to the list modes in use //qDebug() << "MainWindow::qsoToEdit: Mode query valid but not in comboBox: " << aux1 << endl; /* for (int i = 0; i < (modeComboBox->count()); i++) { //qDebug() << "MainWindow::qsoToEdit: Mode: " << modeComboBox->itemText(i) << endl; } */ } //qDebug() << "MainWindow::qsoToEdit: After Mode IF" << endl; } else { //qDebug() << "MainWindow::qsoToEdit: Mode query not valid" << endl; modeComboBox->setCurrentIndex(modeComboBox->findText(dataProxy->getNameFromSubModeId(defaultMode), Qt::MatchCaseSensitive)); //modeComboBox->setCurrentIndex(defaultMode); } //qDebug() << "MainWindow::qsoToEdit: After ALL Mode actions" << endl; nameCol = rec.indexOf("rst_sent"); aux1 = (query.value(nameCol)).toString(); rstTXLineEdit->setText(aux1); //qDebug() << "MainWindow::qsoToEdit: - RST_SENT: " << aux1 << endl; nameCol = rec.indexOf("rst_rcvd"); aux1 = (query.value(nameCol)).toString(); rstRXLineEdit->setText(aux1); //qDebug() << "MainWindow::qsoToEdit: - before switch" << endl; if (contestMode == "DX") { //qDebug() << "MainWindow::qsoToEdit: - in default" << endl; nameCol = rec.indexOf("qsl_via"); aux1 = (query.value(nameCol)).toString(); QSLTabWidget->setQSLVia(aux1); nameCol = rec.indexOf("qslmsg"); aux1 = (query.value(nameCol)).toString(); QSLTabWidget->setQSLMsg(aux1); //qslmsgTextEdit->setText(aux1); nameCol = rec.indexOf("comment"); aux1 = (query.value(nameCol)).toString(); if (aux1.length()>0) { commentTabWidget->setData(aux1); //commentLineEdit->setText(aux1); } else { commentTabWidget->clear(); //commentLineEdit->clear(); } nameCol = rec.indexOf("name"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "MainWindow::qsoToEdit: - NAME: " << aux1 << endl; if (aux1.length()>0) { nameLineEdit->setText(aux1); } else { nameLineEdit->clear(); } nameCol = rec.indexOf("qth"); aux1 = (query.value(nameCol)).toString(); qthLineEdit->setText(aux1); nameCol = rec.indexOf("gridsquare"); aux1 = (query.value(nameCol)).toString(); locatorLineEdit->setText(aux1); satTabWidget->setLocator(aux1); nameCol = rec.indexOf("operator"); aux1 = (query.value(nameCol)).toString(); myDataTabWidget->setOperator(aux1); nameCol = rec.indexOf("station_callsign"); aux1 = (query.value(nameCol)).toString(); myDataTabWidget->setStationQRZ(aux1); nameCol = rec.indexOf("my_gridsquare"); aux1 = (query.value(nameCol)).toString(); myDataTabWidget->setMyLocator(aux1); nameCol = rec.indexOf("tx_pwr"); myDataTabWidget->setMyPower((query.value(nameCol)).toDouble()); nameCol = rec.indexOf("rx_pwr"); aux1 = (query.value(nameCol)).toString(); testValueDouble = aux1.toDouble(); if (testValueDouble >=0) { rxPowerSpinBox->setValue(testValueDouble); } else { rxPowerSpinBox->setValue(0.0); } nameCol = rec.indexOf("freq"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "MainWindow::qsoToEdit (freq STRING):" << aux1 << endl; testValueDouble = aux1.toDouble(); //qDebug() << "MainWindow::qsoToEdit (freq):" << QString::number(testValueDouble) << endl; if ((testValueDouble >0) && (testValueDouble <= txFreqSpinBox->maximum()) ) { txFreqSpinBox->setValue(testValueDouble); //qDebug() << "MainWindow::qsoToEdit: Freq - OverFlow " << endl; } else { //qDebug() << "MainWindow::qsoToEdit: Freq - OK " << endl; txFreqSpinBox->setValue(0); } nameCol = rec.indexOf("freq_rx"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "MainWindow::qsoToEdit (freq_rx STRING):" << aux1 << endl; testValueDouble = aux1.toDouble(); //qDebug() << "MainWindow::qsoToEdit (freq_rx):" << QString::number(testValueDouble) << endl; if ((testValueDouble >0) && (testValueDouble <= rxFreqSpinBox->maximum()) ) { rxFreqSpinBox->setValue(testValueDouble); //qDebug() << "MainWindow::qsoToEdit: Freq_RX - OverFlow " << endl; } else { //qDebug() << "MainWindow::qsoToEdit: Freq_RX - OK " << endl; rxFreqSpinBox->setValue(0); } //QSL SENT nameCol = rec.indexOf("qsl_sent"); aux1 = (query.value(nameCol)).toString(); QSLTabWidget->setQSLSenStatus(aux1); //TODO: Depending on the Value a date should or not exist. // This code may be importing dates when they should not exist. nameCol = rec.indexOf("qslsdate"); aux1 = (query.value(nameCol)).toString(); if ( (QDate::fromString(aux1, "yyyy/MM/dd")).isValid() ) { QSLTabWidget->setQSLSenDate(QDate::fromString(aux1, "yyyy/MM/dd")); } nameCol = rec.indexOf("qsl_sent_via"); aux1 = (query.value(nameCol)).toString(); QSLTabWidget->setQSLSenVia(aux1); //QSL RECEPTION // tr("Y-Yes") << tr("N-No") << tr("R-Requested") << tr("I-Ignore") << tr("V-Verified"); // tr("B-Bureau") << tr("D-Direct") << tr("E-Electronic") << tr("M-Manager"); //QSLRDATE: (only valid if QSL_RCVD is Y, I, or V) nameCol = rec.indexOf("qsl_rcvd"); aux1 = (query.value(nameCol)).toString(); QSLTabWidget->setQSLRecStatus(aux1); //TODO: Depending on the Value a date should or not exist. // This code may be importing dates when they should not exist. nameCol = rec.indexOf("qslrdate"); aux1 = (query.value(nameCol)).toString(); if ( (QDate::fromString(aux1, "yyyy/MM/dd")).isValid() ) { QSLTabWidget->setQSLRecDate(QDate::fromString(aux1, "yyyy/MM/dd")); } nameCol = rec.indexOf("qsl_rcvd_via"); aux1 = (query.value(nameCol)).toString(); QSLTabWidget->setQSLRecVia(aux1); //TODO: BUG: When something is selected while modifying the QSL is deleted??? //CLUBLOG nameCol = rec.indexOf("clublog_qso_upload_status"); aux1 = (query.value(nameCol)).toString(); eQSLTabWidget->setClubLogStatus(aux1.toUpper()); //TODO: Depending on the Value a date should or not exist. // This code may be importing dates when they should not exist. nameCol = rec.indexOf("clublog_qso_upload_date"); aux1 = (query.value(nameCol)).toString(); if ( (QDate::fromString(aux1, "yyyy/MM/dd")).isValid() ) { eQSLTabWidget->setClubLogDate((QDate::fromString(aux1, "yyyy/MM/dd"))); } //CLUBLOG //EQSL_QSL_SENT: {Y, N, R, Q, I} // tr("Y-Yes") << tr("N-No") << tr("R-Requested") << tr("Q-Queued") << tr("I-Ignore"); //EQSL_QSLSDATE (only valid if EQSL_SENT is Y, Q, or I) nameCol = rec.indexOf("eqsl_qsl_sent"); aux1 = (query.value(nameCol)).toString(); eQSLTabWidget->setEQSLSenStatus(aux1.toUpper()); //TODO: Depending on the Value a date should or not exist. // This code may be importing dates when they should not exist. nameCol = rec.indexOf("eqsl_qslsdate"); aux1 = (query.value(nameCol)).toString(); if ( (QDate::fromString(aux1, "yyyy/MM/dd")).isValid() ) { eQSLTabWidget->setEQSLSenDate(QDate::fromString(aux1, "yyyy/MM/dd")); } //E-QSL RECEPTION // tr("Y-Yes") << tr("N-No") << tr("R-Requested") << tr("I-Ignore") << tr("V-Verified"); // EQSL_QSL_RCVD: {Y, N, R, I, V} // EQSL_QSLRDATE: (only valid if EQSL_RCVD is Y, I, or V) nameCol = rec.indexOf("eqsl_qsl_rcvd"); aux1 = (query.value(nameCol)).toString(); eQSLTabWidget->setEQSLRecStatus(aux1.toUpper()); //TODO: Depending on the Value a date should or not exist. // This code may be importing dates when they should not exist. nameCol = rec.indexOf("eqsl_qslrdate"); aux1 = (query.value(nameCol)).toString(); if ( (QDate::fromString(aux1, "yyyy/MM/dd")).isValid() ) { eQSLTabWidget->setEQSLRecDate(QDate::fromString(aux1, "yyyy/MM/dd")); } //LOTW_QSL_SENT: {Y, N, R, Q, I} // tr("Y-Yes") << tr("N-No") << tr("R-Requested") << tr("Q-Queued") << tr("I-Ignore"); //LOTW_QSLSDATE (only valid if LOTW_SENT is Y, Q, or I) nameCol = rec.indexOf("lotw_qsl_sent"); aux1 = (query.value(nameCol)).toString(); eQSLTabWidget->setLOTWSenStatus(aux1.toUpper()); //qDebug() << "MainWindow::qsoToEdit: - LoTW Sent Status: " << aux1 << endl; //TODO: Depending on the Value a date should or not exist. // This code may be importing dates when they should not exist. nameCol = rec.indexOf("lotw_qslsdate"); aux1 = (query.value(nameCol)).toString(); if ( (QDate::fromString(aux1, "yyyy/MM/dd")).isValid() ) { eQSLTabWidget->setLOTWSenDate(QDate::fromString(aux1, "yyyy/MM/dd")); } //E-QSL RECEPTION // tr("Y-Yes") << tr("N-No") << tr("R-Requested") << tr("I-Ignore") << tr("V-Verified"); // lotw_QSL_RCVD: {Y, N, R, I, V} // lotw_QSLRDATE: (only valid if lotw_RCVD is Y, I, or V) nameCol = rec.indexOf("lotw_qsl_rcvd"); aux1 = (query.value(nameCol)).toString(); eQSLTabWidget->setLOTWRecStatus(aux1.toUpper()); //TODO: Depending on the Value a date should or not exist. // This code may be importing dates when they should not exist. nameCol = rec.indexOf("lotw_qslrdate"); aux1 = (query.value(nameCol)).toString(); if ( (QDate::fromString(aux1, "yyyy/MM/dd")).isValid() ) { eQSLTabWidget->setLOTWRecDate(QDate::fromString(aux1, "yyyy/MM/dd")); } //qDebug() << "MainWindow::qsoToEdit: - just before IOTA" << endl; nameCol = rec.indexOf("iota"); aux1 = (query.value(nameCol)).toString(); aux1 = awards->checkIfValidIOTA(aux1); othersTabWidget->setIOTA(aux1); nameCol = rec.indexOf("sat_name"); aux1 = (query.value(nameCol)).toString(); if (aux1.length()>0) { satTabWidget->setSatName(aux1); } else { satTabWidget->clear(); } nameCol = rec.indexOf("sat_mode"); aux1 = (query.value(nameCol)).toString(); if (aux1.length()>1) { satTabWidget->setSatMode(aux1); } else { satTabWidget->setSatMode("-CLEAR-"); } //qDebug() << "MainWindow::qsoToEdit: - in default - 100: " << QString::number(currentEntity) << endl; nameCol = rec.indexOf("dxcc"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "MainWindow::qsoToEdit: Checking DXCC: " << aux1 << " - " << world->getEntityName(aux1.toInt()) << endl; if (aux1.toInt()>=1) { if (aux1.toInt() == util->getNormalizedDXCCValue(currentEntity)) { } else { currentEntity = aux1.toInt(); } //qDebug() << "MainWindow::qsoToEdit: - in default - 101: " << QString::number(currentEntity) << endl; } else { currentEntity = world->getQRZARRLId(currentQrz); //qDebug() << "MainWindow::qsoToEdit: - in default - 103: " << QString::number(currentEntity) << endl; } //qDebug() << "MainWindow::qsoToEdit: - in default - 104: " << QString::number(currentEntity) << endl; nameCol = rec.indexOf("prop_mode"); aux1 = (query.value(nameCol)).toString(); othersTabWidget->setPropMode(aux1); infoLabel2->setText(world->getEntityName(currentEntity)); infoWidget->showEntityInfo(currentEntity); //selectCorrectComboBoxEntity(currentEntity); //qDebug() << "MainWindow::qsoToEdit: " << QString::number(currentEntity) << endl; othersTabWidget->setEntity(currentEntity); //qDebug() << "MainWindow::qsoToEdit: - in default - 101" << endl; QStringList _qs; //for the showStatusOfDXCC(const QStringList _qs) _qs.clear(); //TODO: The band sometimes fails here. Check _qs << QString::number(currentEntity) << QString::number(dataProxy->getIdFromBandName(bandComboBox->currentText())) << QString::number(dataProxy->getIdFromBandName(modeComboBox->currentText())) << QString::number(currentLog); //qDebug() << "MainWindow::qsoToEdit: - in default - 104" << endl; showStatusOfDXCC(_qs); //qDebug() << "MainWindow::qsoToEdit: - in default - 105" << endl; //qDebug() << "MainWindow::qsoToEdit: - just after de IOTA" << endl; } else if (contestMode == "CQ-WW-SSB") { } else { //TODO: Manage the else... is it a DX or show a message? } //qDebug() << "MainWindow::qsoToEdit: - in default - 106" << endl; } //Closes the next.isValid //qDebug() << "MainWindow::qsoToEdit: - in default - END" << endl; } void MainWindow::slotLocatorTextChanged() {//TO BE REMOVED ONCE InfoWidget is FINISHED - At least modified //qDebug() << "MainWindow::slotLocatorTextChanged: " << locatorLineEdit->text() << endl; if ( locator->isValidLocator((locatorLineEdit->text()).toUpper()) ) { dxLocator = (locatorLineEdit->text()).toUpper(); infoWidget->showDistanceAndBearing(myLocator, dxLocator); satTabWidget->setLocator(dxLocator); //showInfoFromLocators(myLocator, dxLocator); } else { return; } } void MainWindow::slotMyLocatorTextChanged() { //qDebug() << "MainWindow::slotMyLocatorTextChanged: " << myLocatorLineEdit->text() << endl; if ( locator->isValidLocator((myLocatorLineEdit->text()).toUpper()) ) { myLocator = (myLocatorLineEdit->text()).toUpper(); //qDebug() << "MainWindow::slotMyLocatorTextChanged: My LOCATOR CHANGED TO: " << myLocator << endl; slotLocatorTextChanged(); } else { return; } } void MainWindow::showStatusOfDXCC(const QStringList _qs) { //qDebug() << "MainWindow::showStatusOfDXC: Entity: " << _qs.at(0) << "/ Bandid :" << _qs.at(1) << "/Modeid: " << _qs.at(2) << endl; // Receives: QStringList _qs; //_qs << Entity << BandId << ModeId << lognumber; // Check if new one, needed, worked, confirmed // Print the infoLabel1 // Print/Color the band boxes/labels /* 0 - New One 1 - Needed 2 - Worked 3 - Confirmed */ if ((_qs.length() != 4) || (_qs.at(1) == "-1")) // is the qs valid? { infoWidget->clear(); infoLabel1->setText(tr("--")); return; } // Set the status bar with the appropriate message int status = awards->getDXStatus (_qs); QString message = QString(); //qDebug() << "MainWindow::showStatusOfDXC: " << QString::number(status) << endl; message = awards->getDXStatusString(status); infoLabel1->setText(message); //infoWidget->showInfo((_qs.at(0)).toInt(), (_qs.at(1)).toInt(), (_qs.at(2)).toInt(), (_qs.at(3)).toInt() ); infoWidget->showInfo((_qs.at(0)).toInt()); } void MainWindow::showDXMarathonNeeded(const int _dxcc, const int _cqz, const int _year, const int _log) { //qDebug() << "MainWindow::showDXMarathonNeeded" << endl; if ((_dxcc<=0) || (_cqz<=0)) { return; } if ( awards->isDXMarathonNeed(_dxcc, _cqz, _year, _log)) { infoLabel1->setText(infoLabel1->text()+ tr(" - Needed for DXMarathon")); } } void MainWindow::slotShowAwards() { //To be called from the logWindow & searchWidget awards->recalculateAwards(); logWindow->refresh(); showAwards(); dxccStatusWidget->refresh(); } void MainWindow::showAwards() { // Updates and show all the award status tab. //qDebug() << "MainWindow::showAwards" << endl; /* WAZ Local */ int _num = 0; QSqlQuery query; QString aux; /* aux = QString("SELECT count(id) FROM log WHERE lognumber='%1'").arg(currentLog); query.exec(aux); query.next(); if (query.isValid()) { _num = (query.value(0)).toInt(); } */ _num = dataProxy->getHowManyQSOInLog(currentLog); qsoWorkedQLCDNumber->display(_num); _num = dataProxy->getHowManyConfirmedQSLInLog(currentLog); qsoConfirmedQLCDNumber->display(_num); _num = 0; dxccWorkedQLCDNumber->display(awards->getDXCCWorked(currentLog)); _num = 0; dxccConfirmedQLCDNumber->display(awards->getDXCCConfirmed(currentLog)); _num = 0; wazWorkedQLCDNumber->display(awards->getWAZWorked(currentLog)); _num = 0; wazConfirmedQLCDNumber->display(awards->getWAZConfirmed(currentLog)); showDXMarathon(selectedYear); } void MainWindow::showDXMarathon(const int _year) { //qDebug() << "MainWindow::MainWindow::showDXMarathon: Year: " << QString::number(_year) << endl; int i = 0; i = awards->getDXMarathonQSO(_year, currentLog); //qDebug() << "MainWindow::MainWindow::showDXMarathon: QSO: " << QString::number(i) << endl; dxMarathonQSOLCDNumber->display(i); i = awards->getDXMarathonDXCC(_year, currentLog); //qDebug() << "MainWindow::MainWindow::showDXMarathon: DXCC: " << QString::number(i) << endl; dxMarathonDXCCQLCDNumber->display(i); i = awards->getDXMarathonCQ(_year, currentLog); dxMarathonCQQLCDNumber->display(i); //qDebug() << "MainWindow::MainWindow::showDXMarathon: CQ: " << QString::number(i) << endl; i = awards->getDXMarathonScore(_year, currentLog); dxMarathonPointsQLCDNumber->display(i); //qDebug() << "MainWindow::MainWindow::showDXMarathon: Score: " << QString::number(i) << endl; } void MainWindow::fillQSOData() { // Updates all QSO with the dxcc, CQZ, ... if empty. //qDebug() << "MainWindow::fillQSOData" << endl; QString stringQuery = QString("SELECT call, bandid, modeid, qso_date, time_on, lognumber, confirmed, id, cqz, ituz, dxcc FROM log WHERE lognumber='%1'").arg(currentLog); QSqlQuery query; bool sqlOK = query.exec(stringQuery); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } QSqlQuery query1; QSqlRecord rec = query.record(); int nameCol; QString aux, queryString; QString _call, _bandid, _modeid, _tdate, _ttime, _lognumber, _id, aux1, updateString, _confirmed; bool toModify = false; bool noMoreQso = false; int numberOfQsos = 0; int i = 0; numberOfQsos = dataProxy->getHowManyQSOInLog(currentLog); //int progressBarPosition = 0; QProgressDialog progress(tr("Filling QSOs..."), tr("Abort filling"), 0, numberOfQsos, this); progress.setWindowModality(Qt::WindowModal); while ( (query.next()) && (!noMoreQso) ) { if (query.isValid()) { i++; toModify = false; nameCol = rec.indexOf("call"); if ( (query.value(nameCol)).isValid() ) { _call = (query.value(nameCol)).toString(); } nameCol = rec.indexOf("bandid"); if ( (query.value(nameCol)).isValid() ) { _bandid = (query.value(nameCol)).toString(); } nameCol = rec.indexOf("modeid"); if ( (query.value(nameCol)).isValid() ) { _modeid = (query.value(nameCol)).toString(); } nameCol = rec.indexOf("qso_date"); if ( (query.value(nameCol)).isValid() ) { _tdate = (query.value(nameCol)).toString(); } nameCol = rec.indexOf("time_on"); if ( (query.value(nameCol)).isValid() ) { _ttime = (query.value(nameCol)).toString(); } nameCol = rec.indexOf("lognumber"); if ( (query.value(nameCol)).isValid() ) { _lognumber = (query.value(nameCol)).toString(); } nameCol = rec.indexOf("confirmed"); if ( (query.value(nameCol)).isValid() ) { _confirmed = (query.value(nameCol)).toString(); } nameCol = rec.indexOf("id"); if ( (query.value(nameCol)).isValid() ) { _id = (query.value(nameCol)).toString(); } //qDebug() << "MainWindow::fillQSOData: ID: " << _id << endl; //TODO: Prepare this query updateString = "UPDATE log SET call = '" + _call + "', bandid = '" + _bandid + "', modeid = '" + _modeid + "', qso_date = '" + _tdate + "', time_on = '" + _ttime + "', lognumber = '" + _lognumber + "', confirmed = '" + _confirmed + "'"; nameCol = rec.indexOf("cqz"); if (( (query.value(nameCol)).toString()).length() < 1 ) { aux1 = QString::number(world->getQRZCqz(_call)); updateString = updateString + ", cqz='" + aux1 + "'"; toModify = true; } else { } nameCol = rec.indexOf("ituz"); if (( (query.value(nameCol)).toString()).length() < 1 ) { aux1 = QString::number( world->getQRZItuz(_call) ); updateString = updateString + ", ituz='" + aux1 + "'"; toModify = true; } else {} //qDebug() << "MainWindow::fillQSOData: DXCC" << endl; nameCol = rec.indexOf("dxcc"); if (( (query.value(nameCol)).toString()).length() < 1 ) { aux1 = QString::number(world->getQRZARRLId(_call) ); //qDebug() << "MainWindow::fillQSOData: DXCC proposed: " << aux1 << endl; if (aux1.toInt()>0) { updateString = updateString + ", dxcc='" + aux1 + "'"; toModify = true; //qDebug() << "MainWindow::fillQSOData: DXCC: " << aux1 << endl; } else { //qDebug() << "MainWindow::fillQSOData: no DXCC identified" << endl; } } else { //qDebug() << "MainWindow::fillQSOData: DXCC already existed" << endl; } //qDebug() << "MainWindow::fillQSOData1: " << updateString << endl; if (toModify) { updateString = updateString + " WHERE id = " + "'" + _id + "'"; //qDebug() << "MainWindow::fillQSOData2: " << updateString << endl; sqlOK = query1.exec(updateString); if (sqlOK) { //qDebug() << "MainWindow::fillQSOData: sqlOK=True" << endl; } else { emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number(), query1.lastQuery()); //qDebug() << "MainWindow::fillQSOData: sqlOK=False" << endl; } } else { updateString.clear(); } aux = tr("Filling QSOs...\n QSO: ") + QString::number(i) + "/" + QString::number(numberOfQsos); progress.setLabelText(aux); progress.setValue(i); if ( progress.wasCanceled() ) { //qDebug() << "MainWindow::fillQSOData3: " << endl; noMoreQso = true; } } // Closes the next.isValid } // Closes the While } void MainWindow::slotFillEmptyDXCCInTheLog() { dataProxy->fillEmptyDXCCInTheLog(); } void MainWindow::slotUpdateCTYDAT() { //qDebug() << "MainWindow::slotUpdateCTYDAT" << endl; downloadcty->download(); } void MainWindow::slotWorldReload() { //qDebug() << "MainWindow::slotWorldReload" << endl; //TODO: world.recreate returns a boolean, so it is possible to manage the errors world->recreate(ctyDatFile); } void MainWindow::slotFilePrint() { //qDebug() << "MainWindow::slotFilePrint" << endl; QPrinter printer; QString aux; QSqlQuery query, query1; int row = 0; int _numberOfQsos = 0; bool cancelPrinting = false; bool sqlOK; _numberOfQsos = dataProxy->getHowManyQSOInLog(currentLog); int step = util->getProgresStepForDialog(_numberOfQsos); QTextCursor cursor(doc); QTextTable *textTable = cursor.insertTable(1, 9); QTextBlockFormat centerAlignment; centerAlignment.setAlignment(Qt::AlignCenter); QTextTableFormat tableFormat; tableFormat.setHeaderRowCount(1); tableFormat.setCellPadding(5); tableFormat.setAlignment(Qt::AlignCenter); textTable->setFormat(tableFormat); //The first row is the header cursor = textTable->cellAt(row, 0).firstCursorPosition(); cursor.setBlockFormat(centerAlignment); cursor.insertText(tr("Number")); cursor = textTable->cellAt(row, 1).firstCursorPosition(); cursor.insertText(tr("Date")); cursor = textTable->cellAt(row, 2).firstCursorPosition(); cursor.insertText(tr("Time")); cursor = textTable->cellAt(row, 3).firstCursorPosition(); cursor.insertText(tr("QRZ")); cursor = textTable->cellAt(row, 4).firstCursorPosition(); cursor.insertText(tr("RSTtx")); cursor = textTable->cellAt(row, 5).firstCursorPosition(); cursor.insertText(tr("RSTrx")); cursor = textTable->cellAt(row, 6).firstCursorPosition(); cursor.insertText(tr("Band")); cursor = textTable->cellAt(row, 7).firstCursorPosition(); cursor.insertText(tr("Mode")); cursor = textTable->cellAt(row, 8).firstCursorPosition(); cursor.insertText(tr("Comment")); int nameCol = 0; //int qsoPerPage = 25; //int maxPages = (int)(Klog::number / qsoPerPage)+1; // To print just 10 QSO per page //int printedSoFar = 0; //int page = 1; printer.setOrientation(QPrinter::Landscape); // For testing, the log will be printed landscape. printer.setDocName(stationQRZ+"-log"); QPrintDialog printDialog(&printer, this); printDialog.setWindowTitle(tr("Print Log")); if (printDialog.exec() == QDialog::Accepted) { int _qsos = 0; QProgressDialog progress(tr("Printing the log..."), tr("Abort printing"), 0, _numberOfQsos, this); progress.setMaximum(_numberOfQsos); progress.setWindowModality(Qt::WindowModal); QString stringQuery = QString("SELECT id, qso_date, time_on, call, rst_sent, rst_rcvd, bandid, modeid, comment FROM log WHERE lognumber='%1'").arg(currentLog); sqlOK = query.exec(stringQuery); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return; //TODO: Print a message showing an error and exit. } QSqlRecord rec = query.record(); aux = tr("Printing the log...\n QSO: ") + QString::number(_qsos) + "/" + QString::number(_numberOfQsos); progress.setLabelText(aux); progress.setValue(_qsos); while ((query.next()) && (!cancelPrinting)) { if (query.isValid()) { textTable->appendRows(1); row++; _qsos++; //qDebug() << "MainWindow::slotFilePrint: QSO: " << QString::number(_qsos) << " - Step: " << QString::number(step) << " - Div: " << QString::number(_qsos % step)<< endl; if (( (_qsos % step )== 0) ) { // To update the speed I will only show the progress once each X QSOs aux = tr("Printing the log...\n QSO: ") + QString::number(_qsos) + "/" + QString::number(_numberOfQsos); progress.setLabelText(aux); progress.setValue(_qsos); } nameCol = rec.indexOf("id"); cursor = textTable->cellAt(row, 0).firstCursorPosition(); cursor.insertText((query.value(nameCol)).toString()); nameCol = rec.indexOf("qso_date"); cursor = textTable->cellAt(row, 1).firstCursorPosition(); cursor.insertText((query.value(nameCol)).toString()); nameCol = rec.indexOf("time_on"); cursor = textTable->cellAt(row, 2).firstCursorPosition(); cursor.insertText((query.value(nameCol)).toString()); nameCol = rec.indexOf("call"); cursor = textTable->cellAt(row, 3).firstCursorPosition(); cursor.insertText((query.value(nameCol)).toString()); nameCol = rec.indexOf("rst_sent"); cursor = textTable->cellAt(row, 4).firstCursorPosition(); cursor.insertText((query.value(nameCol)).toString()); nameCol = rec.indexOf("rst_rcvd"); cursor = textTable->cellAt(row, 5).firstCursorPosition(); cursor.insertText((query.value(nameCol)).toString()); nameCol = rec.indexOf("bandid"); aux = (query.value(nameCol)).toString(); stringQuery = QString("SELECT name FROM band WHERE id='%1'").arg(aux); sqlOK = query1.exec(stringQuery); if (sqlOK) { query1.next(); if (query1.isValid()) { cursor = textTable->cellAt(row, 6).firstCursorPosition(); cursor.insertText((query1.value(0)).toString()); } } else { emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number(), query1.lastQuery()); } nameCol = rec.indexOf("modeid"); aux = (query.value(nameCol)).toString(); aux = dataProxy->getNameFromSubModeId(aux.toInt()); if (aux.length()>1) { cursor = textTable->cellAt(row, 7).firstCursorPosition(); cursor.insertText((query1.value(0)).toString()); } nameCol = rec.indexOf("comment"); aux = (query.value(nameCol)).toString(); if ((aux.length())>0) { cursor = textTable->cellAt(row, 8).firstCursorPosition(); cursor.insertText(aux); } } if ( progress.wasCanceled() ) { cancelPrinting = true; } } progress.setValue(_numberOfQsos); if (!cancelPrinting) { doc->print(&printer); } } } //DX-CLUSTER - DXCLUSTER void MainWindow::slotAnalyzeDxClusterSignal(QStringList ql) { //qDebug() << "MainWindow::slotAnalyzeDxClusterSignal: 1: " << ql.at(0) <<"/1: " << ql.at(1) << "/2: " << ql.at(2) << endl; QStringList qls; int _entity = world->getQRZARRLId(ql.at(0)); qls.clear(); QString _mode = "-1"; if (!manageMode) { _mode = "-1"; } if (ql.length()==3) { if ((ql.at(2)) == "double") { clusterSpotToLog(ql.at(0), ql.at(1)); } else if ((ql.at(2)) == "selected") { infoLabel2->setText(world->getEntityName(_entity)); infoWidget->showEntityInfo( _entity ); // Becareful, he Frecuency arrives in KHz instead of bandid!! // db.getBandFromFreq expects a MHz! //(ql.at(1)).toDouble() qls << QString::number(_entity) << QString::number(dataProxy->getBandIdFromFreq((ql.at(1).toDouble()/1000))) << _mode << QString::number(currentLog); // We use a mode = -1 because we don't know the mode info from the DXCluster spot // TODO: Check if we can know the mode and replace the "-1" in previous sentence //qls << QRZ << BandId << ModeId << lognumber; showStatusOfDXCC(qls); } else { } } else { // Signal was not properly emited } } double MainWindow::checkFreqRanges(double _f) { if ( (_f > double(0)) && (_f <= txFreqSpinBox->maximum())) { return _f; } else { return 0; } return 0; } //void MainWindow::clusterSpotToLog(const QStringList _qs) void MainWindow::clusterSpotToLog(const QString _call, const QString _freq) { //qDebug() << "MainWindow::clusterSpotToLog: " << _call <<"/" << _freq << endl; QString _aux; double _freqN = (_freq.toDouble()) / 1000; qrzLineEdit->setText(_call); //qrzLineEdit->setText(_qs.at(0)); txFreqSpinBox->setValue(checkFreqRanges(_freqN)); //freqQLCDNumber->display(_freqN); _aux = QString::number(_freqN); //qDebug() << "MainWindow::clusterSpotToLog - Freq: " << _aux << endl; int _bandi = dataProxy->getBandIdFromFreq(_aux.toDouble()); //qDebug() << "MainWindow::clusterSpotToLog - Bandi: " << QString::number(_bandi) << endl; _aux = QString::number(_bandi); _aux = QString("SELECT name FROM band WHERE id ='%1'").arg(_aux); //qDebug() << "MainWindow::clusterSpotToLog - Band: " << _aux << endl; QSqlQuery query(_aux); query.next(); if (query.isValid()) { _aux = (query.value(0)).toString(); bandComboBox->setCurrentIndex(bandComboBox->findText(_aux, Qt::MatchCaseSensitive)); } else { bandComboBox->setCurrentIndex(bandComboBox->findText(dataProxy->getNameFromBandId(defaultBand), Qt::MatchCaseSensitive)); //bandComboBox->setCurrentIndex(defaultBand); } } //DX-CLUSTER - DXCLUSTER void MainWindow::updateQSLRecAndSent() { //qDebug() << "MainWindow::updateQSLRecAndSent " << endl; // Checks the log to fill all the qsl_rcvd and qsl_sent QSqlQuery query, query1; QString queryString, aux, idT; //int nameCol=0; //queryString = QString("SELECT id, qsl_rcvd, qsl_sent FROM log WHERE lognumber='%1'").arg(currentLog); //queryString = QString("SELECT id, qsl_rcvd, qsl_sent FROM log WHERE qsl_rcvd !='Y' AND qsl_rcvd !='N' AND qsl_rcvd !='R' AND qsl_rcvd !='I' AND qsl_rcvd !='V' AND lognumber='%1'").arg(currentLog); //queryString = QString("SELECT id, qsl_rcvd, qsl_sent FROM log WHERE qsl_rcvd ='' OR qsl_sent ='' AND lognumber='%1'").arg(currentLog); queryString = QString("UPDATE log SET qsl_rcvd='N' WHERE qsl_rcvd ='' AND lognumber='%1'").arg(currentLog); bool sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } queryString = QString("UPDATE log SET qsl_sent='N' WHERE qsl_sent ='' AND lognumber='%1'").arg(currentLog); sqlOK = query.exec(queryString); if (!sqlOK) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } /* QSqlRecord rec = query.record(); int numberOfQsos = 0; int i = 0; numberOfQsos = dataProxy->getHowManyQSOInLog(currentLog); int step = util->getProgresStepForDialog(numberOfQsos); QProgressDialog progress(tr("Updating QSL status..."), tr("Abort updating"), 0, numberOfQsos, this); progress.setWindowModality(Qt::WindowModal); while (query.next()) { if (query.isValid()) { i++; nameCol = rec.indexOf("id"); idT = (query.value(nameCol)).toString(); //qDebug() << "MainWindow::updateQSLRecAndSent: " << idT << endl; // {Y, N, R, I, V} nameCol = rec.indexOf("qsl_rcvd"); aux = (query.value(nameCol)).toString(); if ( (aux != "Y") && (aux != "N") && (aux != "R") && (aux != "I") && (aux != "V") ) {//QSL_RCVD nameCol = rec.indexOf("qsl_sent"); aux = (query.value(nameCol)).toString(); //{Y, N, R, Q, I} if ( (aux != "Y") && (aux != "N") && (aux != "R") && (aux != "Q") && (aux != "I") ) {//QSL_SENT queryString = QString("UPDATE log SET qsl_rcvd='N', qsl_sent='N' WHERE id='%1'").arg(idT); if (!query1.exec(queryString)) { emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number(), query1.lastQuery()); } } else { queryString = QString("UPDATE log SET qsl_rcvd='N' WHERE id='%1'").arg(idT); if(!query1.exec(queryString)) { emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number(), query1.lastQuery()); } } } else {//QSL_SENT nameCol = rec.indexOf("qsl_sent"); aux = (query.value(nameCol)).toString(); //{Y, N, R, Q, I} if ( (aux != "Y") && (aux != "N") && (aux != "R") && (aux != "Q") && (aux != "I") ) {//QSL_SENT queryString = QString("UPDATE log SET qsl_sent='N' WHERE id='%1'").arg(idT); if(!query1.exec(queryString)) { emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number(), query1.lastQuery()); } } else { } } } if (( (i % step )== 0) ) { // To update the speed I will only show the progress once each X QSOs aux = tr("Updating QSLs...\n QSO: ") + QString::number(i) + "/" + QString::number(numberOfQsos); progress.setLabelText(aux); progress.setValue(i); } if ( progress.wasCanceled() ) { return; } } */ //qDebug() << "MainWindow::updateQSLRecAndSent - END" << endl; } void MainWindow::slotOperatingYearComboBoxChanged() { //qDebug() << "MainWindow::slotOperatingYearComboBoxChanged: " << operatingYearsComboBox->currentText() << endl; selectedYear = (operatingYearsComboBox->currentText()).toInt(); showDXMarathon(selectedYear); } void MainWindow::defineStationCallsign() { //qDebug() << "MainWindow::defineStationCallsign (currentLog): " << QString::number(currentLog) << endl; QString logQRZ; logQRZ = dataProxy->getStationCallSignFromLog(currentLog); //qDebug() << "MainWindow::defineStationCallsign (logQrz): " << logQRZ << endl; if (world->checkQRZValidFormat(logQRZ)) { stationQRZ = logQRZ; } else { stationQRZ = mainQRZ; } myDataTabWidget->setData(myPower, stationQRZ, operatorQRZ, myLocator); //qDebug() << "MainWindow::defineStationCallsign: " << stationQRZ << " - END" << endl; } void MainWindow::slotSetPropMode(const QString _p) { //qDebug() << "MainWindow::slotSetPropMode: " << _p << endl; //if(modify) //{ // return; //} othersTabWidget->setPropMode(_p); //int indexC = propModeComboBox->findText(" - " + _p + " - ", Qt::MatchContains); //propModeComboBox->setCurrentIndex(indexC); } void MainWindow::completeWithPreviousQSO(const QString _call) { //qDebug() << "MainWindow::completeWithPreviousQSO" << endl; //This function completes: Name, QTH, Locator, Entity, Iota if ((!completeWithPrevious) || (_call.length()<=0) || (dataProxy->isWorkedB4(_call, -1)<=0)) //if ( (_call.length()<=0) || (dataProxy->isWorkedB4(_call, -1)<=0)) { if (completedWithPreviousName) { nameLineEdit->clear(); completedWithPreviousName = false; nameLineEdit->setPalette(palBlack); } if (completedWithPreviousQTH) { qthLineEdit->clear(); completedWithPreviousQTH = false; qthLineEdit->setPalette(palBlack); } if (completedWithPreviousLocator) { locatorLineEdit->clear(); completedWithPreviousLocator = false; locatorLineEdit->setPalette(palBlack); } if (completedWithPreviousIOTA) { othersTabWidget->clearIOTA(); //iotaContinentComboBox->setCurrentIndex(0); //iotaNumberLineEdit->setText("000"); completedWithPreviousIOTA = false; //iotaNumberLineEdit->setPalette(palBlack); } if (completedWithPreviousQSLVia) { QSLTabWidget->setQSLVia(""); //qslViaLineEdit->clear(); completedWithPreviousQSLVia = false; //qslViaLineEdit->setPalette(palBlack); } return; } QString aux = QString(); aux = dataProxy->getNameFromQRZ(_call); if ((aux.length()>=0) && ((nameLineEdit->text()).length()<=0) ) { nameLineEdit->setPalette(palRed); completedWithPreviousName = true; nameLineEdit->setText(aux); } else if (completedWithPreviousName) { nameLineEdit->clear(); completedWithPreviousName = false; nameLineEdit->setPalette(palBlack); } else { } aux = dataProxy->getQTHFromQRZ(_call); if ((aux.length()>=0) && ((qthLineEdit->text()).length()<=0) ) { qthLineEdit->setPalette(palRed); completedWithPreviousQTH = true; qthLineEdit->setText(aux); } else if (completedWithPreviousQTH) { qthLineEdit->clear(); completedWithPreviousQTH = false; qthLineEdit->setPalette(palBlack); } aux = dataProxy->getLocatorFromQRZ(_call); if ((aux.length()>=0) && ((locatorLineEdit->text()).length()<=0) ) { locatorLineEdit->setPalette(palRed); locatorLineEdit->setText(aux); completedWithPreviousLocator=true; } else if (completedWithPreviousLocator) { locatorLineEdit->clear(); completedWithPreviousLocator = false; locatorLineEdit->setPalette(palBlack); } aux = dataProxy->getIOTAFromQRZ(_call); //othersTabWidget->setIOTA(aux); if ((aux.length()>=0) && (othersTabWidget->isIOTAModified()) ) { aux = awards->checkIfValidIOTA(aux); if ((aux.length())==6) { othersTabWidget->setIOTA(aux, false); //TODO: Decide if it is better this way or like in : void MainWindowInputQSL::setQSLVia(const QString _qs, QColor qColor) //QStringList values = aux.split("-", QString::SkipEmptyParts); //iotaContinentComboBox->setCurrentIndex( iotaContinentComboBox->findText(values.at(0) ) ); //iotaNumberLineEdit->setPalette(palRed); //iotaNumberLineEdit->setText(values.at(1)); completedWithPreviousIOTA=true; } else if (completedWithPreviousIOTA) { othersTabWidget->clearIOTA(); completedWithPreviousName = false; } } else if (completedWithPreviousIOTA) { othersTabWidget->clearIOTA(); completedWithPreviousIOTA = false; } aux = dataProxy->getQSLViaFromQRZ(_call); if ((aux.length()>=0) && ((QSLTabWidget->getQSLVia()).length()<=0) ) { QSLTabWidget->setQSLVia(aux, Qt::red); completedWithPreviousQSLVia=true; } else if (completedWithPreviousQSLVia) { QSLTabWidget->setQSLVia(""); } } void MainWindow::slotSatBandTXComboBoxChanged(const QString _q) { //qDebug() << "MainWindow::slotSatBandTXComboBoxChanged" << _q << endl; if (modify) { return; } bandComboBox->setCurrentIndex(bandComboBox->findText(_q, Qt::MatchCaseSensitive)); } void MainWindow::slotFreqTXChanged() { //qDebug() << "MainWindow::slotFreqTXChanged" << QString::number(txFreqSpinBox->value()) << endl; QString _q; int v = dataProxy->getBandIdFromFreq(txFreqSpinBox->value()); if ((v<0) || (modify)) { return; } _q = dataProxy->getNameFromBandId (v); if (bandComboBox->findText(_q, Qt::MatchCaseSensitive) < 0) {// The selected frequency is of a band that is not currently selected //qDebug() << "MainWindow::slotFreqTXChanged - New band found: " << _q << endl; if (dataProxy->getIdFromBandName(_q) > 1) {// Not affected if 0 (light) is the frequency // In this case the user should select the band in the setup //qDebug() << "MainWindow::slotFreqTXChanged - Band is valid: " << _q << endl; QStringList qsTemp; qsTemp.clear(); qsTemp << bands; qsTemp << _q; bands.clear(); bands << dataProxy->sortBandNamesBottonUp(qsTemp); bandComboBox->clear(); bandComboBox->addItems(bands); dxccStatusWidget->setBands(bands); satTabWidget->addBands(bands); //qDebug() << "MainWindow::slotFreqTXChanged - Band has been added!" << endl; } else { //qDebug() << "MainWindow::slotFreqTXChanged - Band is NOT valid: " << _q << endl; return; } } bandComboBox->setCurrentIndex(bandComboBox->findText(_q, Qt::MatchCaseSensitive)); } void MainWindow::slotFreqRXChanged() { QString _q; int v = dataProxy->getBandIdFromFreq(rxFreqSpinBox->value()); //qDebug() << "MainWindow::slotFreqRXChanged: F/v(rx): " << QString::number(rxFreqSpinBox->value()) << "/" << QString::number(v) << endl; if ((v<0) || (modify)) { return; } //int txv = dataProxy->getBandIdFromFreq(txFreqSpinBox->value()); if ((rxFreqSpinBox->value() > 0) && (txFreqSpinBox->value()<=0)) { // There is no TX freq but there is a RX Freq. Band Used (bandid) will be updated to the RX Freq _q = dataProxy->getNameFromBandId (v); bandComboBox->setCurrentIndex(bandComboBox->findText(_q, Qt::MatchCaseSensitive)); //qDebug() << "MainWindow::slotFreqRXChanged: NO TX, so RX" << endl; } else { //qDebug() << "MainWindow::slotFreqRXChanged: TX is there, no change" << endl; //_q = dataProxy->getNameFromBandId (v); } //qDebug() << "MainWindow::slotFreqRXChanged: END" << endl; } void MainWindow::slotQueryErrorManagement(QString functionFailed, QString errorCodeS, int errorCodeN, QString queryFailed) { //qDebug() << "MainWindow::slotQueryErrorManagement: Function: " << functionFailed << endl; //qDebug() << "MainWindow::slotQueryErrorManagement: Error N#: " << QString::number(errorCodeN) << endl; //qDebug() << "MainWindow::slotQueryErrorManagement: Error: " << functionFailed << errorCodeS << endl; if (noMoreErrorShown) {return;} // TODO: An error on DB has been detected. // KLog should suggest to export ALL the data to an ADIF file to prevent any log lose QString aux = "
" + tr("An unexpected error ocurred!!") + "

" + tr("If the problem persists, please contact the developers") + "(klog-devel@nongnu.org)" + tr("for analysis:") + "
"; QString errorMSG = "
    " "
  • " + tr("Error in function") + ": " + functionFailed + "
  • " + "
  • " + tr("Error code") +": " + QString::number(errorCodeN) + "
  • " + "
  • " + tr("Error text") + ": " + errorCodeS + "
  • " + "
  • " + tr("Failed query") + ": " + queryFailed + "
  • " + "

" "Recomendation: Export, periodically, your data to ADIF to prevent a potential data loss.
"; showErrorDialog->setText(aux + errorMSG); //showErrorDialog->setModal(true); showErrorDialog->exec(); QMessageBox msgBox; msgBox.setIcon(QMessageBox::Question); aux = tr("Do you want to keep showing errors?"); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Ok ); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: break; case QMessageBox::No: noMoreErrorShown = true; break; default: // should never be reached break; } } void MainWindow::slotChangeRXFreq(const QString _f) { rxFreqSpinBox->setValue(_f.toDouble()); } void MainWindow::slotChangeTXFreq(const QString _f) { txFreqSpinBox->setValue(_f.toDouble()); } void MainWindow::slotUpdateLocator(QString _loc) { locatorLineEdit->setText(_loc.toUpper()); } klog-0.9.2.9/contest_cqwwdxssb.cpp0000644000076700000620000004113613237613107015073 0ustar staff/*************************************************************************** contestcqwwdxssb.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "contest_cqwwdxssb.h" #include //#include /* V. MULTIPLIER: Two types of multiplier will be used. A multiplier of one (1) for each different zone contacted on each band. A multiplier of one (1) for each different country contacted on each band. Stations are permitted to contact their own country and zone for multiplier credit. The CQ Zone Map, DXCC country list, WAE country list, and WAC boundaries are standards. Maritime mobile stations count only for a zone multiplier. VI. POINTS: Contacts between stations on different continents are worth three (3) points. Contacts between stations on the same continent but different countries, one (1) point. Exception: For North American stations only, contacts between stations within the North American boundaries count two (2) points. Contacts between stations in the same country are permitted for zone or country multiplier credit but have zero (0) point value. VII. SCORING: All stations: the final score is the result of the total QSO points multiplied by the sum of your zone and country multipliers. Example: 1000 QSO points 100 multiplier (30 Zones + 70 Countries) = 100,000 (final score). */ ContestCQWWDXSSB::ContestCQWWDXSSB() { //qDebug() << "ContestCQWWDXSSB::ContestCQWWDXSSB2" << endl; constrid = 1; myEntity = ""; myCQz = ""; myContinent = ""; NA = -1; mycategory = ""; arrlSection = ""; stationQrz = ""; claimedScore = ""; name = ""; address = ""; operators = ""; soapbox = ""; thiscontest = ""; club = ""; createdby = ""; //qDebug() << "ContestCQWWDXSSB::ContestCQWWDXSSB1" << endl; } ContestCQWWDXSSB::ContestCQWWDXSSB(const QStringList _qs) { // Receives: QStringList _qs; //_qs << myEntity << myCQz << myContinent << NA-id; //qDebug() << "ContestCQWWDXSSB::ContestCQWWDXSSB- 2:" << endl; constrid = 2; myEntity = _qs.at(0); myCQz = _qs.at(1); myContinent = _qs.at(2); NA = _qs.at(3); // NA is North America for scoring purposes thiscontest = "CQ-WW-SSB"; mycategory = "SINGLE-OP ALL HIGH"; club = "NoClub"; createdby ="KLog-Alpha"; /* OFFICIAL CATEGORIES CATEGORY: SINGLE-OP ALL HIGH CATEGORY: SINGLE-OP 160M HIGH CATEGORY: SINGLE-OP 80M HIGH CATEGORY: SINGLE-OP 40M HIGH CATEGORY: SINGLE-OP 20M HIGH CATEGORY: SINGLE-OP 15M HIGH CATEGORY: SINGLE-OP 10M HIGH CATEGORY: SINGLE-OP ALL LOW CATEGORY: SINGLE-OP 160M LOW CATEGORY: SINGLE-OP 80M LOW CATEGORY: SINGLE-OP 40M LOW CATEGORY: SINGLE-OP 20M LOW CATEGORY: SINGLE-OP 15M LOW CATEGORY: SINGLE-OP 10M LOW CATEGORY: SINGLE-OP ALL QRP CATEGORY: SINGLE-OP 160M QRP CATEGORY: SINGLE-OP 80M QRP CATEGORY: SINGLE-OP 40M QRP CATEGORY: SINGLE-OP 20M QRP CATEGORY: SINGLE-OP 15M QRP CATEGORY: SINGLE-OP 10M QRP CATEGORY: SINGLE-OP-ASSISTED ALL CATEGORY: SINGLE-OP-ASSISTED 160M CATEGORY: SINGLE-OP-ASSISTED 80M CATEGORY: SINGLE-OP-ASSISTED 40M CATEGORY: SINGLE-OP-ASSISTED 20M CATEGORY: SINGLE-OP-ASSISTED 15M CATEGORY: SINGLE-OP-ASSISTED 10M CATEGORY: MULTI-ONE CATEGORY: MULTI-TWO CATEGORY: MULTI-MULTI CATEGORY: CHECKLOG */ arrlSection = "DX"; stationQrz = ""; claimedScore = "000"; name = "No-Name"; address = "MyPoBox\nADDRESS: SecondLineOfAddress"; operators = "EA4TV, EA4GCA"; soapbox = "MySoapbox\nSOAPBOX: Another line\nSOAPBOX: and even one more"; //qDebug() << "ContestCQWWDXSSB::ContestCQWWDXSSB: " << myEntity << "/" << myCQz << "/" << myContinent << "/" << NA << endl; //qDebug() << "ContestCQWWDXSSB::ContestCQWWDXSSB- 2: - END" << endl; } ContestCQWWDXSSB::~ContestCQWWDXSSB(){ } bool ContestCQWWDXSSB::isMultiplier(const QStringList _qs){ //qDebug() << "ContestCQWWDXSSB::isMultiplier" << endl; for (int i = 0; i<_qs.length(); i++){ ////qDebug() << _qs.at(i) <<", "; } // Receives: QStringList _qs; //_qs << DX-Entity << DXCQz << DX-band; // V. MULTIPLIER: Two types of multiplier will be used. // // A multiplier of one (1) for each different zone contacted on each band. // A multiplier of one (1) for each different country contacted on each band. // Stations are permitted to contact their own country and zone for multiplier credit. // The CQ Zone Map, DXCC country list, WAE country list, and WAC boundaries are standards. // Maritime mobile stations count only for a zone multiplier. if (_qs.length() != 3){ //qDebug() << "ContestCQWWDXSSB::isMultiplier: diferent THAN 3" << endl; return false; } QString dxEntity = _qs.at(0); QString dxCQz = _qs.at(1); if (!( (isValidCQz(dxCQz) ) && (isValidEntity(dxEntity) ) ) ){ return false; } //TODO: Check if the band is a valid string QString dxBand = _qs.at(2); // A multiplier of one (1) for each different zone contacted on each band. QString queryString; QSqlQuery query; queryString = QString("SELECT id FROM log WHERE bandid='%1' AND stx='%2'").arg(dxBand).arg(dxCQz); //qDebug() << "ContestCQWWDXSSB::isMultiplier-1: " << queryString << endl; bool sqlOK = query.exec(queryString); if (!sqlOK) { //emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number()); } query.next(); if (!(query.isValid())){ //qDebug() << "ContestCQWWDXSSB::isMultiplier: Not Worked Zone" << endl; return true; } // A multiplier of one (1) for each different country contacted on each band. queryString = QString("SELECT id FROM log WHERE bandid='%1' AND dxcc='%2'").arg(dxBand).arg(dxEntity); //qDebug() << "ContestCQWWDXSSB::isMultiplier-2: " << queryString << endl; sqlOK = query.exec(queryString); if (!sqlOK) { //emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number()); } query.next(); if (!(query.isValid())){ //qDebug() << "ContestCQWWDXSSB::isMultiplier: MULT2 - Not worked DXCC" << endl; return true; } return false; } int ContestCQWWDXSSB::getQSOPoints(const QStringList _qs){ //qDebug() << "ContestCQWWDXSSB::getQSOPoints" << endl; // Receives: QStringList _qs; //_qs << DX-Entity << DX-Continent // VI. POINTS: // // Contacts between stations on different continents are worth three (3) points. // Contacts between stations on the same continent but different countries, one (1) point. // Exception: For North American stations only, contacts between stations within the North American // boundaries count two (2) points. // // Contacts between stations in the same country are permitted for zone or country multiplier // credit but have zero (0) point value. if (_qs.length() != 2){ return false; } QString dxEntity =_qs.at(0); QString dxContinent = _qs.at(1); if (myContinent != dxContinent){ return 3; }else if (myContinent == NA) { return 2; } else if (myEntity != dxEntity){ return 1; }else{ return 0; } return 0; } bool ContestCQWWDXSSB::isValidCQz(const QString _cqz){ //qDebug() << "ContestCQWWDXSSB::isValidCQz: " << _cqz << endl; if ( (_cqz.toInt()>0) && (_cqz.toInt()<41) ){ return true; }else{ return false; } return false; } bool ContestCQWWDXSSB::isValidEntity(const QString _ent){ //qDebug() << "ContestCQWWDXSSB::isValidEntity: " << _ent << endl; if ( (_ent.toInt()>0) ) { return true; }else{ return false; } return false; } bool ContestCQWWDXSSB::saveFileToSend(const QString& _fileName) { //qDebug() << "Contest::saveFileToSend" << _fileName << endl; QFile file(_fileName); QSqlQuery query1; if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return false; QTextStream out(&file); //_qs << myEntity << myCQz << myContinent << NA-id; //myARRLSect << StationQRZ << myCategory << myClub << //myAddress << operators(comma separated EA4TV, EA4GCA, ...) //SoapBox out << "START-OF-LOG: 3" << endl; out << "ARRL-SECTION: " << arrlSection << endl; out << "CALLSIGN: " << stationQrz << endl; out << "CATEGORY: " + mycategory << endl; out << "CLAIMED-SCORE: " << claimedScore << endl; out << "CLUB: " << club << endl; out << "CONTEST: " << thiscontest << endl; out << "NAME: " << name << endl; out << "ADDRESS: " << address << endl; out << "CREATED-BY: " << createdby << endl; out << "OPERATORS: " << operators << endl;// [required for multi-op stations] out << "SOAPBOX: " << soapbox << endl; //[add lines if needed] QSqlQuery query("SELECT * FROM log"); QSqlRecord rec = query.record(); int nameCol; QString aux1, aux2, queryString; /* START-OF-LOG: 3.0 CONTEST: CQ-WW-RTTY CONTEST: CQ-WW-SSB CONTEST: CQ-WW-CW CALLSIGN: LU6ETB CATEGORY-OPERATOR: SINGLE-OP CATEGORY-BAND: 10M CATEGORY-POWER: HIGH CATEGORY-ASSISTED: NON-ASSISTED CLAIMED-SCORE: 1410 OPERATORS: N5KO CLUB: Radio Club Quilmes NAME: Trey Garlough ADDRESS: 7375 Oak Ridge Road ADDRESS-CITY: Aptos ADDRESS-STATE: CA ADDRESS-POSTALCODE: 95003 ADDRESS-COUNTRY: USA QSO: 3799 PH 2000-11-26 0711 N6TW 59 03 K9QZO 59 04 0 END-OF-LOG: */ while (query.next()) { if ( query.isValid()) { out << "QSO: "; nameCol = rec.indexOf("freq"); aux1 = (query.value(nameCol)).toString(); if (aux1.length()<1) { nameCol = rec.indexOf("bandid"); aux1 = (query.value(nameCol)).toString(); queryString = QString("SELECT cabrillo FROM band WHERE id='%1'").arg(aux1); bool sqlOK = query1.exec(queryString); if (!sqlOK) { //emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number()); } query1.next(); if (query1.isValid()) { aux1 = query1.value(0).toString(); //qDebug() << "ContestCQWWDXSSB::saveFileToSend: band: " << queryString << "/" << aux1 << endl; if (!(aux1.length()>1)) { aux1 = " NULL"; } } } aux1.remove(QChar('.'), Qt::CaseInsensitive); out << aux1.rightJustified(5, ' ', true) << " "; nameCol = rec.indexOf("modeid"); aux1 = (query.value(nameCol)).toString(); queryString = QString("SELECT name FROM mode WHERE id='%1'").arg(aux1); bool sqlOK = query1.exec(queryString); if (!sqlOK) { //emit queryError(Q_FUNC_INFO, query1.lastError().databaseText(), query1.lastError().number()); } query1.next(); if (query1.isValid()) { aux1 = (query1.value(0)).toString(); if (aux1=="RTTY") { out << "RY "; } else if (aux1=="CW") { out << "CW "; } else { out << "PH "; } } nameCol = rec.indexOf("qso_date"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "ContestCQWWDXSSB::saveFileToSend date: " << aux1 << endl; aux1.replace(QString("/"), QString("-")); if ((aux1.length()) == 10) { out << aux1 << " "; } nameCol = rec.indexOf("time_on"); aux1 = (query.value(nameCol)).toString(); //qDebug() << "ContestCQWWDXSSB::saveFileToSend time1: " << aux1 << endl; aux1.remove(QChar(':'), Qt::CaseInsensitive); aux1.truncate(4); aux1 = aux1.leftJustified(4, '0', true); out << aux1 << " "; //qDebug() << "ContestCQWWDXSSB::saveFileToSend time2: " << aux1 << endl; nameCol = rec.indexOf("station_callsign"); aux1 = (query.value(nameCol)).toString(); if (aux1.length()<3) { nameCol = rec.indexOf("operator"); aux1 = (query.value(nameCol)).toString(); } out << aux1.leftJustified(13, ' ', true) << " "; nameCol = rec.indexOf("rst_sent"); aux1 = (query.value(nameCol)).toString(); aux1.truncate(3); out << aux1.leftJustified(3, ' ', true) << " "; //qDebug() << "ContestCQWWDXSSB::saveFileToSend: rsttx" << aux1 << endl; nameCol = rec.indexOf("stx"); aux1 = (query.value(nameCol)).toString(); aux1.truncate(6); out << aux1.leftJustified(6, ' ', true) << " "; nameCol = rec.indexOf("call"); aux1 = (query.value(nameCol)).toString(); aux1.truncate(13); out << aux1.leftJustified(13, ' ') << " "; nameCol = rec.indexOf("rst_rcvd"); aux1 = (query.value(nameCol)).toString(); out << aux1.leftJustified(3, ' ', true) << " "; nameCol = rec.indexOf("srx"); aux1 = (query.value(nameCol)).toString(); aux1.truncate(6); out << aux1.leftJustified(6, ' ', true) << " "; nameCol = rec.indexOf("transmiterid"); aux1 = (query.value(nameCol)).toString(); aux1.truncate(1); out << aux1 ; // out << "0"; // This is the RIG used to log the QSO. 1 is used as out << endl; } } out << "END-OF-LOG:" << endl; return true; } int ContestCQWWDXSSB::getTotalScore() { return (getMultipliers()) * (getPoints()); } int ContestCQWWDXSSB::getMultipliers() { int multipliers = 0; QSqlQuery query("SELECT * FROM log"); QSqlRecord rec = query.record(); int nameCol = rec.indexOf("multiplier"); while (query.next()) { if (query.isValid()) { multipliers += (query.value(nameCol)).toInt(); } } return multipliers; } int ContestCQWWDXSSB::getPoints() { int points = 0; QSqlQuery query("SELECT * FROM log"); QSqlRecord rec = query.record(); int nameCol = rec.indexOf("points"); while (query.next()) { if (query.isValid()) { points += (query.value(nameCol)).toInt(); } } return points; } klog-0.9.2.9/startwizard.cpp0000644000076700000620000015350213233376355013675 0ustar staff#include "startwizard.h" //#include StartWizard::StartWizard(const QString _klogDir, const QString _softVersion, QWidget *parent) : QWizard(parent) { //qDebug() << "StartWizard::StartWizard: v=" << _softVersion << endl; //licAcepted = false; version = _softVersion; klogDir = _klogDir; inMemory = true; //fileOrMemoryPage = new FileOrMemoryPage(); ctyPage = new CTYPage(klogDir, version); setWizardStyle(QWizard::AeroStyle); setPage(Page_Intro, new IntroPage); setPage(Page_Lic, new LicPage); //setPage(Page_Mem, new FileOrMemoryPage); setPage(Page_CTY, ctyPage); setStartId(Page_Intro); QAbstractButton* finishButton = this->button(QWizard::FinishButton); QAbstractButton* cancelButton = this->button(QWizard::CancelButton); connect(finishButton, SIGNAL(clicked()), this, SLOT(slotButtonFinishedClicked())); disconnect( cancelButton, SIGNAL( clicked() ), this, SLOT( reject() ) ); connect(cancelButton, SIGNAL( clicked() ), this, SLOT( slotCancelWizard() ) ); //connect(fileOrMemoryPage, SIGNAL(exeInMemory(bool)), this, SLOT(slotRunInMemory(bool) ) ); //connect(ctyPage, SIGNAL(downloadTheFileSignal(bool)), this, SLOT(slotDownloadCTY(bool) ) ); QList layout; layout << QWizard::Stretch << QWizard::BackButton << QWizard::CancelButton << QWizard::NextButton << QWizard::FinishButton; setButtonLayout(layout); setWindowTitle(tr("KLog - The free hamradio logging program")); //qDebug() << "StartWizard::StartWizard: - END" << endl; } void StartWizard::setVersion(QString tversion) { version = tversion; } /*void StartWizard::slotUpdateDownloadProgress(qint64 received, qint64 total) { //qDebug() << "StartWizard::slotUpdateDownloadProgress: " << QString::number(received) << "/" << QString::number(total) << endl; ctyPage->updateProgress(received, total); } */ /* void StartWizard::slotDownloadFinished() { //qDebug() << "StartWizard::slotDownloadFinished" << endl; //close(); } */ void StartWizard::slotCancelWizard() { if( QMessageBox::question( this, tr("Quit Setup"), tr("Setup is not complete yet. Are you sure you want to quit setup?"), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes ) { // allow cancel reject(); } } void StartWizard::slotRunInMemory(bool checked) { if (checked) { inMemory = true; } else { inMemory = false; } } void StartWizard::slotButtonFinishedClicked() { //qDebug() << "StartWizard::slotButtonFinishedClicked " << endl; if (inMemory) { setResult(1); //qDebug() << "StartWizard::slotButtonFinishedClicked: done 1 " << endl; } else { //qDebug() << "StartWizard::slotButtonFinishedClicked: done 2 " << endl; setResult(2); } } /* bool StartWizard::doTheDownload() { //qDebug() << "StartWizard::doTheDownload" << endl; int downloading = 1; int i = 0; int ret; QMessageBox msgBox; QString str; msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); i = dl->download(); if (downloadValueResult == 0) { return true; } return false; } void StartWizard::slotValueReturnedFromDownload(int value) { //qDebug() << "StartWizard::slotValueReturnedFromDownload: " << QString::number(value) << endl; downloadValueResult = value; //close(); } */ IntroPage::IntroPage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Welcome to KLog!")); topLabel = new QLabel(tr("Welcome to KLog! " "- brought to you under the terms of the GPL!")); topLabel->setWordWrap(true); welcomeBrowser = new QTextEdit; welcomeBrowser->setReadOnly(true); QString welcometxt = "" + tr("Welcome to KLog") + "" + "

" + tr("This looks like it's the first time you've run KLog on this computer.") + "

" + "

" + tr("KLog is a free hamradio logging program that can run on Linux macOS and Windows.") + tr("It is designed to provide general purpose, DX and contest logging.") + "

" + "

" + tr("It supports QSL management, import and export of ADIF ") + tr("and Cabrillo file formats and many other features...") + "

" + tr("Before you can start using KLog, you will be asked to:") + "

    " + "
  • " + tr("Acknowledge to the terms of the license.") + "
  • " + "
  • " + tr("Download the DX entities information.") + "
  • " + "
  • " + tr("Enter your callsign, CQ zone, etc. and main configuration.") + "
" + "

" + tr("Enjoy KLog and contact the development team if you have any suggestions!") + "

" + "

73 de EA4TV

"; welcomeBrowser->setHtml(welcometxt); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(welcomeBrowser); setLayout(layout); } int IntroPage::nextId() const { return StartWizard::Page_Lic; } LicPage::LicPage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("KLog License information")); //setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark.png")); topLabel = new QLabel(tr("Welcome to KLog!" "- brought to you under the terms of the GPL!")); topLabel->setWordWrap(true); licenseBrowser = new QTextEdit; licenseBrowser->setReadOnly(true); QString gplLic = "" "GNU General Public License v3.0 - GNU Project - Free Software Foundation (FSF)" "" "" "

GNU GENERAL PUBLIC LICENSE

" "

Version 3, 29 June 2007

" "

Copyright (c) 2007 Free Software Foundation, Inc.

" "

Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

" "

Preamble

" "

The GNU General Public License is a free, copyleft license for software and other kinds of works.

" "

The licenses for most software and other practical works are designed " "to take away your freedom to share and change the works. By contrast, " "the GNU General Public License is intended to guarantee your freedom to " "share and change all versions of a program--to make sure it remains free " "software for all its users. We, the Free Software Foundation, use the " "GNU General Public License for most of our software; it applies also to " "any other work released this way by its authors. You can apply it to " "your programs, too.

" "

When we speak of free software, we are referring to freedom, not " "price. Our General Public Licenses are designed to make sure that you " "have the freedom to distribute copies of free software (and charge for " "them if you wish), that you receive source code or can get it if you " "want it, that you can change the software or use pieces of it in new " "free programs, and that you know you can do these things.

" "

To protect your rights, we need to prevent others from denying you " "these rights or asking you to surrender the rights. Therefore, you have " "certain responsibilities if you distribute copies of the software, or if " "you modify it: responsibilities to respect the freedom of others.

" "

For example, if you distribute copies of such a program, whether " "gratis or for a fee, you must pass on to the recipients the same " "freedoms that you received. You must make sure that they, too, receive " "or can get the source code. And you must show them these terms so they " "know their rights.

" "

Developers that use the GNU GPL protect your rights with two steps: " "(1) assert copyright on the software, and (2) offer you this License " "giving you legal permission to copy, distribute and/or modify it.

" "

For the developers' and authors' protection, the GPL clearly explains " "that there is no warranty for this free software. For both users' and " "authors' sake, the GPL requires that modified versions be marked as " "changed, so that their problems will not be attributed erroneously to " "authors of previous versions.

" "

Some devices are designed to deny users access to install or run " "modified versions of the software inside them, although the manufacturer " "can do so. This is fundamentally incompatible with the aim of " "protecting users' freedom to change the software. The systematic " "pattern of such abuse occurs in the area of products for individuals to " "use, which is precisely where it is most unacceptable. Therefore, we " "have designed this version of the GPL to prohibit the practice for those " "products. If such problems arise substantially in other domains, we " "stand ready to extend this provision to those domains in future versions " "of the GPL, as needed to protect the freedom of users.

" "

Finally, every program is threatened constantly by software patents." "States should not allow patents to restrict development and use of " "software on general-purpose computers, but in those that do, we wish to " "avoid the special danger that patents applied to a free program could " "make it effectively proprietary. To prevent this, the GPL assures that " "patents cannot be used to render the program non-free.

" "

The precise terms and conditions for copying, distribution and " "modification follow.

" "

TERMS AND CONDITIONS

" "

0. Definitions.

" "

This License refers to version 3 of the GNU General Public License.

" "

Copyright also means copyright-like laws that apply to other kinds of " "works, such as semiconductor masks.

" "

The Program refers to any copyrightable work licensed under this " "License. Each licensee is addressed as you. Licensees and " "recipients may be individuals or organizations.

" "

To modify a work means to copy from or adapt all or part of the work " "in a fashion requiring copyright permission, other than the making of an " "exact copy. The resulting work is called a modified version of the " "earlier work or a work based on the earlier work.

" "

A covered work means either the unmodified Program or a work based " "on the Program.

" "

To propagate a work means to do anything with it that, without " "permission, would make you directly or secondarily liable for " "infringement under applicable copyright law, except executing it on a " "computer or modifying a private copy. Propagation includes copying, " "distribution (with or without modification), making available to the " "public, and in some countries other activities as well.

" "

To convey a work means any kind of propagation that enables other " "parties to make or receive copies. Mere interaction with a user through " "a computer network, with no transfer of a copy, is not conveying.

" "

An interactive user interface displays Appropriate Legal Notices " "to the extent that it includes a convenient and prominently visible " "feature that (1) displays an appropriate copyright notice, and (2) " "tells the user that there is no warranty for the work (except to the " "extent that warranties are provided), that licensees may convey the " "work under this License, and how to view a copy of this License. If " "the interface presents a list of user commands or options, such as a " "menu, a prominent item in the list meets this criterion.

" "

1. Source Code.

" "

The source code for a work means the preferred form of the work " "for making modifications to it. Object code means any non-source " "form of a work.

" "

A Standard Interface means an interface that either is an official " "standard defined by a recognized standards body, or, in the case of " "interfaces specified for a particular programming language, one that " "is widely used among developers working in that language.

" "

The System Libraries of an executable work include anything, other " "than the work as a whole, that (a) is included in the normal form of " "packaging a Major Component, but which is not part of that Major " "Component, and (b) serves only to enable use of the work with that " "Major Component, or to implement a Standard Interface for which an " "implementation is available to the public in source code form. A " "Major Component, in this context, means a major essential component " "(kernel, window system, and so on) of the specific operating system " "(if any) on which the executable work runs, or a compiler used to " "produce the work, or an object code interpreter used to run it.

" "

The Corresponding Source for a work in object code form means all " "the source code needed to generate, install, and (for an executable " "work) run the object code and to modify the work, including scripts to " "control those activities. However, it does not include the work's " "System Libraries, or general-purpose tools or generally available free " "programs which are used unmodified in performing those activities but " "which are not part of the work. For example, Corresponding Source " "includes interface definition files associated with source files for " "the work, and the source code for shared libraries and dynamically " "linked subprograms that the work is specifically designed to require, " "such as by intimate data communication or control flow between those " "subprograms and other parts of the work.

" "

The Corresponding Source need not include anything that users " "can regenerate automatically from other parts of the Corresponding " "Source.

" "

The Corresponding Source for a work in source code form is that " "same work.

" "

2. Basic Permissions.

" "

All rights granted under this License are granted for the term of " "copyright on the Program, and are irrevocable provided the stated " "conditions are met. This License explicitly affirms your unlimited " "permission to run the unmodified Program. The output from running a " "covered work is covered by this License only if the output, given its " "content, constitutes a covered work. This License acknowledges your " "rights of fair use or other equivalent, as provided by copyright law.

" "

You may make, run and propagate covered works that you do not " "convey, without conditions so long as your license otherwise remains " "in force. You may convey covered works to others for the sole purpose " "of having them make modifications exclusively for you, or provide you " "with facilities for running those works, provided that you comply with " "the terms of this License in conveying all material for which you do " "not control copyright. Those thus making or running the covered works " "for you must do so exclusively on your behalf, under your direction " "and control, on terms that prohibit them from making any copies of " "your copyrighted material outside their relationship with you.

" "

Conveying under any other circumstances is permitted solely under " "the conditions stated below. Sublicensing is not allowed; section 10 " "makes it unnecessary.

" "

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

" "

No covered work shall be deemed part of an effective technological " "measure under any applicable law fulfilling obligations under article " "11 of the WIPO copyright treaty adopted on 20 December 1996, or " "similar laws prohibiting or restricting circumvention of such " "measures.

" "

When you convey a covered work, you waive any legal power to forbid " "circumvention of technological measures to the extent such circumvention " "is effected by exercising rights under this License with respect to " "the covered work, and you disclaim any intention to limit operation or " "modification of the work as a means of enforcing, against the work's " "users, your or third parties' legal rights to forbid circumvention of " "technological measures.

" "

4. Conveying Verbatim Copies.

" "

You may convey verbatim copies of the Program's source code as you " "receive it, in any medium, provided that you conspicuously and " "appropriately publish on each copy an appropriate copyright notice; " "keep intact all notices stating that this License and any " "non-permissive terms added in accord with section 7 apply to the code; " "keep intact all notices of the absence of any warranty; and give all " "recipients a copy of this License along with the Program.

" "

You may charge any price or no price for each copy that you convey, " "and you may offer support or warranty protection for a fee.

" "

5. Conveying Modified Source Versions.

" "

You may convey a work based on the Program, or the modifications to " "produce it from the Program, in the form of source code under the " "terms of section 4, provided that you also meet all of these conditions:

" "
    " "
  • a) The work must carry prominent notices stating that you modified" "it, and giving a relevant date.
  • " "
  • b) The work must carry prominent notices stating that it is " "released under this License and any conditions added under section " "7. This requirement modifies the requirement in section 4 to " "keep intact all notices.
  • " "
  • c) You must license the entire work, as a whole, under this " "License to anyone who comes into possession of a copy. This " "License will therefore apply, along with any applicable section 7 " "additional terms, to the whole of the work, and all its parts, " "regardless of how they are packaged. This License gives no " "permission to license the work in any other way, but it does not " "invalidate such permission if you have separately received it.
  • " "
  • d) If the work has interactive user interfaces, each must display " "Appropriate Legal Notices; however, if the Program has interactive " "interfaces that do not display Appropriate Legal Notices, your " "work need not make them do so.
  • " "
" "

A compilation of a covered work with other separate and independent " "works, which are not by their nature extensions of the covered work, " "and which are not combined with it such as to form a larger program, " "in or on a volume of a storage or distribution medium, is called an " "aggregate if the compilation and its resulting copyright are not " "used to limit the access or legal rights of the compilation's users " "beyond what the individual works permit. Inclusion of a covered work " "in an aggregate does not cause this License to apply to the other " "parts of the aggregate.

" "

6. Conveying Non-Source Forms.

" "

You may convey a covered work in object code form under the terms " "of sections 4 and 5, provided that you also convey the " "machine-readable Corresponding Source under the terms of this License, " "in one of these ways:

" "
    " "
  • a) Convey the object code in, or embodied in, a physical product " "(including a physical distribution medium), accompanied by the " "Corresponding Source fixed on a durable physical medium " "customarily used for software interchange.
  • " "
  • b) Convey the object code in, or embodied in, a physical product " "(including a physical distribution medium), accompanied by a " "written offer, valid for at least three years and valid for as " "long as you offer spare parts or customer support for that product " "model, to give anyone who possesses the object code either (1) a " "copy of the Corresponding Source for all the software in the " "product that is covered by this License, on a durable physical " "medium customarily used for software interchange, for a price no " "more than your reasonable cost of physically performing this " "conveying of source, or (2) access to copy the " "Corresponding Source from a network server at no charge.
  • " "
  • c) Convey individual copies of the object code with a copy of the " "written offer to provide the Corresponding Source. This " "alternative is allowed only occasionally and noncommercially, and " "only if you received the object code with such an offer, in accord " "with subsection 6b.
  • " "
  • d) Convey the object code by offering access from a designated " "place (gratis or for a charge), and offer equivalent access to the " "Corresponding Source in the same way through the same place at no " "further charge. You need not require recipients to copy the " "Corresponding Source along with the object code. If the place to " "copy the object code is a network server, the Corresponding Source " "may be on a different server (operated by you or a third party) " "that supports equivalent copying facilities, provided you maintain " "clear directions next to the object code saying where to find the " "Corresponding Source. Regardless of what server hosts the " "Corresponding Source, you remain obligated to ensure that it is " "available for as long as needed to satisfy these requirements.
  • " "
  • e) Convey the object code using peer-to-peer transmission, provided " "you inform other peers where the object code and Corresponding " "Source of the work are being offered to the general public at no " "charge under subsection 6d.
  • " "
" "

A separable portion of the object code, whose source code is excluded " "from the Corresponding Source as a System Library, need not be " "included in conveying the object code work.

" "

A User Product is either (1) a consumer product, which means any " "tangible personal property which is normally used for personal, family, " "or household purposes, or (2) anything designed or sold for incorporation " "into a dwelling. In determining whether a product is a consumer product, " "doubtful cases shall be resolved in favor of coverage. For a particular " "product received by a particular user, normally used refers to a " "typical or common use of that class of product, regardless of the status " "of the particular user or of the way in which the particular user " "actually uses, or expects or is expected to use, the product. A product " "is a consumer product regardless of whether the product has substantial " "commercial, industrial or non-consumer uses, unless such uses represent " "the only significant mode of use of the product.

" "

Installation Information for a User Product means any methods, " "procedures, authorization keys, or other information required to install " "and execute modified versions of a covered work in that User Product from " "a modified version of its Corresponding Source. The information must " "suffice to ensure that the continued functioning of the modified object " "code is in no case prevented or interfered with solely because " "modification has been made.

" "

If you convey an object code work under this section in, or with, or " "specifically for use in, a User Product, and the conveying occurs as " "part of a transaction in which the right of possession and use of the " "User Product is transferred to the recipient in perpetuity or for a " "fixed term (regardless of how the transaction is characterized), the " "Corresponding Source conveyed under this section must be accompanied " "by the Installation Information. But this requirement does not apply " "if neither you nor any third party retains the ability to install " "modified object code on the User Product (for example, the work has " "been installed in ROM).

" "

The requirement to provide Installation Information does not include a " "requirement to continue to provide support service, warranty, or updates " "for a work that has been modified or installed by the recipient, or for " "the User Product in which it has been modified or installed. Access to a " "network may be denied when the modification itself materially and " "adversely affects the operation of the network or violates the rules and " "protocols for communication across the network.

" "

Corresponding Source conveyed, and Installation Information provided, " "in accord with this section must be in a format that is publicly " "documented (and with an implementation available to the public in " "source code form), and must require no special password or key for " "unpacking, reading or copying.

" "

7. Additional Terms.

" "

Additional permissions are terms that supplement the terms of this " "License by making exceptions from one or more of its conditions. " "Additional permissions that are applicable to the entire Program shall " "be treated as though they were included in this License, to the extent " "that they are valid under applicable law. If additional permissions " "apply only to part of the Program, that part may be used separately " "under those permissions, but the entire Program remains governed by " "this License without regard to the additional permissions.

" "

When you convey a copy of a covered work, you may at your option " "remove any additional permissions from that copy, or from any part of " "it. (Additional permissions may be written to require their own " "removal in certain cases when you modify the work.) You may place " "additional permissions on material, added by you to a covered work, " "for which you have or can give appropriate copyright permission.

" "

Notwithstanding any other provision of this License, for material you " "add to a covered work, you may (if authorized by the copyright holders of " "that material) supplement the terms of this License with terms:

" "
    " "
  • a) Disclaiming warranty or limiting liability differently from the " " terms of sections 15 and 16 of this License; or
  • " "
  • b) Requiring preservation of specified reasonable legal notices or " "author attributions in that material or in the Appropriate Legal " "Notices displayed by works containing it; or
  • " "
  • c) Prohibiting misrepresentation of the origin of that material, or " "requiring that modified versions of such material be marked in " "reasonable ways as different from the original version; or
  • " "
  • d) Limiting the use for publicity purposes of names of licensors or " "authors of the material; or
  • " "
  • e) Declining to grant rights under trademark law for use of some " "trade names, trademarks, or service marks; or
  • " "
  • f) Requiring indemnification of licensors and authors of that " "material by anyone who conveys the material (or modified versions of " "it) with contractual assumptions of liability to the recipient, for " "any liability that these contractual assumptions directly impose on " "those licensors and authors.
  • " "
" "

All other non-permissive additional terms are considered further " "restrictions within the meaning of section 10. If the Program as you " "received it, or any part of it, contains a notice stating that it is " "governed by this License along with a term that is a further " "restriction, you may remove that term. If a license document contains " "a further restriction but permits relicensing or conveying under this " "License, you may add to a covered work material governed by the terms " "of that license document, provided that the further restriction does " "not survive such relicensing or conveying.

" "

If you add terms to a covered work in accord with this section, you " "must place, in the relevant source files, a statement of the " "additional terms that apply to those files, or a notice indicating " "where to find the applicable terms.

" "

Additional terms, permissive or non-permissive, may be stated in the " "form of a separately written license, or stated as exceptions; " "the above requirements apply either way.

" "

8. Termination.

" "

You may not propagate or modify a covered work except as expressly " "provided under this License. Any attempt otherwise to propagate or " "modify it is void, and will automatically terminate your rights under " "this License (including any patent licenses granted under the third " "paragraph of section 11).

" "

However, if you cease all violation of this License, then your " "license from a particular copyright holder is reinstated (a) " "provisionally, unless and until the copyright holder explicitly and " "finally terminates your license, and (b) permanently, if the copyright " "holder fails to notify you of the violation by some reasonable means " "prior to 60 days after the cessation.

" "

Moreover, your license from a particular copyright holder is " "reinstated permanently if the copyright holder notifies you of the " "violation by some reasonable means, this is the first time you have " "received notice of violation of this License (for any work) from that " "copyright holder, and you cure the violation prior to 30 days after " "your receipt of the notice.

" "

Termination of your rights under this section does not terminate the " "licenses of parties who have received copies or rights from you under " "this License. If your rights have been terminated and not permanently " "reinstated, you do not qualify to receive new licenses for the same " "material under section 10.

" "

9. Acceptance Not Required for Having Copies.

" "

You are not required to accept this License in order to receive or " "run a copy of the Program. Ancillary propagation of a covered work " "occurring solely as a consequence of using peer-to-peer transmission " "to receive a copy likewise does not require acceptance. However, " "nothing other than this License grants you permission to propagate or " "modify any covered work. These actions infringe copyright if you do " "not accept this License. Therefore, by modifying or propagating a " "covered work, you indicate your acceptance of this License to do so.

" "

10. Automatic Licensing of Downstream Recipients.

" "

Each time you convey a covered work, the recipient automatically " "receives a license from the original licensors, to run, modify and " "propagate that work, subject to this License. You are not responsible " "for enforcing compliance by third parties with this License.

" "

An entity transaction is a transaction transferring control of an " "organization, or substantially all assets of one, or subdividing an " "organization, or merging organizations. If propagation of a covered " "work results from an entity transaction, each party to that " "transaction who receives a copy of the work also receives whatever " "licenses to the work the party's predecessor in interest had or could " "give under the previous paragraph, plus a right to possession of the " "Corresponding Source of the work from the predecessor in interest, if " "the predecessor has it or can get it with reasonable efforts.

" "

You may not impose any further restrictions on the exercise of the " "rights granted or affirmed under this License. For example, you may" "not impose a license fee, royalty, or other charge for exercise of " "rights granted under this License, and you may not initiate litigation " "(including a cross-claim or counterclaim in a lawsuit) alleging that " "any patent claim is infringed by making, using, selling, offering for " "sale, or importing the Program or any portion of it.

" "

11. Patents.

" "

A contributor is a copyright holder who authorizes use under this " "License of the Program or a work on which the Program is based. The " "work thus licensed is called the contributor's contributor version.

" "

A contributor's essential patent claims are all patent claims " "owned or controlled by the contributor, whether already acquired or " "hereafter acquired, that would be infringed by some manner, permitted " "by this License, of making, using, or selling its contributor version, " "but do not include claims that would be infringed only as a " "consequence of further modification of the contributor version. For " "purposes of this definition, control includes the right to grant " "patent sublicenses in a manner consistent with the requirements of " "this License.

" "

Each contributor grants you a non-exclusive, worldwide, royalty-free " "patent license under the contributor's essential patent claims, to " "make, use, sell, offer for sale, import and otherwise run, modify and " "propagate the contents of its contributor version.

" "

In the following three paragraphs, a patent license is any express " "agreement or commitment, however denominated, not to enforce a patent " "(such as an express permission to practice a patent or covenant not to " "sue for patent infringement). To grant such a patent license to a " "party means to make such an agreement or commitment not to enforce a " "patent against the party.

" "

If you convey a covered work, knowingly relying on a patent license, " "and the Corresponding Source of the work is not available for anyone " "to copy, free of charge and under the terms of this License, through a " "publicly available network server or other readily accessible means, " "then you must either (1) cause the Corresponding Source to be so " "available, or (2) arrange to deprive yourself of the benefit of the " "patent license for this particular work, or (3) arrange, in a manner " "consistent with the requirements of this License, to extend the patent " "license to downstream recipients. Knowingly relying means you have " "actual knowledge that, but for the patent license, your conveying the " "covered work in a country, or your recipient's use of the covered work " "in a country, would infringe one or more identifiable patents in that " "country that you have reason to believe are valid.

" "

If, pursuant to or in connection with a single transaction or " "arrangement, you convey, or propagate by procuring conveyance of, a " "covered work, and grant a patent license to some of the parties " "receiving the covered work authorizing them to use, propagate, modify " "or convey a specific copy of the covered work, then the patent license " "you grant is automatically extended to all recipients of the covered " "work and works based on it.

" "

A patent license is discriminatory if it does not include within " "the scope of its coverage, prohibits the exercise of, or is " "conditioned on the non-exercise of one or more of the rights that are " "specifically granted under this License. You may not convey a covered " "work if you are a party to an arrangement with a third party that is " "in the business of distributing software, under which you make payment " "to the third party based on the extent of your activity of conveying " "the work, and under which the third party grants, to any of the " "parties who would receive the covered work from you, a discriminatory " "patent license (a) in connection with copies of the covered work " "conveyed by you (or copies made from those copies), or (b) primarily " "for and in connection with specific products or compilations that " "contain the covered work, unless you entered into that arrangement, " "or that patent license was granted, prior to 28 March 2007.

" "

Nothing in this License shall be construed as excluding or limiting " "any implied license or other defenses to infringement that may " "otherwise be available to you under applicable patent law.

" "

12. No Surrender of Others' Freedom.

" "

If conditions are imposed on you (whether by court order, agreement or " "otherwise) that contradict the conditions of this License, they do not " "excuse you from the conditions of this License. If you cannot convey a " "covered work so as to satisfy simultaneously your obligations under this " "License and any other pertinent obligations, then as a consequence you may " "not convey it at all. For example, if you agree to terms that obligate you " "to collect a royalty for further conveying from those to whom you convey " "the Program, the only way you could satisfy both those terms and this " "License would be to refrain entirely from conveying the Program.

" "

13. Use with the GNU Affero General Public License.

" "

Notwithstanding any other provision of this License, you have " "permission to link or combine any covered work with a work licensed " "under version 3 of the GNU Affero General Public License into a single " "combined work, and to convey the resulting work. The terms of this " "License will continue to apply to the part which is the covered work, " "but the special requirements of the GNU Affero General Public License, " "section 13, concerning interaction through a network will apply to the " "combination as such.

" "

14. Revised Versions of this License.

" "

The Free Software Foundation may publish revised and/or new versions of " "the GNU General Public License from time to time. Such new versions will " "be similar in spirit to the present version, but may differ in detail to " "address new problems or concerns.

" "

Each version is given a distinguishing version number. If the " "Program specifies that a certain numbered version of the GNU General " "Public License or any later version applies to it, you have the " "option of following the terms and conditions either of that numbered " "version or of any later version published by the Free Software " "Foundation. If the Program does not specify a version number of the " "GNU General Public License, you may choose any version ever published " "by the Free Software Foundation.

" "

If the Program specifies that a proxy can decide which future " "versions of the GNU General Public License can be used, that proxy's " "public statement of acceptance of a version permanently authorizes you " "to choose that version for the Program.

" "

Later license versions may give you additional or different " "permissions. However, no additional obligations are imposed on any" "author or copyright holder as a result of your choosing to follow a " "later version.

" "

15. Disclaimer of Warranty.

" "

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY " "APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT " "HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM AS IS WITHOUT WARRANTY " "OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, " "THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR " "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM " "IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF " "ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

" "

16. Limitation of Liability.

" "

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING " "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS " "THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY " "GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE " "USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF " "DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD " "PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), " "EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF " "SUCH DAMAGES.

" "

17. Interpretation of Sections 15 and 16.

" "

If the disclaimer of warranty and limitation of liability provided " "above cannot be given local legal effect according to their terms, " "reviewing courts shall apply local law that most closely approximates " "an absolute waiver of all civil liability in connection with the " "Program, unless a warranty or assumption of liability accompanies a " "copy of the Program in return for a fee.

" "

END OF TERMS AND CONDITIONS

" ""; licenseBrowser->setHtml(gplLic); aceptLicCheckBox = new QCheckBox(tr("Acknowledge")); aceptLicCheckBox->setToolTip(tr("Be aware that KLog is free software.")); registerField("licAgreement*", aceptLicCheckBox); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(licenseBrowser); layout->addWidget(aceptLicCheckBox); setLayout(layout); } int LicPage::nextId() const { return StartWizard::Page_CTY; //return StartWizard::Page_Mem; } void LicPage::setNextButtonActive(const bool _active) { } /* FileOrMemoryPage::FileOrMemoryPage(QWidget *parent) : QWizardPage(parent) { runInMemory = false; setTitle(tr("File or Memory")); //setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark.png")); topLabel = new QLabel(tr("Please select whether you prefer to run the DB in memory or in a file:" "
    " "
  • Running KLog in memory will be much faster, specially when managing several thousands of QSOs.
  • " "
  • Running KLog in a file will be much secure and you will not be forced to save the file before exiting or opening the logfile when starting KLog.
  • " "
" "Please know that in this version this feature is still not fully-implemented so KLog will run in file.")); topLabel->setWordWrap(true); memoryRadioButton = new QRadioButton(tr("Run KLog DB in &memory")); fileRadioButton = new QRadioButton(tr("Run KLog DB in a &file")); //memoryRadioButton->setChecked(true); memoryRadioButton->setChecked(false); fileRadioButton->setChecked(true); memoryRadioButton->setToolTip(tr("Recommended for day-to-day logging")); fileRadioButton->setToolTip(tr("Recommended for contest logging")); connect( memoryRadioButton, SIGNAL(toggled(bool) ), this, SLOT(slotRunningModeSelectedMemory(bool))); connect( fileRadioButton, SIGNAL(toggled(bool) ), this, SLOT(slotRunningModeSelectedFile(bool))); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(topLabel); layout->addWidget(memoryRadioButton); layout->addWidget(fileRadioButton); setLayout(layout); } void FileOrMemoryPage::slotRunningModeSelectedFile(bool checked) { if (checked) { exeInMemory(false); } } void FileOrMemoryPage::slotRunningModeSelectedMemory(bool checked) { if (checked) { exeInMemory(true); } } int FileOrMemoryPage::nextId() const { return StartWizard::Page_CTY; } */ CTYPage::CTYPage(const QString _klogDir, const QString _version, QWidget *parent) : QWizardPage(parent) { //completed = false; dl = new DownLoadCTY(_klogDir, _version); QObject::connect(dl, SIGNAL(actionReturnDownload(int)), this, SLOT(slotDownloadFinished(int))); QObject::connect(dl, SIGNAL(actionShowProgres(qint64,qint64)), this, SLOT(slotUpdateDownloadProgress(qint64,qint64))); QObject::connect(dl, SIGNAL(actionError(int)), this, SLOT(slotDownloadError(int))); setTitle(tr("Country data download")); topLabel = new QLabel(tr("KLog needs country data...")); topLabel->setWordWrap(true); progressBar = new QProgressBar; progressBar->setEnabled(false); downloadButton = new QPushButton(tr("&Download")); ignoreDownloadButton = new QPushButton(tr("&Ignore")); // downloadButton.setText(tr("Download")); connect(downloadButton, SIGNAL(clicked()), this, SLOT(slotDownloadButtonClicked() ) ); connect(ignoreDownloadButton, SIGNAL(clicked()), this, SLOT(slotIgnoreDownloadButtonClicked() ) ); hiddenCheckBox = new QCheckBox(); registerField("downloadSelection*", hiddenCheckBox); QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addWidget(progressBar); buttonLayout->addWidget(downloadButton); buttonLayout->addWidget(ignoreDownloadButton); ctyBrowser = new QTextEdit; ctyBrowser->setReadOnly(true); QString st = tr("Country data needed"); QString gplLic = ""; gplLic = gplLic+st+"

"; st = tr("KLog uses the cty.csv file from http://www.country-files.com/ to get DXCC information."); gplLic = gplLic + st + "

"; st = tr("You need to download the cty.csv file if you want KLog to show you the countries, locator, ... of the QSOs you do."); gplLic = gplLic + st + "

"; st = tr("Click on Download to download now."); gplLic = gplLic+st+"

"; ctyBrowser->setHtml(gplLic); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(ctyBrowser); layout->addLayout(buttonLayout); setLayout(layout); } void CTYPage::slotUpdateDownloadProgress(qint64 received, qint64 total) { //qDebug() << "CTYPage::slotUpdateDownloadProgress: " << QString::number(received) << "/" << QString::number(total) << endl; progressBar->setMaximum(total); progressBar->setValue(received); } void CTYPage::slotDownloadButtonClicked() { //qDebug() << "CTYPage::slotDownloadButtonClicked" << endl; progressBar->setEnabled(true); dl->download(); //completed = true; } void CTYPage::slotIgnoreDownloadButtonClicked() { //qDebug() << "CTYPage::slotIgnoreDownloadButtonClicked" << endl; //ignoreDownloadButton->setChecked(true); hiddenCheckBox->setChecked(true); progressBar->setEnabled(false); //completed = true; } void CTYPage::slotDownloadFinished(const int ret) { //qDebug() << "CTYPage::slotDownloadFinished: " << QString::number(ret) << endl; if (ret == QNetworkReply::NoError) // No error { hiddenCheckBox->setChecked(true); progressBar->setEnabled(false); progressBar->setValue(progressBar->maximum()); //hiddenCheckBox->setChecked(true); //qDebug() << "CTYPage::slotDownloadFinished: (no error): " << QString::number(ret) << endl; } else if (ret == -1) // File could not be created! { //qDebug() << "CTYPage::slotDownloadFinished: (file could not be created): " << QString::number(ret) << endl; } else { //qDebug() << "CTYPage::slotDownloadFinished: (another result): " << QString::number(ret) << endl; } } void CTYPage::slotDownloadError(const int ret) { //qDebug() << "CTYPage::slotDownloadError: " << QString::number(ret) << endl; int errorCode = ret; int i; progressBar->setValue(0); progressBar->setEnabled(false); if(errorCode == QNetworkReply::NoError) { } else if(errorCode == QNetworkReply::HostNotFoundError) { i = QMessageBox::warning(this, tr("KLog"), tr("I can't find the host. Please check your network and try again\n" "Do you want to try again?"), QMessageBox::Retry | QMessageBox::Ignore); if (i == QMessageBox::Retry) { slotDownloadButtonClicked(); } else { slotDownloadFinished(-1); } } else { //TODO: Add a message showing the error that has occur. errorString()? } } klog-0.9.2.9/utilities.cpp0000644000076700000620000002350613233376355013332 0ustar staff#include "utilities.h" Utilities::Utilities() { //qDebug() << "Utilities::Utilities" << endl; //dbPath = getKLogDBFile(); softwareVersion = "0.0"; //qDebug() << "Utilities::Utilities - END" << endl; } Utilities::~Utilities() { } void Utilities::setVersion(const QString _v) { //qDebug() << "Utilities::setVersion: " << _v << endl; softwareVersion = _v; } QString Utilities::getVersion() { return softwareVersion; } double Utilities::getVersionDouble() { //qDebug() << "Utilities::getVersionDouble: " << softwareVersion << endl; if (softwareVersion.count('.')>1) { QString first = softwareVersion.section('.', 0, 0); int pos = softwareVersion.indexOf('.'); QString decimals = softwareVersion.section('.', pos, -1); decimals.remove('.'); first = first + "." + decimals; //qDebug() << "Utilities::getVersionDouble - returning: " << first << endl; return first.toDouble(); } //qDebug() << "Utilities::getVersionDouble: no points detected" << endl; return softwareVersion.toDouble(); } int Utilities::getProgresStepForDialog(int totalSteps){ //qDebug() << "Utilities::getProgresStepForDialog"; if (totalSteps <=100) return 1; else if (totalSteps <=1000) return 5; else if (totalSteps <=4000) return 10; else if (totalSteps <=5000) return 15; else if (totalSteps <=7000) return 20; else if (totalSteps <=9999) return 25; else return 50; } bool Utilities::trueOrFalse(const QString _s) {// reads a String and return true if s.upper()== TRUE :-) //qDebug() << "Utilities::trueOrFalse: " << _s << endl; if ( (_s.toUpper()) == "TRUE") { return true; } else { return false; } return false; } QString Utilities::checkAndFixASCIIinADIF(const QString _data) { //qDebug() << "SetupDialog::checkAndFixASCIIinADIF " << _data << endl; // This function is not really working with ASCII but with Unicode //TODO: this function is also in the FileManager class. Maybe I should call that one and keep just one copy ushort unicodeVal; QString st = _data; QString newString; newString.clear(); for(int i=0; i < st.length(); i++) { // Get unicode VALUE into unicodeVal unicodeVal = (st.at(i)).unicode(); if ((20 <= unicodeVal ) && (unicodeVal <= 126)) { newString.append(st.at(i)); } //qDebug() << "SetupDialog::checkAndFixunicodeinADIF: " << st.at(i) <<" = " << QString::number(unicodeVal) << endl; } // Show into another lineEdit return newString; } void Utilities::printQString(const QStringList _qs) { //qDebug() << "Utilities::printQString: COMMENT THIS CALL BEFORE RELEASING" << endl; if (_qs.length()<1) { //qDebug() << "Utilities::printQString: EMPTY QStringList received!!" << endl; return; } for (int i=0; i<_qs.length()-1;i++) { //qDebug() << _qs.at(i) << "/" ; } //qDebug() << _qs.at(_qs.length()-1) << endl; } QString Utilities::getAgent(const QString _klogversion) { QString version; version = _klogversion; #if defined(Q_OS_WIN32) return "KLog-Win32-" + version; #elif defined(Q_OS_WIN64) return "KLog-Win64-" + version; #elif defined(Q_OS_LINUX) return "KLog-Linux-" + version; #elif defined(Q_OS_WIN) return "KLog-Win-"+ version; #elif defined(Q_OS_MACOS) return "KLog-macOS-" + version; #elif defined(Q_OS_OSX) return "KLog-OSX-" + version; #elif defined(Q_OS_MAC) return "KLog-MAC-" + version; #elif defined(Q_OS_AIX) return "KLog-aix-" + version; #elif defined(Q_OS_ANDROID) return "KLog-android-" + version; //#elif defined(Q_OS_BSD4) // return "KLog-bsd4-" + version; #elif defined(Q_OS_BSDI) return "KLog-bsdi-" + version; #elif defined(Q_OS_CYGWIN) return "KLog-cygwin-" + version; #elif defined(Q_OS_DARWIN) return "KLog-darwin-" + version; #elif defined(Q_OS_DGUX) return "KLog-dgux-" + version; #elif defined(Q_OS_DYNIX) return "KLog-dynix-" + version; #elif defined(Q_OS_FREEBSD) return "KLog-freebsd-" + version; #elif defined(Q_OS_HPUX) return "KLog-hpux-" + version; #elif defined(Q_OS_IOS) return "KLog-ios-" + version; #elif defined(Q_OS_IRIX) return "KLog-irix-" + version; #elif defined(Q_OS_LYNX) return "KLog-lynx-" + version; #elif defined(Q_OS_NETBSD) return "KLog-netbsd-" + version; #elif defined(Q_OS_OPENBSD) return "KLog-openbsd-" + version; #elif defined(Q_OS_OSF) return "KLog-osf-" + version; #elif defined(Q_OS_QNX) return "KLog-qnx-" + version; #elif defined(Q_OS_SCO) return "KLog-sco-" + version; #elif defined(Q_OS_SOLARIS) return "KLog-solaris-" + version; #elif defined(Q_OS_TVOS) return "KLog-tvos-" + version; #elif defined(Q_OS_UNIX) return "KLog-unix-" + version; #elif defined(Q_OS_UNIXWARE) return "KLog-unixware-" + version; #elif defined(Q_OS_WHATCHOS) return "KLog-whatchos-" + version; #elif defined(Q_OS_WINRT) return "KLog-winrt-" + version; #else return "KLog-Other-" + version; #endif //return "KLog-Unknown-" + version; } QString Utilities::getHomeDir() { //TODO: To be removed when the defaultDir is saved in the config file #ifdef Q_OS_WIN //qDebug() << "WINDOWS DETECTED!: " << QDir::homePath() + "/klog" << endl; return QDir::homePath()+"/klog"; // We create the \klog for the logs and data #else //qDebug() << "NO WINDOWS DETECTED!" << endl; return QDir::homePath()+"/.klog"; // We create the ~/.klog for the logs and data #endif } QString Utilities::getKLogDefaultDatabaseFile() { //TODO: To be removed when the defaultDir is saved in the config file return getHomeDir() ; } QString Utilities::getKLogDBFile() { //qDebug() << "Utilities::getKLogDBFile: start " << endl; dbPath = getKLogDefaultDatabaseFile(); QFile file(getCfgFile()); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){ //qDebug() << "Utilities::getKLogDBFile: return1: " << getKLogDatabaseFile(dbPath) << endl; //return dbPath; //return getKLogDatabaseFile(dbPath); } else { while (!file.atEnd()) { QByteArray line = file.readLine(); processConfigLine(line); } if (dbPath.length()<1) { dbPath = getKLogDefaultDatabaseFile(); } } //qDebug() << "Utilities::getKLogDBFile: path to use: " << dbPath << endl; return dbPath + "/logbook.dat"; } bool Utilities::processConfigLine(const QString _line) { //qDebug() << "Utilities::processConfigLine: " << _line << endl; QString line = _line.simplified(); //line.simplified(); //QString aux; QStringList values = line.split("=", QString::SkipEmptyParts); if (line.startsWith('#')){ //qDebug() << "Utilities::processConfigLine: notes Line!" << endl; return true; } if (!( (line.contains('=')) && (line.contains(';')))){ //qDebug() << "Utilities::processConfigLine: Wrong Line!" << endl; return false; } QString field = (values.at(0)).toUpper(); QString value = values.at(1); int endValue = value.indexOf(';'); if (endValue>-1){ value = value.left(value.length() - (value.length() - endValue)); } if (field == "DBPATH") { //qDebug() << "Utilities::processConfigLine: dbPATH found: " << value << endl; dbPath = value; } return true; } /* QString Utilities::getKLogDatabaseFile(const QString _file) { //qDebug() << "Utilities::getKLogDatabaseFile:" << _file << endl; if ( QFile::exists(_file + "/logbook.dat") ) { //qDebug() << "Utilities::getKLogDatabaseFile:returning: " << _file + "/logbook.dat" << endl; return _file + "/logbook.dat"; } else {} //qDebug() << "Utilities::getKLogDatabaseFile: Does not exist so default: " << getKLogDefaultDatabaseFile() << endl; return getKLogDefaultDatabaseFile(); } */ QString Utilities::getCfgFile() { //TODO: To be removed when the defaultDir is saved in the config file #ifdef Q_OS_WIN //qDebug() << "WINDOWS DETECTED!: " << getHomeDir() + "/klogrc.cfg" << endl; return getHomeDir() + "/klogrc.cfg"; #else //qDebug() << "NO WINDOWS DETECTED!: " << getHomeDir() + "/klogrc.cfg" << endl; return getHomeDir() + "/klogrc"; #endif } QString Utilities::getCTYFile() { return getHomeDir() + "/cty.csv"; } int Utilities::getNormalizedDXCCValue(const int _dxcc) { if (_dxcc >1000) { return ((QString::number(_dxcc)).right(3)).toInt(); } else { return _dxcc; } } QDate Utilities::getDefaultDate() { return QDate::fromString("18000101", "yyyyMMdd"); } bool Utilities::isValidDate(const QDate _d) { if (_d.isValid()) { if (_d>QDate::fromString("18500101", "yyyyMMdd")) { return true; } } return false; } bool Utilities::isDBFileExisting() { //qDebug() << "Utilities::isDBFileExisting: " << getKLogDBFile() << endl; if (QFile::exists(getKLogDBFile())) { //qDebug() << "Utilities::isDBFileExisting - true" << endl; return true; } else { //qDebug() << "Utilities::isDBFileExisting - false" << endl; return false; } return false; } bool Utilities::isDBFileExisting(const QString _file) { //qDebug() << "Utilities::isDBFileExisting2: " << _file << endl; if (QFile::exists(_file)) { //qDebug() << "Utilities::isDBFileExisting2 - true" << endl; return true; } else { //qDebug() << "Utilities::isDBFileExisting2 - false" << endl; return false; } return false; } klog-0.9.2.9/dxcluster.cpp0000644000076700000620000007146213233376355013340 0ustar staff/*************************************************************************** dxcluster.cpp - description ------------------- begin : oct 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "dxcluster.h" DXClusterWidget::DXClusterWidget(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "DXClusterWidget::DXClusterWidget" << endl; dataProxy = dp; constrid = 1; awards = new Awards(dataProxy); initClass(); //qDebug() << "DXClusterWidget::DXClusterWidget - END" << endl; } DXClusterWidget::DXClusterWidget(DataProxy *dp, const QString &clusterToConnect, const int portToConnect, QWidget *parent) : QWidget(parent) { //qDebug() << "DXClusterWidget::DXClusterWidget2" << clusterToConnect << QString::number(portToConnect) << endl; constrid = 2; initClass(); server = clusterToConnect; port = portToConnect; dxSpotColor.setNamedColor("slategrey"); //defaultColor.setNamedColor("slategrey"); //neededColor.setNamedColor("slategrey"); //workedColor.setNamedColor("slategrey"); //confirmedColor.setNamedColor("slategrey"); //newOneColor.setNamedColor("slategrey"); dataProxy = dp; world = new World(dataProxy); awards = new Awards(dataProxy); tcpSocket = new QTcpSocket(this); dxClusterListWidget = new QListWidget(); inputCommand = new QLineEdit; sendButton = new QPushButton; clearButton = new QPushButton; inputCommand->setDisabled(true); inputCommand->setToolTip(tr("Click on Connect to connect to the DX-Cluster server")); dxClusterListWidget->setMouseTracking(true); sendButton->setText(tr("Connect")); clearButton->setText(tr("Clear")); QHBoxLayout *bottonLayout = new QHBoxLayout; bottonLayout->addWidget(inputCommand); bottonLayout->addWidget(sendButton); bottonLayout->addWidget(clearButton); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(dxClusterListWidget); layout->addLayout(bottonLayout); setLayout(layout); connect(sendButton , SIGNAL(clicked()), this, SLOT(slotClusterSendToServer()) ); connect(inputCommand, SIGNAL(textChanged(QString)), this, SLOT(slotClusterInputTextChanged()) ); //connect(searchResultsTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(slotDoubleClickSearch(QTreeWidgetItem *, int))); connect(dxClusterListWidget, SIGNAL(itemDoubleClicked ( QListWidgetItem *)), this, SLOT(slotClusterDXClusterWidgetItemDoubleClicked( QListWidgetItem * )) ); connect(dxClusterListWidget, SIGNAL(itemEntered ( QListWidgetItem *)), this, SLOT(slotClusterDXClusterWidgetItemEntered( QListWidgetItem * )) ); connect(dxClusterListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(slotClusterDXClusterWidgetItemSelected() ) ); //void QListWidget::itemDoubleClicked ( QListWidgetItem * item ) [signal] // TO BE DELETED addData(); //TESTADDSPOT(); //qDebug() << "DXClusterWidget::DXClusterWidget2 - END" << endl; } void DXClusterWidget::initClass() { dxClusterConnected = false; dxClusterAlreadyConnected = false; showhf = true; showvhf = true; showwarc = true; showworked = true; showconfirmed = true; showann = true; showwwv = true; showwcy = true; myQrz = QString(); currentLog = 0; } void DXClusterWidget::setMyQRZ(const QString _qrz) { if (_qrz.length()>2) { myQrz = _qrz; } } void DXClusterWidget::addData() { //qDebug() << "DXClusterWidget::addData " << endl; /* QTreeWidgetItem *item = new QTreeWidgetItem(searchResultsTreeWidget); i = world->getQRZARRLId(_call); aux = world->getEntityName(i) + " - CQ: " + QString::number(world->getEntityCqz(i)); item->setToolTip(0, aux); item->setToolTip(1, aux); item->setToolTip(2, aux); item->setToolTip(3, aux); item->setToolTip(4, aux); item->setToolTip(5, aux); item->setToolTip(6, aux); */ dxClusterSpotItem * item = new dxClusterSpotItem(dxClusterListWidget, tr("Click on connect to connect to the DX-Cluster"), awards->getDefaultColor()); } DXClusterWidget::~DXClusterWidget() { //qDebug() << "DXClusterWidget::~DXClusterWidget" << endl; } void DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked( QListWidgetItem * item ) { //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: " << item->text() << endl; QStringList ql; ql.clear(); if (item) { ql = readItem(item); //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: Length: " << QString::number(ql.length()) << endl; if (ql.length()==2) { ql << "double"; //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: EMMITED" << endl; emit dxspotclicked(ql); } else { //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: NOT EMMITED-1" << endl; } } else { //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: NOT EMMITED-2 (no item)" << endl; } } void DXClusterWidget::connectToDXCluster() { //qDebug() << "DXClusterWidget::connectToDXCluster" << endl; if (dxClusterConnected) { //qDebug() << "DXClusterWidget::connectToDXCluster: - Already connected!!" << endl; return; // If we are connected we don't want to start another connection } connect(tcpSocket, SIGNAL(connected()), SLOT(slotClusterSocketConnected()) ); connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(slotClusterDataArrived() )); connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotClusterDisplayError(QAbstractSocket::SocketError))); connect(tcpSocket, SIGNAL(disconnected()), SLOT(slotClusterSocketConnectionClosed()) ); connect(inputCommand, SIGNAL(returnPressed()), this, SLOT(slotClusterSendToServer()) ); connect(clearButton, SIGNAL(clicked()), this, SLOT(slotClusterClearLineInput()) ); tcpSocket->connectToHost( server, port ); dxClusterListWidget->setSortingEnabled (false); dxClusterSpotItem * item = new dxClusterSpotItem(dxClusterListWidget, tr("Trying to connect to the server") + "\n", awards->getDefaultColor()); } void DXClusterWidget::slotClusterDisplayError(QAbstractSocket::SocketError socketError) { //qDebug() << "DXClusterWidget:displayError:" << endl; switch (socketError) { case QAbstractSocket::RemoteHostClosedError: break; case QAbstractSocket::HostNotFoundError: QMessageBox::warning(this, tr("KLog DXCluster"), tr("The host was not found. Please check:") + "\n\n" + tr ("- your network connection;\n" "- the host name and port settings.")); break; case QAbstractSocket::ConnectionRefusedError: QMessageBox::warning(this, tr("KLog DXCluster"), tr("The connection was refused by the peer. " "Make sure the DXCluster server is running, " "and check that the host name and port " "settings are correct.")); break; default: QMessageBox::warning(this, tr("KLog DXCluster"), tr("The following error occurred: %1.") .arg(tcpSocket->errorString())); } } bool DXClusterWidget::checkIfNeedsToBePrinted(const QString _DXEntity, int const _band, const int _mode) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: " << _dxCall << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< endl; QStringList qs; qs.clear(); qs << _DXEntity << QString::number(_band) << QString::number(_mode) << QString::number(currentLog); //bool isConfirmed = false; bool status = awards->isThisSpotConfirmed (qs); //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: Status: " << _dxCall << "/" << QString::number(status); if (!showconfirmed) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is confirmed? ("<< QString::number(status)<< ")" << endl; if (status) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: It is confirmed: DON'T' print: " << _dxCall <<"/" << dataProxy->getNameFromBandId(_band) << endl; return false; } } if (!showhf) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is HF?" << endl; if (dataProxy->isHF(_band)) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: Not showing HF but... is it WARC?" << endl; if ( (showwarc) && dataProxy->isWARC(_band) ) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: Not showing HF but... is WARC, print!" << endl; return true; } //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is HF: DON'T print: "<< _dxCall << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< endl; return false; } else { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is NOT HF" << endl; } } if (!showwarc) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is WARC?" << endl; if (dataProxy->isWARC(_band)) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is WARC, DON'T print: "<< _dxCall << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< endl; return false; } else { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is NOT WARC" << endl; } } if (!showvhf) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is VHF?" << endl; if (dataProxy->isVHF(_band)) { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is VHF, DON'T print: "<< _dxCall << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< endl; return false; } else { //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: is NOT VHF " << endl; } } //qDebug() << "DXClusterWidget::checkIfNeedsToBePrinted: returns TRUE and will be printed: " << _dxCall << "/" << dataProxy->getNameFromBandId(_band) << QString::number(_mode)<< endl; return true; } void DXClusterWidget::setCurrentLog(const int _log) { if (dataProxy->doesThisLogExist(_log)) { currentLog = _log; } else { currentLog = -1; } } void DXClusterWidget::slotClusterDataArrived() { //qDebug() << "DXClusterWidget::slotClusterDataArrived" << endl; QStringList qs; QString dxClusterString; QString dxCall; QString dxFrequency; QString spotBand; spotBand = "-1"; //bool isADXSpot = false; int dxEntity = -1; while ( tcpSocket->canReadLine() ) { dxClusterString = tcpSocket->readLine(); dxClusterString = dxClusterString.trimmed(); QStringList tokens = dxClusterString.split(" ", QString::SkipEmptyParts); if (tokens.size()<2){ return; } // It is a "DX de SP0TTER FREC DXCALL" //0 = DX, 1 = de, 2 = spotter, 3 = Freq, 4 = dxcall, 5 = comment //qDebug() << "DXClusterWidget::slotClusterDataArrived: " << "DXCLUSTER->" << dxClusterString << "\nTOKENS: " << tokens << endl; if ((tokens[0] == "DX") && (tokens[1] == "de")) { //qDebug() << "******************** DXClusterWidget::slotClusterDataArrived: DX DE" << endl; //isADXSpot = true; QString spotter = tokens[2]; spotter.truncate(spotter.size() - 1); dxFrequency = tokens[3]; // Convert KHz to MHz... //dxFrequency = QString::number(abs (dxFrequency.toFloat())/1000); dxFrequency = QString::number( (dxFrequency.toFloat())/1000); dxCall = tokens[4]; dxEntity = world->getQRZARRLId(dxCall); // spotBand = QString::number(dataProxy->getBandIdFromFreq( dxFrequency.toDouble() ) ); qs.clear(); //spotBand = QString::number(world->getBandIdFromFreq( dxFrequency ) ); qs << QString::number(dxEntity) << spotBand << "-1" << QString::number(currentLog) ; //qDebug() << "DXClusterWidget::slotClusterDataArrived: Calling-2: " << QString::number(dxEntity) << endl; dxSpotColor = awards->getQRZDXStatusColor(qs); if (awards->isDXMarathonNeed(dxEntity, world->getQRZCqz(dxCall), QDateTime::currentDateTime().date().year(), currentLog)) { dxClusterString = dxClusterString + " ### Needed for DXMarathon - " + QString::number(QDateTime::currentDateTime().date().year()) + " ###"; } //qDebug() << "DX de ->" << "Spotter: " << spotter << "Freq: "<< dxFrequency << "DX: " << dxCall << endl; } else if ((tokens[0] == "To") && (tokens[1] == "ALL")) { //qDebug() << "DXClusterWidget::slotClusterDataArrived: TO ALL" << endl; dxSpotColor = awards->getDefaultColor(); } else if ( (dxClusterString.length()>=5) && (world->checkQRZValidFormat(tokens[1])) && (tokens[0]!="login:")) { // Freq / DXCall / Date // time //_qs << QRZ << Freq in MHz << lognumber; //qDebug() << "DXClusterWidget::slotClusterDataArrived: LENGTH >= 5" << endl; //qDebug() << "DXClusterWidget::slotClusterDataArrived: token0=" << tokens[0] << " / token1=" << tokens[1] << endl; //isADXSpot = true; dxCall = tokens[1]; dxFrequency = tokens[0]; dxFrequency = QString::number( (dxFrequency.toFloat())/1000); qs.clear(); spotBand = QString::number(dataProxy->getBandIdFromFreq( dxFrequency.toDouble() ) ); dxEntity = world->getQRZARRLId(dxCall); //qDebug() << "DXClusterWidget::slotClusterDataArrived: Calling-1: " << QString::number(dxEntity) << endl; qs << QString::number(dxEntity) << spotBand << "-1" << QString::number(currentLog) ; dxSpotColor = awards->getQRZDXStatusColor(qs); if (awards->isDXMarathonNeed(dxEntity, world->getQRZCqz(dxCall), QDateTime::currentDateTime().date().year(), currentLog)) { dxClusterString = dxClusterString + " ### Needed for DXMarathon - " + QString::number(QDateTime::currentDateTime().date().year()) + " ###"; } } else { //qDebug() << "DXClusterWidget::slotClusterDataArrived: DEFAULT" << endl; dxSpotColor = awards->getDefaultColor(); } // qs.clear(); //spotBand = QString::number(world->getBandIdFromFreq( dxFrequency ) ); //qs << dxCall << spotBand << "0"; //dxSpotColor = awards->getQRZDXStatusColor(qs); //qDebug() << "DXClusterWidget::slotClusterDataArrived: Call/dxSpotColor: " << dxCall <<"/"<< dxSpotColor.name() << endl; //dxClusterSpotItem * item = new dxClusterSpotItem(dxClusterListWidget, dxClusterString, dxSpotColor); //TODO: Change the "-1" by the mode if (!checkIfNeedsToBePrinted(QString::number(dxEntity), spotBand.toInt(), -1)) { //qDebug() << "DXClusterWidget::slotClusterDataArrived - Not to be printed!: " << dxCall << endl; return; } // QString flagSt; // QString aux; QListWidgetItem *item = new QListWidgetItem(); item->setForeground(QBrush(dxSpotColor)); item->setText(dxClusterString); /* if (dxEntity>0) { flagSt.clear(); aux = dataProxy->getISOName(dxEntity); if (aux.length()>1) { flagSt = ":/" + aux + ".png"; } else { flagSt.clear(); } flagSt = ":/flags/" + dataProxy->getISOName(dxEntity) + ".png"; QIcon flagIcon(flagSt); item->setIcon(flagIcon); } */ dxClusterListWidget->insertItem(0,item); //dxClusterListWidget->insertItem(0,item); //QListWidgetItem *item = new QListWidgetItem(); //item->setForeground(QBrush(awards->getQRZDXStatusColor(qs))); //item->setText(dxClusterString); //dxClusterListWidget->insertItem(0,item); } //qDebug() << "--------------------- DXClusterWidget::slotClusterDataArrived: " << dxClusterString << endl; //qDebug() << "DXClusterWidget::slotClusterDataArrived: " << dxClusterString << endl; } void DXClusterWidget::slotClusterSocketConnected() { //qDebug() << "DXClusterWidget::slotClusterSocketConnected" << endl; QListWidgetItem *item = new QListWidgetItem(); item->setForeground(QBrush(awards->getDefaultColor())); item->setText(tr("Connected to server")); dxClusterListWidget->insertItem(0,item); // dxClusterSpotItem * item = new dxClusterSpotItem(dxclusterListWidget, i18n("Connected to server"), awards->getDefaultColor()); dxClusterConnected = true; inputCommand->setFocus(Qt::OtherFocusReason); if (( dxClusterConnected ) && (!dxClusterAlreadyConnected) ){ bool ok; QString callsignText; if (myQrz.length()>2) { callsignText = QInputDialog::getText(this, tr("KLog message"), tr("Enter your callsign to connect to the cluster:"), QLineEdit::Normal, myQrz, &ok); } else { callsignText = QInputDialog::getText(this, tr("KLog message"), tr("Enter your callsign to connect to the cluster:"), QLineEdit::Normal, "", &ok); } //QString callsignText = QInputDialog::getText(this, tr("KLog message"), tr("Enter your callsign to connect to the cluster:"), QLineEdit::Normal, "", &ok); 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); QTextStream os(tcpSocket); if ( callsignText.length() > 2 && ok ) { os << callsignText << "\n"; //TODO: Check the DXCluster answer and enter the password if needed. sendButton->setText(tr("Disconnect")); clearButton->setText(tr("Clear")); dxClusterAlreadyConnected = true; } else { os << tr("Not logged on, you may need to enter your callsign again.") << "\n"; dxClusterAlreadyConnected = false; } inputCommand->setEnabled(true); inputCommand->setToolTip(tr("Enter here the commands to be sent to the DX-Cluster server")); } } void DXClusterWidget::slotClusterSocketConnectionClosed() { //qDebug() << "DXClusterWidget::slotClusterSocketConnectionClosed" << endl; QListWidgetItem *item = new QListWidgetItem(); item->setForeground(QBrush(awards->getDefaultColor())); item->setText(tr("Connection closed by the server")); dxClusterListWidget->insertItem(0,item); dxClusterConnected = false; dxClusterAlreadyConnected = false; sendButton->setText(tr("Connect")); inputCommand->setDisabled(true); inputCommand->setToolTip(tr("Click on Connect to connect to the DX-Cluster server")); //connect(inputCommand, SIGNAL(returnPressed()), this, SLOT(slotClusterSendToServer()) ); disconnect (inputCommand, SIGNAL(returnPressed()), this, SLOT(slotClusterSendToServer()) ); } void DXClusterWidget::slotClusterSendToServer() { //qDebug() << "DXClusterWidget::slotClusterSendToServer()" << endl; if (!dxClusterConnected) { connectToDXCluster(); return; // If we try to connect... } if ( inputCommand ->text().length() < 1 ) { //qDebug() << "DXClusterWidget::slotClusterSendToServer() - Vacio..." << endl; QTextStream os(tcpSocket); os << "bye\n"; return; } // write to the server QTextStream os(tcpSocket); os << inputCommand ->text() << "\n"; inputCommand ->clear(); } void DXClusterWidget::slotClusterClearLineInput() { //qDebug() << "DXClusterWidget::slotClusterClearLineInput" << endl; if ( ((inputCommand->text()).length()) <= 0 ) { if ( dxClusterConnected ) { QTextStream os(tcpSocket); os << "bye\n"; } else { } } else { inputCommand->clear(); } } void DXClusterWidget::slotClusterInputTextChanged() { //qDebug() << "DXClusterWidget::slotClusterInputTextChanged" << endl; if ( ((inputCommand->text()).length()) <= 0 ) { sendButton->setText(tr("Disconnect")); clearButton->setText(tr("Clear")); } else if (dxClusterConnected) { sendButton->setText(tr("Send")); clearButton->setText(tr("Clear")); } else {} } void DXClusterWidget::setColors (const QString _newOne, const QString _needed, const QString _worked, const QString _confirmed, const QString _default) { //qDebug() << "DXClusterWidget::setColors: " << _newOne << "/" << _needed << "/" << _worked << "/" << _confirmed << "/" << _default << endl; // Just to pass the colors to the awards class awards->setColors(_newOne, _needed, _worked, _confirmed, _default); } void DXClusterWidget::setDXClusterSpotConfig(bool _showhf, bool _showvhf, bool _showwarc, bool _showworked, bool _showconfirmed, bool _showann, bool _showwwv, bool _showwcy ) { //qDebug() << "DXClusterWidget::setDXClusterSpotConfig " << endl; showhf = _showhf; showvhf = _showvhf; showwarc = _showwarc; showworked = _showworked; showconfirmed = _showconfirmed; showann = _showann; showwwv = _showwwv; showwcy = _showwcy; } void DXClusterWidget::slotClusterDXClusterWidgetItemSelected() { //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemSelected " << endl; QListWidgetItem * item = dxClusterListWidget->currentItem(); QStringList ql; ql.clear(); ql = readItem(item); if (ql.length()==2) { ql << "selected"; emit dxspotclicked(ql); } else { } } void DXClusterWidget::slotClusterDXClusterWidgetItemEntered( QListWidgetItem * item ) { //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemEntered" << endl; /* This code comes from slotClusterDXClusterWidgetItemDoubleClicked */ QString tip; tip.clear(); QStringList ql; ql.clear(); if (item) { ql = readItem(item); if (ql.length()==2) { tip = world->getQRZEntityName(ql.at(0)); item->setToolTip(tip); } else { } } else { } } bool DXClusterWidget::isConnected() { return dxClusterConnected; } QStringList DXClusterWidget::readItem(QListWidgetItem * item) { //qDebug() << "DXClusterWidget::readItem" << endl; QStringList fields; QString dxClusterString; //int currentEntity; QString dxCallsign, dxFreq; bool FirstFrecOK; if (item) { fields.clear(); dxClusterString = ((item->data(0)).toString()).simplified(); fields << dxClusterString.split(" "); (fields.at(0)).toFloat(&FirstFrecOK); // Just to see if the first string is a frecuency if ( (fields.at(0) == "DX" ) && (fields.at(1) == "de" ) ) { // DX de EA4TV: 21200.1 EA0JC The comment 1550 if ( world->getQRZARRLId(fields.at(4))> 0 ) { //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: ARRLid: " << QString::number(world->getQRZARRLId(fields.at(4))) << endl; dxCallsign = (fields.at(4)).toUpper(); (fields.at(3)).toFloat(&FirstFrecOK); if (FirstFrecOK) { // The frecuency is valid dxFreq = fields.at(3); fields.clear(); //TODO: Change FREQ into bandId fields << dxCallsign << dxFreq; return fields; } else { // the frecuency is not a number! dxCallsign.clear(); dxFreq.clear(); fields.clear(); } } else { // The call is not from a valid country // TODO: if it is from a new entity/prefix it would not work. //qDebug() << "DXClusterWidget::slotClusterDXClusterWidgetItemDoubleClicked: Entity not valid" << endl; dxCallsign.clear(); dxFreq.clear(); fields.clear(); } } //else if (( isAFrecuency(fields.at(0) ) ) && ( isACall(fields.at(1)) ) ) else if ( (((fields.at(0)).toFloat()) > 0.0 )&& ( world->getQRZARRLId(fields.at(1))> 0 ) ) { // 14205.0 EA0JC 5-Mar-2012 1500Z dxCallsign = (fields.at(1)).toUpper(); dxFreq = fields.at(0); fields.clear(); fields << dxCallsign << dxFreq; return fields; } else { dxCallsign.clear(); dxFreq.clear(); fields.clear(); } } else { // No Item } return fields; } void DXClusterWidget::setDXClusterServer(const QString &clusterToConnect, const int portToConnect) { server = clusterToConnect; port = portToConnect; //qDebug() << "DXClusterWidget::setDXClusterServer: " << server << ":"<< QString::number(port) << endl; } /* void DXClusterWidget::TESTADDSPOT() { //qDebug() << "DXClusterWidget::TESTADDSPOT " << endl; ; // Just a test spot QListWidgetItem *item = new QListWidgetItem(); item->setForeground(QBrush(dxSpotColor)); item->setText("DX de SP0TTER 14.000 DX1CALL"); dxClusterListWidget->insertItem(0,item); } */ /*************************************************************************** ** This is an auxiliary class intended to provide color to the DX-Cluster ** ** spots. ** ** It may be moved to a self .h & .cpp archives ** ****************************************************************************/ dxClusterSpotItem::dxClusterSpotItem( QListWidget *parent, const QString& spot, const QColor& color ) : QListWidgetItem( parent ){ //qDebug() << "dxClusterSpotItem::dxClusterSpotItem - Constructor" << endl; spotColor = color; setText(spot); // Experimenting with fonts for the cluster QFont f("Helvetica"); f.setFixedPitch(true); setFont(f); } dxClusterSpotItem::~dxClusterSpotItem() { //qDebug() << "dxClusterSpotItem::dxClusterSpotItem - Destructor" << endl; } klog-0.9.2.9/dxccstatuswidget.h0000644000076700000620000000604313233376355014352 0ustar staff#ifndef DXCCSTATUSWIDGET_H #define DXCCSTATUSWIDGET_H /*************************************************************************** dxccstatuswidget.h - description ------------------- begin : feb 2016 copyright : (C) 2016 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include #include #include //#include #include "awards.h" #include "world.h" #include "dataproxy.h" //TODO: Creating the widget to show the DXCC status class DXCCStatusWidget : public QWidget { Q_OBJECT public: explicit DXCCStatusWidget(DataProxy *dp, QWidget *parent = 0); ~DXCCStatusWidget(); void update(); void setBands(const QStringList _ent, const bool _creating = false); // Receives the list of bandIDs void setCurrentLog(const int _logN); void refresh(); signals: public slots: //void slotSearchLineEditTextChanged(); void slotRefreshButtonClicked(); private: void createUI(); void setDefaultBands(); void addEntity(QStringList const _ent); // DXCC id, bandid, bandid, ... //QStringList sortBandNamesBottonUp(const QStringList _qs); QTableWidget *dxccView; Awards *awards; World *world; DataProxy *dataProxy; QHeaderView *hv, *hh; //QLineEdit *searchLineEdit; QPushButton *refreshButton; //QRadioButton *showAllLogsButton; int numberOfColumns; // Columns will be number Of Bands + 2 (Id + Name) QStringList bandNames, validBands; int logNumber, tempLog; // log in use in the log / log to be used in the widget }; #endif // DXCCSTATUSWIDGET_H klog-0.9.2.9/setupdialog.cpp0000644000076700000620000011671013233376355013637 0ustar staff/*************************************************************************** setupdialog.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "setupdialog.h" //#include /* This class calls all the othet "Setup..." to manage the configuration */ SetupDialog::SetupDialog(DataProxy *dp, const bool _firstTime) { //qDebug() << "SetupDialog::SetupDialog 1" << endl; util = new Utilities; constrid = 1; nolog = true; configFileName = "klogrc"; version = "."; pageRequested = 0; //qDebug() << "SetupDialog::SetupDialog 2" << endl; dataProxy = dp; //qDebug() << "SetupDialog::SetupDialog 3" << endl; firstTime = _firstTime; if (firstTime) { //qDebug() << "SetupDialog::SetupDialog FIRST TIME = TRUE" << endl; } else { //qDebug() << "SetupDialog::SetupDialog FIRST TIME = FALSE" << endl; } //qDebug() << "SetupDialog::SetupDialog 3.1" << endl; logsPageTabN=-1; //qDebug() << "SetupDialog::SetupDialog 3.2" << endl; locator = new Locator(); //qDebug() << "SetupDialog::SetupDialog 3.3" << endl; tabWidget = new QTabWidget; //qDebug() << "SetupDialog::SetupDialog 3.4" << endl; userDataPage = new SetupPageUserDataPage(dataProxy); //qDebug() << "SetupDialog::SetupDialog 3.5" << endl; bandModePage = new SetupPageBandMode(dataProxy, this); //qDebug() << "SetupDialog::SetupDialog 3.6" << endl; dxClusterPage = new SetupPageDxCluster(this); //qDebug() << "SetupDialog::SetupDialog 3.7" << endl; colorsPage = new SetupPageColors(this); //qDebug() << "SetupDialog::SetupDialog 3.8" << endl; miscPage = new SetupPageMisc(this); //qDebug() << "SetupDialog::SetupDialog 3.9" << endl; worldEditorPage = new SetupPageWorldEditor (dataProxy, this); //qDebug() << "SetupDialog::SetupDialog 3.10" << endl; logsPage = new SetupPageLogs(dataProxy, this); //qDebug() << "SetupDialog::SetupDialog 3.11" << endl; clubLogPage = new SetupPageClubLog(this); //qDebug() << "SetupDialog::SetupDialog 3.12" << endl; //qDebug() << "SetupDialog::SetupDialog 4" << endl; tabWidget->addTab(userDataPage, tr("My Data")); tabWidget->addTab(bandModePage, tr("Bands/Modes")); tabWidget->addTab(dxClusterPage, tr("DX-Cluster")); tabWidget->addTab(colorsPage, tr("Colors")); tabWidget->addTab(miscPage, tr("Misc")); tabWidget->addTab(worldEditorPage, tr("World Editor")); logsPageTabN = tabWidget->addTab(logsPage, tr("Logs")); tabWidget->addTab(clubLogPage, tr("ClubLog")); QPushButton *closeButton = new QPushButton(tr("Cancel")); QPushButton *okButton = new QPushButton(tr("OK")); connect(closeButton, SIGNAL(clicked()), this, SLOT(slotCancelButtonClicked())); connect(okButton, SIGNAL(clicked()), this, SLOT(slotOkButtonClicked())); connect(logsPage, SIGNAL(queryError(QString, QString, int, QString)), this, SLOT(slotQueryErrorManagement(QString, QString, int, QString)) ); connectActions(); QHBoxLayout *horizontalLayout = new QHBoxLayout; horizontalLayout->addWidget(tabWidget); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addStretch(1); buttonsLayout->addWidget(okButton); buttonsLayout->addWidget(closeButton); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(horizontalLayout); mainLayout->addLayout(buttonsLayout); setLayout(mainLayout); setWindowTitle(tr("Config Dialog")); slotReadConfigData(); if ((pageRequested==6) && (logsPageTabN>0))// The user is opening a new log { tabWidget->setCurrentIndex(logsPageTabN); } nolog = !(haveAtleastOneLog()); //qDebug() << "SetupDialog::SetupDialog 1 END" << endl; } SetupDialog::SetupDialog(DataProxy *dp, const QString _configFile, const QString _softwareVersion, const int _page, const bool _firstTime) { //qDebug() << "SetupDialog::SetupDialog 2" << endl; constrid = 2; util = new Utilities; firstTime = _firstTime; dataProxy = dp; configFileName = _configFile; version = _softwareVersion; pageRequested = _page; int logsPageTabN=-1; //qDebug() << "SetupDialog::SetupDialog 01" << endl; locator = new Locator(); tabWidget = new QTabWidget; userDataPage = new SetupPageUserDataPage(dataProxy); bandModePage = new SetupPageBandMode(dataProxy, this); dxClusterPage = new SetupPageDxCluster(this); colorsPage = new SetupPageColors(this); miscPage = new SetupPageMisc(this); worldEditorPage = new SetupPageWorldEditor (dataProxy, this); logsPage = new SetupPageLogs(dataProxy, this); clubLogPage = new SetupPageClubLog(this); //qDebug() << "SetupDialog::SetupDialog 02" << endl; tabWidget->addTab(userDataPage, tr("User data")); tabWidget->addTab(bandModePage, tr("Bands/Modes")); tabWidget->addTab(dxClusterPage, tr("D&X-Cluster")); tabWidget->addTab(colorsPage, tr("Colors")); tabWidget->addTab(miscPage, tr("Misc")); tabWidget->addTab(worldEditorPage, tr("World Editor")); logsPageTabN = tabWidget->addTab(logsPage, tr("Logs")); tabWidget->addTab(clubLogPage, tr("ClubLog")); //qDebug() << "SetupDialog::SetupDialog 03" << endl; QPushButton *closeButton = new QPushButton(tr("Cancel")); QPushButton *okButton = new QPushButton(tr("OK")); QHBoxLayout *horizontalLayout = new QHBoxLayout; horizontalLayout->addWidget(tabWidget); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addStretch(1); buttonsLayout->addWidget(okButton); buttonsLayout->addWidget(closeButton); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(horizontalLayout); mainLayout->addLayout(buttonsLayout); //qDebug() << "SetupDialog::SetupDialog 04" << endl; setLayout(mainLayout); setWindowTitle(tr("Config Dialog")); //qDebug() << "SetupDialog::SetupDialog 05" << endl; slotReadConfigData(); //qDebug() << "SetupDialog::SetupDialog 05.1" << endl; if ((pageRequested==6) && (logsPageTabN>0))// The user is opening a new log { //qDebug() << "SetupDialog::SetupDialog 05.2" << endl; tabWidget->setCurrentIndex(logsPageTabN); } //qDebug() << "SetupDialog::SetupDialog 05.3" << endl; nolog = !(haveAtleastOneLog()); connect(closeButton, SIGNAL(clicked()), this, SLOT(slotCancelButtonClicked())); connect(okButton, SIGNAL(clicked()), this, SLOT(slotOkButtonClicked())); connectActions(); //qDebug() << "SetupDialog::SetupDialog 2 - END" << endl; } SetupDialog::~SetupDialog() { //qDebug() << "SetupDialog::~SetupDialog " << endl; } void SetupDialog::connectActions() { connect (logsPage, SIGNAL(newLogData(QStringList)), this, SLOT(slotAnalyzeNewLogData(QStringList))); connect (userDataPage, SIGNAL(stationCallSignal(QString)), this, SLOT(slotSetStationCallSign(QString))); connect (userDataPage, SIGNAL(operatorsSignal(QString)), this, SLOT(slotSetOperators(QString))); connect (userDataPage, SIGNAL(enterKey()), this, SLOT(slotOkButtonClicked())); } void SetupDialog::setData(const QString _configFile, const QString _softwareVersion, const int _page, const bool _firstTime) { //qDebug() << "SetupDialog::setData: " << QString::number(_page) << endl; nolog = !(haveAtleastOneLog()); firstTime = _firstTime; if (firstTime) { //qDebug() << "SetupDialog::setData FIRST TIME! " << endl; } else { //qDebug() << "SetupDialog::setData NOT FIRST TIME! " << endl; miscPage->setUseDefaultDBPath(miscPage->getDefaultDBPath()); } setConfigFile(_configFile); setSoftVersion(_softwareVersion); setPage(_page); //removeBandModeDuplicates(); } void SetupDialog::setConfigFile(const QString _configFile) { //qDebug() << "SetupDialog::setConfigFile" << endl; configFileName = _configFile; } void SetupDialog::setSoftVersion(const QString _softwareVersion) { //qDebug() << "SetupDialog::setSoftVersion" << endl; version = _softwareVersion; } void SetupDialog::setPage(const int _page) { //qDebug() << "SetupDialog::setPage("<0))// The user is opening a new log { tabWidget->setCurrentIndex(pageRequested); } } void SetupDialog::slotCancelButtonClicked() { //qDebug() << "SetupDialog::slotCancelButtonClicked" << endl; if (firstTime || nolog) { if (nolog) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("You need to enter at least one log in the Logs tab.")); msgBox.exec(); return; } emit exitSignal(2); } // close(); } void SetupDialog::createIcons() { //qDebug() << "SetupDialog::createIcons" << endl; QListWidgetItem *configButton = new QListWidgetItem(contentsWidget); configButton->setIcon(QIcon(":/images/config.png")); configButton->setText(tr("User data")); configButton->setTextAlignment(Qt::AlignHCenter); configButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); QListWidgetItem *logsButton = new QListWidgetItem(contentsWidget); logsButton->setIcon(QIcon(":/images/config.png")); logsButton->setText(tr("Logs")); logsButton->setTextAlignment(Qt::AlignHCenter); logsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); QListWidgetItem *bandsButton = new QListWidgetItem(contentsWidget); bandsButton->setIcon(QIcon(":/images/query.png")); bandsButton->setText(tr("Bands/Modes")); bandsButton->setTextAlignment(Qt::AlignHCenter); bandsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); QListWidgetItem *dxClusterButton = new QListWidgetItem(contentsWidget); dxClusterButton->setIcon(QIcon(":/images/query.png")); dxClusterButton->setText(tr("DX-Cluster")); dxClusterButton->setTextAlignment(Qt::AlignHCenter); dxClusterButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); QListWidgetItem *colorsButton = new QListWidgetItem(contentsWidget); colorsButton->setIcon(QIcon(":/images/query.png")); colorsButton->setText(tr("Colors")); colorsButton->setTextAlignment(Qt::AlignHCenter); colorsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); QListWidgetItem *miscButton = new QListWidgetItem(contentsWidget); miscButton->setIcon(QIcon(":/images/query.png")); miscButton->setText(tr("Misc")); miscButton->setTextAlignment(Qt::AlignHCenter); miscButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); QListWidgetItem *worldButton = new QListWidgetItem(contentsWidget); worldButton->setIcon(QIcon(":/images/query.png")); worldButton->setText(tr("World")); worldButton->setTextAlignment(Qt::AlignHCenter); worldButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); connect(contentsWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*))); } void SetupDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) { //qDebug() << "SetupDialog::changePage" << endl; if (!current) current = previous; pagesWidget->setCurrentIndex(contentsWidget->row(current)); } void SetupDialog::slotOkButtonClicked() { qDebug() << "SetupDialog::slotOkButtonClicked" << endl; if (!miscPage->areDBPathChangesApplied()) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setText(tr("DB has not been moved to new path")); msgBox.setInformativeText(tr("Go to the") + " " + tr("Misc tab") + " " + tr("and click on") + " " + tr("Move DB") + "\n" + tr("or the DB will not be moved to the new location.")); msgBox.exec(); return; } if ((userDataPage->getStationQrz()).length() < 3){ // There are no valid calls with less than 3 Chars QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("You need to enter at least a valid QRZ.")); msgBox.setInformativeText(tr("Go to the") + " " + tr("User tab") + " " + tr("and enter valid QRZ.")); msgBox.exec(); return; } if (!haveAtleastOneLog()) { //qDebug() << "SetupDialog::slotOkButtonClicked - NO LOG!" << endl; QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setText(tr("You have not selected the kind of log you want.")); msgBox.setInformativeText(tr("You will be redirected to the Log tab.\nPlease add and select the kind of log you want to use.")); msgBox.exec(); tabWidget->setCurrentIndex(tabWidget->indexOf(logsPage)); logsPage->createNewLog(); //emit newLogRequested(true); // Signal to be catched by logsPage true show new log return; } QFile file (configFileName); QString tmp; tmp = "true"; if (file.open (QIODevice::WriteOnly)){ QTextStream stream (&file); /*QString stationCall; int contest; int contestCategory; int modes;*/ //QRZ/CQ/ITU/CONTEST stream << "version=" << version << ";" << endl; stream << "callsign=" << userDataPage->getStationQrz() << ";" << endl; if ((userDataPage->getOperators()).length() >= 3){ // There are no valid calls with less than 3 Chars stream << "operators=" << userDataPage->getOperators() << ";" << endl; } //stream << "contest=" << userDataPage->getContest() << ";" << endl; //stream << "contestcategory=" << userDataPage->getContestCategory() << ";" << endl; stream << "cqz=" << QString::number(userDataPage->getCQz()) << ";" << endl; stream << "ituz=" << QString::number(userDataPage->getITUz()) << ";" << endl; if ( locator->isValidLocator(userDataPage->getStationLocator()) ) { stream << "StationLocator=" << userDataPage->getStationLocator() << ";" << endl; } if ((!(userDataPage->getName()).isNull()) && ( (userDataPage->getName()).length() > 0 )) { stream << "Name=" << userDataPage->getName() <<";" << endl; } if ((!(userDataPage->getAddress1()).isNull()) && ( (userDataPage->getAddress1()).length() > 0 )) { stream << "Address1=" << userDataPage->getAddress1() <<";" << endl; } if ((!(userDataPage->getAddress2()).isNull()) && ( (userDataPage->getAddress2()).length() > 0 )) { stream << "Address2=" << userDataPage->getAddress2() <<";" << endl; } if ((!(userDataPage->getAddress3()).isNull()) && ( (userDataPage->getAddress3()).length() > 0 )) { stream << "Address3=" << userDataPage->getAddress3() <<";" << endl; } if ((!(userDataPage->getAddress4()).isNull()) && ( (userDataPage->getAddress4()).length() > 0 )) { stream << "Address4=" << userDataPage->getAddress4() <<";" << endl; } if ((!(userDataPage->getCity()).isNull()) && ( (userDataPage->getCity()).length() > 0 )) { stream << "City=" << userDataPage->getCity() <<";" << endl; } if ((!(userDataPage->getZipCode()).isNull()) && ( (userDataPage->getZipCode()).length() > 0 )) { stream << "ZipCode=" << userDataPage->getZipCode() <<";" << endl; } if ((!(userDataPage->getProvince()).isNull()) && ( (userDataPage->getProvince()).length() > 0 )) { stream << "ProvinceState=" << userDataPage->getProvince() <<";" << endl; } if ((!(userDataPage->getCountry()).isNull()) && ( (userDataPage->getCountry()).length() > 0 )) { stream << "Country=" << userDataPage->getCountry() <<";" << endl; } if ((!(userDataPage->getRig1()).isNull()) && ( (userDataPage->getRig1()).length() > 0 )) { stream << "Rig1=" << userDataPage->getRig1() <<";" << endl; } if ((!(userDataPage->getRig2()).isNull()) && ( (userDataPage->getRig2()).length() > 0 )) { stream << "Rig2=" << userDataPage->getRig2() <<";" << endl; } if ((!(userDataPage->getRig3()).isNull()) && ( (userDataPage->getRig3()).length() > 0 )) { stream << "Rig3=" << userDataPage->getRig3() <<";" << endl; } if ((!(userDataPage->getAntenna1()).isNull()) && ( (userDataPage->getAntenna1()).length() > 0 )) { stream << "Antenna1=" << userDataPage->getAntenna1() <<";" << endl; } if ((!(userDataPage->getAntenna2()).isNull()) && ( (userDataPage->getAntenna2()).length() > 0 )) { stream << "Antenna2=" << userDataPage->getAntenna2() <<";" << endl; } if ((!(userDataPage->getAntenna3()).isNull()) && ( (userDataPage->getAntenna2()).length() > 0 )) { stream << "Antenna3=" << userDataPage->getAntenna3() <<";" << endl; } if ((userDataPage->getPower()).toFloat()>=0) { stream << "Power=" << userDataPage->getPower() << ";" << endl; } //stream << "locator=" << (MyLocatorkLineEdit->text ()).toUpper () << ";" << endl; //stream << "CallUsed=" << (UserDataPage.qrzLineEdit).text() << ";" << endl; //stream << "Operators=" << ";" << endl; stream << "Bands=" << bandModePage->getBands() << ";" << endl; stream << "Modes=" << bandModePage->getModes() << ";" << endl; //stream << "InMemory=" << miscPage->getInMemory() << ";" << endl; stream << "RealTime=" << miscPage->getRealTime() << ";" << endl; stream << "UTCTime=" << miscPage->getUTCTime() << ";" << endl; stream << "AlwaysADIF=" << miscPage->getAlwaysADIF() << ";" << endl; stream << "UseDefaultName=" << miscPage->getUseDefaultName() << ";" << endl; stream << "DefaultADIFFile=" << miscPage->getDefaultFileName() << ";" << endl; stream << "DBPath=" << miscPage->getDefaultDBPath() << ";" << endl; stream << "ImperialSystem=" << miscPage->getImperial() << ";" << endl; stream << "SendQSLWhenRec=" << miscPage->getSendQSLWhenRec() << ";" << endl; stream << "ShowCallsignInSearch=" << miscPage->getShowStationCallSignInSearch() << ";" << endl; stream << "KeepMyData=" << miscPage->getKeepMyData() << ";" << endl; stream << "CompleteWithPrevious=" << miscPage->getCompleteWithPrevious() << ";" << endl; stream << "CheckNewVersions=" << miscPage->getCheckNewVersions() << ";" << endl; if ((miscPage->getReportInfo()).toUpper() == "TRUE") { stream << "ProvideInfo=True;" << endl; } if ((!(dxClusterPage->getSelectedDxClusterServer()).isNull()) && ( (dxClusterPage->getSelectedDxClusterServer()).length() > 0 )) { stream << "DXClusterServerToUse=" << dxClusterPage->getSelectedDxClusterServer() <<";" << endl; } QStringList stringList; stringList.clear(); stringList << dxClusterPage->getDxclusterServersComboBox(); if (stringList.size()>0) { for (int i = 0; i < stringList.size(); i++) { stream << "DXClusterServerPort="<< stringList.at(i) << ";" << endl; } } stream << "DXClusterShowHF=" << dxClusterPage->getShowHFRadiobutton() << ";" << endl; stream << "DXClusterShowVHF=" << dxClusterPage->getShowVHFRadiobutton() << ";" << endl; stream << "DXClusterShowWARC=" << dxClusterPage->getShowWARCRadiobutton() << ";" << endl; stream << "DXClusterShowWorked=" << dxClusterPage->getShowWorkedRadiobutton() << ";" << endl; stream << "DXClusterShowConfirmed=" << dxClusterPage->getShowConfirmedRadiobutton() << ";" << endl; stream << "DXClusterShowAnn=" << dxClusterPage->getShowANNRadiobutton() << ";" << endl; stream << "DXClusterShowWWV=" << dxClusterPage->getShowWWVRadiobutton() << ";" << endl; stream << "DXClusterShowWCY=" << dxClusterPage->getShowWCYRadiobutton() << ";" << endl; stream << "NewOneColor=" << colorsPage->getNewOneColor() << ";" << endl; stream << "NeededColor=" << colorsPage->getNeededColor() << ";" << endl; stream << "WorkedColor=" << colorsPage->getWorkedColor() << ";" << endl; stream << "ConfirmedColor=" << colorsPage->getConfirmedColor() << ";" << endl; stream << "DefaultColor=" << colorsPage->getDefaultColor() << ";" << endl; stream << "SelectedLog=" << QString::number(logsPage->getSelectedLog()) << ";" << endl; // CLUBLOG if ((clubLogPage->getClubLog()).toUpper() == "TRUE" ) { stream << "ClubLogActive=" << clubLogPage->getClubLog() << ";" << endl; stream << "ClubLogRealTime=" << clubLogPage->getClubLogRealTime() << ";" << endl; stream << "ClubLogCall=" << clubLogPage->getCallsign() << ";" << endl; stream << "ClubLogPass=" << clubLogPage->getPassword() << ";" << endl; stream << "ClubLogEmail=" << clubLogPage->getEmail() << ";" << endl; stream << "ClubLogUseStationCallsign=" << clubLogPage->getUseQSOStationCallsign() << ";" << endl; } // CLUBLOG file.close (); } //qDebug() << "SetupDialog::slotOkButtonClicked - just before leaving" << endl; QDialog::accept(); //qDebug() << "SetupDialog::slotOkButtonClicked - END" << endl; //close(); } void SetupDialog::slotReadConfigData() { //qDebug() << "SetupDialog::slotReadConfigData" << endl; if (firstTime) { setDefaults(); bands.removeDuplicates(); modes.removeDuplicates(); bandModePage->setActiveModes(modes); bandModePage->setActiveBands(bands); } //qDebug() << "SetupDialog::slotReadConfigData - 1" << endl; QFile file(configFileName); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){ //qDebug() << "SetupDialog::slotReadConfigData() File not found" << configFileName << endl; //firstTime = true; return; } //qDebug() << "SetupDialog::slotReadConfigData - 2" << endl; //dxClusterServers.clear(); while (!file.atEnd()) { QByteArray line = file.readLine(); processConfigLine(line); //qDebug() << "SetupDialog::slotReadConfigData - in the while" << endl; } //qDebug() << "SetupDialog::slotReadConfigData - 3" << endl; dxClusterPage->setDxclusterServersComboBox(dxClusterServers); dxClusterPage->setSelectedDxClusterServer(dxClusterServerToUse); if (modes.isEmpty()) { modes << "SSB" << "CW" << "RTTY"; } if (bands.isEmpty()) { bands << "10M" << "12M" << "15M" << "17M" << "20M" << "40M" << "80M" << "160M"; } modes.removeDuplicates(); //qDebug() << "SetupDialog::slotReadConfigData - duplicate modes: " << QString::number(a) << endl; bandModePage->setActiveModes(modes); bands.removeDuplicates(); //qDebug() << "SetupDialog::slotReadConfigData - duplicate bands: " << QString::number(a) << endl; bandModePage->setActiveBands(bands); //qDebug() << "SetupDialog::slotReadConfigData - END" << endl; } bool SetupDialog::processConfigLine(const QString _line) { //qDebug() << "SetupDialog::processConfigLine: " << _line << endl; QString line = _line.simplified(); //line.simplified(); int i = 0; //aux variable QStringList values = line.split("=", QString::SkipEmptyParts); QString tab = QString(); if (line.startsWith('#')){ //qDebug() << "SetupDialog::processConfigLine: Comment Line!" << endl; return true; } if (!( (line.contains('=')) && (line.contains(';')))){ //qDebug() << "SetupDialog::processConfigLine: Wrong Line!" << endl; return false; } QString value = values.at(1); tab = (values.at(0)).toUpper(); int endValue = value.indexOf(';'); if (endValue>-1){ value = value.left(value.length() - (value.length() - endValue)); } value = checkAndFixASCIIinADIF(value); // Check whether the value is valid. if (tab == "CALLSIGN"){ //qDebug() << "SetupDialog::processConfigLine: CALLSIGN: " << value << endl; userDataPage->setStationQrz(value); }else if (tab == "OPERATORS"){ userDataPage->setOperators(value); }else if (tab=="CQZ"){ userDataPage->setCQz((value).toInt()); }else if (tab=="ITUZ"){ userDataPage->setITUz((value).toInt()); }else if (tab=="CONTEST"){ //userDataPage->setContest(value); }else if (tab=="MODES"){ //qDebug() << "SetupDialog::processConfigLine: MODES: " << value << endl; readActiveModes(value); modes.removeDuplicates(); bandModePage->setActiveModes(modes); //qDebug() << "SetupDialog::processConfigLine: MODES-2: " << value << endl; }else if (tab=="BANDS"){ readActiveBands(value); bands.removeDuplicates(); bandModePage->setActiveBands(bands); //}else if (tab=="INMEMORY"){ // miscPage->setInMemory(value); }else if (tab=="REALTIME"){ miscPage->setRealTime(value); }else if (tab=="UTCTIME"){ miscPage->setUTCTime(value); }else if (tab=="ALWAYSADIF"){ miscPage->setAlwaysADIF(value); }else if (tab=="USEDEFAULTNAME"){ miscPage->setDefaultFileName(value); }else if (tab=="DBPATH"){ miscPage->setUseDefaultDBPath(value); }else if (tab=="DEFAULTADIFFILE"){ miscPage->setDefaultFileName(value.toLower()); //qDebug() << "SetupDialog::processConfigLine: FILE: " << value << endl; }else if (tab=="IMPERIALSYSTEM"){ miscPage->setImperial(value.toLower()); }else if (tab=="KEEPMYDATA"){ miscPage->setKeepMyData(value.toLower()); }else if (tab=="COMPLETEWITHPREVIOUS"){ miscPage->setCompleteWithPrevious(value.toLower()); }else if (tab=="SENDQSLWHENREC"){ miscPage->setSendQSLWhenRec(value.toLower()); } else if (tab=="SHOWCALLSIGNINSEARCH"){ miscPage->setShowStationCallSignInSearch(value.toLower()); } else if (tab=="CHECKNEWVERSIONS"){ miscPage->setCheckNewVersions(value); } else if (tab=="PROVIDEINFO"){ miscPage->setReportInfo(value); } else if (tab =="NAME") { userDataPage->setName(value); } else if (tab =="ADDRESS1") { userDataPage->setAddress1(value); } else if (tab =="ADDRESS2") { userDataPage->setAddress2(value); } else if (tab =="ADDRESS3") { userDataPage->setAddress3(value); } else if (tab =="ADDRESS4") { userDataPage->setAddress4(value); } else if (tab =="CITY") { userDataPage->setCity(value); } else if (tab =="ZIPCODE") { userDataPage->setZipCode(value); } else if (tab =="PROVINCESTATE") { userDataPage->setProvince(value); } else if (tab =="COUNTRY") { userDataPage->setCountry(value); } else if (tab =="POWER") { userDataPage->setPower(value); } else if (tab =="RIG1") { userDataPage->setRig1(value); } else if (tab =="RIG2") { userDataPage->setRig2(value); } else if (tab =="RIG3") { userDataPage->setRig3(value); } else if (tab =="ANTENNA1") { userDataPage->setAntenna1(value); } else if (tab =="ANTENNA2") { userDataPage->setAntenna2(value); } else if (tab =="ANTENNA3") { userDataPage->setAntenna3(value); } else if (tab =="STATIONLOCATOR"){ if ( locator->isValidLocator(value) ) { userDataPage->setStationLocator(value); } }else if (tab =="DXCLUSTERSHOWHF"){ dxClusterPage->setShowHFRadiobutton(value); }else if (tab =="DXCLUSTERSHOWVHF"){ dxClusterPage->setShowVHFRadiobutton(value); }else if (tab =="DXCLUSTERSHOWWARC"){ dxClusterPage->setShowWARCRadiobutton(value); }else if (tab =="DXCLUSTERSHOWWORKED"){ dxClusterPage->setShowWorkedRadiobutton(value); }else if (tab =="DXCLUSTERSHOWCONFIRMED"){ dxClusterPage->setShowConfirmedRadiobutton(value); }else if (tab =="DXCLUSTERSHOWANN"){ dxClusterPage->setShowANNRadiobutton(value); }else if (tab =="DXCLUSTERSHOWWWV"){ dxClusterPage->setShowWWVRadiobutton(value); }else if (tab =="DXCLUSTERSHOWWCY"){ dxClusterPage->setShowWCYRadiobutton(value); }else if(tab =="DXCLUSTERSERVERPORT"){ dxClusterServers << value; //qDebug() << "SetupDialog::processConfigLine: dxClusterServers: " << dxClusterServers.last() << endl; }else if (tab =="DXCLUSTERSERVERTOUSE"){ dxClusterServerToUse=value; } else if(tab =="NEWONECOLOR"){ colorsPage->setNewOneColor(value); }else if(tab =="NEEDEDCOLOR"){ colorsPage->setNeededColor(value); }else if(tab =="WORKEDCOLOR"){ colorsPage->setWorkedColor(value); }else if(tab =="CONFIRMEDCOLOR"){ colorsPage->setConfirmedColor(value); }else if(tab =="DEFAULTCOLOR"){ colorsPage->setDefaultColor(value); }else if(tab =="SELECTEDLOG"){ //qDebug() << "SetupDialog::processConfigLine: SELECTEDLOG: " << value << endl; i = value.toInt(); if (dataProxy->doesThisLogExist(i)) { //qDebug() << "SetupDialog::processConfigLine: dataProxy->doesThisLogExist TRUE" << endl; } else { //qDebug() << "SetupDialog::processConfigLine: dataProxy->doesThisLogExist FALSE" << endl; i = 0; while(!dataProxy->doesThisLogExist(i)) { i++; } } logsPage->setSelectedLog(i); //qDebug() << "SetupDialog::processConfigLine: dataProxy->doesThisLogExist END" << endl; }else if(tab =="CLUBLOGACTIVE"){ clubLogPage->setClubLog(value); } else if(tab =="CLUBLOGREALTIME"){ clubLogPage->setClubLogRealTime(value); } else if(tab =="CLUBLOGCALL"){ clubLogPage->setCallsign(value); } else if(tab =="CLUBLOGPASS"){ clubLogPage->setPassword(value); } else if(tab =="CLUBLOGEMAIL"){ clubLogPage->setEmail(value); } else if(tab =="CLUBLOGUSESTATIONCALLSIGN"){ clubLogPage->setUseStationCall(value); }else{ //qDebug() << "SetupDialog::processConfigLine: NONE: " << endl; } // Lines are: Option = value; //qDebug() << "SetupDialog::processConfigLine: END " << endl; return true; } void SetupDialog::readActiveBands (const QString actives) { // Checks a "10m, 12m" QString, checks if they are valid bands and import to the // bands used in the program //qDebug() << "SetupDialog::readActiveBands: " << actives << endl; bool atLeastOne = false; QStringList values = actives.split(", ", QString::SkipEmptyParts); QStringList _abands; for (int i = 0; i < values.size() ; i++) { if (isValidBand(values.at(i))) { if (!atLeastOne) { //qDebug() << "SetupDialog::readActiveBands (at least One!): " << values.at(i) << endl; atLeastOne = true; _abands.clear(); } _abands << values.at(i); //qDebug() << "SetupDialog::readActiveBands: " << values.at(i) << endl; } } bands.clear(); _abands.removeDuplicates(); bands << dataProxy->getBandsInLog(-1); bands << _abands; bands.removeDuplicates(); } void SetupDialog::readActiveModes (const QString actives) { //qDebug() << "SetupDialog::readActiveModes: " << actives << endl; bool atLeastOne = false; QStringList _amodes;//, _backModes; // _backModes.clear(); // _backModes << modes; QStringList values = actives.split(", ", QString::SkipEmptyParts); values.removeDuplicates(); for (int i = 0; i < values.size() ; i++) { if (isValidMode(values.at(i))) { if (!atLeastOne) { atLeastOne = true; _amodes.clear(); } _amodes << values.at(i); } } modes.clear(); modes << dataProxy->getModesInLog(-1); modes << _amodes; modes.removeDuplicates(); //qDebug() << "SetupDialog::readActiveModes-end: " << modes.join(" / ") << endl; } bool SetupDialog::isValidBand (const QString b) { //qDebug() << "SetupDialog::isValidBand: "<< b << endl; QString stringQuery = QString("SELECT id FROM band WHERE name='%1'").arg(b); QSqlQuery query(stringQuery); query.next(); return query.isValid(); } bool SetupDialog::isValidMode (const QString b) { //qDebug() << "SetupDialog::isValidMode: " << b << endl; QString stringQuery = QString("SELECT id FROM mode WHERE name='%1'").arg(b); QSqlQuery query(stringQuery); query.next(); return query.isValid(); } void SetupDialog::setDefaults() { //qDebug() << "SetupDialog::setDefaults" << endl; //miscPage->setInMemory("TRUE"); miscPage->setRealTime("TRUE"); miscPage->setUTCTime("TRUE"); miscPage->setImperial("FALSE"); //Metric system is the default miscPage->setAlwaysADIF("FALSE"); miscPage->setSendQSLWhenRec("TRUE"); miscPage->setShowStationCallSignInSearch("TRUE"); miscPage->setKeepMyData("TRUE"); miscPage->setCheckNewVersions("TRUE"); miscPage->setReportInfo("FALSE"); dxClusterPage->setShowHFRadiobutton("TRUE"); dxClusterPage->setShowVHFRadiobutton("TRUE"); dxClusterPage->setShowWARCRadiobutton("TRUE"); dxClusterPage->setShowWorkedRadiobutton("TRUE"); dxClusterPage->setShowConfirmedRadiobutton("TRUE"); dxClusterPage->setShowANNRadiobutton("TRUE"); dxClusterPage->setShowWWVRadiobutton("TRUE"); dxClusterPage->setShowWCYRadiobutton("TRUE"); dxClusterServers.clear(); dxClusterServers.append("dxfun.com:8000"); dxClusterServerToUse = "dxfun.com:8000"; if (modes.isEmpty()) { modes << "SSB" << "CW" << "RTTY"; modes.removeDuplicates(); } if (bands.isEmpty()) { bands << "10M" << "12M" << "15M" << "17M" << "20M" << "40M" << "80M" << "160M"; bands.removeDuplicates(); } } QString SetupDialog::checkAndFixASCIIinADIF(const QString _data) { //qDebug() << "SetupDialog::checkAndFixASCIIinADIF " << _data << endl; //TODO: this function is also in the FileManager class. Maybe I should call that one and keep just one copy ushort unicodeVal; QString st = _data; QString newString; newString.clear(); for(int i=0; i < st.length(); i++) { // Get unicode VALUE into unicodeVal unicodeVal = (st.at(i)).unicode(); if ((20 <= unicodeVal ) && (unicodeVal <= 126)) { newString.append(st.at(i)); } //qDebug() << "SetupDialog::checkAndFixunicodeinADIF: " << st.at(i) <<" = " << QString::number(unicodeVal) << endl; } // Show into another lineEdit return newString; } bool SetupDialog::haveAtleastOneLog() { return dataProxy->haveAtLeastOneLog(); } void SetupDialog::setClubLogActive(const bool _b) { if (_b == true) { clubLogPage->setClubLog("True"); } else { clubLogPage->setClubLog("False"); } } void SetupDialog::checkIfNewBandOrMode() { //qDebug() << "SetupDialog::checkIfNewBandOrMode " << endl; QStringList _items; _items.clear(); //qDebug() << "SetupDialog::checkIfNewBandOrMode -1" << endl; _items << dataProxy->getBandsInLog(-1); //qDebug() << "SetupDialog::checkIfNewBandOrMode -2" << endl; _items << (bandModePage->getBands()).split(", ", QString::SkipEmptyParts); //qDebug() << "SetupDialog::checkIfNewBandOrMode -3" << endl; _items.removeDuplicates(); //qDebug() << "SetupDialog::checkIfNewBandOrMode -4" << endl; bandModePage->setActiveBands(_items); //qDebug() << "SetupDialog::checkIfNewBandOrMode -5" << endl; _items.clear(); _items << dataProxy->getModesInLog(-1); _items << (bandModePage->getModes()).split(", ", QString::SkipEmptyParts); _items.removeDuplicates(); bandModePage->setActiveModes(_items); //qDebug() << "SetupDialog::checkIfNewBandOrMode END" << endl; } void SetupDialog::slotAnalyzeNewLogData(const QStringList _qs) { //qDebug() << "SetupDialog::slotAnalyzeNewLogData (length=" << QString::number(_qs.length()) << ")" << endl; //qDebug() << "SetupDialog::slotAnalyzeNewLogData" << endl; // We receive the station callsign and operators from the logs tab if (_qs.length()!=2) { return; } userDataPage->setStationQrz(_qs.at(0)); userDataPage->setOperators(_qs.at(1)); } void SetupDialog::slotSetStationCallSign(const QString _p) { //qDebug() << "SetupDialog::slotSetStationCallSign: " << _p << endl; logsPage->setDefaultStationCallsign(_p); } void SetupDialog::slotSetOperators(const QString _p) { //qDebug() << "SetupDialog::slotSetOperators: " << _p << endl; logsPage->setDefaultOperators(_p); } void SetupDialog::slotQueryErrorManagement(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery) { emit queryError(functionFailed, errorCodeS, errorCodeN, failedQuery); } klog-0.9.2.9/setuppagedxcluster.cpp0000644000076700000620000003375113233376355015255 0ustar staff/*************************************************************************** setuppagedxcluster.cpp - description ------------------- begin : nov 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include "setuppagedxcluster.h" SetupPageDxCluster::SetupPageDxCluster(QWidget *parent) : QWidget(parent) { //qDebug() << "SetupPageDxCluster::SetupPageDxCluster" << endl; //xClusterServers = new QStringList; //dxClusterServers << "dxfun.com:8000"; dxclusterServersComboBox = new QComboBox; dxclusterServersComboBox->addItem("dxfun.com:8000"); addClusterButton = new QPushButton; deleteClusterButton = new QPushButton; showHFRadiobutton = new QRadioButton; showVHFRadiobutton = new QRadioButton; showWARCRadiobutton = new QRadioButton; showWorkedRadiobutton = new QRadioButton; showConfirmedRadiobutton = new QRadioButton; showANNRadiobutton = new QRadioButton; showWWVRadiobutton = new QRadioButton; showWCYRadiobutton = new QRadioButton; saveAllDXClusterDataRadiobutton = new QRadioButton; showHFRadiobutton->setAutoExclusive(false); showVHFRadiobutton->setAutoExclusive(false); showWARCRadiobutton->setAutoExclusive(false); showWorkedRadiobutton->setAutoExclusive(false); showConfirmedRadiobutton->setAutoExclusive(false); showANNRadiobutton->setAutoExclusive(false); showWWVRadiobutton->setAutoExclusive(false); showWCYRadiobutton->setAutoExclusive(false); showHFRadiobutton->setChecked(true); showVHFRadiobutton->setChecked(true); showWARCRadiobutton->setChecked(true); showWorkedRadiobutton->setChecked(true); showConfirmedRadiobutton->setChecked(true); showANNRadiobutton->setChecked(true); showWWVRadiobutton->setChecked(true); showWCYRadiobutton->setChecked(true); addClusterButton->setText(tr("Add")); deleteClusterButton->setText(tr("Delete")); showHFRadiobutton->setText(tr("Show &HF spots")); showVHFRadiobutton->setText(tr("Show V/&UHF spots")); showWARCRadiobutton->setText(tr("Show W&ARC spots")); showWorkedRadiobutton->setText(tr("Show &worked spots")); showConfirmedRadiobutton->setText(tr("Show &confirmed spots")); showANNRadiobutton->setText(tr("Show ANN/&FULL messages")); showWWVRadiobutton->setText(tr("Show WW&V messages")); showWCYRadiobutton->setText(tr("Show WC&Y messages")); QGroupBox *spotsGroupBox = new QGroupBox(tr("DX Spots")); QVBoxLayout *spotsVBoxLayout = new QVBoxLayout; spotsVBoxLayout->addWidget(showHFRadiobutton); spotsVBoxLayout->addWidget(showVHFRadiobutton); spotsVBoxLayout->addWidget(showWARCRadiobutton); spotsVBoxLayout->addWidget(showWorkedRadiobutton); spotsVBoxLayout->addWidget(showConfirmedRadiobutton); spotsVBoxLayout->addStretch(1); spotsGroupBox->setLayout(spotsVBoxLayout); QGroupBox *messagesGroupBox = new QGroupBox(tr("Messages")); QVBoxLayout *messagesVBoxLayout = new QVBoxLayout; messagesVBoxLayout->addWidget(showANNRadiobutton); messagesVBoxLayout->addWidget(showWWVRadiobutton); messagesVBoxLayout->addWidget(showWCYRadiobutton); messagesVBoxLayout->addStretch(1); messagesGroupBox->setLayout(messagesVBoxLayout); // ( QWidget * widget, int fromRow, int fromColumn, int rowSpan, //int columnSpan, Qt::Alignment alignment = 0 ) QHBoxLayout *serversButtonsLayout = new QHBoxLayout; serversButtonsLayout->addSpacerItem(new QSpacerItem(10,0,QSizePolicy::Expanding,QSizePolicy::Maximum)); serversButtonsLayout->addWidget(addClusterButton); serversButtonsLayout->addWidget(deleteClusterButton); QVBoxLayout *serversLayout = new QVBoxLayout; serversLayout->addWidget(dxclusterServersComboBox); serversLayout->addLayout(serversButtonsLayout); QGridLayout *mainLayout = new QGridLayout; mainLayout->addLayout(serversLayout, 0, 0); mainLayout->addWidget(spotsGroupBox, 1, 0); mainLayout->addWidget(messagesGroupBox, 1, 1); setLayout(mainLayout); createActions(); //qDebug() << "SetupPageDxCluster::SetupPageDxCluster - END" << endl; } SetupPageDxCluster::~SetupPageDxCluster() { //qDebug() << "SetupPageDxCluster::~SetupPageDxCluster" << endl; } void SetupPageDxCluster::createActions() { //qDebug() << "SetupPageDxCluster::createActions" << endl; connect(addClusterButton, SIGNAL(clicked()), this, SLOT(slotAddButtonClicked()) ); connect(deleteClusterButton, SIGNAL(clicked()), this, SLOT(slotDeleteButtonClicked()) ); } void SetupPageDxCluster::slotAddButtonClicked() { //qDebug() << "SetupPageDxCluster::slotAddButtonClicked" << endl; bool ok; ok = false; while (!ok) { QString text = QInputDialog::getText (this, tr("KLog: Add a DXCluster server"), tr("Add the address followed by the :port\nExample: dxfun.com:8000\nIf no port is specified, 41112 will be used by default:"), QLineEdit::Normal, QString::null, &ok); if (ok && !text.isEmpty ()) { if (checkIfValidDXCluster (text)) { if (checkIfNewDXCluster (text)) { ok = true; if ((text.contains (":")) == 0) { text = text + ":41112"; } dxclusterServersComboBox->insertItem (0, text); } else { ok = false; } } else { ok = false; } } else { // user entered nothing or pressed Cancel ok = true; } } } void SetupPageDxCluster::slotDeleteButtonClicked() { //qDebug() << "SetupPageDxCluster::slotDeleteButtonClicked" << endl; dxclusterServersComboBox->removeItem (dxclusterServersComboBox->currentIndex ()); } bool SetupPageDxCluster::checkIfValidDXCluster (const QString & tdxcluster) { QUrl url ("http://" + tdxcluster); if ((!url.host ().isEmpty ()) || (url.port () != -1)) { return true; } else { return false; } } bool SetupPageDxCluster::checkIfNewDXCluster (const QString & tdxcluster) { //qDebug() << "checkIfNewDXCluster: -" << tdxcluster << "-"<< endl; int numberOfDXClusterServers = dxclusterServersComboBox->count (); for (int i = 0; i <= numberOfDXClusterServers - 1; i++) { if ((dxclusterServersComboBox->currentText ()) == (tdxcluster)) { return false; } else { return true; } dxclusterServersComboBox->setCurrentIndex(i); } return true; } QStringList SetupPageDxCluster::getDxclusterServersComboBox() { //qDebug() << "SetupPageDxCluster::getDxclusterServersComboBox" << endl; QStringList servers; int numberOfDXClusterServers = dxclusterServersComboBox->count (); servers.clear(); if(numberOfDXClusterServers>=1) { //stream << "DXClusterServerToUse=" << dxclusterServersComboBox->currentText () << endl; //servers << dxclusterServersComboBox->currentText (); for (int i = 0; i <= numberOfDXClusterServers - 1; i++) { dxclusterServersComboBox->setCurrentIndex (i); servers << dxclusterServersComboBox->currentText (); //stream << "DXClusterServerPort=" << dxclusterServersComboBox->currentText () << endl; } } return servers; } void SetupPageDxCluster::setDxclusterServersComboBox(const QStringList t) { //qDebug() << "SetupPageDxCluster::setDxclusterServersComboBox" << endl; if (t.count()>0) { QString text; for (int i=0; i < t.count(); i++) { text.clear(); text = t.at(i); if (checkIfValidDXCluster (text)) { if (checkIfNewDXCluster (text)) { if ((text.contains (":")) == 0) { text = text + ":41112"; } dxclusterServersComboBox->insertItem (0, text); } else { // Not added } } } } } QString SetupPageDxCluster::getShowHFRadiobutton() { if (showHFRadiobutton->isChecked()) { return "True"; } else { return "False"; } } QString SetupPageDxCluster::getShowVHFRadiobutton() { if (showVHFRadiobutton->isChecked()) { return "True"; } else { return "False"; } } QString SetupPageDxCluster::getShowWARCRadiobutton() { if (showWARCRadiobutton->isChecked()) { return "True"; } else { return "False"; } } QString SetupPageDxCluster::getShowWorkedRadiobutton() { if (showWorkedRadiobutton->isChecked()) { return "True"; } else { return "False"; } } QString SetupPageDxCluster::getShowConfirmedRadiobutton() { if (showConfirmedRadiobutton->isChecked()) { return "True"; } else { return "False"; } } QString SetupPageDxCluster::getShowANNRadiobutton() { if (showANNRadiobutton->isChecked()) { return "True"; } else { return "False"; } } QString SetupPageDxCluster::getShowWWVRadiobutton() { if (showWWVRadiobutton->isChecked()) { return "True"; } else { return "False"; } } QString SetupPageDxCluster::getShowWCYRadiobutton() { if (showWCYRadiobutton->isChecked()) { return "True"; } else { return "False"; } } void SetupPageDxCluster::setShowHFRadiobutton(const QString t) { if ( (t.toUpper()) == "FALSE") { showHFRadiobutton->setChecked(false); } else { showHFRadiobutton->setChecked(true); } } void SetupPageDxCluster::setShowVHFRadiobutton(const QString t) { if ( (t.toUpper()) == "FALSE") { showVHFRadiobutton->setChecked(false); } else { showVHFRadiobutton->setChecked(true); } } void SetupPageDxCluster::setShowWARCRadiobutton(const QString t) { if ( (t.toUpper()) == "FALSE") { showWARCRadiobutton->setChecked(false); } else { showWARCRadiobutton->setChecked(true); } } void SetupPageDxCluster::setShowWorkedRadiobutton(const QString t) { if ( (t.toUpper()) == "FALSE") { showWorkedRadiobutton->setChecked(false); } else { showWorkedRadiobutton->setChecked(true); } } void SetupPageDxCluster::setShowConfirmedRadiobutton(const QString t) { if ( (t.toUpper()) == "FALSE") { showConfirmedRadiobutton->setChecked(false); } else { showConfirmedRadiobutton->setChecked(true); } } void SetupPageDxCluster::setShowANNRadiobutton(const QString t) { if ( (t.toUpper()) == "FALSE") { showANNRadiobutton->setChecked(false); } else { showANNRadiobutton->setChecked(true); } } void SetupPageDxCluster::setShowWWVRadiobutton(const QString t) { if ( (t.toUpper()) == "FALSE") { showWWVRadiobutton->setChecked(false); } else { showWWVRadiobutton->setChecked(true); } } void SetupPageDxCluster::setShowWCYRadiobutton(const QString t) { if ( (t.toUpper()) == "FALSE") { showWCYRadiobutton->setChecked(false); } else { showWCYRadiobutton->setChecked(true); } } QString SetupPageDxCluster::getSelectedDxClusterServer() { //return dxclusterServersComboBox->currentText(); int dxclusterServerListItems = dxclusterServersComboBox->count (); if (dxclusterServerListItems >= 1) { return dxclusterServersComboBox->currentText (); } else { return QString::null; } return QString::null; } void SetupPageDxCluster::setSelectedDxClusterServer(const QString t) { dxclusterServersComboBox->setCurrentIndex(dxclusterServersComboBox->findText(t)); } klog-0.9.2.9/mainwindowinputeqsl.h0000644000076700000620000000711513233376355015103 0ustar staff#ifndef MAINWINDOWINPUTEQSL_H #define MAINWINDOWINPUTEQSL_H /*************************************************************************** mainwindowinputeqsl.h - description ------------------- begin : jun 2017 copyright : (C) 2017 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implement the tab of the mainwindow that supports the eQSL options // #include #include #include #include "dataproxy.h" #include "utilities.h" class MainWindowInputEQSL : public QWidget { Q_OBJECT public: explicit MainWindowInputEQSL(DataProxy *dp, QWidget *parent = 0); //~MainWindowInputEQSL(); //void setData(const QString _comment); //QString getComment(); void clear(); QString getClubLogStatus(); QString getEQSLRecStatus(); QString getEQSLSenStatus(); QString getLOTWRecStatus(); QString getLOTWSenStatus(); void setClubLogStatus(const QString _qs); void setEQSLRecStatus(const QString _qs); void setEQSLSenStatus(const QString _qs); void setLOTWRecStatus(const QString _qs); void setLOTWSenStatus(const QString _qs); QDate getClubLogDate(); QDate getEQSLRecDate(); QDate getEQSLSenDate(); QDate getLOTWRecDate(); QDate getLOTWSenDate(); void setClubLogDate(const QDate _qs); void setEQSLRecDate(const QDate _qs); void setEQSLSenDate(const QDate _qs); void setLOTWRecDate(const QDate _qs); void setLOTWSenDate(const QDate _qs); signals: private slots: void slotClubLogComboBoxChanged(); void sloteQSLRecvComboBoxChanged(); void sloteQSLSentComboBoxChanged(); void slotLotwRecvComboBoxChanged(); void slotLotwSentComboBoxChanged(); private: void createUI(); void setDefaultData(); QComboBox *eqslSentComboBox, *eqslRecComboBox, *lotwSentComboBox, *lotwRecComboBox, *clublogComboBox; QDateEdit *eqslSentQDateEdit, *eqslRecQDateEdit, *lotwSentQDateEdit, *lotwRecQDateEdit, *clublogQDateEdit; DataProxy *dataProxy; Utilities *util; QStringList qslSentStatusList, qslRcvdStatusList, clubLogStatusList; }; #endif // MAINWINDOWINPUTEQSL_H klog-0.9.2.9/showerrordialog.cpp0000644000076700000620000000372313233376355014530 0ustar staff#include "showerrordialog.h" ShowErrorDialog::ShowErrorDialog() { //qDebug() << "ShowErrorDialog::ShowErrorDialog" << endl; text.clear(); setWindowTitle(tr("KLog Message")); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QVBoxLayout *layout = new QVBoxLayout(this); layout->setSizeConstraint(QLayout::SetFixedSize); txtLabel = new QLabel(text); // QLabel *txtLabel = new QLabel(text); txtLabel->setWordWrap(true); txtLabel->setOpenExternalLinks(true); txtLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); QPushButton *closeButton = buttonBox->button(QDialogButtonBox::Close); buttonBox->addButton(closeButton, QDialogButtonBox::ButtonRole(QDialogButtonBox::RejectRole | QDialogButtonBox::AcceptRole)); connect(buttonBox , &QDialogButtonBox::rejected, this, &QDialog::reject); txtLabel->setFrameShadow(QFrame::Raised); txtLabel->setFrameStyle(QFrame::StyledPanel); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addWidget(closeButton); //QVBoxLayout *mainLayout = new QVBoxLayout; layout->addWidget(txtLabel); layout->addLayout(buttonsLayout); setLayout(layout); //qDebug() << "ShowErrorDialog::ShowErrorDialog - END" << endl; } void ShowErrorDialog::setText(const QString txt) { //qDebug() << "ShowErrorDialog::setVersion: " << tversion << endl; text = txt; txtLabel->setText(txt); //textBrowser->setHtml(text); } ShowErrorDialog::~ShowErrorDialog() { //qDebug() << "ShowErrorDialog::~ShowErrorDialog" << endl; } void ShowErrorDialog::slotAcceptButtonClicked() { //qDebug() << "ShowErrorDialog::slotAcceptButtonClicked" << endl; accept(); } void ShowErrorDialog::keyPressEvent(QKeyEvent *event){ switch (event->key()) { break; default: //QFrame::keyPressEvent(event) slotAcceptButtonClicked(); } } klog-0.9.2.9/INSTALL-win.txt0000644000076700000620000000014713233376355013251 0ustar staffInstalling KLog on a Windows system is easy. Just double-click on the installer and follow the steps. klog-0.9.2.9/setuppagelogs.cpp0000644000076700000620000005461313233376355014204 0ustar staff/*************************************************************************** setuppagelogs.cpp - description ------------------- begin : feb 2012 copyright : (C) 2012 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include "setuppagelogs.h" SetupPageLogs::SetupPageLogs(DataProxy *dp, QWidget *parent) : QWidget(parent){ //qDebug() << "SetupPageLogs::SetupPageLogs" << endl; dataProxy = dp; stationCallsign = QString(); operators = QString(); comment = QString(); //dateString = QDate::currentDate().toString("yyyy/MM/dd"); dateString = QString(); typeContest = QString(); contestCatMode = -1; contestCatOperators = -1; contestCatAssisted = -1; contestCatPower = -1; contestCatBands = -1; contestBands = -1; typeContestN = -1; selectedLog = -1; defaultStationCallSign.clear(); //setupD = new SetupDialog(); currentLogs = new QComboBox(); logsAvailable.clear(); newLog = new SetupPageLogsNew(dataProxy); logsModel = new QSqlRelationalTableModel(this); logsView = new QTableView; logsView->setContextMenuPolicy(Qt::CustomContextMenu); logsView->setSortingEnabled(true); createLogsModel(); createLogsPanel(); logsView->setCurrentIndex(logsModel->index(0, 0)); lastLog = 0; newLogPushButton = new QPushButton(tr("&New"), this); editPushButton = new QPushButton(tr("&Edit"), this); removePushButton = new QPushButton(tr("&Remove"), this); newLogPushButton->setToolTip(tr("Add a new log")); //loadAllPushButton->setToolTip(tr("Load all the logs")); //loadSelectedPushButton->setToolTip(tr("Load only the selected log")); //clearPushButton->setToolTip(tr("Clear selection")); editPushButton->setToolTip(tr("Edit the selected log")); removePushButton->setToolTip(tr("Remove the selected log")); currentLogs->setToolTip(tr("Select the log you want to open")); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addWidget(newLogPushButton); buttonsLayout->addWidget(editPushButton); buttonsLayout->addWidget(removePushButton); QVBoxLayout *widgetLayout = new QVBoxLayout; widgetLayout->addWidget(logsView); widgetLayout->addWidget(currentLogs); widgetLayout->addLayout(buttonsLayout); //widgetLayout->addLayout(logDataLayout); setLayout(widgetLayout); //connect(newLogPushButton, SIGNAL(clicked ( )), this, SLOT(slotNewButtonClicked() ) ); //QObject::connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(slotDownloadFinished(QNetworkReply*))); //connect(setupD, SIGNAL(newLogRequested(true)), this, slotNewButtonClicked() ) createActions(); updateSelectedLogs(); //qDebug() << "SetupPageLogs::SetupPageLogs - END" << endl; } SetupPageLogs::~SetupPageLogs(){ //qDebug() << "SetupPageLogs::~SetupPageLogs" << endl; } void SetupPageLogs::createNewLog() { //qDebug() << "SetupPageLogs::createNewLog" << endl; selectedLog = -1; //newLog->clear(); newLog->setEditing(false); if (defaultStationCallSign.length()>2) { newLog->setStationCallSign(defaultStationCallSign); } if (defaultOperators.length()>2) { newLog->setOperators(defaultOperators); } newLog->setDateString(QDate::currentDate().toString("yyyy/MM/dd")); newLog->setComment(""); newLog->exec(); } void SetupPageLogs::slotNewButtonClicked() { //qDebug() << "SetupPageLogs::slotNewButtonClicked" << endl; createNewLog(); } void SetupPageLogs::slotEditButtonClicked() { //qDebug() << "SetupPageLogs::slotEditButtonClicked" << endl; //QSqlQuery query; //int nameCol = -1; selectedLog = getSelectedLog(); QString getStationCallSignFromLog(const int _log); newLog->setEditing(true); newLog->setStationCallSign(dataProxy->getStationCallSignFromLog(selectedLog)); newLog->setOperators(dataProxy->getOperatorsFromLog(selectedLog)); newLog->setComment(dataProxy->getCommentsFromLog(selectedLog)); newLog->setDateString(dataProxy->getLogDateFromLog(selectedLog)); newLog->setTypeN(dataProxy->getLogTypeNFromLog(selectedLog).toInt()); /* //qDebug() << "SetupPageLogs::slotEditButtonClicked-1 (selectedlog: " << QString::number(selectedLog) << ")" << endl; QString stringQuery = QString("SELECT * FROM logs WHERE id='%1'").arg(selectedLog); //qDebug() << "SetupPageLogs::slotEditButtonClicked -2" << endl; bool sqlOk = query.exec(stringQuery); QSqlRecord rec = query.record(); if (sqlOk) { //qDebug() << "SetupPageLogs::slotEditButtonClicked Query OK" << endl; QSqlRecord rec = query.record(); if ( (query.next()) && (query.isValid()) ) {//id/logdate/stationcall/comment/logtype/logtypeid //qDebug() << "SetupPageLogs::slotEditButtonClicked Query Valid" << endl; //nameCol = rec.indexOf("stationcall"); //newLog->setStationCallSign((query.value(nameCol)).toString()); //nameCol = rec.indexOf("operators"); //newLog->setOperators((query.value(nameCol)).toString()); //nameCol = rec.indexOf("comment"); //newLog->setComment((query.value(nameCol)).toString()); //nameCol = rec.indexOf("logdate"); //newLog->setDateString((query.value(nameCol)).toString()); //nameCol = rec.indexOf("logtypen"); //qDebug() << "SetupPageLogs::slotEditButtonClicked -3" << endl; //newLog->setTypeN((query.value(nameCol)).toInt()); newLog->exec(); } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } */ } void SetupPageLogs::slotLogsCancelled(const bool _q) { selectedLog = -1; } void SetupPageLogs::slotRemoveButtonClicked() { //qDebug() << "SetupPageLogs::slotRemoveButtonClicked" << endl; int selectedLog = getSelectedLog(); QMessageBox::StandardButton ret; ret = QMessageBox::warning(this, tr("KLog"), tr("Do you really want to remove this log?") + "\n" + tr("All the QSOs from this log will be also deleted..."), QMessageBox::Yes | QMessageBox::No); if (ret == QMessageBox::Yes) { //qDebug() << "SetupPageLogs::slotRemoveButtonClicked (selected log to remove: " << QString::number(selectedLog) << ")" << endl; QString stringQuery = QString("DELETE FROM logs WHERE id='%1'").arg(selectedLog); QSqlQuery query(stringQuery); bool sqlOk = query.exec(); if (sqlOk) { //qDebug() << "SetupPageLogs::slotRemoveButtonClicked (REMOVED: " << QString::number(selectedLog) << ")" << endl; logsModel->select(); updateSelectedLogs(); stringQuery = QString("DELETE FROM log WHERE lognumber='%1'").arg(selectedLog); query.exec(stringQuery); sqlOk = query.exec(); //qDebug() << "SetupPageLogs::slotRemoveButtonClicked: LastQuery: " << query.lastQuery() << endl; if (sqlOk) { //qDebug() << "SetupPageLogs::slotRemoveButtonClicked (QSOS REMOVED: " << QString::number(selectedLog) << ")" << endl; stringQuery = QString("DELETE FROM awarddxcc WHERE lognumber='%2'").arg(selectedLog); query.exec(stringQuery); sqlOk = query.exec(); //qDebug() << "SetupPageLogs::slotRemoveButtonClicked: LastQuery: " << query.lastQuery() << endl; if (sqlOk) { //qDebug() << "SetupPageLogs::slotRemoveButtonClicked (AWARDDXCC REMOVED: " << QString::number(selectedLog) << ")" << endl; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); showError(tr("Log has not been removed. (#3)")); //qDebug() << "SetupPageLogs::slotRemoveButtonClicked (AWARDDXCC NOT REMOVED: " << QString::number(selectedLog) << ")" << endl; } } else { showError(tr("Log has not been removed. (#2)")); //qDebug() << "SetupPageLogs::slotRemoveButtonClicked (QSOS NOT REMOVED: " << QString::number(selectedLog) << ")" << endl; } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); showError(tr("Log has not been removed. (#1)")); //qDebug() << "SetupPageLogs::slotRemoveButtonClicked (NOT REMOVED: " << QString::number(selectedLog) << ")" << endl; } } //ASK FOR A CONFIRMATION //DELETE ALL THE QSO IN THE REMOVED LOG } void SetupPageLogs::createLogsPanel() { //qDebug() << "SetupPageLogs::createLogsPanel" << endl; logsView->setModel(logsModel); QString stringQuery = QString("SELECT * FROM logs"); QSqlQuery query(stringQuery); QSqlRecord rec = query.record(); // Number of columns int columns = rec.count(); for (int i = 0; i < columns; i++ ){ logsView->setColumnHidden(i, true); } columns = rec.indexOf("id"); logsView->setColumnHidden(columns, false); columns = rec.indexOf("logdate"); logsView->setColumnHidden(columns, false); columns = rec.indexOf("stationcall"); logsView->setColumnHidden(columns, false); columns = rec.indexOf("operators"); logsView->setColumnHidden(columns, false); columns = rec.indexOf("comment"); logsView->setColumnHidden(columns, false); columns = rec.indexOf("logtype"); logsView->setColumnHidden(columns, false); logsView->setItemDelegate(new QSqlRelationalDelegate(this)); logsView->setSelectionMode( QAbstractItemView::SingleSelection); logsView->setSelectionBehavior(QAbstractItemView::SelectRows); logsView->resizeColumnsToContents(); logsView->horizontalHeader()->setStretchLastSection(true); } void SetupPageLogs::createLogsModel() { //qDebug() << "SetupPageLogs::createLogsModel" << endl; QString stringQuery = QString("SELECT * FROM logs"); QSqlQuery q(stringQuery); QSqlRecord rec = q.record(); int nameCol; //logsModel = new QSqlRelationalTableModel(this); logsModel->setTable("logs"); nameCol = rec.indexOf("id"); logsModel->setSort(nameCol, Qt::AscendingOrder); logsModel->setHeaderData(nameCol, Qt::Horizontal, tr("ID")); nameCol = rec.indexOf("logdate"); logsModel->setHeaderData(nameCol, Qt::Horizontal, tr("Date")); nameCol = rec.indexOf("stationcall"); logsModel->setHeaderData(nameCol, Qt::Horizontal, tr("Station Callsign")); nameCol = rec.indexOf("operators"); logsModel->setHeaderData(nameCol, Qt::Horizontal, tr("Operators")); nameCol = rec.indexOf("comment"); logsModel->setHeaderData(nameCol, Qt::Horizontal, tr("Comments")); nameCol = rec.indexOf("logtype"); logsModel->setHeaderData(nameCol, Qt::Horizontal, tr("Type")); logsModel->select(); } void SetupPageLogs::slotLogSelected(const QModelIndex & index) { //qDebug() << "SetupPageLogs::slotLogSelected" << endl; int row = index.row(); setSelectedLog((logsModel->index(row, 0)).data(0).toInt()); } void SetupPageLogs::slotLogDoubleClicked(const QModelIndex & index) { //qDebug() << "SetupPageLogs::slotLogDoubleClicked" << endl; int row = index.row(); setSelectedLog((logsModel->index(row, 0)).data(0).toInt()); slotEditButtonClicked(); } void SetupPageLogs::createActions() { //qDebug() << "SetupPageLogs::createActions" << endl; connect(newLogPushButton, SIGNAL(clicked ( )), this, SLOT(slotNewButtonClicked() ) ); connect(removePushButton, SIGNAL(clicked ( )), this, SLOT(slotRemoveButtonClicked() ) ); connect(editPushButton, SIGNAL(clicked ( )), this, SLOT(slotEditButtonClicked() ) ); connect(newLog, SIGNAL(newLogData(QStringList)), this, SLOT(slotAnalyzeNewLogData(QStringList) ) ); connect(logsView, SIGNAL(clicked(QModelIndex)), this, SLOT(slotLogSelected(QModelIndex) ) ); connect(logsView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotLogDoubleClicked(QModelIndex) ) ); //connect(logView, SIGNAL(doubleClicked ( const QModelIndex& ) ), this, SLOT(slotDoubleClickLog( const QModelIndex& ) ) ); //loadAllPushButton->setToolTip(tr("Load all the logs")); //loadSelectedPushButton->setToolTip(tr("Load only the selected log")); //clearPushButton->setToolTip(tr("Clear selection")); } QStringList SetupPageLogs::readLogs() { //qDebug() << "SetupPageLogs::readLogs" << endl; QString aux, aux2; QStringList _logs; QSqlQuery query; int nameCol = -1; bool sqlOk = false; //QDate date = QDate::currentDate(); aux2.clear(); aux.clear(); _logs.clear(); aux = "SELECT id, logdate, stationcall, logtype FROM logs"; sqlOk = query.exec(aux); if (sqlOk) { QSqlRecord rec = query.record(); while ( (query.next()) && (query.isValid()) ) { aux2.clear(); nameCol = rec.indexOf("id"); aux2 = (query.value(nameCol)).toString(); nameCol = rec.indexOf("stationcall"); aux2 = aux2.append("-"); aux2.append((query.value(nameCol)).toString()); nameCol = rec.indexOf("logtype"); aux2 = aux2.append("-"); aux2.append((query.value(nameCol)).toString()); nameCol = rec.indexOf("logdate"); aux2 = aux2.append(" ("); aux2.append((query.value(nameCol)).toString()); aux2 = aux2.append(")"); _logs.append(aux2); } return _logs; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return _logs; } _logs.clear(); //qDebug() << "SetupPageLogs::readLogs: " << QString::number(_logs.size())<< endl; return _logs; } void SetupPageLogs::slotAnalyzeNewLogData(const QStringList _qs) { //qDebug() << "SetupPageLogs::slotAnalyzeNewLogData (length=" << QString::number(_qs.length()) << ")" << endl; if (_qs.length()!=14) { return; } /* From SetupPageLogsNew::gatherAndSend() logData.clear(); logData << stationCallsign << operators << comment << dateString << typeConteststr << QString::number(contestCatMode) << QString::number(contestCatOperators) << QString::number(contestCatAssisted) << QString::number(contestCatPower) << QString::number(contestCatBands) << QString::number(contestBands) << QString::number(contestCatOverlay) << QString::number(typeContest); << editing (1/0) */ stationCallsign = _qs.at(0); operators = _qs.at(1); comment = _qs.at(2); dateString = _qs.at(3); typeContest = _qs.at(4); /* contestCatMode = (_qs.at(5)).toInt(); contestCatOperators = (_qs.at(6)).toInt(); contestCatAssisted = (_qs.at(7)).toInt(); contestCatPower = (_qs.at(8)).toInt(); contestCatBands = (_qs.at(9)).toInt(); contestBands = (_qs.at(10)).toInt(); typeContestN = (_qs.at(12)).toInt(); */ /* bool editing; if ( (_qs.at(13)).toInt() == 1) { editing = true; } else { editing = false; } */ //OVERLAY = 11 /* QString _dateString = _qs.at(0); QString _stationCallsign = _qs.at(1); QString _operators = _qs.at(2); QString _typeContest = _qs.at(3); QString _comment = _qs.at(4); QString _typeContestN = _qs.at(5); QString id = _qs.at(6); QString editing = _qs.at(7); */ QStringList newLogq; newLogq.clear(); //If qs.at(12) == 1 then we are editing, any other value is a new log //Date/Call/Operators/"DX"/comment/"1" newLogq << dateString << stationCallsign << operators << typeContest << comment << "1" << QString::number(selectedLog) << _qs.at(13) ; if (dataProxy->addNewLog(newLogq)) { logsModel->select(); updateSelectedLogs(); } // We send the data to the main tab QStringList logData; logData.clear(); logData << stationCallsign << operators ; emit newLogData(logData); } /* bool SetupPageLogs::addNewLog(const QStringList _qs) { //qDebug() << "SetupPageLogs::addNewLog: " << _qs.at(2) << endl; QString aux = QString(); int nameCol = -1; QString _dateString = _qs.at(0); QString _stationCallsign = _qs.at(1); QString _typeContest = _qs.at(2); QString _comment = _qs.at(3); QString _typeContestN = _qs.at(4); QString queryString = QString("SELECT * FROM logs WHERE logdate='%1' AND stationcall='%2' AND logtype='%3' AND logtypen='%4'").arg(_dateString).arg(_stationCallsign).arg(_typeContest).arg(_typeContestN); //"logs" //"id, logdate, stationcall, comment, logtype" //qDebug() << "SetupPageLogs::addNewLog query1: " << queryString << endl; QSqlQuery query; bool sqlOK = query.exec(queryString); QSqlRecord rec = query.record(); // Number of columns while ( (query.next()) && (query.isValid()) ) { nameCol = rec.indexOf("id"); aux = (query.value(nameCol)).toString(); //qDebug() << "SetupPageLogs::addNewLog: id = " << aux << endl; return false; } queryString = QString("INSERT INTO logs (logdate, stationcall, comment, logtype, logtypen) values('%1','%2','%3','%4', '%5')").arg(_dateString).arg(_stationCallsign).arg(_comment).arg(_typeContest).arg(_typeContestN); //qDebug() << "SetupPageLogs::addNewLog query1: " << queryString << endl; sqlOK = query.exec(queryString); if (sqlOK) { //qDebug() << "SetupPageLogs::addNewLog ADDED! id = " << endl; logsModel->select(); updateSelectedLogs(); return true; } else { return false; } return false; } */ void SetupPageLogs::updateSelectedLogs() { //qDebug() << "SetupPageLogs::updateSelectedLogs" << endl; logsAvailable = readLogs(); if (logsAvailable.length()>0) { currentLogs->clear(); currentLogs->addItems(logsAvailable); } else { //qDebug() << "SetupPageLogs::updateSelectedLogs Not selected (less than 1)" << endl; currentLogs->clear(); } } int SetupPageLogs::getSelectedLog() { //qDebug() << "SetupPageLogs::getSelectedLog: " << currentLogs->currentText() << endl; QString selectedLog = currentLogs->currentText(); int i = 0; QStringList qs; qs.clear(); qs << selectedLog.split("-"); i = (qs.at(0)).toInt(); if (i>=1) { return i; } else { return 0; } return 0; } void SetupPageLogs::setSelectedLog(const int _i) { //qDebug() << "SetupPageLogs::SetupPageLogs::setSelectedLog: " << QString::number(_i) << endl; QString n = QString::number(_i) + "--"; int selected = currentLogs->findText(n, Qt::MatchStartsWith); if (selected >= 0) { //qDebug() << "SetupPageLogs::SetupPageLogs::setSelectedLog selected>0: " << QString::number(selected) << endl; currentLogs->setCurrentIndex(selected); } else { //qDebug() << "SetupPageLogs::SetupPageLogs::setSelectedLog not selcted" << endl; return; } } void SetupPageLogs::readSelectedLog(const int _i) { /* stationCallsign = _qs.at(0); operators = _qs.at(1); comment = _qs.at(2); dateString = _qs.at(3); typeContest = _qs.at(4); contestCatMode = (_qs.at(5)).toInt(); contestCatOperators = (_qs.at(6)).toInt(); contestCatAssisted = (_qs.at(7)).toInt(); contestCatPower = (_qs.at(8)).toInt(); contestCatBands = (_qs.at(9)).toInt(); contestBands = (_qs.at(10)).toInt(); */ } void SetupPageLogs::showError(const QString _errorC) { QString text = QString(tr("An error has occurred showing the following error code:") + "\n'%1'").arg(_errorC); QMessageBox::warning(this, tr("KLog - SetupPageLogs"), text, QMessageBox::Ok); } void SetupPageLogs::setDefaultStationCallsign(const QString _p) { //qDebug() << "SetupPageLogs::setDefaultStationCallsign: " << _p << endl; defaultStationCallSign = _p; } void SetupPageLogs::setDefaultOperators(const QString _p) { //qDebug() << "SetupPageLogs::setDefaultOperators: " << _p << endl; defaultOperators = _p; } klog-0.9.2.9/setupentitydialog.h0000644000076700000620000000671213233376355014541 0ustar staff#ifndef SETUPENTITYDIALOG_H #define SETUPENTITYDIALOG_H /*************************************************************************** SetupEntityDialog.h - description ------------------- begin : sept 2012 copyright : (C) 2012 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include #include #include #include class SetupEntityDialog : public QDialog { Q_OBJECT public: SetupEntityDialog(); ~SetupEntityDialog(); public slots: private slots: void slotOkButtonClicked(); void slotCancelButtonClicked(); void slotCheckEntity(); void slotCheckMainprefix(); void slotCheckCQz(); void slotCheckITUz(); void slotCheckContinent(); void slotCheckLatitude(); void slotCheckLongitude(); void slotCheckUTC(); void slotCheckARRLid(); void slotCheckDeleted(); void slotCheckDeletedDate(); void slotCheckPrefixes(); signals: void entityAdded(const QStringList _qs); // entity private: QString checkEntity(); QString checkMainprefix(); QString checkCQz(); QString checkITUz(); QString checkContinent(); QString checkLatitude(); QString checkLongitude(); QString checkUTC(); QString checkARRLid(); QString checkDeleted(); QString checkDeletedDate(); QString checkPrefixes(); bool entityBool, mainPrefixBool, cqBool, ituBool, contBool; bool latBool, lonBool, utcBool, arrlidBool, delBool, delDateBool, prefBool; QLineEdit *entityLineEdit, *cqLineEdit, *ituLineEdit; QLineEdit *contLineEdit, *latLineEdit, *lonLineEdit; QLineEdit *utcLineEdit, *mprefLineEdit, *arrlidLineEdit; QLineEdit *deletedLineEdit, *prefLineEdit; QDateEdit *delQDateEdit; QRadioButton *delRbutton; QStringList entityData; //QPalette *paletteOrig, *paletteWrong; //QColor color; QPalette pal, palw; }; #endif // SetupEntityDialog_H klog-0.9.2.9/Changelog0000644000076700000620000010475213233376355012430 0ustar staffJanuary - 0.9.2.9 - Bugfix: Adding new QSO that implies a DXCC or WAZ status already worked failed. - Bugfix: Modes where not properly added from the setup (TNX KB2YSI). - UI Change: Freq in the Satellite tab is now not deleted when a new QSO is added. - New translation: Catalan by Josep (Thank you!) - New translation: Finnish by Kristjan (Thank you!) January - 0.9.2.8 - Important Optimization on KLog speed on start and general use. - New satellites (AO-91 & AO-92) added. - Added ALL the ADIF 3.0.7 fields (except the _INTL ones). - New feature: New menus to export ADIF files for LoTW and manage LoTW status. - GUI: Implemented an error reporting for the users for main errors - GUI: When a satellite is selected the main bands are automatically proposed. - GUI: QSO band is now linked to the uplink & downlink bands in the satellite tab. - Bugfix: Some ADIF fields were not properly imported/exported. - Bugfix: When searching calls like 1A0XX, 2E0XX, ... no results were found but there are with 3D0XXX - Bugfix: If an empty log was selected on config file, on next KLog start KLog crashed. - Bugfix: Doubleclicking on the log to edit was sometimes causing the band/mode data to be shown as a number instead of the human readable name. - Bugfix: Windows version did not detected the DB movement correctly. - New translation: Polish by LA7RRA (Thank you!). - New translation: Danish by Joe (Thank you!). - Updated translations: Croatian (TNX M0NKC), Italian (TNX IU5HIU), Spanish (EA4TV) - Several internal updates. September 2017 - 0.9.2.7 - KLog offers the possibility to move the DB to another path (maybe a DropBox folder!) - New Operating systems recognized in runtime. - Updated the references to macOS from OSX. - Updated the list of valid modes up to ADIF 3.0.6. - Updated the list of valid propagation modes up to ADIF 3.0.6. - Update the 136KHz band limits to the new US licenses. - Optimized the speed of printing the log. - GUI: Added the QSO information done in a year on the DX-Marathon area. - GUI: Simplified the way active bands/modes are selected. - GUI: Satellite tab is redesigned. - GUI: Created a widget to manage all "eQSL" simplifying implementation of the main widget. - GUI: Created a widget to manage the Log, simplifying implementation of the main widget. - GUI: Created a widget to manage the Search, simplifying implementation of the main widget. - GUI: Added a SplashScreen on KLog start to show the user the starting process. - GUI: If the user adds a frequency in the TX Freq box that is not a currently used band, it is automatically added to the band seletion widget. - BugFix: Fixed how new logs were added to the DB. - BugFix: Identification is a band was HF or VHF was not always properly done. - BugFix: Higher bands where not shown to be selected in the preferences. - BugFix: DB updating function (009) blocked the execution of KLog the first time it was executed. - BugFix: Language message if English is the System language is no shown anymore. - New translation: Italian by IU5HIU (Thank you!). - Translations updated: Original English (TNX JustinBRye, from Debian-10n-english), Spanish (EA4TV), Japanese (TNX JL3OXR). May 2017 - 0.9.2.6 - Check updates feature added. On start or when user desires KLog checks if there is one updated version available. - Simplified the way new logs are added, importing the general StationCallsign & Operators as default for new logs. - Improved the way first start was managed when no entity information was loaded. - GUI: Application icon is now shown in the application windows. - GUI: Updated some messages & tips. - GUI: DXCluster offers the Station Callsign as default value to connect. - GUI: Some menu minor reorganization. - Console: Added a few commands to the console command. - Changed the World class to be able to import files from any folder. - Changed how some non ARRL valid entities are managed to show the common name (Sicily / Italy) - BugFix: When manually importing a new CTY.CSV, although data was updated, it was not shown until next KLog start. - BugFix: In the others tab, the DXCC was sometime not correctly identified. - BugFix: Update on the DXCC widget caused no data to be shown if some columns were selected. - BugFix: Identification is a band was HF or VHF was not always properly done. - BugFix: Some improvements in data quality when exporting an ADIF file. - BugFix: When importing an ADIF file, if the file was not correct it was not possible to cancel the whole importing process. - Some minor changes on source code to optimize and improve. - Translations updated: Croatian (TNX M0NKC), Japanese (TNX JL3OXR) & Spanish (EA4TV). November 2016 - 0.9.2.5 - BugFix: ADIF export function was not exporting the correct BAND & MODE data. September 2016 - 0.9.2.4 - GUI: Created a DXCC status where all the DXCC entities are listed showing the working/confirmed status. - GUI: Created a Satellite list including (up to now) only LOTW compatible satellites. - GUI: Created a widget to manage all "My Data" simplifying implementation of the main widget. - GUI: Bands in the combobox are always shown correctly ordered (botton-up). - GUI: Improved the LOTW date management (TNX JL3OXR). - BugFix: Preferences->Misc: It was not possible to edit the default filename. (TNX K6XT). - BugFix: Added the Power unit (W) to the power box. Debian bug #654332. - BugFix: When editing a QSO in some text boxes text was reused from previous QSO and data could be corrupted. - BugFix: Minor bug in WAZ management. - BugFix: When managing logs in the setup is was not possible to edit the log data as a new log was always created. - When starting KLog for the first time, the setup guidance has been improved. - When selecting an entity, different from the proposed on country file, KLog asks the user which one to use. - Operator from the selected log is used as default when entering QSO (as station callsign). - Japanese translation updated. (TNX JL3OXR). - Spanish translation updated. - Some cleaning in the code. January 2016 - 0.9.2.3 - Improved the way translations are managed (Specially in Linux). - Icon application is now shown in OSX & Windows. - New translation: Japanese by JL3OXR (Thank you!). - Bugfix: Some strings where not defined to be translated (TNX JL3OXR). - Bugfix: Some tips in the UI where not correctly placed (TNX JL3OXR). - Bugfix: QSOs in JT9 were not properly imported from ADIF (TNX EA3XQ). - Bugfix: Logfiles with the in the first line, following some test were not properly imported. November-2015 - 0.9.2.2 - Translations are now working properly in Windows & OSX. - New translation: Catalan by EA3NM (Thank you!). - Ported from Qt4 to Qt5. - BugFix: Aether ADIF files could not be properly imported. (TNX AA5VU). - BugFix: QSOs where not properly shown in the search box. - BugFix: When started for the first time, no modes were shown as default. - BugFix: CTY.CSV was not properly updated. - BugFix: When upgrading the mode information in database some modes where not properly updated. - GUI: Changed the year to show the full number to avoid problems with old QSO. - Import ADIF functionality is improved to support importing of logs with some missing data. - Removed the Spot button until its functionality is implemented. September-2015 - 0.9.2.1 -BugFix: Band & Mode information was not properly stored. August-2015 - 0.9.2 - Bugfix: An ADIF file with one blank line and one QSO used to froze KLog. - Bugfix: Minor bugfix in the definition of propagation modes. - BugFix: When editing a QSO the name was not shown. - BugFix: STX_String field was not always imported properly. - BugFix: Fixed a minor bug in log table regarding the prop_mode foreign key. - BugFix: Improved the color & status shown of a QSO on the DXCC. - BugFix: DXCluster: Fixed a bug that caused the colors to appear always as new one. - BugFix: DXCluster: The option to show only not confirmed was not working correcty. - BugFix: IOTA reference was not saved when entering a QSO. - BugFix: BIGCTY.DAT was not properly download in KLog first start. - GUI: Added some shortcuts in the preference widget. - GUI: DXCluster: Add a suggestion to hit enter if no password is expected for the cluster. (tnx AA5VI) - GUI: DXCluster: Warns you if the spot is needed for the current year DX-Marathon - GUI: Added a Propagation Mode Combobox. - GUI: Prop_Mode combobox automatically goes to SAT if sat name or sat mode are defined. - GUI: Added a Find DX-QSL requested option. - Added the 630M & 13CM bands. - Updated Mode & submode definition up to ADIF 3.0.4. - Special CQ & ITU zones in some calls are now identified. - KLog is able to import QSOs with no BAND field if FREQ field is present. - KLog offers the user a default value if RST_TX or RST_RX field is not present when importing. - Support of realtime upload, modification & removal of a single QSO to/from ClubLog.org. - Updated the DB with the PROP_MODE options. - Improved the way KLog manages & shows the bands & modes. - Removed the option to choose to run in memory or file in the start wizard. KLog will run always using a file for the DB. - Added an auto complete option to auto-complete info (QTH, Locator, Name, QSL Manager & IOTA) from previously worked QSO. - Cleared the world.cpp file. - Some minor performance improvements. April-2015 - 0.9.1.1 - Bugfix: Editing a QSO with satellite data was not properly done and caused some errors. April-2015 - 0.9.1 - Bugfix: Fixed DataBase::getBandIdFromFreq it was not ansswering properly. - Now checks if band & frequency are coherent before adding a QSO. Band wins. - All Satellite QSO include the PROP_MODE ADIF tag to make it compatible with LOTW. - Improved the DXMarathon code. - GUI: Added basic Satellite support. - GUI: It is possible to mark a QSL sent via bureau/direct & DX QSL as requested with one action from Search box. - GUI: KLog request a valid QRZ and at least one first logtype to start using it. - KLog supports the management of several logs, being possible to edit, remove and select the one to use. January-2015 - 0.9.0.3 - Bugfix: ADIF was not properly imported when Fields where using the Type of data optional field preventing logs from Logger32 being imported. (TNX EB1TR) - Bugfix: QSL Sent/Received status in the search box were switched. - Bugfix: CTY.CSV was not updated if the file was already existing. - Bugfix: Entity DB was not updated when CTY.CSV was updated. - Bugfix: Search results showed the default Station Callsign if non was in the QSO. This lead to errors if QRZ was not the default. - KLog recognizes now .ADIF files (instead of only .ADI). - KLog shows now the WAZ status. - Added a very basic support of DX Marathon (http://www.dxmarathon.com/). - DXCluster filters are now working. - The user can manually assign the DXCC entity for a DX. - Improved the function to update the DB from one release to the following. - DB file is compressed everytime KLog finishes. - It is possible to find QSL pending to receive. - It is possible to modify entities data in the World Editor in preferences. - It is possible to choose in preferences whether to keep my Data Tab from one QSO to the next or not. - GUI: A tooltip is shown in the search results showing the DXCC name / CQ zone. - GUI: Added a button to rescore awards. - GUI: Added a button to update the search Box without modifying the text. - GUI: Updates Bearing/distance/... when changing Locator. - GUI: When the QRZ lineedit is blank or the clear button is clicked, entity info is deleted (beam, distance, ...). - GUI: The IOTA continent is updated when the QRZ is modified. - GUI: DXCluster input is disabled when not connected. - GUI: Corrected the behaviour of the status bar. - GUI: Added primary & secondary subdivisions in the Others Tab. - Some other minor fixes. November-2014 - 0.9.0.2 - Bugfix: Right-click on search result sometimes caused KLog to crash. November-2014 - 0.9.0.1 - Bugfix: Selected DX-Cluster servers were not used to connect. (TNX DL6FBS) November-2014 - 0.9.0 - Ensures the ASCII requirement of ADIF. - Updated the Preferences dialog. - Added the About Qt help menu. - Bugfix: Selected DX-Cluster servers were not used to connect. - Bugfix: When selecting QSL received/sent with right click, date was not updated. - Bugfix: Fixed the FileManager::adifReadLog to be able to read logs with several lines per QSO. - Some other minor bugfixes. - New feature: It is possible to show Imperial System (Miles instead of Km) data. (TNX - KF5JNU) - New feature: It is possible to mark/look for & export requested QSL. - New feature: It is possible to automatically mark(or not) a QSL as requested by the DX when the DX's card is received. - New feature: It is possible to show (or not) the callsign used in the search box. - New feature: KLog uses bigcty.csv for normal DX & will use cty.csv for contesting. April-2014 - 0.7.1 - Backport to Qt 4.8. - Download the http://www.country-files.com/cty/cty.csv instead of cty.dat (with no ARRL id). - Capable to read cty.csv to get the info of the ARRL id. April-2014 - 0.7.0 - Full rewritten software based only in Qt. NO KDE dependency. - KLog can now run on Linux, OSX and Windows. November-2013 - 0.6.2 - Bug fixed: Under some conditions, KLog crashes when entering a new QRZ. (TNX LW1EQI). - Bug fixed: IOTA data was not properly cleared when clicking the Cancel button. - Bug fixed: QSL combobox content was not properly managed. (TNX DF4FH). - Bug (gui) fixed: IOTA continent is now "automagically" detected... again (a bug prevented this functionality). - GUI updated: You can click on RX or TX Frequency buttons to copy the frequency to the other one. - GUI updated: You can select eQSL in the QSL combobox as an option to mark the QSL information of a QSO. - GUI updated: Two new shortcuts: CTRL+W: deletes the current QSO. CTRL+Q: to (quick)edit the last QSO added. - GUI updated: Minor tab reorder. June-2013 - 0.6.1 - Bug fixed: Locator was not properly calculated due to a sign difference management from KLog and CTY.DAT. - GUI updated: The cursor position management of the QRZ box has been improved to ease the operation. January-2013 - 0.6.0 - Bug fixed: Typo "Frecuency" changed to "Frequency" in a tooltip. (Debian bug: #654328) (TNX Jonas Stein) - Bug fixed: Typo/wishlist "Numb" changed to "Number" in main table. (Debian bug: #654331) (TNX Jonas Stein) - Bug fixed: Typo/wishlist "UTC" changed to "Time" in main table. (Debian bug: #654331) (TNX Jonas Stein) - Removal of several not needed #includes. - Removed some warnings on compilation. - GUI improved: The information boxes are now independant from the top right tab widget to improve usability. - GUI updated: Disabled the Setup tab of Hamlib until hamlib is properly working. January-2012 - 0.5.9 - Bug fixed: When starting for the first time, the CTY.DAT file downloaded had a loop that was not properly managed. (Debian bug: #653697) (TNX Jonas Stein) - Fixed some typo: "Km" changed to "km". (Debian bug: #6536978) (TNX Jonas Stein) December-2011 - 0.5.8 - Bug fixed: Right button in the search result did not "sent" the QSL card. - Bug fixed: Closing the window did not ask to save data before exit. (TNX EA7HEG). - Bug fixed: Beam was not properly calculated. (TNX DL6FBS). - Bug fixed: Minor problem of APP_KLOG_NUMBER ADIF header fixed. - Bug fixed: When modifying, some fields did not accepted empty fields (deleting). (TNX VK4JAZ). - GUI updated: Remove the map tab in the main GUI as it is still not implemented. - GUI updated: Ordered the tab-switching to make it more usable. (TNX Cedric). - Added the support for QRP. Power has two decimals. (TNX VK4JAZ). November-2010 - 0.5.7 - New feature: Added the Export needed QSL that allows to create an ADIF file with all the QSO with new ones and new bands still not confirmed that has not been QSLed. The objective is to export it to a QSL or label printing software (until KLog implements that feature). - Updated translations: SV by SM4ABE. - GUI improved: Added sliders to be able to move panels. - GUI improved: Changing the band combobox changes the TX Freq box and viceversa. - Minor fix: The PROGRAMVERSION tag in log was not properly formated. July-2010 - 0.5.6 - Fixed the hamlib compilation scripts (CMakeLists.txt, FindHamlib.cmake). (TNX AB4BD). - Fixed one bug that causes some architectures not to compile. - Fixed some permisions and other warnings for Fedora packaging. (TNX N3LRX). - BUG fixed: Setting QSL from the log with right button was not working. May-2010 - 0.5.5 - New feature: If cty.dat file is not found, KLog offers to download from the web. - New feature: New tool to update the update the cty.dat file from the web. - New feature: QRZ font color changes to red if has been worked previously. (Proposed by KE7TDY) March-2010 - 0.5.4 - Small fix to initialize a variable before using it.(realTimeLog in klog.cpp) - Fixed a bug that caused KLog to crash of no cty.dat file was found (bug #016917)(TNX KA6MAL) February-2010 - 0.5.3 - Fixed a bug that caused modified QSO not being updated. - Fixed a bug in the way the band & mode combobox managed the data. February-2010 - 0.5.2 - Fixed a bug that causes a crash when connectiong to DXCluster. (bug #016653) - Added a very basic Satellite support. - Removed the Freq LCD and added two new editable widgets: Freq TX and Freq RX. (bug #016609) - Added again the entity count of /M stations. January-2010 - 0.5.1 - Fixed a bug with the display of the Date. December-2009 - 0.5.0 - Migrated to Qt4. - Updated translations: SV by SM4ABE, DE by DL5PD, ES by EA4TV. - ZL2ACG joined the KLog team. Welcome and thank you Andrew! April-2009 0.4.7 - New feature: Import cabrillo logs. - Improved the ADIF compatibility up to ADIF 2.2.2. - BUG fixed: Improved the confirmed QSO accounting. - BUG fixed: RST format were not changed when another mode was selected if the CALL was empty. (TNX Alvaro, EA4RCT). - BUG fixed: Calls like F0XXX/TU8 were not recognised if written as TU8/F0XXX. - BUG fixed: TX_PWR is only saved when bigger than 0w :-) - BUG fixed: Prefixes were not properly managed and some information, as the STATE from ADIF files were not always well imported. - BUG fixed: Related with the ADIF saving CQ & ITU zones for QSO. It was not properly saved but can be recovered from the CALL. 20-dic-2008 - 0.4.6 - BUG fixed: Printing was not properly working due to library actualization. - BUG fixed: Fields STX/SRX/STATION_CALLSIGN/CONTEST_ID were copied from one QSO to the following one. 23-nov-2008 - 0.4.5 - GUI fixed: Changed the order of the input fields tab switching. - GUI fixed: Corrected the layout to fix the screen as ITU was not properly shown. - GUI improved: Added a new one color to differ a completely new one spot in the DX-cluster from a needed in a band. This last improvement is specially usefull in the search QSO to QSL. Test it! - GUI improved: Added a tab in the botton box with the DXCC status (only main HF bands). - New feature: Added the possibility to choose to show or not DX Spots based on CW/SSB activity. (TNX EA7BJ) - New feature: Added the support of the 0.136KHz and GHz bands (not to the GUI but KLog can process them). - BUG fixed: Minor check on QSL sent date was not properly done (no data lost). - BUG fixed: Some Entities & zones where not properly recognized. - BUG fixed: The state (needed/worked/confirmed) was not always properly shown. - Improved the way is readed the cty.dat file and added support for its new format. - Improved the ADIF compatibility supported fields, band frecuencies, modes... - Improved the QSO merging with previous data. - Updated translations: English, Spanish, TNX: Swedish (SM4ABE), German (DL5PD). 1-may-2008 - 0.4.4 - BUG fixed: KLog now recognises a "/LH" LightHouse stations (TNX G3OAG) - BUG fixed: TLF import did not show the imported QSO in the log. QSO were not lost, just not shown. They were added to the logfile and saved when saving. No data was lost. This bug was introduced in release 0.4.2 after an optimization in the logfile reading. BUG: Frequency was not compliance with ADIF as was saved in KHz instead of MHz. - BUG fixed: If a logfile does not provide a MY_GRIDSQUARE, KLog does not add the predefined MY_GRIDSQUARE. - BUG fixed: Some GRIDSQUARES were not detected as wrong althought they were. - Minor fix: Corrected the URL to CTY.DAT file in the start message. - GUI improved: Added a progress dialog when saving. - GUI changes: Some widgets have been changed to prepare for the Qt4 migration. Specially the Led near the QRZ box that will reapear as usual when KLog is migrated to Qt4. - Added the 70Mhz band. - New feature: New tool added "Merge QSO data" that looks in all the log for the QSO that has been worked more than once and merges the data like Name, QSL info, QTH, Locator, ... The information comming from all the appearances of a call in the log is grouped in the first appearance of that call in the log. 18-jan-2008 - 0.4.3.1 - Package fix: Distributed with the language (po) files. 12-jan-2008 - 0.4.3 - BUG fixed: KLog copied the QSL sent date into the QSL rec date. Only QSL rec date was lost but not the QSL status. - BUG fixed: KLog now recognises a "/J" (Jamboree On The Air) Scout Station. - GUI improved: Added the cty.dat URL. 12-Sep-2007 - 0.4.2 - New feature: The user can now configure to require or not the mandatory data for each QSO (QRZ, date, time, band, mode, RST tx & RST rx. (if not all the mandatory fields are entered, KLog's behaviour may be unexpected). - New feature: Klog creates a temp file (~.klog/tempklog.adi) where it saves automatically all the QSOs entered until the log is manually saved. It prevents the log to be lost in case of unprevented KLog/computer failure. (TNX SM5OUU) - BUG fixed: If the field (maybe any other field too) COMMENT is more than one line long, the log is broken and cannot be read. (TNX SM5OUU) - BUG fixed: KLog does not ask for the file name if you have previously opened one file and the name has not changed. - BUG fixed: In the GUI, the "Preferences" is correctly shown and not as "&Preferences". - BUG fixed: When modifying a QSO, the number of QSOs was incremented when the user click over OK. - BUG fixed: If a QSO was deleted the awards/number of QSO where not decresed. - BUG fixed: When the date - GUI improved: Deleted the WAE box (the WAE calculations was not implemented). - New translation: KLog is now also in Swedish.(TNX SM4BE) - New translation: KLog is now also in Galician.(TNX Fuco Mera) - Updated German translation.(TNX DL5PD) - Updated Spanish translation. 16-Dic-2006 - 0.4.1 - Bug fixed: The distance and beam is also resetted when the call box is deleted. - Bug fixed: Calls /M and /MM do not count for DXCC.(TNX SM5CNQ) - Bug fixed: It is possible to filter only for needed entities spots. - Change: The hamlib signal meter has been removed from the GUI. - New feature: There is a new tool available to find QSO from which the QSL is needed that you have still not sent the QSL. Very useful to find which QSL you need to send first! - New feature: The MY_GRIDSQUARE is managed by default by all QSO (saves the default if none is entered) 10-Sep-2006 - 0.4.0 - New feature: It is possible to manage user-created local awards (TPEA, DOK, WAS, ...) KLog reads user defined awards in a special format. - New feature: KLog reads ".adif" files also.(TNX DL5PD) - New feature: It is possible to add/delete new DXServer clusters in the setup box.(TNX DL5PD) - GUI Improved: IOTA continent is now "automagically" detected. - Bug fixed: Not really a bug but now, the log is cleaner as it does not save the "STATE" for ALL the QSO, only does it if needed. - Bug fixed: After modifying a QSO the band and mode did not return to the last used (TNX DL5PD). - Bug fixed: If the band changed, without any call in the Call box, KLog showed "new one, work it" - Bug fixed: If the band changed, when modifying KLog fooled the entity color band boxes. - Bug fixed: KLog recognises /MM as maritime mobile station - Bug fixed: When opening a new log, the number of QSO did not start from zero. - New translation: KLog is now also in German.(TNX DL5PD) 18-Jan-2006 - 0.3.3 - New feature: It is now possible to sort the log by numbers from the main log. - New feature: The frequency box is now also used when no hamlib support is active (double clicking over a dx-cluster spot. - New feature: If file name does not end in .adi, add the .adi. - Bug fixed: Reporting a bug does not crash KLog although the widget has been temporally/drastically simplified. - Bug fixed: It is possible to select the radio from the setup. - Bug fixed: (introduced in 0.3.2) It was not possible to activate the progress dialog. - Bug fixed: When clicking over "New File", confirmed entities was not set to "zero". - Bug fixed: When reading from cty.dat file, the prefix was reading with some spaces at the begining. - GUI Improved: After pressing OK/clear button, the QRZ box is selected. (TNX P.H. Rankin Hansen) - GUI Improved: You can now reach to Name&QTH using the tab key (TNX P.H. Rankin Hansen) - GUI Improved: QTH/Locator is now on the main QSO tab (TNX P.H. Rankin Hansen) 25-Apr-2005 - 0.3.2 - New feature-(unstable): Hamlib support to control/read the rig from KLog. - New feature-(unstable): It is possible to click over a DX-Spot and set the radio to that frecuency & mode to work the spot (hamlib). - New feature-(unstable): KLog reads the frecuency, band, mode and signal from the radio in real time (hamlib). - New feature: After QSLing using the Right Button option from the search box, the search box is updated so the QSL status is shown updated. - New feature: Local operator callsign can now be also logged. - Bug fixed: A call ending in /B is now correctly recognised as a beacon. - Bug fixed: Now it recognise all the "special suffix" like /r Rotuma, /a Mount Athos,... - Bug fixed: WARC Bands were not correctly detected. - GUI improved: The QRZ box always shows the QRZ as uppercase. (TNX ea4eej) - Bug fixed: KLog can now read ADIF files where the QSO can be in several lines. - Bug fixed: Importing from tlf, the QSO count was not properly done because of the comment lines. 16-Jan-2005 - 0.3.1 - KLog has been optimized and now runs faster. - New feature: KLog saves the date/time of the last log file save. - New feature: KLog ask the user for a comment when Importing a TLF log (for example to note that those QSO are from an specific contest or whatever). - Bug fixed: When selecting a DX-Spot from the DX-Cluster it did not overwrote the name. - Bug fixed: When writting the log, there was an space missing before the . It is just a "cosmetic" fix, not a real bug. - Bug fixed: The same with the QSL card status. - Bug fixed: KLog now recognises all the prefix that appears in cty.dat file with special CQ/ITU zones. - Bug fixed: KLog recognises the special call "3XDQC/P" as "3X" although it does not follow the "prefix+number+suffix" pattern - Bug fixed: When starting it now looks the cty.dat file in: ~/.klog and in the current directory before starting without Entities' data. (TNX oh7jjt) - Bug fixed: If we are modifying a QSO, the search box is not updated. Avoids some crashes. 07-Nov-2004 - 0.3.0 - Fixed source code to allow compiling in more architectures. - New feature: It is possible to show a progress dialog when opening the log file. This is configurable. - New feature: It is now possible to hide/show WARC spots or announces from cluster. - New feature: Printing the is now possible. - New feature: Sorting the log file is now possible. - New feature: New option in right button to send&rec QSL at once. - New feature: If a CALL has been previously worked it shows data to the actual QSO. - Fixed bug: When modifying, the QTH was not modified. - Fixed bug: It did not make you save if you just modify a QSO. - Improved the gui: The "T" (from RST) does not disappears but is disabled when is not needed. (TNX Ferm�n H.). - Improved the gui: The QSL info text box is always active. - Improved the gui: When connecting to the DX-Cluster server, automatically sets the DXCluster window as active. 2-May-2004 - 0.2.9 - New feature: Selection of a DX-Spot shows the Entity data and state. - New feature: KLog checks and captures the output of a sh/dx command in cluster. - Fixed bug(caused in 0.2.8): QRZs as KA3AA, when the prefix is just one letter but the call uses two are now well recognised. - Fixed bug: Better recognision from /number calls from DX-Cluster. 21-Mar-2004 - 0.2.8 - Fixed bug: Now ignores comments in TLF's files. - Fixed bug: QRZs as VP2MCV, with complex prefixes are now well recognised. - Improved the gui: RST, Power size adjusted. (TNX ea1ddn) - Improved the gui: Name and QTH moved to QSO tab. - Improved the gui: QSL via bureau is now the default option. (TNX ea1ddn) - New feature: Calculate distance and beam if locator is entered. (TNX ea1ddn) - New feature: Auto-open logfile when starting is now possible. (TNX ke6sls & ea1ddn) - New feature: Now it is possible to double-click over a DXCluster spot to copy it to the QSO input box. (TNX ea1ddn) - New feature: In the search box, QSOs are colored indicating if worked, needed, ... 04-Jan-2004 - 0.2.7 - Fixed bug: When editing a QSO, the QSL date was not properly displayed. - Fixed bug: When entering a QSO, if the band is changed, KLog checks the state in this new band. - Fixed bug: RST (tx&rx) in ADIF was always length 3, now is calculated for every QSO (at writing). - Fixed bug: When modifying if QSL rec, the date was shown as 00/00/0000 - New feature: It is posible to select a default mode & band in the setup. - First Icon draft created. 02-Dec-2003 - 0.2.6 - Fixed bug: When Non real time logging was setting the time was "real time" when modifying. (TNX rz3dfs) - Fixed bug: When reading the log file if an entity was not recognised Klog used to crash. - Fixed bug: Now we recognise calls like 3XY1L when reading from a log file. - Fixed bug: Improved the way of checking the confirmed/worked entities. - Fixed bug: /P, /M and /QRZ are now better recognised when reading from logfile or clicked. - Fixed bug: Stats were not shown after importing a tlf log file. - Fixed bug: The zone & entity numbering fixed. - New feature: It is posible to setup a default power level. - New feature: When receiving a qsl with the mouse's right button the numbers are updated. - New feature: Also a default color is selectionable as non-info color. - Improved the gui: Band info leds removed to gain space in the info widget. 26-Aug-2003 - 0.2.5 - Fixed bug:�RST was changed so when entering SSB RST. Entering 590 -> showed 509. (TNX ke6sls) - Fixed bug: In cluster some frecs (432MHz and 2190m) were not properly recognized. - New feature: It is now possible to hide HF/VHF/ANN spots or announces from cluster. - New feature: It ask for the file name when saving first time instead of using "klog.adi" as default. (TNX ke6sls) - New feature: It is now possible to add QSO in non real time (to add previous QSOs). (TNX yu1is) - New feature: Power value is remembered from previous QSO. (TNX ke6sls) - New feature: Basic bug report system. (TNX ke6sls) - New feature: Mode selection affects to the RST configuration (TNX yu1is & ke6sls) - New feature: Colors for confirmed/worked/needed are configurable by the user. - New feature: Added tips to many widgets to explain their functions. 31-Jul-2003 - 0.2.4 - Fixed bug: Some calls were not recognized when checked (as 3da0sv). - Fixed bug: When opening a second log having a previous one KLog did not ask for saving if needed. - New feature: Basic Setup dialog and functions. - New feature: Now the band combo change checks automatically the entity state. - New feature: Smart cluster tells you if a dx spot is needed, worked and/or confirmed using colors. - New feature: Clock is now in UTC by default but can be changed in preferences. 24-Jul-2003 - 0.2.3 - Improved the gui: The "entity state" LED has been moved to a always seen zone. - Improved the gui: The way to edit QSO. - Fixed bug: When searching it showed a wrong name and a qth. - New feature: Basic DX-Cluster support. - New feature: It is possible to add a log file to the current log. - New feature: QSO deletion. - New feature: QSO selection's data is shown in the show box. - New feature: You can delete qso & manage qsl from the list with righ button quickly & easily. 30-Jun-2003 - 0.2.2 - Changed the behavior of the search box to look not only for complete calls but characters. - Fixed bug: Improved the GUI layout. - Fixed bug: When editing a previous QSO the date was not always properly saved. - New feature: Added real time clock. 20-Mar-2003 - 0.2.0 - New feature: Added search for QSO tab. - New feature: Added Name field. - New feature: Added QTH field. - New feature: Added operator (self call) field. - Fixed bug: When saving log to file comment is not saved if there is no comment. - Fixed bug: When selecting a "portable" (/P) (or /number) qso in the list it didn't recognize the entity. - Translation updated: pt_BR. 13-Mar-2003 - 0.1-beta02 - Added many modes and some more bands. - New feature: Asking for saving when finishing without save. - New feature: Asking if overwrite when saving as to an existing file. - New feature: The main led only shows info about the current band. - New feature: Band/Mode sticky between contacts. - New feature: Added the long path beam and distance. - New feature: You can track each entity state per band with leds. - New feature: Basic WAZ award support. - Fixed bug: If you had a log and started a new one, the DXCC kept the data. - Fixed bug: The IOTA number was limited to 99 (now 999). 28-Feb-2003 - 0.1-beta - New feature: Led is green (new one), yellow (worked but not confirmed), red (confirmed). - New feature: Support calls as EA4TV/EA8, EA8/EA4TV. - New feature: Import TLF logs. - New feature: Added beam and distance calculations. - New feature: Added Locator & IOTA fields. - New feature: Basic DXCC award support. - Improved the search the Entity algorithm (much quick). - Clear button shows "Cancel" when modifying. - Changed many classes from Qt classes to KDE classes. - Fixed bug: Some times the QSL was checked automaticaly. - Fixed bug: The Mode combobox showed SBB and it is SSB. - Fixed bug: some calls showed as worked before and they were not. 29-Jan-2003 - 0.1-alpha - Fixed bug: When modifying a QSO it was not shown in the log box. - Fixed bug: If you clicked over the log box but not over a qso, the program crashed - Fixed bug: When modifying a QSO the date was always set to "now". - Now you can select what log file you want to open. - Now you can select the file's name when saving the log. - Now you can create a new log always you want. - Logs are now stored in ~/.klog directory by default. - Logs are saved as klog.adi by default. - Some prefix were not found in previous version. - QSL date is activated when a QSO is selected - QSL via is working, manager field, and QSL info field 22-Jan-2003 - 0.1-pre-alpha - First "release" of the software. - You can add/edit QSOs and save/read your log to/from the disk with a fixed name in ADIF format. - Can manage QSL sent/rec. klog-0.9.2.9/setuppageuserdata.cpp0000644000076700000620000005674413233376355015057 0ustar staff/*************************************************************************** userdatapage.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * Foobar 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "setuppageuserdata.h" SetupPageUserDataPage::SetupPageUserDataPage(DataProxy *dp, QWidget *parent) : QWidget(parent){ //qDebug() << "SetupPageUserDataPage::SetupPageUserDataPage" << endl; locator = new Locator(); dataProxy = dp; world = new World(dataProxy); operatorOK = false; operatorsOK = false; tabWidget = new QTabWidget; QWidget *personalTab = new QWidget; QWidget *stationTab = new QWidget; tabWidget->addTab(personalTab, tr("&Personal data")); tabWidget->addTab(stationTab, tr("Station &data")); qrzLineEdit = new QLineEdit; operatorsLineEdit = new QLineEdit; nameLineEdit = new QLineEdit; cqzLineEdit = new QLineEdit; ituzLineEdit = new QLineEdit; myLocatorLineEdit = new QLineEdit; defaultPalette = new QPalette; //defaultPalette = operatorsLineEdit->palette(); wrongPalette = new QPalette; //wrongPalette->setColor(QPalette::WindowText, setNamedColor(Qt::red)); //redColor.setNamedColor(Qt::red); //redColor->setNamedColor(Qt::red); wrongPalette->setColor(QPalette::Text, Qt::red); //Personal Tab nameLineEdit = new QLineEdit; address1LineEdit = new QLineEdit; address2LineEdit = new QLineEdit; address3LineEdit = new QLineEdit; address4LineEdit = new QLineEdit; cityLineEdit = new QLineEdit; zipLineEdit = new QLineEdit; provinceLineEdit = new QLineEdit; countryLineEdit = new QLineEdit; nameLineEdit->setToolTip(tr("Enter your name")); address1LineEdit->setToolTip(tr("Enter your address - 1st line")); address2LineEdit->setToolTip(tr("Enter your address - 2nd line")); address3LineEdit->setToolTip(tr("Enter your address - 3rd line")); address4LineEdit->setToolTip(tr("Enter your address - 4th line")); cityLineEdit->setToolTip(tr("Enter your city")); zipLineEdit->setToolTip(tr("Enter your zip code")); provinceLineEdit->setToolTip(tr("Enter your province or state")); countryLineEdit->setToolTip(tr("Enter your country")); QLabel *nameLabel = new QLabel(tr("&Name")); QLabel *addressLabel = new QLabel(tr("&Address")); QLabel *cityLabel = new QLabel(tr("Cit&y")); QLabel *zipLabel = new QLabel(tr("&Zip Code")); QLabel *provLabel = new QLabel(tr("Pro&v/State")); QLabel *countryLabel = new QLabel(tr("Countr&y")); nameLabel->setBuddy(nameLineEdit); addressLabel->setBuddy(address1LineEdit); cityLabel->setBuddy(cityLineEdit); zipLabel->setBuddy(zipLineEdit); provLabel->setBuddy(provinceLineEdit); countryLabel->setBuddy(countryLineEdit); //void addWidget ( QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = 0 ) // 0 1 2 3 QGridLayout *personalLayout = new QGridLayout(); personalLayout->addWidget(nameLabel, 0, 0); personalLayout->addWidget(nameLineEdit, 1, 0); personalLayout->addWidget(addressLabel, 2, 0); personalLayout->addWidget(address1LineEdit, 3, 0, 1, 2); personalLayout->addWidget(address2LineEdit, 4, 0, 1, 2); personalLayout->addWidget(address3LineEdit, 5, 0, 1, 2); personalLayout->addWidget(address4LineEdit, 6, 0, 1, 2); personalLayout->addWidget(cityLabel, 2, 2); personalLayout->addWidget(cityLineEdit, 3, 2, 1, 1); personalLayout->addWidget(zipLabel, 2, 5); personalLayout->addWidget(zipLineEdit, 3, 5, 1, 1); personalLayout->addWidget(provLabel, 4, 2); personalLayout->addWidget(provinceLineEdit, 5, 2, 1, 1); personalLayout->addWidget(countryLabel, 4, 5); personalLayout->addWidget(countryLineEdit, 5, 5, 1, 1); //personalLayout->addWidget(); //QHBoxLayout *personalAllLayout = new QHBoxLayout(); //personalAllLayout->addLayout(nameLayout); //personalAllLayout->addLayout(personalLayout); personalTab->setLayout(personalLayout); // Station Tab rig1LineEdit = new QLineEdit; rig2LineEdit = new QLineEdit; rig3LineEdit = new QLineEdit; ant1LineEdit = new QLineEdit; ant2LineEdit = new QLineEdit; ant3LineEdit = new QLineEdit; //powerLineEdit = new QLineEdit; myPowerSpinBox = new QDoubleSpinBox; myPowerSpinBox->setDecimals(2); myPowerSpinBox->setMaximum(9999); rig1LineEdit->setToolTip(tr("Enter your information for rig") + " #1"); rig2LineEdit->setToolTip(tr("Enter your information for rig") + " #2"); rig3LineEdit->setToolTip(tr("Enter your information for rig") + " #3"); ant1LineEdit->setToolTip(tr("Enter your information for antenna") + " #1"); ant2LineEdit->setToolTip(tr("Enter your information for antenna") + " #2"); ant3LineEdit->setToolTip(tr("Enter your information for antenna") + " #3"); myPowerSpinBox->setToolTip(tr("Enter your power information")); QLabel *rig1Label = new QLabel(tr("&Rig 1")); QLabel *rig2Label = new QLabel(tr("R&ig 2")); QLabel *rig3Label = new QLabel(tr("Ri&g 3")); QLabel *antenna1Label = new QLabel(tr("Antenna &1")); QLabel *antenna2Label = new QLabel(tr("Antenna &2")); QLabel *antenna3Label = new QLabel(tr("Antenna &3")); QLabel *powerLabel = new QLabel(tr("Po&wer")); rig1Label->setBuddy(rig1LineEdit); rig2Label->setBuddy(rig2LineEdit); rig3Label->setBuddy(rig3LineEdit); antenna1Label->setBuddy(ant1LineEdit); antenna2Label->setBuddy(ant2LineEdit); antenna3Label->setBuddy(ant3LineEdit); powerLabel->setBuddy(myPowerSpinBox); //void addWidget ( QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = 0 ) // 0 1 2 3 QGridLayout *stationLayout = new QGridLayout(); stationLayout->addWidget(rig1Label, 0, 0); stationLayout->addWidget(rig1LineEdit, 1, 0, 1, 1); stationLayout->addWidget(rig2Label, 2, 0); stationLayout->addWidget(rig2LineEdit, 3, 0, 1, 1); stationLayout->addWidget(rig3Label, 4, 0); stationLayout->addWidget(rig3LineEdit, 5, 0, 1, 1); stationLayout->addWidget(antenna1Label, 0, 2); stationLayout->addWidget(ant1LineEdit, 1, 2, 1, 1); stationLayout->addWidget(antenna2Label, 2, 2); stationLayout->addWidget(ant2LineEdit, 3, 2, 1, 1); stationLayout->addWidget(antenna3Label, 4, 2); stationLayout->addWidget(ant3LineEdit, 5, 2, 1, 1); stationLayout->addWidget(powerLabel, 0, 4); stationLayout->addWidget(myPowerSpinBox, 1, 4); stationTab->setLayout(stationLayout); //TODO:Defining ALL the tooltips qrzLineEdit->setToolTip(tr("Enter the station callsign that will be used for logging")); operatorsLineEdit->setToolTip(tr("Enter the operators (comma separated if more than one).")); myLocatorLineEdit->setToolTip(tr("Enter the locator of your station. Alternatively, KLog can use an approximate locator based on your callsign.")); QLabel *qrzLabel = new QLabel(tr("&QRZ")); QLabel *operatorsLabel = new QLabel (tr("&Operators")); QLabel *cqzLabel = new QLabel(tr("&CQ Zone")); QLabel *ituzLabel = new QLabel(tr("&ITU Zone")); myLocatorLabel = new QLabel(tr("&Locator")); qrzLabel->setBuddy(qrzLineEdit); operatorsLabel->setBuddy(operatorsLineEdit); cqzLabel->setBuddy(cqzLineEdit); ituzLabel->setBuddy(ituzLineEdit); myLocatorLabel->setBuddy(myLocatorLineEdit); cqzLineEdit->setInputMask("09"); ituzLineEdit->setInputMask("09"); cqzLineEdit->setText("00"); ituzLineEdit->setText("00"); //QHBoxLayout *operatorLayout = new QHBoxLayout; //operatorLayout->addWidget(qrzLabel); //operatorLayout->addWidget(qrzLineEdit); //operatorLayout->addWidget(operatorsLabel); //operatorLayout->addWidget(operatorsLineEdit); //QGridLayout *operatorLayout = new QGridLayout(); //operatorLayout->addWidget(qrzLabel, 0, 0); //operatorLayout->addWidget(qrzLineEdit, 1, 0); ////operatorLayout->addWidget(nameLabel, 0, 1); ////operatorLayout->addWidget(nameLineEdit, 1, 1); /* QGridLayout *zonesBoxLayout = new QGridLayout; zonesBoxLayout->addWidget(myLocatorLabel,0,0); zonesBoxLayout->addWidget(cqzLabel,0,1); zonesBoxLayout->addWidget(ituzLabel,0,2); zonesBoxLayout->addWidget(myLocatorLineEdit,1,0); zonesBoxLayout->addWidget(cqzLineEdit,1,1); zonesBoxLayout->addWidget(ituzLineEdit,1,2); QVBoxLayout *userdataLayout = new QVBoxLayout(); userdataLayout->addLayout(operatorLayout); userdataLayout->addLayout(zonesBoxLayout); */ QGridLayout *userdataLayout = new QGridLayout; userdataLayout->addWidget(qrzLabel, 0, 0); userdataLayout->addWidget(qrzLineEdit, 1, 0); userdataLayout->addWidget(operatorsLabel, 0, 1); userdataLayout->addWidget(operatorsLineEdit, 1, 1, 1, -1); userdataLayout->addWidget(myLocatorLabel, 3, 0); userdataLayout->addWidget(myLocatorLineEdit, 4, 0); userdataLayout->addWidget(cqzLabel, 3, 1); userdataLayout->addWidget(cqzLineEdit, 4, 1); userdataLayout->addWidget(ituzLabel, 3, 2); userdataLayout->addWidget(ituzLineEdit, 4, 2); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(userdataLayout); mainLayout->addWidget(tabWidget); //mainLayout->addStretch(1); connect(qrzLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotQRZTextChanged() ) ); connect(qrzLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(operatorsLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(nameLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(cqzLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(ituzLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(myLocatorLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(address1LineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(address2LineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(address3LineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(address4LineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(cityLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(zipLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(provinceLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(countryLineEdit, SIGNAL(returnPressed()), this, SLOT(slotEnterKeyPressed() ) ); connect(myLocatorLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotMyLocatorTextChanged() ) ); connect(operatorsLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotOperatorsChanged() ) ); setLayout(mainLayout); //qDebug() << "SetupPageUserDataPage::SetupPageUserDataPage - END" << endl; } SetupPageUserDataPage::~SetupPageUserDataPage() { //qDebug() << "SetupPageUserDataPage::~SetupPageUserDataPage" << endl; } QString SetupPageUserDataPage::getStationQrz() { operatorOK = world->checkQRZValidFormat(qrzLineEdit->text()); if (operatorOK) { return qrzLineEdit->text(); } else { return QString(); } } void SetupPageUserDataPage::slotEnterKeyPressed() { emit enterKey(); } void SetupPageUserDataPage::slotQRZTextChanged() { //qDebug() << "SetupPageUserDataPage::slotQRZTextChanged: " << qrzLineEdit->text() << " / Length: " << QString::number((qrzLineEdit->text()).size()) << endl; int i = qrzLineEdit->cursorPosition(); QString _a = qrzLineEdit->text(); if ((_a.at(i-1)).isSpace()) { qrzLineEdit->setText(_a.remove(i-1, 1)); } qrzLineEdit->setText(((qrzLineEdit->text())).simplified()); qrzLineEdit->setText((qrzLineEdit->text()).toUpper()); cqzLineEdit->setText(QString::number(world->getQRZCqz(qrzLineEdit->text()))); ituzLineEdit->setText(QString::number(world->getQRZItuz(qrzLineEdit->text()))); myLocatorLineEdit->setText(world->getQRZLocator(qrzLineEdit->text())); qrzLineEdit->setCursorPosition(i); emit stationCallSignal(qrzLineEdit->text()); //emit stationCallSignal("TEST"); /* if (!locator->isValidLocator(myLocatorLineEdit->text()) ) { myLocatorLineEdit->setText(world->getQRZLocator(qrzLineEdit->text())); } */ } int SetupPageUserDataPage::getCQz(){ return (cqzLineEdit->text()).toInt(); } int SetupPageUserDataPage::getITUz(){ return (ituzLineEdit->text()).toInt(); } bool SetupPageUserDataPage::setStationQrz(const QString _qrz){ qrzLineEdit->setText((_qrz).toUpper()); return true; } bool SetupPageUserDataPage::setCQz(const int _cqz){ cqzLineEdit->setText(QString::number(_cqz)); return true; } bool SetupPageUserDataPage::setITUz(const int _ituz){ ituzLineEdit->setText(QString::number(_ituz)); return true; } void SetupPageUserDataPage::slotMyLocatorTextChanged() { //qDebug() << "SetupPageUserDataPage::slotMyLocatorTextChanged: " << myLocatorLineEdit->text() << endl; //int i; myLocatorLineEdit->setText(((myLocatorLineEdit->text())).simplified()); myLocatorLineEdit->setText((myLocatorLineEdit->text()).toUpper()); if ( ((myLocatorLineEdit->text()).length()) >3 ) { if (!(locator->isValidLocator(myLocatorLineEdit->text()) )) { myLocatorLabel->setText(tr("&Locator (not valid)")); } else { myLocatorLabel->setText(tr("&Locator")); } } } QString SetupPageUserDataPage::getStationLocator() { if (!(locator->isValidLocator(myLocatorLineEdit->text()) )) { return ""; } else { return (myLocatorLineEdit->text()).toUpper(); } } bool SetupPageUserDataPage::setStationLocator(const QString _loc) { if (!(locator->isValidLocator(_loc) )) { return false; } else { myLocatorLineEdit->setText((_loc).toUpper()); return true; } } QString SetupPageUserDataPage::getName() { return nameLineEdit->text(); } QStringList SetupPageUserDataPage::getAddress() { QStringList a; a.clear(); a << address1LineEdit->text() << address2LineEdit->text() << address3LineEdit->text() << address4LineEdit->text(); return a; } QString SetupPageUserDataPage::getAddress1() { return address1LineEdit->text(); } QString SetupPageUserDataPage::getAddress2() { return address2LineEdit->text(); } QString SetupPageUserDataPage::getAddress3() { return address3LineEdit->text(); } QString SetupPageUserDataPage::getAddress4() { return address4LineEdit->text(); } QString SetupPageUserDataPage::getRig1() { return rig1LineEdit->text(); } QString SetupPageUserDataPage::getRig2() { return rig2LineEdit->text(); } QString SetupPageUserDataPage::getRig3() { return rig3LineEdit->text(); } QString SetupPageUserDataPage::getAntenna1() { return ant1LineEdit->text(); } QString SetupPageUserDataPage::getAntenna2() { return ant2LineEdit->text(); } QString SetupPageUserDataPage::getAntenna3() { return ant3LineEdit->text(); } QString SetupPageUserDataPage::getCity() { return cityLineEdit->text(); } QString SetupPageUserDataPage::getZipCode() { return zipLineEdit->text(); } QString SetupPageUserDataPage::getProvince() { return provinceLineEdit->text(); } QString SetupPageUserDataPage::getCountry() { return countryLineEdit->text(); } bool SetupPageUserDataPage::setName (const QString _aux) { nameLineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setAddress (const QStringList _aux) { address1LineEdit->setText(_aux.at(0)); address2LineEdit->setText(_aux.at(1)); address3LineEdit->setText(_aux.at(2)); address4LineEdit->setText(_aux.at(3)); return true; } bool SetupPageUserDataPage::setAddress1 (const QString _aux) { address1LineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setAddress2 (const QString _aux) { address2LineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setAddress3 (const QString _aux) { address3LineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setAddress4 (const QString _aux) { address4LineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setCity (const QString _aux) { cityLineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setZipCode(const QString _aux) { zipLineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setProvince (const QString _aux) { provinceLineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setCountry (const QString _aux) { countryLineEdit->setText(_aux); return true; } QStringList SetupPageUserDataPage::getRigs() { QStringList a; a.clear(); a << rig1LineEdit->text() << rig2LineEdit->text() << rig3LineEdit->text(); return a; } QStringList SetupPageUserDataPage::getAntennas() { QStringList a; a.clear(); a << ant1LineEdit->text() << ant2LineEdit->text() << ant3LineEdit->text(); return a; } QString SetupPageUserDataPage::getPower() { return QString::number(myPowerSpinBox->value()); } bool SetupPageUserDataPage::setPower(const QString _aux) { myPowerSpinBox->setValue(_aux.toFloat()); return true; } bool SetupPageUserDataPage::setRig1 (const QString _aux) { rig1LineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setRig2 (const QString _aux) { rig2LineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setRig3 (const QString _aux) { rig3LineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setAntenna1 (const QString _aux) { ant1LineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setAntenna2 (const QString _aux) { ant2LineEdit->setText(_aux); return true; } bool SetupPageUserDataPage::setAntenna3 (const QString _aux) { ant3LineEdit->setText(_aux); return true; } void SetupPageUserDataPage::slotOperatorsChanged() { //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged" << endl; //QString _operators = operatorsLineEdit->text(); if (operatorsLineEdit->text().length() < 1) return; int i = operatorsLineEdit->cursorPosition(); //QColor defaultColor = (operatorsLineEdit->palette()).color(QPalette::WindowText); //int ent = -1; //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged-00" << endl; QString _a = operatorsLineEdit->text(); if ((_a.at(i-1)).isSpace()) { operatorsLineEdit->setText(_a.remove(i-1, 1)); } //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged-01" << endl; //operatorsLineEdit->setText(((operatorsLineEdit->text())).simplified()); //operatorsLineEdit->setText((operatorsLineEdit->text()).toUpper()); operatorsLineEdit->setText(_a.simplified().toUpper()); _a = operatorsLineEdit->text(); QStringList operators = _a.split(",", QString::SkipEmptyParts); //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged-02" << endl; //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged-02.5 Size: " << QString::number(operators.size()) << endl; for (int ii = 0; ii < operators.size(); ++ii) { //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged-03 - " << QString::number(ii) << endl; operatorsOK = world->checkQRZValidFormat(operators.at(ii)); //ent = world->getQRZARRLId(operators.at(ii)); if (operatorsOK) { //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged: NO VALID CALL: " << operators.at(ii) << endl; } else { //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged: VALID CALL: " << operators.at(ii) << endl; } } // cout << fonts.at(i).toLocal8Bit().constData() << endl; //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged-04" << endl; if (operatorsOK) { //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged: VALID FORMAT" << endl; //QColor defaultColor = (operatorsLineEdit->palette()).color(QPalette::WindowText); operatorsLineEdit->setPalette(*defaultPalette); emit operatorsSignal(operatorsLineEdit->text()); } else { operatorsLineEdit->setPalette(*wrongPalette); //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged: NOT VALID FORMAT" << endl; } //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged-05" << endl; /* cqzLineEdit->setText(QString::number(world->getQRZCqz(qrzLineEdit->text()))); ituzLineEdit->setText(QString::number(world->getQRZItuz(qrzLineEdit->text()))); myLocatorLineEdit->setText(world->getQRZLocator(qrzLineEdit->text())); */ //operatorsLineEdit->setText(_a); operatorsLineEdit->setCursorPosition(i); //qDebug() << "SetupPageUserDataPage::slotOperatorsChanged-END" << endl; } QString SetupPageUserDataPage::getOperators() { if (operatorsOK) { return operatorsLineEdit->text(); } else { return QString(); } } bool SetupPageUserDataPage::setOperators(const QString _aux) { if (checkOperatorsLineQString(_aux)) { operatorsLineEdit->setText(_aux); return true; } return false; } bool SetupPageUserDataPage::checkOperatorsLineQString(const QString _auxLine) { QStringList _aux = _auxLine.split(','); for (int ii = 0; ii < _aux.size(); ++ii) { operatorsOK = world->checkQRZValidFormat(_aux.at(ii)); if (!operatorsOK) return operatorsOK; } return true; } klog-0.9.2.9/klog.10000644000076700000620000000274713233376355011635 0ustar staff.TH KLog 1 "version 0.9.2" "Jaime Robles, EA4TV" "Hamradio" .SH "NAME" klog \- The Ham Radio Logging program .SH SYNOPSIS \fBklog\fR \fI[option]\fR .SH OPTIONS A summary of options is included below. .TP \fB\-\-help\fR Show summary of options. .TP \fB\-\-version\fR Output version information and exit. .SH DESCRIPTION \fBklog\fR is a ham radio logging program for Linux, macOS and Windows. With KLog you can log your QSOs and save it in ADIF format. KLog helps you to manage DXCC, WAZ and IOTA award. .SH USAGE Enter you QSO data in the top left box while entity data, direction and other usefull information will be shown in the top right box. .P Previous QSOs are shown in the botton box where you can click to edit them. .P Here is a list of keys that can be used to navigate through klog: .TP \fIControl a\fR: Add a QSO. .TP \fIControl d\fR: Delete a selected QSO. .SH PRINTING KLog has a very basic printing feature implemented. .SH PREFERENCES You can edit the ~/.klog/klogrc file to setup you call and locator. .P All the data files are saved in the KLog home directory (~/.klog) by default. .SH FILES \fI/usr/share/klog/cty.csv\fR contains the DXCC entries read by KLog. \fI~/.klog/logbook.dat.\fR contains all the logbook and information of KLog. .SH AUTHORS KLog was written by Jaime Robles, EA4TV aka Download the last version from: http://www.klog.xyz Calculation of heading and distance was taken from Loccalc code by Marco Bersani, IK2PIH. klog-0.9.2.9/awarddxmarathon.h0000644000076700000620000000440513233376355014145 0ustar staff#ifndef AWARDDXMARATHON_H #define AWARDDXMARATHON_H /*************************************************************************** awarddxmarathon.h - description ------------------- begin : feb 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "dataproxy.h" class DXMarathon { public: DXMarathon(DataProxy *dp); int getDXMarathonQSO(const int _year, const int _logNumber); int getDXMarathonDXCC(const int _year, const int _logNumber); int getDXMarathonCQ(const int _year, const int _logNumber); int getDXMarathonScore(const int _year, const int _logNumber); bool neededForDXMarathon(const int _dxcc, const int _cq, const int _year, const int _logNumber); private: DataProxy *dataProxy; }; #endif // AWARDDXMARATHON_H klog-0.9.2.9/awards.cpp0000644000076700000620000014321113233376355012574 0ustar staff#include "awards.h" /*************************************************************************** awards.cpp - description ------------------- begin : nov 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include Awards::Awards(DataProxy *dp) { //qDebug() << "Awards::Awards" << endl; dataProxy = dp; //QSqlDatabase db = QSqlDatabase::database("QSQLITE"); world = new World(dp); //qDebug() << "Awards::Awards - Before DXMarathon" << endl; dxMarathon = new DXMarathon(dataProxy); //qDebug() << "Awards::Awards - After DXMarathon" << endl; util = new Utilities(); //world->create(); /* newOneColor.setNamedColor("#ff0000"); neededColor.setNamedColor("#ff8c00"); workedColor.setNamedColor("#ffd700"); confirmedColor.setNamedColor("#32cd32"); defaultColor.setNamedColor("#00bfff"); */ //"Awards::setColors: " << _newOne << "/" << _needed << "/" << _worked << "/" << _confirmed << "/" << _default << endl; //Awards::setColors: "#ff0000" / "#ff8c00" / "#ffd700" / "#32cd32" / "#00bfff" newOneColor = Qt::black; neededColor = Qt::black; workedColor = Qt::black; confirmedColor = Qt::black; defaultColor = Qt::black; dxccWorked.clear(); dxccConfirmed.clear(); wazWorked.clear(); wazConfirmed.clear(); manageModes = false; //qDebug() << "Awards::Awards - END" << endl; } Awards::~Awards() {} void Awards::setAwardDXCC(const int _qsoId) { //qDebug() << "Awards::setAwardDXCC: _qsoId: " << QString::number(_qsoId) << endl; dataProxy->setDXCCAwardStatus(_qsoId); } void Awards::setAwardWAZ(const int _qsoId) { //qDebug() << "Awards::setAwardWAZ: _qsoId: " << QString::number(_qsoId) << endl; dataProxy->setWAZAwardStatus(_qsoId); } int Awards::getDXCCWorked(const int _logNumber) { //qDebug() << "Awards::getDXCCWorked (logNumber): " << QString::number(_logNumber) << endl; QSqlQuery query; QString stringQuery; bool sqlOK; stringQuery = QString("SELECT COUNT (DISTINCT dxcc) FROM log where lognumber='%1'").arg(_logNumber); sqlOK = query.exec(stringQuery); //qDebug() << "Awards::getDXCCWorked: stringQuery: " << stringQuery << endl; if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); //qDebug() << "Awards::getDXCCWorked: " << QString::number((query.value(0)).toInt()) << endl; return v; } else { //qDebug() << "Awards::getDXCCWorked: 0" << endl; return 0; } } else { query.finish(); emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "Awards::getDXCCWorked: Query error" << endl; return 0; } } int Awards::getDXCCConfirmed(const int _logNumber) { //qDebug() << "Awards::getDXCCConfirmed (logNumber): " << QString::number(_logNumber) << endl; QSqlQuery query; QString stringQuery; bool sqlOK; stringQuery = QString("SELECT COUNT (DISTINCT dxcc) FROM log where qsl_rcvd='Y' AND lognumber='%1'").arg(_logNumber); sqlOK = query.exec(stringQuery); //qDebug() << "Awards::getDXCCWorked: stringQuery: " << stringQuery << endl; if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "Awards::getDXCCConfirmed: " << QString::number((query.value(0)).toInt()) << endl; int v = (query.value(0)).toInt(); query.finish(); return v; } else { //qDebug() << "Awards::getDXCCConfirmed: 0" << endl; return 0; } } else { query.finish(); emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "Awards::getDXCCConfirmed: query error" << endl; return 0; } } int Awards::getWAZWorked(const int _logNumber) { //qDebug() << "Awards::getWAZWorked (logNumber): " << QString::number(_logNumber) << endl; QSqlQuery query; QString stringQuery; //stringQuery = QString("SELECT count (cqz) FROM (SELECT DISTINCT cqz FROM log WHERE cqz!='' AND qsl_rcvd='Y' AND lognumber='%1')").arg(_logNumber); stringQuery = QString("SELECT count (cqz) FROM (SELECT DISTINCT cqz FROM log WHERE cqz!='' AND lognumber='%1')").arg(_logNumber); //stringQuery = QString("SELECT count (cqz) from (SELECT DISTINCT cqz FROM awardwaz WHERE lognumber='%1' AND cqz <> '')").arg(_logNumber); bool sqlOK = query.exec(stringQuery); if (sqlOK) { query.next(); if (query.isValid()) { int v = (query.value(0)).toInt(); query.finish(); return v; } else { return 0; } } else { query.finish(); emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return 0; } } int Awards::getWAZConfirmed(const int _logNumber) { //qDebug() << "Awards::getWAZConfirmed (logNumber): " << QString::number(_logNumber) << endl; QSqlQuery query; QString stringQuery; //Usar la siguiente para el confirmed stringQuery = QString("SELECT count (cqz) FROM (SELECT DISTINCT cqz FROM log WHERE cqz!='' AND qsl_rcvd='Y' AND lognumber='%1')").arg(_logNumber); //stringQuery = QString("SELECT COUNT (cqz) FROM (SELECT DISTINCT cqz FROM awardwaz WHERE lognumber='%1' AND confirmed='1' AND cqz <> '')").arg(_logNumber); bool sqlOK = query.exec(stringQuery); if (sqlOK) { query.next(); if (query.isValid()) { int v =(query.value(0)).toInt(); query.finish(); return v; } else { return 0; } } else { query.finish(); emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return 0; } } bool Awards::isThisSpotConfirmed(const QStringList _qs) { if (getDXStatus(_qs) == 13) { return true; } else { return false; } } int Awards::getDXStatus (const QStringList _qs) { //qDebug() << "Awards::getDXStatus: Entity: " << _qs.at(0) << "/ Band: " << _qs.at(1) << "/ Mode: " << _qs.at(2) << "/ Log: " << _qs.at(3) << endl; // Receives: QStringList _qs; //_qs << Entity << BandId << << ModeId << lognumber; /* Not mode -1 - Error. - ERROR - ERROR 0 - New one - New One - New One - 0 1 - Worked but not in this band nor this mode - Needed One - Needed One - 1 2 - Worked in this band, not this mode - Needed One - Worked One - 3 3 - Worked in this band and in this mode - Worked One - Worked One - 3 4 - Worked in this mode, not this band - Needed One - Needed One - 1 5 - Confirmed in another band/mode but not worked in this band nor this mode - Needed One - Needed One - 1 6 - Confirmed in another band/mode but just worked in this band and not in this mode - Needed One - Worked One - 3 7 - Confirmed in another band/mode but just worked in this mode and not in this band - Needed One - Needed One - 1 8 - Confirmed in another band/mode but just worked in this band and mode - Worked One - Worked One - 3 9 - Confirmed in this mode, but not worked this band - Needed One - Needed One - 1 10 - Confirmed in this mode, but worked this band - Worked One - Worked One - 3 11 - Confirmed in this band but not worked in this mode - Needed One - Confirmed One - 13 12 - Confirmed in this band but worked in this mode - Worked One - Confirmed One - 13 13 - Confirmed in this band and mode - Confirmed One - Confirmed One - 13 */ /* 0 - New One - Never worked before - RED 1 - Needed - New one in this band - ORANGE 2 - Worked - Worked in this band but not confirmed - YELLOW 3 - Confirmed - Confirmed in this band - GREEN */ if (_qs.length() != 4 ) { return -1; } //int errorCode = 0; int _band = _qs.at(1).toInt(); int _mode = _qs.at(2).toInt(); int _logNumber = _qs.at(3).toInt(); int dxccEntity = (_qs.at(0)).toInt(); //int dxccEntity = world->getQRZARRLId(_qs.at(0) ); //qDebug() << "Awards::getDXStatus: dxccEntity: " << QString::number(dxccEntity) << endl; if (dxccEntity<=0) { return -1; } bool checkingMode = true; if ( (_mode==-1) || (manageModes==false)) { checkingMode = false; //qDebug() << "Awards::getDXStatus: checkingMode = FALSE" << endl; } // dxccStatusMode(const int _ent, const int _mode, const int _logNumber) //-1 error / 0 Not worked / 1 worked / 2 confirmed int wb = dxccStatusBand(dxccEntity, _band, _logNumber); //-1 error / 0 Not worked / 1 worked / 2 confirmed int wm = dxccStatusMode(dxccEntity, _mode, _logNumber); //-1 error / 0 Not worked / 1 worked / 2 confirmed if (wm==-1) { checkingMode = false; } //qDebug() << "Awards::getDXStatus: wb=" << QString::number(wb) << " - wm=" << QString::number(wm) << endl; switch(dxccStatus(dxccEntity, _logNumber)) { case 0: //qDebug() << "Awards::getDXStatus: return 0" << endl; return 0; // ATNO break; case 1: // Worked, not confirmed switch (wb) { case 0: // Not worked in this band but in another band if (checkingMode) { if (wm==1) { //qDebug() << "Awards::getDXStatus: return 4" << endl; return 4; } else { //qDebug() << "Awards::getDXStatus: return 1" << endl; return 1; } } else { //qDebug() << "Awards::getDXStatus: return 4 nc" << endl; return 4; } break; case 1: // Worked in this band if (checkingMode) { if (wm==1) { //qDebug() << "Awards::getDXStatus: return 3" << endl; return 3; } else { //qDebug() << "Awards::getDXStatus: return 2" << endl; return 2; } } else { //qDebug() << "Awards::getDXStatus: return 3 nc" << endl; return 3; } break; default: // ERROR //qDebug() << "Awards::getDXStatus: return -1 - 1" << endl; return -1; break; } break; case 2: // Confirmed if (wb==2) { if (checkingMode) { if (wm==2) { //qDebug() << "Awards::getDXStatus: return 13" << endl; return 13; } else if (wm==1) { //qDebug() << "Awards::getDXStatus: return 12" << endl; return 12; } else { //qDebug() << "Awards::getDXStatus: return 11" << endl; return 11; } } else { //qDebug() << "Awards::getDXStatus: return 13 nc" << endl; return 13; } } else if ((wb ==1) || (wb == 0)) { if (checkingMode) { if (wb==1) { if (wm==1) { //qDebug() << "Awards::getDXStatus: return 8" << endl; return 8; } else { //qDebug() << "Awards::getDXStatus: return 6" << endl; return 6; } } else { if (wm==1) { //qDebug() << "Awards::getDXStatus: return 7" << endl; return 7; } else { //qDebug() << "Awards::getDXStatus: return 5" << endl; return 5; } } } else { if (wb==0) { //qDebug() << "Awards::getDXStatus: return 7 nc" << endl; return 7; } else { //qDebug() << "Awards::getDXStatus: return 8 nc" << endl; return 8; } } } else { //qDebug() << "Awards::getDXStatus: return -1 - 2" << endl; return -1; } break; default: //qDebug() << "Awards::getDXStatus: return -1 default" << endl; return -1; break; } // END OF SWITCH return -1; } int Awards::dxccStatusBandMode(const int _ent, const int _band, const int _mode, const int _logNumber, bool _checkingMode) {//-1 error / 0 Not worked / 1 worked / 2 confirmed //qDebug() << "Awards::dxccStatusBandMode: " << QString::number(_ent) << "/" << QString::number(_band) << "/" << QString::number(_mode) << endl; QSqlQuery query = QSqlQuery(); QString queryString = QString(); if (_checkingMode) { //qDebug() << "Awards::dxccStatusBandMode: Checking Mode TRUE" << endl; queryString = QString("SELECT confirmed FROM awarddxcc WHERE dxcc='%1' AND band='%2' AND mode='%3' AND lognumber='%4' ").arg(QString::number(_ent)).arg(QString::number(_band)).arg(QString::number(_mode)).arg(QString::number(_logNumber)); } else { //qDebug() << "Awards::dxccStatusBandMode: Checking Mode FALSE" << endl; queryString = QString("SELECT confirmed FROM awarddxcc WHERE dxcc='%1' AND band='%2' AND lognumber='%3' ").arg(QString::number(_ent)).arg(QString::number(_band)).arg(QString::number(_logNumber)); } if (query.exec(queryString)) { if (query.next()) { if ( query.isValid() ) { if(query.value(0).toString() == "1") { //qDebug() << "Awards::dxccStatusBandMode: return - 2" << endl; query.finish(); return 2; } else if(query.value(0).toString() == "0") { //qDebug() << "Awards::dxccStatusBandMode: return - 1" << endl; query.finish(); return 1; } else { //qDebug() << "Awards::dxccStatusBandMode: return - 0-1" << endl; query.finish(); return 0; } } else { //qDebug() << "Awards::dxccStatusBandMode: return - 0-2" << endl; query.finish(); return 0; } } else { // No value => Not Worked //qDebug() << "Awards::dxccStatusBandMode: return - 0-3" << endl; query.finish(); return 0; } } else { // The query fails... //qDebug() << "Awards::dxccStatusBandMode: return - -1" << endl; query.finish(); emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return -1; } //qDebug() << "Awards::dxccStatusBandMode: return - 0-4" << endl; return 0; } int Awards::dxccStatus(const int _ent, const int _logNumber) {//-1 error / 0 Not worked / 1 worked / 2 confirmed //qDebug() << "Awards::dxccStatus: " << QString::number(_ent) << endl; QSqlQuery query = QSqlQuery(); QString queryString = QString(); int worked = 0; queryString = QString("SELECT confirmed FROM awarddxcc WHERE dxcc='%1' AND lognumber='%2' ").arg(QString::number(_ent)).arg(QString::number(_logNumber)); if (query.exec(queryString)) { while (query.next()) { if ( query.isValid() ) { if(query.value(0).toString() == "1") { query.finish(); return 2; } else if(query.value(0).toString() == "0") { query.finish(); worked = 1; } } } //qDebug() << "Awards::dxccStatus: return "<< QString::number(worked) << endl; query.finish(); return worked; } else { // The query fails... //qDebug() << "Awards::dxccStatus: return -1" << endl; query.finish(); emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return -1; } //qDebug() << "Awards::dxccStatus: return 0" << endl; return 0; } QColor Awards::getQRZDXStatusColor(const QStringList _qs) { //qs << Entity << spotBand << "-1" << QString::number(currentLog) ; //qDebug() << "Awards::getQRZDXStatusColor qs.length: " << QString::number(_qs.length()) << endl; //From Search QSO to QSL: q << _call << bandid << _mode << QString::number(currentLog); //qDebug() << "Awards::getQRZDXStatusColor: " << _qs.at(0) << "/" << _qs.at(1) << "/" << _qs.at(2) << _qs.at(3) << endl; // Receives: QStringList _qs; //_qs << Entity << BandID << ModeId << lognumber; /* 0 - New One 1 - Needed 2 - Worked 3 - Confirmed */ QColor returnedColor; int status = getDXStatus(_qs); //qDebug() << "Awards::getQRZDXStatusColor: status: " << QString::number(status) << "/" << getDXStatusString(status) << endl; //qDebug() << "Awards::getQRZDXStatusColor: status: " << QString::number(status) << endl; switch (status) { case 0: returnedColor = newOneColor; break; case 1: returnedColor = neededColor; break; case 2: returnedColor = neededColor; break; case 3: returnedColor = workedColor; break; case 4: returnedColor = neededColor; break; case 5: returnedColor = neededColor; break; case 6: returnedColor = neededColor; break; case 7: returnedColor = neededColor; break; case 8: returnedColor = workedColor; break; case 9: returnedColor = neededColor; break; case 10: returnedColor = workedColor; break; case 11: returnedColor = neededColor; break; case 12: returnedColor = workedColor; break; case 13: returnedColor = confirmedColor; break; break; default: returnedColor = defaultColor; break; } return returnedColor; } QString Awards::getDXStatusString (const int _status) { //qDebug() << "Awards::getDXStatusString: " << QString::number(_status) << endl; QString message = QString(); switch (_status) { case 0: message = QObject::tr("New One, work it!"); //message = QObject::tr("0-new One"); break; case 1: message = QObject::tr("Needed, work it!"); //message = QObject::tr("1-Needed, work it!"); break; case 2: message = QObject::tr("Needed, work it!"); break; case 3: message = QObject::tr("Worked but not confirmed"); break; case 4: message = QObject::tr("Needed, work it!"); break; case 5: message = QObject::tr("Needed, work it!"); break; case 6: message = QObject::tr("Needed, work it!"); break; case 7: message = QObject::tr("Needed, work it!"); break; case 8: message = QObject::tr("Worked but not confirmed"); break; case 9: message = QObject::tr("Needed, work it!"); break; case 10: message = QObject::tr("Worked but not confirmed"); break; case 11: message = QObject::tr("Needed, work it!"); break; case 12: message = QObject::tr("Worked but not confirmed"); break; case 13: message = QObject::tr("Confirmed"); break; break; default: message = QObject::tr("Not identified"); break; } return message; } QString Awards::getDXCCStatusBand(const int _dxcc, const int _band, const int _logNumber) { // Returns -, W or C (Not worked, worked, Confirmed) //qDebug() << "Awards::getDXCCStatusBand: log received: " << QString::number(_logNumber) << endl; QString stringQuery; if (_logNumber<0) { stringQuery = QString("SELECT confirmed from awarddxcc WHERE dxcc='%1' AND band='%2'").arg(_dxcc).arg(_band); } else { stringQuery = QString("SELECT confirmed from awarddxcc WHERE dxcc='%1' AND band='%2' AND lognumber='%3'").arg(_dxcc).arg(_band).arg(_logNumber); } QSqlQuery query; bool sqlOk = query.exec(stringQuery); if (sqlOk) { while (query.next()) { if (query.isValid()) { if ((query.value(0)).toString() == "1") { query.finish(); return "C"; } else if ((query.value(0)).toString() == "0") { query.finish(); return "W"; } else { query.finish(); return "-"; } } } } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return "-"; } query.finish(); return "-"; } QString Awards::checkIfValidIOTA(const QString _tiota) { /********************************** IOTA should be always with this format: CC-NNN being: - CC the shortname of the continent - NNN Number of the reference. NNN has ALWAYS to include THREE(3) characters. ADIF Specs says: CC is the continent designator {NA, SA, EU , AF, OC, AS, AN} XXX is the island designator, where 0 <= XXX ,<= 999 [use leading zeroes] Returns a valid format IOTA if possible and "" in other cases. ************************************/ //qDebug() << "Awards::checkIfValidIOTA: " << _tiota << endl; //bool _valid = false; QString _continent; QString _number; if (_tiota.count("-") == 1) { QStringList _values = _tiota.split("-", QString::SkipEmptyParts); _continent = _values.at(0); _number = _values.at(1); } else { return ""; } //qDebug() << "Awards::checkIfValidIOTA (cont) " << _continent << endl; //qDebug() << "Awards::checkIfValidIOTA (numb): " << _number << endl; // Check if continent is valid if (dataProxy->isValidContinentShortName(_continent)) { if ( (_number.toInt() >0 ) && ((_number.toInt()) < 1000 )) { if ((_number.length()) == 3) { return _continent + "-" + _number ; } else if ((_number.length()) == 2) { return _continent + "-0" + QString::number((_number).toInt()); } else if ((_number.length()) == 1) { return _continent + "-00" + QString::number((_number).toInt()); } else { return ""; } } else { return ""; } } else { return QString(); } return QString(); /* QString stringQuery = QString("SELECT id FROM continent WHERE shortname ='%1'").arg(_continent); QSqlQuery query; query.exec(stringQuery); while (query.next()) { if (query.isValid()) { _valid = true; if ( (_number.toInt() >0 ) && ((_number.toInt()) < 1000 )) { if ((_number.length()) == 3) { return _continent + "-" + _number ; } else if ((_number.length()) == 2) { return _continent + "-0" + QString::number((_number).toInt()); } else if ((_number.length()) == 1) { return _continent + "-00" + QString::number((_number).toInt()); } else { return ""; } } else { return ""; } } } return ""; */ } void Awards::setColors (const QString _newOne, const QString _needed, const QString _worked, const QString _confirmed, const QString _default) //void Awards::setColors (const QString &_newOne, const QString &_needed, const QString &_worked, const QString &_confirmed, const QString &_default) { //qDebug() << "Awards::setColors: " << _newOne << "/" << _needed << "/" << _worked << "/" << _confirmed << "/" << _default << endl; defaultColor = QColor(_default.toUpper()); neededColor = QColor(_needed.toUpper()); workedColor = QColor(_worked.toUpper()); confirmedColor = QColor(_confirmed.toUpper()); newOneColor = QColor(_newOne.toUpper()); if (defaultColor.isValid()) { defaultColor.setNamedColor(_default.toUpper()); } else { } if (neededColor.isValid()) { neededColor.setNamedColor(_needed.toUpper()); } else { } if (confirmedColor.isValid()) { confirmedColor.setNamedColor(_confirmed.toUpper()); } else { } if (newOneColor.isValid()) { newOneColor.setNamedColor(_newOne.toUpper()); } else { } if (workedColor.isValid()) { workedColor.setNamedColor(_worked.toUpper()); } else { //qDebug() << "Awards::setColors: Worked NOT VALID" << endl; } } QColor Awards::getDefaultColor() { return defaultColor; } void Awards::recalculateAwards() { /* TODO: I need to optimize this function. The select & insert of setAwardDXCC are too slow) Should go in a transaction */ //qDebug() << "Awards::recalculateAwards" << endl; dataProxy->updateAwardDXCC(); emit awardDXCCUpdated(); dataProxy->updateAwardWAZ(); //qDebug() << "Awards::recalculateAwards - END" << endl; } int Awards::getQSOsInLog(const int _logNumber) { //qDebug() << "Awards::getQSOsInLog: " << QString::number(_logNumber) << endl; QSqlQuery query; QString queryString; int v; queryString = QString("SELECT COUNT (id) FROM log WHERE lognumber='%1'").arg(_logNumber) ; if( !query.exec(queryString) ) { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } else { query.next(); if (query.isValid()) { v = query.value(0).toInt(); query.finish(); return v; } else { query.finish(); return -2; } } } /* void Awards::setAwards(const int _dxcc, const int _waz, const int _band, const int _mode, const int _workedOrConfirmed, const int _logNumber, const int _qsoId) { //qDebug() << "Awards::setAwards: " << QString::number(_dxcc) << endl; //_workedOrConfirmed = -1 Remove this pair //_workedOrConfirmed = 0 Set as Worked //_workedOrConfirmed = 1 Set as Confirmed int d = _dxcc; int b = _band; int m = _mode; int w = _workedOrConfirmed; int l = _logNumber; int i = _qsoId; int z = _waz; setAwardDXCC(d, b, m, w, l, i); setAwardWAZ(z, b, m, w, l, i); //setAwardWAZ(_waz, _band, _mode, _workedOrConfirmed, _logNumber); } */ void Awards::setAwards(const int _qsoId) { //qDebug() << "Awards::setAwards: _qsoId: " << QString::number(_qsoId) << endl; dataProxy->setDXCCAwardStatus(_qsoId); dataProxy->setWAZAwardStatus(_qsoId); } /* int Awards::setAwardDXCCst(const int _dxcc, const int _band, const int _mode, const bool _confirmed, const int _logNumber, const int _qsoId) { //qDebug() << "Awards::setAwardDXCCst-0: " << QString::number(_dxcc) << "/" << QString::number(_band) << "/" << QString::number(_mode) << "/" << QString::number(_logNumber) << "/" << QString::number(_qsoId) << endl; int nameCol=-1; QString _refid = QString(); // _confirmedQSO == false QSO is just worked // _confirmedQSO == true QSO is confirmed //TODO: Fix the way we check for data validity for this function if (!( (_dxcc>=0) && (_band >=0) && (_mode>=0) && (_logNumber>=0) && (_qsoId >=0) )) { //qDebug() << "Awards::setAwardDXCCst: Not valid data received!" << endl; return -1; } int _iconfirmed; if (_confirmed) { _iconfirmed = 1; } else { _iconfirmed = 0; } //qDebug() << "Awards::setAwardDXCCst: _qsoId: " << QString::number(_qsoId) << "/" << QString::number(_iconfirmed) << endl; QString stringQuery = QString(); QSqlQuery query; bool sqlOK = false; int errorCode = -1; stringQuery = QString("SELECT id, confirmed FROM awarddxcc where dxcc='%1' AND band='%2' AND mode='%3' AND lognumber='%4'").arg(_dxcc).arg(_band).arg(_mode).arg(_logNumber); sqlOK = query.exec(stringQuery); if (sqlOK) { //qDebug() << "Awards::setAwardDXCCst-1:" << endl; query.next(); QSqlRecord rec = query.record(); if (query.isValid()) {// We have some data, we need to UPDATE - We are only confirming! //qDebug() << "Awards::setAwardDXCCst: We have some data, we neer to update" << endl; nameCol = rec.indexOf("id"); _refid = query.value(nameCol).toString(); stringQuery = QString("UPDATE awarddxcc SET confirmed='1', qsoid='%1' WHERE id='%2'").arg(_qsoId).arg(_refid); //qDebug() << "Awards::setAwardDXCCst: (UPDATE): " << stringQuery << endl; if (sqlOK) { // Set of data updated //qDebug() << "Awards::setAwardDXCCst: Data updated!" << endl; query.finish(); return 1; } else { // Something failed. Trace it! errorCode = query.lastError().number(); emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } } else { // We don't have this set, we need to INSERT stringQuery = QString("INSERT INTO awarddxcc (dxcc, band, mode, confirmed, lognumber, qsoid) values('%1','%2','%3','%4','%5','%6')").arg(_dxcc).arg(_band).arg(_mode).arg(_iconfirmed).arg(_logNumber).arg(_qsoId); sqlOK = query.exec(stringQuery); //qDebug() << "Awards::setAwardDXCCst: We don't have data... so we INSERT" << endl; //qDebug() << "Awards::setAwardDXCCst: (INSERT): " << stringQuery << endl; if (sqlOK) { // Set of data included query.finish(); //qDebug() << "Awards::setAwardDXCCst: Data inserted!" << endl; } else { // Something failed. Trace it! emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); errorCode = query.lastError().number(); query.finish(); return -1; } } } else { // Trace the error... what may be happening??? emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); errorCode = query.lastError().number(); query.finish(); return -1; } return -1; } */ /* int Awards::setAwardWAZst(const int _cqz, const int _band, const int _mode, const bool _confirmed, const int _logNumber, const int _qsoId) { //qDebug() << "Awards::setAwardWAZst(CQZ/BAND/MODE/WORKED/log/qsoid): " << QString::number(_cqz) << "/" << QString::number(_band) << "/" << QString::number(_mode) << "/" << QString::number(_logNumber) << "/" << QString::number(_qsoId) << endl; // _confirmed == false QSO is just worked // _confirmed == true QSO is confirmed //TODO: Fix the way we check for data validity for this function if (!( (_cqz>=0) && (_band >=0) && (_mode>=0) && (_logNumber>=0) && (_qsoId >=0) )) { //qDebug() << "Awards::setAwardWAZst: some data was NOK" << endl; return -1; } int _iconfirmed; if (_confirmed) { _iconfirmed = 1; } else { _iconfirmed = 0; } QString stringQuery; QSqlQuery query; bool sqlOK; //int errorCode = -1; stringQuery = QString("INSERT INTO awardwaz (cqz, band, mode, confirmed, lognumber, qsoid) values('%1','%2','%3','%4','%5','%6')").arg(_cqz).arg(_band).arg(_mode).arg(_iconfirmed).arg(_logNumber).arg(_qsoId); sqlOK = query.exec(stringQuery); if ((sqlOK) && (!_confirmed)) // First time a DXCC/Band/mode is worked { //qDebug() << "Awards::setAwardWAZst: _qsoId: " << QString::number(_qsoId) << "- 1" << endl; query.finish(); return 1; } else if ((sqlOK) && (_confirmed)) // First time a CQZ/Band/Mode is confirmed { //qDebug() << "Awards::setAwardWAZst: _qsoId: " << QString::number(_qsoId) << "- 2" << endl; query.finish(); return 2; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "Awards::setAwardWAZst: _qsoId: " << QString::number(_qsoId) << "- sqlOK ERROR: " << endl; //errorCode = query.lastError().number(); query.finish(); //qDebug() << "Awards::setAwardWAZst: LastQuery: " << query.lastQuery() << endl; //qDebug() << "Awards::setAwardWAZst: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "Awards::setAwardWAZst: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "Awards::setAwardWAZst: LastError-n: " << QString::number(query.lastError().number() ) << endl; } return -1; } */ /* int Awards::setAwardDXCCConfirmed(const int _band, const int _mode, const int _dxcc, const int _newQSOid) // Changes the status of a DXCC from worked to confirmed { //qDebug() << "Awards::setAwardDXCCConfirmed: " << QString::number(_band) << "/" << QString::number(_mode) << "/" << QString::number(_dxcc)<< "/" << QString::number(_newQSOid)<< endl; QString stringQuery; QSqlQuery query = QSqlQuery(); bool sqlOK = false; int errorCode = -1; int nameCol = -1; QString aux = QString(); stringQuery = QString("SELECT qsoid FROM awarddxcc WHERE band='%1' AND mode='%2' AND dxcc='%3'").arg(_band).arg(_mode).arg(_dxcc); sqlOK = query.exec(stringQuery); if (sqlOK) { QSqlRecord rec = query.record(); if (query.next()) { if (query.isValid()) { nameCol = rec.indexOf("qsoid"); aux = (query.value(nameCol)).toString(); query.finish(); stringQuery = QString("UPDATE awarddxcc SET confirmed='1', qsoid='%1' WHERE qsoid='%2'").arg(_newQSOid).arg(aux); sqlOK = query.exec(stringQuery); if (sqlOK) { query.finish(); return _newQSOid; } else { // UPDATE failed emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); errorCode = query.lastError().number(); query.finish(); //qDebug() << "Awards::setAwardDXCCConfirmed-Update: LastQuery: " << query.lastQuery() << endl; //qDebug() << "Awards::setAwardDXCCConfirmed-Update: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "Awards::setAwardDXCCConfirmed-Update: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "Awards::setAwardDXCCConfirmed-Update: LastError-n: " << QString::number(query.lastError().number() ) << endl; return errorCode; } } else { // Not valid record //qDebug() << "Awards::setAwardDXCCConfirmed: Not valid record" << endl; return -3; } } else { // Not next record //qDebug() << "Awards::setAwardDXCCConfirmed: Not next record" << endl; return -2; } } else { // emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); errorCode = query.lastError().number(); query.finish(); //qDebug() << "Awards::setAwardDXCCConfirmed: LastQuery: " << query.lastQuery() << endl; //qDebug() << "Awards::setAwardDXCCConfirmed: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "Awards::setAwardDXCCConfirmed: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "Awards::setAwardDXCCConfirmed: LastError-n: " << QString::number(query.lastError().number() ) << endl; return errorCode; } return 1; } */ int Awards::setDXCCToQSO(const int _dxcc, const int _qsoid) // Defines the DXCC in a QSO { //qDebug() << "Awards::setDXCCToQSO: " << QString::number(_dxcc) << "/" << QString::number(_qsoid) << endl; int errorCode = -1; QString queryString = QString("UPDATE log SET dxcc='%1' WHERE id='%2'").arg(_dxcc).arg(_qsoid); QSqlQuery query = QSqlQuery(); bool sqlOK = query.exec(queryString); if (sqlOK) { query.finish(); return 1; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "Awards::setDXCCToQSO: DXCC Updated in Log but failed...." << endl; errorCode = query.lastError().number(); query.finish(); //qDebug() << "Awards::setDXCCToQSO: LastQuery: " << query.lastQuery() << endl; //qDebug() << "Awards::setDXCCToQSO: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "Awards::setDXCCToQSO: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "Awards::setDXCCToQSO: LastError-n: " << QString::number(query.lastError().number() ) << endl; return errorCode; } } int Awards::setCQToQSO(const int _cqz, const int _qsoid) // Defines the CQ in a QSO { //qDebug() << "Awards::setCQToQSO: " << QString::number(_cqz) << "/" << QString::number(_qsoid) << endl; int errorCode = -1; QString queryString = QString("UPDATE log SET cqz='%1' WHERE id='%2'").arg(_cqz).arg(_qsoid); QSqlQuery query = QSqlQuery(); bool sqlOK = query.exec(queryString); if (sqlOK) { query.finish(); return 1; } else { emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "Awards::setCQToQSO: DXCC Updated in Log but failed...." << endl; errorCode = query.lastError().number(); query.finish(); //qDebug() << "Awards::setCQToQSO: LastQuery: " << query.lastQuery() << endl; //qDebug() << "Awards::setCQToQSO: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "Awards::setCQToQSO: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "Awards::setCQToQSO: LastError-n: " << QString::number(query.lastError().number() ) << endl; return errorCode; } } bool Awards::getIsDXCCConfirmed(const int _dxcc, const int _logNumber) { // isDXCCConfirmed(const int _dxcc, const int _currentLog); return dataProxy->isDXCCConfirmed(_dxcc, _logNumber); } int Awards::getDXMarathonQSO(const int _year, const int _logNumber) { //qDebug() << "Awards::getDXMarathonQSO: " << QString::number(_year) << endl; return dxMarathon->getDXMarathonQSO(_year, _logNumber); } int Awards::getDXMarathonDXCC(const int _year, const int _logNumber) { //qDebug() << "Awards::getDXMarathonDXCC: " << QString::number(_year) << endl; return dxMarathon->getDXMarathonDXCC(_year, _logNumber); } int Awards::getDXMarathonCQ(const int _year, const int _logNumber) { //qDebug() << "Awards::getDXMarathonCQ: " << QString::number(_year) << endl; return dxMarathon->getDXMarathonCQ(_year, _logNumber); } int Awards::getDXMarathonScore(const int _year, const int _logNumber) { //qDebug() << "Awards::getDXMarathonScore: " << QString::number(_year) << endl; return dxMarathon->getDXMarathonScore(_year, _logNumber); } bool Awards::isDXMarathonNeed(const int _dxcc, const int _cq, const int _year, const int _logNumber) { return dxMarathon->neededForDXMarathon(_dxcc, _cq, _year, _logNumber); } int Awards::dxccStatusBand(const int _ent, const int _band, const int _logNumber) //-1 error / 0 Not worked / 1 worked / 2 confirmed { //-1 error / 0 Not worked / 1 worked / 2 confirmed //qDebug() << "Awards::dxccStatusBand: " << QString::number(_ent) << "/" << QString::number(_band) << endl; QSqlQuery query = QSqlQuery(); QString queryString = QString(); queryString = QString("SELECT confirmed FROM awarddxcc WHERE dxcc='%1' AND band='%2' AND lognumber='%4' ").arg(QString::number(_ent)).arg(QString::number(_band)).arg(QString::number(_logNumber)); if (query.exec(queryString)) { if (query.next()) { if ( query.isValid() ) { if(query.value(0).toString() == "1") // Confirmed { query.finish(); return 2; } else if(query.value(0).toString() == "0") // Worked { query.finish(); return 1; } else // Not worked { query.finish(); return 0; } } // Not present => Not worked else { query.finish(); return 0; } } else // Not present => Not worked { // No value => Not Worked query.finish(); return 0; } } else { // The query fails... //TODO: Manage the query error emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } //qDebug() << "Awards::dxccStatusBand: return - 0.3" << endl; return 0; // if arrives to here decision => not worked } int Awards::dxccStatusMode(const int _ent, const int _mode, const int _logNumber) //-1 error / 0 Not worked / 1 worked / 2 confirmed { //-1 error / 0 Not worked / 1 worked / 2 confirmed //qDebug() << "Awards::dxccStatusMode: " << QString::number(_ent) << "/" << QString::number(_mode) << endl; QSqlQuery query = QSqlQuery(); QString queryString = QString(); if (_mode == -1) { return -1; } queryString = QString("SELECT confirmed FROM awarddxcc WHERE dxcc='%1' AND mode='%2' AND lognumber='%4' ").arg(QString::number(_ent)).arg(QString::number(_mode)).arg(QString::number(_logNumber)); if (query.exec(queryString)) { if (query.next()) { if ( query.isValid() ) { if(query.value(0).toString() == "1") // Confirmed { query.finish(); return 2; } else if(query.value(0).toString() == "0") // Worked { query.finish(); return 1; } else // Not worked { query.finish(); return 0; } } // Not present => Not worked else { query.finish(); return 0; } } else // Not present => Not worked { // No value => Not Worked query.finish();return 0; } } else { // The query fails... emit queryError(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); //TODO: Manage the query error return -1; } return 0; // if arrives to here decision => not worked } void Awards::setManageModes(const bool _manageModes) { manageModes = _manageModes; } klog-0.9.2.9/database.cpp0000644000076700000620000104470713233376355013072 0ustar staff/*************************************************************************** database.cpp - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "database.h" //#include DataBase::DataBase(const QString _parentClass, const QString _DBName) { //qDebug() << "DataBase::DataBase: PLAIN: " << _parentClass << " / Name = " << _DBName << endl; constrid = 1; util = new Utilities(); softVersion = util->getVersion(); dbName = _DBName; //qDebug() << "DataBase::DataBase1: dbName: " << dbName << endl; //db = QSqlDatabase::database(); dbVersion = DBVersionf; createConnection(); //qDebug() << "DataBase::DataBase: PLAIN - connection Name: " << dbConnectionName << endl; //qDebug() << "DataBase::DataBase: PLAIN - DB Name: " << db.databaseName() << endl; insertPreparedQueries.clear(); insertQueryFields.clear(); //qDebug() << "DataBase::DataBase: PLAIN: - END" << endl; } DataBase::DataBase(const QString _parentClass, const QString _softVersion, const QString _DBName){ //qDebug() << "DataBase::DataBase2: " << _parentClass << "/" << _softVersion << " / Name = " << _DBName << endl; //TODO: Sometimes the DB is created without the proper calling (without passing softVersion) constrid = 2; dbVersion = DBVersionf; softVersion = _softVersion; //inMemoryOnly = inmemoryonly; latestReaded = 0.0; util = new Utilities(); util->setVersion(softVersion); //dbName = util->getKLogDBFile(); dbName = _DBName; //qDebug() << "DataBase::DataBase2: dbName: " << dbName << endl; //dbDir = dbName; //qDebug() << "DataBase::DataBase: DB(string): " << dbName << endl; //db = QSqlDatabase::database(); if (util->getVersionDouble()>0) { createConnection(); } //qDebug() << "DataBase::DataBase: - connection Name: " << dbConnectionName << endl; //qDebug() << "DataBase::DataBase: - DB Name: " << db.databaseName() << endl; insertPreparedQueries.clear(); insertQueryFields.clear(); //qDebug() << "DataBase::DataBase2: END" << endl; } /* bool DataBase::queryAddField(const QString _field, const QString value) { //QStringList insertPreparedQueries, insertQueryFields; insertQueryFields << _field << value; } bool DataBase::queryPrepare() { //insertPreparedQueries.clear(); //insertQueryFields.clear(); for (int i = 0; i < insertQueryFields.size(); ++i) { if (insertQueryFields.at(i) != "EOR") { insertPreparedQueries << insertQueryFields.at(i) << insertQueryFields.at(i+1); } else { insertPreparedQueries << "EOR"; return true; } } return true; } bool DataBase::queryExec() { //qDebug() << "DataBase::queryExec " << endl; bool sqlOK; //insertQueryFields.clear(); //insertPreparedQueries.clear(); //bool sqlOK = preparedQuery.exec(); QSqlQuery preparedQuery; //Prepare the Query for (int i = 0; i < insertPreparedQueries.size(); ++i) { preparedQuery.bindValue(insertPreparedQueries.at(i), insertPreparedQueries.at(i+1)); } if (!sqlOK) { queryErrorManagement("DataBase::queryExec", preparedQuery.lastError().databaseText(), preparedQuery.lastError().number(), preparedQuery.lastQuery()); //emit queryError(Q_FUNC_INFO, preparedQuery.lastError().databaseText(), preparedQuery.lastError().number(), preparedQuery.lastQuery()); //qDebug() << "DataBase::queryExec - FAILED execution: " << preparedQuery.lastQuery() << endl; } else { //qDebug() << "DataBase::queryExec - executed: " << preparedQuery.lastQuery() << endl; } return sqlOK; } */ DataBase::~DataBase() { //qDebug() << "DataBase::~DataBase" << endl; } QString DataBase::getSoftVersion() { QSqlQuery query; QString stringQuery ("SELECT MAX (softversion) FROM softwarecontrol"); bool sqlOK = query.exec(stringQuery); if (sqlOK) { query.next(); if (query.isValid()) { return (query.value(0)).toString(); } else { query.finish(); return QString(); } } else { //ERROR in Query execution queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } return QString(); } QString DataBase::getDBVersion() { QSqlQuery query; QString stringQuery ("SELECT MAX (dbversion) FROM softwarecontrol"); bool sqlOK = query.exec(stringQuery); if (sqlOK) { query.next(); if (query.isValid()) { return (query.value(0)).toString(); } else { query.finish(); return QString(); } } else { //ERROR in Query execution queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return QString(); } return QString(); } /* bool DataBase::setDir(const QString _dir) { dbDir = _dir; return true; } */ QString DataBase::getDBName() { return db.databaseName(); } QStringList DataBase::getColumnNamesFromTable(const QString _tableName) { //qDebug() << "DataBase::getColumnNamesFromTable: " << _tableName << endl; QSqlQuery query; QString queryString = QString("PRAGMA table_info('%1')").arg(_tableName); bool sqlOK = query.exec(queryString); QStringList list; list.clear(); QString aux; if (sqlOK) { //qDebug() << "DataBase::getColumnNamesFromTable: OK" << endl; while(query.next()) { if (query.isValid()) { aux = (query.value(1)).toString(); if (( aux.toUpper() != "ID" ) && (aux.length()>0)) { list << aux; //qDebug() << "DataBase::getColumnNamesFromTable: " << (query.value(1)).toString() << endl; } } } query.finish(); } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } query.finish(); //qDebug() << "DataBase::getColumnNamesFromTable: " << QString::number(list.size()) << endl; return list; } void DataBase::compress() { //qDebug() << "DataBase::compress " << endl; //QSqlDatabase db = QSqlDatabase::database(); if (!db.open()) { QMessageBox::warning(0, QObject::tr("Database Error"), db.lastError().text()); } else { db.exec("VACUUM;"); } } bool DataBase::reConnect(const QString _DBName) { //qDebug() << "DataBase::reConnect:" << endl; db.close(); dbName = _DBName; //qDebug() << "DataBase::reConnect: DB closed" << endl; //dbName = util->getKLogDBFile(); //qDebug() << "DataBase::reConnect: DB: " << dbDir << endl; return createConnection(); //qDebug() << "DataBase::reConnect: END" << endl; } bool DataBase::createConnection(bool newDB) { //qDebug() << "DataBase::createConnection: " << QString::number(dbVersion) << "/" << softVersion << endl; QString stringQuery; QSqlQuery query; if (!db.isOpen()) { //qDebug() << "DataBase::createConnection: DB NOT Opened" << endl; //db = QSqlDatabase::database(); db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName(dbName); if (!db.open()) { QMessageBox::warning(0, QObject::tr("Database Error"), db.lastError().text()); //qDebug() << "DataBase::createConnection: DB creation ERROR" << endl; return false; } else { //qDebug() << "DataBase::createConnection: created and opened after the creation" << endl; if (isTheDBCreated()) { //qDebug() << "DataBase::createConnection: DB Exists" << endl; } else { //qDebug() << "DataBase::createConnection: DB does not exist" << endl; createDataBase(); stringQuery ="PRAGMA main.page_size = 4096;"; query.exec(stringQuery); stringQuery ="PRAGMA main.cache_size=10000;"; query.exec(stringQuery); stringQuery ="PRAGMA main.locking_mode=EXCLUSIVE;"; query.exec(stringQuery); stringQuery ="PRAGMA main.synchronous=NORMAL;"; query.exec(stringQuery); stringQuery ="PRAGMA main.journal_mode=WAL;"; query.exec(stringQuery); stringQuery ="PRAGMA main.cache_size=5000;"; query.exec(stringQuery); stringQuery ="PRAGMA synchronous=OFF;"; query.exec(stringQuery); stringQuery ="PRAGMA main.temp_store = MEMORY;"; query.exec(stringQuery); //stringQuery="PRAGMA auto_vacuum = FULL;"; //query.exec(stringQuery); stringQuery ="PRAGMA case_sensitive_like=OFF;"; query.exec(stringQuery); } } } else { //qDebug() << "DataBase::createConnection: No Error, DB is open" << endl; } //qDebug() << "DataBase::createConnection: Going to run - createBandModeMaps " << endl; if (createBandModeMaps()) { //qDebug() << "DataBase::createConnection: createBandModeMaps true" << endl; } else { //qDebug() << "DataBase::createConnection: createBandModeMaps false SSSSSSSSSSSSSSSTOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPP" << endl; } //created = true; //qDebug() << "DataBase::createConnection -------------------------------------------- END" << endl; return unMarkAllQSO(); } bool DataBase::isTheDBCreated() { //qDebug() << "DataBase::isTheDBCreated: Called from: " << QString::number(constrid) << endl; QSqlQuery query; int _num = 0; QString stringQuery ("SELECT count(id) FROM softwarecontrol"); bool sqlOK = query.exec(stringQuery); if (sqlOK) { //qDebug() << "DataBase::isTheDBCreated - SQL OK" << endl; query.next(); if (query.isValid()) { //qDebug() << "DataBase::isTheDBCreated - valid" << endl; _num = (query.value(0)).toInt(); if (_num > 0) { //qDebug() << "DataBase::isTheDBCreated - DB Exists" << endl; //qDebug() << "DataBase::isTheDBCreated: ------------------------------------------------- END TRUE" << endl; query.finish(); return true; } else { //qDebug() << "DataBase::isTheDBCreated - DB does not Exist" << endl; //qDebug() << "DataBase::isTheDBCreated: ------------------------------------------------- END FALSE-1" << endl; query.finish(); return false; } } else { //qDebug() << "DataBase::isTheDBCreated - not valid" << endl; //qDebug() << "DataBase::isTheDBCreated: ------------------------------------------------- END FALSE-2" << endl; query.finish(); return false; } } else { //ERROR in Query execution //qDebug() << "DataBase::isTheDBCreated: ------------------------------------------------ ERROR IN QUERY EXECUTION" << endl; queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } query.finish(); //qDebug() << "DataBase::isTheDBCreated: ------------------------------------------------- END FALSE-X" << endl; return false; } bool DataBase::recreateTableLog() { //qDebug() << "DataBase::recreateTableLog" << endl; if (!createTableLog(false)) // Create modetemp { //qDebug() << "DataBase::recreateTableLog: CreateTableLog returned false" << endl; return false; } QString queryString; queryString.clear(); QStringList columns; columns.clear(); columns << getColumnNamesFromTable("log"); queryString = columns.first(); for (int i=1;i= '%2'").arg(fr).arg(fr); QSqlQuery query; bool sqlOK = query.exec(queryString); //qDebug() << "DataBase::getBandIdFromFreq: Query: " << query.lastQuery() << endl; if (sqlOk) { //qDebug() << "DataBase::getBandIdFromFreq: Query OK" << endl; query.next(); if (query.isValid()) { //qDebug() << "DataBase::getBandIdFromFreq: Query OK - END" << endl; return (query.value(0)).toInt(); } else { //qDebug() << "DataBase::getBandIdFromFreq: Valid NOK - END" << endl; query.finish(); return -1; } } else { //qDebug() << "DataBase::getBandIdFromFreq: Query NOK" << endl; queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return -1; } //qDebug() << "DataBase::getBandIdFromFreq: END-X" << endl; query.finish(); return -1; } bool DataBase::isThisFreqInBand(const QString b, const QString fr) {//Freq should be in MHz //qDebug() << "DataBase::isThisFreqInBand: " << b << "/" << fr << endl; int bandNf = getBandIdFromFreq(fr); int bandN = getBandIDFromName2(b); //qDebug() << "DataBase::isThisFreqInBand: (b/f)" << QString::number(bandN) << "/" << QString::number(bandNf) << endl; if (bandNf == bandN) { //qDebug() << "DataBase::isThisFreqInBand: OK " << b << "/" << fr << endl; return true; } else { //qDebug() << "DataBase::isThisFreqInBand: NOK " << b << "/" << fr << endl; return false; } //qDebug() << "DataBase::isThisFreqInBand: END" << endl; return false; } bool DataBase::unMarkAllQSO() { //qDebug() << "DataBase::unMarkAllQSO" << endl; QString stringQuery = QString("UPDATE log SET marked = 'N' WHERE 1"); return execQuery(Q_FUNC_INFO, stringQuery); } bool DataBase::updateIfNeeded() { //qDebug() << "DataBase::updateIfNeeded - Version: " << QString::number(dbVersion) << endl; /************************************************************************************** * This function should call to bool updateToXXX () being XXX dbVersion and * */ //float aux = 0.0; int nameCol = -1; //int errorCode = -1; //bool toBeUpdated = false; //bool sqlOK; QSqlQuery query; QString stringQuery = QString("SELECT MAX (dbversion) FROM softwarecontrol"); bool sqlOK = query.exec(stringQuery); if (sqlOK) { query.next(); latestReaded = (query.value(0)).toFloat(); } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } //QSqlQuery query("SELECT dbversion FROM softwarecontrol"); //QSqlRecord rec = query.record(); //query.next(); //latestReaded = (query.value(0)).toFloat(); query.finish(); //qDebug() << "DataBase::updateIfNeeded - LatestReaded: " << QString::number(latestReaded) << endl; if (latestReaded >= dbVersion) { // DB is updated, no update is needed //qDebug() << "DataBase::updateIfNeeded - DB updated (no need to update anything!) " << endl; //toBeUpdated = false; //qDebug() << "DataBase::updateIfNeeded - TRUE - END " << endl; return true; } else { // DB is outdated. We need to update!! //qDebug() << "DataBase::updateIfNeeded - DB outdated... upgrade starts now! " << endl; QMessageBox msgBox; msgBox.setWindowTitle("KLog"); msgBox.setText( QObject::tr("KLog DB needs to be upgraded.")); msgBox.setInformativeText( QObject::tr("Do you want to upgrade it now?") + "\n"+ QObject::tr("If DB is not upgraded KLog may not work properly.")); msgBox.setStandardButtons(QMessageBox::Apply | QMessageBox::Discard); msgBox.setDefaultButton(QMessageBox::Apply); msgBox.setIcon(QMessageBox::Warning); msgBox.raise(); //this->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); msgBox.setWindowFlags(Qt::WindowStaysOnTopHint|Qt::Popup); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Apply: // Save was clicked updateToLatest(); break; case QMessageBox::Discard: // Discard was clicked break; default: // should never be reached //qDebug() << "DataBase::updateIfNeeded - FALSE - CHECK IF SEEN, shoud not be here! - END " << endl; return false; break; } } // If the DB needs to be updated... we update it! :-) //qDebug() << "DataBase::updateIfNeeded - END!" << endl; return true; } bool DataBase::createTheBandQuickReference() { /* KEY Value QHash bandIDHash; QHash modeIDHash; QHash IDBandHash; QHash IDModeHash QHash freqBandIdHash; */ //qDebug() << "DataBase::createTheBandQuickReference: " << endl; QString st = "NULL"; int in = 0; QString stringQuery = QString("SELECT id, name, lower FROM band"); QString fr = QString(); bandIDHash.clear(); IDBandHash.clear(); QSqlQuery query; bool sqlOK = query.exec(stringQuery); if (!sqlOK) { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } while (query.next()) { if (query.isValid()) { st = (query.value(1)).toString(); in = (query.value(0)).toInt(); fr = (query.value(2)).toString(); bandIDHash.insert(st, in ); IDBandHash.insert(in, st); freqBandIdHash.insert(in, fr); //qDebug() << "DataBase::createTheBandQuickReference: " << st <<"/" << QString::number(in)<< endl; } else { //qDebug() << "DataBase::createTheBandQuickReference: Query not valid -'RETURN FALSE - END" << endl; // QMessageBox::warning(0, QObject::tr("Database Error (DataBase::createTheBandQuickReference)"), // query.lastError().text()); query.finish(); return false; //TODO: Manage this error, in case the query is NOK. } //qDebug() << "DataBase::createTheBandQuickReference: Go for the next one!" << endl; } query.finish(); //qDebug() << "DataBase::createTheBandQuickReference: END" << endl; return true; } bool DataBase::createTheModeQuickReference() { /* KEY Value QHash modeIDHash; QHash IDModeHash */ //qDebug() << "DataBase::createTheModeQuickReference: " << endl; QString st = QString(); QString sm = QString(); int in = 0; modeIDHash.clear(); IDModeHash.clear(); subModeIDHash.clear(); IDSubModeHash.clear(); QString stringQuery = QString("SELECT id, name, submode FROM mode"); QSqlQuery query; bool sqlOK = query.exec(stringQuery); if (!sqlOK) { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } while (query.next()) { if (query.isValid()) { in = (query.value(0)).toInt(); st = (query.value(1)).toString(); sm = (query.value(2)).toString(); modeIDHash.insert(st, in ); IDModeHash.insert(in, st); subModeIDHash.insert(sm, in ); IDSubModeHash.insert(in, sm); //qDebug() << "DataBase::createTheModeQuickReference: " << st <<"/" << QString::number(in)<< endl; } else { //qDebug() << "DataBase::createTheModeQuickReference: Query not valid - END" << endl; //QMessageBox::warning(0, QObject::tr("Database Error (DataBase::createTheModeQuickReference)"), // query.lastError().text()); query.finish(); return false; //TODO: Manage this error, in case the query is NOK. } } query.finish(); //qDebug() << "DataBase::createTheModeQuickReference: END" << endl; return true; } int DataBase::getBandIDFromName2(const QString b) {//KEY, value //name, id /* KEY Value QHash bandIDHash; QHash modeIDHash; QHash IDBandHash; QHash IDModeHash */ //qDebug() << "DataBase::getBandIDFromName2: " << b << endl; //qDebug() << "DataBase::getBandIDFromName2: This line should be the last one... " << endl; return getBandIdFromName(b); //qDebug() << "DataBase::getBandIDFromName2: CHECK IF THIS LINE IS SEEN" << endl; if (b.length()<1) { return -3; } if (bandIDHash.contains(b)) { //qDebug() << "DataBase::getBandIDFromName2: " << b << ":" << bandIDHash.value(b) << endl; return bandIDHash.value(b); } else { //qDebug() << "DataBase::getBandIDFromName2: Contains - False" << endl; return -1; } //qDebug() << "DataBase::getBandIDFromName2: Safety exit" << endl; return -2; } int DataBase::getModeIDFromName2(const QString b) { //qDebug() << "DataBase::getModeIDFromName2: " << b << endl; return getModeIdFromName(b); if (b.length()<2) { //qDebug() << "DataBase::getModeIDFromName2: END -3" << endl; return -3; } if (modeIDHash.contains(b)) { //qDebug() << "DataBase::getModeIDFromName2: END - " << b << ":" << modeIDHash.value(b) << endl; return modeIDHash.value(b); } else { //qDebug() << "DataBase::getModeIDFromName2: Contains - False - END" << endl; return -1; } //qDebug() << "DataBase::getModeIDFromName2: Safety exit - END" << endl; return -2; } int DataBase::getSubModeIDFromName2(const QString b) { //qDebug() << "DataBase::getSubModeIDFromName2: " << b << endl; return getModeIdFromSubMode(b); //return getModeIdFromName(b); if (b.length()<2) { //qDebug() << "DataBase::getSubModeIDFromName2: END -3" << endl; return -3; } if (subModeIDHash.contains(b)) { //qDebug() << "DataBase::getSubModeIDFromName2: END - " << b << ":" << modeIDHash.value(b) << endl; return subModeIDHash.value(b); } else { //qDebug() << "DataBase::getSubModeIDFromName2: Contains - False - END" << endl; return -1; } //qDebug() << "DataBase::getSubModeIDFromName2: Safety exit - END" << endl; return -2; } QString DataBase::getBandNameFromID2(const int _i) { //qDebug() << "DataBase::getBandNameFromid2: " << QString::number(_i) << endl; //return getBandNameFromNumber(_i); if (IDBandHash.contains(_i)) { //qDebug() << "DataBase::getBandNameFromid2: END OK" << endl; return IDBandHash.value(_i); } else { //qDebug() << "DataBase::getBandNameFromid2: END-1" << endl; return "-1"; } //qDebug() << "DataBase::getBandNameFromid2: END-2" << endl; return "-2"; } QString DataBase::getModeNameFromID2(const int _i) { //qDebug() << "DataBase::getModeNameFromId2: " << QString::number(_i) << endl; //return getSubModeNameFromNumber(_i); if (IDModeHash.contains(_i)) { //qDebug() << "DataBase::getModeNameFromId2: END OK - " << IDModeHash.value(_i) << endl; return IDModeHash.value(_i); } else { //qDebug() << "DataBase::getModeNameFromId2: END-1" << endl; return "-1"; } //qDebug() << "DataBase::getModeNameFromId2: END-2" << endl; return "-2"; } QString DataBase::getSubModeNameFromID2(const int _i) { //qDebug() << "DataBase::getSubModeNameFromId2: " << QString::number(_i) << endl; return getSubModeNameFromNumber(_i); if (IDSubModeHash.contains(_i)) { //qDebug() << "DataBase::getSubModeNameFromId2: END OK - " << IDModeHash.value(_i) << endl; return IDSubModeHash.value(_i); } else { //qDebug() << "DataBase::getSubModeNameFromId2: END-1" << endl; return "-1"; } //qDebug() << "DataBase::getSubModeNameFromId2: END-2" << endl; return "-2"; } bool DataBase::createBandModeMaps() { //qDebug() << "DataBase::createBandModeMaps" << endl; bool b = false; bool m = false; //return (b && m); if (isTheDBCreated()) { b = createTheBandQuickReference(); m = createTheModeQuickReference(); //qDebug() << "DataBase::createBandModeMaps - isTheDbCreated TRUE" << endl; return (b && m); } else { //qDebug() << "DataBase::createBandModeMaps - isTheDbCreated FALSE" << endl; return false; } return false; //qDebug() << "DataBase::createBandModeMaps END" << endl; } QString DataBase::getFreqFromBandId(const int _i) { //qDebug() << "DataBase::getFreqFromBandId" << endl; if (freqBandIdHash.contains(_i)) { //qDebug() << "DataBase::getFreqFromBandId OK END" << endl; return freqBandIdHash.value(_i); } else { //qDebug() << "DataBase::getFreqFromBandId END-1" << endl; return "-1.0"; } //qDebug() << "DataBase::getFreqFromBandId END-2" << endl; return "-2.0"; } int DataBase::getLogTypeNumber(const QString _logType) { //qDebug() << "DataBase::getLogTypeNumber: " << _logType << endl; QSqlQuery query; QString queryString = QString("SELECT id FROM supportedcontests WHERE name='%1'").arg(_logType); bool sqlOK = query.exec(queryString); if(!sqlOK) { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); } query.next(); if ( query.isValid() ) { return (query.value(0)).toInt(); } else { query.finish(); return -1; } query.finish(); return -2; } QString DataBase::getLogTypeName(const int _logType) { //qDebug() << "DataBase::getLogTypeName: " << QString::number(_logType) << endl; QSqlQuery query; QString queryString = QString("SELECT name FROM supportedcontests WHERE id='%1'").arg(_logType); bool sqlOK = query.exec(queryString); if(!sqlOK) { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); } query.next(); if ( query.isValid() ) { return (query.value(0)).toString(); } else { query.finish(); return QString(); } query.finish(); return QString(); } bool DataBase::updateToLatest() { /* * With the DB updates, the function that is called from here should be also updated. * The updateXXX are recursive calls that calls the previous one. * */ //qDebug() << "DataBase::updateToLatest " << endl; //return updateTo010(); return updateTo011(); } bool DataBase::updateTo003() {// Updates the DB to 0.0.3 /* * This function should be used as a template to create the all the update functions implementing the needed changes * in the dB to update from one version to the following one. * * // dbVersion shows the DB version that is being deployed * // latestReaded shows the DB version that is currently deployed. *i.e.: * QString stringQuery = QString ("ALTER TABLE award_enumeration ADD COLUMN dxcc INTEGER;"); * */ //qDebug() << "DataBase::updateTo003" << endl; bool IAmIn003 = false; bool IAmIn002 = false; bool ErrorUpdating = false; if (latestReaded >= float(0.003)) { //IAmIn003 = true; return true; } else { IAmIn003 = false; } while (!IAmIn003 && !ErrorUpdating) { while (!IAmIn002 && !ErrorUpdating) { //IAmIn002 = updateTo002(); IAmIn002 = true; } if (ErrorUpdating) { return false; } //DO ALL THE TASKS TO BE IN 0.003 from 0.002 HERE and set ErrorUpdating if it is not possible. IAmIn003 = true; } return IAmIn003; } bool DataBase::updateTo004() {// Updates the DB to 0.0.4 //qDebug() << "DataBase::updateTo004" << endl; bool IAmIn004 = false; bool IAmIn003 = false; bool ErrorUpdating = false; QString stringQuery = QString(); //QString dateString = (date.currentDateTime()).toString("yyyyMMdd"); QSqlQuery query; bool sqlOk = false; if (latestReaded >= float(0.004)) { //qDebug() << "DataBase::updateTo004: - I am in 004" << endl; return true; } else { //qDebug() << "DataBase::updateTo004: - I am not in 004" << endl; IAmIn004 = false; } while (!IAmIn004 && !ErrorUpdating) { while (!IAmIn003 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo004: - And I am not in 003" << endl; //IAmIn002 = updateTo002(); IAmIn003 = true; } if (ErrorUpdating) { return false; } sqlOk = updateDBVersion(); if (sqlOk) { // Version updated sqlOk = execQuery(Q_FUNC_INFO, "DROP TABLE award_enumeration"); } else { // Version not updated } //DO ALL THE TASKS TO BE IN 0.004 from 0.003 HERE and set ErrorUpdating if it is not possible. IAmIn004 = true; } return IAmIn004; } bool DataBase::updateTo005() {// Updates the DB to 0.0.5 //qDebug() << "DataBase::updateTo005" << endl; bool IAmIn005 = false; bool IAmIn004 = false; bool ErrorUpdating = false; QString stringQuery = QString(); //QString dateString = (date.currentDateTime()).toString("yyyyMMdd"); QSqlQuery query; QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); //int errorCode; bool sqlOk = false; if (latestReaded >= float(0.005)) { //qDebug() << "DataBase::updateTo005 - Already in 005" << endl; return true; } else { //qDebug() << "DataBase::updateTo005 - 005 update false" << endl; IAmIn005 = false; } while (!IAmIn005 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo005 - I am not in 005" << endl; while (!IAmIn004 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo005 - I am not in 004" << endl; IAmIn004 = updateTo004(); } //qDebug() << "DataBase::updateTo005 - I am in 004" << endl; if (ErrorUpdating) { //qDebug() << "DataBase::updateTo005 - 005 update false2" << endl; return false; } sqlOk = updateDBVersion(); if (sqlOk) { // Version updated if (recreateContestData()) { //qDebug() << "DataBase::updateTo005 - recreateContestData OK" << endl; sqlOk = execQuery(Q_FUNC_INFO, "DROP table logs"); sqlOk = createTableLogs(true); if (!sqlOk) { //queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::updateTo005 - logs table do not created" << endl; } if (howManyQSOsInLog(0)>0) { // If the user has QSOs that were added with previous versions... // We need to create a new log and rename all QSOs to that QSO. //stringQuery = QString("UPDATE log SET lognumber='1' WHERE lognumber='0'"); msgBox.setText(QObject::tr("KLog has detected a previous log in the DB. All data will be migrated to a newly created DX type log for you.")); msgBox.exec(); if (execQuery(Q_FUNC_INFO, "UPDATE log SET lognumber='1' WHERE lognumber='0'")) {} else { //queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //showError(QObject::tr("QSOs not updated to main log")); //qDebug() << "DataBase::updateTo005 - QSOs not updated to main log" << endl; } QString dateString = (QDate::currentDate()).toString("yyyy/MM/dd"); QString callToUse = QString(); bool ok; //QString text; //text = QInputDialog::getText(this, QObject::tr("Station Callsign"), QObject::tr("Enter the Station Callsign you want to use in the imported log:"), QLineEdit::Normal, QObject::tr("N0CALL"), &ok); QString text = (QInputDialog::getText(0, QObject::tr("KLog: Enter Station callsign"), QObject::tr("Enter the station callsign used in this log"), QLineEdit::Normal, QObject::tr("Station Callsign"), &ok)).toUpper(); text = text.toUpper(); if (ok && !text.isEmpty()) { callToUse = text; } else { callToUse = "N0CALL"; } stringQuery = QString("INSERT INTO logs (logdate, stationcall, logtype, logtypen) values('%1','%2','DX', '1')").arg(dateString).arg(callToUse); sqlOk = execQuery(Q_FUNC_INFO, stringQuery); if (sqlOk) { } else { //queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //showError(QObject::tr("New Log not created")); //qDebug() << "DataBase::updateTo005 - New Log not created" << endl; //qDebug() << "DataBase::clearLog: Log deleted FAILED" << endl; } } else { } IAmIn005 = true; } else { //qDebug() << "DataBase::updateTo005 - recreateContestData FAILED" << endl; ErrorUpdating = true; } } else { // Version not updated //qDebug() << "DataBase::updateTo005 - 005 update false6" << endl; ErrorUpdating = true; } } //qDebug() << "DataBase::updateTo005 - 005 updated 3" << endl; //TODO: Delete the table and recreate it if (IAmIn005) { msgBox.setText(QObject::tr("All the data was migrated correctly. You should now go to Setup->Preferences->Logs to check that everything is OK.")); msgBox.exec(); } //qDebug() << "DataBase::updateTo005 - I am in 005 already!! " << endl; return IAmIn005; } bool DataBase::recreateSatelliteData() { //qDebug() << "DataBase::recreateSatelliteData" << endl; QSqlQuery query; //bool sqlOk = false; //beginTransaction(); if (execQuery(Q_FUNC_INFO, "DROP TABLE satellites")) { // commitTransaction(); if (createTableSatellites(true)) { //qDebug() << "DataBase::recreateSatelliteData SAT table created" << endl; return populateTableSatellites(true); } else { //qDebug() << "DataBase::recreateSatelliteData SAT table NOT created" << endl; } } else { //commitTransaction(); //qDebug() << "DataBase::recreateSatelliteData execQuery FAILED" << endl; } //qDebug() << "DataBase::recreateSatelliteData END FALSE" << endl; return false; } bool DataBase::recreateContestData() { //qDebug() << "DataBase::recreateContestData" << endl; QSqlQuery query; bool sqlOk = false; sqlOk = execQuery(Q_FUNC_INFO, "DROP TABLE contest"); if (sqlOk) { if (createTableContest()) { return populateContestData(); } } return false; } bool DataBase::recreateSupportedContest() { //qDebug() << "DataBase::recreateSupportedContest" << endl; QSqlQuery query; bool sqlOk = false; sqlOk = execQuery(Q_FUNC_INFO, "DROP TABLE supportedcontests"); if (sqlOk) { //qDebug() << "DataBase::recreateSupportedContest SQLOK" << endl; if (createTableSupportedContest()) { //qDebug() << "DataBase::recreateSupportedContest - createTable OK" << endl; //return populateTableSupportedContest(); return populateTableSupportedContest(); } else { //qDebug() << "DataBase::recreateSupportedContest createTableSupportContest FALSE" << endl; return false; } } else { //queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } //qDebug() << "DataBase::recreateSupportedContest - FALSE end" << endl; return false; } bool DataBase::recreatePropModes() { //qDebug() << "DataBase::recreatePropModes" << endl; //QSqlQuery query; bool sqlOk = false; sqlOk = execQuery(Q_FUNC_INFO, "DROP TABLE prop_mode_enumeration"); if (sqlOk) { //qDebug() << "DataBase::recreatePropModes SQLOK" << endl; if (createTablePropModes()) { //qDebug() << "DataBase::recreatePropModes - createTable OK" << endl; if (populatePropagationModes()) { //qDebug() << "DataBase::recreatePropModes - populatePropModes OK" << endl; return true; } else { //qDebug() << "DataBase::recreatePropModes - populatePropModes NOK" << endl; return false; } } else { //qDebug() << "DataBase::recreatePropModes createTableSupportContest FALSE" << endl; } } else { //queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::recreatePropModes - prop_mode_enumeration table has not been dropped" << endl; //qDebug() << "DataBase::recreatePropModes : Table creation FAILED" << endl; } //qDebug() << "DataBase::recreatePropModes - FALSE end" << endl; return false; } bool DataBase::createTableLogs(const bool real) { // NoTmp = false => TMP data table to operate and be deleted afterwards //Creating the Sats DB to be able to include satellites to the LOTW //qDebug() << "DataBase::createTableLogs" << endl; QString stringQuery = QString(); //QSqlQuery query; if (real) { //qDebug() << "DataBase::createTableLogs - logs" << endl; stringQuery = "CREATE TABLE logs" ; } else { //qDebug() << "DataBase::createTableLogs - logstemp" << endl; stringQuery = "CREATE TABLE logstemp" ; } stringQuery = stringQuery + QString(" (id INTEGER PRIMARY KEY AUTOINCREMENT, " "logdate VARCHAR(10), " "stationcall VARCHAR(15) NOT NULL, " "operators VARCHAR, " "comment VARCHAR, " "logtype VARCHAR, " "logtypen INTEGER, " "FOREIGN KEY (logtypen) REFERENCES supportedcontests(id)," "FOREIGN KEY (logtype) REFERENCES supportedcontests(name))"); //qDebug() << "DataBase::createTableLogs - END" << endl; return execQuery(Q_FUNC_INFO, stringQuery); } bool DataBase::createTablePropModes() { //qDebug() << "DataBase::createTablePropModes" << endl; return execQuery(Q_FUNC_INFO, "CREATE TABLE prop_mode_enumeration (id INTEGER PRIMARY KEY AUTOINCREMENT, shortname VARCHAR(8), name VARCHAR(55) )"); } bool DataBase::createTableSupportedContest() { //qDebug() << "DataBase::createTableSupportedContest" << endl; QString st = QString("CREATE TABLE supportedcontests (" "id INTEGER PRIMARY KEY, " "longname VARCHAR," "name VARCHAR)"); return execQuery(Q_FUNC_INFO, st); } bool DataBase::createTableContest() { //qDebug() << "DataBase::createTableContest" << endl; //QSqlQuery query; execQuery(Q_FUNC_INFO, "CREATE TABLE contest (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "contest INTEGER NOT NULL," "catoperator INTEGER NOT NULL," "catassisted INTEGER NOT NULL," "catpower INTEGER NOT NULL," "catband INTEGER NOT NULL," "catoverlay INTEGER NOT NULL," "catmode INTEGER NOT NULL," "FOREIGN KEY (contest) REFERENCES supportedcontests(id), " "FOREIGN KEY (catoperator) REFERENCES contestcatoperator(id), " "FOREIGN KEY (catassisted) REFERENCES contestcatassisted(id), " "FOREIGN KEY (catpower) REFERENCES contestcatpower(id), " "FOREIGN KEY (catband) REFERENCES contestcatband(id), " "FOREIGN KEY (catoverlay) REFERENCES contestcatoverlay(id), " "FOREIGN KEY (catmode) REFERENCES contestcatmode(id))"); createTableSupportedContest(); execQuery(Q_FUNC_INFO, "CREATE TABLE contestcatoperator (" "id INTEGER PRIMARY KEY, " "name VARCHAR)"); execQuery(Q_FUNC_INFO, "CREATE TABLE contestcatassisted (" "id INTEGER PRIMARY KEY, " "name VARCHAR)"); execQuery(Q_FUNC_INFO, "CREATE TABLE contestcatpower (" "id INTEGER PRIMARY KEY, " "name VARCHAR)"); execQuery(Q_FUNC_INFO, "CREATE TABLE contestcatband (" "id INTEGER PRIMARY KEY, " "name VARCHAR)"); execQuery(Q_FUNC_INFO, "CREATE TABLE contestcatoverlay (" "id INTEGER PRIMARY KEY, " "name VARCHAR)"); execQuery(Q_FUNC_INFO, "CREATE TABLE contestcatmode (" "id INTEGER PRIMARY KEY, " "name VARCHAR)"); populateTableSupportedContest(); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatoperator (id, name) VALUES ('0', 'N/A')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatoperator (id, name) VALUES ('1', 'Single-Operator')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatoperator (id, name) VALUES ('2', 'Multi-One')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatoperator (id, name) VALUES ('3', 'Multi-Two')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatoperator (id, name) VALUES ('4', 'Multi-Unlimited')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatoperator (id, name) VALUES ('5', 'CheckLog')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatassisted (id, name) VALUES ('0', 'N/A')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatassisted (id, name) VALUES ('1', 'Non-Assisted')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatassisted (id, name) VALUES ('2', 'Assisted')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatpower (id, name) VALUES ('0', 'N/A')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatpower (id, name) VALUES ('1', 'High-Power')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatpower (id, name) VALUES ('2', 'Low-Power')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatpower (id, name) VALUES ('3', 'QRP')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatband (id, name) VALUES ('0', 'N/A')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatband (id, name) VALUES ('1', 'All-Band')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatband (id, name) VALUES ('2', 'Single-Band')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatoverlay (id, name) VALUES ('0', 'N/A')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatoverlay (id, name) VALUES ('1', 'Classic')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatoverlay (id, name) VALUES ('2', 'Rookie')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatmode (id, name) VALUES ('0', 'N/A')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatmode (id, name) VALUES ('1', 'SSB')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatmode (id, name) VALUES ('2', 'CW')"); execQuery(Q_FUNC_INFO, "INSERT INTO contestcatmode (id, name) VALUES ('3', 'MIXED')"); //qDebug() << "DataBase::createTableContest END" << endl; return true; } bool DataBase::populateTableSupportedContest() { //qDebug() << "DataBase::populateTableSupportedContest" << endl; // ADDING ALL THE CATEGORIES OPTIONS return execQuery(Q_FUNC_INFO, "INSERT INTO supportedcontests (id, longname, name) VALUES ('0', 'Normal log', 'DX')"); } bool DataBase::createTableMode(const bool NoTmp) { // NoTmp = false => TMP data table to operate and be deleted afterwards //qDebug() << "DataBase::createTableMode" << endl; QString stringQuery = QString(); QSqlQuery query; if (NoTmp) { stringQuery = "CREATE TABLE mode" ; } else { stringQuery = "CREATE TABLE modetemp" ; } stringQuery = stringQuery + QString(" (id INTEGER PRIMARY KEY AUTOINCREMENT, " "cabrillo VARCHAR(2) NOT NULL, " "name VARCHAR(40) NOT NULL, " "submode VARCHAR(40) NOT NULL, " "deprecated VARCHAR(1) NOT NULL)"); //qDebug() << "DataBase::createTableMode END" << endl; return execQuery(Q_FUNC_INFO, stringQuery); } bool DataBase::populateTableMode(const bool NoTmp) { //qDebug() << "DataBase::populateTableMode" << endl; //QSqlQuery query; QString tableName = QString(); QString squery = QString(); if (NoTmp) { tableName = "mode"; } else { tableName = "modetemp"; } bool sqlOK = execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('AM', 'AM', 'PH', '0')").arg(tableName)); int errorCode = -1; if (!sqlOK) { //queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::populateTableMode: Mode table population FAILED" << endl; //errorCode = query.lastError().number(); //qDebug() << "DataBase::populateTableMode: - query error: " << QString::number(errorCode) << endl; //qDebug() << "DataBase::populateTableMode: LastQuery: " << query.lastQuery() << endl; //qDebug() << "DataBase::populateTableMode: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "DataBase::populateTableMode: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "DataBase::populateTableMode: LastError-n: " << QString::number(query.lastError().number() ) << endl; } else { //qDebug() << "DataBase::populateTableMode: Mode table population OK" << endl; } execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ARDOP', 'ARDOP', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('AMTORFEC', 'TOR', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ASCI', 'RTTY', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ATV', 'ATV', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('C4FM', 'C4FM', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('CHIP', 'CHIP', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('CHIP64', 'CHIP', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('CHIP128', 'CHIP', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('CLO', 'CLO', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('CONTESTI', 'CONTESTI', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('CW', 'CW', 'CW', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('DIGITALVOICE', 'DIGITALVOICE', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('DSTAR', 'DSTAR', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('DOMINO', 'DOMINO', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('DOMINOEX', 'DOMINO', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('DOMINOF', 'DOMINO', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('FAX', 'FAX', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('FM', 'FM', 'PH', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('FMHELL', 'HELL', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('FT8', 'FT8', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('FSK31', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('FSK441', 'FSK441', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('FSKHELL', 'HELL', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('FSQCALL', 'MFSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('GTOR', 'TOR', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('HELL', 'HELL', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('HELL80', 'HELL', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('HFSK', 'HELL', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ISCAT', 'ISCAT', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ISCAT-A', 'ISCAT', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ISCAT-B', 'ISCAT', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT4', 'JT4', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT4A', 'JT4', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT4B', 'JT4', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT4C', 'JT4', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT4D', 'JT4', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT4E', 'JT4', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT4F', 'JT4', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT4G', 'JT4', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT6M', 'JT6M', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9-1', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9-2', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9-5', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9-10', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9-30', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9A', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9B', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9C', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9D', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9E', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9E FAST', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9F', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9F FAST', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9G', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9G FAST', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9H', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT9H FAST', 'JT9', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT44', 'JT44', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT65', 'JT65', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT65A', 'JT65', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT65B', 'JT65', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT65B2', 'JT65', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT65C', 'JT65', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('JT65C2', 'JT65', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK', 'MFSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK4', 'MFSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK8', 'MFSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK11', 'MFSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK16', 'MFSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK22', 'MFSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK31', 'MFSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK32', 'MFSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK64', 'MFSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MFSK128', 'MFSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MSK144', 'MSK144', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('MT63', 'MT63', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OLIVIA', 'OLIVIA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OLIVIA 4/125', 'OLIVIA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OLIVIA 4/250', 'OLIVIA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OLIVIA 8/250', 'OLIVIA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OLIVIA 8/500', 'OLIVIA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OLIVIA 16/500', 'OLIVIA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OLIVIA 16/1000', 'OLIVIA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OLIVIA 32/1000', 'OLIVIA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OPERA', 'OPERA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OPERA-BEACON', 'OPERA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('OPERA-QSO', 'OPERA', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PAC', 'PAC', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PAC2', 'PAC', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PAC3', 'PAC', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PAC4', 'PAC', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PAX', 'PAX', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PAX2', 'PAX', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PCW', 'CW', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PKT', 'PKT', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK', 'PSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK10', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK31', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK63', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK63F', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK125', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK250', 'PSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK500', 'PSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK1000', 'PSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSKAM10', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSKAM31', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSKAM50', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSKFEC31', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSK2K', 'PSK2K', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('PSKHELL', 'HELL', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('Q15', 'Q15', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QPSK31', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QPSK63', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QPSK125', 'PSK', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QPSK250', 'PSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QPSK500', 'PSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QRA64', 'QRA64', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QRA64A', 'QRA64', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QRA64B', 'QRA64', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QRA64C', 'QRA64', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QRA64D', 'QRA64', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('QRA64E', 'QRA64', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ROS', 'ROS', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ROS-EME', 'ROS', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ROS-HF', 'ROS', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('ROS-MF', 'ROS', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('RTTY', 'RTTY', 'RY', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('RTTYM', 'RTTYM', 'RY', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('SSB', 'SSB', 'PH', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('LSB', 'SSB', 'PH', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('USB', 'SSB', 'PH', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('SIM31', 'PSK', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('SSTV', 'SSTV', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('T10', 'T10', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('THRB', 'THRB', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('THRBX', 'THRB', 'NO', '1')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('THOR', 'THOR', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('TOR', 'TOR', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('V4', 'V4', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('VOI', 'VOI', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('WINMOR', 'WINMOR', 'NO', '0')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (submode, name, cabrillo, deprecated) VALUES ('WSPR', 'WSPR', 'NO', '0')").arg(tableName)); createTheModeQuickReference(); //qDebug() << "DataBase::populateTableMode END" << endl; return true; } bool DataBase::createTableSatellites(const bool NoTmp) { // NoTmp = false => TMP data table to operate and be deleted afterwards //Creating the Sats DB to be able to include satellites to the LOTW //qDebug() << "DataBase::createTableSatellites" << endl; // The satmode column has the following format: {Up/down-mode;Up/down-mode} // this way we can implement several freqs/modes per sat // Initially I will implement Up/Down only but KLog should be prepared to work with "-mode" also // being mode "SSB, CW, ... and other ADIF modes QString stringQuery = QString(); //QSqlQuery query; if (NoTmp) { stringQuery = "CREATE TABLE satellites" ; } else { stringQuery = "CREATE TABLE satellitestemp" ; } stringQuery = stringQuery + QString(" (id INTEGER PRIMARY KEY AUTOINCREMENT, " "satarrlid VARCHAR, " "satname VARCHAR, " "uplink VARCHAR," "downlink VARCHAR," "satmode VARCHAR, " "UNIQUE (satarrlid) )"); /* * * uplink/downlink format is the following: * Single frecuency: 145.950 * Segment: 145.950-145.975 * Several freqs: 145.950,435.950 * Several segments: 145.950-145.975,435.950-435.975 * * satmode format: * Single mode: FM * Modes complex Up/Downlink: USB/LSB * Several modes (one per uplink/downlink pair): FM,SSB * Several complex modes (one per uplink/downlink pair): USB/LSB,LSB/USB,FM * */ return execQuery(Q_FUNC_INFO, stringQuery); /* bool sqlOK = query.exec(stringQuery); if (!sqlOK) { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); } */ //qDebug() << "DataBase::createTableSatellites END" << endl; //return sqlOK; } bool DataBase::populateTableSatellites(const bool NoTmp) { // Data must come from: // https://lotw.arrl.org/lotw-help/frequently-asked-questions/#sats //qDebug() << "DataBase::populateTableSatellites" << endl; //QSqlQuery query; QString tableName = QString(); QString squery = QString(); if (NoTmp) { tableName = "satellites"; } else { tableName = "satellitestemp"; } // The satmode column has the following format: {Up/down-mode;Up/down-mode} // this way we can implement several freqs/modes per sat // Initially I will implement Up/Down only but KLog should be prepared to work with "-mode" also // being mode "SSB, CW, ... and other ADIF modes //To add a band, just create another line: execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-10', 'AMSAT-OSCAR 10', '435.030,146.180', '145.81', 'SSB,CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-13', 'AMSAT-OSCAR 13', '435.423-435.573', '145.975-145.825', 'SSB,CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-16', 'AMSAT-OSCAR 16', '145.92', '437.026', 'FM/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-21', 'OSCAR 21/RS-14', '', '145.8', 'CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-24', 'Arsene-OSCAR 24', '', '145.975', 'PKT')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-27', 'AMRAD-OSCAR 27', '145.85', '436.795', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-3', 'AMSAT-OSCAR 3', '145.975-146.025', '144.325-144.375', 'SSB,CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-4', 'AMSAT-OSCAR 4', '432.145-432.155', '144.300-144.310', 'SSB,CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-40', 'AMSAT-OSCAR 40','145.840-145.990,435.790-435.520', '2401.2225-2401.475', 'SSB,CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-51', 'AMSAT-OSCAR 51', '145.92', '435.3', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-6', 'AMSAT-OSCAR 6', '145.900-146.000', '29.450-29.550', 'SSB,CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-7', 'AMSAT-OSCAR 7', '145.850-145.950,432.180-432.120', '29.400-29.500,145.920-145.980', 'USB,LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-73', 'AMSAT-OSCAR 73', '435.150-435.130', '145.950-145.970', 'LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-8', 'AMSAT-OSCAR 8', '145.850-145.900,145.900-146.000', '29.400-29.500,435.200-435.100', 'SSB,CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-85', 'AMSAT-OSCAR 85 (Fox-1A)', '435.170', '145.980', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('ARISS', 'ARISS', '145.200,144.490', '145.800,145.800', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('BY70-1', 'Bayi Kepu Weixing 1', '145.92', '436.2', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('CAS-3H', 'LilacSat 2', '144.350', '437.200', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('DO-64', 'Delfi OSCAR-64', '', '145.870', 'CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('EO-88', 'Emirates OSCAR 88 (Nayif-1)', '435.045-435.015', '145.960-145.990', 'LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('FO-12', 'Fuji-OSCAR 12', '145.900-146.000,145.85', '435.900-435.800,435.91', 'SSB,PKT')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('FO-20', 'Fuji-OSCAR 20', '145.900-146.000', '435.900-435.800', 'SSB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('FO-29', 'Fuji-OSCAR 29', '145.900-145.999', '435.900-435.800', 'LSB/USB,CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('HO-68', 'Hope OSCAR 68', '145.925-145.975,145.825', '435.765-435.715,435.675', 'LSB/USB,FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('IO-86', 'Indonesia OSCAR 86 (LAPAN-ORARI)', '435.880', '145.880', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('LO-19', 'Lusat-OSCAR 19', '145.840-145.900', '437.125-437.150', 'CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('LO-78', 'LituanicaSAT-1', '145.95,145.85', '435.1755,437.543', 'FM,PKT')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('MIREX', 'Mir packet digipeater', '145.985', '145.985', 'PKT')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('NO-44', 'Navy-OSCAR 44', '145.827', '145.827', 'PKT')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('RS-1', 'Radio Sputnik 1', '145', '29', '')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('RS-10', 'Radio Sputnik 10', '','29.357,29.403', '')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('RS-11', 'Radio Sputnik 11', '','29.357,29.403', '')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('RS-12', 'Radio Sputnik 12', '21.210-21.250', '29.410-29.450', 'SSB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('RS-13', 'Radio Sputnik 13', '21.260-21.300', '145.860-145.900', 'SSB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('RS-15', 'Radio Sputnik 15', '', '29.3525-29.3987', '')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('RS-2', 'Radio Sputnik 2', '145', '29', '')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, satmode) VALUES ('RS-5', 'Radio Sputnik 5', 'CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, satmode) VALUES ('RS-6', 'Radio Sputnik 6', '')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, satmode) VALUES ('RS-7', 'Radio Sputnik 7', 'CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, satmode) VALUES ('RS-8', 'Radio Sputnik 8', '')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('SAREX', 'Shuttle Amateur Radio Experiment packet digipeater', '144.80,144.49', '144.55', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('SO-35', 'Sunsat-OSCAR 35', '436.291', '145.825', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('SO-41', 'Saudi-OSCAR 41', '145.850', '436.775', 'CW')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('SO-50', 'Saudi-OSCAR 50', '145.850', '436.795', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('SO-67', 'Sumbandila OSCAR 67', '145.875', '435.345', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('UO-14', 'UOSAT-OSCAR 14', '145.975', '435.07', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('VO-52', 'VUsat-OSCAR 52', '435.220-435.280,435.225-435.275', '145.930-145.870,145.925-145.875', 'LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('XW-2A', 'Hope 2A', '435.030-435.050', '145.665-145.685', 'LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('XW-2B', 'Hope 2B', '435.090-435.110', '145.730-145.750', 'LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('XW-2C', 'Hope 2C', '435.150-435.170', '145.795-145.815', 'LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('XW-2D', 'Hope 2D', '435.210-435.230', '145.860-145.880', 'LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('XW-2E', 'Hope 2E', '435.270-435.290', '145.915-145.935', 'LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('XW-2F', 'Hope 2F', '435.330-435.350', '145.980-145.999', 'LSB/USB')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('LO-90', 'LilacSat-OSCAR 90 (LilacSat-1)', '145.985', '436.510', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-91', 'RadFxSat (Fox-1B)', '435.250', '145.960', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('AO-92', 'Fox-1D', '435.350,1267.35', '145.880', 'FM')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (satarrlid, satname, uplink, downlink, satmode) VALUES ('FS-3', 'FalconSat-3', '435.103', '145.840', 'PKT')").arg(tableName)); //qDebug() << "DataBase::populateTableSatellites - END" << endl; return true; } bool DataBase::createTableEntity(const bool NoTmp) { // NoTmp = false => TMP data table to operate and be deleted afterwards //qDebug() << "DataBase::createTableEntity" << endl; QString stringQuery = QString(); //QSqlQuery query; if (NoTmp) { stringQuery = "CREATE TABLE entity" ; } else { stringQuery = "CREATE TABLE entitytemp" ; } stringQuery = stringQuery + QString( " (id INTEGER PRIMARY KEY AUTOINCREMENT, " "name VARCHAR(40) NOT NULL," "cqz INTEGER NOT NULL, " "ituz INTEGER NOT NULL, " "continent INTEGER NOT NULL, " "latitude REAL NOT NULL, " "longitude REAL NOT NULL, " "utc INTEGER NOT NULL, " "dxcc INTEGER NOT NULL, " "mainprefix VARCHAR(15) NOT NULL, " "deleted INTEGER, " "sincedate VARCHAR(10), " "todate VARCHAR(10), " "isoname VARCHAR(10), " "UNIQUE (dxcc, mainprefix), " "FOREIGN KEY (continent) REFERENCES continent(shortname) )"); //qDebug() << "DataBase::createTableEntity END" << endl; return execQuery(Q_FUNC_INFO, stringQuery); //TODO: To add some columns in this the table to mark if worked/confirmed/band/Mode } bool DataBase::createTableBand(const bool NoTmp) { // NoTmp = false => TMP data table to operate and be deleted afterwards //qDebug() << "DataBase::createTableBand" << endl; QString stringQuery = QString(); //QSqlQuery query; if (NoTmp) { stringQuery = "CREATE TABLE band" ; } else { stringQuery = "CREATE TABLE bandtemp" ; } stringQuery = stringQuery + QString(" (id INTEGER PRIMARY KEY AUTOINCREMENT, " "lower REAL NOT NULL, " "upper REAL NOT NULL, " "cabrillo VARCHAR(6) NOT NULL, " "name VARCHAR(40) NOT NULL, " "UNIQUE (lower, upper, cabrillo, name) )"); //qDebug() << "DataBase::createTableBand END" << endl; return execQuery(Q_FUNC_INFO, stringQuery); } bool DataBase::populateTableBand(const bool NoTmp) { // Cabrillo definition: http://wwrof.org/cabrillo/cabrillo-specification-v3/ //qDebug() << "DataBase::populateTableBand" << endl; QString tableName = QString(); QString squery = QString(); if (NoTmp) { tableName = "band"; } else { tableName = "bandtemp"; } //To add a band, just create another line: execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('0', '0', '0', 'Light')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('1mm', '241000', '250000', '241G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('2mm', '142000', '149000', '142G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('2.5mm', '119980', '120020', '119G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('4mm', '75500', '81000', '75G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('6mm', '47000', '47200', '47G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('1.25CM', '24000', '24250', '24G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('3CM', '10000', '10500', '10G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('6CM', '5650', '5925', '5.7G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('9CM', '3300', '3500', '3.4G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('13CM', '2340', '2450', '2.3G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('23CM', '1240', '1300', '1.2G')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('33CM', '902', '928', '902')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('70CM', '420', '450', '432')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('1.25M', '222', '225', '222')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('2M', '144', '148', '144')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('4M', '70', '71', '4M')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('6M', '50', '54', '50')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('10M', '28.0', '29.7', '28000')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('12M', '24.89', '24.99', '24000')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('15M', '21.0', '21.45', '21000')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('17M', '18.068', '18.168', '18100')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('20M', '14.0', '14.35', '14000')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('30M', '10.0', '10.15', '10000')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('40M', '7.0', '7.3', '7000')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('60M', '5.102', '5.404', '5100')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('80M', '3.5', '4.0', '3500')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('160M', '1.8', '2.0', '1800')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('560M', '0.501', '0.504', '560M')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('630M', '0.472', '0.479', '630M')").arg(tableName)); execQuery(Q_FUNC_INFO, QString("INSERT INTO %1 (name, lower, upper, cabrillo) VALUES ('2190M', '0.1357', '0.1378', '2190M')").arg(tableName)); createTheBandQuickReference(); //qDebug() << "DataBase::populateTableBand END" << endl; return true; } bool DataBase::populatePropagationModes() { //qDebug() << "DataBase::populatePropagationModes" << endl; //QSqlQuery query; execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('AS', 'Aircraft Scatter')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('AUR', 'Aurora')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('AUE', 'Aurora-E')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('BS', 'Back scatter')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('ECH', 'EchoLink')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('EME', 'Earth-Moon-Earth')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('ES', 'Sporadic E')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('FAI', 'Field Aligned Irregularities')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('F2', 'F2 Reflection')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('INTERNET', 'Internet-assisted')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('ION', 'Ionoscatter')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('IRL', 'IRLP')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('MS', 'Meteor scatter')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('RPT', 'Terrestrial or atmospheric repeater or transponder')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('RS', 'Rain scatter')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('SAT', 'Satellite')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('TEP', 'Trans-equatorial')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('TR', 'Tropospheric ducting')")); //qDebug() << "DataBase::populatePropagationModes END" << endl; return true; } bool DataBase::populateContestData() { //qDebug() << "DataBase::populateContestData" << endl; // CONTEST DEFINITIONS START HERE // DX execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (0, 0, 0, 0, 0, 0, 0)"); // DX START /* // CQ WW DX SSB START execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 1, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 1, 2, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 2, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 2, 2, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 3, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 3, 2, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 1, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 1, 2, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 2, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 2, 2, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 3, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 3, 2, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 1, 1, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 1, 2, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 2, 1, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 2, 2, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 3, 1, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 3, 2, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 1, 1, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 1, 2, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 2, 1, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 2, 2, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 3, 1, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 3, 2, 1, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 1, 1, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 1, 2, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 2, 1, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 2, 2, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 3, 1, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 1, 3, 2, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 1, 1, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 1, 2, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 2, 1, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 2, 2, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 3, 1, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 1, 2, 3, 2, 2, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 2, 0, 1, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 2, 0, 2, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 3, 0, 1, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 3, 0, 2, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 4, 0, 1, 1, 0, 1)"); execQuery(Q_FUNC_INFO, "INSERT INTO contest (contest, catoperator, catassisted, catpower, catband, catoverlay, catmode) VALUES (1, 5, 0, 0, 0, 0, 1)"); // CQ WW DX SSB END */ //qDebug() << "DataBase::populateContestData END" << endl; return true; } bool DataBase::howManyQSOsInLog(const int i) { //qDebug() << "DataBase::howManyQSOsInLog" << endl; QSqlQuery query; QString sqlQueryString = QString("SELECT COUNT(id) from log WHERE lognumber='%1'").arg(i); bool sqlOK = query.exec(sqlQueryString); if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataBase::howManyQSOsInLog OK END" << endl; return (query.value(0)).toInt(); } else { //qDebug() << "DataBase::howManyQSOsInLog END-1" << endl; query.finish(); return -1; } } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); //qDebug() << "DataBase::howManyQSOsInLog END-2" << endl; return -1; } query.finish(); return -2; } bool DataBase::updateTo006() {// Updates the DB to 0.0.6 //qDebug() << "DataBase::updateTo006" << endl; bool IAmIn006 = false; bool IAmIn005 = false; bool ErrorUpdating = false; QString stringQuery = QString(); //QString dateString = (date.currentDateTime()).toString("yyyyMMdd"); bool sqlOk = false; if (latestReaded >= float(0.006)) { return true; } else { IAmIn006 = false; } while (!IAmIn006 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo006: - Still not in 006" << endl; while (!IAmIn005 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo006: - And still not in 005" << endl; IAmIn005 = updateTo005(); } //qDebug() << "DataBase::updateTo006: - Already in 005" << endl; if (ErrorUpdating) { return false; } sqlOk = updateDBVersion(); if(sqlOk) { sqlOk = recreatePropModes(); if(sqlOk) { sqlOk = updateTableLog(6); // We copy the log into logtemp } else { ErrorUpdating = true; IAmIn006 = false; return false; } if (!sqlOk) { ErrorUpdating = true; IAmIn006 = false; return false; //qDebug() << "DataBase::updateTo006 - prop_mode table do not created" << endl; } createTableBand(false); // We create the bandTemp populateTableBand(false); // Populate the bandTemp updateBandIdTableLogToNewOnes(); updateBandIdTableAward(1); // DXCC updateBandIdTableAward(2); // WAZ if (execQuery(Q_FUNC_INFO, "DROP TABLE band")) { if (execQuery(Q_FUNC_INFO, "ALTER TABLE bandtemp RENAME TO band")) { } else { //qDebug() << "DataBase::updateTo006 - ERROR - bandtemp not renamed" << endl; ErrorUpdating = true; IAmIn006 = false; return false; } } else { //qDebug() << "DataBase::updateTo006 - ERROR - bandtemp not dropped" << endl; ErrorUpdating = true; IAmIn006 = false; return false; } updateTheModeTableAndSyncLog(); createTableClubLogStatus(); populateTableClubLogStatus(); } else {// Version not updated ErrorUpdating = true; IAmIn006 = false; return false; } } //DO ALL THE TASKS TO BE IN 0.006 from 0.005 HERE and set ErrorUpdating if it is not possible. //qDebug() << "DataBase::updateTo006 - I am in 006 " << endl; IAmIn006 = true; //qDebug() << "DataBase::updateTo006 - END " << endl; return IAmIn006; } bool DataBase::updateTableLog(const int _v) { //qDebug() << "DataBase::updateTableLog " << endl; createTableLog(false); QString queryString; switch (_v) { case 6: // If 6, we copy in logtemp the full data coming from the old log. This way, the structure of // the log table is updated without any data loss. queryString = QString ("INSERT INTO logtemp (qso_date, time_on, call, rst_sent, rst_rcvd, bandid, modeid, srx, stx, points, multiplier, cqz, ituz, dxcc, address, age, cnty, comment, a_index, ant_az, ant_el, ant_path, arrl_sect, band_rx, checkcontest, class, contacted_op, contest_id, country, credit_submitted, credit_granted, distance, email, eq_call, eqsl_qslrdate, eqsl_qslsdate, eqsl_qsl_rcvd, eqsl_qsl_sent, force_init, freq, freq_rx, gridsquare, iota, iota_island_id, k_index, lat, lon, lotw_qslrdate, lotw_qslsdate, lotw_qsl_rcvd, lotw_qsl_sent, max_bursts, ms_shower, my_city, my_cnty, my_country, my_cq_zone, my_gridsquare, my_iota, my_iota_island_id, my_lat, my_lon, my_name, my_rig, my_sig, my_sig_info, my_state, my_street, name, notes, nr_bursts, nr_pings, operator, owner_callsign, pfx, precedence, prop_mode, public_key, qslmsg, qslrdate, qslsdate, qsl_rcvd, qsl_sent, qsl_rcvd_via, qsl_sent_via, qsl_via, qso_complete, qso_random, qth, rx_pwr, sat_mode, sat_name, sfi, sig, sig_info, srx_string, stx_string, state, station_callsign, swl, ten_ten, tx_pwr, web, qso_date_off, time_off, transmiterid, marked, lognumber) SELECT qso_date, time_on, call, rst_sent, rst_rcvd, bandid, modeid, srx, stx, points, multiplier, cqz, ituz, dxcc, address, age, cnty, comment, a_index, ant_az, ant_el, ant_path, arrl_sect, band_rx, checkcontest, class, contacted_op, contest_id, country, credit_submitted, credit_granted, distance, email, eq_call, eqsl_qslrdate, eqsl_qslsdate, eqsl_qsl_rcvd, eqsl_qsl_sent, force_init, freq, freq_rx, gridsquare, iota, iota_island_id, k_index, lat, lon, lotw_qslrdate, lotw_qslsdate, lotw_qsl_rcvd, lotw_qsl_sent, max_bursts, ms_shower, my_city, my_cnty, my_country, my_cq_zone, my_gridsquare, my_iota, my_iota_island_id, my_lat, my_lon, my_name, my_rig, my_sig, my_sig_info, my_state, my_street, name, notes, nr_bursts, nr_pings, operator, owner_callsign, pfx, precedence, prop_mode, public_key, qslmsg, qslrdate, qslsdate, qsl_rcvd, qsl_sent, qsl_rcvd_via, qsl_sent_via, qsl_via, qso_complete, qso_random, qth, rx_pwr, sat_mode, sat_name, sfi, sig, sig_info, srx_string, stx_string, state, station_callsign, swl, ten_ten, tx_pwr, web, qso_date_off, time_off, transmiterid, marked, lognumber FROM log"); break; default: //qDebug() << "DataBase::updateTableLog FALSE END" << endl; return false; break; } if (execQuery(Q_FUNC_INFO, queryString)) { //qDebug() << "DataBase::updateTableLog: " << QString::number(_v) << " - Query executed" << endl; queryString = "DROP TABLE log"; if (execQuery(Q_FUNC_INFO, queryString)) { //qDebug() << "DataBase::updateTableLog: " << QString::number(_v) << " - Table log dropped" << endl; queryString = "ALTER TABLE logtemp RENAME TO log" ; if (execQuery(Q_FUNC_INFO, queryString)) { //qDebug() << "DataBase::updateTableLog: " << QString::number(_v) << " - tmp renamed - END" << endl; return true; } else { //qDebug() << "DataBase::updateTableLog: " << QString::number(_v) << " - Renaming failed" << endl; } } else { //qDebug() << "DataBase::updateTableLog: " << QString::number(_v) << " - Table log Not dropped" << endl; } } else { //qDebug() << "DataBase::updateTableLog: " << QString::number(_v) << " - query failed" << endl; } //qDebug() << "DataBase::updateTableLog END" << endl; return false; } bool DataBase::createTableClubLogStatus() { //qDebug() << "createTableClubLogStatus" << endl; QString queryString = QString("CREATE TABLE clublog_status (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "shortname VARCHAR(1) NOT NULL, " "name VARCHAR(15) NOT NULL)"); return execQuery(Q_FUNC_INFO, queryString); } bool DataBase::populateTableClubLogStatus() { //qDebug() << "populateTableClubLogStatus" << endl; QString queryString = "INSERT INTO clublog_status (shortname, name) VALUES ('Y', 'Uploaded')"; if (execQuery(Q_FUNC_INFO, queryString)) { queryString = "INSERT INTO clublog_status (shortname, name) VALUES ('N', 'Do not upload')"; if (execQuery(Q_FUNC_INFO, queryString)) { queryString = "INSERT INTO clublog_status (shortname, name) VALUES ('M', 'Modified')"; //qDebug() << "populateTableClubLogStatus END" << endl; return execQuery(Q_FUNC_INFO, queryString); } } //qDebug() << "populateTableClubLogStatus FALSE END" << endl; return false; } /* bool DataBase::moveFromModeIdToSubmodeId() { return false; } */ bool DataBase::updateTableEntity() { //qDebug() << "DataBase::updateTableEntity" << endl; bool result = false; QString stringQuery; bool sqlOk; result = createTableEntity(false); // Now we have a temp entity table with the correct format if (result) { //qDebug() << "DataBase::updateTableEntity: Table entitytemp created!" << endl; // Now we need to move all the data from the old to the temp entity table. stringQuery = QString("INSERT INTO entitytemp (name, cqz, ituz, continent, latitude, longitude, utc, dxcc, mainprefix, deleted, sincedate, todate) SELECT name, cqz, ituz, continent, latitude, longitude, utc, dxcc, mainprefix, deleted, sincedate, todate FROM entity"); sqlOk = execQuery(Q_FUNC_INFO, stringQuery); if (sqlOk) { //qDebug() << "DataBase::updateTableEntity: Data copied from entity to entitytemp!" << endl; stringQuery = "DROP TABLE entity"; if (execQuery(Q_FUNC_INFO, stringQuery)) { //qDebug() << "DataBase::updateTableEntity: Table entity DELETED" << endl; stringQuery = "ALTER TABLE entitytemp RENAME TO entity"; return execQuery(Q_FUNC_INFO, stringQuery); } else { return false; } } else { //qDebug() << "DataBase::updateTableEntity: Data NOT copied from entity to entitytemp!" << endl; //TODO: If it fails, we should manage errors... return false; } } else { //qDebug() << "DataBase::updateTableEntity: Table entitytemp NOT created!" << endl; return false; } return false; } bool DataBase::updateTableLogs() { //qDebug() << "DataBase::updateTableLogs" << endl; bool result = false; QString stringQuery; bool sqlOk; result = createTableLogs(false); // Now we have a temp entity table with the correct format if (result) { //qDebug() << "DataBase::updateTableLogs: Table logstemp created!" << endl; // Now we need to move all the data from the old to the temp logs table. stringQuery = QString("INSERT INTO logstemp (logdate, stationcall, comment, logtype, logtypen) SELECT logdate, stationcall, comment, logtype, logtypen FROM logs"); sqlOk = execQuery(Q_FUNC_INFO, stringQuery); if (sqlOk) { //qDebug() << "DataBase::updateTableLogs: data copied" << endl; stringQuery = "DROP TABLE logs"; if (execQuery(Q_FUNC_INFO, stringQuery)) { //qDebug() << "DataBase::updateTableLogs: Table logs DELETED" << endl; stringQuery = "ALTER TABLE logstemp RENAME TO logs"; return execQuery(Q_FUNC_INFO, stringQuery); } else { //qDebug() << "DataBase::updateTableLogs: Table logs NOT DELETED" << endl; return false; } } else { //queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::updateTableLogs: data NOT copied" << endl; //TODO: If it fails, we should manage errors... return false; } } else { //qDebug() << "DataBase::updateTableLogs: Table logstemp NOT created!" << endl; return false; } //qDebug() << "DataBase::updateTableLogs: END" << endl; return false; } bool DataBase::updateModeIdFromSubModeId() {// Updates the log with the new mode IDs in each QSO: // STEP-1: Get the modeid and QSOid from the log // STEP-2: uses the modeid to get the name of the mode in the mode table (the old one) // STEP-3: uses the name of the mode in the modetemp table (the new one) to get the new ID // STEP-4: Updates the new ID in the QSO in the log //qDebug() << "DataBase::updateModeIdFromSubModeId: " << endl; bool cancel = false; bool alreadyCancelled = false; QString modetxt = QString(); QString sq = QString(); bool sqlOk2 = false; bool sqlOk3 = false; int modeFound = -1; int id = -1; int qsos; int i = 0; QString aux; QSqlQuery query, query2; bool sqlOk = query.exec("SELECT COUNT (*) FROM log"); if (sqlOk) { //QSqlDatabase::database().commit(); query.next(); qsos = (query.value(0)).toInt(); query.finish(); } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); //qDebug() << "DataBase::updateModeIdFromSubModeId: FALSE END" << endl; return false; } int step = util->getProgresStepForDialog(qsos); QProgressDialog progress(QObject::tr("Updating mode information..."), QObject::tr("Abort updating"), 0, qsos); progress.setMaximum(qsos); progress.setWindowModality(Qt::WindowModal); sqlOk = query.exec("SELECT modeid, id FROM log ORDER BY modeid"); // STEP-1 if (sqlOk) { while (query.next()) { modetxt = QString(); modeFound = -1; if (query.isValid()) { i++; if (( (i % step )== 0) ) { // To update the speed I will only show the progress once each X QSOs aux = QObject::tr("Updating mode information...") + "\n" + QObject::tr("QSO: ") + QString::number(i) + "/" + QString::number(qsos); progress.setLabelText(aux); progress.setValue(i); } modeFound = (query.value(0)).toInt(); id = (query.value(1)).toInt(); //qDebug() << "DataBase::updateModeIdFromSubModeId: (STEP-1) modeFound (numb): " << QString::number(modeFound) << endl; modetxt = getModeNameFromNumber(modeFound, false); //STEP-2 //qDebug() << "DataBase::updateModeIdFromSubModeId: (STEP-2) mode found (txt): " << modetxt << endl; //TODO The following query can be executed in: getModeIdFromSubMode() sq = QString("SELECT id FROM modetemp WHERE submode='%1'").arg(modetxt); // STEP-3 sqlOk2 = query2.exec(sq); if (sqlOk2) { //qDebug() << "DataBase::updateModeIdFromSubModeId: (STEP-3) sqlOK2 TRUE" << endl; if (query2.next()) { if (query2.isValid()) { modeFound = query2.value(0).toInt(); query2.finish(); sq = QString ("UPDATE log SET modeid='%1' WHERE id='%2'").arg(modeFound).arg(id); // STEP-4 sqlOk3 = execQuery(Q_FUNC_INFO, sq); if (sqlOk3) { //qDebug() << "DataBase::updateModeIdFromSubModeId: (STEP-4) ID: " << QString::number(id) << " updated to: " << QString::number(modeFound) <<"/"<< modetxt << endl; } else { //queryErrorManagement(Q_FUNC_INFO, query3.lastError().databaseText(), query3.lastError().number(), query3.lastQuery()); //qDebug() << "DataBase::updateModeIdFromSubModeId: (STEP-4) ID: " << QString::number(id) << " NOT updated-2" << endl; } } else { query2.finish(); //qDebug() << "DataBase::updateModeIdFromSubModeId: (STEP-3) query2 not valid " << endl; } } else { //qDebug() << "DataBase::updateModeIdFromSubModeId: query2 not next " << endl; } } else { queryErrorManagement(Q_FUNC_INFO, query2.lastError().databaseText(), query2.lastError().number(), query2.lastQuery()); query2.finish(); //qDebug() << "DataBase::updateModeIdFromSubModeId: ID: " << QString::number(id) << " NOT updated-1" << endl; } } if ( progress.wasCanceled() ) { if (alreadyCancelled) { } else { alreadyCancelled = true; QMessageBox msgBox; aux = QObject::tr("Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel?"); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked cancel = true; break; case QMessageBox::No: // No Save was clicked cancel = false; progress.setCancelButton(0); break; default: // should never be reached cancel = false; break; } } } } query.finish(); if (cancel && (!alreadyCancelled)) { //qDebug() << "DataBase::updateModeIdFromSubModeId: FALSE END 2" << endl; query.finish(); return false; } //qDebug() << "DataBase::updateModeIdFromSubModeId: END" << endl; query.finish(); return true; } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::updateModeIdFromSubModeId: FALSE END 3" << endl; query.finish(); return false; } //qDebug() << "DataBase::updateModeIdFromSubModeId: CHECK IF this is seen - END" << endl; query.finish(); return false; } bool DataBase::updateBandIdTableLogToNewOnes() { //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: " << endl; QString bandtxt = QString(); bool cancel = false; bool alreadyCancelled = false; //int errorCode = -1; QString sq = QString(); bool sqlOk2 = false; bool sqlOk3 = false; int bandFound = -1; int id = -1; int qsos; int i = 0; QString aux; QSqlQuery query, query2; bool sqlOk = query.exec("SELECT COUNT (*) FROM log"); if (sqlOk) { query.next(); qsos = (query.value(0)).toInt(); query.finish(); } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: FALSE END" << endl; query.finish(); return false; } int step = util->getProgresStepForDialog(qsos); QProgressDialog progress(QObject::tr("Updating bands information..."), QObject::tr("Abort updating"), 0, qsos); progress.setMaximum(qsos); progress.setWindowModality(Qt::WindowModal); sqlOk = query.exec("SELECT bandid, id FROM log ORDER BY bandid DESC"); if (sqlOk) { while (query.next() && (!cancel) ) { bandtxt = QString(); bandFound = -1; if (query.isValid()) { i++; if (( (i % step )== 0) ) { // To update the speed I will only show the progress once each X QSOs aux = QObject::tr("Updating bands information...") + "\n" + QObject::tr("QSO: ") + QString::number(i) + "/" + QString::number(qsos); progress.setLabelText(aux); progress.setValue(i); } bandFound = (query.value(0)).toInt(); id = (query.value(1)).toInt(); bandtxt = getBandNameFromNumber(bandFound); //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: band found: " << bandtxt << endl; sq = QString("SELECT id FROM bandtemp WHERE name='%1'").arg(bandtxt); sqlOk2 = query2.exec(sq); if (sqlOk2) { if (query2.next()) { if (query2.isValid()) { bandFound = query2.value(0).toInt(); sq = QString ("UPDATE log SET bandid='%1' WHERE id='%2'").arg(bandFound).arg(id); query.finish(); sqlOk3 = execQuery(Q_FUNC_INFO, sq); if (sqlOk3) { //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: ID: " << QString::number(id) << " updated to: " << QString::number(bandFound) <<"/"<< bandtxt << endl; } else { //queryErrorManagement(Q_FUNC_INFO, query3.lastError().databaseText(), query3.lastError().number(), query3.lastQuery()); //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: ID: " << QString::number(id) << " NOT updated-2" << endl; //qDebug() << "DataBase::updateBandIdTableLogToNewOnes - QSOs not updated to main log" << endl; } } else { //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: query2 not valid " << endl; } } else { //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: query2 not next " << endl; } query2.finish(); } else { queryErrorManagement(Q_FUNC_INFO, query2.lastError().databaseText(), query2.lastError().number(), query2.lastQuery()); query2.finish(); //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: ID: " << QString::number(id) << " NOT updated-1" << endl; } } if ( progress.wasCanceled() ) { if (alreadyCancelled) { } else { alreadyCancelled = true; QMessageBox msgBox; aux = QObject::tr("Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel?"); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked cancel = true; break; case QMessageBox::No: // No Save was clicked cancel = false; progress.setCancelButton(0); break; default: // should never be reached cancel = false; break; } } } } query.finish(); if (cancel && (!alreadyCancelled)) { //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: FALSE END 2" << endl; return false; } //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: END OK" << endl; return true; } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); //qDebug() << "DataBase::updateBandIdTableLogToNewOnes: FALSE END 3" << endl; return false; } } bool DataBase::updateBandIdTableAward(const int _db) { //qDebug() << "DataBase::updateBandIdTableAward: " << endl; QString table = QString(); QString field = QString(); QString awardSelected = QString(); switch (_db) { case 1: // table = "awarddxcc"; field = "band"; awardSelected = "DXCC"; break; case 2: table = "awardwaz"; field = "band"; awardSelected = "WAZ"; break; default: //qDebug() << "DataBase::updateBandIdTableAward: FALSE END" << endl; return false; break; } QString bandtxt = QString(); bool cancel = false; bool alreadyCancelled = false; //int errorCode = -1; QString sq = QString(); bool sqlOk2 = false; bool sqlOk3 = false; int bandFound = -1; int id = -1; int qsos; int i = 0; QString aux; QSqlQuery query, query2; sq = QString("SELECT COUNT (*) FROM %1").arg(table); bool sqlOk = query.exec(sq); if (sqlOk) { query.next(); qsos = (query.value(0)).toInt(); query.finish(); } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); //qDebug() << "DataBase::updateBandIdTableAward: FALSE END-2" << endl; return false; } int step = util->getProgresStepForDialog(qsos); QString progressmsg = QString(QObject::tr("Updating bands information in %1 status...")).arg(awardSelected); QProgressDialog progress(progressmsg, QObject::tr("Abort updating"), 0, qsos); progress.setMaximum(qsos); progress.setWindowModality(Qt::WindowModal); sq = QString("SELECT %1, id FROM %2 ORDER BY %3 DESC").arg(field).arg(table).arg(field); sqlOk = query.exec(sq); if (sqlOk) { while (query.next() && (!cancel) ) { bandtxt = QString(); bandFound = -1; if (query.isValid()) { i++; if (( (i % step )== 0) ) { // To update the speed I will only show the progress once each X QSOs aux = QObject::tr("Updating bands information...") + "\n" + QObject::tr("Progress: ") + QString::number(i) + "/" + QString::number(qsos); progress.setLabelText(aux); progress.setValue(i); } bandFound = (query.value(0)).toInt(); id = (query.value(1)).toInt(); bandtxt = getBandNameFromNumber(bandFound); //qDebug() << "DataBase::updateBandIdTableAward: band found: " << bandtxt << endl; sq = QString("SELECT id FROM bandtemp WHERE name='%1'").arg(bandtxt); sqlOk2 = query2.exec(sq); if (sqlOk2) { if (query2.next()) { if (query2.isValid()) { bandFound = query2.value(0).toInt(); query2.finish(); sq = QString ("UPDATE %1 SET %2='%3' WHERE id='%4'").arg(table).arg(field).arg(bandFound).arg(id); sqlOk3 = execQuery(Q_FUNC_INFO, sq); if (sqlOk3) { //qDebug() << "DataBase::updateBandIdTableAward: ID: " << QString::number(id) << " updated to: " << QString::number(bandFound) <<"/"<< bandtxt << endl; } else { //queryErrorManagement(Q_FUNC_INFO, query3.lastError().databaseText(), query3.lastError().number(), query3.lastQuery()); //qDebug() << "DataBase::updateBandIdTableAward: ID: " << QString::number(id) << " NOT updated-2" << endl; //qDebug() << "DataBase::updateBandIdTableAward - QSOs not updated to main log" << endl; } } else { //qDebug() << "DataBase::updateBandIdTableAward: query2 not valid " << endl; } } else { //qDebug() << "DataBase::updateBandIdTableAward: query2 not next " << endl; } query2.finish(); } else { queryErrorManagement(Q_FUNC_INFO, query2.lastError().databaseText(), query2.lastError().number(), query2.lastQuery()); query2.finish(); //qDebug() << "DataBase::updateBandIdTableAward: ID: " << QString::number(id) << " NOT updated-1" << endl; } } if ( progress.wasCanceled() ) { if (alreadyCancelled) { } else { alreadyCancelled = true; QMessageBox msgBox; aux = QObject::tr("Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel?"); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked cancel = true; break; case QMessageBox::No: // No Save was clicked cancel = false; progress.setCancelButton(0); break; default: // should never be reached cancel = false; break; } } } } if (cancel && (!alreadyCancelled)) { //qDebug() << "DataBase::updateBandIdTableAward: FALSE END-3" << endl; query.finish(); return false; } //qDebug() << "DataBase::updateBandIdTableAward: END OK" << endl; query.finish(); return true; } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::updateBandIdTableAward: FALSE END-4" << endl; query.finish(); return false; } //qDebug() << "DataBase::updateBandIdTableAward: CHECK IF SEEN END" << endl; query.finish(); return false; } bool DataBase::updateModeIdTableAward(const int _db) { //qDebug() << "DataBase::updateModeIdTableAward: " << QString::number(_db) << endl; QString table = QString(); QString field = "mode"; QString awardSelected = QString(); switch (_db) { case 1: // table = "awarddxcc"; awardSelected = "DXCC"; break; case 2: table = "awardwaz"; awardSelected = "WAZ"; break; default: //qDebug() << "DataBase::updateModeIdTableAward: FALSE END" << endl; return false; break; } QString bandtxt = QString(); bool cancel = false; bool alreadyCancelled = false; //int errorCode = -1; QString sq = QString(); bool sqlOk2 = false; bool sqlOk3 = false; int bandFound = -1; int id = -1; int qsos; int i = 0; QString aux; QSqlQuery query, query2; sq = QString("SELECT COUNT (*) FROM %1").arg(table); bool sqlOk = query.exec(sq); if (sqlOk) { query.next(); qsos = (query.value(0)).toInt(); query.finish(); } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::updateModeIdTableAward: FALSE END-2" << endl; query.finish(); return false; } int step = util->getProgresStepForDialog(qsos); QString progressmsg = QString(QObject::tr("Updating mode information in %1 status...")).arg(awardSelected); QProgressDialog progress(progressmsg, QObject::tr("Abort updating"), 0, qsos); progress.setMaximum(qsos); progress.setWindowModality(Qt::WindowModal); sq = QString("SELECT %1, id FROM %2 ORDER BY %3 DESC").arg(field).arg(table).arg(field); sqlOk = query.exec(sq); //qDebug() << "DataBase::updateModeIdTableAward (query): " << query.lastQuery() << endl; if (sqlOk) { while (query.next() && (!cancel) ) { bandtxt = QString(); bandFound = -1; if (query.isValid()) { i++; if (( (i % step )== 0) ) { // To update the speed I will only show the progress once each X QSOs aux = QObject::tr("Updating bands information...") + "\n" + QObject::tr("Progress: ") + QString::number(i) + "/" + QString::number(qsos); progress.setLabelText(aux); progress.setValue(i); } bandFound = (query.value(0)).toInt(); id = (query.value(1)).toInt(); //qDebug() << "DataBase::updateModeIdTableAward: bandfound: " << QString::number(bandFound) << endl; //qDebug() << "DataBase::updateModeIdTableAward: id: " << QString::number(id) << endl; bandtxt = getSubModeNameFromNumber(bandFound, true); //qDebug() << "DataBase::updateModeIdTableAward: mode found: " << bandtxt << "/" << QString::number(bandFound) << endl; sq = QString("SELECT id FROM modetemp WHERE submode='%1'").arg(bandtxt); sqlOk2 = query2.exec(sq); //qDebug() << "DataBase::updateModeIdTableAward (query2): " << query2.lastQuery() << endl; if (sqlOk2) { if (query2.next()) { if (query2.isValid()) { bandFound = query2.value(0).toInt(); query2.finish(); sq = QString ("UPDATE %1 SET %2='%3' WHERE id='%4'").arg(table).arg(field).arg(bandFound).arg(id); sqlOk3 = execQuery(Q_FUNC_INFO, sq); //qDebug() << "DataBase::updateModeIdTableAward (query3 update): " << query3.lastQuery() << endl; if (sqlOk3) { //qDebug() << "DataBase::updateModeIdTableAward: ID: " << QString::number(id) << " updated to: " << QString::number(bandFound) <<"/"<< bandtxt << endl; } else { //queryErrorManagement(Q_FUNC_INFO, query3.lastError().databaseText(), query3.lastError().number(), query3.lastQuery()); //qDebug() << "DataBase::updateModeIdTableAward: ID: " << QString::number(id) << " NOT updated-2" << endl; //qDebug() << "DataBase::updateModeIdTableAward - QSOs not updated to main log" << endl; } } else { //qDebug() << "DataBase::updateModeIdTableAward: query2 not valid " << endl; } } else { //qDebug() << "DataBase::updateModeIdTableAward: query2 not next " << endl; } } else { queryErrorManagement(Q_FUNC_INFO, query2.lastError().databaseText(), query2.lastError().number(), query2.lastQuery()); query2.finish(); //qDebug() << "DataBase::updateModeIdTableAward: ID: " << QString::number(id) << " NOT updated-1" << endl; } } if ( progress.wasCanceled() ) { if (alreadyCancelled) { } else { alreadyCancelled = true; QMessageBox msgBox; aux = QObject::tr("Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel?"); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked cancel = true; break; case QMessageBox::No: // No Save was clicked cancel = false; progress.setCancelButton(0); break; default: // should never be reached cancel = false; break; } } } } if (cancel && (!alreadyCancelled)) { //qDebug() << "DataBase::updateModeIdTableAward: FALSE END-3" << endl; query.finish(); return false; } //qDebug() << "DataBase::updateModeIdTableAward: END OK" << endl; query.finish(); return true; } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::updateModeIdTableAward: FALSE END-4" << endl; query.finish(); return false; } //qDebug() << "DataBase::updateModeIdTableAward: Checkif seen END" << endl; query.finish(); return false; } /* bool DataBase::updateModeIdTableLogToNewOnes() { //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: " << endl; QString bandtxt = QString(); bool cancel = false; bool alreadyCancelled = false; int errorCode = -1; QString sq = QString(); bool sqlOk2 = false; bool sqlOk3 = false; int bandFound = -1; int id = -1; int qsos; int i = 0; QString aux; QSqlQuery query, query2, query3; bool sqlOk = query.exec("SELECT COUNT (*) FROM log"); if (sqlOk) { query.next(); qsos = (query.value(0)).toInt(); } else { return false; } int step = util->getProgresStepForDialog(qsos); QProgressDialog progress(QObject::tr("Updating mode information..."), QObject::tr("Abort updating"), 0, qsos); progress.setMaximum(qsos); progress.setWindowModality(Qt::WindowModal); sqlOk = query.exec("SELECT modeid, id FROM log ORDER BY bandid DESC"); if (sqlOk) { while (query.next() && (!cancel) ) { bandtxt = QString(); bandFound = -1; if (query.isValid()) { i++; if (( (i % step )== 0) ) { // To update the speed I will only show the progress once each X QSOs aux = QObject::tr("Updating mode information...\n QSO: ") + QString::number(i) + "/" + QString::number(qsos); progress.setLabelText(aux); progress.setValue(i); } bandFound = (query.value(0)).toInt(); id = (query.value(1)).toInt(); bandtxt = getModeNameFromNumber(bandFound, false); //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: mode found: " << bandtxt << endl; sq = QString("SELECT id FROM modetemp WHERE name='%1'").arg(bandtxt); sqlOk2 = query2.exec(sq); if (sqlOk2) { if (query2.next()) { if (query2.isValid()) { bandFound = query2.value(0).toInt(); sq = QString ("UPDATE log SET modeid='%1' WHERE id='%2'").arg(bandFound).arg(id); sqlOk3 = query3.exec(sq); if (sqlOk3) { //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: ID: " << QString::number(id) << " updated to: " << QString::number(bandFound) <<"/"<< bandtxt << endl; } else { //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: ID: " << QString::number(id) << " NOT updated-2" << endl; //qDebug() << "DataBase::updateModeIdTableLogToNewOnes - QSOs not updated to main log" << endl; errorCode = query3.lastError().number(); //qDebug() << "DataBase::updateModeIdTableLogToNewOnes - query error: " << QString::number(errorCode) << endl; //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: LastQuery: " << query3.lastQuery() << endl; //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: LastError-data: " << query3.lastError().databaseText() << endl; //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: LastError-driver: " << query3.lastError().driverText() << endl; //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: LastError-n: " << QString::number(query3.lastError().number() ) << endl; } } else { //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: query2 not valid " << endl; } } else { //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: query2 not next " << endl; } } else { //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: ID: " << QString::number(id) << " NOT updated-1" << endl; } } if ( progress.wasCanceled() ) { if (alreadyCancelled) { } else { alreadyCancelled = true; QMessageBox msgBox; aux = QObject::tr("Canceling this update will cause data inconsistencies and possibly data loss. Do you still want to cancel?"); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: // Yes was clicked cancel = true; break; case QMessageBox::No: // No Save was clicked cancel = false; progress.setCancelButton(0); break; default: // should never be reached cancel = false; break; } } } } if (cancel && (!alreadyCancelled)) { return false; } //qDebug() << "DataBase::updateModeIdTableLogToNewOnes: FINISHED OK" << endl; return true; } else { return false; } } */ bool DataBase::updateTo007() {// Updates the DB to 0.0.7 //qDebug() << "DataBase::updateTo007" << endl; bool IAmIn007 = false; bool IAmIn006 = false; bool ErrorUpdating = false; QString stringQuery = QString(); //QString dateString = (date.currentDateTime()).toString("yyyyMMdd"); QSqlQuery query; bool sqlOk = false; if (latestReaded >= float(0.007)) { //qDebug() << "DataBase::updateTo007: - I am in 007" << endl; return true; } else { //qDebug() << "DataBase::updateTo007: - I am not in 007" << endl; IAmIn007 = false; } while (!IAmIn007 && !ErrorUpdating) { while (!IAmIn006 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo007: - And I am not in 006" << endl; IAmIn006 = updateTo006(); } if (ErrorUpdating) { return false; } sqlOk = updateDBVersion(); if (sqlOk) { // Version updated IAmIn007 = updateTableLog(6); } else { // Version not updated } //DO ALL THE TASKS TO BE IN 0.004 from 0.003 HERE and set ErrorUpdating if it is not possible. IAmIn007 = true; } return IAmIn007; } bool DataBase::updateTo008() {// Updates the DB to 0.0.8 //qDebug() << "DataBase::updateTo008" << endl; bool IAmIn008 = false; bool IAmIn007 = false; bool ErrorUpdating = false; //QString stringQuery = QString(); //QString dateString = (date.currentDateTime()).toString("yyyyMMdd"); //QSqlQuery query; bool sqlOk = false; if (latestReaded >= (0.008)) { //qDebug() << "DataBase::updateTo008: - I am in 008" << endl; return true; } else { //qDebug() << "DataBase::updateTo008: - I am not in 008" << endl; IAmIn008 = false; } while (!IAmIn008 && !ErrorUpdating) { while (!IAmIn007 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo008: - And I am not in 007" << endl; IAmIn007 = updateTo007(); } if (ErrorUpdating) { return false; } sqlOk = updateDBVersion(); if (sqlOk) { // Version updated //IAmIn008 = updateTableLog(6); } else { // Version not updated } //DO ALL THE TASKS TO BE IN 0.008 from 0.007 HERE and set ErrorUpdating if it is not possible. IAmIn008 = updateTheModeTableAndSyncLog(); //IAmIn008 = true; } return IAmIn008; } bool DataBase::updateTo009() {// Updates the DB to 0.0.9 - We add the Satellite tables //qDebug() << "DataBase::updateTo009: latestRead: " << QString::number(latestReaded) << endl; bool IAmIn009 = false; bool IAmIn008 = false; bool ErrorUpdating = false; //QString stringQuery = QString(); //QString dateString = (date.currentDateTime()).toString("yyyyMMdd"); //QSqlQuery query; bool sqlOk = false; //if (latestReaded >= 0.009) //qDebug() << "DataBase::updateTo009: Checking:" << QString::number(latestReaded) << ":" << QString::number(0.009)<< endl; if (latestReaded >= float(0.009)) //if ((latestReaded = 0.009) || (latestReaded > 0.009)) { //qDebug() << "DataBase::updateTo009: - I am in 009" << endl; //IAmIn009 = true; return true; } else { //qDebug() << "DataBase::updateTo009: - I am not in 009 I am in: " << QString::number(latestReaded)<< endl; IAmIn009 = false; } //qDebug() << "DataBase::updateTo009: compared latestRead: " << QString::number(latestReaded) << endl; while (!IAmIn009 && !ErrorUpdating) { while (!IAmIn008 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo009: - And I am not in 008" << endl; IAmIn008 = updateTo008(); } //qDebug() << "DataBase::updateTo009: - And I am already at least in 008" << endl; if (ErrorUpdating) { return false; } sqlOk = updateDBVersion(); if (sqlOk) { // Version updated //qDebug() << "DataBase::updateTo009: - version updated" << endl; //IAmIn009 = updateTableLog(6); } else { // Version not updated //qDebug() << "DataBase::updateTo009: - version not updated" << endl; } //DO ALL THE TASKS TO BE IN 0.009 from 0.008 HERE and set ErrorUpdating if it is not possible. if (recreateSatelliteData()) //if (createTableSatellites(true)) { //qDebug() << "DataBase::updateTo009: - createTableSatellites OK" << endl; //if (populateTableSatellites(true)) if (true) { //qDebug() << "DataBase::updateTo009: - populateTableSatellites OK" << endl; if (updateTableEntity()) { //qDebug() << "DataBase::updateTo009: - updateTableEntity OK" << endl; if (updateTheEntityTableISONames()) { //qDebug() << "DataBase::updateTo009: - isonames updated" << endl; // Now I need to update the logs table if (updateTableLogs()) { //qDebug() << "DataBase::updateTo009: - logs updated and Function finished successfuly!!" << endl; IAmIn009 = true; } else { //qDebug() << "DataBase::updateTo009: - logs NOT updated" << endl; IAmIn009 = false; ErrorUpdating = true; } } else { //qDebug() << "DataBase::updateTo009: - isonames NOT updated" << endl; IAmIn009 = false; ErrorUpdating = true; } } else { ErrorUpdating = true; IAmIn009 = false; } } else { //qDebug() << "DataBase::updateTo009: - populateTableSatellites FALSE" << endl; ErrorUpdating = true; IAmIn009 = false; } } else { //qDebug() << "DataBase::updateTo009: - createTableSatellites FALSE" << endl; ErrorUpdating = true; IAmIn009 = false; } } //qDebug() << "DataBase::updateTo009: - END" << endl; return IAmIn009; } bool DataBase::updateTo010() {// Updates the DB to 0.010: // We add FT8 mode and // AS Propagation //qDebug() << "DataBase::updateTo010: latestRead: " << QString::number(latestReaded) << endl; bool IAmIn010 = false; bool IAmIn009 = false; bool ErrorUpdating = false; QString stringQuery = QString(); QSqlQuery query; bool sqlOk = false; //qDebug() << "DataBase::updateTo010: Checking (latestRead/dbVersion):" << QString::number(latestReaded) << "/" << QString::number(dbVersion) << endl; if (latestReaded >= float(0.01)) { //qDebug() << "DataBase::updateTo010: - I am in 010" << endl; IAmIn010 = true; return true; } else { //qDebug() << "DataBase::updateTo010: - I am not in 010 I am in: " << QString::number(latestReaded)<< endl; while (!IAmIn009 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo010: - Check if I am in 009: !" << endl; IAmIn009 = updateTo009(); if (IAmIn009) { //qDebug() << "DataBase::updateTo010: - updateTo009 returned TRUE - I am in 0.009: " << QString::number(latestReaded) << endl; } else { //qDebug() << "DataBase::updateTo010: - updateTo009 returned FALSE - I am NOT in 0.009: " << QString::number(latestReaded) << endl; ErrorUpdating = false; } } if (ErrorUpdating) { //qDebug() << "DataBase::updateTo010: - I Could not update to: " << QString::number(dbVersion) << endl; return false; } } sqlOk = execQuery(Q_FUNC_INFO, "UPDATE band SET lower = '0.1357', upper = '0.1378' WHERE name='2190M'"); if (sqlOk) { //qDebug() << "DataBase::updateTo010: - Band update OK" << endl; } else { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::updateTo010: - Band update NOK" << endl; } execQuery(Q_FUNC_INFO, QString("INSERT INTO mode (submode, name, cabrillo, deprecated) VALUES ('FT8', 'FT8', 'NO', '0')")); execQuery(Q_FUNC_INFO, QString("INSERT INTO prop_mode_enumeration (shortname, name) VALUES ('AS', 'Aircraft Scatter')")); if (updateDBVersion()) { //qDebug() << "DataBase::updateTo010: - We are in 010! " << endl; IAmIn010 = true; } else { //qDebug() << "DataBase::updateTo010: - Failed to go to 010! " << endl; IAmIn010 = false; } //qDebug() << "DataBase::updateTo010: - END" << endl; return IAmIn010; } bool DataBase::updateDBVersion() { QString dateString = (QDate::currentDate()).toString("yyyyMMdd"); //qDebug() << "DataBase::updateDBVersion: (date/SoftVersion/dbVersion): " << dateString << "/" << softVersion << "/" << QString::number(dbVersion) << endl; QString stringQuery = "INSERT INTO softwarecontrol (dateupgrade, softversion, dbversion) VALUES ('" + dateString + "', '" + softVersion + "', '" + QString::number(dbVersion) + "')"; return execQuery(Q_FUNC_INFO, stringQuery); } bool DataBase::updateTheModeTableAndSyncLog() { //qDebug() << "DataBase::updateTheModeTableAndSyncLog" << endl; QSqlQuery query; createTableMode(false); // Create modetemp populateTableMode(false); // Populate modetemp updateModeIdFromSubModeId(); // Updates the log with the new mode IDs in each QSO //updateModeIdTableAward(1); //DXCC //updateModeIdTableAward(2); // WAZ bool sqlOK; //QSqlDatabase::database().commit(); sqlOK = execQuery(Q_FUNC_INFO, "DROP TABLE mode"); if (sqlOK) { //QSqlDatabase::database().commit(); //qDebug() << "DataBase::updateTheModeTableAndSyncLog - OK - mode was dropped" << endl; return execQuery(Q_FUNC_INFO, "ALTER TABLE modetemp RENAME TO mode"); } else { //queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::updateTheModeTableAndSyncLog - ERROR - modetemp not dropped" << endl; return false; } //qDebug() << "DataBase::updateTheModeTableAndSyncLog END" << endl; return true; } bool DataBase::recreateTableBand() { //qDebug() << "DataBase::recreateTableBand" << endl; QSqlQuery query; createTableBand(false); // Create modetemp populateTableBand(false); // Populate modetemp if (execQuery(Q_FUNC_INFO, "DROP TABLE band")) { return execQuery(Q_FUNC_INFO, "ALTER TABLE bandtemp RENAME TO mode"); } else { //queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); //qDebug() << "DataBase::recreateTableBand - ERROR - bandtemp not dropped" << endl; return false; } //qDebug() << "DataBase::recreateTableBand END" << endl; return true; } bool DataBase::updateTheEntityTableISONames() { //qDebug() << "DataBase::updateTheEntityTableISONames" << endl; QSqlQuery query; QString sq; bool sqlOK; //First of all we will check if the entity table does contain data. We can't update something non existent! if (!hasTheTableData("entity")) { //qDebug() << "DataBase::updateTheEntityTableISONames: Entity has NO data" << endl; return false; } //qDebug() << "DataBase::updateTheEntityTableISONames-1" << endl; sq = QString ("UPDATE entity SET isoname='mt' WHERE dxcc='246'"); //Sovereign Order of Malta sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return false; } //qDebug() << "DataBase::updateTheEntityTableISONames-2" << endl; sq = QString ("UPDATE entity SET isoname='un' WHERE dxcc='247'"); //Spratly sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); return false; } sq = QString ("UPDATE entity SET isoname='mc' WHERE dxcc='260'"); //Monaco sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mu' WHERE dxcc='4'"); // Agalega sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mu' WHERE dxcc='165'"); //Mauricio sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mu' WHERE dxcc='207'"); //Rodriguez sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gq' WHERE dxcc='49'"); // Equatorial Guinea sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fj' WHERE dxcc='176'"); //Fidji sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gq' WHERE dxcc='195'"); //Annobon sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fj' WHERE dxcc='489'"); // Conway reef sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fj' WHERE dxcc='460'"); // Rotuma sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sz' WHERE dxcc='468'"); // Swaziland sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tn' WHERE dxcc='474'"); // Tunisia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='vn' WHERE dxcc='293'"); // Vietnam sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gn' WHERE dxcc='107'"); // Guinea sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bv' WHERE dxcc='24'"); // Bouvet sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='no' WHERE dxcc='199'"); // Peter 1 Is" sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='az' WHERE dxcc='18'"); // Azerbaijan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ge' WHERE dxcc='75'"); // Georgia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='me' WHERE dxcc='514'"); // Montenegro sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='lk' WHERE dxcc='315'"); // Sri lanka sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ch' WHERE dxcc='117'"); // ITU HQ sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='289'"); // UN HQ sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tl' WHERE dxcc='511'"); // Timor Leste sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='il' WHERE dxcc='336'"); // Israel sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ly' WHERE dxcc='436'"); // Libya sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cy' WHERE dxcc='215'"); // Cyprus sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tz' WHERE dxcc='470'"); // Tanzania sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ng' WHERE dxcc='450'"); // Nigeria sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mg' WHERE dxcc='438'"); // Madagascar sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mr' WHERE dxcc='444'"); // Mauritania sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ne' WHERE dxcc='187'"); // Niger sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tg' WHERE dxcc='483'"); // Togo sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ws' WHERE dxcc='190'"); // Samoa sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ug' WHERE dxcc='286'"); // Uganda sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ke' WHERE dxcc='430'"); // Kenya sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sn' WHERE dxcc='456'"); // Senegal sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='jm' WHERE dxcc='82'"); // Jamaica sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='es' WHERE dxcc='281'"); // Spain sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ls' WHERE dxcc='432'"); //Lesotho sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mw' WHERE dxcc='440'"); // Malawi sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='dz' WHERE dxcc='400'"); // Algeria sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ye' WHERE dxcc='492'"); // Yemen sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bb' WHERE dxcc='62'"); // Barbados sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mv' WHERE dxcc='159'"); // Maldives sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gy' WHERE dxcc='129'"); // Guyana sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='hr' WHERE dxcc='497'"); // Croatia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gh' WHERE dxcc='424'"); // Ghana sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mt' WHERE dxcc='257'"); // Malta sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='zm' WHERE dxcc='482'"); // Zambia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='kw' WHERE dxcc='348'"); // Kuwait sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sl' WHERE dxcc='458'"); // Sierra Leone sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='my' WHERE dxcc='299'"); // West Malaysia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='my' WHERE dxcc='46'"); // East Malaysia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='np' WHERE dxcc='369'"); // Nepal sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cd' WHERE dxcc='414'"); // Dem Rep Congo sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bi' WHERE dxcc='404'"); // Burundi sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sg' WHERE dxcc='381'"); // Singapore sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='rw' WHERE dxcc='454'"); // Rwanda sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tt' WHERE dxcc='90'"); // Trinidad & Tobago sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bw' WHERE dxcc='402'"); // Botswana sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='to' WHERE dxcc='160'"); // Tonga sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='om' WHERE dxcc='370'"); // Oman sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bt' WHERE dxcc='306'"); // Bhutan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ae' WHERE dxcc='391'"); // Un Arab Emirates sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='qa' WHERE dxcc='376'"); // Qatar sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bh' WHERE dxcc='304'"); // Bahrain sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pk' WHERE dxcc='372'"); // Pakistan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tw' WHERE dxcc='386'"); // Taiwan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tw' WHERE dxcc='505'"); // Pratas Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cn' WHERE dxcc='318'"); // China sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nr' WHERE dxcc='157'"); // Nauru sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ad' WHERE dxcc='203'"); // Andorra sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gm' WHERE dxcc='422'"); // Gambia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bs' WHERE dxcc='60'"); // Bahamas sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mz' WHERE dxcc='181'"); // Mozambique sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cl' WHERE dxcc='112'"); // Chile sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cl' WHERE dxcc='217'"); // San Felix sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cl' WHERE dxcc='47'"); // Easter Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cl' WHERE dxcc='125'"); // Juan Fernandez is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cu' WHERE dxcc='70'"); // Cuba sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ma' WHERE dxcc='446'"); // Morocco sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bo' WHERE dxcc='104'"); // Bolivia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pt' WHERE dxcc='272'"); // Portugal sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pt' WHERE dxcc='256'"); // Madeira sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pt' WHERE dxcc='149'"); // Azores sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='uy' WHERE dxcc='144'"); // Uruguay sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ca' WHERE dxcc='211'"); // Sable Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ca' WHERE dxcc='252'"); // St Paul is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ao' WHERE dxcc='401'"); // Angola sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cv' WHERE dxcc='409'"); // Cape Verde sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='km' WHERE dxcc='411'"); // Comoros sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='de' WHERE dxcc='230'"); // Fed Rep Germany sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ph' WHERE dxcc='375'"); //Philippines sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='er' WHERE dxcc='51'"); // Eritrea sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ps' WHERE dxcc='510'"); // Palestine sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ck' WHERE dxcc='191'"); // North Cook sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ck' WHERE dxcc='234'"); // South Cook sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nu' WHERE dxcc='188'"); // Niue sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ba' WHERE dxcc='501'"); // Bosnia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='es' WHERE dxcc='21'"); // Balearic is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='canary' WHERE dxcc='29'"); // Canary Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='es' WHERE dxcc='32'"); // Ceuta & Melilla sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ie' WHERE dxcc='245'"); // Ireland sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='am' WHERE dxcc='14'"); // Armenia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='lr' WHERE dxcc='434'"); // Liberia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ir' WHERE dxcc='330'"); // Iran sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mv' WHERE dxcc='179'"); // Moldova sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ee' WHERE dxcc='52'"); // Estonia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='et' WHERE dxcc='53'"); // Ethiopia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='by' WHERE dxcc='27'"); // Belarus sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='kg' WHERE dxcc='135'"); // Kyrgyzstan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tm' WHERE dxcc='262'"); // Turkmenistan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='227'"); // France sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='79'"); // Guadeloupe sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='yt' WHERE dxcc='169'"); // Mayotte sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='516'"); // St Barthelemy sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nc' WHERE dxcc='162'"); // New Caledonia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nc' WHERE dxcc='512'"); // Chesterfield Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mq' WHERE dxcc='84'"); // Martinique sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pf' WHERE dxcc='175'"); // French Polynesia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pf' WHERE dxcc='508'"); // Austral Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pm' WHERE dxcc='277'"); // St Pierre & Miquelon sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='re' WHERE dxcc='453'"); //Reunion Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='213'"); // St Marteen sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='99'"); // Glorioso is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='124'"); // Juan de nova, Europa sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='276'"); // Tromelin - TODO: Add the wikipedia flag sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='41'"); // Crozet sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='131'"); // Kerguelen sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag http://es.wikipedia.org/wiki/Tierras_Australes_y_Ant%C3%A1rticas_Francesas sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='10'"); //Amsterdam & St Paul is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='wf' WHERE dxcc='298'"); // Wallis & Futuna is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gf' WHERE dxcc='63'"); // French Guiana sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='england' WHERE dxcc='223'"); // England sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gb' WHERE dxcc='114'"); //Isle of Man sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='northernireland' WHERE dxcc='265'"); // Northern Ireland sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gb' WHERE dxcc='122'"); // Jersey sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='scotland' WHERE dxcc='279'"); // Scotland & Shetland is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gb' WHERE dxcc='106'"); // Guernsey sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='wales' WHERE dxcc='294'"); // Wales sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sb' WHERE dxcc='185'"); // Solomon sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sb' WHERE dxcc='507'"); // Temotu Province sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='hu' WHERE dxcc='239'"); // Hungary sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ch' WHERE dxcc='287'"); // Switzerland sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='li' WHERE dxcc='251'"); // Liechtenstein sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ec' WHERE dxcc='120'"); // Ecuador sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ec' WHERE dxcc='71'"); // Galapagos Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ht' WHERE dxcc='78'"); // Haiti sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='do' WHERE dxcc='72'"); // Dominican Rep sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='co' WHERE dxcc='116'"); // Colombia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='co' WHERE dxcc='216'"); // San Andres & Providencia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='co' WHERE dxcc='161'"); // Malpelo sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='kr' WHERE dxcc='137'"); // Rep Korea sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pa' WHERE dxcc='88'"); // Panama sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='hn' WHERE dxcc='80'"); // Honduras sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='th' WHERE dxcc='387'"); // Thailand sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='va' WHERE dxcc='295'"); // Vatican City sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sa' WHERE dxcc='378'"); // Saudi Arabia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='it' WHERE dxcc='248'"); // Italy sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='dj' WHERE dxcc='382'"); // Djibouti sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gd' WHERE dxcc='77'"); // Grenada sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gw' WHERE dxcc='109'"); // Guinea-Bissau sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='lc' WHERE dxcc='97'"); // St Lucia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='dm' WHERE dxcc='95'"); // Dominica sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='vc' WHERE dxcc='98'"); // St Vicent sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='jp' WHERE dxcc='339'"); // Japan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='jp' WHERE dxcc='177'"); // Minami Torishima sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='jp' WHERE dxcc='192'"); // Ogasawara sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mn' WHERE dxcc='363'"); // Mongolia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sj' WHERE dxcc='259'"); // Svalbard sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sj' WHERE dxcc='118'"); // Jan Mayen sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='jo' WHERE dxcc='342'"); // Jordan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='291'"); // United States sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='105'"); // Guantanamo Bay sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mp' WHERE dxcc='166'"); // Mariana is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='20'"); // Baker & Howland is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gu' WHERE dxcc='103'"); // Guam sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='123'"); // Johnston is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='174'"); // Midway is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='197'"); // Palmyra & Jarbis is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='134'"); // Kingman Reef sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='110'"); // Hawaii sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='138'"); // Kure is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='as' WHERE dxcc='9'"); // American Samoa sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='as' WHERE dxcc='515'"); // Swains is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='297'"); // Wake is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='6'"); // Alaska sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='182'"); // Navassa Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='vi' WHERE dxcc='285'"); // Us Virgin is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pr' WHERE dxcc='202'"); // Puerto Rico sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='us' WHERE dxcc='43'"); // Desecheo Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='no' WHERE dxcc='266'"); // Norway sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ar' WHERE dxcc='100'"); // Argentina sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='lu' WHERE dxcc='254'"); // Luxembourg sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='lt' WHERE dxcc='146'"); // Lithuania sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bg' WHERE dxcc='212'"); // Bulgaria sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pe' WHERE dxcc='136'"); // Peru sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='lb' WHERE dxcc='354'"); // Lebanon sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='at' WHERE dxcc='206'"); // Austria & Viena Intl HQ sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fi' WHERE dxcc='224'"); // Findland sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fi' WHERE dxcc='5'"); // Aland is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fi' WHERE dxcc='167'"); // Market Reef sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cz' WHERE dxcc='503'"); // Czech Rep sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sk' WHERE dxcc='504'"); // Slovak Rep sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='be' WHERE dxcc='209'"); // Belgium sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gl' WHERE dxcc='237'"); // Greenland sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='dk' WHERE dxcc='222'"); // Faroe is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='dk' WHERE dxcc='221'"); // Denmark sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pg' WHERE dxcc='163'"); // Papua New Guinea sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='aw' WHERE dxcc='91'"); // Aruba sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='kp' WHERE dxcc='344'"); //Dpr Korea sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nl' WHERE dxcc='263'"); // Netherlands sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cw' WHERE dxcc='517'"); // Curacao sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='bq' WHERE dxcc='520'"); // Bonaire sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='nl' WHERE dxcc='519'"); // Saba & St Eustatius sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='shm' WHERE dxcc='518'"); // Sint Marteen sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='br' WHERE dxcc='108'"); // Brazil sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='br' WHERE dxcc='56'"); // Fernando de Noronha sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='br' WHERE dxcc='253'"); // St Peter & St Paul sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='br' WHERE dxcc='273'"); // Trindade & Martim Vaz sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sr' WHERE dxcc='140'"); // Suriname sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ru' WHERE dxcc='61'"); // Franz Josef Land sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='eh' WHERE dxcc='302'"); // Western Sahara sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='bd' WHERE dxcc='305'"); // Bangladesh sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='si' WHERE dxcc='499'"); // Slovenia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sc' WHERE dxcc='379'"); // Seychelles sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='st' WHERE dxcc='219'"); // Sao Tome & Principe sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='se' WHERE dxcc='284'"); // Sweden sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pl' WHERE dxcc='269'"); // Poland sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sd' WHERE dxcc='466'"); // Sudan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='eg' WHERE dxcc='479'"); // Egypt sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gr' WHERE dxcc='236'"); // Greece sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gr' WHERE dxcc='180'"); // Mount Athos sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gr' WHERE dxcc='45'"); // Dodecanese sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gr' WHERE dxcc='40'"); // Crete sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tv' WHERE dxcc='282'"); // Tuvalu sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ki' WHERE dxcc='301'"); // Western Kiribati sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ki' WHERE dxcc='31'"); // Central Kiribati sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ki' WHERE dxcc='48'"); // Eastern Kiribati sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ki' WHERE dxcc='490'"); // Banaba is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='so' WHERE dxcc='232'"); // Somalia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sm' WHERE dxcc='278'"); // San Marino sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pw' WHERE dxcc='22'"); // Palau sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tr' WHERE dxcc='390'"); // Turkey sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='is' WHERE dxcc='242'"); // Iceland sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gt' WHERE dxcc='76'"); // Guatemala sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='cr' WHERE dxcc='308'"); // Costa Rica sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cr' WHERE dxcc='37'"); // Coco is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cm' WHERE dxcc='406'"); // Cameroon sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fr' WHERE dxcc='214'"); // Corsica sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} // TODO: Add the wikipedia flag sq = QString ("UPDATE entity SET isoname='cf' WHERE dxcc='408'"); // Central African Rep sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cg' WHERE dxcc='412'"); // Rep of Congo sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ga' WHERE dxcc='420'"); // Gabon sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='td' WHERE dxcc='410'"); // Chad sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ci' WHERE dxcc='428'"); // Cote d'Ivoire sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bj' WHERE dxcc='416'"); // Benin sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ml' WHERE dxcc='442'"); // Mali sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ru' WHERE dxcc='54'"); // European Rusia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ru' WHERE dxcc='126'"); // Kaliningrad sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) sq = QString ("UPDATE entity SET isoname='ru' WHERE dxcc='15'"); // Asiatic Rusia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='uz' WHERE dxcc='292'"); // Uzbekistan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='kz' WHERE dxcc='130'"); // Kazakhstan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ua' WHERE dxcc='288'"); // Ukraine sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ag' WHERE dxcc='94'"); // Antigua & Barbuda sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bz' WHERE dxcc='66'"); // Belize sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='kn' WHERE dxcc='249'"); // St Kitts & Nevis sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='na' WHERE dxcc='464'"); // Namibia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fm' WHERE dxcc='173'"); // Micronesia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fm' WHERE dxcc='168'"); // Marshall Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bn' WHERE dxcc='345'"); // Brunei Darusalam sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ca' WHERE dxcc='1'"); // Canada sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='au' WHERE dxcc='150'"); // Australia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='hm' WHERE dxcc='111'"); // Heard Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='au' WHERE dxcc='153'"); // Macquarie is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cc' WHERE dxcc='38'"); // Cocos / Keeling is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='au' WHERE dxcc='147'"); // Lord Howe is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='au' WHERE dxcc='171'"); // Mellish Reed sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nf' WHERE dxcc='189'"); // Norkfolk is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='au' WHERE dxcc='303'"); // Willis Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='cx' WHERE dxcc='35'"); // Christmas is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ai' WHERE dxcc='12'"); // Anguilla sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ms' WHERE dxcc='96'"); // Montserrat sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='vg' WHERE dxcc='65'"); // British is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tc' WHERE dxcc='89'"); // Turks & Caicos is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='pn' WHERE dxcc='172'"); // Pitcairn sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gb' WHERE dxcc='513'"); // Ducie is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='fk' WHERE dxcc='141'"); // Falkland is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gs' WHERE dxcc='235'"); // South Georgia is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='un' WHERE dxcc='241'"); // South Shetland is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='un' WHERE dxcc='238'"); // South Orkney is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gs' WHERE dxcc='240'"); // South Sandwich Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bm' WHERE dxcc='64'"); // Bermuda sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='io' WHERE dxcc='33'"); // Chagos is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='hk' WHERE dxcc='321'"); // Hong Kong sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='in' WHERE dxcc='324'"); // India sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='in' WHERE dxcc='11'"); // Andaman & Nicobar sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='in' WHERE dxcc='142'"); // Lakshadweep Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mx' WHERE dxcc='50'"); // Mexico sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mx' WHERE dxcc='204'"); // Revilagigedo sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='bf' WHERE dxcc='480'"); // Burkina Faso sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='kh' WHERE dxcc='312'"); // Cambodia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='la' WHERE dxcc='143'"); // Laos sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mo' WHERE dxcc='152'"); // Macao sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mm' WHERE dxcc='309'"); // Myanmar sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='af' WHERE dxcc='3'"); // Afganistan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='id' WHERE dxcc='327'"); // Indonesia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='iq' WHERE dxcc='333'"); // Iraq sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='vu' WHERE dxcc='158'"); // Vanuatu sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sy' WHERE dxcc='384'"); // Syria sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='lv' WHERE dxcc='145'"); // Latvia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ni' WHERE dxcc='86'"); // Nicaragua sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ro' WHERE dxcc='275'"); // Romania sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sv' WHERE dxcc='74'"); // El Salvador sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='rs' WHERE dxcc='296'"); // Serbia && Kosovo sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ve' WHERE dxcc='148'"); // Venezuela sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ve' WHERE dxcc='17'"); // Aves Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='zw' WHERE dxcc='452'"); // Zimbabwe sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='mk' WHERE dxcc='502'"); // Macedonia sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ss' WHERE dxcc='521'"); //Rep South Sudan sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='al' WHERE dxcc='7'"); // Albania sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gi' WHERE dxcc='233'"); // Gibraltar sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='gb' WHERE dxcc='283'"); // UK Base Aereas Cyprus sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sh' WHERE dxcc='250'"); // St Helena sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sh' WHERE dxcc='205'"); // Ascension is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='sh' WHERE dxcc='274'"); // Tristan da Cunha & Gough is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='ky' WHERE dxcc='69'"); // Cayman Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='tk' WHERE dxcc='270'"); // Tokelau Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nz' WHERE dxcc='170'"); // New Zeland sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nz' WHERE dxcc='34'"); // Chatham Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nz' WHERE dxcc='133'"); // Kermadec is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='nz' WHERE dxcc='16'"); // Auckland & Campbell is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='py' WHERE dxcc='132'"); // Paraguay sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='za' WHERE dxcc='462'"); // South Africa sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='za' WHERE dxcc='201'"); // Pr Edward & Marion Is sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} // Countries without flag or controversial - Data is added just to keep the DB filled-up sq = QString ("UPDATE entity SET isoname='un' WHERE dxcc='506'"); // Scarboroug Reef sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} sq = QString ("UPDATE entity SET isoname='un' WHERE dxcc='13'"); // Antartica sqlOK = execQuery(Q_FUNC_INFO, sq); if (!sqlOK) {return false;} //qDebug() << "DataBase::updateTheEntityTableISONames-END" << endl; return true; } bool DataBase::hasTheTableData(const QString _tableName) { //qDebug() << "DataBase::hasTheTableData" << _tableName << endl; QSqlQuery query; int _num = 0; QString stringQuery = QString("SELECT count(id) FROM %1").arg(_tableName); bool sqlOK = query.exec(stringQuery); if (sqlOK) { query.next(); if (query.isValid()) { //qDebug() << "DataBase::hasTheTableData - valid" << endl; _num = (query.value(0)).toInt(); query.finish(); if (_num > 0) { //qDebug() << "DataBase::hasTheTableData - DB Exists" << endl; return true; } else { //qDebug() << "DataBase::hasTheTableData - DB does not Exist" << endl; return false; } } else { //qDebug() << "DataBase::hasTheTableData - not valid" << endl; query.finish(); return false; } } else { //qDebug() << "DataBase::hasTheTableData: LastQuery: " << query.lastQuery() << endl; //qDebug() << "DataBase::hasTheTableData: LastError-data: " << query.lastError().databaseText() << endl; //qDebug() << "DataBase::hasTheTableData: LastError-driver: " << query.lastError().driverText() << endl; //qDebug() << "DataBase::hasTheTableData LastError-n: " << QString::number(query.lastError().number() ) << endl; //qDebug() << "DataBase::updateTheEntityTableISONames" << endl; queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } //qDebug() << "DataBase::isTheDBCreated: END FALSE" << endl; query.finish(); return false; } bool DataBase::updateTo011() {// Updates the DB to 0.011: // We add FT8 mode and // AS Propagation //qDebug() << "DataBase::updateTo011: latestRead: " << QString::number(latestReaded) << endl; bool IAmIn011 = false; bool IAmIn010 = false; bool ErrorUpdating = false; QString stringQuery = QString(); //QSqlQuery query; //bool sqlOk = false; //qDebug() << "DataBase::updateTo011: Checking (latestRead/dbVersion):" << QString::number(latestReaded) << "/" << QString::number(dbVersion) << endl; if (latestReaded >= float(0.012)) { //qDebug() << "DataBase::updateTo011: - I am in 011" << endl; IAmIn011 = true; return true; } else { //qDebug() << "DataBase::updateTo011: - I am not in 0.012 I am in: " << QString::number(latestReaded)<< endl; while (!IAmIn010 && !ErrorUpdating) { //qDebug() << "DataBase::updateTo011: - Check if I am in 010: !" << endl; IAmIn010 = updateTo010(); if (IAmIn010) { //qDebug() << "DataBase::updateTo011: - updateTo010 returned TRUE - I am in 0.010: " << QString::number(latestReaded) << endl; } else { //qDebug() << "DataBase::updateTo011: - updateTo009 returned FALSE - I am NOT in 0.010: " << QString::number(latestReaded) << endl; ErrorUpdating = false; } } if (ErrorUpdating) { //qDebug() << "DataBase::updateTo011: - I Could not update to: " << QString::number(dbVersion) << endl; return false; } } if (!recreateSatelliteData()) { //qDebug() << "DataBase::updateTo011: - Sats update NOK " << endl; return false; } if (!recreateTableDXCC()) { return false; } if (!recreateTableWAZ()) { return false; } if(!execQuery(Q_FUNC_INFO, "INSERT INTO mode (submode, name, cabrillo, deprecated) VALUES ('MSK144', 'MSK144', 'NO', '0')")) { //qDebug() << "DataBase::updateTo011: - MSK NOK " << endl; return false; } if (!recreateTableLog()) { //qDebug() << "DataBase::updateTo011: - Failed to recreate Table Log " << endl; return false; } if (updateDBVersion()) { //qDebug() << "DataBase::updateTo011: - We are in 011! " << endl; IAmIn011 = true; } else { //qDebug() << "DataBase::updateTo011: - Failed to go to 011! " << endl; IAmIn011 = false; } //qDebug() << "DataBase::updateTo011: - END" << endl; updateAwardDXCCTable(); updateAwardWAZTable(); return IAmIn011; } bool DataBase::updateAwardDXCCTable() { //qDebug() << "DataBase::updateAwardDXCCTable" << endl; QList dxccStatusList; //QList dxccStatusListCheck; dxccStatusList.clear(); //dxccStatusListCheck.clear(); AwarddxccEntry awardEntry; awardEntry.dxcc = QString(); awardEntry.band = QString(); awardEntry.status = QString(); awardEntry.logNumber = QString(); awardEntry.qsoID = QString(); //AwarddxccEntryCheck awardEntryCheck; //awardEntryCheck.dxcc = QString(); //awardEntryCheck.band = QString(); //awardEntryCheck.status = QString(); QString stringQuery = QString("SELECT id, bandid, modeid, dxcc, qsl_rcvd, lognumber FROM log ORDER BY dxcc"); QSqlQuery query;//, query2; bool sqlOK = query.exec(stringQuery); QSqlRecord rec = query.record(); if (!sqlOK) { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } else { //qDebug() << "DataBase::updateAwardDXCCTable SELECT when OK" << endl; } QStringList dxccStatus = QStringList(); //dxcc, band, mode, confirmed, lognumber, qsoid (per award set) QStringList dxccStatusCheck = QStringList(); //dxcc, band, mode, confirmed, lognumber (per award set) just to check int nameCol = -1; QString _aux = QString(); //qDebug() << "DataBase::updateAwardDXCCTable before the while" << endl; while (query.next()) { //qDebug() << "DataBase::updateAwardDXCCTable IN the while" << endl; if (query.isValid()) { //qDebug() << "DataBase::updateAwardDXCCTable VALID" << endl; awardEntry.dxcc.clear(); awardEntry.band.clear(); awardEntry.status.clear(); awardEntry.logNumber.clear(); awardEntry.qsoID.clear(); //qDebug() << "DataBase::updateAwardDXCCTable in the while" << endl; nameCol = rec.indexOf("qsl_rcvd"); if ((query.value(nameCol)).toString() == "Y") { awardEntry.status = "1"; } else { awardEntry.status = "0"; } //qDebug() << "DataBase::updateAwardDXCCTable - status" << awardEntry.status << endl; if ((awardEntry.status == "1") || (awardEntry.status == "0") ) { nameCol = rec.indexOf("dxcc"); awardEntry.dxcc = (query.value(nameCol)).toString(); if ((awardEntry.dxcc).toInt()>0) { nameCol = rec.indexOf("bandid"); awardEntry.band = (query.value(nameCol)).toString(); nameCol = rec.indexOf("modeid"); awardEntry.mode = (query.value(nameCol)).toString(); nameCol = rec.indexOf("id"); awardEntry.qsoID = (query.value(nameCol)).toString(); nameCol = rec.indexOf("lognumber"); awardEntry.logNumber = (query.value(nameCol)).toString(); //qDebug() << "DataBase::updateAwardDXCCTable: Adding: " << awardEntry.dxcc <<"/" << awardEntry.band <<"/" << awardEntry.mode <<"/" << awardEntry.status <<"/" << awardEntry.logNumber <<"/" << awardEntry.qsoID << endl; dxccStatusList.append(awardEntry); } } // END OF IF VALID } } // END OF WHILE //qDebug() << "DataBase::updateAwardDXCCTable - END OF WHILE" << endl; query.finish(); //qDebug() << "DataBase::updateAwardDXCCTable: Log analized... let's clean the table!" << endl; stringQuery = QString("DELETE FROM awarddxcc"); sqlOK = execQuery(Q_FUNC_INFO, stringQuery); if (!sqlOK) {return false;} else { //qDebug() << "DataBase::updateAwardDXCCTable: awarddxcc table DELETED" << endl; } //qDebug() << "DataBase::updateAwardDXCCTable: Now we start writing the table!!" << endl; //int i = 0; _aux.clear(); int qsos = dxccStatusList.length(); int step = util->getProgresStepForDialog(qsos); QProgressDialog progress(QObject::tr("Updating DXCC award information..."), QObject::tr("Abort updating"), 0, qsos); progress.setMaximum(qsos); progress.setWindowModality(Qt::WindowModal); //qDebug() << "DataBase::updateAwardDXCCTable: INSERTING: " << QString::number(qsos) << " QSOS..." << endl; for (int j=0;j dxccStatusList; //QList dxccStatusListCheck; dxccStatusList.clear(); //dxccStatusListCheck.clear(); AwarddxccEntry awardEntry; awardEntry.dxcc = QString(); awardEntry.band = QString(); awardEntry.status = QString(); awardEntry.logNumber = QString(); awardEntry.qsoID = QString(); QString stringQuery = QString("SELECT id, bandid, modeid, cqz, qsl_rcvd, lognumber FROM log ORDER BY cqz"); QSqlQuery query;//, query2; bool sqlOK = query.exec(stringQuery); QSqlRecord rec = query.record(); if (!sqlOK) { queryErrorManagement(Q_FUNC_INFO, query.lastError().databaseText(), query.lastError().number(), query.lastQuery()); query.finish(); return false; } else { //qDebug() << "DataBase::updateAwardWAZTable SELECT when OK" << endl; } QStringList dxccStatus = QStringList(); //cqz, band, mode, confirmed, lognumber, qsoid (per award set) QStringList dxccStatusCheck = QStringList(); //cqz, band, mode, confirmed, lognumber (per award set) just to check int nameCol = -1; QString _aux = QString(); //qDebug() << "DataBase::updateAwardWAZTable before the while" << endl; while (query.next()) { //qDebug() << "DataBase::updateAwardWAZTable IN the while" << endl; if (query.isValid()) { //qDebug() << "DataBase::updateAwardWAZTable VALID" << endl; awardEntry.dxcc.clear(); awardEntry.band.clear(); awardEntry.status.clear(); awardEntry.logNumber.clear(); awardEntry.qsoID.clear(); //qDebug() << "DataBase::updateAwardWAZTable in the while" << endl; nameCol = rec.indexOf("qsl_rcvd"); if ((query.value(nameCol)).toString() == "Y") { awardEntry.status = "1"; } else { awardEntry.status = "0"; } //qDebug() << "DataBase::updateAwardWAZTable - status" << awardEntry.status << endl; if ((awardEntry.status == "1") || (awardEntry.status == "0") ) { nameCol = rec.indexOf("cqz"); awardEntry.dxcc = (query.value(nameCol)).toString(); if ((awardEntry.dxcc).toInt()>0) { nameCol = rec.indexOf("bandid"); awardEntry.band = (query.value(nameCol)).toString(); nameCol = rec.indexOf("modeid"); awardEntry.mode = (query.value(nameCol)).toString(); nameCol = rec.indexOf("id"); awardEntry.qsoID = (query.value(nameCol)).toString(); nameCol = rec.indexOf("lognumber"); awardEntry.logNumber = (query.value(nameCol)).toString(); //qDebug() << "DataBase::updateAwardWAZTable: Adding: " << awardEntry.dxcc <<"/" << awardEntry.band <<"/" << awardEntry.mode <<"/" << awardEntry.status <<"/" << awardEntry.logNumber <<"/" << awardEntry.qsoID << endl; dxccStatusList.append(awardEntry); } } // END OF IF VALID } } // END OF WHILE //qDebug() << "DataBase::updateAwardWAZTable - END OF WHILE" << endl; query.finish(); //qDebug() << "DataBase::updateAwardWAZTable: Log analized... let's clean the table!" << endl; stringQuery = QString("DELETE FROM awardwaz"); sqlOK = execQuery(Q_FUNC_INFO, stringQuery); if (!sqlOK) {return false;} else { //qDebug() << "DataBase::updateAwardWAZTable: awardwaz table DELETED" << endl; } //qDebug() << "DataBase::updateAwardWAZTable: Now we start writing the table!!" << endl; //int i = 0; _aux.clear(); int qsos = dxccStatusList.length(); int step = util->getProgresStepForDialog(qsos); QProgressDialog progress(QObject::tr("Updating WAZ award information..."), QObject::tr("Abort updating"), 0, qsos); progress.setMaximum(qsos); progress.setWindowModality(Qt::WindowModal); //qDebug() << "DataBase::updateAwardWAZTable: INSERTING: " << QString::number(qsos) << " QSOS..." << endl; for (int j=0;j. * * * *****************************************************************************/ #include #include #include #include #include #include //#include //#include //#include #include //#include #include "utilities.h" #include "softwareupdatedialog.h" class QSslError; class SoftwareUpdate: public QObject { Q_OBJECT public: SoftwareUpdate(const QString _klogVersion); ~SoftwareUpdate(); void addCall(const QString _call); void needToUpdate(bool _showWithoutVersion=false); void setVersion(const QString _klogVersion); private slots: void slotReadyRead(); void slotError(int _p); //void slotSslErrors(QList _p); //void replyFinished(QNetworkReply *data); void slotDownloadFinished(QNetworkReply *reply); signals: void updateNeededSignal(const bool _q); // Will be TRUE if updated if needed and FALSE if we already have the latest version private: void connectToURL(); bool checkUpdates(QIODevice *data); void updateNeeded(QString _newVer); void setTheURL(QString _url); void setHeader(); Utilities *util; QString klogVersion, latestVersion, callsign; QString urld; QUrl *url; QNetworkAccessManager *manager; QNetworkRequest request; SoftwareUpdateDialog *updateDialog; //int result; //bool toUpdate; bool repositoryFound; // True when the versions have been checked to prevent multiple qmessagebox due to redirections bool messageShown; }; #endif // SOFTWAREUPDATE_H klog-0.9.2.9/setuppagedxcluster.h0000644000076700000620000000741313233376355014716 0ustar staff#ifndef SETUPPAGEDXCLUSTER_H #define SETUPPAGEDXCLUSTER_H /*************************************************************************** setuppagedxcluster.h - description ------------------- begin : nov 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ //#include //#include //#include //#include #include class SetupPageDxCluster : public QWidget { Q_OBJECT public: SetupPageDxCluster(QWidget *parent=0); ~SetupPageDxCluster(); QStringList getDxclusterServersComboBox(); void setDxclusterServersComboBox(const QStringList t); QString getSelectedDxClusterServer(); void setSelectedDxClusterServer(const QString t); QString getShowHFRadiobutton(); QString getShowVHFRadiobutton(); QString getShowWARCRadiobutton(); QString getShowWorkedRadiobutton(); QString getShowConfirmedRadiobutton(); QString getShowANNRadiobutton(); QString getShowWWVRadiobutton(); QString getShowWCYRadiobutton(); void setShowHFRadiobutton(const QString t); void setShowVHFRadiobutton(const QString t); void setShowWARCRadiobutton(const QString t); void setShowWorkedRadiobutton(const QString t); void setShowConfirmedRadiobutton(const QString t); void setShowANNRadiobutton(const QString t); void setShowWWVRadiobutton(const QString t); void setShowWCYRadiobutton(const QString t); private slots: void slotAddButtonClicked(); void slotDeleteButtonClicked(); private: void createActions(); bool checkIfValidDXCluster (const QString &tdxcluster); bool checkIfNewDXCluster (const QString &tdxcluster); QComboBox *dxclusterServersComboBox; QPushButton *addClusterButton; QPushButton *deleteClusterButton; QRadioButton *showHFRadiobutton; QRadioButton *showVHFRadiobutton; QRadioButton *showWARCRadiobutton; QRadioButton *showWorkedRadiobutton; QRadioButton *showConfirmedRadiobutton; QRadioButton *showANNRadiobutton; QRadioButton *showWWVRadiobutton; QRadioButton *showWCYRadiobutton; QRadioButton *saveAllDXClusterDataRadiobutton; //QStringList dxClusterServers; }; #endif // SETUPPAGEDXCLUSTER_H klog-0.9.2.9/downloadcty.cpp0000644000076700000620000001333013233376355013640 0ustar staff#include "downloadcty.h" #include #include #include #include //#include DownLoadCTY::DownLoadCTY(const QString _klogDir, const QString _klogVersion) : QObject(0) { //qDebug() << "DownLoadCTY::DownLoadCTY(): " << _klogDir << endl; util = new Utilities; url = new QUrl; klogDir = _klogDir; result = -1; // Error unknown manager = new QNetworkAccessManager; request = new QNetworkRequest; //request->setUrl(QUrl("http://www.country-files.com/cty/cty.csv")); request->setUrl(QUrl("http://www.country-files.com/bigcty/cty.csv")); QString ver = "KLog"+_klogVersion; QByteArray str; str.clear(); str.append(util->getAgent(_klogVersion)); //str.append(_klogVersion); //request.setUrl(QUrl("http://qt.nokia.com")); request->setRawHeader("User-Agent", str); //request->setHeader(QNetworkRequest::UserAgentHeader, str); //qDebug() << "DownLoadCTY::DownLoadCTY() - UserAgent: " << request->rawHeader("QNetworkRequest::UserAgentHeader") << endl; QObject::connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(slotDownloadFinished(QNetworkReply*))); //qDebug() << "DownLoadCTY::DownLoadCTY(): - END" << endl; } DownLoadCTY::~DownLoadCTY() { //qDebug() << "DownLoadCTY::~DownLoadCTY" << endl; } void DownLoadCTY::slotDownloadFinished(QNetworkReply *reply) { //qDebug() << "DownLoadCTY::slotDownloadFinished" << endl; QUrl url = reply->url(); //qDebug() << "DownLoadCTY::slotDownloadFinished - URL: " << url.toString() << endl; QMessageBox msgBox; QString aux; aux.clear(); if (reply->error()) { //fprintf(stderr, "Download of %s failed: %s\n", // url.toEncoded().constData(), // qPrintable(reply->errorString())); //errorCode = query.lastError().number(); msgBox.setIcon(QMessageBox::Warning); aux = tr("Download of cty.csv failed with the following error code: "); msgBox.setText(aux + reply->errorString()); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); } else { QString filename = saveFileName(url); if (saveToDisk(filename, reply)) { msgBox.setIcon(QMessageBox::Information); aux = tr("Download of cty.csv done."); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); emit actionReturnDownload(QNetworkReply::NoError); } //printf("Download of %s succeeded (saved to %s)\n", // url.toEncoded().constData(), qPrintable(filename)); } reply->deleteLater(); emit done(); } int DownLoadCTY::download() { //qDebug() << "DownLoadCTY::download..." << endl; manager->get(*request); return 1; } void DownLoadCTY::slotDownloadProgress(qint64 received, qint64 total) { //qDebug() << "DownLoadCTY::slotDownloadProgress: " << endl; //qDebug() << "DownLoadCTY::downloadProgress: " << QString::number(received) << "/" << QString::number(total) << endl; //qDebug() << received << total; emit actionShowProgres(received, total); } void DownLoadCTY::slotErrorManagement(QNetworkReply::NetworkError networkError) { //qDebug() << "DownLoadCTY::slotErrorManagement: " << QString::number(networkError) << endl; result = networkError; if (result == QNetworkReply::NoError) { //qDebug() << "DownLoadCTY::downloadFinished: No error" << endl; } else if (result == QNetworkReply::HostNotFoundError) { //qDebug() << "DownLoadCTY::downloadFinished: Host not found" << endl; } else { //qDebug() << "DownLoadCTY::downloadFinished: ERROR: " << QString::number(result) << endl; } actionError(result); } QString DownLoadCTY::saveFileName(const QUrl &url) { //qDebug() << "DownLoadCTY::saveFileName" << endl; QString path = url.path(); QString basename = QFileInfo(path).fileName(); QMessageBox msgBox; QString aux; aux.clear(); if (basename.isEmpty()) basename = "download"; if (QFile::exists(basename)) { msgBox.setIcon(QMessageBox::Warning); aux = tr("There is already a cty.csv file in the folder but it will be replaced with the new one."); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); // already exists, don't overwrite //int i = 0; //basename += '.'; //while (QFile::exists(basename + QString::number(i))) // ++i; //basename += QString::number(i); } return basename; } bool DownLoadCTY::saveToDisk(const QString &filename, QIODevice *data) { //qDebug() << "DownLoadCTY::saveToDisk: " << filename << endl; QFile file(filename); QMessageBox msgBox; QString aux; aux.clear(); if (!file.open(QIODevice::WriteOnly)) { msgBox.setIcon(QMessageBox::Warning); aux = tr("Could not open ") + filename + tr(" for writing."); msgBox.setText(aux); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); //fprintf(stderr, "Could not open %s for writing: %s\n", // qPrintable(filename), // qPrintable(file.errorString())); return false; } file.write(data->readAll()); file.close(); return true; } klog-0.9.2.9/dxcluster.h0000644000076700000620000001127113233376355012775 0ustar staff#ifndef DXCLUSTER_H #define DXCLUSTER_H /*************************************************************************** dxcluster.h - description ------------------- begin : oct 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include //#include #include #include #include #include "awards.h" #include "world.h" #include "dataproxy.h" class QWidget; class QTcpSocket; class DXClusterWidget : public QWidget { Q_OBJECT public: DXClusterWidget(DataProxy *dp, QWidget *parent ); DXClusterWidget(DataProxy *dp, const QString &clusterToConnect, const int portToConnect, QWidget *parent ); void setColors (const QString _newOne, const QString _needed, const QString _worked, const QString _confirmed, const QString _default); void setDXClusterSpotConfig(bool _showhf, bool _showvhf, bool _showwarc, bool _showworked, bool _showconfirmed, bool _showann, bool _showwwv, bool _showwcy ); void setDXClusterServer(const QString &clusterToConnect, const int portToConnect); void setCurrentLog(const int _log); bool isConnected(); void setMyQRZ(const QString _qrz); //void sendSpotToCluster(const QString _dx, const QString _freq); ~DXClusterWidget(); private slots: void slotClusterDisplayError(QAbstractSocket::SocketError socketError); void slotClusterDataArrived(); void slotClusterSocketConnected(); void slotClusterSocketConnectionClosed(); void slotClusterSendToServer(); void slotClusterClearLineInput(); void slotClusterInputTextChanged(); void slotClusterDXClusterWidgetItemDoubleClicked( QListWidgetItem * item ); void slotClusterDXClusterWidgetItemEntered( QListWidgetItem * item); void slotClusterDXClusterWidgetItemSelected(); signals: void dxspotclicked(const QStringList _qs); // DXSpotCall, DX-Freq, doubleClicked private: //void TESTADDSPOT(); // Just a test spot void initClass(); void connectToDXCluster(); QStringList readItem(QListWidgetItem * item); bool checkIfNeedsToBePrinted(const QString _DXEntity, const int _band, const int _mode); void addData(); //TO BE DELETED, JUST FOR TESTING PURPOSES QTcpSocket *tcpSocket; QListWidget *dxClusterListWidget; QLineEdit *inputCommand; QPushButton *sendButton; QPushButton *clearButton; bool dxClusterConnected; bool dxClusterAlreadyConnected; QString server; quint16 port; quint16 blockSize; QColor dxSpotColor; World *world; Awards *awards; DataProxy *dataProxy; bool showhf, showvhf, showwarc, showworked, showconfirmed, showann, showwwv, showwcy; bool dxClusterShowHF, dxClusterShowVHF, dxClusterShowWARC, dxClusterShowWorked, dxClusterShowConfirmed, dxClusterShowAnn, dxClusterShowWWV, dxClusterShowWCY; QString myQrz; int currentLog; int constrid; // Just an id for the constructor to check who is being executed at one specific time }; class dxClusterSpotItem : public QListWidgetItem { public: dxClusterSpotItem( QListWidget* parent, const QString& spot, const QColor& color ); ~dxClusterSpotItem(); protected: QColor spotColor; }; #endif // DXCLUSTER_H klog-0.9.2.9/tips-for-devel.txt0000644000076700000620000000046513233376355014213 0ustar staffSQLite http://www.w3schools.com/sql/default.asp Transfer or populate sqlite table to another table INSERT INTO TABLE2 (COL1, COL2, COL3) SELECT COL1, COL4, COL7 FROM TABLE1 Select only different DXCC select count (distinct dxcc) from log DELETED ENTITIES: http://www.ng3k.com/Dxcc/dxccde.html klog-0.9.2.9/NEWS0000644000076700000620000000005413233376355011303 0ustar staffLook at http://www.klog.xyz for NEWS of KLogklog-0.9.2.9/logmodel.cpp0000644000076700000620000000667013233376355013124 0ustar staff#include "logmodel.h" LogModel::LogModel(DataProxy *dp, QObject *parent):QSqlRelationalTableModel(parent) { //qDebug() << "LogModel::LogModel " << endl; //logModel = new QSqlRelationalTableModel(this); dataProxy = dp; setTable("log"); setEditStrategy(QSqlTableModel::OnFieldChange); //qDebug() << "LogModel::LogModel - END" << endl; } void LogModel::createlogModel(const int _i) { /* Log_Id = 0, Log_Name = 1, Log_BandId = 2, Log_ModeId = 3, Log_DateId = 4, Log_TimeId = 5 setRelation ( int column, const QSqlRelation & relation ) model->setTable("employee"); model->setRelation(2, QSqlRelation("city", "id", "name")); The setRelation() call specifies that column 2 in table employee is a foreign key that maps with field id of table city, and that the view should present the city's name field to the user. */ /* This should be coherent with the logview */ //qDebug() << "LogModel::createlogModel: log: " << QString::number(_i) << endl; QString contestMode = dataProxy->getLogTypeOfUserLog(_i); //qDebug() << "LogModel::createlogModel - contestMode: " << contestMode << endl; QString stringQuery = QString("lognumber='%1'").arg(_i); QSqlQuery query(stringQuery); setFilter(stringQuery); //if (contestMode.compare("DX")) if (contestMode == "DX") { //qDebug() << "LogModel::createlogModel: found type DX" << endl; setColumnsToDX(); } else if (contestMode == "CQ-WW-SSB") { //qDebug() << "LogModel::createlogModel: found type CQ-WW-SSB" << endl; } else { // THIS POINT SHOULD NOT BE REACHED. It means that there is a kind of contest not supported. // Maybe the way should be to move ALL the actions from DX here. //qDebug() << "LogModel::createlogModel: log type NOT found" << endl; } select(); } void LogModel::setColumnsToDX() { //qDebug() << "LogModel::setColumnsToDX" << endl; QSqlQuery q; QString stringQuery = QString("SELECT * from log LIMIT 1"); QSqlRecord rec; // = q.record(); int nameCol; bool sqlOK = q.exec(stringQuery); if (!sqlOK) { emit queryError(Q_FUNC_INFO, q.lastError().databaseText(), q.lastError().number(), q.lastQuery()); } q.next(); rec = q.record(); // Number of columns //qDebug() << "LogModel::createlogModel - columns: " << QString::number(rec.count()) << endl; nameCol = rec.indexOf("bandid"); setRelation(nameCol, QSqlRelation("band", "id", "name")); nameCol = rec.indexOf("modeid"); setRelation(nameCol, QSqlRelation("mode", "id", "submode")); nameCol = rec.indexOf("id"); setSort(nameCol, Qt::AscendingOrder); nameCol = rec.indexOf("qso_date"); setHeaderData(nameCol, Qt::Horizontal, tr("Date")); nameCol = rec.indexOf("time_on"); setHeaderData(nameCol, Qt::Horizontal, tr("Time")); nameCol = rec.indexOf("call"); setHeaderData(nameCol, Qt::Horizontal,tr("QRZ")); nameCol = rec.indexOf("bandid"); setHeaderData(nameCol, Qt::Horizontal, tr("Band")); nameCol = rec.indexOf("modeid"); setHeaderData(nameCol, Qt::Horizontal, tr("Mode")); nameCol = rec.indexOf("rst_sent"); setHeaderData(nameCol, Qt::Horizontal, tr("RSTtx")); nameCol = rec.indexOf("rst_rcvd"); setHeaderData(nameCol, Qt::Horizontal, tr("RSTrx")); nameCol = rec.indexOf("comment"); setHeaderData(nameCol, Qt::Horizontal, tr("Comment")); } klog-0.9.2.9/filemanager.h0000644000076700000620000001226113233376355013232 0ustar staff#ifndef FILEMANAGER_H #define FILEMANAGER_H /*************************************************************************** filemanager.h - description ------------------- begin : sept 2011 copyright : (C) 2011 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include //#include #include #include #include #include #include #include #include #include #include #include "world.h" #include "awards.h" #include "database.h" #include "dataproxy.h" #include "dataproxy_sqlite.h" #include "utilities.h" enum { CQZones = 40, ITUZones = 90, DXCCEntities = 521 // http://www.adif.org/adif302.htm#Country%20Codes }; class FileManager : public QWidget { Q_OBJECT public: FileManager(DataProxy *dp); //FileManager(DataProxy *dp, const QString _klogDir); FileManager(DataProxy *dp, const QString _klogDir, const QString _softVersion); //FileManager(DataProxy *dp, const QString _softVersion); ~FileManager(); //bool readAdif(const QString& tfileName, const int logN); bool adifReadLog(const QString& tfileName, const int logN); bool adifLoTWReadLog(const QString& tfileName); int adifLoTWLogExport(const QString& _fileName, const int _logN); bool adifLogExport(const QString& _fileName, const int _logN); bool adifLogExportMarked(const QString& _fileName); bool adifReqQSLExport(const QString& _fileName); bool cabrilloLogExport(const QString& _fileName, const QString _contestType, const int logNconst); bool modifySetupFile(const QString& _filename, QString _field, const QString _value); void setVersion(const QString _version); private: bool adifLogExportToFile(const QString& _fileName, const int _logN=0, bool justMarked = false, bool _qslRequested = false, bool _lotw=false); bool cabrilloLogExportToFile(const QString& _fileName, const int logNconst); bool cabrilloLogExportCQWWToFile(const QString& _fileName, const int logNconst); //bool adifCheckMoreThanOneLog(QFile &_f); int howManyLogsInFile(QFile & _f); bool fillHashLog(QFile & _f); QStringList getListOfLogsInFile(QFile & _f); //QString checkAndFixASCIIinADIF(const QString _data); bool processQsoReadingADIF(const QStringList _line, const int logNumber, const bool _keepLogsInFile); void queryPreparation(const int _logN); bool checkADIFValidFormat(const QStringList _qs); QStringList readAdifField (const QString _field); QString prepareStringLog(); bool dbCreated; DataBase *db; //float softwareVersion; //DataProxy_SQLite *dataProxy; DataProxy *dataProxy;//, *dataProxyPrepared; Utilities *util; bool rstTXDefault, rstRXDefault; // If true and a log is not including RST, 59 is automatically added //bool printQs(const QString _q, const QStringList _line); bool printQs(const QStringList _line); //int confirmed; QString klogDir; QString klogVersion; //QProgressBar *progressBar; bool ignoreUnknownAlways; // When importing ADIF, ignore all unknown fields. bool noMoreQso; World *world; Awards *awards; //QSqlDatabase db; QHash hashLogs; // to create different logs when importing a ADIF file QSqlQuery preparedQuery; int constrid; // Just an id for the constructor to check who is being executed at one specific time signals: void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution }; #endif // FILEMANAGER_H klog-0.9.2.9/setuppagelogsnew.h0000644000076700000620000001152213233376355014353 0ustar staff#ifndef SETUPPAGELOGSNEW_H #define SETUPPAGELOGSNEW_H /*************************************************************************** setuppagelogsnew.h - description ------------------- begin : feb 2015 copyright : (C) 2015 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implements the Dialog to add a new log // #include "dataproxy.h" #include #include #include //TODO: Read the data when the user clicks the OK button //TODO: Fill the data from the list of logs when the user wants to edit a log class SetupPageLogsNew : public QDialog { Q_OBJECT public: //SetupPageLogsNew(QWidget *parent = 0); SetupPageLogsNew(DataProxy *dp, QWidget *parent = 0); void setEditing(const bool b); void setStationCallSign(const QString _st); void setOperators(const QString _st); void setComment(const QString _st); void setDateString(const QString _st); void setTypeN(const int _n); void setType(const QString _st); void setCMode(const int _n); void setCOperators(const int _n); void setCAssisted(const int _n); void setCPower(const int _n); void setCBands(const int _n); void setBands(const int _n); void setCOverlay(const int _n); private slots: void slotOKButtonClicked(); void slotCancelButtonClicked(); void slotStationCallSignTextChanged(); void slotTypeComboBoxChanged(); void slotCatAssistedComboBoxChanged(); void slotCatOperatorsComboBoxChanged(); void slotOperatorsTextChanged(); void slotCatPowerComboBoxChanged(); void slotCatBandsComboBoxChanged(); void slotBandsComboBoxChanged(); void slotCatModeComboBoxChanged(); void slotCatOverlayComboBoxChanged(); signals: void newLogData(const QStringList _qs); // void cancelled(const bool _c); // Cancel button is clicked private: //bool isThereAnyNotManagedLog(); void createWidget(); void gatherAndSend(); QStringList getValidCatOptions(const int _currentCat, const int _higherCat); int getSelectedTypeContest(); void fillWithType(const int _n); void updateAllCats(); void showOK(); void showNOK(); void clear(); DataProxy *dataProxy; QDateEdit *dateEdit; QLineEdit *stationCallsignLineEdit; QLineEdit *operatorsLineEdit, *commentLineEdit; QComboBox *typeComboBox; QComboBox *contestCatModeComboBox; QComboBox *contestCatOperatorsComboBox; QComboBox *contestCatAssistedComboBox; QComboBox *contestCatPowerComboBox; QComboBox *contestCatBandsComboBox; QComboBox *contestBandsComboBox; QComboBox *contestCatOverlayComboBox; QString stationCallsign, operators, comment, dateString, typeConteststr; int typeContest, typeContestSelected, contestCatMode, contestCatOperators, contestCatAssisted, contestCatPower, contestCatBands, contestBands, contestCatOverlay; bool stationCallsignFilled, operatorsFilled; int typeOperation; // DX, CQ-WW-SSB, CQ-WW-CW, CQ-WPX-SSB, CQ-WPX-CW QPushButton *okButton, *cancelButton; QStringList logData; bool editing; QLabel *catAsLabel, *catOpLabel, *catModeLabel, *catPowerLabel, *catBandsLabel, *overlayLabel; QLabel *typeLabel, *validCats, *stationCallsignLabel, *operatorsLabel, *commentLabel, *dateLabel; //nameLabel->setBuddy(); bool checking, bCass, bCOp, bCMo, bCPo, bCBa, bCOv, bCTy; }; #endif // SETUPPAGELOGSNEW_H klog-0.9.2.9/flags/0000755000076700000620000000000013237612476011702 5ustar staffklog-0.9.2.9/flags/am.png0000644000076700000620000000076113233376355013010 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbׯ0?1@1QW)'veýL02 OW001$T~joF ? t &B5&a2~: XDf51yۿ*_2HW7lWAouMp~ 8<Ý q 9^?(T_?o?/?[ŜH@9jp=X'2000#F F ?>0^o ~1 01 ?Hq ͦWIENDB`klog-0.9.2.9/flags/sj.png0000644000076700000620000000100013233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|rsE]D3?`A @,@Qj )FFF0~ "߿n@,`{H|σ@ ׿_,+  U@_ @=@$@W߿@g@c@e>#sdv@m@$ H 9 @ɂgqq&&=ffܬ? l줷v~|o7~aQVz@d@ g'D/ H'?f ?$A.,_P3@WaQމ̮ 1$`$ZlIENDB`klog-0.9.2.9/flags/dm.png0000644000076700000620000000115413233376355013010 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdd@ @(fU?WD~1@_ T $2 Z\9+ ϟVX@,~{_PC̕_)=͍$@=@L 0×v?QVS~y?~1BI/\Α@X}q ש1|{v d+1\ N ߿@=t/2Kd?)Ծ({bdf(.~¢H9οvnt!n&@()j?@Lr~r1%fz~4D5P @,@[SD@Zcπ3/vPH5#C.JDB/>}*" $M,8̃IENDB`klog-0.9.2.9/flags/ir.png0000644000076700000620000000100013233376355013010 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd 10da / ծ @￿ϟ?o X|}_?߿Hc`b1Z     **V߿@' >}@LB e߼тObBW 11>D5s-;;3g~?A޴ X@j{(/nOk_@L@V?T߿L@?9鿺:0#ÿ_ b ?9kj̓&q?5+ח/ A@j7;9ߴ?'7 `o5 q4^(8?[gN &PPuMb<d<6?+|XQ_?9c?/P1@?L cYTYP˫W,rr  P1@1>d`Ȍ?q`=歆bIENDB`klog-0.9.2.9/flags/wales.png0000644000076700000620000000121413233376355013520 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|9 `ɟ00bJKv~?"D٤.UMVA!i.Ii{H#˽;~Ywߘ߼_uD?? )Y_up~}7?y~TX#/_b: @.Zr]~rʷb}⟓ ӂ,C|6Qq1 wu  wo$*1 FzP  'bo) "1E%P$>ZRw1. [HS1$%x-ٟ= K^xP_! L20hzIENDB`klog-0.9.2.9/flags/kh.png0000644000076700000620000000104513233376355013011 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbda` dC` _ }j@@d_aG _^**?D/ 7H5PWZ @ ZO6 wn3~lA2 tDud]-+/7)P/b_32 gp{x2pp2ppga X6a93' H>OO&&6V` `  1Fv rK0}^@#²Oua`/8X@nz^A{Utߧ"`9P<(LAa/>ڰyЈDC1 AL43UIENDB`klog-0.9.2.9/flags/bm.png0000644000076700000620000000114313233376355013004 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<^IzzK,L /eeDI}X:?0F@13kX:ɧƲeοu ׵8c,0Z]_/߿deV4U-7}(Ω([~]ʕ χ))@W3_< 31ۓ_?kM'I@ 1try!H kJe[\MMJyů}y_9t/? aT/ O/cֲsqp X@! 8P Q %Y rꟿ@4UR<߿_ ĸ,"X-$@5K]IENDB`klog-0.9.2.9/flags/by.png0000644000076700000620000000100213233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxLA {$mYJ֚a&N 0tg!fKq(|qn@2$EO0|Ȱk| jP H(+ XP Q Rob5ƍ `?9 A?!@  *wRTyPmp@?6׭?i20O F'?H߯_߿Qs mnj)}f $?AOL>2,> X2|TS"'_a @譿@~0/I?x|ڴʔa@0  o7u[TbeIENDB`klog-0.9.2.9/flags/cr.png0000644000076700000620000000073513233376355013020 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<oIDATxbdoe1$ F?Ĺ A>*Wm1z;d*,!{@?gf+`X3 ?|@, 1?Ŀ`/:lkJA @ ؀_!(h\HD ӽdުO=t/PF4\L@)@@J*~# % XD[9} q(s7엿L||2'?YAr J Pz-@120΋: h0= d@qeԐExt¹$@yIENDB`klog-0.9.2.9/flags/td.png0000644000076700000620000000107213233376355013016 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbu/`='KL՟?3  $͇_}EZ ߿Ekپx~q@`$lk[-,3qZqA jCS @ $90BQN:T? ʑ͐-xP8)0aZMWC@ #o&+HNI?,R.Ku?i2ɥC;#iJ yp< @0t 6 @ @ fz~C X~5rPϿ N(H0Xj / QA6?Yف~gb#/9P  7Atpu(nfbG&H :"z[VIENDB`klog-0.9.2.9/flags/hu.png0000644000076700000620000000066013233376355013025 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<BIDATxb<ˀ0B@bp 'VBBء,irN<6'O 2$P)d*+  XfGV  V V @10>}@'AUX#@@123ddw?~ D  UR:[p X~H_~AUH?  t@0b$$0Pf P/H@12X3 g@"m~gIENDB`klog-0.9.2.9/flags/io.png0000644000076700000620000000122213233376355013013 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<$IDATxb^ۻ\g 1la700a`As0@1[GI%$   &C1  >{Ue;UM.w~S_([gIYit ;?1BP" 1 ̷R=<.Ϻ.IÝw4LUg#,\4_ r[fέ F>?\?L[8)~Q*;V)~gzP\b:h2PAD~*{_7ӯN2 @Oog/ά/ QQ--zIr]"@=t{_[_I1#E~26*|ӊbЋ^j<~@s+.aVضd/F%  CoY_Ӧٺ_bE +Yp$+_@?ߧz ¿kI|f9R_"B@" XURSppHJJBι\\/d: aqa r c!@q`u)=IENDB`klog-0.9.2.9/flags/sk.png0000644000076700000620000000106213233376355013023 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb;?8A8 @,@Y&.. &f 2 @@>1ç//P0?`dd@1Bdm^G {}הwl1EBEjk]]vzCƔ?__L?b @t-[=Gi ? lĸA뻽KFr?\{~20 aL@7JJs"YY@ $ A@pĀE\*=MIENDB`klog-0.9.2.9/flags/dk.png0000644000076700000620000000075713233376355013016 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb zAR Q] VxyK}ϟ3I /7m PǀI6c+VP n0ڍ7~aP_ 7a@nWȯ4Guve;z ]x>PwYLB\FFg׮?0ݩ_$?`H-XP÷o{vSujc@2j'6_[7- -+1UIENDB`klog-0.9.2.9/flags/kp.png0000644000076700000620000000106113233376355013017 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb4 ï?@ bc ƃ7(?v @1~d`d_ ,L|? ~IJb|9(Q^_Wٽo߿@oFf /[?k栠ll~?B@ /U0 tN ϟ? r.Э/^޼% ߿{ϟ E?BUm* v-Y–_REMgm7ofx& b` -xx=zP򕁋?+?:p(c?AA`˩ߵY@ sH,cq5@12x @6@ Xg "IENDB`klog-0.9.2.9/flags/mn.png0000644000076700000620000000075413233376355013027 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<~IDATxbπ^20x@+?$U]`?j|?af'@>i@50/_w$E_FYY RA/C_? `AQ`bbTϟP!D !a\L?UgZRj$N PO 6 ?00H?f`j?@ : @fa"觿RL\ #I?L@J "" 3\f`@A‚N[YIENDB`klog-0.9.2.9/flags/tm.png0000644000076700000620000000112113233376355013022 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdd$?|!ѐ~10`? 1|s" u  Rss ?çO~>|u'ϥ7x۷ 1sn=xٽ?;3&ۇ{+ן߿~hobjϿ~_]LSyo  X~/+o_r'RTK({Ƿ@ K8 Xa_8~}/هW~؆?@o5 /ǯ\q/`j50ghn `~q0pi >߽"s)I?  Vl bdEğ 2 w A&IENDB`klog-0.9.2.9/flags/hm.png0000644000076700000620000000124113233376355013011 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<3IDATxb<^|CrǻXV*Dsg101KMy<"[M-ܣ1  =F;! 鐎>_aQY.3߲we~pkt ano!$AXx?*Dz5I%Ѯ&1 gK 1/W j1\?c3Z = 1P|8 H)#%wXO~-o.]{6#Ы}t{o8i ?0(g߿ߟ_{3Kq:/(h 0ԀP9xJ:?^)# ~OB ( >0JR ,"&y G9I٫h_xIENDB`klog-0.9.2.9/flags/th.png0000644000076700000620000000070413233376355013023 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<VIDATxbπPX@ a@oHRWZ"{ <"bd3c>} FG׍9:hAϿBe[e3"}$Ͽ߿ѯ__8)/ ~q'ȑ@z~@D(,߿ h/lfI 7/;8vЌ`6IISϟ8۷o;;SI č2FJmٻ F$8bͪIENDB`klog-0.9.2.9/flags/mz.png0000644000076700000620000000111013233376355013026 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbg(c`a`DF`$ @`q"UĈp%lWI[ W000(|˿*(߯_ܲ@|v /dJcaa.u X10?uݗ~?@~ H 귬] I7ƺb\|}/}zK z-9 [v~{Yga~ d  200WepϿڏc@_ 4Û?3xf`? #edWQyv X$!No@r$(~30!_a Ư z1@~PL`c0fI@3IENDB`klog-0.9.2.9/flags/ga.png0000644000076700000620000000075113233376355013001 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<{IDATxbdhf@ `$!0 RA7DUFjo;͚v9ђɐ}M} y?￿ ~/ CG@ amTv)fTooZ<|?N+X002/00~32d@,`k SI5?i*!C!j Fr  l?i92@0h`?N)ba4?L`SCx90~#zo~3<A`#h_plIENDB`klog-0.9.2.9/flags/gt.png0000644000076700000620000000075513233376355013030 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdNc`,$ߧo#8(." FϿ*  H@! Q@Ew_4_Zh@]21@s_6,a XcrT{~5b  P?}4 @I!N rҟ a s ï0E@E @4@#?&1>%?~102D!3#0nY \2No{ϟ`W{1p*1 sIENDB`klog-0.9.2.9/flags/er.png0000644000076700000620000000121513233376355013014 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<0GaW9_0 ;33?7_?ѿ߿ɿ~i&b3%?ʗڱY?{5~c?߲ܲ@Kd?ր?Y?ړsEI'd?1G't;9!01WJG dX 7[џa _3s0?/l^ǎa[=@1<265 %dÿͦSLj]T7;-jC+㏟ ~B1+K4 q#5 1y-~p0FX@ P8PIENDB`klog-0.9.2.9/flags/bb.png0000644000076700000620000000111113233376355012764 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`nds1u> Pz'?L2_ f?L,c/o0 X&߿bïe%6h?@3n~ϯ?~@, wUD/ _6oC_?/ ׯ`Kj ?_mp; 6 @@ lï̿x~1} /x@J;߿@~ b4 ` tOVa`GIAa X D o7/0cad` fg{5̽IENDB`klog-0.9.2.9/flags/id.png0000644000076700000620000000065613233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<@IDATxb//P_;P _ ߟ 7q{"ba`9H_4 տ,%  X2VT7Ͽ߿@_ ?@9b9׿_>jP~P@r`r2 ? @?0!n{b###H=>Y/ R4mhD d@@.H @~h0bvBIENDB`klog-0.9.2.9/flags/la.png0000644000076700000620000000106313233376355013003 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbˀ 8a "[36:u${6kz?XB߿￿џ%61"p#YFϿ~cǟL2\@T(AH/@1 ab|̿`@ ïcx |? ? @~ TN{' ɫuC@ @ ) տ~@LA`rjeAG @@h1ÿ0p@@1"") Bzf?IENDB`klog-0.9.2.9/flags/ua.png0000644000076700000620000000067613233376355013025 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<PIDATxbdh1 ?(# rr1Pz(* jd!7nG3K,TCœ~KG00T??߿ !~!@lTd6H+ks X. l$P*  rJSߟ wHʖbc:@20?/WdbRz@C, HTE( @ P6  @uJDA:#B?bz@I8`@pAHnGIENDB`klog-0.9.2.9/flags/cf.png0000644000076700000620000000114613233376355013001 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbԿ/Vҿ9~axA/c 2L1ئ}2k m<n_9loO R? ). л?FUE!5Cn_?+ yF[L5]^gw^ +TWy'##Ż Ogwxci7;N07z*mn0|;?f`׊+7>ݷGĀ\{re7; 3%?qp׿߿Eeѐy lmY@?'`Jk<7BtΫ>0{+%_my3gCsv͋Llnqa3;/Y0ϟ@0o\d>S\3}l7s!30jJ3jJ#.氦9mY~;-m0m?2z!9[ A K~IENDB`klog-0.9.2.9/flags/vg.png0000644000076700000620000000116613233376355013027 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbܟ^VoŜ8~վ!/`1: 1 ͻ@; 1:b' ! %P]1>^!<,,)!V?7שc+T=Nd|ױ7r3/*E ?1ӫ ,@߿~?PC*/ۭ[d,@5uTݺ͡#ߟk9j@@ @IJrI?@ڀ.X2_ȑ􏁁 )CnIENDB`klog-0.9.2.9/flags/ec.png0000644000076700000620000000076413233376355013005 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbyS' @A0P D@0{,V@!@?nt g$BJ$#8zr V u n O?; ,8E-/? IL} @,oI= o4?L\ J$Ư?@_Py_P/ 6$eUR:{ @(00p|  RbYT/ou!Pl?H $@l#KIENDB`klog-0.9.2.9/flags/np.png0000644000076700000620000000067313233376355013032 0ustar staffPNG  IHDR YgAMA7tEXtSoftwareAdobe ImageReadyqe<MIDATxb4<-;/p^  cc?"UYyZ߿10Br10<h1VVnn..J;>2 c1Þ'44 w_,+tgϯ_@b;⺗ 'ɉ @,"ISXÊo~fc4fn{ϯ`[1쾾ﱱ H8UFߺ_v}zq|l*goW|￿mz/j2~bKߩp/y[ 1h߿ ivU叿f ۾ρ.b~j* X"M$(9?YeEJr?Pdb<>Ôs {10|g  +9IENDB`klog-0.9.2.9/flags/bo.png0000644000076700000620000000076413233376355013016 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb/e~01@`8ގ(oKlhF[l܉B)Ѐp ߼**?H(& XEeSO?X`<@|Ib0?Po]0oXy?0 # A@PE13 ?ojfl%`@,k0? f@a1@~bO(\  WO ($" ?Ib H| a#8 !,n! P #|9FIENDB`klog-0.9.2.9/flags/lv.png0000644000076700000620000000072113233376355013030 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<cIDATxb 10db` / @߿I 37m >y R D@90 _~ree =( 4 ߿?10˓'yBg: 2A9,ll ƿ222pF&>˛sed60@n ɓX}P8( P_I9bz  ?W@` X.II1E0B:0,"!E/hD?@|(IEPZIENDB`klog-0.9.2.9/flags/si.png0000644000076700000620000000077613233376355013034 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb+Df(?Ïsq05(|@,<~=󿿭 LLFFF%,xxBB,~? CB}CO~ԙg[s=bof_@ ~ɿ>f`x@@'aW"__`b B Xcl@@#0/ïPL@ӧ@gr2:ן@@%'3L /vo!.7A?T=L@JJ@ba@/#0!!T.^\1 Pp,IENDB`klog-0.9.2.9/flags/jp.png0000644000076700000620000000064413233376355013024 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<6IDATxb+Df($SHŋSط#of h @^…Ç?}?9Bb$ի/(ZpK@LG`˗YT @,@ gV h,))* &@ H :sqߵ L @@1}. e@?B޽ @ ޽{H &l争=IENDB`klog-0.9.2.9/flags/mq.png0000644000076700000620000000121713233376355013025 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<!IDATx1%xB& ɼvYoJ2.ucӡэLIYB^IT' gzp)ԅ#G?W_<~">O"\g`@, /UUZ ߾oE7o~ ٫ϛJ?}^nV#'}W6?I_w /Ͽ ,?| yk.K 𲳱2>y_@F$x{6VE1uzLgV.PBb ta4{?_>ySn.VN߿AFP ?m$/_ %! ɦ_bb+@%>4310b`ݗ/W}") G.!$@ :hIENDB`klog-0.9.2.9/flags/yt.png0000644000076700000620000000112113233376355013036 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATx$A 0To{ֹBRR|:f tY\(c@ w&/\$vY \/镽m-̝ɜH@D\1aapq02?3?P'###b/xϜy:&jý?{4ZE]cܻ/_``3[/OOOϟ?淯_UUU8L6:0s?PVS[˗HzU##f&ʟS~g󻓙_fO22@4:_X@ק_?~I@YXX~32r$X998 * Ʒo-yׯ_Mݻwp Z t`&C WM$BIENDB`klog-0.9.2.9/flags/northernireland.png0000644000076700000620000000075213233376355015611 0ustar staffPNG  IHDR n pHYs  tIME 5OIDAT(}QM(a~C3ʞVٙRr&j~Ϧ\\6)Q$E}EZV&-'v}yz^lЬϊ2+P(s!Hn^qd#n90nu"DI +T  @eBs"W{􈫤|];r >_Q8w<CĴ1+"@lci3OMD#qI %"hY'旵RƇ=Ϋca8W|5F hdBEy֗RhqIJjy~68o!|YiXQ=daL$=n6IJplEpdcFIENDB`klog-0.9.2.9/flags/pa.png0000644000076700000620000000100713233376355013005 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#L)aa @@,@y>>> 2^ }כ6 g9qfLR|{ϟ~U3 $/×@Q&C4"b^?8 X)Xo߿6VKWϿ2I?~b:$oF11>o BY*&&?ߟ 0u '׌&LxS/0?P_w^  XN't=0d3TfMMΞPtC \]ï? _@Pp?y] z-IENDB`klog-0.9.2.9/flags/is.png0000644000076700000620000000102413233376355013017 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdПϥcfVYaï? LD`Pm l#1QBaKwi^fz ,CtԮ ? ϣG@_T_ :94_@H`@=@@% [g&ן~u\5 (7T} @ B.c^=VBzE҈Rf a,l@, @ԁLj D #- 6N f/@123@T$p<31ShBIENDB`klog-0.9.2.9/flags/ve.png0000644000076700000620000000102013233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxba &!@# e æE^ y af/6 ? *(  ߌ@e !/P7P@1vv# JJ ? >PHUm>mެT A@e@ _/R=mګ_UV7!&3uvVo5?@SA$+$Rz X1e=!Cp?`@,@k~aEd0@H :+4f&Zt8IENDB`klog-0.9.2.9/flags/ki.png0000644000076700000620000000122013233376355013005 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<"IDATxb`? PL?0qb12g_ߟ?O?> H1=R@ P@o6 ֿ h6$ Csn'397ؖEHsP<T r 1׍EM w xn p` x1{qjDM9jP{R~eQ[wnUW O=>WRSW>_z;_}S# ]Ƞ<ށEz{}ɷK ”*s>H[E]@?@1gt5U9}PH߿/~?~{+}7 1wET(5M͵cq,S_2GW4  8IENDB`klog-0.9.2.9/flags/uz.png0000644000076700000620000000100313233376355013037 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`H\LCC…Yw+5_" 0ӧi;w=wſM3ᅴ6U ޼'a!Ǐ s޽~P,?bIep/D=߿y(߿[ kb'//+О3!.xbr,#?^6@130$e5ߟ?n "@to $rm {Vן_ϟ߿ s HJ1 {_' !! 0:\DE9H߿ ſ~Rl6bb|-???~Cd~u@iQgx a!A HpcdXG X@I  0eF_ 0~G-@12l)R0@Z gu}a^eNIENDB`klog-0.9.2.9/flags/qa.png0000644000076700000620000000070213233376355013007 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<TIDATxb?(/IB~10 ظCW߿&]|-@@^T" ~I!ibBV߿FZ `_  Xh[\U2/ PA^c & -? UL P_Rr/67H@1?l/ jo`5 Iq:? H%@1~| ep '޽@yY @k}[T^YIENDB`klog-0.9.2.9/flags/ag.png0000644000076700000620000000111713233376355012776 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd vo#_οaߟ~߿[a&1.g 2!1H[z1?9-<0J*w?3 .??{LgQbi?Vv.&?25<_ W0bz?~-) %(%D2b 2~4y}oϟ#o#"%K~2T @L@ t?u?.^q@!I䇿Lb⌿uy=wT[&Sh( ƫ i.6 "iIENDB`klog-0.9.2.9/flags/at.png0000644000076700000620000000062313233376355013014 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<%IDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@, 5DŁVY?~&.ovb|򥨨(ؖ `J!$77۷o$*8; BV?bXXk$_oeߴ˿4Xa%!?at@CIIPEr0@HT @_Q#OC@|WZ^IENDB`klog-0.9.2.9/flags/nu.png0000644000076700000620000000107413233376355013033 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb,.2W݉"Y?~t'IK9 A_by%u'gb7?_>z?feLL*c1!3% 22ɚ F08(0Stګ'$“HMciSm9,3l Sμ 7X0h|:epkHP|ן?@5^'sq {ϼ 1hNyV *:yLVO~ 1pG U  .c ATCCh-$DA$ @@@ 30'+ I@e`wXhg?@F hc Hx|!IENDB`klog-0.9.2.9/flags/ar.png0000644000076700000620000000077213233376355013017 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<a Ͽ?E@󏍉 X>aHU?@ÿg/\= X~a @@K@\([?b})& h6  `> $YD:?a6bZ }/2q{p f .T B?2@ f`cN93@\O 0r+T l, @,YJ^~<@C4A'yD Xcd`e_`Ȃt2@ t78N@~ ~} ?@H-(l pmA`IENDB`klog-0.9.2.9/flags/scotland.png0000644000076700000620000000121113233376355014211 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|C[\b`b?_`ýw w?H;@1|&ߦG/H xۤ0E.fM;@̇.[21 <o{Ǜ;lm$=eX 7=\ < D8|!#b l".)ճS*=g˹; XvgwbR̛@{=-[7boV\' 7ٻ/_l~c @60ϯd k8]kd_9~N0*s3aaG_(_V`X2ñ gT~OfF#=TxδF @1ο,F(ew<[7?ϣk1g @Ƿk0r0H0|fR P+@@)KӣiIENDB`klog-0.9.2.9/flags/lk.png0000644000076700000620000000116313233376355013016 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxDƱ 0%3 Rpqg ҈3O1v=ڼ- `g˟??\"bd _@K]7-S=!(ﯿ_{|{  ߿7_sAn;7'Bn&( & Hj/.7r3K%8hbZT / ` S/?W} XaP X_H?ٕ_h@؆~7I?~><ǟ16#bF \,L2300񑍕ֿX3{n#RDPe}`TsRS_IENDB`klog-0.9.2.9/flags/ma.png0000644000076700000620000000066013233376355013006 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<BIDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@,`<_ =` 5 3UUHY6>/=P @ ?Hnԯp! S AM Ȇ߿n?4d#IvX*_g@V00H3ċ` P@ L0HJl$"pP1@1~EH30<\ W}n?t՟_ ?NP2gcV?[) X.ka`)?kd P-@5|e`_afY/0 K/?yA@`# $ A@_ ` mL7!U_)IENDB`klog-0.9.2.9/flags/sy.png0000644000076700000620000000064613233376355013050 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<8IDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@,>~e!Fw@~{ѧ?_z@L@ 7u[u{ݏvM:fß? >T yZ4v0@1}!w F +--޽{@ ?UTT.^@`$P ( ?`0 @D20ϞJ* ҶIENDB`klog-0.9.2.9/flags/nl.png0000644000076700000620000000070513233376355013022 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<WIDATxbπPX@`U 5/w9~LO)V*<'ρJ@~$(+  XD 3T j Ə??< AT40Ved@+o>Ƞ_^kן $߿ <{;g óOzH߯@u5@H?p20 _ uœ#@?`@hc`FDB2kgIENDB`klog-0.9.2.9/flags/jm.png0000644000076700000620000000117513233376355013021 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb '_1?0~10``c 1U;{ MA%11=D26'. k 103<4 =[p ߿?~Y٫b*do _W[_@ۄ~* & o0zwR_ 0 l_b*~K׭?~Tj  @N}zbi;UWJ| 1FB1bKMG3I:.Q$^K0FGO_w_w@_2<`tc - >sw!IENDB`klog-0.9.2.9/flags/kg.png0000644000076700000620000000077613233376355013022 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbȀ`$2p) 0أꊐ{3# pzU}ߓ @7_F ] ($+  XGfߌ~.` @T @L @΀ΤQŨYH/%@ ߟ(?/~}20'od/b˯O~BU-: ~bï_fd`]P1@5@<uկ~1ן}N %%A 1@7#ِ0$b|03v!f Tg_TIENDB`klog-0.9.2.9/flags/gw.png0000644000076700000620000000100413233376355013017 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπd``b?"?$\] $L2m'O30_`Qh@_F߿KAV !~5Щ- I) @l߿Ϛq@ϿdS @2'/ׯ?_aJ|c ~0T @ @@2Tj? S D _II?s /а?q @_ G <700@A aq%#aIENDB`klog-0.9.2.9/flags/zw.png0000644000076700000620000000107613233376355013053 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbf&`fBb1_9gno `ߟ?@_~betW307Fe?}@, ;q:&_?@Ư~ "Y_@,&U1+0띧wU7H_ d{@1=y/ϟP D+**=z XXL^:R}{Ud`~~s@,EQ_X~12 @ P ҃/]͐n9ʲ<[r-%M뇻by,Aˈ0f3tg?M^q,zZ ,|ik` +yV3> BA 7`+rԁKhu) $%{}р᫩l@Ҧ 7j `:'F3[PePP\0L"j Х#5FxL:_zL1^Q+f~x&x5^IENDB`klog-0.9.2.9/flags/lc.png0000644000076700000620000000101013233376355012775 0ustar staffPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<IDATx4Q=kTA3o7Y7F0! M@Ơ؄P,&bh*kH*6@A,}o{sgހ|{>/b첌tm D&Jath# MHCy7 F$FQ H6ʭ|+8;B4yGsnJ[/dQ*0T+:1@ƕtatFQUՕ:& 5ʺF!T5qh̒Z%`YKoTy}^ +y}$ͳ, [놝 ~7O E;*+._߿ MP1@A5@s-k޲UD(; UИݯ_jZ31!ԃm 3 00p3Z?Nv_vvS T @?EY;x D߿sͬx(/i Lׯ2o?*-@S~T=Z@_^AB@ ?Xj0R+7IENDB`klog-0.9.2.9/flags/ge.png0000644000076700000620000000112213233376355012776 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|5 BH2e?0\ X^8Ϥo((?ï~KJhj )ubwgxgO><~ h@l*bua7p?; Y@tր?101߿s(P6v3ӿo?^ˏ3D?6o;Porr_ P&3UF?mI~&;G6032IPm.1YTRM瓋 ?6}k۷+ &ٷSw,v#37oͬ (.'###;$ЈCM_h'\: ҶNsKIENDB`klog-0.9.2.9/flags/gd.png0000644000076700000620000000117513233376355013005 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπ:^10203_,?!1@@1e`X:^ ߿bu  X _qoz4&̿7H)_f@,L o˿<} 7?~-y{ś__~1@, [#-o;@2&ߌ#~-x߿?b4@3-o?12<_@ t?3 /L o{/ߌ @ '{ï? x~ fQ~p׿?3ی8_~˰n,_oM "4H2f/l@60~=_[wb` Ư XA>Oÿ Y0B/!iIENDB`klog-0.9.2.9/flags/za.png0000644000076700000620000000120213233376355013014 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb`hfh_~ 7O _>30|d`x 3bt#,G1?1MY3_>|yrDo_XHݯ(+ 1~!' s1h$ LGㅃ-Of A 7o4 Xqwxǟo? ' idxDxߝQC&,~}lS./xYde~3KI7_0.6Iؽu/^? @+HE]ϋ"7hyg}c0H] 2f/` F ` B._CIENDB`klog-0.9.2.9/flags/cs.png0000644000076700000620000000066713233376355013025 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IIDATxbd` 10d@,1U&aFwOx$r3{IK&_m@U y< T T7￿~E20| SSMM!QQl<N0DE9o ƿ/_20?ݸ@,B h@< k>ІP@,~ z̀ dEDtv˿י0/0"~3ˠt3@IIH(7#B bb b@I@sg_IENDB`klog-0.9.2.9/flags/sz.png0000644000076700000620000000120313233376355013037 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATx (>lк,~$ˡdöMC_,ίj ,2 0@OO߿woֿ]y3-fN6 o`@+_mu/0E3(. '1b P Fo>D$? <PKT`$aN::yIENDB`klog-0.9.2.9/flags/vc.png0000644000076700000620000000110113233376355013010 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`8߻  D?  Puu"Iղ/Pf?L'"~i&j~o8~-#  Vϟ`@\5ϟ xkF"Yx_ᗉ_@5@տgʻ'^2+؋_gfdt0tbHoZ~|~ qI7oйfLD~mï~RA6(X$/oTCD`a {$$؀>abd`e` #o,3e0 @ [q(h!PhEcO{Zέ IENDB`klog-0.9.2.9/flags/sl.png0000644000076700000620000000066413233376355013033 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<FIDATxbd8̀103` 0@1n⨷8T۫BdeX%Nt@ O?Q￿ TR׿_44bUaWd ߿@PiEYDJ Ư_sr2- qFFG˿  e@ybbսX\,a_,_\ @\|1{߯_ a@ zp20\ `JKJBC;"0 a%"?$1Rq}IENDB`klog-0.9.2.9/flags/ai.png0000644000076700000620000000120313233376355012774 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATx1]hP9J+ 71, G0XaD\emlz_#n^)ryOXϿg2120| ^6R=m/]"#cjghS gުk ?1+  ?  OMwԕ' X~;ﯿJX+k?Pwbd[jÏD_#yvF?|! ~/8q}gq@~ o`1%B_u￟h_Y~  @ym8 A2@9? @#P'RD~#ܿ@7$@YH@{IENDB`klog-0.9.2.9/flags/ro.png0000644000076700000620000000075713233376355013040 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd>010?`` !@0SݤTL?D~?߿_6m  O^L=b`o(_f@, 3U B@&C40 @, UxEtba0 Nbh@4P_$ `I`'H u `n@0I?@  TR䍿LL R0: 20K\|o0 ÿ?xC 'oEEIENDB`klog-0.9.2.9/flags/tf.png0000644000076700000620000000101713233376355013017 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd,g:b13 !/@,@~@ 322t2O߿?@?L@ xj |_߿JK0M0ᘷ4les {S+X~߿@b^092v8Y% H@` @SR,0fd@,L9X;ܑ﯑mU #?_&Fضlk9O h ( T'bb;~,͵k_?b B`}) Zd ::~|ߟ?@#/q9@0a!_`00b  EE @I0?` !h?H"` >>  ϟR3b*2>7!FF? j ~!k;@1yvvNut.}}  h@nϿӵ5~__o_D?tҟ_ |T$mǓ@ze`@o߾燺>zs@<:jP !W h2Ah20ߧ ?x47H@&N  f  @Q$ t@40S @~aH'#H DBP1@1~EHl ISf捧IENDB`klog-0.9.2.9/flags/af.png0000644000076700000620000000113413233376355012774 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbXY  V2LL``qݻwMMM@ 7㟿̿~(_?\<{1@PW~{%>CKh @߿@@ /1?P~'a(w#@шU;MlAƭG\Mˏo4{qr13c~$b9@?˿2KsojH/bat?~@]?Dv:\37P@@zn: _p @ @uBO3'_?2 >qE^~ibd@a c8ƒ:8.EiS^wIENDB`klog-0.9.2.9/flags/bn.png0000644000076700000620000000117713233376355013014 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbzPƿ? P0 bl0 07\Q :F+@BkW+PZ8&Ԛ/X 3D3տ~y'N_~f`/FV=aem [G~(?``߷~[1wyybhh" yhpQQÇ?V,T?-O`b|Q~fj$ׯߝ2Yu޿1u#u311cee555Ev?gA>w߿~篊ŋR@9Ff?LlV} O<@ӠXF_Pdbad4 paw p1iIENDB`klog-0.9.2.9/flags/cm.png0000644000076700000620000000101513233376355013003 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd X3Ȁ+ÿ0B97_`fSVEWֆl]LtkFXr]h@#S TO>_ƿfP_oFFY%8c`9T'Eu&.$l4eD| Jd*P[ 0߿ ~__ _PT @_~:??@,@ I@gd} =P@4$_!k:& <zI? `@ Ʌ J D dPIENDB`klog-0.9.2.9/flags/cg.png0000644000076700000620000000101113233376355012771 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd8@R XՊ`? 'F &}@MSҿHUK6P/Zq,zbd0LRD[sA~ob* 4n_fh:@42ߟ4v @yR߯$?|k~/FhbDÔI_@U3 j럿B~ XgQ` CbaǏ_(oi0 !$bʰ'4"ݘ fv&RIENDB`klog-0.9.2.9/flags/kn.png0000644000076700000620000000113413233376355013016 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd 10@ D20aH* FVjjpp o'O|ߛ6m O>*o-!쿧Wk]\b:h2P@~5w_F<>fԙg  r0߳[~_t¯/{2^@ѿf`>- _?fP bh)?1Bwܶe׿~-!kZocOׯ3 @, L ! Yr/;VqpP @5@u`8K@m|ZZK u ӿ@?#g'7 ߬G~3 4l00+d_}< GAA@S- \0~IENDB`klog-0.9.2.9/flags/sa.png0000644000076700000620000000104713233376355013014 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdf@ H @#(,lg2EYi) i~P_~ˏ2B@tah,ǧ1132{NK Z@ `?})# y~~7 ̿]@L@on_|ڋklמ_`k; $  @a,WBڇroYZBc  3:%xXWdj  g-÷@ Xq > pEF+.ONHh'P@12(D$O 0z79NIENDB`klog-0.9.2.9/flags/br.png0000644000076700000620000000112113233376355013005 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdHf@ `/03 @5F7g`￿6ZXl9 ϟ߿UOBY;K^?K_h@5T T5ToUդ $~涐eO; o bL_g~ UszhdČY/D:U6[R?f?OGsA_2ЖҶ0<t{W|x_D˒_.fg y)h)˖bU?}n[/I^r2|d   &go~Ko2,@ `H?$x$A^; 3˿kaܿ(@128"b9F1C/AnIENDB`klog-0.9.2.9/flags/jo.png0000644000076700000620000000073113233376355013020 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<kIDATxb@ ow20\L@߿a$شi@50zt߿7Po8@dHuWo FFƇ?/Z @QQ?~iǢ;&?xYJ$9 d= ߿?j`' P?@=UO`w-+_?ϿJG[H{?k%)J@`@￿ qn4}~S4 _Ƌr%G~٢7Y tP?bd`NDH0DB`0@ྭIENDB`klog-0.9.2.9/flags/md.png0000644000076700000620000000106613233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdre`a`?.yAHJP_Hf?of*_9?׿D~Ϟ=,?,`cHݯ,+  @,/;vp VWT7P/@@ '>xښ~ 1HU3 XVrxx3qq l0ß?0JJxxLLLo |gp,?f0 @`! @, xB4`OVY}IENDB`klog-0.9.2.9/flags/bs.png0000644000076700000620000000101613233376355013011 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdfb`ccc60 R18: Mǎ Ȱwܽ7$䯨 =1~D@m x?3wn +@5@ f1~3c@4x1Fz`!J {ˏ~_P@ma~ ~'5䷬"7P@lׯ?A~1$98 ^/xJIENDB`klog-0.9.2.9/flags/zm.png0000644000076700000620000000076413233376355013044 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdndf2c`F@/0  X&yN>|߯_pٷ X f ߿? ,qϯ jhF D߬'WR("r@22Pk\8Gd) h6B~@dAV/oEK~Ô/ @u@ RBmi XJp,:03 WE Ȑx= | ͯwKݵIENDB`klog-0.9.2.9/flags/lu.png0000644000076700000620000000074113233376355013031 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<sIDATxbo??_ÿ  X>al 2/ӟ!0KS'@0ׯe? U"Aߌ@/俒*HP'O^ ߾}+((r ` 022~ X ޅX##0T@@ ; 9s cC pA;eO>_p0@A.:47ß@i=~c00b/`_`LA $@yk ߿IENDB`klog-0.9.2.9/flags/sr.png0000644000076700000620000000100113233376355013023 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdg``/0 $YP(F0p4I\"=  fkJ7܁*1$ŠO1?0 0,$#w$9߿@C"?Ц߿ d0JI}\ Xf|S:@*~gk @ ?A԰_e~!;i߿@nOO߿$^`7Lo(Mk^6`?@4,?3#W!;?pHBй ` Bybd(f`_H pH0i hIENDB`klog-0.9.2.9/flags/vn.png0000644000076700000620000000073213233376355013034 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<lIDATxbπPX@_upɒ2ҒKF6hU wg@ տH_/8,bE5P 7P@1#P5?.'"4M /R Df{ $@ 䤿~;ͯ@ @ï~TIvo WM$w/o@C00H38ȀT3:9~P@ L0HJQd$ȗ@+jDc0RZ2IENDB`klog-0.9.2.9/flags/na.png0000644000076700000620000000120713233376355013005 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`_ -2q/)W` 1~}C  26OK h*U;")yX~-b@L@'習 v>wG?%ytt"`eQ|!_GǓ?W`P~_@Wi &_^<?>dP}OoHog{P;^g ÿ?@,0__agr? W4;<{ S!@, ^1~ _,6=/@? H o _ 0b@f 0(t0IENDB`klog-0.9.2.9/flags/dj.png0000644000076700000620000000107413233376355013006 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<|= /1p100??~Ͽ"~3~cca p1߿/? f@,@< f*Nf?Ha@ @K7/j@1a_ s3x&b0go'`F qt &A'';æg>_~&VbWb:@,@'1|W|<F"I O{_P?f >CL\22@u # !~1˴ӊ3|``0&` ` |^#iIENDB`klog-0.9.2.9/flags/iq.png0000644000076700000620000000100313233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f9 x[ ֠j68%dT6d`8$v"e1Ӟ$]vpOb\bB'^gabfg󥷗|HO_YIZ-e13AO(e$pP: 10 d mwZ{Ds@h7Z1(e@,/^IDATxb#L) @,@?DN!/^ Ld@1  PUcvOw?h?P m_N7n|"gbb_?p1@ 03 ֻo^a; Xƃۗ3ݼ0xW{e95Cݻ[>>>dc,HwAb0]/uTIENDB`klog-0.9.2.9/flags/fr.png0000644000076700000620000000104113233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb,zߟ??022*'b ¦$A@? ~mE@40g߿ _~@6x=|Ϟ "@K890Kt&8@[zM"-b봗bP߿@*)qm@@/A00q;^ 7Lh3 |Tt@P?zD_6ˏ_@A]T aUV j=I,$߿@|z?.Nf &H@ %1d@|m?~}ˏ_Ҝ@ǏzA {f uDIENDB`klog-0.9.2.9/flags/vi.png0000644000076700000620000000115013233376355013022 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#L) @,@q]ƌL_ IE߿} 1Z@1 Y > L:ei  s 180 7 ioO^j=mQ}FX^q☙߀ &97o~ g;-W2WfvG޽?(۷k\AFOot߷9oOJIqܽ{ X A*LKz/̚_޿7^AԔBQ $995~|v劐_&&FFf $fhqhZ E v&[IENDB`klog-0.9.2.9/flags/bd.png0000644000076700000620000000077013233376355013000 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdpf@ /D1XúLVwO²\9fgYdR'p5!t@,`?y/H_'ߏYׯ~-+, T @,@gMlwڥL~o/ _{Vj &s o'@$/{~/_ Ͽ?@UIC9H?F5 /67Bj@4Y@!À$A6 0t hV?5_% 9ʿWȀ @,  6(@DQbdDH _ak9IENDB`klog-0.9.2.9/flags/so.png0000644000076700000620000000101713233376355013027 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbTߟ? 1 /B97hh&ȰO@Q]z7$a*8 W_AJ2`8#P@1*6vr? t@a f8gd; _ NR<%* ? `W+ g?$ϿAfd2@,@[e Ӱ_@vy / 3a -W  ` t@12~eHb@G < mxȮIENDB`klog-0.9.2.9/flags/gr.png0000644000076700000620000000074713233376355013027 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<yIDATxb?pb4x (" P]L3S@  ?ÃGѣG q02Ttxb(nߟ/$R? @1[v3أ TuhҶ ZPW0@֭G̍7s%CH?'˅Cwŋ7""H"31н@{@,}eI!fT apq0 Xy$˯@_y=$"ڹ&@1޼QTH(… 0:{ 7C#??;0kPl~IENDB`klog-0.9.2.9/flags/et.png0000644000076700000620000000112013233376355013011 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdTda/_0_`ap0 çwթm ydޔ; X~1f| տE_/@VDh.@0(H?3139_~x@Hs321v̄> 2x:` ٿ@>1 ZϿNK|#@4!(#ӏB%scHNp 51jQ T"?f(W]su m`Xj9_j/9$ؘ ~342`T @_QPhR@`! =ڮIENDB`klog-0.9.2.9/flags/gl.png0000644000076700000620000000072613233376355013016 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<hIDATxb#L) @,@ >>>  $" ={@,A|aX ߿joaϟ?U D ?x߾KWl: nC ˖aj ƿ!!?|Лџ??VV z1Gͨ{bH=#GQT-fhbj`r~d8df/^4cP 2 ,@40 ) 2ft1Q66G>|` BBP1@1~(b@I@[JăIENDB`klog-0.9.2.9/flags/smh.png0000644000076700000620000000053613233376355013202 0ustar staffPNG  IHDRvbKGD pHYsgRtIME0uluIDAT(c'1NfpT #/`e\W<,2b `M u2eswcxW{AX~}á`/+  s0te030 r1ܼwP?p0p2Ä| Uݿb%> |`59bC_^̓IENDB`klog-0.9.2.9/flags/gs.png0000644000076700000620000000116613233376355013024 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbYYY{tA(IuݴA(@ O2~eÇB*U˞|9qׯ~BM1b~  T=q1`?MR ( <,ͮJJ/bb8 洴ѷCL0;!ُjZ(G98 fK12wPŒT!3y*$ŴTST1io@ m8%}p I~ {C"^} X~PXP3$.:xi ۷**@  ȗA/X3d_^ @f`f  $)OIENDB`klog-0.9.2.9/flags/sn.png0000644000076700000620000000102413233376355013024 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdhd@ @&@TVY R1e`?0̟"l@,`?e~_@Ռ@490sT7Z:pZ_XR+@2Uϟ~{?P%i￿+~mR\! /Xm0e.ۯ_v@? l`; @~/g C&n<h0I@_= b0PO@, ~#- 8X~32Iq àN Fd/z=O`,[XIENDB`klog-0.9.2.9/flags/kr.png0000644000076700000620000000112013233376355013015 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb+1@18كGW_d--|w 5 ׯ_oݺ"bbʊg/^]F@PPXHHFVh@l~mhb,%Au bn^^o޼yPbիW\{pL/~%)"7RR= /EDDo0fl29}vvni)FF޾}U]7W؇?GIIIF o޼9m4= 8U-T0 1|$o'OB@, @c?ܒ o BFFF8PR)#(AlY8@ 8.VwQrIENDB`klog-0.9.2.9/flags/us.png0000644000076700000620000000114113233376355013033 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbLN?1?%o^P rn@+0Dc0P,Je >{2}RjL{D`bjX~ @AefxG/}cq@m4h}ݯ_ZU|~>}ûw޼yo/N<@, wofk ˟ -W~z+n `/_/Τ?WCrm~~Ѭׯ >~+W^|ݲe@d?[/i'7 GJJ-t΀!0eb^0#i/_2|t1_@K [.˫}feqQ?b`x?I U?(?A"?>30|`.D [0+IENDB`klog-0.9.2.9/flags/eh.png0000644000076700000620000000077413233376355013013 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb` ld`  U__$ ?~bZݸ X:?} (~$߯_s}@,JU @,"R"ܬ `̙'Oy9PCKKٟ?  b`  f+WϚ@j@P)@1셫-II׮/BB9?N) A߿u,aTRzs@(7(x70   "MϖxbIIџ@$0oЌ;@ ~j9v^f0 O :uIENDB`klog-0.9.2.9/flags/vu.png0000644000076700000620000000113413233376355013040 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxL @5k C$^u"b24bҗ'wXVu??0ϟ0˦MpoF2Mno?A* / QV@15K7.c߿JA~_P=@ !8w,Z'!?_~H20HÏ;V.Ms?~o7 Ic/+u o?2ׯ@;~ $ $PTr@4;_&:@ 1 ߿D'C c@'}?I02|a -?ArI  d$P=//bad`0'`$h)PĀLr0$QOJQIENDB`klog-0.9.2.9/flags/ne.png0000644000076700000620000000103113233376355013004 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbc`@?`/021a@0ۀWx9֖a2,-E#DudG6\!U<22 R߿EdJ͓ @u@K6 32>= Xdt89@yZ.a@j.S[3bi!/ 0 X̬@ ɩ`Ucga?@123x@ D߿UT.6] `f#' T?  ϟ@ PPƀ(c0eA IENDB`klog-0.9.2.9/flags/fam.png0000644000076700000620000000102413233376355013147 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd8a`ï ?X@BQ?_L܌Uec??5e {K@  o & ~rK0&%7i>O'*k@ Q T??0 ÿ3y:  r_ d? \zd6P 6:I4CV4I@O'%soH H(xc?/FN/nc 3IC7F)!~Fff!D@@ aWpci6TP ];T@ae/IENDB`klog-0.9.2.9/flags/mh.png0000644000076700000620000000116413233376355013015 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdf~c~!61M2' &T vABF+w\з̜?8*") 11221CLZ7#`3+;y?Wqo/t@1 [ H'96^(1C^+*:)줆t$L 5oV]w9pы_@` @K~3{!/Q=&]'_:7?j5G &o O޴S{޿?P&ߠ ?iQ|f|C_?/1Na~@sg``xQ4lKIENDB`klog-0.9.2.9/flags/ye.png0000644000076700000620000000063513233376355013030 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe</IDATxb|π`$2IbJpV1?D7doŒM6OD~3 Vo0׿߿l&iY "ޞm$A:A @AFo,WNNN3!.#bD5Hn@YFFbi 5he„>ϟ?ȇpT  F3߿ ~D N8@`HHHHC -@ V3azDIENDB`klog-0.9.2.9/flags/gu.png0000644000076700000620000000077513233376355013033 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbɀb„PdMR@ ?@ܿ7P ̨ /߂U_໥LD@=K3a` & `{pć @Dm: 79ǿ~#P@0h@mI߮?u_Fbv{& k7;/Y* & \_J y̯ߌjiwۘW1*z,T @ '{Ӂ0 kFjzbb? 0HsdIENDB`klog-0.9.2.9/flags/hr.png0000644000076700000620000000101413233376355013014 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπPX@$?߿~eJk`S(ZG;(\~ee6pտZqܔ~ R   ߿}/Gǟg03ӷo߾~ sj)/'N|@O>  65{jU@Ǐ!p{?}~|c:}$5" YL5*e 0q az@$ bȿ`$X@12dU@ Df08v%3%&IENDB`klog-0.9.2.9/flags/st.png0000644000076700000620000000111013233376355013026 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:c`#/@,V >Uz00Ͽ?Lu7 s>- T_0ׯ~-#@,@p}wҵ~r of[E `+8yw>_|쿙:1w/~_ld~k+W^.hɯ_~E @B\A~fgrLToN_!: X¿O"F?yW`?0y @[0 t! :ez ?=%$?#_/ ĸ!8"!E/hD?@^mI9џ\IENDB`klog-0.9.2.9/flags/rw.png0000644000076700000620000000102513233376355013035 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATx$ pviSS > TJ}y"G} @cO$=i X f TR/ßd?UMBE~1@E SAe z/o ߿/@h@qfOOV9h:d0ؿؿ L/^ ./g_XI&&!>6bz$Uj?σO/$1*=!9HXωU +:I6F- jK Fd @#$8!\  hGIENDB`klog-0.9.2.9/flags/nf.png0000644000076700000620000000113213233376355013007 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb`pf{g~?~||ڽAsllxw)^)οNNMn{kH?|߿ ``AVBk V} t#ñǞ{ݳ ;&0g @  ??t!m~j &_@3UE-; ?`/~YPAm  (tȰ߿{˧߿yuo@=4_ bRY.Y7_ 2*@ I~I6VvMNMq@ʢ* $z@C86w_CGˏ/MZ >T GHIENDB`klog-0.9.2.9/flags/dz.png0000644000076700000620000000110613233376355013022 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbT ǯ_|af[(` @,o}$,*)T?@)+g8@,l ~0I D a @w  DC@`k/|IENDB`klog-0.9.2.9/flags/ng.png0000644000076700000620000000074213233376355013016 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<tIDATxbd10av_M߿ xަb``a / ծ 3q00 o? M37 PPקL(x_~[Gh@1d ?H@t@?j A6P@=4_ 8  @p:?ir@տ$O &* @JCV5 P1@c ƒܒ o  LJJ!_ P Ǡp$+ gP430|v PIENDB`klog-0.9.2.9/flags/canary.png0000644000076700000620000000036413233376355013667 0ustar staffPNG  IHDR n pHYs  tIME 0p57IDAT(c?zxgL 3y˝DU D[)#럕'W1~"230(H?Տ??1'Ө'M4-1BIENDB`klog-0.9.2.9/flags/ms.png0000644000076700000620000000114613233376355013030 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<]{IvէzM|,9+_/`1/%@ 1Ȼ96&88i oy5Y?e5?s _T_z 7P@'&drJ?cZiƢS73 @~ mT; ß?oܼ*ǭ׏_@@15+<-Q,4(ٺ v@c~a|ww9?u,h?5@ :=?(!! $@:&D~//#C$,FH 2wF-5 IENDB`klog-0.9.2.9/flags/tj.png0000644000076700000620000000076013233376355013027 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπ gCV"`Ml_O(H_@Ư~l@WNNN$i` fSb{?,f&G AT̲y.@gb{Ǐ<<xlh@UV 1 vFu&hc'JHo `S(@3_{ϯ E/ 2l$r2@# qk~$L=}/G X _@ af!#+ 4P=Kx,>`ȰMC x0_i{IENDB`klog-0.9.2.9/flags/cl.png0000644000076700000620000000070213233376355013004 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<TIDATxbdH?&.b``00 ×?Qf N/'3#FFFfff&&H˗/!B?CУ?~ T  ;]x7?_P@0p|ڸ 9K5 ý;L8??ӿ8X&o_߿~ F"ޟ:@,@0AQ$0`"Lm2 @~aH'#H DBP1@1~.b@I@h9?9IENDB`klog-0.9.2.9/flags/pk.png0000644000076700000620000000107113233376355013020 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#|Ez4 f1XH1߿ߛfl 㯏? e_ ZGh@1ATC?U+[;F,,@A5%$vY~a`bf!!?0 3ʅ3(OL< #6qL-AIENDB`klog-0.9.2.9/flags/bi.png0000644000076700000620000000124313233376355013001 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<5IDATxb*/*~e1Ǐ?c` ?OĨ\J= ɓ_ae @m981<   , 39]`,-)%|yҵEOM`~C1xNIo=x0pM  Б <\~/(4!1# /ଜݢ! )  Hu?|PWz5%3_]Hƛ1e,i73feqp놅0Əϊa:@};~%"x߿C$n7`ee>3@aC얯& }h&tIENDB`klog-0.9.2.9/flags/pm.png0000644000076700000620000000126113233376355013023 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<CIDATxbTMf8#?K^ol``  0  1Pmf{5>w+G!:;!EE @ B?>~I$&/1WG Ƿ^dꬨЛo$E_h* 1sl!^P.'.TLARK@߿c￟n߾c{?_N10'/$ :*E9̎r1 nPx =N΃17 3qrɰJ x]r?'3c 30|GtwD?6ps c RIENDB`klog-0.9.2.9/flags/mx.png0000644000076700000620000000107613233376355013037 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdf`ba?^cb`$JQ$@25Fw200BLL ߬9 Ⱦ5o@ӫ~ ?7$b hȿ?f߻rY kf߿7a@hoxsꉭw:_~6 ï_ j`%- h?`26d6jwS!A]: l? /@50 L}y NT@@'1/ү_AA 5HyBLLr@O#-8m٘؀|yfkV@TLi)IENDB`klog-0.9.2.9/flags/tg.png0000644000076700000620000000106213233376355013020 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπ` v `da |u5' >? ~0s@5pp`05eX  ~d_@o&vV/b=qd_?/.[ X\\ W?[_ן@aݷ N|E _ "[{ 2oRpL 6{)GQF?3З~Aٕ?@,70H70&k@,Ry!- ?L<pl|/a FbO1&y qnC1IENDB`klog-0.9.2.9/flags/mm.png0000644000076700000620000000074313233376355013024 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<uIDATxbd`8~10c``a`(VQ\MWǏ|o?0ϟ0˦Mʤ.+ g{ u~ee6`YnaG%jH$H@gO j`~3|wڏ31V5h:@;~ӧ?eo m K~ Ln6`' o},$0d pE5ei`ARl_? `# $ A@5".\  3V[YIENDB`klog-0.9.2.9/flags/km.png0000644000076700000620000000110113233376355013007 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb_0Cg@@.D€e{j7%- @ &pMg>J~ Ӓbg`FF @KȢ/?4+ ZW 1Y\]OQ͞NMGK//zzHY`Xٿ=@P FF>_N^aA_EVS̠y´˿oo_ ~1LX\@P*˾Xv[^ r99I? _ qasG_ ?0__6O FPq'k1|`tI0?$* Z4K.IENDB`klog-0.9.2.9/flags/ws.png0000644000076700000620000000073413233376355013044 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<nIDATxbd`f@ `䏟 w9 XKDLLnd${W^߿F~ٴ X9Я_ QVh@1a?кzP?@`u?A/i޽7!~u  4/d @IX`Ԯwo` @'A!T X2g{ob ѿa$#IČ`!(PUd@ c+/߿@?H? `c2d!_* ƯɀR@`o] .oIENDB`klog-0.9.2.9/flags/cc.png0000644000076700000620000000116113233376355012773 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdef?I_0?lsA/oZ.߿W{8ξcT6 @|d&any5l+Ǐ?}?_μa@L "9~)7boV_jl_7L@1W1 Rg7lm"27^"1 } %  ,~ﯿש I'v_ 0~'6ٯEA@,@  ϗ9~/_`@,`H*}bO@` @r `~Wh@4R \<nY_5*N@L@`dFnzA$zMbɆ[@eddcF#33Wu5{Pi_?g<-3ɽڵ  <e޼y@,JӘo'2puծ/TuuXPSf_@ fL\l /H..mƋ/gxj ;#W2Q 1A `B% [IENDB`klog-0.9.2.9/flags/uy.png0000644000076700000620000000102413233376355013041 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#"AL8(MX0 ,=Ͽ߿~2ڏ۷o611``XgN?8c011]q Xw&e`k߀ An\@q0?ln? t?YA3 ho?^p?X_ @,E;0}|%8Yf +Ɋ?y KA0ϕ"@!& 5#l}`87$? t? o-Z@>4!,?`?(YL ̓"K{IENDB`klog-0.9.2.9/flags/mo.png0000644000076700000620000000111413233376355013017 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd 10` B0 jjed)ϟOJ,/8/~_@ղ<@; &?$)qj? d~D@=@W :?i_5~i &ofu1 Z)Z kVP./P)@1>6"6k,j;;/0  ռ  _%J8Y8wFw?޽h9P?  $ PP)n)]Am}a5bb0%%A~o|߿@#$@ t_ P `)!E?@A>wAIENDB`klog-0.9.2.9/flags/cu.png0000644000076700000620000000106313233376355013016 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb긜7 0 H0DE?? ϟ"sgOϞ%%a`?`Ǐt9<}ׯ  a L22211Gvf3߳gcv0r %9n , ̿Nḑ]__@ b`@ v`?˫*ZTc b|& 00;ϟpehH`ËJ~ EzgM a߿?þ9xTt&4RS0 L ` SvepIENDB`klog-0.9.2.9/flags/al.png0000644000076700000620000000113013233376355012776 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb򏁁X0"#8@%'U߿,y5߹odr3ϯѕ |wB9t{ϯ_} eZ@,?Wq3߿~fs2߯_ ~53_K?=珟"_~ 5 _߿KA%/_ 7 !c~_k}cϯ>Kagdh6Б@~ ??rc0?~Qc@Aj@ Љ 6>f?f!ֿ~|r6  VEĘ!O0PȠ?@FX@1?`HBc ,0eB@Mv=IENDB`klog-0.9.2.9/flags/tv.png0000644000076700000620000000103013233376355013032 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd@ C`X T[Rÿ2 bo%KA9s?x%@1BFFO> D'^~Ͽ@Ȁ_6N]*0-@1\Bu|t/ R 3N7 І/l?Zd!=2HOB S ~ ,pI?@t܎)'ȱt+@1ןߗV/Qt[  ,0޾} @ io0_[N뗂gw^߿u ݑ"~2E'sր#?,5&SPɽIENDB`klog-0.9.2.9/flags/sm.png0000644000076700000620000000076613233376355013037 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb??0!?`Ib)?#3G| `ƿU322- L~?nd  wۋ~|r~N\d=0#C>oD פO"͇x?K1-h@L tc <_zl @@ɯ9{2ߘ  @e2_5-k߿ /ba&n% 70(FͻßpcȐh!(. `DOaIENDB`klog-0.9.2.9/flags/cn.png0000644000076700000620000000073013233376355013007 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<jIDATxb@@n", @,@D}5o,Xx? $}m&i,7۪f3˪ u~,@K/k붿fϯ/AJ~I( X@u8M~@Uk q8V7T@@ / : D UM@ @ĉ΀l0X X@$P (7xX_bb<Ȍ?Ha `:s056IENDB`klog-0.9.2.9/flags/gy.png0000644000076700000620000000120513233376355013024 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbeӺr 1$ F1 D! $*޹1,ŋAAUr.PӞ 1<<$ I[AC  /PCYãG@QEU?0λɗ7WXCQ~/~߅ſ$D @=/{~/jK~eލ_^1a1 O{>8(aٶ#"ϟo[%'ēߚNꯟ_~3X + /oWy>?@/0XQI  /Ԙ&y 6!j IENDB`klog-0.9.2.9/flags/ky.png0000644000076700000620000000120313233376355013026 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbZXOxޕr[L D M> ?01'3sW   jE} p116(Ŝ5 1 ("$!! ,*WY"12: rz1$ "V'ԙںe'nu ßߌ~ɯ_<c@`UѲ h@00]ןʯgmXNy6P.@_o@5+ ([ @P矿 ح+~0@P? ~8 ~~b %bd`Ѕ(2  %WIENDB`klog-0.9.2.9/flags/rs.png0000644000076700000620000000064713233376355013042 0ustar staffPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<IIDATxtPMK@m6\DZ؜{UQG7QDWգ TQ4"q6ff罙 Q3Ÿx">HvdyȘE>_+*7>ao $k ;iܘLZ=K/-]wT ڋQߩθŒ*vd2렌\4jMxo\EunF8%dQAserw^2 :DBWNomy T,+ C$۶azyhBV -? 0Xx<4IENDB`klog-0.9.2.9/flags/tn.png0000644000076700000620000000075713233376355013041 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπPX@_upɒ2ҒKF6hU wg@  rr_ee6 Pqq ?1eeoh߿ nj ?t迆 %@rџ W^^8?//H~_F GGl$9 "CCA~53$|@n@50Cڀ._X_L J۶߳}5Bi`ARl_y:F2@H%%HP1@1~EH̀$LX ``@,=,/J0~ ~}Y,YY,Q ?`d0I @@ U1a@џ?ba``x w0qAr2n>_4/@113cmͿ֚@ $[/h0L~p| O/f ?'Ko_\o%B XaQ[]KO?/@ @"}?*{kKf tҿ? Rnk(0XSO+ =FPI@`2(r3Eix_d_q@ bdX_%;x\@0001iZsqIENDB`klog-0.9.2.9/flags/sd.png0000644000076700000620000000075413233376355013023 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<~IDATxLA A6I`);]LAQ)\܀abBWξL1?a߿F~ٴ X0Pcek =@ H(+ @DuI C3Gpt~y2`c?/ bc5[+؀@ ϯ7y61gp{3dP?XY33Oß^r^:pf/0:JY篊ŋ +NC\B  0$`J-N:cIENDB`klog-0.9.2.9/flags/bq.png0000644000076700000620000000064013233376355013011 0ustar staffPNG  IHDRvbKGD pHYsgRtIMERz-IDAT(ύ̱Kqg T$CA D NAMA`JAK$fVf(AF*oxZ,ڧ^ZQ ? $JGZ"-$&3‘^6@$/ֽKR[&u|YⴇgEQHdo Wbdl6(F9t¯&PNykFBMӈbD幇p':i=sTgs]оDSw,U}IENDB`klog-0.9.2.9/flags/england.png0000644000076700000620000000076013233376355014022 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#߷/礥10ܾ P?T'zQѿ?#gϞ D\5H߿߿@@,h!$P_J;@jN !Lgdl_s `K ~I0U@,`m1GM_pЀl ߟ1#C)P(j$a0e#WIENDB`klog-0.9.2.9/flags/ly.png0000644000076700000620000000064313233376355013036 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<5IDATxbdɀ00ؿ$@b`BWZ\}`f6{jW&ɱ"4E} x_j "$296H! T/ *b9/ PE Ư_06H@lo`JAF im @W qfj ?,P9ӑ@6( (!!(@V* ` %"$ r(IENDB`klog-0.9.2.9/flags/pe.png0000644000076700000620000000061513233376355013015 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπs (*KA@VW1f?@˦M rdp_ee6 Pտj߿6Lh@/ĕ44 N_50@`' *V `うa` fprV @t@40 ) 6/$ѩ C * ƯH "B =a;n'IENDB`klog-0.9.2.9/flags/tr.png0000644000076700000620000000075413233376355013042 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<~IDATxbπPX@ $-(ҼN33Ȗ\F8U@'?yT R;R߿d3m `ALMAꔕwtk` @ڨII7lZT @L ' uq1W/$͚ffP M 10kk%=oDIČ`K/ E2@40 hYYAN5Bi`ARl_':8  F$8;\FoIENDB`klog-0.9.2.9/flags/wf.png0000644000076700000620000000105213233376355013021 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`A0@UWہ+/9_/c&i=7ʏ T?1!+ T@ 1@_2~fQ UtHĒ011|m흲wvHN)* 4 X.:0{:?׿~ttI <@,߿6d}%{z$RS_,Xm`v@1ſ@a$!߿7KJ]]nH?CU5]ɓ@?eQQ* _ IJ0Y d A?q)7cp00A=qtݯIENDB`klog-0.9.2.9/flags/es.png0000644000076700000620000000072513233376355013022 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<gIDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@, 3}^_/03f`@1 T?'00t|}/jb@v_1bØUzW[Fz@L`EO?Zf]#l 7P@11Ęw/q?̆@7  200w,0Ɵ 2x XfARC!@T @_Q#OC@ ZGIENDB`klog-0.9.2.9/flags/pw.png0000644000076700000620000000104613233376355013036 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd c"?#Yp('E0 ) YHkps{2ǿRʈ)kRqQ{@, L OHv?P,#ÿ2@;0+WjedxAPhub/H @WP_~{Mddx01>T^> &02a >[Ǭ  7ߊp ' X_??ވ c@s eÜw?xʬsw>+$> ~cfK0\}v+(3/#0f! t@12e?@P?h :ZYIENDB`klog-0.9.2.9/flags/un.png0000644000076700000620000000050413233376355013030 0ustar staffPNG  IHDR  fbKGD pHYsgRtIME;>,IDAT(ϭ=n@wm,c_@DD(%9 pq b6"fӛ7#zw?pB<) .+r!ZId}!ۃc1vNIK $Ep5 !+ 'j)`y,+s3`;%SchC$;{'hʥt`n *A_XIENDB`klog-0.9.2.9/flags/ba.png0000644000076700000620000000112113233376355012764 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`8.O.fQ/$ 1VIƷE1Sm*>^3mŮwaf20~l@K h˿ 0m.KOj @ Ts?8G?ϟ~AT Tq٫߻z'@?5_ @ l?_CN]?e`?6 ߟ?u¢w>A["``@s$>{ۀ @h:@l_Rhb2@{{ƏY3 ȱ@ ;@ Tj/ `@IENDB`klog-0.9.2.9/flags/ao.png0000644000076700000620000000065413233376355013013 0ustar staffPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<NIDATx\QJA=/wp\qH! |~e`..;n82y3N~NH)DB!HI K!ELp((p0&/`ol(D\"M5d|о' ӱ[-4a-bݺğu`f#bo 5Će3X#:y\YUAkWe[+|u({^Q&aQ=GgčSPej7``y"o)7cvfR\^+)m< HI4 Y^Yo #? AH-@1aã?~0B˗']8& ~aOh` 0 ?D3/8X٘8>}(L| bb0ā~}@, L~ h?'Pϟ@:@, _>"&OX/H5p|,210 û71 `C&5aIENDB`klog-0.9.2.9/flags/tl.png0000644000076700000620000000100213233376355013017 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxLA ]=3=\$IfMNp :J!s#5^ 1|?@?$˦Mp¿Oc/ $ f@ ?/aJAC40 @L@ Gg 6biknn8syI_`?6Hm[ʓ#kO?~ T߯@j1S__)) ﯩ="{ll! ??B0X@ d,? 3XTR"@Cux23$KK0 [+>$ڰRd"G/0   P=BeIENDB`klog-0.9.2.9/flags/mt.png0000644000076700000620000000064413233376355013033 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<6IDATxb#ÿ LL Hߛ7< @,@rMmm-FXX1?/6˿?ܿٳ?)g QVh@0hhh~)7P@{  oqUgj?J|$N W7P$ /߿@5Ăq 22 @A_ @ ޼yւWlAc0M[yvIENDB`klog-0.9.2.9/flags/bt.png0000644000076700000620000000116713233376355013021 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe< IDATx4ɱ (P|/_"7` v P3w~޼Mj@?00 3ga;7?oj[}_ïܿj w,ވpQg}yo? 4?滏z>)Lexp/Li_?@,L< ?Vn?2|bg`?0 F| ?"CA@!#IENDB`klog-0.9.2.9/flags/bv.png0000644000076700000620000000100013233376355013005 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|rsE]D3?`A @,@Qj )FFF0~ "߿n@,`{H|σ@ ׿_,+  U@_ @=@$@W߿@g@c@e>#sdv@m@$ H 9 @ɂgqq&&=ffܬ? l줷v~|o7~aQVz@d@ g'D/ H'?f ?$A.,_P3@WaQމ̮ 1$`$ZlIENDB`klog-0.9.2.9/flags/nz.png0000644000076700000620000000117713233376355013044 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<\ظHKWؘ_JrP \0 X1-k]C 1*=1M $1 0$)#$0/]]#߲ZAESߏ_p2,~-@[O'@ 1( M * #ػe]|f?| '7_~~fV9 Ư@@Is(?bj_I"_`gE_< XR( xN 0ffr߿#C0_@'q:IENDB`klog-0.9.2.9/flags/gn.png0000644000076700000620000000074013233376355013014 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<rIDATxbπ5|c.c`F@ X@@@%\302af;&ϟMS7XO2 Df`o~T-#  Xf Q?` @Ư_ D@ t7#P?an6DÿH4I@f#i$!@`'i%6 NU~?=P@40Qdm@ `/@ L0HJ 00fd L @ +8*?1h4ѳo 8I313g!=IENDB`klog-0.9.2.9/flags/gf.png0000644000076700000620000000104113233376355012777 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb,zߟ??022*'b ¦$A@? ~mE@40g߿ _~@6x=|Ϟ "@K890Kt&8@[zM"-b봗bP߿@*)qm@@/A00q;^ 7Lh3 |Tt@P?zD_6ˏ_@A]T aUV j=I,$߿@|z?.Nf &H@ %1d@|m?~}ˏ_Ҝ@ǏzA {f uDIENDB`klog-0.9.2.9/flags/be.png0000644000076700000620000000070113233376355012773 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<SIDATxbd@31c'?q @,@j ? x@Ml'O~307~U3m JФ@տ ~h` @@!4Hß?B?j?6_j0N ~Y Í8 [(P_KbIII722}LeàN F} w0q0{B$p ZeIENDB`klog-0.9.2.9/flags/no.png0000644000076700000620000000100013233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|rsE]D3?`A @,@Qj )FFF0~ "߿n@,`{H|σ@ ׿_,+  U@_ @=@$@W߿@g@c@e>#sdv@m@$ H 9 @ɂgqq&&=ffܬ? l줷v~|o7~aQVz@d@ g'D/ H'?f ?$A.,_P3@WaQމ̮ 1$`$ZlIENDB`klog-0.9.2.9/flags/ni.png0000644000076700000620000000077413233376355013025 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd( cC@*b` g2/@5M_d J3 ?#÷bj *_hPDߟz 6IQ./nFFӿY8sgO>ķP1jd ĂQ_Y (@1O]h Eeal[ X.wZ;`80B&P2@lHBAEa%@o& ~(o`$1h?x@ _"(=v!Q /1blIENDB`klog-0.9.2.9/flags/hn.png0000644000076700000620000000103113233376355013007 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd_ݯ.[ ? T"ПW. _~ϿAa/?'+ X'x:J| A@V@1<Wϟ~Ǐ7_/_Ǐķ!YXŪ// N6F?>(_} d96%ߧ~2@_?QTߟ^1InP_ b@Pz9H?/@1>~H3<G)<&I$cݛxIENDB`klog-0.9.2.9/flags/tc.png0000644000076700000620000000116013233376355013013 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbܟ_CsǧOXp`$0yf)7n0|OJO˃ߟ?~ "ߦN1 ɾ?4 eS6'_neeWVx5N/~SgIXkKj v~L\\>a{g1k2K@51Ȩ! Ƽ /e"l~8_7|ﯿw~b(? a>儕/_>n?bj( 5 h6 "3cϿr@5翤О?  oR_^qc?#C(j\+RL 2%>%IENDB`klog-0.9.2.9/flags/ae.png0000644000076700000620000000063013233376355012773 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<*IDATxbπk P V8)妛/F4e{/ђ"[@` ?y/=߿_ Ȑ@,`CTt^`dd| XNe;ȓI@f;/ NU~q: @Af kk_~JY篊ŋII?es!$=p$@ziٟ>IENDB`klog-0.9.2.9/flags/nr.png0000644000076700000620000000101713233376355013025 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdg1$  P#x?׵W bR?4Hʈ @S2/0?j0 d @, \03?Ю ׀ā ޟ^@,gҰ՟`d07!qS/@(K>~a#{O_ϯ 7]ϟ`W)H @L @glӞ/p0~]zӗo?}Ǐa4`O  &9w a?0S f@i FK(-r 9IENDB`klog-0.9.2.9/flags/fm.png0000644000076700000620000000105013233376355013005 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATx4 g4Z >㤭YL0"5bT_?s' *!@ͽn202 TMbar H1cd`Xy1Ph HHP@_CW~xPP?ДSނg m! tɏ/nV7/π2$bL^ @P6в@`IEt|rIENDB`klog-0.9.2.9/flags/om.png0000644000076700000620000000073613233376355013030 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<pIDATxbπ d`   PÇoqYZ>oh(?BϞ= ?{ףGXA##? (,&a66%R @'#*ee?f~/ ׿_`]^?7ï_ @CH$V 4o ~3Jz @_J~_ l[mg P(r7P'PBr뿿e@JJW /P {*T@1e L&20iyx9IENDB`klog-0.9.2.9/flags/pf.png0000644000076700000620000000076213233376355013021 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb"$6@a = )Bl9֬J )rE|@ @@A  f@_3\tc5#;!?FFƏ>?W?.:ϝ?}sb}󟷟2J^fW7 j /?z13AĂP+4Y9e@,%$w/W0Ƚa_v/(X$)7㟿@9߿ad"/q_Cb1/IENDB`klog-0.9.2.9/flags/fk.png0000644000076700000620000000121013233376355013001 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb_XCrɛL~10%?hTc%e< '? ?~@ 1;3A 1Q1<5e; 1H|z"'۞?_~ 1J^I 3 7M+ m׶E"A~ן.Uf?Y__9$j ~L~~|?a'ןoA6 C~7/{)aSH?;0oϿ>gxׯm=+ _Rh}@,B ׿ _L \5|CuOmk͉bةĸGU9@?@@yg~Kы_08~C/$I3O IQ?7H05(b 2eG$cCbtXlMIENDB`klog-0.9.2.9/flags/nc.png0000644000076700000620000000111713233376355013007 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd>1@B!C O.3~.ϿFg  e'|0l@Ҧ`YEa3?-}߶Q ܻwR &1|((12AP60 7,<ԃ lME"#VJQB]@,`8Ot̯߿vNL{h?`@$# l{?{'ٱPϟRR~7[ h?~eѿgO1 ЂB\p!xh֛Z|Lg_*! zH ̀AǏ$IENDB`klog-0.9.2.9/flags/as.png0000644000076700000620000000120713233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbTT`@Ʋr4l 1+! %12: =7l6P .ZemKݽH?8D X7.Ek9ٝs˞_>"$|lu{؟r2rqOڕ L |~}"# @1!;&  ; !6[1D# 0/JN&rH 鿿~ z:|5s6y,l\1YY21= ?X~`'0A?z11`?|MZyˋ` d.$1310H10 !IENDB`klog-0.9.2.9/flags/tk.png0000644000076700000620000000117613233376355013032 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd> c&y?01{!4'0$ %+ dÓiϓW#X>Y)voEϝ)#X#6t@11?~{U|@wyp+e_Nj@@}?cvK~Sad%'@e@ e{ֺg~fxoxG@#\+z7V_=J'(U'P1@l ǯ xع??w P_.{0~J;ayI^@120FK/ π1000e@[%tIENDB`klog-0.9.2.9/flags/mk.png0000644000076700000620000000123013233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<*IDATx< 0TK"RDxiD{ybr2}1x{rf _(NAӧ Q7HY~?P8Oa1#@H*15+25(Ў?ρ ݯJf Xl'|@ ?ͨ$bwd a߯>7Wa` ?O͠wY_A`8a30/SǒfxA7ߌj0(nahP?Yb_ÿ @L?k T@DV;0IENDB`klog-0.9.2.9/flags/mr.png0000644000076700000620000000107113233376355013024 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd0c@?8P(60CSd5b`2Zt\=9cEoϧ^>{CABHJ*d1ba`*Sҿ@@T{@?~120)@ח_J#~ߟ<@Hat__~f_X~+JH'PH@1_ h׿8ׯ~?寵Ͻן ?5?~ei~זӿ  @@> _{wץ_U 4h.P@49@:k)@_@qc"k0 o @ _8vbi!zh]3IENDB`klog-0.9.2.9/flags/de.png0000644000076700000620000000104113233376355012773 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbqf?f_ pb{qq9 / ~^n5@011U8y $?A~N@" ,X_@:~"?~@Ne@b@ь7h4LVg2-K , z#2ׯP `@;D?H%@1??ڀ T /@b`PPI@҄ab_A*$B$b`.a ?FL A@@@ X~e3o?6fA1?`@03b21@wt_XIENDB`klog-0.9.2.9/flags/lt.png0000644000076700000620000000077413233376355013036 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb}D $l bb j&f2?P@ÿߟ. &Fg  BUh.@\ _@3B7`0beu@a(s˗? /_ 6? X~0i)Ii@h XϟB`~h@T @,k[t hֿ?e`/PN?.2?_J?0.?Y8z00/fKJ  $?`` #rāg%"wCݙIENDB`klog-0.9.2.9/flags/gp.png0000644000076700000620000000075013233376355013017 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<zIDATxb} c 1PQV8GUګBcƪp"R٤)1O1~KK ##??&>47t 7 QBÔ C_aK!H(@L _-X gcb 2A  :f @,L_= tr17㟿 7 *p4ҌB#G =4(d| %J:`7YOEIENDB`klog-0.9.2.9/flags/re.png0000644000076700000620000000104113233376355013011 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb,zߟ??022*'b ¦$A@? ~mE@40g߿ _~@6x=|Ϟ "@K890Kt&8@[zM"-b봗bP߿@*)qm@@/A00q;^ 7Lh3 |Tt@P?zD_6ˏ_@A]T aUV j=I,$߿@|z?.Nf &H@ %1d@|m?~}ˏ_Ҝ@ǏzA {f uDIENDB`klog-0.9.2.9/flags/gm.png0000644000076700000620000000075513233376355013021 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<`0D v@?\9Up]?mȼ߿wSzh??q}  PK<D?/ۀUt (lp C 20f H@5$) rLLb\A @$0*jDBH?p+ C IJwOI;WIENDB`klog-0.9.2.9/flags/va.png0000644000076700000620000000105113233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|}^; #=&Ͽr?P5 H?E8/^`?Hϟg`??` ! u0 @fϗOP@16lzE]?ÿ``4g'O7 X}b<ٿ~.%>iFǎIɲ1 E +Ż7ؙߚ勗 u?P@<Y?n F&F&FVEb20 pN!!`xw?ÿe I ?hh0SF.7IENDB`klog-0.9.2.9/flags/au.png0000644000076700000620000000124113233376355013012 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<3IDATxb<^|CrǻXV*Dsg101KMy<"[M-ܣ1  =F;! 鐎>_aQY.3߲we~pkt ano!$AXx?}@LB]~~g-j0?Ĩ_XXkR_MZ]$mmmr}ZZڽ{~/00@$4EEEŋ V@)(0[b_* @NcHIENDB`klog-0.9.2.9/flags/kw.png0000644000076700000620000000074613233376355013037 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<xIDATxbdN``1B^F䀡jE rbc?ŊW40|dӿ 7HP)׿_@,, 7,?O?UADY2_c"d"%)`dd41 ?vj?n 6,t|?ȉh_m:zЅ`ɿ_|ϗ?, +6P' $e/ʇJHJ_?`E@F F b _"he);IENDB`klog-0.9.2.9/flags/py.png0000644000076700000620000000073113233376355013040 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<kIDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@, _gcc?CbG~nYo6 99o~ħpCA˧8?2``@1[5 WX Ʒsis>i! 3ӓ/Abs㗿&I8/'fiA 49P{AzK8 (UX_120F8IRS]IENDB`klog-0.9.2.9/flags/fi.png0000644000076700000620000000075113233376355013010 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<{IDATxb|30I`2.?A0bab`*kƿePr!ڝ_l8Dٛ@S`dd@5_ ߟ?$d 15#o~ @m@w?Po Јa_հ tl@ 4Β*NW7T`S9bad%Pj" /c`dxqh*Ws'>~@0cfr @V@5:<Yƀz;@"rVQ_(@>}`iIENDB`klog-0.9.2.9/flags/bg.png0000644000076700000620000000071613233376355013003 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<`IDATxb+Df($SHŋS`ddZ@,w>ݑa/B? 0DL, Ff2G~ B $ Dt c 5S d޲IU%sX Raf:%@a´f!|g W0aן b@s @,=q S@;JB~3˨򷎁 X$P(? $ A@H&@U;;qX'O<~<-IIw?}[n޼ T @WOTտ%K%&Ȧg7P],}|߿?tܭ;P,9@07Bϔ8b۪dljuyd9#/5؇9FxAZK$3 (N;5,bG/ʟ# ƫ+)C>x0yӟ?$@b /gaf9pd%@1ylJm 3"+)ʈП8~D6!?~?P?bbdgR ~$a0[b=+ `iIENDB`klog-0.9.2.9/flags/pn.png0000644000076700000620000000122113233376355013020 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<#IDATxbLN<=\ 7QpN5700|c`L1Qo}h1%  10C0/ 1 #E <-&;1>+( H ܿ>81 ()̌ @ 516F23   po濿?~g{W;$ _ϿTܐKt@(!.?_?wS1>4@120#G$A$@/Z:YIENDB`klog-0.9.2.9/flags/ps.png0000644000076700000620000000073013233376355013031 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<jIDATxb@ ow20\L@߿a$شi@50zt߿7Po8@dHuWo FFƇ?oA)L`j* ?~ht@,?_ I`K $~d!ϯ^XU t?ݪ'xז~_e~-G=۟5Y%H? `|P0_? P 1$@T1p4qIENDB`klog-0.9.2.9/flags/mu.png0000644000076700000620000000076013233376355013033 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<`0D X?D`>i@b`pbP? _@@lYy R\?iVo 4ᯜ0'8@iPڦ aF\(`T #X$H 2y4 6*)1 _?VIS FF0Pmb } (hBA o} 2C0%A  3jc@123E1gb0eWIENDB`klog-0.9.2.9/flags/fj.png0000644000076700000620000000114213233376355013004 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<[TkؘʟˤK~ 0T ?`?o@@1o]G\+}cvCC_  rҴ/2*ƫj2w6A,?bl/X $@l2HTzB ?xK!"^ 0W1@1=3rcXyoX}fW|~/?@61*( &%*.5WQ2Uo3ó1@\ Jտga~gr$ X  ׷)nۏO  ?F4B{)w{g_2 XI/IڀlF@ܳ/N  F̯ _`W @`8FIENDB`klog-0.9.2.9/flags/gh.png0000644000076700000620000000075213233376355013011 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<|IDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@,`J̓( 7P@ ` >7:BSx+)% =Z FL<q_ڴJNh#@1}2?DWD/9_?㣁ܟ0 j 2?￿~߯ߎmDemd ? }" R7 j D #- 6N? /05c Fd=  !pB0br(IENDB`klog-0.9.2.9/flags/lb.png0000644000076700000620000000100513233376355013000 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπ`$cIbJHtT1_? @o dM3@i?a@~ٿ &)%1H```|ռS~h,',󟑑-<@11011 F ;w?0?btJw]_nƋȚrd21:@5@1oV$ʙ @r>z PO`8~yO 0.(  f&` LA ePb"e@`SD>|IENDB`klog-0.9.2.9/flags/ss.png0000644000076700000620000000045613233376355013041 0ustar staffPNG  IHDRvbKGD pHYsgRtIMEUIDAT(c2(),*n*f^2? _ܖ&1AS1C{>}/Sh-k `b```􏁑? >0=W($-*;sc O <IENDB`klog-0.9.2.9/flags/ls.png0000644000076700000620000000116413233376355013027 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|- ?@}r8@,@/Nգ3^ BԣOϯ~fV~mv_@?_[= @1 &:]'<^O䇗w Ji000>Fj?|׷b~o `1'@(@]ۯ>?z,o~ Ÿ@  @^6rgo~ϟ~1KϮ \`x տ1Mec`z<&I>mP!j&@IENDB`klog-0.9.2.9/flags/il.png0000644000076700000620000000065713233376355013023 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<AIDATxb|%p.@1'*dALL  ##kYuߒ/Bq'@@\ Ua7g/?o5 @\5X?g+Uaޥ?w@ =)~ v\g Y ~@ $x 4@< @,.Z l ?e r?Êxmd J)yo~.IENDB`klog-0.9.2.9/flags/bj.png0000644000076700000620000000074613233376355013011 0ustar staffPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<xIDATxbd 10Æ Ck5H@ 3&J~ XX|}߿2cG"Fe Ȯ@7#єBH@ 2/P?HP4 yma^Ӏ"yf3up& z/Xc/$o`(HȨz~@ @9@A4@TC4j/HrK񗅉ߟ<@#߿t@1220|G/021T4$k<@+IENDB`klog-0.9.2.9/mainwindowinputothers.cpp0000644000076700000620000003173713233376355016005 0ustar staff/*************************************************************************** mainwindowinputothers.cpp - description ------------------- begin : Ago 2016 copyright : (C) 2016 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "mainwindowinputothers.h" MainWindowInputOthers::MainWindowInputOthers(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "MainWindowInputOthers::MainWindowInputOthers" << endl; entitiesList.clear(); propModeList.clear(); dataProxy = dp; propModeList = dataProxy->getPropModeList(); //QLabel *entityPrimLabel, *entitySecLabel, *iotaAwardLabel, *entityNameLabel, *propModeLabel; iotaContinentComboBox = new QComboBox(); entityPrimDivComboBox = new QComboBox(); entitySecDivComboBox = new QComboBox(); entityNameComboBox = new QComboBox(); propModeComboBox = new QComboBox(); iotaNumberLineEdit = new QLineEdit(); // TODO: I should find the way to connect the SAT tabwidget's signal to set the propmode in this widget // Now it is done though the mainwindow but I should avoid depending on that class for that, if possible //connect(satTabWidget, SIGNAL(setPropModeSat(QString)), this, SLOT(slotSetPropMode(QString)) ) ; createUI(); //qDebug() << "MainWindowInputOthers::MainWindowInputOthers - END" << endl; } MainWindowInputOthers::~MainWindowInputOthers(){} void MainWindowInputOthers::createUI() { //qDebug() << "MainWindowInputOthers::createUI" << endl; palRed.setColor(QPalette::Text, Qt::red); palBlack.setColor(QPalette::Text, Qt::black); QLabel *entityPrimLabel = new QLabel(tr("Primary Div")); QLabel *entitySecLabel = new QLabel(tr("Secondary Div")); QLabel *iotaAwardLabel = new QLabel(tr("IOTA")); QLabel *entityNameLabel = new QLabel(tr("Entity")); QLabel *propModeLabel = new QLabel(tr("Propagation mode")); entityPrimLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); entitySecLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); iotaAwardLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); entityNameLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); propModeLabel->setAlignment(Qt::AlignVCenter| Qt::AlignRight); entityPrimDivComboBox->setToolTip(tr("Select the primary division for this QSO")); entitySecDivComboBox->setToolTip(tr("Select the secondary division for this QSO")); entityNameComboBox->setToolTip(tr("Select the entity for this QSO")); propModeComboBox->setToolTip(tr("Select the propagation mode for this QSO")); iotaContinentComboBox->setToolTip(tr("Select the IOTA continent for this QSO")); iotaNumberLineEdit->setToolTip(tr("Select the IOTA reference number for this QSO")); entityPrimDivComboBox->setEnabled(false); entitySecDivComboBox->setEnabled(false); entityNameComboBox->setEnabled(true); propModeComboBox->setEnabled(true); QGridLayout *tabLayout = new QGridLayout; tabLayout->addWidget(entityNameLabel, 0, 0); tabLayout->addWidget(entityNameComboBox, 0, 1, 1, 2); tabLayout->addWidget(entityPrimLabel, 1, 0); tabLayout->addWidget(entityPrimDivComboBox, 1, 1, 1, 2); tabLayout->addWidget(entitySecLabel, 2, 0); tabLayout->addWidget(entitySecDivComboBox, 2, 1, 1, 2); tabLayout->addWidget(iotaAwardLabel, 3, 0); tabLayout->addWidget(iotaContinentComboBox, 3, 1); tabLayout->addWidget(iotaNumberLineEdit, 3, 2); tabLayout->addWidget(propModeLabel, 4, 0); tabLayout->addWidget(propModeComboBox, 4, 1, 1, 2); setLayout(tabLayout); if (entitiesList.size()>1) { entitiesList.prepend("00-" + tr("Not Identified") + " (000)"); entityNameComboBox->addItems(entitiesList); } if (propModeList.size()>1) { propModeList.prepend("00 - " + tr("Not - Not Identified")); propModeComboBox->addItems(propModeList); } /* QStringList continents; QSqlQuery query2("SELECT shortname FROM continent"); while (query2.next()) { if (query2.isValid()) { continents << query2.value(0).toString(); } } */ iotaContinentComboBox->addItems(dataProxy->getContinentShortNames()); iotaNumberLineEdit->setInputMask("000"); iotaNumberLineEdit->setText("000"); } void MainWindowInputOthers::clear() { //qDebug() << "MainWindowInputOthers::clear" << endl; entityNameComboBox->setCurrentIndex(0); propModeComboBox->setCurrentIndex(0); iotaContinentComboBox->setCurrentIndex(0); iotaNumberLineEdit->setText("000"); } void MainWindowInputOthers::setEntitiesList(const QStringList _qs) { //qDebug() << "MainWindowInputOthers::setEntitiesList: " << QString::number(_qs.length()) << endl; entitiesList.clear(); entitiesList << _qs; if (entitiesList.size()>1) { entitiesList.prepend("00-" + tr("Not Identified") + " (000)"); //entitiesList.prepend("00-Not Identified (000)"); entityNameComboBox->addItems(entitiesList); } } void MainWindowInputOthers::setEntity(const int _ent) {// Select the appropriate entity in the ComboBox //qDebug() << "MainWindowInputOthers::setEntity: " << QString::number(_ent) << endl; if (_ent<=0) { entityNameComboBox->setCurrentIndex(0); return; } QString aux = QString(); aux = QString::number(_ent); if (_ent > 1000) { aux = (QString::number(_ent)).right(3); } QString pref = QString(); //pref = world->getEntityMainPrefix(_ent); //pref = world->getEntityName(_ent); pref = dataProxy->getEntityNameFromId(_ent); //int indexC = entityNameComboBox->findText(pref, Qt::MatchContains); //qDebug() << "MainWindow::selectCorrectEntity: aux to the findText: " << aux << endl; //int indexC = entityNameComboBox->findText("(" + aux + ")", Qt::MatchContains); int indexC = entityNameComboBox->findText("(" + aux + ")", Qt::MatchEndsWith); //qDebug() << "MainWindow::selectCorrectEntity: " << pref << "/" << QString::number(indexC) << endl; entityNameComboBox->setCurrentIndex(indexC); setIOTAContinentFromEntity(_ent); } QString MainWindowInputOthers::getEntityPrefix() { //qDebug() << "MainWindowInputOthers::getEntityName" << endl; return (entityNameComboBox->currentText()).split('-').at(0); //qDebug() << "MainWindowInputOthers::getEntity: " << pref << "/" << QString::number(world->getQRZARRLId(pref))<< endl; //return world->getQRZARRLId(pref); } void MainWindowInputOthers::setPropMode(const QString _qs) { //qDebug() << "MainWindowInputOthers::setPropMode: " << _qs << endl; if(( propModeComboBox->findText(_qs+" -", Qt::MatchContains))>0) { propModeComboBox->setCurrentIndex( propModeComboBox->findText(_qs+" -", Qt::MatchContains)); } else { propModeComboBox->setCurrentIndex(0); } } QString MainWindowInputOthers::getPropModeFromComboBox() { QString _pm = QString(); //qDebug() << "MainWindow::getPropModeFromComboBox:" << propModeComboBox->currentText() << endl; _pm = (((propModeComboBox->currentText()).split('-')).at(1)).simplified(); //qDebug() << "MainWindow::getPropModeFromComboBox: " << _pm << endl; if (_pm == "Not") { return QString(); } return _pm; } void MainWindowInputOthers::clearIOTA() { iotaContinentComboBox->setCurrentIndex(0); iotaNumberLineEdit->setText("000"); iotaNumberLineEdit->setPalette(palBlack); } bool MainWindowInputOthers::isIOTAModified() { if ((iotaContinentComboBox->currentIndex()>0) || (iotaNumberLineEdit->text()).toInt()>0) { return true; } else { return false; } return false; } void MainWindowInputOthers::setIOTA(const QString _qs, const bool _black) {//TODO: Seems to be better to send the color info like in: (it is much more flexible as I can send any color!) //void MainWindowInputQSL::setQSLVia(const QString _qs, QColor qColor) //qDebug() << "MainWindow::setIOTA: " << _qs << endl; if ( (checkIfValidIOTA(_qs)).length() !=6 ) { return; } else { QStringList values = _qs.split("-", QString::SkipEmptyParts); //qDebug() << "MainWindowInputOthers::setIOTA: IOTA " << _qs << endl; iotaContinentComboBox->setCurrentIndex( iotaContinentComboBox->findText(values.at(0) ) ); iotaNumberLineEdit->setText(values.at(1)); } if (_black) { iotaNumberLineEdit->setPalette(palBlack); } else { iotaNumberLineEdit->setPalette(palRed); } } QString MainWindowInputOthers::getIOTA() { return (checkIfValidIOTA(iotaContinentComboBox->currentText() + "-" + iotaNumberLineEdit->text())); } void MainWindowInputOthers::setIOTAContinentFromEntity(const int _n) { //qDebug() << "MainWindow::setIOTAContinentFromEntity:" << QString::number(_n) << endl; setIOTAContinent(dataProxy->getContinentShortNameFromEntity(_n)) ; } void MainWindowInputOthers::setIOTAContinent(const QString _qs) { //qDebug() << "MainWindowInputOthers::setIOTAContinent: " << _qs << endl; //qDebug() << "MainWindowInputOthers::setIOTAContinent: setting to index(a): " << QString::number(iotaContinentComboBox->findText(_qs, Qt::MatchContains)) << endl; if(( iotaContinentComboBox->findText(_qs, Qt::MatchContains))>0) { //qDebug() << "MainWindowInputOthers::setIOTAContinent: setting to index: " << QString::number(iotaContinentComboBox->findText(_qs, Qt::MatchContains)) << endl; iotaContinentComboBox->setCurrentIndex( iotaContinentComboBox->findText(_qs, Qt::MatchContains)); } else { //qDebug() << "MainWindowInputOthers::setIOTAContinent: setting to index: 00" << endl; iotaContinentComboBox->setCurrentIndex(0); } } QString MainWindowInputOthers::checkIfValidIOTA(const QString _tiota) { /********************************** IOTA should be always with this format: CC-NNN being: - CC the shortname of the continent - NNN Number of the reference. NNN has ALWAYS to include THREE(3) characters. ADIF Specs says: CC is the continent designator {NA, SA, EU , AF, OC, AS, AN} XXX is the island designator, where 0 <= XXX ,<= 999 [use leading zeroes] Returns a valid format IOTA if possible and "" in other cases. ************************************/ //qDebug() << "MainWindowInputOthers::checkIfValidIOTA: " << _tiota << endl; //bool _valid = false; QString _continent; QString _number; if (_tiota.count("-") == 1) { QStringList _values = _tiota.split("-", QString::SkipEmptyParts); _continent = _values.at(0); _number = _values.at(1); } else { return ""; } //qDebug() << "MainWindowInputOthers::checkIfValidIOTA (cont) " << _continent << endl; //qDebug() << "MainWindowInputOthers::checkIfValidIOTA (numb): " << _number << endl; // Check if continent is valid if (dataProxy->isValidContinentShortName(_continent)) { if ( (_number.toInt() >0 ) && ((_number.toInt()) < 1000 )) { if ((_number.length()) == 3) { return _continent + "-" + _number ; } else if ((_number.length()) == 2) { return _continent + "-0" + QString::number((_number).toInt()); } else if ((_number.length()) == 1) { return _continent + "-00" + QString::number((_number).toInt()); } else { return ""; } } else { return ""; } } else { return QString(); } return QString(); } klog-0.9.2.9/klog.ico0000644000076700000620000026552113233376355012250 0ustar staff;kPNG  IHDRx IDATxwE=3 HJP$ (1;=ƻߝ =yzxS1Pwa8;3geβ3LoOuuUuW^AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!΀ MKVVn۶-BJJ . CJJ ۍvvmuZ|>_U@DAHbz۷oOVVtЁliӦ ~A~eUyّ#3|Qօ@)L0 L rJ(/+)//˲o&F2AHpvvJҥ =zsδmoE3 yχ?(mT>xm<ʋR 0PA0 \@XEqq1%%%PZZ~! y!Ah߾۷/:twݛݺ)++RQ^NՇGqy܎4Ja&i'Lٽ{7唔`۶e%B3`>|8={dСCIq1TSQQw<ǩ]4M޽Tҿ B"=zAq0tPڵkGݔwN Q ͐kMSϽU *eee N  4ݻw׃ bԨQ 6 5%Ŕ-/4߇ڎAJþJ+ֶZ;j*E!2 Q pzzCʖBFA.K=C9C=M]aeYPo;Q{X|Tשm_`5) RU#^bdРAbуB)--%8KbM?ՏW_jL+wdz?$uS__my$EFצ4FxyeY J. G1QF1qDRܹsR#ن z ?$ʨ;UTT :,`r\r /\Ө PH)w+D܎ Hq BQF1vXƍGee%vxngUj0BB=r9pRg}|q1%%ҒgՀ3 cAM#Ы&+B6E!Z%"2:"AQH6l?~<'N;wR7wN𑿓1cRTTDQQ;K 3nD ߐ l=0tCcMB @ ѣ0aSN)**a:QJ" ؾcEiZaˁa O4dA,׬*RMB" Whɓ'3c :vHAAŻwc 9y^6mDm~io@}#U#J[#SB# Vh 4HO2?'C-[uV6mĖ͛0&)W@КGy$3f̠]vl26_)lٸa[msF֚lHZ};Çm;xC?g4z]5kְn:,d/ԏF!q(RSSz 2Dy晴mۖ[)-) y>GKp~AAWfU,QDDRÆ c̙defef^/JGGJ)Ld-W~]@@B\E@H$ IaضG'PC)UHʚ~֭[YjkVo"&G!F'$ϧ W]k5Wzj|%B_hDilBѿ}I'a{ P05W?SVY)B_HDidBЩS'}I'ѶMnJǽφayfV+[ s_HhD%Ҹ'33SO6޽{5¹/k?R ֬^͚5kضx IEO M4,!ǏgȑoFiIIx"WZEΝb;K-iPB"QG]ؽkמ`WJq֬YC/}E!BS! IH(222ԩSؾN>˲ذ~=6n1 -j4wH#`}衇2p@nތlX;/:dZ@xFw҅1cPZ\LI !*^6oZ9b 40MS1l k0*+ٶm;w}A@Bc#4SNx.*:TضmKKE B-5@i,>E)JjJ %w5ZSXXȮb@ D4aKYI ~/|<_\\bib A/]tMV{F~KII^ DO5@xVqM]:wcE, ۶Myy9eՕ Q"ᄅF!4:55 ^s@kC *~ PBhǃ:8i^A 2% Ԅ4!h@CV ՑF ċtDDH@F$_B*_h,"! A*^h /Ɋn…X/- hHe Ѣi8_ZNh/-ql}H% E#J@B*Xh"S~wUj;5QZRB}of-aJ?a J@@*V GZH2? UU˻tHTP"H@'h=EHaQZ.RBMQ{yc֢UR/D hHe #zjBP7_#iyTfQjF(_"@2kHX=2P$?RiV/k8!@`r#:i¿Z#UvITXD-}k _YHe>ZLTQZó$#RQV/̝;Ea6͝׌9K*ZU@B*5d5?(̛7uD65o Lt>ej,2 jh/?~,]@BkmzRsr ,Xהk ˵:F<-ZRA-/?,Zெ͝s=ˬY5_- -wj@Os_# :(/oaCҨ%Qb-$>R1-e:Xxm%MP;77ɵ&ZE@40b#֙m bK3;;4 ey﷕Rֲ-?&jhIKk|H QZ0-rCaDԧ4c&~:]U(0M˭rs)ۆ9s~JJ?j 7Ev[ H~E bZIڰ8ZSgښHy19S|ca7T@.X0nXH^š),N?y}7RAa Hi+u> (-[UN!jiӆN#Fg r $gOT WY)6?Wlx]e)}4ÏWhZÃυ^ ״@ N8%t/~0gPF\u%Ǎp~AXer۪F#  r㍋Dk"}qLBHӿ8Q 1vUYm.l۸ bPP#*댌 ƶ f…6a7 EntCJA=MAy27zXk\.,ÆqO0/ٽ{ ۵F."/o^:/oA?k}C [$]"6?$9,MkXߚ:ozx9̝2Q6}>a- mY=~'=WZZ,rK,7^XH8n@JX $_F G&_v9C:~MMG瞅]}5R< O.%ϣ\@>S}`8O̩:GވZU3dY`!$%g1735QspѾ__,oݍ7Iϰjɴ&PYI'`Ҳedv֠z!*_)Rm۩y{ \|>ŇՓSH$DH>r_+6G=sDN|es6 >j/:L CQZZFj,6=4`|z ':#3%\.9昽|˹뮻+o^|h]mI)C$!ɿ32p}gn)PJQvkׯ'5͛PPP0 읻nU[">Pt٥ 8d>[z3^;*'{oЀ=2mYN'"D$B 'Fv&kMnԣ3fpʻc&Vhӡ?ǟeV #LWB),6mp_8y* ~po}[l+kRd$Ry$"K(J+UҶ-SWJJԱmٴ?d8kOԁΝ֚@E ا{&{wSSٳgsR[u&GD^|EF"KȒA$#*,bК5>N~um:NHO?(m\z v (TV{df.\%aÆ 7(w?{tP7a%'ZZKGH@q+3ucC TT4{d!k7c(M.!g{/l(Jah`]S i?DUp LC5~hlARZkrsE"M=o -¿~ .W]ofG)ibSqff]:Lޖ].z&ic.g݆ocݺucر 8Jk |-7u6Mjhݩy,Zse\JطH!'ͶO+QDr %73dp9% E_a7w22(ݼ948蠃;v ~G6xKӟgѢeBRmPK v2z4'O=Չ'?L͆P*lzmzJc.@Czǎ;\(rW9d6*g|33h'*;,+nw=Thﬠ7`mWfY! ;ZzޒgS'N[wF>,hӤۻ>f6; ϞU&e.W%7RvmөS' ,ˢ6OPC۶V)68 Ng/FivD =|х{樻LI_b ]]U(\l^>fCڶ*}8f*٠|Bf˖-ΫU/Z%D J)k!L+Q+`gp{'P+źf×_%u7,*+#ea[C9SYsFwO}W^UB n|-> cvkB镀D yh Pu2MN~Y={rfPp:񗔲UZ41M۷e˵ wǝ\N|UzqD;@5+̚5kxw#YJcAU/$F"&Nd4⫵5QJ)]z /n*+Ǫ(|w]v0 3%51nZBk|><{{ 0x*]./^[Sǎh#f8j`K $&u'i;&KJ۶1\n^|)eͿpI֕nc; .Ww}@Ze˲YTU:~eG᧟~B)a+r7?-Jt^Bi%z} 8y u*Zg I W_y;J GLEHm>yF8%ZvEEhۦqw%SO`X^/߇+3Ycبfryݲ[S9ߏO>bɒEXVNR[BĴ \?dRŃ˥_:%U lb:tglwK/Pe-t] l[0S&bCg=wJOmʹ4{6͜+==|BC_m5 wãh5Jf-Z֍50Q #j%G۸1ݶmJJa<}YpKHP8Юmv#8 IDAT)S5P7~''ƯxWFF2Ml-]Z7W8=]>ʶѕ5-ǤIne/xd8$D5`oW֚݀tuqˡ&Az! 0t0iܹsg; fL{1Fϝ$=fj ?Vyy m|;]+W:aw? ؠ)6ʶ"PVFjv6>=4R.K[@)RrlbXO=ӑo k.Y`h'E0 3Zu% t aZWZg_Vx׏++G4_Lɓ -b6] >qc|(ܵC[3|zxt>8:tF{ ,VZ[5TnM^uSO;lۦoܵvNu$%2bH4@}9CIKM {4f1˅4Mәw Uc Q ω+kT(p5^0M,_{/ʲdC.v>qt'jݻwxRSt]pWJ)**y vP;w`w!l-h ;GgUkmیuF\$mڴO}\?R! 0袋6mGR0#fmzja| mO?^CP]Y/?{om'@(Cˍ7Q_J)P]桿V-RX>1z-z}t";m[n~M͝_]}-U#dg N0Lf4SO:$J@H^eN9dv* @h!o6W^y%'N ;<ٴ˘ќt%ή}I>a[6^7fJk |9>*.je)'0 R~/PeJJpgd000th̠_{4/P\\:Tk˫ᘘ̨^TO?]"Ym+0P"Q 072d*#LJ)N=T.ZWw@J&ە1GIJ-{?;f̝w2|<*}|S6mތG&۝(L]t8N|U&;urAQ[lj 7"[ך+lL~[6=Ǣy5lGQ 0`@19|GɛoɊ+B?D NԣӦq;+t f[\q?x~1s B ' P7??H3*QeS K6SkMeq1}?SY/\Zy5MVj5jT1L"=ma#?NkTIMMOCs=sa^Q?NŘ\ L,~fhڲesw9(gqeeQ7p}5fJJ> c3bx(Uh _{=ra ++a=c_iۤz* ;Jjr,"V(rssk}^oi\,YeqhN{q.ν>$8g=A,˪eY.݅lٲ l6 09sIKM7H SO=;5kT7'QK]t]t1ܙO0sr9l{LڲHfȕWmtEe(-PڶQJ+6IR5~/4i={uTFRTD˫(~Y?{,n7ÆaF=TPo-C׫!j@)gW4>8F9فLzϜINզMB/\.gL: R-[U }O<0Ҙ޽.[_ŋqsX(bx.,R/9_ VJQ\\LfffO (++假o=N2͂ؾG?0vpdOMMwL:ޢ@){gK G)rUo(ZcSu+?? ^}[sJaWVѳ?SG ʼn̍s֔0{ҥ@n\ڵˠ荆n7^{]cl(7|m -[7'.B#Yf!'?%qpj),?#G'U'gx J&z+99 e `dݳ6ؓ^&kױ'0`GP7:LMGiᔬ]Kن 1{+$PVFw܏=:r]^/mׯcPT*? (ݴ1,xw9 pb?gd"Y?sG>ZpD猌LzyQ̒)-[t׮]Xz:ue9ڬm۵&Mg_Qwp]ǎ尼N$DA4 @w rO=Q0V2M{wCui8m4a(~ӽ{ҴF͛"֟| Çs^Y婧g]H>ِwh%71fU##m&''72{lHJҘ;'<#Le[1RRhUVv]g옚`*YG? 3^'ϤJ(Q b5tŤ`Ѵ׹O1SS TTSO!AL~cǎ ZkLM{ (rs%[P:##b^of̟??"NK(&'1<4!#GڷXOF}@pڇ$6}N;7/Ӿ}nPa{>_\7oaa*\Χw9L|Yy"v \raUVsgL_$ت櫼{m72?RqsJaUV}`_r7n\oUj ܁Ƃ?nਲ2N:$ ^Nl9HOKk'#)"##H!0yd;fyD%=m0i2&u.a48(Xt>?pnw슀ָ(>a&<v0mP ŝɰ? #ǜOƻc-^_oľ_AsL>諯)  CFf?r;*җB)^/6md ' ^N<ĽNIIaٲykUsmbHHQ/ ѿ@~A$04=w5zaT4w\ݛxkBr=z3řKnRkUYwRڶMtіEc mY)VE@)d#։3*Zc|dޟ1wؿMZ.?ALvO/CŶmI('JKg}~֮YsrJW56}g3i׷oҥ3}r4]< TI5{0=spFwaģ8t!$D QG9!/k3W},X_G-3{Ga­-1Q7|lݬ}58gOXlwF#0on؁ؖs @E_ݰ/_ڶ}~:̈́'?'%{o㧿KMm >'a{z:J2갘h>~<'_;OV* QTTȧ~ZcDli ^b*ӦM]v@UmV_ۜRq1}o~j>oN1bXןW˖'ydP~yٽvtkV>3(Ԏc߬Hk̴TJ׬ .䋹sT5GǔO~{:#_z3O®P\XJ~}wlϫEh8[nG j0Hҹt>r9zm{n#F 2=--7x5xKw]6sxgqzTB}֚~߆<1F J?IX;rԴZcW۾}{/__[?Q?T ct6,>J)6>袽գ;ﺓ㎠|۶y*@kڧfc9Q!p3sO) M]yeT-2ht8Ploe¶@y9_]r9gWK:9Ja\^ϖ.aF0 o҆/!3f>"~yN;dF)N@ms:·-d܄XVJKK)//8ʀlg|Wt5/R(M8i ̙3~Zk={dȐ!uW/ .h.sZiӆ;Mk=-xڶKxbx yr@͠K.).vVP &Jׯwy4R2uOȍaPq+/Ļekb|t9vpUqa))a_C=AQQ~GTiq8=pu-\h>`uC, ;K[WSғ'OW_eǎ5 m+@͊JӠ۵os?C›WD"4hӦM~īiQ2[c UϿ?9y :MM֘ia%?y'E_}jT^vC0xlrU!Ɨ_Į6jAii:D|̔q ggSO(EhҒu+;BǕ1Fi1ccǎ щDkcp{ vP. ={d;+(** Xa+3 8ls `a;w;m&b#:~s#ZVxKg "CW]uU3!OVxΆ3qJ)}9^{TΟerMdtUepӚի+b\6nO>,>y2SZNsvֿ(i-_yO>oՒJaedT< sӦ*];/}ԗر#G9i/o&j޼y5 NFƍy8V Lm6v[g 6\xoCi HWv^ZA!oY"14Vir-мu18䚫ZS,WZ::$v|M>,?@#نZgibyV?$B:$s)QWTķKn$Q.Weh;h \s5 s`:A&n]D(Iy勯ym{vSc͆\|Et-l5 E˻[ؽ{W5t1 WXw!U<4o_y= K9m숹лjm7zԟ3t('2\on ̔VzZ<{vP tfjj„֖B3?}I㱠Lm۬yI;|ֽF?Aߏ;+Qwθ{,CſË/[ eCֿ*ުVN`=^'m[&? ӟ}vNvv62erxgؽ{𼇨8Xp!.+ljrB]ۖv,.o~3zxXT!ڵoǠ4xѣ;gqo@<2R۷PaL^xg&L`WG!c ]dص2oahc_{t3^x;> =[ߟIO?Arqef<5 el[yVxgD(cC0n ?EYyaPQeֻ؆I7k} -g7Ҷmr!"PJqFFԴuq3^}U~簷+dwIKwJA]b*߫w/:{ fEs 0SR~|Q^} IDAT <,|F/Νx7yV8F?qrݔ3-=vxtdG2 xO< 6؁)99 "z;J b #%g_I隵tCYy%%%Ug%u m|yUpjڷorx'bʮi 03'wOˎ  #k[λ h5x]U~Z-RVțj?93ҹ+4SSqh" J4AGwˊ.իWþzKfu2ɯhMx:W`Fѣkv<64J6mbۧϐKCeҲ] ( c/o+(羐~O9琒>nVƻ};vVjDÐ@A|ed샐rX5b̳O6XA2<ʷmy_m?\SY*Vzعs^@̙z =N֡V֎O@ 2xR0M4 +*_|G}̎Kru3 w _q9dgӾ]{RjiZPl0 ~?;vsghp ,]]G;buO=YqlxuGq57< իظbNhrٌ];}Y^3%oa!<0_zm[®$SG{~s32?_$[7g,*wY:7\i:ucH% Jx23nSr}X8A/رNT8aWYxwp7&~v9N,8),D&[_{0]aK{?6Ol3 nͧ9p>#^y?Q'ףG;l,#FL1$ >Ox<@)E~A>l Xa3t{} )m$a`&}eP/h8z4f_F**r%;~@e0ּxxE6Q e^֗Mن ]Lc8~,_W0æi.gŊ17%%YNS:t5G%=#-$o>Y hiv,DQZce7 v4 vG}V{z/=g&/IFzڏ@@3tLkhEjZ }=}?[ᯬDn.]0p@Fȑ#k%%%^_~^Ŝ9s:ª)?4gO2قRSYē|8m[x"[?W6Y~һt6v,ݏ8Wj*'8@3% ?7CEA+ZַvFaNahmh;`CÞቂ2*BӆA?+`(ŊfK/A|nOΙga(t0=aPk(Zn2o0ʢK.xn|g=8O?{U-SC - t#*‹`ku-+] bDtP HO(}mwfL0=g0sν{`~^zW!;:ձ#n#y| 3fo1 YY\:(~ҥtv5PQ@ڻ @q,K6߸g6 #::xzteF((;߿?;tf2 A7a@qq˾_ƾ}{ݷW^q%6-6_~FQ[lYhLFhrn?: 3pf~^y.bHـ70ڽMQA6mc@h膁(ݿ,y}C }n~7߄HҧJˋ.>&#FzN;gRZ PŲw]ǁ?׹g?$77A ("2y7)޹ӬXW[رdg3T^U MG&5Ae`}ɡ?su֔$4_z?&PRRS6a<ݓ.B]0lxbn).d$IbtՆ,a{. 8xkCQհ[U+̸ۭ^ܓ `k›o[躎 9s&W\vlV[?#` $iiۑD KIqk~^5WOo~9 |T]cǮ{>(9jN݋Q/HiԹ\mX"#披8fQ9ET۶$ L H 9"\Řy Hv;x1suM#㫅(%"YwKTtm6:P?"`9Νq2>l6v=Vf)).(-GZ)=t/o"r'q޹q)$'E?1Z3_08-2c3 ѡ|? ѾmNv¿_+$22 n&[( O(+]בdNf͘M3=:grGGr-5t02#"ZG|j~)}om>Gfa!-Q|wux]Ѯl}-DLQU=w/R](@Epz1Aln j/Oa Hb|][\lM,qyX ={*W("*-֠ iXN:\x!IQo: jv5l6#'ӮMpaX,|MF@ 9wT(.)fb;i/kFQT:fX-6|>vܜ<^Yy @^lmvtMGE^}&@TD6I/ Id"!Jb8` iޗ$1l,Q1 <} /2jTFf8N R˨j0-=jm&!駎EY<S7sp rT^46<Qp@d=35Mua Z(r y7" 04Ν979G5O/hf +/DXۨI&ojt1mKJJٖ%K}_^T>}Dn]ag >f$'*AU]Cv*.[5YC@0$n(l`ڭ%$2x[vc FiI)W\uuI\2"s󉋎GQU4]痵kInْqD:db1%QEILn!6@!`ۉ#..o/V  pڝ%))ïq Q]85;vT5tPwoEnM[nVΛk*jG~zjt߽.,tgr2^|3~6mŧ Z-Yw]N<&MC5 ܳtǍfm@n( Oa¥ϛg.hbQDee߯`bޗ[ÙY~ΆtB-o ktt]r!X$bbf)`_|Έ# h V 4]L@40Ġ n^lKbߌC[o!":,,~oAq2)#xDGEkIfwK| EAqbAv:+:tlxj[vR8阕i"F1O 鐲l.?N (1uߏ-6~=ʙM\ަ[%v\tYwx3뗂x4lVEAT6ni:x())WI %%JJq^b*j&#N4]C``pra`ZiѼ7o1i*5 USJBRR]drƣp;ocj͂@֭*IV+23}CUGbbgp饗UCjo֌~^w + Fne94>0-2JI ?\M HՔX5N99٧q$%.:*Aڵ,ti/7sڍ7,!OA|i-$Agk:~Zl,[̵\SPu Uetؙ@@y >TUS\{0M,fjfQ!UL Y. @dT4111au"#"""h_zRZnC%5a8tYx}RZZjJ(qJ@Ii)%R<7US4մ 4 1UGYfBtt4AGU(DFEV6qq;t<708jջ.&OJndaf`ۇVo$"hќ>з }/A@e3>.+XF1b,r3Z!XSa|xGʖYtEc7UZwQݻ7?]9?P{ a= ^<@Jc !yk*5k?@߇*,kBahhJZLB4AEZli`}xߚZqÎiH6(>\.tUGD/Ȓ$ӟ&If\% ED >DI44t*I6p(bV 0tdY.Wʓ qoaing*8۫+ fUǛ=.A-:7l *Ч7'Nhuf}28b|@QQbȷ@ʸ|4䨨zKꪊ tv5Sgr`"uV@?ɾ뮻h6?5. [j.w.l*F=꫱'${,#T^f!)A lA *1l7En Xd ׬ ho ?gz`DLL4 TEA-(ĄuG'@`Q&OUR]U*VRW wI)n O#X5PC/9E `z (tcp޻uT~%|mh RPn (~i z=>4=d73t4뺎FTTU ǁsv̘.]3ch G=i5N*!I}>:& P˅ *Ae.-o7n wM|/@zn"J( }5k.'3W]Sc5ys^w};+O[4 l11U6)G #1cH4IpQz!6hc0[ǴAA?iL `F77cX0n~?~}>|>)>!TTEEUUsQp W_ PŬZTDrܻ n8ޕR6oڌ,|f ޽zrRTTp̿ev ۍ!?/ykZʼܮR<͙}NuJd`w;pgD$ٳ~-HVkse/x~w ‡~DIi B:kU/R5 j(7t.YhӺ5 ͚jZ:(蒄pf&vI\Hj/f7m8WQbdYfcʃ h7mУG"iJ>}8~VVU,zWdd5t0nW\Q/ݩ#/­bjBn42,@r8 A'1 A˳Ϣ3qߏ;#/lNG7`uO?/<';n_=[lx]-"l[v-1f7TЃ+/jJ>Lff&w^ǟa]q{~J$IBUK9q\[C]Qcdv&!Є dؠ+ dɡM۶A.;-Zf ~3LL UQC%(pJٿ?߯R =&Fʍ UV9dꘒʯoС*w-M84 p=g-Gs86$ #YyU/Crݱ#C*}grr8mP9c JO='Cǧhԩo6&L8@p|;~رc";;\˃i?n:m RZZE$T5_ތ ƌ@D iպ%yefx\4NF@xhԜlzbbcrQ\\Lbbb $IVYE1&;;;,KM៝7\n *E%p6~3TQ+-6G?ZDEWYWur0 ElªBӉhѢIec4kt4?$g?:vDW 2ÇXݬvl|a*-ޣ7!Z,w1QRNH@d;OɎ?qD.4w]v^زe o0\iRudfeRP'9 i9mO#&&܀4M ;2*l>咝K֭8̡x}`M./QG~f!oEr:u!KRX˲jj^ Mbo e àf}=U˄ Z,'b|^l1U Ԣ %*O>vW.cG]~R72S0;v`'XK!V+6+P=ĆbO0ӿhdԩC"IJNNfժUtTc<2pBPUٳ>!;'Xg"=#(_ dU6̷p:""Vo;ӪeKP Ib`ZX,X,ɬ ӲUKgqq W\R'aUQ ];c,VüWz@ w[g*[ 3me!i(f!36y$q૯X>n<{mqjfL rm9Ԉ,NZZZXYSN =*QTTNaaۤyW}۷˅ c6om~?y%Ŝֹ7L]3$!zWhMNɫ@};ޘ&vw%9zV YB?4Q, (b9\;S j l^MWw9xsTSdd!;U+UKd$k|Zti{SViJ7p7 I:,^͊N'3T6J7@${9V\iQF5Hg^^x%M% T/22^{SSٶmpe7$ ɗ]ĉg Eb~Mkmp '{F^~NȄf#,7Il6_(&M_OmPU-XO$sP>ykmj夀Tk6v>\n]%,j﹧V)ߏd3Dw^GoZMdO2?vUɓ'w^f̘Qi-[w}vףfsTf}!秎AV mAeV>;wB4t]#7/g.Fvvv(.'c\ylܸ UaXnX,v$Q@UܞR/o_Z|AڇiBD|UqgeWkN _LqK/%kZj A@)-%];F?4rddzsOq4dQN:mouYlܸO>ЫW ӹ;زe+3s/#66Jntt4N3z=x&mQTTKa/ _|>W_%ِ52A$@PYn=s>ݻvyZ MSQah#G% 2%M/7tAgfSCWul2g>rNH67wUobʯTo{9&|ct<( #& *&p+$t()aOr`Q4z~%O$UX5" nsw .䢋.ɱtYdEkIYzf1%HDQtҮ];^/Vl~\O s!Eٔ#G{K.$&&RRRGUD6}b*3)鄉Bn0DڬXKDi;W(-|wud,]V{ࢹs1c'YV+{rq8!4E%:%NIًv)a}^=!-[ލd)/ȈYH>',z<7V} ̙3ݻwνxbRSSjrN ԂcZH?@DD$@ܺ."8Nn7?C11 wAuAHĉtz(jQe'J:;ڵk=rJۗE0O=Ŏf?bd vԪ){$Pb6 geLyyUFEi%tl2; s0dz|~K V4NWO7 gOpjjsrKUM)ԩ)))f2 fy戢@4֯_Oii)ZK6f .]ʮ]K 0Gx?2Q\Bsla/W~w0 > W@߲4#/mewS1۞s<Q>>}Z(-a`x]xrr̀y+ hu9Y^Y3:\ue݆oU[+gϞz ;wGBWԿPPj%...h1cгgO:utNZ @]9sOdbcceJEB~r$@;v~k{Y$/TS5v2_;+.. D-dV jt!%_X""Xs֨hzOS WXpgfR{C$Gjf0iҤرc믫jrNϞ=:#2 餰k)Z0M M{uDY;v %%A @Uh`Ql˰RB( .H|>=sX&ŐŠGT&Xyk?6ae+/a:A~r(֭[/kQ7tڵ }gѫWp9ߐ8'M6'kGRb(.&Mq߼~cѤXc r7d%WOkP;o 0:Q<鄿p1V?66E1gΜgϞ=U59¿,B]Vn>Dw90tPl4 @h4 #̪UjW}2hѿ)Z@e4Ea^׷ުu$[m #aNJΦMնw-~聀\QDv:WQu︝ǩ:MJֆ >JRDQdƌLV!m[̸ CN@v89w.?=pZm0tBuX2*qk klɱDDk9|ybb QQw Պ(]V}˼yh_MlHC5fyc >-[K < }UDozj|' i"P{=fTH-.I7o>¿-`-)܉t=P^N;)[гhr d<VrD%"Tds$&2k%L{qqN0-Y}Zl޼ 0-ՠQ B@Xj7nD TݽVѫK/+4jexPʚ7nh|WFRRFWd9]uTUEUUĵ>/kj~z!ħm@w3yjZyFoOƁ?#%+WVٷibckaDV{-,y2B$@ӧí֪1c8|0ӧO?#;.n`wfѢEae.YhiIII\ve8c> '}Fve90ʾ*z`Gjqb4Cc14g3 H,X5 [l,c>ԏg\Ç9z REuPTt:5q%#j IDAT^CO6 w-ʔeaZywYx1ɵ ~Ç70%,X|"7~V\ul6ƍgϞFjj! *@WJJJ70ZlVʚbajexx4w5)?ATd_dO:Y& v`ԫYv㍸6 62T zt<)n)=$&q)8Pe!C,)nZe[jE۱FE!٬+ v;;fˋ.O?׸oBBg'**(f׿EaaтsNϟOnnn8 "7rr p饗vJv 49;pYG}d:tN; ͆iXél222Xb5v$BlXC+WmT8[t~*P%B)jdV:o~OӐUsQ**Ĵo_iF HV+%o" ؉Ov6-Zط }нyRj j%o6~n nF^}UF矩A{S_Lb>3ϦG$$$%YrHu"""KXb1bA^yrqc&;vSOVv!IR9~e.#i呓æMߠiOXZ*Z ޅ_1OMA8Ujl{}6Zg>On|AZM65"uP\ٲ6q;WpOH ?/ <3&cG3"P%IBs۵}0rȣ8A4JYN4!,[䬳")) 9S_ 9f͚!z&s ==}g8W_gA 8… OBl~n*m3NYE(׿ߧ3/l#Gb| }*clUAsiDjU3f#r1T<@H+XV{/{`2IAZ ߨٿ}KuNDضm1vvW(g*s=ޥK.Bl6q2j(4_akFmUQY @h_XXȞ={ؾ};s̡dj۵N@ƍ,1_A 2+7I\#H_&^A)8gUٮYnH?eC+W!V]R잿FUX"#th xrsk5..[R #5 x0|a֬Y] +PQ๦i2vX"##nݺ9gXd |1z(q)p:)ucddd 2bHYᯪ*^CΆ bK=8q"s&]A0tM>;>DDƿZ&0tf3T`ADDԫ9hJ8&Cjf1 DY曫"{*[0\=P$Yw^W9jA81e 9fEpןvo鯊`5۷/ ""/A w}7/bu꼮~d =z0$YFv'QQT^8ӧ\p)))8NdYFe$IBr($E!*2m#رgΆ>)jZ@!0?zELLLX EBW4OLDelv;$).*;odU0HMM537܀7` Պ˖߶ _vΝ;Ylm4~Ku(a#1/jPH> >1:ג#d3g*iy{^w ß~OVT_DD2sf\]$I 8޽{WTg[Gi ,^h^{.Ղ(am $3 w>aX2d[.g(!:h(""V ÁbP '租~:&cE7ވ>aHbb \E!##[rJ/^(od3t4ڶmKIhn+g: AD8N sO;? V[*3l#(ڷGb"A% KD]:F¿Сw)-|f_Iy~V/d4Ȗ-+PfOeӧ[j%SSSy'ܹs0mZ5) G1SL!)oA@$h,}aL q(3gr!^=z`ZMRPPa` ugxIzau=z1qDOE %Yb!~?lb׾]|>v޽{YlYYYp쯷C {)>0TcNx>^^/%*‚_5dQ;0~<$ рdgwm٪%Cץ Q b=dJEX=mz c\wu޽ p LDMA>};64\jΝ;i;F#'#1Hᤸ#77rsr!$ ~qèQ$I8NrrriӦqQ~}Z:vHLL F!^HaAv@Xx8f +b:PsVZY?~+#ɲ޽{ٻw/~-vM{FTT1b&==BAA˖-s!.>N*/`Eeͪ)!٧Upg`=&MAJۿ?XǎgUi?<,Ml:gN?:5Q?84fUvK>v)gRӞڵâY_~9_~ {AF(*`6Sx8_BE_9pM֭[3k,~>Cl6f$9rd?h̛7Hݽ;7j :ywab6l(qq#Ȳ$K^t6Xʪ*$)!!$f͚Exx8$a(((>;v`̙}IN/"FW^4lؐDTEWD@67jwݻ7+W;x(ЬY3k.LfMˋ Ef@fa+aZ)).fݺulܸj;^ykl6Lll[0''qq!zINILHp`infVEج}ذ~cu9RED5iR~P !KH1c8bE7s:r3vQ\ )7Dm ͛2>B Mױ׼Oy}>\IöY3mzPoDDo+l|g,]kaÆQ=JΝrг~}ee1(5<$I{ 8~vb,,:]vedtBRR"9srrs%77@W ĬY4"ѣGٹs'}T P@ՋK.!CЮukJc4$,, %+PRT=۹lePG|f٭kB lظF||HKK^z4nY1 FE!&&N:PDШa#v{3fd~-coӭal"H֜ ~u= =IQ绍쩍+OyDe9cdOZxV,ǖWVl2w?=.h[oѬY X,3 /k&L_ΤLի6ҞII\0`X_,9x7l`Æ $''Ӯ};:t@ʹ1ct$ ҥ 111^0RSS'>>H7|Sр]߿ݺ!Zִ!\@ɟ˞V;T8Ȏ;@I?$@f=@ $1qD5kFǎINNFU; h%F־ * 5A?`뫯񟡗pdC/C>~<>s&>K+"0#2:2hPPSl6F\:8.zmlu!,?Y_oԨgfѢE2HJJJXxq52t̩E^HIJKcAùm[칹,i9^Ǥ5YILL,SG"##i޼9=z+5A/ؾU%dAKehFj?Z0l߾z@J͖BgW;ׯ/x`0`X óNUo a2PN!0軞+-|V Jр'Y~=4ޝ&жFb?$ f#c{v 3Amd=6^mq  O5nI",>J͝Kdrrջ,No{hMK뮻hѢt!>`1 (AjzGOlJH`Md/..f-4m곚d2s +, [B*~j 5ƻх{GUE%%%3gEwdY_':eƑS5M"::Z;$2220 { tOvݤ&$@E7ze#I֒ʳ@*9'׭i5j]z-W\5!PZ^1VW?ro8JfQrHZ]}:~+2Vkvh Cʇ=54J u ׻IQl66<,;}/\˖-?~<-[$&&j<û˚5k~c]0*-M3Bh\a0p{6\ev|#N'aÆ$''ӿΜ9#SRttV*\Znt,M |$Q*bu6 bԫW f;S ! /@Dշ*9{>˖qエv 韲r- O 2%<#/FQĶH#,.͆p:srݸ"#W!'/rDSkJ)2ΊԄu]kh4ҩS'ڎ&O͚Pi}gpoѣ{,v0۷Өq#M(BAǎ9r ''GdggWM d*6Ǧ~xVj('@%P5= "55,ILL1-jbpu=g48P"AGq1ffcDGl0 z$m[UC b0J`+~*;8] 3xĄZHg<jݖ-[2k,ׯjl6wux LQ1}{ܙ汱EGhÇy|ֹ&YI90 VCس#,уbz_]mcbb]UQl$j'@w 2&7χ&PN`ugZh!:wL݉"))RЅl6&G )vV) z+O)SNIZ T1}b04ּ H~M#d::sl zRΌI7nW^y%Nxx8={ƣ>>|{M Q%G/+l`t#܃)2RP=$kލ?1lz Ԡ] Epנm޼9/]Hn0ƺu?~<˗/ %2ǻtΝd!8$6mbΖ-df상9@Jn1 J+%B,Ѯ];Ξ=ˑ#GDAAARJaB1wONɋU1N",aCݻ7)))lْ%B6(I=/i%_㳝j. !wt@~ ?5Tf^sʎj* hd…8Pr w'ڕCX8  E]oFNN}AKϾ./SNdee|rz&'dtwmba0(>-[<$ 4PrY3}:3g* L? d!} d4b1װjʵ^K֭q:8q%KvZڶmVPyѤI.rmf6j_qh=ђn_-[p* y@*nNtuK\e3hgg>Or(Ջ:Pkdd[@d4PN{W7j V2g)))) N2VRa(/ ر#IIIF}o<;hr\<8x sA3;vգ(9sXK 2m ,C+%_N{SD[l̘ zhb7l4sB>0kVzp_lv>uU]v1sLVTs#'Or_OXw/ | I`ݨrd%[&--%l1Ji[{VJNnͨduذa4jH!{K!ʈŅD="**TAh·! +v;x?ޚOxB"aIIHLɓL裘""V濞wslfP 0qD233)**bڵ8p ?y$O?4;v')))_ꫯ={6 y<#ڴjMdFAx>\.ǰ0F`p~RSeO#:*B9z(G i7>:ʲf*\υ(L;3~(-^VRbcBԩ餦Q xJ$eL΀+(:qYYbIp"Z(i {~>XIMe+/-Jqv6Ů`Jk}!0EFm?u7>5aĈ7$I_~oߞlw8m6{1ȑ#kDW^aΜ9p3oؐݻӷImkb4bۙs'36l/P4FB܊&t1ʌR_\zHOO]v>4炸8P@Q$**]lU~+:!(((pG#n E :WQ|kNg @_4 #Pb/G'׮Kfh>昘|`0ϰK):v GI OԨi3z4A?㗇&gϞyӧm]`eAۤIfΜIZZދ#::aÆq)~7N>9@^7߰j*FE߾}ʁfc֬Y̝;$4у !bLQmܭ[)q:k@!NW xQٳNjݯ, Z׏( ݺuСCر㜣q(fUIXsG\EQP՚sj5@|/{P!onhժIII^_^\q*(h,m% @eNG6v!v}!>;[BP?#kNNpd LoC* #2ݍ)**dѤ__YQ!0EEqz>O58B`PT䵞^(ɚ$ YgPǪ/5k \/V$Ak&_k1ǜ+7zK_i=|uŕ>]XhwuW\ADDYYY L&Æ cƌwy$N8ٳy UXz5_~9)))kDF^tOfew Fr7ߐp!I", < / 5]zꩀ 8_Jff&mڴsDEEi3{2N- }H5WU'] W,A}iTر#iiit⟿y7$I8TUK=]"N$In6;y믓Z;n䇻dChU+R'A>LbY>=Q?/@ƸqN#u&k׮Ջ/.2_\߲%bKw3 KZ/^X<&\<7)kSNKK}t\(N+į*F_N$V襀03FiӆΝ; @W[C@@+etK$d \+ЩS'̙3gHKK?gżKAyG~~NN=w#NׇG~dӋ/}xG$J1l !Cʌ%Oݷ):RK@el0Wn&&t>YF$ܵf|Яf˙3 ~6P?-@Cw7%=KJJ 5*w5w*NwD$ `P'FHI2ߙg0vDXXqqq"11z]ݎ*|R \>V ܓ7tPZn=m6SLO>]vAԖ/?̗#]K0ELQg_AΟj7lokrж _s b6iRP=z{ѷoJ;vnݺ-k6 .M***bر宻}vƎK6mQS{ͼz4X4`0P ް 9TXU.sKIG}KTT( 'B#V DDDhMTTedY&P)4z@*`RzꑐUTT _1T7UT^GV*6InQ%!![n%S#2yyyƲh"~f̘ԏ,|$-.'W+j xxSe I~4z MUc+ (8v5ϯ1"Άs"FFF2eC:@PU.]PC&..o .>JNެXiӦO?:6={2ys$U v(α`2q'w)a8P#]$~G̚5 󗪭.^zʑ#GOZ 8Rk:_SȲ̱cjdR'A~V)pyrHovMNɓ,J Nbw?HqqqAҦMC ͚5G)yBG1yd tJF~(+g0iZp j ;. >Mh׮8拹N@ӇIIIl޼ 6e1X\l"Jmg$8qNTS):yϰղώ>:H^HNN&??f/j$@sb* ;Y&_4=qmڴaСAqUUgԨQL>ݷR(l|9v/^y3Ӹo_X;BQhثÿ۶VN0!u-c]!/^ jհ0СC8AUURSSC,hAA/2O?;5M&df\osj2q&YϮQK`pcRF8h:u*l:z8::޽{ӳgOTUeǎ\7hl\VR$J*NRTTTSQ% @UK#xVx p9"""ÇӨQ# >kh}N+fakGNh4rw= vJJJPU~?SrУ"} 2k֬adddТE |^Arr2Z:#G0m4yN'F#33ysgb46 }a\]`pqR LGDkVˤ,EsBfA >.uֱvZR@REyBr]ġ8@M8 I_)`B=:t(eD3|UHI\wQpPrO8'BhҤ }_~%>lP^5kt`^w}__6(7H{)sڞbaIM šY3;AKINNvM&6UVk.w0G.شi?;,*;wHh佝;q#de/@8~~snf1EMFqqq2LmۖtvŚ5kDII Q(jSp!=gNT w_!h޼9-Znny? avdIvU됴(;-VI8{,k Ϣ=Zy٠(Xbb8l/Rݷ$wRo Ԗ-gإAIԩW\qE>Dnn.| ?3EEE^5C׮]C]t|7mۖL~'z&'r}{-s(؀۶`7X\ ,e@s7^>CslhD+;/k}XCe_ߖWnӰaC.6l$K8W- T8NN4SS}8QQQ87׷g:@tAy߇nGrEtiuKSG8u/ƌCrrrHK$IBQ{/ jSg]ĩMͦs/B:ķlɐe/I>sl%$%h{u\׫d0:,Ao̵>\uXx1< 6t~=tK.eÆ 8NdY&222$:^uٵk#[`ȑ~\޴)z5oCWsG@zhTpoQ0 0-(F=ФF"K j~ϙ4;NqC3Jwc\$EH8q(* XuzFDD`'"G@7$p{53_r大3|j#3JDqq1aaa+[iӦqJo#!3{4,qqkPUFbƍݵ-[ۿ{a!qD4!uZbABf11cǰQ)2ƍ+p˾^|;vUVQXX&B۶m۷nݺqחW0c Νh׎)ݺ "B2g6#;7o]WGhݮu9h|{cD1=[5>ٿh(YOM Iɺ7p8 j-&.(8N*:A]'3ຨQQQ ,<9 j3 I L-u#$qc2D ,Kzz:_~%-W^ sp8t.{BQcXz#H2Át"E3 !f%%|suVOOO穧"))Y򩉉\uUl߾M6a:FΊ+8x \s%(8pG}O?zaaӹ3v DuX,r37lۣG->MNu`upp 0hҤ1%%e]_tڵkQhG:w]7~(#\&EEܼmr4Gˏ'r &=#*3y.Zlny"m%l k uQ IDATqG f7⯨'${M(Ec$Յ*2ۈ yh4oziInhѢE!k#G2{dug4>3e뫯jtt4SN{X֐qEI&׏ /%K?t:*F#Ge֭v$FE1Knip +a6s('׬a}f$GˏWqf׮Im~*g؄hԨ!e+hldE+#,9g"{=/  tEuonYY  T[3cx8[j$ԺGnCUUl6[ȢGzIsWseL&{e֭vf$&l^ HI ~(`)]_\њMe/E*p+P\A%Z@ u; e-f@s]_CNDDDP$I5*TgpGH0'b`0B8.Z\N6wCy.t:59.ւZ(n6LyA$I_J D~~>˖-#55ݻ7 'IEEE4mڔŋW_n>v-G]Ok߻{]d0 ~r,j݄f̘AvB6BO|}ǽo햔I^>|Yǎqʕlw}eI^=(Ӏ#ם: F3HV+p$!4bR{\'LR^ w֕ ]VUȠRzԚB]r0ـ\uW  fpF|?_~/k$uG+Yf!袋܊od2qq 6nn\XXȀꫯ$+㽅ש3{A[!&i{x,[VZ,*Ak׮eFL40͛GqQwmK΍7Z/I`0.\Ȁ%K؞4MM_V? ^Zs͆>\Z dYᰗʫ]WL hi_AjKខ« @UK{PUhV+F\o>ЍhzRUխXFJ4m(plj ;~3&舅eJz111ߟǏa5$}vG.]hѢ,{ᮻ⪫b٬YCu8u$<;z]P!ΩŐddfA˥^%\R-yO!={0gϟ@=CLFc}s֖-3g`A ީ_~DDeuF׮]q:,[ E\\\,, ݺus^|9< @Ө(ݛ˛75Oq*+o܉յ[F-{h4 sH@ xRvq+HDv)rΖ̗esGu,Aμ$I8VV>ZԺgĸ#E&ӧOtRZlI.]X,v֍0/^̌3"P=ΣgFZ~l3V+w h3GԑATRhF_u*$(h>ۯ/7t3_{:,I8΀@c{uq xk b޽B_Eu*M&YYYt`0o>8@FFZ`0kԩSC$hޜY=z21aVhdٳܿj;huvO57T^wB3кK_!|&W^wM8u*RIpc#;o7]q8DEWYP,ڵkGqq16 Zƀ+.C 4YQ}T^?ڵ#==͛7gϞN!wߑJnyjץnݺ_p* 8o ,O;"{떠8p Ǐh4bZݳ&@FFlܸÇWfɒ%lْ ȗ޼gݻvfʹܾ%Jl[J\f[nO5Ts84!!hSPKzB'^VTbbBEטUf?t'|$@cs1^ߞo s}"zZЍht_‚Bb8:'n3_^$ AY旜,jSPӫJrЪU+.Qi3"[oИۓSؤe²ϐr0hw6 ""sϭZbݺuJOq8U{_SJO?C/(*p+zFB@3 U[V`0:.NgF@@@IRXi b,,fb1$m''LEV ~Yλf: 'Jرc[€3O۷~222HKK p8X,7bKϽ2(p# {d穧j$r[ڰa?~]3{%g#cĉnNHKK#55;vcF3gΰ~zw8:wΝTG~_1dg,tЄon n6ZE#?x*4簭Bm5Q_V(^9T1=2;Aj}ܴiSv;&L& ܹ UJH@yᚂ^QXߟg <O^˻m!Z@,0㎪kfr:M~3>\#:S~zRI^_ f3ij"o߾=lڴ{6ߓB׮] 3p@X>?^OL5LZ@ &[_{uO?SU cƌ[nAyV:?sΤm6V^ի$[x.?{UϽwf;HB-W! "bq]t-+U]A BPwd2ydmsڶՌz?;7o{S*Z;!4t4K|lC[ˆ):+}^RZeA@e眭#P$uO?UUE{ @ڰaC~{@YU @Vmn;N>][}o YK@heL{:_(&#O_]6U7o'iaM&# r3HY=sv 1zsZ рtիm۶eÆ u$IӦMڷoO?Fbڴi_>{#[v y$(IVk ^!Haa۷5O?MmAֶm[~aڴiSocԽO>q/o҄箸`c'oy;6 LXI){Bob_'Il:SgqDEwc:[Ldq~3ԅ߲9ץ R9iLKKiӦ޽۷x`0l[{ңGRRR| 7UVVҮ];f͚Ŝ9sPwn>6c*1,vLQnD6J]2,#H,ѨDnr[Vb ttr)G}ĬYp8It߳$`In;vq8'z_'U?};uq ~^ETs>9F}ן'E!222$@S_-WZZZM WU‫0o^_WIZNH.pxݺu;/ꄞ dwe:xOx/7߹k~a%& "wgӜ/'Iej*0t__9tPTwNBB{dZ>|8C weѢE!߫s{rn^ڱbb1DAtZш(ic^^siʎ 'OfȑT6L|̘18rǎ}Z̷^ș e o8UMhjw \nD'Cuṃ# -.ʊJo҃,6{fEW\DEEF09:$I7KUUjΝ hztbq *Ε89ppF#?yǏm6zpDGi;Gnk'_|רbe[#:nCtTp$lAqxN9"!W@>}h߾'((( 33Ν;c4eY`0O0zh^}Րd=a++VVJIB$MW\Qo`0xbf̘AV&4Jeƽ_ p&[JhOtp-(ꄻ꧆? jfY3-jQ@QKC͔jo6śT;,LJ{"!&&Es\])7_(ŹW\\9xK@ζ\*pntgwu/7 ڋ-[PVVƒ%K駟l.c+a/X52%p`nҐ}q0-q Ӭ=N #'uD{;aȐ!׏0_~w͂ طoKV+M4> 4.bccykU (e^}U"Kg=CN-xF}-$NFgr"?8Aܹ.( ^.=sDz@3YhzsHV4_+5h͌uP9-mxYC6b=#ު<8.=@JlI d6/(kنCC&$)cbPFwtPQڷoM7Df:zY|9FQo 2jԨ{DQ};N:aِ$C1|vΝs3eFt~%Eaբʎ 8p~o1-gVW|5In="ZB+$4C0 Mulۂ>Ƅ$UKz遢@ >GEE]_j]O***|#GBջ,'Bwco۱X,U!l׾z 7h}u)A1p@j Qټy-",?k.rrrHJJ=QL&:=7AQQ1v#Yȑ4^LA1Ff濰}ݪb0+]"I8qdffҵkW$I&MĄ ػw/~)<XZlIn0 .sN޽;!IAWTT? >}m oq0w&Y]G߼$Qp֭Lݶb7MU΂fA#*ZuE\rn3Z͸Xŋڼ^ ?T/F{ߛ /@mW%: ;u(>W\-ltw Ǻ;T::[]V? NDDDPVVƱcرcӧOS\\\:UL&őFff&͛7'##%[nMٺuɠVϜ9Ò%Khժ;wvwŋӣk+|>)Im ONā~9q.h\~ߌX 0_M>$ (4E@7QH}BwVi>zK 𜷽mnkQٗL@DWпlY ze_f>JN5p8@ :.@аaCn喀%&&2p@>ݻ]"N#T:R/S(-71ugXqW[>w\`͛7'''0ױ$MEӱ6j|+ z÷ƙZ?9vFٰa6- ?`߾}.~@}6٩-Eqxݻ۷TTTO?l/Ab +g>w`iAo9huEr1hDO@6XFxsW3^ૹ9}-?y{jHpI|??%B jVڠR$aA m޼9C%)) ł v{,MhdQQiypMdΊ^,#I{ovӗQUǙ5k;v쨖:mvA5@/QEGt$]'MٜYyW%'‚*KJӦM[СC qF~12UUbj*ǭ[kphDG2:BA;;Ќ| NNT\&?e6q,V#J3h͝Ԫk.ԜE_($@Qu=Q%胢k=U"WtUXE w1}AK.\uUHāHr:{hLI&S) jX=Pe[ИӈQw1߻&Mp7ӻwoW{g_-ZDIIOd$ng. &X5KJ:AS%w#Gl|z>R.GĠ9:p@:bbb .dÆ 5Bk]s5\uU5fyb4oꫡU Mc&>־wP?ߌV:-.pO}ᰣW:h"[D@9} Ub4K|ݣzt s1- P\a,T\p]Vo@#xy]LdZY=ubsx}aje6~3337nZRU0JKKo_\vc 4j=3m۰7#"jD TDEDeGY5{::v˓ i8FE>}0  v w^̙UP FEܹse]ZRֲ_&\hjuu䛍ƼD3ᰄ1<+;wczEN}nDA(P-E넿{@G'@tHZu3w:Y"X2EQI;}_w%@V=*83jֲ}ewDLn ѼLN|z2[̓0G1nºD^y}ϡ`4]р*q\Ջ;j*N8vxx8yyy:tΝ;ӱcG$IB, ~{?|7aEgo,+@!3“䯽&DU֠n Zj֭[ٹs arssΦI&(*mڴ!99x+OΝcs=vs"elÏs9\IE+h>}ơ4FN4Gck;+* * vF9Tiy ýxFBXU:Rq\o' S/8 !;ގ>@JKKmM8BfwT]HUVUXW`ܨXƍr+*YX *l/bgzϳ/.@NR_pEt{p@hqqqH@|^<ͰkҿhA]kpֳ*>pGDHE'O9(+SYEc~XU李F2,)Fzo `TdEMXmڴ]vY]vlũXp!-[G5dlUIϿ$nAͯ͜|Sa }MR,Mhj3AX,r7rA6n܈l׿{r!W 5n$I?fҥ\#?[d`qʻ Y :ϧ-~ /> ||.I_UqMʨ5A ;9TVp߿F \?\@wc\RRRGj"%xFA"UWqYe:i]xr6M'ø{TёM^gH6=>Hgx$1pwތ7XfF^^sa˖-. A9tY5{6DŽIbMn{'{rzw& 2[izuj%==ѣGӥKux8e$2c $p$"Dx<x H@S;\V(~}8_}ߍjiݠ (Jտ7}9ȀN!o`Ԋy/ϓu/ .E+UUQ}8K>SMHxLFੇ۲hu2iMoJiDNRVn֐Y1 6ÇRT.p`KLd׈D{1=G!!SN\FYՅTU)5Hì;4]taȑl2Er{{у@o|3?oTx/'I8$12Vʍ24E$f]wŎ;Xz5>Ǎhtسg={tH+ŝ;o/Fl߈s 9"0Q9f"ti >wpvIIvQׯڵc~W b~~>ͣM6tդÇpp$G1\/$-P e^?ໍEYSu>OnC hvGo?mV a0UEQw7P*Gs ˡ\&T[{F> lv CUnߙQ!+ ZJ_A8w\}+4O3r۰x3nsljl]CϘhfa"]fff5~/Е7oW\ALLIDMSYt q)х}{qdci/,߶bNnd#Rh$*͐`p 9r7RVVtޝ֭[W#L0 H6?{3ھuOqut ekҤ O>=ڄtXgjzpDWW+TlV|(t?IIDSYYbbn^)t)Tr(++cŚڞZ'x.Q"NmMٹ)wߚ tnwPQ)"*ё 34/s_$f1#뮻quU՚vVZŋ9}tл5)˗q|11l~l}oDȣ߰1v Mh;b&%dO1y 4' ۯ  7@ So0 3w\6o : /@nn656n;A6IB*AR6n FpIl|ls^,~ Zhv~*' 8{ѿN:0mZ Z%Vΰ7CI}^wY>^`xuTnv=犉 3 @xxXm^uU/ hØ;nU2@QQTV]=Eξ;yc5%ݷ{T{_Fv LorxMW={6'Ofl .VA (3oL )( #-++8}Tj@o*պukZhPd2QRR’%Kt9ݎ9 +iUۤg1b4i 0`ڿ:SQ)EzbMj@[/Z4cll,CeDEEą|}vIسgsΉ޶}YjkPƮ YGKX JYϣ2x㭵hB:јh ~+ьu}tmoDk2Zɓ)..棏>BQz8vw- |dYb‹ϒެ)PYi&**4bGto n#<"<@Lt4.bᅿ?np/ӿxw>=EETTdAE{[ ì]F~LƎKjjj^se1|fv8„gЩu99IQ'^o3-ӷ[ 9ːӻhr}{\SNa4z_ hرc?~mҩS'WUzS6ч>[%T4F;Òq DUI+k{Lb琖Fjj*{a(7cxٳ] ̜9 }z?7qiPie}u~47a׀47;OG DcjU4F4C'䩧v'M78vEuE~7>.sX_iCp#iպ++΁>W4WҶ]߰qDFrK522o78OdNfC=WӻԜ:D@|3Z/7!8v^t}g {ؼ)?ܘHiI:;%Ae4 GG$IodСAw۵kྊd;La{oQFiV&=3=`7_p&TY ȑއq,eb4ם3rH2`0~ٌ`O> f (Wy B 8N_vN{5hV肦7؊Vg_?(FK)\fSRRx7gfWZ_пv-MTKR5w{-0q7u}Bj." K\|5e5EF(B~W](9>ތܷq7X@mPkTU)P[D^x ZlSN[z5=˖b%Қh+/rhrzv"93+3\RXm"I*=wA=M`0l^EqiW@X(l JõbjC1c1-(UҾGTm_{={v@#< zINNfߝ`0PPPܹs9s&ӦM?@2s/{r~. µ=``!J-~:t9qh:LVVƍUV./FJJJXl+W±#ib*Z4Ct8hX0#DJQnHrD8 i gf]v;\s5 4Hl6(Oee%|I@B?> __>ZM/ Ek Էo_.]Ν;;}gm۶`N;<`;gTQ\ >!=/2 kQYwxðn!绻E.  356d$'O擜8cȲL||})&EQ3gM08v|L; ~)%U|Fx 2d[laժU <>3$}Y@f ˍih42OZJϮa,Vn#`89^h Yfa2kݻ7o^M~w> Ni@oأ4LħIڲccq7LVVVƗ_~Y/ܓSEV.`ze>fufU 8 tM9r%Kеkנ5eʔj}5W*RE P-T-TOkJZjj5G9//vڇpӔcC&#YHǨ-.  b082N x[yVx +|UX"V QF?ɓ'ӢE eXz5=+VQNL(*Ri&n/|Ќb#,>.A_j~~РAnz 'jJng͚5,\SNRP#(Gs%S'06Os`/_GohkMOЌ5ƍp8?~@+X:\oY u8fMhMyo]wEII _5͚?1ر?0f?S)K(TGsםȨjTVL& (`[\ٳ\FIe6Mc۶m!*-[II ٳgnJ f @pWTEFSպOf@[fɌ?UU1c_عsgMahj[0^DYLۇҤowX8lI~mV+mڴnsKKKYb˗/*Ӂdf!velNFlUώ@TTÆ cΝTF+¶mS̶e @[ 0 C귅O 2~i(Ջ#GҨQ#G@~'Xp!6l@UU׽mv~}u:Ae992P @$/yUU]h}JB%Khs$|Mf3J0 ,~pȲơP|ϒ@o@i_ُ,6W{Slwu$oV-pY8%%8UU~D3eʔ,~:MsTͳݳקlOq!s)r#zB\ sO:?`ʔ)3`zXX?HTyyMVxDѳgO:uhDrS iS<' s]! J06n_ϠA{]gΝ [|W{/K_DD&+:Mj~ ̙3E!>W{ *.hiQ`20BX 4oޜ3fp&NXK+++sKupFKyTQWoZ '_@wWADB*sjTtkސ v'c0Q))-Gh4ra^ziI\y|yBGޣNZmk/\4>oFxꩧ@sVZń C>_rrc36C4hLve׎\ K~V>>h?':Ra>ɒU Y$)\>oEQhԨm۶nSTT(>* `Z9pQ3M!vem[wp*[qʞM$*Sklaرdee`HTI(Q8/ݗpV'ć1zү(&d|Y(`40M,_~̙3^x-Ze>|qZ^ʅ>aVf)i)8vv;6 @iiq4o¥ u8߿sg2x.( Np,~C&ƕ hw~cޢ:5z8%Vk&9_Þ{ؼu3Q"1)1nWj&,<{﹂ y#Z PE:ˢg*X)w}'֋@;wfٲeXӀ y饗h߾=ǏYGv=N)DQD1H2κSM^=z4cǎaZټy3۷o$Bt"8R`f(l &Mnu=z4/YYYҞ|I˱!Z3 WG@:{ϕmڴ}hޢV2{,n} իLF 1s&Hѣy^wvkek`r h_3 a" Tܜzā?>#FHWQQQ9+saUU L8Aq EE|r2y'D4H9N |M"YF$$fA2[(C;EHWe5jDxx8wq>l6֬Yŋ)++sBݱ)'^^ IiF(-֨9*u[G`b߈&#ĉyIKKÉfف6\Wy1 Sf]66=+<' s}rsL_4Id2QtS h0\,j1<9鯡ޢ:R!۹&>M7 f9<<}wM2d222?Q]ݍ l2+hNRbP(__(PPP9`L^^^ZW_}}vӡ;hz+W_}u<) xw#? yfQ~-y+SIw6CO߿[Ӈ, y;ݞx#Ɓ!8dJ3o X07N'Gni x૫bwaڵȑ#G8}4ŔV6&BkxlO͌#1HxV'Fa"B2ь|К3Ë/ȃ>3W_l;jKaέ-.dw|E-!޻"RD *'6Sp|>c*6ٝgR'lLvQDDQR[+$$;9.MSгw?Єc0(((޻٧DEEѵkWʤoiBA~ꃂ2338qb<ibcc=)((Wؾ};}Ɏߊyhm'"rn)%-[[n8N<0>d+Юo0p@XعupMt~m[ROq)%v#Gh5x饗x k̛?4@ @ΝHJJfcٰ\U{@~^>t7faZrrrؿVOf)N} BBB h4Q6̺Nv \j(T[@|BkW{q2g2 !9:-i:**.]мyr m/GC{\^^n/!**f͚! HA~A~.W9/mƅ^HRRRA` 11?ȁқf͙0a[DJl&,,֭[ӭ[7zEi׮QQQs2+EF6l9Gxhm2sRRR*=1͹2d0t^Jl 999p80\s51RUs/=Fh_ّD;XH.<ht,uT!>\;v젰cIhh(#Fs򷇅2tt[%s|,Y{,M?vм jeʕ믴hnc۹ 駟ؾ};[n'##ƍc5s)vbРAM54.GͰC(B ʭZIZƶbQ7ny'M())];rHzFkQe'-*}hx}7Ձ!Fk*fcz^}ՆJtڕ?UEh4t:yϸٳ jT`仝8dc-oEsP(6 Oѿ{@1߲L!m}t֍;{n݋L@qq191Pct}eOE8;Zpkt:^8ӽ!*:Ĵ+Yf̛7C裏CXXXL&*}7x#C aСqdee_ܹs߿X[̙3ʕG+I,ԯP,oEY)jkj4D1RJ8x ȨBBB@[d-*c9Bp! EV]va21bD ` ))#Gb4INN.W0XV6nȡC֭aaa^bź{frV+NUvV.I,=}17>iMEFq8`$6nmCN=711;RPPS<Bvލj)>"$~#Ӵ=B"rzwa$ilZ]z1rs/! g^DLIUnD%\B1`ƍٳg/,,XW_UW]E|||R[KTN]R;mZ>y=Z"),(YP&ZFW B@@AuITT;wJhݮC;DFDb`p+k-y0<4 M e = 1LٓCűcp?'??.]L3(Ɲ(XL'΅ek"7: 3I>ڌB#6nayYtl?}tb6ܹ3m۶ԩSs:[رlNr{v'}h2vmhGcc2 `bĚ7d!'\xv5JC<#.W@ǎW^yeDu4?=kDRRv/]K ,+JPhNNZF6|"+03,$)*Y9 H?0seɒ% =lْ3fpBB`6ٸq#saӦM۸6sƛvʡO?Mbn^ԍ#'Bt ƖtJ,d34v;\|Ō9DIIIhp)?#o&999'HIabWU23p|g܊(@7߈>8?P(Chl1==^OvRrȓ3vEW 2zccc֭'kP۷ ڷo1;N^D~-< {gĻ"v@ut#}%1՚FHHcƌO>l޼ -.Z;hݺ5[nz>_YS'LLlKb$6;6{Y˺&^TTbm۶4 @)P@e)GcMYp+N7eAr6Tݏ=鹽OmTdZbҤIfm7>l6p8شi{}"C _ kJ Il͆a޵jEEX /S@.t6m2n8ڵkw\:ͷp؉#""Ʉh`txiJ~.]vofPi+"++7|-[T*t2n8&NHddd맦ىDEh}!=(9̩N'&!dh$##[Nf2 7tN?eÇ= NHLp;c/cG!5bcZYZXXȈ#2eJ+_5cǎ 8 r.wY}svb"l.%Tl"B#x9m۶\V2AGe+25Zk*iz_ Sos8l`n5ROn:[hТE fΜ… ILL `4/;w.6l;\qQFR|O/=9r$:tf7pX3̦eMp8hٲ%&L`̘1Fl6_g}sr'Uw fF=!W?]0hXȃ 6?Av|@!>}:>,qqq_5Hp0gΜkVDfm/?koSD)hQ*K/2 ťԥbz>J׮]YhӧO',,odf+poƛE;n+l6ӭ[74DmyxJ'f!p;@>ދ1VS޽{O3yd=qK)kU%33E)\x6i vv(l 9S @@H:u*jcǎb2YB r 5`7ҁ%gyf+Nl hwތ1 RRRjoܸ|:vXz:$Z86Ķ$$v  9|1bg,@0$RzOjׯcƌaС۷4O.tE?/e˖$&&z  ! 3\ E2 п txYEZ< DYnݺq饗1L )Sн{*_s=lڴ)а_O:>Ĥњ˩:݇-UEV+&V-[Yj[Z<A5^opTO-6 fiZip"@88x Y"ȴJ~ 83g2w:^4oޜnd^yRRR*ײ6֯_O?ĤI1bDB=GЬy{O tJ,fgQX kQ&c.&&&dnʋ/jP0 l6y>cf̘A۶m]wC+֭sx3 Bt~B->A\5!  W7_~i8@ll,&LujΝ;y /k& )ǂ*}岾hPy]Oe;ܦMƎsҝK;?8mIf&BF1%OD f3'˗ZE>$,Yµ^[;?oIaa !_GQQCnpF   GluՊ rYfE Ͼ rVĀU~o4mFHH}VUe|ׁ,K]NߏsKIPII;O;;XȀ!Dq:%67rr1VXt)?=]YjwU#< y<:Xr( ?x-dR[+-}g_BX|9 4,Ntkf{hV*.Pdw<\V n F'YPPeڵ+=\]̩Nҥ =7x#ůkl6S\\ڵkYh;w{P,ٌ (,rҭ^[=\w* Bq HBU#6lO>$\r ~]HHiii̟?gyƷϹS fBd8y+K!51g&%wMGf*NGaŊ5/ht_ g-3CJS-E`Ϟ=?I&:V!ꫯgϞl6bw^/^kFNNҹS&F2hXŒ'Ns9y'uO1sZ39.8#,&&ٳgCKQQ߲F>;m۶DO(C,YǗ !$# 1yCE|?;!4'3΂ټ2!gVu|wkl6t 7PV)dhɄt=bȳ#>$F߄1$tFَ@ /ؿ42طo_ h&Y_Իݧ7qa9p8kOT[1tБ]1WuSOIIoUig UkV> v fzjڷo?_sSt²e˸1%)%"J IDATʫʢEرckg9drp-12)JFیWO"m+_穧b„ }!!!`{9ߊi-c]eK GWFr=,&qM?awW\}լ\={RXX0>`֭y|'#C/^믿xL_"=;~"_l;cy8^|;vB_e3t^ p*f-3gw-[l!s[n]ggy/o, s"z 7{w"_ʃΝKVVVaMKصtiM W2fQ<̓EWeMTo{wnKVj)ׯ[n̞=wkZhwͽK6 ֯_ܹs/)6 [y}F,WVcvFzˋs3x\|*D$?޽;?07tFf3<YsSzɊ+ -->_ 1p݌oK9ik Bʬ60;iZUwJJ ;w`DFDb41LMF B`p72M&L&'ػZyMU} |۷o/ѣk{>un7`ӦM6!nӷo_ڴi8_vӥ9m)b'k1 '|.wTFNbڵرf͚t:1 \z饌?޷}rq @dsΆ)oFg|ꪫ 6YԻ|ӷ7=zvwp˯jf 6 mѣ[2.wߑV믯ZTrHXW `Oe+z5q j9˜1c?~|:dbԩ<#to!!!f={h"PPP4k+pt\O6dɓٜ‚b1 `V8T˜9s?>111~OњKglٲFx6#MZ;nZ[dtU}%@Or& }0#y,`zh ?̙37..sw7X|̛7M6PrY̛sٙͅ/) $D0t`3qo:]kR|q2*VPxG:ujxꩧXlY F;;ț rE,YBjjjag&l nW{dvh:۝5z;v xNʫzLǝ FmO?4aaa<3=:\+hjX(**bڵ,\{VxN,A][T?KeO;i?1& Q|BEN17RcѬ^ѣG>|ŋ}z!JrOVjĿk7<Á5MH0\ŴCgwz7ojv;Sŗ65>E'xE3iyYy=Z>42e ̘1:ꖋ/zc BZZ>(WrfJ9ݛNanwYn9KOrA{_9{HH]w˗/G~eػw/@<0u0{&XfΜ7Q)N^ѹ/`SH3tZ+L v^#ESa9rÇ3bzjt6!!!/f͚5=zSj4Z;v{nƌ_^v3-ŰL2gf!iEr|#6~me !2«8G1Cnݺ5wu{W_%##ܲvS֫uͬ[.а8xd[vLxӦVzkjMxm&q7ϰajeHIIa1\&ѕ EMLcZxEU&ׅFǬYXzumϥ^غu+~BBJJJ䪫bȑ}蘍vztj`Y.B3ښ3,k/$"vl_oCLt/?RҡCz׽{w@Â{Իl2l0 lv66 ݁ Nu,r ~`5yFۘ+}Gډ߅gJ鯙LJx'0LYS 4'x'7ٌj_f4ҎIfJFn'7>ʧg ?mOx hn+cz~ h#KbSǏϪU=zTn禛nR]yW Fk1xm*?4O+g.m1zMRZa ߠ @=S. V|`tЁ-[IJR#.rx =\Oa0ͤb VZɓ'^xU$;3ca[wZ}y\yk+[c1>st}c'g pײtRvyWj宻S } q7 N (NZihrn7UKsVjVn3&48\U%]: Rs{뗲TjYV+\s z[X'1 L8˗3l0*ZY'N|rV\Ifff׾֭Ieʨ _'iľyV,6{e_|ρ5GSYt޿ٗ<.&@2`̝;w}ׯ<}ϖ%̙p:ɉ 7]ET G6OV6mZ>zpYfwzdllIfIhI [o+kj)^I-jk:Tk=EEEkq饗|裏(,,b r8iӆSҭ[?xFv. ` ŽNas!'ni7b2"666аk/JŀlL/j"'н{+lٲZxEբg1Y۵=V߾Z ,T5 77I&1`:Va0 Yt)#FpThB`2HKKcҥ^:Yi8hcV<%6;̿-A6oAWQ;h}N:cªhE+ B]T*cAe\*"sNzu]ڰ>M7O>}6v]w;7@c0.8S3Tf,duQ??_Nغu+qaR1T@nƘLJe ;w.9egɒ%\X,+TF#ż ̛7!a̸>sʩP_<>|8а<\(AK*ͼ*W&W&}[wgcQZ(UϯS=R-E ++I&1h `Zudbܸq,]ǻ*Z'OdV^MNNp)`ƌ = E-=2d,DP,h4^тkoT*[Nz+^"m6vʍ7HnnnLkO>T8Vba׮]qA'g͚U r O\[JmeOu@6&ޭh+&6jk(={6׿hժ~L&_|3f￯ٖѣGy S#h4ܧӾN^et{wR{2z[IFH룵R_*!5t2w\`ZuK=x6m&ohnfϟρyLn1=cܩ:K+:7j#2׻r76Gs^/rWU*`PRK/ѪU+*7ih;Yx1Z"??UB Z=Ü>}:0uoDFyHS2֩kHJcU}% }V3* @R-kfcΜ9tرQ֭<3gDQn)%;wf2",XhX ಝ  }5YϪjrYY:|ӤyiUk{ߠj))))L4#G6Yr%\r EEE>S7tSgԩ\èhQG:}]\U `h0崱+PGo^ZL..Pg P-EoW^z뭜̵t3 E#ZC8q"ƍcǎu0iz :d4jx~&W!AO55jMOmiRJd~Sj6kR O 8묳IOOi5^VkaA#hUh2*ޠ?);vݸh6i FP(^em᫽T%DtܙG}2^'##+VTVQuf QON4@W0Ĩ֚,((o߾|ezIm)(쒛6~D:v,Aw*}B"(0}tT`HNN+ .`׮]u0fӦMlڴ)аc2AH\Q~'߯UԂQ&u\{@5ux(bU¥=zGL*S-E`ӦMߟӧ16뮻'L&ބ(ׂiR^Z_ϙh|HvԞɫ*>Vx.\Ye!TK`Ynݺ|r j{NAŴiHMM 4Q^E`L&;DʝED6}h={6KCOCM&w C! \.((JȔ)S())C1[H;(IflAAFF'O&֔m9QPP@hhh#5>Oo«hE*dظq# cǎL<+޽{h"55/[V!MZ +\M.ZVDHQq:*EEE5? e8~8Uep9<7^4%`U,,]AǸqxQPPP?L=xl6d; v/mT ==] mMY*AQQO&33-ZT鱾~~ystxn+>lVE5@#?? 3j(&Ll8qk׮eTM^+h2O}b1N\UM633ӧO7y߿R*8q %""զ*֚W8n-Wz:jh,_HN;v,K.Ntt4>}Ga[lR+Lfw_OFI֧!R_Nff&Ǐw?YG)t4i2СC?k{,Z~P pjE`߿ZEiaU'&sNW+dfwzR"t:Ϙ5b@~~>٤z4*ZpZʜ]j:e׫AA59*x4SPdeeZƂYHOO@BB$($7<뿔}:Ka4K9`%lq٤kA)UG;vLjbGX_)V/8 Ͽn;{ O@_ ]`'ߵYűc \{Jѣtp8HHH0TJmj[jaj: ﷨JB/:X,fAԵZ'ZzVRYjj*gJ "%%El6 -JJJ'xoS 4AYvԩpF.|EkZ:SBBB}[4&L % !v<B`ZIOOA)5EhO~ll,͚5,̨(1]V}w+BWiDjXBBluuaEj5D =RvТ=n`0ODDw?++ NFFOƢ#rrrɑmڴd2yZGGGNp.1.QR7 ZC % ?} uPqVd6QPPb5 >}Tmg,y}1ӲUKbZ%6DJ'⥗_mĺBp\tE =Bhp&OSP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP( BP{pH ko+a3h/+IENDB`klog-0.9.2.9/searchwidget.h0000644000076700000620000001234313233376355013432 0ustar staff#ifndef SEARCHWIDGET_H #define SEARCHWIDGET_H /*************************************************************************** searchwidget.h - description ------------------- begin : jul 2017 copyright : (C) 2017 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implement the tab of the search widget // #include #include #include "dataproxy.h" #include "awards.h" #include "world.h" #include "utilities.h" #include "filemanager.h" class SearchWidget : public QWidget { Q_OBJECT public: explicit SearchWidget(DataProxy *dp, QWidget *parent = 0); ~SearchWidget(); void setCurrentLog(const int _log); void setColors (const QString _newOne, const QString _needed, const QString _worked, const QString _confirmed, const QString _default); void setVersion (const QString _version); // Defines the KLog version to be written in the exported logs void setShowCallInSearch(const bool _sh); void clear(); void searchToolNeededQSLToSend(); public slots: //void slotQsoFound(QStringList _qso); void slotSearchBoxTextChanged(); void slotToolSearchQSL(const int actionQSL); void slotToolSearchRequestedQSLToSend(); void slotToolSearchNeededQSLPendingToReceive(); void slotToolSearchNeededQSLRequested(); private slots: void slotDoubleClickSearch( QTreeWidgetItem* item, int); // Double click on a QSO in the search box void slotSearchExportButtonClicked(); void slotSearchBoxSelectAllButtonClicked(); void slotSearchClearButtonClicked(); void slotSearchBoxSelectionChanged(); void slotSearchBoxReSearchButtonClicked(); void slotRighButtonSearch(const QPoint& pos); void showMenuRightButtonSearchCreateActions(); void righButtonSearchMenu(const int trow); void slotQsoDeleteFromSearch(); void slotQSLSentViaBureauFromSearch(); void slotQSLSentViaDirectFromSearch(); void slotQSLSentViaDirectMarkDXReqFromSearch(); void slotQSLSentViaBureuMarkDXReqFromSearch(); void slotQSLRecViaDirectFromSearch(); void slotQSLRecViaBureauFromSearch(); void slotQSLRecViaDirectMarkReqFromSearch(); void slotQSLRecViaBureauMarkReqFromSearch(); void slotQSLSentMarkAsRequested(); void slotQSLRecMarkAsRequested(); void slotQSOToEditFromSearch(); void qslRecViaBureauMarkReq(const int _qsoId); void qslRecViaDirectMarkReq(const int _qsoId); signals: void actionQSODoubleClicked(const int _qsoid); void updateAwards(); void logRefresh(); void toStatusBar(const QString statusm); void requestBeingShown(); void actionQSODelete(const int _qsoid); void queryError(QString functionFailed, QString errorCodeS, int errorCodeN, QString failedQuery); // To alert about any failed query execution private: void createUI(); QLineEdit *searchBoxLineEdit; QPushButton *searchBoxClearButton, *searchBoxExportButton, *searchBoxSelectAllButton, *searchBoxReSearchButton; QRadioButton *searchAllRadioButton; QTreeWidget *searchResultsTreeWidget; bool qslingNeeded; bool searchSelectAllClicked, stationCallSignShownInSearch; int currentLog; DataProxy *dataProxy; Awards *awards; World *world; Utilities *util; FileManager *filemanager; QAction *delQSOFromSearchAct; QAction *qsoToEditFromSearchAct; QAction *qslSentViaBureauFromSearchAct; QAction *qslSentViaDirectFromSearchAct; QAction *qslSentViaDirectMarkRcvReqFromSearchAct; QAction *qslSentViaBureauMarkRcvReqFromSearchAct; QAction *qslRecViaBureauFromSearchAct; QAction *qslRecViaDirectFromSearchAct; QAction *qslRecViaBureauMarkReqFromSearchAct; QAction *qslRecViaDirectMarkReqFromSearchAct; QAction *qslSentRequestedAct; QAction *qslRecRequestedAct; }; #endif // SEARCHWIDGET_H klog-0.9.2.9/KLog.pro0000644000076700000620000000767113233376355012176 0ustar staffCONFIG += app_bundle CONFIG += static #CONFIG += release TEMPLATE = app VERSION = 0.9.2.9 DEFINES += APP_VERSION="$$VERSION" APP_NAME = KLog DEFINES += APP_NAME="$$APP_NAME" APP_UNIX_NAME = klog DEFINES += APP_UNIX_NAME="$$APP_UNIX_NAME" message(Building $${APP_NAME} $${VERSION}) message(Qt $$[QT_VERSION] in $$[QT_INSTALL_PREFIX]) #DEFINES *= QT_NO_DEBUG_OUTPUT DEFINES *= QT_USE_QSTRINGBUILDER DEFINES *= QT_STRICT_ITERATORS TARGET = $${APP_UNIX_NAME} QT += core \ gui \ sql \ network \ widgets greaterThan(QT_MAJOR_VERSION, 4) { QT *= printsupport QT += widgets } HEADERS += setupdialog.h \ aboutdialog.h \ mainwindow.h \ world.h \ logwindow.h \ filemanager.h \ contest.h \ database.h \ setuppagemisc.h \ locator.h \ dxcluster.h \ awards.h \ setuppageuserdata.h \ setuppagedxcluster.h \ setuppagecolors.h \ contest_cqwwdxssb.h \ setuppagelogs.h \ setuppageworldeditor.h \ setupentitydialog.h \ startwizard.h \ downloadcty.h \ dataproxy.h \ dataproxy_sqlite.h \ mainwindowsattab.h \ awarddxmarathon.h \ setuppagelogsnew.h \ setuppageclublog.h \ elogclublog.h \ softwareupdate.h \ softwareupdatedialog.h \ utilities.h \ dxccstatuswidget.h \ mainwindowmydatatab.h \ mainwindowinputcomment.h \ mainwindowinputothers.h \ mainwindowinputeqsl.h \ mainwindowinputqsl.h \ setuppagebandmode.h \ logmodel.h \ searchwidget.h \ infowidget.h \ showerrordialog.h SOURCES += main.cpp \ aboutdialog.cpp \ setupdialog.cpp \ mainwindow.cpp \ world.cpp \ logwindow.cpp \ filemanager.cpp \ contest.cpp \ contest_cqwwdxssb.cpp \ database.cpp \ dataproxy.cpp \ dataproxy_sqlite.cpp \ downloadcty.cpp \ dxcluster.cpp \ setuppagemisc.cpp \ locator.cpp \ awards.cpp \ setuppageuserdata.cpp \ setuppagedxcluster.cpp \ setuppagecolors.cpp \ setuppagelogs.cpp \ setuppageworldeditor.cpp \ setupentitydialog.cpp \ startwizard.cpp \ mainwindowsattab.cpp \ awarddxmarathon.cpp \ setuppagelogsnew.cpp \ setuppageclublog.cpp \ elogclublog.cpp \ softwareupdate.cpp \ softwareupdatedialog.cpp \ utilities.cpp \ dxccstatuswidget.cpp \ mainwindowmydatatab.cpp \ mainwindowinputcomment.cpp \ mainwindowinputothers.cpp \ mainwindowinputeqsl.cpp \ mainwindowinputqsl.cpp \ setuppagebandmode.cpp \ logmodel.cpp \ searchwidget.cpp \ infowidget.cpp \ showerrordialog.cpp OTHER_FILES += \ README-DEVEL \ TODO \ tips-for-devel.txt \ INSTALL.txt \ INSTALL-linux \ INSTALL-win.txt \ Changelog \ INSTALL-osx.txt \ NEWS \ klog.1 \ COPYING \ AUTHORS \ README RESOURCES += klog.qrc DESTDIR = build/target/ OBJECTS_DIR = build/obj/ MOC_DIR = build/moc/ RCC_DIR = build/rcc/ # Tell Qt Linguist that we use UTF-8 strings in our sources CODECFORTR = UTF-8 CODECFORSRC = UTF-8 #include(translations/translations.pri) TRANSLATIONS = translations/klog_es.ts \ translations/klog_ca.ts \ translations/klog_da.ts \ translations/klog_fi.ts \ translations/klog_hr.ts \ translations/klog_it.ts \ translations/klog_pl.ts \ translations/klog_template.ts \ translations/klog_ja.ts # deploy DISTFILES += CHANGES COPYING unix:!mac { DEFINES += APP_LINUX CONFIG += c++11 # QT += dbus isEmpty(PREFIX):PREFIX = /usr BINDIR = $$PREFIX/bin INSTALLS += target target.path = $$BINDIR DATADIR = $$PREFIX/share PKGDATADIR = $$DATADIR/klog DEFINES += DATADIR=\\\"$$DATADIR\\\" \ PKGDATADIR=\\\"$$PKGDATADIR\\\" translations.path = $$PKGDATADIR translations.files += $$DESTDIR/translations INSTALLS += translations } macx: { ICON = klog.icns TARGET = KLog } win32: { RC_ICONS = klog.ico TARGET = klog } else:TARGET = klog klog-0.9.2.9/softwareupdate.cpp0000644000076700000620000002146013233376355014351 0ustar staff#include "softwareupdate.h" //#include SoftwareUpdate::SoftwareUpdate(const QString _klogVersion) : QObject(0) { //qDebug() << "SoftwareUpdate::SoftwareUpdate(): " << _klogVersion << endl; util = new Utilities; updateDialog = new SoftwareUpdateDialog(); latestVersion = "0.0"; //updateDialog->setVersion(_klogVersion, fale); //toUpdate = false; repositoryFound = false; url = new QUrl; //klogDir = _klogDir; setVersion(_klogVersion); //klogVersion = _klogVersion; //latestVersion = "0.0"; callsign = QString(); //result = -1; // Error unknown //reply = new QNetworkReply; manager = new QNetworkAccessManager(this); //request = new QNetworkRequest(this); //request.setUrl(QUrl("http://localhost")); //request.setUrl(QUrl("https://download.savannah.gnu.org/releases/klog/")); //request.setUrl(QUrl("http://www.klog.xyz/download")); setTheURL("http://download.klog.xyz"); //request.setUrl(QUrl("http://download.klog.xyz")); messageShown = false; setHeader(); //qDebug() << "SoftwareUpdate::SoftwareUpdate(): - END" << endl; } SoftwareUpdate::~SoftwareUpdate() { } void SoftwareUpdate::setTheURL(QString _url) { //qDebug() << "SoftwareUpdate::setTheURL: " << _url << endl; request.setUrl(QUrl(_url)); } void SoftwareUpdate::setVersion(const QString _klogVersion) { klogVersion = _klogVersion; //latestVersion = "0.0"; setHeader(); } void SoftwareUpdate::slotReadyRead() { //qDebug() << "SoftwareUpdate::slotReadyRead: " << endl; } void SoftwareUpdate::slotError(int _p) { //qDebug() << "SoftwareUpdate::slotError: " << endl; } void SoftwareUpdate::slotDownloadFinished(QNetworkReply *reply) { //qDebug() << "SoftwareUpdate::slotDownloadFinished" << endl; QUrl url = reply->url(); //qDebug() << "SoftwareUpdate::slotDownloadFinished - URL: " << url.toString() << endl; //QMessageBox msgBox; //QString aux; //aux.clear(); QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); if (reply->error()) { //qDebug() << "SoftwareUpdate::slotDownloadFinished: reply error" << endl; /* fprintf(stderr, "Updates %s failed: %s\n", url.toEncoded().constData(), qPrintable(reply->errorString())); //errorCode = query.lastError().number(); msgBox.setIcon(QMessageBox::Warning); aux = tr("The following error code was received when trying to check for updates: "); msgBox.setText(aux + reply->errorString()); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); */ } else if (!redirectionTarget.isNull()) { repositoryFound = false; QUrl newUrl = url.resolved(redirectionTarget.toUrl()); //qDebug() << "SoftwareUpdate::slotDownloadFinished: Redirect: " << newUrl.toString() << endl; url = newUrl; reply->deleteLater(); setTheURL(url.toString()); connectToURL(); return; } else { if (checkUpdates(reply)) { //qDebug() << "SoftwareUpdate::slotDownloadFinished checkupdates true" << endl; if (repositoryFound) { //qDebug() << "SoftwareUpdate::slotDownloadFinished repository found" << endl; if(latestVersion>klogVersion) { //qDebug() << "SoftwareUpdate::slotDownloadFinished checkupdates should update!" << endl; updateDialog->setVersion(latestVersion, true); } updateDialog->show(); latestVersion = klogVersion; repositoryFound = false; } } else { if (repositoryFound && messageShown) { updateDialog->setVersion(latestVersion, false); updateDialog->show(); } //qDebug() << "SoftwareUpdate::slotDownloadFinished: checkupdates false" << endl; } } reply->deleteLater(); //qDebug() << "SoftwareUpdate::slotDownloadFinished end" << endl; } bool SoftwareUpdate::checkUpdates(QIODevice *data) { // Checks if there is a new version in the repository //qDebug() << "SoftwareUpdate::checkUpdates: " << QString::number(data->size()) << endl; QString line, release; QStringList stringList, klogStringList; QRegularExpression rx("href=\"klog-(\\d\\.)+tar.gz"); //qDebug() << "SoftwareUpdate::checkUpdates: Before entering the while"<< endl; while (!data->atEnd()) { //qDebug() << "SoftwareUpdate::checkUpdates: In the while"<< endl; stringList.clear(); klogStringList.clear(); line.clear(); line = data->readLine(); //qDebug() << "SoftwareUpdate::checkUpdates: line: " << line << endl; if (line.contains("klog-")) { repositoryFound = true; stringList << line.split(">", QString::SkipEmptyParts); klogStringList << stringList.filter("klog"); foreach (const QString &str, klogStringList) { //qDebug() << "SoftwareUpdate::checkUpdates klog: " << str << endl; if (rx.match(str).hasMatch()) { //qDebug() << "SoftwareUpdate::checkUpdates: MATCH: " << str << endl; release = str.section("-",1); release = release.section(".tar.gz", 0, 0); //release = release.section("^.*([.]tar[.]gz)", 0, 0); //release = release.section("^.*\\.(tar.gz)?", 0, 0); updateNeeded(release); } else { //qDebug() << "SoftwareUpdate::checkUpdates: DOES NOT MATCH: " << str << endl; } } //qDebug() << "SoftwareUpdate::checkUpdates: " << line << endl; } } //qDebug() << "SoftwareUpdate::checkUpdates:Latest/Actual: " << latestVersion << "/" << klogVersion << endl; if (latestVersion > klogVersion) { emit updateNeededSignal (true); //qDebug() << "SoftwareUpdate::checkUpdates: signal true" << endl; return true; } else { //emit updateNeededSignal (false); //qDebug() << "SoftwareUpdate::checkUpdates: signal false 1" << endl; return false; } //emit updateNeededSignal (false); //qDebug() << "SoftwareUpdate::checkUpdates: signal false 2" << endl; return false; } void SoftwareUpdate::updateNeeded(QString _newVer) { //qDebug() << "SoftwareUpdate::updateNeeded: " << _newVer << endl; if (latestVersion<_newVer) { latestVersion = _newVer; } /* if (klogVersion < _newVer) { //qDebug() << "SoftwareUpdate::updateNeeded TRUE: " << _newVer << endl; if } else { //qDebug() << "SoftwareUpdate::updateNeeded - FALSE " << _newVer << endl; } */ //qDebug() << "SoftwareUpdate::updateNeeded - KLogVersion/latestVersion/newver: "<< klogVersion <<"/"<< latestVersion << "/"<<_newVer << endl; } void SoftwareUpdate::needToUpdate(bool _showWithoutVersion) { // This is used to connect to the main server URL. // If _showWithoutVersio is false: We are checking for new versions at KLog start: No message should be shown if no new version is found. // If _showWithoutVersio is true: The user is manually asking to check. A message should is shown if no new version is found. //qDebug() << "SoftwareUpdate::needToUpdate (current version: " << klogVersion << ")" << endl; messageShown = _showWithoutVersion; setVersion(klogVersion); setTheURL("http://download.klog.xyz"); connectToURL(); //QNetworkReply *reply = manager->get(request); //connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead())); //connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(slotDownloadFinished(QNetworkReply*))); } void SoftwareUpdate::connectToURL() { // This is where the connection takes place.... so first connection may be the main URL but it launches connection after redirections QNetworkReply *reply = manager->get(request); connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead())); connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(slotDownloadFinished(QNetworkReply*))); } void SoftwareUpdate::setHeader() { QString ver = util->getAgent(klogVersion); if (callsign.length()>2) { ver = ver + "-" + callsign; } QByteArray str; str.clear(); str.append(ver); //qDebug() << "SoftwareUpdate::setHeader: " << str << endl; request.setRawHeader("User-Agent", str); } void SoftwareUpdate::addCall(const QString _call) { if (_call.length()>2) { callsign = _call; setHeader(); } } klog-0.9.2.9/INSTALL.txt0000644000076700000620000000030613233376355012453 0ustar staffThis file is about the installation process of KLog. Please read: INSTALL-linux.txt for linux installations. INSTALL-OSX.txt for OSX installations. INSTALL-win.txt for Windows installations. klog-0.9.2.9/mainwindowinputcomment.cpp0000644000076700000620000000523113233376355016131 0ustar staff/*************************************************************************** mainwindowinputcomment.cpp - description ------------------- begin : Ago 2016 copyright : (C) 2016 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ #include "mainwindowinputcomment.h" MainWindowInputComment::MainWindowInputComment(QWidget *parent) : QWidget(parent) { //qDebug() << "MainWindowInputComment::MainWindowInputComment" << endl; commentLineEdit = new QLineEdit(); comment.clear(); createUI(); //qDebug() << "MainWindowInputComment::MainWindowInputComment - END" << endl; } MainWindowInputComment::~MainWindowInputComment(){} void MainWindowInputComment::createUI() { commentLineEdit->setToolTip(tr("Add a comment for this QSO")); QVBoxLayout *tabLayout = new QVBoxLayout; tabLayout->addWidget(commentLineEdit); setLayout(tabLayout); } void MainWindowInputComment::setData(const QString _comment) { comment = _comment; commentLineEdit->setText(comment); } QString MainWindowInputComment::getComment() { return commentLineEdit->text(); } void MainWindowInputComment::clear() { comment.clear(); commentLineEdit->clear(); } klog-0.9.2.9/INSTALL-macOS.txt0000644000076700000620000000014613233376355013455 0ustar staffInstalling KLog on a macOS system is easy. Just click and drop the icon into the Applications folder klog-0.9.2.9/dxccstatuswidget.cpp0000644000076700000620000002367513233376355014717 0ustar staff#include "dxccstatuswidget.h" //#include /* TODO: Adjust the header columns TODO: Add some color to the texts depending on C, W or - TODO: Call the creation of this depending on the bands that the user is using */ DXCCStatusWidget::DXCCStatusWidget(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "DXCCStatusWidget::DXCCStatusWidget" << endl; dataProxy = dp; awards = new Awards(dataProxy); world = new World(dataProxy); dxccView = new QTableWidget; //hv = new QHeaderView(Qt::Vertical, dxccView); //hh = new QHeaderView(Qt::Horizontal, this); numberOfColumns = 0; logNumber = -1; // -1 means that ALL the logs will be used (if showAllLogsButton is not checked) tempLog = -1; // -1 means that ALL the logs will be used //searchLineEdit = new QLineEdit; refreshButton = new QPushButton; //showAllLogsButton = new QRadioButton; bandNames.clear(); validBands.clear(); setDefaultBands(); createUI(); //qDebug() << "DXCCStatusWidget::DXCCStatusWidget - END" << endl; } DXCCStatusWidget::~DXCCStatusWidget(){} void DXCCStatusWidget::createUI() { //qDebug() << "DXCCStatusWidget::createUI " << endl; // We remove the vertical header hv = dxccView->verticalHeader(); hv->hide(); hv->setStretchLastSection(true); hh = dxccView->horizontalHeader(); refreshButton->setText(tr("Update")); //showAllLogsButton->setText("All logs"); dxccView->setContextMenuPolicy(Qt::CustomContextMenu); dxccView->setSortingEnabled(true); dxccView->horizontalHeader()->setStretchLastSection(true); dxccView->setColumnCount(numberOfColumns); dxccView->setRowCount(0); QHBoxLayout *bottonLineLayout = new QHBoxLayout; bottonLineLayout->addSpacerItem(new QSpacerItem(10,0,QSizePolicy::Expanding,QSizePolicy::Maximum)); bottonLineLayout->addWidget(refreshButton); QVBoxLayout *tabLayout = new QVBoxLayout; tabLayout->addWidget(dxccView); tabLayout->addLayout(bottonLineLayout); setLayout(tabLayout); dxccView->resizeColumnsToContents(); dxccView->resizeRowsToContents(); connect(refreshButton, SIGNAL(clicked()), this, SLOT(slotRefreshButtonClicked() ) ); } void DXCCStatusWidget::update() { //qDebug() << "DXCCStatusWidget::update " << endl; int entities = world->getHowManyEntities(); //qDebug() << "DXCCStatusWidget::update: " << QString::number(entities) << " entities to update" << endl; QStringList list; QString aux; dxccView->sortByColumn(1, Qt::AscendingOrder); dxccView->clearContents(); tempLog = -1; for (int i=1; i<=entities; i++) { aux = world->getEntityName(i); list.clear(); if (aux.length()>2) { list << QString::number(i) << aux << bandNames; addEntity(list); } } //qDebug() << "DXCCStatusWidget::update END" << endl; } void DXCCStatusWidget::addEntity(QStringList const _ent) { //qDebug() << "DXCCStatusWidget::addEntity: " << _ent.at(1) << " / " << QString::number(_ent.length()) << endl; // DXCC id, Entity Name, bandName1, bandName2, ... if (_ent.length() != numberOfColumns) { //qDebug() << "DXCCStatusWidget::addEntity: ERROR: in number of columns" << QString::number(_ent.length()) << "/" << QString::number(numberOfColumns) << endl; return; } int status = -1; int ent = (_ent.at(0)).toInt(); int bandid = 0; QString entName = _ent.at(1); if (entName.length()<2) { //qDebug() << "DXCCStatusWidget::addEntity: ERROR: entname too short!" << endl; return; } QString flagSt; flagSt.clear(); QString aux; aux = dataProxy->getISOName(ent); if (aux.length()>1) { flagSt = ":/" + aux + ".png"; } else { flagSt.clear(); } flagSt = ":/flags/" + aux + ".png"; QIcon flagIcon(flagSt); //qDebug() << "DXCCStatusWidget::addEntity: Flag: " << flagSt << endl; dxccView->insertRow(dxccView->rowCount()); //qDebug() << "DXCCStatusWidget::addEntity: rowCount: " << QString::number(dxccView->rowCount()) << endl; QTableWidgetItem *newItemID = new QTableWidgetItem(_ent.at(0)); newItemID->setTextAlignment(Qt::AlignCenter); newItemID->setFlags(Qt::NoItemFlags); dxccView->setItem(dxccView->rowCount()-1, 0, newItemID); //QTableWidgetItem::QTableWidgetItem(const QIcon & icon, const QString & text, int type = Type) // QTableWidgetItem *newItemFlag = new QTableWidgetItem(QIcon(flagSt), "T", 0); //QFont font; // To show smaller letters "W" and "C" in the table //font.setStretch(QFont::UltraCondensed); for (int i=2; i < _ent.length(); i++) { bandid = dataProxy->getIdFromBandName(_ent.at(i)); QTableWidgetItem *newItem = new QTableWidgetItem(awards->getDXCCStatusBand(ent, bandid, tempLog)); newItem->setTextAlignment(Qt::AlignCenter); newItem->setFlags(Qt::NoItemFlags); //newItem->setFont(font); if (newItem->text()=="C") { newItem->setTextColor(Qt::blue); newItem->setBackgroundColor(Qt::green); status = 1; } else if (newItem->text()=="W") { if (status < 0) { status = 0; } newItem->setTextColor(Qt::red); newItem->setBackgroundColor(Qt::yellow); } else { } dxccView->setItem(dxccView->rowCount()-1, i, newItem); //qDebug() << "DXCCStatusWidget::addEntity: rowCount-2: " << QString::number(dxccView->rowCount()) << "/" << QString::number(i) << " / " << newItem->text() << endl; } QTableWidgetItem *newItemName = new QTableWidgetItem(entName); newItemName->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter); newItemName->setFlags(Qt::ItemIsEnabled); //newItemName->setFlags(Qt::ItemIsUserCheckable); newItemName->setIcon(flagIcon); if (status == 1) { newItemName->setTextColor(Qt::blue); //newItemName->setTextColor(Qt::blue); //newItemName->setBackgroundColor(Qt::green); } else if (status == 0) { newItemName->setTextColor(Qt::darkRed); } else { newItemName->setTextColor(Qt::red); } dxccView->setItem(dxccView->rowCount()-1, 1, newItemName); //qDebug() << "DXCCStatusWidget::addEntity: END" << endl; } void DXCCStatusWidget::setBands(QStringList const _ent, const bool _creating) {// Receives the list of band names //qDebug() << "DXCCStatusWidget::setBands: " << QString::number(_ent.length()) << endl; if (_creating) { //qDebug() << "DXCCStatusWidget::setBands (creating true) " << QString::number(_ent.length()) << endl; } else { //qDebug() << "DXCCStatusWidget::setBands (creating false) " << QString::number(_ent.length()) << endl; } QStringList qs; qs.clear(); //qDebug() << "DXCCStatusWidget::setBands - 1 " << endl; qs << dataProxy->sortBandNamesBottonUp(_ent); //qDebug() << "DXCCStatusWidget::setBands - 2 " << endl; if (qs.length()<0) { //qDebug() << "DXCCStatusWidget::setBands no bands received here " << endl; return; } QString testBand; testBand.clear(); bandNames.clear(); //bandNames << "Id" << "Entity"; //qDebug() << "DXCCStatusWidget::setBands - 3 " << endl; validBands.clear(); //validBands << dataProxy->getBands(); validBands << dataProxy->getBandNames(); //qDebug() << "DXCCStatusWidget::setBands - 4 " << endl; dxccView->clearContents(); // for (int x = 0; x < dxccView->columnCount(); x++) // { // dxccView->removeColumn(x); // } //bands.clear(); for (int i = 0; isetColumnCount(numberOfColumns); dxccView->setRowCount(0); QStringList headerqs; headerqs.clear(); headerqs << tr("ID") << tr("Entity") << bandNames; dxccView->setHorizontalHeaderLabels(headerqs); //qDebug() << "DXCCStatusWidget::setBands: PRE-END" << endl; if (!_creating) { update(); } //qDebug() << "DXCCStatusWidget::setBands: END" << endl; } void DXCCStatusWidget::setDefaultBands() { //qDebug() << "DXCCStatusWidget::setDefaultBands" << endl; /* Default bands: 160M 80M 40M 30M 20M 17M 15M 12M 10M 6M 4M 2M 70CM 28 27 25 24 23 22 21 12 19 18 17 16 14 */ bandNames.clear(); bandNames << "160M" << "80M" << "40M" << "30M" << "20M" << "17M" << "15M" << "12M" << "10M" << "6M" << "4M" << "2M" << "70CM"; setBands(bandNames, true); } /* void DXCCStatusWidget::slotSearchLineEditTextChanged() { //qDebug() << "DXCCStatusWidget::slotSearchLineEditTextChanged: " << searchLineEdit->text() << endl; } */ void DXCCStatusWidget::slotRefreshButtonClicked() { //qDebug() << "DXCCStatusWidget::slotRefreshButtonClicked" << endl; //TODO: Define a way to show the status of the selected log or all the logs in the DB QStringList _bands = bandNames; setBands(_bands); //update(); } void DXCCStatusWidget::refresh() { //qDebug() << "DXCCStatusWidget::refresh" << endl; slotRefreshButtonClicked(); } void DXCCStatusWidget::setCurrentLog(const int _logN) { //qDebug() << "DXCCStatusWidget::setCurrentLog: " << QString::number(_logN) << endl; if (dataProxy->doesThisLogExist(_logN)) { logNumber = _logN; } else { logNumber = -1; } } klog-0.9.2.9/setuppagebandmode.cpp0000644000076700000620000001020413233376355014775 0ustar staff#include "setuppagebandmode.h" SetupPageBandMode::SetupPageBandMode(DataProxy *dp, QWidget *parent) : QWidget(parent) { //qDebug() << "SetupPageBandMode::SetupPageBandMode" << endl; dataProxy = dp; bandsListWidget = new QListWidget; modesListWidget = new QListWidget; QHBoxLayout *layout = new QHBoxLayout; QVBoxLayout *bLayout = new QVBoxLayout; QVBoxLayout *mLayout = new QVBoxLayout; QLabel *bandsLabel = new QLabel(bandsListWidget); bandsLabel->setText(tr("Bands")); bandsLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); QLabel *modesLabel = new QLabel(modesListWidget); modesLabel->setText(tr("Modes")); modesLabel->setAlignment(Qt::AlignVCenter| Qt::AlignCenter); addBands(dataProxy->getBands()); addModes(dataProxy->getModes()); bLayout->addWidget(bandsLabel); bLayout->addWidget(bandsListWidget); mLayout->addWidget(modesLabel); mLayout->addWidget(modesListWidget); layout->addLayout(bLayout); layout->addLayout(mLayout); //layout->addWidget(bandsListWidget); //layout->addWidget(modesListWidget); setLayout(layout); //qDebug() << "SetupPageBandMode::SetupPageBandMode - END" << endl; } SetupPageBandMode::~SetupPageBandMode() {} void SetupPageBandMode::addBands(QStringList _b) { bandsListWidget->addItems(_b); QListWidgetItem* item = 0; for(int i = 0; i < bandsListWidget->count(); ++i){ item = bandsListWidget->item(i); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(Qt::Unchecked); } } void SetupPageBandMode::addModes(QStringList _b) { modesListWidget->addItems(_b); QListWidgetItem* item = 0; for(int i = 0; i < modesListWidget->count(); ++i){ item = modesListWidget->item(i); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(Qt::Unchecked); } } QString SetupPageBandMode::getBands() { //qDebug() << "SetupPageBandMode::getBands" << endl; QString b; QListWidgetItem *it; if ( (bandsListWidget->count()) < 1) { return ""; } for (int i = 0; i < bandsListWidget->count(); i++) { it = bandsListWidget->item(i); if (it->checkState() == Qt::Checked) { b = b + it->text(); b = b + ", "; } } if (b.size()<2) { }else { b.chop(2); } return b; } QString SetupPageBandMode::getModes() { //qDebug() << "SetupPageBandMode::getModes" << endl; QString b; QListWidgetItem *it; if ( (modesListWidget->count()) < 1) { return ""; } for (int i = 0; i < modesListWidget->count(); i++) { it = modesListWidget->item(i); if (it->checkState() == Qt::Checked) { b = b + it->text(); b = b + ", "; } } if (b.size()<2) { }else { b.chop(2); } //qDebug() << "SetupPageBandMode::getModes: " << b << endl; return b; } void SetupPageBandMode::setActiveBands(QStringList q) { //qDebug() << "SetupPageBandMode::setActiveBands" << endl; if (q.isEmpty()) {return;} QString b; QListWidgetItem *it; if ( (bandsListWidget->count()) < 1) { return; } for (int i = 0; i < bandsListWidget->count(); i++) { it = bandsListWidget->item(i); it->setCheckState(Qt::Unchecked); for (int j=0;jtext() == q.at(j)) { it->setCheckState(Qt::Checked); } } } } void SetupPageBandMode::setActiveModes(QStringList q) { //qDebug() << "SetupPageBandMode::setActiveModes" << endl; if (q.isEmpty()) {return;} QString b; QListWidgetItem *it; if ( (modesListWidget->count()) < 1) { return; } for (int i = 0; i < modesListWidget->count(); i++) { it = modesListWidget->item(i); it->setCheckState(Qt::Unchecked); for (int j=0;jtext() == q.at(j)) { it->setCheckState(Qt::Checked); } } } } klog-0.9.2.9/mainwindowinputqsl.h0000644000076700000620000000707513233376355014743 0ustar staff#ifndef MAINWINDOWINPUTQSL_H #define MAINWINDOWINPUTQSL_H /*************************************************************************** mainwindowinputqsl.h - description ------------------- begin : jun 2017 copyright : (C) 2017 by Jaime Robles email : jaime@robles.es ***************************************************************************/ /***************************************************************************** * This file is part of KLog. * * * * KLog 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 3 of the License, or * * (at your option) any later version. * * * * KLog 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 KLog. If not, see . * * * *****************************************************************************/ // // This class implement the tab of the mainwindow that supports the QSL options // #include #include #include #include "dataproxy.h" #include "dataproxy_sqlite.h" #include "utilities.h" class MainWindowInputQSL : public QWidget { Q_OBJECT public: explicit MainWindowInputQSL(DataProxy *dp, QWidget *parent = 0); ~MainWindowInputQSL(); QString getQSLRecStatus(); QString getQSLSenStatus(); QString getSentVia(); QString getRecVia(); QString getQSLVia(); QString getQSLMsg(); void setQSLRecStatus(const QString _qs); void setQSLSenStatus(const QString _qs); void setQSLRecVia(const QString _qs); void setQSLSenVia(const QString _qs); void setQSLVia(const QString _qs, QColor qColor=Qt::black); void setQSLMsg(const QString _qs); QDate getQSLRecDate(); QDate getQSLSenDate(); void setQSLRecDate(const QDate _qs); void setQSLSenDate(const QDate _qs); void clear(); void qslViaClear(); signals: void returnPressed(); private slots: void slotQSLViaTextChanged(); void slotQSLSentComboBoxChanged(); void slotQSLRecvComboBoxChanged(); void slotQSLViaLineEditReturnPressed(); /* void sloteQSLRecvComboBoxChanged(); void sloteQSLSentComboBoxChanged(); void slotLotwRecvComboBoxChanged(); void slotLotwSentComboBoxChanged(); */ private: void createUI(); void setDefaultData(); QComboBox *qslSentComboBox, *qslRecComboBox, *qslSentViaComboBox, *qslRecViaComboBox; QDateEdit *qslSentQDateEdit, *qslRecQDateEdit; QTextEdit *qslmsgTextEdit; QLineEdit *qslViaLineEdit; DataProxy *dataProxy; Utilities *util; QStringList qslSentStatusList, qslRcvdStatusList, qslViaList; QPalette palette; // To color some widgets }; #endif // MAINWINDOWINPUTQSL_H klog-0.9.2.9/softwareupdatedialog.cpp0000644000076700000620000000432413233376355015531 0ustar staff#include "softwareupdatedialog.h" //#include SoftwareUpdateDialog::SoftwareUpdateDialog() { //qDebug() << "SoftwareUpdateDialog::SoftwareUpdateDialog" << endl; textBrowser = new QTextBrowser; textBrowser->setOpenLinks(true); textBrowser->setOpenExternalLinks(true); //textBrowser->setFrameShadow(QFrame::Raised); //textBrowser->setFrameStyle(QFrame::StyledPanel); QPushButton *acceptButton = new QPushButton(tr("Ok")); textBrowser->setOpenExternalLinks(true); //textBrowser->setHTML(url); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addWidget(acceptButton); /// QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(textBrowser); mainLayout->addLayout(buttonsLayout); setLayout(mainLayout); setWindowTitle(tr("KLog update")); /// connect(acceptButton, SIGNAL(clicked()), this, SLOT(slotAcceptButtonClicked())); //qDebug() << "SoftwareUpdateDialog::SoftwareUpdateDialog - END" << endl; } void SoftwareUpdateDialog::setVersion(const QString tversion, const bool updateNeeded) { //qDebug() << "SoftwareUpdateDialog::setVersion: " << tversion << endl; _version = tversion; if (updateNeeded) { text = "

KLog new version ("+ tversion + ") is available!


There is a new version of KLog available.

You can get the new version from:

http://www.klog.xyz
"; } else { text = "

" + tr("Congratulations!") + "



" + tr("Your KLog has been updated.") + "

" + tr("You already have the latest version.") + "
("+ tversion + ")
"; } textBrowser->setHtml(text); } SoftwareUpdateDialog::~SoftwareUpdateDialog() { //qDebug() << "SoftwareUpdateDialog::~SoftwareUpdateDialog" << endl; } void SoftwareUpdateDialog::slotAcceptButtonClicked() { //qDebug() << "SoftwareUpdateDialog::slotAcceptButtonClicked" << endl; accept(); } void SoftwareUpdateDialog::keyPressEvent(QKeyEvent *event){ switch (event->key()) { break; default: //QFrame::keyPressEvent(event) slotAcceptButtonClicked(); } }