mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	[i18n] start multilang support for webconsole
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
		
							parent
							
								
									59b471b9a2
								
							
						
					
					
						commit
						0e68fe4a57
					
				
					 6 changed files with 140 additions and 19 deletions
				
			
		
							
								
								
									
										9
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -7,6 +7,7 @@ I2PD := i2pd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LIB_SRC_DIR := libi2pd
 | 
					LIB_SRC_DIR := libi2pd
 | 
				
			||||||
LIB_CLIENT_SRC_DIR := libi2pd_client
 | 
					LIB_CLIENT_SRC_DIR := libi2pd_client
 | 
				
			||||||
 | 
					LANG_SRC_DIR := i18n
 | 
				
			||||||
DAEMON_SRC_DIR := daemon
 | 
					DAEMON_SRC_DIR := daemon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# import source files lists
 | 
					# import source files lists
 | 
				
			||||||
| 
						 | 
					@ -49,12 +50,13 @@ ifeq ($(USE_MESHNET),yes)
 | 
				
			||||||
	NEEDED_CXXFLAGS += -DMESHNET
 | 
						NEEDED_CXXFLAGS += -DMESHNET
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR)
 | 
					NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LIB_OBJS        += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
 | 
					LIB_OBJS        += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
 | 
				
			||||||
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
 | 
					LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
 | 
				
			||||||
 | 
					LANG_OBJS       += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
 | 
				
			||||||
DAEMON_OBJS     += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
 | 
					DAEMON_OBJS     += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
 | 
				
			||||||
DEPS            += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d)
 | 
					DEPS            += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
 | 
					all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +65,7 @@ mk_obj_dir:
 | 
				
			||||||
	@mkdir -p obj/Win32
 | 
						@mkdir -p obj/Win32
 | 
				
			||||||
	@mkdir -p obj/$(LIB_SRC_DIR)
 | 
						@mkdir -p obj/$(LIB_SRC_DIR)
 | 
				
			||||||
	@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
 | 
						@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
 | 
				
			||||||
 | 
						@mkdir -p obj/$(LANG_SRC_DIR)
 | 
				
			||||||
	@mkdir -p obj/$(DAEMON_SRC_DIR)
 | 
						@mkdir -p obj/$(DAEMON_SRC_DIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
api: mk_obj_dir $(SHLIB) $(ARLIB)
 | 
					api: mk_obj_dir $(SHLIB) $(ARLIB)
 | 
				
			||||||
| 
						 | 
					@ -82,7 +85,7 @@ obj/%.o: %.cpp
 | 
				
			||||||
# '-' is 'ignore if missing' on first run
 | 
					# '-' is 'ignore if missing' on first run
 | 
				
			||||||
-include $(DEPS)
 | 
					-include $(DEPS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
 | 
					$(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
 | 
				
			||||||
	$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
 | 
						$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(SHLIB): $(LIB_OBJS)
 | 
					$(SHLIB): $(LIB_OBJS)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,12 @@
 | 
				
			||||||
#include "Daemon.h"
 | 
					#include "Daemon.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
#include "ECIESX25519AEADRatchetSession.h"
 | 
					#include "ECIESX25519AEADRatchetSession.h"
 | 
				
			||||||
 | 
					#include "I18N.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					#include <boost/filesystem.hpp>
 | 
				
			||||||
 | 
					#include <codecvt>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WIN32_APP
 | 
					#ifdef WIN32_APP
 | 
				
			||||||
#include "Win32App.h"
 | 
					#include "Win32App.h"
 | 
				
			||||||
| 
						 | 
					@ -130,23 +136,37 @@ namespace http {
 | 
				
			||||||
	static std::string ConvertTime (uint64_t time);
 | 
						static std::string ConvertTime (uint64_t time);
 | 
				
			||||||
	std::map<uint32_t, uint32_t> HTTPConnection::m_Tokens;
 | 
						std::map<uint32_t, uint32_t> HTTPConnection::m_Tokens;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string DataPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static void SetDataDir ()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
							boost::filesystem::wpath path (i2p::fs::GetDataDir());
 | 
				
			||||||
 | 
							auto loc = boost::filesystem::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16<wchar_t>() ) );
 | 
				
			||||||
 | 
							i2p::http::DataPath = path.string();
 | 
				
			||||||
 | 
							boost::filesystem::path::imbue(loc); // Return it back
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							i2p::http::DataPath = i2p::fs::GetDataDir();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static void ShowUptime (std::stringstream& s, int seconds)
 | 
						static void ShowUptime (std::stringstream& s, int seconds)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		int num;
 | 
							int num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((num = seconds / 86400) > 0) {
 | 
							if ((num = seconds / 86400) > 0) {
 | 
				
			||||||
			s << num << " days, ";
 | 
								s << num << " " << tr("days", num) << ", ";
 | 
				
			||||||
			seconds -= num * 86400;
 | 
								seconds -= num * 86400;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if ((num = seconds / 3600) > 0) {
 | 
							if ((num = seconds / 3600) > 0) {
 | 
				
			||||||
			s << num << " hours, ";
 | 
								s << num << " " << tr("hours", num) << ", ";
 | 
				
			||||||
			seconds -= num * 3600;
 | 
								seconds -= num * 3600;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if ((num = seconds / 60) > 0) {
 | 
							if ((num = seconds / 60) > 0) {
 | 
				
			||||||
			s << num << " min, ";
 | 
								s << num << " " << tr("minutes", num) << ", ";
 | 
				
			||||||
			seconds -= num * 60;
 | 
								seconds -= num * 60;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		s << seconds << " seconds";
 | 
							s << seconds << " " << tr("seconds", seconds);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static void ShowTraffic (std::stringstream& s, uint64_t bytes)
 | 
						static void ShowTraffic (std::stringstream& s, uint64_t bytes)
 | 
				
			||||||
| 
						 | 
					@ -197,11 +217,7 @@ namespace http {
 | 
				
			||||||
			"<!DOCTYPE html>\r\n"
 | 
								"<!DOCTYPE html>\r\n"
 | 
				
			||||||
			"<html lang=\"en\">\r\n" /* TODO: Add support for locale */
 | 
								"<html lang=\"en\">\r\n" /* TODO: Add support for locale */
 | 
				
			||||||
			"  <head>\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
 | 
								"  <head>\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
 | 
				
			||||||
#if (!defined(WIN32))
 | 
					 | 
				
			||||||
			"  <meta charset=\"UTF-8\">\r\n"
 | 
								"  <meta charset=\"UTF-8\">\r\n"
 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
			"  <meta charset=\"windows-1251\">\r\n"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
			"  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n"
 | 
								"  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n"
 | 
				
			||||||
			"  <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
 | 
								"  <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
 | 
				
			||||||
			"  <title>Purple I2P " VERSION " Webconsole</title>\r\n"
 | 
								"  <title>Purple I2P " VERSION " Webconsole</title>\r\n"
 | 
				
			||||||
| 
						 | 
					@ -315,7 +331,7 @@ namespace http {
 | 
				
			||||||
		s << "<b>Transit:</b> ";
 | 
							s << "<b>Transit:</b> ";
 | 
				
			||||||
		ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
 | 
							ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
 | 
				
			||||||
		s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)<br>\r\n";
 | 
							s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)<br>\r\n";
 | 
				
			||||||
		s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n";
 | 
							s << "<b>Data path:</b> " << i2p::http::DataPath << "<br>\r\n";
 | 
				
			||||||
		s << "<div class='slide'>";
 | 
							s << "<div class='slide'>";
 | 
				
			||||||
		if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) {
 | 
							if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) {
 | 
				
			||||||
			s << "<label for=\"slide-info\">Hidden content. Press on text to see.</label>\r\n<input type=\"checkbox\" id=\"slide-info\" />\r\n<div class=\"slidecontent\">\r\n";
 | 
								s << "<label for=\"slide-info\">Hidden content. Press on text to see.</label>\r\n<input type=\"checkbox\" id=\"slide-info\" />\r\n<div class=\"slidecontent\">\r\n";
 | 
				
			||||||
| 
						 | 
					@ -1374,6 +1390,8 @@ namespace http {
 | 
				
			||||||
			LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
 | 
								LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							i2p::http::SetDataDir();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m_IsRunning = true;
 | 
							m_IsRunning = true;
 | 
				
			||||||
		m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this)));
 | 
							m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this)));
 | 
				
			||||||
		m_Acceptor.listen ();
 | 
							m_Acceptor.listen ();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,4 +19,6 @@ LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp)
 | 
				
			||||||
#DAEMON_SRC = \
 | 
					#DAEMON_SRC = \
 | 
				
			||||||
#	HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp
 | 
					#	HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp)
 | 
					DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										39
									
								
								i18n/I18N.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								i18n/I18N.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,39 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2021, The PurpleI2P Project
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* This file is part of Purple i2pd project and licensed under BSD3
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* See full license text in LICENSE file at top of project tree
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __I18N_H__
 | 
				
			||||||
 | 
					#define __I18N_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace i2p {
 | 
				
			||||||
 | 
					namespace i18n {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						namespace russian {
 | 
				
			||||||
 | 
							std::string GetString (std::string arg);
 | 
				
			||||||
 | 
							std::string GetPlural (std::string arg, int n);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string translate (std::string arg)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return i2p::i18n::russian::GetString (arg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template<typename inttype>
 | 
				
			||||||
 | 
						std::string translate (std::string arg, inttype&& n)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return i2p::i18n::russian::GetPlural (arg, (int) n);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // i18n
 | 
				
			||||||
 | 
					} // i2p
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... TArgs>
 | 
				
			||||||
 | 
					std::string tr (TArgs&&... args) {
 | 
				
			||||||
 | 
						return i2p::i18n::translate(std::forward<TArgs>(args)...);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // __I18N_H__
 | 
				
			||||||
							
								
								
									
										56
									
								
								i18n/russian.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								i18n/russian.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,56 @@
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Russian localization file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace i2p {
 | 
				
			||||||
 | 
					namespace i18n {
 | 
				
			||||||
 | 
					namespace russian { // language
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// See for language plural forms here:
 | 
				
			||||||
 | 
						// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
 | 
				
			||||||
 | 
						int plural (int n) {
 | 
				
			||||||
 | 
							return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static std::map<std::string, std::string> strings
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							{"Enabled", "Включено"},
 | 
				
			||||||
 | 
							{"Disabled", "Выключено"}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static std::map<std::string, std::vector<std::string>> plurals
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							{"days",    {"день", "дня", "дней"}},
 | 
				
			||||||
 | 
							{"hours",   {"час", "часа", "часов"}},
 | 
				
			||||||
 | 
							{"minutes", {"минута", "минуты", "минут"}},
 | 
				
			||||||
 | 
							{"seconds", {"секунда", "секунды", "секунд"}}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string GetString (std::string arg)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto it = strings.find(arg);
 | 
				
			||||||
 | 
							if (it == strings.end())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return arg;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return it->second;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string GetPlural (std::string arg, int n)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto it = plurals.find(arg);
 | 
				
			||||||
 | 
							if (it == plurals.end())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return arg;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								int form = plural(n);
 | 
				
			||||||
 | 
								return it->second[form];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // language
 | 
				
			||||||
 | 
					} // i18n
 | 
				
			||||||
 | 
					} // i2p
 | 
				
			||||||
| 
						 | 
					@ -47,10 +47,10 @@ namespace fs {
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
		char localAppData[MAX_PATH];
 | 
							wchar_t localAppData[MAX_PATH];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// check executable directory first
 | 
							// check executable directory first
 | 
				
			||||||
		if(!GetModuleFileName(NULL, localAppData, MAX_PATH))
 | 
							if(!GetModuleFileNameW(NULL, localAppData, MAX_PATH))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
#ifdef WIN32_APP
 | 
					#ifdef WIN32_APP
 | 
				
			||||||
			MessageBox(NULL, TEXT("Unable to get application path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
 | 
								MessageBox(NULL, TEXT("Unable to get application path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
 | 
				
			||||||
| 
						 | 
					@ -61,14 +61,15 @@ namespace fs {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			auto execPath = boost::filesystem::path(localAppData).parent_path();
 | 
								auto execPath = boost::filesystem::wpath(localAppData).parent_path();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// if config file exists in .exe's folder use it
 | 
								// if config file exists in .exe's folder use it
 | 
				
			||||||
			if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string
 | 
								if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string
 | 
				
			||||||
				dataDir = execPath.string ();
 | 
					 | 
				
			||||||
			else // otherwise %appdata%
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK)
 | 
									dataDir = execPath.string ();
 | 
				
			||||||
 | 
								} else // otherwise %appdata%
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
#ifdef WIN32_APP
 | 
					#ifdef WIN32_APP
 | 
				
			||||||
					MessageBox(NULL, TEXT("Unable to get AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
 | 
										MessageBox(NULL, TEXT("Unable to get AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
 | 
				
			||||||
| 
						 | 
					@ -78,7 +79,9 @@ namespace fs {
 | 
				
			||||||
					exit(1);
 | 
										exit(1);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					dataDir = std::string(localAppData) + "\\" + appName;
 | 
									{
 | 
				
			||||||
 | 
										dataDir = boost::filesystem::wpath(localAppData).string() + "\\" + appName;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue