Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

#$Id: wxMainFrame.py 201 2014-04-29 00:31:07Z sarkiss $ 

"""MainFrame for PyRx: Virtual Screening with AutoDock 

Uses VTK and wxPython GUI with  wx.aui (Advanced User Interface)""" 

import wx 

import wx.aui 

import pdb, sys, os, traceback, shutil 

from utils import rcFolder 

from enthought.preferences.api import get_default_preferences 

class ProgressStop(Exception): 

    """This exception is raised when cancel is pressed in the ProgressDialog""" 

    pass 

 

from about import version 

from hbonds import toggle_hbonds 

from mayaviActions import AddMayaviMenus, ID_RUN 

from icons import atomPNG, pythonPNG, PyRxIcon, selectionPNG, hbondPNG 

ID_OPEN = wx.NewId() 

ID_PREFERENCES = wx.NewId() 

ID_PERSPECTIVE = wx.NewId() 

ID_ABOUT = wx.NewId() 

ID_UPDATE = wx.NewId() 

ID_IMPORT = wx.NewId() 

ID_EXPORT = wx.NewId() 

ID_HBOND = wx.NewId() 

#ID_SHELL = wx.NewId() 

 

class MainFrame(wx.Frame): 

    "This is the main frame for the app" 

    def __init__(self, parent, id=-1, 

                 size=(800, 500), style=wx.DEFAULT_FRAME_STYLE): 

        title = "PyRx - Virtual Screening Tool - Version "+version 

        wx.Frame.__init__(self, parent, id, title, (10,10), size, style) 

        flags = wx.aui.AUI_MGR_ALLOW_FLOATING|wx.aui.AUI_MGR_TRANSPARENT_HINT|wx.aui.AUI_MGR_HINT_FADE|\ 

        wx.aui.AUI_MGR_TRANSPARENT_DRAG|wx.aui.AUI_MGR_NO_VENETIAN_BLINDS_FADE|wx.aui.AUI_MGR_ALLOW_ACTIVE_PANE 

        self._mgr = wx.aui.AuiManager(self, flags) 

        # create menu 

        self.menuBar = wx.MenuBar() 

 

        fileMenu = wx.Menu() 

        fileMenu.Append(ID_OPEN, "&Load Molecule") 

        AddMayaviMenus(fileMenu, self) 

        fileMenu.AppendSeparator() 

        fileMenu.Append(ID_IMPORT, "&Import...") 

        fileMenu.Append(ID_EXPORT, "&Export...") 

 

        fileMenu.AppendSeparator() 

        fileMenu.Append(wx.ID_EXIT, "&Exit") 

        self.fileMenu = fileMenu 

        self.menuBar.Append(fileMenu, "&File") 

 

        editMenu = wx.Menu() 

        editMenu.Append(ID_PREFERENCES, "&Preferences...") 

        self.menuBar.Append(editMenu, "&Edit") 

 

 

        viewMenu = wx.Menu() 

 

        self.navigatorMenu = viewMenu.Append(wx.ID_ANY, "Navigator", kind=wx.ITEM_CHECK) 

        self.navigatorMenu.Check() 

        #removed View -> Graphics/Documents from here since hiding was not working properly (on Linux) 

        self.shellMenu = viewMenu.Append(wx.ID_ANY, "Wizard/Shell", kind=wx.ITEM_CHECK) 

        self.shellMenu.Check() 

 

        viewMenu.AppendSeparator() 

        viewMenu.Append(ID_PERSPECTIVE, "&Reset Perspective") 

        self.menuBar.Append(viewMenu, "&View") 

 

        helpMenu = wx.Menu() 

        helpMenu.Append(ID_UPDATE, "&Check for Updates...") 

        helpMenu.AppendSeparator() 

        helpMenu.Append(ID_ABOUT, "&About...") 

 

        self.menuBar.Append(helpMenu, "&Help") 

 

 

        self.SetMenuBar(self.menuBar) 

        #bind Menu and Toolbar event 

        self.Bind(wx.EVT_MENU, self.OnFileOpenMenu, id=ID_OPEN) 

        self.Bind(wx.EVT_MENU, self.OnImport, id=ID_IMPORT) 

        self.Bind(wx.EVT_MENU, self.OnExport, id=ID_EXPORT) 

        self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT) 

        self.Bind(wx.EVT_MENU, self.OnPreferences, id=ID_PREFERENCES) 

        self.Bind(wx.EVT_MENU, self.ResetPerspective, id=ID_PERSPECTIVE) 

        self.Bind(wx.EVT_MENU_RANGE, self.OnFileHistory, id=wx.ID_FILE1, id2=wx.ID_FILE9) 

 

        self.Bind(wx.EVT_MENU, self.ToggleNavigator, self.navigatorMenu) 

        self.Bind(wx.EVT_MENU, self.ToggleShell, self.shellMenu) 

 

        self.Bind(wx.EVT_CLOSE, self.OnClose) 

 

        # create statusbar 

        self.statusBar = self.CreateStatusBar(1, wx.ST_SIZEGRIP) 

        self.statusBar.SetStatusWidths([-1]) 

        self.statusBar.SetStatusText("Welcome to " + title, 0) 

        self.progressDialog = None 

        self.progressTextSuffix = None 

        # create toolbar 

        self.toolBar = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize, 

                                  wx.TB_FLAT | wx.TB_NODIVIDER) 

 

        self.toolBar.AddLabelTool(ID_OPEN, "Open", atomPNG, 

                                  shortHelp="Load Molecule (MolKit)", longHelp="Reads Molecule supported by MolKit and displays it") 

        self.toolBar.AddLabelTool(ID_RUN, "Run", pythonPNG, 

                                  shortHelp="Run Python script", longHelp="Run Python script") 

 

 

        self.navigator = wx.aui.AuiNotebook(self,size=wx.Size(size[0]/2,size[1]), 

                                           style=wx.aui.AUI_NB_TOP | 

                                       wx.aui.AUI_NB_TAB_SPLIT | 

                                       wx.aui.AUI_NB_TAB_MOVE | 

                                       wx.aui.AUI_NB_SCROLL_BUTTONS | 

                                       wx.aui.AUI_NB_WINDOWLIST_BUTTON) 

 

        self.view = wx.aui.AuiNotebook(self,size=wx.Size(size[0],size[1]), 

                                           style=wx.aui.AUI_NB_TOP | 

                                           wx.aui.AUI_NB_TAB_SPLIT | 

                                           wx.aui.AUI_NB_TAB_MOVE | 

                                           #wx.aui.AUI_NB_WINDOWLIST_BUTTON| 

                                           wx.aui.AUI_NB_SCROLL_BUTTONS 

                                           #|wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB 

                                           ) 

 

        self.controls = wx.aui.AuiNotebook(self,size=wx.Size(size[0],size[1]/2), 

                                           style=wx.aui.AUI_NB_TOP | 

                                           wx.aui.AUI_NB_TAB_SPLIT | 

                                           wx.aui.AUI_NB_TAB_MOVE | 

                                           wx.aui.AUI_NB_SCROLL_BUTTONS) 

 

        messages = [] 

        import preferences 

        self.preferences_manager = preferences.preferences_manager 

        from molNavigator import MolNavigator, ID_CLEAR 

        self.molNav = MolNavigator(self) #Navigator -> Molecules tab 

        from autodockNavigator import AutoDockNavigator 

        self.autodockNav = AutoDockNavigator(self) #Navigator -> AutoDock tab 

        from mayaviEngine import MayaviEngine 

        MayaviEngine(self) #Navigator -> Graphics tab 

 

        try: 

            from matplotlibCanvas import PlotNotebook 

            self.matplot = PlotNotebook(self) 

        except Exception, inst: 

            messages.append("Error importing matplotlibCanvas: " + str(inst)) 

 

        from textView import DocumentsView 

        self.documentsView = DocumentsView(self) # View -> Documents 

 

        from vinaWizard import VinaWizard 

        self.vinaWiz = VinaWizard(self) #Vina controls   

        from autodockWizard import AutoDockWizard 

        self.autodockWiz = AutoDockWizard(self) #AutoDock controls   

        try: 

            import traitedBabel 

            self.openBabel = traitedBabel.ChemicalTable(self) 

        except Exception, inst: 

            messages.append("Error importing traitedBabel: " + str(inst)) 

        from shellCtrl import ShellController 

        self.shellCtrl = ShellController(self) #Python Shell under controls 

        from database import TableList 

        self.dbView = TableList(self) 

        from logger import Logger 

        self.logger = Logger(self) 

        from vtkAdaptor import vtkAdaptor 

        self.pmv = vtkAdaptor() 

        if messages: 

            for msg in messages: 

                self.log.warning(msg) 

 

        self._mgr.AddPane(self.navigator, wx.aui.AuiPaneInfo().Name('Navigator').Caption('Navigator').CloseButton(False).MaximizeButton(True).MinimizeButton(True).Left()) 

        self.graphicsPaneInfo = wx.aui.AuiPaneInfo().Name("Graphics").Caption('View').CaptionVisible(True).CloseButton(False).MaximizeButton(True).MinimizeButton(True).Center() 

        self._mgr.AddPane(self.view, self.graphicsPaneInfo) 

        self.shellPaneInfo = wx.aui.AuiPaneInfo().Name("Controls").Caption('Controls').CaptionVisible(True).CloseButton(False).MaximizeButton(True).MinimizeButton(True).Bottom() 

        self._mgr.SetDockSizeConstraint(1./3., 0.4) 

        self._mgr.AddPane(self.controls, self.shellPaneInfo) 

 

        from about import About 

        self.Bind(wx.EVT_MENU, About, id=ID_ABOUT) 

        from update import Update 

        self.Bind(wx.EVT_MENU, Update, id=ID_UPDATE) 

 

        self.toolBar.AddSeparator() 

        self.toolBar.AddCheckLabelTool(ID_HBOND, "Hydrogen Bonds", hbondPNG, 

                                  shortHelp="Toggle Hydrogen Bonds", longHelp="Hydrogen Bonds") 

        self.Bind(wx.EVT_TOOL, toggle_hbonds, id=ID_HBOND) 

 

        self.toolBar.AddCheckLabelTool(ID_CLEAR, "Selection Spheres", selectionPNG, 

                                  shortHelp="Toggle Selection Spheres", longHelp="Toggle Selection Spheres") 

        self.Bind(wx.EVT_TOOL, self.molNav.ToggleSelection, id=ID_CLEAR) 

 

        self.toolBar.Realize() 

        self._mgr.AddPane(self.toolBar, wx.aui.AuiPaneInfo().Name("toolbar").Caption("Toolbar").ToolbarPane().Top()) 

 

        size1 = self.autodockWiz.book.GetPage(0).sizer.GetMinSize() 

        size2 = self.controls.GetSize() 

        if size2[1] < size1[1]: 

            size2[1] = size1[1] 

            self.controls.SetSize(size2) 

        self.perspectiveInfo = self._mgr.SavePerspective() 

        self.LoadPerspective() 

        self.__create_file_history() 

        self.SetIcon(PyRxIcon) 

        preferences.setGlobalPreferences() 

#         from PyRx import Plugins 

#         wx.CallAfter(Plugins.init, self)   

 

    def ToggleShell(self, event): 

        "Toggles shell if self.shellMenu.IsChecked" 

        pane = self._mgr.GetPane("Controls") 

        if self.shellMenu.IsChecked(): 

            self._mgr.RestorePane(pane) 

            #restoring shell when navigator is hidden restores navigator too this just makes sure that menus are in sync. 

            if not self.navigatorMenu.IsChecked(): 

                self.navigatorMenu.Check() 

        else: 

            self._mgr.ClosePane(pane) 

        self._mgr.Update() 

 

    def ToggleNavigator(self, event): 

        pane = self._mgr.GetPane("Navigator") 

        if self.navigatorMenu.IsChecked(): 

            self._mgr.RestorePane(pane) 

            if not self.shellMenu.IsChecked(): 

                self.shellMenu.Check() 

        else: 

            self._mgr.ClosePane(pane) 

        self._mgr.Update() 

 

 

    def shellMenuUnCheck(self, event): 

        "This is called on wx.aui.EVT_AUI_PANE_CLOSE" 

        pane = event.GetPane() 

        if pane.name == "shell": 

            self.shellMenu.Check(False) 

        else: 

            event.Skip() 

 

    def OnPreferences(self, event): 

        # Show the UI... 

        self.preferences_manager.configure_traits(kind='modal') 

 

        # Save the preferences... 

        get_default_preferences().flush() 

 

    def ResetPerspective(self, event): 

        self._mgr.LoadPerspective(self.perspectiveInfo, True) 

 

    def SavePerspective(self): 

        filePath = os.path.join(rcFolder, '.PyRx_Perspective'+version) 

        open(filePath,'w').write(self._mgr.SavePerspective()) 

 

    def LoadPerspective(self): 

        filePath = os.path.join(rcFolder, '.PyRx_Perspective'+version) 

        if os.path.exists(filePath): 

            self._mgr.LoadPerspective(open(filePath).read(), True) 

        else: 

            self._mgr.Update() 

 

    def OnClose(self, event): 

        "Invoked when application closes" 

        try: 

            # deinitialize the frame manager 

            self.documentsView.OnCloseWindow(event) 

            if hasattr(event,'GetVeto') and event.GetVeto(): 

                return 

            self.SavePerspective() 

            old_path = self.wxcfg.GetPath() 

            self.wxcfg.SetPath('/RecentFiles') 

            self.fileHistory.Save(self.wxcfg) 

            self.wxcfg.SetPath(old_path) 

            self._mgr.UnInit() 

            # delete the frame 

            self.Destroy() 

        except Exception, inst: 

            print inst 

 

    def OnFileOpenMenu(self, event): 

        "Invoked on File Open Menu" 

        last_fileOpen = self.wxcfg.Read("last_fileOpen") 

        dlg = wx.FileDialog(self, "Choose a file", last_fileOpen, "", 

                            "All Supported Files (*.pdb,*.pdbq(st),*.cif,*.mol2,*.pqr,*.gro)|*.cif;*.mol2;*.pdb;*.pqr;*.pdbq;*.pdbqs;*.pdbqt;*.gro|"+ 

                            "PDB files (*.pdb)|*.pdb|"+ 

                            "AutoDock files (*.pdbq,*.pdbqs,*.pdbqt)|*.pdbq;*.pdbqs;*.pdbqt|"+ 

                            "MOL2 files (*.mol2)|*.mol2|"+ 

                            "mmCIF files (*.cif)|*.cif|MEAD files (*.pqr)|*.pqr|"+ 

                            "Gromacs files (*.gro)|*.gro|All Files (*)|*", 

                            style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR) 

        returnMol = [] 

        try: 

            if dlg.ShowModal() == wx.ID_OK: 

                fileNames = dlg.GetPaths() 

                maximum = len(fileNames) 

                if maximum > 1: 

                    dlg = wx.ProgressDialog("Reading Input Files. Please Wait...", 

                                   "Reading Input Files. Please Wait...", 

                                   maximum = maximum, 

                                   parent=self, 

                                   style = wx.PD_CAN_ABORT | wx.PD_APP_MODAL  | wx.PD_ELAPSED_TIME 

                                    | wx.PD_REMAINING_TIME 

                                    ) 

                keepGoing = True 

                for index, molFile in enumerate(fileNames): 

#                    name, ext = os.path.splitext(molFile) 

#                    if ext.lower() == '.pdbqt': #move the file to ~/.mgltools/PyRx/Ligands 

#                        dst = os.path.join(self.vsModel.ligandsFolder, os.path.split(molFile)[-1]) 

#                        shutil.copy(molFile, dst) 

                    if maximum > 1: 

                        if maximum > 100 and ext.lower() == '.pdbqt': #change this number if needed 

                                continue 

                        (keepGoing, skip) = dlg.Update(index, "Reading  "+molFile) 

                        if not keepGoing: 

                            break 

                    mol = self.molNav.TryOpenMolecule(molFile) 

                    returnMol.append(mol) 

                #self.navigator.SetSelection(0) #selects Molecules tab off Navigator 

                if fileNames: 

                     self.wxcfg.Write("last_fileOpen", os.path.split(fileNames[0])[0]) 

        except: 

                sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info() 

                traceback.print_exc(file=self.shell) 

                self.shell.prompt() 

                self.log.error("Error in : "+str(command)+"\n"+self.shell.GetText()) 

        finally: 

            dlg.Destroy() 

            return returnMol 

 

    def OpenDocument(self, path): 

        frame.documentsView._docManager.CreateDocument(path, flags=wx.lib.docview.DOC_SILENT) 

        frame.view.SetSelection(frame.view.GetPageIndex(frame.documentsView)) 

 

    def TryCommand(self, command, *args, **kw): 

        """ 

        This function used try/except to execute a command. 

        except writes "Error in executing command" message in sys.stderr if try fails. 

        """ 

        self.SetAllCursors(wx.StockCursor(wx.CURSOR_WAIT)) 

        self.Refresh() 

        self.Update() 

        retObject = None 

        try: 

            retObject = command(*args, **kw) 

        except Exception, inst: 

            self.SetAllCursors(wx.NullCursor) 

            if inst.__class__ !=  ProgressStop: 

                sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info() 

                traceback.print_exc(file=self.shell) 

                self.shell.prompt() 

                self.log.error("Error in : "+str(command)+"\n"+self.shell.GetText()) 

        self.SetAllCursors(wx.NullCursor) 

        return retObject 

 

    def PrintMessage(self, txt): 

        "Prints txt message" 

        print txt 

        self.shell.prompt() 

 

    def ConfigureProgressBar(self, **kw): 

        "Configures and opens wx.ProgressDialog" 

        self.progressCount = 0 

        if not kw.has_key('max'): return 

        self.progressMax = kw['max'] 

        if self.progressDialog: 

            self.progressDialog.Destroy() 

        if self.progressTextSuffix: 

            self.progressText = self.progressTextTemplate.replace('??', self.progressTextSuffix[self.progressTextPositions]) 

            self.progressTextPositions += 1 

 

        self.progressDialog = wx.ProgressDialog("Progress dialog", 

                               self.progressText.strip(), 

                               maximum = self.progressMax, 

                               parent=self, 

                               style = wx.PD_CAN_ABORT 

                                | wx.PD_APP_MODAL 

                                | wx.PD_ELAPSED_TIME 

                                | wx.PD_REMAINING_TIME 

                                ) 

 

    def UpdateProgressBar(self): 

        "Updates ProgressBar" 

        self.progressCount = self.progressCount + 1 

        if self.progressCount >= self.progressMax-1: 

            if self.progressDialog: 

                self.progressDialog.Destroy() 

                self.progressDialog = None 

        else: 

            (keepGoing, skip) = self.progressDialog.Update(self.progressCount) 

            if not keepGoing: 

                self.progressDialog.Destroy() 

                raise ProgressStop() 

 

    def OnImport(self, event): 

        from importWizard import ImportWizard 

        wizard = ImportWizard(self) 

        wizard.Start() 

 

    def OnExport(self, event): 

        from exportWizard import ExportWizard 

        wizard = ExportWizard(self) 

        wizard.Start() 

 

    def OnFileHistory(self, evt): 

        # get the file based on the menu ID 

        fileNum = evt.GetId() - wx.ID_FILE1 

        path = self.fileHistory.GetHistoryFile(fileNum) 

 

        # add it back to the history so it will be moved up the list 

        self.fileHistory.AddFileToHistory(path) 

        retrunMol = self.molNav.TryOpenMolecule(path) 

        if not retrunMol: 

            self.fileHistory.RemoveFileFromHistory(0) 

        return retrunMol 

 

    def __create_file_history(self): 

        self.fileHistory = wx.FileHistory() 

        self.fileHistory.UseMenu(self.fileMenu) 

        self.wxcfg = wx.Config('PyRx') 

        old_path = self.wxcfg.GetPath() 

        self.wxcfg.SetPath('/RecentFiles') 

        self.fileHistory.Load(self.wxcfg) 

        self.wxcfg.SetPath(old_path) 

 

    def SetAllCursors(self, cursor): 

        SetAllCursors(self, cursor) 

 

def SetAllCursors(parent, cursor): 

    "Sets the cursor for all Childrens. Note this function is needed because self.SetCursor is not working properly." 

    for child in parent.Children: 

        for grandChild in child.Children: 

            for grandGrandChild in grandChild.Children: 

                try:  #to avoid GTKUpdateCursor(): NULL window returned by GTKGetWindow() 

                    grandGrandChild.SetCursor(cursor) 

                except: 

                    pass 

            grandChild.SetCursor(cursor) 

        child.SetCursor(cursor) 

 

if __name__ == "__main__": 

    app = wx.App() 

    frame = MainFrame(None) 

    frame.Show() 

    app.MainLoop()