Skip to content

Commit fa90959

Browse files
authored
Merge pull request #74 from NickvisionApps/next
V2025.5.2
2 parents 4078e85 + 41cb003 commit fa90959

File tree

7 files changed

+71
-41
lines changed

7 files changed

+71
-41
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
# Changelog
22

3+
## 2025.5.2
4+
### Breaking Changes
5+
None
6+
### New APIs
7+
#### Localization
8+
- Added `_fn()` macro for creating strings with translated plural format strings
9+
### Fixes
10+
- Fixed compilation on x86 Windows
11+
312
## 2025.5.1
413
### Breaking Changes
514
#### System
615
- A Process' status can now be queued with `Process::getState()` which returns a `ProcessState` value
716
### New APIs
8-
#### Localizationm
17+
#### Localization
918
- Added `_f()` macro for creating strings with translated format strings
1019
- Added `Gettext::getAvailableLanguages()` function
1120
#### System

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ endif()
2020
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
2121

2222
#libnick Definition
23-
project ("libnick" LANGUAGES C CXX VERSION 2025.5.1 DESCRIPTION "A cross-platform base for native Nickvision applications.")
23+
project ("libnick" LANGUAGES C CXX VERSION 2025.5.2 DESCRIPTION "A cross-platform base for native Nickvision applications.")
2424
include(CMakePackageConfigHelpers)
2525
include(GNUInstallDirs)
2626
include(CTest)

Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ PROJECT_NAME = "libnick"
4848
# could be handy for archiving the generated documentation or if some version
4949
# control system is used.
5050

51-
PROJECT_NUMBER = "2025.5.1"
51+
PROJECT_NUMBER = "2025.5.2"
5252

5353
# Using the PROJECT_BRIEF tag one can provide an optional one line description
5454
# for a project that appears at the top of each page and should give viewer a

include/localization/gettext.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define _(String) dgettext(::Nickvision::Localization::Gettext::getDomainName().c_str(), String)
3333
#define _n(String, StringPlural, N) dngettext(::Nickvision::Localization::Gettext::getDomainName().c_str(), String, StringPlural, static_cast<unsigned long>(N))
3434
#define _f(String, ...) ::Nickvision::Localization::Gettext::fgettext(String, __VA_ARGS__)
35+
#define _fn(String, StringPlural, N, ...) ::Nickvision::Localization::Gettext::fngettext(String, StringPlural, static_cast<unsigned long>(N), __VA_ARGS__)
3536
#define _p(Context, String) ::Nickvision::Localization::Gettext::pgettext(Context GETTEXT_CONTEXT_SEPARATOR String, String)
3637
#define _pn(Context, String, StringPlural, N) ::Nickvision::Localization::Gettext::pngettext(Context GETTEXT_CONTEXT_SEPARATOR String, String, StringPlural, static_cast<unsigned long>(N))
3738

@@ -65,6 +66,20 @@ namespace Nickvision::Localization::Gettext
6566
res = std::vformat(_(msg), std::make_format_args(args...));
6667
return res.c_str();
6768
}
69+
/**
70+
* @brief Translates a plural message and formats it with the given arguments.
71+
* @param msg The message to translate
72+
* @param msgPlural The plural version of the message to translate
73+
* @param n The number of objects (used to determine whether or not to use the plural version of the message)
74+
* @param args The arguments to format the translated message with
75+
*/
76+
template<typename... Args>
77+
const char* fngettext(const char* msg, const char* msgPlural, unsigned long n, Args&&... args)
78+
{
79+
static std::string res;
80+
res = std::vformat(_n(msg, msgPlural, n), std::make_format_args(args...));
81+
return res.c_str();
82+
}
6883
/**
6984
* @brief Translates a message for a given context.
7085
* @param context The context of the message

manual/README.md

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,14 @@
66

77
libnick provides Nickvision apps with a common set of cross-platform APIs for managing system and desktop app functionality such as network management, taskbar icons, translations, app updates, and more.
88

9-
## 2025.5.1
9+
## 2025.5.2
1010
### Breaking Changes
11-
#### System
12-
- A Process' status can now be queued with `Process::getState()` which returns a `ProcessState` value
11+
None
1312
### New APIs
14-
#### Localizationm
15-
- Added `_f()` macro for creating strings with translated format strings
16-
- Added `Gettext::getAvailableLanguages()` function
17-
#### System
18-
- Added `ProcessState` enum
19-
- Added `Process::pause()` method
20-
- Added `Process::resume()` method
13+
#### Localization
14+
- Added `_fn()` macro for creating strings with translated plural format strings
2115
### Fixes
22-
None
16+
- Fixed compilation on x86 Windows
2317

2418
## Dependencies
2519
The following are a list of dependencies used by libnick.

src/notifications/shellnotification.cpp

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,42 +18,48 @@
1818
using namespace Nickvision::App;
1919
using namespace Nickvision::System;
2020

21+
#ifdef _WIN32
22+
static std::filesystem::path s_openPath;
23+
24+
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
25+
{
26+
if(msg == WM_TRAYICON)
27+
{
28+
if(lParam == NIN_BALLOONUSERCLICK)
29+
{
30+
if(std::filesystem::exists(s_openPath))
31+
{
32+
ShellExecuteA(hwnd, "open", s_openPath.string().c_str(), nullptr, nullptr, SW_SHOWDEFAULT);
33+
}
34+
}
35+
}
36+
else if(msg == WM_TIMER)
37+
{
38+
if(wParam == TIMER_ID)
39+
{
40+
KillTimer(hwnd, TIMER_ID);
41+
PostQuitMessage(0);
42+
}
43+
}
44+
else if(msg == WM_DESTROY)
45+
{
46+
PostQuitMessage(0);
47+
}
48+
return DefWindowProcA(hwnd, msg, wParam, lParam);
49+
}
50+
#endif
51+
2152
namespace Nickvision::Notifications
2253
{
2354
void ShellNotification::send(const ShellNotificationSentEventArgs& e, const AppInfo& info, const std::string& openText)
2455
{
2556
#ifdef _WIN32
57+
s_openPath = e.getAction() == "open" ? e.getActionParam() : "";
2658
std::thread worker{ [e, info]()
2759
{
28-
static std::filesystem::path path{ e.getAction() == "open" ? e.getActionParam() : "" };
2960
std::string className{ "libnick_notification" };
3061
WNDCLASSA wc{};
31-
wc.lpfnWndProc = +[](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -> LRESULT
32-
{
33-
if(msg == WM_TRAYICON)
34-
{
35-
if(lParam == NIN_BALLOONUSERCLICK)
36-
{
37-
if(std::filesystem::exists(path))
38-
{
39-
ShellExecuteA(hwnd, "open", path.string().c_str(), nullptr, nullptr, SW_SHOWDEFAULT);
40-
}
41-
}
42-
}
43-
else if(msg == WM_TIMER)
44-
{
45-
if(wParam == TIMER_ID)
46-
{
47-
KillTimer(hwnd, TIMER_ID);
48-
PostQuitMessage(0);
49-
}
50-
}
51-
else if(msg == WM_DESTROY)
52-
{
53-
PostQuitMessage(0);
54-
}
55-
return DefWindowProcA(hwnd, msg, wParam, lParam);
56-
};
62+
wc.lpfnWndProc = wndProc;
5763
wc.hInstance = GetModuleHandleA(nullptr);
5864
wc.lpszClassName = className.c_str();
5965
RegisterClassA(&wc);

tests/localizationtests.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ TEST(LocalizationTests, fgettext)
3131
ASSERT_EQ(std::string(_f("Hello {} {}", "World", count)), std::string("Hello World 1"));
3232
}
3333

34+
TEST(LocalizationTests, fngettext)
35+
{
36+
int count{ 2 };
37+
ASSERT_EQ(std::string(_fn("Hello {}", "Hellos {}", count, "World")), std::string("Hellos World"));
38+
}
39+
3440
TEST(LocalizationTests, pgettext)
3541
{
3642
ASSERT_EQ(std::string(_p("Test", "Hello")), std::string("Hello"));

0 commit comments

Comments
 (0)