Merge branch 'master' of git@git.quassel-irc.org:quassel
authorMarcus Eggenberger <egs@quassel-irc.org>
Sun, 15 Jun 2008 14:03:39 +0000 (16:03 +0200)
committerMarcus Eggenberger <egs@quassel-irc.org>
Sun, 15 Jun 2008 14:03:39 +0000 (16:03 +0200)
21 files changed:
CMakeLists.txt [new file with mode: 0644]
README.cmake [new file with mode: 0644]
build/modules/module.pri
scripts/build/Info.plist [new file with mode: 0644]
scripts/build/macosx_makebundle.py [new file with mode: 0755]
src/client/CMakeLists.txt [new file with mode: 0644]
src/client/clientsyncer.cpp
src/common/CMakeLists.txt [new file with mode: 0644]
src/common/genversion.cpp [new file with mode: 0644]
src/common/global.cpp
src/common/global.h
src/common/main.cpp
src/core/CMakeLists.txt [new file with mode: 0644]
src/core/core.cpp
src/core/ctcphandler.cpp
src/icons/win32.rc [new file with mode: 0644]
src/qtui/CMakeLists.txt [new file with mode: 0644]
src/qtui/aboutdlg.cpp
src/qtui/settingspages/settingspages.inc [new file with mode: 0644]
src/uisupport/CMakeLists.txt [new file with mode: 0644]
version.inc

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bc14806
--- /dev/null
@@ -0,0 +1,190 @@
+# This is the cmake-based build system for Quassel IRC.
+# You may pass various options to cmake:
+# -DBUILD=<string> : Select binaries to build. <string> may contain any combination
+#                    of "core", "client", "mono" or "all".
+# -DQT=/path/to/qt : Choose a Qt4 installation to use instead of the system Qt4
+# -DSTATIC=1       : Enable static building of Quassel, most useful with a static Qt.
+# -DSTATICWIN=1    : Enable static building for Windows.
+# -DSPUTDEV        : Do not use.
+#
+# NOTE: You need to remove CMakeCache.txt if you plan to change any of these values!
+
+project(QuasselIRC)
+
+cmake_minimum_required(VERSION 2.4.5)
+
+# This would suppress annoying warnings on cmake-2.6, but we can't use it 
+# with 2.4, so... DUH!
+# cmake_policy(SET CMP0003 OLD)  # suppress linker warnings
+
+if(STATICWIN)
+  set(CMAKE_BUILD_TYPE Release)
+endif(STATICWIN)
+
+# Enable various flags on gcc
+include(CheckCXXCompilerFlag)
+check_cxx_compiler_flag(-Wall Wall)
+if(Wall)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+endif(Wall)
+check_cxx_compiler_flag(-Wextra Wextra)
+if(Wextra)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
+endif(Wextra)
+check_cxx_compiler_flag(-ansi ansi)
+if(ansi)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ansi")
+endif(ansi)
+
+set(QT_MIN_VERSION "4.4.0")
+
+# By default, we build all binaries
+if(NOT DEFINED BUILD)
+  set(BUILD all)
+endif(NOT DEFINED BUILD)
+
+# User might define which binaries to build by invoking cmake -DBUILD=<string>,
+# where <string> might contain any combination of "core", "client", "mono" or "all"
+if(BUILD MATCHES all)
+  set(BUILD_CORE true)
+  set(BUILD_QTCLIENT true)
+  set(BUILD_MONO true)
+  message(STATUS "Building Quassel Client, Quassel Core and monolithic Quassel.")
+else(BUILD MATCHES all)
+  if(BUILD MATCHES core)
+    set(BUILD_CORE true)
+    message(STATUS "Building Quassel Core")
+  endif(BUILD MATCHES core)
+  if(BUILD MATCHES client)
+    set(BUILD_QTCLIENT true)
+    message(STATUS "Building Quassel Client")
+  endif(BUILD MATCHES client)
+  if(BUILD MATCHES mono)
+    set(BUILD_MONO true)
+    message(STATUS "Building monolithic Quassel")
+  endif(BUILD MATCHES mono)
+endif(BUILD MATCHES all)
+
+# Enable mostly b0rked stuff (new ChatView), do not enable this unless you know what you do...
+if(SPUTDEV)
+  add_definitions(-DSPUTDEV)
+endif(SPUTDEV)
+
+# Set up OpenSSL
+find_package(OpenSSL)
+
+# Select a Qt installation here, if you don't want to use system Qt
+if(DEFINED QT)
+  # FindQt4 will look for the qmake binary in $PATH, so we just prepend the Qt dir
+  set(ENV{PATH} ${QT}/bin:$ENV{PATH})
+  #SET(QT_QMAKE_EXECUTABLE ${QT}/bin/qmake CACHE FILEPATH "" FORCE)
+endif(DEFINED QT)
+
+# Now that we have the correct $PATH, lets find Qt!
+find_package(Qt4 REQUIRED)
+
+set(QT_DONT_USE_QTGUI 1)
+include(${QT_USE_FILE})
+include_directories(${QT_INCLUDES})
+
+# We need to create a version.gen
+# For this, we create our genversion binary and make sure it is run every time.
+add_executable(genversion ${CMAKE_SOURCE_DIR}/src/common/genversion.cpp)
+target_link_libraries(genversion ${QT_LIBRARIES})
+
+add_custom_target(genversion_run ALL ${CMAKE_BINARY_DIR}/genversion
+                  ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/src/common/version.gen)
+add_dependencies(genversion_run genversion)
+
+# Add needed subdirs
+add_subdirectory(src/common)
+include_directories(src/common)
+if(BUILD_CORE OR BUILD_MONO)
+  add_subdirectory(src/core)
+  include_directories(src/core)
+endif(BUILD_CORE OR BUILD_MONO)
+if(BUILD_QTCLIENT OR BUILD_MONO)
+  add_subdirectory(src/client)
+  add_subdirectory(src/uisupport)
+  add_subdirectory(src/qtui)
+  include_directories(src/client)
+  include_directories(src/uisupport)
+  include_directories(src/qtui)
+endif(BUILD_QTCLIENT OR BUILD_MONO)
+
+# Make sure version.gen exists before building mod_common
+add_dependencies(mod_common genversion_run)
+
+# Add resources
+qt4_add_resources(RC_I18N i18n/i18n.qrc)
+qt4_add_resources(RC_ICONS src/icons/icons.qrc)
+qt4_add_resources(RC_QUASSEL_ICONS src/icons/quassel-icons.qrc)
+qt4_add_resources(RC_SQL src/core/sql.qrc)
+
+# Set global buildflags
+if(DEFINED STATIC)
+  set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc ${CMAKE_EXE_LINKER_FLAGS}")
+  link_directories(${CMAKE_BINARY_DIR}/staticlibs)
+endif(DEFINED STATIC)
+
+if(STATICWIN AND WIN32)
+  link_libraries(imm32 winmm)  # missing by default :/
+   if(OPENSSL_FOUND)
+     link_libraries(${OPENSSL_LIBRARIES} libeay32MD)
+   endif(OPENSSL_FOUND)
+endif(STATICWIN AND WIN32)
+
+if(WIN32)
+  set(WIN32_RC src/icons/win32.rc)  # for app icons on windows
+endif(WIN32)
+
+# Here comes the dirty part. Our targets need different Qt4 modules, i.e. different libs
+# and defines. We can't simply include UseQt4 several times, since definitions add up.
+# We workaround this by using our own macro to figure out what to add.
+
+# This macro sets variables for additional Qt modules.
+macro(setup_qt4_variables)
+  set(QUASSEL_QT_LIBRARIES )
+  foreach(qtmod CORE ${ARGV})
+    set(QUASSEL_QT_LIBRARIES ${QUASSEL_QT_LIBRARIES} ${QT_QT${qtmod}_LIBRARY} ${QT_${qtmod}_LIB_DEPENDENCIES})
+  endforeach(qtmod ${ARGV})
+  set(QUASSEL_QT_LIBRARIES ${QUASSEL_QT_LIBRARIES} ${QT_LIBRARIES})
+endmacro(setup_qt4_variables)
+
+# Now we have everything, so just glue the right pieces together :)
+if(BUILD_CORE)
+  setup_qt4_variables(NETWORK SCRIPT SQL)
+  add_executable(quasselcore ${CMAKE_SOURCE_DIR}/src/common/main.cpp
+                             ${RC_SQL} ${RC_I18N} ${WIN32_RC})
+  set_target_properties(quasselcore PROPERTIES 
+                                    COMPILE_FLAGS "-DQT_NETWORK_LIB -DQT_SCRIPT_LIB -DQT_SQL_LIB -DBUILD_CORE")
+  target_link_libraries(quasselcore mod_core mod_common ${QUASSEL_QT_LIBRARIES})
+endif(BUILD_CORE)
+
+if(BUILD_QTCLIENT)
+  setup_qt4_variables(GUI NETWORK)
+  add_executable(quasselclient ${CMAKE_SOURCE_DIR}/src/common/main.cpp
+                               ${RC_ICONS} ${RC_QUASSEL_ICONS} ${RC_I18N} ${WIN32_RC})
+  set_target_properties(quasselclient PROPERTIES
+                                      COMPILE_FLAGS "-DQT_GUI_LIB -DQT_NETWORK_LIB -DBUILD_QTUI")
+  target_link_libraries(quasselclient mod_qtui mod_uisupport mod_client mod_common ${QUASSEL_QT_LIBRARIES})
+endif(BUILD_QTCLIENT)
+
+if(BUILD_MONO)
+  setup_qt4_variables(GUI NETWORK SCRIPT SQL)
+  add_executable(quassel ${CMAKE_SOURCE_DIR}/src/common/main.cpp
+                         ${RC_ICONS} ${RC_QUASSEL_ICONS} ${RC_SQL} ${RC_I18N} ${WIN32_RC})
+  set_target_properties(quassel PROPERTIES 
+                                COMPILE_FLAGS "-DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_SCRIPT_LIB -DQT_SQL_LIB -DBUILD_MONO")
+  target_link_libraries(quassel mod_qtui mod_uisupport mod_client mod_core mod_common ${QUASSEL_QT_LIBRARIES})
+endif(BUILD_MONO)
+
+# Build bundles for MacOSX
+if(APPLE)
+  add_custom_command(TARGET quasselclient POST_BUILD
+                     COMMAND ${CMAKE_SOURCE_DIR}/scripts/build/macosx_makebundle.py
+                             ${CMAKE_SOURCE_DIR} "Quassel Client" quasselclient)
+  add_custom_command(TARGET quassel POST_BUILD
+                     COMMAND ${CMAKE_SOURCE_DIR}/scripts/build/macosx_makebundle.py
+                             ${CMAKE_SOURCE_DIR} "Quassel" quassel)
+endif(APPLE)
diff --git a/README.cmake b/README.cmake
new file mode 100644 (file)
index 0000000..28a6c39
--- /dev/null
@@ -0,0 +1,53 @@
+CMake supports and encourages out-of-source builds, which do not clutter the source directory.
+You can (and should) thus use an arbitrary directory for building.
+There is no "make distclean"; "make clean" should usually be enough since CMake actually
+cleans up properly (qmake often didn't). If you really want to get rid of all build files,
+just remove the build directory.
+
+Usually, you will build Quassel as follows:
+
+cd /path/to/build/dir
+cmake /path/to/quassel
+make
+
+Additionally, you may add some options to the cmake call, prefixed by -D. These need to follow
+the source directory PATH:
+
+cmake /path/to/quassel -D<option1> -D<option2>
+
+NOTE: In order to reconfigure, you need to remove CMakeCache.txt (or empty
+      the build directory), otherwise cmake will ignore modified -D options!
+
+Quassel recognizes the following options:
+
+-DBUILD=<string>
+    Specify which Quassel binaries to build. <string> may contain any combination of
+    "core", "client", "mono" or "all".
+
+-DQT=/path/to/qt
+    Use a non-system Qt installation. This is for example useful if you have a static
+    Qt installed in some local dir.
+
+-DSTATIC=1
+    Enable static building of Quassel. You should link the static versions of some libs
+    (in particular libstdc++.a) into /path/to/build/dir/staticlibs in oder to create
+    a portable binary!
+
+-DSTATICWIN=1
+    Enable static building for Windows platforms. This adds some libs that are not automatically
+    included for some reason.
+
+BUILDING ON WINDOWS:
+--------------------
+We have tested building on Windows with a statically built Qt (with its /bin directory in %PATH%)
+and MSVC 2005/2008. Make sure that you use a "shell" that has all needed env variables setup,
+such as the "Visual Studio Command Prompt". You will also need the /bin of the Microsoft SDK in
+your %PATH% at least for VS 2008, otherwise rc.exe is not found.
+Currently, only building in the shell using nmake seems to work; CMake can also create MSVC project
+files, but they seem to be problematic. However, YMMV.
+
+After you have everything setup:
+
+cd C:\path\to\quassel-build
+cmake -G"NMake Makefiles" C:\path\to\quassel\source -DSTATICWIN=1
+nmake
index cc452f8..6dc018d 100644 (file)
@@ -46,7 +46,7 @@ include(../contrib/contrib.pri)
 for(dep, DEPMOD) {
   INCLUDEPATH *= $$SRCPATH/$$dep
 }
-INCLUDEPATH *= $$MODPATH  # and don't forget our own dir
+INCLUDEPATH *= $$MODPATH ../../  # and don't forget our own dir
 
 # Now prefix all filenames with the correct dirname
 
diff --git a/scripts/build/Info.plist b/scripts/build/Info.plist
new file mode 100644 (file)
index 0000000..fbc7ac1
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>English</string>
+   <key>CFBundleExecutable</key>
+  <string>%(BUNDLE_NAME)s</string>
+  <key>CFBundleGetInfoString</key>
+  <string>Quassel IRC Client</string>
+  <key>CFBundleIconFile</key>
+  <string>%(ICON_FILE)s</string>
+  <key>CFBundleIdentifier</key>
+  <string>org.quassel-irc.client</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleName</key>
+  <string>Quassel IRC Client</string>
+  <key>CFBundlePackageType</key>
+  <string>APPL</string>
+  <key>CFBundleShortVersionString</key>
+  <string>%(BUNDLE_VERSION)s</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>CFBundleVersion</key>
+  <string>%(BUNDLE_VERSION)s</string>
+  <!-- <key>CSResourcesFileMapped</key>
+       <true/> -->
+  <key>LSRequiresCarbon</key>
+  <true/>
+  <key>NSHumanReadableCopyright</key>
+  <string>© 2005-08, Quassel IRC Team</string>
+</dict>
+</plist>
diff --git a/scripts/build/macosx_makebundle.py b/scripts/build/macosx_makebundle.py
new file mode 100755 (executable)
index 0000000..821ce74
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+# -*- coding: iso-8859-1 -*-
+
+# ==============================
+#  Imports
+# ==============================
+import os
+import sys
+
+# ==============================
+#  Constants
+# ==============================
+if len(sys.argv) < 2:
+    sys.exit(1)
+
+SOURCE_DIR = sys.argv[1]
+
+if len(sys.argv) < 4:
+    BUNDLE_NAME= "Quassel Client"
+    EXE_NAME = "quasselclient"
+else:
+    BUNDLE_NAME = sys.argv[2]
+    EXE_NAME = sys.argv[3]
+CONTENTS_DIR = BUNDLE_NAME + ".app/Contents/"
+
+BUNDLE_VERSION = "0.2.0-pre"
+ICON_FILE = "src/icons/quassel/quassel.icns"
+
+def createBundle():
+    try:
+        os.makedirs(CONTENTS_DIR + "MacOS")
+        os.makedirs(CONTENTS_DIR + "Resources")
+    except:
+        pass
+
+def copyFiles(exeFile, iconFile):
+    os.system("cp %s %sMacOs/%s" % (exeFile, CONTENTS_DIR.replace(' ', '\ '), BUNDLE_NAME.replace(' ', '\ ')))
+    os.system("cp %s/%s %s/Resources" % (SOURCE_DIR, iconFile, CONTENTS_DIR.replace(' ', '\ ')))
+
+def createPlist(bundleName, iconFile, bundleVersion):
+    templateFile = file(SOURCE_DIR + "/scripts/build/Info.plist", 'r')
+    template = templateFile.read()
+    templateFile.close()
+    print 
+
+    plistFile = file(CONTENTS_DIR + "Info.plist", 'w')
+    plistFile.write(template % {"BUNDLE_NAME" : bundleName,
+                                "ICON_FILE" : iconFile[iconFile.rfind("/")+1:],
+                                "BUNDLE_VERSION" : bundleVersion})
+    plistFile.close()
+
+if __name__ == "__main__":
+    createBundle()
+    createPlist(BUNDLE_NAME, ICON_FILE, BUNDLE_VERSION)
+    copyFiles(EXE_NAME, ICON_FILE)
+    pass
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt
new file mode 100644 (file)
index 0000000..39436cb
--- /dev/null
@@ -0,0 +1,48 @@
+# Builds the client module
+
+# We still have some minor deps to QtUi: QItemSelectionModel
+# set(QT_DONT_USE_QTGUI 1)
+set(QT_USE_QTNETWORK 1)
+include(${QT_USE_FILE})
+
+set(SOURCES
+    buffer.cpp
+    buffermodel.cpp
+    buffersettings.cpp
+    client.cpp
+    clientbacklogmanager.cpp
+    clientsettings.cpp
+    clientsyncer.cpp
+    mappedselectionmodel.cpp
+    networkmodel.cpp
+    selectionmodelsynchronizer.cpp
+    treemodel.cpp)
+
+set(MOC_HDRS
+    buffer.h
+    buffermodel.h
+    client.h
+    clientbacklogmanager.h
+    clientsyncer.h
+    networkmodel.h
+    mappedselectionmodel.h
+    quasselui.h
+    selectionmodelsynchronizer.h
+    treemodel.h)
+
+set(HEADERS
+    buffersettings.h
+    clientsettings.h)
+
+if(SPUTDEV)
+  set(SOURCES ${SOURCES} messagefilter.cpp messagemodel.cpp)
+  set(MOC_HDRS ${MOC_HDRS} messagefilter.h messagemodel.h)
+endif(SPUTDEV)
+
+qt4_wrap_cpp(MOC ${MOC_HDRS})
+
+include_directories(${CMAKE_SOURCE_DIR}/src/common)
+
+add_library(mod_client STATIC ${SOURCES} ${MOC} ${HEADERS})
+add_dependencies(mod_client mod_common)
+
index e7f68b0..93d73bb 100644 (file)
@@ -157,8 +157,9 @@ void ClientSyncer::coreSocketConnected() {
   QVariantMap clientInit;
   clientInit["MsgType"] = "ClientInit";
   clientInit["ClientVersion"] = Global::quasselVersion;
-  clientInit["ClientDate"] = Global::quasselDate;
-  clientInit["ClientBuild"] = Global::quasselBuild; // this is a minimum, since we probably won't update for every commit
+  clientInit["ClientBuild"] = 860; // FIXME legacy!
+  clientInit["ClientDate"] = Global::quasselBuildDate;
+  clientInit["ProtocolVersion"] = Global::protocolVersion;
   clientInit["UseSsl"] = coreConnectionInfo["useSsl"];
 #ifndef QT_NO_COMPRESS
   clientInit["UseCompression"] = true;
@@ -166,7 +167,6 @@ void ClientSyncer::coreSocketConnected() {
   clientInit["UseCompression"] = false;
 #endif
 
-  
   SignalProxy::writeDataToDevice(socket, clientInit);
 }
 
@@ -186,9 +186,10 @@ void ClientSyncer::coreSocketDisconnected() {
 
 void ClientSyncer::clientInitAck(const QVariantMap &msg) {
   // Core has accepted our version info and sent its own. Let's see if we accept it as well...
-  if(msg["CoreBuild"].toUInt() < Global::coreBuildNeeded) {
+  if(msg.contains("CoreBuild") && msg["CoreBuild"].toUInt() < 732  // legacy!
+    || !msg.contains("CoreBuild") && msg["ProtocolVersion"].toUInt() < Global::clientNeedsProtocol) {
     emit connectionError(tr("<b>The Quassel Core you are trying to connect to is too old!</b><br>"
-        "Need at least a Core Version %1 (Build >= %2) to connect.").arg(Global::quasselVersion).arg(Global::coreBuildNeeded));
+        "Need at least core/client protocol v%1 to connect.").arg(Global::clientNeedsProtocol));
     disconnectFromCore();
     return;
   }
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3b1f2ab
--- /dev/null
@@ -0,0 +1,52 @@
+# Builds the common module
+
+set(QT_DONT_USE_QTGUI 1)
+set(QT_USE_QTNETWORK 1)
+include(${QT_USE_FILE})
+
+set(SOURCES
+    backlogmanager.cpp
+    bufferinfo.cpp
+    buffersyncer.cpp
+    bufferviewconfig.cpp
+    bufferviewmanager.cpp
+    global.cpp
+    identity.cpp
+    logger.cpp
+    message.cpp
+    settings.cpp
+    signalproxy.cpp
+    syncableobject.cpp
+    util.cpp
+    network.cpp
+    ircuser.cpp
+    ircchannel.cpp)
+
+set(MOC_HDRS
+    backlogmanager.h
+    buffersyncer.h
+    bufferviewconfig.h
+    bufferviewmanager.h
+    identity.h
+    ircchannel.h
+    ircuser.h
+    logger.h
+    network.h
+    signalproxy.h
+    syncableobject.h)
+
+set(HEADERS ${MOC_HDRS}
+    bufferinfo.h
+    global.h
+    message.h
+    settings.h
+    types.h
+    util.h)
+
+qt4_wrap_cpp(MOC ${MOC_HDRS})
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})  # for version.inc and version.gen
+add_definitions(-DHAVE_VERSION_GEN)  # we ensure that by deps in the main CMakeLists.txt
+set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES version.gen)
+
+add_library(mod_common STATIC ${SOURCES} ${MOC})
diff --git a/src/common/genversion.cpp b/src/common/genversion.cpp
new file mode 100644 (file)
index 0000000..e8e75f9
--- /dev/null
@@ -0,0 +1,86 @@
+/***************************************************************************
+ *   Copyright (C) 2005-08 by the Quassel Project                          *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+/** This is called at compile time and generates a suitable version.gen.
+ *  usage: genversion git_root target_file
+ * 
+ */
+
+#include <QDebug>
+#include <QProcess>
+#include <QString>
+#include <QStringList>
+#include <QRegExp>
+#include <QFile>
+
+int main(int argc, char **argv) {
+  if(argc < 3) {
+    qFatal("Usage: ./genversion <git_root> <target_file>");
+    return 255;
+  }
+  QString gitroot = argv[1];
+  QString target = argv[2];
+  QString version;
+
+  if(QFile::exists(gitroot + "/.git")) {
+    // try to execute git-describe to get a version string
+    QProcess git;
+    git.setWorkingDirectory(gitroot);
+    git.start("git-describe", QStringList("--long"));
+    if(git.waitForFinished(10000)) {
+      QString gitversion = git.readAllStandardOutput();
+      if(!gitversion.isEmpty() && !gitversion.contains("fatal")) {
+        // seems we have a valid version string, now prettify it...
+        // check if the workdir is dirty first
+        QString dirty;
+        QStringList params = QStringList() << "--name-only" << "HEAD";
+        git.start("git-diff-index", params);
+        if(git.waitForFinished(10000)) {
+          if(!git.readAllStandardOutput().isEmpty()) dirty = "*";
+        }
+        // Now we do some replacement magic...
+        QRegExp rxCheckTag("(.*)-0-g[0-9a-f]+\n$");
+        QRegExp rxGittify("(.*)-(\\d+)-g([0-9a-f]+)\n$");
+        gitversion.replace(rxCheckTag, QString("\\1%1").arg(dirty));
+        gitversion.replace(rxGittify, QString("\\1:git-\\3+\\2%1").arg(dirty));
+        if(!gitversion.isEmpty()) version = gitversion;
+      }
+    }
+  }
+  if(version.isEmpty()) {
+    // hmm, Git failed... let's check for version.dist instead
+    QFile dist(gitroot + "/version.dist");
+    if(dist.open(QIODevice::ReadOnly | QIODevice::Text)) {
+      version = dist.readAll();
+      dist.close();
+    }
+  }
+  // ok, create our version.gen now
+  QFile gen(target);
+  if(!gen.open(QIODevice::WriteOnly | QIODevice::Text)) {
+    qFatal(QString("Could not write %1!").arg(target).toAscii());
+    return 255;
+  }
+  gen.write(QString("quasselGeneratedVersion = \"%1\";\n"
+                    "quasselBuildDate = \"%2\";\n"
+                    "quasselBuildTime = \"%3\";\n").arg(version).arg(__DATE__).arg(__TIME__).toAscii());
+  gen.close();
+  return EXIT_SUCCESS;
+}
index 59afde1..8941d5b 100644 (file)
@@ -98,15 +98,35 @@ void Global::registerMetaTypes() {
   qRegisterMetaTypeStreamOperators<MsgId>("MsgId");
 }
 
+//! This includes version.inc and possibly version.gen and sets up our version numbers.
+void Global::setupVersion() {
+
+#  include "version.inc"
+#  ifdef HAVE_VERSION_GEN
+#    include "version.gen"
+#  endif
+
+  if(quasselGeneratedVersion.isEmpty()) {
+    quasselVersion = QString("v%1 (unknown rev)").arg(quasselBaseVersion);
+  } else {
+    QStringList parts = quasselGeneratedVersion.split(':');
+    quasselVersion = QString("v%1").arg(parts[0]);
+    if(parts.count() >= 2) quasselVersion.append(QString(" (%1)").arg(parts[1]));
+  }
+  quasselBuildDate = __DATE__;
+  quasselBuildTime = __TIME__;
+}
+
 // Static variables
 
 QString Global::quasselVersion;
-QString Global::quasselDate;
-uint Global::quasselBuild;
-uint Global::clientBuildNeeded;
-QString Global::clientVersionNeeded;
-uint Global::coreBuildNeeded;
-QString Global::coreVersionNeeded;
+QString Global::quasselBaseVersion;
+QString Global::quasselGeneratedVersion;
+QString Global::quasselBuildDate;
+QString Global::quasselBuildTime;
+uint Global::protocolVersion;
+uint Global::clientNeedsProtocol;
+uint Global::coreNeedsProtocol;
 
 Global::RunMode Global::runMode;
 uint Global::defaultPort;
index 0759c27..777be21 100644 (file)
 namespace Global {
 
   extern QString quasselVersion;
-  extern QString quasselDate;
-  extern uint quasselBuild;
+  extern QString quasselBaseVersion;
+  extern QString quasselBuildDate;
+  extern QString quasselBuildTime;
+  extern uint protocolVersion;
 
-  //! Minimum client build number the core needs
-  extern uint clientBuildNeeded;
-  extern QString clientVersionNeeded;
+  extern uint clientNeedsProtocol;  //< Minimum protocol version the client needs
+  extern uint coreNeedsProtocol;    //< Minimum protocol version the core needs
 
-  //! Minimum core build number the client needs
-  extern uint coreBuildNeeded;
-  extern QString coreVersionNeeded;
+  extern QString quasselGeneratedVersion;  //< This is possibly set in version.gen
 
   // We need different config (QSettings) files for client and gui, since the core cannot work with GUI types
   // Set these here. They're used in ClientSettings and CoreSettings.
@@ -56,6 +55,7 @@ namespace Global {
   extern bool DEBUG;
 
   void registerMetaTypes();
+  void setupVersion();
 };
 
 #endif
index 3c36a28..eca54ba 100644 (file)
@@ -66,8 +66,7 @@ int main(int argc, char **argv) {
   // Logger logger;
 
   Global::registerMetaTypes();
-
-#include "../../version.inc"
+  Global::setupVersion();
 
 #if defined BUILD_CORE
   Global::runMode = Global::CoreOnly;
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2219f0a
--- /dev/null
@@ -0,0 +1,64 @@
+# Builds the core module
+
+set(QT_DONT_USE_QTGUI 1)
+set(QT_USE_QTNETWORK 1)
+set(QT_USE_QTSQL 1)
+set(QT_USE_QTSCRIPT 1)
+include(${QT_USE_FILE})
+
+set(SOURCES
+    abstractsqlstorage.cpp
+    basichandler.cpp
+    core.cpp
+    corebacklogmanager.cpp
+    corebufferviewconfig.cpp
+    corebufferviewmanager.cpp
+    corenetwork.cpp
+    coresession.cpp
+    coresettings.cpp
+    coreusersettings.cpp
+    ctcphandler.cpp
+    ircserverhandler.cpp
+    networkconnection.cpp
+    sessionthread.cpp
+    sqlitestorage.cpp
+    storage.cpp
+    userinputhandler.cpp)
+
+set(MOC_HDRS
+    abstractsqlstorage.h
+    basichandler.h
+    core.h
+    corebacklogmanager.h
+    corebufferviewconfig.h
+    corebufferviewmanager.h
+    corenetwork.h
+    coresession.h
+    ctcphandler.h
+    ircserverhandler.h
+    networkconnection.h
+    sqlitestorage.h
+    storage.h
+    sessionthread.h
+    userinputhandler.h)
+
+set(HEADERS
+    coresettings.h
+    coreusersettings.h)
+
+# QT_DEFINITIONS actually does not work, stuff gets included always.
+# Funny enough that does not seem to be harmful, but we should still find a way to figure out
+# if we have openssl in Qt...
+if(OPENSSL_FOUND AND NOT QT_DEFINITIONS MATCHES "-DQT_NO_OPENSSL")
+  set(SOURCES ${SOURCES} sslserver.cpp)
+  set(MOC_HDRS ${MOC_HDRS} sslserver.h)
+  link_libraries(${OPENSSL_LIBRARIES})
+  include_directories(${OPENSSL_INCLUDE_DIR})
+endif(OPENSSL_FOUND AND NOT QT_DEFINITIONS MATCHES "-DQT_NO_OPENSSL")
+
+QT4_WRAP_CPP(MOC ${MOC_HDRS})
+
+include_directories(${CMAKE_SOURCE_DIR}/src/common)
+
+add_library(mod_core STATIC ${SOURCES} ${MOC} ${HEADERS})
+add_dependencies(mod_core mod_common)
index f413bbf..ebfe491 100644 (file)
@@ -100,7 +100,7 @@ void Core::saveState() {
   QVariantMap state;
   QVariantList activeSessions;
   foreach(UserId user, instance()->sessions.keys()) activeSessions << QVariant::fromValue<UserId>(user);
-  state["CoreBuild"] = Global::quasselBuild;
+  state["CoreStateVersion"] = 1;
   state["ActiveSessions"] = activeSessions;
   s.setCoreState(state);
 }
@@ -115,11 +115,13 @@ void Core::restoreState() {
     return;
   }
   CoreSettings s;
-  uint build = s.coreState().toMap()["CoreBuild"].toUInt();
-  if(build < 362) {
+  /* We don't check, since we are at the first version since switching to Git
+  uint statever = s.coreState().toMap()["CoreStateVersion"].toUInt();
+  if(statever < 1) {
     qWarning() << qPrintable(tr("Core state too old, ignoring..."));
     return;
   }
+  */
   QVariantList activeSessions = s.coreState().toMap()["ActiveSessions"].toList();
   if(activeSessions.count() > 0) {
     qDebug() << "Restoring previous core state...";
@@ -382,16 +384,31 @@ void Core::processClientMessage(QTcpSocket *socket, const QVariantMap &msg) {
   // OK, so we have at least an init message format we can understand
   if(msg["MsgType"] == "ClientInit") {
     QVariantMap reply;
+
+    // Just version information -- check it!
+    if(msg.contains("ClientBuild") && msg["ClientBuild"].toUInt() < 732
+       || !msg.contains("ClientBuild") && msg["ProtocolVersion"].toUInt() < Global::coreNeedsProtocol) {
+      reply["MsgType"] = "ClientInitReject";
+      reply["Error"] = tr("<b>Your Quassel Client is too old!</b><br>"
+      "This core needs at least client/core protocol version %1.<br>"
+      "Please consider upgrading your client.").arg(Global::coreNeedsProtocol);
+      SignalProxy::writeDataToDevice(socket, reply);
+      qWarning() << qPrintable(tr("Client %1 too old, rejecting.").arg(socket->peerAddress().toString()));
+      socket->close(); return;
+    }
+
     reply["CoreVersion"] = Global::quasselVersion;
-    reply["CoreDate"] = Global::quasselDate;
-    reply["CoreBuild"] = Global::quasselBuild;
+    reply["CoreDate"] = Global::quasselBuildDate;
+    reply["CoreBuild"] = 860; // FIXME legacy
+    reply["ProtocolVersion"] = Global::protocolVersion;
     // TODO: Make the core info configurable
     int uptime = startTime.secsTo(QDateTime::currentDateTime());
     int updays = uptime / 86400; uptime %= 86400;
     int uphours = uptime / 3600; uptime %= 3600;
     int upmins = uptime / 60;
-    reply["CoreInfo"] = tr("<b>Quassel Core Version %1 (Build &ge; %2)</b><br>"
-                            "Up %3d%4h%5m (since %6)").arg(Global::quasselVersion).arg(Global::quasselBuild)
+    reply["CoreInfo"] = tr("<b>Quassel Core Version %1</b><br>"
+                            "Built: %2<br>"
+                            "Up %3d%4h%5m (since %6)").arg(Global::quasselVersion).arg(Global::quasselBuildDate)
                             .arg(updays).arg(uphours,2,10,QChar('0')).arg(upmins,2,10,QChar('0')).arg(startTime.toString(Qt::TextDate));
 
 #ifndef QT_NO_OPENSSL
@@ -407,23 +424,13 @@ void Core::processClientMessage(QTcpSocket *socket, const QVariantMap &msg) {
 #else
     bool supportsCompression = false;
 #endif
-    
+
     reply["SupportSsl"] = supportSsl;
     reply["SupportsCompression"] = supportsCompression;
     // switch to ssl/compression after client has been informed about our capabilities (see below)
 
     reply["LoginEnabled"] = true;
 
-    // Just version information -- check it!
-    if(msg["ClientBuild"].toUInt() < Global::clientBuildNeeded) {
-      reply["MsgType"] = "ClientInitReject";
-      reply["Error"] = tr("<b>Your Quassel Client is too old!</b><br>"
-                          "This core needs at least client version %1 (Build >= %2).<br>"
-                          "Please consider upgrading your client.").arg(Global::quasselVersion).arg(Global::quasselBuild);
-      SignalProxy::writeDataToDevice(socket, reply);
-      qWarning() << qPrintable(tr("Client %1 too old, rejecting.").arg(socket->peerAddress().toString()));
-      socket->close(); return;
-    }
     // check if we are configured, start wizard otherwise
     if(!configured) {
       reply["Configured"] = false;
index ba48964..a864fe6 100644 (file)
@@ -175,8 +175,8 @@ void CtcpHandler::handlePing(CtcpType ctcptype, const QString &prefix, const QSt
 void CtcpHandler::handleVersion(CtcpType ctcptype, const QString &prefix, const QString &target, const QString &param) {
   Q_UNUSED(target)
   if(ctcptype == CtcpQuery) {
-    reply(nickFromMask(prefix), "VERSION", QString("Quassel IRC (v%1 build >= %2) -- http://www.quassel-irc.org")
-        .arg(Global::quasselVersion).arg(Global::quasselBuild));
+    reply(nickFromMask(prefix), "VERSION", QString("Quassel IRC %1 (built on %2) -- http://www.quassel-irc.org")
+        .arg(Global::quasselVersion).arg(Global::quasselBuildDate));
     emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Received CTCP VERSION request by %1").arg(prefix));
   } else {
     // display Version answer
diff --git a/src/icons/win32.rc b/src/icons/win32.rc
new file mode 100644 (file)
index 0000000..4318d06
--- /dev/null
@@ -0,0 +1 @@
+IDI_ICON1               ICON    DISCARDABLE     "quassel/quassel.ico"
\ No newline at end of file
diff --git a/src/qtui/CMakeLists.txt b/src/qtui/CMakeLists.txt
new file mode 100644 (file)
index 0000000..98e83c6
--- /dev/null
@@ -0,0 +1,109 @@
+# Builds the qtui module
+
+set(QT_DONT_USE_QTGUI 0)
+set(QT_USE_QTNETWORK 1)
+include(${QT_USE_FILE})
+
+set(SOURCES
+    aboutdlg.cpp
+    bufferwidget.cpp
+    coreconfigwizard.cpp
+    coreconnectdlg.cpp
+    debugconsole.cpp
+    inputwidget.cpp
+    jumpkeyhandler.cpp
+    mainwin.cpp
+    nicklistwidget.cpp
+    qtui.cpp
+    qtuisettings.cpp
+    qtuistyle.cpp
+    settingsdlg.cpp
+    settingspagedlg.cpp
+    titlesetter.cpp
+    topicbutton.cpp
+    topicwidget.cpp
+    verticaldock.cpp)
+
+set(MOC_HDRS
+    aboutdlg.h
+    bufferwidget.h
+    coreconfigwizard.h
+    coreconnectdlg.h
+    debugconsole.h
+    inputwidget.h
+    jumpkeyhandler.h
+    mainwin.h
+    nicklistwidget.h
+    qtui.h
+    settingsdlg.h
+    settingspagedlg.h
+    titlesetter.h
+    topicbutton.h
+    topicwidget.h
+    verticaldock.h)
+
+set(HEADERS
+    qtuisettings.h
+    qtuistyle.h)
+
+if(SPUTDEV)
+  set(SOURCES ${SOURCES} chatitem.cpp chatline.cpp chatlinemodelitem.cpp
+                         chatlinemodel.cpp chatscene.cpp chatview.cpp)
+  set(MOC_HDRS ${MOC_HDRS} chatlinemodel.h chatscene.h chatview.h)
+  set(HEADERS ${HEADERS} chatitem.h chatline.h chatlinemodelitem.h)
+else(SPUTDEV)
+  set(SOURCES ${SOURCES} chatline-old.cpp chatwidget.cpp)
+  set(MOC_HDRS ${MOC_HDRS} chatline-old.h chatwidget.h)
+endif(SPUTDEV)
+
+set(FORMS
+    aboutdlg.ui
+    bufferviewwidget.ui
+    bufferwidget.ui
+    coreaccounteditdlg.ui
+    coreconfigwizardintropage.ui
+    coreconfigwizardadminuserpage.ui
+    coreconfigwizardstorageselectionpage.ui
+    coreconfigwizardsyncpage.ui
+    coreconnectdlg.ui
+    debugconsole.ui
+    inputwidget.ui
+    mainwin.ui
+    nicklistwidget.ui
+    settingsdlg.ui
+    settingspagedlg.ui
+    topicwidget.ui)
+
+foreach(FORM ${FORMS})
+  set(FORMPATH ${FORMPATH} ui/${FORM})
+endforeach(FORM ${FORMS})
+
+# handle settingspages
+include(settingspages/settingspages.inc)
+foreach(SP ${SETTINGSPAGES})
+  set(SPSRC ${SPSRC} settingspages/${SP}settingspage.cpp)
+  set(SPHDR ${SPHDR} settingspages/${SP}settingspage.h)
+  set(SPFRM ${SPFRM} settingspages/${SP}settingspage.ui)
+endforeach(SP ${SETTINGSPAGES})
+foreach(SRC ${SP_SOURCES})
+  set(SPSRC ${SPSRC} settingspages/${SRC})
+endforeach(SRC ${SP_SOURCES})
+foreach(HDR ${SP_HEADERS})
+  set(SPHDR ${SPHDR} settingspages/${HDR})
+endforeach(HDR ${SP_HEADERS})
+foreach(FRM ${SP_FORMS})
+  set(SPFRM ${SPFRM} settingspages/${FRM})
+endforeach(FRM ${SP_FORMS})
+
+
+qt4_wrap_cpp(MOC ${MOC_HDRS} ${SPHDR})
+qt4_wrap_ui(UI ${FORMPATH} ${SPFRM})
+
+include_directories(${CMAKE_SOURCE_DIR}/src/common
+                    ${CMAKE_SOURCE_DIR}/src/client
+                    ${CMAKE_SOURCE_DIR}/src/qtui
+                    ${CMAKE_SOURCE_DIR}/src/uisupport
+                    ${CMAKE_CURRENT_BINARY_DIR})
+
+add_library(mod_qtui STATIC ${SOURCES} ${SPSRC} ${MOC} ${UI} ${HEADERS})
+add_dependencies(mod_qtui mod_common mod_client mod_uisupport)
index a32ab6b..0c55277 100644 (file)
@@ -24,7 +24,8 @@
 AboutDlg::AboutDlg(QWidget *parent) : QDialog(parent) {
   ui.setupUi(this);
 
-  ui.versionLabel->setText(QString("<b>Version %1, Build &ge; %2 (%3)</b>").arg(Global::quasselVersion).arg(Global::quasselBuild).arg(Global::quasselDate));
+  ui.versionLabel->setText(QString("<b>Version %1</b><br>Built: %2 %3").arg(Global::quasselVersion)
+      .arg(Global::quasselBuildDate).arg(Global::quasselBuildTime));
   ui.aboutTextBrowser->setHtml(about());
   ui.authorTextBrowser->setHtml(authors());
   ui.contributorTextBrowser->setHtml(contributors());
diff --git a/src/qtui/settingspages/settingspages.inc b/src/qtui/settingspages/settingspages.inc
new file mode 100644 (file)
index 0000000..b3d93b6
--- /dev/null
@@ -0,0 +1,8 @@
+# Putting $FOO in SETTINGSPAGES automatically includes
+# $FOOsettingspage.cpp, $FOOsettingspage.h and $FOOsettingspage.ui
+set(SETTINGSPAGES appearance bufferview color fonts general highlight identities networks)
+
+# Specify additional files (e.g. for subdialogs) here!
+set(SP_SOURCES )
+set(SP_HEADERS )
+set(SP_FORMS buffervieweditdlg.ui createidentitydlg.ui saveidentitiesdlg.ui networkeditdlg.ui nickeditdlg.ui servereditdlg.ui)
diff --git a/src/uisupport/CMakeLists.txt b/src/uisupport/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ad63477
--- /dev/null
@@ -0,0 +1,53 @@
+# Builds the uisupport module
+
+set(QT_DONT_USE_QTGUI 0)
+set(QT_USE_QTNETWORK 1)
+include(${QT_USE_FILE})
+
+set(SOURCES
+    abstractbuffercontainer.cpp
+    abstractitemview.cpp
+    bufferview.cpp
+    bufferviewfilter.cpp
+    clearablelineedit.cpp
+    colorbutton.cpp
+    nickviewfilter.cpp
+    inputline.cpp
+    nickview.cpp
+    settingspage.cpp
+    tabcompleter.cpp
+    uisettings.cpp
+    uistylesettings.cpp)
+
+set(MOC_HDRS
+    abstractbuffercontainer.h
+    abstractitemview.h
+    bufferview.h
+    bufferviewfilter.h
+    clearablelineedit.h
+    colorbutton.h
+    nickviewfilter.h
+    inputline.h
+    nickview.h
+    settingspage.h
+    tabcompleter.h)
+
+set(HEADERS
+    uisettings.h
+    uistylesettings.h)
+
+if(SPUTDEV)
+  set(SOURCES ${SOURCES} uistyle.cpp)
+  set(HEADERS ${HEADERS} uistyle.h)
+else(SPUTDEV)
+  set(SOURCES ${SOURCES} old-uistyle.cpp)
+  set(HEADERS ${HEADERS} old-uistyle.h)
+endif(SPUTDEV)
+
+qt4_wrap_cpp(MOC ${MOC_HDRS})
+
+include_directories(${CMAKE_SOURCE_DIR}/src/common
+                    ${CMAKE_SOURCE_DIR}/src/client)
+
+add_library(mod_uisupport STATIC ${SOURCES} ${MOC} ${HEADERS})
+add_dependencies(mod_uisupport mod_common mod_client)
index 10b10a6..92fc5fd 100644 (file)
@@ -1,18 +1,9 @@
 // Versioning, should be kept current :)
 // This is included in main.cpp
 
-{ using namespace Global;
+//! This is the fallback version number in case we can't autogenerate one
+quasselBaseVersion = "0.3.0-pre";
+protocolVersion = 1;       //< Version of the client/core protocol
 
-  quasselVersion = "0.3.0-pre";
-  quasselDate = "2008-06-04";
-  quasselBuild = 869;
-
-  //! Minimum client build number the core needs
-  clientBuildNeeded = 731;
-  clientVersionNeeded = quasselVersion;
-
-  //! Minimum core build number the client needs
-  coreBuildNeeded = 731;
-  coreVersionNeeded = quasselVersion;
-
-}
+coreNeedsProtocol   = 1;   //< Minimum protocol version the core needs
+clientNeedsProtocol = 1;   //< Minimum protocol version the client needs