diff --git a/LicenseManager/keyGen/keygenWidget.cc b/LicenseManager/keyGen/keygenWidget.cc
index 1b945b8aab83af4ec6643f3d9e8406b96ebb4ec1..980578535e7246afc36c0f98a1b205b1c8d8fede 100644
--- a/LicenseManager/keyGen/keygenWidget.cc
+++ b/LicenseManager/keyGen/keygenWidget.cc
@@ -45,6 +45,7 @@
 #include <QtWidgets>
 
 #include <QMessageBox>
+#include <QRegularExpression>
 
 #include "keygenWidget.hh"
 #include <iostream>
@@ -137,10 +138,11 @@ QString KeyGen::Generate(QString expiryDate) const
 }
 
 QString KeyGen::filterString(QString in) {
-    const QRegExp validChar("[a-f0-9]");
-    QString out; out.reserve(in.size());
+    const QRegularExpression validChar("[a-f0-9]");
+    QString out;
+    out.reserve(in.size());
     for (QString::iterator it = in.begin(), it_end = in.end(); it != it_end; ++it) {
-        if (validChar.exactMatch(*it))
+        if (validChar.match(*it).hasMatch())
             out.append(*it);
     }
     return out;
@@ -148,36 +150,38 @@ QString KeyGen::filterString(QString in) {
 
 std::vector<KeyGen> KeyGen::CreateFromMessyString(QString info)
 {
-	const QString dirt = "[\\s;>]*";
-	const QRegExp rx("\\b([\\w-]+)" + dirt + "((?:(?:[a-f0-9]" + dirt + "){40}){6,})\\b");
-	const QRegExp partRe("((?:[a-f0-9]" + dirt + "){40})");
+    const QString dirt = "[\\s;>]*";
+    const QRegularExpression rx("\\b([\\w-]+)" + dirt + "((?:(?:[a-f0-9]" + dirt + "){40}){6,})\\b");
+    const QRegularExpression partRe("((?:[a-f0-9]" + dirt + "){40})");
 
     std::vector<KeyGen> R;
-	int pos = 0;
-	while ((pos = rx.indexIn(info, pos)) != -1) {
-	    QString hashesStr = rx.cap(2);
+    QRegularExpressionMatch rxMatch;
+    int pos = 0;
+    while ((pos = info.indexOf(rx, pos, &rxMatch)) != -1) {
+        QString hashesStr = rxMatch.captured(2);
         QStringList hashes;
+        QRegularExpressionMatch partReMatch;
         int hashPos = 0;
-	    while ((hashPos = partRe.indexIn(hashesStr, hashPos)) != -1) {
-	        hashes.append(filterString(partRe.cap(1)));
-	        hashPos += partRe.matchedLength();
-	    }
-
-	    QStringList macList;
-	    std::copy(hashes.begin() + 4, hashes.end() - 1, std::back_inserter(macList));
-
-		KeyGen K(rx.cap(1),
-		        hashes[0],
-		        hashes[1],
-		        hashes[2],
-		        hashes[3],
-		        macList,
-		        hashes[hashes.count()-1]);
-		R.push_back(K);
-		pos += rx.matchedLength();
-	}
+        while ((hashPos = hashesStr.indexOf(partRe, hashPos, &partReMatch)) != -1) {
+            hashes.append(filterString(partReMatch.captured(1)));
+            hashPos += partReMatch.capturedLength(1);
+        }
+
+        QStringList macList;
+        std::copy(hashes.begin() + 4, hashes.end() - 1, std::back_inserter(macList));
+
+        KeyGen K(rxMatch.captured(1),
+                 hashes[0],
+                 hashes[1],
+                 hashes[2],
+                 hashes[3],
+                 macList,
+                 hashes[hashes.count() - 1]);
+        R.push_back(K);
+        pos += rxMatch.capturedLength(0);
+    }
 
-	return R;
+    return R;
 }
 
 KeyGenWidget::KeyGenWidget(QMainWindow *parent)
@@ -253,20 +257,19 @@ void KeyGenWidget::slotAnalyze() {
 	keygens_ = KeyGen::CreateFromMessyString(inputData);
 
 	keyList->clear();
-	for (std::vector<KeyGen>::const_iterator it = keygens_.begin(), it_end = keygens_.end();
-	        it != it_end; ++it) {
+    for (const auto& keygen : keygens_) {
         QListWidgetItem *newItem = new QListWidgetItem( keyList);
-        newItem->setText(it->name);
+        newItem->setText(keygen.name);
         newItem->setHidden(false);
-        KeyGen::ValidationResult r = it->isValid();
+        KeyGen::ValidationResult r = keygen.isValid();
         if (!r)
-          newItem->setTextColor(QColor(255, 0, 0));
+          newItem->setForeground(QColor(255, 0, 0));
         else if (r == KeyGen::LATIN1)
-          newItem->setTextColor(QColor(128, 128, 0));
+          newItem->setForeground(QColor(128, 128, 0));
 	}
 
 	generateLocalButton->setVisible(false);
-	generateAllButton->setVisible(keygens_.size());
+    generateAllButton->setVisible(!keygens_.empty());
 }
 
 void KeyGenWidget::slotSplit() {
@@ -274,7 +277,7 @@ void KeyGenWidget::slotSplit() {
   QString inputData = requestData->toPlainText();
   
   // Split with ;
-  QStringList data = inputData.split(";",QString::SkipEmptyParts);
+  QStringList data = inputData.split(";",Qt::SkipEmptyParts);
   
   QString newText = data.join("\n");
   
diff --git a/PythonInterpreter/PythonInterpreter.cc b/PythonInterpreter/PythonInterpreter.cc
index 2c6053d3d595adc090a6c8975125bcee88751f22..492c57acf07bb0e80b8a5e1ad9b80680f4a14395 100644
--- a/PythonInterpreter/PythonInterpreter.cc
+++ b/PythonInterpreter/PythonInterpreter.cc
@@ -166,8 +166,15 @@ void PythonInterpreter::initPython() {
       std::cerr << "Importing OpenFlipper core module ...";
     #endif
 
-    py::module of_module(py::module::import("openflipper"));
-    main_namespace["openflipper"] = of_module;
+    try{
+      py::module of_module(py::module::import("openflipper"));
+      main_namespace["openflipper"] = of_module;
+    }
+    catch (py::error_already_set &e)
+    {
+      pyError(e.what());
+      return;
+    }
 
     #ifdef PYTHON_DEBUG
       std::cerr << " Done" << std::endl;
@@ -185,8 +192,16 @@ void PythonInterpreter::initPython() {
         std::cerr << "Importing "+ pythonPlugins[i].toStdString() + " module ...";
       #endif
 
-      py::module om_module(py::module::import(pythonPlugins[i].toStdString().c_str()));
-      main_namespace[pythonPlugins[i].toStdString().c_str()] = om_module;
+      //try catching an error here for debugging purposes
+      try{
+        py::module om_module(py::module::import(pythonPlugins[i].toStdString().c_str()));
+        main_namespace[pythonPlugins[i].toStdString().c_str()] = om_module;
+      }
+      catch (py::error_already_set &e)
+      {
+        pyError(e.what());
+        return;
+      }
 
       #ifdef PYTHON_DEBUG
         std::cerr << " Done" << std::endl;
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 2897728c4d77dc974c5ec02c185003ba3c0123ab..6dbab6e8d7adebb380127a079e99729c1b8b78b0 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -95,14 +95,15 @@ if (NOT DISABLE_OPENFLIPPER_PYTHON_SYSTEM)
 endif()
 
 if (NOT DISABLE_OPENFLIPPER_PYTHON_SYSTEM)
-  find_package(Python3 COMPONENTS Interpreter Development)
-
+  if (NOT Python3_FOUND)
+      find_package(Python3 3.11 COMPONENTS Interpreter Development)
+  endif()
   if (NOT TARGET pybind11::module OR NOT TARGET pybind11::embed)
       include(FetchContent)
       FetchContent_Declare(
         pybind11
         GIT_REPOSITORY https://github.com/pybind/pybind11
-        GIT_TAG v2.10.4
+        GIT_TAG v2.13.6
       )
       set(FETCHCONTENT_FULLY_DISCONNECTED OFF)
       FetchContent_MakeAvailable(pybind11)
diff --git a/cmake/fixbundle.cmake.in b/cmake/fixbundle.cmake.in
index 73698d927af4093b8416762dfa925fd8bcded8b1..cb4da4d149af606944ea8e2e48f2ddc67ffb8e81 100644
--- a/cmake/fixbundle.cmake.in
+++ b/cmake/fixbundle.cmake.in
@@ -58,3 +58,9 @@ fixup_bundle (@CMAKE_BINARY_DIR@/Build/@OPENFLIPPER_PRODUCT_STRING@.app "${_plug
 # create qt plugin configuration file
 file(WRITE "@CMAKE_BINARY_DIR@/Build/@OPENFLIPPER_PRODUCT_STRING@.app/Contents/Resources/qt.conf" "[Paths]\nPlugins = Resources/QtPlugins")
 
+# Sign all Libraries (needed for Code Signing) 
+execute_process(COMMAND find "@CMAKE_BINARY_DIR@/Build/@OPENFLIPPER_PRODUCT_STRING@.app/Contents/Resources/QtPlugins/" -type f -name "*.dylib" -exec codesign --force --sign - --timestamp=none {} \;)
+execute_process(COMMAND find "@CMAKE_BINARY_DIR@/Build/@OPENFLIPPER_PRODUCT_STRING@.app/Contents/Libraries/" -type f -name "*.dylib" -exec codesign --force --sign - --timestamp=none {} \;)
+
+# Sign all Frameworks (Also needed for Code Signing)
+execute_process(COMMAND find "@CMAKE_BINARY_DIR@/Build/@OPENFLIPPER_PRODUCT_STRING@.app/Contents/Frameworks/" -type d -name "*.framework" -exec codesign --force --sign - --timestamp=none {} \;)
diff --git a/libs_required/ACG/CMakeLists.txt b/libs_required/ACG/CMakeLists.txt
index df8c5814c0a073e99d8bcc749bd384d600e49d80..4b16dbb4034e75015e1190f5b218bb8bca8884f7 100644
--- a/libs_required/ACG/CMakeLists.txt
+++ b/libs_required/ACG/CMakeLists.txt
@@ -93,6 +93,7 @@ set ( headers
     Math/QuaternionT.hh
     Math/VectorT.hh
     QtWidgets/QtApplication.hh
+    QtWidgets/QtChartHistogram.hh
     QtWidgets/QtClippingDialog.hh
     QtWidgets/QtColorChooserButton.hh
     QtWidgets/QtColorTranslator.hh
@@ -209,6 +210,7 @@ set (sources
     GL/stipple_alpha.cc
     Math/BSplineBasis.cc
     QtWidgets/QtApplication.cc
+    QtWidgets/QtChartHistogram.cc
     QtWidgets/QtClippingDialog.cc
     QtWidgets/QtColorChooserButton.cc
     QtWidgets/QtColorTranslator.cc
@@ -364,7 +366,7 @@ target_link_libraries ( ACG  ${OPENMESH_LIBRARIES}
                              ${GLEW_TARGET} )
 
 if (QT6_FOUND)
-  target_link_libraries( ACG ${QT_TARGET}::OpenGLWidgets )
+  target_link_libraries( ACG ${QT_TARGET}::OpenGLWidgets ${QT_TARGET}::Charts)
 endif()
 
 
@@ -377,7 +379,7 @@ include(FetchContent)
 FetchContent_Declare(
   googletest
   GIT_REPOSITORY https://github.com/google/googletest.git
-  GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 # v1.14.0
+  GIT_TAG b514bdc898e2951020cbdca1304b75f5950d1f59 # v1.15.2
 )
 if(WIN32)
     # avoid linking errors, cf https://stackoverflow.com/questions/12540970/how-to-make-gtest-build-mdd-instead-of-mtd-by-default-using-cmake
@@ -436,7 +438,7 @@ if ( ACG_BUILD_UNIT_TESTS )
   )
 
   target_link_libraries(ACG_tests
-    GTest::gtest GTest::gtest_main ${OPENMESH_LIBRARIES} ACG ${GLEW_TARGET}
+    GTest::gtest GTest::gtest_main ${OPENMESH_LIBRARIES} ACG ${GLEW_TARGET} Qt6::Charts
   )
 
   add_test(NAME AllTestsIn_ACG_tests COMMAND ${OUT_DIR}/ACG_tests)
diff --git a/libs_required/ACG/QtWidgets/QtChartHistogram.cc b/libs_required/ACG/QtWidgets/QtChartHistogram.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d0d987a6a6e7284df0b96b9cc50ae6c21faf0b0e
--- /dev/null
+++ b/libs_required/ACG/QtWidgets/QtChartHistogram.cc
@@ -0,0 +1,293 @@
+/*===========================================================================*\
+ *                                                                           *
+ *                              OpenFlipper                                  *
+ *           Copyright (c) 2001-2024, RWTH-Aachen University                 *
+ *           Department of Computer Graphics and Multimedia                  *
+ *                          All rights reserved.                             *
+ *                            www.openflipper.org                            *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenFlipper.                                         *
+ *---------------------------------------------------------------------------*
+ *                                                                           *
+ * Redistribution and use in source and binary forms, with or without        *
+ * modification, are permitted provided that the following conditions        *
+ * are met:                                                                  *
+ *                                                                           *
+ * 1. Redistributions of source code must retain the above copyright notice, *
+ *    this list of conditions and the following disclaimer.                  *
+ *                                                                           *
+ * 2. Redistributions in binary form must reproduce the above copyright      *
+ *    notice, this list of conditions and the following disclaimer in the    *
+ *    documentation and/or other materials provided with the distribution.   *
+ *                                                                           *
+ * 3. Neither the name of the copyright holder nor the names of its          *
+ *    contributors may be used to endorse or promote products derived from   *
+ *    this software without specific prior written permission.               *
+ *                                                                           *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
+ *                                                                           *
+\*===========================================================================*/
+
+
+//=============================================================================
+//
+//  CLASS QtChart - IMPLEMENTATION
+//
+//=============================================================================
+
+//== INCLUDES =================================================================
+
+#include "QtChartHistogram.hh"
+#include <QChart>
+#include <QValueAxis>
+#include <QBarSeries>
+#include <QLineSeries>
+#include <QStackedBarSeries>
+#include <QBarCategoryAxis>
+#include <QBarSet>
+#include <QChartView>
+#include <QRubberBand>
+
+#include <cfloat>
+
+#include <Utils/ColorCoder.hh>
+//== NAMESPACES ===============================================================
+
+namespace ACG {
+namespace QtWidgets {
+
+//This class creates a Histogram in a QChartView. The Histogram can be zoomed in and out by using a rubberband. 
+//The x-axis values are updated when the rubberband is moved. The y-axis values are updated automatically.
+//The Histogram can be color coded.
+//!!!!!IMPORTANT!!!! This class allows for colored bars in the Histogram, which is not possible with QCharts alone. 
+//In order to achieve that we have to create a new QBarSet for each bar. And "stack" them on top of each other.
+//This is not very efficient and should be avoided if possible. In addition to that, the x-axis is detached in order to allow 
+//a correct zoom behavior. (This is also very hacky and should be avoided but I didnt see any other way to make it work)
+//However I think there is a bug in the QCharts library and as soon as it is fixed, the workaround is not needed anymore..
+QtChartHistogram::QtChartHistogram(QString title_X, QString title_Y, const std::vector<double>& _values, QWidget* _parent) : QChartView(_parent)
+{
+    //create chart
+    chart_ = new QChart();
+  
+    //create x-axis 
+    axisX = new QValueAxis();
+    axisX->setTitleText(title_X);
+    axisX->setRange(0, 100);
+    chart_->addAxis(axisX, Qt::AlignBottom);
+
+    // Create y-axis
+    axisY = new QValueAxis();
+    axisY->setTitleText(title_Y);
+    axisY->setRange(0, 500);
+    chart_->addAxis(axisY, Qt::AlignLeft);
+
+    // Set the chart to the chartView(this widget)
+    setChart(chart_);
+    setRubberBand(QChartView::RectangleRubberBand);
+
+    // Create the series and attach it to the chart
+    series = new QStackedBarSeries();
+    chart_->addSeries(series);
+    series->attachAxis(axisY);
+
+    // Set the values
+    setValues(_values);
+
+    // Get the rubberband from the chartView
+    rubberBand_ = findChild<QRubberBand *>();
+    rubberBand_->installEventFilter(this);
+
+    // Install eventfilter for the chartView, so we can update the cursor type if inside the chart 
+    this->installEventFilter(this);
+
+    // Connect the rubberband signal to the slot
+    connect(this, &QtChartHistogram::rubberBandChanged, this, &QtChartHistogram::rubberBandChangedSlot);
+    
+    // Set the render hint to antialiasing, so the chart looks nicer
+    setRenderHint(QPainter::Antialiasing);
+
+    // Hide the legend
+    chart_->legend()->setVisible(false);
+
+    replot();
+
+}
+
+//destructor 
+QtChartHistogram::~QtChartHistogram()
+{}
+
+//------------------------------------------------------------------------------
+
+// Override the mouseReleaseEvent to emit a signal when the right mouse button is released 
+void QtChartHistogram::mouseReleaseEvent(QMouseEvent *event)
+{
+    if (event->button() == Qt::RightButton) {
+       // There might be a more elegant way to reset the zoom, but this is simple and works well
+       replot();
+    }
+    else {
+       QChartView::mouseReleaseEvent(event);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Event filter
+bool QtChartHistogram::eventFilter(QObject *obj, QEvent *event)
+{
+    if (obj == this && event->type() == QEvent::Enter){
+        // if we are inside the chart, we wanna change the cursor to a cross
+        setCursor(Qt::CrossCursor);
+    }
+    else if (obj == chart_ && event->type() == QEvent::Leave){
+        // if we leave the chart, we wanna change the cursor back to the default
+        setCursor(Qt::ArrowCursor);
+    }
+
+    // if we use rubberband on the chartView, we wanna update the x-axis values (as the x-axis is detached from the series)
+    if (obj == rubberBand_ && (event->type() == QEvent::HideToParent)){
+        //transform the rubberband coordinates to the x-axis values
+        auto rubberminX = rubberBand_->geometry().x() - chart_->plotArea().x();
+        auto rubbermaxX = rubberBand_->geometry().x() - chart_->plotArea().x() + rubberBand_->geometry().width();
+        
+        emit rubberBandChanged(rubberminX, rubbermaxX);
+    } 
+    return false;
+
+}
+
+//------------------------------------------------------------------------------
+
+void QtChartHistogram::rubberBandChangedSlot(double rubberminX, double rubbermaxX)
+{
+
+  //get the x values of the chart
+  qreal minX = static_cast<const QValueAxis*>(chart_->axes(Qt::Horizontal).back())->min();
+  qreal maxX = static_cast<const QValueAxis*>(chart_->axes(Qt::Horizontal).back())->max();
+  
+  //compute the new x-axis values
+  double newMin = minX + ((rubberminX)/ chart_->plotArea().width()) * (maxX - minX);
+  double newMax = minX + (rubbermaxX / chart_->plotArea().width()) * (maxX - minX);
+
+  //set the new x-axis values
+  dynamic_cast<QValueAxis*>(chart_->axes(Qt::Horizontal).back())->setRange(newMin, newMax);
+
+}
+
+//------------------------------------------------------------------------------
+
+// Set the values
+void QtChartHistogram::setValues(const std::vector<double>& _values)
+{
+  values_ = _values;
+}
+
+//------------------------------------------------------------------------------
+
+// Replot the chart
+void QtChartHistogram::replot()
+{
+    // Create intervals
+    const int intervalCount = 101;
+
+    std::vector<int> intervals(intervalCount, 0);
+
+    double realMin = FLT_MAX;
+    double realMax = -FLT_MAX;
+
+    // Compute realMin and realMax
+    for (const auto& value : values_) {
+        if (!std::isnan(value)) { // Check for NaN
+            realMin = std::min(realMin, value);
+            realMax = std::max(realMax, value);
+        }
+    }
+
+    // Check for the edge case where realMin equals realMax
+    // In this case we have only one value and we want to create some margins around the value
+    // In order to display the value correctly in the histogram
+    if (realMin == realMax) {
+        realMax = realMin + 50;
+        realMin = realMin - 50;
+    }
+
+    float width = (realMax - realMin) / intervalCount;
+
+    // Populate the intervals
+    for (const auto& value : values_) {
+        if (!std::isnan(value)) { // Check for NaN
+            int index = std::min(intervalCount - 1, static_cast<int>((value - realMin) / width));
+            intervals[index]++;
+        }
+    }
+    
+    std::vector<QColor> colors;
+
+    // If we want to color code the histogram
+    if (colorCoding_){
+        // Create Colors for the intervals
+        ACG::ColorCoder cCoder(realMin,realMax);
+        for (int i = 0; i < intervalCount; i++) {
+            const double intervalCenter = realMin + (i + 0.5) * width;
+            colors.push_back(cCoder.color_qcolor(intervalCenter));
+        }
+    } 
+    else {
+        // Use just one color
+        for (int i = 0; i < intervalCount; i++) {
+            const double intervalCenter = realMin + (i + 0.5) * width;
+            colors.push_back(Qt::black);
+        }
+    } 
+    
+    // Remove the old series and create a new one. For some reason you have to remove the series. Simply clearing the series and appending new values does not work.
+    chart_->removeSeries(series);
+
+    // Clear the series
+    series = new QStackedBarSeries();
+    
+    // Set the axes range
+    axisX->setRange(realMin, realMax);
+    axisY->setRange(0, *std::max_element(intervals.begin(), intervals.end()));
+
+    // Create for each Bar a new set. This is needed to add different colors to each bar.
+    for (int i = 0; i < intervalCount; i++) {
+        QBarSet* set = new QBarSet("Values");
+        for (int j = 0; j < intervalCount; j++){
+            if (j == i){
+            *set << intervals[j];
+            set->setColor(colors[j]);
+            }
+            else{
+            *set << 0;
+            }
+        }
+        set->setColor(colors[i]);
+        series->append(set);
+    }
+    chart_->addSeries(series);
+    series->attachAxis(axisY);
+}
+
+void QtChartHistogram::setColorCoding(bool _colorCoding)
+{
+    colorCoding_ = _colorCoding;
+}
+
+} // namespace QtWidgets
+
+} // namespace ACG
+
+
diff --git a/libs_required/ACG/QtWidgets/QtChartHistogram.hh b/libs_required/ACG/QtWidgets/QtChartHistogram.hh
new file mode 100644
index 0000000000000000000000000000000000000000..30a636c2a732b5c6fe78596f848fba94fd551ba2
--- /dev/null
+++ b/libs_required/ACG/QtWidgets/QtChartHistogram.hh
@@ -0,0 +1,125 @@
+/*===========================================================================*\
+ *                                                                           *
+ *                              OpenFlipper                                  *
+ *           Copyright (c) 2001-2024, RWTH-Aachen University                 *
+ *           Department of Computer Graphics and Multimedia                  *
+ *                          All rights reserved.                             *
+ *                            www.openflipper.org                            *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenFlipper.                                         *
+ *---------------------------------------------------------------------------*
+ *                                                                           *
+ * Redistribution and use in source and binary forms, with or without        *
+ * modification, are permitted provided that the following conditions        *
+ * are met:                                                                  *
+ *                                                                           *
+ * 1. Redistributions of source code must retain the above copyright notice, *
+ *    this list of conditions and the following disclaimer.                  *
+ *                                                                           *
+ * 2. Redistributions in binary form must reproduce the above copyright      *
+ *    notice, this list of conditions and the following disclaimer in the    *
+ *    documentation and/or other materials provided with the distribution.   *
+ *                                                                           *
+ * 3. Neither the name of the copyright holder nor the names of its          *
+ *    contributors may be used to endorse or promote products derived from   *
+ *    this software without specific prior written permission.               *
+ *                                                                           *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
+ *                                                                           *
+\*===========================================================================*/
+
+
+//=============================================================================
+//
+//  CLASS QtChart - IMPLEMENTATION
+//
+//=============================================================================
+
+//== INCLUDES =================================================================
+#include <QChart>
+#include <QBarSeries>
+#include <QLineSeries>
+#include <QStackedBarSeries>
+#include <QChartView>
+#include <QRubberBand>
+#include <cfloat>
+#include <QValueAxis>
+
+
+#include <QBarSet>
+
+
+
+//== NAMESPACES ===============================================================
+namespace ACG {
+namespace QtWidgets {
+
+//This class creates a Histogram in a QChartView. The Histogram can be zoomed in and out by using a rubberband. 
+//The x-axis values are updated when the rubberband is moved. The y-axis values are updated automatically.
+//The Histogram can be color coded.
+//!!!!!IMPORTANT!!!! This class allows for colored bars in the Histogram, which is not possible with QCharts alone. 
+//In order to achieve that we have to create a new QBarSet for each bar. And "stack" them on top of each other.
+//This is not very efficient and should be avoided if possible. In addition to that, the x-axis is detached in order to allow 
+//a correct zoom behavior. (This is also very hacky and should be avoided but I didnt see any other way to make it work)
+//However I think there is a bug in the QCharts library and as soon as it is fixed, the workaround is not needed anymore.
+class QtChartHistogram : public QChartView {
+    Q_OBJECT
+
+public:
+
+    /// Default constructor
+    explicit QtChartHistogram(QString title_X, QString title_Y, const std::vector<double>& _values, QWidget* _parent = 0);
+
+    /// Destructor
+    ~QtChartHistogram();
+
+    void setColorCoding(bool _colorCoding);
+
+    void setValues(const std::vector<double>& _values);
+
+    void replot();
+
+public slots:
+
+  void rubberBandChangedSlot(double rubber_min, double rubber_max);
+
+signals:  
+
+  void rubberBandChanged(double rubber_min, double rubber_max);
+
+private:
+
+    //variables
+    QChart* chart_;
+    QValueAxis* axisX;
+    QValueAxis* axisY;
+    QStackedBarSeries* series;
+    QRubberBand* rubberBand_;
+    bool colorCoding_;
+    std::vector<double> values_;
+
+protected:
+
+    bool eventFilter(QObject *obj, QEvent *event) override;
+    void mouseReleaseEvent(QMouseEvent *event) override;
+
+};
+
+} // namespace QtWidgets
+} // namespace ACG
+
+
+
+
+
diff --git a/libs_required/ACG/QwtWidgets/QwtHistogramm.hh b/libs_required/ACG/QwtWidgets/QwtHistogramm.hh
index 662d9b9e837c0240870dd8c5863f1ec502c0e3e4..a055b285b3df67730d3284a3da52454cad94991e 100644
--- a/libs_required/ACG/QwtWidgets/QwtHistogramm.hh
+++ b/libs_required/ACG/QwtWidgets/QwtHistogramm.hh
@@ -60,7 +60,7 @@ class QString;
  * via HistogramItem::setData(). Additionally you can set colors for each bar,
  * which are provided via HistogramItem::setColors()
  */
-class ACGDLLEXPORT Histogram: public QwtPlotItem
+class [[deprecated("Use QCharts instead!")]] ACGDLLEXPORT Histogram: public QwtPlotItem
 {
 public:
     /// Constructor
diff --git a/tests/run_tests.py b/tests/run_tests.py
index d1c5f65d9b244c0a680016b1bdc44c7f19444fc1..f2444d19ae0ad04eb4a0eb76b11e6e01b9f83488 100644
--- a/tests/run_tests.py
+++ b/tests/run_tests.py
@@ -156,7 +156,7 @@ elif sys.platform == "win32":
 
     src_files = os.listdir("../Build")
     for file_name in src_files:
-        full_file_name = os.path.join("../Build", file_name)
+        full_file_name = os.path.join("..\Build", file_name)
         if os.path.isfile(full_file_name) and full_file_name.endswith(".dll"):
            print("Copyining" + full_file_name + " to testBinaries")
            shutil.copy(full_file_name, "testBinaries")
@@ -184,7 +184,7 @@ print("Working directory for test execution: " + os.getcwd(), flush=True)
 
 # call ctest
 ctest = subprocess.run(
-    [ctest_executable, "-C", "Release", "--no-tests=error", "--no-compress-output", "--output-on-failure","--gtest_output=xml:report.xml"])
+    [ctest_executable, "-C", "Debug", "--no-tests=error", "--no-compress-output", "--output-on-failure","--output-junit","report.xml"])
 
 print("Return Code: ", ctest.returncode)
 
diff --git a/widgets/glWidget/QtBaseViewer.cc b/widgets/glWidget/QtBaseViewer.cc
index 89b70742e6dcde77ea273b281561de2b308ebfdd..601c3580323b7fa3f6c904845260e7e85bb447d7 100644
--- a/widgets/glWidget/QtBaseViewer.cc
+++ b/widgets/glWidget/QtBaseViewer.cc
@@ -1117,6 +1117,8 @@ void glViewer::paintGL(double _aspect)
 void glViewer::resizeEvent(QGraphicsSceneResizeEvent *)
 {
   const auto current_screen = QGuiApplication::screenAt(geometry().center().toPoint());
+  if(!current_screen)
+      return;
   /// update device pixel ratio. getters in this class will make use of it
   /// so we only need to multiply scene information
   properties()->setDevicePixelRatio(current_screen->devicePixelRatio());