From efdce20a46e772a208ffc0cbd012116a5914fffc Mon Sep 17 00:00:00 2001
From: nextime <nextime@nexlab.it>
Date: Sat, 23 Feb 2013 23:04:57 +0100
Subject: [PATCH] Fixed a JSBridge potential memory leak

---
 gui/SkyliveX.js     | 22 ++++++++++++++++---
 gui/maingui.html    | 27 -----------------------
 plugins/skproto.cpp | 29 +++++++++++++++++++++++--
 plugins/skproto.h   |  1 +
 src/mainwin.cpp     | 53 ++++++++++++++++++++++++++++++++++++++-------
 src/mainwin.h       | 10 +++++++--
 6 files changed, 100 insertions(+), 42 deletions(-)

diff --git a/gui/SkyliveX.js b/gui/SkyliveX.js
index 9b962a1..6cd36f4 100644
--- a/gui/SkyliveX.js
+++ b/gui/SkyliveX.js
@@ -2,9 +2,8 @@ function changeContent(id, content)
 {
    var n=document.getElementById(id);
    if(typeof(n)!="undefined")
-     n.innerHTML="ESTICAZZI";
+     n.innerHTML=content;
 }
-
 function notify(content)
 {
    if(typeof(notifycb)=="function")
@@ -17,7 +16,24 @@ function msgalert(content)
    else
       alert(content);
 }
+function publicReceived(user, msg)
+{
+   if(typeof(public_received)=="function")
+   {
+      public_received(user, msg);
+   } else {
+      n = document.getElementById("chatarea");
+      if(typeof(n)!="undefined")
+      {
+         var newel = document.createElement('p');
+         newel.innerHTML="&lt;"+user+"&gt; "+msg;
+         n.appendChild(newel);
+         n.scollTop = n.scrollHeight;
+      }
+   }
+}
 
 SkyliveX.changeContent.connect(changeContent);
 SkyliveX.notify.connect(notify);
-SkyliveX.alert.connect(msgalert);
+SkyliveX.alertmsg.connect(msgalert);
+SkyliveX.public_received.connect(publicReceived);
diff --git a/gui/maingui.html b/gui/maingui.html
index e72b496..5aa0503 100644
--- a/gui/maingui.html
+++ b/gui/maingui.html
@@ -93,33 +93,6 @@
          </div>
          <div id="right">
             <div id="chatarea">
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>CHAT</p>
-               <p>PIPPO</p>
             </div>
             <div id="chatlist">
                <p>user1</p>
diff --git a/plugins/skproto.cpp b/plugins/skproto.cpp
index 50571d3..8504a8a 100644
--- a/plugins/skproto.cpp
+++ b/plugins/skproto.cpp
@@ -48,6 +48,7 @@ void SkyliveProtocol::startPlugin()
    std::cout << "SkyliveProtocol initialized in thread " << thread() << std::endl;
    registerHandler((QString)"connectTelescopes", &SkyliveProtocol::handle_connect);
    registerHandler((QString)"putlogin", &SkyliveProtocol::handle_putlogin);
+   registerHandler((QString)"publicChatSend", &SkyliveProtocol::handle_publicsend);
 
    //pktTimer = new QTimer();
    //QObject::connect(pktTimer, SIGNAL(timeout()), this, SLOT(processPackets()));
@@ -138,9 +139,16 @@ void SkyliveProtocol::processPackets()
          {
             sendPacket("PONG", "NIL");
          }
-         if(pkt.cmd=="CPUBLIC")
+         else if(pkt.cmd=="CPUBLIC")
          {
-
+            QList<QString> paramlist = pkt.params.split(PARAM_SEPARATOR);
+            if(paramlist.size() > 1) // For safety
+            {
+               SKMessage pmsg("publicchatrcv");
+               pmsg.parameters.insert("username", QByteArray::fromPercentEncoding(paramlist[0].toLocal8Bit()));
+               pmsg.parameters.insert("msg", QByteArray::fromPercentEncoding(paramlist[1].toLocal8Bit()));
+               sendMessage(pmsg);
+            }
          }
          else if(pkt.cmd=="CPRIVAT")
          {
@@ -149,6 +157,10 @@ void SkyliveProtocol::processPackets()
          else if(pkt.cmd=="STATUS")
          {
                
+         }
+         else if(pkt.cmd=="ULIST")
+         {
+
          }
          else if(pkt.cmd=="ENABLE")
          {
@@ -328,6 +340,19 @@ void SkyliveProtocol::handle_putlogin(SKMessage msg)
 
 }
 
+
+void SkyliveProtocol::handle_publicsend(SKMessage msg)
+{
+   if(msg.parameters.size() > 0)
+   {
+      QString cmd("CPUBLIC");
+      QList<QString> paramlist;
+      QByteArray message(msg.parameters[0].toLocal8Bit());
+      paramlist.append(message.toPercentEncoding());
+      sendPacket(cmd, paramlist);
+   }
+}
+
 void SkyliveProtocol::clientConnected()
 {
    SM_TCPCLIENT = CONNECTED;
diff --git a/plugins/skproto.h b/plugins/skproto.h
index efd7c46..34b3378 100644
--- a/plugins/skproto.h
+++ b/plugins/skproto.h
@@ -108,6 +108,7 @@ class SkyliveProtocol : public QObject, SkylivexPluginInterface
       void registerHandler(QString type, SKHandlerFunction handler);
       void handle_connect(SKMessage msg);
       void handle_putlogin(SKMessage msg);
+      void handle_publicsend(SKMessage msg);
       void sendPacket(const char* cmd, const char* params);
       void sendPacket(QString &cmd, QString &params);
       void sendPacket(SKProtoMsg &pkt);
diff --git a/src/mainwin.cpp b/src/mainwin.cpp
index b8dad8a..51cdfae 100644
--- a/src/mainwin.cpp
+++ b/src/mainwin.cpp
@@ -60,8 +60,15 @@ MainWin::MainWin(QString &htmlfile)
    setAttribute(Qt::WA_OpaquePaintEvent, false);
    setHtmlFile(htmlfile);
    resize(250,200);
+   //jsbridge.mwin=qobject_cast<MainWin *>(this);
+   //page()->mainFrame()->addToJavaScriptWindowObject("SkyliveX", &jsbridge);
 
-   jsbridge.mwin=qobject_cast<MainWin *>(this);
+   jsbridge = new JSBridge();
+   jsbridge->mwin = qobject_cast<MainWin *>(this);
+   page()->mainFrame()->addToJavaScriptWindowObject("SkyliveX", jsbridge);
+
+
+   connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(refreshJsObject()));
 
    registerHandler((QString)"coreStarted", (SKHandlerFunction)&MainWin::handle_corestarted);
    registerHandler((QString)"telescopeConnected", (SKHandlerFunction)&MainWin::handle_connected);
@@ -70,6 +77,10 @@ MainWin::MainWin(QString &htmlfile)
    registerHandler((QString)"notify", (SKHandlerFunction)&MainWin::handle_notify);
    registerHandler((QString)"loginok", (SKHandlerFunction)&MainWin::handle_loginres);
    registerHandler((QString)"loginfailed", (SKHandlerFunction)&MainWin::handle_loginres);
+   registerHandler((QString)"publicchatrcv", (SKHandlerFunction)&MainWin::handle_chatreceived);
+
+
+
 }
 
 MainWin::~MainWin()
@@ -86,6 +97,15 @@ void MainWin::dragMoveEvent(QDragMoveEvent *ev)
 }
 */
 
+void MainWin::refreshJsObject()
+{
+   //page()->mainFrame()->addToJavaScriptWindowObject("SkyliveX", &jsbridge);
+   jsbridge = new JSBridge();
+   jsbridge->mwin = qobject_cast<MainWin *>(this);
+   page()->mainFrame()->addToJavaScriptWindowObject("SkyliveX", jsbridge);
+
+}
+
 void MainWin::setHtmlFile(QString &fname)
 {
 
@@ -93,8 +113,8 @@ void MainWin::setHtmlFile(QString &fname)
    filename.open(QIODevice::ReadOnly);
    htmlFileCont = QString::fromUtf8(filename.readAll().constData());
    setHtml(htmlFileCont, baseUrl);
-   page()->mainFrame()->addToJavaScriptWindowObject("SkyliveX", &jsbridge);
-
+   //page()->mainFrame()->addToJavaScriptWindowObject("SkyliveX", &jsbridge);
+   //jsbridge.mwin=qobject_cast<MainWin *>(this);
 }
 
 void MainWin::setHtmlFile(QString &fname, bool borders, bool transparentbg)
@@ -184,20 +204,23 @@ void MainWin::handle_corestarted(SKMessage &msg)
 {
    msg.handle = "connectTelescopes";
    sendMessage(msg);
-   jsbridge.notify("Connecting...");
+   //jsbridge.notify("Connecting...");
+   jsbridge->notify("Connecting...");
 
 }
 
 void MainWin::handle_connected(SKMessage &msg)
 {
    std::cout << "Connected by " << msg.sender.toStdString() << std::endl;
-   jsbridge.notify("Connected");
+   //jsbridge.notify("Connected");
+   jsbridge->notify("Connected");
 }
 
 void MainWin::handle_asklogin(SKMessage &msg)
 {
    std::cout << "asklogin by " << msg.sender.toStdString() << std::endl;
-   jsbridge.notify("Logging in");
+   //jsbridge.notify("Logging in");
+   jsbridge->notify("Logging in");
    QString html("gui/login.html");
    setHtmlFile(html, true, false);
    resize(250, 200);
@@ -207,13 +230,15 @@ void MainWin::handle_asklogin(SKMessage &msg)
 void MainWin::handle_alert(SKMessage &msg)
 {
    if(msg.parameters.contains("msg"))
-      jsbridge.alert(msg.parameters["msg"]);
+      //jsbridge.alertmsg(msg.parameters["msg"]);
+      jsbridge->alertmsg(msg.parameters["msg"]);
 }
 
 void MainWin::handle_notify(SKMessage &msg)
 {
    if(msg.parameters.contains("msg"))
-      jsbridge.notify(msg.parameters["msg"]);
+      //jsbridge.notify(msg.parameters["msg"]);
+      jsbridge->notify(msg.parameters["msg"]);
 }
 
 void MainWin::handle_loginres(SKMessage &msg)
@@ -231,6 +256,18 @@ void MainWin::handle_loginres(SKMessage &msg)
    }
 }
 
+void MainWin::handle_chatreceived(SKMessage &msg)
+{
+   if(msg.handle=="publicchatrcv")
+   {
+      if(msg.parameters.contains("msg") && msg.parameters.contains("username"))
+      {
+         //jsbridge.public_received(msg.parameters["username"], msg.parameters["msg"]);
+         jsbridge->public_received(msg.parameters["username"], msg.parameters["msg"]);
+      }
+   }
+}
+
 
 void JSBridge::changePageContent(QString elementid, QString content)
 {
diff --git a/src/mainwin.h b/src/mainwin.h
index c25a84f..4f81a60 100644
--- a/src/mainwin.h
+++ b/src/mainwin.h
@@ -64,7 +64,8 @@ class JSBridge : public QObject
    signals:
       void changeContent(QString elementid, QString content);
       void notify(QString content);
-      void alert(QString content);
+      void alertmsg(QString content);
+      void public_received(QString user, QString content);
 
    public slots:
       void pushLogin(QString username, QString password);
@@ -88,7 +89,8 @@ class MainWin : public QWebView
    QUrl baseUrl;
    QString htmlfile;
    QString htmlFileCont;
-   JSBridge jsbridge;
+   //JSBridge jsbridge;
+   JSBridge* jsbridge;
 
    private:
       QHash<QString, SKHandlerFunction> _handlers;
@@ -107,9 +109,13 @@ class MainWin : public QWebView
       void handle_alert(SKMessage &msg);
       void handle_notify(SKMessage &msg);
       void handle_loginres(SKMessage &msg);
+      void handle_chatreceived(SKMessage &msg);
       void toggleBorders(bool borders);
       void toggleTransparentBackground(bool transparentbg);
 
+   private slots:
+     void refreshJsObject();
+
    public slots:
      void msgFromCore(SKMessage &msg);
 
-- 
2.18.1