見出し画像

Notes C API探訪: コンバートシミュレーターダイアログv1.1

以前の記事(UI作成コーディング)で、コンバートシミュレーターダイアログを作成しました。
今回、日時コンバーターの紹介も終わったところなので、少しコードを見直したら、バグや不具合を見つけたので、機能もアップしてバージョン1.1にしてみました。

まず、TIMEDATE型からQDateTimeに変換するロジックの修正です(掲載記事)。タイムゾーンに夏時間が含まれていないことがわかったので、夏時間を含むタイムゾーンになるように調整しました。修正コードもそちらの記事に掲載しています。

次に、数値フォーマットを設定するUIについて(掲載記事)。実は、ここにパーセント表示をオン/オフするチェックボックスが欠落していました。記事は動画と画像で紹介しているので、記事内の修正でなく、こちらの画像で修正点を紹介します。

スクリーンショット 2021-09-26 16.17.15

ソースコードも次のように直しています。次の画像はフォーマット作成時です。

スクリーンショット 2021-09-26 16.19.47

次の画像は、デフォルト設定に戻すボタン設定です。

スクリーンショット 2021-09-26 16.21.44

次は、機能をアップしたところです。
今回、日時のタイムゾーンを見直した経緯もあり、日時に現地時間を適用する機能を付けました。まずはUIです。

スクリーンショット 2021-09-26 16.24.52

上の方が、設定した日時を現地時間に変更するためのタイムゾーン選択コンボボックスです。
下の方は、変換した日時が含んでいるタイムゾーンリストの表示と、夏時間の有無です。

日時をテキストに変換する方は、次のようなコードに変更しました。

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

 try {
   QDateTime dt = ui_->dateTimeToTextDateTimeEdit->dateTime();
   QTimeZone timeZone(
         ui_->dateTimeToTextTimeZoneComboBox->currentText().toLatin1()
         );
   dt = dt.toTimeZone(timeZone);
   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));
 }
}

日時エディタに設定されている時間はローカル時間(日本時間)なので、選択したタイムゾーンで現地時間に修正します。現地時間になったQDateTimeをTIMEDATEにした上で、テキストにコンバートします。ここで「タイムゾーンフォーマット」の設定が「ローカルのタイムゾーンに合わせる」になっていると、せっかく現地時間にしても日本時間に戻ってしまいます。「ローカル以外はタイムゾーンを表示する」または「常にタイムゾーンを表示する」を選択して、現地時間でテキストに変換すれば、期待したテキストが表示されます。

次にテキストから日時に変換するロジックです。

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

 try {
   QString text = ui_->textToDateTimeLineEdit->text();
   TIMEDATE td = converter(toLmbcsQ(text));
   auto dt = nxpp::qt::fromTIMEDATE(td);
   ui_->textToDateTimeDateTimeEdit->setDateTime(dt);
   ui_->textToDateTimeDstCheckBox->setChecked(dt.isDaylightTime());

   ui_->textToDateTimeTimeZoneComboBox->clear();
   auto tz = dt.timeZone();
   auto isDST = tz.isDaylightTime(dt);
   auto offset = dt.offsetFromUtc() - (isDST ? 3600 : 0);
   auto ids = QTimeZone::availableTimeZoneIds(offset);
   foreach (auto id, ids) {
     QTimeZone timeZone(id);
     if (timeZone.isDaylightTime(dt) == isDST) {
       ui_->textToDateTimeTimeZoneComboBox->addItem(QString::fromLatin1(id));
     }
   }
 }
 // Notesステータスがスローされたらそのエラーメッセージに変換して表示
 catch (nxpp::Status &status) {
   consoleLog(nxpp::qt::fromStatus(status.error()));
 }
 // それ以外の例外ならそのメッセージを表示
 catch (std::exception &ex) {
   std::string what(ex.what());
   consoleLog(QString::fromStdString(what));
 }
}

少々複雑ですが、これはタイムゾーンの復元度によるものです。テキストから日時(TIMEDATE)に変換すると、タイムゾーンは「UTCからのオフセット値」と「夏時間の有無」にパースされます。この2つから適切なタイムゾーンを導き出すのは以外に面倒で、現時点では「オフセット夏時間の有無から有効なタイムゾーンリストを提示する」ことを落とし所としました。

実演

以上を踏まえて、簡単な実演を動画にしました。

まとめ

今回の記事までで、いったんテキストコンバートシリーズは完結とします。ここで紹介したかったNotes C APIは、以下の4つです。

1. ConvertFLOATToText
2. ConvertTextToFLOAT
3. ConvertTIMEDATEToText
4. ConvertTextToTIMEDATE

たったこれだけだったんですが、INTLFORMATのラップから始めて、途中にQt5のウィジェットも絡めながら、計25件の記事を要しました。

次回は番外編、このシリーズの途中で世界時計を作ったので、それをご紹介します。



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