set(QUASSEL_PATCH  0)
 set(QUASSEL_VERSION_STRING "0.11-pre")
 
-# Tell CMake about or own stuff
+# Tell CMake about or own modules
 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
 
+# General conveniences
 set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
+# Moar stuff
 include(CheckFunctionExists)
 include(CheckIncludeFile)
 
 
-# This macro sets variables for the Qt modules we need.
+# This file contains various macros useful for building Quassel.
+#
+# (C) 2014 by the Quassel Project <devel@quassel-irc.org>
+#
+# The qt4_use_modules function was taken from CMake's Qt4Macros.cmake:
+# (C) 2005-2009 Kitware, Inc.
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
 
-macro(setup_qt_variables)
-  set(QUASSEL_QT_LIBRARIES )
-  set(QUASSEL_QT_INCLUDES ${QT_INCLUDE_DIR})    # Qt4
-  set(QUASSEL_QT_DEFINITIONS ${QT_DEFINITIONS}) # Qt4
+############################
+# Macros for dealing with Qt
+############################
 
-  IF(WIN32)
-    set(MAIN Main)
-  ENDIF(WIN32)
-  foreach(qtmod Core ${ARGV} ${MAIN})
-    if(WITH_QT5)
-      find_package(Qt5${qtmod} ${QT_MIN_VERSION} REQUIRED)
-      list(APPEND QUASSEL_QT_LIBRARIES ${Qt5${qtmod}_LIBRARIES})
-      list(APPEND QUASSEL_QT_INCLUDES ${Qt5${qtmod}_INCLUDE_DIRS})
-      list(APPEND QUASSEL_QT_DEFINITIONS ${Qt5${qtmod}_DEFINITIONS} ${Qt5${qtmod}_EXECUTABLE_COMPILE_FLAGS})
-    else(WITH_QT5)
-      string(TOUPPER ${qtmod} QTMOD)
-      list(APPEND QUASSEL_QT_LIBRARIES ${QT_QT${QTMOD}_LIBRARY})
-      if(STATIC)
-        list(APPEND QUASSEL_QT_LIBRARIES ${QT_QT${QTMOD}_LIB_DEPENDENCIES})
-      endif(STATIC)
-      list(APPEND QUASSEL_QT_INCLUDES ${QT_QT${QTMOD}_INCLUDE_DIR})
-      list(APPEND QUASSEL_QT_DEFINITIONS -DQT_QT${QTMOD}_LIB)
-    endif(WITH_QT5)
-  endforeach(qtmod)
+# CMake gained this function in 2.8.10. To be able to use older versions, we've copied
+# this here. If present, the function from CMake will take precedence and our copy will be ignored.
+function(quassel_qt4_use_modules _target _link_type)
+    message("SPUT calling")
+    if ("${_link_type}" STREQUAL "LINK_PUBLIC" OR "${_link_type}" STREQUAL "LINK_PRIVATE")
+        set(modules ${ARGN})
+        set(link_type ${_link_type})
+    else()
+        set(modules ${_link_type} ${ARGN})
+    endif()
+    foreach(_module ${modules})
+        string(TOUPPER ${_module} _ucmodule)
+        set(_targetPrefix QT_QT${_ucmodule})
+        if (_ucmodule STREQUAL QAXCONTAINER OR _ucmodule STREQUAL QAXSERVER)
+            if (NOT QT_Q${_ucmodule}_FOUND)
+                message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.")
+            endif()
+            set(_targetPrefix QT_Q${_ucmodule})
+        else()
+            if (NOT QT_QT${_ucmodule}_FOUND)
+                message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.")
+            endif()
+            if ("${_ucmodule}" STREQUAL "MAIN")
+                message(FATAL_ERROR "Can not use \"${_module}\" module with qt4_use_modules.")
+            endif()
+        endif()
+        target_link_libraries(${_target} ${link_type} ${${_targetPrefix}_LIBRARIES})
+        set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${${_targetPrefix}_INCLUDE_DIR} ${QT_HEADERS_DIR} ${QT_MKSPECS_DIR}/default)
+        set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${${_targetPrefix}_COMPILE_DEFINITIONS})
+    endforeach()
+endfunction()
 
-  list(REMOVE_DUPLICATES QUASSEL_QT_LIBRARIES)
-  list(REMOVE_DUPLICATES QUASSEL_QT_INCLUDES)
-  list(REMOVE_DUPLICATES QUASSEL_QT_DEFINITIONS)
+# Some wrappers for simplifying dual-Qt support
 
-  # The COMPILE_FLAGS property expects a string, not a list...
-  set(QUASSEL_QT_COMPILEFLAGS )
-  foreach(flag ${QUASSEL_QT_DEFINITIONS})
-    set(QUASSEL_QT_COMPILEFLAGS "${QUASSEL_QT_COMPILEFLAGS} ${flag}")
-  endforeach(flag)
+function(qt_use_modules)
+    if (WITH_QT5)
+        qt5_use_modules(${ARGN})
+    else()
+        qt4_use_modules(${ARGN})
+    endif()
+endfunction()
 
-endmacro(setup_qt_variables)
+function(qt_wrap_ui _var)
+    if (WITH_QT5)
+        qt5_wrap_ui(var ${ARGN})
+    else()
+        qt4_wrap_ui(var ${ARGN})
+    endif()
+    set(${_var} ${${_var}} ${var} PARENT_SCOPE)
+endfunction()
+
+function(qt_add_resources _var)
+    if (WITH_QT5)
+        qt5_add_resources(var ${ARGN})
+    else()
+        qt4_add_resources(var ${ARGN})
+    endif()
+    set(${_var} ${${_var}} ${var} PARENT_SCOPE)
+endfunction()
+
+function(qt_add_dbus_interface _var)
+    if (WITH_QT5)
+        qt5_add_dbus_interface(var ${ARGN})
+    else()
+        qt4_add_dbus_interface(var ${ARGN})
+    endif()
+    set(${_var} ${${_var}} ${var} PARENT_SCOPE)
+endfunction()
+
+function(qt_add_dbus_adaptor _var)
+    if (WITH_QT5)
+        qt5_add_dbus_adaptor(var ${ARGN})
+    else()
+        qt4_add_dbus_adaptor(var ${ARGN})
+    endif()
+    set(${_var} ${${_var}} ${var} PARENT_SCOPE)
+endfunction()
+
+######################################
+# Macros for dealing with translations
+######################################
 
 # This generates a .ts from a .po file
 macro(generate_ts outvar basename)
 # This is a workaround to add (duplicate) strings that lconvert missed to the .ts
           COMMAND ${QT_LUPDATE_EXECUTABLE}
           ARGS -silent
-              ${CMAKE_SOURCE_DIR}/src/
+               ${CMAKE_SOURCE_DIR}/src/
                -ts ${output}
           DEPENDS ${basename}.po)
   set(${outvar} ${output})
 
 
 # Add resources. Can't be done in other subdirs apparently.
 # Note that these variables need to contain paths relative to src/ (this dir)
-if(WITH_QT5)
-  qt5_add_resources(CLIENT_DEPS ${CLIENT_RCS})
-  qt5_add_resources(CORE_DEPS ${CORE_RCS})
-  qt5_add_resources(COMMON_DEPS ${COMMON_RCS})
-else(WITH_QT5)
-  qt4_add_resources(CLIENT_DEPS ${CLIENT_RCS})
-  qt4_add_resources(CORE_DEPS ${CORE_RCS})
-  qt4_add_resources(COMMON_DEPS ${COMMON_RCS})
-endif(WITH_QT5)
+qt_add_resources(CLIENT_DEPS ${CLIENT_RCS})
+qt_add_resources(CORE_DEPS ${CORE_RCS})
+qt_add_resources(COMMON_DEPS ${COMMON_RCS})
+
+# For Windows, Qt4 needs the QtMain module
+if (WIN32 AND NOT WITH_QT5)
+    set(MAIN Main)
+endif()
 
 if(WANT_CORE)
-  setup_qt_variables(Network Script Sql ${CORE_QT_MODULES})
-  include_directories(${QUASSEL_QT_INCLUDES})
   add_executable(quasselcore common/main.cpp ${COMMON_DEPS} ${CORE_DEPS})
+  qt_use_modules(quasselcore Core Network ${CORE_QT_MODULES} ${MAIN})
   add_dependencies(quasselcore po)
   set_target_properties(quasselcore PROPERTIES
-                                    COMPILE_FLAGS "-DBUILD_CORE ${QUASSEL_QT_COMPILEFLAGS}"
+                                    COMPILE_FLAGS "-DBUILD_CORE"
                                     OUTPUT_NAME ../quasselcore)
-  target_link_libraries(quasselcore mod_core mod_common ${COMMON_LIBRARIES}
-                                    ${QUASSEL_QT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES})
+  target_link_libraries(quasselcore mod_core mod_common ${COMMON_LIBRARIES} ${QUASSEL_SSL_LIBRARIES})
   install(TARGETS quasselcore RUNTIME DESTINATION ${BIN_INSTALL_DIR})
 endif(WANT_CORE)
 
 if(WANT_QTCLIENT)
-  setup_qt_variables(Gui Network ${CLIENT_QT_MODULES})
-  include_directories(${QUASSEL_QT_INCLUDES})
   add_executable(quasselclient WIN32 common/main.cpp ${COMMON_DEPS} ${CLIENT_DEPS})
+  qt_use_modules(quasselclient Core Gui Network ${CLIENT_QT_MODULES} ${MAIN})
   add_dependencies(quasselclient po)
   set_target_properties(quasselclient PROPERTIES
-                                      COMPILE_FLAGS "-DBUILD_QTUI ${QUASSEL_QT_COMPILEFLAGS} ${CLIENT_COMPILE_FLAGS}"
+                                      COMPILE_FLAGS "-DBUILD_QTUI ${CLIENT_COMPILE_FLAGS}"
                                       OUTPUT_NAME ../quasselclient)
-  target_link_libraries(quasselclient ${LINK_KDE} mod_qtui mod_uisupport mod_client mod_common ${COMMON_LIBRARIES}
-                                      ${QUASSEL_QT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES} ${CLIENT_LIBRARIES})
+  target_link_libraries(quasselclient ${LINK_KDE} mod_qtui mod_uisupport mod_client mod_common ${COMMON_LIBRARIES} ${CLIENT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES})
   install(TARGETS quasselclient RUNTIME DESTINATION ${BIN_INSTALL_DIR})
 endif(WANT_QTCLIENT)
 
 if(WANT_MONO)
-  setup_qt_variables(Gui Network Script Sql ${CLIENT_QT_MODULES} ${CORE_QT_MODULES})
-  include_directories(${QUASSEL_QT_INCLUDES})
   add_executable(quassel WIN32 common/main.cpp qtui/monoapplication.cpp ${COMMON_DEPS} ${CLIENT_DEPS} ${CORE_DEPS})
+  qt_use_modules(quassel Core Gui Network ${CLIENT_QT_MODULES} ${CORE_QT_MODULES} ${MAIN})
   add_dependencies(quassel po)
   set_target_properties(quassel PROPERTIES
-                                COMPILE_FLAGS "-DBUILD_MONO ${QUASSEL_QT_COMPILEFLAGS} ${CLIENT_COMPILE_FLAGS}"
+                                COMPILE_FLAGS "-DBUILD_MONO ${CLIENT_COMPILE_FLAGS}"
                                 OUTPUT_NAME ../quassel)
-  target_link_libraries(quassel mod_qtui mod_uisupport mod_client mod_core mod_common ${COMMON_LIBRARIES}
-                                ${QUASSEL_QT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES} ${CLIENT_LIBRARIES})
+  target_link_libraries(quassel mod_qtui mod_uisupport mod_client mod_core mod_common ${COMMON_LIBRARIES} ${CLIENT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES})
   install(TARGETS quassel RUNTIME DESTINATION ${BIN_INSTALL_DIR})
 endif(WANT_MONO)
 
 
 # Builds the client module
 
-# In Qt4, we still have some minor deps to QtUi: QItemSelectionModel, QSortFilterProxyModel
+# In Qt4, we still have some minor deps to QtGui: QItemSelectionModel, QSortFilterProxyModel
 # Still in Qt5: QAbstractItemView in BufferModel
 
-set(_modules )
-
-if(WITH_QT5)
-  list(APPEND _modules Widgets)
-endif(WITH_QT5)
-
-if(HAVE_DBUS)
-  list(APPEND _modules DBus)
-endif(HAVE_DBUS)
-
-setup_qt_variables(Gui Network ${_modules})
-
 set(SOURCES
     abstractmessageprocessor.cpp
     backlogrequester.cpp
     clientcoreinfo.h
 )
 
-include_directories(${CMAKE_SOURCE_DIR}/src/common ${QUASSEL_QT_INCLUDES})
+if (WITH_QT5)
+    list(APPEND qt_modules Widgets)
+endif()
+
+if (HAVE_DBUS)
+    list(APPEND qt_modules DBus)
+endif()
 
 add_library(mod_client STATIC ${SOURCES})
+qt_use_modules(mod_client Network Core Gui ${qt_modules})
 add_dependencies(mod_client mod_common)
-
-set_target_properties(mod_client PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}")
 
 # Builds the common module
 
-setup_qt_variables(Core Network)
-
 set(SOURCES
     aliasmanager.cpp
     authhandler.cpp
     set(SOURCES ${SOURCES} logbacktrace_unix.cpp)
 endif(CMAKE_HOST_UNIX)
 
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${QUASSEL_QT_INCLUDES})  # for version.inc and version.gen
-
 add_library(mod_common STATIC ${SOURCES})
-set_target_properties(mod_common PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}")
+qt_use_modules(mod_common Core Network)
 
 if(APPLE)
   target_link_libraries(mod_common "-framework CoreServices" "-framework CoreFoundation")
 
 # Builds the core module
 
-setup_qt_variables(Network Sql Script)
-
 set(SOURCES
     abstractsqlstorage.cpp
     core.cpp
   include_directories(${QCA2_INCLUDE_DIR})
 endif(HAVE_QCA2)
 
-include_directories(${CMAKE_SOURCE_DIR}/src/common ${QUASSEL_QT_INCLUDES})
+include_directories(${CMAKE_SOURCE_DIR}/src/common)
 
 set(CORE_RCS ${CORE_RCS} core/sql.qrc PARENT_SCOPE)
 
 add_library(mod_core STATIC ${SOURCES})
+qt_use_modules(mod_core Core Network Script Sql)
+
 add_dependencies(mod_core mod_common)
-set_target_properties(mod_core PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}")
 
 if(HAVE_QCA2)
   target_link_libraries(mod_core ${QCA2_LIBRARIES})
 
 # Builds the qtui module
 
-set(_modules )
-
-if(WITH_QT5)
-  list(APPEND _modules Widgets)
-endif(WITH_QT5)
-
-if(HAVE_DBUS)
-  list(APPEND _modules DBus)
-endif(HAVE_DBUS)
-
-if(HAVE_WEBKIT)
-  list(APPEND _modules Webkit XmlPatterns)
-endif(HAVE_WEBKIT)
-
-setup_qt_variables(Gui Network ${_modules})
-
 set(SOURCES
     aboutdlg.cpp
     awaylogfilter.cpp
   endif(HAVE_PHONON)
 endif(HAVE_KDE)
 
-if(HAVE_DBUS)
-  set(SOURCES ${SOURCES} statusnotifieritem.cpp statusnotifieritemdbus.cpp dockmanagernotificationbackend.cpp)
-  set(FORMS ${FORMS})
-  if(WITH_QT5)
-    qt5_add_dbus_interface(DBUS ../../interfaces/org.kde.StatusNotifierWatcher.xml statusnotifierwatcher)
-    qt5_add_dbus_interface(DBUS ../../interfaces/org.freedesktop.Notifications.xml notificationsclient)
-    qt5_add_dbus_adaptor(DBUS ../../interfaces/org.kde.StatusNotifierItem.xml statusnotifieritemdbus.h StatusNotifierItemDBus)
-  else(WITH_QT5)
-    qt4_add_dbus_interface(DBUS ../../interfaces/org.kde.StatusNotifierWatcher.xml statusnotifierwatcher)
-    qt4_add_dbus_interface(DBUS ../../interfaces/org.freedesktop.Notifications.xml notificationsclient)
-    qt4_add_dbus_adaptor(DBUS ../../interfaces/org.kde.StatusNotifierItem.xml statusnotifieritemdbus.h StatusNotifierItemDBus)
-  endif(WITH_QT5)
+if (HAVE_DBUS)
+    set(SOURCES ${SOURCES} statusnotifieritem.cpp statusnotifieritemdbus.cpp dockmanagernotificationbackend.cpp)
+    qt_add_dbus_interface(DBUS ../../interfaces/org.kde.StatusNotifierWatcher.xml statusnotifierwatcher)
+    qt_add_dbus_interface(DBUS ../../interfaces/org.freedesktop.Notifications.xml notificationsclient)
+    qt_add_dbus_adaptor(DBUS ../../interfaces/org.kde.StatusNotifierItem.xml statusnotifieritemdbus.h StatusNotifierItemDBus)
 endif(HAVE_DBUS)
 
 if(HAVE_SSL)
                     ${CMAKE_SOURCE_DIR}/src/qtui
                     ${CMAKE_SOURCE_DIR}/src/qtui/settingspages
                     ${CMAKE_SOURCE_DIR}/src/uisupport
-                    ${CMAKE_CURRENT_BINARY_DIR}
-                    ${QUASSEL_QT_INCLUDES})
 
-if(WITH_QT5)
-  qt5_wrap_ui(UI ${FORMPATH} ${SPFRM})
-else(WITH_QT5)
-  qt4_wrap_ui(UI ${FORMPATH} ${SPFRM})
-endif(WITH_QT5)
+)
+
+qt_wrap_ui(UI ${FORMPATH} ${SPFRM})
+
+if (WITH_QT5)
+    list(APPEND qt_modules Widgets)
+endif()
+
+if (HAVE_DBUS)
+    list(APPEND qt_modules DBus)
+endif()
+
+if (HAVE_WEBKIT)
+    list(APPEND qt_modules Webkit XmlPatterns)
+endif()
 
 add_library(mod_qtui STATIC ${SOURCES} ${SPSRC} ${DBUS} ${UI})
+qt_use_modules(mod_qtui Core Gui Network ${qt_modules})
+
 add_dependencies(mod_qtui mod_common mod_client mod_uisupport)
-set_target_properties(mod_qtui PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}")
 
 # Builds the uisupport module
 
-if(WITH_QT5)
-  setup_qt_variables(Widgets Network)
-else(WITH_QT5)
-  setup_qt_variables(Gui Network)
-endif(WITH_QT5)
-
 set(SOURCES
     abstractbuffercontainer.cpp
     abstractitemview.cpp
 
 include_directories(${CMAKE_SOURCE_DIR}/src/common
                     ${CMAKE_SOURCE_DIR}/src/client
-                    ${QUASSEL_QT_INCLUDES})
+)
 
 if(HAVE_QCA2)
   include_directories(${QCA2_INCLUDE_DIR})
 endif(HAVE_QCA2)
 
+if (WITH_QT5)
+    list(APPEND qt_modules Widgets)
+endif()
+
 add_library(mod_uisupport STATIC ${SOURCES})
+qt_use_modules(mod_uisupport Core Gui Network ${qt_modules})
+
 add_dependencies(mod_uisupport mod_common mod_client)
-set_target_properties(mod_uisupport PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}")