diff --git a/ibridgesgui/browser.py b/ibridgesgui/browser.py
index 683e9a78..e014a243 100644
--- a/ibridgesgui/browser.py
+++ b/ibridgesgui/browser.py
@@ -22,7 +22,7 @@
populate_table,
populate_textfield,
)
-from ibridgesgui.popup_widgets import CreateCollection
+from ibridgesgui.popup_widgets import CreateCollection, Rename
from ibridgesgui.ui_files.tabBrowser import Ui_tabBrowser
@@ -44,7 +44,6 @@ def __init__(self, session, app_name):
if self.session.home is not None:
root_path = IrodsPath(self.session).absolute()
else:
-
root_path = IrodsPath(
self.session, f"/{self.session.zone}/home/{self.session.username}"
)
@@ -76,6 +75,7 @@ def browse(self):
self.upload_dir_button.clicked.connect(self.folder_upload)
self.download_button.clicked.connect(self.download)
self.create_coll_button.clicked.connect(self.create_collection)
+ self.rename_button.clicked.connect(self.rename_item)
# Browser table behaviour
self.browser_table.doubleClicked.connect(self.update_path)
@@ -105,7 +105,6 @@ def set_parent(self):
self.path_input.setText(str(current_path.parent))
self.load_browser_table()
- # @PyQt6.QtCore.pyqtSlot(PyQt6.QtCore.QModelIndex)
def update_path(self, index):
"""Take path from path_input and loads browser table."""
self.error_label.clear()
@@ -123,6 +122,20 @@ def create_collection(self):
coll_widget.exec()
self.load_browser_table()
+ def rename_item(self):
+ """Rename/move a collection or data object."""
+ self.error_label.clear()
+ if self.browser_table.currentRow() == -1:
+ self.error_label.setText("Please select a row from the table first!")
+ return
+ item_name = self.browser_table.item(self.browser_table.currentRow(), 1).text()
+ irods_path = IrodsPath(self.session, "/" + self.path_input.text().strip("/")).joinpath(
+ item_name
+ )
+ rename_widget = Rename(irods_path, self.logger)
+ rename_widget.exec()
+ self.load_browser_table()
+
def folder_upload(self):
"""Select a folder and upload."""
self.error_label.clear()
diff --git a/ibridgesgui/config.py b/ibridgesgui/config.py
index af94ef4c..b9c69585 100644
--- a/ibridgesgui/config.py
+++ b/ibridgesgui/config.py
@@ -128,6 +128,7 @@ def _get_config() -> Union[None, dict]:
# irods config functions
+
def is_session_from_config(session: Session) -> Union[Session, None]:
"""Create a new session from the given session.
diff --git a/ibridgesgui/gui_utils.py b/ibridgesgui/gui_utils.py
index f0fa2c1b..288ee5d8 100644
--- a/ibridgesgui/gui_utils.py
+++ b/ibridgesgui/gui_utils.py
@@ -1,7 +1,6 @@
"""Handy and reusable functions for the GUI."""
import pathlib
-from importlib.resources import files
from typing import Union
import irods
@@ -10,6 +9,12 @@
from ibridgesgui.config import get_last_ienv_path, is_session_from_config
+try:
+ from importlib.resources import files
+except ImportError:
+ from importlib_resources import files
+
+
UI_FILE_DIR = files(__package__) / "ui_files"
diff --git a/ibridgesgui/popup_widgets.py b/ibridgesgui/popup_widgets.py
index c820e0ec..0914651a 100644
--- a/ibridgesgui/popup_widgets.py
+++ b/ibridgesgui/popup_widgets.py
@@ -14,6 +14,7 @@
from ibridgesgui.gui_utils import UI_FILE_DIR, populate_textfield
from ibridgesgui.ui_files.configCheck import Ui_configCheck
from ibridgesgui.ui_files.createCollection import Ui_createCollection
+from ibridgesgui.ui_files.renameItem import Ui_renameItem
class CreateCollection(QDialog, Ui_createCollection):
@@ -85,6 +86,43 @@ def accept(self):
self.error_label.setText("ERROR: insufficient rights.")
+class Rename(QDialog, Ui_renameItem):
+ """Popup window to rename and move a collection or data object."""
+
+ def __init__(self, irods_path: IrodsPath, logger):
+ """Initialise window."""
+ super().__init__()
+ if getattr(sys, "frozen", False):
+ super().setupUi(self)
+ else:
+ loadUi(UI_FILE_DIR / "renameItem.ui", self)
+
+ self.logger = logger
+ self.setWindowTitle("Create iRODS collection")
+ self.setWindowFlags(QtCore.Qt.WindowType.WindowStaysOnTopHint)
+ self.irods_path = irods_path
+ self.item_path_label.setText(str(irods_path))
+ self.item_path_input.setText(str(irods_path))
+ self.buttonBox.accepted.connect(self.accept)
+
+ def accept(self):
+ """Create new collection."""
+ if self.item_path_input.text() != "":
+ new_path = IrodsPath(self.irods_path.session, self.item_path_input.text())
+ if new_path.exists():
+ self.error_label.setText(f"{new_path} already exists.")
+ else:
+ try:
+ new_irods_path = self.irods_path.rename(new_path)
+ self.logger.info(f"Rename/Move {self.irods_path} --> {new_irods_path}")
+ self.done(0)
+ except irods.exception.CAT_NO_ACCESS_PERMISSION:
+ self.error_label.setText(f"No access rights to {new_path}.")
+ except Exception as err:
+ self.logger.exception(f"Could not create {new_path}: {err}")
+ self.error_label.setText(f"Could not create {new_path}, consult the logs.")
+
+
class CheckConfig(QDialog, Ui_configCheck):
"""Popup window to edit, create and check an environment.json."""
diff --git a/ibridgesgui/ui_files/MainMenu.py b/ibridgesgui/ui_files/MainMenu.py
index a77a52d2..5a6cac2b 100644
--- a/ibridgesgui/ui_files/MainMenu.py
+++ b/ibridgesgui/ui_files/MainMenu.py
@@ -1,6 +1,6 @@
# Form implementation generated from reading ui file 'ibridgesgui/ui_files/MainMenu.ui'
#
-# Created by: PyQt6 UI code generator 6.6.1
+# Created by: PyQt6 UI code generator 6.4.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
@@ -14,35 +14,44 @@ def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1300, 850)
MainWindow.setMinimumSize(QtCore.QSize(1300, 850))
- MainWindow.setStyleSheet(
- "QWidget\n"
- "{\n"
- " color: rgb(86, 184, 139);\n"
- " background-color: rgb(54, 54, 54);\n"
- " selection-background-color: rgb(58, 152, 112);\n"
- " font: 16pt;\n"
- "}\n"
- "\n"
- "QTabBar::tab:top:selected {\n"
- " background-color: rgb(58, 152, 112);\n"
- " color: rgb(54, 54, 54);\n"
- "}\n"
- ""
- )
+ MainWindow.setStyleSheet("QWidget\n"
+"{\n"
+" color: rgb(86, 184, 139);\n"
+" background-color: rgb(54, 54, 54);\n"
+" selection-background-color: rgb(58, 152, 112);\n"
+" font: 16pt;\n"
+"}\n"
+"\n"
+"QTabBar::tab:top:selected {\n"
+" background-color: rgb(58, 152, 112);\n"
+" color: rgb(54, 54, 54);\n"
+"}\n"
+"\n"
+"QLabel#error_label\n"
+"{\n"
+" color: rgb(217, 174, 23);\n"
+" font: 18pt;\n"
+"}\n"
+"")
self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
self.centralwidget.setStyleSheet("")
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.tab_widget = QtWidgets.QTabWidget(parent=self.centralwidget)
- self.tab_widget.setMinimumSize(QtCore.QSize(600, 300))
+ self.tab_widget.setMinimumSize(QtCore.QSize(600, 500))
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(False)
font.setItalic(False)
+ font.setWeight(50)
self.tab_widget.setFont(font)
self.tab_widget.setObjectName("tab_widget")
self.verticalLayout.addWidget(self.tab_widget)
+ self.error_label = QtWidgets.QLabel(parent=self.centralwidget)
+ self.error_label.setText("")
+ self.error_label.setObjectName("error_label")
+ self.verticalLayout.addWidget(self.error_label)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1300, 24))
@@ -50,6 +59,7 @@ def setupUi(self, MainWindow):
font.setPointSize(16)
font.setBold(False)
font.setItalic(False)
+ font.setWeight(50)
self.menubar.setFont(font)
self.menubar.setObjectName("menubar")
self.main_menu = QtWidgets.QMenu(parent=self.menubar)
@@ -57,14 +67,12 @@ def setupUi(self, MainWindow):
font.setPointSize(16)
font.setBold(False)
font.setItalic(False)
+ font.setWeight(50)
self.main_menu.setFont(font)
self.main_menu.setObjectName("main_menu")
self.config_menu = QtWidgets.QMenu(parent=self.menubar)
self.config_menu.setObjectName("config_menu")
MainWindow.setMenuBar(self.menubar)
- self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
- self.statusbar.setObjectName("statusbar")
- MainWindow.setStatusBar(self.statusbar)
self.action_close_session = QtGui.QAction(parent=MainWindow)
font = QtGui.QFont()
self.action_close_session.setFont(font)
diff --git a/ibridgesgui/ui_files/MainMenu.ui b/ibridgesgui/ui_files/MainMenu.ui
index db8e7068..b6a8e5a9 100644
--- a/ibridgesgui/ui_files/MainMenu.ui
+++ b/ibridgesgui/ui_files/MainMenu.ui
@@ -50,12 +50,13 @@ QLabel#error_label
600
- 300
+ 500
16
+ 50
false
false
@@ -86,6 +87,7 @@ QLabel#error_label
16
+ 50
false
false
@@ -94,6 +96,7 @@ QLabel#error_label
16
+ 50
false
false
diff --git a/ibridgesgui/ui_files/renameItem.py b/ibridgesgui/ui_files/renameItem.py
new file mode 100644
index 00000000..591bfdff
--- /dev/null
+++ b/ibridgesgui/ui_files/renameItem.py
@@ -0,0 +1,77 @@
+# Form implementation generated from reading ui file 'ibridgesgui/ui_files/renameItem.ui'
+#
+# Created by: PyQt6 UI code generator 6.4.2
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
+# run again. Do not edit this file unless you know what you are doing.
+
+
+from PyQt6 import QtCore, QtGui, QtWidgets
+
+
+class Ui_renameItem(object):
+ def setupUi(self, renameItem):
+ createCollection.setObjectName("createCollection")
+ createCollection.resize(500, 200)
+ createCollection.setMinimumSize(QtCore.QSize(500, 200))
+ createCollection.setMaximumSize(QtCore.QSize(500, 200))
+ createCollection.setStyleSheet("QWidget\n"
+"{\n"
+" color: rgb(86, 184, 139);\n"
+" background-color: rgb(54, 54, 54);\n"
+" font: 16pt\n"
+"}\n"
+"\n"
+"QLineEdit\n"
+"{\n"
+" background-color: rgb(85, 87, 83);\n"
+" border-color: rgb(217, 174, 23)\n"
+"}\n"
+"\n"
+"QLabel#error_label\n"
+"{\n"
+" color: rgb(217, 174, 23);\n"
+"}\n"
+"\n"
+"")
+ self.verticalLayout = QtWidgets.QVBoxLayout(createCollection)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.label = QtWidgets.QLabel(parent=createCollection)
+ self.label.setObjectName("label")
+ self.verticalLayout.addWidget(self.label)
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.item_path_label = QtWidgets.QLabel(parent=createCollection)
+ self.item_path_label.setText("")
+ self.item_path_label.setObjectName("item_path_label")
+ self.horizontalLayout.addWidget(self.item_path_label)
+ self.verticalLayout.addLayout(self.horizontalLayout)
+ self.label_2 = QtWidgets.QLabel(parent=createCollection)
+ self.label_2.setObjectName("label_2")
+ self.verticalLayout.addWidget(self.label_2)
+ self.item_path_input = QtWidgets.QLineEdit(parent=createCollection)
+ self.item_path_input.setObjectName("item_path_input")
+ self.verticalLayout.addWidget(self.item_path_input)
+ self.error_label = QtWidgets.QLabel(parent=createCollection)
+ self.error_label.setStyleSheet("")
+ self.error_label.setText("")
+ self.error_label.setObjectName("error_label")
+ self.verticalLayout.addWidget(self.error_label)
+ spacerItem = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum)
+ self.verticalLayout.addItem(spacerItem)
+ self.buttonBox = QtWidgets.QDialogButtonBox(parent=createCollection)
+ self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
+ self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok)
+ self.buttonBox.setObjectName("buttonBox")
+ self.verticalLayout.addWidget(self.buttonBox)
+
+ self.retranslateUi(createCollection)
+ self.buttonBox.accepted.connect(createCollection.accept) # type: ignore
+ self.buttonBox.rejected.connect(createCollection.reject) # type: ignore
+ QtCore.QMetaObject.connectSlotsByName(createCollection)
+
+ def retranslateUi(self, createCollection):
+ _translate = QtCore.QCoreApplication.translate
+ createCollection.setWindowTitle(_translate("createCollection", "Rename/Move"))
+ self.label.setText(_translate("createCollection", "Rename or move:"))
+ self.label_2.setText(_translate("createCollection", "to new location:"))
diff --git a/ibridgesgui/ui_files/renameItem.ui b/ibridgesgui/ui_files/renameItem.ui
new file mode 100644
index 00000000..087e515f
--- /dev/null
+++ b/ibridgesgui/ui_files/renameItem.ui
@@ -0,0 +1,151 @@
+
+
+ renameItem
+
+
+
+ 0
+ 0
+ 500
+ 200
+
+
+
+
+ 500
+ 200
+
+
+
+
+ 500
+ 200
+
+
+
+ Rename/Move
+
+
+ QWidget
+{
+ color: rgb(86, 184, 139);
+ background-color: rgb(54, 54, 54);
+ font: 16pt
+}
+
+QLineEdit
+{
+ background-color: rgb(85, 87, 83);
+ border-color: rgb(217, 174, 23)
+}
+
+QLabel#error_label
+{
+ color: rgb(217, 174, 23);
+}
+
+
+
+
+ -
+
+
+ Rename or move:
+
+
+
+ -
+
+
-
+
+
+
+
+
+
+
+
+ -
+
+
+ to new location:
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Minimum
+
+
+
+ 20
+ 10
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ renameItem
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ renameItem
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/ibridgesgui/ui_files/tabBrowser.ui b/ibridgesgui/ui_files/tabBrowser.ui
index d27db280..dd39cabe 100644
--- a/ibridgesgui/ui_files/tabBrowser.ui
+++ b/ibridgesgui/ui_files/tabBrowser.ui
@@ -76,6 +76,7 @@ QPushButton#confirm_button
16
+ 75
true
@@ -156,6 +157,13 @@ QPushButton#confirm_button
+ -
+
+
+ Rename/Move
+
+
+
-
@@ -231,6 +239,15 @@ QPushButton#confirm_button
QAbstractItemView::NoEditTriggers
+
+ false
+
+
+ false
+
+
+ false
+
false
@@ -311,6 +328,7 @@ QPushButton#confirm_button
+ 50
false
@@ -380,6 +398,7 @@ QPushButton#confirm_button
+ 75
true
@@ -412,6 +431,7 @@ QPushButton#confirm_button
+ 75
true
@@ -438,6 +458,7 @@ QPushButton#confirm_button
20
+ 75
true
@@ -460,6 +481,7 @@ QPushButton#confirm_button
+ 75
true
@@ -532,6 +554,7 @@ QPushButton#confirm_button
20
+ 75
true
@@ -631,6 +654,7 @@ QPushButton#confirm_button
+ 75
true
@@ -733,9 +757,8 @@ QPushButton#confirm_button
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
-<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-hr { height: 1px; border-width: 0; }
</style></head><body style=" font-family:'.AppleSystemUIFont'; font-size:13pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Summary</p></body></html>
@@ -771,6 +794,7 @@ hr { height: 1px; border-width: 0; }
13
+ 75
true
diff --git a/ibridgesgui/ui_files/tabSync.py b/ibridgesgui/ui_files/tabSync.py
index 36d352b8..a5d41cdf 100644
--- a/ibridgesgui/ui_files/tabSync.py
+++ b/ibridgesgui/ui_files/tabSync.py
@@ -1,6 +1,6 @@
# Form implementation generated from reading ui file 'ibridgesgui/ui_files/tabSync.ui'
#
-# Created by: PyQt6 UI code generator 6.6.1
+# Created by: PyQt6 UI code generator 6.4.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
@@ -12,7 +12,7 @@
class Ui_tabSync(object):
def setupUi(self, tabSync):
tabSync.setObjectName("tabSync")
- tabSync.resize(1234, 721)
+ tabSync.resize(1234, 749)
tabSync.setStyleSheet("QWidget\n"
"{\n"
" color: rgb(86, 184, 139);\n"
@@ -58,6 +58,7 @@ def setupUi(self, tabSync):
font = QtGui.QFont()
font.setPointSize(13)
font.setBold(True)
+ font.setWeight(75)
self.label_19.setFont(font)
self.label_19.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.label_19.setObjectName("label_19")
@@ -143,6 +144,7 @@ def setupUi(self, tabSync):
font = QtGui.QFont()
font.setPointSize(13)
font.setBold(True)
+ font.setWeight(75)
self.label_20.setFont(font)
self.label_20.setTextFormat(QtCore.Qt.TextFormat.PlainText)
self.label_20.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
@@ -196,6 +198,11 @@ def setupUi(self, tabSync):
item = QtWidgets.QTableWidgetItem()
self.diff_table.setHorizontalHeaderItem(2, item)
self.verticalLayout_11.addWidget(self.diff_table)
+ self.sync_button = QtWidgets.QPushButton(parent=self.layoutWidget)
+ self.sync_button.setObjectName("sync_button")
+ self.verticalLayout_11.addWidget(self.sync_button)
+ spacerItem11 = QtWidgets.QSpacerItem(20, 100, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Fixed)
+ self.verticalLayout_11.addItem(spacerItem11)
self.retranslateUi(tabSync)
QtCore.QMetaObject.connectSlotsByName(tabSync)
@@ -213,3 +220,4 @@ def retranslateUi(self, tabSync):
item.setText(_translate("tabSync", "Destination"))
item = self.diff_table.horizontalHeaderItem(2)
item.setText(_translate("tabSync", "Size in Bytes"))
+ self.sync_button.setText(_translate("tabSync", "Synchronise"))
diff --git a/ibridgesgui/ui_files/tabSync.ui b/ibridgesgui/ui_files/tabSync.ui
index d472e579..6daa5b20 100644
--- a/ibridgesgui/ui_files/tabSync.ui
+++ b/ibridgesgui/ui_files/tabSync.ui
@@ -7,7 +7,7 @@
0
0
1234
- 721
+ 749
@@ -47,7 +47,7 @@ QLabel#error_label
771
-
+
QLayout::SetDefaultConstraint
@@ -72,6 +72,7 @@ QLabel#error_label
13
+ 75
true
@@ -311,6 +312,7 @@ QLabel#error_label
13
+ 75
true
@@ -455,6 +457,22 @@ QLabel#error_label
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 100
+
+
+
+
diff --git a/pyproject.toml b/pyproject.toml
index c2c7a3b4..014ae479 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -24,8 +24,8 @@ classifiers = [
dependencies = [
"PyQt6>=6.4.2",
"ibridges==0.2.0",
- # "pyinstaller==5.8.0",
"setproctitle==1.3.3",
+ "importlib-resources;python_version<='3.9'",
]
dynamic = ["version"]