diff --git a/src/ActionManager.cpp b/src/ActionManager.cpp
index ce03d43..425f968 100644
--- a/src/ActionManager.cpp
+++ b/src/ActionManager.cpp
@@ -52,7 +52,7 @@ QAction * ActionManager::action( const QString & actionName )
 	}
     }
 
-    logError() << "No action with name " << actionName << " found" << endl;
+    logError() << "No action with name " << actionName << " found" << ENDL;
     return 0;
 }
 
diff --git a/src/AdaptiveTimer.cpp b/src/AdaptiveTimer.cpp
index 1395c18..d20645c 100644
--- a/src/AdaptiveTimer.cpp
+++ b/src/AdaptiveTimer.cpp
@@ -105,7 +105,7 @@ void AdaptiveTimer::increaseDelay()
 #if VERBOSE_DELAY
         logDebug() << "Increasing delay to stage " << _delayStage
                    << ": " << delay << " millisec"
-                   << endl;
+                   << ENDL;
 #endif
 
         _deliveryTimer.setInterval( delay );
@@ -124,7 +124,7 @@ void AdaptiveTimer::decreaseDelay()
 #if VERBOSE_DELAY
         logDebug() << "Decreasing delay to stage " << _delayStage
                    << ": " << delay << " millisec"
-                   << endl;
+                   << ENDL;
 #endif
 
         _deliveryTimer.setInterval( delay );
@@ -147,7 +147,7 @@ void AdaptiveTimer::heatUp()
 #if VERBOSE_STAGES
         logDebug() << "Heating up to cooldown stage " << _coolDownStage
                    << ": " << coolDownInterval << " millisec"
-                   << endl;
+                   << ENDL;
 #endif
 
         _coolDownTimer.setInterval( coolDownInterval );
@@ -171,7 +171,7 @@ void AdaptiveTimer::coolDown()
 #if VERBOSE_STAGES
         logDebug() << "Cooling down to stage " << _coolDownStage
                    << ": " << coolDownInterval << " millisec"
-                   << endl;
+                   << ENDL;
 #endif
 
         _coolDownTimer.setInterval( coolDownInterval );
diff --git a/src/BookmarksManager.cpp b/src/BookmarksManager.cpp
index 2ee4532..b4ac350 100644
--- a/src/BookmarksManager.cpp
+++ b/src/BookmarksManager.cpp
@@ -49,7 +49,7 @@ void BookmarksManager::add( const QString & bookmark, bool update )
     if ( _bookmarks.contains( bookmark, Qt::CaseSensitive ) )
         return;
 
-    logInfo() << "Adding bookmark \"" << bookmark << "\"" << endl;
+    logInfo() << "Adding bookmark \"" << bookmark << "\"" << ENDL;
 
     _bookmarks << bookmark;
     _dirty = true;
@@ -67,7 +67,7 @@ void BookmarksManager::remove( const QString & bookmark, bool update )
     if ( ! _bookmarks.contains( bookmark, Qt::CaseSensitive ) )
         return;
 
-    logInfo() << "Removing bookmark \"" << bookmark << "\"" << endl;
+    logInfo() << "Removing bookmark \"" << bookmark << "\"" << ENDL;
 
     _bookmarks.removeAll( bookmark );
     _dirty = true;
@@ -81,7 +81,7 @@ void BookmarksManager::rebuildBookmarksMenu()
 {
     if ( ! _bookmarksMenu )
     {
-        logError() << "NULL _bookmarksMenu" << endl;
+        logError() << "NULL _bookmarksMenu" << ENDL;
         return;
     }
 
@@ -162,7 +162,7 @@ void BookmarksManager::navigateToBookmark()
 
         if ( ! bookmark.isEmpty() )
         {
-            logDebug() << bookmark << endl;
+            logDebug() << bookmark << ENDL;
             emit navigateToUrl( expandedPath( bookmark ) );
         }
     }
@@ -191,14 +191,14 @@ void BookmarksManager::read()
     if ( ! bookmarksFile.exists() )
     {
         logInfo() << "Bookmarks file " << BookmarksFile
-                  << " does not exist" << endl;
+                  << " does not exist" << ENDL;
 
         return;
     }
 
     if ( ! bookmarksFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
     {
-	logError() << "Can't open " << bookmarksFileName() << endl;
+	logError() << "Can't open " << bookmarksFileName() << ENDL;
 	return;
     }
 
@@ -214,11 +214,11 @@ void BookmarksManager::read()
     }
 
     sort();
-    logInfo() << _bookmarks.size() << " bookmarks read from " << BookmarksFile << endl;
+    logInfo() << _bookmarks.size() << " bookmarks read from " << BookmarksFile << ENDL;
 
 #if 0
     foreach ( const QString & bookmark, _bookmarks )
-        logDebug() << "Read bookmark \"" << bookmark << "\"" << endl;
+        logDebug() << "Read bookmark \"" << bookmark << "\"" << ENDL;
 #endif
 }
 
@@ -227,7 +227,7 @@ void BookmarksManager::write()
 {
     if ( ! _dirty )
     {
-        logDebug() << "No changes to write to " << BookmarksFile << endl;
+        logDebug() << "No changes to write to " << BookmarksFile << ENDL;
         return;
     }
 
@@ -235,7 +235,7 @@ void BookmarksManager::write()
 
     if ( ! bookmarksFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
     {
-	logError() << "Can't open " << bookmarksFileName() << endl;
+	logError() << "Can't open " << bookmarksFileName() << ENDL;
 	return;
     }
 
@@ -246,7 +246,7 @@ void BookmarksManager::write()
         out << shortenedPath( bookmark ) << "\n";
     }
 
-    logInfo() << _bookmarks.size() << " bookmarks written to " << BookmarksFile << endl;
+    logInfo() << _bookmarks.size() << " bookmarks written to " << BookmarksFile << ENDL;
     _dirty = false;
 }
 
diff --git a/src/BreadcrumbNavigator.cpp b/src/BreadcrumbNavigator.cpp
index 0f277cd..ebb1a97 100644
--- a/src/BreadcrumbNavigator.cpp
+++ b/src/BreadcrumbNavigator.cpp
@@ -7,8 +7,6 @@
  */
 
 
-#include "Qt4Compat.h" // qHtmlEscape()
-
 #include "BreadcrumbNavigator.h"
 #include "DirInfo.h"
 #include "Logger.h"
@@ -152,7 +150,7 @@ void BreadcrumbNavigator::shortenBreadcrumbs()
                    << " from " << crumb.pathComponent.length()
                    << " to " <<  crumb.displayName.length()
                    << ": " << crumb.pathComponent
-                   << endl;
+                   << ENDL;
 #endif
     }
 }
@@ -221,7 +219,7 @@ void BreadcrumbNavigator::splitBasePath( const QString & path,
 
     if ( path != "/" && path.contains( "/" ) )
     {
-        QStringList components = path.split( "/", QString::SkipEmptyParts );
+        QStringList components = path.split( "/", SKIPEMPTYPARTS );
 
         if ( ! components.empty() )
             name_ret = components.takeLast();
@@ -237,7 +235,7 @@ void BreadcrumbNavigator::splitBasePath( const QString & path,
 
 void BreadcrumbNavigator::logPathClicked( const QString & path )
 {
-    logInfo() << "Clicked path " << path << endl;
+    logInfo() << "Clicked path " << path << ENDL;
 }
 
 
@@ -253,7 +251,7 @@ void BreadcrumbNavigator::logBreadcrumbs() const
                    << " pathComponent: \"" << crumb.pathComponent
                    << "\" displayName: \"" << crumb.displayName
                    << "\" url: " << crumb.url << "\""
-                   << endl;
+                   << ENDL;
     }
 
     logNewline();
diff --git a/src/Cleanup.cpp b/src/Cleanup.cpp
index cbda2dc..a48e761 100644
--- a/src/Cleanup.cpp
+++ b/src/Cleanup.cpp
@@ -101,7 +101,7 @@ void Cleanup::executeRecursive( FileInfo *item, OutputWindow * outputWindow )
 
                 logError() << this << ": Recursive operation is not supported "
                            << "for \"Assume Deleted\" refresh policy."
-                           << endl;
+                           << ENDL;
             }
             else
             {
@@ -142,7 +142,7 @@ const QString Cleanup::itemDir( const FileInfo *item ) const
 
     if ( ! item->isDir() && ! item->isPseudoDir() )
     {
-	dir.replace( QRegExp ( "/[^/]*$" ), "" );
+        dir = qregexp_replaceIn( QRegExp( "/[^/]*$" ), dir, "" );
     }
 
     return dir;
@@ -160,7 +160,7 @@ QString Cleanup::cleanTitle() const
 
     // Get rid of any "&" characters in the text that denote keyboard
     // shortcuts in menus.
-    title.replace( QRegExp( "&" ), "" );
+    title = qregexp_replaceIn( QRegExp( "&" ), title, "");
 
     return title;
 }
@@ -225,7 +225,7 @@ QString Cleanup::chooseShell( OutputWindow * outputWindow ) const
 
     if ( ! shell.isEmpty() )
     {
-	logDebug() << "Using custom shell " << shell << endl;
+	logDebug() << "Using custom shell " << shell << ENDL;
 
 	if ( ! isExecutable( shell ) )
 	{
@@ -240,7 +240,7 @@ QString Cleanup::chooseShell( OutputWindow * outputWindow ) const
     if ( shell.isEmpty() )
     {
 	shell = defaultShell();
-	logDebug() << "No custom shell configured - using " << shell << endl;
+	logDebug() << "No custom shell configured - using " << shell << ENDL;
     }
 
     if ( ! errMsg.isEmpty() )
@@ -263,7 +263,7 @@ void Cleanup::runCommand( const FileInfo * item,
     {
 	outputWindow->show(); // Regardless of user settings
 	outputWindow->addStderr( tr( "No usable shell - aborting cleanup action" ) );
-	logError() << "ERROR: No usable shell" << endl;
+	logError() << "ERROR: No usable shell" << ENDL;
 	return;
     }
 
@@ -332,7 +332,7 @@ QString Cleanup::loginShell()
 
 	if ( ! isExecutable( shell ) )
 	{
-	    logError() << "ERROR: Shell \"" << shell << "\" is not executable" << endl;
+	    logError() << "ERROR: Shell \"" << shell << "\" is not executable" << ENDL;
 	    shell = "";
 	}
     }
@@ -358,16 +358,16 @@ const QStringList & Cleanup::defaultShells()
 		 shells << shell;
 	    else if ( ! shell.isEmpty() )
 	    {
-		logWarning() << "Shell " << shell << " is not executable" << endl;
+		logWarning() << "Shell " << shell << " is not executable" << ENDL;
 	    }
 	}
 
 	if ( ! shells.isEmpty() )
-	    logDebug() << "Default shell: " << shells.first() << endl;
+	    logDebug() << "Default shell: " << shells.first() << ENDL;
     }
 
     if ( shells.isEmpty() )
-	logError() << "ERROR: No usable shell" << endl;
+	logError() << "ERROR: No usable shell" << ENDL;
 
     return shells;
 }
@@ -392,17 +392,17 @@ const QMap<QString, QString> & Cleanup::desktopSpecificApps()
 	else
 	{
 	    logDebug() << "Overriding $XDG_CURRENT_DESKTOP with $QDIRSTAT_DESKTOP (\""
-		       << desktop << "\")" << endl;
+		       << desktop << "\")" << ENDL;
 	}
 
 	if ( desktop.isEmpty() )
 	{
-	    logWarning() << "$XDG_CURRENT_DESKTOP is not set - using fallback apps" << endl;
+	    logWarning() << "$XDG_CURRENT_DESKTOP is not set - using fallback apps" << ENDL;
 	    apps = fallbackApps();
 	}
 	else
 	{
-	    logInfo() << "Detected desktop \"" << desktop << "\"" << endl;
+	    logInfo() << "Detected desktop \"" << desktop << "\"" << ENDL;
 	    desktop = desktop.toLower();
 
 	    if ( desktop == "kde" )
@@ -450,7 +450,7 @@ const QMap<QString, QString> & Cleanup::desktopSpecificApps()
 
 	    if ( apps.isEmpty() )
 	    {
-		logWarning() << "No mapping available for this desktop - using fallback apps" << endl;
+		logWarning() << "No mapping available for this desktop - using fallback apps" << ENDL;
 		apps = fallbackApps();
 	    }
 	}
@@ -459,7 +459,7 @@ const QMap<QString, QString> & Cleanup::desktopSpecificApps()
 	      it != apps.constEnd();
 	      ++it )
 	{
-	    logInfo() << it.key() << " => \"" << it.value() << "\"" << endl;
+	    logInfo() << it.key() << " => \"" << it.value() << "\"" << ENDL;
 	}
     }
 
diff --git a/src/CleanupCollection.cpp b/src/CleanupCollection.cpp
index 692ee01..505bb4d 100644
--- a/src/CleanupCollection.cpp
+++ b/src/CleanupCollection.cpp
@@ -76,7 +76,7 @@ void CleanupCollection::remove( Cleanup * cleanup )
 
     if ( index == -1 )
     {
-	logError() << "No such cleanup: " << cleanup << endl;
+	logError() << "No such cleanup: " << cleanup << ENDL;
 	return;
     }
 
@@ -102,7 +102,7 @@ int CleanupCollection::indexOf( Cleanup * cleanup ) const
     int index = _cleanupList.indexOf( cleanup );
 
     if ( index == -1 )
-	logError() << "Cleanup " << cleanup << " is not in this collection" << endl;
+	logError() << "Cleanup " << cleanup << " is not in this collection" << ENDL;
 
     return index;
 }
@@ -176,7 +176,7 @@ void CleanupCollection::updateActions()
 
 void CleanupCollection::updateMenus()
 {
-    _menus.removeAll( 0 ); // Remove QPointers that have become invalid
+    _menus.removeAll( nullptr ); // Remove QPointers that have become invalid
 
     foreach ( QMenu * menu, _menus )
     {
@@ -201,7 +201,7 @@ void CleanupCollection::updateMenus()
 
 void CleanupCollection::updateToolBars()
 {
-    _toolBars.removeAll( 0 ); // Remove QPointers that have become invalid
+    _toolBars.removeAll( nullptr ); // Remove QPointers that have become invalid
 
     foreach ( QToolBar * toolBar, _toolBars )
     {
@@ -231,7 +231,7 @@ void CleanupCollection::execute()
     if ( ! cleanup )
     {
 	logError() << "Wrong sender type: "
-		   << sender()->metaObject()->className() << endl;
+		   << sender()->metaObject()->className() << ENDL;
 	return;
     }
 
@@ -239,13 +239,13 @@ void CleanupCollection::execute()
 
     if ( selection.isEmpty() )
     {
-	logWarning() << "Nothing selected" << endl;
+	logWarning() << "Nothing selected" << ENDL;
 	return;
     }
 
     if ( cleanup->askForConfirmation() && ! confirmation( cleanup, selection ) )
     {
-	logDebug() << "User declined confirmation" << endl;
+	logDebug() << "User declined confirmation" << ENDL;
 	return;
     }
 
@@ -306,7 +306,7 @@ void CleanupCollection::execute()
 	else
 	{
 	    logWarning() << "Cleanup " << cleanup
-			 << " does not work for " << item << endl;
+			 << " does not work for " << item << ENDL;
 	}
     }
 
@@ -322,7 +322,7 @@ void CleanupCollection::execute()
             DirTree * tree = item->tree();
 
             if ( tree->isBusy() )
-                logWarning() << "Ignoring AssumeDeleted: DirTree is being read" << endl;
+                logWarning() << "Ignoring AssumeDeleted: DirTree is being read" << ENDL;
             else
                 tree->deleteSubtree( item );
         }
@@ -569,8 +569,8 @@ void CleanupCollection::readSettings()
 
                         hotkey = "Ctrl+G";
                         logError() << "The Ctrl+F hotkey for '" << title
-                                   << "' is now taken by 'Edit' -> 'Find...'." << endl;
-                        logError() << "Changing to " << hotkey << "." << endl;
+                                   << "' is now taken by 'Edit' -> 'Find...'." << ENDL;
+                        logError() << "Changing to " << hotkey << "." << ENDL;
                     }
 
 		    cleanup->setShortcut( hotkey );
@@ -581,7 +581,7 @@ void CleanupCollection::readSettings()
 	    }
 	    else
 	    {
-		logError() << "Need at least Command and Title for a cleanup" << endl;
+		logError() << "Need at least Command and Title for a cleanup" << ENDL;
 	    }
 
 	    settings.endGroup(); // [Cleanup_01], [Cleanup_02], ...
diff --git a/src/DataColumns.cpp b/src/DataColumns.cpp
index 35ebf74..ded56c4 100644
--- a/src/DataColumns.cpp
+++ b/src/DataColumns.cpp
@@ -111,7 +111,7 @@ DataColumn DataColumns::mappedCol( DataColumn viewCol ) const
 {
     if ( viewCol < 0 || viewCol >= colCount() )
     {
-	logError() << "Invalid view column no.: " << (int) viewCol << endl;
+	logError() << "Invalid view column no.: " << (int) viewCol << ENDL;
 	return UndefinedCol;
     }
 
@@ -152,7 +152,7 @@ QString DataColumns::toString( DataColumn col )
 	    // can catch unhandled enum values
     }
 
-    logError() << "Unknown DataColumn " << (int) col << endl;
+    logError() << "Unknown DataColumn " << (int) col << ENDL;
     return QString( "<Unknown DataColumn %1>" ).arg( (int) col );
 }
 
@@ -170,7 +170,7 @@ DataColumn DataColumns::fromString( const QString & str )
 	    return col;
     }
 
-    logError() << "Undefined DataColumn \"" << str << "\"" << endl;
+    logError() << "Undefined DataColumn \"" << str << "\"" << ENDL;
     return UndefinedCol;
 }
 
@@ -208,9 +208,9 @@ void DataColumns::ensureNameColFirst( DataColumnList & colList )
 {
     if ( colList.first() != NameCol )
     {
-	logError() << "NameCol is required to be first!" << endl;
+	logError() << "NameCol is required to be first!" << ENDL;
 	colList.removeAll( NameCol );
 	colList.prepend( NameCol );
-	logError() << "Fixed column list: " << toStringList( colList ) << endl;
+	logError() << "Fixed column list: " << toStringList( colList ) << ENDL;
     }
 }
diff --git a/src/DebugHelpers.cpp b/src/DebugHelpers.cpp
index a02c57c..2210296 100644
--- a/src/DebugHelpers.cpp
+++ b/src/DebugHelpers.cpp
@@ -31,7 +31,7 @@ namespace Debug
 	{
 	    logDebug() << "Children of " << dir
 		       << "  (" << (void *) dir << ")"
-		       << endl;
+		       << ENDL;
 	    int count = 0;
 
 	    while ( *it )
@@ -39,13 +39,13 @@ namespace Debug
 		logDebug() << "	   #" << count++ << ": "
 			   << (void *) *it
 			   << "	 " << *it
-			   << endl;
+			   << ENDL;
 		++it;
 	    }
 	}
 	else
 	{
-	    logDebug() << "    No children in " << dir << endl;
+	    logDebug() << "    No children in " << dir << ENDL;
 	}
     }
 
@@ -53,24 +53,24 @@ namespace Debug
     void dumpChildrenList( FileInfo	      * dir,
 			   const FileInfoList & children )
     {
-	logDebug() << "Children of " << dir << endl;
+	logDebug() << "Children of " << dir << ENDL;
 
 	for ( int i=0; i < children.size(); ++i )
 	{
-	    logDebug() << "    #" << i << ": " << children.at(i) << endl;
+	    logDebug() << "    #" << i << ": " << children.at(i) << ENDL;
 	}
     }
 
 
     void dumpChildrenBySize( FileInfo * dir )
     {
-	logDebug() << "Direct children of " << dir << " by size:" << endl;
+	logDebug() << "Direct children of " << dir << " by size:" << ENDL;
 
 	QDirStat::FileInfoSortedBySizeIterator it( dir );
 
 	while ( *it )
 	{
-	    logDebug() << "  " << formatSize( (*it)->totalSize() ) << "	 " << *it << endl;
+	    logDebug() << "  " << formatSize( (*it)->totalSize() ) << "	 " << *it << ENDL;
 	    ++it;
 	}
     }
@@ -86,13 +86,13 @@ namespace Debug
 	if ( data.isValid() )
 	{
 	    if ( rowCount > 0 )
-		logDebug() << indent << data.toString() << ": " << rowCount << " rows" << endl;
+		logDebug() << indent << data.toString() << ": " << rowCount << " rows" << ENDL;
 	    else
-		logDebug() << indent << data.toString() << endl;
+		logDebug() << indent << data.toString() << ENDL;
 	}
 	else
 	{
-	    logDebug() << "<No data> " << rowCount << " rows" << endl;
+	    logDebug() << "<No data> " << rowCount << " rows" << ENDL;
 	}
 
 	for ( int row=0; row < rowCount; row++ )
@@ -125,13 +125,13 @@ namespace Debug
     void dumpExcludeRules()
     {
 	if ( ExcludeRules::instance()->isEmpty() )
-	    logDebug() << "No exclude rules defined" << endl;
+	    logDebug() << "No exclude rules defined" << ENDL;
 
 	for ( ExcludeRuleListIterator it = ExcludeRules::instance()->begin();
 	      it != ExcludeRules::instance()->end();
 	      ++it )
 	{
-	    logDebug() << *it << endl;
+	    logDebug() << *it << ENDL;
 	}
     }
 
diff --git a/src/DirInfo.cpp b/src/DirInfo.cpp
index 6c6dae9..1978806 100644
--- a/src/DirInfo.cpp
+++ b/src/DirInfo.cpp
@@ -697,7 +697,7 @@ void DirInfo::unlinkChild( FileInfo * deletedChild )
     if ( deletedChild->parent() != this )
     {
 	logError() << deletedChild << " is not a child of " << this
-		   << " - cannot unlink from children list!" << endl;
+		   << " - cannot unlink from children list!" << ENDL;
 	return;
     }
 
@@ -727,7 +727,7 @@ void DirInfo::unlinkChild( FileInfo * deletedChild )
     }
 
     logError() << "Couldn't unlink " << deletedChild << " from "
-	       << this << " children list" << endl;
+	       << this << " children list" << ENDL;
 }
 
 
@@ -1208,7 +1208,7 @@ void DirInfo::findDominantChildren()
     logDebug() << this
                << "  median: "    << formatPercent( medianPercent )
                << "  threshold: " << formatPercent( FileSize( dominanceThreshold ) )
-               << endl;
+               << ENDL;
 #endif
 
 
diff --git a/src/DirReadJob.cpp b/src/DirReadJob.cpp
index 37302dd..810dc34 100644
--- a/src/DirReadJob.cpp
+++ b/src/DirReadJob.cpp
@@ -88,7 +88,7 @@ void DirReadJob::finished()
     if ( _queue )
 	_queue->jobFinishedNotify( this );
     else
-	logError() << "No job queue for " << _dir << endl;
+	logError() << "No job queue for " << _dir << ENDL;
 }
 
 
@@ -130,11 +130,11 @@ bool DirReadJob::crossingFilesystems( DirInfo * parent, DirInfo * child )
     {
         logInfo() << "Filesystem boundary at mount point " << child
                   << " on device " << ( childDevice.isEmpty() ? "<unknown>" : childDevice )
-                  << endl;
+                  << ENDL;
     }
     else
     {
-        logInfo() << child << " is still on the same device " << childDevice << endl;
+        logInfo() << child << " is still on the same device " << childDevice << ENDL;
     }
 
     return crossing;
@@ -170,7 +170,7 @@ bool DirReadJob::shouldCrossIntoFilesystem( const DirInfo * dir ) const
 
     if ( ! mountPoint )
     {
-        logError() << "Can't find mount point for " << dir->url() << endl;
+        logError() << "Can't find mount point for " << dir->url() << ENDL;
 
         return false;
     }
@@ -181,7 +181,7 @@ bool DirReadJob::shouldCrossIntoFilesystem( const DirInfo * dir ) const
 	! mountPoint->isNetworkMount();		//  NFS or CIFS (Samba)
 
     logDebug() << ( doCross ? "Reading" : "Not reading" )
-	       << " mounted filesystem " << mountPoint->path() << endl;
+	       << " mounted filesystem " << mountPoint->path() << ENDL;
 
     return doCross;
 }
@@ -225,7 +225,7 @@ void LocalDirReadJob::startReading()
     if ( access( _dirName.toUtf8(), X_OK | R_OK ) != 0 )
     {
 	ok = false;
-	logWarning() << "No permission to read directory " << _dirName << endl;
+	logWarning() << "No permission to read directory " << _dirName << ENDL;
 	finishReading( _dir, DirPermissionDenied );
     }
 
@@ -235,7 +235,7 @@ void LocalDirReadJob::startReading()
 
 	if ( ! diskDir )
 	{
-	    logWarning() << "opendir(" << _dirName << ") failed" << endl;
+	    logWarning() << "opendir(" << _dirName << ") failed" << ENDL;
 	    ok = false;
 	    // opendir() doesn't set 'errno' according to POSIX	 :-(
 	    finishReading( _dir, DirError );
@@ -291,7 +291,7 @@ void LocalDirReadJob::startReading()
 		{
 		    if ( entryName == defaultCacheName )	// .qdirstat.cache.gz found?
 		    {
-			logDebug() << "Found cache file " << defaultCacheName << endl;
+			logDebug() << "Found cache file " << defaultCacheName << ENDL;
 
 			// Try to read the cache file. If that was successful and the toplevel
 			// path in that cache file matches the path of the directory we are
@@ -318,7 +318,7 @@ void LocalDirReadJob::startReading()
                                          << _dir->url() << "/" << entryName
                                          << "\" links: " << statInfo.st_nlink
                                          << " -> resetting to 1"
-                                         << endl;
+                                         << ENDL;
                             _warnedAboutNtfsHardLinks = true;
                         }
 
@@ -463,14 +463,14 @@ bool LocalDirReadJob::readCacheFile( const QString & cacheFileName )
 
     if ( firstDirInCache == _dirName )	 // Does this cache file match this directory?
     {
-	logDebug() << "Using cache file " << cacheFullName << " for " << _dirName << endl;
+	logDebug() << "Using cache file " << cacheFullName << " for " << _dirName << ENDL;
 
 	DirTree * tree = _tree;	 // Copy data members to local variables:
 	DirInfo * dir  = _dir;	 // This object might be deleted soon by killAll()
 
 	if ( _tree->isToplevel( _dir ) )
 	{
-	    logDebug() << "Clearing complete tree" << endl;
+	    logDebug() << "Clearing complete tree" << ENDL;
 
 	    _tree->clearAndReadCache( cacheFullName );
 
@@ -496,7 +496,7 @@ bool LocalDirReadJob::readCacheFile( const QString & cacheFileName )
 	    _queue->killAll( _dir, cacheReadJob );	// Will delete this job as well!
 	    // All data members of this object are invalid from here on!
 
-	    logDebug() << "Deleting subtree " << dir << endl;
+	    logDebug() << "Deleting subtree " << dir << ENDL;
 	    tree->deleteSubtree( dir );
 	}
 
@@ -507,7 +507,7 @@ bool LocalDirReadJob::readCacheFile( const QString & cacheFileName )
 	logWarning() << "NOT using cache file " << cacheFullName
 		     << " with dir " << firstDirInCache
 		     << " for " << _dirName
-		     << endl;
+		     << ENDL;
 
         cacheReadJob->reader()->setAborted();
 	delete cacheReadJob;
@@ -519,7 +519,7 @@ bool LocalDirReadJob::readCacheFile( const QString & cacheFileName )
 
 void LocalDirReadJob::excludeDirLate()
 {
-    logDebug() << "Excluding dir " << _dir << endl;
+    logDebug() << "Excluding dir " << _dir << ENDL;
 
     // Kill all queued jobs for this dir except this one
     _queue->killAll( _dir, this );
@@ -532,7 +532,7 @@ void LocalDirReadJob::excludeDirLate()
 void LocalDirReadJob::handleLstatError( const QString & entryName )
 {
     logWarning() << "lstat(" << fullName( entryName ) << ") failed: "
-		 << formatErrno() << endl;
+		 << formatErrno() << ENDL;
 
     /*
      * Not much we can do when lstat() didn't work; let's at
@@ -574,7 +574,7 @@ FileInfo * LocalDirReadJob::stat( const QString & url,
 
 	if ( parent && parent != tree->root() )
 	{
-	    QStringList components = url.split( "/", QString::SkipEmptyParts );
+	    QStringList components = url.split( "/", SKIPEMPTYPARTS );
 	    name = components.last();
 	}
 
@@ -591,7 +591,7 @@ FileInfo * LocalDirReadJob::stat( const QString & url,
 		 ! parent->isPkgInfo() &&
 		 dir->device() != parent->device() )
 	    {
-		logDebug() << dir << " is a mount point" << endl;
+		logDebug() << dir << " is a mount point" << ENDL;
 		dir->setMountPoint();
 	    }
 
@@ -803,7 +803,7 @@ void DirReadJobQueue::killAll( DirInfo * subtree, DirReadJob * exceptJob )
 
 	if ( exceptJob && job == exceptJob )
 	{
-	    logDebug() << "NOT killing " << job << endl;
+	    logDebug() << "NOT killing " << job << ENDL;
 	    continue;
 	}
 
@@ -824,7 +824,7 @@ void DirReadJobQueue::killAll( DirInfo * subtree, DirReadJob * exceptJob )
 
 	if ( exceptJob && job == exceptJob )
 	{
-	    logDebug() << "NOT killing " << job << endl;
+	    logDebug() << "NOT killing " << job << ENDL;
 	    continue;
 	}
 
@@ -837,7 +837,7 @@ void DirReadJobQueue::killAll( DirInfo * subtree, DirReadJob * exceptJob )
 	}
     }
 
-    logDebug() << "Killed " << count << " read jobs for " << subtree << endl;
+    logDebug() << "Killed " << count << " read jobs for " << subtree << ENDL;
 }
 
 
@@ -871,7 +871,7 @@ void DirReadJobQueue::deletingChildNotify( FileInfo * child )
 {
     if ( child && child->isDirInfo() )
     {
-	logDebug() << "Killing all pending read jobs for " << child << endl;
+	logDebug() << "Killing all pending read jobs for " << child << ENDL;
 	killAll( child->toDirInfo() );
     }
 }
@@ -889,5 +889,5 @@ void DirReadJobQueue::unblock( DirReadJob * job )
     enqueue( job );
 
     if ( _blocked.isEmpty() )
-	logDebug() << "No more jobs waiting for external processes" << endl;
+	logDebug() << "No more jobs waiting for external processes" << ENDL;
 }
diff --git a/src/DirSaver.cpp b/src/DirSaver.cpp
index 8cb8230..9302c16 100644
--- a/src/DirSaver.cpp
+++ b/src/DirSaver.cpp
@@ -29,7 +29,7 @@ void DirSaver::cd( const QString & newPath )
 {
     if ( newPath.isEmpty() )
     {
-	logWarning() << "Empty path" << endl;
+	logWarning() << "Empty path" << ENDL;
 	return;
     }
 
@@ -37,7 +37,7 @@ void DirSaver::cd( const QString & newPath )
     int result = chdir( newPath.toUtf8() );
 
     if ( result != 0 )
-        logWarning() << "chdir( " << newPath << " ) failed" << endl;
+        logWarning() << "chdir( " << newPath << " ) failed" << ENDL;
 }
 
 
diff --git a/src/DirTree.cpp b/src/DirTree.cpp
index 063795a..c3ad5ba 100644
--- a/src/DirTree.cpp
+++ b/src/DirTree.cpp
@@ -138,10 +138,10 @@ void DirTree::startReading( const QString & rawUrl )
     QFileInfo fileInfo( rawUrl );
     _url = fileInfo.absoluteFilePath();
     // logDebug() << "rawUrl: \"" << rawUrl << "\"" << endl;
-    logInfo() << "   url: \"" << _url	 << "\"" << endl;
+    logInfo() << "   url: \"" << _url	 << "\"" << ENDL;
     MountPoint * mountPoint = MountPoints::findNearestMountPoint( _url );
     _device = mountPoint ? mountPoint->device() : "";
-    logInfo() << "device: " << _device << endl;
+    logInfo() << "device: " << _device << ENDL;
 
     if ( _root->hasChildren() )
 	clear();
@@ -171,7 +171,7 @@ void DirTree::startReading( const QString & rawUrl )
     }
     else	// stat() failed
     {
-	logWarning() << "stat(" << _url << ") failed" << endl;
+	logWarning() << "stat(" << _url << ") failed" << ENDL;
 	_isBusy = false;
 	emit finished();
     }
@@ -210,7 +210,7 @@ void DirTree::refresh( DirInfo * subtree )
 	// if one selected item is in the subtree of another, and that parent
 	// was already refreshed.
 
-	logWarning() << "Item is no longer valid - not refreshing subtree" << endl;
+	logWarning() << "Item is no longer valid - not refreshing subtree" << ENDL;
 	return;
     }
 
@@ -295,7 +295,7 @@ void DirTree::childAddedNotify( FileInfo * newChild )
 
 void DirTree::deletingChildNotify( FileInfo * deletedChild )
 {
-    logDebug() << "Deleting child " << deletedChild << endl;
+    logDebug() << "Deleting child " << deletedChild << ENDL;
     emit deletingChild( deletedChild );
 
     if ( deletedChild == _root )
@@ -328,7 +328,7 @@ void DirTree::deleteSubtree( FileInfo *subtree )
 	    {
 		if ( parent->parent()->isFinished() )
 		{
-		    // logDebug() << "Removing empty dot entry " << parent << endl;
+		    // logDebug() << "Removing empty dot entry " << parent << ENDL;
 
 		    deletingChildNotify( parent );
 		    parent->parent()->deleteEmptyDotEntry();
@@ -339,7 +339,7 @@ void DirTree::deleteSubtree( FileInfo *subtree )
 	    }
 	    else	// no parent - this should never happen (?)
 	    {
-		logError() << "Internal error: Killing dot entry without parent " << parent << endl;
+		logError() << "Internal error: Killing dot entry without parent " << parent << ENDL;
 
 		// Better leave that dot entry alone - we shouldn't have come
 		// here in the first place. Who knows what will happen if this
@@ -502,16 +502,16 @@ void DirTree::setExcludeRules( ExcludeRules * newRules )
 #if VERBOSE_EXCLUDE_RULES
     if ( newRules )
     {
-	logDebug() << "New tmp exclude rules:" << endl;
+	logDebug() << "New tmp exclude rules:" << ENDL;
 
 	for ( ExcludeRuleListIterator it = newRules->begin(); it != newRules->end(); ++it )
 	{
-	    logDebug() << *it << endl;
+	    logDebug() << *it << ENDL;
 	}
     }
     else
     {
-	logDebug() << "Clearing tmp exclude rules" << endl;
+	logDebug() << "Clearing tmp exclude rules" << ENDL;
     }
 #endif
 
@@ -683,9 +683,9 @@ void DirTree::detectClusterSize( FileInfo * item )
         _haveClusterSize  = true;
 
         logInfo() << "Cluster size: " << _blocksPerCluster << " blocks ("
-                  << formatSize( clusterSize() ) << ")" << endl;
+                  << formatSize( clusterSize() ) << ")" << ENDL;
         logDebug() << "Derived from " << item << " " << formatSize( item->rawByteSize() )
                    << " (allocated: " << formatSize( item->rawAllocatedSize() ) << ")"
-                   << endl;
+                   << ENDL;
     }
 }
diff --git a/src/DirTreeCache.cpp b/src/DirTreeCache.cpp
index 996d103..36cd0a9 100644
--- a/src/DirTreeCache.cpp
+++ b/src/DirTreeCache.cpp
@@ -62,7 +62,7 @@ bool CacheWriter::writeCache( const QString & fileName, DirTree *tree )
 
     if ( cache == 0 )
     {
-	logError() << "Can't open " << fileName << ": " << formatErrno() << endl;
+	logError() << "Can't open " << fileName << ": " << formatErrno() << ENDL;
 	return false;
     }
 
@@ -205,7 +205,7 @@ QByteArray CacheWriter::urlEncoded( const QString & path )
 
     if ( encoded.isEmpty() )
     {
-        logError() << "Invalid file/dir name: " << path << endl;
+        logError() << "Invalid file/dir name: " << path << ENDL;
     }
 
     return encoded;
@@ -258,7 +258,7 @@ CacheReader::CacheReader( const QString & fileName,
 
     if ( _cache == 0 )
     {
-	logError() << "Can't open " << fileName << ": " << formatErrno() << endl;
+	logError() << "Can't open " << fileName << ": " << formatErrno() << ENDL;
 	_ok = false;
 	emit error();
 	return;
@@ -274,7 +274,7 @@ CacheReader::~CacheReader()
     if ( _cache )
 	gzclose( _cache );
 
-    logDebug() << "Cache reading finished" << endl;
+    logDebug() << "Cache reading finished" << ENDL;
 
     if ( _toplevel && ! _aborted )
     {
@@ -323,13 +323,13 @@ void CacheReader::addItem()
 	logError() << "Syntax error in " << _fileName << ":" << _lineNo
 		   << ": Expected at least " << expectedFields
                    << " fields, saw only " << fieldsCount()
-		   << endl;
+		   << ENDL;
 
 	setReadError( _lastDir );
 
 	if ( ++_errorCount > MAX_ERROR_COUNT )
 	{
-	    logError() << "Too many syntax errors. Giving up." << endl;
+	    logError() << "Too many syntax errors. Giving up." << ENDL;
 	    _ok = false;
 	    emit error();
 	}
@@ -434,7 +434,7 @@ void CacheReader::addItem()
     {
 	if ( path.startsWith( _lastExcludedDirUrl ) )
 	{
-	    // logDebug() << "Excluding " << path << "/" << name << endl;
+	    // logDebug() << "Excluding " << path << "/" << name << ENDL;
 	    return;
 	}
     }
@@ -455,7 +455,7 @@ void CacheReader::addItem()
 
 #if DEBUG_LOCATE_PARENT
 	if ( parent )
-	    logDebug() << "Using cache starting point as parent for " << fullPath << endl;
+	    logDebug() << "Using cache starting point as parent for " << fullPath << ENDL;
 #endif
 
 
@@ -467,7 +467,7 @@ void CacheReader::addItem()
 
 #if DEBUG_LOCATE_PARENT
 	    if ( parent )
-		logDebug() << "Located parent " << path << " in tree" << endl;
+		logDebug() << "Located parent " << path << " in tree" << ENDL;
 #endif
 	}
 
@@ -475,11 +475,11 @@ void CacheReader::addItem()
 	{
 	    logError() << _fileName << ":" << _lineNo << ": "
 		       << "Could not locate parent \"" << path << "\" for "
-		       << name << endl;
+		       << name << ENDL;
 
             if ( ++_errorCount > MAX_ERROR_COUNT )
             {
-                logError() << "Too many consistency errors. Giving up." << endl;
+                logError() << "Too many consistency errors. Giving up." << ENDL;
                 _ok = false;
                 emit error();
             }
@@ -495,7 +495,7 @@ void CacheReader::addItem()
     {
 	QString url = ( parent == _tree->root() ) ? buildPath( path, name ) : name;
 #if VERBOSE_CACHE_DIRS
-	logDebug() << "Creating DirInfo for " << url << " with parent " << parent << endl;
+	logDebug() << "Creating DirInfo for " << url << " with parent " << parent << ENDL;
 #endif
 	DirInfo * dir = new DirInfo( _tree, parent, url,
 				     mode, size,
@@ -522,7 +522,7 @@ void CacheReader::addItem()
 	{
 	    if ( ExcludeRules::instance()->match( dir->url(), dir->name() ) )
 	    {
-		logDebug() << "Excluding " << name << endl;
+		logDebug() << "Excluding " << name << ENDL;
 		dir->setExcluded();
 		dir->setReadState( DirOnRequestOnly );
 		dir->finalizeLocal();
@@ -540,7 +540,7 @@ void CacheReader::addItem()
 	{
 #if VERBOSE_CACHE_FILE_INFOS
 	    logDebug() << "Creating FileInfo for "
-		       << buildPath( parent->debugUrl(), name ) << endl;
+		       << buildPath( parent->debugUrl(), name ) << ENDL;
 #endif
 
 	    FileInfo * item = new FileInfo( _tree, parent, name,
@@ -554,7 +554,7 @@ void CacheReader::addItem()
 	else
 	{
 	    logError() << _fileName << ":" << _lineNo << ": "
-		       << "No parent for item " << name << endl;
+		       << "No parent for item " << name << ENDL;
 	}
     }
 }
@@ -616,7 +616,7 @@ bool CacheReader::checkHeader()
 	{
 	    _ok = false;
 	    logError() << _fileName << ":" << _lineNo
-		      << ": Unknown file format" << endl;
+		      << ": Unknown file format" << ENDL;
 	}
     }
 
@@ -628,7 +628,7 @@ bool CacheReader::checkHeader()
 
 	if ( ! _ok )
 	    logError() << _fileName << ":" << _lineNo
-		      << ": Incompatible cache file version" << endl;
+		      << ": Incompatible cache file version" << ENDL;
     }
 
     // logDebug() << "Cache file header check OK: " << _ok << endl;
@@ -659,7 +659,7 @@ bool CacheReader::readLine()
 	    if ( ! gzeof( _cache ) )
 	    {
 		_ok = false;
-		logError() << _fileName << ":" << _lineNo << ": Read error" << endl;
+		logError() << _fileName << ":" << _lineNo << ": Read error" << ENDL;
 		emit error();
 	    }
 
@@ -761,7 +761,7 @@ void CacheReader::splitPath( const QString & fileNameWithPath,
 			     QString	   & name_ret ) const
 {
     bool absolutePath = fileNameWithPath.startsWith( "/" );
-    QStringList components = fileNameWithPath.split( "/", QString::SkipEmptyParts );
+    QStringList components = fileNameWithPath.split( "/", SKIPEMPTYPARTS );
 
     if ( components.isEmpty() )
     {
@@ -805,7 +805,7 @@ QString CacheReader::unescapedPath( const QString & rawPath ) const
 QString CacheReader::cleanPath( const QString & rawPath ) const
 {
     QString clean = rawPath;
-    return clean.replace( _multiSlash, "/" );
+    return qregexp_replaceIn(_multiSlash, clean, QString("/"));
 }
 
 
@@ -835,7 +835,7 @@ void CacheReader::finalizeRecursive( DirInfo * dir )
 
 void CacheReader::setReadError( DirInfo * dir )
 {
-    logDebug() << "Setting read error for " << dir << endl;
+    logDebug() << "Setting read error for " << dir << ENDL;
 
     while ( dir )
     {
diff --git a/src/DirTreeModel.cpp b/src/DirTreeModel.cpp
index 1e7dc54..6057936 100644
--- a/src/DirTreeModel.cpp
+++ b/src/DirTreeModel.cpp
@@ -9,8 +9,6 @@
 
 #include <QPalette>
 
-#include "Qt4Compat.h"
-
 #include "DirTreeModel.h"
 #include "DirTree.h"
 #include "DirInfo.h"
@@ -141,7 +139,7 @@ void DirTreeModel::setSlowUpdate( bool slow )
     _updateTimer.setInterval( _slowUpdate ? _slowUpdateMillisec : _updateTimerMillisec );
 
     if ( slow )
-	logInfo() << "Display update every " << _updateTimer.interval() << " millisec" << endl;
+	logInfo() << "Display update every " << _updateTimer.interval() << " millisec" << ENDL;
 }
 
 
@@ -223,7 +221,7 @@ void DirTreeModel::loadIcons()
 {
     if ( _treeIconDir.isEmpty() )
     {
-	logWarning() << "No tree icons" << endl;
+	logWarning() << "No tree icons" << ENDL;
 	return;
     }
 
@@ -265,8 +263,8 @@ FileInfo * DirTreeModel::findChild( DirInfo * parent, int childNo ) const
     if ( childNo < 0 || childNo >= childrenList.size() )
     {
 	logError() << "Child #" << childNo << " is out of range: 0.."
-		   << childrenList.size()-1 << " children for "
-		   << parent << endl;
+		   << ((quint64)childrenList.size()-1) << " children for "
+		   << parent << ENDL;
 	Debug::dumpChildrenList( parent, childrenList );
 
 	return 0;
@@ -295,7 +293,7 @@ int DirTreeModel::rowNumber( FileInfo * child ) const
 	logError() << "Child " << child
 		   << " (" << (void *) child << ")"
 		   << " not found in \""
-		   << child->parent() << "\"" << endl;
+		   << child->parent() << "\"" << ENDL;
 
 	Debug::dumpDirectChildren( child->parent() );
     }
@@ -426,7 +424,7 @@ QVariant DirTreeModel::data( const QModelIndex & index, int role ) const
 
 		if ( item && item->isDirInfo() )
 		{
-		    // logDebug() << "Touching " << col << "\tof " << item << endl;
+		    // logDebug() << "Touching " << col << "\tof " << item << ENDL;
 		    item->toDirInfo()->touch();
 		}
 
@@ -436,7 +434,7 @@ QVariant DirTreeModel::data( const QModelIndex & index, int role ) const
 	case Qt::ForegroundRole: // Text color
 	    {
 		if ( item->isIgnored() || item->isAttic() )
-		    return qAppPalette().brush( QPalette::Disabled, QPalette::Foreground );
+		    return qAppPalette().brush( QPalette::Disabled, QPalette::WindowText );
 
 		if ( item->isDir() )
 		{
@@ -608,7 +606,7 @@ void DirTreeModel::sort( int column, Qt::SortOrder order )
 
     logDebug() << "Sorting by " << static_cast<DataColumn>( column )
 	       << ( order == Qt::AscendingOrder ? " ascending" : " descending" )
-	       << endl;
+	       << ENDL;
 
     // logDebug() << "Before layoutAboutToBeChanged()" << endl;
     // dumpPersistentIndexList();
@@ -1056,7 +1054,7 @@ void DirTreeModel::readJobFinished( DirInfo * dir )
     if ( anyAncestorBusy( dir ) )
     {
 	if  ( dir && ! dir->isMountPoint() )
-	    logDebug() << "Ancestor busy - ignoring readJobFinished for " << dir << endl;
+	    logDebug() << "Ancestor busy - ignoring readJobFinished for " << dir << ENDL;
     }
     else
     {
@@ -1088,7 +1086,7 @@ void DirTreeModel::newChildrenNotify( DirInfo * dir )
 
     if ( ! dir )
     {
-	logError() << "NULL DirInfo *" << endl;
+	logError() << "NULL DirInfo *" << ENDL;
 	return;
     }
 
@@ -1201,7 +1199,7 @@ void DirTreeModel::dumpPersistentIndexList() const
 {
     QModelIndexList persistentList = persistentIndexList();
 
-    logDebug() << persistentList.size() << " persistent indexes" << endl;
+    logDebug() << (quint64)persistentList.size() << " persistent indexes" << ENDL;
 
     for ( int i=0; i < persistentList.size(); ++i )
     {
@@ -1213,7 +1211,7 @@ void DirTreeModel::dumpPersistentIndexList() const
 	logDebug() << "#" << i
 		   << " Persistent index "
 		   << index
-		   << endl;
+		   << ENDL;
     }
 }
 
@@ -1236,7 +1234,7 @@ void DirTreeModel::updatePersistentIndexes()
 		       << " col " << oldIndex.column()
 		       << " row " << oldIndex.row()
 		       << " --> " << newIndex.row()
-		       << endl;
+		       << ENDL;
 #endif
 	    changePersistentIndex( oldIndex, newIndex );
 	}
@@ -1248,14 +1246,14 @@ void DirTreeModel::beginRemoveRows( const QModelIndex & parent, int first, int l
 {
     if ( _removingRows )
     {
-	logError() << "Removing rows already in progress" << endl;
+	logError() << "Removing rows already in progress" << ENDL;
 	return;
     }
 
 
     if ( ! parent.isValid() )
     {
-	logError() << "Invalid QModelIndex" << endl;
+	logError() << "Invalid QModelIndex" << ENDL;
 	return;
     }
 
@@ -1276,7 +1274,7 @@ void DirTreeModel::endRemoveRows()
 
 void DirTreeModel::deletingChild( FileInfo * child )
 {
-    logDebug() << "Deleting child " << child << endl;
+    logDebug() << "Deleting child " << child << ENDL;
 
     if ( child->parent() &&
 	 ( child->parent() == _tree->root() ||
@@ -1284,7 +1282,7 @@ void DirTreeModel::deletingChild( FileInfo * child )
     {
 	QModelIndex parentIndex = modelIndex( child->parent(), 0 );
 	int row = rowNumber( child );
-	logDebug() << "beginRemoveRows for " << child << " row " << row << endl;
+	logDebug() << "beginRemoveRows for " << child << " row " << row << ENDL;
 	beginRemoveRows( parentIndex, row, row );
     }
 
@@ -1300,7 +1298,7 @@ void DirTreeModel::childDeleted()
 
 void DirTreeModel::clearingSubtree( DirInfo * subtree )
 {
-    logDebug() << "Deleting all children of " << subtree << endl;
+    logDebug() << "Deleting all children of " << subtree << ENDL;
 
     if ( subtree == _tree->root() || subtree->isTouched() )
     {
@@ -1309,7 +1307,7 @@ void DirTreeModel::clearingSubtree( DirInfo * subtree )
 
 	if ( count > 0 )
 	{
-	    logDebug() << "beginRemoveRows for " << subtree << " row 0 to " << count - 1 << endl;
+	    logDebug() << "beginRemoveRows for " << subtree << " row 0 to " << count - 1 << ENDL;
 	    beginRemoveRows( subtreeIndex, 0, count - 1 );
 	}
     }
@@ -1340,7 +1338,7 @@ void DirTreeModel::invalidatePersistent( FileInfo * subtree,
 	    if ( item != subtree || includeParent )
 	    {
 #if 1
-		logDebug() << "Invalidating " << index << endl;
+		logDebug() << "Invalidating " << index << ENDL;
 #endif
 		changePersistentIndex( index, QModelIndex() );
 	    }
@@ -1375,7 +1373,7 @@ void DirTreeModel::refreshSelected()
 
     if ( sel && sel->isDirInfo() )
     {
-	logDebug() << "Refreshing " << sel << endl;
+	logDebug() << "Refreshing " << sel << ENDL;
 	busyDisplay();
 	FileInfoSet refreshSet;
 	refreshSet << sel;
@@ -1384,7 +1382,7 @@ void DirTreeModel::refreshSelected()
     }
     else
     {
-	logWarning() << "NOT refreshing " << sel << endl;
+	logWarning() << "NOT refreshing " << sel << ENDL;
     }
 }
 
diff --git a/src/DirTreePatternFilter.cpp b/src/DirTreePatternFilter.cpp
index 9f4af15..1f178da 100644
--- a/src/DirTreePatternFilter.cpp
+++ b/src/DirTreePatternFilter.cpp
@@ -48,7 +48,7 @@ DirTreePatternFilter::DirTreePatternFilter( const QString & pattern ):
 	_pattern :
 	QString( "*/" ) + _pattern;
 
-    logDebug() << "Creating pattern filter matching against " << pat << endl;
+    logDebug() << "Creating pattern filter matching against " << pat << ENDL;
     _regExp = QRegExp( pat, Qt::CaseSensitive, QRegExp::Wildcard );
 }
 
@@ -66,7 +66,7 @@ bool DirTreePatternFilter::ignore( const QString & path ) const
 #if VERBOSE_MATCH
     if ( match )
     {
-	logDebug() << "Ignoring " << path << " by pattern filter *" << _pattern << endl;
+	logDebug() << "Ignoring " << path << " by pattern filter *" << _pattern << ENDL;
     }
 #endif
 
@@ -80,7 +80,7 @@ bool DirTreePatternFilter::ignore( const QString & path ) const
 DirTreeSuffixFilter::DirTreeSuffixFilter( const QString & suffix ):
     _suffix( suffix )
 {
-    logDebug() << "Creating suffix filter matching *" << suffix << endl;
+    logDebug() << "Creating suffix filter matching *" << suffix << ENDL;
 }
 
 
@@ -97,7 +97,7 @@ bool DirTreeSuffixFilter::ignore( const QString & path ) const
 #if VERBOSE_MATCH
     if ( match )
     {
-	logDebug() << "Ignoring " << path << " by suffix filter *" << _suffix << endl;
+	logDebug() << "Ignoring " << path << " by suffix filter *" << _suffix << ENDL;
     }
 #endif
 
diff --git a/src/DirTreePkgFilter.cpp b/src/DirTreePkgFilter.cpp
index 3898939..de05073 100644
--- a/src/DirTreePkgFilter.cpp
+++ b/src/DirTreePkgFilter.cpp
@@ -21,9 +21,9 @@ DirTreePkgFilter::DirTreePkgFilter( PkgManager * pkgManager )
 {
     CHECK_PTR( pkgManager );
 
-    logInfo() << "Creating file list cache for " << pkgManager->name() << endl;
+    logInfo() << "Creating file list cache for " << pkgManager->name() << ENDL;
     _fileListCache = pkgManager->createFileListCache( PkgFileListCache::LookupGlobal );
-    logInfo() << "Done." << endl;
+    logInfo() << "Done." << ENDL;
 }
 
 
diff --git a/src/DirTreeView.cpp b/src/DirTreeView.cpp
index 223e989..a35e2d5 100644
--- a/src/DirTreeView.cpp
+++ b/src/DirTreeView.cpp
@@ -187,7 +187,7 @@ QModelIndexList DirTreeView::expandedIndexes() const
 
     if ( ! dirTreeModel )
     {
-	logError() << "Wrong model type to get this information" << endl;
+	logError() << "Wrong model type to get this information" << ENDL;
 	return QModelIndexList();
     }
 
@@ -234,7 +234,7 @@ void DirTreeView::setExpanded( FileInfo * item, bool expanded )
 
     if ( ! dirTreeModel )
     {
-	logError() << "Wrong model type" << endl;
+	logError() << "Wrong model type" << ENDL;
         return;
     }
 
diff --git a/src/DpkgPkgManager.cpp b/src/DpkgPkgManager.cpp
index 1561cc1..a1bb542 100644
--- a/src/DpkgPkgManager.cpp
+++ b/src/DpkgPkgManager.cpp
@@ -113,10 +113,10 @@ PkgInfoList DpkgPkgManager::parsePkgList( const QString & output )
     {
 	if ( ! line.isEmpty() )
 	{
-	    QStringList fields = line.split( " | ", QString::KeepEmptyParts );
+	    QStringList fields = line.split( " | ", KEEPEMPTYPARTS );
 
 	    if ( fields.size() != 4 )
-		logError() << "Invalid dpkg-query output: \"" << line << "\n" << endl;
+		logError() << "Invalid dpkg-query output: \"" << line << "\n" << ENDL;
 	    else
 	    {
 		QString name	= fields.takeFirst();
@@ -134,7 +134,7 @@ PkgInfoList DpkgPkgManager::parsePkgList( const QString & output )
 		}
 		else
 		{
-		    // logDebug() << "Ignoring " << line << endl;
+		    // logDebug() << "Ignoring " << line << ENDL;
 		}
 	    }
 	}
@@ -196,7 +196,7 @@ PkgFileListCache * DpkgPkgManager::createFileListCache( PkgFileListCache::Lookup
 
     QStringList lines = output.split( "\n" );
     output.clear(); // Free all that text ASAP
-    logDebug() << lines.size() << " output lines" << endl;
+    logDebug() << lines.size() << " output lines" << ENDL;
 
     PkgFileListCache * cache = new PkgFileListCache( this, lookupType );
     CHECK_NEW( cache );
@@ -216,7 +216,7 @@ PkgFileListCache * DpkgPkgManager::createFileListCache( PkgFileListCache::Lookup
 
 	if ( fields.size() != 2 )
 	{
-	    logError() << "Unexpected file list line: \"" << line << "\"" << endl;
+	    logError() << "Unexpected file list line: \"" << line << "\"" << ENDL;
 	}
 	else
 	{
@@ -234,7 +234,7 @@ PkgFileListCache * DpkgPkgManager::createFileListCache( PkgFileListCache::Lookup
 	}
     }
 
-    logDebug() << "file list cache finished." << endl;
+    logDebug() << "file list cache finished." << ENDL;
 
     return cache;
 }
diff --git a/src/Exception.h b/src/Exception.h
index 7c208af..9e96326 100644
--- a/src/Exception.h
+++ b/src/Exception.h
@@ -402,7 +402,7 @@ void _throw_helper( const EX_t	  &exception,
 	<< "THROW "
 	<< exception.className() << ": "
 	<< exception.what()
-	<< endl;
+	<< ENDL;
 
     throw( exception );
 }
@@ -419,7 +419,7 @@ void _caught_helper( const EX_t	   &exception,
 	<< "CAUGHT "
 	<< exception.className() << ": "
 	<< exception.what()
-	<< endl;
+	<< ENDL;
 }
 
 
@@ -436,7 +436,7 @@ void _rethrow_helper( const EX_t    &exception,
 	<< "RETHROW "
 	<< exception.className() << ": "
 	<< exception.what()
-	<< endl;
+	<< ENDL;
 
     throw;
 }
diff --git a/src/ExcludeRules.cpp b/src/ExcludeRules.cpp
index 492eaeb..db4f7ae 100644
--- a/src/ExcludeRules.cpp
+++ b/src/ExcludeRules.cpp
@@ -202,7 +202,7 @@ bool ExcludeRules::match( const QString & fullPath, const QString & fileName )
 	    _lastMatchingRule = rule;
 #if VERBOSE_EXCLUDE_MATCHES
 
-	    logDebug() << fullPath << " matches " << rule << endl;
+	    logDebug() << fullPath << " matches " << rule << ENDL;
 
 #endif
 	    return true;
@@ -226,7 +226,7 @@ bool ExcludeRules::matchDirectChildren( DirInfo * dir )
 	    _lastMatchingRule = rule;
 #if VERBOSE_EXCLUDE_MATCHES
 
-	    logDebug() << dir << " matches " << rule << endl;
+	    logDebug() << dir << " matches " << rule << ENDL;
 
 #endif
 	    return true;
@@ -279,7 +279,7 @@ void ExcludeRules::moveToBottom( ExcludeRule * rule )
 
 void ExcludeRules::addDefaultRules()
 {
-    logInfo() << "Adding default exclude rules" << endl;
+    logInfo() << "Adding default exclude rules" << ENDL;
 
     QRegExp regexp( ".snapshot", Qt::CaseSensitive, QRegExp::FixedString );
     ExcludeRule * rule = new ExcludeRule( regexp );
@@ -287,7 +287,7 @@ void ExcludeRules::addDefaultRules()
     add( rule );
     _defaultRulesAdded = true;
 
-    logInfo() << "Added " << rule << endl;
+    logInfo() << "Added " << rule << ENDL;
 }
 
 
@@ -326,7 +326,7 @@ void ExcludeRules::readSettings()
 	    {
 		logError() << "Invalid regexp: \"" << regexp.pattern()
 			   << "\": " << regexp.errorString()
-			   << endl;
+			   << ENDL;
 	    }
 
 	    settings.endGroup(); // [ExcludeRule_01], [ExcludeRule_02], ...
diff --git a/src/ExistingDirValidator.cpp b/src/ExistingDirValidator.cpp
index b4006d5..1e33c0d 100644
--- a/src/ExistingDirValidator.cpp
+++ b/src/ExistingDirValidator.cpp
@@ -45,7 +45,7 @@ ExistingDirValidator::validate( QString & input, int & pos) const
 #if 0
     logDebug() << "Checking \"" << input << "\": "
                << ( ok ? "OK" : "no such directory" )
-               << endl;
+               << ENDL;
 #endif
 
     return ok ? QValidator::Acceptable : QValidator::Intermediate;
diff --git a/src/FileDetailsView.cpp b/src/FileDetailsView.cpp
index 80ffe0b..bc409c4 100644
--- a/src/FileDetailsView.cpp
+++ b/src/FileDetailsView.cpp
@@ -7,8 +7,6 @@
  */
 
 
-#include "Qt4Compat.h"
-
 #include "FileDetailsView.h"
 #include "AdaptiveTimer.h"
 #include "DirInfo.h"
@@ -501,7 +499,7 @@ void FileDetailsView::showDetails( PkgInfo * pkg )
 
 	case DirCached:
 	case DirOnRequestOnly:
-	    logError() << "Invalid readState for a Pkg" << endl;
+	    logError() << "Invalid readState for a Pkg" << ENDL;
 	    break;
     }
 
@@ -666,7 +664,7 @@ QString FileDetailsView::limitText( const QString & longText )
     limited += "...";
     limited += longText.right( _labelLimit / 2 - 1 );
 
-    logDebug() << "Limiting \"" << longText << "\"" << endl;
+    logDebug() << "Limiting \"" << longText << "\"" << ENDL;
 
     return limited;
 }
diff --git a/src/FileInfo.cpp b/src/FileInfo.cpp
index 40da608..f6282b5 100644
--- a/src/FileInfo.cpp
+++ b/src/FileInfo.cpp
@@ -140,14 +140,14 @@ FileInfo::FileInfo( const QString & filenameWithoutPath,
 		       << "    Byte size: "     << formatSize( _size )
 		       << "  Allocated: "       << formatSize( _allocatedSize )
 		       << " (" << (int) _blocks << " blocks)"
-		       << endl;
+		       << ENDL;
 	}
 #endif
 
 #if 0
 	if ( isFile() && _links > 1 )
 	{
-	    logDebug() << _links << " hard links: " << this << endl;
+	    logDebug() << _links << " hard links: " << this << ENDL;
 	}
 #endif
     }
@@ -614,7 +614,7 @@ QString FileInfo::baseName() const
 void FileInfo::setIgnoreHardLinks( bool ignore )
 {
     if ( ignore )
-	logInfo() << "Ignoring hard links" << endl;
+	logInfo() << "Ignoring hard links" << ENDL;
 
     _ignoreHardLinks = ignore;
 }
@@ -756,7 +756,7 @@ bool FileInfo::isDominant()
 
 QString QDirStat::baseName( const QString & fileName )
 {
-    QStringList segments = fileName.split( '/', QString::SkipEmptyParts );
+    QStringList segments = fileName.split( '/', SKIPEMPTYPARTS );
     return segments.isEmpty() ? "" : segments.last();
 }
 
diff --git a/src/FileInfo.h b/src/FileInfo.h
index e060cc6..b30c220 100644
--- a/src/FileInfo.h
+++ b/src/FileInfo.h
@@ -186,7 +186,7 @@ namespace QDirStat
 	 * Notice: You can simply use the QTextStream operator<< to output
 	 * exactly this:
 	 *
-	 * logDebug() << "Found fileInfo " << info << endl;
+	 * logDebug() << "Found fileInfo " << info << ENDL;
 	 **/
 	virtual QString debugUrl() const;
 
diff --git a/src/FileInfoIterator.h b/src/FileInfoIterator.h
index 73b7f6f..21f03d7 100644
--- a/src/FileInfoIterator.h
+++ b/src/FileInfoIterator.h
@@ -28,7 +28,7 @@ namespace QDirStat
      *
      *	  while ( *it )
      *	  {
-     *	     logDebug() << *it << ":\t" << (*it)->totalSize() << endl;
+     *	     logDebug() << *it << ":\t" << (*it)->totalSize() << ENDL;
      *	     ++it;
      *	  }
      *
diff --git a/src/FileInfoSet.cpp b/src/FileInfoSet.cpp
index 1a0ff70..6e539fd 100644
--- a/src/FileInfoSet.cpp
+++ b/src/FileInfoSet.cpp
@@ -40,7 +40,7 @@ FileInfoSet FileInfoSet::normalized() const
 	    normalized << item;
 #if 0
 	else
-	    logDebug() << "Removing " << item << " with ancestors in the set" << endl;
+	    logDebug() << "Removing " << item << " with ancestors in the set" << ENDL;
 #endif
     }
 
@@ -56,12 +56,12 @@ FileInfoSet FileInfoSet::invalidRemoved() const
     {
 	if ( item && item->checkMagicNumber() )
 	{
-	    // logDebug() << "Keeping " << item << endl;
+	    // logDebug() << "Keeping " << item << ENDL;
 	    result << item;
 	}
 	else
 	{
-	    logWarning() << "Removing invalid item" << endl;
+	    logWarning() << "Removing invalid item" << ENDL;
 	}
     }
 
diff --git a/src/FileSizeStats.cpp b/src/FileSizeStats.cpp
index 83728f9..40ec7b0 100644
--- a/src/FileSizeStats.cpp
+++ b/src/FileSizeStats.cpp
@@ -127,7 +127,7 @@ QRealList FileSizeStats::fillBuckets( int bucketCount,
                << " startVal: " << formatSize( startVal )
                << " endVal: " << formatSize( endVal )
                << " bucketWidth: " << formatSize( bucketWidth )
-               << endl;
+               << ENDL;
 #endif
 
     for ( int i=0; i < _data.size(); ++i )
diff --git a/src/FileSizeStatsWindow.cpp b/src/FileSizeStatsWindow.cpp
index df16168..9740510 100644
--- a/src/FileSizeStatsWindow.cpp
+++ b/src/FileSizeStatsWindow.cpp
@@ -153,7 +153,7 @@ void FileSizeStatsWindow::populate( FileInfo * subtree, const QString & suffix )
 
     if ( ! _subtree )
     {
-	logWarning() << "No tree" << endl;
+	logWarning() << "No tree" << ENDL;
 	return;
     }
 
@@ -450,7 +450,7 @@ void FileSizeStatsWindow::applyOptions()
     if ( newStart != histogram->startPercentile() ||
 	 newEnd	  != histogram->endPercentile()	    )
     {
-	logDebug() << "New start: " << newStart << " new end: " << newEnd << endl;
+	logDebug() << "New start: " << newStart << " new end: " << newEnd << ENDL;
 
 	histogram->setStartPercentile( newStart );
 	histogram->setEndPercentile  ( newEnd	);
@@ -497,10 +497,10 @@ void FileSizeStatsWindow::showHelp()
     else if ( button == _ui->percentilesTableHelpButton	   )  topic = "Percentiles-Table.md";
     else if ( button == _ui->bucketsTableHelpButton	   )  topic = "Buckets-Table.md";
 
-    logInfo() << "Help topic: " << topic << endl;
+    logInfo() << "Help topic: " << topic << ENDL;
     QString helpUrl = "https://github.com/shundhammer/qdirstat/blob/master/doc/stats/" + topic;
     QString program = "/usr/bin/xdg-open";
 
-    logInfo() << "Starting  " << program << " " << helpUrl << endl;
+    logInfo() << "Starting  " << program << " " << helpUrl << ENDL;
     QProcess::startDetached( program, QStringList() << helpUrl );
 }
diff --git a/src/FileTypeStats.cpp b/src/FileTypeStats.cpp
index d173664..3976146 100644
--- a/src/FileTypeStats.cpp
+++ b/src/FileTypeStats.cpp
@@ -14,6 +14,7 @@
 #include "FormatUtil.h"
 #include "Logger.h"
 #include "Exception.h"
+#include "QtCompat.h"
 
 using namespace QDirStat;
 
@@ -262,12 +263,12 @@ void FileTypeStats::removeCruft()
     }
 
 #if 1
-    logDebug() << "Merged " << cruft.size() << " suffixes to <NO SUFFIX>: "
-	       << cruft.join( ", " ) << endl;
+    logDebug() << "Merged " << (quint64)cruft.size() << " suffixes to <NO SUFFIX>: "
+	       << cruft.join( ", " ) << ENDL;
 #endif
     logDebug() << "Merged: " << totalMergedCount << " files "
 	       << "(" << formatSize( totalMergedSum ) << ")"
-	       << endl;
+	       << ENDL;
 }
 
 
@@ -283,7 +284,7 @@ void FileTypeStats::removeEmpty()
 
 	if ( remove )
 	{
-	    logDebug() << "Removing empty suffix *." << suffix << endl;
+	    logDebug() << "Removing empty suffix *." << suffix << ENDL;
 	    it = _suffixCount.erase( it );
 	    _suffixSum.remove( suffix );
 	}
@@ -308,7 +309,7 @@ bool FileTypeStats::isCruft( const QString & suffix ) const
 
     int count	 = _suffixCount[ suffix ];
     int len	 = suffix.size();
-    int letters	 = suffix.count( QRegExp( "[a-zA-Z]" ) );
+    int letters = qregexp_countIn( QRegExp( "[a-zA-Z]" ), suffix );
     float lettersPercent = len > 0 ? (100.0 * letters) / len : 0.0;
 
     if ( letters == 0 )
@@ -344,5 +345,5 @@ void FileTypeStats::sanityCheck()
     logDebug() << "Unaccounted in categories: " << formatSize( missing )
 	       << " of " << formatSize( totalSize() )
 	       << " (" << QString::number( percentage( missing ), 'f', 2 ) << "%)"
-	       << endl;
+	       << ENDL;
 }
diff --git a/src/FileTypeStatsWindow.cpp b/src/FileTypeStatsWindow.cpp
index 336b4f9..95615e9 100644
--- a/src/FileTypeStatsWindow.cpp
+++ b/src/FileTypeStatsWindow.cpp
@@ -220,7 +220,7 @@ void FileTypeStatsWindow::populate( FileInfo * newSubtree )
 		parentItem->addChild( item );
 	    else
 	    {
-		logError() << "ERROR: No parent category item for " << suffix << endl;
+		logError() << "ERROR: No parent category item for " << suffix << ENDL;
 		otherItems << item;
 		otherCount += count;
 		otherSum   += sum;
@@ -324,10 +324,10 @@ void FileTypeStatsWindow::addTopXOtherItems( CategoryFileTypeItem  * otherCatego
         foreach ( FileTypeItem * item, otherItems )
             suffixes << item->text(0);
 
-        logDebug() << "Discarding " << otherItems.size()
+        logDebug() << "Discarding " << (quint64)otherItems.size()
                    << " suffixes below <other>: "
                    << suffixes.join( ", " )
-                   << endl;
+                   << ENDL;
 #endif
         // Delete all items that are not in the top X
         qDeleteAll( otherItems );
@@ -383,7 +383,7 @@ void FileTypeStatsWindow::sizeStatsForCurrentFileType()
     if ( suffix.isEmpty() || ! dir )
         return;
 
-    logDebug() << "Size stats for " << suffix << endl;
+    logDebug() << "Size stats for " << suffix << ENDL;
 
     FileSizeStatsWindow::populateSharedInstance( dir, suffix );
 }
@@ -399,13 +399,13 @@ QString FileTypeStatsWindow::currentSuffix() const
 
     if ( current->suffix() == NO_SUFFIX )
     {
-	logWarning() << "NO_SUFFIX selected" << endl;
+	logWarning() << "NO_SUFFIX selected" << ENDL;
 
 	return QString();
     }
     if ( current->suffix() == NON_SUFFIX_RULE )
     {
-	logWarning() << "NON_SUFFIX_RULE selected" << endl;
+	logWarning() << "NON_SUFFIX_RULE selected" << ENDL;
 
 	return QString();
     }
diff --git a/src/FilesystemsWindow.cpp b/src/FilesystemsWindow.cpp
index a16e843..f826226 100644
--- a/src/FilesystemsWindow.cpp
+++ b/src/FilesystemsWindow.cpp
@@ -153,7 +153,7 @@ void FilesystemsWindow::readSelectedFilesystem()
 
     if ( ! path.isEmpty() )
     {
-	logDebug() << "Read " << path << endl;
+	logDebug() << "Read " << path << ENDL;
 	emit readFilesystem( path );
     }
 }
diff --git a/src/FindFilesDialog.cpp b/src/FindFilesDialog.cpp
index 4923986..66a6d0d 100644
--- a/src/FindFilesDialog.cpp
+++ b/src/FindFilesDialog.cpp
@@ -7,8 +7,6 @@
  */
 
 
-#include "Qt4Compat.h"       // qEnableClearButton()
-
 #include "FindFilesDialog.h"
 #include "Settings.h"
 #include "SettingsHelpers.h"
@@ -87,7 +85,7 @@ FileSearchFilter FindFilesDialog::fileSearchFilter()
     filter.setFindPkg( filter.findDirs() );
     filter.setCaseSensitive ( _ui->caseSensitiveCheckBox->isChecked() );
 
-    logDebug() << filter << endl;
+    logDebug() << filter << ENDL;
 
     return filter;
 }
diff --git a/src/FormatUtil.cpp b/src/FormatUtil.cpp
index 2381a0d..51de65e 100644
--- a/src/FormatUtil.cpp
+++ b/src/FormatUtil.cpp
@@ -146,7 +146,7 @@ QString QDirStat::formatTime( time_t rawTime )
     if ( rawTime == (time_t) 0 )
 	return "";
 
-    QDateTime time = QDateTime::fromTime_t( rawTime );
+    QDateTime time = QDateTime::fromSecsSinceEpoch( rawTime );
 
     QString ret;
 
@@ -160,7 +160,7 @@ QString QDirStat::formatTime( time_t rawTime )
     }
     else
     {
-        ret = time.toString( Qt::DefaultLocaleShortDate );
+        ret = time.toString(QLocale::system().dateFormat(QLocale::ShortFormat));
     }
 
     return ret;
diff --git a/src/FormatUtil.h b/src/FormatUtil.h
index fedf250..784e13e 100644
--- a/src/FormatUtil.h
+++ b/src/FormatUtil.h
@@ -65,7 +65,7 @@ namespace QDirStat
      *
      * Note: For logDebug() etc., operator<< is overwritten to do exactly that:
      *
-     *	   logDebug() << "Size: " << x->totalSize() << endl;
+     *	   logDebug() << "Size: " << x->totalSize() << ENDL;
      **/
     QString formatSize( FileSize size );
 
diff --git a/src/HeaderTweaker.cpp b/src/HeaderTweaker.cpp
index 91771ad..031e1e9 100644
--- a/src/HeaderTweaker.cpp
+++ b/src/HeaderTweaker.cpp
@@ -10,8 +10,6 @@
 #include <QMenu>
 #include <QAction>
 
-#include "Qt4Compat.h"
-
 #include "HeaderTweaker.h"
 #include "DirTreeView.h"
 #include "Settings.h"
@@ -216,7 +214,7 @@ QString HeaderTweaker::colName( int section ) const
 						   Qt::Horizontal,
 						   Qt::DisplayRole ).toString();
     if ( col == UndefinedCol )
-	logError() << "No column at section " << section << endl;
+	logError() << "No column at section " << section << ENDL;
 
     return name;
 }
@@ -232,7 +230,7 @@ void HeaderTweaker::hideCurrentCol()
 {
     if ( _currentSection >= 0 )
     {
-	logDebug() << "Hiding column \"" << colName( _currentSection ) << "\"" << endl;
+	logDebug() << "Hiding column \"" << colName( _currentSection ) << "\"" << ENDL;
 	_header->setSectionHidden( _currentSection, true );
     }
 
@@ -250,7 +248,7 @@ void HeaderTweaker::autoSizeCurrentCol()
 		       QHeaderView::Interactive );
     }
     else
-	logWarning() << "No current section" << endl;
+	logWarning() << "No current section" << ENDL;
 
     _currentSection = -1;
 }
@@ -282,7 +280,7 @@ void HeaderTweaker::showHiddenCol()
     if ( ! action )
     {
 	logError() << "Wrong sender type: "
-		   << sender()->metaObject()->className() << endl;
+		   << sender()->metaObject()->className() << ENDL;
 	return;
     }
 
@@ -292,15 +290,15 @@ void HeaderTweaker::showHiddenCol()
 
 	if ( section >= 0 && section < _header->count() )
 	{
-	    logDebug() << "Showing column \"" << colName( section ) << "\"" << endl;
+	    logDebug() << "Showing column \"" << colName( section ) << "\"" << ENDL;
 	    _header->setSectionHidden( section, false );
 	}
 	else
-	    logError() << "Section index out of range: " << section << endl;
+	    logError() << "Section index out of range: " << section << ENDL;
     }
     else
     {
-	logError() << "No data() set for this QAction" << endl;
+	logError() << "No data() set for this QAction" << ENDL;
     }
 }
 
@@ -311,7 +309,7 @@ void HeaderTweaker::showAllHiddenColumns()
     {
 	if ( _header->isSectionHidden( section ) )
 	{
-	    logDebug() << "Showing column \"" << colName( section ) << "\"" << endl;
+	    logDebug() << "Showing column \"" << colName( section ) << "\"" << ENDL;
 	    _header->setSectionHidden( section, false );
 	}
     }
@@ -339,11 +337,11 @@ void HeaderTweaker::setColumnOrder( const DataColumnList & columns )
     {
 	if ( visualIndex < _header->count() )
 	{
-	    // logDebug() << "Moving " << col << " to position " << visualIndex << endl;
+	    // logDebug() << "Moving " << col << " to position " << visualIndex << ENDL;
 	    _header->moveSection( _header->visualIndex( col ), visualIndex++ );
 	}
 	else
-	    logWarning() << "More columns than header sections" << endl;
+	    logWarning() << "More columns than header sections" << ENDL;
     }
 }
 
@@ -471,7 +469,7 @@ void HeaderTweaker::changeLayout( const QString & name )
 {
     if ( ! _layouts.contains( name ) )
     {
-	logError() << "No layout " << name << endl;
+	logError() << "No layout " << name << ENDL;
 	return;
     }
 
@@ -518,7 +516,7 @@ void HeaderTweaker::fixupLayout( ColumnLayout * layout )
 
     if ( layout->columns.isEmpty() )
     {
-	logDebug() << "Falling back to default visible columns" << endl;
+	logDebug() << "Falling back to default visible columns" << ENDL;
 	layout->columns = layout->defaultColumns;
     }
 
diff --git a/src/HistogramItems.cpp b/src/HistogramItems.cpp
index 1d29b67..c7a7192 100644
--- a/src/HistogramItems.cpp
+++ b/src/HistogramItems.cpp
@@ -80,7 +80,7 @@ void HistogramBar::mousePressEvent( QGraphicsSceneMouseEvent * event )
 			   << ": " << _parentView->bucket( _number ) << " items;"
 			   << " range: " << formatSize( _startVal )
 			   << " .. " << formatSize( _endVal )
-			   << endl;
+			   << ENDL;
 	    }
 	    break;
 
@@ -148,7 +148,7 @@ void PercentileMarker::mousePressEvent( QGraphicsSceneMouseEvent * event )
 	    logDebug() << "Percentile marker #" << _percentileIndex
 		       << ": " << _name
 		       << ": " << formatSize( _parentView->percentile( _percentileIndex ) )
-		       << endl;
+		       << ENDL;
 	    break;
 
 	default:
diff --git a/src/HistogramView.cpp b/src/HistogramView.cpp
index 325eb82..b4cc47e 100644
--- a/src/HistogramView.cpp
+++ b/src/HistogramView.cpp
@@ -134,7 +134,7 @@ qreal HistogramView::bestBucketCount( int n )
     {
 	logInfo() << "Limiting bucket count to " << MAX_BUCKET_COUNT
 		  << " instead of " << result
-		  << endl;
+		  << ENDL;
 
 	// Enforcing an upper limit so each histogram bar remains wide enough
 	// to be clicked on or for tooltips etc.
@@ -234,7 +234,7 @@ void HistogramView::setEndPercentile( int index )
     {
 	logError() << "startPercentile must be less than endPercentile: "
 		   << _startPercentile << ".." << _endPercentile
-		   << endl;
+		   << ENDL;
     }
 }
 
@@ -320,7 +320,7 @@ void HistogramView::autoStartEndPercentiles()
 {
     if ( _percentiles.isEmpty() )
     {
-	logError() << "No percentiles set" << endl;
+	logError() << "No percentiles set" << ENDL;
 	return;
     }
 
@@ -352,12 +352,12 @@ void HistogramView::autoStartEndPercentiles()
 	      << "  Q3: " << formatSize( q3 )
 	      << "  minVal: " << formatSize( minVal )
 	      << "  maxVal: " << formatSize( maxVal )
-	      << endl;
+	      << ENDL;
     logInfo() << "startPercentile: " << _startPercentile
 	      << "  " << formatSize( percentile( _startPercentile ) )
 	      << "  endPercentile: " << _endPercentile
 	      << "  " << formatSize( percentile( _endPercentile	 ) )
-	      << endl;
+	      << ENDL;
 }
 
 
@@ -365,7 +365,7 @@ bool HistogramView::autoLogHeightScale()
 {
     if ( _buckets.isEmpty() )
     {
-	logError() << "No buckets set" << endl;
+	logError() << "No buckets set" << ENDL;
 	return false;
     }
 
@@ -393,7 +393,7 @@ bool HistogramView::autoLogHeightScale()
 		  << " bucket P" << referencePercentile
 		  << ": " << referencePercentileValue
 		  << "	 -> use log height scale: " << _useLogHeightScale
-		  << endl;
+		  << ENDL;
     }
 
     return _useLogHeightScale;
@@ -424,7 +424,7 @@ void HistogramView::calcGeometry( const QSize & newSize )
 #if 0
     logDebug() << "Histogram width: " << _histogramWidth
 	       << " height: " << _histogramHeight
-	       << endl;
+	       << ENDL;
 #endif
 }
 
@@ -478,7 +478,7 @@ void HistogramView::fitToViewport()
     {
 	logDebug() << "Histogram in " << rect.size()
 		   << " fits into visible size " << visibleSize
-		   << endl;
+		   << ENDL;
 
 	setTransform( QTransform() ); // Reset scaling etc.
 	ensureVisible( rect, 0, 0 );
@@ -487,7 +487,7 @@ void HistogramView::fitToViewport()
     {
 	logDebug() << "Scaling down histogram in " << rect.size()
 		   << " to fit into visible size " << visibleSize
-		   << endl;
+		   << ENDL;
 
 	fitInView( rect, Qt::KeepAspectRatio );
     }
@@ -502,7 +502,7 @@ void HistogramView::rebuild()
 	return;
     }
 
-    logInfo() << "Rebuilding histogram" << endl;
+    logInfo() << "Rebuilding histogram" << ENDL;
 
     if ( _geometryDirty )
         autoResize();
@@ -522,7 +522,7 @@ void HistogramView::rebuild()
     if ( _buckets.size() < 1 || _percentiles.size() != 101 )
     {
 	scene()->addText( "No data yet" );
-	logInfo() << "No data yet" << endl;
+	logInfo() << "No data yet" << ENDL;
 	return;
     }
 
diff --git a/src/History.cpp b/src/History.cpp
index 825d917..dc35df2 100644
--- a/src/History.cpp
+++ b/src/History.cpp
@@ -109,7 +109,7 @@ bool History::setCurrentIndex( int index )
     }
     else
     {
-        logWarning() << "Index " << index << " out of range" << endl;
+        logWarning() << "Index " << index << " out of range" << ENDL;
         dump();
 
         return false;
@@ -155,7 +155,7 @@ void History::dump() const
 {
     if ( _items.isEmpty() )
     {
-        logDebug() << "Empty history" << endl;
+        logDebug() << "Empty history" << ENDL;
         return;
     }
 
@@ -170,7 +170,7 @@ void History::dump() const
 
         logDebug() << prefix
                    << "#" << i
-                   << ": \"" << _items.at( i ) << "\"" << endl;
+                   << ": \"" << _items.at( i ) << "\"" << ENDL;
     }
 
     logNewline();
diff --git a/src/LocateFileTypeWindow.cpp b/src/LocateFileTypeWindow.cpp
index 2740c01..384d7fe 100644
--- a/src/LocateFileTypeWindow.cpp
+++ b/src/LocateFileTypeWindow.cpp
@@ -108,7 +108,7 @@ void LocateFileTypeWindow::populate( const QString & suffix, FileInfo * newSubtr
                            .arg( _subtree.url() ) );
 
     logDebug() << "Locating all files ending with \""
-	       << _searchSuffix << "\" below " << _subtree.url() << endl;
+	       << _searchSuffix << "\" below " << _subtree.url() << ENDL;
 
     // For better Performance: Disable sorting while inserting many items
     _ui->treeWidget->setSortingEnabled( false );
@@ -117,7 +117,7 @@ void LocateFileTypeWindow::populate( const QString & suffix, FileInfo * newSubtr
 
     _ui->treeWidget->setSortingEnabled( true );
     _ui->treeWidget->sortByColumn( SSR_PathCol, Qt::AscendingOrder );
-    logDebug() << _ui->treeWidget->topLevelItemCount() << " directories" << endl;
+    logDebug() << _ui->treeWidget->topLevelItemCount() << " directories" << ENDL;
 
     // Make sure something is selected, even if this window is not the active
     // one (for example because the user just clicked on another suffix in the
diff --git a/src/Logger.cpp b/src/Logger.cpp
index 1ec1f79..58dc09f 100644
--- a/src/Logger.cpp
+++ b/src/Logger.cpp
@@ -81,7 +81,7 @@ Logger::~Logger()
 {
     if ( _logFile.isOpen() )
     {
-        logInfo() << "-- Log End --\n" << endl;
+        logInfo() << "-- Log End --\n" << ENDL;
         _logFile.close();
     }
 
@@ -141,7 +141,7 @@ void Logger::openLogFile( const QString & filename )
             _logStream.setDevice( &_logFile );
             _logStream << "\n\n";
             log( __FILE__, __LINE__, __FUNCTION__, LogSeverityInfo )
-                << "-- Log Start --" << endl;
+                << "-- Log Start --" << ENDL;
         }
         else
         {
@@ -256,7 +256,7 @@ void Logger::setLogLevel( Logger *logger, LogSeverity newLevel )
 
 void Logger::newline()
 {
-    _logStream << endl;
+    _logStream << ENDL;
 }
 
 
@@ -313,7 +313,7 @@ static void qt_logger( QtMsgType msgType, const char *msg)
     Logger::log( 0, // use default logger
                  "[Qt]", 0, "", // file, line, function
                  toLogSeverity( msgType ) )
-        << msg << endl;
+        << msg << ENDL;
 
     if ( msgType == QtFatalMsg )
     {
@@ -348,7 +348,7 @@ static void qt_logger( QtMsgType msgType,
             Logger::log( 0, // use default logger
                          context.file, context.line, context.function,
                          toLogSeverity( msgType ) )
-                << "[Qt] " << line << endl;
+                << "[Qt] " << line << ENDL;
         }
     }
 
@@ -401,20 +401,20 @@ static void qt_logger( QtMsgType msgType,
 
                 QString text = "FATAL: Could not connect to the display.";
                 fprintf( stderr, "\n%s\n", qPrintable( text ) );
-                logError() << text << endl;
+                logError() << text << ENDL;
             }
             else
             {
                 fprintf( stderr, "FATAL: %s\n", qPrintable( msg ) );
             }
 
-            logInfo() << "-- Exiting --\n" << endl;
+            logInfo() << "-- Exiting --\n" << ENDL;
             exit( 1 ); // Don't dump core, just exit
         }
         else
         {
             fprintf( stderr, "FATAL: %s\n", qPrintable( msg ) );
-            logInfo() << "-- Aborting with core dump --\n" << endl;
+            logInfo() << "-- Aborting with core dump --\n" << ENDL;
             abort(); // Exit with core dump (it might contain a useful backtrace)
         }
     }
@@ -466,7 +466,7 @@ QString Logger::createLogDir( const QString & rawLogDir )
     if ( (uid_t) dirInfo.ownerId()  != getuid() )
     {
         logError() << "ERROR: Directory " << logDir
-                   << " is not owned by " << userName() << endl;
+                   << " is not owned by " << userName() << ENDL;
 
         QByteArray nameTemplate( QString( logDir + "-XXXXXX" ).toUtf8() );
         char * result = mkdtemp( nameTemplate.data() );
@@ -479,7 +479,7 @@ QString Logger::createLogDir( const QString & rawLogDir )
         else
         {
             logError() << "Could not create log dir " << nameTemplate
-                       << ": " << formatErrno() << endl;
+                       << ": " << formatErrno() << ENDL;
 
             logDir = "/";
             // No permissions to write to /,
@@ -504,7 +504,7 @@ QString Logger::oldName( const QString & filename, int no )
     QString oldName = filename;
 
     if ( oldName.endsWith( ".log" ) )
-        oldName.remove( QRegExp( "\\.log$" ) );
+        oldName = qregexp_removeIn(QRegExp( "\\.log$" ), oldName);
 
     oldName += QString( "-%1.old" ).arg( no, 2, 10, QChar( '0' ) );
 
@@ -517,7 +517,7 @@ QString Logger::oldNamePattern( const QString & filename )
     QString pattern = filename;
 
     if ( pattern.endsWith( ".log" ) )
-        pattern.remove( QRegExp( "\\.log$" ) );
+        pattern = qregexp_removeIn( QRegExp( "\\.log$" ), pattern);
 
     pattern += "-??.old";
 
@@ -542,7 +542,7 @@ void Logger::logRotate( const QString & logDir,
         {
             bool success = dir.remove( newName );
 #if VERBOSE_ROTATE
-            logDebug() << "Removing " << newName << ( success ? "" : " FAILED" ) << endl;
+            logDebug() << "Removing " << newName << ( success ? "" : " FAILED" ) << ENDL;
 #else
             Q_UNUSED( success );
 #endif
@@ -554,7 +554,7 @@ void Logger::logRotate( const QString & logDir,
 #if VERBOSE_ROTATE
             logDebug() << "Renaming " << currentName << " to " << newName
                        << ( success ? "" : " FAILED" )
-                       << endl;
+                       << ENDL;
 #else
             Q_UNUSED( success );
 #endif
@@ -572,7 +572,7 @@ void Logger::logRotate( const QString & logDir,
         {
             bool success = dir.remove( match );
 #if VERBOSE_ROTATE
-            logDebug() << "Removing leftover " << match << ( success ? "" : " FAILED" ) << endl;
+            logDebug() << "Removing leftover " << match << ( success ? "" : " FAILED" ) << ENDL;
 #else
             Q_UNUSED( success );
 #endif
diff --git a/src/Logger.h b/src/Logger.h
index 1535860..85de4fe 100644
--- a/src/Logger.h
+++ b/src/Logger.h
@@ -15,6 +15,7 @@
 #include <QFile>
 #include <QTextStream>
 
+#include "QtCompat.h"
 
 // Intentionally not using LogDebug, LogMilestone etc. to avoid confusion
 // because of simple typos: logDebug() vs. LogDebug()
@@ -72,9 +73,9 @@ enum LogSeverity
         if ( obj )                                                       \
             logDebug() << "sender(): " << obj->metaObject()->className() \
                        << " " << obj->objectName()                       \
-                       << endl;                                          \
+                       << ENDL;                                          \
         else                                                             \
-            logDebug() << "No sender" << endl;                           \
+            logDebug() << "No sender" << ENDL;                           \
                                                                          \
     } while( 0 )
 
@@ -83,8 +84,8 @@ enum LogSeverity
 /**
  * Logging class. Use one of the macros above for stream output:
  *
- *     logDebug() << "Debug logging demo " << myString << ": " << 42 << endl;
- *     logError() << "Can't open file " << filename << ": " << errno << endl;
+ *     logDebug() << "Debug logging demo " << myString << ": " << 42 << ENDL;
+ *     logError() << "Can't open file " << filename << ": " << errno << ENDL;
  *
  * Remember to terminate each log line with 'endl'.
  * Unlike qDebug() etc., this class does NOT add spaces or quotes.
@@ -201,7 +202,7 @@ public:
      * Notice that due to the way C++ evaluates expressions, the runtime cost
      * will not change significantly, only the log file size:
      *
-     *     logDebug() << "Result: " << myObj->result() << endl;
+     *     logDebug() << "Result: " << myObj->result() << ENDL;
      *
      * Even if the log level is higher than logDebug(), this will still call
      * myObj->result() and its operator<<(). If you want to avoid that, use
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index bfc30d5..5ea4421 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -192,7 +192,7 @@ void MainWindow::checkPkgManagerSupport()
     {
 	logInfo() << "No package manager support "
 		  << "for getting installed packages or file lists"
-		  << endl;
+		  << ENDL;
 
 	_ui->actionOpenPkg->setEnabled( false );
     }
@@ -203,7 +203,7 @@ void MainWindow::checkPkgManagerSupport()
     {
 	logInfo() << "No package manager support "
 		  << "for getting a file lists cache"
-		  << endl;
+		  << ENDL;
 
 	_ui->actionShowUnpkgFiles->setEnabled( false );
     }
@@ -456,7 +456,7 @@ void MainWindow::busyDisplay()
 
 void MainWindow::idleDisplay()
 {
-    logInfo() << endl;
+    logInfo() << ENDL;
 
     updateActions();
     _updateTimer.stop();
@@ -471,7 +471,7 @@ void MainWindow::idleDisplay()
     }
     else if ( ! app()->selectionModel()->currentBranch() )
     {
-	logDebug() << "No current branch - expanding tree to level 1" << endl;
+	logDebug() << "No current branch - expanding tree to level 1" << ENDL;
 	expandTreeToLevel( 1 );
     }
 
@@ -517,13 +517,13 @@ void MainWindow::startingReading()
 
 void MainWindow::readingFinished()
 {
-    logInfo() << endl;
+    logInfo() << ENDL;
 
     idleDisplay();
 
     QString elapsedTime = formatMillisec( _stopWatch.elapsed() );
     _ui->statusBar->showMessage( tr( "Finished. Elapsed time: %1").arg( elapsedTime ), LONG_MESSAGE );
-    logInfo() << "Reading finished after " << elapsedTime << endl;
+    logInfo() << "Reading finished after " << elapsedTime << ENDL;
 
     if ( app()->dirTree()->firstToplevel() &&
 	 app()->dirTree()->firstToplevel()->errSubDirCount() > 0 )
@@ -537,12 +537,12 @@ void MainWindow::readingFinished()
 
 void MainWindow::readingAborted()
 {
-    logInfo() << endl;
+    logInfo() << ENDL;
 
     idleDisplay();
     QString elapsedTime = formatMillisec( _stopWatch.elapsed() );
     _ui->statusBar->showMessage( tr( "Aborted. Elapsed time: %1").arg( elapsedTime ), LONG_MESSAGE );
-    logInfo() << "Reading aborted after " << elapsedTime << endl;
+    logInfo() << "Reading aborted after " << elapsedTime << ENDL;
 }
 
 
@@ -616,7 +616,7 @@ QString MainWindow::handleSymLink( const QString & origUrl ) const
             QString target = urlInfo.canonicalFilePath();
 
             logInfo() << "Following symlink \"" << url
-                      <<"\" to target \"" << target << "\"" << endl;
+                      <<"\" to target \"" << target << "\"" << ENDL;
 
             msg = new PanelMessage( _ui->messagePanel );
             CHECK_NEW( msg );
@@ -698,7 +698,7 @@ void MainWindow::askFindFiles()
 
 void MainWindow::readPkg( const PkgFilter & pkgFilter )
 {
-    logInfo() << "URL: " << pkgFilter.url() << endl;
+    logInfo() << "URL: " << pkgFilter.url() << ENDL;
 
     _futureSelection.setUrl( "Pkg:/" );
     updateWindowTitle( pkgFilter.url() );
@@ -721,7 +721,7 @@ void MainWindow::refreshAll()
 
     if ( ! url.isEmpty() )
     {
-	logDebug() << "Refreshing " << url << endl;
+	logDebug() << "Refreshing " << url << ENDL;
         _futureSelection.setUrl( url );
 
 	if ( PkgFilter::isPkgUrl( url ) )
@@ -762,8 +762,8 @@ void MainWindow::applyFutureSelection()
     _futureSelection.clear();
 
 #if 0
-    logDebug() << "Using future selection: " << sel << endl;
-    logDebug() << "Branch: " << branch << endl;
+    logDebug() << "Using future selection: " << sel << ENDL;
+    logDebug() << "Branch: " << branch << ENDL;
 #endif
 
     if ( sel )
@@ -921,7 +921,7 @@ void MainWindow::startingCleanup( const QString & cleanupName )
 
     FileInfo * sel = app()->selectionModel()->selectedItems().first();
     _futureSelection.set( sel );
-    logDebug() << "Storing future selection " << sel << endl;
+    logDebug() << "Storing future selection " << sel << ENDL;
     showProgress( tr( "Starting cleanup action %1" ).arg( cleanupName ) );
 }
 
@@ -931,7 +931,7 @@ void MainWindow::cleanupFinished( int errorCount )
     // Notice that this is not called for actions that are not owned by the
     // CleanupCollection such as _ui->actionMoveToTrash().
 
-    logDebug() << "Error count: " << errorCount << endl;
+    logDebug() << "Error count: " << errorCount << ENDL;
 
     if ( errorCount == 0 )
 	showProgress( tr( "Cleanup action finished successfully." ) );
@@ -966,7 +966,7 @@ void MainWindow::copyCurrentPathToClipboard()
 
 void MainWindow::expandTreeToLevel( int level )
 {
-    logDebug() << "Expanding tree to level " << level << endl;
+    logDebug() << "Expanding tree to level " << level << ENDL;
 
     if ( level < 1 )
 	_ui->dirTreeView->collapseAll();
@@ -1056,7 +1056,7 @@ void MainWindow::updateBookmarkButton( FileInfo * newCurrent )
             _ui->bookmarkButton->setChecked( isBookmarked );
 #if 0
             if ( isBookmarked )
-                logDebug() << url << " is bookmarked" << endl;
+                logDebug() << url << " is bookmarked" << ENDL;
 #endif
         }
     }
@@ -1115,7 +1115,7 @@ void MainWindow::moveToTrash()
 
     FileInfo * sel = selectedItems.first();
     _futureSelection.set( sel );
-    logDebug() << "Storing future selection " << sel << endl;
+    logDebug() << "Storing future selection " << sel << ENDL;
 
     // Prepare output window
 
@@ -1280,8 +1280,8 @@ void MainWindow::currentItemChanged( FileInfo * newCurrent, FileInfo * oldCurren
 
     if ( _verboseSelection )
     {
-	logDebug() << "new current: " << newCurrent << endl;
-	logDebug() << "old current: " << oldCurrent << endl;
+	logDebug() << "new current: " << newCurrent << ENDL;
+	logDebug() << "old current: " << oldCurrent << ENDL;
 	app()->selectionModel()->dumpSelectedItems();
     }
 }
@@ -1339,7 +1339,7 @@ void MainWindow::toggleVerboseSelection()
 	app()->selectionModel()->setVerbose( _verboseSelection );
 
     logInfo() << "Verbose selection is now " << ( _verboseSelection ? "on" : "off" )
-	      << ". Change this with Shift-F7." << endl;
+	      << ". Change this with Shift-F7." << ENDL;
 }
 
 
@@ -1356,13 +1356,13 @@ void MainWindow::itemClicked( const QModelIndex & index )
 		   << " col " << index.column()
 		   << " (" << QDirStat::DataColumns::fromViewCol( index.column() ) << ")"
 		   << "\t" << item
-		   << endl;
+		   << ENDL;
 	// << " data(0): " << index.model()->data( index, 0 ).toString()
 	// logDebug() << "Ancestors: " << Debug::modelTreeAncestors( index ).join( " -> " ) << endl;
     }
     else
     {
-	logDebug() << "Invalid model index" << endl;
+	logDebug() << "Invalid model index" << ENDL;
     }
 
     // app()->dirTreeModel()->dumpPersistentIndexList();
diff --git a/src/MainWindow.h b/src/MainWindow.h
index c32ebb2..cc11a10 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -10,6 +10,7 @@
 #ifndef MainWindow_h
 #define MainWindow_h
 
+#include <QActionGroup>
 #include <QMainWindow>
 #include <QString>
 #include <QElapsedTimer>
diff --git a/src/MainWindowLayout.cpp b/src/MainWindowLayout.cpp
index 6afa241..a186477 100644
--- a/src/MainWindowLayout.cpp
+++ b/src/MainWindowLayout.cpp
@@ -75,7 +75,7 @@ void MainWindow::changeLayout( const QString & name )
 	    action->data().toString() : "L2";
     }
 
-    logDebug() << "Changing to layout " << _layoutName << endl;
+    logDebug() << "Changing to layout " << _layoutName << ENDL;
 
     _ui->dirTreeView->headerTweaker()->changeLayout( _layoutName );
 
@@ -89,7 +89,7 @@ void MainWindow::changeLayout( const QString & name )
     }
     else
     {
-	logError() << "No layout " << _layoutName << endl;
+	logError() << "No layout " << _layoutName << ENDL;
     }
 }
 
diff --git a/src/MainWindowMenus.cpp b/src/MainWindowMenus.cpp
index 637b86c..31091e0 100644
--- a/src/MainWindowMenus.cpp
+++ b/src/MainWindowMenus.cpp
@@ -211,7 +211,7 @@ void MainWindow::connectHelpSolutionsMenu()
         QString url = action->statusTip();
 
         if ( url.isEmpty() )
-            logWarning() << "No URL in statusTip property of action " << action->objectName() << endl;
+            logWarning() << "No URL in statusTip property of action " << action->objectName() << ENDL;
         else
             CONNECT_ACTION( action, this, openActionUrl() );
     }
diff --git a/src/MainWindowUnpkg.cpp b/src/MainWindowUnpkg.cpp
index 7bc6867..b27ab14 100644
--- a/src/MainWindowUnpkg.cpp
+++ b/src/MainWindowUnpkg.cpp
@@ -27,7 +27,7 @@ void MainWindow::askShowUnpkgFiles()
 
     if ( ! pkgManager )
     {
-	logError() << "No supported primary package manager" << endl;
+	logError() << "No supported primary package manager" << ENDL;
 	return;
     }
 
@@ -49,14 +49,14 @@ void MainWindow::showUnpkgFiles( const QString & url )
 
 void MainWindow::showUnpkgFiles( const UnpkgSettings & unpkgSettings )
 {
-    logDebug() << "Settings:" << endl;
+    logDebug() << "Settings:" << ENDL;
     unpkgSettings.dump();
 
     PkgManager * pkgManager = PkgQuery::primaryPkgManager();
 
     if ( ! pkgManager )
     {
-	logError() << "No supported primary package manager" << endl;
+	logError() << "No supported primary package manager" << ENDL;
 	return;
     }
 
@@ -121,10 +121,10 @@ void MainWindow::setUnpkgFilters( const UnpkgSettings & unpkgSettings,
 QString MainWindow::parseUnpkgStartingDir( const UnpkgSettings & unpkgSettings )
 {
     QString dir = unpkgSettings.startingDir;
-    dir.replace( QRegExp( "^unpkg:" ), "" );
+    dir = qregexp_replaceIn( QRegExp( "^unpkg:" ), dir, "" );
 
     if ( dir != unpkgSettings.startingDir )
-	logInfo() << "Parsed starting dir: " << dir << endl;
+	logInfo() << "Parsed starting dir: " << dir << ENDL;
 
     return dir;
 }
diff --git a/src/MimeCategorizer.cpp b/src/MimeCategorizer.cpp
index 44941bc..50f0f80 100644
--- a/src/MimeCategorizer.cpp
+++ b/src/MimeCategorizer.cpp
@@ -138,7 +138,7 @@ MimeCategory * MimeCategorizer::category( const QString & filename,
 
 #if 0
     if ( category )
-	logVerbose() << "Found " << category << " for " << filename << endl;
+	logVerbose() << "Found " << category << " for " << filename << ENDL;
 #endif
 
     return category;
@@ -221,7 +221,7 @@ void MimeCategorizer::addSuffixes( QMap<QString, MimeCategory *> & suffixMap,
 	{
 	    logError() << "Duplicate suffix: " << suffix << " for "
 		       << suffixMap.value( suffix ) << " and " << category
-		       << endl;
+		       << ENDL;
 	}
 	else
 	{
diff --git a/src/MimeCategoryConfigPage.cpp b/src/MimeCategoryConfigPage.cpp
index f1934d9..22ee175 100644
--- a/src/MimeCategoryConfigPage.cpp
+++ b/src/MimeCategoryConfigPage.cpp
@@ -321,7 +321,7 @@ void MimeCategoryConfigPage::populateTreemapView()
 
     logDebug() << "Demo tree: " << fileCount << " files with "
 	       << formatSize( topDir->totalSize() ) << " total"
-	       << endl;
+	       << ENDL;
 
     _ui->treemapView->setDirTree( _dirTree );
 }
diff --git a/src/MountPoints.cpp b/src/MountPoints.cpp
index e0eff42..75fd7d4 100644
--- a/src/MountPoints.cpp
+++ b/src/MountPoints.cpp
@@ -126,7 +126,7 @@ QStorageInfo * MountPoint::storageInfo()
     if ( ! _storageInfo )
     {
         if ( isNetworkMount() )
-            logDebug() << "Creating QStorageInfo for " << _path << endl;
+            logDebug() << "Creating QStorageInfo for " << _path << ENDL;
 
         _storageInfo = new QStorageInfo( _path );
         CHECK_NEW( _storageInfo );
@@ -256,13 +256,13 @@ MountPoint * MountPoints::findNearestMountPoint( const QString & startPath )
     QString path = fileInfo.canonicalFilePath(); // absolute path without symlinks or ..
 
     if ( path != startPath )
-	logDebug() << startPath << " canonicalized is " << path << endl;
+	logDebug() << startPath << " canonicalized is " << path << ENDL;
 
     MountPoint * mountPoint = findByPath( path );
 
     if ( ! mountPoint )
     {
-	QStringList pathComponents = startPath.split( "/", QString::SkipEmptyParts );
+	QStringList pathComponents = startPath.split( "/", SKIPEMPTYPARTS );
 
 	while ( ! mountPoint && ! pathComponents.isEmpty() )
 	{
@@ -327,7 +327,7 @@ void MountPoints::ensurePopulated()
     read( "/proc/mounts" ) || read( "/etc/mtab" );
 
     if ( ! _isPopulated )
-	logError() << "Could not read either /proc/mounts or /etc/mtab" << endl;
+	logError() << "Could not read either /proc/mounts or /etc/mtab" << ENDL;
 
 #endif
 
@@ -349,12 +349,12 @@ bool MountPoints::read( const QString & filename )
 
     if ( ! file.open( QIODevice::ReadOnly | QIODevice::Text ) )
     {
-	logWarning() << "Can't open " << filename << endl;
+	logWarning() << "Can't open " << filename << ENDL;
 	return false;
     }
 
     findNtfsDevices();
-    logDebug() << "Reading " << filename << endl;
+    logDebug() << "Reading " << filename << ENDL;
 
     QTextStream in( &file );
     int lineNo = 0;
@@ -364,14 +364,14 @@ bool MountPoints::read( const QString & filename )
     while ( ! line.isNull() ) // in.atEnd() always returns true for /proc/*
     {
 	++lineNo;
-	QStringList fields = line.split( QRegExp( "\\s+" ), QString::SkipEmptyParts );
+	QStringList fields = qregexp_splitString( QRegExp( "\\s+" ), line, SKIPEMPTYPARTS );
 
 	if ( fields.isEmpty() ) // allow empty lines
 	    continue;
 
 	if ( fields.size() < 4 )
 	{
-	    logError() << "Bad line " << filename << ":" << lineNo << ": " << line << endl;
+	    logError() << "Bad line " << filename << ":" << lineNo << ": " << line << ENDL;
 	    continue;
 	}
 
@@ -406,7 +406,7 @@ bool MountPoints::read( const QString & filename )
 
     if ( count < 1 )
     {
-	logWarning() << "Not a single mount point in " << filename << endl;
+	logWarning() << "Not a single mount point in " << filename << ENDL;
 	return false;
     }
     else
@@ -428,13 +428,13 @@ void MountPoints::postProcess( MountPoint * mountPoint )
 
         logInfo() << "Found duplicate mount of " << mountPoint->device()
                   << " at " << mountPoint->path()
-                  << endl;
+                  << ENDL;
     }
 
     if ( mountPoint->isSnapPackage() )
     {
         QString pkgName = mountPoint->path().section( "/", 1, 1, QString::SectionSkipEmpty );
-        logInfo() << "Found snap package \"" << pkgName << "\" at " << mountPoint->path() << endl;
+        logInfo() << "Found snap package \"" << pkgName << "\" at " << mountPoint->path() << ENDL;
     }
 }
 
@@ -478,7 +478,7 @@ bool MountPoints::readStorageInfo()
 
     if ( _mountPointList.isEmpty() )
     {
-	logWarning() << "Not a single mount point found with QStorageInfo" << endl;
+	logWarning() << "Not a single mount point found with QStorageInfo" << ENDL;
 	return false;
     }
     else
@@ -515,7 +515,7 @@ void MountPoints::findNtfsDevices()
         lsblkCommand = "/usr/bin/lsblk";
     if ( ! SysUtil::haveCommand( lsblkCommand ) )
     {
-        logInfo() << "No lsblk command available" << endl;
+        logInfo() << "No lsblk command available" << ENDL;
 
         return;
     }
@@ -534,13 +534,13 @@ void MountPoints::findNtfsDevices()
                                           false );      // ignoreErrCode
     if ( exitCode == 0 )
     {
-        QStringList lines = output.split( "\n" )
-            .filter( QRegExp( "\\s+ntfs", Qt::CaseInsensitive ) );
+        QStringList lines = qregexp_filterList(
+            QRegExp( "\\s+ntfs", Qt::CaseInsensitive ), output.split( "\n" ));
 
         foreach ( QString line, lines )
         {
-            QString device = "/dev/" + line.split( QRegExp( "\\s+" ) ).first();
-            logDebug() << "NTFS on " << device << endl;
+            QString device = "/dev/" + qregexp_splitString( QRegExp( "\\s+" ), line ).first();
+            logDebug() << "NTFS on " << device << ENDL;
             _ntfsDevices << device;
         }
     }
@@ -548,7 +548,7 @@ void MountPoints::findNtfsDevices()
     _hasNtfs = ! _ntfsDevices.isEmpty();
 
     if ( ! _hasNtfs )
-        logDebug() << "No NTFS devices found" << endl;
+        logDebug() << "No NTFS devices found" << ENDL;
 }
 
 
@@ -575,7 +575,7 @@ QList<MountPoint *> MountPoints::normalMountPoints()
 void MountPoints::dumpNormalMountPoints()
 {
     foreach ( MountPoint * mountPoint, normalMountPoints() )
-	logDebug() << mountPoint << endl;
+	logDebug() << mountPoint << ENDL;
 }
 
 
@@ -583,7 +583,7 @@ void MountPoints::dump()
 {
     foreach ( MountPoint * mountPoint, instance()->_mountPointList )
     {
-	logDebug() << mountPoint << endl;
+	logDebug() << mountPoint << ENDL;
     }
 }
 
diff --git a/src/OpenDirDialog.cpp b/src/OpenDirDialog.cpp
index 9e1c3ba..88ff864 100644
--- a/src/OpenDirDialog.cpp
+++ b/src/OpenDirDialog.cpp
@@ -12,8 +12,6 @@
 #include <QFileSystemModel>
 #include <QTimer>
 
-#include "Qt4Compat.h"
-
 #include "OpenDirDialog.h"
 #include "MountPoints.h"
 #include "ExistingDirCompleter.h"
@@ -143,7 +141,7 @@ void OpenDirDialog::initialSelection()
     QString path = QDir::currentPath();
 
 #if VERBOSE_SELECTION
-    logDebug() << "Selecting " << path << endl;
+    logDebug() << "Selecting " << path << ENDL;
 #endif
 
     setPath( path );
@@ -179,7 +177,7 @@ void OpenDirDialog::setPath( const QString & path )
     _settingPath = true;
 
 #if VERBOSE_SELECTION
-    logDebug() << "Selecting " << path << endl;
+    logDebug() << "Selecting " << path << ENDL;
 #endif
 
     SignalBlocker sigBlockerPathSelector( _ui->pathSelector );
@@ -233,7 +231,7 @@ void OpenDirDialog::pathEdited( bool ok )
     if ( path != _lastPath )
     {
 #if VERBOSE_SELECTION
-        logDebug() << "New path:" << path << endl;
+        logDebug() << "New path:" << path << ENDL;
 #endif
         setPath( path );
     }
@@ -249,7 +247,7 @@ void OpenDirDialog::treeSelection( const QModelIndex & newCurrentItem,
     if ( path != _lastPath )
     {
 #if VERBOSE_SELECTION
-        logDebug() << "Selecting " << path << endl;
+        logDebug() << "Selecting " << path << ENDL;
 #endif
         setPath( path );
     }
@@ -258,7 +256,7 @@ void OpenDirDialog::treeSelection( const QModelIndex & newCurrentItem,
 
 void OpenDirDialog::populatePathComboBox( const QString & fullPath )
 {
-    QStringList pathComponents = fullPath.split( "/", QString::SkipEmptyParts );
+    QStringList pathComponents = fullPath.split( "/", SKIPEMPTYPARTS );
 
     _ui->pathComboBox->clear();
     _ui->pathComboBox->addItem( "/" );
@@ -274,7 +272,7 @@ void OpenDirDialog::populatePathComboBox( const QString & fullPath )
 
 void OpenDirDialog::goUp()
 {
-    QStringList pathComponents = selectedPath().split( "/", QString::SkipEmptyParts );
+    QStringList pathComponents = selectedPath().split( "/", SKIPEMPTYPARTS );
 
     if ( ! pathComponents.isEmpty() )
         pathComponents.removeLast();
@@ -284,7 +282,7 @@ void OpenDirDialog::goUp()
     if ( path != _lastPath )
     {
 #if VERBOSE_SELECTION
-        logDebug() << "Navigating up to " << path << endl;
+        logDebug() << "Navigating up to " << path << ENDL;
 #endif
         setPath( path );
     }
@@ -342,11 +340,11 @@ QString OpenDirDialog::askOpenDir( bool *    crossFilesystems_ret,
     OpenDirDialog dialog( parent );
     dialog.pathSelector()->addHomeDir();
     dialog.pathSelector()->addMountPoints( MountPoints::normalMountPoints() );
-    logDebug() << "Waiting for user selection" << endl;
+    logDebug() << "Waiting for user selection" << ENDL;
 
     if ( dialog.exec() == QDialog::Rejected )
     {
-        logInfo() << "[Cancel]" << endl;
+        logInfo() << "[Cancel]" << ENDL;
 	return QString();
     }
 
@@ -356,7 +354,7 @@ QString OpenDirDialog::askOpenDir( bool *    crossFilesystems_ret,
 	*crossFilesystems_ret = _crossFilesystems;
 
     QString path = dialog.selectedPath();
-    logInfo() << "User selected path " << path << endl;
+    logInfo() << "User selected path " << path << ENDL;
 
     return path;
 }
diff --git a/src/OpenPkgDialog.cpp b/src/OpenPkgDialog.cpp
index 38f49e5..4630bb6 100644
--- a/src/OpenPkgDialog.cpp
+++ b/src/OpenPkgDialog.cpp
@@ -7,8 +7,6 @@
  */
 
 
-#include "Qt4Compat.h"
-
 #include "OpenPkgDialog.h"
 #include "Logger.h"
 #include "Exception.h"
@@ -40,7 +38,7 @@ PkgFilter OpenPkgDialog::pkgFilter()
 {
     if ( _ui->allPkgRadioButton->isChecked() )
     {
-        logDebug() << "SelectAll" << endl;
+        logDebug() << "SelectAll" << ENDL;
         return PkgFilter( "", PkgFilter::SelectAll );
     }
     else
diff --git a/src/OutputWindow.cpp b/src/OutputWindow.cpp
index ab336eb..23e1156 100644
--- a/src/OutputWindow.cpp
+++ b/src/OutputWindow.cpp
@@ -37,7 +37,7 @@ OutputWindow::OutputWindow( QWidget * parent ):
     _errorCount( 0 )
 {
     _ui->setupUi( this );
-    logDebug() << "Creating" << endl;
+    logDebug() << "Creating" << ENDL;
     readSettings();
 
     _ui->terminal->clear();
@@ -54,14 +54,14 @@ OutputWindow::OutputWindow( QWidget * parent ):
 
 OutputWindow::~OutputWindow()
 {
-    logDebug() << "Destructor" << endl;
+    logDebug() << "Destructor" << ENDL;
 
     if ( ! _processList.isEmpty() )
     {
-	logWarning() << _processList.size() << " processes left over" << endl;
+	logWarning() << _processList.size() << " processes left over" << ENDL;
 
 	foreach ( Process * process, _processList )
-	    logWarning() << "Left over: " << process << endl;
+	    logWarning() << "Left over: " << process << ENDL;
 
 	qDeleteAll( _processList );
     }
@@ -78,7 +78,7 @@ void OutputWindow::addProcess( Process * process )
     if ( _killedAll )
     {
 	logInfo() << "User killed all processes - "
-                  << "no longer accepting new processes" << endl;
+                  << "no longer accepting new processes" << ENDL;
 	process->kill();
 	process->deleteLater();
     }
@@ -162,11 +162,11 @@ Process * OutputWindow::senderProcess( const char * function ) const
 	{
 	    logError() << "Expecting QProcess as sender() in " << function
 		       <<" , got "
-		       << sender()->metaObject()->className() << endl;
+		       << sender()->metaObject()->className() << ENDL;
 	}
 	else
 	{
-	    logError() << "NULL sender() in " << function << endl;
+	    logError() << "NULL sender() in " << function << ENDL;
 	}
     }
 
@@ -197,7 +197,7 @@ void OutputWindow::processFinished( int exitCode, QProcess::ExitStatus exitStatu
     switch ( exitStatus )
     {
 	case QProcess::NormalExit:
-	    logDebug() << "Process finished normally." << endl;
+	    logDebug() << "Process finished normally." << ENDL;
 	    addCommandLine( tr( "Process finished." ) );
 	    break;
 
@@ -210,12 +210,12 @@ void OutputWindow::processFinished( int exitCode, QProcess::ExitStatus exitStatu
 		// code of the shell; that would only be useful if the shell
 		// crashed or could not be started.
 
-		logError() << "Process crashed." << endl;
+		logError() << "Process crashed." << ENDL;
 		addStderr( tr( "Process crashed." ) );
 	    }
 	    else
 	    {
-		logError() << "Process crashed. Exit code: " << exitCode << endl;
+		logError() << "Process crashed. Exit code: " << exitCode << ENDL;
 		addStderr( tr( "Process crashed. Exit code: %1" ).arg( exitCode ) );
 	    }
 	    break;
@@ -229,7 +229,7 @@ void OutputWindow::processFinished( int exitCode, QProcess::ExitStatus exitStatu
 
 	if ( _processList.isEmpty() && _noMoreProcesses )
 	{
-	    logDebug() << "Emitting lastProcessFinished() err: " << _errorCount << endl;
+	    logDebug() << "Emitting lastProcessFinished() err: " << _errorCount << ENDL;
 	    emit lastProcessFinished( _errorCount );
 	}
 
@@ -273,7 +273,7 @@ void OutputWindow::processError( QProcess::ProcessError error )
 
     if ( ! msg.isEmpty() )
     {
-	logError() << msg << endl;
+	logError() << msg << ENDL;
 	addStderr( msg );
     }
 
@@ -285,7 +285,7 @@ void OutputWindow::processError( QProcess::ProcessError error )
 
 	if ( _processList.isEmpty() && _noMoreProcesses )
 	{
-	    logDebug() << "Emitting lastProcessFinished() err: " << _errorCount << endl;
+	    logDebug() << "Emitting lastProcessFinished() err: " << _errorCount << ENDL;
 	    emit lastProcessFinished( _errorCount );
 	}
 
@@ -306,7 +306,7 @@ void OutputWindow::closeIfDone()
 	if ( ( autoClose() && _errorCount == 0 ) ||
 	     _closed || ! isVisible() )
 	{
-	    logDebug() << "No more processes to watch. Auto-closing." << endl;
+	    logDebug() << "No more processes to watch. Auto-closing." << ENDL;
 	    this->deleteLater(); // It is safe to call this multiple times
 	}
     }
@@ -319,7 +319,7 @@ void OutputWindow::noMoreProcesses()
 
     if ( _processList.isEmpty() && _noMoreProcesses )
     {
-	logDebug() << "Emitting lastProcessFinished() err: " << _errorCount << endl;
+	logDebug() << "Emitting lastProcessFinished() err: " << _errorCount << ENDL;
 	emit lastProcessFinished( _errorCount );
     }
 
@@ -334,13 +334,13 @@ void OutputWindow::zoom( double factor )
     if ( font.pixelSize() != -1 )
     {
 	int pixelSize = qRound( font.pixelSize() * factor );
-	logDebug() << "New font size: " << pixelSize << " pixels" << endl;
+	logDebug() << "New font size: " << pixelSize << " pixels" << ENDL;
 	font.setPixelSize( pixelSize );
     }
     else
     {
 	qreal pointSize = font.pointSize() * factor;
-	logDebug() << "New font size: " << pointSize << " points" << endl;
+	logDebug() << "New font size: " << pointSize << " points" << ENDL;
 	font.setPointSize( pointSize );
     }
 
@@ -362,7 +362,7 @@ void OutputWindow::zoomOut()
 
 void OutputWindow::resetZoom()
 {
-    logDebug() << "Resetting font to normal" << endl;
+    logDebug() << "Resetting font to normal" << ENDL;
     _ui->terminal->setFont( _terminalDefaultFont );
 }
 
@@ -373,7 +373,7 @@ void OutputWindow::killAll()
 
     foreach ( Process * process, _processList )
     {
-	logInfo() << "Killing process " << process << endl;
+	logInfo() << "Killing process " << process << ENDL;
 	process->kill();
 	_processList.removeAll( process );
 	process->deleteLater();
@@ -437,7 +437,7 @@ Process * OutputWindow::startNextProcess()
 	}
 
 	addCommandLine( command( process ) );
-	logInfo() << "Starting: " << process << endl;
+	logInfo() << "Starting: " << process << ENDL;
 
 	process->start();
 	qApp->processEvents(); // Keep GUI responsive
diff --git a/src/PacManPkgManager.cpp b/src/PacManPkgManager.cpp
index cabfdab..32fde8b 100644
--- a/src/PacManPkgManager.cpp
+++ b/src/PacManPkgManager.cpp
@@ -46,7 +46,7 @@ QString PacManPkgManager::owningPkg( const QString & path )
     // blank-separated section #4; let's remove the part before the package
     // name.
 
-    output.remove( QRegExp( "^.*is owned by " ) );
+    output = qregexp_removeIn( QRegExp( "^.*is owned by " ), output);
     QString pkg = output.section( " ", 0, 0 );
 
     return pkg;
@@ -77,10 +77,10 @@ PkgInfoList PacManPkgManager::parsePkgList( const QString & output )
     {
         if ( ! line.isEmpty() )
         {
-            QStringList fields = line.split( " ", QString::KeepEmptyParts );
+            QStringList fields = line.split( " ", KEEPEMPTYPARTS );
 
             if ( fields.size() != 2 )
-                logError() << "Invalid pacman -Qn output: \"" << line << "\n" << endl;
+                logError() << "Invalid pacman -Qn output: \"" << line << "\n" << ENDL;
             else
             {
                 QString name    = fields.takeFirst();
diff --git a/src/PercentBar.cpp b/src/PercentBar.cpp
index 799e391..39df1a6 100644
--- a/src/PercentBar.cpp
+++ b/src/PercentBar.cpp
@@ -105,7 +105,7 @@ void PercentBarDelegate::paint( QPainter		   * painter,
 	    if ( percent > 100.0f )
 	    {
 		if ( percent > 103.0f )
-		    logError() << "Percent maxed out: " << percent << endl;
+		    logError() << "Percent maxed out: " << percent << ENDL;
 		percent = 100.0f;
 	    }
 
@@ -150,7 +150,7 @@ QVariant PercentBarDelegate::percentData( const QModelIndex & index ) const
 
         if ( ! ok )
         {
-            logWarning() << "float conversion failed from \"" << text << "\"" << endl;
+            logWarning() << "float conversion failed from \"" << text << "\"" << ENDL;
             return data;
         }
 
diff --git a/src/PercentileStats.cpp b/src/PercentileStats.cpp
index 82f7400..8db9c30 100644
--- a/src/PercentileStats.cpp
+++ b/src/PercentileStats.cpp
@@ -43,13 +43,13 @@ void PercentileStats::clear()
 void PercentileStats::sort()
 {
     if ( _data.size() > VERBOSE_SORT_THRESHOLD )
-	logDebug() << "Sorting " << _data.size() << " elements" << endl;
+	logDebug() << "Sorting " << _data.size() << " elements" << ENDL;
 
     std::sort( _data.begin(), _data.end() );
     _sorted = true;
 
     if ( _data.size() > VERBOSE_SORT_THRESHOLD )
-	logDebug() << "Sorting done." << endl;
+	logDebug() << "Sorting done." << ENDL;
 }
 
 
@@ -216,8 +216,8 @@ PercentileSums PercentileStats::percentileSums()
 #if 0
     for ( int i=0; i < sums.size(); ++i )
     {
-	logDebug() << "sum[ "	  << i << " ] : " << formatSize( sums._individual[i] ) << endl;
-	logDebug() << "cum_sum[ " << i << " ] : " << formatSize( sums._cumulative[i] ) << endl;
+	logDebug() << "sum[ "	  << i << " ] : " << formatSize( sums._individual[i] ) << ENDL;
+	logDebug() << "cum_sum[ " << i << " ] : " << formatSize( sums._cumulative[i] ) << ENDL;
     }
 #endif
 
diff --git a/src/PkgFileListCache.cpp b/src/PkgFileListCache.cpp
index d078798..f5d087d 100644
--- a/src/PkgFileListCache.cpp
+++ b/src/PkgFileListCache.cpp
@@ -34,7 +34,7 @@ PkgFileListCache::PkgFileListCache( PkgManager * pkgManager,
 
 PkgFileListCache::~PkgFileListCache()
 {
-    logDebug() << "Destroying the file list cache." << endl;
+    logDebug() << "Destroying the file list cache." << ENDL;
 }
 
 
diff --git a/src/PkgFilter.cpp b/src/PkgFilter.cpp
index 8ce010c..4d61ce3 100644
--- a/src/PkgFilter.cpp
+++ b/src/PkgFilter.cpp
@@ -35,12 +35,12 @@ PkgFilter::PkgFilter( const QString & pattern,
 void PkgFilter::normalizePattern()
 {
     QString oldPattern = _pattern;
-    _pattern.remove( QRegExp( "^Pkg:/*", Qt::CaseInsensitive ) );
-    _pattern.remove( QRegExp( "/.*$" ) );
+    _pattern = qregexp_removeIn( QRegExp( "^Pkg:/?", Qt::CaseInsensitive ), _pattern ) ;
+    _pattern = qregexp_removeIn( QRegExp( "/.*$" ), _pattern );
 
     if ( _pattern != oldPattern )
     {
-        logInfo() << "Normalizing pkg pattern to \"" << _pattern << "\"" << endl;
+        logInfo() << "Normalizing pkg pattern to \"" << _pattern << "\"" << ENDL;
         _regexp.setPattern( _pattern );
     }
 }
diff --git a/src/PkgInfo.cpp b/src/PkgInfo.cpp
index a2553b8..458563e 100644
--- a/src/PkgInfo.cpp
+++ b/src/PkgInfo.cpp
@@ -94,7 +94,7 @@ QString PkgInfo::pkgUrl( const QString & path ) const
 
 FileInfo * PkgInfo::locate( const QString & path )
 {
-    QStringList components = path.split( "/", QString::SkipEmptyParts );
+    QStringList components = path.split( "/", SKIPEMPTYPARTS );
 
     if ( isPkgUrl( path ) )
     {
@@ -107,7 +107,7 @@ FileInfo * PkgInfo::locate( const QString & path )
 
         if ( pkgName != _name )
         {
-            logError() << "Path " << path << " does not belong to " << this << endl;
+            logError() << "Path " << path << " does not belong to " << this << ENDL;
             return 0;
         }
 
diff --git a/src/PkgQuery.cpp b/src/PkgQuery.cpp
index a46ad0c..730db75 100644
--- a/src/PkgQuery.cpp
+++ b/src/PkgQuery.cpp
@@ -63,7 +63,7 @@ PkgQuery::~PkgQuery()
 
 void PkgQuery::checkPkgManagers()
 {
-    logInfo() << "Checking available supported package managers..." << endl;
+    logInfo() << "Checking available supported package managers..." << ENDL;
 
     checkPkgManager( new DpkgPkgManager()   );
     checkPkgManager( new RpmPkgManager()    );
@@ -73,7 +73,7 @@ void PkgQuery::checkPkgManagers()
     _secondaryPkgManagers.clear();
 
     if ( _pkgManagers.isEmpty() )
-        logInfo() << "No supported package manager found." << endl;
+        logInfo() << "No supported package manager found." << ENDL;
     else
     {
         QStringList available;
@@ -81,7 +81,7 @@ void PkgQuery::checkPkgManagers()
         foreach ( PkgManager * pkgManager, _pkgManagers )
             available << pkgManager->name();
 
-        logInfo() << "Found " << available.join( ", " )  << endl;
+        logInfo() << "Found " << available.join( ", " )  << ENDL;
     }
 }
 
@@ -92,12 +92,12 @@ void PkgQuery::checkPkgManager( PkgManager * pkgManager )
 
     if ( pkgManager->isPrimaryPkgManager() )
     {
-	logInfo() << "Found primary package manager " << pkgManager->name() << endl;
+	logInfo() << "Found primary package manager " << pkgManager->name() << ENDL;
 	_pkgManagers << pkgManager;
     }
     else if ( pkgManager->isAvailable() )
     {
-	logInfo() << "Found secondary package manager " << pkgManager->name() << endl;
+	logInfo() << "Found secondary package manager " << pkgManager->name() << ENDL;
 	_secondaryPkgManagers << pkgManager;
     }
     else
@@ -175,9 +175,9 @@ QString PkgQuery::getOwningPackage( const QString & path )
 
 #if VERBOSE_PKG_QUERY
     if ( pkg.isEmpty() )
-	logDebug() << foundBy << ": No package owns " << path << endl;
+	logDebug() << foundBy << ": No package owns " << path << ENDL;
     else
-	logDebug() << foundBy << ": Package " << pkg << " owns " << path << endl;
+	logDebug() << foundBy << ": Package " << pkg << " owns " << path << ENDL;
 #endif
 
     return pkg;
diff --git a/src/PkgReader.cpp b/src/PkgReader.cpp
index ee30fd1..2e8cb68 100644
--- a/src/PkgReader.cpp
+++ b/src/PkgReader.cpp
@@ -43,7 +43,7 @@ PkgReader::~PkgReader()
 
 void PkgReader::read( const PkgFilter & filter )
 {
-    logInfo() << "Reading " << filter << endl;
+    logInfo() << "Reading " << filter << ENDL;
 
     _pkgList = PkgQuery::installedPkg();
     filterPkgList( filter );
@@ -88,7 +88,7 @@ void PkgReader::filterPkgList( const PkgFilter & filter )
     {
 	if ( filter.matches( pkg->baseName() ) )
 	{
-	    // logDebug() << "Selecting pkg " << pkg << endl;
+	    // logDebug() << "Selecting pkg " << pkg << ENDL;
 	    matches << pkg;
 	}
     }
@@ -139,7 +139,7 @@ void PkgReader::createDisplayName( const QString & pkgName )
     {
 	logDebug() << "Found multi version pkg " << pkgName
 		   << " same arch: " << sameArch
-		   << endl;
+		   << ENDL;
     }
 
     foreach ( PkgInfo * pkg, pkgList )
@@ -195,7 +195,7 @@ void PkgReader::createCachePkgReadJobs()
 
     if ( ! fileListCache )
     {
-	logError() << "Creating the file list cache failed" << endl;
+	logError() << "Creating the file list cache failed" << ENDL;
 	return;
     }
 
@@ -210,7 +210,7 @@ void PkgReader::createCachePkgReadJobs()
 
 void PkgReader::createAsyncPkgReadJobs()
 {
-    logDebug() << endl;
+    logDebug() << ENDL;
 
     ProcessStarter * processStarter = new ProcessStarter;
     CHECK_NEW( processStarter );
@@ -243,11 +243,11 @@ Process * PkgReader::createReadFileListProcess( PkgInfo * pkg )
 
     if ( command.isEmpty() )
     {
-	logError() << "Empty file list command for " << pkg << endl;
+	logError() << "Empty file list command for " << pkg << ENDL;
 	return 0;
     }
 
-    QStringList args	 = command.split( QRegExp( "\\s+" ) );
+    QStringList args	 = qregexp_splitString( QRegExp( "\\s+" ), command);
     QString	program	 = args.takeFirst();
 
     QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
@@ -337,9 +337,9 @@ void PkgReadJob::reportCacheStats()
     if ( _lstatCalls > 0 )
         hitPercent = ( 100.0 * _cacheHits ) /_lstatCalls;
 
-    logDebug() << _lstatCalls << " lstat() calls" << endl;
+    logDebug() << _lstatCalls << " lstat() calls" << ENDL;
     logDebug() << _cacheHits << " stat cache hits ("
-               << qRound( hitPercent ) << "%)" << endl;
+               << qRound( hitPercent ) << "%)" << ENDL;
 }
 
 
@@ -365,7 +365,7 @@ void PkgReadJob::startReading()
 
 QStringList PkgReadJob::fileList()
 {
-    logDebug() << "Using default PkgQuery::fileList() for " << _pkg << endl;
+    logDebug() << "Using default PkgQuery::fileList() for " << _pkg << ENDL;
 
     return PkgQuery::fileList( _pkg );
 }
@@ -378,7 +378,7 @@ void PkgReadJob::addFile( const QString & fileListPath )
 
     // logDebug() << "Adding " << fileListPath << " to " << _pkg << endl;
 
-    QStringList remaining = fileListPath.split( "/", QString::SkipEmptyParts );
+    QStringList remaining = fileListPath.split( "/", SKIPEMPTYPARTS );
     QStringList currentPath;
     DirInfo *	parent = _pkg;
 
@@ -404,13 +404,13 @@ void PkgReadJob::addFile( const QString & fileListPath )
                     //
                     // parent->setReadState( DirError );
 
-                    logWarning() << _pkg << ": missing: " << fileListPath << endl;
+                    logWarning() << _pkg << ": missing: " << fileListPath << ENDL;
                 }
 
 		return;
 	    }
 
-	    // logDebug() << "Created " << newParent << endl;
+	    // logDebug() << "Created " << newParent << ENDL;
 	}
 
 	if ( ! remaining.isEmpty() )
@@ -419,7 +419,7 @@ void PkgReadJob::addFile( const QString & fileListPath )
 
 	    if ( ! parent )
 	    {
-		logWarning() << newParent << " should be a directory, but is not" << endl;
+		logWarning() << newParent << " should be a directory, but is not" << ENDL;
 		return;
 	    }
 	}
@@ -554,14 +554,14 @@ void AsyncPkgReadJob::readFileListFinished( int			 exitCode,
     if ( exitStatus != QProcess::NormalExit )
     {
 	ok = false;
-	logError() << "Get file list command crashed for " << _pkg << endl;
+	logError() << "Get file list command crashed for " << _pkg << ENDL;
     }
 
     if ( ok && exitCode != 0 )
     {
 	ok = false;
 	logError() << "Get file list command exited with "
-		   << exitStatus << " for " << _pkg << endl;
+		   << exitStatus << " for " << _pkg << ENDL;
     }
 
     if ( ok )
@@ -624,7 +624,7 @@ QStringList CachePkgReadJob::fileList()
         return fileList;
     }
 
-    logDebug() << "Falling back to the simple PkgQuery::fileList() for " << _pkg << endl;
+    logDebug() << "Falling back to the simple PkgQuery::fileList() for " << _pkg << ENDL;
 
     return PkgQuery::fileList( _pkg );
 }
diff --git a/src/PopupLabel.cpp b/src/PopupLabel.cpp
index cd8d6f2..741fe8f 100644
--- a/src/PopupLabel.cpp
+++ b/src/PopupLabel.cpp
@@ -77,7 +77,12 @@ void PopupLabel::mousePressEvent( QMouseEvent * event )
 }
 
 
+// this sucks ...
+#if (QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ))
 void PopupLabel::enterEvent( QEvent * event )
+#else
+void PopupLabel::enterEvent( QEnterEvent * event )
+#endif
 {
     Q_UNUSED( event );
 
diff --git a/src/PopupLabel.h b/src/PopupLabel.h
index 92a7fc1..bd57804 100644
--- a/src/PopupLabel.h
+++ b/src/PopupLabel.h
@@ -11,6 +11,7 @@
 
 
 #include <QLabel>
+#include <QEnterEvent>
 
 class QMouseEvent;
 
@@ -89,7 +90,11 @@ namespace QDirStat
 	// Event handlers (all inherited from QWidget)
 
 	virtual void mousePressEvent( QMouseEvent * event ) Q_DECL_OVERRIDE;
+#if (QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ))
 	virtual void enterEvent( QEvent * event ) Q_DECL_OVERRIDE;
+#else
+	virtual void enterEvent( QEnterEvent * event ) Q_DECL_OVERRIDE;
+#endif
 	virtual void leaveEvent( QEvent * event ) Q_DECL_OVERRIDE;
 
 
diff --git a/src/ProcessStarter.cpp b/src/ProcessStarter.cpp
index 32c3079..923dfb6 100644
--- a/src/ProcessStarter.cpp
+++ b/src/ProcessStarter.cpp
@@ -27,8 +27,8 @@ ProcessStarter::ProcessStarter( QObject * parent ):
 
 void ProcessStarter::start()
 {
-    logDebug() << "Starting. Processes in queue: " << _waiting.count() << endl;
-    logDebug() << "Maximum parallel processes: " << _maxParallel << endl;
+    logDebug() << "Starting. Processes in queue: " << _waiting.count() << ENDL;
+    logDebug() << "Maximum parallel processes: " << _maxParallel << ENDL;
 
     _started = true;
     startProcesses();
@@ -75,7 +75,7 @@ void ProcessStarter::processFinished( int                  exitCode,
 
     if ( ! process )
     {
-        logError() << "Ignoring non-process QObject " << (void *) sender() << endl;
+        logError() << "Ignoring non-process QObject " << (void *) sender() << ENDL;
         return;
     }
 
diff --git a/src/QDirStatApp.cpp b/src/QDirStatApp.cpp
index 5f29092..dca7b82 100644
--- a/src/QDirStatApp.cpp
+++ b/src/QDirStatApp.cpp
@@ -106,7 +106,7 @@ QWidget * QDirStatApp::findMainWindow() const
     }
 
     if ( ! mainWin )
-        logWarning() << "NULL mainWin for shared instance" << endl;
+        logWarning() << "NULL mainWin for shared instance" << ENDL;
 
     return mainWin;
 }
diff --git a/src/Qt4Compat.h b/src/Qt4Compat.h
deleted file mode 100644
index cd5b8a8..0000000
--- a/src/Qt4Compat.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- *   File name: Qt4Compat.h
- *   Summary:	Helpers for Qt4 compatibility
- *   License:	GPL V2 - See file LICENSE for details.
- *
- *   Author:	Stefan Hundhammer <Stefan.Hundhammer@gmx.de>
- */
-
-#ifndef Qt4Compat_h
-#define Qt4Compat_h
-
-#include <QString>
-#include <QComboBox>
-
-
-#if (QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 ))
-
-
-#include <QTextDocument> // Qt::escape()
-#include <QApplication>
-#include <QLineEdit>
-
-#define setSectionResizeMode setResizeMode
-#define sectionResizeMode    resizeMode
-
-inline QString qHtmlEscape( const QString & text )
-{
-    return Qt::escape( text );
-}
-
-
-inline QPalette qAppPalette()
-{
-    return QApplication::palette();
-}
-
-
-inline void qSetComboBoxText( QComboBox *     comboBox,
-			      const QString & text )
-{
-    QLineEdit * lineEdit = comboBox->lineEdit();
-
-    if ( lineEdit )
-	lineEdit->setText( text );
-}
-
-
-inline void qEnableClearButton( QComboBox * comboBox )
-{
-    Q_UNUSED( comboBox );
-}
-
-
-inline void qEnableClearButton( QLineEdit * lineEdit )
-{
-    Q_UNUSED( lineEdit );
-}
-
-
-
-#else // Qt 5.x
-
-
-#include <QGuiApplication>
-#include <QLineEdit>
-
-
-inline QString qHtmlEscape( const QString & text )
-{
-    return text.toHtmlEscaped();
-}
-
-
-inline QPalette qAppPalette()
-{
-    return QGuiApplication::palette();
-}
-
-
-inline void qSetComboBoxText( QComboBox *     comboBox,
-			      const QString & text )
-{
-    comboBox->setCurrentText( text );
-}
-
-
-inline void qEnableClearButton( QComboBox * comboBox )
-{
-    QLineEdit * lineEdit = comboBox->lineEdit();
-
-    if ( lineEdit )
-	lineEdit->setClearButtonEnabled( true );
-}
-
-
-inline void qEnableClearButton( QLineEdit * lineEdit )
-{
-    lineEdit->setClearButtonEnabled( true );
-}
-
-
-#endif
-
-
-
-#endif // Qt4Compat_h
diff --git a/src/QtCompat.h b/src/QtCompat.h
new file mode 100644
index 0000000..ab3d889
--- /dev/null
+++ b/src/QtCompat.h
@@ -0,0 +1,187 @@
+/*
+ *   File name: QtCompat.h
+ *   Summary:	Helpers for Qt4, Qt5, Qt6 compatibility
+ *   License:	GPL V2 - See file LICENSE for details.
+ *
+ *   Author:	Stefan Hundhammer <Stefan.Hundhammer@gmx.de>
+ */
+
+#ifndef QtCompat_h
+#define QtCompat_h
+
+#include <QString>
+#include <QComboBox>
+#include <QRegExp>
+
+#if (QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 ))
+
+
+#include <QTextDocument> // Qt::escape()
+#include <QApplication>
+#include <QLineEdit>
+
+#define setSectionResizeMode setResizeMode
+#define sectionResizeMode    resizeMode
+
+inline QString qHtmlEscape( const QString & text )
+{
+    return Qt::escape( text );
+}
+
+
+inline QPalette qAppPalette()
+{
+    return QApplication::palette();
+}
+
+
+inline void qSetComboBoxText( QComboBox *     comboBox,
+			      const QString & text )
+{
+    QLineEdit * lineEdit = comboBox->lineEdit();
+
+    if ( lineEdit )
+	lineEdit->setText( text );
+}
+
+
+inline void qEnableClearButton( QComboBox * comboBox )
+{
+    Q_UNUSED( comboBox );
+}
+
+
+inline void qEnableClearButton( QLineEdit * lineEdit )
+{
+    Q_UNUSED( lineEdit );
+}
+
+
+
+#else // Qt >= 5.x
+
+
+#include <QGuiApplication>
+#include <QLineEdit>
+
+
+inline QString qHtmlEscape( const QString & text )
+{
+    return text.toHtmlEscaped();
+}
+
+
+inline QPalette qAppPalette()
+{
+    return QGuiApplication::palette();
+}
+
+
+inline void qSetComboBoxText( QComboBox *     comboBox,
+			      const QString & text )
+{
+    comboBox->setCurrentText( text );
+}
+
+
+inline void qEnableClearButton( QComboBox * comboBox )
+{
+    QLineEdit * lineEdit = comboBox->lineEdit();
+
+    if ( lineEdit )
+	lineEdit->setClearButtonEnabled( true );
+}
+
+
+inline void qEnableClearButton( QLineEdit * lineEdit )
+{
+    lineEdit->setClearButtonEnabled( true );
+}
+
+
+#endif
+
+
+// Qt5 and earlier QRegExp exists
+#if (QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ))
+    inline QString qregexp_replaceIn(const QRegExp& regexp, const QString& source, const QString& after)
+    {
+        QString str = source;
+        return str.replace( regexp, after );
+    }
+
+    inline QString qregexp_removeIn(const QRegExp& regexp, const QString& source)
+    {
+        QString str = source;
+        return str.remove( regexp );
+    }
+
+    inline QStringList qregexp_splitString(const QRegExp& regexp, const QString& source, Qt::SplitBehavior behavior = Qt::KeepEmptyParts )
+    {
+       QString str = source;
+       return str.split(regexp, behavior);
+    }
+
+    inline bool qregexp_containedIn( const QRegExp& regexp, const QString& source)
+    {
+        return source.contains(regexp);
+    }
+
+    inline int qregexp_countIn( const QRegExp& regexp, const QString& source )
+    {
+        return source.count( regexp );
+    }
+
+    inline QStringList qregexp_filterList( const QRegExp& regexp, const QStringList& source )
+    {
+        return source.filter( regexp );
+    }
+
+
+//    #define QEnterEvent QEvent
+
+// Qt6, QRegExp is only available in compatibility modes
+#else
+    inline QString qregexp_replaceIn(const QRegExp& regexp, const QString& source, const QString& after)
+    {
+        return regexp.replaceIn( source, after);
+    }
+
+    inline QString qregexp_removeIn(const QRegExp& regexp, const QString& source)
+    {
+        return regexp.removeIn( source );
+    }
+
+    inline QStringList qregexp_splitString(const QRegExp& regexp, const QString& source, Qt::SplitBehavior behavior = Qt::KeepEmptyParts )
+    {
+        return regexp.splitString(source, behavior );
+    }
+
+    inline bool qregexp_containedIn( const QRegExp& regexp, const QString& source)
+    {
+        return regexp.containedIn( source );
+    }
+
+    inline int qregexp_countIn( const QRegExp& regexp, const QString& source )
+    {
+        return regexp.countIn(source);
+    }
+
+    inline QStringList qregexp_filterList( const QRegExp& regexp, const QStringList& source )
+    {
+        return regexp.filterList(source);
+    }
+
+#endif
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
+#define ENDL Qt::endl
+#define KEEPEMPTYPARTS Qt::KeepEmptyParts
+#define SKIPEMPTYPARTS Qt::SkipEmptyParts
+#else
+#define ENDL endl
+#define KEEPEMPTYPARTS QString::KeepEmptyParts
+#define SKIPEMPTYPARTS QString::SkipEmptyParts
+#endif
+
+#endif // QtCompat_h
diff --git a/src/Refresher.cpp b/src/Refresher.cpp
index 6f564a6..ecb3a6c 100644
--- a/src/Refresher.cpp
+++ b/src/Refresher.cpp
@@ -37,13 +37,13 @@ void Refresher::refresh()
 {
     if ( ! _items.isEmpty() && _tree )
     {
-	logDebug() << "Refreshing " << _items.size() << " items" << endl;
+	logDebug() << "Refreshing " << _items.size() << " items" << ENDL;
 
 	_tree->refresh( _items );
     }
     else
     {
-	logWarning() << "No items to refresh" << endl;
+	logWarning() << "No items to refresh" << ENDL;
     }
 
     this->deleteLater();
diff --git a/src/RpmPkgManager.cpp b/src/RpmPkgManager.cpp
index ca20822..9b804ac 100644
--- a/src/RpmPkgManager.cpp
+++ b/src/RpmPkgManager.cpp
@@ -112,10 +112,10 @@ PkgInfoList RpmPkgManager::parsePkgList( const QString & output )
     {
 	if ( ! line.isEmpty() )
 	{
-	    QStringList fields = line.split( " | ", QString::KeepEmptyParts );
+	    QStringList fields = line.split( " | ", KEEPEMPTYPARTS );
 
 	    if ( fields.size() != 3 )
-		logError() << "Invalid rpm -qa output: " << line << "\n" << endl;
+		logError() << "Invalid rpm -qa output: " << line << "\n" << ENDL;
 	    else
 	    {
 		QString name	= fields.takeFirst();
@@ -187,7 +187,7 @@ PkgFileListCache * RpmPkgManager::createFileListCache( PkgFileListCache::LookupT
 
     QStringList lines = output.split( "\n" );
     output.clear(); // Free all that text ASAP
-    logDebug() << lines.size() << " output lines" << endl;
+    logDebug() << lines.size() << " output lines" << ENDL;
 
     PkgFileListCache * cache = new PkgFileListCache( this, lookupType );
     CHECK_NEW( cache );
@@ -207,7 +207,7 @@ PkgFileListCache * RpmPkgManager::createFileListCache( PkgFileListCache::LookupT
 
 	if ( fields.size() != 2 )
 	{
-	    logError() << "Unexpected file list line: \"" << line << "\"" << endl;
+	    logError() << "Unexpected file list line: \"" << line << "\"" << ENDL;
 	}
 	else
 	{
@@ -219,7 +219,7 @@ PkgFileListCache * RpmPkgManager::createFileListCache( PkgFileListCache::LookupT
 	}
     }
 
-    logDebug() << "file list cache finished." << endl;
+    logDebug() << "file list cache finished." << ENDL;
 
     return cache;
 }
@@ -246,8 +246,8 @@ void RpmPkgManager::rebuildRpmDbWarning()
 
     if ( ! issuedWarning )
     {
-	cerr << "WARNING: rpm is very slow. Run	  sudo rpm --rebuilddb\n" << endl;
-	logWarning()  << "rpm is very slow. Run	  sudo rpm --rebuilddb"	  << endl;
+	cerr << "WARNING: rpm is very slow. Run	  sudo rpm --rebuilddb\n" << ENDL;
+	logWarning()  << "rpm is very slow. Run	  sudo rpm --rebuilddb"	  << ENDL;
     }
 
     // Add a panel message so the user is sure to see this message.
diff --git a/src/SearchFilter.cpp b/src/SearchFilter.cpp
index 2c01e6c..839896e 100644
--- a/src/SearchFilter.cpp
+++ b/src/SearchFilter.cpp
@@ -41,7 +41,7 @@ void SearchFilter::guessFilterMode()
     else if ( _pattern.startsWith( "=" ) )
     {
         _filterMode = ExactMatch;
-        _pattern.remove( QRegExp( "^=" ) );
+        _pattern = qregexp_removeIn( QRegExp( "^=" ), _pattern );
         _regexp.setPattern( _pattern );
     }
     else if ( _pattern.contains( "*.*" ) )
@@ -73,7 +73,7 @@ void SearchFilter::guessFilterMode()
 #if 0
     logDebug() << "using filter mode " << toString( _filterMode )
                << " from \"" << _pattern << "\""
-               << endl;
+               << ENDL;
 #endif
 }
 
@@ -88,14 +88,14 @@ bool SearchFilter::matches( const QString & str ) const
         case StartsWith: return str.startsWith( _pattern, caseSensitivity );
         case ExactMatch: return QString::compare( str, _pattern, caseSensitivity ) == 0;
         case Wildcard:   return _regexp.exactMatch( str );
-        case RegExp:     return str.contains( _regexp );
+        case RegExp:     return qregexp_containedIn(_regexp, str);
         case SelectAll:  return true;
         case Auto:
-            logWarning() << "Unexpected filter mode 'Auto' - assuming 'Contains'" << endl;
+            logWarning() << "Unexpected filter mode 'Auto' - assuming 'Contains'" << ENDL;
             return str.contains( _pattern );
     }
 
-    logError() << "Undefined filter mode " << (int) _filterMode << endl;
+    logError() << "Undefined filter mode " << (int) _filterMode << ENDL;
     return false;
 }
 
diff --git a/src/SelectionModel.cpp b/src/SelectionModel.cpp
index 78c5f05..9efa848 100644
--- a/src/SelectionModel.cpp
+++ b/src/SelectionModel.cpp
@@ -136,7 +136,7 @@ void SelectionModel::extendSelection( FileInfo * item, bool clear )
 
 	if ( index.isValid() )
 	{
-	    logDebug() << "Selecting " << item << endl;
+	    logDebug() << "Selecting " << item << ENDL;
 	    SelectionFlags flags = Select | Rows;
 
 	    if ( clear )
@@ -156,7 +156,7 @@ void SelectionModel::extendSelection( FileInfo * item, bool clear )
 void SelectionModel::setSelectedItems( const FileInfoSet & selectedItems )
 {
     if ( _verbose )
-	logDebug() << "Selecting " << selectedItems.size() << " items" << endl;
+	logDebug() << "Selecting " << ((quint64)selectedItems.size()) << " items" << ENDL;
 
     QItemSelection sel;
 
@@ -175,7 +175,7 @@ void SelectionModel::setSelectedItems( const FileInfoSet & selectedItems )
 void SelectionModel::setCurrentItem( FileInfo * item, bool select )
 {
     if ( _verbose )
-	logDebug() << item << " select: " << select << endl;
+	logDebug() << item << " select: " << select << ENDL;
 
     if ( select )
 	clear();
@@ -189,13 +189,13 @@ void SelectionModel::setCurrentItem( FileInfo * item, bool select )
 	if ( index.isValid() )
 	{
 	    if ( _verbose )
-		logDebug() << "Setting current to " << index << endl;
+		logDebug() << "Setting current to " << index << ENDL;
 
 	    setCurrentIndex( index, select ? ( Current | Select | Rows ) : Current );
 	}
 	else
 	{
-	    logError() << "NOT FOUND in dir tree: " << item << endl;
+	    logError() << "NOT FOUND in dir tree: " << item << ENDL;
 	}
     }
     else
@@ -216,7 +216,7 @@ void SelectionModel::setCurrentItem( const QString & path )
     if ( item )
 	setCurrentItem( item, true );
     else
-	logError() << "No item with path " << path << endl;
+	logError() << "No item with path " << path << ENDL;
 }
 
 
@@ -252,7 +252,7 @@ void SelectionModel::prepareRefresh( const FileInfoSet & refreshSet )
     }
 
     if ( _verbose )
-	logDebug() << "Selecting " << dir << endl;
+	logDebug() << "Selecting " << dir << ENDL;
 
     setCurrentItem( dir, true );
     setCurrentBranch( dir );
@@ -271,12 +271,12 @@ void SelectionModel::deletingChildNotify( FileInfo * deletedChild )
 
 void SelectionModel::dumpSelectedItems()
 {
-    logDebug() << "Current item: " << _currentItem << endl;
-    logDebug() << selectedItems().size() << " items selected" << endl;
+    logDebug() << "Current item: " << _currentItem << ENDL;
+    logDebug() << ((quint64)selectedItems().size()) << " items selected" << ENDL;
 
     foreach ( FileInfo * item, selectedItems() )
     {
-	logDebug() << "	 Selected: " << item << endl;
+	logDebug() << "	 Selected: " << item << ENDL;
     }
 
     logNewline();
diff --git a/src/Settings.cpp b/src/Settings.cpp
index a039748..6509901 100644
--- a/src/Settings.cpp
+++ b/src/Settings.cpp
@@ -103,7 +103,7 @@ void Settings::fixFileOwner( const QString & filename )
 
         if ( homeDir.isEmpty() )
         {
-            logWarning() << "Can't get home directory for UID " << uid << endl;
+            logWarning() << "Can't get home directory for UID " << uid << ENDL;
             return;
         }
 
@@ -117,7 +117,7 @@ void Settings::fixFileOwner( const QString & filename )
                            << " to UID "  << uid
                            << " and GID " << gid
                            << ": " << strerror( errno )
-                           << endl;
+                           << ENDL;
             }
             else
             {
@@ -125,7 +125,7 @@ void Settings::fixFileOwner( const QString & filename )
                 logDebug() << "Success: chown " << filename
                            << " to UID "  << uid
                            << " and GID " << gid
-                           << endl;
+                           << ENDL;
 #endif
             }
         }
@@ -136,7 +136,7 @@ void Settings::fixFileOwner( const QString & filename )
     }
     else
     {
-        logWarning() << "$SUDO_UID / $SUDO_GID not set" << endl;
+        logWarning() << "$SUDO_UID / $SUDO_GID not set" << ENDL;
     }
 }
 
@@ -200,13 +200,13 @@ void Settings::moveGroups( const QString & groupPrefix,
     if ( ! hasGroup( groupPrefix ) )
     {
 #if 0
-	logInfo() << "Migrating " << groupPrefix << "* to " << to->name() << endl;
+	logInfo() << "Migrating " << groupPrefix << "* to " << to->name() << ENDL;
 #endif
 	QStringList groups = from->findGroups( groupPrefix );
 
 	foreach ( const QString & group, groups )
 	{
-	    // logVerbose() << "  Migrating " << group << endl;
+	    // logVerbose() << "  Migrating " << group << ENDL;
 
 	    from->beginGroup( group );
 	    to->beginGroup( group );
@@ -229,7 +229,7 @@ void Settings::moveGroups( const QString & groupPrefix,
 	logVerbose() << "Target settings " << to->name()
 		     << " have group " << groupPrefix
 		     << " - nothing to migrate"
-		     << endl;
+		     << ENDL;
 #endif
     }
 
diff --git a/src/SettingsHelpers.cpp b/src/SettingsHelpers.cpp
index 0dca381..26d4288 100644
--- a/src/SettingsHelpers.cpp
+++ b/src/SettingsHelpers.cpp
@@ -32,7 +32,7 @@ namespace QDirStat
 	    color = fallback;
 #if 0
 	    logDebug() << "Using fallback for " << entryName
-		       << ": " << color.name() << endl;
+		       << ": " << color.name() << ENDL;
 #endif
 	}
 
@@ -66,7 +66,7 @@ namespace QDirStat
 	    else
 	    {
 		logError() << "ERROR in " << entryName << ": \""
-			   << rgb << "\" is not a valid color" << endl;
+			   << rgb << "\" is not a valid color" << ENDL;
 	    }
 	}
 
@@ -138,7 +138,7 @@ namespace QDirStat
 	}
 
 	logError() << "Invalid value for " << entryName
-		   << ": \"" << str << "\"" << endl;
+		   << ": \"" << str << "\"" << ENDL;
 
 	return fallback;
     }
@@ -151,7 +151,7 @@ namespace QDirStat
     {
 	if ( ! enumMapping.contains( enumValue ) )
 	{
-	    logError() << "No string for enum value " << enumValue << endl;
+	    logError() << "No string for enum value " << enumValue << ENDL;
 	    return;
 	}
 
diff --git a/src/ShowUnpkgFilesDialog.cpp b/src/ShowUnpkgFilesDialog.cpp
index 1606d85..3b9800a 100644
--- a/src/ShowUnpkgFilesDialog.cpp
+++ b/src/ShowUnpkgFilesDialog.cpp
@@ -10,8 +10,6 @@
 #include <QPushButton>
 #include <QMessageBox>
 
-#include "Qt4Compat.h"
-
 #include "ShowUnpkgFilesDialog.h"
 #include "ExistingDirCompleter.h"
 #include "ExistingDirValidator.h"
@@ -91,7 +89,7 @@ QStringList ShowUnpkgFilesDialog::ignorePatterns() const
 QStringList ShowUnpkgFilesDialog::cleanedLines( QPlainTextEdit *widget ) const
 {
     QString	text  = widget->toPlainText();
-    QStringList lines = text.split( '\n', QString::SkipEmptyParts );
+    QStringList lines = text.split( '\n', SKIPEMPTYPARTS );
     QStringList result;
 
     foreach ( QString line, lines )
diff --git a/src/SizeColDelegate.cpp b/src/SizeColDelegate.cpp
index cd5e04d..8e937f2 100644
--- a/src/SizeColDelegate.cpp
+++ b/src/SizeColDelegate.cpp
@@ -12,7 +12,6 @@
 
 #include "SizeColDelegate.h"
 #include "DirTreeModel.h"
-#include "Qt4Compat.h"
 #include "Exception.h"
 #include "FileInfo.h"
 #include "Logger.h"
@@ -93,7 +92,7 @@ void SizeColDelegate::paint( QPainter		        * painter,
                     // to reserve some space for the allocated size.
 
                     QFontMetrics fontMetrics( option.font );
-                    int allocWidth = fontMetrics.width( allocText );
+                    int allocWidth = fontMetrics.horizontalAdvance( allocText );
                     rect.setWidth( rect.width() - allocWidth );
 
                     painter->setPen( textColor );
@@ -141,13 +140,13 @@ QSize SizeColDelegate::sizeHint( const QStyleOptionViewItem & option,
             {
                 QString text = _model->data( index, Qt::DisplayRole ).toString();
                 QFontMetrics fontMetrics( option.font );
-                int width  = fontMetrics.width( text );
+                int width  = fontMetrics.horizontalAdvance( text );
                 int height = fontMetrics.height();
                 QSize size( width  + MARGIN_RIGHT + MARGIN_LEFT,
                             height + MARGIN_TOP   + MARGIN_BOTTOM );
 #if 0
                 logDebug() << "size hint for \"" << text << "\": "
-                           << size.width() << ", " << size.height() << endl;
+                           << size.width() << ", " << size.height() << ENDL;
 #endif
                 return size;
             }
@@ -194,7 +193,7 @@ void SizeColDelegate::ensureModel( const QModelIndex & index ) const
             _model = const_cast<DirTreeModel *>( constModel );
 
         if ( ! _model )
-            logError() << "WRONG_MODEL TYPE" << endl;
+            logError() << "WRONG_MODEL TYPE" << ENDL;
     }
 }
 
diff --git a/src/Subtree.cpp b/src/Subtree.cpp
index f979c67..2cfbecf 100644
--- a/src/Subtree.cpp
+++ b/src/Subtree.cpp
@@ -72,7 +72,7 @@ void Subtree::setUrl( const QString & newUrl )
     _url = newUrl;
 
     if ( ! _tree )
-        logWarning() << "NULL tree!" << endl;
+        logWarning() << "NULL tree!" << ENDL;
 }
 
 
diff --git a/src/SysUtil.cpp b/src/SysUtil.cpp
index b9c32a4..18f47ec 100644
--- a/src/SysUtil.cpp
+++ b/src/SysUtil.cpp
@@ -58,11 +58,11 @@ QString SysUtil::runCommand( const QString & commandLine,
     if ( exitCode_ret )
 	*exitCode_ret = -1;
 
-    QStringList args = commandLine.split( QRegExp( "\\s+" ) );
+    QStringList args = qregexp_splitString( QRegExp( "\\s+" ), commandLine );
 
     if ( args.size() < 1 )
     {
-	logError() << "Bad command line: \"" << commandLine << "\"" << endl;
+	logError() << "Bad command line: \"" << commandLine << "\"" << ENDL;
 	return "ERROR: Bad command line";
     }
 
@@ -86,7 +86,7 @@ QString SysUtil::runCommand( const QString &	 command,
 
     if ( ! haveCommand( command ) )
     {
-	logInfo() << "Command not found: " << command << endl;
+	logInfo() << "Command not found: " << command << ENDL;
 	return "ERROR: Command not found";
     }
 
@@ -100,7 +100,7 @@ QString SysUtil::runCommand( const QString &	 command,
     process.setProcessChannelMode( QProcess::MergedChannels ); // combine stdout and stderr
 
     if ( logCommand )
-	logDebug() << command << " " << args.join( " " ) << endl;
+	logDebug() << command << " " << args.join( " " ) << ENDL;
 
     process.start();
     bool success = process.waitForFinished( timeout_sec * 1000 );
@@ -118,18 +118,18 @@ QString SysUtil::runCommand( const QString &	 command,
 		logError() << "Command exited with exit code "
 			   << process.exitCode() << ": "
 			   << command << "\" args: " << args
-			   << endl;
+			   << ENDL;
 	    }
 	}
 	else
 	{
-	    logError() << "Command crashed: \"" << command << "\" args: " << args << endl;
+	    logError() << "Command crashed: \"" << command << "\" args: " << args << ENDL;
 	    output = "ERROR: Command crashed\n\n" + output;
 	}
     }
     else
     {
-	logError() << "Timeout or crash: \"" << command << "\" args: " << args << endl;
+	logError() << "Timeout or crash: \"" << command << "\" args: " << args << ENDL;
 	output = "ERROR: Timeout or crash\n\n" + output;
     }
 
@@ -138,9 +138,9 @@ QString SysUtil::runCommand( const QString &	 command,
         QString logOutput = output.trimmed();
 
         if ( logOutput.contains( '\n' ) )
-            logDebug() << "Output: \n" << output << endl;
+            logDebug() << "Output: \n" << output << ENDL;
         else
-            logDebug() << "Output: \"" << logOutput << "\"" << endl;
+            logDebug() << "Output: \"" << logOutput << "\"" << ENDL;
     }
 
     return output;
@@ -149,7 +149,7 @@ QString SysUtil::runCommand( const QString &	 command,
 
 void SysUtil::openInBrowser( const QString & url )
 {
-    logDebug() << "Opening URL " << url << endl;
+    logDebug() << "Opening URL " << url << ENDL;
 
     Process::startDetached( "/usr/bin/xdg-open", QStringList() << url );
 }
@@ -203,7 +203,7 @@ bool SysUtil::isBrokenSymLink( const QString & path )
 
     // Start from the symlink's parent directory
 
-    QStringList pathSegments = path.split( '/', QString::SkipEmptyParts );
+    QStringList pathSegments = path.split( '/', SKIPEMPTYPARTS );
     pathSegments.removeLast(); // We already know it's a symlink, not a directory
     QString parentPath = QString( path.startsWith( "/" ) ? "/" : "" ) + pathSegments.join( "/" );
     DirSaver dir( parentPath );
@@ -225,7 +225,7 @@ bool SysUtil::isBrokenSymLink( const QString & path )
             logWarning() << "Permission denied for one of the directories"
                          << " in symlink target " << QString::fromUtf8( target )
                          << " of symlink " << path
-                         << endl;
+                         << ENDL;
 
             return false;       // We don't know if the symlink is broken
         }
@@ -233,7 +233,7 @@ bool SysUtil::isBrokenSymLink( const QString & path )
         {
             logWarning() << "Broken symlink " << path
                          << " errno: " << strerror( errno )
-                         << endl;
+                         << ENDL;
             return true;
         }
     }
@@ -253,7 +253,7 @@ QByteArray SysUtil::readLink( const QByteArray & path )
 
     if ( len == 0 )
     {
-        logWarning() << QString::fromUtf8( path ) << " is not a symlink" << endl;
+        logWarning() << QString::fromUtf8( path ) << " is not a symlink" << ENDL;
     }
     else if ( len == targetBuf.size() )
     {
@@ -264,7 +264,7 @@ QByteArray SysUtil::readLink( const QByteArray & path )
         // workarounds and simply fail with an error in the log.
 
         logError() << "Symlink target of " << QString::fromUtf8( path )
-                   << " is longer than " << PATH_MAX << " bytes" << endl;
+                   << " is longer than " << PATH_MAX << " bytes" << ENDL;
         targetBuf.clear();
     }
     else
diff --git a/src/Trash.cpp b/src/Trash.cpp
index 72d135f..1d85889 100644
--- a/src/Trash.cpp
+++ b/src/Trash.cpp
@@ -70,7 +70,7 @@ dev_t Trash::device( const QString & path )
     if ( result < 0 )
     {
 	logError() << "stat( " << path << " ) failed: "
-		   << formatErrno() << endl;
+		   << formatErrno() << ENDL;
 
 	dev = static_cast<dev_t>( -1 );
     }
@@ -84,7 +84,7 @@ QString Trash::toplevel( const QString & rawPath )
     dev_t dev = device( rawPath );
     QFileInfo fileInfo( rawPath );
     QString path = fileInfo.canonicalPath();
-    QStringList components = path.split( "/", QString::SkipEmptyParts );
+    QStringList components = path.split( "/", SKIPEMPTYPARTS );
     QString lastPath;
 
     // Go one directory level up as long as we are on the same device
@@ -125,9 +125,9 @@ TrashDir * Trash::trashDir( const QString & path )
 	{
 	    // No $TOPDIR/.Trash: Use $TOPDIR/.Trash-$UID
 
-	    logInfo() << "No " << trashPath << endl;
+	    logInfo() << "No " << trashPath << ENDL;
 	    trashPath = topDir + QString( "/.Trash-%1" ).arg( getuid() );
-	    logInfo() << "Using " << trashPath << endl;
+	    logInfo() << "Using " << trashPath << ENDL;
 	}
 	else if ( result < 0 )
 	{
@@ -146,7 +146,7 @@ TrashDir * Trash::trashDir( const QString & path )
 		// Use $TOPDIR/.Trash/$UID
 
 		trashPath += QString( "/%1" ).arg( getuid() );
-		logInfo() << "Using " << trashPath << endl;
+		logInfo() << "Using " << trashPath << ENDL;
 	    }
 	    else // Not a directory or sticky bit not set
 	    {
@@ -167,7 +167,7 @@ TrashDir * Trash::trashDir( const QString & path )
     {
 	CAUGHT( ex );
 	logWarning() << "Falling back to home trash dir: "
-		     << _homeTrashDir->path() << endl;
+		     << _homeTrashDir->path() << ENDL;
 
 	return _homeTrashDir;
     }
@@ -190,12 +190,12 @@ bool Trash::trash( const QString & path )
     catch ( const FileException & ex )
     {
 	CAUGHT( ex );
-	logError() << "Move to trash failed for " << path << endl;
+	logError() << "Move to trash failed for " << path << ENDL;
 
 	return false;
     }
 
-    logInfo() << "Successfully moved to trash: " << path << endl;
+    logInfo() << "Successfully moved to trash: " << path << ENDL;
 
     return true;
 }
@@ -271,7 +271,7 @@ bool TrashDir::ensureDirExists( const QString & path,
     if ( dir.exists() )
 	return true;
 
-    logInfo() << "mkdir " << path << endl;
+    logInfo() << "mkdir " << path << ENDL;
     int result = mkdir( path.toUtf8(), mode );
 
     if ( result < 0 && doThrow )
@@ -294,9 +294,9 @@ void TrashDir::createTrashInfo( const QString & path,
 	THROW( FileException( trashInfo.fileName(), "Can't open " + trashInfo.fileName() ) );
 
     QTextStream str( &trashInfo );
-    str << "[Trash Info]" << endl;
-    str << "Path=" << path << endl;
-    str << "DeletionDate=" << QDateTime::currentDateTime().toString( Qt::ISODate ) << endl;
+    str << "[Trash Info]" << ENDL;
+    str << "Path=" << path << ENDL;
+    str << "DeletionDate=" << QDateTime::currentDateTime().toString( Qt::ISODate ) << ENDL;
 }
 
 
diff --git a/src/TreeWalker.cpp b/src/TreeWalker.cpp
index 1e41c0f..e60f9f7 100644
--- a/src/TreeWalker.cpp
+++ b/src/TreeWalker.cpp
@@ -34,12 +34,12 @@ qreal TreeWalker::upperPercentileThreshold( PercentileStats & stats )
 
     if ( percentile > 0 )
     {
-        logDebug() << "Threshold: " << percentile << ". percentile" << endl;
+        logDebug() << "Threshold: " << percentile << ". percentile" << ENDL;
         threshold = stats.percentile( percentile );
     }
     else
     {
-        logDebug() << "Threshold: " << MAX_RESULTS << " items" << endl;
+        logDebug() << "Threshold: " << MAX_RESULTS << " items" << ENDL;
         int index = stats.dataSize() - MAX_RESULTS;
         threshold = stats.data().at( index );
     }
@@ -61,12 +61,12 @@ qreal TreeWalker::lowerPercentileThreshold( PercentileStats & stats )
 
     if ( percentile > 0 )
     {
-        logDebug() << "Threshold: " << percentile << ". percentile" << endl;
+        logDebug() << "Threshold: " << percentile << ". percentile" << ENDL;
         threshold = stats.percentile( percentile );
     }
     else
     {
-        logDebug() << "Threshold: " << MAX_RESULTS << " items" << endl;
+        logDebug() << "Threshold: " << MAX_RESULTS << " items" << ENDL;
         int index = MAX_RESULTS;
         threshold = stats.data().at( index );
     }
diff --git a/src/TreemapTile.cpp b/src/TreemapTile.cpp
index 81a7438..e780834 100644
--- a/src/TreemapTile.cpp
+++ b/src/TreemapTile.cpp
@@ -192,7 +192,7 @@ void TreemapTile::createSquarifiedChildren( const QRectF & rect )
 {
     if ( _orig->totalAllocatedSize() == 0 )
     {
-	logError()  << "Zero totalAllocatedSize()" << endl;
+	logError()  << "Zero totalAllocatedSize()" << ENDL;
 	return;
     }
 
@@ -653,7 +653,7 @@ void TreemapTile::mousePressEvent( QGraphicsSceneMouseEvent * event )
 	    _parentView->setCurrentItem( this );
 	    break;
 
-	case Qt::MidButton:
+	case Qt::MiddleButton:
             // logDebug() << "Middle click on " << _orig << endl;
 
             // Handle item selection (with or without Ctrl) ourselves here;
@@ -703,7 +703,7 @@ void TreemapTile::mouseReleaseEvent( QGraphicsSceneMouseEvent * event )
                              << "  xx2: "         << _cushionSurface.xx2()
                              << "  yy1: "         << _cushionSurface.yy1()
                              << "  yy2: "         << _cushionSurface.yy2()
-                             << endl;
+                             << ENDL;
 #endif
 	    }
 	    break;
@@ -722,12 +722,12 @@ void TreemapTile::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * event )
     switch ( event->button() )
     {
 	case Qt::LeftButton:
-	    logDebug() << "Zooming treemap in" << endl;
+	    logDebug() << "Zooming treemap in" << ENDL;
 	    _parentView->zoomIn();
 	    break;
 
-	case Qt::MidButton:
-	    logDebug() << "Zooming treemap out" << endl;
+	case Qt::MiddleButton:
+	    logDebug() << "Zooming treemap out" << ENDL;
 	    _parentView->zoomOut();
 	    break;
 
@@ -767,7 +767,7 @@ void TreemapTile::contextMenuEvent( QGraphicsSceneContextMenuEvent * event )
 
     if ( ! selectedItems.contains( _orig ) )
     {
-	logDebug() << "Abandoning old selection" << endl;
+	logDebug() << "Abandoning old selection" << ENDL;
 	_parentView->selectionModel()->setCurrentItem( _orig, true );
 	selectedItems = _parentView->selectionModel()->selectedItems();
     }
@@ -775,7 +775,7 @@ void TreemapTile::contextMenuEvent( QGraphicsSceneContextMenuEvent * event )
     if ( _parentView->selectionModel()->verbose() )
 	_parentView->selectionModel()->dumpSelectedItems();
 
-    logDebug() << "Context menu for " << this << endl;
+    logDebug() << "Context menu for " << this << ENDL;
 
     QMenu menu;
     QStringList actions;
diff --git a/src/TreemapView.cpp b/src/TreemapView.cpp
index 748ad3d..23da0b4 100644
--- a/src/TreemapView.cpp
+++ b/src/TreemapView.cpp
@@ -369,7 +369,7 @@ void TreemapView::rebuildTreemap( FileInfo *	 newRoot,
 #if REBUILD_STOPWATCH
             logDebug() << "Treemap finished after "
                        << formatMillisec( stopwatch.elapsed() )
-                       << endl;
+                       << ENDL;
 #endif
 	}
 
@@ -559,7 +559,7 @@ void TreemapView::setCurrentItem( FileInfo * node )
 
 	if ( treemapRoot != _rootTile->orig() )	  // need to zoom out?
 	{
-	    logDebug() << "Zooming out to " << treemapRoot << " to make current item visible" << endl;
+	    logDebug() << "Zooming out to " << treemapRoot << " to make current item visible" << ENDL;
 	    rebuildTreemap( treemapRoot );
 	}
     }
diff --git a/src/UnpkgSettings.cpp b/src/UnpkgSettings.cpp
index 9c718cf..3f2972c 100644
--- a/src/UnpkgSettings.cpp
+++ b/src/UnpkgSettings.cpp
@@ -70,9 +70,9 @@ void UnpkgSettings::write()
 
 void UnpkgSettings::dump() const
 {
-    logDebug() << "startingDir:    " << startingDir << endl;
-    logDebug() << "excludeDirs:    " << excludeDirs << endl;
-    logDebug() << "ignorePatterns: " << ignorePatterns << endl;
+    logDebug() << "startingDir:    " << startingDir << ENDL;
+    logDebug() << "excludeDirs:    " << excludeDirs << ENDL;
+    logDebug() << "ignorePatterns: " << ignorePatterns << ENDL;
 }
 
 
diff --git a/src/UnreadableDirsWindow.cpp b/src/UnreadableDirsWindow.cpp
index ccd8cc4..ebaccf7 100644
--- a/src/UnreadableDirsWindow.cpp
+++ b/src/UnreadableDirsWindow.cpp
@@ -117,14 +117,14 @@ void UnreadableDirsWindow::populate( FileInfo * newSubtree )
     clear();
     _subtree = newSubtree;
 
-    logDebug() << "Locating all unreadable dirs below " << _subtree.url() << endl;
+    logDebug() << "Locating all unreadable dirs below " << _subtree.url() << ENDL;
 
     populateRecursive( newSubtree ? newSubtree : _subtree() );
     _ui->treeWidget->sortByColumn( 0, Qt::AscendingOrder );
 
     int count = _ui->treeWidget->topLevelItemCount();
     _ui->totalLabel->setText( QString( "Total: %1" ).arg( count ) );
-    logDebug() << count << " directories" << endl;
+    logDebug() << count << " directories" << ENDL;
 
     // Make sure something is selected, even if this window is not the active
     // one (for example because the user just clicked on another suffix in the
diff --git a/src/main.cpp b/src/main.cpp
index ea9dc61..8965156 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -49,7 +49,7 @@ void usage( const QStringList & argList )
 	 << "\n"
 	 << std::endl;
 
-    logError() << "FATAL: Bad command line args: " << argList.join( " " ) << endl;
+    logError() << "FATAL: Bad command line args: " << argList.join( " " ) << ENDL;
     // Simply exit(1) here results in a segfault (?).
     fatal = true;
 }
@@ -59,12 +59,12 @@ void logVersion()
 {
     logInfo() << "QDirStat-" << QDIRSTAT_VERSION
               << " built with Qt " << QT_VERSION_STR
-              << endl;
+              << ENDL;
 
 #if (QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 ))
     logWarning() << "WARNING: You are using Qt " << QT_VERSION_STR
-                 << ". This may or may not work." << endl;
-    logWarning() << "The supported Qt version for QDirStat is Qt 5.2 or newer." << endl;
+                 << ". This may or may not work." << ENDL;
+    logWarning() << "The supported Qt version for QDirStat is Qt 5.2 or newer." << ENDL;
 #endif
 }
 
@@ -82,7 +82,7 @@ bool commandLineSwitch( const QString & longName,
     {
 	argList.removeAll( longName  );
 	argList.removeAll( shortName );
-        logDebug() << "Found " << longName << endl;
+        logDebug() << "Found " << longName << ENDL;
 	return true;
     }
     else
@@ -129,7 +129,7 @@ int main( int argc, char *argv[] )
 	    if ( argList.size() == 2 )
 	    {
 		QString cacheFileName = argList.at(1);
-		logDebug() << "Reading cache file " << cacheFileName << endl;
+		logDebug() << "Reading cache file " << cacheFileName << ENDL;
 		mainWin->readCache( cacheFileName );
 	    }
 	    else
diff --git a/src/src.pro b/src/src.pro
index 9212004..237c64c 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -23,6 +23,9 @@ major_is_less_5 = $$find(QT_MAJOR_VERSION, [234])
 !isEmpty(major_is_less_5):DEFINES += 'Q_DECL_OVERRIDE=""'
 isEmpty(INSTALL_PREFIX):INSTALL_PREFIX = /usr
 
+# Qt6 Support
+greaterThan(QT_MAJOR_VERSION,5): QT += core5compat
+
 TARGET		 = qdirstat
 TARGET.files	 = qdirstat
 TARGET.path	 = $$INSTALL_PREFIX/bin
@@ -235,7 +238,7 @@ HEADERS	  =				\
 	    PopupLabel.h		\
 	    Process.h			\
 	    ProcessStarter.h		\
-	    Qt4Compat.h			\
+	    QtCompat.h			\
 	    Refresher.h			\
 	    RpmPkgManager.h		\
 	    SearchFilter.h              \
