<html>
 <body>
  <div style="font-family: Verdana, Arial, Helvetica, Sans-Serif;">
   <table bgcolor="#f9f3c9" width="100%" cellpadding="8" style="border: 1px #c9c399 solid;">
    <tr>
     <td>
      This is an automatically generated e-mail. To reply, visit:
      <a href="http://git.reviewboard.kde.org/r/104655/">http://git.reviewboard.kde.org/r/104655/</a>
     </td>
    </tr>
   </table>
   <br />



 <p>Ship it!</p>



 <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Ship It!</pre>
 <br />







<p>- Torsten</p>


<br />
<p>On April 18th, 2012, 2:15 p.m., Jason Roehm wrote:</p>






<table bgcolor="#fefadf" width="100%" cellspacing="0" cellpadding="8" style="background-image: url('http://git.reviewboard.kde.org/media/rb/images/review_request_box_top_bg.png'); background-position: left top; background-repeat: repeat-x; border: 1px black solid;">
 <tr>
  <td>

<div>Review request for Marble.</div>
<div>By Jason Roehm.</div>


<p style="color: grey;"><i>Updated April 18, 2012, 2:15 p.m.</i></p>






<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Description </h1>
 <table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
 <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">MarbleWidget::addLayer() takes a pointer to a LayerInterface-derived object as an argument. The pointer is added to an internal list of layers that are rendered in the Marble widget. When exposing this function via Python, the /Transfer/ SIP parameter annotation must be supplied. This notation indicates to SIP that control of the lifetime of the object passed via addLayer() is placed in the C++ library's hands. If you don't do this, then Python might decide to garbage-collect the layer object when it's no longer used on that side. That is obviously a bad thing if the layer is still being used by the widget.

Likewise, the /TransferBack/ annotation is used to return ownership of the object back to Python if the removeLayer() function is later called to remove the layer from the widget. At that time, the object can safely be garbage-collected since it is no longer used by the widget C++ library.</pre>
  </td>
 </tr>
</table>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Testing </h1>
<table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
 <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Without these annotations, adding an instance of a Python subclass of LayerInterface via addLayer() yielded a crash (at least on my system) the first time the C++ library tried to invoke any member functions on the layer. This is consistent with the layer having been destroyed before the C++ library could use it. After adding the annotations, I am able to add Python layer classes and have them render properly. The below test can be used; it dumps to stdout when any of the member functions are called, and draws some text at 40 deg N, 80 deg W that should be visible.

#!/usr/bin/python

# Import the PyQt modules that we need.
from PyQt4.QtCore import *
from PyQt4.QtGui import *
# Import the Marble widget library.
from PyKDE4.marble import *
# Import other modules that we need.
import os
import sys

class OurLayer(Marble.LayerInterface):
    def __init__(self):
        super(OurLayer, self).__init__()

    def renderPosition(self):
        print "renderposition"
        return QStringList("SURFACE")

    def render(self, painter, viewport, renderPos, layer):
        print "render"
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.setPen(QPen(QBrush(QColor.fromRgb(255, 255, 255, 200)), 3.0, Qt.SolidLine, Qt.RoundCap))
        painter.drawText(Marble.GeoDataCoordinates(-80, 40, 0, Marble.GeoDataCoordinates.Degree), "This layer works!")
        return True

    def zValue(self):
        print "zvalue"
        return 0

# Main function that runs when we execute the script.
def main():
    # Create the Qt application object.
    app = QApplication(sys.argv)

    # Instantiate the Marble widget.
    marble = Marble.MarbleWidget()
    marble.setMapThemeId("earth/bluemarble/bluemarble.dgml")
    marble.addLayer(OurLayer())
    marble.show()
    
    # Execute the application.
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

</pre>
  </td>
 </tr>
</table>




<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Diffs</b> </h1>
<ul style="margin-left: 3em; padding-left: 0;">

 <li>src/bindings/python/sip/MarbleWidget.sip <span style="color: grey">(9f96274)</span></li>

</ul>

<p><a href="http://git.reviewboard.kde.org/r/104655/diff/" style="margin-left: 3em;">View Diff</a></p>




  </td>
 </tr>
</table>








  </div>
 </body>
</html>