New Upstream Release - sugar-pippy-activity

Ready changes

Summary

Merged new upstream version: 76 (was: 75).

Resulting package

Built on 2023-08-16T12:34 (took 7m49s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases sugar-pippy-activity

Lintian Result

Diff

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e3d5ea3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,54 @@
+locale
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+
+# Distribution / packaging
+.Python
+env/
+bin/
+build/
+develop-eggs/
+dist/
+eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Translations
+*.mo
+
+# Mr Developer
+.mr.developer.cfg
+.project
+.pydevproject
+
+# Rope
+.ropeproject
+
+# Django stuff:
+*.log
+*.pot
+
+# Sphinx documentation
+docs/_build/
+
+*~
diff --git a/NEWS b/NEWS
index b82fa57..56e4257 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+76
+
+* Check box2d installation when loading box2d example (Sparsh Goenka),
+* Fix undo and redo buttons remaining sensitive (Sparsh Goenka),
+* Fix full screen glitch (Sparsh Goenka)
+* Fix no source tab on resume of empty file (Shaan Subbaiah),
+* Fix dark mode is not set on new tabs (Shaan Subbaiah),
+* Verify source files names before exporting to distutils (Martin Abente),
+* Fix bug in demo (Sebastian Silva)
+
 75
 
 * Port to Python 3 - inline template and #! (Srevin Saju),
diff --git a/activity/activity.info b/activity/activity.info
index e419d6a..17e8341 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -3,7 +3,7 @@ name = Pippy
 bundle_id = org.laptop.Pippy
 exec = sugar-activity3 pippy_app.PippyActivity
 icon = activity-icon
-activity_version = 75
+activity_version = 76
 max_participants = 4
 mime_types = text/x-python
 show_launcher = yes
diff --git a/data/en/graphics/bounce b/data/en/graphics/bounce
index 74b87dd..558180b 100644
--- a/data/en/graphics/bounce
+++ b/data/en/graphics/bounce
@@ -22,7 +22,7 @@ pygame.mouse.set_visible(False)
 
 # create the window and keep track of the surface
 # for drawing into
-screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
+screen = pygame.display.set_mode((0, 0), pygame.NOFRAME | pygame.FULLSCREEN)
 
 # ask for screen's width and height
 size = width, height = screen.get_size()
diff --git a/data/en/graphics/camera b/data/en/graphics/camera
index 93b9130..0e1ca68 100644
--- a/data/en/graphics/camera
+++ b/data/en/graphics/camera
@@ -21,7 +21,7 @@ pygame.mouse.set_visible(False)
 
 # create the pygame window and return a Surface object for
 # drawing in that window.
-screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
+screen = pygame.display.set_mode((0, 0), pygame.NOFRAME | pygame.FULLSCREEN)
 
 # grab a frame from camera to file
 pipeline = Gst.parse_launch('v4l2src ! videoconvert ! jpegenc ! filesink location=/tmp/pippypic.jpg')
diff --git a/data/en/graphics/lines b/data/en/graphics/lines
index 16db9d6..40c926c 100644
--- a/data/en/graphics/lines
+++ b/data/en/graphics/lines
@@ -15,7 +15,7 @@ pygame.mouse.set_visible(False)
 
 # create the window and keep track of the surface
 # for drawing into
-screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
+screen = pygame.display.set_mode((0, 0), pygame.NOFRAME | pygame.FULLSCREEN)
 
 # ask for screen's width and height
 size = width, height = screen.get_size()
diff --git a/data/en/graphics/physics b/data/en/graphics/physics
index 08aa696..8f43f30 100644
--- a/data/en/graphics/physics
+++ b/data/en/graphics/physics
@@ -9,7 +9,7 @@ from pippy import physics
 
 # initialize pygame first thing
 pygame.init()
-screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
+screen = pygame.display.set_mode((0, 0), pygame.NOFRAME | pygame.FULLSCREEN)
 
 # set up the physics world (instance of Elements)
 world = physics.Elements(screen.get_size())
diff --git a/data/en/graphics/pong b/data/en/graphics/pong
index 7cb71c9..381f889 100644
--- a/data/en/graphics/pong
+++ b/data/en/graphics/pong
@@ -16,7 +16,7 @@ pygame.init()
 
 # create the window and keep track of the surface
 # for drawing into
-screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
+screen = pygame.display.set_mode((0, 0), pygame.NOFRAME | pygame.FULLSCREEN)
 
 # ask for screen's width and height
 size = width, height = screen.get_size()
diff --git a/data/en/graphics/snow b/data/en/graphics/snow
index e1b2df1..e6126c6 100644
--- a/data/en/graphics/snow
+++ b/data/en/graphics/snow
@@ -11,7 +11,7 @@ pygame.init()
 
 # create the window and keep track of the surface
 # for drawing into
-screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
+screen = pygame.display.set_mode((0, 0), pygame.NOFRAME | pygame.FULLSCREEN)
 
 # ask for screen's width and height
 width, height = screen.get_size()
diff --git a/data/en/graphics/tree b/data/en/graphics/tree
index adc179f..cd1799f 100644
--- a/data/en/graphics/tree
+++ b/data/en/graphics/tree
@@ -12,7 +12,7 @@ pygame.init()
 
 # create the window and keep track of the surface
 # for drawing into
-screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
+screen = pygame.display.set_mode((0, 0), pygame.NOFRAME | pygame.FULLSCREEN)
 
 # ask for screen's width and height
 width, height = screen.get_size()
diff --git a/data/es/tutorials/Tutorial_03_rango.py b/data/es/tutorials/Tutorial_03_rango.py
index e6f8b47..8a791db 100644
--- a/data/es/tutorials/Tutorial_03_rango.py
+++ b/data/es/tutorials/Tutorial_03_rango.py
@@ -9,7 +9,7 @@ def suma_en_rango(num1, num2):
 numero1 = int(eval(input('Escribe primer numero: ')))
 numero2 = int(eval(input('Escribe segundo numero: ')))
 
-if numero1 > numero2:
+if numero1 < numero2:
     suma_en_rango(numero1, numero2)
 else:
     suma_en_rango(numero2, numero1)
diff --git a/debian/changelog b/debian/changelog
index 8ff937e..f20b35e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+sugar-pippy-activity (76-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 16 Aug 2023 12:27:13 -0000
+
 sugar-pippy-activity (75-2) unstable; urgency=medium
 
   * simplify build;
diff --git a/notebook.py b/notebook.py
index 74f1ee9..7ef1637 100644
--- a/notebook.py
+++ b/notebook.py
@@ -48,6 +48,9 @@ class TabLabel(Gtk.HBox):
         'tab-rename': (GObject.SignalFlags.RUN_FIRST,
                       None,
                       ([GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT, ])),
+        'tab-switch': (GObject.SignalFlags.RUN_FIRST,
+                      None,
+                      ([GObject.TYPE_PYOBJECT])),
     }
 
     def __init__(self, child, label, path, tabs, editor_id):
@@ -109,6 +112,7 @@ class TabLabel(Gtk.HBox):
     def _label_clicked(self, eventbox, data):
         if self.tabs.page_num(self.child) is not self.tabs.get_current_page():
             self.child.grab_focus()
+            self.emit('tab-switch', self.child)
         else:
             self.label_entry.set_text(self.label_text)
             eventbox.hide()
@@ -225,10 +229,11 @@ class PippySourceView(GtkSource.View):
         self._css_provider.load_from_data(theme)
 
 class SourceNotebook(AddNotebook):
-    def __init__(self, activity, collab):
+    def __init__(self, activity, collab, edit_toolbar=None):
         AddNotebook.__init__(self)
         self.activity = activity
         self._collab = collab
+        self._edit_toolbar = edit_toolbar
         self.set_scrollable(True)
         self.last_tab = 0
         self._font_size = DEFAULT_FONT_SIZE
@@ -254,7 +259,9 @@ class SourceNotebook(AddNotebook):
                                      path, self, editor_id)
         tablabel.connect('tab-close', self._tab_closed_cb)
         tablabel.connect('tab-rename', self._tab_renamed_cb)
+        tablabel.connect('tab-switch', self._tab_switched_cb)
         self.connect('key-press-event', self._key_press_cb)
+        self.connect('key-release-event', self._key_release_cb)
 
         codesw.show_all()
 
@@ -299,6 +306,17 @@ class SourceNotebook(AddNotebook):
             return True
         return False
 
+    def update_edit_toolbar(self, text_buffer=None):
+        if self._edit_toolbar is None:
+            return
+        if text_buffer is None:
+            text_buffer = self.get_text_buffer()
+        self._edit_toolbar.undo.set_sensitive(text_buffer.can_undo())
+        self._edit_toolbar.redo.set_sensitive(text_buffer.can_redo())
+    
+    def _key_release_cb(self, widget, event):
+        self.update_edit_toolbar()
+
     def set_current_label(self, label):
         child = self.get_nth_page(self.get_current_page())
         widget = self.get_tab_label(child)
@@ -458,6 +476,12 @@ class SourceNotebook(AddNotebook):
         logging.debug('SourceNotebook._tab_renamed_cb %r %r' % (index, name))
         self.emit('tab-renamed', index, name)
 
+    def _tab_switched_cb(self, notebook, child):
+        index = self.page_num(child)
+        page = self.get_nth_page(index)
+        text_buffer = page.get_children()[0].get_buffer()
+        self.update_edit_toolbar(text_buffer)
+
     def rename_tab(self, index, name):
         logging.debug('SourceNotebook.rename_tab %r %r' % (index, name))
         page = self.get_nth_page(index)
diff --git a/pippy_app.py b/pippy_app.py
index 6b4a4ed..1cc3111 100644
--- a/pippy_app.py
+++ b/pippy_app.py
@@ -238,7 +238,9 @@ class PippyActivity(ViewSourceActivity):
         self._edit_toolbar.show()
 
         self._edit_toolbar.undo.connect('clicked', self.__undobutton_cb)
+        self._edit_toolbar.undo.set_sensitive(False)
         self._edit_toolbar.redo.connect('clicked', self.__redobutton_cb)
+        self._edit_toolbar.redo.set_sensitive(False)
         self._edit_toolbar.copy.connect('clicked', self.__copybutton_cb)
         self._edit_toolbar.paste.connect('clicked', self.__pastebutton_cb)
 
@@ -403,7 +405,7 @@ class PippyActivity(ViewSourceActivity):
         data_path = os.path.join(get_bundle_path(), 'data')
         self.paths.append([_('My examples'), data_path])
 
-        self._source_tabs = SourceNotebook(self, self._collab)
+        self._source_tabs = SourceNotebook(self, self._collab, self._edit_toolbar)
         self._source_tabs.connect('tab-added', self._add_source_cb)
         self._source_tabs.connect('tab-renamed', self._rename_source_cb)
         self._source_tabs.connect('tab-closed', self._close_source_cb)
@@ -539,8 +541,31 @@ class PippyActivity(ViewSourceActivity):
         self._dialog.run()
         path = self._dialog.get_path()
         if path:
+            if path.endswith('physics') and not self._ensure_box2d_support():
+                return
             self._select_func_cb(path)
 
+    def _ensure_box2d_support(self):
+        try:
+            import Box2D
+        except ImportError:
+            dialog = Gtk.MessageDialog(
+                None, Gtk.DialogFlags.MODAL,
+                Gtk.MessageType.WARNING,
+                Gtk.ButtonsType.OK,
+                _('Box2D is not installed on your system'))
+            dialog.format_secondary_text(
+                _('Box2D is required to run this example.'))
+
+            from sugar3.graphics import style
+            dialog.modify_bg(Gtk.StateType.NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color())
+            dialog.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse('white'))
+    
+            dialog.run()
+            dialog.destroy()
+            return False
+        return True
+
     def _add_source_cb(self, button, force=False, editor_id=None):
         if self._collab._leader or force:
             if editor_id is None:
@@ -557,12 +582,17 @@ class PippyActivity(ViewSourceActivity):
             # The leader must do it first so that they can set
             # up the text buffer
             self._collab.post(dict(action='add-source-request'))
+        # Check if dark mode enabled, apply it
+        self._source_tabs.update_edit_toolbar()
+        if self._inverted_colors.props.active:
+            self._source_tabs.set_dark()
 
     def _rename_source_cb(self, notebook, page, name):
         _logger.debug('_rename_source_cb %r %r' % (page, name))
         self._collab.post(dict(action='rename-source', page=page, name=name))
 
     def _close_source_cb(self, notebook, page):
+        self._source_tabs.update_edit_toolbar()
         _logger.debug('_close_source_cb %r' % (page))
         self._collab.post(dict(action='close-source', page=page))
 
@@ -661,15 +691,21 @@ class PippyActivity(ViewSourceActivity):
         self._vte.grab_focus()
         self._vte.feed(b'\x1B[H\x1B[J\x1B[0;39m')
 
-    def __undobutton_cb(self, butston):
+    def __undobutton_cb(self, button):
         text_buffer = self._source_tabs.get_text_buffer()
         if text_buffer.can_undo():
             text_buffer.undo()
+            self._edit_toolbar.redo.set_sensitive(True)
+        if not text_buffer.can_undo():
+            button.set_sensitive(False)
 
     def __redobutton_cb(self, button):
         text_buffer = self._source_tabs.get_text_buffer()
         if text_buffer.can_redo():
             text_buffer.redo()
+            self._edit_toolbar.undo.set_sensitive(True)
+        if not text_buffer.can_redo():
+            button.set_sensitive(False)
 
     def __copybutton_cb(self, button):
         text_buffer = self._source_tabs.get_text_buffer()
@@ -921,6 +957,23 @@ class PippyActivity(ViewSourceActivity):
             self.add_alert(alert)
             return
 
+        found = next((
+            name for name in data[0]
+            if name != self._source_tabs.purify_name(name)),
+            None)
+        if found is not None:
+            example = self._source_tabs.purify_name(found)
+            alert = Alert()
+            alert.props.title = _('Save as distutils package error')
+            alert.props.msg = _('Please give your source files a proper '
+                                'name, for example "%s", before attempting to '
+                                'save it as an distutils package.') % example
+            ok_icon = Icon(icon_name='dialog-ok')
+            alert.add_button(Gtk.ResponseType.OK, _('Ok'), ok_icon)
+            alert.connect('response', self._dismiss_alert_cb)
+            self.add_alert(alert)
+            return
+
         setup_script = DISTUTILS_SETUP_SCRIPT.format(modulename=title,
                                                      filenames=filenames)
         setupfile = open(os.path.join(app_temp, 'setup.py'), 'w')
@@ -1074,6 +1127,8 @@ class PippyActivity(ViewSourceActivity):
         session_list = []
         app_temp = os.path.join(self.get_activity_root(), 'instance')
         tmpfile = os.path.join(app_temp, 'pippy-tempfile-storing.py')
+        if not self.session_data:
+            self.session_data.append(None)
         for zipdata, content in zip(zipped_data, self.session_data):
             _logger.debug('Session data %r', content)
             name, python_code, path, modified, editor_id = zipdata
@@ -1267,8 +1322,12 @@ class PippyActivity(ViewSourceActivity):
                     self.session_data.append(content)
                     self._loaded_session.append([name, python_code, path])
 
-        for name, content, path in self._loaded_session:
-            self._source_tabs.add_tab(name, content, path)
+        # Create tabs from the datastore, else add a blank tab
+        if self._loaded_session:
+            for name, content, path in self._loaded_session:
+                self._source_tabs.add_tab(name, content, path)
+        else:
+            self._source_tabs.add_tab()
 
 # TEMPLATES AND INLINE FILES
 ACTIVITY_INFO_TEMPLATE = '''

Debdiff

File lists identical (after any substitutions)

Control files: lines which differ (wdiff format)

  • Depends: gir1.2-gdkpixbuf-2.0, gir1.2-glib-2.0, gir1.2-gtk-3.0, gir1.2-gtksource-3.0, gir1.2-pango-1.0, gir1.2-telepathyglib-0.12, gir1.2-vte-2.91, python3, python3-dbus, python3-jarabe, python3-pygame, python3-sugar3, base-files (>= 12.3) 13)

More details

Full run details