OpenStructure
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
menu.py
Go to the documentation of this file.
1 from PyQt5.QtCore import *
2 from PyQt5.QtGui import *
3 from PyQt5.QtWidgets import *
4 from ost import *
5 from ost import gui
6 from ost.gui.init_splash import _InitSplash
7 from ost.gui.dng import termuse
8 from ost.gui.dng import superpositiondialog
9 
10 import sys
11 class FileMenu(QMenu):
12  def __init__(self, parent=None):
13  QMenu.__init__(self, parent)
14  self.setTitle('File')
15  gui.AddMenuAction(self, 'Open', self._Open, shortcut='Ctrl+O')
16  gui.AddMenuAction(self, 'Save As...', self._SaveAs,
17  shortcut='Ctrl+Shift+S',
18  enabled=gui.OneOf(gfx.Entity))
19  def _Open(self):
20  filename,_=QFileDialog.getOpenFileName(None, 'Open file','')
21  if(QFileInfo(filename).isFile()):
22  gui.FileLoader.LoadObject(str(filename))
23 
24  def _SaveAs(self):
25  sel_node=gui.SceneSelection.Instance().GetActiveNode(0)
26  filename=QFileDialog.getSaveFileName(None, 'Save As',
27  '%s.pdb' % sel_node.name)
28  io.SavePDB(sel_node.view, str(filename))
29 
30 class ClipWidget(QWidget):
31  def __init__(self, width=500, height=500):
32  QWidget.__init__(self)
33  self.setWindowFlags(Qt.Tool)
34  l = QGridLayout(self)
35  l.addWidget(QLabel("Near"), 0, 0)
36  l.addWidget(QLabel("Far"), 1, 0)
37  bounds_near = QLineEdit(str(0))
38  bounds_near.setValidator(QIntValidator(0, 9999, bounds_near))
39  bounds_near.setMaxLength(4)
40  bounds_near.setMaximumWidth(50)
41  bounds_far = QLineEdit(str(200))
42  bounds_far.setValidator(QIntValidator(0, 9999, bounds_far))
43  bounds_far.setMaxLength(4)
44  bounds_far.setMaximumWidth(50)
45  l.addWidget(bounds_near, 0, 1, 2, 1)
46  l.addWidget(bounds_far, 0, 3, 2, 1)
47  self.near_ = QSlider(Qt.Horizontal)
48  self.near_.setMinimum(int(bounds_near.text()))
49  self.near_.setMaximum(int(bounds_far.text()))
50  self.near_.setValue(int(gfx.Scene().near))
51  self.far_ = QSlider(Qt.Horizontal)
52  self.far_.setMinimum(int(bounds_near.text()))
53  self.far_.setMaximum(int(bounds_far.text()))
54  far = int(gfx.Scene().far)
55  if far>sys.maxsize:
56  far = sys.maxsize
57  self.far_.setValue(far)
58  self.auto_ = QCheckBox("Continuous Automatic Clipping")
59  self.auto_.setChecked(gfx.Scene().GetAutoAutoslab())
60 
61  l.addWidget(self.near_, 0, 2)
62  l.addWidget(self.far_, 1, 2)
63  l.addWidget(self.auto_, 2, 0, 1, 4)
64  self.near_.valueChanged.connect(self.SetNear)
65  self.far_.valueChanged.connect(self.SetFar)
66  self.auto_.stateChanged.connect(self.SetAuto)
67  bounds_near.textEdited.connect(self.SetNearBounds)
68  bounds_far.textEdited.connect(self.SetFarBounds)
69 
70  def SetNear(self, val):
71  gfx.Scene().near = val
72 
73  def SetFar(self, val):
74  gfx.Scene().far = val
75 
76  def SetAuto(self, val):
77  gfx.Scene().AutoAutoslab(val)
78  gfx.Scene().near = int(self.near_.value())
79  gfx.Scene().far = int(self.far_.value())
80 
81  def SetNearBounds(self, text):
82  if text!='':
83  self.near_.setMinimum(int(text))
84  self.far_.setMinimum(int(text))
85 
86  def SetFarBounds(self, text):
87  if text!='':
88  self.near_.setMaximum(int(text))
89  self.far_.setMaximum(int(text))
90 
91 class ExportSceneDialog(QDialog):
92  def __init__(self, width=500, height=500):
93  QDialog.__init__(self)
94  l=QGridLayout(self)
95  l.setColumnMinimumWidth(0, 100)
96  l.addWidget(QLabel("Width (px)"), 0, 0)
97  l.addWidget(QLabel("Height (px)"), 1, 0)
98  self.width_=QLineEdit(str(width))
99  self.height_=QLineEdit((str(height)))
100  self.width_.setValidator(QIntValidator(50, 3000, self.width_))
101  self.height_.setValidator(QIntValidator(50, 3000, self.height_))
102  self.opaque_=QCheckBox("Force Opaque Background")
103  l.addWidget(self.width_, 0, 1)
104  l.addWidget(self.height_, 1, 1)
105  l.addWidget(self.opaque_, 2, 1)
106  hbox=QHBoxLayout()
107  cancel=QPushButton("Cancel")
108  cancel.clicked.connect(self.reject)
109  hbox.addWidget(cancel)
110  export=QPushButton("Export")
111  hbox.addWidget(export)
112  export.setDefault(True)
113  l.addLayout(hbox, 3, 1, 2, 1)
114  export.clicked.connect(self.accept)
115  @property
116  def transparent(self):
117  return not self.opaque_.isChecked()
118 
119  @property
120  def width(self):
121  return int(self.width_.text())
122 
123  @property
124  def height(self):
125  return int(self.height_.text())
126 
127 class SceneMenu(QMenu):
128  def __init__(self, parent=None):
129  QMenu.__init__(self, parent)
130  self.setTitle('Scene')
131  self.aboutToShow.connect(self._AboutToShow)
132  gui.AddMenuAction(self, 'Background Color', self._SetSceneBackground)
133  self.fog_action=gui.AddMenuAction(self, 'Depth Cueing', self._ToggleFog,
134  shortcut='Ctrl+Shift+F', checkable=True,
135  checked=gfx.Scene().fog)
136  gui.AddMenuAction(self, 'Center', self._Center,
137  enabled=gui.ManyOf(gfx.GfxObj))
138  gui.AddMenuAction(self, 'Fit To Screen', self._FitToScreen,
139  enabled=gui.OneOf(gfx.Entity))
140  gui.AddMenuAction(self, 'Superpose', self._SuperposeDialog,
141  enabled=gui.TwoOf(gfx.Entity))
142  gui.AddMenuAction(self, 'Save Snapshot', self._ExportScene)
143  gui.AddMenuAction(self, 'Scene Clipping', self._ClipScene, shortcut='Ctrl+Shift+C')
144 
145  def _ExportScene(self):
146  qd=ExportSceneDialog()
147  if not qd.exec_():
148  return
149 
150  options = QFileDialog.Options()
151  options |= QFileDialog.DontUseNativeDialog
152  filename, _ = QFileDialog.getSaveFileName(self,"Save Snapshot","snapshot.png", "", options=options)
153 
154  if filename:
155  gfx.Scene().Export(str(filename), qd.width, qd.height, qd.transparent)
156 
157  def _ClipScene(self):
158  self.cw = ClipWidget()
159  self.cw.show()
160 
161  def _AboutToShow(self):
162  self.fog_action.setChecked(gfx.Scene().fog)
163 
164  def _Center(self):
165  sel=gui.SceneSelection.Instance()
166  gfx.Scene().center=sel.GetActiveNode(0).center
167 
168  def _SetSceneBackground(self):
169  new_color=gui.PickColor(gfx.Scene().bg)
170  if new_color:
171  gfx.Scene().bg=new_color
172 
173  def _ToggleFog(self):
174  gfx.Scene().fog=not gfx.Scene().fog
175  self.fog_action.setChecked(gfx.Scene().fog)
176 
177  def _FitToScreen(self):
178  sel=gui.SceneSelection.Instance()
179  gfx.FitToScreen(sel.GetActiveNode(0))
180 
181  def _SuperposeDialog(self):
182  sel=gui.SceneSelection.Instance()
183  act_count=sel.GetActiveNodeCount()
184  # we now that there have to be 2 gfx.Entities, because of using TwoOf to
185  # enable menu entry!
186  i = 0;
187  gfx_ent_1 = sel.GetActiveNode(i)
188  while not isinstance(gfx_ent_1, gfx.Entity):
189  i += 1
190  gfx_ent_1 = sel.GetActiveNode(i)
191  i += 1
192  gfx_ent_2 = sel.GetActiveNode(i)
193  while not isinstance(gfx_ent_2, gfx.Entity):
194  i += 1
195  gfx_ent_2 = sel.GetActiveNode(i)
196  sd = superpositiondialog.SuperpositionDialog(gfx_ent_1, gfx_ent_2)
197  if sd.rmsd_superposed_atoms != None:
198  if sd.reference == 0:
199  gfx_ent_2.UpdatePositions()
200  gfx.Scene().CenterOn(gfx_ent_1)
201  else:
202  gfx_ent_1.UpdatePositions()
203  gfx.Scene().CenterOn(gfx_ent_2)
204  LogScript('RMSD: %.3f'%sd.rmsd)
205  LogScript('RMSD superposed atoms: %.3f'%sd.rmsd_superposed_atoms)
206  LogScript('fraction superposed: %.3f'%sd.fraction_superposed)
207  elif sd.rmsd != None:
208  if sd.reference == 0:
209  gfx_ent_2.UpdatePositions()
210  gfx.Scene().CenterOn(gfx_ent_1)
211  else:
212  gfx_ent_1.UpdatePositions()
213  gfx.Scene().CenterOn(gfx_ent_2)
214  LogScript('RMSD: %.3f'%sd.rmsd)
215  elif sd.superposition_error != None:
216  LogScript('Superposition Failed: ' + sd.superposition_error)
217  else:
218  LogScript('Superposition Failed!')
219 
220 class WindowMenu(QMenu):
221  def __init__(self, parent=None):
222  QMenu.__init__(self, parent)
223  self.setTitle('Window')
224  gosty=gui.GostyApp.Instance()
225  self.aboutToShow.connect(self._AboutToShow)
226  inspector_visible=gosty.GetWidget('InspectorDialog').isVisible()
227  self._gl_win_action=gui.AddMenuAction(self, 'GL Window',
228  self._ToggleShowGLWindow, checkable=True,
229  checked=gosty.gl_win.qobject.isVisible(),
230  shortcut='Ctrl+G')
231  self._inspector_action=gui.AddMenuAction(self, 'Inspector',
233  checkable=True,
234  checked=inspector_visible,
235  shortcut='Ctrl+I')
236  self.addSeparator()
237  self.addMenu(gosty.perspective.panels.menu)
238  gui.AddMenuAction(self, 'Reset View', self._ResetView)
239  def _AboutToShow(self):
240  gosty=gui.GostyApp.Instance()
241  self._gl_win_action.setChecked(gosty.gl_win.qobject.isVisible())
242  inspector_visible=gosty.GetWidget('InspectorDialog').isVisible()
243  self._inspector_action.setChecked(inspector_visible)
244 
245  def _ToggleShowGLWindow(self):
246  gosty=gui.GostyApp.Instance()
247  gl_win=gosty.GetGLWin()
248  if gl_win and gl_win.qobject.isHidden():
249  gl_win.Show()
250  else:
251  gl_win.Hide()
252 
253  def _ToggleShowInspector(self):
254  gosty=gui.GostyApp.Instance()
255  inspector=gosty.GetWidget('InspectorDialog')
256  if inspector and inspector.isHidden():
257  inspector.show()
258  else:
259  inspector.hide()
260 
261  def _ResetView(self):
262  msg_box = QMessageBox()
263  msg_box.setWindowTitle("Reset the Panels and Widget");
264  msg_box.setIcon(QMessageBox.Question)
265  msg_box.setText("Do you really want to reset the Panels and Widgets?");
266  msg_box.setStandardButtons(QMessageBox.Yes |
267  QMessageBox.Cancel);
268  msg_box.setDefaultButton(QMessageBox.Cancel);
269  ret = msg_box.exec_();
270  if(ret == QMessageBox.Yes):
271  settings = QSettings()
272  settings.setValue("restore_settings",QVariant(False))
273  info_box = QMessageBox()
274  info_box.setStandardButtons(QMessageBox.Ok)
275  info_box.setIcon(QMessageBox.Information)
276  info_box.setWindowTitle("Restart OpenStructure")
277  info_box.setText("You must restart OpenStructure for the changes to take effect!");
278  info_box.exec_();
279 
280 class HelpMenu(QMenu):
281  def __init__(self, parent=None):
282  QMenu.__init__(self, parent)
283  self.setTitle('Help')
284  gui.AddMenuAction(self, 'Documentation', self._VisitDocs)
285  gui.AddMenuAction(self, 'About', self._ShowAboutDialog)
286  if sys.platform=='darwin':
287  gui.AddMenuAction(self, 'Install Command Line Tool',
288  termuse.InstallTerminalPrograms)
289  def _VisitDocs(self):
290  QDesktopServices.openUrl(QUrl("http://www.openstructure.org/docs/"))
291 
292  def _ShowAboutDialog(self):
293  _InitSplash()
294 
295 def _InitMenu():
296  _InitMenu.mbar=gui.GostyApp.Instance().perspective.GetMenuBar()
297  file_menu=FileMenu(_InitMenu.mbar)
298  scene_menu=SceneMenu(_InitMenu.mbar)
299  win_menu=WindowMenu(_InitMenu.mbar)
300  help_menu=HelpMenu(_InitMenu.mbar)
301  _InitMenu.mbar.addMenu(file_menu)
302  _InitMenu.mbar.addMenu(scene_menu)
303  _InitMenu.mbar.addMenu(win_menu)
304  _InitMenu.mbar.addMenu(help_menu)
main class for organization and root for the graphical display
Definition: scene.hh:80
main class for all graphic objects
Definition: gfx_object.hh:51
graphical rendering of mol::EntityHandle entites
Definition: entity.hh:60