Commit 7e4a5c23 authored by Samuel GAIST's avatar Samuel GAIST
Browse files

[widgets] Implement dialog to create new assets

Depending on the asset type, it can be:
- A new asset from scratch
- A new version of an asset
- A fork from an asset
parent bc8d1155
# vim: set fileencoding=utf-8 :
###############################################################################
# #
# Copyright (c) 2019 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.editor module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform 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. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
import pytest
from PyQt5 import QtCore
from PyQt5.QtWidgets import QDialogButtonBox
from ..backend.assetmodel import AssetType
from ..widgets.dialogs import AssetCreationDialog
@pytest.fixture(
params=[
AssetCreationDialog.NEW,
AssetCreationDialog.NEW_VERSION,
AssetCreationDialog.FORK,
]
)
def creation_type(request):
return request.param
class TestAssetCreationDialog:
"""Test that the asset creation dialog works as expected"""
def test_widget_visibility(self, qtbot, test_prefix, asset_type):
dialog = AssetCreationDialog(test_prefix, asset_type)
dialog.show()
qtbot.addWidget(dialog)
assert dialog.new_radio_button.isVisible() == asset_type.can_create()
assert dialog.new_version_radio_button.isVisible() == asset_type.can_create()
assert dialog.fork_radio_button.isVisible() == asset_type.can_fork()
def test_input_disabling(self, qtbot, test_prefix):
dialog = AssetCreationDialog(test_prefix, AssetType.DATAFORMAT)
dialog.show()
qtbot.addWidget(dialog)
assert dialog.name_lineedit.isEnabled()
assert not dialog.new_version_combobox.isEnabled()
assert not dialog.fork_combobox.isEnabled()
assert dialog.creationType() == AssetCreationDialog.NEW
qtbot.mouseClick(dialog.new_version_radio_button, QtCore.Qt.LeftButton)
assert not dialog.name_lineedit.isEnabled()
assert dialog.new_version_combobox.isEnabled()
assert not dialog.fork_combobox.isEnabled()
assert dialog.creationType() == AssetCreationDialog.NEW_VERSION
qtbot.mouseClick(dialog.fork_radio_button, QtCore.Qt.LeftButton)
assert not dialog.name_lineedit.isEnabled()
assert not dialog.new_version_combobox.isEnabled()
assert dialog.fork_combobox.isEnabled()
assert dialog.creationType() == AssetCreationDialog.FORK
def test_create_new(self, qtbot, test_prefix):
dialog = AssetCreationDialog(test_prefix, AssetType.DATAFORMAT)
qtbot.addWidget(dialog)
asset_name = "test_asset"
qtbot.mouseClick(dialog.new_radio_button, QtCore.Qt.LeftButton)
with qtbot.waitCallback() as cb:
dialog.open(cb)
qtbot.keyClicks(dialog.name_lineedit, asset_name)
qtbot.mouseClick(
dialog.buttonbox.button(QDialogButtonBox.Ok), QtCore.Qt.LeftButton
)
assert dialog.creationType() == AssetCreationDialog.NEW
assert dialog.assetInfo() == asset_name
def test_create_new_version(self, qtbot, test_prefix):
dialog = AssetCreationDialog(test_prefix, AssetType.DATAFORMAT)
qtbot.addWidget(dialog)
with qtbot.waitCallback() as cb:
dialog.open(cb)
qtbot.mouseClick(dialog.new_version_radio_button, QtCore.Qt.LeftButton)
qtbot.mouseClick(
dialog.buttonbox.button(QDialogButtonBox.Ok), QtCore.Qt.LeftButton
)
assert dialog.creationType() == AssetCreationDialog.NEW_VERSION
assert dialog.assetInfo() == dialog.new_version_combobox.currentText()
def test_create_fork(self, qtbot, test_prefix):
dialog = AssetCreationDialog(test_prefix, AssetType.DATAFORMAT)
qtbot.addWidget(dialog)
asset_name = "test_asset"
with qtbot.waitCallback() as cb:
dialog.open(cb)
qtbot.mouseClick(dialog.fork_radio_button, QtCore.Qt.LeftButton)
qtbot.keyClicks(dialog.fork_lineedit, asset_name)
qtbot.mouseClick(
dialog.buttonbox.button(QDialogButtonBox.Ok), QtCore.Qt.LeftButton
)
assert dialog.creationType() == AssetCreationDialog.FORK
assert dialog.assetInfo() == (dialog.fork_combobox.currentText(), asset_name)
# vim: set fileencoding=utf-8 :
###############################################################################
# #
# Copyright (c) 2019 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.editor module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform 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. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
from PyQt5.QtWidgets import QComboBox
from PyQt5.QtWidgets import QDialog
from PyQt5.QtWidgets import QDialogButtonBox
from PyQt5.QtWidgets import QFormLayout
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QRadioButton
from PyQt5.QtWidgets import QVBoxLayout
from beat.cmdline.config import Configuration
from ..backend.assetmodel import AssetType
from ..backend.assetmodel import AssetModel
from ..utils import dataformat_basetypes
class CreationType:
(NEW, NEW_VERSION, FORK) = range(3)
def __init__(self, **kwds):
super().__init__(**kwds)
class AssetCreationDialog(QDialog, CreationType):
def __init__(self, prefix_path, asset_type, parent=None):
super(AssetCreationDialog, self).__init__(parent)
config = Configuration({})
asset_model = AssetModel()
asset_model.asset_type = asset_type
asset_model.prefix_path = prefix_path
self.fork_asset_list = asset_model.stringList()
self.new_version_asset_list = asset_model.stringList()
if asset_type == AssetType.DATAFORMAT:
basetypes = dataformat_basetypes()
self.fork_asset_list = [
asset for asset in self.fork_asset_list if asset not in basetypes
]
self.new_version_asset_list = [
asset for asset in self.fork_asset_list if config.user in asset
]
# New asset
self.name_lineedit = QLineEdit()
self.new_radio_button = QRadioButton(self.tr("New"))
self.new_radio_button.setChecked(True)
# New version
self.new_version_combobox = QComboBox()
self.new_version_combobox.addItems(self.new_version_asset_list)
self.new_version_combobox.setEnabled(False)
self.new_version_radio_button = QRadioButton(self.tr("New version"))
# Fork part
self.fork_combobox = QComboBox()
self.fork_combobox.addItems(self.fork_asset_list)
self.fork_combobox.setEnabled(False)
self.fork_lineedit = QLineEdit()
self.fork_lineedit.setEnabled(False)
self.fork_radio_button = QRadioButton(self.tr("Fork"))
self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonbox.button(QDialogButtonBox.Ok).setEnabled(False)
# Layouts
fork_layout = QVBoxLayout()
fork_layout.addWidget(self.fork_combobox)
fork_layout.addWidget(self.fork_lineedit)
form_layout = QFormLayout(self)
if asset_type.can_create():
form_layout.addRow(self.new_radio_button, self.name_lineedit)
form_layout.addRow(self.new_version_radio_button, self.new_version_combobox)
if asset_type.can_fork():
form_layout.addRow(self.fork_radio_button, fork_layout)
form_layout.addRow(self.buttonbox)
self.name_lineedit.textChanged.connect(self.__validate_name)
self.new_radio_button.toggled.connect(self.name_lineedit.setEnabled)
self.new_radio_button.toggled.connect(self.__update_ui)
self.fork_lineedit.textChanged.connect(self.__validate_name)
self.fork_radio_button.toggled.connect(self.fork_combobox.setEnabled)
self.fork_radio_button.toggled.connect(self.fork_lineedit.setEnabled)
self.fork_radio_button.toggled.connect(self.__update_ui)
self.new_version_radio_button.toggled.connect(
self.new_version_combobox.setEnabled
)
self.new_version_radio_button.toggled.connect(self.__update_ui)
self.buttonbox.accepted.connect(self.accept)
self.buttonbox.rejected.connect(self.reject)
def __update_ui(self):
if self.isNew():
self.__validate_name(self.name_lineedit.text())
elif self.isFork():
self.__validate_name(self.fork_lineedit.text())
else:
self.buttonbox.button(QDialogButtonBox.Ok).setEnabled(True)
def __validate_name(self, name):
"""Validate that new name is not already used"""
ok_button = self.buttonbox.button(QDialogButtonBox.Ok)
if name:
used_names = [asset.split("/")[-2] for asset in self.fork_asset_list]
ok_button.setEnabled(name not in used_names)
else:
ok_button.setEnabled(False)
def isNew(self):
return self.new_radio_button.isChecked()
def isNewVersion(self):
return self.new_version_radio_button.isChecked()
def isFork(self):
return self.fork_radio_button.isChecked()
def assetInfo(self):
if self.isNew():
return self.name_lineedit.text()
elif self.isNewVersion():
return self.new_version_combobox.currentText()
else:
return (self.fork_combobox.currentText(), self.fork_lineedit.text())
def open(self, slot):
self.accepted.connect(slot)
super(AssetCreationDialog, self).open()
def creationType(self):
"""Returns the type of creation done"""
if self.isNew():
return self.NEW
elif self.isNewVersion():
return self.NEW_VERSION
else:
return self.FORK
@staticmethod
def getAssetInfo(parent, prefix_path, asset_type):
dialog = AssetCreationDialog(prefix_path, asset_type, parent)
result = dialog.exec_()
if result == QDialog.Accepted:
return True, dialog.creationType(), dialog.assetInfo()
else:
return False, None, None
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment