Skip to content

Commit 9297fc4

Browse files
committed
fix(i18n): use proper plural forms in UserStatusSelectorModel
Many languages have different ways of handling plurals where checking for `n == 1` is simply not enough. Fixes #8149 Signed-off-by: Jyrki Gadinger <[email protected]>
1 parent ac12a0e commit 9297fc4

File tree

2 files changed

+37
-49
lines changed

2 files changed

+37
-49
lines changed

src/gui/userstatusselectormodel.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -410,25 +410,13 @@ QString UserStatusSelectorModel::timeDifferenceToString(int differenceSecs) cons
410410
return tr("Less than a minute");
411411
} else if (differenceSecs < 60 * 60) {
412412
const auto minutesLeft = static_cast<int>(std::ceil(differenceSecs / 60.0));
413-
if (minutesLeft == 1) {
414-
return tr("1 minute");
415-
} else {
416-
return tr("%1 minutes", "", minutesLeft).arg(minutesLeft);
417-
}
413+
return tr("%n minute(s)", "", minutesLeft);
418414
} else if (differenceSecs < 60 * 60 * 24) {
419415
const auto hoursLeft = static_cast<int>(std::ceil(differenceSecs / 60.0 / 60.0));
420-
if (hoursLeft == 1) {
421-
return tr("1 hour");
422-
} else {
423-
return tr("%1 hours", "", hoursLeft).arg(hoursLeft);
424-
}
416+
return tr("%n hour(s)", "", hoursLeft);
425417
} else {
426418
const auto daysLeft = static_cast<int>(std::ceil(differenceSecs / 60.0 / 60.0 / 24.0));
427-
if (daysLeft == 1) {
428-
return tr("1 day");
429-
} else {
430-
return tr("%1 days", "", daysLeft).arg(daysLeft);
431-
}
419+
return tr("%n day(s)", "", daysLeft);
432420
}
433421
}
434422

test/testsetuserstatusdialog.cpp

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ private slots:
228228
QCOMPARE(model.userStatusMessage(), userStatusMessage);
229229
QCOMPARE(model.userStatusEmoji(), userStatusIcon);
230230
QCOMPARE(model.onlineStatus(), userStatusState);
231-
QCOMPARE(model.clearAtDisplayString(), tr("1 day"));
231+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("1 day(s)"));
232232

233233
// Were predefined statuses fetched correctly?
234234
const auto predefinedStatusesCount = model.predefinedStatuses().count();
@@ -252,7 +252,7 @@ private slots:
252252

253253
QCOMPARE(model.userStatusMessage(), "");
254254
QCOMPARE(model.userStatusEmoji(), "😀");
255-
QCOMPARE(model.clearAtDisplayString(), tr("Don't clear"));
255+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("Don't clear"));
256256
}
257257

258258
void testCtor_fetchStatusButNoStatusSet_showSensibleDefaults()
@@ -265,7 +265,7 @@ private slots:
265265
QCOMPARE(model.onlineStatus(), OCC::UserStatus::OnlineStatus::Offline);
266266
QCOMPARE(model.userStatusMessage(), "");
267267
QCOMPARE(model.userStatusEmoji(), "😀");
268-
QCOMPARE(model.clearAtDisplayString(), tr("Don't clear"));
268+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("Don't clear"));
269269
}
270270

271271
void testSetOnlineStatus_emiUserStatusChanged()
@@ -393,7 +393,7 @@ private slots:
393393
QCOMPARE(model.userStatusMessage(), fakePredefinedUserStatus.message());
394394
QCOMPARE(model.userStatusEmoji(), fakePredefinedUserStatus.icon());
395395
QCOMPARE(model.onlineStatus(), fakePredefinedUserStatus.state());
396-
QCOMPARE(model.clearAtDisplayString(), tr("1 hour"));
396+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("1 hour(s)"));
397397
}
398398

399399
void testSetClear_setClearAtStage0_emitclearAtDisplayStringChangedAndClearAtSet()
@@ -406,7 +406,7 @@ private slots:
406406
model.setClearAt(clearAtToSet);
407407

408408
QCOMPARE(clearAtDisplayStringChangedSpy.count(), 1);
409-
QCOMPARE(model.clearAtDisplayString(), tr("Don't clear"));
409+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("Don't clear"));
410410
}
411411

412412
void testSetClear_setClearAtStage1_emitclearAtDisplayStringChangedAndClearAtSet()
@@ -419,7 +419,7 @@ private slots:
419419
model.setClearAt(clearAtToSet);
420420

421421
QCOMPARE(clearAtDisplayStringChangedSpy.count(), 1);
422-
QCOMPARE(model.clearAtDisplayString(), tr("30 minutes"));
422+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("30 minute(s)"));
423423
}
424424

425425
void testSetClear_setClearAtStage2_emitclearAtDisplayStringChangedAndClearAtSet()
@@ -432,7 +432,7 @@ private slots:
432432
model.setClearAt(clearAtToSet);
433433

434434
QCOMPARE(clearAtDisplayStringChangedSpy.count(), 1);
435-
QCOMPARE(model.clearAtDisplayString(), tr("1 hour"));
435+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("1 hour(s)"));
436436
}
437437

438438
void testSetClear_setClearAtStage3_emitclearAtDisplayStringChangedAndClearAtSet()
@@ -445,7 +445,7 @@ private slots:
445445
model.setClearAt(clearAtToSet);
446446

447447
QCOMPARE(clearAtDisplayStringChangedSpy.count(), 1);
448-
QCOMPARE(model.clearAtDisplayString(), tr("4 hours"));
448+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("4 hour(s)"));
449449
}
450450

451451
void testSetClear_setClearAtStage4_emitclearAtDisplayStringChangedAndClearAtSet()
@@ -458,7 +458,7 @@ private slots:
458458
model.setClearAt(clearAtToSet);
459459

460460
QCOMPARE(clearAtDisplayStringChangedSpy.count(), 1);
461-
QCOMPARE(model.clearAtDisplayString(), tr("Today"));
461+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("Today"));
462462
}
463463

464464
void testSetClear_setClearAtStage5_emitclearAtDisplayStringChangedAndClearAtSet()
@@ -471,24 +471,24 @@ private slots:
471471
model.setClearAt(clearAtToSet);
472472

473473
QCOMPARE(clearAtDisplayStringChangedSpy.count(), 1);
474-
QCOMPARE(model.clearAtDisplayString(), tr("This week"));
474+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("This week"));
475475
}
476476

477477
void testClearAtStages()
478478
{
479479
auto fakeUserStatusJob = std::make_shared<FakeUserStatusConnector>();
480480
OCC::UserStatusSelectorModel model(fakeUserStatusJob);
481481

482-
QCOMPARE(model.clearAtDisplayString(), tr("Don't clear"));
482+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("Don't clear"));
483483
const auto clearStageTypes = model.clearStageTypes();
484484
QCOMPARE(clearStageTypes.count(), 6);
485485

486-
QCOMPARE(clearStageTypes[0].value<QVariantMap>()[QStringLiteral("display")], tr("Don't clear"));
487-
QCOMPARE(clearStageTypes[1].value<QVariantMap>()[QStringLiteral("display")], tr("30 minutes"));
488-
QCOMPARE(clearStageTypes[2].value<QVariantMap>()[QStringLiteral("display")], tr("1 hour"));
489-
QCOMPARE(clearStageTypes[3].value<QVariantMap>()[QStringLiteral("display")], tr("4 hours"));
490-
QCOMPARE(clearStageTypes[4].value<QVariantMap>()[QStringLiteral("display")], tr("Today"));
491-
QCOMPARE(clearStageTypes[5].value<QVariantMap>()[QStringLiteral("display")], tr("This week"));
486+
QCOMPARE(clearStageTypes[0].value<QVariantMap>()[QStringLiteral("display")], QStringLiteral("Don't clear"));
487+
QCOMPARE(clearStageTypes[1].value<QVariantMap>()[QStringLiteral("display")], QStringLiteral("30 minutes"));
488+
QCOMPARE(clearStageTypes[2].value<QVariantMap>()[QStringLiteral("display")], QStringLiteral("1 hour"));
489+
QCOMPARE(clearStageTypes[3].value<QVariantMap>()[QStringLiteral("display")], QStringLiteral("4 hours"));
490+
QCOMPARE(clearStageTypes[4].value<QVariantMap>()[QStringLiteral("display")], QStringLiteral("Today"));
491+
QCOMPARE(clearStageTypes[5].value<QVariantMap>()[QStringLiteral("display")], QStringLiteral("This week"));
492492
}
493493

494494
void testClearAt_clearAtTimestamp()
@@ -506,7 +506,7 @@ private slots:
506506

507507
OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider));
508508

509-
QCOMPARE(model.clearAtDisplayString(), tr("Less than a minute"));
509+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("Less than a minute"));
510510
}
511511

512512
{
@@ -521,7 +521,7 @@ private slots:
521521

522522
OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider));
523523

524-
QCOMPARE(model.clearAtDisplayString(), tr("1 minute"));
524+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("1 minute(s)"));
525525
}
526526

527527
{
@@ -536,7 +536,7 @@ private slots:
536536

537537
OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider));
538538

539-
QCOMPARE(model.clearAtDisplayString(), tr("30 minutes"));
539+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("30 minute(s)"));
540540
}
541541

542542
{
@@ -551,7 +551,7 @@ private slots:
551551

552552
OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider));
553553

554-
QCOMPARE(model.clearAtDisplayString(), tr("1 hour"));
554+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("1 hour(s)"));
555555
}
556556

557557
{
@@ -566,7 +566,7 @@ private slots:
566566

567567
OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider));
568568

569-
QCOMPARE(model.clearAtDisplayString(), tr("4 hours"));
569+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("4 hour(s)"));
570570
}
571571

572572
{
@@ -581,7 +581,7 @@ private slots:
581581

582582
OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider));
583583

584-
QCOMPARE(model.clearAtDisplayString(), tr("1 day"));
584+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("1 day(s)"));
585585
}
586586

587587
{
@@ -596,7 +596,7 @@ private slots:
596596

597597
OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider));
598598

599-
QCOMPARE(model.clearAtDisplayString(), tr("7 days"));
599+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("7 day(s)"));
600600
}
601601
}
602602

@@ -611,7 +611,7 @@ private slots:
611611

612612
OCC::UserStatusSelectorModel model(userStatus);
613613

614-
QCOMPARE(model.clearAtDisplayString(), tr("Today"));
614+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("Today"));
615615
}
616616

617617
{
@@ -623,7 +623,7 @@ private slots:
623623

624624
OCC::UserStatusSelectorModel model(userStatus);
625625

626-
QCOMPARE(model.clearAtDisplayString(), tr("This week"));
626+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("This week"));
627627
}
628628
}
629629

@@ -638,7 +638,7 @@ private slots:
638638

639639
OCC::UserStatusSelectorModel model(userStatus);
640640

641-
QCOMPARE(model.clearAtDisplayString(), tr("30 minutes"));
641+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("30 minute(s)"));
642642
}
643643

644644
{
@@ -650,7 +650,7 @@ private slots:
650650

651651
OCC::UserStatusSelectorModel model(userStatus);
652652

653-
QCOMPARE(model.clearAtDisplayString(), tr("1 hour"));
653+
QCOMPARE(model.clearAtDisplayString(), QStringLiteral("1 hour(s)"));
654654
}
655655
}
656656

@@ -671,7 +671,7 @@ private slots:
671671
OCC::UserStatusSelectorModel model(fakeUserStatusJob);
672672

673673
QCOMPARE(model.errorMessage(),
674-
tr("Could not fetch predefined statuses. Make sure you are connected to the server."));
674+
QStringLiteral("Could not fetch predefined statuses. Make sure you are connected to the server."));
675675
}
676676

677677
void testError_couldNotFetchUserStatus_emitError()
@@ -681,7 +681,7 @@ private slots:
681681
OCC::UserStatusSelectorModel model(fakeUserStatusJob);
682682

683683
QCOMPARE(model.errorMessage(),
684-
tr("Could not fetch status. Make sure you are connected to the server."));
684+
QStringLiteral("Could not fetch status. Make sure you are connected to the server."));
685685
}
686686

687687
void testError_userStatusNotSupported_emitError()
@@ -691,7 +691,7 @@ private slots:
691691
OCC::UserStatusSelectorModel model(fakeUserStatusJob);
692692

693693
QCOMPARE(model.errorMessage(),
694-
tr("Status feature is not supported. You will not be able to set your status."));
694+
QStringLiteral("Status feature is not supported. You will not be able to set your status."));
695695
}
696696

697697
void testError_couldSetUserStatus_emitError()
@@ -702,7 +702,7 @@ private slots:
702702
model.setUserStatus();
703703

704704
QCOMPARE(model.errorMessage(),
705-
tr("Could not set status. Make sure you are connected to the server."));
705+
QStringLiteral("Could not set status. Make sure you are connected to the server."));
706706
}
707707

708708
void testError_emojisNotSupported_emitError()
@@ -712,7 +712,7 @@ private slots:
712712
OCC::UserStatusSelectorModel model(fakeUserStatusJob);
713713

714714
QCOMPARE(model.errorMessage(),
715-
tr("Emojis are not supported. Some status functionality may not work."));
715+
QStringLiteral("Emojis are not supported. Some status functionality may not work."));
716716
}
717717

718718
void testError_couldNotClearMessage_emitError()
@@ -723,7 +723,7 @@ private slots:
723723
model.clearUserStatus();
724724

725725
QCOMPARE(model.errorMessage(),
726-
tr("Could not clear status message. Make sure you are connected to the server."));
726+
QStringLiteral("Could not clear status message. Make sure you are connected to the server."));
727727
}
728728

729729
void testError_setUserStatus_clearErrorMessage()

0 commit comments

Comments
 (0)