__main__.py 19.3 KB
Newer Older
Yan's avatar
Yan committed
1
2
3
4
#!/usr/bin/env python3

from PyQt5 import QtCore
from PyQt5 import QtWidgets
Yan's avatar
Yan committed
5
from PyQt5 import QtGui
6
from PyQt5 import QtPrintSupport
Yan's avatar
Yan committed
7
from prasopes.predictmz import predict as getmzpattern
8
from pathlib import Path
Yan's avatar
Yan committed
9
try:
Yan's avatar
Yan committed
10
    import rawautoparams
Yan's avatar
Yan committed
11
    autoparams = True
12
except ImportError:
Yan's avatar
Yan committed
13
    autoparams = False
14
import copy
Yan's avatar
Yan committed
15
import rawprasslib
Yan's avatar
Yan committed
16
import prasopes.config as cf
17
import prasopes.datatools as dt
18
import prasopes.drltools_gui as drlgui
Yan's avatar
Yan committed
19
import prasopes.filetools as ft
Yan's avatar
Yan committed
20
21
import prasopes.graphtools as gt
import prasopes.imagetools as imgt
Yan's avatar
Yan committed
22
import prasopes.zcetools as zce
Yan's avatar
Yan committed
23
import prasopes.docks as docks
Yan's avatar
Yan committed
24
import prasopes.datasets as datasets
25
import prasopes.mobtools_gui as mtg
Yan's avatar
Yan committed
26
import prasopes.drlmobtools_gui as mdrlgui
Yan's avatar
Yan committed
27
import prasopes.tangoicons
Yan's avatar
Yan committed
28
29
import sys
import logging
3Yan's avatar
3Yan committed
30
import os.path
Yan's avatar
Yan committed
31
32


33
34
35
36
class update_signal(QtCore.QObject):
    signal = QtCore.pyqtSignal()


37
38
39
40
class QStatusBarLogger(logging.Handler):
    def __init__(self, parent=None):
        super().__init__()
        self.statusBar = QtWidgets.QStatusBar(parent)
Yan's avatar
Yan committed
41
42
        self.trigger = update_signal()
        self.msg = str("")
43
44

    def emit(self, record):
Yan's avatar
Yan committed
45
46
        self.msg = self.format(record)
        self.trigger.signal.emit()
47
48


49
def show_exception_and_exit(exc_type, exc_value, tb):
50
51
    if "figure size must be positive finite not" in str(exc_value):
        return
52
53
    import traceback
    traceback.print_exception(exc_type, exc_value, tb)
Yan's avatar
Yan committed
54
55
    details = "\n".join(traceback.format_exception(exc_type, exc_value, tb))
    errmsg = "\n".join(traceback.format_exception_only(exc_type, exc_value))\
Yan's avatar
Yan committed
56
        + ("\n The program might misbehave, do you want to continue?")
Yan's avatar
Yan committed
57
58
59
60
61
62
    msgbox = QtWidgets.QMessageBox(
        3, "Exception!", errmsg,
        QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
    msgbox.setDetailedText(details)
    outvalue = msgbox.exec_()
    if outvalue != QtWidgets.QMessageBox.Yes:
3Yan's avatar
3Yan committed
63
        sys.exit(-1)
64
65


Yan's avatar
Yan committed
66
def load_file(parent, augCanvas, update, settings, loadthread, filename=None,
Yan's avatar
Yan committed
67
              nothreading=False):
Yan's avatar
Yan committed
68
    """populates dataset and plots it"""
Yan's avatar
Yan committed
69
    directory = augCanvas.ds.filename if augCanvas.ds\
Yan's avatar
Yan committed
70
        else settings.value("open_folder")
71
72
    filename = filename or QtWidgets.QFileDialog.getOpenFileName(
            caption="Open spectrum", directory=directory,
Yan's avatar
Yan committed
73
74
            filter="All supported formats (*.raw *.RAW *.d);;"
                   "Finnigan RAW files (*.raw *.RAW);;timsTOF file (*.d)")[0]
75
76
    if filename != '' and os.path.isfile(filename)\
            and not os.path.isdir(filename):
Yan's avatar
Yan committed
77
78
        error = update_signal()
        errormsg = []
79

80
        def runfnc():
Yan's avatar
Yan committed
81
            try:
Yan's avatar
Yan committed
82
83
84
                augCanvas.ds = datasets.ThermoRawDataset(filename) if\
                        os.path.splitext(filename)[1] in (".raw", ".RAW")\
                        else datasets.BrukerTimsDataset(filename)
85
            except rawprasslib.ParsingException as pex:
Yan's avatar
Yan committed
86
87
                errormsg.append("Opening of the file has failed!")
                errormsg.append(
88
89
                    "File is incompatible with the rawprasslib, "
                    "canceling request!\n\n"
Yan's avatar
Yan committed
90
                    "Error message:\n{}".format(pex.args[0]))
Yan's avatar
Yan committed
91
                error.signal.emit()
92
                return
93
            gt.populate(augCanvas)
94
95
            oldrecents = settings.value("recents")
            oldrecents.remove(filename) if filename in oldrecents else None
Yan's avatar
Yan committed
96
            settings.setValue("recents", [filename, *oldrecents][:10])
97
            update.signal.emit()
98
99
        error.signal.connect(lambda: QtWidgets.QMessageBox.critical(
            parent, errormsg[0], errormsg[1]))
Yan's avatar
Yan committed
100
101
102
103
104
        if nothreading:
            runfnc()
        else:
            loadthread.run = runfnc
            loadthread.start()
3Yan's avatar
3Yan committed
105

Yan's avatar
Yan committed
106

107
def print_graph(augCanvas):
Yan's avatar
Yan committed
108
    def printimage(printdevice, img):
Yan's avatar
Yan committed
109
        printer.setResolution(600)
Yan's avatar
Yan committed
110
        painter = QtGui.QPainter(printdevice)
Yan's avatar
Yan committed
111
112
113
114
        font = painter.font()
        linesize = printer.resolution()/15
        font.setPixelSize(linesize)
        painter.setFont(font)
115
        painter.drawImage(0, 0, img)
Yan's avatar
Yan committed
116
117
118
        offset = img.size().height()
        line = 1
        spacing = 1.5
119
120
121
122
123
        for row in range(augCanvas.paramstable.rowCount()):
            if augCanvas.paramstable.cellWidget(row, 0).checkState() == 2:
                text = augCanvas.paramstable.item(row, 1).text() +\
                       augCanvas.paramstable.item(row, 2).text()
                painter.drawText(300, int(offset+line*linesize*spacing), text)
Yan's avatar
Yan committed
124
                line += 1
Yan's avatar
Yan committed
125
        painter.end()
126
    # TODO: substitute the QPrintPreviewDialog with QPrintPreviewWidget
127
128
    printPreview = QtPrintSupport.QPrintPreviewDialog()
    printer = printPreview.printer()
Yan's avatar
Yan committed
129
130
    printer.setPageSize(printer.A5)
    printer.setDuplex(printer.DuplexNone)
131
    imggen = imgt.ImagePainter("msspec", printer)
Yan's avatar
Yan committed
132
    imggen.popfig = lambda: paint_override(imggen, augCanvas)
133
    image = imggen.paint()
Yan's avatar
Yan committed
134
    printPreview.paintRequested.connect(lambda:
Yan's avatar
Yan committed
135
                                        printimage(printer, image))
136
137
138
    printPreview.exec()


139
def update_spectrum(augCanvas, config):
Yan's avatar
Yan committed
140
    if augCanvas.ds:
141
142
        slims = [augCanvas.spectplot.get_xlim(),
                 augCanvas.spectplot.get_ylim()]
Yan's avatar
Yan committed
143
        augCanvas.ds.refresh()
144
145
146
147
148
        gt.populate(augCanvas)
        augCanvas.spectplot.set_xlim(slims[0])
        augCanvas.spectplot.set_ylim(slims[1])
        gt.ann_spec(augCanvas.spectplot, augCanvas.ms)
        augCanvas.draw()
Yan's avatar
Yan committed
149
150


151
def update_recents(rcm, main_window, augCanvas, update, config, loadthread):
152
    """updates recents_menu (rcm)"""
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    rcm.clear()
    # Actions need to be stored somewhere. Otherwise they end up in garbage.
    rcm.actionCache = []
    for i, j in enumerate(config.value("recents"), start=1):
        rcm.actionCache.append(QtWidgets.QAction("&{}. {}".format(i, j), None))
        rcm.actionCache[-1].triggered.connect(lambda _, fn=j: load_file(
            main_window, augCanvas, update, config, loadthread, filename=fn))
    rcm.actionCache.append(rcm.addSeparator())
    rcm.actionCache.append(QtWidgets.QAction("Clear Recents", None))
    [rcm.actionCache[-1].triggered.connect(i) for i in (
         lambda: config.setValue("recents", ""), lambda: update_recents(
             rcm, main_window, augCanvas, update, config, loadthread))]
    rcm.addActions(rcm.actionCache)


168
def dropped(event, parent, augCanvas, update, config, loadthread):
169
    dropurl = event.mimeData().urls()[0].toLocalFile()
170
    load_file(parent, augCanvas, update, config, loadthread, filename=dropurl)
Yan's avatar
Yan committed
171
172
173
174


def drag_entered(event):
    if event.mimeData().hasUrls() and event.mimeData().urls()[0]\
175
            .toLocalFile().lower().endswith('.raw'):
Yan's avatar
Yan committed
176
177
178
        event.accept()


179
def predictmz(form, augCanvas):
Yan's avatar
Yan committed
180
181
    text = form.text()
    if text == "":
182
        augCanvas.ms["predict"] = None
Yan's avatar
Yan committed
183
        return
184
185
186
187
188
189
190
    slims = [augCanvas.spectplot.get_xlim(),
             augCanvas.spectplot.get_ylim()]
    augCanvas.ms["predict"] = getmzpattern(text)
    gt.populate(augCanvas)
    augCanvas.spectplot.set_xlim(slims[0])
    augCanvas.spectplot.set_ylim(slims[1])
    augCanvas.draw()
Yan's avatar
Yan committed
191
192


193
def oddeven_changed(augCanvas, config, oddevenact):
Yan's avatar
Yan committed
194
    print("trigd")
3Yan's avatar
3Yan committed
195
    config.setValue("view/oddeven", oddevenact.isChecked())
196
    update_spectrum(augCanvas, config)
3Yan's avatar
3Yan committed
197
198


Yan's avatar
Yan committed
199
def legendvis_changed(augCanvas, config, legendact):
Yan's avatar
Yan committed
200
    config.setValue("view/legend", legendact.isChecked())
Yan's avatar
Yan committed
201
202
203
204
205
206
    if augCanvas.chromplot.get_legend():
        for ax in (augCanvas.spectplot, augCanvas.chromplot):
            ax.get_legend().set_visible(config.value("view/legend", type=bool))
        augCanvas.draw()


Yan's avatar
Yan committed
207
def paint_override(self, augCanvas):
208
209
210
211
    self.plot.set_xlim(augCanvas.spectplot.get_xlim())
    self.plot.set_ylim(augCanvas.spectplot.get_ylim())
    data = [line.get_data() for line in augCanvas.spectplot.lines]
    texts = copy.copy(augCanvas.ms)
212
213
    if augCanvas.ds and augCanvas.ds.headers and\
            cf.settings().value("view/legend", type=bool):
214
215
216
217
218
219
        legend = augCanvas.spectplot.get_legend().get_texts()
        [gt.pop_plot(*line, self.plot, texts, i, legend[i].get_text(),
                     not (cf.settings().value(
                         self.conftype.format("onlymanann"), type=bool)))
            for i, line in enumerate(data)]
        legend = 1
Yan's avatar
Yan committed
220
        if legend:
221
222
223
224
225
226
            self.plot.legend(loc=2)
    else:
        [gt.pop_plot(*line, self.plot, texts, i)
            for i, line in enumerate(data)]
    xtics = int(cf.settings().value(self.conftype.format("xtics")))
    self.plot.locator_params(nbins=xtics, axis='x')
227
    if augCanvas.ds and cf.settings().value("imggen/path", type=bool):
228
        self.plot.set_title(Path(
Yan's avatar
Yan committed
229
            *Path(augCanvas.ds.filename).resolve().parts[-2:]), loc="right")
230
231


3Yan's avatar
3Yan committed
232
def key_pressed(event, augCanvas, config, update):
Yan's avatar
Yan committed
233
    if event.key() == QtCore.Qt.Key_F5:
234
        update_spectrum(augCanvas, config)
Yan's avatar
Yan committed
235
        if augCanvas.ds:
3Yan's avatar
3Yan committed
236
            update.signal.emit()
237
238
    if event.key() == QtCore.Qt.Key_C:
        if event.modifiers().__int__() == QtCore.Qt.ControlModifier:
239
240
241
            if augCanvas.paramstable.underMouse():
                dt.clip_tablestr(augCanvas)
            else:
242
                painter = imgt.ImagePainter("msspec")
Yan's avatar
Yan committed
243
                painter.popfig = lambda: paint_override(painter, augCanvas)
244
                painter.clip()
245
246
        if event.modifiers().__int__() == QtCore.Qt.ControlModifier + \
                QtCore.Qt.ShiftModifier:
247
            dt.clip_spectstr(augCanvas)
Yan's avatar
Yan committed
248
    if event.key() in (QtCore.Qt.Key_Left, QtCore.Qt.Key_Right):
249
        gt.shift_times(event, augCanvas)
Yan's avatar
Yan committed
250
251


252
253
254
255
256
257
258
259
260
261
262
263
def updatehelp(parent):
    """constructs window with "update" info"""
    QtWidgets.QMessageBox.information(
            parent, "Updating Prasopes",
            "How to update prasopes (windows):\n"
            "1. run cmd (as administrator)\n"
            "2. type: \"pip install prasopes -U\"\n"
            "3. Check versionin help->about\n\n"
            "Linux:\n"
            "probably not in repos yet, go for git..")


Yan's avatar
Yan committed
264
265
def about(parent):
    """constructs window with "about" info"""
Yan's avatar
Yan committed
266
    rawparver = rawautoparams.__version__ if autoparams else\
Yan's avatar
Yan committed
267
        "library not found"
Yan's avatar
Yan committed
268

Yan's avatar
Yan committed
269
270
271
    QtWidgets.QMessageBox.information(
            parent, "About Prasopes",
            "Prasopes Finnigan raw file viewer\n\n"
Yan's avatar
Yan committed
272
273
274
275
            "Version: {} (alpha)\n\n"
            "Rawprasslib version: {}\n"
            "Rawautoparams version: {}".format(
                prasopes.__version__, rawprasslib.__version__, rawparver))
Yan's avatar
Yan committed
276
277


Yan's avatar
Yan committed
278
def main():
279
280
281
    # thx to: https://stackoverflow.com/questions/779675/stop-python-from-closing-on-error/781074#781074
    sys.excepthook = show_exception_and_exit

282
    app = QtWidgets.QApplication(sys.argv)
283
    loadthread = QtCore.QThread()
284

285
    augCanvas = gt.AugFigureCanvas()
286
    update = update_signal()
Yan's avatar
Yan committed
287

Yan's avatar
Yan committed
288
289
    config = cf.settings()

290
    barHandler = QStatusBarLogger()
291
292
    barHandler.trigger.signal.connect(
        lambda: barHandler.statusBar.showMessage(barHandler.msg))
293

Yan's avatar
Yan committed
294
    p_logger = logging.getLogger('parseLogger')
295
    params_logger = logging.getLogger('acqLogLogger')
Yan's avatar
Yan committed
296
    drl_logger = logging.getLogger('drlLogger')
297
298
    zce_logger = logging.getLogger('zcelogger')
    rxn_logger = logging.getLogger('reactivityLogger')
Yan's avatar
Yan committed
299
    ds_logger = logging.getLogger('dsLogger')
Yan's avatar
Yan committed
300
301
    toflogger = logging.getLogger('tofLogger')
    toflogger.setLevel("DEBUG")
Yan's avatar
Yan committed
302
    logging.basicConfig()
303
    # p_logger.setLevel("WARN")
304
    p_logger.setLevel("DEBUG")
Yan's avatar
Yan committed
305
    ds_logger.setLevel("DEBUG")
306
    rxn_logger.setLevel("DEBUG")
307
    # drl_logger.setLevel("INFO")
Yan's avatar
Yan committed
308
    drl_logger.setLevel("DEBUG")
309
    zce_logger.setLevel("DEBUG")
310
    # params_logger.setLevel("DEBUG")
311
312
    p_logger.addHandler(barHandler)
    zce_logger.addHandler(barHandler)
313
    params_logger.addHandler(barHandler)
Yan's avatar
Yan committed
314
    ds_logger.addHandler(barHandler)
315
    barHandler.setLevel("DEBUG")
Yan's avatar
Yan committed
316

Yan's avatar
Yan committed
317
    main_window = QtWidgets.QMainWindow(windowTitle="Prasopes")
318
    update.signal.connect(lambda: main_window.setWindowTitle(
Yan's avatar
Yan committed
319
        "Prasopes - {}".format(os.path.basename(augCanvas.ds.filename))))
Yan's avatar
Yan committed
320

321
    if QtGui.QIcon.themeName() == "":
Yan's avatar
Yan committed
322
323
        QtGui.QIcon.setThemeName("TangoMFK")

Yan's avatar
Yan committed
324
325
326
    consoledock = docks.consoleDockWidget(
            locals(), "&Console", "view/consolevisible")
    treedock = docks.treeDockWidget(
327
328
            "&File browser", "view/filebrowservisible", update, load_file,
            main_window, augCanvas, config, loadthread)
Yan's avatar
Yan committed
329
    paramsdock = docks.AugDock("Acquisition parameters", "&Acq parameters",
330
                               "view/acqparvisible")
331
332
    update.signal.connect(lambda: gt.update_paramstable(augCanvas))
    paramsdock.setWidget(augCanvas.paramstable)
Yan's avatar
Yan committed
333

Yan's avatar
Yan committed
334
    openact = QtWidgets.QAction(QtGui.QIcon.fromTheme(
Yan's avatar
Yan committed
335
        "document-open"), "&Open...", None)
Yan's avatar
Yan committed
336
337
    openact.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_O)
    openact.triggered.connect(lambda: load_file(
338
        main_window, augCanvas, update, config, loadthread))
Yan's avatar
Yan committed
339
    exportact = QtWidgets.QAction(QtGui.QIcon.fromTheme(
Yan's avatar
Yan committed
340
        "document-save-as"), "&Export...", None)
Yan's avatar
Yan committed
341
342
    exportact.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_E)
    exportact.triggered.connect(lambda: ft.export_dial(
343
        augCanvas, main_window))
344
345
346
    printact = QtWidgets.QAction(QtGui.QIcon.fromTheme(
        "document-print"), "&Print", None)
    printact.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_P)
347
    printact.triggered.connect(lambda: print_graph(augCanvas))
Yan's avatar
Yan committed
348
    settingsact = QtWidgets.QAction(QtGui.QIcon.fromTheme(
Yan's avatar
Yan committed
349
        "preferences-system"), "&Settings...", None)
Yan's avatar
Yan committed
350
351
    settingsact.triggered.connect(lambda: cf.dial(main_window))
    quitact = QtWidgets.QAction(QtGui.QIcon.fromTheme(
Yan's avatar
Yan committed
352
        "application-exit"), "&Quit", None)
Yan's avatar
Yan committed
353
354
355
    quitact.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
    quitact.triggered.connect(main_window.close)
    zceact = QtWidgets.QAction(QtGui.QIcon.fromTheme(
Yan's avatar
Yan committed
356
        "applications-utilities"), "&TSQ zce...", None)
Yan's avatar
Yan committed
357
358
    zceact.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_T)
    zceact.triggered.connect(lambda: zce.dialog(
359
        main_window, augCanvas, update))
Yan's avatar
Yan committed
360
    drlact = QtWidgets.QAction(QtGui.QIcon.fromTheme(
Yan's avatar
Yan committed
361
        "applications-utilities"), "&DRL...", None)
Yan's avatar
Yan committed
362
    drlact.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_D)
363
    drlact.triggered.connect(lambda: drlgui.main_window(
364
        main_window, augCanvas, update))
Yan's avatar
Yan committed
365
    mobact = QtWidgets.QAction(QtGui.QIcon.fromTheme(
Yan's avatar
Yan committed
366
        "applications-utilities"), "&MOB...", None)
Yan's avatar
Yan committed
367
368
369
370
371
372
373
    mobact.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_M)
    mobact.triggered.connect(lambda: mtg.main_window(
        main_window, augCanvas, update))
    drlmobact = QtWidgets.QAction(QtGui.QIcon.fromTheme(
        "applications-utilities"), "DR&LMOB...", None)
    drlmobact.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_L)
    drlmobact.triggered.connect(lambda: mdrlgui.main_window(
Yan's avatar
Yan committed
374
        main_window, augCanvas, update))
Yan's avatar
Yan committed
375
376
    aboutact = QtWidgets.QAction("&About Prasopes", None)
    aboutact.triggered.connect(lambda: about(main_window))
377
378
    updatehelpact = QtWidgets.QAction("&Update Prasopes", None)
    updatehelpact.triggered.connect(lambda: updatehelp(main_window))
Yan's avatar
Yan committed
379
    autozoomy = QtWidgets.QAction(QtGui.QIcon.fromTheme(
Yan's avatar
Yan committed
380
381
382
383
        "zoom-original"), "Auto Zoom Y", None, checkable=True,
        checked=config.value("view/autozoomy", type=bool))
    autozoomy.triggered.connect(lambda: config.setValue(
                                "view/autozoomy", autozoomy.isChecked()))
Yan's avatar
Yan committed
384
    autozoomy.triggered.connect(lambda: gt.autozoomy(augCanvas.spectplot))
385
    intensitiesact = QtWidgets.QAction(
Yan's avatar
Yan committed
386
387
        "&Show intensities", None, checkable=True,
        checked=config.value("view/intensities", type=bool))
388
389
    intensitiesact.triggered.connect(lambda: config.setValue(
        "view/intensities", intensitiesact.isChecked()))
Yan's avatar
Yan committed
390
391
    intensitiesact.triggered.connect(lambda: gt.ann_spec(
        augCanvas.spectplot, augCanvas.ms))
392
    intensitiesact.triggered.connect(lambda: augCanvas.draw())
Yan's avatar
Yan committed
393
394
395
396
397
    legendact = QtWidgets.QAction(
        "&Show legend", None, checkable=True,
        checked=config.value("view/legend", type=bool))
    legendact.triggered.connect(lambda: legendvis_changed(
        augCanvas, config, legendact))
398
    oddevenact = QtWidgets.QAction(
Yan's avatar
Yan committed
399
400
            "&Odd / even", None, checkable=True,
            checked=config.value("view/oddeven", type=bool))
401
402
    oddevenact.triggered.connect(
        lambda: oddeven_changed(augCanvas, config, oddevenact))
Yan's avatar
Yan committed
403

Yan's avatar
Yan committed
404
405
    predictform = QtWidgets.QLineEdit(maximumWidth=150)
    predictform.editingFinished.connect(lambda: predictmz(
406
        predictform, augCanvas))
Yan's avatar
Yan committed
407

408
409
410
411
412
413
    recents_menu = QtWidgets.QMenu('Open &Recent', main_window)
    update_recents(recents_menu, main_window, augCanvas,
                   update, config, loadthread)
    update.signal.connect(lambda: update_recents(
        recents_menu, main_window, augCanvas, update, config, loadthread))

Yan's avatar
Yan committed
414
415
    file_menu = QtWidgets.QMenu('&File', main_window)
    main_window.menuBar().addMenu(file_menu)
Yan's avatar
Yan committed
416
    file_menu.addAction(openact)
417
    file_menu.addMenu(recents_menu)
Yan's avatar
Yan committed
418
419
    file_menu.addAction(exportact)
    file_menu.addSeparator()
420
421
    file_menu.addAction(printact)
    file_menu.addSeparator()
Yan's avatar
Yan committed
422
423
424
    file_menu.addAction(settingsact)
    file_menu.addSeparator()
    file_menu.addAction(quitact)
Yan's avatar
Yan committed
425
426
    tools_menu = QtWidgets.QMenu('&Tools', main_window)
    main_window.menuBar().addMenu(tools_menu)
Yan's avatar
Yan committed
427
428
    tools_menu.addAction(zceact)
    tools_menu.addAction(drlact)
Yan's avatar
Yan committed
429
430
    tools_menu.addAction(mobact)
    tools_menu.addAction(drlmobact)
431
    tools_menu.addSeparator()
Yan's avatar
Yan committed
432
    view_menu = QtWidgets.QMenu('&View', main_window)
433
434
    [view_menu.addAction(i.action) for i in
     (treedock, paramsdock, consoledock)]
Yan's avatar
Yan committed
435
    [view_menu.addAction(i) for i in (autozoomy, intensitiesact, legendact)]
436
437
    view_menu.addSeparator()
    view_menu.addAction(oddevenact)
Yan's avatar
Yan committed
438
    main_window.menuBar().addMenu(view_menu)
Yan's avatar
Yan committed
439
440
    help_menu = QtWidgets.QMenu('&Help', main_window)
    main_window.menuBar().addMenu(help_menu)
441
    help_menu.addAction(updatehelpact)
Yan's avatar
Yan committed
442
    help_menu.addAction(aboutact)
Yan's avatar
Yan committed
443

444
    main_window.setCentralWidget(augCanvas)
Yan's avatar
Yan committed
445

Yan's avatar
Yan committed
446
447
448
449
450
    toolBar = QtWidgets.QToolBar(main_window)
    toolBar.setAllowedAreas(QtCore.Qt.TopToolBarArea)
    toolBar.setFloatable(False)
    toolBar.setMovable(False)
    toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
Yan's avatar
Yan committed
451

Yan's avatar
Yan committed
452
453
454
    toolBar.addAction(openact)
    toolBar.addAction(exportact)
    toolBar.addSeparator()
Yan's avatar
Yan committed
455
456
457
    toolBar.addWidget(QtWidgets.QLabel("Predict Formula:"))
    toolBar.addWidget(predictform)
    toolBar.addSeparator()
Yan's avatar
Yan committed
458
459
    toolBar.addAction(zceact)
    toolBar.addAction(drlact)
Yan's avatar
Yan committed
460
461
    toolBar.addAction(mobact)
    toolBar.addAction(drlmobact)
Yan's avatar
Yan committed
462
463
    toolBar.addSeparator()
    toolBar.addAction(autozoomy)
Yan's avatar
Yan committed
464

Yan's avatar
Yan committed
465
466
    main_window.dragEnterEvent = lambda event: drag_entered(event)
    main_window.dropEvent = lambda event: dropped(
467
        event, main_window, augCanvas, update, config, loadthread)
Yan's avatar
Yan committed
468
    main_window.setAcceptDrops(True)
469
    main_window.keyPressEvent = lambda event: key_pressed(
3Yan's avatar
3Yan committed
470
            event, augCanvas, config, update)
Yan's avatar
Yan committed
471
472
    main_window.resizeEvent = lambda event: augCanvas.constrained_draw()
    update.signal.connect(lambda: augCanvas.constrained_draw())
Yan's avatar
Yan committed
473

474
475
    main_window.addToolBar(QtCore.Qt.TopToolBarArea, toolBar)
    main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, treedock)
Yan's avatar
Yan committed
476
    main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, paramsdock)
Yan's avatar
Yan committed
477
    main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, consoledock)
478
    main_window.setStatusBar(barHandler.statusBar)
479
480
481

    main_window.setFocus()

Yan's avatar
Yan committed
482
    if len(sys.argv) == 2:
483
        load_file(main_window, augCanvas, update, config, loadthread,
Yan's avatar
Yan committed
484
                  filename=sys.argv[1], nothreading=True)
Yan's avatar
Yan committed
485
    else:
3Yan's avatar
3Yan committed
486
487
        gt.pop_plot([], [], augCanvas.spectplot, augCanvas.ms)
        gt.pop_plot([], [], augCanvas.chromplot, augCanvas.chrom)
Yan's avatar
Yan committed
488
489
490

    main_window.show()
    sys.exit(app.exec_())
Yan's avatar
Yan committed
491

492

Yan's avatar
Yan committed
493
494
if __name__ == "__main__":
    main()