11# SPDX-License-Identifier: LGPL-2.1-or-later
22# ***************************************************************************
33# * *
4- # * Copyright (c) 2022-2023 FreeCAD Project Association *
4+ # * Copyright (c) 2022-2025 The FreeCAD Project Association AISBL *
55# * *
66# * This file is part of FreeCAD. *
77# * *
2222# ***************************************************************************
2323
2424import os
25+ from typing import Dict
2526
26- import FreeCAD
27- import FreeCADGui
28- from addonmanager_git import initialize_git
27+ import addonmanager_freecad_interface as fci
28+ import addonmanager_utilities as utils
2929
30- from PySide import QtWidgets , QtCore
30+ from addonmanager_git import initialize_git , GitFailed
3131
32- translate = FreeCAD .Qt .translate
32+ try :
33+ from PySide import QtWidgets , QtCore
34+ except ImportError :
35+ try :
36+ from PySide6 import QtWidgets , QtCore
37+ except ImportError :
38+ from PySide2 import QtWidgets , QtCore
39+
40+ translate = fci .translate
3341
3442
3543class ChangeBranchDialog (QtWidgets .QWidget ):
@@ -39,9 +47,7 @@ class ChangeBranchDialog(QtWidgets.QWidget):
3947 def __init__ (self , path : str , parent = None ):
4048 super ().__init__ (parent )
4149
42- self .ui = FreeCADGui .PySideUic .loadUi (
43- os .path .join (os .path .dirname (__file__ ), "change_branch.ui" )
44- )
50+ self .ui = utils .loadUi (os .path .join (os .path .dirname (__file__ ), "change_branch.ui" ))
4551
4652 self .item_filter = ChangeBranchDialogFilter ()
4753 self .ui .tableView .setModel (self .item_filter )
@@ -54,6 +60,9 @@ def __init__(self, path: str, parent=None):
5460
5561 # Figure out what row gets selected:
5662 git_manager = initialize_git ()
63+ if git_manager is None :
64+ return
65+
5766 row = 0
5867 self .current_ref = git_manager .current_branch (path )
5968 selection_model = self .ui .tableView .selectionModel ()
@@ -111,14 +120,51 @@ def exec(self):
111120 if result == QtWidgets .QMessageBox .Cancel :
112121 return
113122
114- gm = initialize_git ()
115- remote_name = ref ["ref_name" ]
116- _ , _ , local_name = ref ["ref_name" ].rpartition ("/" )
123+ self ._change_branch (self .item_model .path , ref )
124+
125+ def _change_branch (self , path : str , ref : Dict [str , str ]) -> None :
126+ """Change the git clone in `path` to git ref `ref`. Emits the branch_changed signal
127+ on success."""
128+ remote_name = ref ["ref_name" ]
129+ _ , _ , local_name = ref ["ref_name" ].rpartition ("/" )
130+ gm = initialize_git ()
131+ if gm is None :
132+ self ._show_no_git_dialog ()
133+ return
134+
135+ try :
117136 if ref ["upstream" ]:
118- gm .checkout (self . item_model . path , remote_name )
137+ gm .checkout (path , remote_name )
119138 else :
120- gm .checkout (self . item_model . path , remote_name , args = ["-b" , local_name ])
139+ gm .checkout (path , remote_name , args = ["-b" , local_name ])
121140 self .branch_changed .emit (self .current_ref , local_name )
141+ except GitFailed :
142+ self ._show_git_failed_dialog ()
143+
144+ def _show_no_git_dialog (self ):
145+ QtWidgets .QMessageBox .critical (
146+ self ,
147+ translate ("AddonsInstaller" , "Cannot find git" ),
148+ translate (
149+ "AddonsInstaller" ,
150+ "Could not find git executable: cannot change branch" ,
151+ ),
152+ QtWidgets .QMessageBox .Ok ,
153+ QtWidgets .QMessageBox .Ok ,
154+ )
155+
156+ def _show_git_failed_dialog (self ):
157+ QtWidgets .QMessageBox .critical (
158+ self ,
159+ translate ("AddonsInstaller" , "git operation failed" ),
160+ translate (
161+ "AddonsInstaller" ,
162+ "Git returned an error code when attempting to change branch. There may be "
163+ "more details in the Report View." ,
164+ ),
165+ QtWidgets .QMessageBox .Ok ,
166+ QtWidgets .QMessageBox .Ok ,
167+ )
122168
123169
124170class ChangeBranchDialogModel (QtCore .QAbstractTableModel ):
@@ -235,11 +281,11 @@ def _remove_tracking_duplicates(self):
235281
236282class ChangeBranchDialogFilter (QtCore .QSortFilterProxyModel ):
237283 def lessThan (self , left : QtCore .QModelIndex , right : QtCore .QModelIndex ):
238- leftData = self .sourceModel ().data (left , ChangeBranchDialogModel .DataSortRole )
239- rightData = self .sourceModel ().data (right , ChangeBranchDialogModel .DataSortRole )
240- if leftData is None or rightData is None :
241- if rightData is not None :
284+ left_data = self .sourceModel ().data (left , ChangeBranchDialogModel .DataSortRole )
285+ right_data = self .sourceModel ().data (right , ChangeBranchDialogModel .DataSortRole )
286+ if left_data is None or right_data is None :
287+ if right_data is not None :
242288 return True
243289 else :
244290 return False
245- return leftData < rightData
291+ return left_data < right_data
0 commit comments