20 months agologger: export LogEntry symbols
Wolfgang Müller [Thu, 14 Feb 2019 17:54:07 +0000 (18:54 +0100)]
logger: export LogEntry symbols

20 months agologger: Dedup code, fix client Debug Log loglevel
Shane Synan [Thu, 14 Feb 2019 13:58:46 +0000 (14:58 +0100)]
logger: Dedup code, fix client Debug Log loglevel

Deduplicate code by moving LogEntry formatting into a separate
function, LogEntry::toString(), which applies timestamps and the log
level string.

Fix client Debug Log dialog to print log level using this new function.

Modify msgWithTime() to use this new function, too.

20 months agologger: resolve program name using RunMode and BuildInfo
Wolfgang Müller [Wed, 13 Feb 2019 13:48:19 +0000 (14:48 +0100)]
logger: resolve program name using RunMode and BuildInfo

20 months agologger: resolve level string in msgWithTime
Wolfgang Müller [Sat, 12 Jan 2019 18:14:28 +0000 (19:14 +0100)]
logger: resolve level string in msgWithTime

This means that the log level string is included in logs to files
and stdout even if syslog output is enabled.

20 months agologger: Make output to syslog nicer
Wolfgang Müller [Fri, 11 Jan 2019 16:45:52 +0000 (16:45 +0000)]
logger: Make output to syslog nicer

20 months agoUpdate Help>About Qt to use modern Qt logo and remove old Qt logo from repo
phuzion [Wed, 13 Feb 2019 14:28:13 +0000 (14:28 +0000)]
Update Help>About Qt to use modern Qt logo and remove old Qt logo from repo

20 months agocore: Remove updateSQLResource.sh, cleanup docs
Shane Synan [Wed, 13 Feb 2019 05:00:48 +0000 (00:00 -0500)]
core: Remove updateSQLResource.sh, cleanup docs

Remove updateSQLResource.sh as it's no longer needed.  `sql.qrc` is
now generated automatically as of commit

Update the README.md documentation in `src/core` to match.


20 months agocore: Remove redundant updateSchemaVersion() call
Shane Synan [Tue, 29 Jan 2019 07:52:25 +0000 (02:52 -0500)]
core: Remove redundant updateSchemaVersion() call

Remove the redundant updateSchemaVersion() call at the end of schema
migrations.  This is already called within the final iteration of the

Cleans up a leftover from f10304a35af0a7a4f8b812e467e69287d358ce7c

20 months agocore: Display problem step if storage setup fails
Shane Synan [Tue, 29 Jan 2019 04:08:30 +0000 (23:08 -0500)]
core: Display problem step if storage setup fails

Print the problematic setup step (e.g. 'setup_070_coreinfo') if
storage backend initialization fails.  This may help with debugging.

Modify setupQueries() to return a list of query strings and
resource filenames, used for the above.

20 months agocore: Track upgrade step within schema version
Shane Synan [Tue, 29 Jan 2019 04:08:03 +0000 (23:08 -0500)]
core: Track upgrade step within schema version

Track the last successful upgrade step (upgrade_###_XXX.sql) within
each schema version, storing it within 'coreinfo' table as
'schemaupgradestep'. When a schema upgrade finishes, clear
'schemaupgradestep' and set 'schemaversion'.

This allows for resuming multi-step schema upgrades that were
interrupted in the middle.

Whenever starting a schema upgrade, also check the value of
'schemaupgradestep'.  One of two states exist:
1.  Empty ('') or nonexistent
    No interrupted schema upgrade, start the next schema version
    upgrade from the first query.
2.  Contains text, e.g. 'upgrade_010_alter_sender_64bit_ids'
    The schema upgrade was interrupted, skip schema upgrade steps
    including the specified successful step, and resume from the next

For case 2, if the schema upgrade step cannot be found, warn and bail
out.  This should only happen if:
1.  The storage of successful query glitched, or the database was
    manually changed
2.  Quassel changed the filenames of upgrade queries, and the local
    Quassel core version was replaced during an interrupted schema

Modify SqliteStorage and PostgreSqlStorage to fetch/save the
'schemaupgradestep' key.  Clearing this key is done atomically within

(Ideally, the whole upgrade would be wrapped in a transaction, but
 that doesn't seem to be easily possible.)

Modify upgradeQueries() to return a list of query strings and
resource filenames, used for tracking the upgrade step and providing
clearer feedback on what steps fail.

20 months agocommon: Don't add quotes to exit exceptions
Shane Synan [Sun, 27 Jan 2019 07:42:40 +0000 (02:42 -0500)]
common: Don't add quotes to exit exceptions

When logging exit exceptions, wrap the QString in qPrintable(),
removing the extra quotes added by the debug logger.

20 months agobuild: Add Boost 1.0 license for CMake script
Shane Synan [Sat, 26 Jan 2019 04:16:40 +0000 (23:16 -0500)]
build: Add Boost 1.0 license for CMake script

Add copy of Boost 1.0 license for the included CMake script
GetGitRevisionDescription.  This addresses licensing concerns for
Debian and derivatives.

Rename the license file according to existing licenses GPLv2 and v3.

See https://www.boost.org/LICENSE_1_0.txt

Fixes #1504

20 months agoFixes misalignment of buttons in inputwidget
Janne Koschinski [Tue, 15 Jan 2019 16:32:43 +0000 (17:32 +0100)]
Fixes misalignment of buttons in inputwidget

20 months agoFixes bug where nicklist was broken on first start
Janne Koschinski [Tue, 15 Jan 2019 16:32:08 +0000 (17:32 +0100)]
Fixes bug where nicklist was broken on first start

Starting with commit 66e6d26 the nicklist gets hidden in
setDisconnectedState, but only unhidden in loadLayout.

As loadLayout skips the setVisible(true) if the state is empty, the
actual widget gets never shown, and the nicklist dock remains empty.

This was fixed by moving the setVisible call above the conditional

20 months agoApply suggested info change
Shane Synan [Wed, 13 Feb 2019 08:35:36 +0000 (09:35 +0100)]
Apply suggested info change

Co-Authored-By: justjanne <janne@kuschku.de>
20 months agoAllow configuring listen address
Janne Koschinski [Tue, 12 Feb 2019 21:42:26 +0000 (22:42 +0100)]
Allow configuring listen address

20 months agoProperly handle options if core has just now been configured
Janne Koschinski [Wed, 2 Jan 2019 18:35:43 +0000 (19:35 +0100)]
Properly handle options if core has just now been configured

20 months agoMake the identd listen on all adresses
Janne Koschinski [Wed, 2 Jan 2019 18:35:00 +0000 (19:35 +0100)]
Make the identd listen on all adresses

21 months agosrc: Yearly copyright bump
Manuel Nickschas [Thu, 24 Jan 2019 22:57:15 +0000 (23:57 +0100)]
src: Yearly copyright bump

... and it's still January!

22 months agocmake: Remove left-over debug message
Manuel Nickschas [Thu, 13 Dec 2018 20:05:04 +0000 (21:05 +0100)]
cmake: Remove left-over debug message

23 months agocmake: Add missing Boost dependency
Manuel Nickschas [Tue, 20 Nov 2018 21:29:58 +0000 (22:29 +0100)]
cmake: Add missing Boost dependency

Add a dependency to Boost in the modules that use Boost already,
so Boost headers installed in a non-standard location are found.

23 months agocmake: Create imported target for Boost, if it doesn't exist yet
Manuel Nickschas [Tue, 20 Nov 2018 22:33:56 +0000 (23:33 +0100)]
cmake: Create imported target for Boost, if it doesn't exist yet

Older versions of CMake's FindBoost.cmake don't create imported
targets for the library. Create it ourselves if necessary.

23 months agocmake: Fix OSX post-build if not all targets are requested
Manuel Nickschas [Tue, 20 Nov 2018 21:10:27 +0000 (22:10 +0100)]
cmake: Fix OSX post-build if not all targets are requested

The post-build actions for OSX were not conditional on the selected
Quassel variants, so add_custom_command would be added to an undefined
target in that case.

This bug has been there since literally forever; however, CMake < 3.0
silently ignored the custom commands in that case, and thus this
issue was not visible.

With cmake_minimum_required now set to 3.5, the new behavior is
enabled and causes an error at configure time. Fix this by adding
the missing conditions.

23 months agoserializers: Fix quint16 deserialization, remove code duplication
Manuel Nickschas [Sun, 18 Nov 2018 22:18:47 +0000 (23:18 +0100)]
serializers: Fix quint16 deserialization, remove code duplication

Fix a bug where a quint16 would be deserialized into a QVariant
of type Int (instead of UShort). This broke the sync of
autoReconnectRetries in the network settings, because the slot's
signature didn't match the type of the QVariant.

The issue was caused by QVariant not having a constructor for
quint16, thus casting it into an int. Fix this by using
QVariant::fromValue(), which handles the type correctly.

Use the opportunity to remove much of the code duplication in the
deserialization code by providing and using a template function,
avoiding potential other issues with using QVariant's constructor.

23 months agocmake: Allow to make compile warnings fatal
Manuel Nickschas [Sun, 18 Nov 2018 20:02:12 +0000 (21:02 +0100)]
cmake: Allow to make compile warnings fatal

Failing on any compile warning is very useful in CI builds,
so add an option for enabling this. The option defaults to OFF,
because we don't want to annoy users that don't want this.

Enable fatal warnings in Travis CI.

23 months agoqa: Remove dead code
Manuel Nickschas [Sun, 18 Nov 2018 19:51:01 +0000 (20:51 +0100)]
qa: Remove dead code

23 months agoqa: Simplify main window activation logic
Manuel Nickschas [Sun, 18 Nov 2018 19:50:25 +0000 (20:50 +0100)]
qa: Simplify main window activation logic

Remove code duplication, avoid a warning about unreachable code.

23 months agoqa: Don't import whole Protocol namespace
Manuel Nickschas [Sun, 18 Nov 2018 19:49:05 +0000 (20:49 +0100)]
qa: Don't import whole Protocol namespace

Explicitly specify the Protocol namespace where needed. This avoids
warnings about hidden global symbols.

23 months agocmake: Increase warning level on MSVC
Manuel Nickschas [Sun, 18 Nov 2018 18:12:10 +0000 (19:12 +0100)]
cmake: Increase warning level on MSVC

By default, CMake sets /W3, which basically outputs nothing.
The next level /W4 is more useful, but causes lots of false positives.
So let's use /W4 and silence stuff that is annoying and useless.

23 months agocmake: Set proper install paths for Windows
Manuel Nickschas [Sun, 18 Nov 2018 17:31:07 +0000 (18:31 +0100)]
cmake: Set proper install paths for Windows

Instead of dumping everything into the install prefix, set
separate paths for runtime and library artifacts.

The paths chosen match the expectations of Craft packaging, so
we can subsequently remove the overrides in the craft blueprint.

23 months agotravis: Add Ubuntu 18.10 "Cosmic" to the list of CI distros
Manuel Nickschas [Fri, 16 Nov 2018 22:29:56 +0000 (23:29 +0100)]
travis: Add Ubuntu 18.10 "Cosmic" to the list of CI distros

Add Ubuntu 18.10 to the build matrix, so we ensure we can build
on the newest Ubuntu release.

Rework the combination of build options; it's probably enough to
test building without KDE only on the baseline, since the non-KDE
code does not change between distro versions (while the installed
version of KDE Frameworks does). This keeps the number of build
jobs reasonably low.

23 months agocmake: Move version setup into a separate .cmake file
Manuel Nickschas [Fri, 16 Nov 2018 22:09:50 +0000 (23:09 +0100)]
cmake: Move version setup into a separate .cmake file

Introduce a new QuasselVersion.cmake that contains the hard-coded
version, as well as the code for retrieving version information from
git (if available). This file also sets up version.h with the given
information. Remove the corresponding code from the main

Output the git revision at configure time if available, which helps
when analyzing build logs.

23 months agocmake: Consolidate compile settings
Manuel Nickschas [Thu, 15 Nov 2018 21:41:26 +0000 (22:41 +0100)]
cmake: Consolidate compile settings

Consolidate the various places where we were setting compiler options
in QuasselCompileSettings.cmake. No longer include KDE's settings;
instead, take some inspiration from their setup and incorporate this
in our own, so we not only benefit when building against KDE

Properly handle CMAKE_CXX_FLAGS and friends; append the flags to the
end of our own list of flags, so one can override what we define.
Clear the variables afterwards to avoid duplication.

Get rid of some MinGW options that have been around for a decade
and are most likely no longer required.

23 months agofunchelpers: Provide overload for invoking a member function
Manuel Nickschas [Wed, 7 Nov 2018 23:09:33 +0000 (00:09 +0100)]
funchelpers: Provide overload for invoking a member function

To avoid having to write boilerplate code for invoking a member
function pointer on an object, provide an appropriate overload
for invokeWithArgsList().

Extend the test case accordingly.

23 months agofunchelpers: Support the invocation of non-void callables
Manuel Nickschas [Wed, 31 Oct 2018 23:39:21 +0000 (00:39 +0100)]
funchelpers: Support the invocation of non-void callables

Let invokeWithArgsList() handle and return the return value of
non-void callables wrapped in a QVariant. To avoid special-casing,
the invocation of a void callable also returns a (default-constructed,
thus invalid) QVariant.

To indicate failure, wrap the QVariant in a boost::optional that is
empty if the callable could not be invoked.

23 months agotravis: Use ctest to execute unit tests
Manuel Nickschas [Thu, 18 Oct 2018 22:20:30 +0000 (00:20 +0200)]
travis: Use ctest to execute unit tests

ctest gives us more options than make/ninja, for example verbose

23 months agocleanup: Clean up BufferViewConfig
Manuel Nickschas [Thu, 18 Oct 2018 22:00:58 +0000 (00:00 +0200)]
cleanup: Clean up BufferViewConfig

Only mark methods as slots that need to be slots. Don't return const
refs. Un-inline everything. Rename the overload of initSetBufferList()
that isn't actually used as an init setter to simply setBufferList()
to avoid confusion.

23 months agotests: Extend SignalProxyTest to cover request/receive method pairs
Manuel Nickschas [Thu, 18 Oct 2018 18:33:03 +0000 (20:33 +0200)]
tests: Extend SignalProxyTest to cover request/receive method pairs

When sending an RPC request (using REQUEST()), if the request method
on the server side returns a value, a corresponding receive method
is called on the client side. Extend the test case to cover this, so
we can safely refactor relevant parts of SignalProxy in the future.

23 months agosigproxy: Modernize RPC calls (remote signals)
Manuel Nickschas [Wed, 17 Oct 2018 23:00:12 +0000 (01:00 +0200)]
sigproxy: Modernize RPC calls (remote signals)

The previous implementation relied on undocumented Qt internals to
transform signals into RpcCall messages. It also relied on the
old-style, slow signal/slot connections and required RPC call
receivers to be actual slots, a feature deprecated in Qt.

Reimplement this feature to make use of PMF connections. Utilize
C++14 features such as variadic lambdas and templates to shift
most of the work to compile time, which is not only more efficient,
but also gives us compile-time checks for most things.

Arguments are now marshalled to and from QVariant using the methods
intended for the purpose, rather than reinterpreting void pointers
into raw memory (which mimicked the way Qt works internally, but
is of course fully unsupported, even though it miraculously worked
basically unchanged since the early days of Qt 4...). The marshalling
code is generated at compile time, which is more efficient than the
previous approach of looking up types and constructing arguments
at runtime.

SignalProxy::attachSignal() now expects the signal to be given as a
member function pointer. SignalProxy::attachSlot() supports member
function pointers as well as functors, similar to QObject::connect().

Remove SignalRelay and related methods that are no longer needed.

While we're at it, rename RpcCall's slotName attribute to signalName,
which better reflects reality.

The reimplementation does not affect the protocol; the serialization
format remains unchanged.

23 months agosigproxy: Actually rename SyncableObjects when requested
Manuel Nickschas [Wed, 17 Oct 2018 20:14:24 +0000 (22:14 +0200)]
sigproxy: Actually rename SyncableObjects when requested

Until now, renaming a SyncableObject would properly update the maps
in SignalProxy, but it would not actually update the objectName
property on the client side. Fix this.

Remove the renameObject() method in SyncableObject in favor of
using setObjectName() and listening to the notifier signal emitted
by Qt for triggering the update. This ensures that the actual object
name and the expected one stay in sync. Also change places where
we unnecessarily rename right after construction to use the
appropriate constructor instead.

Extend the test case to cover the renaming of SyncableObject.

23 months agotests: Check that sourcePeer() is set in SignalProxyTest
Manuel Nickschas [Wed, 17 Oct 2018 20:09:53 +0000 (22:09 +0200)]
tests: Check that sourcePeer() is set in SignalProxyTest

We expect SignalProxy::current()->sourcePeer() to be set to the
currently sending peer when handling a signal, so add a check
for this to SignalProxyTest.

23 months agofunchelpers: Add a way to invoke a callable with a list of arguments
Manuel Nickschas [Mon, 15 Oct 2018 22:39:31 +0000 (00:39 +0200)]
funchelpers: Add a way to invoke a callable with a list of arguments

In various places, we serialize function arguments as a QVariantList,
and later use QMetaMethod and friends to call a slot with that list.

In order to avoid this kind of runtime method lookup, we need a way
to directly invoke a given callable (e.g. a function pointer) with
a list of serialized arguments. We'll also want to use the type-based
conversion functionality of QVariant instead of using undocumented
methods and reinterpret_cast'ing raw memory, as is currently the case.

Provide a method invokeWithArgsList() that takes any callable and
a list of arguments serialized in a QVariantList, performs some
runtime sanity checks (argument count and types), and invokes the
callable with the arguments converted to the correct type, if

Also add a test case for this function.

23 months agofunchelpers: Support traits for non-member functions
Manuel Nickschas [Mon, 15 Oct 2018 20:18:24 +0000 (22:18 +0200)]
funchelpers: Support traits for non-member functions

Add a FuncHelper overload for non-member (free) functions. Rename
MemberFunction to FunctionTraits to reflect that enhancement.

23 months agotypes: Add STL-compliant Hash functor for Qt types
Manuel Nickschas [Mon, 15 Oct 2018 19:22:04 +0000 (21:22 +0200)]
types: Add STL-compliant Hash functor for Qt types

In order to use Qt types with std::unordered_set (and map), a
compatible hash function needs to be provided. Provide a generic
Hash<T> functor that just uses the qHash() function for the given

This can be used as follows:
    std::unordered_set<QString, Hash<QString>> set;

23 months agotests: Add unit test for basic SignalProxy functionality
Manuel Nickschas [Thu, 4 Oct 2018 20:16:50 +0000 (22:16 +0200)]
tests: Add unit test for basic SignalProxy functionality

Add unit test cases for attached signals as well as syncable objects.
These test cases don't check for error behavior (yet); they mostly
are intended for ensuring that the upcoming refactoring of the
SignalProxy does not affect the format on the wire. As such, the test
cases mostly focus on the protocol messages sent by invoking
SignalProxy and SyncableObject functionality.

23 months agotest: Add a spy type that waits for one or more signals
Manuel Nickschas [Thu, 4 Oct 2018 19:10:13 +0000 (21:10 +0200)]
test: Add a spy type that waits for one or more signals

Introducing SignalSpy that allows to wait for one or more signals
to be emitted in test cases. Unlike QSignalSpy, it is not bound to
a particular signal on construction; instead, one has to explicitly
connect one or more signal(s) before calling wait().

23 months agotest: Add a way to mock peers for SignalProxy-related test cases
Manuel Nickschas [Thu, 4 Oct 2018 17:03:02 +0000 (19:03 +0200)]
test: Add a way to mock peers for SignalProxy-related test cases

Introduce a new mock class MockedPeer that allows for setting
expectations for dispatched Quassel protocol messages. Also provide
matchers to express such expectations in a straightforward way.

MockedPeer for now only supports SignalProxy messages; support for
authentication messages can be added later if needed. Note that
expectations can be set on the level of protocol messages, but things
like a testing a particular serialization, the use of network sockets,
or other lower-level implementation details are not supported, nor is
MockedPeer intended for such use cases (we'd expect specific tests for
specific peer types).

23 months agotest: Add GTest printers for commonly used Qt types
Manuel Nickschas [Thu, 4 Oct 2018 16:59:59 +0000 (18:59 +0200)]
test: Add GTest printers for commonly used Qt types

Because GTest by default prints out unknown types as hexdump or other
badly readably formats, provide PrintTo functions for Qt types we use
in tests. That way, GTest will use those instead of falling back to
its own default.

Reuse Qt's own QDebug stream support to avoid having to reimplement
printing functionality for all the types. This makes it very easy
to see e.g. the contents of a QVariantMap or other complex types.

23 months agotest: Add InvocationSpy and ValueSpy helper classes
Manuel Nickschas [Thu, 4 Oct 2018 16:40:23 +0000 (18:40 +0200)]
test: Add InvocationSpy and ValueSpy helper classes

For test cases testing asynchronous operations that require a running
event loop, it is convenient to have a way to wait until something
happens. Qt provides QSignalSpy to wait for a specific signal while
spinning the event loop. This is not always convenient to use, though.

Provide InvocationSpy and ValueSpy (based on QSignalSpy) that provide
an explicit way of notifying them, without having to connect a signal
first. Unlike QSignalSpy, those classes also time out when not notified
within a given time span.

Put those classes in a new library Quassel::Test::Util, which will
gain more testing-related utils over time.

23 months agotest: Introduce Quassel::Test::Global library
Manuel Nickschas [Sun, 30 Sep 2018 20:11:56 +0000 (22:11 +0200)]
test: Introduce Quassel::Test::Global library

Move things that are needed in every test case into a new library,
rather than requiring the Test::Main one (which is not going to be
linked to other test tooling which we'll introduce).

23 months agomodernize: Remove custom Quassel-specific log macros
Manuel Nickschas [Sun, 14 Oct 2018 22:49:57 +0000 (00:49 +0200)]
modernize: Remove custom Quassel-specific log macros

The quInfo(), quWarning(), quError() macros were introduced a long
time ago to provide custom log message handling, such as logging to
file or syslog. Such features have been directly supported for the
standard Qt log macros for a while now, using a global message handler.
The only reason for Quassel's custom macros to still exist was the
lack of an info log level prior to Qt 5.5.

As we can now rely on Qt 5.5 to be available, replace the custom
macros by Qt ones, and remove LogMessage which is no longer needed.

23 months agomodernize: Remove Uncrustify config and script
Manuel Nickschas [Mon, 24 Sep 2018 22:42:00 +0000 (00:42 +0200)]
modernize: Remove Uncrustify config and script

Since we can now use clang-format for formatting the code, and
provide a .clang-format ruleset in the repository, we can remove
the ancient Uncrustify configuration and script.

23 months agomodernize: Reformat ALL the source... again!
Manuel Nickschas [Mon, 24 Sep 2018 22:13:14 +0000 (00:13 +0200)]
modernize: Reformat ALL the source... again!

It's been more than six years since we last used an autoformatter
on the codebase. Tooling has progressed, so has the language and
of course our personal preferences.

Use clang-format this time to reformat the whole codebase, following
the rules laid out in .clang-format (which one can use for configuring
an IDE, too, if it supports autoformatting). Overall, the new style
is not too different from what we used before, with one significant

We now attach pointer/reference indicators (*&) to the type rather
than the name, i.e. we left-align. While this is a major deviation
from the Qt style which we use for almost everything else, it aligns
more closely with many other projects, as well as the C++
documentation and STL. It also makes more sense semantically,
because */& are really part of the type.

Other changes include (but are not limited to):

- Use only one blank line between function definitions
- Categorize includes from generic/system to local, sorting each
  category alphabetically. The generic-to-local sort order seems to
  be more common than the other way round, so we use that.
- In .cpp files, the corresponding header is always included first.
  This is a general recommendation, because it makes it harder to
  accidentally introduce a reliance on transitive includes in headers.
- Consistently break initializers in ctors before the comma, so the
  commas are left-aligned together with the colon.
- Use two spaces between code and trailing comments.

Note that sometimes even clang-format gets things wrong. In a few
places, formatting was manually fixed; however, reviewing a diff of
almost 80k lines is a rather boring task, so we didn't thoroughly
go through all the changes. Wrong formatting can always be fixed
in follow-up commits, anyway.

Note also that we don't intend to re-run clang-format on a regular
basis, nor do we want to religiously follow a hardcoded set of rules
for new code in the future. Where it makes sense, the rules may be
bent in favor of better readability or more pleasing code.

23 months agocmake: Add build-time dependency to Boost 1.56
Manuel Nickschas [Mon, 24 Sep 2018 19:55:42 +0000 (21:55 +0200)]
cmake: Add build-time dependency to Boost 1.56

We'll be using some Boost features in the future, so prepare the
build system to reflect that dependency.

23 months agotravis: Reduce ccache size
Manuel Nickschas [Mon, 24 Sep 2018 19:26:35 +0000 (21:26 +0200)]
travis: Reduce ccache size

Reduce the ccache size in order to not waste too much time packing/
extracting the cache. Since we're only building one project, 1G should
be plenty.

23 months agotests: Enable tests in Travis
Manuel Nickschas [Mon, 24 Sep 2018 19:04:30 +0000 (21:04 +0200)]
tests: Enable tests in Travis

Build Quassel with -DBUILD_TESTING=ON and run the tests as part of
the CI build.

23 months agotests: Convert ExpressionMatchTests into a GTest-based test case
Manuel Nickschas [Mon, 24 Sep 2018 18:42:51 +0000 (20:42 +0200)]
tests: Convert ExpressionMatchTests into a GTest-based test case

As first contender for the newly introduced test framework, use
the recently added ExpressionMatchTests class. Convert to use
GTest, and move into the new home for Quassel unit tests (the
tests/<module>/ directory).

With this, "make test" (or "ninja test") actually does something
if Quassel is configured with -DBUILD_TESTING=ON.

23 months agotest: Add build system support and a main function for unit tests
Manuel Nickschas [Mon, 24 Sep 2018 18:36:21 +0000 (20:36 +0200)]
test: Add build system support and a main function for unit tests

Add a new CMake option BUILD_TESTING (defaults to OFF) that, if
enabled, will build unit tests and related requirements.

Add a new library Quassel::Test::Main that provides a main function
for test cases.

Add a new CMake macro quassel_add_test for making the adding of test
cases convenient by hiding most of the boilerplate.

Test cases should #include "testglobal.h", so they automatically have
access to GTest/GMock macros as well as the imported main function.

23 months agotest: Bundle GTest/GMock 1.8.1 sources and provide a find script
Manuel Nickschas [Mon, 24 Sep 2018 18:30:25 +0000 (20:30 +0200)]
test: Bundle GTest/GMock 1.8.1 sources and provide a find script

GTest/GMock is a unit testing framework that we want to use for
writing unit tests for Quassel in the future. Since Google
recommends building the test libraries with the same flags and
settings as the code under test, we should build them as part of
Quassel's build process rather than relying on system-provided

Because most distros don't seem to package the GTest/GMock sources,
bundle them with Quassel. The upstream sources are unmodified,
although the set of files shipped is trimmed down significantly
in order to not needlessly blow up the repo size.

Provide FindGTest.cmake, which builds the libraries from the
bundled sources.

23 months agomodernize: Require member function pointers for Settings::notify()
Manuel Nickschas [Wed, 19 Sep 2018 22:54:21 +0000 (00:54 +0200)]
modernize: Require member function pointers for Settings::notify()

Require member function pointers for Settings::notify() and
Settings::initAndNotify(). This brings us one step closer to being

23 months agomodernize: Remove old-style slot usage in NetworkModelController
Manuel Nickschas [Wed, 19 Sep 2018 19:05:08 +0000 (21:05 +0200)]
modernize: Remove old-style slot usage in NetworkModelController

Use member function pointers in NetworkModelController and related
classes, instead of old-style slots and invokeMethod().

23 months agomodernize: Don't use apparent connect-by-name slots in MainWin
Manuel Nickschas [Tue, 18 Sep 2018 21:48:08 +0000 (23:48 +0200)]
modernize: Don't use apparent connect-by-name slots in MainWin

Rename slots named "on_*" to follow our naming conventions, and avoid
association with the very old and very discouraged connect-by-name
feature in Qt (also known as "auto-connection slots"). MainWin doesn't
even use this feature, so we should not confuse casual readers.

23 months agomodernize: Migrate action-related things to PMF connects
Manuel Nickschas [Tue, 18 Sep 2018 21:37:02 +0000 (23:37 +0200)]
modernize: Migrate action-related things to PMF connects

In our quest to get rid of the deprecated use of slots, refactor
Action and ActionCollection to require pointer-to-member-function
connects. Ensure nobody accidentally still uses SLOT through a static

Add a convenience function to ActionCollection for adding lists of
actions. While we're at it, also rework ActionCollection's optional
KDE Frameworks support to simplify things.

Adapt the rest of the code accordingly.

23 months agouisupport: Provide helpers for dealing with widget changes
Manuel Nickschas [Mon, 17 Sep 2018 21:42:37 +0000 (23:42 +0200)]
uisupport: Provide helpers for dealing with widget changes

In many places, we want to connect to a widget's changed signal,
i.e. a signal that is emitted whenever the widget changes. This
requires a great deal of boilerplate especially in settingspages,
since the signal to listen to varies between widget types.

Provide helpers that automate most of this by matching the given
widget against a static list of supported widgets' changed signals,
and connecting automatically. A sprinkle of template magic makes
it very easy to support a bunch of different widget types in a generic

Make use of this feature to get rid of the remaining old-style
connects in SettingsPage. Also migrate a couple of specific
settingspages as proof-of-concept and API validation; others
can follow over time.

23 months agocommon: Provide helper for getting member function traits
Manuel Nickschas [Mon, 17 Sep 2018 21:39:37 +0000 (23:39 +0200)]
common: Provide helper for getting member function traits

Add a new header funchelpers.h that contains helpers for dealing
with member function traits. MemberFunction<Callable> provides
the class, return and argument types of the given Callable, as well
as a compatible std::function type.

23 months agomodernize: Replace most remaining old-style connects by PMF ones
Manuel Nickschas [Wed, 12 Sep 2018 17:45:13 +0000 (19:45 +0200)]
modernize: Replace most remaining old-style connects by PMF ones

Manually replace old-style connects (using the SIGNAL/SLOT macros)
by the much more efficient and typesafe pointer-to-member-function-
based ones.

This fixes the cases where clazy could not auto-migrate to the new
syntax for a variety of reasons. In most of the cases, we need to
remove overloads or explicitly select the desired one, because the
plain syntax cannot deal with overloads. Another issue is trying
to connect to signals in a baseclass that are only declared in a
derived class (which works with the old-style runtime connection
handling, but obviously no longer with the compile-time version).

Also do some selected cleanups in places.

23 months agocommon: Provide helper for resolving overloaded function pointers
Manuel Nickschas [Mon, 10 Sep 2018 20:12:44 +0000 (22:12 +0200)]
common: Provide helper for resolving overloaded function pointers

The pointer-to-member-function connect syntax cannot directly deal
with overloaded method signatures. Provide a helper to avoid ugly
static_cast incantations:

  #include "util.h"
  connect(this, selectOverload<int, QString>(&MyClass::mySignal), other, &Other::mySlot);

This helper can be used for both signals and slots.

23 months agoqtui: Fix initialization order after switching to PMF connects
Manuel Nickschas [Thu, 13 Sep 2018 21:35:29 +0000 (23:35 +0200)]
qtui: Fix initialization order after switching to PMF connects

Seems like switching to PMF connections has changed the order signals
are processed in, resulting in the UI being initialized after the
session manager asks for saving the UI state (for whatever reason).

Make this less fragile (and avoid a crash when using KDE) by
connecting to the session manager only after initializing the UI, and
replace the initUi() slot by a lambda while we're at it.

23 months agoclazy: Convert many old-style connects into function pointer based
Manuel Nickschas [Mon, 10 Sep 2018 16:38:20 +0000 (18:38 +0200)]
clazy: Convert many old-style connects into function pointer based

Since Qt5, signal/slot connections can be expressed using function
pointers rather than the SIGNAL/SLOT macros. This is a) much more
efficient, and b) provides a compile-time check for the sender
and receiver being compatible.

Let clazy auto-fix old-style connects where it can. However, a lot of
occurrences remain where we'll need manual intervention for one
reason or another.

23 months agomodernize: Use ranged-for loops in some obvious cases
Manuel Nickschas [Sun, 9 Sep 2018 22:11:38 +0000 (00:11 +0200)]
modernize: Use ranged-for loops in some obvious cases

Some old-style loops can be automatically converted by clang-tidy
to use ranged-for.

23 months agomodernize: Use 'while(true)' instead of 'while(1)'
Manuel Nickschas [Sun, 9 Sep 2018 22:04:49 +0000 (00:04 +0200)]
modernize: Use 'while(true)' instead of 'while(1)'

23 months agomodernize: Use std::make_unique
Manuel Nickschas [Sun, 9 Sep 2018 22:04:11 +0000 (00:04 +0200)]
modernize: Use std::make_unique

23 months agomodernize: Use C++ versions of system headers
Manuel Nickschas [Sun, 9 Sep 2018 22:02:03 +0000 (00:02 +0200)]
modernize: Use C++ versions of system headers

System headers ending on .h are deprecated; use the c* version

23 months agomodernize: Use raw string literals instead of escaped strings
Manuel Nickschas [Sun, 9 Sep 2018 21:37:56 +0000 (23:37 +0200)]
modernize: Use raw string literals instead of escaped strings

Replace escaped strings with raw string literals in places where
it makes sense, and doesn't confuse lupdate.

23 months agomodernize: Use braced-init list when returning types
Manuel Nickschas [Sun, 9 Sep 2018 21:20:09 +0000 (23:20 +0200)]
modernize: Use braced-init list when returning types

23 months agomodernize: Use auto where the type is clear from context
Manuel Nickschas [Sun, 9 Sep 2018 20:44:18 +0000 (22:44 +0200)]
modernize: Use auto where the type is clear from context

Apply clang-tidy's modernize-use-auto fix, which uses auto where
the type would otherwise be duplicated in the line (e.g. when casting
a type, or creating an instance with 'new').

23 months agomodernize: Use '= default' instead of empty ctor/dtor bodies
Manuel Nickschas [Thu, 6 Sep 2018 23:08:09 +0000 (01:08 +0200)]
modernize: Use '= default' instead of empty ctor/dtor bodies

Also remove lots of unnecessary, empty ctors and dtors.

23 months agomodernize: Prefer default member init over ctor init
Manuel Nickschas [Thu, 6 Sep 2018 20:43:39 +0000 (22:43 +0200)]
modernize: Prefer default member init over ctor init

Where appropriate, initialize class members in the header rather
than in the constructor.

23 months agomodernize: Pass arguments by value and move in constructors
Manuel Nickschas [Thu, 6 Sep 2018 19:01:22 +0000 (21:01 +0200)]
modernize: Pass arguments by value and move in constructors

If a method (or constructor) wants to store an argument in a local
variable or attribute, one should prefer passing it in by value
and moving it into the final location, rather than taking a
const reference and copying it over. In the best case, this saves
one copy, if the method is called with an rvalue.

This pattern is most frequent in constructors initializing class
members, so let clang-tidy fix this for argument types that have
move constructors.

23 months agomodernize: Use 'using' instead of 'typedef'
Manuel Nickschas [Thu, 6 Sep 2018 17:47:17 +0000 (19:47 +0200)]
modernize: Use 'using' instead of 'typedef'

23 months agomodernize: Use override instead of virtual
Manuel Nickschas [Wed, 5 Sep 2018 22:36:28 +0000 (00:36 +0200)]
modernize: Use override instead of virtual

Let clang-tidy fix all occurrences where override should be used
instead of virtual. Also, let it annotate member functions where
virtual was missing in the first place.

23 months agomodernize: Use nullptr
Manuel Nickschas [Wed, 5 Sep 2018 22:09:45 +0000 (00:09 +0200)]
modernize: Use nullptr

Let clang-tidy fix all occurrences where nullptr should be used
instead of 0.

23 months agoclang-tidy: Mark several settingspage methods as final
Manuel Nickschas [Tue, 4 Sep 2018 22:56:14 +0000 (00:56 +0200)]
clang-tidy: Mark several settingspage methods as final

To avoid warnings about calling virtual methods during construction,
mark affected methods as final. It's legitimate to call things like
load() from their ctors as long as nobody inherits from them.

23 months agoclang-tidy: Don't call virtual methods from CoreAccountModel's ctor
Manuel Nickschas [Tue, 4 Sep 2018 22:36:11 +0000 (00:36 +0200)]
clang-tidy: Don't call virtual methods from CoreAccountModel's ctor

23 months agocmake: Build shared libraries (DLLs) on Windows
Manuel Nickschas [Sun, 2 Sep 2018 21:29:43 +0000 (23:29 +0200)]
cmake: Build shared libraries (DLLs) on Windows

Since symbols are now properly marked for export, we can finally
enable the building of DLLs on Windows.

23 months agocmake: Make symbols hidden by default on GCC/Clang
Manuel Nickschas [Sun, 2 Sep 2018 21:26:24 +0000 (23:26 +0200)]
cmake: Make symbols hidden by default on GCC/Clang

With symbols now being explicitly marked as exported where needed,
there is no need to globally export all symbols anymore.
Tell CMake to set the appropriate compiler flags
(i.e. -fvisibility=hidden) for GCC and Clang so, they only export
requested symbols.

23 months agosrc: Mark symbols to be exported where needed
Manuel Nickschas [Sun, 2 Sep 2018 21:34:36 +0000 (23:34 +0200)]
src: Mark symbols to be exported where needed

Generate export headers for the Quassel modules, and mark all
relevant classes and function to be exported so that shared libraries
can be linked against without globally exporting all symbols.
This is a hard requirement for Windows DLLs, and more efficient on
other platforms, too.

For now, this was done incrementally until everything linked properly.
In the future, we may consider explicitly defining the public
interfaces for each module, and trying to minimize the linker
interface e.g. by PIMPLing.

23 months agocmake: Support generation of export headers
Manuel Nickschas [Sun, 2 Sep 2018 21:06:18 +0000 (23:06 +0200)]
cmake: Support generation of export headers

For using shared libraries without globally exporting all symbols,
one has to explicitly mark classes and free functions to be exported.
This is more efficient on platforms like Linux (enabling the use
of -fvisibility=hidden on GCC/Clang), and a hard requirement for
using DLLs on Windows (which don't support global export at all).

Extend the quassel_add_module() macro with an optional EXPORT
argument, which, if provided, uses CMake's built-in support for
generating an export header that provides macros for exporting
symbols. The same macro will also import the marked symbols when
building against a library.

While we're at it, also fix the install rule to use the proper
install locations for RUNTIME/LIBRARY/ARCHIVE target types.

23 months agosigproxy: Don't expose the thread_local '_current' attribute
Manuel Nickschas [Sun, 2 Sep 2018 21:23:06 +0000 (23:23 +0200)]
sigproxy: Don't expose the thread_local '_current' attribute

Windows does not allow exporting thread_local attributes in the
DLL interface. Since it's not good practice anyway to expose such
an implementation detail in the public header, make the accessor
non-inline and move the attribute into a private anonymous namespace,
removing it from the public interface.

23 months agouisupport: Let ClickableList inherit from std::vector instead of QList
Manuel Nickschas [Sun, 2 Sep 2018 21:18:40 +0000 (23:18 +0200)]
uisupport: Let ClickableList inherit from std::vector instead of QList

Apparently, a class inheriting from a QList specialization cannot
be properly exported, while this works fine when inheriting from
std::vector instead. Since we now prefer std containers over Qt's
anyway, changing the baseclass is a Good Thing™ either way, so
just do it.

23 months agoqtui: Add debug dialog for showing the resource file tree
Manuel Nickschas [Wed, 29 Aug 2018 18:38:31 +0000 (20:38 +0200)]
qtui: Add debug dialog for showing the resource file tree

Add a dialog in the debug menu that shows the compiled-in
resource files. This is useful for checking that resource generation
and loading works properly.

23 months agocommon: Simplify SyncableObject macros and usage
Manuel Nickschas [Thu, 23 Aug 2018 21:40:36 +0000 (23:40 +0200)]
common: Simplify SyncableObject macros and usage

Since the C++11 standard defines "__func__", and modern versions
of MSVC support this, we can remove the workaround for MSVC from
the SyncableObject macros. It is no longer necessary to derive
the function name from MSVC's __FUNCTION__ (which contains the
enclosing class name), and thus the _classNameOffset__ function
declared by the SYNCABLE_OBJECT macro is no longer needed.

Repurpose the macro to define the syncMetaObject() member function
instead, and remove the no-longer needed INIT_SYNCABLE_OBJECT
The syncMetaObject() function is used by the signal proxy for
accessing the metaObject() of the base class in case there are
client- or core-specific specializations of a syncable object;
i.e. if you have Foo directly inheriting from SyncableObject,
and ClientFoo derived from Foo, the function must only be
declared in Foo, otherwise syncing won't work.

Thus, the SYNCABLE_OBJECT macro declares the function as final,
so it can't be accidentally overridden.

While we're at it, replace include guards with #pragma once in
files we touched.

23 months agoqa: Remove lots of superfluous semicolons
Manuel Nickschas [Wed, 22 Aug 2018 19:15:11 +0000 (21:15 +0200)]
qa: Remove lots of superfluous semicolons

Since we have now enabled -Wpedantic, the compiler warns us about
superfluous semicolons, of which we apparently have a lot.
Remove them.

23 months agocmake: Reorder slightly for consistency
Manuel Nickschas [Wed, 29 Aug 2018 16:17:26 +0000 (18:17 +0200)]
cmake: Reorder slightly for consistency

Other modules link the main dependencies before caring about
options, so do the same for the core module.

23 months agocmake: Link resources statically, and init locally
Manuel Nickschas [Wed, 29 Aug 2018 16:15:47 +0000 (18:15 +0200)]
cmake: Link resources statically, and init locally

Link resource libraries statically in order to avoid problems with
symbol exporting. Move resource initialization from main() into the
respective libraries.

23 months agocmake: Add support for static libs to quassel_add_module
Manuel Nickschas [Wed, 29 Aug 2018 16:10:56 +0000 (18:10 +0200)]
cmake: Add support for static libs to quassel_add_module

We'll need this for building resource libraries, which we can't
easily export symbols from (and which also are not used more than

23 months agocmake: Build shared libraries
Manuel Nickschas [Wed, 22 Aug 2018 21:47:22 +0000 (23:47 +0200)]
cmake: Build shared libraries

The days of static builds are finally over. Build dynamic libraries
for all Quassel modules.

Let CMake handle the RPATH in a way that doesn't cause inconvenience;
always set an RPATH in the build tree so the correct libraries
are loaded, and also set an RPATH for installed binaries unless
they go into a system location.

Also define output directories for all build artifacts.

23 months agocmake: Modernize compile settings; require C++14
Manuel Nickschas [Wed, 22 Aug 2018 18:15:50 +0000 (20:15 +0200)]
cmake: Modernize compile settings; require C++14

Clean up QuasselCompileSettings.cmake, treat GNU and Clang the same.
Use add_compile_options() instead of CMAKE_CXX_FLAGS. Curate the list
of compiler flags, and add sensible linker flags, too.

Check explicitly for required compiler features using CMake's
target_compile_features(), rather than hard-coding compiler versions.
The set of required features basically implies that we now require
a C++14 compiler (even though the new stuff isn't used in the code

23 months agocmake: Build Windows icon resource again
Manuel Nickschas [Tue, 21 Aug 2018 22:29:17 +0000 (00:29 +0200)]
cmake: Build Windows icon resource again

Building the Windows resource got lost while refactoring the build
system, so bring it back.

23 months agocmake: Modernize translation generation
Manuel Nickschas [Tue, 21 Aug 2018 21:31:45 +0000 (23:31 +0200)]
cmake: Modernize translation generation

Refactor and modernize the CMake support for translation generation.
Properly use targets, custom commands and dependencies to ensure that
files are only regenerated when needed, and avoid useless rebuilds.

Avoid individual invocations of lupdate and lrelease, which both
support processing multiple files at once.

Make use of the newly added quassel_add_resource function instead of
building the .qrc file explicitly.

Fix LINGUAS support, which was previously not working as intended.