diff --git a/tools/rxbag/src/rxbag/timeline.py b/tools/rxbag/src/rxbag/timeline.py index 5c84b4a6..92c2efbf 100755 --- a/tools/rxbag/src/rxbag/timeline.py +++ b/tools/rxbag/src/rxbag/timeline.py @@ -397,9 +397,9 @@ class Timeline(wx.Window): def copy_region_to_bag(self): dialog = wx.FileDialog(self, 'Copy messages to...', wildcard='Bag files (*.bag)|*.bag', style=wx.FD_SAVE) if dialog.ShowModal() == wx.ID_OK: - self._export_region(dialog.Path, self.topics, *self.play_region) + wx.CallAfter(self._export_region, dialog.Path, self.topics, self.play_region[0], self.play_region[1]) dialog.Destroy() - + def _export_region(self, path, topics, start_stamp, end_stamp): bag_entries = list(self.get_entries_with_bags(topics, start_stamp, end_stamp)) @@ -417,38 +417,39 @@ class Timeline(wx.Window): except Exception, ex: print >> sys.stderr, 'Error opening bag file [%s] for writing' % path - # Create a dialog to track progress - self._export_progress = wx.ProgressDialog('Exporting messages...', 'Saving %d messages to %s...' % (total_messages, path), - maximum=total_messages, - parent=self, - style=wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME | wx.PD_SMOOTH | wx.PD_AUTO_HIDE) - # Run copying in a background thread self._export_thread = threading.Thread(target=self._run_export_region, args=(export_bag, topics, start_stamp, end_stamp, bag_entries)) self._export_thread.start() def _run_export_region(self, export_bag, topics, start_stamp, end_stamp, bag_entries): - self._keep_exporting = True + #self._keep_exporting = True total_messages = len(bag_entries) update_step = max(1, total_messages / 100) message_num = 1 - + + progress = 0 + + wx.CallAfter(self.frame.StatusBar.gauge.Show) + for bag, entry in bag_entries: try: topic, msg, t = self.read_message(bag, entry.position) export_bag.write(topic, msg, t) except Exception, ex: - print >> sys.stderr, 'Error exporting message at position %d: %s' % (entry.position, str(ex)) + print >> sys.stderr, 'Error exporting message at position %s: %s' % (str(entry.position), str(ex)) if message_num % update_step == 0 or message_num == total_messages: - wx.CallAfter(self._update_export_progress, message_num) - if not self._keep_exporting: - wx.CallAfter(self._export_progress.Destroy) - break - + def update_progress(v): + self.frame.StatusBar.progress = v + + new_progress = int(100.0 * (float(message_num) / total_messages)) + if new_progress != progress: + progress = new_progress + wx.CallAfter(update_progress, progress) + message_num += 1 try: @@ -456,8 +457,7 @@ class Timeline(wx.Window): except Exception, ex: print >> sys.stderr, 'Error closing bag file [%s]: %s' % (export_bag.filename, str(ex)) - def _update_export_progress(self, message_num): - self._keep_exporting, _ = self._export_progress.Update(message_num) + wx.CallAfter(self.frame.StatusBar.gauge.Hide) ### Publishing diff --git a/tools/rxbag/src/rxbag/timeline_status_bar.py b/tools/rxbag/src/rxbag/timeline_status_bar.py index d97b16ea..8c0a34f9 100644 --- a/tools/rxbag/src/rxbag/timeline_status_bar.py +++ b/tools/rxbag/src/rxbag/timeline_status_bar.py @@ -45,28 +45,54 @@ class TimelineStatusBar(wx.StatusBar): self.timeline = timeline - self.timestamp_field = 1 - self.human_readable_field = 2 - self.elapsed_field = 3 - self.playspeed_field = 4 + self.progress_field = 1 + self.timestamp_field = 2 + self.human_readable_field = 3 + self.elapsed_field = 4 + self.playspeed_field = 5 + self.progress_width = 150 self.timestamp_width = 125 self.human_readable_width = 180 self.elapsed_width = 110 self.playspeed_width = 80 - self.SetFieldsCount(5) + self.SetFieldsCount(6) + + self.gauge = wx.Gauge(self, range=100) + self.gauge.Hide() + + self._reposition_progress() parent.Bind(EVT_PLAYHEAD_CHANGED, lambda e: self._update()) parent.Bind(wx.EVT_SIZE, self.on_size) self._update() + # property: progress + + def _get_progress(self): + return self.gauge.Value + + def _set_progress(self, value): + self.gauge.Value = value + + progress = property(_get_progress, _set_progress) + def on_size(self, event): - main_width = self.Size[0] - (self.timestamp_width + self.human_readable_width + self.elapsed_width + self.playspeed_width) - self.SetStatusWidths([main_width, self.timestamp_width, self.human_readable_width, self.elapsed_width, self.playspeed_width]) + main_width = self.Size[0] - (self.progress_width + self.timestamp_width + self.human_readable_width + self.elapsed_width + self.playspeed_width) + self.SetStatusWidths([main_width, self.progress_width, self.timestamp_width, self.human_readable_width, self.elapsed_width, self.playspeed_width]) + + self._reposition_progress() + event.Skip() + def _reposition_progress(self): + rect = self.GetFieldRect(self.progress_field) + + self.gauge.SetPosition((rect.x + 1, rect.y + 1)) + self.gauge.SetSize((rect.width - 2, rect.height - 2)) + def _update(self): if self.timeline.playhead is None or self.timeline.start_stamp is None: return