Skip to content

Commit

Permalink
update 1.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
olivierpascalhenry committed Aug 25, 2020
1 parent 77a6f4b commit af6f285
Show file tree
Hide file tree
Showing 80 changed files with 2,339 additions and 1,682 deletions.
Binary file not shown.
34 changes: 27 additions & 7 deletions Documentation/changelog.txt
@@ -1,19 +1,39 @@
#### To do list: ####

* add map export possibility for GE. (v 1.3)
* rework logging system (v1.3)
* create a system to permit movement in TreeWidget and dimension handling in NetCdf with groups.
* add a button to change dimension.
* when creating a new variable or run an algorithme, the new variable shouldn't have a dimension -> let the user decide which dimension should be linked from a dimension list.
* when error occures during var processing, return the error to the user.
* update cartopy
* add map export possibility for GE. (v 1.5)
* rework logging system (v1.5)
* create a system to permit movement in TreeWidget and dimension handling in NetCdf with groups (v1.4)
* add a button to change dimension (v1.4)
* when creating a new variable or run an algorithme, the new variable shouldn't have a dimension -> let the user decide which dimension should be linked from a dimension list (v1.4)


#### To fix list: ####

* nothing


### August 24 2020, Release version 1.3.0 ###

Cartopy has been updated to version 0.18. Thus, from version 1.3.0, EGADS Lineage GUI is only compatible with Python 3.7+.

* FIXED
* in Quick Access menu, if a path is not valid, the GUI crashes. Now a warning icon is displayed and a warning message is displayed if the user try to open the associated folder.
* few style inconsistencies have been fixed (plot, ticks, colorbar windows).
* the use of set_extent has been fixed. The information text linked to the extent of the map has been modified for a better understanding.

* MODIFIED
* matplotlib code has been modified to control plot parameters from Axis object and remove deprecation warning.
* fixed deprecation warning with printing function.
* dictionary for projection options has been enhanced with new parameters to reinforce the use of ticks, labels, extent options.

* ADDED
* if an exception occurs in the plot/batch/processing windows or in the reading/saving functions, the exception is displayed to the user for information.
* in the plot window, once the figure si resized, the figure dimensions are displayed in the 'save options' tab.
* a default button has been added to the map extent and ticks windows to put back default values.
* new controls in the gui for the plot window has been added to reinforce the use of ticks, labels, extent options.
* it is now possible to insert new cells between existing cells in tick and colorbar windows.


### July 15 2020, Release version 1.2.0 ###

EGADS Lineage v1.2.7 is mandatory ro run this version of the GUI. The GUI has been reworked to handle Hdf5 file and groups (NetCdf and Hdf5). Thus the GUI and its code have been totally redone and are now more flexible.
Expand Down
24 changes: 12 additions & 12 deletions README.md
@@ -1,7 +1,7 @@
Version:
-------

EGADS Lineage GUI 1.2.0 (Python 3).
EGADS Lineage GUI 1.3.0 (Python 3).


Developments:
Expand Down Expand Up @@ -48,17 +48,17 @@ Installation:
Actually, EGADS GUI is a simple python script. Just open a terminal in the EGADS GUI directory and launch the script as usual: python egads_gui.py.

Do not forget to install dependancies:
* Python (3.5.4 or newer)
* PyQt5 (5.11.3 or newer)
* EGADS Lineage (1.0.0 or newer)
* Matplotlib (2.2.2 or newer)
* Cartopy (0.17 or newer, optional, only to draw maps)
* Simplekml (1.3.1 or newer)
* Markdown (3.1.1 or newer, optional, only to read the changelog in the GUI)
* Requests (2.18.4 or newer, optional, only to check updates if the user activates the option)
* Pillow (5.2 or newer, optional, only to save figures in JPEG format)

Anaconda3 can be a good alternative, in particular if the use of Cartopy is mandatory and if the user can't build Cartopy himself.
* Python (3.7 or newer)
* PyQt5 (5.15.0 or newer)
* EGADS Lineage (1.2.7 or newer)
* Matplotlib (3.3.0 or newer)
* Cartopy (0.18 or newer)
* Simplekml (1.3.5 or newer)
* Markdown (3.2.2 or newer, optional, only to read the changelog in the GUI)
* Requests (2.24.0 or newer, optional, only to check updates if the user activates the option)
* Pillow (7.2 or newer, optional, only to save figures in JPEG and TIFF format)

Anaconda3 can be a good alternative, in particular if the use of Cartopy is mandatory and if the user can't build Cartopy himself. For Windows, an already-built version of Cartopy exists at the followind address : https://www.lfd.uci.edu/~gohlke/pythonlibs/


Stand-alone package:
Expand Down
4 changes: 2 additions & 2 deletions doc/source/conf.py
Expand Up @@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
version = '1.1.1'
version = '1.3.0'
# The full version, including alpha/beta/rc tags.
release = '1.1.1'
release = '1.3.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
19 changes: 11 additions & 8 deletions doc/source/install.rst
Expand Up @@ -11,14 +11,15 @@ Prerequisites

The use of the EGADS GUI as a standard Python script requires the following packages:

* Python 3.5.4 or newer. Available at https://www.python.org/
* PyQt 5.11.3 or newer. Available at https://www.riverbankcomputing.com/software/pyqt/download5
* EGADS 1.0.0 or newer. Available at https://pypi.python.org/pypi/egads
* Matplotlib 3.0.3 or newer. Available at https://pypi.python.org/pypi/matplotlib
* Cartopy 0.17.0 or newer. Available at https://pypi.org/project/Cartopy/
* Simplekml 1.3.1 or newer. Available at https://pypi.org/project/simplekml/
* Requests 2.18.4 or newer. Optional, only for update checking. Available at https://pypi.org/project/requests/
* Markdown 3.1.1 or newer. Optional, only to have a nice changelog in the GUI. Available at https://pypi.org/project/Markdown/
* Python 3.7 or newer. Available at https://www.python.org/
* PyQt 5.15 or newer. Available at https://www.riverbankcomputing.com/software/pyqt/download5
* EGADS Lineage 1.2.7 or newer. Available at https://pypi.python.org/pypi/egads
* Matplotlib 3.3 or newer. Available at https://pypi.python.org/pypi/matplotlib
* Cartopy 0.18 or newer. Available at https://pypi.org/project/Cartopy/
* Simplekml 1.3.5 or newer. Available at https://pypi.org/project/simplekml/
* Requests 2.24 or newer. Optional, only for update checking. Available at https://pypi.org/project/requests/
* Markdown 3.2.2 or newer. Optional, only to have a nice changelog in the GUI. Available at https://pypi.org/project/Markdown/
* Pillow 7.2 or newer. Optional, only to save figures in JPEG and TIFF format. Available at https://pypi.org/project/Pillow/


*************
Expand All @@ -36,6 +37,8 @@ The EGADS GUI is actually available as a common Python script, thus it doesn't n

To learn how to install EGADS, please read the EGADS documentation available at the following places: https://github.com/EUFAR/egads/tree/Lineage/Documentation & https://egads.readthedocs.io/en/lineage/

Anaconda3 can be a good alternative, in particular if the use of Cartopy is mandatory and if the user can't build Cartopy himself. For Windows, an already-built version of Cartopy exists at the followind address : https://www.lfd.uci.edu/~gohlke/pythonlibs/.


***********
Stand-alone
Expand Down
2 changes: 1 addition & 1 deletion egads_gui.py
Expand Up @@ -42,9 +42,9 @@ def launch_egads_gui(gui_path, user_path):
logging.info('**********************************')
logging.info('EGADS GUI ' + _gui_version + ' is starting ...')
logging.info('**********************************')
logging.info('gui - gui frozen ? ' + str(frozen))
system, release, version = platform.system_alias(platform.system(), platform.release(), platform.version())
logging.info('gui - operating system: ' + system + ' ' + release + ' (' + version + ')')
logging.info('gui - gui frozen ? ' + str(frozen))
installed = None
if system == 'Windows':
try:
Expand Down
Binary file added fonts/SourceSansPro-SemiBold.ttf
Binary file not shown.
16 changes: 11 additions & 5 deletions functions/file_functions/reading_file_functions.py
Expand Up @@ -18,10 +18,14 @@ def reading_file(self):
self.reading_window = MyWaitReading(self.file_name, self.file_ext, self.config_dict)
self.reading_window.exec_()
if self.reading_window.error_occurred:
info_str = ('An unexpected error occurred during the reading of the file, thus the GUI decided to stop the '
'reading. Please read the log file to check which kind of error occurred.')
self.infoWindow = MyInfo(info_str)
self.infoWindow.exec_()
exc_type = self.reading_window.error_reason[0]
exc_value = self.reading_window.error_reason[1]
info_str = ('An exception occurred during the reading of the file. Thus the GUI decided to stop the '
'process. Please read the log file to have more details about the exception. Contact the '
'developer if the same exception occurs again.<br><br>Exception type: ' + exc_type +
'<br><br>Exception value: ' + exc_value)
self.info_window = MyInfo(info_str)
self.info_window.exec_()
if self.reading_window.success:
self.opened_file = self.reading_window.final_dict['opened_file']
self.list_of_global_attributes = self.reading_window.final_dict['glob_attr_list']
Expand Down Expand Up @@ -57,6 +61,7 @@ def __init__(self, file_name, file_ext, config_dict):
self.error_occurred = False
self.success = True
self.final_dict = None
self.error_reason = None
self.setup_spinner()
self.launch_reading_thread()
logging.info('gui - old_reading_functions.py - MyWaitReading - ready')
Expand All @@ -81,10 +86,11 @@ def reading_finished(self, final_dict):
self.final_dict = final_dict
self.close()

def reading_failed(self):
def reading_failed(self, val):
logging.debug('gui - old_reading_functions.py - MyWaitReading - reading_failed')
self.error_occurred = True
self.success = False
self.error_reason = val
self.close()

def setup_spinner(self):
Expand Down
14 changes: 9 additions & 5 deletions functions/file_functions/saving_file_functions.py
Expand Up @@ -14,12 +14,17 @@ def saving_file(self, save_file_name, save_file_ext, open_file_ext):
self.saving_window.exec_()
if self.saving_window.error_occurred:
if self.saving_window.error_reason:
info_str = self.saving_window.error_reason
exc_type = self.saving_window.error_reason[0]
exc_value = self.saving_window.error_reason[1]
info_str = ('An exception occurred during the saving of the file. Thus the GUI decided to stop the '
'process. Please read the log file to have more details about the exception. Contact the '
'developer if the same exception occurs again.<br><br>Exception type: ' + exc_type +
'<br><br>Exception value: ' + exc_value)
else:
info_str = ('An unexpected error occurred during the saving of the file, thus the GUI decided to stop the '
'process. Please read the log file to check which kind of error occurred.')
self.infoWindow = MyInfo(info_str)
self.infoWindow.exec_()
self.info_window = MyInfo(info_str)
self.info_window.exec_()
if self.saving_window.success:
self.modified = False
self.make_window_title()
Expand Down Expand Up @@ -72,8 +77,7 @@ def saving_failed(self, val):
logging.debug('gui - saving_file_functions.py - MyWaitSaving - saving_failed')
self.error_occurred = True
self.success = False
if val:
self.error_reason = val
self.error_reason = val
self.close()

def setup_spinner(self):
Expand Down
75 changes: 62 additions & 13 deletions functions/gui_functions/gui_global_functions.py
Expand Up @@ -9,6 +9,7 @@
replace_old_path_by_new_path_tooltip, get_element_value)
from functions.gui_functions.gui_widgets import DropFrame
from functions.gui_functions.gui_support_functions import too_many_files
from functions.window_functions.other_windows_functions import MyInfo


def gui_reset_function(self):
Expand Down Expand Up @@ -39,6 +40,7 @@ def gui_reset_function(self):
def file_drop_layout(self):
logging.debug('gui - old_gui_global_functions.py - file_drop_layout')
font1 = font_creation_function('normal')
font2 = font_creation_function('big')
self.drop_grid_layout_2 = QtWidgets.QGridLayout()
self.drop_grid_layout_2.setObjectName("drop_grid_layout_2")
self.drop_grid_layout_2.addItem(QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum,
Expand Down Expand Up @@ -77,15 +79,42 @@ def file_drop_layout(self):
self.drop_hor_layout.addItem(QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Minimum))
self.drop_vert_layout.addLayout(self.drop_hor_layout)
self.drop_hor_layout_2 = QtWidgets.QHBoxLayout()
self.drop_hor_layout_2.setObjectName("drop_hor_layout_2")
self.drop_label_2 = QtWidgets.QLabel(self.drop_frame)
self.drop_label_2.setMinimumSize(QtCore.QSize(0, 27))
self.drop_label_2.setMaximumSize(QtCore.QSize(16777215, 27))
self.drop_label_2.setFont(font1)
self.drop_label_2.setFont(font2)
self.drop_label_2.setStyleSheet(stylesheet_creation_function('qlabel_noborder'))
self.drop_label_2.setObjectName("drop_label_2")
self.drop_label_2.setText("<html><head/><body><p><span style=\" font-weight:600;\">Choose</span> a file or <span "
"style=\" font-weight:600;\">drop</span> it here.</p></body></html>")
self.drop_vert_layout.addWidget(self.drop_label_2)
self.drop_label_2.setText('Choose')
self.drop_label_3 = QtWidgets.QLabel(self.drop_frame)
self.drop_label_3.setMinimumSize(QtCore.QSize(0, 27))
self.drop_label_3.setMaximumSize(QtCore.QSize(16777215, 27))
self.drop_label_3.setFont(font1)
self.drop_label_3.setStyleSheet(stylesheet_creation_function('qlabel_noborder'))
self.drop_label_3.setObjectName("drop_label_3")
self.drop_label_3.setText('a file or')
self.drop_label_4 = QtWidgets.QLabel(self.drop_frame)
self.drop_label_4.setMinimumSize(QtCore.QSize(0, 27))
self.drop_label_4.setMaximumSize(QtCore.QSize(16777215, 27))
self.drop_label_4.setFont(font2)
self.drop_label_4.setStyleSheet(stylesheet_creation_function('qlabel_noborder'))
self.drop_label_4.setObjectName("drop_label_4")
self.drop_label_4.setText('drop')
self.drop_label_5 = QtWidgets.QLabel(self.drop_frame)
self.drop_label_5.setMinimumSize(QtCore.QSize(0, 27))
self.drop_label_5.setMaximumSize(QtCore.QSize(16777215, 27))
self.drop_label_5.setFont(font1)
self.drop_label_5.setStyleSheet(stylesheet_creation_function('qlabel_noborder'))
self.drop_label_5.setObjectName("drop_label_5")
self.drop_label_5.setText('it here.')
self.drop_hor_layout_2.addWidget(self.drop_label_2)
self.drop_hor_layout_2.addWidget(self.drop_label_3)
self.drop_hor_layout_2.addWidget(self.drop_label_4)
self.drop_hor_layout_2.addWidget(self.drop_label_5)
self.drop_hor_layout_2.setSpacing(4)
self.drop_vert_layout.addLayout(self.drop_hor_layout_2)
self.drop_grid_layout.addLayout(self.drop_vert_layout, 1, 1, 1, 1)
self.drop_grid_layout.addItem(QtWidgets.QSpacerItem(55, 20, QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Minimum), 1, 2, 1, 1)
Expand Down Expand Up @@ -465,17 +494,26 @@ def create_quick_access_menu(self):
self.menuQuick_access.clear()
self.menuQuick_access.setEnabled(True)
font = font_creation_function('normal')
icon = icon_creation_function('quick_access_icon.svg')
icon1 = icon_creation_function('quick_access_icon.svg')
icon2 = icon_creation_function('small_warning_icon.svg')
f = open(str(pathlib.Path(self.user_path).joinpath('user_folder_list.xml')), 'r')
doc = xml.dom.minidom.parse(f)
folders = doc.getElementsByTagName('Folders')[0]
nodes = folders.getElementsByTagName('Folder')
for node in nodes:
if pathlib.Path(get_element_value(node, 'Path')).exists():
path_exist = True
else:
path_exist = False
quick_folder = QtWidgets.QAction(self)
quick_folder.setIcon(icon)
quick_folder.setFont(font)
quick_folder.setText(get_element_value(node, 'Name'))
quick_folder.setToolTip(get_element_value(node, 'Path'))
if path_exist:
quick_folder.setIcon(icon1)
quick_folder.setToolTip(get_element_value(node, 'Path'))
else:
quick_folder.setIcon(icon2)
quick_folder.setToolTip('not valid')
quick_folder.triggered.connect(lambda: quick_access_open_folder(self))
quick_folder.setObjectName(get_element_value(node, 'Name'))
self.menuQuick_access.addAction(quick_folder)
Expand All @@ -484,21 +522,32 @@ def create_quick_access_menu(self):

def quick_access_open_folder(self):
path = self.sender().toolTip()
file_name, _ = self.get_file_name('open', path)
if file_name:
self.open_file(file_name)
if path == 'not valid':
text = ('EGADS can\'t find the following folder:\n\n\t\t\t' + str(self.sender().text())
+ '\n\nPlease check that the folder exists before trying to open it.')
info_window = MyInfo(text)
info_window.exec_()
else:
file_name, _ = self.get_file_name('open', path)
if file_name:
self.open_file(file_name)


def create_recent_file_menu(self):
self.menuOpen_recent.clear()
self.menuOpen_recent.setEnabled(True)
if self.opened_file_list:
font = font_creation_function('normal')
icon = icon_creation_function('del_icon.svg')
icon1 = icon_creation_function('del_icon.svg')
icon2 = icon_creation_function('small_warning_icon.svg')
for i, file in enumerate(self.opened_file_list):
recent_file = QtWidgets.QAction(self)
recent_file.setFont(font)
recent_file.setToolTip(file)
if pathlib.Path(file).exists():
recent_file.setToolTip(file)
else:
recent_file.setToolTip('not valid')
recent_file.setIcon(icon2)
recent_file.setObjectName(file)
if len(file) > 65:
file = file[:30] + ' ... ' + file[-30:]
Expand All @@ -508,7 +557,7 @@ def create_recent_file_menu(self):
self.menuOpen_recent.addSeparator()
del_action = QtWidgets.QAction(self)
del_action.setFont(font)
del_action.setIcon(icon)
del_action.setIcon(icon1)
del_action.setText('Clear the list...')
del_action.triggered.connect(lambda: clear_file_list_in_menu(self))
del_action.setObjectName('del_action')
Expand Down

0 comments on commit af6f285

Please sign in to comment.