mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-03 13:30:52 -05:00 
			
		
		
		
	Add Fox log ADIF export to the Fox Log window log table contextual pop up menu
This commit is contained in:
		
							parent
							
								
									db5c9e1fe9
								
							
						
					
					
						commit
						12299957d7
					
				@ -9,7 +9,9 @@
 | 
			
		||||
#include <QSqlRecord>
 | 
			
		||||
#include <QSqlError>
 | 
			
		||||
#include <QSqlQuery>
 | 
			
		||||
#include <QTextStream>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include "Configuration.hpp"
 | 
			
		||||
#include "qt_db_helpers.hpp"
 | 
			
		||||
#include "pimpl_impl.hpp"
 | 
			
		||||
 | 
			
		||||
@ -17,12 +19,15 @@ class FoxLog::impl final
 | 
			
		||||
  : public QSqlTableModel
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  impl ();
 | 
			
		||||
  impl (Configuration const * configuration);
 | 
			
		||||
 | 
			
		||||
  Configuration const * configuration_;
 | 
			
		||||
  QSqlQuery mutable dupe_query_;
 | 
			
		||||
  QSqlQuery mutable export_query_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
FoxLog::impl::impl ()
 | 
			
		||||
FoxLog::impl::impl (Configuration const * configuration)
 | 
			
		||||
  : configuration_ {configuration}
 | 
			
		||||
{
 | 
			
		||||
  if (!database ().tables ().contains ("fox_log"))
 | 
			
		||||
    {
 | 
			
		||||
@ -43,6 +48,9 @@ FoxLog::impl::impl ()
 | 
			
		||||
  SQL_error_check (dupe_query_, &QSqlQuery::prepare,
 | 
			
		||||
                   "SELECT COUNT(*) FROM fox_log WHERE call = :call AND band = :band");
 | 
			
		||||
 | 
			
		||||
  SQL_error_check (export_query_, &QSqlQuery::prepare,
 | 
			
		||||
                   "SELECT band, \"when\", call, grid, report_sent, report_rcvd FROM fox_log ORDER BY \"when\"");
 | 
			
		||||
 | 
			
		||||
  setEditStrategy (QSqlTableModel::OnFieldChange);
 | 
			
		||||
  setTable ("fox_log");
 | 
			
		||||
  setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)"));
 | 
			
		||||
@ -60,7 +68,8 @@ FoxLog::impl::impl ()
 | 
			
		||||
  SQL_error_check (*this, &QSqlTableModel::select);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FoxLog::FoxLog ()
 | 
			
		||||
FoxLog::FoxLog (Configuration const * configuration)
 | 
			
		||||
  : m_ {configuration}
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -142,3 +151,59 @@ void FoxLog::reset ()
 | 
			
		||||
      m_->setEditStrategy (QSqlTableModel::OnFieldChange);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
  struct ADIF_field
 | 
			
		||||
  {
 | 
			
		||||
    explicit ADIF_field (QString const& name, QString const& value)
 | 
			
		||||
      : name_ {name}
 | 
			
		||||
      , value_ {value}
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QString name_;
 | 
			
		||||
    QString value_;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  QTextStream& operator << (QTextStream& os, ADIF_field const& field)
 | 
			
		||||
  {
 | 
			
		||||
    if (field.value_.size ())
 | 
			
		||||
      {
 | 
			
		||||
        os << QString {"<%1:%2>%3 "}.arg (field.name_).arg (field.value_.size ()).arg (field.value_);
 | 
			
		||||
      }
 | 
			
		||||
    return os;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FoxLog::export_qsos (QTextStream& out) const
 | 
			
		||||
{
 | 
			
		||||
  out << "WSJT-X FT8 DXpedition Mode Fox Log\n<eoh>";
 | 
			
		||||
 | 
			
		||||
  SQL_error_check (m_->export_query_, static_cast<bool (QSqlQuery::*) ()> (&QSqlQuery::exec));
 | 
			
		||||
  auto record = m_->export_query_.record ();
 | 
			
		||||
  auto band_index = record.indexOf ("band");
 | 
			
		||||
  auto when_index = record.indexOf ("when");
 | 
			
		||||
  auto call_index = record.indexOf ("call");
 | 
			
		||||
  auto grid_index = record.indexOf ("grid");
 | 
			
		||||
  auto sent_index = record.indexOf ("report_sent");
 | 
			
		||||
  auto rcvd_index = record.indexOf ("report_rcvd");
 | 
			
		||||
  while (m_->export_query_.next ())
 | 
			
		||||
    {
 | 
			
		||||
      auto when = QDateTime::fromMSecsSinceEpoch (m_->export_query_.value (when_index).toULongLong () * 1000ull, Qt::UTC);
 | 
			
		||||
      out << '\n'
 | 
			
		||||
          << ADIF_field {"band", m_->export_query_.value (band_index).toString ()}
 | 
			
		||||
          << ADIF_field {"mode", "FT8"}
 | 
			
		||||
          << ADIF_field {"qso_date", when.toString ("yyyyMMdd")}
 | 
			
		||||
          << ADIF_field {"time_on", when.toString ("hhmmss")}
 | 
			
		||||
          << ADIF_field {"call", m_->export_query_.value (call_index).toString ()}
 | 
			
		||||
          << ADIF_field {"gridsquare", m_->export_query_.value (grid_index).toString ()}
 | 
			
		||||
          << ADIF_field {"rst_sent", m_->export_query_.value (sent_index).toString ()}
 | 
			
		||||
          << ADIF_field {"rst_rcvd", m_->export_query_.value (rcvd_index).toString ()}
 | 
			
		||||
          << ADIF_field {"station_callsign", m_->configuration_->my_callsign ()}
 | 
			
		||||
          << ADIF_field {"my_gridsquare", m_->configuration_->my_grid ()}
 | 
			
		||||
          << ADIF_field {"operator", m_->configuration_->opCall ()}
 | 
			
		||||
          << "<eor>";
 | 
			
		||||
    }
 | 
			
		||||
  out << endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,12 +7,14 @@
 | 
			
		||||
class QDateTime;
 | 
			
		||||
class QString;
 | 
			
		||||
class QSqlTableModel;
 | 
			
		||||
class QTextStream;
 | 
			
		||||
class Configuration;
 | 
			
		||||
 | 
			
		||||
class FoxLog final
 | 
			
		||||
  : private boost::noncopyable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  explicit FoxLog ();
 | 
			
		||||
  explicit FoxLog (Configuration const *);
 | 
			
		||||
  ~FoxLog ();
 | 
			
		||||
 | 
			
		||||
  // returns false if insert fails, dupe call+band
 | 
			
		||||
@ -23,6 +25,7 @@ public:
 | 
			
		||||
 | 
			
		||||
  QSqlTableModel * model ();
 | 
			
		||||
  void reset ();
 | 
			
		||||
  void export_qsos (QTextStream&) const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  class impl;
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,17 @@
 | 
			
		||||
#include "FoxLogWindow.hpp"
 | 
			
		||||
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
#include <QSqlTableModel>
 | 
			
		||||
#include <QAction>
 | 
			
		||||
#include <QFile>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QSqlTableModel>
 | 
			
		||||
#include <QFileDialog>
 | 
			
		||||
 | 
			
		||||
#include "SettingsGroup.hpp"
 | 
			
		||||
#include "Configuration.hpp"
 | 
			
		||||
#include "MessageBox.hpp"
 | 
			
		||||
#include "models/Bands.hpp"
 | 
			
		||||
#include "models/FoxLog.hpp"
 | 
			
		||||
#include "item_delegates/ForeignKeyDelegate.hpp"
 | 
			
		||||
#include "item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp"
 | 
			
		||||
#include "item_delegates/CallsignDelegate.hpp"
 | 
			
		||||
@ -22,23 +24,23 @@
 | 
			
		||||
class FoxLogWindow::impl final
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  explicit impl (QSqlTableModel * log_model)
 | 
			
		||||
    : log_model_ {log_model}
 | 
			
		||||
  explicit impl (FoxLog * log)
 | 
			
		||||
    : log_ {log}
 | 
			
		||||
  {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QSqlTableModel * log_model_;
 | 
			
		||||
  FoxLog * log_;
 | 
			
		||||
  Ui::FoxLogWindow ui_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
FoxLogWindow::FoxLogWindow (QSettings * settings, Configuration const * configuration
 | 
			
		||||
                            , QSqlTableModel * fox_log_model, QWidget * parent)
 | 
			
		||||
                            , FoxLog * fox_log, QWidget * parent)
 | 
			
		||||
  : AbstractLogWindow {"Fox Log Window", settings, configuration, parent}
 | 
			
		||||
  , m_ {fox_log_model}
 | 
			
		||||
  , m_ {fox_log}
 | 
			
		||||
{
 | 
			
		||||
  setWindowTitle (QApplication::applicationName () + " - Fox Log");
 | 
			
		||||
  m_->ui_.setupUi (this);
 | 
			
		||||
  m_->ui_.log_table_view->setModel (m_->log_model_);
 | 
			
		||||
  m_->ui_.log_table_view->setModel (m_->log_->model ());
 | 
			
		||||
  set_log_view (m_->ui_.log_table_view);
 | 
			
		||||
  m_->ui_.log_table_view->setItemDelegateForColumn (1, new DateTimeAsSecsSinceEpochDelegate {this});
 | 
			
		||||
  m_->ui_.log_table_view->setItemDelegateForColumn (2, new CallsignDelegate {this});
 | 
			
		||||
@ -50,6 +52,31 @@ FoxLogWindow::FoxLogWindow (QSettings * settings, Configuration const * configur
 | 
			
		||||
  m_->ui_.callers_label->setNum (0);
 | 
			
		||||
 | 
			
		||||
  // actions
 | 
			
		||||
  auto export_action = new QAction {tr ("&Export ADIF ..."), m_->ui_.log_table_view};
 | 
			
		||||
  m_->ui_.log_table_view->insertAction (nullptr, export_action);
 | 
			
		||||
  connect (export_action, &QAction::triggered, [this, configuration] (bool /*checked*/) {
 | 
			
		||||
      auto file_name = QFileDialog::getSaveFileName (this
 | 
			
		||||
                                                     , tr ("Export ADIF Log File")
 | 
			
		||||
                                                     , configuration->writeable_data_dir ().absolutePath ()
 | 
			
		||||
                                                     , tr ("ADIF Log (*.adi)"));
 | 
			
		||||
      if (file_name.size () && m_->log_)
 | 
			
		||||
        {
 | 
			
		||||
          QFile ADIF_file {file_name};
 | 
			
		||||
          if (ADIF_file.open (QIODevice::WriteOnly | QIODevice::Text))
 | 
			
		||||
            {
 | 
			
		||||
              QTextStream output_stream {&ADIF_file};
 | 
			
		||||
              m_->log_->export_qsos (output_stream);
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              MessageBox::warning_message (this
 | 
			
		||||
                                           , tr ("Export ADIF File Error")
 | 
			
		||||
                                           , tr ("Cannot open \"%1\" for writing: %2")
 | 
			
		||||
                                           .arg (ADIF_file.fileName ()).arg (ADIF_file.errorString ()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  auto reset_action = new QAction {tr ("&Reset ..."), m_->ui_.log_table_view};
 | 
			
		||||
  m_->ui_.log_table_view->insertAction (nullptr, reset_action);
 | 
			
		||||
  connect (reset_action, &QAction::triggered, [this, configuration] (bool /*checked*/) {
 | 
			
		||||
@ -88,10 +115,10 @@ void FoxLogWindow::log_model_changed (int row)
 | 
			
		||||
{
 | 
			
		||||
  if (row >= 0)
 | 
			
		||||
    {
 | 
			
		||||
      m_->log_model_->selectRow (row);
 | 
			
		||||
      m_->log_->model ()->selectRow (row);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      m_->log_model_->select ();
 | 
			
		||||
      m_->log_->model ()->select ();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
class QSettings;
 | 
			
		||||
class Configuration;
 | 
			
		||||
class QFont;
 | 
			
		||||
class QSqlTableModel;
 | 
			
		||||
class FoxLog;
 | 
			
		||||
 | 
			
		||||
class FoxLogWindow final
 | 
			
		||||
  : public AbstractLogWindow
 | 
			
		||||
@ -15,7 +15,7 @@ class FoxLogWindow final
 | 
			
		||||
  Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  explicit FoxLogWindow (QSettings *, Configuration const *, QSqlTableModel * fox_log_model
 | 
			
		||||
  explicit FoxLogWindow (QSettings *, Configuration const *, FoxLog * fox_log
 | 
			
		||||
                         , QWidget * parent = nullptr);
 | 
			
		||||
  ~FoxLogWindow ();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2453,15 +2453,15 @@ void MainWindow::on_actionAstronomical_data_toggled (bool checked)
 | 
			
		||||
 | 
			
		||||
void MainWindow::on_fox_log_action_triggered()
 | 
			
		||||
{
 | 
			
		||||
  if (!m_foxLog) m_foxLog.reset (new FoxLog);
 | 
			
		||||
  if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config});
 | 
			
		||||
  if (!m_foxLogWindow)
 | 
			
		||||
    {
 | 
			
		||||
      m_foxLogWindow.reset (new FoxLogWindow {m_settings, &m_config, m_foxLog->model ()});
 | 
			
		||||
      m_foxLogWindow.reset (new FoxLogWindow {m_settings, &m_config, m_foxLog.data ()});
 | 
			
		||||
 | 
			
		||||
      // Connect signals from fox log window
 | 
			
		||||
      connect (this, &MainWindow::finished, m_foxLogWindow.data (), &FoxLogWindow::close);
 | 
			
		||||
      connect (m_foxLogWindow.data (), &FoxLogWindow::reset_log_model, [this] () {
 | 
			
		||||
          if (!m_foxLog) m_foxLog.reset (new FoxLog);
 | 
			
		||||
          if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config});
 | 
			
		||||
          m_foxLog->reset ();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
@ -8236,7 +8236,7 @@ list2Done:
 | 
			
		||||
      m_hisGrid=m_foxQSO[hc1].grid;
 | 
			
		||||
      m_rptSent=m_foxQSO[hc1].sent;
 | 
			
		||||
      m_rptRcvd=m_foxQSO[hc1].rcvd;
 | 
			
		||||
      if (!m_foxLog) m_foxLog.reset (new FoxLog);
 | 
			
		||||
      if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config});
 | 
			
		||||
      if (!m_foxLogWindow) on_fox_log_action_triggered ();
 | 
			
		||||
      if (m_foxLog->add_QSO (QSO_time, m_hisCall, m_hisGrid, m_rptSent, m_rptRcvd, m_lastBand))
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user