Allow a QString in a LOG4CXX_ macro when 'Qt support/integration' is ON (#247)

* Update Qt support documentation

* Change configuration examples to links

* Fix NDC example file name

* Improve example code
diff --git a/.github/workflows/log4cxx-ubuntu.yml b/.github/workflows/log4cxx-ubuntu.yml
index ee8ac96..45b2fbf 100644
--- a/.github/workflows/log4cxx-ubuntu.yml
+++ b/.github/workflows/log4cxx-ubuntu.yml
@@ -30,18 +30,30 @@
             os: ubuntu-20.04
             cxx: g++
             cc: gcc
+            fmt: OFF
+            qt: ON
+            odbc: OFF
           - name: ubuntu20-clang
             os: ubuntu-20.04
             cxx: clang++
             cc: clang
+            fmt: ON
+            qt: OFF
+            odbc: ON
           - name: ubuntu22-gcc
             os: ubuntu-22.04
             cxx: g++
             cc: gcc
+            fmt: OFF
+            qt: OFF
+            odbc: OFF
           - name: ubuntu22-clang
             os: ubuntu-22.04
             cxx: clang++
             cc: clang
+            fmt: ON
+            qt: OFF
+            odbc: OFF
 
     steps:
     - uses: actions/checkout@v3
@@ -51,14 +63,17 @@
     - name: 'Configure Dependencies'
       run: |
         sudo apt-get update
-        sudo apt-get install -y libapr1-dev libaprutil1-dev libfmt-dev unixodbc-dev
+        sudo apt-get install -y libapr1-dev libaprutil1-dev
+        if [ ${{ matrix.fmt }} == ON ]; then sudo apt-get install -y libfmt-dev; fi
+        if [ ${{ matrix.odbc }} == ON ]; then sudo apt-get install -y unixodbc-dev; fi
+        if [ ${{ matrix.qt }} == ON ]; then sudo apt-get install -y qtbase5-dev; fi
 
     - name: 'run cmake - posix'
       run: |
         cd main
         mkdir build
         cd build
-        cmake -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} -DCMAKE_C_COMPILER=${{ matrix.cc }} -DLOG4CXX_ENABLE_ODBC=ON ..
+        cmake -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} -DCMAKE_C_COMPILER=${{ matrix.cc }} -DLOG4CXX_ENABLE_ODBC=${{ matrix.odbc }} -DLOG4CXX_QT_SUPPORT=${{ matrix.qt }} ..
         cmake --build .
 
     - name: run unit tests
diff --git a/src/cmake/win32_target_environment_path.cmake b/src/cmake/win32_target_environment_path.cmake
index ea122c8..3de5bc9 100644
--- a/src/cmake/win32_target_environment_path.cmake
+++ b/src/cmake/win32_target_environment_path.cmake
@@ -8,6 +8,9 @@
   set(EXPAT_DLL_DIR "${EXPAT_LIB_DIR}/../bin")
   set(LOG4CXX_DLL_DIR "$<SHELL_PATH:$<TARGET_FILE_DIR:log4cxx>>;")
   set(PATH_FOR_TESTS ${CMAKE_PROGRAM_PATH};${APR_DLL_DIR};${APR_UTIL_DLL_DIR};${LOG4CXX_DLL_DIR};${EXPAT_DLL_DIR}\;)
+  if(LOG4CXX_QT_SUPPORT)
+    list(APPEND PATH_FOR_TESTS "$<SHELL_PATH:$<TARGET_FILE_DIR:log4cxx-qt>>\;")
+  endif(LOG4CXX_QT_SUPPORT)
   list(REMOVE_DUPLICATES PATH_FOR_TESTS)
 
   # Note: we need to include the APR DLLs on our path so that the tests will run.
diff --git a/src/examples/cpp/CMakeLists.txt b/src/examples/cpp/CMakeLists.txt
index f1cf57d..4508a6e 100644
--- a/src/examples/cpp/CMakeLists.txt
+++ b/src/examples/cpp/CMakeLists.txt
@@ -15,7 +15,10 @@
 # limitations under the License.
 #
 
-set(ALL_LOG4CXX_EXAMPLES auto-configured console delayedloop stream trivial custom-appender MyApp1 MyApp2)
+set(ALL_LOG4CXX_EXAMPLES auto-configured console delayedloop stream ndc-example custom-appender MyApp1 MyApp2)
+if(LOG4CXX_QT_SUPPORT)
+  list(APPEND ALL_LOG4CXX_EXAMPLES MyApp-qt)
+endif(LOG4CXX_QT_SUPPORT)
 if( WIN32 )
     include(win32_target_environment_path)
     get_target_environment_path(ESCAPED_PATH)
@@ -34,6 +37,10 @@
     if(${exampleName} STREQUAL MyApp2)
         target_sources(${PROGRAM_NAME} PRIVATE com/foo/config2.cpp com/foo/bar.cpp)
     endif()
+    if(${exampleName} STREQUAL MyApp-qt)
+        target_sources(${PROGRAM_NAME} PRIVATE com/foo/config-qt.cpp com/foo/bar-qt.cpp)
+        target_link_libraries(${PROGRAM_NAME} PRIVATE log4cxx-qt)
+    endif()
     if(${exampleName} STREQUAL auto-configured)
         target_sources(${PROGRAM_NAME} PRIVATE com/foo/config3.cpp )
     endif()
diff --git a/src/examples/cpp/MyApp-qt.cpp b/src/examples/cpp/MyApp-qt.cpp
new file mode 100644
index 0000000..9040c5e
--- /dev/null
+++ b/src/examples/cpp/MyApp-qt.cpp
@@ -0,0 +1,20 @@
+#include <QCoreApplication>
+#include "com/foo/config-qt.h"
+#include "com/foo/bar.h"
+
+int main(int argc, char **argv) {
+	int result = EXIT_SUCCESS;
+	QCoreApplication app(argc, argv);
+	com::foo::ConfigureLogging();
+	try {
+		auto logger = com::foo::getLogger("MyApp");
+		LOG4CXX_INFO(logger, QString("Message %1").arg(1));
+		com::foo::Bar bar;
+		bar.doIt();
+		LOG4CXX_INFO(logger, QString("Message %1").arg(2));
+	}
+	catch(std::exception&) {
+		result = EXIT_FAILURE;
+	}
+	return result;
+}
diff --git a/src/examples/cpp/auto-configured.cpp b/src/examples/cpp/auto-configured.cpp
index fb0a9a5..1933f8f 100644
--- a/src/examples/cpp/auto-configured.cpp
+++ b/src/examples/cpp/auto-configured.cpp
@@ -16,9 +16,9 @@
  */
 #include "com/foo/config.h"
 
-extern auto rootLogger = com::foo::getLogger();
+auto rootLogger = com::foo::getLogger();
 
-static struct ExampleStaticData {
+struct ExampleStaticData {
 	ExampleStaticData()	{
 		LOG4CXX_DEBUG(rootLogger, "static initializer message");
 	}
diff --git a/src/examples/cpp/com/foo/bar-qt.cpp b/src/examples/cpp/com/foo/bar-qt.cpp
new file mode 100644
index 0000000..34d4468
--- /dev/null
+++ b/src/examples/cpp/com/foo/bar-qt.cpp
@@ -0,0 +1,10 @@
+#include "com/foo/bar.h"
+#include "com/foo/config-qt.h"
+
+using namespace com::foo;
+
+LoggerPtr Bar::m_logger(getLogger("com.foo.bar"));
+
+void Bar::doIt() {
+	LOG4CXX_DEBUG(m_logger, QString("Did it again!") << QString(" - again!"));
+}
diff --git a/src/examples/cpp/com/foo/config-qt.cpp b/src/examples/cpp/com/foo/config-qt.cpp
new file mode 100644
index 0000000..6488908
--- /dev/null
+++ b/src/examples/cpp/com/foo/config-qt.cpp
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "config-qt.h"
+#include <log4cxx/logmanager.h>
+#include <log4cxx-qt/configuration.h>
+#include <log4cxx/helpers/loglog.h>
+#include <QCoreApplication>
+#include <QVector>
+#include <QFileInfo>
+#include <QDir>
+
+namespace com { namespace foo {
+
+// Provide the name of the configuration file to Log4cxx.
+// Reload the configuration on a QFileSystemWatcher::fileChanged event.
+void ConfigureLogging() {
+	static struct log4cxx_finalizer {
+		~log4cxx_finalizer() {
+			log4cxx::LogManager::shutdown();
+		}
+	} finaliser;
+	QFileInfo app{QCoreApplication::applicationFilePath()};
+	QString basename{app.baseName()};
+	QVector<QString> paths =
+		{ QString(".")
+		, app.absoluteDir().absolutePath()
+		};
+	QVector<QString> names =
+		{ QString(basename + ".xml")
+		, QString(basename + ".properties")
+		, QString("MyApp.properties")
+		, QString("log4cxx.xml")
+		, QString("log4cxx.properties")
+		, QString("log4j.xml")
+		, QString("log4j.properties")
+	};
+#if defined(_DEBUG)
+	log4cxx::helpers::LogLog::setInternalDebugging(true);
+#endif
+	log4cxx::qt::Configuration::configureFromFileAndWatch(paths, names);
+}
+
+// Retrieve the \c name logger pointer.
+auto getLogger(const QString& name) -> LoggerPtr {
+	return name.isEmpty()
+		? log4cxx::LogManager::getRootLogger()
+		: log4cxx::LogManager::getLogger(name.toStdString());
+}
+
+// Retrieve the \c name logger pointer.
+auto getLogger(const char* name) -> LoggerPtr {
+	return name
+		? log4cxx::LogManager::getLogger(name)
+		: log4cxx::LogManager::getRootLogger();
+}
+
+} } // namespace com::foo
diff --git a/src/examples/cpp/com/foo/config-qt.h b/src/examples/cpp/com/foo/config-qt.h
new file mode 100644
index 0000000..238199f
--- /dev/null
+++ b/src/examples/cpp/com/foo/config-qt.h
@@ -0,0 +1,21 @@
+#ifndef COM_FOO_CONFIG_QT_H_
+#define COM_FOO_CONFIG_QT_H_
+#include <log4cxx-qt/logger.h>
+
+/// Methods specific to foo.com
+namespace com { namespace foo {
+
+// Provide the name of the configuration file to Log4cxx.
+void ConfigureLogging();
+
+/// The logger pointer we use
+using LoggerPtr = log4cxx::LoggerPtr;
+
+/// Retrieve the \c name logger pointer.
+extern auto getLogger(const QString& name) -> LoggerPtr;
+
+/// Retrieve the \c name logger pointer.
+extern auto getLogger(const char* name = NULL) -> LoggerPtr;
+
+} } // namespace com::foo
+#endif // COM_FOO_CONFIG_QT_H_
diff --git a/src/examples/cpp/trivial.cpp b/src/examples/cpp/ndc-example.cpp
similarity index 100%
rename from src/examples/cpp/trivial.cpp
rename to src/examples/cpp/ndc-example.cpp
diff --git a/src/main/cpp-qt/configuration.cpp b/src/main/cpp-qt/configuration.cpp
index ef8589f..17654b7 100644
--- a/src/main/cpp-qt/configuration.cpp
+++ b/src/main/cpp-qt/configuration.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 #include <log4cxx-qt/configuration.h>
+#include <log4cxx-qt/transcoder.h>
 #include <log4cxx/helpers/loglog.h>
 #include <log4cxx/xml/domconfigurator.h>
 #include <log4cxx/propertyconfigurator.h>
@@ -107,16 +108,16 @@
 			QString canidate_str = dir + "/" + fname;
 			QFile candidate(canidate_str);
 
-			QString debugMsg = LOG4CXX_STR("Checking file ");
-			debugMsg.append(canidate_str);
-			LogLog::debug(debugMsg.toStdString());
+			LOG4CXX_DECODE_QSTRING(msg, "Checking file " + canidate_str);
+			LogLog::debug(msg);
 			if (candidate.exists())
 			{
 				log4cxx::spi::ConfigurationStatus configStatus = tryLoadFile(canidate_str);
 				if( configStatus == log4cxx::spi::ConfigurationStatus::Configured ){
 					return {configStatus, canidate_str};
 				}
-				LogLog::debug("Unable to load file: trying next");
+				LOG4CXX_DECODE_QSTRING(failmsg, "Unable to load  " + canidate_str + ": trying next");
+				LogLog::debug(failmsg);
 			}
 		}
 	}
diff --git a/src/main/cpp/domconfigurator.cpp b/src/main/cpp/domconfigurator.cpp
index 4d3b9e0..0fd1805 100644
--- a/src/main/cpp/domconfigurator.cpp
+++ b/src/main/cpp/domconfigurator.cpp
@@ -865,7 +865,7 @@
 }
 #endif
 
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 spi::ConfigurationStatus DOMConfigurator::configure(const std::basic_string<UniChar>& filename)
 {
 	File file(filename);
@@ -894,7 +894,7 @@
 }
 #endif
 
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 spi::ConfigurationStatus DOMConfigurator::configureAndWatch(const std::basic_string<UniChar>& filename)
 {
 	return configureAndWatch(filename, FileWatchdog::DEFAULT_DELAY);
@@ -958,7 +958,7 @@
 }
 #endif
 
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 spi::ConfigurationStatus DOMConfigurator::configureAndWatch(const std::basic_string<UniChar>& filename, long delay)
 {
 	File file(filename);
diff --git a/src/main/cpp/file.cpp b/src/main/cpp/file.cpp
index 56fe768..88a04a9 100644
--- a/src/main/cpp/file.cpp
+++ b/src/main/cpp/file.cpp
@@ -95,7 +95,7 @@
 }
 #endif
 
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 File::File(const std::basic_string<UniChar>& name1)
 	: m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
 {
diff --git a/src/main/cpp/hexdump.cpp b/src/main/cpp/hexdump.cpp
index caa45ac..163cda7 100644
--- a/src/main/cpp/hexdump.cpp
+++ b/src/main/cpp/hexdump.cpp
@@ -14,6 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+#include <log4cxx/log4cxx.h>
+/* Prevent error C2491: 'std::numpunct<_Elem>::id': definition of dllimport static data member not allowed */
+#if defined(_MSC_VER) && (LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR)
+#define __FORCE_INSTANCE
+#endif
 #include <log4cxx/hexdump.h>
 #include <log4cxx/log4cxx.h>
 #include <sstream>
@@ -32,8 +38,8 @@
 	const wchar_t fill_char = L'0';
 	const wchar_t space_fill_char = L' ';
 #else
-	const char fill_char = '0';
-	const char space_fill_char = ' ';
+	const logchar fill_char = '0';
+	const logchar space_fill_char = ' ';
 #endif
 
 	if(flags & HexdumpFlags::AddStartingNewline){
diff --git a/src/main/cpp/level.cpp b/src/main/cpp/level.cpp
index 7d794c5..8fb6af1 100644
--- a/src/main/cpp/level.cpp
+++ b/src/main/cpp/level.cpp
@@ -173,7 +173,7 @@
 
 #endif
 
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 LevelPtr Level::toLevel(const std::basic_string<UniChar>& sArg)
 {
 	return toLevel(sArg, Level::getDebug());
diff --git a/src/main/cpp/messagebuffer.cpp b/src/main/cpp/messagebuffer.cpp
index 6972dc7..4a546a7 100644
--- a/src/main/cpp/messagebuffer.cpp
+++ b/src/main/cpp/messagebuffer.cpp
@@ -17,7 +17,7 @@
 
 #include <log4cxx/log4cxx.h>
 /* Prevent error C2491: 'std::numpunct<_Elem>::id': definition of dllimport static data member not allowed */
-#if defined(_MSC_VER) && LOG4CXX_UNICHAR_API
+#if defined(_MSC_VER) && (LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR)
 #define __FORCE_INSTANCE
 #endif
 #include <log4cxx/helpers/messagebuffer.h>
@@ -587,7 +587,7 @@
 
 #endif // LOG4CXX_WCHAR_T_API
 
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 struct UniCharMessageBuffer::UniCharMessageBufferPrivate : public StringOrStream<UniChar> {};
 
 UniCharMessageBuffer::UniCharMessageBuffer() :
diff --git a/src/main/cpp/timebasedrollingpolicy.cpp b/src/main/cpp/timebasedrollingpolicy.cpp
index 2679867..f304ca9 100644
--- a/src/main/cpp/timebasedrollingpolicy.cpp
+++ b/src/main/cpp/timebasedrollingpolicy.cpp
@@ -171,7 +171,11 @@
 
 	if (stat == APR_SUCCESS)
 	{
+#ifdef WIN32
+		snprintf(szUid, MAX_FILE_LEN, "%p", uid);
+#else
 		snprintf(szUid, MAX_FILE_LEN, "%u", uid);
+#endif
 	}
 
 	log4cxx::filesystem::path path(fileName);
diff --git a/src/main/cpp/transcoder.cpp b/src/main/cpp/transcoder.cpp
index 6cbe9f2..7ad9ad2 100644
--- a/src/main/cpp/transcoder.cpp
+++ b/src/main/cpp/transcoder.cpp
@@ -576,7 +576,7 @@
 
 
 
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 void Transcoder::decode(const std::basic_string<UniChar>& src, LogString& dst)
 {
 #if LOG4CXX_LOGCHAR_IS_UNICHAR
diff --git a/src/main/include/log4cxx-qt/logger.h b/src/main/include/log4cxx-qt/logger.h
new file mode 100644
index 0000000..f79d7fd
--- /dev/null
+++ b/src/main/include/log4cxx-qt/logger.h
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOG4CXX_QT_LOGGER_H
+#define _LOG4CXX_QT_LOGGER_H
+#include <log4cxx/logger.h>
+#include <log4cxx-qt/messagebuffer.h>
+#endif // _LOG4CXX_QT_LOGGER_H
diff --git a/src/main/include/log4cxx-qt/messagebuffer.h b/src/main/include/log4cxx-qt/messagebuffer.h
new file mode 100644
index 0000000..bd4c9b7
--- /dev/null
+++ b/src/main/include/log4cxx-qt/messagebuffer.h
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOG4CXX_QT_MESSAGE_BUFFER_H
+#define _LOG4CXX_QT_MESSAGE_BUFFER_H
+#include <log4cxx-qt/transcoder.h>
+
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
+	inline log4cxx::helpers::UniCharMessageBuffer&
+operator<<(log4cxx::helpers::UniCharMessageBuffer& mb, const QString& msg)
+{
+	return mb << msg.utf16();
+}
+
+#if LOG4CXX_WCHAR_T_API
+	inline log4cxx::helpers::WideMessageBuffer&
+operator<<(log4cxx::helpers::WideMessageBuffer& mb, const QString& msg)
+{
+	return mb << msg.toStdWString();
+}
+
+	inline log4cxx::helpers::WideMessageBuffer&
+operator<<(log4cxx::helpers::MessageBuffer& mb, const QString& msg)
+{
+	return mb << msg.toStdWString();
+}
+#else // !LOG4CXX_WCHAR_T_API
+	inline log4cxx::helpers::UniCharMessageBuffer&
+operator<<(log4cxx::helpers::MessageBuffer& mb, const QString& msg)
+{
+	return mb << msg.utf16();
+}
+#endif // !LOG4CXX_WCHAR_T_API
+
+#else // !(LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR)
+
+#if LOG4CXX_WCHAR_T_API
+	inline log4cxx::helpers::WideMessageBuffer&
+operator<<(log4cxx::helpers::WideMessageBuffer& mb, const QString& msg)
+{
+	return mb << msg.toStdWString();
+}
+
+	inline log4cxx::helpers::WideMessageBuffer&
+operator<<(log4cxx::helpers::MessageBuffer& mb, const QString& msg)
+{
+	return mb << msg.toStdWString();
+}
+#else // !LOG4CXX_WCHAR_T_API
+	inline log4cxx::helpers::CharMessageBuffer&
+operator<<(log4cxx::helpers::CharMessageBuffer& mb, const QString& msg)
+{
+	LOG4CXX_DECODE_QSTRING(tmp, msg);
+	return mb << tmp;
+}
+#endif // !LOG4CXX_WCHAR_T_API
+
+#endif // !(LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR)
+
+#endif // _LOG4CXX_QT_MESSAGE_BUFFER_H
diff --git a/src/main/include/log4cxx-qt/transcoder.h b/src/main/include/log4cxx-qt/transcoder.h
new file mode 100644
index 0000000..71002a2
--- /dev/null
+++ b/src/main/include/log4cxx-qt/transcoder.h
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOG4CXX_QT_TRANSCODER_H
+#define _LOG4CXX_QT_TRANSCODER_H
+#include <log4cxx/logstring.h>
+#include <QString>
+
+#if LOG4CXX_LOGCHAR_IS_UTF8
+#define LOG4CXX_DECODE_QSTRING(var, src) \
+	log4cxx::LogString var = (src).toStdString()
+
+#define LOG4CXX_ENCODE_QSTRING(var, src) \
+	QString var = QString::fromStdString(src)
+#endif // LOG4CXX_LOGCHAR_IS_UTF8
+
+#if LOG4CXX_LOGCHAR_IS_WCHAR
+#define LOG4CXX_DECODE_QSTRING(var, src) \
+	log4cxx::LogString var = (src).toStdWString()
+
+#define LOG4CXX_ENCODE_QSTRING(var, src) \
+	QString var = QString::fromStdWString(src)
+#endif // LOG4CXX_LOGCHAR_IS_WCHAR
+
+#if LOG4CXX_LOGCHAR_IS_UNICHAR
+#define LOG4CXX_DECODE_QSTRING(var, src) \
+	log4cxx::LogString var = (src).utf16()
+
+#define LOG4CXX_ENCODE_QSTRING(var, src) \
+	QString var = QString::fromUtf16((char16_t*)src.c_str())
+#endif // LOG4CXX_LOGCHAR_IS_UNICHAR
+
+#endif // _LOG4CXX_QT_TRANSCODER_H
diff --git a/src/main/include/log4cxx/file.h b/src/main/include/log4cxx/file.h
index cc669ea..7bd9592 100644
--- a/src/main/include/log4cxx/file.h
+++ b/src/main/include/log4cxx/file.h
@@ -66,7 +66,7 @@
 		*/
 		File(const std::wstring& path);
 #endif
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 		/**
 		*   Construct a new instance.  Use setPath to specify path using a LogString.
 		* @param path file path.
diff --git a/src/main/include/log4cxx/level.h b/src/main/include/log4cxx/level.h
index 8644b81..b0b98d5 100644
--- a/src/main/include/log4cxx/level.h
+++ b/src/main/include/log4cxx/level.h
@@ -126,7 +126,7 @@
 		 */
 		void toString(std::wstring& name) const;
 #endif
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 		/**
 		Convert the string passed as argument to a level. If the
 		conversion fails, then this method returns DEBUG.
diff --git a/src/main/include/log4cxx/xml/domconfigurator.h b/src/main/include/log4cxx/xml/domconfigurator.h
index 9f49c69..026fea9 100644
--- a/src/main/include/log4cxx/xml/domconfigurator.h
+++ b/src/main/include/log4cxx/xml/domconfigurator.h
@@ -221,7 +221,7 @@
 #if LOG4CXX_WCHAR_T_API
 		static spi::ConfigurationStatus configure(const std::wstring& filename);
 #endif
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 		static spi::ConfigurationStatus configure(const std::basic_string<UniChar>& filename);
 #endif
 #if LOG4CXX_CFSTRING_API
@@ -237,7 +237,7 @@
 #if LOG4CXX_WCHAR_T_API
 		static spi::ConfigurationStatus configureAndWatch(const std::wstring& configFilename);
 #endif
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 		static spi::ConfigurationStatus configureAndWatch(const std::basic_string<UniChar>& configFilename);
 #endif
 #if LOG4CXX_CFSTRING_API
@@ -260,7 +260,7 @@
 		static spi::ConfigurationStatus configureAndWatch(const std::wstring& configFilename,
 			long delay);
 #endif
-#if LOG4CXX_UNICHAR_API
+#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
 		static spi::ConfigurationStatus configureAndWatch(const std::basic_string<UniChar>& configFilename,
 			long delay);
 #endif
diff --git a/src/site/markdown/development/build-cmake.md b/src/site/markdown/development/build-cmake.md
index 242430b..e860118 100644
--- a/src/site/markdown/development/build-cmake.md
+++ b/src/site/markdown/development/build-cmake.md
@@ -71,6 +71,7 @@
 | -DAPR_STATIC=yes       | Link to the APR static library. By default, the Log4cxx shared library is linked to the APR shared library. If BUILD_SHARED_LIBS=off, the static APR library is always used.        |
 |-DLOG4CXX_TEST_PROGRAM_PATH=path| An extra path to prepend to the PATH for test programs.  Log4cxx requires zip, sed, and grep on the PATH in order for the tests to work properly.                          |
 | -DPREFER_BOOST=on      | Prefer the Boost version of dependent libraries over standard library |
+| -DLOG4CXX_QT_SUPPORT=ON | Enable QString API and log4cxx::qt namespace methods, requires QtCore, choice of ON, OFF (default).                   |
 
 ## A note on C++ version and Boost
 
diff --git a/src/site/markdown/example-programs.md b/src/site/markdown/example-programs.md
index dfbbb83..72992d8 100644
--- a/src/site/markdown/example-programs.md
+++ b/src/site/markdown/example-programs.md
@@ -72,15 +72,14 @@
 The *com::foo::Bar* class is implemented in the file *com/foo/bar.cpp*.
 \include com/foo/bar.cpp
 
-The header file *com/foo/config.h* defines the com::foo::getLogger() function
+The header file \ref com/foo/config.h defines the com::foo::getLogger() function
 and a *LoggerPtr* type for convenience.
-\include com/foo/config.h
 
-The file *com/foo/config.cpp* which implements the com::foo::getLogger() function
+
+The file \ref com/foo/config1.cpp implements the com::foo::getLogger() function
 defines *initAndShutdown* as a *static struct* so its constructor
 is invoked on the first call to the com::foo::getLogger() function
 and its destructor is automatically called during application exit.
-\include com/foo/config1.cpp
 
 The invocation of the
 [BasicConfigurator::configure](@ref log4cxx.BasicConfigurator.configure)
@@ -189,5 +188,11 @@
 according to local server policy, for example by forwarding the log
 event to a second Log4cxx server.
 
+\example com/foo/config.h
+This header file is for encapsulating Log4cxx configuration.
+
+\example com/foo/config1.cpp
+This file is a simplified example of encapsulated Log4cxx configuration.
+
 \example com/foo/config3.cpp
 This file is an example of how to use the current module name to select the Log4cxx configuration file.
diff --git a/src/site/markdown/filters/filters.md b/src/site/markdown/filters/filters.md
index 4f4bbbb..4e3ab35 100644
--- a/src/site/markdown/filters/filters.md
+++ b/src/site/markdown/filters/filters.md
@@ -28,7 +28,7 @@
 you can push contextual information
 into the *Nested Diagnostic Context* (NDC) using the *log4cxx::NDC* class
 or the *Mapped Diagnostic Context* provided by *log4cxx::MDC* class.
-For an example using log4cxx::NDC refer to \ref trivial.cpp.
+For an example using log4cxx::NDC refer to \ref ndc-example.cpp.
 
 The NDC is managed per thread as a *stack* of contextual information.
 When the layout specifies that the NDC is to be included,
@@ -93,5 +93,5 @@
 * @subpage map-filter
 * @subpage location-info-filter
 
-\example trivial.cpp
+\example ndc-example.cpp
 This example shows how to add a context string to each logging message using the NDC.
diff --git a/src/site/markdown/qt-support.md b/src/site/markdown/qt-support.md
index a324a26..7e0bb13 100644
--- a/src/site/markdown/qt-support.md
+++ b/src/site/markdown/qt-support.md
@@ -26,8 +26,14 @@
 thus bypassing the logger entirely.  In order to have these messages
 routed to Log4cxx, a message handler for Qt must be installed.
 
-Log4cxx provides a separate library, log4cxx-qt, which contains useful
-utilities for working with Qt.
+Log4cxx provides a cmake build option `LOG4CXX_QT_SUPPORT=ON`
+which adds the log4cxx::qt namespace methods
+for directing Qt messages to Log4cxx and
+using the Qt event loop to process a configuration file change.
+Use the target `log4cxx-qt` instead of `log4cxx`
+in your `target_link_libraries` cmake directive.
+Also, including `log4cxx-qt/logger.h` allows you to use QString values
+in the LOG4CXX_WARN, LOG4CXX_INFO, LOG4CXX_DEBUG etc. macros.
 
 To install a message handler that will route the Qt logging messages
 through Log4cxx, include the messagehandler.h and call
@@ -43,3 +49,20 @@
 
 Note that by default, this message handler also calls `abort` upon a
 fatal message.
+
+For how to use the Qt event loop to monitor the configuration file,
+see the \ref com/foo/config-qt.h and \ref com/foo/config-qt.cpp example files.
+
+Note that when using the above technique
+you *must* configure Log4cxx after creating your QCoreApplication instance
+(see the \ref MyApp-qt.cpp file for an example of this).
+
+\example MyApp-qt.cpp
+This file is an example of how to configure Log4cxx in a Qt application.
+
+\example com/foo/config-qt.h
+This header file is for Log4cxx configuration in a Qt application.
+
+\example com/foo/config-qt.cpp
+This file is an example of how to use the Qt event loop to monitor the Log4cxx configuration file.
+