From 18082cbef53a7a830316420b3a5709e2636b6fc5 Mon Sep 17 00:00:00 2001 From: Mark Watkins Date: Sat, 10 May 2014 10:50:35 +1000 Subject: [PATCH] Replace pixmap caching code with Qt's build in stuff --- sleepyhead/Graphs/gGraph.cpp | 20 +-- sleepyhead/Graphs/gGraph.h | 10 +- sleepyhead/Graphs/gGraphView.cpp | 275 +++++++++---------------------- sleepyhead/Graphs/gGraphView.h | 47 ++++-- sleepyhead/Graphs/gLineChart.cpp | 12 +- sleepyhead/Graphs/gLineChart.h | 2 + sleepyhead/Graphs/gXAxis.cpp | 1 + sleepyhead/Graphs/gXAxis.h | 1 + sleepyhead/Graphs/gYAxis.cpp | 3 + sleepyhead/mainwindow.cpp | 4 +- 10 files changed, 124 insertions(+), 251 deletions(-) diff --git a/sleepyhead/Graphs/gGraph.cpp b/sleepyhead/Graphs/gGraph.cpp index 55ba4059..5c5dbc2b 100644 --- a/sleepyhead/Graphs/gGraph.cpp +++ b/sleepyhead/Graphs/gGraph.cpp @@ -26,8 +26,6 @@ QFont *defaultfont = nullptr; QFont *mediumfont = nullptr; QFont *bigfont = nullptr; QHash images; -bool fbo_unsupported = false; -QGLFramebufferObject *fbo = nullptr; static bool globalsInitialized = false; @@ -110,17 +108,6 @@ void DestroyGraphGlobals() delete i.value(); } - // Clear the frame buffer object. - if (fbo) { - if (fbo->isBound()) { - fbo->release(); - } - - delete fbo; - fbo = nullptr; - fbo_unsupported = true; // just in case shutdown order gets messed up - } - globalsInitialized = false; } @@ -268,8 +255,7 @@ void gGraph::qglColor(QColor col) m_graphview->qglColor(col); } -void gGraph::renderText(QString text, int x, int y, float angle, QColor color, QFont *font, - bool antialias) +void gGraph::renderText(QString text, int x, int y, float angle, QColor color, QFont *font, bool antialias) { m_graphview->AddTextQue(text, x, y, angle, color, font, antialias); } @@ -1081,9 +1067,9 @@ void gGraph::ZoomX(double mult, int origin_px) //updateSelectionTime(max-min); } -void gGraph::DrawTextQue() +void gGraph::DrawTextQue(QPainter &painter) { - m_graphview->DrawTextQue(); + m_graphview->DrawTextQue(painter); } // margin recalcs.. diff --git a/sleepyhead/Graphs/gGraph.h b/sleepyhead/Graphs/gGraph.h index 999426d3..3ae41dbc 100644 --- a/sleepyhead/Graphs/gGraph.h +++ b/sleepyhead/Graphs/gGraph.h @@ -11,11 +11,11 @@ #define graphs_ggraph_h #include -#include #include #include #include #include +#include #include "Graphs/layer.h" @@ -26,14 +26,10 @@ extern QFont *defaultfont; extern QFont *mediumfont; extern QFont *bigfont; extern QHash images; -extern bool fbo_unsupported; -extern QGLFramebufferObject *fbo; bool InitGraphGlobals(); void DestroyGraphGlobals(); -const int max_fbo_width = 2048; -const int max_fbo_height = 2048; const int mouse_movement_threshold = 6; /*! \class gGraph @@ -41,7 +37,7 @@ const int mouse_movement_threshold = 6; */ class gGraph : public QObject { - Q_OBJECT; + Q_OBJECT public: friend class gGraphView; @@ -226,7 +222,7 @@ class gGraph : public QObject void setGroup(short group) { m_group = group; } //! \brief Forces the main gGraphView object to draw all Text Components - void DrawTextQue(); + void DrawTextQue(QPainter &painter); //! \brief Sends supplied day object to all Graph layers so they can precalculate stuff void setDay(Day *day); diff --git a/sleepyhead/Graphs/gGraphView.cpp b/sleepyhead/Graphs/gGraphView.cpp index 0b07961b..0a87ab87 100644 --- a/sleepyhead/Graphs/gGraphView.cpp +++ b/sleepyhead/Graphs/gGraphView.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) # include @@ -38,11 +39,6 @@ #include "SleepLib/profiles.h" extern MainWindow *mainwin; - -// for profiling purposes, a count of lines drawn in a single frame -int lines_drawn_this_frame = 0; -int quads_drawn_this_frame = 0; - extern QLabel *qstatus2; gToolTip::gToolTip(gGraphView *graphview) @@ -136,9 +132,6 @@ void gToolTip::paint(QPainter &painter) //actually paints it. rect.setHeight(h); } - lines_drawn_this_frame += 4; - quads_drawn_this_frame += 1; - QBrush brush(QColor(255, 255, 128, 230)); brush.setStyle(Qt::SolidPattern); painter.setBrush(brush); @@ -248,11 +241,9 @@ gGraphView::gGraphView(QWidget *parent, gGraphView *shared) { m_shared = shared; m_sizer_index = m_graph_index = 0; - m_textque_items = 0; m_button_down = m_graph_dragging = m_sizer_dragging = false; m_lastypos = m_lastxpos = 0; m_horiz_travel = 0; - pixmap_cache_size = 0; m_minx = m_maxx = 0; m_day = nullptr; m_selected_graph = nullptr; @@ -278,13 +269,6 @@ gGraphView::gGraphView(QWidget *parent, gGraphView *shared) //gt->start(); }*/ - //vlines=new gVertexBuffer(20000,GL_LINES); - - //stippled->setSize(1.5); - //stippled->forceAntiAlias(false); - //lines->setSize(1.5); - //backlines->setSize(1.5); - setFocusPolicy(Qt::StrongFocus); m_showsplitter = true; timer = new QTimer(this); @@ -307,6 +291,7 @@ gGraphView::gGraphView(QWidget *parent, gGraphView *shared) m_blockUpdates = false; use_pixmap_cache = true; + // pixmapcache.setCacheLimit(10240*2); #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) m_dpr = this->windowHandle()->devicePixelRatio(); #else @@ -337,14 +322,6 @@ gGraphView::~gGraphView() m_graphs[i]=NULL; } - QHash::iterator it; - - for (it = pixmap_cache.begin(); it != pixmap_cache.end(); it++) { - delete(*it); - } - - pixmap_cache.clear(); - delete m_tooltip; m_graphs.clear(); @@ -359,15 +336,20 @@ gGraphView::~gGraphView() bool gGraphView::usePixmapCache() { //use_pixmap_cache is an overide setting - return use_pixmap_cache & PROFILE.appearance->usePixmapCaching(); + return PROFILE.appearance->usePixmapCaching(); } +#define CACHE_DRAWTEXT +#ifndef CACHE_DRAWTEXT // Render all qued text via QPainter method void gGraphView::DrawTextQue(QPainter &painter) { int w, h; - for (int i = 0; i < m_textque_items; i++) { + // not sure if global antialiasing would be better.. + //painter.setRenderHint(QPainter::TextAntialiasing, PROFILE.appearance->antiAliasing()); + int m_textque_items = m_textque.size(); + for (int i = 0; i < m_textque_items; ++i) { TextQue &q = m_textque[i]; painter.setPen(q.color); painter.setRenderHint(QPainter::TextAntialiasing, q.antialias); @@ -387,188 +369,88 @@ void gGraphView::DrawTextQue(QPainter &painter) painter.rotate(+q.angle); painter.translate(-q.x, -q.y); } - + strings_drawn_this_frame++; q.text.clear(); } - m_textque_items = 0; + m_textque.clear(); } +#else // Render graphs with QPainter or pixmap caching, depending on preferences -void gGraphView::DrawTextQue() +void gGraphView::DrawTextQue(QPainter &painter) { - const qint64 expire_after_ms = 4000; // expire string pixmaps after this many milliseconds - //const qint64 under_limit_cache_bonus=30000; // If under the limit, give a bonus to the millisecond timeout. - const qint32 max_pixmap_cache = 4 * - 1048576; // Maximum size of pixmap cache (it can grow over this, but only temporarily) - - quint64 ti = 0, exptime = 0; - int w, h; - QHash::iterator it; - QPainter painter; - - // Purge the Pixmap cache of any old text strings - if (usePixmapCache()) { - // Current time in milliseconds since epoch. - ti = QDateTime::currentDateTime().toMSecsSinceEpoch(); - - if (pixmap_cache_size > - max_pixmap_cache) { // comment this if block out to only cleanup when past the maximum cache size - // Expire any strings not used - QList expire; - - exptime = expire_after_ms; - - // Uncomment the next line to allow better use of pixmap cache memory - //if (pixmap_cache_size < max_pixmap_cache) exptime+=under_limit_cache_bonus; - - for (it = pixmap_cache.begin(); it != pixmap_cache.end(); it++) { - if ((*it)->last_used < (ti - exptime)) { - expire.push_back(it.key()); - } - } - - - // TODO: Force expiry if over an upper memory threshold.. doesn't appear to be necessary. - - for (int i = 0; i < expire.count(); i++) { - const QString key = expire.at(i); - // unbind the texture - myPixmapCache *pc = pixmap_cache[key]; - deleteTexture(pc->textureID); - QImage &pm = pc->image; - pixmap_cache_size -= pm.width() * pm.height() * (pm.depth() / 8); - // free the pixmap - //delete pc->pixmap; - - // free the myPixmapCache object - delete pc; - - // pull the dead record from the cache. - pixmap_cache.remove(key); - } - } - } - - //glPushAttrib(GL_COLOR_BUFFER_BIT); - painter.begin(this); - - int buf = 4; - -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - float dpr = devicePixelRatio(); - buf *= dpr; -#endif - // process the text drawing queue - for (int i = 0; i < m_textque_items; i++) { + int m_textque_items = m_textque.size(); + + int h,w; + + + for (int i = 0; i < m_textque_items; ++i) { TextQue &q = m_textque[i]; // can do antialiased text via texture cache fine on mac if (usePixmapCache()) { // Generate the pixmap cache "key" - QString hstr = QString("%4:%5:%6%7").arg(q.text).arg(q.color.name()).arg(q.font->key()).arg( - q.antialias); + QString hstr = QString("%1:%2:%3"). + arg(q.text). + arg(q.color.name()). + arg(q.font->pointSize()); - QImage pm; - - it = pixmap_cache.find(hstr); - myPixmapCache *pc = nullptr; - - if (it != pixmap_cache.end()) { - pc = (*it); - - } else { - // not found.. create the image and store it in a cache - - //This is much slower than other text rendering methods, but caching more than makes up for the speed decrease. - pc = new myPixmapCache; - pc->last_used = ti; // set the last_used value. + QPixmap pm; + const int buf = 8; + if (!QPixmapCache::find(hstr, &pm)) { QFontMetrics fm(*q.font); - QRect rect = fm.boundingRect(q.text); + QRect rect=fm.tightBoundingRect(q.text); w = fm.width(q.text); - h = fm.height(); - -//#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) -// w *= dpr; -// h *= dpr; -//#endif - - rect.setWidth(w); - rect.setHeight(h); - - pm = QImage(w + buf, h + buf, QImage::Format_ARGB32_Premultiplied); + h = fm.height()+buf; + pm=QPixmap(w, h); pm.fill(Qt::transparent); QPainter imgpainter(&pm); - QBrush b(q.color); - imgpainter.setBrush(b); + imgpainter.setPen(q.color); - QFont font = *q.font; -//#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) -// int fs = font.pointSize(); - -// if (fs > 0) { -// font.setPointSize(fs * dpr); -// } else { -// font.setPixelSize(font.pixelSize()*dpr); -// } - -//#endif - imgpainter.setFont(font); + imgpainter.setFont(*q.font); imgpainter.setRenderHint(QPainter::TextAntialiasing, q.antialias); - imgpainter.drawText(buf / 2, h, q.text); + imgpainter.drawText(0, h-buf, q.text); imgpainter.end(); - pc->image = pm; - pixmap_cache_size += pm.width() * pm.height() * (pm.depth() / 8); - pixmap_cache[hstr] = pc; - + QPixmapCache::insert(hstr, pm); + strings_drawn_this_frame++; + } else { + //cached + strings_cached_this_frame++; } - if (pc) { - pc->last_used = ti; - int h = pc->image.height(); - int w = pc->image.width(); + h = pm.height(); + w = pm.width(); + if (q.angle != 0) { + float xxx = q.x - h - (h / 2); + float yyy = q.y + w / 2; // + buf / 2; -//#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) -// h /= dpr; -// w /= dpr; -//#endif + xxx+=4; + yyy+=4; - if (q.angle != 0) { - float xxx = q.x - h - (h / 2); - float yyy = q.y + w / 2 + buf / 2; - - painter.translate(xxx, yyy); - painter.rotate(-q.angle); - painter.drawImage(QRect(0, h / 2, w, h), pc->image, pc->image.rect()); - painter.rotate(+q.angle); - painter.translate(-xxx, -yyy); - } else { - painter.drawImage(QRect(q.x - buf / 2, q.y - h + buf / 2, w, h), pc->image, pc->image.rect()); - } + painter.translate(xxx, yyy); + painter.rotate(-q.angle); + painter.drawPixmap(QRect(0, h / 2, w, h), pm); + painter.rotate(+q.angle); + painter.translate(-xxx, -yyy); + } else { + painter.drawPixmap(QRect(q.x - buf / 2, q.y - h + buf, w, h), pm); } } else { // Just draw the fonts.. - QBrush b(q.color); - painter.setBrush(b); + painter.setPen(QColor("red")); //q.color); painter.setFont(*q.font); if (q.angle == 0) { - // ********************************************************* - // Holy crap this is slow - // The following line is responsible for 77% of drawing time - // ********************************************************* - painter.drawText(q.x, q.y, q.text); } else { - QBrush b(q.color); - painter.setBrush(b); painter.setFont(*q.font); w = painter.fontMetrics().width(q.text); @@ -580,42 +462,35 @@ void gGraphView::DrawTextQue() painter.rotate(+q.angle); painter.translate(-q.x, -q.y); } + strings_drawn_this_frame++; + } - q.text.clear(); + //q.text.clear(); //q.text.squeeze(); } - if (!usePixmapCache()) { - painter.end(); - } - - //qDebug() << "rendered" << m_textque_items << "text items"; - m_textque_items = 0; + m_textque.clear(); } +#endif -void gGraphView::AddTextQue(QString &text, short x, short y, float angle, QColor color, +void gGraphView::AddTextQue(const QString &text, short x, short y, float angle, QColor color, QFont *font, bool antialias) { #ifdef ENABLED_THREADED_DRAWING text_mutex.lock(); #endif - - if (m_textque_items >= textque_max) { - DrawTextQue(); - } - - TextQue &q = m_textque[m_textque_items++]; + m_textque.append(TextQue(x,y,angle,text,color,font,antialias)); #ifdef ENABLED_THREADED_DRAWING text_mutex.unlock(); #endif - q.text = text; - q.x = x; - q.y = y; - q.angle = angle; - q.color = color; - q.font = font; - q.antialias = antialias; +// q.text = text; +// q.x = x; +// q.y = y; +// q.angle = angle; +// q.color = color; +// q.font = font; +// q.antialias = antialias; } void gGraphView::addGraph(gGraph *g, short group) @@ -1205,8 +1080,6 @@ bool gGraphView::renderGraphs(QPainter &painter) g->paint(painter, g->m_rect.x(), g->m_rect.y(), g->m_rect.width(), g->m_rect.height()); } - // can't draw snapshot text using this DrawTextQue function - // TODO: Find a better solution for detecting when in snapshot mode if (m_graphs.size() > 1) { DrawTextQue(painter); @@ -1319,6 +1192,11 @@ void gGraphView::paintGL() bool graphs_drawn = true; + lines_drawn_this_frame = 0; + quads_drawn_this_frame = 0; + strings_drawn_this_frame = 0; + strings_cached_this_frame = 0; + graphs_drawn = renderGraphs(painter); if (!graphs_drawn) { // No graphs drawn? @@ -1361,12 +1239,11 @@ void gGraphView::paintGL() } double fps = v / double(rs); - ss = "Debug Mode " + QString::number(fps, 'f', 1) + - "fps " + QString::number(lines_drawn_this_frame, 'f', 0) + - " lines " + QString::number(quads_drawn_this_frame, 'f', 0) + - " quads " + QString::number(pixmap_cache.count(), 'f', 0) + - " strings " + QString::number(pixmap_cache_size / 1024.0, 'f', 1) + - "Kb"; + ss = "Debug Mode " + QString::number(fps, 'f', 1) + "fps " + + QString::number(lines_drawn_this_frame, 'f', 0) + " lines " +// + QString::number(quads_drawn_this_frame, 'f', 0) + " quads " + + QString::number(strings_drawn_this_frame, 'f', 0) + " strings " + + QString::number(strings_cached_this_frame, 'f', 0) + " cached "; int w, h; // this uses tightBoundingRect, which is different on Mac than it is on Windows & Linux. diff --git a/sleepyhead/Graphs/gGraphView.h b/sleepyhead/Graphs/gGraphView.h index f9aa9ce1..33802398 100644 --- a/sleepyhead/Graphs/gGraphView.h +++ b/sleepyhead/Graphs/gGraphView.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,22 @@ const int textque_max = 512; \brief Holds a single item of text for the drawing queue */ struct TextQue { + TextQue() { + } + TextQue(short x, short y, float angle, QString text, QColor color, QFont * font, bool antialias): + x(x), y(y), angle(angle), text(text), color(color), font(font), antialias(antialias) + { + } + TextQue(const TextQue & copy) { + x=copy.x; + y=copy.y; + text=copy.text; + angle=copy.angle; + color=copy.color; + font=copy.font; + antialias=copy.antialias; + } + //! \variable contains the x axis screen position to draw the text short x; //! \variable contains the y axis screen position to draw the text @@ -133,16 +150,6 @@ class gToolTip : public QObject void timerDone(); }; -/*! \struct myPixmapCache - \brief My version of Pixmap cache with texture binding support - - */ -struct myPixmapCache { - quint64 last_used; - QImage image; - GLuint textureID; -}; - /*! \class gGraphView \brief Main OpenGL Graph Area, derived from QGLWidget @@ -237,11 +244,11 @@ class gGraphView : public QGLWidget void selectionTime(); //! \brief Add the Text information to the Text Drawing Queue (called by gGraphs renderText method) - void AddTextQue(QString &text, short x, short y, float angle = 0.0, + void AddTextQue(const QString &text, short x, short y, float angle = 0.0, QColor color = Qt::black, QFont *font = defaultfont, bool antialias = true); - //! \brief Draw all Text in the text drawing queue - void DrawTextQue(); +// //! \brief Draw all Text in the text drawing queue +// void DrawTextQue(); //! \brief Draw all text components using QPainter object painter void DrawTextQue(QPainter &painter); @@ -319,6 +326,12 @@ class gGraphView : public QGLWidget //! \brief Graph drawing routines, returns true if there weren't any graphs to draw bool renderGraphs(QPainter &painter); + // for profiling purposes, a count of lines drawn in a single frame + int lines_drawn_this_frame; + int quads_drawn_this_frame; + int strings_drawn_this_frame; + int strings_cached_this_frame; + protected: //! \brief Set up the OpenGL basics for the QGLWidget underneath virtual void initializeGL(); @@ -401,9 +414,8 @@ class gGraphView : public QGLWidget int m_graph_index; //! \brief List of all queue text to draw.. not sure why I didn't use a vector here.. Might of been a leak issue - TextQue m_textque[textque_max]; + QVector m_textque; - int m_textque_items; int m_lastxpos, m_lastypos; QString m_emptytext; @@ -425,11 +437,10 @@ class gGraphView : public QGLWidget QTime m_animationStarted; - // turn this into a struct later.. - QHash pixmap_cache; - qint32 pixmap_cache_size; bool use_pixmap_cache; + QPixmapCache pixmapcache; + QTime horizScrollTime, vertScrollTime; public slots: diff --git a/sleepyhead/Graphs/gLineChart.cpp b/sleepyhead/Graphs/gLineChart.cpp index 9e696430..f0df316b 100644 --- a/sleepyhead/Graphs/gLineChart.cpp +++ b/sleepyhead/Graphs/gLineChart.cpp @@ -28,6 +28,7 @@ gLineChart::gLineChart(ChannelID code, QColor col, bool square_plot, bool disabl addPlot(code, col, square_plot); m_line_color = col; m_report_empty = false; + lines.reserve(50000); } gLineChart::~gLineChart() { @@ -127,12 +128,7 @@ void gLineChart::SetDay(Day *d) } - //if (m_code==CPAP_Leak) { - // subtract_offset=profile.cpap.[IntentionalLeak].toDouble(); - //} else subtract_offset = 0; - - } EventDataType gLineChart::Miny() { @@ -247,8 +243,6 @@ void gLineChart::paint(QPainter &painter, gGraph &w, int left, int top, int widt painter.setClipRect(left, top, width, height+1); painter.setClipping(true); - QVector lines; - lines.reserve(100000); painter.setRenderHint(QPainter::Antialiasing, true); for (int gi = 0; gi < m_codes.size(); gi++) { @@ -666,8 +660,10 @@ void gLineChart::paint(QPainter &painter, gGraph &w, int left, int top, int widt if (done) { break; } } } - painter.setPen(QPen(m_colors[gi],1.5)); + painter.setPen(QPen(m_colors[gi],1)); painter.drawLines(lines); + w.graphView()->lines_drawn_this_frame+=lines.count(); + lines.clear(); //////////////////////////////////////////////////////////////////// // Draw Legends on the top line diff --git a/sleepyhead/Graphs/gLineChart.h b/sleepyhead/Graphs/gLineChart.h index 48a3a6bf..9033f3ea 100644 --- a/sleepyhead/Graphs/gLineChart.h +++ b/sleepyhead/Graphs/gLineChart.h @@ -133,6 +133,8 @@ class gLineChart: public Layer QVector m_colors; QVector m_square; QHash m_enabled; + + QVector lines; }; #endif // GLINECHART_H diff --git a/sleepyhead/Graphs/gXAxis.cpp b/sleepyhead/Graphs/gXAxis.cpp index 7e55435c..051498e5 100644 --- a/sleepyhead/Graphs/gXAxis.cpp +++ b/sleepyhead/Graphs/gXAxis.cpp @@ -303,6 +303,7 @@ void gXAxis::paint(QPainter &painter, gGraph &w, int left, int top, int width, i } else { painter.drawLines(ticks); } + w.graphView()->lines_drawn_this_frame += ticks.size(); w.invalidate_xAxisImage = false; } diff --git a/sleepyhead/Graphs/gXAxis.h b/sleepyhead/Graphs/gXAxis.h index 63554319..1d1a09ff 100644 --- a/sleepyhead/Graphs/gXAxis.h +++ b/sleepyhead/Graphs/gXAxis.h @@ -13,6 +13,7 @@ #define GXAXIS_H #include +#include #include "Graphs/layer.h" /*! \class gXAxis diff --git a/sleepyhead/Graphs/gYAxis.cpp b/sleepyhead/Graphs/gYAxis.cpp index 55fe14eb..4e0ee7bd 100644 --- a/sleepyhead/Graphs/gYAxis.cpp +++ b/sleepyhead/Graphs/gYAxis.cpp @@ -138,6 +138,7 @@ void gXGrid::paint(QPainter &painter, gGraph &w, int left, int top, int width, i painter.drawLines(majorlines); painter.setPen(QPen(m_minor_color,1)); painter.drawLines(minorlines); + w.graphView()->lines_drawn_this_frame += majorlines.size() + minorlines.size(); } @@ -395,6 +396,8 @@ void gYAxis::paint(QPainter &painter, gGraph &w, int left, int top, int width, i } painter.setPen(m_line_color); painter.drawLines(ticks); + w.graphView()->lines_drawn_this_frame += ticks.size(); + } } const QString gYAxis::Format(EventDataType v, int dp) diff --git a/sleepyhead/mainwindow.cpp b/sleepyhead/mainwindow.cpp index 00a27e59..6489a40f 100644 --- a/sleepyhead/mainwindow.cpp +++ b/sleepyhead/mainwindow.cpp @@ -266,9 +266,9 @@ void MainWindow::closeEvent(QCloseEvent * event) extern MainWindow *mainwin; MainWindow::~MainWindow() { - if (systraymenu) { delete systraymenu; } +// if (systraymenu) { delete systraymenu; } - if (systray) { delete systray; } +// if (systray) { delete systray; } // Trash anything allocated by the Graph objects DestroyGraphGlobals();