@@ -47,40 +47,44 @@ def _create_activity_icon(metadata):
4747 from sugar3 .activity .activity import get_bundle_path
4848 bundle = get_bundle_instance (get_bundle_path ())
4949 icon = Icon (file = bundle .get_icon (), xo_color = color )
50-
5150 return icon
5251
5352
5453class ActivityButton (ToolButton ):
5554
5655 def __init__ (self , activity , ** kwargs ):
5756 ToolButton .__init__ (self , ** kwargs )
58-
5957 icon = _create_activity_icon (activity .metadata )
6058 self .set_child (icon )
6159 icon .set_visible (True )
62-
6360 self .props .hide_tooltip_on_click = False
6461 self .palette_invoker .props .toggle_palette = True
65- self .props .tooltip_text = activity .metadata ['title' ]
62+ # Use safe get for title
63+ self .props .tooltip_text = activity .metadata .get ('title' , '' )
6664 activity .metadata .connect ('updated' , self .__jobject_updated_cb )
6765
6866 def __jobject_updated_cb (self , jobject ):
69- self .props .tooltip_text = jobject ['title' ]
67+ # Use get('title', '') to avoid KeyError
68+ self .props .tooltip_text = jobject .get ('title' , '' )
69+
70+
7071
7172
7273class ActivityToolbarButton (ToolbarButton ):
7374
7475 def __init__ (self , activity , ** kwargs ):
7576 toolbar = ActivityToolbar (activity , orientation_left = True )
7677 toolbar .connect ('enter-key-press' , lambda widget : self .emit ('clicked' ))
77-
78+ # Initialize with the toolbar as page.
7879 ToolbarButton .__init__ (self , page = toolbar , ** kwargs )
79-
8080 icon = _create_activity_icon (activity .metadata )
8181 self .set_child (icon )
8282 icon .set_visible (True )
8383
84+ def do_snapshot (self , snapshot ):
85+ # Override do_snapshot to bypass ToolbarBox’s super() call that fails when self isn’t a ToolbarBox.
86+ return None
87+
8488
8589class StopButton (ToolButton ):
8690
@@ -93,7 +97,7 @@ def __init__(self, activity, **kwargs):
9397
9498 def __stop_button_clicked_cb (self , button , activity ):
9599 activity .close ()
96-
100+
97101 def get_toplevel (self ):
98102 return self .get_ancestor (Gtk .Window )
99103
@@ -190,9 +194,9 @@ def __init__(self, activity, **kwargs):
190194 geometry = monitor .get_geometry ()
191195 self .entry .set_size_request (int (geometry .width / 3 ), - 1 )
192196
197+ # Safe retrieval of title
193198 self .entry .set_text (activity .metadata .get ('title' , '' ))
194199 self .entry .connect ('notify::has-focus' , self .__focus_changed_cb , activity )
195- # self.entry.connect('focus-out-event', self.__focus_out_event_cb, activity)
196200 self .entry .connect ('activate' , self .__activate_cb , activity )
197201 self .entry .set_visible (True )
198202 # Use a GestureClick on the entry
@@ -213,11 +217,6 @@ def __focus_changed_cb(self, widget, param_spec, activity):
213217 widget .select_region (0 , 0 )
214218 self .save_title (activity )
215219
216- def __focus_out_event_cb (self , widget , event , activity ):
217- widget .select_region (0 , 0 )
218- self .save_title (activity )
219- return False
220-
221220 def __activate_cb (self , entry , activity ):
222221 self .save_title (activity )
223222 entry .select_region (0 , 0 )
@@ -227,36 +226,22 @@ def __activate_cb(self, entry, activity):
227226 return False
228227
229228 def __jobject_updated_cb (self , jobject ):
229+ # Use get() to avoid KeyError while updating title
230+ new_title = jobject .get ('title' , '' )
230231 if self .entry .has_focus ():
231232 return
232- if self .entry .get_text () == jobject [ 'title' ] :
233+ if self .entry .get_text () == new_title :
233234 return
234- self .entry .set_text (jobject ['title' ])
235-
236- def __closing_cb (self , activity ):
237- self .save_title (activity )
238- return False
239-
240- def __button_press_event_cb (self , widget , event ):
241- if widget .is_focus ():
242- return False
243- else :
244- widget .grab_focus ()
245- widget .select_region (0 , - 1 )
246- return True
235+ self .entry .set_text (new_title )
247236
248237 def save_title (self , activity ):
249238 title = self .entry .get_text ()
250- # Use get('title', '') so that we have a default if "title" is missing.
251239 if title == activity .metadata .get ('title' , '' ):
252240 return
253-
254241 activity .metadata ['title' ] = title
255242 activity .metadata ['title_set_by_user' ] = '1'
256243 activity .save ()
257-
258244 activity .set_title (title )
259-
260245 shared_activity = activity .get_shared_activity ()
261246 if shared_activity is not None :
262247 shared_activity .props .name = title
@@ -277,8 +262,7 @@ def __init__(self, activity, **kwargs):
277262 display = Gdk .Display .get_default ()
278263 monitor = display .get_monitors ().get_item (0 )
279264 geometry = monitor .get_geometry ()
280- sw .set_size_request (int (geometry .width / 2 ),
281- 2 * style .GRID_CELL_SIZE )
265+ sw .set_size_request (int (geometry .width / 2 ), 2 * style .GRID_CELL_SIZE )
282266 sw .set_policy (Gtk .PolicyType .AUTOMATIC , Gtk .PolicyType .AUTOMATIC )
283267 self ._text_view = Gtk .TextView ()
284268 self ._text_view .set_cursor_visible (True )
@@ -289,8 +273,6 @@ def __init__(self, activity, **kwargs):
289273 if 'description' in activity .metadata :
290274 text_buffer .set_text (activity .metadata ['description' ])
291275 self ._text_view .set_buffer (text_buffer )
292- # Replace "focus-out-event" with "notify::has-focus" for GTK4
293- # self._text_view.connect('focus-out-event', self.__description_changed_cb, activity)
294276 self ._text_view .connect ('notify::has-focus' , self .__focus_changed_cb , activity )
295277 sw .set_child (self ._text_view )
296278 description_box .append_item (sw , vertical_padding = 0 )
@@ -303,44 +285,30 @@ def __focus_changed_cb(self, widget, pspec, activity):
303285 if not widget .has_focus ():
304286 self .__description_changed_cb (widget , None , activity )
305287
288+ def __jobject_updated_cb (self , jobject ):
289+ if self ._text_view .has_focus ():
290+ return
291+ descr = jobject .get ('description' , '' )
292+ if self ._get_text_from_buffer () == descr :
293+ return
294+ buf = self ._text_view .get_buffer ()
295+ buf .set_text (descr )
296+
306297 def __description_changed_cb (self , widget , event , activity ):
307298 description = self ._get_text_from_buffer ()
308- if 'description' in activity .metadata and \
309- description == activity .metadata ['description' ]:
299+ if 'description' in activity .metadata and description == activity .metadata ['description' ]:
310300 return
311301 activity .metadata ['description' ] = description
312302 activity .save ()
313303 return False
314304
315- def set_expanded (self , expanded ):
316- box = self .toolbar_box
317- if not box :
318- return
319-
320- if not expanded :
321- self .palette_invoker .notify_popdown ()
322- return
323-
324- if box .expanded_button is not None :
325- box .expanded_button .queue_draw ()
326- if box .expanded_button != self :
327- box .expanded_button .set_expanded (False )
328- box .expanded_button = self
329-
330- def get_toolbar_box (self ):
331- parent = self .get_parent ()
332- if not hasattr (parent , 'owner' ):
333- return None
334- return parent .owner
335-
336- toolbar_box = property (get_toolbar_box )
337-
338305 def _get_text_from_buffer (self ):
339306 buf = self ._text_view .get_buffer ()
340307 start_iter = buf .get_start_iter ()
341308 end_iter = buf .get_end_iter ()
342309 return buf .get_text (start_iter , end_iter , False )
343310
311+
344312 def __jobject_updated_cb (self , jobject ):
345313 if self ._text_view .has_focus ():
346314 return
@@ -370,30 +338,35 @@ class ActivityToolbar(Gtk.Box):
370338
371339 def __init__ (self , activity , orientation_left = False ):
372340 Gtk .Box .__init__ (self , orientation = Gtk .Orientation .HORIZONTAL )
373-
374341 self ._activity = activity
375342
343+ # Helper: remove child from existing parent before appending.
344+ def safe_append (box , widget ):
345+ if widget .get_parent () is not None :
346+ widget .get_parent ().remove (widget )
347+ box .append (widget )
348+
376349 if activity .metadata :
377350 title_button = TitleEntry (activity )
378- title_button .connect ('enter-key-press' ,
379- lambda widget : self .emit ('enter-key-press' ))
351+ title_button .connect ('enter-key-press' , lambda widget : self .emit ('enter-key-press' ))
380352 title_button .set_visible (True )
381- self . append ( title_button )
353+ safe_append ( self , title_button )
382354
383355 if not orientation_left :
384356 separator = Gtk .Separator (orientation = Gtk .Orientation .VERTICAL )
385357 separator .set_visible (True )
386358 separator .set_expand (True )
387- self . append ( separator )
359+ safe_append ( self , separator )
388360
389361 if activity .metadata :
390362 description_item = DescriptionItem (activity )
391363 description_item .set_visible (True )
392- self . append ( description_item )
364+ safe_append ( self , description_item )
393365
394366 self .share = ShareButton (activity )
395367 self .share .set_visible (True )
396- self .append (self .share )
368+ safe_append (self , self .share )
369+
397370
398371
399372class EditToolbar (Gtk .Box ):
0 commit comments