SVN: UX improvements #136
@ -3,12 +3,13 @@
|
|||||||
# (c) 2022, Blender Foundation - Demeter Dzadik
|
# (c) 2022, Blender Foundation - Demeter Dzadik
|
||||||
|
|
||||||
from typing import Optional, Any, Set, Tuple, List
|
from typing import Optional, Any, Set, Tuple, List
|
||||||
|
import platform
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.props import IntProperty, CollectionProperty, BoolProperty, EnumProperty
|
from bpy.props import IntProperty, CollectionProperty, BoolProperty, EnumProperty
|
||||||
from bpy.types import AddonPreferences
|
from bpy.types import AddonPreferences
|
||||||
|
|
||||||
from .ui import ui_prefs
|
from .ui.ui_repo_list import draw_checkout, draw_repo_list
|
||||||
from .repository import SVN_repository
|
from .repository import SVN_repository
|
||||||
from .svn_info import get_svn_info
|
from .svn_info import get_svn_info
|
||||||
import json
|
import json
|
||||||
@ -156,7 +157,33 @@ class SVN_addon_preferences(AddonPreferences):
|
|||||||
self.load_repo_info_from_file()
|
self.load_repo_info_from_file()
|
||||||
self.save_repo_info_to_file()
|
self.save_repo_info_to_file()
|
||||||
|
|
||||||
draw = ui_prefs.draw_prefs
|
def draw(self, context):
|
||||||
|
if not self.is_svn_installed:
|
||||||
|
draw_prefs_no_svn(self, context)
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.checkout_mode:
|
||||||
|
draw_checkout(self, context)
|
||||||
|
else:
|
||||||
|
draw_repo_list(self, context)
|
||||||
|
|
||||||
|
|
||||||
|
def draw_prefs_no_svn(self, context):
|
||||||
|
terminal, url = "terminal", "https://subversion.apache.org/packages.html"
|
||||||
|
system = platform.system()
|
||||||
|
if system == "Windows":
|
||||||
|
terminal = "command line (cmd.exe)"
|
||||||
|
url = "https://subversion.apache.org/packages.html#windows"
|
||||||
|
elif system == "Darwin":
|
||||||
|
terminal = "Mac terminal"
|
||||||
|
url = "https://subversion.apache.org/packages.html#osx"
|
||||||
|
|
||||||
|
layout = self.layout
|
||||||
|
col = layout.column()
|
||||||
|
col.alert=True
|
||||||
|
col.label(text="Please ensure that Subversion (aka. SVN) is installed on your system.")
|
||||||
|
col.label(text=f"Typing `svn` into the {terminal} should yield a result.")
|
||||||
|
layout.operator("wm.url_open", icon='URL', text='Open Subversion Distribution Page').url=url
|
||||||
|
|
||||||
|
|
||||||
registry = [
|
registry = [
|
||||||
|
@ -3,7 +3,7 @@ from . import (
|
|||||||
ui_sidebar,
|
ui_sidebar,
|
||||||
ui_filebrowser,
|
ui_filebrowser,
|
||||||
ui_log,
|
ui_log,
|
||||||
ui_prefs,
|
ui_repo_list,
|
||||||
ui_outdated_warning,
|
ui_outdated_warning,
|
||||||
ui_context_menus
|
ui_context_menus
|
||||||
)
|
)
|
||||||
@ -13,7 +13,7 @@ modules = [
|
|||||||
ui_sidebar,
|
ui_sidebar,
|
||||||
ui_filebrowser,
|
ui_filebrowser,
|
||||||
ui_log,
|
ui_log,
|
||||||
ui_prefs,
|
ui_repo_list,
|
||||||
ui_outdated_warning,
|
ui_outdated_warning,
|
||||||
ui_context_menus
|
ui_context_menus
|
||||||
]
|
]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
# (c) 2023, Blender Foundation - Demeter Dzadik
|
# (c) 2023, Blender Foundation - Demeter Dzadik
|
||||||
|
|
||||||
from pathlib import Path
|
import platform
|
||||||
|
|
||||||
from bpy.types import UIList, Operator, Menu
|
from bpy.types import UIList, Operator, Menu
|
||||||
from bpy_extras.io_utils import ImportHelper
|
from bpy_extras.io_utils import ImportHelper
|
||||||
@ -10,11 +10,14 @@ from ..util import get_addon_prefs
|
|||||||
from .ui_log import draw_svn_log, is_log_useful
|
from .ui_log import draw_svn_log, is_log_useful
|
||||||
from .ui_file_list import draw_repo_file_list, draw_process_info
|
from .ui_file_list import draw_repo_file_list, draw_process_info
|
||||||
from ..threaded.background_process import Processes
|
from ..threaded.background_process import Processes
|
||||||
import platform
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
class SVN_UL_repositories(UIList):
|
class SVN_UL_repositories(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(
|
||||||
|
self, context, layout, data, item, icon, active_data, active_propname
|
||||||
|
):
|
||||||
repo = item
|
repo = item
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
|
||||||
@ -27,6 +30,7 @@ class SVN_UL_repositories(UIList):
|
|||||||
|
|
||||||
class SVN_OT_repo_add(Operator, ImportHelper):
|
class SVN_OT_repo_add(Operator, ImportHelper):
|
||||||
"""Add a repository to the list"""
|
"""Add a repository to the list"""
|
||||||
|
|
||||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||||
|
|
||||||
bl_idname = "svn.repo_add"
|
bl_idname = "svn.repo_add"
|
||||||
@ -45,7 +49,9 @@ class SVN_OT_repo_add(Operator, ImportHelper):
|
|||||||
repo = prefs.init_repo(context, path)
|
repo = prefs.init_repo(context, path)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.report(
|
self.report(
|
||||||
{'ERROR'}, "Failed to initialize repository. Ensure you have SVN installed, and that the selected directory is the root of a repository.")
|
{'ERROR'},
|
||||||
|
"Failed to initialize repository. Ensure you have SVN installed, and that the selected directory is the root of a repository.",
|
||||||
|
)
|
||||||
print(e)
|
print(e)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
if not repo:
|
if not repo:
|
||||||
@ -62,6 +68,7 @@ class SVN_OT_repo_add(Operator, ImportHelper):
|
|||||||
|
|
||||||
class SVN_OT_repo_remove(Operator):
|
class SVN_OT_repo_remove(Operator):
|
||||||
"""Remove a repository from the list"""
|
"""Remove a repository from the list"""
|
||||||
|
|
||||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||||
|
|
||||||
bl_idname = "svn.repo_remove"
|
bl_idname = "svn.repo_remove"
|
||||||
@ -90,109 +97,14 @@ class SVN_MT_add_repo(Menu):
|
|||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.operator(
|
layout.operator(
|
||||||
"svn.repo_add", text="Browse Existing Checkout", icon='FILE_FOLDER')
|
"svn.repo_add", text="Browse Existing Checkout", icon='FILE_FOLDER'
|
||||||
layout.operator("svn.checkout_initiate",
|
)
|
||||||
text="Create New Checkout", icon='URL').create = True
|
layout.operator(
|
||||||
|
"svn.checkout_initiate", text="Create New Checkout", icon='URL'
|
||||||
|
).create = True
|
||||||
|
|
||||||
|
|
||||||
def draw_prefs(self, context):
|
def draw_repo_list(self, context, draw_files=True, draw_log=True) -> None:
|
||||||
if not self.is_svn_installed:
|
|
||||||
draw_prefs_no_svn(self, context)
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.checkout_mode:
|
|
||||||
draw_prefs_checkout(self, context)
|
|
||||||
else:
|
|
||||||
draw_prefs_repos(self, context)
|
|
||||||
|
|
||||||
|
|
||||||
def draw_prefs_no_svn(self, context):
|
|
||||||
terminal, url = "terminal", "https://subversion.apache.org/packages.html"
|
|
||||||
system = platform.system()
|
|
||||||
if system == "Windows":
|
|
||||||
terminal = "command line (cmd.exe)"
|
|
||||||
url = "https://subversion.apache.org/packages.html#windows"
|
|
||||||
elif system == "Darwin":
|
|
||||||
terminal = "Mac terminal"
|
|
||||||
url = "https://subversion.apache.org/packages.html#osx"
|
|
||||||
|
|
||||||
layout = self.layout
|
|
||||||
col = layout.column()
|
|
||||||
col.alert=True
|
|
||||||
col.label(text="Please ensure that Subversion (aka. SVN) is installed on your system.")
|
|
||||||
col.label(text=f"Typing `svn` into the {terminal} should yield a result.")
|
|
||||||
layout.operator("wm.url_open", icon='URL', text='Open Subversion Distribution Page').url=url
|
|
||||||
|
|
||||||
|
|
||||||
def draw_prefs_checkout(self, context):
|
|
||||||
def get_terminal_howto():
|
|
||||||
msg_windows = "If you don't, cancel this operation and toggle it using Window->Toggle System Console."
|
|
||||||
msg_linux = "If you don't, quit Blender and re-launch it from a terminal."
|
|
||||||
msg_mac = msg_linux
|
|
||||||
|
|
||||||
system = platform.system()
|
|
||||||
if system == "Windows":
|
|
||||||
return msg_windows
|
|
||||||
elif system == "Linux":
|
|
||||||
return msg_linux
|
|
||||||
elif system == "Darwin":
|
|
||||||
return msg_mac
|
|
||||||
|
|
||||||
layout = self.layout
|
|
||||||
col = layout.column()
|
|
||||||
col.alert = True
|
|
||||||
|
|
||||||
col.label(text="IMPORTANT! ", icon='ERROR')
|
|
||||||
col.label(text="Make sure you have Blender's terminal open!")
|
|
||||||
col.label(text=get_terminal_howto())
|
|
||||||
col.separator()
|
|
||||||
col.label(
|
|
||||||
text="Downloading a repository can take a long time, and the UI will be locked.")
|
|
||||||
col.label(
|
|
||||||
text="Without a terminal, you won't be able to track the progress of the checkout.")
|
|
||||||
col.separator()
|
|
||||||
|
|
||||||
col = layout.column()
|
|
||||||
col.label(
|
|
||||||
text="To interrupt the checkout, you can press Ctrl+C in the terminal.", icon='INFO')
|
|
||||||
col.label(
|
|
||||||
text="You can resume it by re-running this operation, or with the SVN Update button.", icon='INFO')
|
|
||||||
col.separator()
|
|
||||||
|
|
||||||
prefs = get_addon_prefs(context)
|
|
||||||
repo = prefs.repositories[-1]
|
|
||||||
col.prop(repo, 'directory')
|
|
||||||
for other_repo in prefs.repositories:
|
|
||||||
if other_repo == repo:
|
|
||||||
continue
|
|
||||||
if other_repo.directory == repo.directory:
|
|
||||||
row = col.row()
|
|
||||||
row.alert = True
|
|
||||||
row.label(
|
|
||||||
text="A repository at this filepath is already specified.", icon='ERROR')
|
|
||||||
break
|
|
||||||
|
|
||||||
col.prop(repo, 'display_name', text="Folder Name", icon='NEWFOLDER')
|
|
||||||
col.prop(repo, 'url', icon='URL')
|
|
||||||
for other_repo in prefs.repositories:
|
|
||||||
if other_repo == repo:
|
|
||||||
continue
|
|
||||||
if other_repo.url == repo.url:
|
|
||||||
sub = col.column()
|
|
||||||
sub.alert = True
|
|
||||||
sub.label(text="A repository with this URL is already specified.")
|
|
||||||
sub.label(
|
|
||||||
text="If you're sure you want to checkout another copy of the repo, feel free to proceed.")
|
|
||||||
break
|
|
||||||
col.prop(repo, 'username', icon='USER')
|
|
||||||
col.prop(repo, 'password', icon='LOCKED')
|
|
||||||
|
|
||||||
op_row = layout.row()
|
|
||||||
op_row.operator('svn.checkout_finalize', text="Checkout", icon='CHECKMARK')
|
|
||||||
op_row.operator('svn.checkout_cancel', text="Cancel", icon="X")
|
|
||||||
|
|
||||||
|
|
||||||
def draw_prefs_repos(self, context) -> None:
|
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
auth_in_progress = False
|
auth_in_progress = False
|
||||||
@ -228,7 +140,7 @@ def draw_prefs_repos(self, context) -> None:
|
|||||||
|
|
||||||
if len(self.repositories) == 0:
|
if len(self.repositories) == 0:
|
||||||
return
|
return
|
||||||
if self.active_repo_idx-1 > len(self.repositories):
|
if self.active_repo_idx - 1 > len(self.repositories):
|
||||||
return
|
return
|
||||||
if not self.active_repo:
|
if not self.active_repo:
|
||||||
return
|
return
|
||||||
@ -247,12 +159,12 @@ def draw_prefs_repos(self, context) -> None:
|
|||||||
draw_repo_error(layout, "Directory is not an SVN repository.")
|
draw_repo_error(layout, "Directory is not an SVN repository.")
|
||||||
split = layout.split(factor=0.24)
|
split = layout.split(factor=0.24)
|
||||||
split.row()
|
split.row()
|
||||||
split.row().operator("svn.checkout_initiate",
|
split.row().operator(
|
||||||
text="Create New Checkout", icon='URL').create = False
|
"svn.checkout_initiate", text="Create New Checkout", icon='URL'
|
||||||
|
).create = False
|
||||||
return
|
return
|
||||||
if not self.active_repo.authenticated and not auth_in_progress and not auth_error:
|
if not self.active_repo.authenticated and not auth_in_progress and not auth_error:
|
||||||
draw_repo_error(
|
draw_repo_error(layout, "Repository not authenticated. Enter your credentials.")
|
||||||
layout, "Repository not authenticated. Enter your credentials.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(self.repositories) > 0 and self.active_repo.authenticated:
|
if len(self.repositories) > 0 and self.active_repo.authenticated:
|
||||||
@ -274,9 +186,80 @@ def draw_repo_error(layout, message):
|
|||||||
col.label(text=message, icon='ERROR')
|
col.label(text=message, icon='ERROR')
|
||||||
|
|
||||||
|
|
||||||
registry = [
|
def draw_checkout(self, context):
|
||||||
SVN_UL_repositories,
|
def get_terminal_howto():
|
||||||
SVN_OT_repo_add,
|
msg_windows = "If you don't, cancel this operation and toggle it using Window->Toggle System Console."
|
||||||
SVN_OT_repo_remove,
|
msg_linux = "If you don't, quit Blender and re-launch it from a terminal."
|
||||||
SVN_MT_add_repo
|
msg_mac = msg_linux
|
||||||
]
|
|
||||||
|
system = platform.system()
|
||||||
|
if system == "Windows":
|
||||||
|
return msg_windows
|
||||||
|
elif system == "Linux":
|
||||||
|
return msg_linux
|
||||||
|
elif system == "Darwin":
|
||||||
|
return msg_mac
|
||||||
|
|
||||||
|
layout = self.layout
|
||||||
|
col = layout.column()
|
||||||
|
col.alert = True
|
||||||
|
|
||||||
|
col.label(text="IMPORTANT! ", icon='ERROR')
|
||||||
|
col.label(text="Make sure you have Blender's terminal open!")
|
||||||
|
col.label(text=get_terminal_howto())
|
||||||
|
col.separator()
|
||||||
|
col.label(
|
||||||
|
text="Downloading a repository can take a long time, and the UI will be locked."
|
||||||
|
)
|
||||||
|
col.label(
|
||||||
|
text="Without a terminal, you won't be able to track the progress of the checkout."
|
||||||
|
)
|
||||||
|
col.separator()
|
||||||
|
|
||||||
|
col = layout.column()
|
||||||
|
col.label(
|
||||||
|
text="To interrupt the checkout, you can press Ctrl+C in the terminal.",
|
||||||
|
icon='INFO',
|
||||||
|
)
|
||||||
|
col.label(
|
||||||
|
text="You can resume it by re-running this operation, or with the SVN Update button.",
|
||||||
|
icon='INFO',
|
||||||
|
)
|
||||||
|
col.separator()
|
||||||
|
|
||||||
|
prefs = get_addon_prefs(context)
|
||||||
|
repo = prefs.repositories[-1]
|
||||||
|
col.prop(repo, 'directory')
|
||||||
|
for other_repo in prefs.repositories:
|
||||||
|
if other_repo == repo:
|
||||||
|
continue
|
||||||
|
if other_repo.directory == repo.directory:
|
||||||
|
row = col.row()
|
||||||
|
row.alert = True
|
||||||
|
row.label(
|
||||||
|
text="A repository at this filepath is already specified.", icon='ERROR'
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
|
col.prop(repo, 'display_name', text="Folder Name", icon='NEWFOLDER')
|
||||||
|
col.prop(repo, 'url', icon='URL')
|
||||||
|
for other_repo in prefs.repositories:
|
||||||
|
if other_repo == repo:
|
||||||
|
continue
|
||||||
|
if other_repo.url == repo.url:
|
||||||
|
sub = col.column()
|
||||||
|
sub.alert = True
|
||||||
|
sub.label(text="A repository with this URL is already specified.")
|
||||||
|
sub.label(
|
||||||
|
text="If you're sure you want to checkout another copy of the repo, feel free to proceed."
|
||||||
|
)
|
||||||
|
break
|
||||||
|
col.prop(repo, 'username', icon='USER')
|
||||||
|
col.prop(repo, 'password', icon='LOCKED')
|
||||||
|
|
||||||
|
op_row = layout.row()
|
||||||
|
op_row.operator('svn.checkout_finalize', text="Checkout", icon='CHECKMARK')
|
||||||
|
op_row.operator('svn.checkout_cancel', text="Cancel", icon="X")
|
||||||
|
|
||||||
|
|
||||||
|
registry = [SVN_UL_repositories, SVN_OT_repo_add, SVN_OT_repo_remove, SVN_MT_add_repo]
|
Loading…
Reference in New Issue
Block a user