mwxlib 0.93.1__py3-none-any.whl → 0.93.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mwxlib might be problematic. Click here for more details.

mwx/controls.py CHANGED
@@ -714,7 +714,7 @@ class ControlPanel(scrolled.ScrolledPanel):
714
714
  ## --------------------------------
715
715
  @property
716
716
  def parameters(self):
717
- return [p.value for p in chain(*self.__params)]
717
+ return [p.value for p in self.get_params()]
718
718
 
719
719
  @parameters.setter
720
720
  def parameters(self, v):
mwx/framework.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "0.93.1"
4
+ __version__ = "0.93.7"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from functools import wraps, partial
@@ -963,9 +963,8 @@ class AuiNotebook(aui.AuiNotebook):
963
963
  pane.name = f"pane{j+1}"
964
964
  self._mgr.LoadPerspective(frames)
965
965
  self._mgr.Update()
966
- except Exception as e:
967
- print(f"- Failed to load perspective: {e}")
968
- pass
966
+ except Exception:
967
+ print("- Failed to load perspective:", e)
969
968
  finally:
970
969
  self.Parent.Thaw()
971
970
 
mwx/graphman.py CHANGED
@@ -33,6 +33,19 @@ from .matplot2g import GraphPlot
33
33
  from .matplot2lg import Histogram
34
34
 
35
35
 
36
+ def split_paths(obj):
37
+ """Split obj path into dirname and basename.
38
+ The object can be module name:str, module, or class.
39
+ """
40
+ if hasattr(obj, '__file__'): #<class 'module'>
41
+ obj = obj.__file__
42
+ elif isinstance(obj, type): #<class 'type'>
43
+ obj = inspect.getsourcefile(obj)
44
+ if obj.endswith(".py"):
45
+ obj, _ = os.path.splitext(obj)
46
+ return os.path.split(obj)
47
+
48
+
36
49
  class Thread(object):
37
50
  """Thread manager for graphman.Layer
38
51
 
@@ -167,12 +180,12 @@ class Thread(object):
167
180
  except BdbQuit:
168
181
  pass
169
182
  except KeyboardInterrupt as e:
170
- print("- Thread:execution stopped: {}".format(e))
183
+ print("- Thread:execution stopped:", e)
171
184
  except AssertionError as e:
172
- print("- Thread:execution failed: {}".format(e))
185
+ print("- Thread:execution failed:", e)
173
186
  except Exception as e:
174
187
  traceback.print_exc()
175
- print("- Thread:exception: {}".format(e))
188
+ print("- Thread:exception:", e)
176
189
  self.handler('thread_error', self)
177
190
  finally:
178
191
  self.active = 0
@@ -298,7 +311,11 @@ class LayerInterface(CtrlInterface):
298
311
  self.parent = parent
299
312
  self.__artists = []
300
313
 
301
- self.parameters = None # => reset
314
+ try:
315
+ ## Check if parameters exists without triggering dynamic lookup.
316
+ inspect.getattr_static(self, "parameters")
317
+ except AttributeError:
318
+ self.parameters = None
302
319
 
303
320
  def copy_params(**kwargs):
304
321
  if self.parameters:
@@ -375,24 +392,30 @@ class LayerInterface(CtrlInterface):
375
392
  self.Bind(wx.EVT_WINDOW_DESTROY, destroy)
376
393
 
377
394
  def on_show(v):
395
+ if not self:
396
+ return
378
397
  if v.IsShown():
379
398
  self.handler('page_shown', self)
380
- elif self and isinstance(self.Parent, aui.AuiNotebook):
381
- self.handler('page_hidden', self) # -> notebook
399
+ elif isinstance(self.Parent, aui.AuiNotebook):
400
+ self.handler('page_hidden', self)
382
401
  v.Skip()
383
402
  self.Bind(wx.EVT_SHOW, on_show)
384
403
 
385
404
  try:
386
405
  self.Init()
387
- if session:
388
- self.load_session(session)
389
406
  except Exception as e:
390
407
  traceback.print_exc()
391
408
  if parent:
392
409
  bmp = wx.StaticBitmap(self, bitmap=Icon('!!!'))
393
410
  txt = wx.StaticText(self, label="Exception")
394
- txt.SetToolTip(repr(e))
411
+ txt.SetToolTip(str(e))
395
412
  self.layout((bmp, txt), row=2)
413
+ try:
414
+ if session:
415
+ self.load_session(session)
416
+ except Exception as e:
417
+ traceback.print_exc()
418
+ print("- Failed to load session of", self)
396
419
 
397
420
  def Init(self):
398
421
  """Initialize layout before load_session (to be overridden)."""
@@ -413,7 +436,13 @@ class LayerInterface(CtrlInterface):
413
436
  lambda self,v: self.Show(v))
414
437
 
415
438
  def IsShown(self):
416
- return self.parent.get_pane(self).IsShown()
439
+ """Returns True if the window is physically visible on the screen.
440
+
441
+ Note: This method is overridden to be equivalent to IsShownOnScreen,
442
+ as the object may be a page within a notebook.
443
+ """
444
+ ## return self.pane.IsShown()
445
+ return self.IsShownOnScreen()
417
446
 
418
447
  def Show(self, show=True, interactive=False):
419
448
  """Show associated pane (override) window."""
@@ -439,13 +468,12 @@ class LayerInterface(CtrlInterface):
439
468
  ## Arts may be belonging to graph, output, and any other windows.
440
469
  for art in self.Arts:
441
470
  art.set_visible(show)
442
- ## EVT_SHOW [page_hidden] is called when the page is destroyed.
443
471
  ## To avoid RuntimeError, check if canvas object has been deleted.
444
472
  canvas = art.axes.figure.canvas
445
473
  if canvas:
446
474
  canvas.draw_idle()
447
475
  except Exception as e:
448
- print("- Failed to draw Arts of {!r}: {}".format(self.__module__, e))
476
+ print("- Failed to draw Arts of {}: {}".format(self.__module__, e))
449
477
  del self.Arts
450
478
 
451
479
 
@@ -457,7 +485,6 @@ class Layer(ControlPanel, LayerInterface):
457
485
  LayerInterface.__init__(self, parent, session)
458
486
 
459
487
  ## Explicit (override) precedence
460
- message = LayerInterface.message
461
488
  IsShown = LayerInterface.IsShown
462
489
  Shown = LayerInterface.Shown
463
490
  Show = LayerInterface.Show
@@ -543,8 +570,8 @@ class MyFileDropLoader(wx.FileDropTarget):
543
570
  """File Drop interface
544
571
 
545
572
  Args:
546
- loader : mainframe
547
573
  target : target view to drop in, e.g. frame, graph, pane, etc.
574
+ loader : mainframe
548
575
  """
549
576
  def __init__(self, target, loader):
550
577
  wx.FileDropTarget.__init__(self)
@@ -687,11 +714,11 @@ class Frame(mwx.Frame):
687
714
  (),
688
715
  (mwx.ID_(13), "&Graph window\tF9", "Show graph window", wx.ITEM_CHECK,
689
716
  lambda v: self.show_pane("graph", v.IsChecked()),
690
- lambda v: v.Check(self.get_pane("graph").IsShown())),
717
+ lambda v: v.Check(self.graph.IsShown())),
691
718
 
692
719
  (mwx.ID_(14), "&Output window\tF10", "Show Output window", wx.ITEM_CHECK,
693
720
  lambda v: self.show_pane("output", v.IsChecked()),
694
- lambda v: v.Check(self.get_pane("output").IsShown())),
721
+ lambda v: v.Check(self.output.IsShown())),
695
722
  (),
696
723
  ]
697
724
  self.menubar["Edit"] = [
@@ -717,7 +744,7 @@ class Frame(mwx.Frame):
717
744
  (),
718
745
  (mwx.ID_(24), "&Histogram\tCtrl-h", "Show Histogram window", wx.ITEM_CHECK,
719
746
  lambda v: self.show_pane("histogram", v.IsChecked()),
720
- lambda v: v.Check(self.get_pane("histogram").IsShown())),
747
+ lambda v: v.Check(self.histogram.IsShown())),
721
748
 
722
749
  (mwx.ID_(25), "&Invert Color\t(C-i)", "Invert colormap", wx.ITEM_CHECK,
723
750
  lambda v: self.__view.invert_cmap(),
@@ -796,7 +823,7 @@ class Frame(mwx.Frame):
796
823
  self.handler('C-g pressed', v)
797
824
 
798
825
  ## Accepts DnD
799
- self.SetDropTarget(MyFileDropLoader(self, self))
826
+ self.SetDropTarget(MyFileDropLoader(self.graph, self))
800
827
 
801
828
  sync_switch = True
802
829
 
@@ -905,23 +932,32 @@ class Frame(mwx.Frame):
905
932
  pane.Float()
906
933
  show = True
907
934
 
935
+ ## Fork page shown/closed events to emulatie EVT_SHOW => plug.on_show.
936
+ ## cf. >>> win.EventHandler.ProcessEvent(wx.ShowEvent(win.Id, show))
937
+ ##
938
+ ## Note: We need to distinguish cases whether:
939
+ ## - pane.window is AuiNotebook or normal Panel,
940
+ ## - pane.window is floating (win.Parent is AuiFloatingFrame) or docked.
908
941
  plug = self.get_plug(name) # -> None if pane.window is a Graph
909
942
  win = pane.window # -> Window (plug / notebook / Graph)
910
- if show:
943
+ try:
944
+ shown = plug.IsShown()
945
+ except AttributeError:
946
+ shown = pane.IsShown()
947
+ if show and not shown:
911
948
  if isinstance(win, aui.AuiNotebook):
912
949
  j = win.GetPageIndex(plug)
913
950
  if j != win.Selection:
914
- win.Selection = j # the focus is moved => [page_shown]
951
+ win.Selection = j # the focus is moved => EVT_SHOW
915
952
  else:
916
953
  plug.handler('page_shown', plug)
917
- elif not pane.IsShown():
918
- if not plug or win.Parent is not self: # otherwise Layer.on_show
919
- win.handler('page_shown', win)
920
- else:
954
+ else:
955
+ win.handler('page_shown', win)
956
+ elif not show and shown:
921
957
  if isinstance(win, aui.AuiNotebook):
922
- for plug in win.all_pages: # => [page_closed] to all pages
958
+ for plug in win.all_pages:
923
959
  plug.handler('page_closed', plug)
924
- elif pane.IsShown():
960
+ else:
925
961
  win.handler('page_closed', win)
926
962
 
927
963
  ## Modify the floating position of the pane when displayed.
@@ -929,8 +965,10 @@ class Frame(mwx.Frame):
929
965
  ## and will be fixed in wxPython 4.2.1.
930
966
  if wx.Display.GetFromWindow(pane.window) == -1:
931
967
  pane.floating_pos = wx.GetMousePosition()
968
+
932
969
  pane.Show(show)
933
970
  self._mgr.Update()
971
+ return (show != shown)
934
972
 
935
973
  def update_pane(self, name, show=False, **kwargs):
936
974
  """Update the layout of the pane.
@@ -964,8 +1002,7 @@ class Frame(mwx.Frame):
964
1002
  pane.Dock()
965
1003
  else:
966
1004
  pane.Float()
967
- self.show_pane(name, show)
968
- self._mgr.Update()
1005
+ return self.show_pane(name, show)
969
1006
 
970
1007
  def OnPaneClose(self, evt): #<wx.aui.AuiManagerEvent>
971
1008
  pane = evt.GetPane()
@@ -975,9 +1012,6 @@ class Frame(mwx.Frame):
975
1012
  plug.handler('page_closed', plug)
976
1013
  else:
977
1014
  win.handler('page_closed', win)
978
- pane.Show(0)
979
- self._mgr.Update()
980
- evt.Veto() # Don't skip. Just hide it.
981
1015
 
982
1016
  ## --------------------------------
983
1017
  ## Plugin (Layer) interface
@@ -1031,13 +1065,9 @@ class Frame(mwx.Frame):
1031
1065
  LayerInterface.__init__(self, parent, session)
1032
1066
 
1033
1067
  ## Explicit (override) precedence
1034
- message = LayerInterface.message
1035
1068
  IsShown = LayerInterface.IsShown
1036
1069
  Shown = LayerInterface.Shown
1037
1070
  Show = LayerInterface.Show
1038
-
1039
- ## Implicit (override) precedence
1040
- ## cls.Init / cls.save_session / cls.load_session
1041
1071
 
1042
1072
  _Plugin.__module__ = cls.__module__ = module.__name__
1043
1073
  _Plugin.__name__ = cls.__name__ + str("~")
@@ -1045,20 +1075,6 @@ class Frame(mwx.Frame):
1045
1075
  module.Plugin = _Plugin
1046
1076
  return _Plugin
1047
1077
 
1048
- @staticmethod
1049
- def _split_paths(root):
1050
- if hasattr(root, '__file__'): #<class 'module'>
1051
- name = root.__file__
1052
- elif isinstance(root, type): #<class 'type'>
1053
- name = inspect.getsourcefile(root)
1054
- else:
1055
- name = root
1056
- dirname = os.path.dirname(name)
1057
- name = os.path.basename(name)
1058
- if name.endswith(".py"):
1059
- name, _ = os.path.splitext(name)
1060
- return dirname, name
1061
-
1062
1078
  def load_module(self, root):
1063
1079
  """Load module of plugin (internal use only).
1064
1080
 
@@ -1066,7 +1082,7 @@ class Frame(mwx.Frame):
1066
1082
  This is called automatically from load_plug,
1067
1083
  and should not be called directly from user.
1068
1084
  """
1069
- dirname_, name = self._split_paths(root)
1085
+ dirname_, name = split_paths(root)
1070
1086
 
1071
1087
  ## Update the include-path to load the module correctly.
1072
1088
  if os.path.isdir(dirname_):
@@ -1130,13 +1146,17 @@ class Frame(mwx.Frame):
1130
1146
  props = dict(show=show, dock=dock, layer=layer, pos=pos, row=row, prop=prop,
1131
1147
  floating_pos=floating_pos, floating_size=floating_size)
1132
1148
 
1133
- _dirname, name = self._split_paths(root)
1149
+ _dirname, name = split_paths(root)
1134
1150
 
1135
1151
  plug = self.get_plug(name)
1136
- if plug and not force: # <plug:name> is already registered.
1152
+ if plug and not force:
1137
1153
  self.update_pane(name, **props)
1138
- if session:
1139
- plug.load_session(session)
1154
+ try:
1155
+ if session:
1156
+ plug.load_session(session)
1157
+ except Exception as e:
1158
+ traceback.print_exc()
1159
+ print("- Failed to load session of", plug)
1140
1160
  return None
1141
1161
 
1142
1162
  module = self.load_module(root)
@@ -1173,8 +1193,8 @@ class Frame(mwx.Frame):
1173
1193
  except (AttributeError, NameError) as e:
1174
1194
  traceback.print_exc()
1175
1195
  wx.CallAfter(wx.MessageBox,
1176
- "{}\n\n".format(e) + traceback.format_exc(),
1177
- "Error in loading {!r}".format(module.__name__),
1196
+ f"{e}\n\n" + traceback.format_exc(),
1197
+ f"Error in loading {module.__name__!r}",
1178
1198
  style=wx.ICON_ERROR)
1179
1199
  return False
1180
1200
 
@@ -1187,8 +1207,8 @@ class Frame(mwx.Frame):
1187
1207
  except Exception as e:
1188
1208
  traceback.print_exc()
1189
1209
  wx.CallAfter(wx.MessageBox,
1190
- "{}\n\n".format(e) + traceback.format_exc(),
1191
- "Error in loading {!r}".format(name),
1210
+ f"{e}\n\n" + traceback.format_exc(),
1211
+ f"Error in loading {name!r}",
1192
1212
  style=wx.ICON_ERROR)
1193
1213
  return False
1194
1214
 
@@ -1252,7 +1272,7 @@ class Frame(mwx.Frame):
1252
1272
  plug.__Menu_item = (
1253
1273
  module.ID_, text, hint, wx.ITEM_CHECK,
1254
1274
  lambda v: self.show_pane(name, v.IsChecked(), interactive=1),
1255
- lambda v: v.Check(self.get_pane(name).IsShown()),
1275
+ lambda v: v.Check(plug.IsShown()),
1256
1276
  )
1257
1277
  if menu not in self.menubar:
1258
1278
  self.menubar[menu] = []
@@ -1300,8 +1320,8 @@ class Frame(mwx.Frame):
1300
1320
  except Exception as e:
1301
1321
  traceback.print_exc()
1302
1322
  wx.CallAfter(wx.MessageBox,
1303
- "{}\n\n".format(e) + traceback.format_exc(),
1304
- "Error in unloading {!r}".format(name),
1323
+ f"{e}\n\n" + traceback.format_exc(),
1324
+ f"Error in unloading {name!r}",
1305
1325
  style=wx.ICON_ERROR)
1306
1326
  return False
1307
1327
 
@@ -1316,7 +1336,7 @@ class Frame(mwx.Frame):
1316
1336
  plug.save_session(session)
1317
1337
  except Exception:
1318
1338
  traceback.print_exc()
1319
- print("- Failed to save session: {}".format(plug))
1339
+ print("- Failed to save session of", plug)
1320
1340
  return self.load_plug(plug.__module__, force=1, session=session)
1321
1341
  return False
1322
1342
 
@@ -1476,7 +1496,7 @@ class Frame(mwx.Frame):
1476
1496
  except FileNotFoundError:
1477
1497
  pass
1478
1498
  except Exception as e:
1479
- print("- Failed to read attributes: {}".format(e))
1499
+ print("- Failed to read attributes:", e)
1480
1500
  wx.MessageBox(str(e), style=wx.ICON_ERROR)
1481
1501
  finally:
1482
1502
  return res, mis # finally raises no exception
@@ -1499,7 +1519,7 @@ class Frame(mwx.Frame):
1499
1519
  pprint(tuple(new.items()), stream=o)
1500
1520
 
1501
1521
  except Exception as e:
1502
- print("- Failed to write attributes: {}".format(e))
1522
+ print("- Failed to write attributes:", e)
1503
1523
  wx.MessageBox(str(e), style=wx.ICON_ERROR)
1504
1524
  finally:
1505
1525
  return new, mis # finally raises no exception
@@ -1617,7 +1637,7 @@ class Frame(mwx.Frame):
1617
1637
  self.message("\b done.")
1618
1638
  except Exception as e:
1619
1639
  self.message("\b failed.")
1620
- wx.MessageBox(repr(e), style=wx.ICON_ERROR)
1640
+ wx.MessageBox(str(e), style=wx.ICON_ERROR)
1621
1641
 
1622
1642
  if frame:
1623
1643
  view.select(frame)
@@ -1778,7 +1798,7 @@ class Frame(mwx.Frame):
1778
1798
  plug.save_session(session)
1779
1799
  except Exception:
1780
1800
  traceback.print_exc()
1781
- print("- Failed to save session: {}".format(plug))
1801
+ print("- Failed to save session of", plug)
1782
1802
  o.write("self.load_plug({!r}, session={})\n".format(path, session or None))
1783
1803
  o.write("self._mgr.LoadPerspective({!r})\n".format(self._mgr.SavePerspective()))
1784
1804
 
mwx/matplot2.py CHANGED
@@ -297,8 +297,8 @@ class MatplotPanel(wx.Panel):
297
297
  self.cursor.visible = 1
298
298
 
299
299
  def draw(self, art=None):
300
- """Draw the plot.
301
- Called every time the drawing is updated.
300
+ """Draw plots.
301
+ Call each time the drawing should be updated.
302
302
  """
303
303
  if isinstance(art, matplotlib.artist.Artist):
304
304
  self.axes.draw_artist(art)
@@ -403,16 +403,16 @@ class MatplotPanel(wx.Panel):
403
403
 
404
404
  def copy_to_clipboard(self):
405
405
  """Copy canvas image to clipboard."""
406
- self.message("Copy image to clipboard.")
406
+ ## b = self.selected.get_visible()
407
+ c = self.cursor.visible
407
408
  try:
408
- b = self.selected.get_visible()
409
- c = self.cursor.visible
410
- self.selected.set_visible(0)
409
+ ## self.selected.set_visible(0)
411
410
  self.cursor.visible = 0
412
411
  self.canvas.draw()
413
412
  self.canvas.Copy_to_Clipboard()
413
+ self.message("Copy image to clipboard.")
414
414
  finally:
415
- self.selected.set_visible(b)
415
+ ## self.selected.set_visible(b)
416
416
  self.cursor.visible = c
417
417
  self.canvas.draw()
418
418
 
@@ -428,8 +428,7 @@ class MatplotPanel(wx.Panel):
428
428
  self.message("({:g}, {:g})".format(x, y))
429
429
 
430
430
  def on_figure_enter(self, evt): #<matplotlib.backend_bases.MouseEvent>
431
- if self.Selector.size:
432
- self.trace_point(*self.Selector)
431
+ pass
433
432
 
434
433
  def on_figure_leave(self, evt): #<matplotlib.backend_bases.MouseEvent>
435
434
  self.cursor.clear(evt)
@@ -605,10 +604,6 @@ class MatplotPanel(wx.Panel):
605
604
 
606
605
  ZOOM_RATIO = 10**0.2
607
606
 
608
- def update_position(self):
609
- self.toolbar.update()
610
- self.toolbar.push_current()
611
-
612
607
  def OnDraw(self, evt):
613
608
  """Called before canvas.draw."""
614
609
  pass
@@ -631,12 +626,14 @@ class MatplotPanel(wx.Panel):
631
626
  def OnHomePosition(self, evt):
632
627
  """Go back to home position."""
633
628
  self.toolbar.home()
634
- self.update_position()
629
+ self.toolbar.update()
630
+ self.toolbar.push_current()
635
631
  self.draw()
636
632
 
637
633
  def OnEscapeSelection(self, evt):
638
634
  """Escape from selection."""
639
635
  del self.Selector
636
+ self.canvas.draw_idle()
640
637
 
641
638
  ## def OnShiftLimit(self, evt, r=0.1):
642
639
  ## w = self.xlim[1] - self.xlim[0]
@@ -687,7 +684,6 @@ class MatplotPanel(wx.Panel):
687
684
  ## self.toolbar.set_cursor(1)
688
685
  self.set_wxcursor(wx.CURSOR_ARROW)
689
686
  self.toolbar.pan()
690
- ## self.draw()
691
687
  self.handler.current_state = self.__prev # --> previous state of PAN
692
688
  del self.__prev
693
689
 
@@ -702,7 +698,6 @@ class MatplotPanel(wx.Panel):
702
698
  ## self.toolbar.set_cursor(1)
703
699
  self.set_wxcursor(wx.CURSOR_ARROW)
704
700
  self.toolbar.zoom()
705
- ## self.draw()
706
701
  self.handler.current_state = self.__prev # --> previous state of ZOOM
707
702
  del self.__prev
708
703
 
mwx/matplot2g.py CHANGED
@@ -703,7 +703,7 @@ class GraphPlot(MatplotPanel):
703
703
 
704
704
  self.draw()
705
705
  self.writeln()
706
- self.trace_point(*self.Selector, type=NORMAL)
706
+ self.trace_point(*self.Selector)
707
707
 
708
708
  return self.frame
709
709
 
@@ -863,7 +863,8 @@ class GraphPlot(MatplotPanel):
863
863
  """Reset display range (xylim's), update home position."""
864
864
  if self.frame:
865
865
  self.axes.axis(self.frame.get_extent()) # reset xlim and ylim
866
- self.update_position()
866
+ self.toolbar.update()
867
+ self.toolbar.push_current()
867
868
  self.draw()
868
869
 
869
870
  def fit_to_canvas(self):
@@ -887,6 +888,7 @@ class GraphPlot(MatplotPanel):
887
888
  MatplotPanel.on_focus_set(self, evt)
888
889
  if self.frame:
889
890
  self.handler('frame_selected', self.frame)
891
+ self.trace_point(*self.Selector)
890
892
 
891
893
  def on_focus_kill(self, evt):
892
894
  """Called when focus is killed (override)."""
@@ -979,24 +981,24 @@ class GraphPlot(MatplotPanel):
979
981
  clipboard_data = None
980
982
 
981
983
  def write_buffer_to_clipboard(self):
982
- """Copy - Write buffer data to clipboard."""
984
+ """Write buffer data to clipboard."""
983
985
  if not self.frame:
984
986
  self.message("No frame")
985
987
  return
986
988
  try:
987
- self.message("Write buffer to clipboard.")
988
989
  name = self.frame.name
989
990
  data = self.frame.roi
990
991
  GraphPlot.clipboard_name = name
991
992
  GraphPlot.clipboard_data = data
992
993
  bins, vlim, img = imconvert(data, self.frame.vlim)
993
994
  Clipboard.imwrite(img)
995
+ self.message("Write buffer to clipboard.")
994
996
  except Exception as e:
995
- self.message("- Failure in clipboard: {}".format(e))
996
997
  traceback.print_exc()
998
+ self.message("- Failed to write to clipboard:", e)
997
999
 
998
1000
  def read_buffer_from_clipboard(self):
999
- """Paste - Read buffer data from clipboard."""
1001
+ """Read buffer data from clipboard."""
1000
1002
  try:
1001
1003
  name = GraphPlot.clipboard_name
1002
1004
  data = GraphPlot.clipboard_data
@@ -1009,8 +1011,8 @@ class GraphPlot(MatplotPanel):
1009
1011
  self.message("Read image from clipboard.")
1010
1012
  self.load(Clipboard.imread())
1011
1013
  except Exception as e:
1012
- self.message("- No data in clipboard: {}".format(e))
1013
1014
  traceback.print_exc()
1015
+ self.message("- No data in clipboard:", e)
1014
1016
 
1015
1017
  def destroy_colorbar(self):
1016
1018
  if self.cbar:
@@ -1137,8 +1139,8 @@ class GraphPlot(MatplotPanel):
1137
1139
 
1138
1140
  def OnMotion(self, evt):
1139
1141
  """Called when mouse moves in axes (overridden)."""
1140
- if self.frame and self.Selector.shape[1] < 2:
1141
- self.trace_point(evt.xdata, evt.ydata, type=NORMAL)
1142
+ if self.Selector.shape[1] < 2:
1143
+ self.trace_point(evt.xdata, evt.ydata)
1142
1144
 
1143
1145
  def OnPageDown(self, evt):
1144
1146
  """Next page."""