SVN: UX improvements #136
@ -62,6 +62,12 @@ class SVN_addon_preferences(AddonPreferences):
|
|||||||
|
|
||||||
return repo
|
return repo
|
||||||
|
|
||||||
|
checkout_mode: BoolProperty(
|
||||||
|
name="Checkout In Progress",
|
||||||
|
description="Internal flag to indicate that the user is currently trying to create a new checkout",
|
||||||
|
default=False
|
||||||
|
)
|
||||||
|
|
||||||
def update_active_repo_idx(self, context):
|
def update_active_repo_idx(self, context):
|
||||||
if len(self.repositories) == 0:
|
if len(self.repositories) == 0:
|
||||||
return
|
return
|
||||||
@ -81,13 +87,6 @@ class SVN_addon_preferences(AddonPreferences):
|
|||||||
else:
|
else:
|
||||||
Processes.kill('Status')
|
Processes.kill('Status')
|
||||||
|
|
||||||
|
|
||||||
checkout_mode: BoolProperty(
|
|
||||||
name="Checkout In Progress",
|
|
||||||
description="Internal flag to indicate that the user is currently trying to create a new checkout",
|
|
||||||
default=False
|
|
||||||
)
|
|
||||||
|
|
||||||
active_repo_idx: IntProperty(
|
active_repo_idx: IntProperty(
|
||||||
name="SVN Repositories",
|
name="SVN Repositories",
|
||||||
options=set(),
|
options=set(),
|
||||||
|
@ -72,18 +72,6 @@ class SVN_file(PropertyGroup):
|
|||||||
options=set()
|
options=set()
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def absolute_path(self) -> Path:
|
|
||||||
"""Return absolute path on the file system."""
|
|
||||||
scene = self.id_data
|
|
||||||
svn = scene.svn
|
|
||||||
return Path(svn.svn_directory).joinpath(Path(self.svn_path))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def relative_path(self) -> str:
|
|
||||||
"""Return relative path with Blender's path conventions."""
|
|
||||||
return bpy.path.relpath(self.absolute_path)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_outdated(self):
|
def is_outdated(self):
|
||||||
return self.repos_status == 'modified' and self.status == 'normal'
|
return self.repos_status == 'modified' and self.status == 'normal'
|
||||||
@ -347,10 +335,6 @@ class SVN_repository(PropertyGroup):
|
|||||||
name="SVN Log",
|
name="SVN Log",
|
||||||
options=set()
|
options=set()
|
||||||
)
|
)
|
||||||
log_active_index_filebrowser: IntProperty(
|
|
||||||
name="SVN Log",
|
|
||||||
options=set()
|
|
||||||
)
|
|
||||||
|
|
||||||
reload_svn_log = svn_log.reload_svn_log
|
reload_svn_log = svn_log.reload_svn_log
|
||||||
|
|
||||||
@ -365,13 +349,6 @@ class SVN_repository(PropertyGroup):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
|
||||||
def active_log_filebrowser(self):
|
|
||||||
try:
|
|
||||||
return self.log[self.log_active_index_filebrowser]
|
|
||||||
except IndexError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_log_by_revision(self, revision: int) -> Tuple[int, SVN_log]:
|
def get_log_by_revision(self, revision: int) -> Tuple[int, SVN_log]:
|
||||||
for i, log in enumerate(self.log):
|
for i, log in enumerate(self.log):
|
||||||
if log.revision_number == revision:
|
if log.revision_number == revision:
|
||||||
@ -457,16 +434,15 @@ class SVN_repository(PropertyGroup):
|
|||||||
|
|
||||||
space = context.space_data
|
space = context.space_data
|
||||||
if space and space.type == 'FILE_BROWSER':
|
if space and space.type == 'FILE_BROWSER':
|
||||||
# Set the active file in the file browser to whatever was selected in the SVN Files panel.
|
space.params.directory = Path(self.active_file.absolute_path).parent.as_posix().encode()
|
||||||
self.log_active_index_filebrowser = latest_rev-1
|
|
||||||
|
|
||||||
space.params.directory = self.active_file.absolute_path.parent.as_posix().encode()
|
|
||||||
space.params.filename = self.active_file.name.encode()
|
space.params.filename = self.active_file.name.encode()
|
||||||
|
|
||||||
space.deselect_all()
|
space.deselect_all()
|
||||||
space.activate_file_by_relative_path(
|
# Set the active file in the file browser to whatever was selected
|
||||||
|
# in the SVN Files panel.
|
||||||
|
space.activate_file_by_relative_path( # This doesn't actually work, due to what I assume is a bug.
|
||||||
relative_path=self.active_file.name)
|
relative_path=self.active_file.name)
|
||||||
Processes.start('Activate File')
|
Processes.start('Activate File') # This is my work-around.
|
||||||
|
|
||||||
# Set the filter flag of the log entries based on whether they affect the active file or not.
|
# Set the filter flag of the log entries based on whether they affect the active file or not.
|
||||||
self.log.foreach_set(
|
self.log.foreach_set(
|
||||||
|
@ -46,12 +46,11 @@ def svn_log_list_context_menu(self: UIList, context: Context) -> None:
|
|||||||
if not check_context_match(context, 'ui_list', 'SVN_UL_log'):
|
if not check_context_match(context, 'ui_list', 'SVN_UL_log'):
|
||||||
return
|
return
|
||||||
|
|
||||||
is_filebrowser = context.space_data.type == 'FILE_BROWSER'
|
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
repo = context.scene.svn.get_repo(context)
|
repo = context.scene.svn.get_repo(context)
|
||||||
active_log = repo.active_log_filebrowser if is_filebrowser else repo.active_log
|
active_log = repo.active_log
|
||||||
layout.operator("svn.update_all",
|
layout.operator("svn.update_all",
|
||||||
text=f"Revert Repository To r{active_log.revision_number}").revision = active_log.revision_number
|
text=f"Revert Repository To r{active_log.revision_number}").revision = active_log.revision_number
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
@ -186,10 +186,18 @@ def draw_process_info(context, layout):
|
|||||||
", ".join([p.name for p in Processes.running_processes]))
|
", ".join([p.name for p in Processes.running_processes]))
|
||||||
|
|
||||||
|
|
||||||
def draw_repo_file_list(context, layout, repo):
|
def draw_file_list(context, layout):
|
||||||
|
prefs = get_addon_prefs(context)
|
||||||
|
repo = prefs.active_repo
|
||||||
if not repo:
|
if not repo:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not repo.authenticated:
|
||||||
|
row = layout.row()
|
||||||
|
row.alert=True
|
||||||
|
row.label(text="Repository is not authenticated.", icon='ERROR')
|
||||||
|
return
|
||||||
|
|
||||||
main_col = layout.column()
|
main_col = layout.column()
|
||||||
main_row = main_col.row()
|
main_row = main_col.row()
|
||||||
split = main_row.split(factor=0.6)
|
split = main_row.split(factor=0.6)
|
||||||
|
@ -4,11 +4,10 @@
|
|||||||
from bpy.types import Panel
|
from bpy.types import Panel
|
||||||
from bl_ui.space_filebrowser import FileBrowserPanel
|
from bl_ui.space_filebrowser import FileBrowserPanel
|
||||||
|
|
||||||
from .ui_log import draw_svn_log
|
from .ui_log import draw_svn_log, is_log_useful
|
||||||
from .ui_file_list import draw_repo_file_list
|
from .ui_file_list import draw_file_list
|
||||||
from ..util import get_addon_prefs
|
from ..util import get_addon_prefs
|
||||||
|
|
||||||
|
|
||||||
class FILEBROWSER_PT_SVN_files(FileBrowserPanel, Panel):
|
class FILEBROWSER_PT_SVN_files(FileBrowserPanel, Panel):
|
||||||
bl_space_type = 'FILE_BROWSER'
|
bl_space_type = 'FILE_BROWSER'
|
||||||
bl_region_type = 'TOOLS'
|
bl_region_type = 'TOOLS'
|
||||||
@ -20,47 +19,37 @@ class FILEBROWSER_PT_SVN_files(FileBrowserPanel, Panel):
|
|||||||
if not super().poll(context):
|
if not super().poll(context):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
repo = context.scene.svn.get_repo(context)
|
prefs = get_addon_prefs(context)
|
||||||
if not repo:
|
return prefs.active_repo and prefs.active_repo.authenticated
|
||||||
return False
|
|
||||||
|
|
||||||
return repo.is_filebrowser_directory_in_repo(context)
|
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
layout.use_property_decorate = False
|
layout.use_property_decorate = False
|
||||||
|
|
||||||
# TODO: Get repository of the current file browser's directory.
|
draw_file_list(context, layout)
|
||||||
prefs = get_addon_prefs(context)
|
|
||||||
if len(prefs.repositories) > 0:
|
|
||||||
repo = prefs.active_repo
|
|
||||||
draw_repo_file_list(context, layout, repo)
|
|
||||||
|
|
||||||
|
|
||||||
class FILEBROWSER_PT_SVN_log(FileBrowserPanel, Panel):
|
class FILEBROWSER_PT_SVN_log(FileBrowserPanel, Panel):
|
||||||
bl_space_type = 'FILE_BROWSER'
|
bl_space_type = 'FILE_BROWSER'
|
||||||
bl_region_type = 'TOOLS'
|
bl_region_type = 'TOOLS'
|
||||||
bl_category = "Bookmarks"
|
bl_category = "Bookmarks"
|
||||||
bl_label = "SVN Log"
|
bl_parent_id = "FILEBROWSER_PT_SVN_files"
|
||||||
|
bl_label = "Revision History"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
if not super().poll(context):
|
if not super().poll(context):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
repo = context.scene.svn.get_repo(context)
|
return is_log_useful(context)
|
||||||
if not repo:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return repo.get_filebrowser_active_file(context)
|
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
layout.use_property_decorate = False
|
layout.use_property_decorate = False
|
||||||
|
|
||||||
draw_svn_log(context, layout, file_browser=True)
|
draw_svn_log(context, layout)
|
||||||
|
|
||||||
|
|
||||||
registry = [
|
registry = [
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
from bpy.props import IntProperty, BoolProperty
|
from bpy.props import IntProperty, BoolProperty
|
||||||
from bpy.types import UIList, Panel, Operator
|
from bpy.types import UIList, Panel, Operator
|
||||||
|
from ..util import get_addon_prefs
|
||||||
|
|
||||||
|
|
||||||
class SVN_UL_log(UIList):
|
class SVN_UL_log(UIList):
|
||||||
@ -21,9 +22,7 @@ class SVN_UL_log(UIList):
|
|||||||
|
|
||||||
num, auth, date, msg = layout_log_split(layout.row())
|
num, auth, date, msg = layout_log_split(layout.row())
|
||||||
|
|
||||||
is_filebrowser = context.space_data.type == 'FILE_BROWSER'
|
active_file = svn.active_file
|
||||||
active_file = svn.get_filebrowser_active_file(
|
|
||||||
context) if is_filebrowser else svn.active_file
|
|
||||||
num.label(text=str(log_entry.revision_number))
|
num.label(text=str(log_entry.revision_number))
|
||||||
if item.revision_number == active_file.revision:
|
if item.revision_number == active_file.revision:
|
||||||
num.operator('svn.tooltip_log', text="", icon='LAYER_ACTIVE',
|
num.operator('svn.tooltip_log', text="", icon='LAYER_ACTIVE',
|
||||||
@ -88,9 +87,13 @@ class SVN_UL_log(UIList):
|
|||||||
toggle=True, icon='ALIGN_JUSTIFY')
|
toggle=True, icon='ALIGN_JUSTIFY')
|
||||||
|
|
||||||
|
|
||||||
def is_log_useful(context):
|
def is_log_useful(context) -> bool:
|
||||||
repo = context.scene.svn.get_repo(context)
|
"""Return whether the log has any useful info to display."""
|
||||||
if not repo:
|
|
||||||
|
prefs = get_addon_prefs(context)
|
||||||
|
repo = prefs.active_repo
|
||||||
|
|
||||||
|
if not repo or not repo.authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if len(repo.log) == 0 or len(repo.external_files) == 0:
|
if len(repo.log) == 0 or len(repo.external_files) == 0:
|
||||||
@ -124,7 +127,7 @@ class VIEW3D_PT_svn_log(Panel):
|
|||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
layout.use_property_decorate = False
|
layout.use_property_decorate = False
|
||||||
|
|
||||||
draw_svn_log(context, layout, file_browser=False)
|
draw_svn_log(context, layout)
|
||||||
|
|
||||||
|
|
||||||
def layout_log_split(layout):
|
def layout_log_split(layout):
|
||||||
@ -143,23 +146,25 @@ def layout_log_split(layout):
|
|||||||
return num, auth, date, msg
|
return num, auth, date, msg
|
||||||
|
|
||||||
|
|
||||||
def draw_svn_log(context, layout, file_browser: bool):
|
def draw_svn_log(context, layout):
|
||||||
num, auth, date, msg = layout_log_split(layout.row())
|
num, auth, date, msg = layout_log_split(layout.row())
|
||||||
num.label(text="Rev. #")
|
num.label(text="Rev. #")
|
||||||
auth.label(text="Author")
|
auth.label(text="Author")
|
||||||
date.label(text="Date")
|
date.label(text="Date")
|
||||||
msg.label(text="Message")
|
msg.label(text="Message")
|
||||||
repo = context.scene.svn.get_repo(context)
|
|
||||||
|
prefs = get_addon_prefs(context)
|
||||||
|
repo = prefs.active_repo
|
||||||
layout.template_list(
|
layout.template_list(
|
||||||
"SVN_UL_log",
|
"SVN_UL_log",
|
||||||
"svn_log",
|
"svn_log",
|
||||||
repo,
|
repo,
|
||||||
"log",
|
"log",
|
||||||
repo,
|
repo,
|
||||||
"log_active_index_filebrowser" if file_browser else "log_active_index",
|
"log_active_index",
|
||||||
)
|
)
|
||||||
|
|
||||||
active_log = repo.active_log_filebrowser if file_browser else repo.active_log
|
active_log = repo.active_log
|
||||||
if not active_log:
|
if not active_log:
|
||||||
return
|
return
|
||||||
layout.label(text="Revision Date: " + active_log.revision_date)
|
layout.label(text="Revision Date: " + active_log.revision_date)
|
||||||
|
@ -8,7 +8,7 @@ from bpy_extras.io_utils import ImportHelper
|
|||||||
|
|
||||||
from ..util import get_addon_prefs
|
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_file_list, draw_process_info
|
||||||
from ..threaded.background_process import Processes
|
from ..threaded.background_process import Processes
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -112,7 +112,7 @@ class SVN_MT_add_repo(Menu):
|
|||||||
).create = True
|
).create = True
|
||||||
|
|
||||||
|
|
||||||
def draw_repo_list(self, context, draw_files=True, draw_log=True) -> None:
|
def draw_repo_list(self, context) -> None:
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
auth_in_progress = False
|
auth_in_progress = False
|
||||||
@ -179,13 +179,13 @@ def draw_repo_list(self, context, draw_files=True, draw_log=True) -> None:
|
|||||||
|
|
||||||
if len(self.repositories) > 0 and self.active_repo.authenticated:
|
if len(self.repositories) > 0 and self.active_repo.authenticated:
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.label(text="Files: ")
|
layout.label(text="SVN Files: ")
|
||||||
draw_repo_file_list(context, layout, self.active_repo)
|
draw_file_list(context, layout)
|
||||||
|
|
||||||
if is_log_useful(context):
|
if is_log_useful(context):
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.label(text="Log: ")
|
layout.label(text="Revision History: ")
|
||||||
draw_svn_log(context, layout, file_browser=False)
|
draw_svn_log(context, layout)
|
||||||
|
|
||||||
|
|
||||||
def draw_repo_error(layout, message):
|
def draw_repo_error(layout, message):
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
from bpy.types import Panel
|
from bpy.types import Panel
|
||||||
|
|
||||||
from ..util import get_addon_prefs
|
from ..util import get_addon_prefs
|
||||||
from .ui_file_list import draw_repo_file_list, draw_process_info
|
from .ui_file_list import draw_file_list, draw_process_info
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_PT_svn_credentials(Panel):
|
class VIEW3D_PT_svn_credentials(Panel):
|
||||||
@ -53,9 +53,8 @@ class VIEW3D_PT_svn_files(Panel):
|
|||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
layout.use_property_decorate = False
|
layout.use_property_decorate = False
|
||||||
|
|
||||||
repo = context.scene.svn.get_repo(context)
|
|
||||||
draw_process_info(context, layout)
|
draw_process_info(context, layout)
|
||||||
draw_repo_file_list(context, layout, repo)
|
draw_file_list(context, layout)
|
||||||
|
|
||||||
|
|
||||||
registry = [
|
registry = [
|
||||||
|
Loading…
Reference in New Issue
Block a user