Source code for populse_mia.user_interface.data_browser.modify_table

# -*- coding: utf-8 -*-
"""
Module to handle updates of the databrowser table after modifications.

Contains:
    Class:
        - ModifyTable
"""

##########################################################################
# Populse_mia - Copyright (C) IRMaGe/CEA, 2018
# Distributed under the terms of the CeCILL license, as published by
# the CEA-CNRS-INRIA. Refer to the LICENSE file or to
# http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html
# for details.
##########################################################################

from datetime import datetime

# Populse_db imports
from populse_db.database import (
    FIELD_TYPE_LIST_BOOLEAN,
    FIELD_TYPE_LIST_DATE,
    FIELD_TYPE_LIST_DATETIME,
    FIELD_TYPE_LIST_FLOAT,
    FIELD_TYPE_LIST_INTEGER,
    FIELD_TYPE_LIST_STRING,
    FIELD_TYPE_LIST_TIME,
)

# PyQt5 imports
from PyQt5.QtWidgets import (
    QDialog,
    QHBoxLayout,
    QMessageBox,
    QPushButton,
    QTableWidget,
    QTableWidgetItem,
    QVBoxLayout,
)

# Populse_MIA imports
from populse_mia.data_manager.project import COLLECTION_CURRENT


[docs] class ModifyTable(QDialog): """Used to modify the contents of cells which contains lists. When the user wishes to modify a cell which contains a list in the databrowser tab, a popup will appear to help the user to change the content of the cell. .. Methods: - add_item: add one more element to self.value - fill_table: fill the table - rem_last_item: remove last element of self.value - update_table_values: update the table in the database """
[docs] def __init__(self, project, value, types, scans, tags): """ Initialization of the ModifyTable class :param project: Instance of project :param value: List of values of the cell :param types: Value types :param scans: Scans of the rows :param tags: Tags of the columns """ super().__init__() self.setModal(True) # Variables init self.types = types self.scans = scans self.tags = tags self.project = project self.value = value # The table that will be filled self.table = QTableWidget() # Filling the table self.fill_table() # Ok button ok_button = QPushButton("Ok") ok_button.clicked.connect(self.update_table_values) # Cancel button cancel_button = QPushButton("Cancel") cancel_button.clicked.connect(self.close) # + button (add one more element to a list) plus_button = QPushButton("+") plus_button.setToolTip("Add one more element to the list") plus_button.clicked.connect(self.add_item) # - button (remove last element from a list) minus_button = QPushButton("-") minus_button.setToolTip("Remove the last element of the list") minus_button.clicked.connect(self.rem_last_item) # Layouts self.v_box_final = QVBoxLayout() self.h_box_final = QHBoxLayout() self.h_box_final.addWidget(ok_button) self.h_box_final.addWidget(cancel_button) self.h_box_final.addWidget(plus_button) self.h_box_final.addWidget(minus_button) self.v_box_final.addWidget(self.table) self.v_box_final.addLayout(self.h_box_final) self.setLayout(self.v_box_final)
[docs] def add_item(self): """Add one more element to self.value""" self.value.append(0) # Filling the table self.fill_table()
[docs] def fill_table(self): """Fill the table.""" # Sizes self.table.setColumnCount(len(self.value)) self.table.setRowCount(1) # Values filled for i in range(0, self.table.columnCount()): column_elem = self.value[i] item = QTableWidgetItem() item.setText(str(column_elem)) self.table.setItem(0, i, item) # Resize self.table.resizeColumnsToContents() total_width = 0 total_height = 0 i = 0 while i < self.table.columnCount(): total_width += self.table.columnWidth(i) total_height += self.table.rowHeight(i) i += 1 if total_width + 20 < 900: self.table.setFixedWidth(total_width + 20) self.table.setFixedHeight(total_height + 25) else: self.table.setFixedWidth(900) self.table.setFixedHeight(total_height + 40)
[docs] def rem_last_item(self): """Remove last element of self.value""" if len(self.value) > 1: self.value.pop() # Filling the table self.fill_table() else: print( "\nThe list must contain at least one element. " "Deletion of the last element is aborted!\n" )
[docs] def update_table_values(self, test=False): """Update the table in the database when the 'OK' button is clicked.""" # import check_value_type only here to prevent circular import issue from populse_mia.utils import check_value_type valid = True # For each value, type checked for i in range(0, self.table.columnCount()): item = self.table.item(0, i) text = item.text() valid_type = True for tag_type in self.types: if not check_value_type(text, tag_type, True): valid_type = False type_problem = tag_type break # Type checked if not valid_type: # Error dialog if invalid cell valid = False if test is False: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Invalid value") msg.setInformativeText( "The value " + text + " is invalid with the type " + type_problem ) msg.setWindowTitle("Warning") msg.setStandardButtons(QMessageBox.Ok) msg.buttonClicked.connect(msg.close) msg.exec() break if valid: # Database updated only if valid type for every cell for cell in range(0, len(self.scans)): scan = self.scans[cell] tag = self.tags[cell] tag_object = self.project.session.get_field( COLLECTION_CURRENT, tag ) tag_type = tag_object.field_type database_value = [] # For each value for i in range(0, self.table.columnCount()): item = self.table.item(0, i) text = item.text() if tag_type == FIELD_TYPE_LIST_INTEGER: database_value.append(int(text)) elif tag_type == FIELD_TYPE_LIST_FLOAT: database_value.append(float(text)) elif tag_type == FIELD_TYPE_LIST_STRING: database_value.append(str(text)) elif tag_type == FIELD_TYPE_LIST_BOOLEAN: database_value.append(eval(text)) elif tag_type == FIELD_TYPE_LIST_DATE: format = "%d/%m/%Y" subvalue = datetime.strptime(text, format).date() database_value.append(subvalue) elif tag_type == FIELD_TYPE_LIST_DATETIME: format = "%d/%m/%Y %H:%M:%S.%f" subvalue = datetime.strptime(text, format) database_value.append(subvalue) elif tag_type == FIELD_TYPE_LIST_TIME: format = "%H:%M:%S.%f" subvalue = datetime.strptime(text, format).time() database_value.append(subvalue) # Database updated for every cell self.project.session.set_value( COLLECTION_CURRENT, scan, tag, database_value ) self.close()