Skip to content

Commit 4ba4453

Browse files
committed
Addon Manager: Show versions in update all
1 parent 6241590 commit 4ba4453

File tree

3 files changed

+59
-22
lines changed

3 files changed

+59
-22
lines changed

src/Mod/AddonManager/AddonManagerTest/gui/test_update_all_gui.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-License-Identifier: LGPL-2.1-or-later
22
# ***************************************************************************
33
# * *
4-
# * Copyright (c) 2022 FreeCAD Project Association *
4+
# * Copyright (c) 2022-2025 FreeCAD project association AISBL *
55
# * *
66
# * This file is part of FreeCAD. *
77
# * *
@@ -73,6 +73,8 @@ def __init__(self, name):
7373
self.display_name = name
7474
self.name = name
7575
self.macro = None
76+
self.metadata = None
77+
self.installed_metadata = None
7678

7779
def status(self):
7880
return Addon.Status.UPDATE_AVAILABLE
@@ -151,22 +153,22 @@ def test_update_addon_status(self):
151153
self.test_object._setup_dialog()
152154
self.test_object._update_addon_status(0, AddonStatus.WAITING)
153155
self.assertEqual(
154-
self.test_object.dialog.tableWidget.item(0, 1).text(),
156+
self.test_object.dialog.tableWidget.item(0, 2).text(),
155157
AddonStatus.WAITING.ui_string(),
156158
)
157159
self.test_object._update_addon_status(0, AddonStatus.INSTALLING)
158160
self.assertEqual(
159-
self.test_object.dialog.tableWidget.item(0, 1).text(),
161+
self.test_object.dialog.tableWidget.item(0, 2).text(),
160162
AddonStatus.INSTALLING.ui_string(),
161163
)
162164
self.test_object._update_addon_status(0, AddonStatus.SUCCEEDED)
163165
self.assertEqual(
164-
self.test_object.dialog.tableWidget.item(0, 1).text(),
166+
self.test_object.dialog.tableWidget.item(0, 2).text(),
165167
AddonStatus.SUCCEEDED.ui_string(),
166168
)
167169
self.test_object._update_addon_status(0, AddonStatus.FAILED)
168170
self.assertEqual(
169-
self.test_object.dialog.tableWidget.item(0, 1).text(),
171+
self.test_object.dialog.tableWidget.item(0, 2).text(),
170172
AddonStatus.FAILED.ui_string(),
171173
)
172174

@@ -175,19 +177,19 @@ def test_process_next_update(self):
175177
self.test_object._launch_active_installer = lambda: None
176178
self.test_object._process_next_update()
177179
self.assertEqual(
178-
self.test_object.dialog.tableWidget.item(0, 1).text(),
180+
self.test_object.dialog.tableWidget.item(0, 2).text(),
179181
AddonStatus.INSTALLING.ui_string(),
180182
)
181183

182184
self.test_object._process_next_update()
183185
self.assertEqual(
184-
self.test_object.dialog.tableWidget.item(1, 1).text(),
186+
self.test_object.dialog.tableWidget.item(1, 2).text(),
185187
AddonStatus.INSTALLING.ui_string(),
186188
)
187189

188190
self.test_object._process_next_update()
189191
self.assertEqual(
190-
self.test_object.dialog.tableWidget.item(2, 1).text(),
192+
self.test_object.dialog.tableWidget.item(2, 2).text(),
191193
AddonStatus.INSTALLING.ui_string(),
192194
)
193195

@@ -208,15 +210,15 @@ def test_update_succeeded(self):
208210
self.test_object._setup_dialog()
209211
self.test_object._update_succeeded(self.addons[0])
210212
self.assertEqual(
211-
self.test_object.dialog.tableWidget.item(0, 1).text(),
213+
self.test_object.dialog.tableWidget.item(0, 2).text(),
212214
AddonStatus.SUCCEEDED.ui_string(),
213215
)
214216

215217
def test_update_failed(self):
216218
self.test_object._setup_dialog()
217219
self.test_object._update_failed(self.addons[0])
218220
self.assertEqual(
219-
self.test_object.dialog.tableWidget.item(0, 1).text(),
221+
self.test_object.dialog.tableWidget.item(0, 2).text(),
220222
AddonStatus.FAILED.ui_string(),
221223
)
222224

src/Mod/AddonManager/addonmanager_update_all_gui.py

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-License-Identifier: LGPL-2.1-or-later
22
# ***************************************************************************
33
# * *
4-
# * Copyright (c) 2022 FreeCAD Project Association *
4+
# * Copyright (c) 2022-2025 FreeCAD project association AISBL *
55
# * *
66
# * This file is part of FreeCAD. *
77
# * *
@@ -85,6 +85,8 @@ class UpdateAllGUI(QtCore.QObject):
8585
finished = QtCore.Signal()
8686
addon_updated = QtCore.Signal(object)
8787

88+
index_role = QtCore.Qt.UserRole + 1
89+
8890
def __init__(self, addons: List[Addon]):
8991
super().__init__()
9092
self.addons = addons
@@ -114,28 +116,58 @@ def _setup_dialog(self):
114116
self.dialog.tableWidget.clear()
115117
self.in_process_row = None
116118
self.row_map = {}
119+
self._setup_empty_table()
120+
counter = 0
117121
for addon in self.addons:
118122
if addon.status() == Addon.Status.UPDATE_AVAILABLE:
119-
self._add_addon_to_table(addon)
123+
self._add_addon_to_table(addon, counter)
120124
self.addons_with_update.append(addon)
125+
counter += 1
121126

122127
def _cancel_installation(self):
123128
self.cancelled = True
124129
if self.worker_thread and self.worker_thread.isRunning():
125130
self.worker_thread.requestInterruption()
126131

127-
def _add_addon_to_table(self, addon: Addon):
128-
"""Add the given addon to the list, with no icon in the first column"""
132+
def _setup_empty_table(self):
133+
self.dialog.tableWidget.setColumnCount(4)
134+
self.dialog.tableWidget.horizontalHeader().setSectionResizeMode(
135+
0, QtWidgets.QHeaderView.ResizeMode.ResizeToContents
136+
)
137+
self.dialog.tableWidget.horizontalHeader().setSectionResizeMode(
138+
1, QtWidgets.QHeaderView.ResizeMode.ResizeToContents
139+
)
140+
self.dialog.tableWidget.horizontalHeader().setSectionResizeMode(
141+
2, QtWidgets.QHeaderView.ResizeMode.ResizeToContents
142+
)
143+
self.dialog.tableWidget.horizontalHeader().setSectionResizeMode(
144+
3, QtWidgets.QHeaderView.ResizeMode.Stretch
145+
)
146+
147+
def _add_addon_to_table(self, addon: Addon, index: int):
148+
"""Add the given addon to the list, storing its index as user data in the first column"""
129149
new_row = self.dialog.tableWidget.rowCount()
130-
self.dialog.tableWidget.setColumnCount(2)
131150
self.dialog.tableWidget.setRowCount(new_row + 1)
132-
self.dialog.tableWidget.setItem(new_row, 0, QtWidgets.QTableWidgetItem(addon.display_name))
133-
self.dialog.tableWidget.setItem(new_row, 1, QtWidgets.QTableWidgetItem(""))
151+
new_item = QtWidgets.QTableWidgetItem(addon.display_name)
152+
new_item.setData(UpdateAllGUI.index_role, index) # Only first item in each row needs data()
153+
self.dialog.tableWidget.setItem(new_row, 0, new_item)
154+
if addon.installed_metadata and addon.installed_metadata.version:
155+
self.dialog.tableWidget.setItem(
156+
new_row, 1, QtWidgets.QTableWidgetItem(str(addon.installed_metadata.version))
157+
)
158+
self.dialog.tableWidget.setItem(new_row, 2, QtWidgets.QTableWidgetItem(""))
159+
self.dialog.tableWidget.setItem(new_row, 3, QtWidgets.QTableWidgetItem(""))
134160
self.row_map[addon.name] = new_row
135161

136162
def _update_addon_status(self, row: int, status: AddonStatus):
137163
"""Update the GUI to reflect this addon's new status."""
138-
self.dialog.tableWidget.item(row, 1).setText(status.ui_string())
164+
self.dialog.tableWidget.item(row, 2).setText(status.ui_string())
165+
if status == AddonStatus.SUCCEEDED and self.addons[row].metadata:
166+
self.dialog.tableWidget.item(row, 2).setText(status.ui_string() + " →")
167+
index = self.dialog.tableWidget.item(row, 0).data(UpdateAllGUI.index_role)
168+
addon = self.addons[index]
169+
if addon.metadata and addon.metadata.version:
170+
self.dialog.tableWidget.item(row, 3).setText(str(addon.metadata.version))
139171

140172
def _process_next_update(self):
141173
"""Grab the next addon in the list and start its updater."""

src/Mod/AddonManager/update_all.ui

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<item>
2828
<widget class="QTableWidget" name="tableWidget">
2929
<property name="editTriggers">
30-
<set>QAbstractItemView::NoEditTriggers</set>
30+
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
3131
</property>
3232
<property name="tabKeyNavigation">
3333
<bool>false</bool>
@@ -39,7 +39,10 @@
3939
<bool>false</bool>
4040
</property>
4141
<property name="selectionMode">
42-
<enum>QAbstractItemView::NoSelection</enum>
42+
<enum>QAbstractItemView::SelectionMode::NoSelection</enum>
43+
</property>
44+
<property name="selectionBehavior">
45+
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
4346
</property>
4447
<property name="showGrid">
4548
<bool>false</bool>
@@ -58,10 +61,10 @@
5861
<item>
5962
<widget class="QDialogButtonBox" name="buttonBox">
6063
<property name="orientation">
61-
<enum>Qt::Horizontal</enum>
64+
<enum>Qt::Orientation::Horizontal</enum>
6265
</property>
6366
<property name="standardButtons">
64-
<set>QDialogButtonBox::Cancel</set>
67+
<set>QDialogButtonBox::StandardButton::Cancel</set>
6568
</property>
6669
</widget>
6770
</item>

0 commit comments

Comments
 (0)