見出し画像

Qt5再入門: Qt DesignerでNotes C APIコンバートシミュレーターダイアログを作る(その15/実演2)

前回は「その14/実演1」として、Qt DesignerとQt Linguistを使用した作業を実演してみました。今回は、ソースコードで肉付けをしていきます。

まずはコンバートシミュレーターダイアログのヘッダーファイルから。

// convertsimulatordialog.h

#ifndef CONVERTSIMULATORDIALOG_H
#define CONVERTSIMULATORDIALOG_H

#include <QDialog>
#include <nxpp/nxpp_number.hpp>
#include <nxpp/nxpp_timedate.hpp>

namespace Ui {
class ConvertSimulatorDialog;
}

class ConvertSimulatorDialog : public QDialog
{
 Q_OBJECT

public:
 explicit ConvertSimulatorDialog(QWidget *parent = nullptr);
 ~ConvertSimulatorDialog();

public slots:
 /**
  * @brief 数値をテキストにコンバートする。
  */
 void convertNumberToText();

 /**
  * @brief テキストを数値にコンバートする。
  */
 void convertTextToNumber();

 /**
  * @brief 日時をテキストにコンバートする。
  */
 void convertTimeToText();

 /**
  * @brief テキストを日時にコンバートする。
  */
 void convertTextToTime();

 /**
  * @brief INTLFORMATをデフォルト設定にする。
  */
 void setIntlFormatToDefault();

 /**
  * @brief NFMTをデフォルト設定にする。
  */
 void setNumberFormatToDefault();

 /**
  * @brief TFMTをデフォルト設定にする。
  */
 void setTimeFormatToDefault();

 /**
  * @brief ログコンソールにメッセージを出力する。
  * @param msg
  */
 void consoleLog(const QString &msg);

private:
 /**
  * @return INTLFORMATグループが有効かどうか
  */
 bool isEnabledIntlSettings() const;

 /**
  * @return NFMTグループが有効かどうか
  */
 bool isEnabledNFMTSettings() const;

 /**
  * @return TFMTグループが有効かどうか
  */
 bool isEnabledTFMTSettings() const;

 /**
  * @return UIデータからINTLFORMATを作成する。
  */
 nxpp::intl::SettingsPtr makeIntlFormat() const;

 /**
  * @return UIデータからNFMTを作成する。
  */
 nxpp::NumberFormatPtr makeNumberFormat() const;

 /**
  * @return UIデータからTFMTを作成する。
  */
 nxpp::TimeFormatPtr makeDateTimeFormat() const;

 /**
  * @return 数値フォーマットコンボボックスの文字列を値に変換する。
  */
 BYTE getNumberFormat() const;

 /**
  * @return 日付フォーマットコンボボックスの文字列を値に変換する。
  */
 BYTE getDateFormat() const;

 /**
  * @return 時刻フォーマットコンボボックスの文字列を値に変換する。
  */
 BYTE getTimeFormat() const;

 /**
  * @return タイムゾーンフォーマットコンボボックスの文字列を値に変換する。
  */
 BYTE getZoneFormat() const;

 /**
  * @return 日時の構成フォーマットコンボボックスの文字列を値に変換する。
  */
 BYTE getStructureFormat() const;

 /**
  * @brief 数値フォーマット値を設定する。
  * @param format フォーマット値
  */
 void setNumberFormat(BYTE format);

 /**
  * @brief 日付フォーマット値を設定する。
  * @param format フォーマット値
  */
 void setDateFormat(BYTE format);

 /**
  * @brief 時刻フォーマット値を設定する。
  * @param format フォーマット値
  */
 void setTimeFormat(BYTE format);

 /**
  * @brief タイムゾーンフォーマット値を設定する。
  * @param format フォーマット値
  */
 void setZoneFormat(BYTE format);

 /**
  * @brief 日時構成フォーマット値を設定する。
  * @param format フォーマット値
  */
 void setStructureFormat(BYTE format);

 /**
  * @brief コンバート関数オブジェクトにINTLFORMATを設定する。
  * @tparam Converter コンバート関数オブジェクトクラス
  * @param コンバート関数オブジェクト
  */
 template <class Converter>
 void setIntlFormat(Converter *converter) {
   if (isEnabledIntlSettings()) {
     converter->setIntlSettings(makeIntlFormat());
   }
 }

 /**
  * @brief コンバート関数オブジェクトにNFMTを設定する。
  * @tparam Converter コンバート関数オブジェクトクラス
  * @param コンバート関数オブジェクト
  */
 template <class Converter>
 void setNumberFormat(Converter *converter) {
   if (isEnabledNFMTSettings()) {
     converter->setFormat(makeNumberFormat());
   }
 }

 /**
  * @brief コンバート関数オブジェクトにTFMTを設定する。
  * @tparam Converter コンバート関数オブジェクトクラス
  * @param コンバート関数オブジェクト
  */
 template <class Converter>
 void setTimeFormat(Converter *converter) {
   if (isEnabledTFMTSettings()) {
     converter->setFormat(makeDateTimeFormat());
   }
 }

 Ui::ConvertSimulatorDialog *ui;
};

#endif // CONVERTSIMULATORDIALOG_H

次はソースファイルです。

// convertsimulatordialog.cpp

#include "convertsimulatordialog.h"
#include "ui_convertsimulatordialog.h"
#include <QMessageBox>
#include <nxpp/qt/nxpp_qt_lmbcs.hpp>
#include <nxpp/qt/nxpp_qt_timedate.hpp>

ConvertSimulatorDialog::ConvertSimulatorDialog(QWidget *parent) :
 QDialog(parent),
 ui(new Ui::ConvertSimulatorDialog)
{
 ui->setupUi(this);

 // タブウィジェットのタブを0番目にする。
 ui->tabWidget->setCurrentIndex(0);

 // 変換用日時エディタのデフォルト値を現在にする。
 QDateTime now = QDateTime::currentDateTime();
 ui->dateTimeToTextDateTimeEdit->setDateTime(now);
 ui->textToDateTimeDateTimeEdit->setDateTime(now);

 // シグナル/スロット接続

 connect(
       ui->numberToTextButton, &QPushButton::clicked,
       this, &ConvertSimulatorDialog::convertNumberToText
       );

 connect(
       ui->textToNumberButton, &QPushButton::clicked,
       this, &ConvertSimulatorDialog::convertTextToNumber
       );

 connect(
       ui->dateTimeToTextButton, &QPushButton::clicked,
       this, &ConvertSimulatorDialog::convertTimeToText
       );

 connect(
       ui->textToDateTimeButton, &QPushButton::clicked,
       this, &ConvertSimulatorDialog::convertTextToTime
       );

 connect(
       ui->setIntlFormatToDefaultButton, &QPushButton::clicked,
       this, &ConvertSimulatorDialog::setIntlFormatToDefault
       );

 connect(
       ui->setNFMTToDefaultButton, &QPushButton::clicked,
       this, &ConvertSimulatorDialog::setNumberFormatToDefault
       );

 connect(
       ui->setTFMTToDefaultButton, &QPushButton::clicked,
       this, &ConvertSimulatorDialog::setTimeFormatToDefault
       );

 /**
  * @brief パラメータ類をデフォルトにする。
  */
 setIntlFormatToDefault();
 setNumberFormatToDefault();
 setTimeFormatToDefault();
}

ConvertSimulatorDialog::~ConvertSimulatorDialog()
{
 delete ui;
}

void ConvertSimulatorDialog::convertNumberToText() {
 nxpp::NumberToTextConverter converter;
 setIntlFormat(&converter);
 setNumberFormat(&converter);

 try {
   bool ok = false;
   double num = ui->numberToTextSrcLineEdit->text().toDouble(&ok);
   if (!ok) {
     consoleLog(tr("Unable to convert numbers to text."));
     return;
   }
   nxpp::Lmbcs text = converter(&num);
   ui->numberToTextDestLineEdit->setText(fromLmbcsQ(text));
 }
 // Notesステータスがスローされたらそのエラーメッセージに変換して表示
 catch (nxpp::Status &status) {
   consoleLog(nxpp::qt::fromStatus(status.error()));
 }
 // それ以外の例外ならそのメッセージを表示
 catch (std::exception &ex) {
   std::string what(ex.what());
   consoleLog(QString::fromStdString(what));
 }
}

void ConvertSimulatorDialog::convertTextToNumber() {
 nxpp::TextToNumberConverter converter;
 setIntlFormat(&converter);
 setNumberFormat(&converter);

 try {
   QString text = ui->textToNumberSrcLineEdit->text();
   NUMBER num = converter(toLmbcsQ(text));
   ui->textToNumberDestLineEdit->setText(QString::number(num));
 }
 // Notesステータスがスローされたらそのエラーメッセージに変換して表示
 catch (nxpp::Status &status) {
   consoleLog(nxpp::qt::fromStatus(status.error()));
 }
 // それ以外の例外ならそのメッセージを表示
 catch (std::exception &ex) {
   std::string what(ex.what());
   consoleLog(QString::fromStdString(what));
 }
}

void ConvertSimulatorDialog::convertTimeToText() {
 nxpp::TimeDateToTextConverter converter;
 setIntlFormat(&converter);
 setTimeFormat(&converter);

 try {
   QDateTime dt = ui->dateTimeToTextDateTimeEdit->dateTime();
   TIMEDATE td = nxpp::qt::toTIMEDATE(dt);
   nxpp::Lmbcs text = converter(&td);
   ui->dateTimeToTextLineEdit->setText(fromLmbcsQ(text));
 }
 // Notesステータスがスローされたらそのエラーメッセージに変換して表示
 catch (nxpp::Status &status) {
   consoleLog(nxpp::qt::fromStatus(status.error()));
 }
 // それ以外の例外ならそのメッセージを表示
 catch (std::exception &ex) {
   std::string what(ex.what());
   consoleLog(QString::fromStdString(what));
 }
}

void ConvertSimulatorDialog::convertTextToTime() {
 nxpp::TextToTimeDateConverter converter;
 setIntlFormat(&converter);
 setTimeFormat(&converter);

 try {
   QString text = ui->textToDateTimeLineEdit->text();
   TIMEDATE td = converter(toLmbcsQ(text));
   ui->textToDateTimeDateTimeEdit->setDateTime(nxpp::qt::fromTIMEDATE(td));
 }
 // Notesステータスがスローされたらそのエラーメッセージに変換して表示
 catch (nxpp::Status &status) {
   consoleLog(nxpp::qt::fromStatus(status.error()));
 }
 // それ以外の例外ならそのメッセージを表示
 catch (std::exception &ex) {
   std::string what(ex.what());
   consoleLog(QString::fromStdString(what));
 }
}

void ConvertSimulatorDialog::setIntlFormatToDefault() {
 nxpp::intl::Settings settings;
 ui->isCurrencySuffixCheckBox->setChecked(settings.isCurrencySuffix());
 ui->isCurrencySpaceCheckBox->setChecked(settings.isCurrencySpace());
 ui->isNumberLeadingZeroCheckBox->setChecked(settings.isNumberLeadingZero());
 ui->isClock24HourCheckBox->setChecked(settings.isClock24Hour());
 ui->isDaylightSavingsCheckBox->setChecked(settings.isDaylightSavings());
 ui->isDateMDYCheckBox->setChecked(settings.isDateMDY());
 ui->isDateDMYCheckBox->setChecked(settings.isDateDMY());
 ui->isDateYMDCheckBox->setChecked(settings.isDateYMD());
 ui->isDate4DigitYearCheckBox->setChecked(settings.isDate4DigitYear());
 ui->isTimeAMPMPrefixCheckBox->setChecked(settings.isTimeAMPMPrefix());
 ui->isDateAbbrevCheckBox->setChecked(settings.isDateAbbrev());
 ui->currencyDigitsSpinBox->setValue(static_cast<int>(settings.currencyDigits()));
 ui->timeZoneSpinBox->setValue(settings.timeZone());
 ui->amStringLineEdit->setText(fromLmbcsQ(settings.amString()));
 ui->pmStringLineEdit->setText(fromLmbcsQ(settings.pmString()));
 ui->currencyStringLineEdit->setText(fromLmbcsQ(settings.currencyString()));
 ui->thousandStringLineEdit->setText(fromLmbcsQ(settings.thousandString()));
 ui->decimalStringLineEdit->setText(fromLmbcsQ(settings.decimalString()));
 ui->dateStringLineEdit->setText(fromLmbcsQ(settings.dateString()));
 ui->timeStringLineEdit->setText(fromLmbcsQ(settings.timeString()));
 ui->yesterdayStringLineEdit->setText(fromLmbcsQ(settings.yesterdayString()));
 ui->todayStringLineEdit->setText(fromLmbcsQ(settings.todayString()));
 ui->tomorrowStringLineEdit->setText(fromLmbcsQ(settings.tomorrowString()));
}

void ConvertSimulatorDialog::setNumberFormatToDefault() {
 nxpp::NumberFormat numFormat;
 ui->digitsSpinBox->setValue(static_cast<int>(numFormat.digits()));
 setNumberFormat(numFormat.format());
 ui->isPunctuatedCheckBox->setChecked(numFormat.isPunctuated());
 ui->isParenCheckBox->setChecked(numFormat.isParen());
 ui->isVaryingCheckBox->setChecked(numFormat.isVarying());
 ui->isBytesCheckBox->setChecked(numFormat.isBytes());
}

void ConvertSimulatorDialog::setTimeFormatToDefault() {
 nxpp::TimeFormat timeFormat;
 setDateFormat(timeFormat.date());
 setTimeFormat(timeFormat.time());
 setZoneFormat(timeFormat.zone());
 setStructureFormat(timeFormat.structure());
}

void ConvertSimulatorDialog::consoleLog(const QString &msg) {
 ui->consoleLog->append(msg);
}

bool ConvertSimulatorDialog::isEnabledIntlSettings() const {
 return ui->intlFormatGroupBox->isChecked();
}

bool ConvertSimulatorDialog::isEnabledNFMTSettings() const {
 return ui->numberFormatGroupBox->isChecked();
}

bool ConvertSimulatorDialog::isEnabledTFMTSettings() const {
 return ui->dateTimeFormatGroupBox->isChecked();
}

nxpp::intl::SettingsPtr ConvertSimulatorDialog::makeIntlFormat() const {
 auto format = std::make_shared<nxpp::intl::Settings>();

 format->setCurrencySuffix(ui->isCurrencySuffixCheckBox->isChecked());
 format->setCurrencySpace(ui->isCurrencySpaceCheckBox->isChecked());
 format->setNumberLeadingZero(ui->isNumberLeadingZeroCheckBox->isChecked());
 format->setClock24Hour(ui->isClock24HourCheckBox->isChecked());
 format->setDaylightSavings(ui->isDaylightSavingsCheckBox->isChecked());
 format->setDateMDY(ui->isDateMDYCheckBox->isChecked());
 format->setDateDMY(ui->isDateDMYCheckBox->isChecked());
 format->setDateYMD(ui->isDateYMDCheckBox->isChecked());
 format->setDate4DigitYear(ui->isDate4DigitYearCheckBox->isChecked());
 format->setTimeAMPMPrefix(ui->isTimeAMPMPrefixCheckBox->isChecked());
 format->setDateAbbrev(ui->isDateAbbrevCheckBox->isChecked());

 format->setCurrencyDigits(static_cast<BYTE>(ui->currencyDigitsSpinBox->value()));
 format->setTimeZone(ui->timeZoneSpinBox->value());

 format->setAmString(toLmbcsQ(ui->amStringLineEdit->text()));
 format->setPmString(toLmbcsQ(ui->pmStringLineEdit->text()));
 format->setCurrencyString(toLmbcsQ(ui->currencyStringLineEdit->text()));
 format->setThousandString(toLmbcsQ(ui->thousandStringLineEdit->text()));
 format->setDecimalString(toLmbcsQ(ui->decimalStringLineEdit->text()));
 format->setDateString(toLmbcsQ(ui->dateStringLineEdit->text()));
 format->setTimeString(toLmbcsQ(ui->timeStringLineEdit->text()));
 format->setYesterdayString(toLmbcsQ(ui->yesterdayStringLineEdit->text()));
 format->setTodayString(toLmbcsQ(ui->todayStringLineEdit->text()));
 format->setTomorrowString(toLmbcsQ(ui->tomorrowStringLineEdit->text()));

 return format;
}

nxpp::NumberFormatPtr ConvertSimulatorDialog::makeNumberFormat() const {
 auto format = std::make_shared<nxpp::NumberFormat>();

 format->setDigits(static_cast<BYTE>(ui->digitsSpinBox->value()));

 format->setFormat(getNumberFormat());

 format->setPunctuated(ui->isPunctuatedCheckBox->isChecked());
 format->setParen(ui->isParenCheckBox->isChecked());
 format->setPercent(ui->isVaryingCheckBox->isChecked());
 format->setBytes(ui->isBytesCheckBox->isChecked());

 return format;
}

nxpp::TimeFormatPtr ConvertSimulatorDialog::makeDateTimeFormat() const {
 auto format = std::make_shared<nxpp::TimeFormat>();

 format->setDate(getDateFormat());
 format->setTime(getTimeFormat());
 format->setZone(getZoneFormat());
 format->setStructure(getStructureFormat());

 return format;
}

BYTE ConvertSimulatorDialog::getNumberFormat() const {
 auto s = ui->formatComboBox->currentText();
 if (s == tr("Fixed")) { return NFMT_FIXED; }
 else if (s == tr("Scientific")) { return NFMT_SCIENTIFIC; }
 else if (s == tr("Currency")) { return NFMT_CURRENCY; }
 else if (s == tr("Bytes")) { return NFMT_BYTES; }
 else { return NFMT_GENERAL; }
}

BYTE ConvertSimulatorDialog::getDateFormat() const {
 auto s = ui->dateComboBox->currentText();
 if (s == tr("Month and Day, Year if not this year")) { return TDFMT_CPARTIAL; }
 else if (s == tr("Month and Day")) { return TDFMT_PARTIAL; }
 else if (s == tr("Year and Month")) { return TDFMT_DPARTIAL; }
 else if (s == tr("Year(4-digit), Month and Day")) { return TDFMT_FULL4; }
 else if (s == tr("Month and Day, Year(4-digit) if not this year")) { return TDFMT_CPARTIAL4; }
 else if (s == tr("Year(4-digit) and Month")) { return TDFMT_DPARTIAL4; }
 else { return TDFMT_FULL; }
}

BYTE ConvertSimulatorDialog::getTimeFormat() const {
 auto s = ui->timeComboBox->currentText();
 if (s == tr("Hour and Minute")) { return TTFMT_PARTIAL; }
 else if (s == tr("Hour")) { return TTFMT_HOUR; }
 else { return TTFMT_FULL; }
}

BYTE ConvertSimulatorDialog::getZoneFormat() const {
 auto s = ui->zoneComboBox->currentText();
 if (s == tr("Show only when outside this time zone")) { return TZFMT_SOMETIMES; }
 else if (s == tr("Show time zone on all times, regardless")) { return TZFMT_ALWAYS; }
 else { return TZFMT_NEVER; }
}

BYTE ConvertSimulatorDialog::getStructureFormat() const {
 auto s = ui->structureComboBox->currentText();
 if (s == tr("Time")) { return TSFMT_TIME; }
 else if (s == tr("Date Time")) { return TSFMT_DATETIME; }
 else if (s == tr("Date Time, Time Today")) { return TSFMT_CDATETIME; }
 else { return TSFMT_DATE; }
}

void ConvertSimulatorDialog::setNumberFormat(BYTE format) {
 QString value;
 switch (format) {
 case NFMT_FIXED: value = tr("Fixed"); break;
 case NFMT_SCIENTIFIC: value = tr("Scientific"); break;
 case NFMT_CURRENCY: value = tr("Currency"); break;
 case NFMT_BYTES: value = tr("Bytes"); break;
 default: value = tr("General"); break;
 }
 ui->formatComboBox->setCurrentText(value);
}

void ConvertSimulatorDialog::setDateFormat(BYTE format) {
 QString value;
 switch (format) {
 case TDFMT_CPARTIAL: value = tr("Month and Day, Year if not this year"); break;
 case TDFMT_PARTIAL: value = tr("Month and Day"); break;
 case TDFMT_DPARTIAL: value = tr("Year and Month"); break;
 case TDFMT_FULL4: value = tr("Year(4-digit), Month and Day"); break;
 case TDFMT_CPARTIAL4: value = tr("Month and Day, Year(4-digit) if not this year"); break;
 case TDFMT_DPARTIAL4: value = tr("Year(4-digit) and Month"); break;
 default: value = tr("Year, Month, and Day"); break;
 }
 ui->dateComboBox->setCurrentText(value);
}

void ConvertSimulatorDialog::setTimeFormat(BYTE format) {
 QString value;
 switch (format) {
 case TTFMT_PARTIAL: value = tr("Hour and Minute"); break;
 case TTFMT_HOUR: value = tr("Hour"); break;
 default: value = tr("Hour, Minute, and Second"); break;
 }
 ui->timeComboBox->setCurrentText(value);
}

void ConvertSimulatorDialog::setZoneFormat(BYTE format) {
 QString value;
 switch (format) {
 case TZFMT_SOMETIMES: value = tr("Show only when outside this time zone"); break;
 case TZFMT_ALWAYS: value = tr("Show time zone on all times, regardless"); break;
 default: value = tr("All times converted to this time zone"); break;
 }
 ui->zoneComboBox->setCurrentText(value);
}

void ConvertSimulatorDialog::setStructureFormat(BYTE format) {
 QString value;
 switch (format) {
 case TSFMT_TIME: value = tr("Time"); break;
 case TSFMT_DATETIME: value = tr("Date Time"); break;
 case TSFMT_CDATETIME: value = tr("Date Time, Time Today"); break;
 default: value = tr("Date"); break;
 }
 ui->structureComboBox->setCurrentText(value);
}

非常に長いコードですが、おおむね今までやってきた内容のことを元に書いています。

強いてトピックスを上げるなら、QComboBoxの扱いについて。
このダイアログでは、QComboBoxを列挙値の選択に使っています。現在選択されている文字列を比較しながら、実際の列挙値を決めています。

まとめ

今回ご紹介したコンバートシミュレーターダイアログのコードには、Notes C APIとそれらをラップした仕組みも含まれています。これらを、次回から詳しく紐解いてみたいと思います。

この記事が気に入ったらサポートをしてみませんか?