![見出し画像](https://assets.st-note.com/production/uploads/images/62110497/rectangle_large_type_2_541a379f4998f7ed5ef8b7838e10c0f9.png?width=1200)
Notes C API探訪: コンバートシミュレーターダイアログv1.1
以前の記事(UI作成とコーディング)で、コンバートシミュレーターダイアログを作成しました。
今回、日時コンバーターの紹介も終わったところなので、少しコードを見直したら、バグや不具合を見つけたので、機能もアップしてバージョン1.1にしてみました。
まず、TIMEDATE型からQDateTimeに変換するロジックの修正です(掲載記事)。タイムゾーンに夏時間が含まれていないことがわかったので、夏時間を含むタイムゾーンになるように調整しました。修正コードもそちらの記事に掲載しています。
次に、数値フォーマットを設定するUIについて(掲載記事)。実は、ここにパーセント表示をオン/オフするチェックボックスが欠落していました。記事は動画と画像で紹介しているので、記事内の修正でなく、こちらの画像で修正点を紹介します。
ソースコードも次のように直しています。次の画像はフォーマット作成時です。
次の画像は、デフォルト設定に戻すボタン設定です。
次は、機能をアップしたところです。
今回、日時のタイムゾーンを見直した経緯もあり、日時に現地時間を適用する機能を付けました。まずはUIです。
上の方が、設定した日時を現地時間に変更するためのタイムゾーン選択コンボボックスです。
下の方は、変換した日時が含んでいるタイムゾーンリストの表示と、夏時間の有無です。
日時をテキストに変換する方は、次のようなコードに変更しました。
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件の記事を要しました。
次回は番外編、このシリーズの途中で世界時計を作ったので、それをご紹介します。