Source code for vdat.gui.menubar
# Virus Data Analysis Tool: a data reduction GUI for HETDEX/VIRUS data
# Copyright (C) 2015, 2016, 2017, 2018 "The HETDEX collaboration"
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import configparser
import os
from qtpy import QtCore, QtWidgets
from qtpy.QtWidgets import QMenu, QAction
from qtpy.QtGui import QIcon
from vdat import config
from vdat.database import connect, VDATDir
from vdat.gui import queue
from vdat.gui.utils import THUMB_DIR
from . import menus_actions
[docs]class VDATMenuBar(QtWidgets.QMenuBar):
"""Menu bar of the main VDAT window
.. list-table:: **Custom signals**
:header-rows: 1
* - Name
- Signature
- Description
* - :attr:`sig_close`
-
- Emitted when the user click on the "Quit" action
* - :attr:`sig_symlink`
-
- Emitted when the user click on the "symlink" action
* - :attr:`sig_selectAll`, :attr:`sig_selectNone`
-
- Emitted when the actions to select or deselect all the IFUs are
clicked
* - :attr:`sig_remove_files`
- list, list
- Emitted when one of the remove file options are clicked. The
arguments are a list of directories containing the files to
remove and a list of file names/wildcards to remove
* - :attr:`sig_clear_log`
-
- Emitted when the user click 'Clear the log window' button
* - :attr:`sig_collapse`
-
- emitted when the "Reduction Browser"'s "Collapse" action is
triggered
* - :attr:`sig_expand`
-
- emitted when the "Reduction Browser"'s "Expand" action is triggered
.. list-table:: **Custom slot**
:header-rows: 1
* - Name
- Signature
- Description
* - :meth:`enableSymlink`
- bool
- whether to enable or not the symlink action
* - :meth:`enable_on_selection`
- str, str
- save the first string into a ``path`` attribute and enabled all the
actions disabled at startup
* - :meth:`clear_files_slot`
-
- If a directory is selected, get the current selected directory and
the wildcards/filenames and emit the :attr:`sig_remove_files`
signal
* - :meth:`clear_all_files_slot`
-
- Get all the directories from the database and the
wildcards/filenames and emit the :attr:`sig_remove_files` signal
* - :meth:`clear_thumb_slot`
-
- If a directory is selected, get the thumbnail directory under it
and emit the :attr:`sig_remove_files` signal with '*' as wildcard
* - :meth:`clear_all_thumb_slot`
-
- Get all the thumbnail directories and emit the
:attr:`sig_remove_files` signal with '*' as wildcard
.. list-table:: **Connections between custom signals and/or slots**
:header-rows: 1
* - Signal
- Slot
* - ``triggered`` signal of the :attr:`self.clear_files` action
- :meth:`clear_files_slot`
* - ``triggered`` signal of the :attr:`self.clear_all_files` action
- :meth:`clear_all_files_slot`
* - ``triggered`` signal of the :attr:`self.clear_thumb` action
- :meth:`clear_thumb_slot`
* - ``triggered`` signal of the :attr:`self.clear_all_thumb` action
- :meth:`clear_all_thumb_slot`
* - :attr:`sig_clear_log`
- :attr:`.menus_actions.LogMenu.clear_log.triggered`
* - :attr:`sig_collapse`
- :attr:`.menus_actions.TreeViewMenu.sig_collapse`
* - :attr:`sig_expand`
- :attr:`.menus_actions.TreeViewMenu.sig_expand`
Parameters
----------
parent : :class:`PyQt5.QtWidgets.QWidget` instance
parent of the menu' bar
"""
sig_close = QtCore.Signal()
sig_symlink = QtCore.Signal()
sig_selectAll = QtCore.Signal()
sig_selectNone = QtCore.Signal()
sig_remove_files = QtCore.Signal(list, list)
sig_clear_log = QtCore.Signal()
sig_collapse = QtCore.Signal()
sig_expand = QtCore.Signal()
def __init__(self, parent=None):
super(VDATMenuBar, self).__init__(parent=parent)
self.setGeometry(QtCore.QRect(0, 0, 919, 20))
self.setObjectName("menubar")
# this will be filled when selecting a directory
self.path = None
self.typ = None
self.addMenu(self.create_file())
self.addMenu(self.create_view())
self.addMenu(self.create_select())
self.log_menu = menus_actions.LogMenu(parent=self)
self.log_menu.clear_log.triggered.connect(self.sig_clear_log)
self.addMenu(self.log_menu)
self.addMenu(menus_actions.HelpMenu(parent=self,
windows_parent=parent))
[docs] @QtCore.Slot(str, str)
def enable_on_selection(self, path, typ):
'''Save the path and the type and enable disabled actions when the path is
non-null.
Parameters
----------
path : string
a path, usually the directory selected in three view
typ : string
type of the path
'''
self.path = path
self.typ = typ
self.clear_files.setEnabled(True)
self.clear_thumb.setEnabled(True)
self.selectAll_action.setEnabled(True)
self.selectNone_action.setEnabled(True)
[docs] def create_file(self):
"""Create and fill the "File" menu
Returns
-------
view_menu : :class:`PyQt5.QtWidgets.QMenu`
menu for the "View" entry
"""
file_menu = QMenu("File", parent=self)
self.symlink_action = QAction(QIcon.fromTheme('emblem-symbolic-link'),
"Redo symlink", file_menu)
self.symlink_action.triggered.connect(self.sig_symlink)
file_menu.addAction(self.symlink_action)
file_menu.addSeparator()
file_menu = self.deletions(file_menu)
file_menu.addSeparator()
self.quit_action = menus_actions.QuitAction(connect_to=self.sig_close,
parent=file_menu)
file_menu.addAction(self.quit_action)
return file_menu
[docs] def deletions(self, menu):
'''Create deletion actions and add them to the menu
Parameters
----------
menu : :class:`PyQt5.QtWidgets.QMenu`
menu to which the action must be added
Returns
-------
menu
input menu
'''
delete_fits_menu = menu.addMenu(QIcon.fromTheme('edit-delete'),
'Delete fits and thumbnails')
self.clear_files = QAction(QIcon.fromTheme('edit-delete'),
'From selected dir', delete_fits_menu)
self.clear_files.setEnabled(False)
self.clear_files.triggered.connect(self.clear_files_slot)
delete_fits_menu.addAction(self.clear_files)
self.clear_all_files = QAction(QIcon.fromTheme('edit-delete'),
'Everywhere', delete_fits_menu)
self.clear_all_files.triggered.connect(self.clear_all_files_slot)
delete_fits_menu.addAction(self.clear_all_files)
delete_thum_menu = menu.addMenu(QIcon.fromTheme('edit-delete'),
'Delete all thumbnails')
self.clear_thumb = QAction(QIcon.fromTheme('edit-delete'),
'From selected dir', delete_thum_menu)
self.clear_thumb.setEnabled(False)
self.clear_thumb.triggered.connect(self.clear_thumb_slot)
delete_thum_menu.addAction(self.clear_thumb)
self.clear_all_thumb = QAction(QIcon.fromTheme('edit-delete'),
'Everywhere', delete_thum_menu)
self.clear_all_thumb.triggered.connect(self.clear_all_thumb_slot)
delete_thum_menu.addAction(self.clear_all_thumb)
return menu
[docs] @QtCore.Slot()
def clear_files_slot(self):
'''Get the current directory and the wildcards/filenames and emit the
:attr:`sig_remove_files` signal'''
if not self.path:
return
else:
conf = config.get_config('main')
try:
wildcards = conf.get_list('general', 'intermediate_files_' +
self.typ)
except configparser.NoOptionError:
wildcards = conf.get_list('general', 'intermediate_files')
wildcards += ['e.' + i for i in wildcards]
wildcards += ['*_' + i for i in wildcards]
self.sig_remove_files.emit([self.path, os.path.join(self.path,
THUMB_DIR)],
wildcards)
[docs] @QtCore.Slot()
def clear_all_files_slot(self):
'''Get all the directories and the wildcards/filenames and emit the
:attr:`sig_remove_files` signal'''
conf = config.get_config('main')
wildcards = conf.get_list('general', 'intermediate_files')
wildcards += ['e.' + i for i in wildcards]
wildcards += ['*_' + i for i in wildcards]
with connect():
dirs = [i.path for i in VDATDir.select(VDATDir.path)]
dirs += [os.path.join(i, THUMB_DIR) for i in dirs]
self.sig_remove_files.emit(dirs, wildcards)
[docs] @QtCore.Slot()
def clear_thumb_slot(self):
'''Get the thumbnail dir under current directory and emit a
:attr:`sig_remove_files` signal matching every file'''
if not self.path:
return
else:
self.sig_remove_files.emit([os.path.join(self.path, THUMB_DIR), ],
['*', ])
[docs] @QtCore.Slot()
def clear_all_thumb_slot(self):
'''Get all the thumbnail directories and emit the
:attr:`sig_remove_files` signal matching every file'''
with connect():
dirs = [os.path.join(i.path, THUMB_DIR)
for i in VDATDir.select(VDATDir.path)]
self.sig_remove_files.emit(dirs, ['*', ])
[docs] def create_view(self):
"""Create and fill the "View" menu
Returns
-------
view_menu : :class:`PyQt5.QtWidgets.QMenu`
menu for the "View" entry
"""
# Hide or reveal different windows
view_menu = QMenu("View", parent=self)
self.showQ = queue.QueuAction(view_menu)
view_menu.addAction(self.showQ)
view_menu.addSeparator()
self.tree_view_menu = menus_actions.TreeViewMenu(parent=view_menu)
view_menu.addMenu(self.tree_view_menu)
self.tree_view_menu.sig_collapse.connect(self.sig_collapse)
self.tree_view_menu.sig_expand.connect(self.sig_expand)
return view_menu
[docs] def create_select(self):
"""Create and fill the "Select" menu
Parameters
----------
fplane : :class:`vdat.gui.FplaneWidget`
instance of fplate to connect to the buttons for selection
Returns
-------
select_menu : :class:`PyQt5.QtWidgets.QMenu`
menu for the "Select" entry
"""
# Select all and select none
select_menu = QMenu("Select", parent=self)
self.selectAll_action = QAction(QIcon.fromTheme('edit-select-all'),
"Select all IFUs", select_menu)
self.selectAll_action.triggered.connect(self.sig_selectAll)
self.selectAll_action.setEnabled(False)
select_menu.addAction(self.selectAll_action)
self.selectNone_action = QAction(QIcon.fromTheme('edit-clear'),
"Select none", select_menu)
self.selectNone_action.triggered.connect(self.sig_selectNone)
self.selectNone_action.setEnabled(False)
select_menu.addAction(self.selectNone_action)
return select_menu