Commit 1c847220 authored by jang dong hyeok's avatar jang dong hyeok
Browse files

.

parent 076f0c68
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace Unity.PlasticSCM.Editor.UI
{
// Assumption: Members are called from an OnGUI method ( otherwise style composition will fail)
internal static class UnityStyles
{
internal static void Initialize(
Action repaintPlasticWindow)
{
mRepaintPlasticWindow = repaintPlasticWindow;
mLazyBackgroundStyles.Add(WarningMessage);
mLazyBackgroundStyles.Add(SplitterIndicator);
mLazyBackgroundStyles.Add(PlasticWindow.ActiveTabUnderline);
mLazyBackgroundStyles.Add(Notification.GreenNotification);
mLazyBackgroundStyles.Add(Notification.RedNotification);
mLazyBackgroundStyles.Add(CancelButton);
mLazyBackgroundStyles.Add(Inspector.HeaderBackgroundStyle);
mLazyBackgroundStyles.Add(Inspector.DisabledHeaderBackgroundStyle);
}
internal static class Colors
{
internal static Color Transparent = new Color(255f / 255, 255f / 255, 255f / 255, 0f / 255);
internal static Color GreenBackground = new Color(34f / 255, 161f / 255, 63f / 255);
internal static Color GreenText = new Color(0f / 255, 100f / 255, 0f / 255);
internal static Color Red = new Color(194f / 255, 51f / 255, 62f / 255);
internal static Color Warning = new Color(255f / 255, 255f / 255, 176f / 255);
internal static Color Splitter = new Color(100f / 255, 100f / 255, 100f / 255);
#if UNITY_2019
internal static Color InspectorHeaderBackground = (EditorGUIUtility.isProSkin) ?
new Color(60f / 255, 60f / 255, 60f / 255) :
new Color(203f / 255, 203f / 255, 203f / 255);
#else
internal static Color InspectorHeaderBackground = Transparent;
#endif
#if UNITY_2019_1_OR_NEWER
internal static Color InspectorHeaderBackgroundDisabled = (EditorGUIUtility.isProSkin) ?
new Color(58f / 255, 58f / 255, 58f / 255) :
new Color(199f / 255, 199f / 255, 199f / 255);
#else
internal static Color InspectorHeaderBackgroundDisabled = (EditorGUIUtility.isProSkin) ?
new Color(60f / 255, 60f / 255, 60f / 255) :
new Color(210f / 255, 210f / 255, 210f / 255);
#endif
internal static Color TabUnderline = new Color(0.128f, 0.456f, 0.776f);
internal static Color Link = new Color(0f, 120f / 255, 218f / 255);
internal static Color SecondaryLabel = (EditorGUIUtility.isProSkin) ?
new Color(135f / 255, 135f / 255, 135f / 255) :
new Color(105f / 255, 105f / 255, 105f / 255);
}
internal static class HexColors
{
internal const string LINK_COLOR = "#0078DA";
}
internal static class Dialog
{
internal static readonly LazyStyle MessageTitle = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.boldLabel);
style.contentOffset = new Vector2(0, -5);
style.wordWrap = true;
style.fontSize = MODAL_FONT_SIZE + 1;
return style;
});
internal static readonly LazyStyle MessageText = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.wordWrap = true;
style.fontSize = MODAL_FONT_SIZE;
return style;
});
internal static readonly LazyStyle Toggle = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.boldLabel);
style.fontSize = MODAL_FONT_SIZE;
style.clipping = TextClipping.Overflow;
return style;
});
internal static readonly LazyStyle RadioToggle = new LazyStyle(() =>
{
var radioToggleStyle = new GUIStyle(EditorStyles.radioButton);
radioToggleStyle.fontSize = MODAL_FONT_SIZE;
radioToggleStyle.clipping = TextClipping.Overflow;
radioToggleStyle.font = EditorStyles.largeLabel.font;
return radioToggleStyle;
});
internal static readonly LazyStyle Foldout = new LazyStyle(() =>
{
GUIStyle paragraphStyle = Paragraph;
var foldoutStyle = new GUIStyle(EditorStyles.foldout);
foldoutStyle.fontSize = MODAL_FONT_SIZE;
foldoutStyle.font = paragraphStyle.font;
return foldoutStyle;
});
internal static readonly LazyStyle EntryLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.textField);
style.wordWrap = true;
style.fontSize = MODAL_FONT_SIZE;
return style;
});
internal static readonly LazyStyle AcceptButtonText = new LazyStyle(() =>
{
var style = new GUIStyle(GetEditorSkin().GetStyle("WhiteLabel"));
style.alignment = TextAnchor.MiddleCenter;
style.fontSize = MODAL_FONT_SIZE + 1;
style.normal.background = null;
return style;
});
internal static readonly LazyStyle NormalButton = new LazyStyle(() =>
{
var style = new GUIStyle(GetEditorSkin().button);
style.alignment = TextAnchor.MiddleCenter;
style.fontSize = MODAL_FONT_SIZE;
return style;
});
}
internal static class Tree
{
internal static readonly LazyStyle IconStyle = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.largeLabel);
style.alignment = TextAnchor.MiddleLeft;
return style;
});
internal static readonly LazyStyle Label = new LazyStyle(() =>
{
var style = new GUIStyle(TreeView.DefaultStyles.label);
style.fontSize = 11;
style.alignment = TextAnchor.MiddleLeft;
return style;
});
internal static readonly LazyStyle SecondaryLabel = new LazyStyle(() =>
{
var style = new GUIStyle(TreeView.DefaultStyles.label);
style.fontSize = 11;
style.alignment = TextAnchor.MiddleLeft;
style.active = new GUIStyleState() { textColor = Colors.SecondaryLabel };
style.focused = new GUIStyleState() { textColor = Colors.SecondaryLabel };
style.hover = new GUIStyleState() { textColor = Colors.SecondaryLabel };
style.normal = new GUIStyleState() { textColor = Colors.SecondaryLabel };
return style;
});
internal static readonly LazyStyle SecondaryBoldLabel = new LazyStyle(() =>
{
var style = new GUIStyle(SecondaryLabel);
style.fontStyle = FontStyle.Bold;
return style;
});
internal static readonly LazyStyle RedLabel = new LazyStyle(() =>
{
var style = new GUIStyle(Label);
style.active = new GUIStyleState() { textColor = Colors.Red };
style.focused = new GUIStyleState() { textColor = Colors.Red };
style.hover = new GUIStyleState() { textColor = Colors.Red };
style.normal = new GUIStyleState() { textColor = Colors.Red };
return style;
});
internal static readonly LazyStyle GreenLabel = new LazyStyle(() =>
{
var style = new GUIStyle(Label);
style.active = new GUIStyleState() { textColor = Colors.GreenText };
style.focused = new GUIStyleState() { textColor = Colors.GreenText };
style.hover = new GUIStyleState() { textColor = Colors.GreenText };
style.normal = new GUIStyleState() { textColor = Colors.GreenText };
return style;
});
internal static readonly LazyStyle BoldLabel = new LazyStyle(() =>
{
var style = new GUIStyle(TreeView.DefaultStyles.boldLabel);
style.fontSize = 11;
style.alignment = TextAnchor.MiddleLeft;
return style;
});
internal static readonly LazyStyle LabelRightAligned = new LazyStyle(() =>
{
var style = new GUIStyle(TreeView.DefaultStyles.label);
style.fontSize = 11;
style.alignment = TextAnchor.MiddleRight;
return style;
});
internal static readonly LazyStyle SecondaryLabelRightAligned = new LazyStyle(() =>
{
var style = new GUIStyle(SecondaryLabel);
style.alignment = TextAnchor.MiddleRight;
return style;
});
internal static readonly LazyStyle SecondaryLabelBoldRightAligned = new LazyStyle(() =>
{
var style = new GUIStyle(SecondaryLabelRightAligned);
style.fontStyle = FontStyle.Bold;
return style;
});
}
public static class Inspector
{
public static readonly LazyStyle HeaderBackgroundStyle = new LazyStyle(() =>
{
return CreateUnderlineStyle(
Colors.InspectorHeaderBackground,
UnityConstants.INSPECTOR_ACTIONS_HEADER_BACK_RECTANGLE_HEIGHT);
});
public static readonly LazyStyle DisabledHeaderBackgroundStyle = new LazyStyle(() =>
{
return CreateUnderlineStyle(
Colors.InspectorHeaderBackgroundDisabled,
UnityConstants.INSPECTOR_ACTIONS_HEADER_BACK_RECTANGLE_HEIGHT);
});
}
internal static class PlasticWindow
{
internal static readonly LazyStyle HeaderTitleLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
return style;
});
internal static readonly LazyStyle ActiveTabButton = new LazyStyle(() =>
{
GUIStyle result = new GUIStyle(EditorStyles.toolbarButton);
result.fontStyle = FontStyle.Bold;
return result;
});
internal static readonly LazyStyle ActiveTabUnderline = new LazyStyle(() =>
{
return CreateUnderlineStyle(
Colors.TabUnderline,
UnityConstants.ACTIVE_TAB_UNDERLINE_HEIGHT);
});
}
internal static class DiffPanel
{
internal static readonly LazyStyle HeaderLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
style.fontStyle = FontStyle.Bold;
#if UNITY_2019_1_OR_NEWER
style.contentOffset = new Vector2(0, 1.5f);
#endif
return style;
});
}
internal static class PendingChangesTab
{
internal static readonly LazyStyle CommentPlaceHolder = new LazyStyle(() =>
{
var style = new GUIStyle();
style.normal = new GUIStyleState() { textColor = Color.gray };
style.padding = new RectOffset(2, 0, 0, 0);
return style;
});
internal static readonly LazyStyle CommentTextArea = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.textArea);
style.margin = new RectOffset(6, 4, 0, 0);
return style;
});
internal static readonly LazyStyle CommentWarningIcon = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
#if !UNITY_2019_1_OR_NEWER
style.margin = new RectOffset(0, 0, 0, 0);
#endif
return style;
});
internal static readonly LazyStyle HeaderLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
style.fontStyle = FontStyle.Bold;
#if UNITY_2019_1_OR_NEWER
style.contentOffset = new Vector2(0, 1.5f);
#endif
return style;
});
}
internal static class IncomingChangesTab
{
internal static readonly LazyStyle PendingConflictsLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
style.fontStyle = FontStyle.Bold;
return style;
});
internal static readonly LazyStyle RedPendingConflictsOfTotalLabel = new LazyStyle(() =>
{
var style = new GUIStyle(PendingConflictsLabel);
style.normal = new GUIStyleState() { textColor = Colors.Red };
return style;
});
internal static readonly LazyStyle GreenPendingConflictsOfTotalLabel = new LazyStyle(() =>
{
var style = new GUIStyle(PendingConflictsLabel);
style.normal = new GUIStyleState() { textColor = Colors.GreenText };
return style;
});
internal static readonly LazyStyle ChangesToApplySummaryLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
return style;
});
internal readonly static LazyStyle HeaderWarningLabel
= new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
#if !UNITY_2019_1_OR_NEWER
style.margin = new RectOffset(0, 0, 0, 0);
#endif
return style;
});
}
internal static class ChangesetsTab
{
internal static readonly LazyStyle HeaderLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
style.fontStyle = FontStyle.Bold;
#if UNITY_2019_1_OR_NEWER
style.contentOffset = new Vector2(0, 1.5f);
#endif
return style;
});
}
internal static class HistoryTab
{
internal static readonly LazyStyle HeaderLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
style.fontStyle = FontStyle.Bold;
#if UNITY_2019_1_OR_NEWER
style.contentOffset = new Vector2(0, 1.5f);
#endif
return style;
});
}
internal static class DirectoryConflictResolution
{
internal readonly static LazyStyle WarningLabel
= new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.alignment = TextAnchor.MiddleLeft;
#if !UNITY_2019_1_OR_NEWER
style.margin = new RectOffset(0, 0, 0, 0);
#endif
return style;
});
}
internal static class Notification
{
internal static readonly LazyStyle Label = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
#if !UNITY_2019_1_OR_NEWER
style.fontSize = 10;
#endif
style.normal = new GUIStyleState() { textColor = Color.white };
return style;
});
internal static readonly LazyStyle GreenNotification = new LazyStyle(() =>
{
var style = new GUIStyle();
style.wordWrap = true;
style.margin = new RectOffset();
style.padding = new RectOffset(4, 4, 2, 2);
style.stretchWidth = true;
style.stretchHeight = true;
style.alignment = TextAnchor.UpperLeft;
var bg = new Texture2D(1, 1);
bg.SetPixel(0, 0, Colors.GreenBackground);
bg.Apply();
style.normal.background = bg;
return style;
});
internal static readonly LazyStyle RedNotification = new LazyStyle(() =>
{
var style = new GUIStyle();
style.wordWrap = true;
style.margin = new RectOffset();
style.padding = new RectOffset(4, 4, 2, 2);
style.stretchWidth = true;
style.stretchHeight = true;
style.alignment = TextAnchor.UpperLeft;
var bg = new Texture2D(1, 1);
bg.SetPixel(0, 0, Colors.Red);
bg.Apply();
style.normal.background = bg;
return style;
});
}
internal static class DirectoryConflicts
{
internal readonly static LazyStyle TitleLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.largeLabel);
RectOffset margin = new RectOffset(
style.margin.left,
style.margin.right,
style.margin.top - 1,
style.margin.bottom);
style.margin = margin;
style.fontStyle = FontStyle.Bold;
return style;
});
internal readonly static LazyStyle BoldLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontStyle = FontStyle.Bold;
return style;
});
internal readonly static LazyStyle FileNameTextField = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.textField);
RectOffset margin = new RectOffset(
style.margin.left,
style.margin.right,
style.margin.top + 2,
style.margin.bottom);
style.margin = margin;
return style;
});
}
internal static readonly LazyStyle SplitterIndicator = new LazyStyle(() =>
{
return CreateUnderlineStyle(
Colors.Splitter,
UnityConstants.SPLITTER_INDICATOR_HEIGHT);
});
internal static readonly LazyStyle HelpBoxLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
style.wordWrap = true;
return style;
});
internal static readonly LazyStyle ProgressLabel = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.label);
style.fontSize = 10;
#if !UNITY_2019_1_OR_NEWER
style.margin = new RectOffset(0, 0, 0, 0);
#endif
return style;
});
internal static readonly LazyStyle TextFieldWithWrapping = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.textField);
style.wordWrap = true;
return style;
});
internal static readonly LazyStyle Search = new LazyStyle(() =>
{
var style = new GUIStyle();
style.normal = new GUIStyleState() { textColor = Color.gray };
style.padding = new RectOffset(18, 0, 0, 0);
return style;
});
internal static readonly LazyStyle WarningMessage = new LazyStyle(() =>
{
var style = new GUIStyle(GetEditorSkin().box);
style.wordWrap = true;
style.margin = new RectOffset();
style.padding = new RectOffset(8, 8, 6, 6);
style.stretchWidth = true;
style.alignment = TextAnchor.UpperLeft;
var bg = new Texture2D(1, 1);
bg.SetPixel(0, 0, Colors.Warning);
bg.Apply();
style.normal.background = bg;
return style;
});
internal static readonly LazyStyle CancelButton = new LazyStyle(() =>
{
var normalIcon = Images.GetImage(Images.Name.IconCloseButton);
var pressedIcon = Images.GetImage(Images.Name.IconPressedCloseButton);
var style = new GUIStyle();
style.normal = new GUIStyleState() { background = normalIcon };
style.onActive = new GUIStyleState() { background = pressedIcon };
style.active = new GUIStyleState() { background = pressedIcon };
return style;
});
internal static readonly LazyStyle MiniToggle = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.boldLabel);
style.fontSize = MODAL_FONT_SIZE - 1;
style.clipping = TextClipping.Overflow;
return style;
});
internal static readonly LazyStyle Paragraph = new LazyStyle(() =>
{
var style = new GUIStyle(EditorStyles.largeLabel);
style.wordWrap = true;
style.richText = true;
style.fontSize = MODAL_FONT_SIZE;
return style;
});
static GUISkin GetEditorSkin()
{
GUISkin editorSkin = null;
if (EditorGUIUtility.isProSkin)
editorSkin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Scene);
else
editorSkin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector);
return editorSkin;
}
static GUIStyle CreateUnderlineStyle(Color color, int height)
{
GUIStyle style = new GUIStyle();
Texture2D pixel = new Texture2D(1, height);
for (int i = 0; i < height; i++)
pixel.SetPixel(0, i, color);
pixel.wrapMode = TextureWrapMode.Repeat;
pixel.Apply();
style.normal.background = pixel;
style.fixedHeight = height;
return style;
}
static void EnsureBackgroundStyles(LazyStyle lazy)
{
// The editor cleans the GUIStyleState.background property
// when entering the edit mode (exiting the play mode)
// and also in other situations (e.g when you use Zoom app)
// Because of this, we have to reset them in order to
// re-instantiate them the next time they're used
if (!mLazyBackgroundStyles.Contains(lazy))
return;
bool needsRepaint = false;
foreach (LazyStyle style in mLazyBackgroundStyles)
{
if (!style.IsInitialized)
continue;
if (style.Value.normal.background != null)
continue;
style.Reset();
needsRepaint = true;
}
if (!needsRepaint)
return;
if (mRepaintPlasticWindow != null)
mRepaintPlasticWindow();
}
static List<LazyStyle> mLazyBackgroundStyles = new List<LazyStyle>();
internal class LazyStyle
{
internal bool IsInitialized { get; private set; }
internal LazyStyle(Func<GUIStyle> builder)
{
mBuilder = builder;
IsInitialized = false;
}
internal GUIStyle Value { get; private set; }
internal void Reset()
{
IsInitialized = false;
}
public static implicit operator GUIStyle(LazyStyle lazy)
{
if (lazy.IsInitialized)
{
EnsureBackgroundStyles(lazy);
return lazy.Value;
}
lazy.Value = lazy.mBuilder();
lazy.IsInitialized = true;
return lazy.Value;
}
readonly Func<GUIStyle> mBuilder;
}
static Action mRepaintPlasticWindow;
const int MODAL_FONT_SIZE = 13;
}
}
using System;
using Codice.Client.Common.Threading;
namespace Unity.PlasticSCM.Editor.UI
{
internal class UnityThreadWaiterBuilder : IThreadWaiterBuilder
{
IThreadWaiter IThreadWaiterBuilder.GetWaiter()
{
return new UnityThreadWaiter(mPlasticTimerBuilder, false);
}
IThreadWaiter IThreadWaiterBuilder.GetWaiter(int timerIntervalMilliseconds)
{
return new UnityThreadWaiter(mPlasticTimerBuilder, false, timerIntervalMilliseconds);
}
IThreadWaiter IThreadWaiterBuilder.GetModalWaiter()
{
return new UnityThreadWaiter(mPlasticTimerBuilder, true);
}
IThreadWaiter IThreadWaiterBuilder.GetModalWaiter(int timerIntervalMilliseconds)
{
return new UnityThreadWaiter(mPlasticTimerBuilder, true, timerIntervalMilliseconds);
}
IPlasticTimer IThreadWaiterBuilder.GetTimer(
int timerIntervalMilliseconds, ThreadWaiter.TimerTick timerTickDelegate)
{
return mPlasticTimerBuilder.Get(false, timerIntervalMilliseconds, timerTickDelegate);
}
static IPlasticTimerBuilder mPlasticTimerBuilder = new UnityPlasticTimerBuilder();
}
internal class UnityThreadWaiter : IThreadWaiter
{
Exception IThreadWaiter.Exception { get { return mThreadOperation.Exception; } }
internal UnityThreadWaiter(
IPlasticTimerBuilder timerBuilder, bool bModalMode)
{
mPlasticTimer = timerBuilder.Get(bModalMode, OnTimerTick);
}
internal UnityThreadWaiter(
IPlasticTimerBuilder timerBuilder,
bool bModalMode,
int timerIntervalMilliseconds)
{
mPlasticTimer = timerBuilder.Get(bModalMode, timerIntervalMilliseconds, OnTimerTick);
}
void IThreadWaiter.Execute(
PlasticThread.Operation threadOperationDelegate,
PlasticThread.Operation afterOperationDelegate)
{
((IThreadWaiter)(this)).Execute(threadOperationDelegate, afterOperationDelegate, null);
}
void IThreadWaiter.Execute(
PlasticThread.Operation threadOperationDelegate,
PlasticThread.Operation afterOperationDelegate,
PlasticThread.Operation timerTickDelegate)
{
mThreadOperation = new PlasticThread(threadOperationDelegate);
mAfterOperationDelegate = afterOperationDelegate;
mTimerTickDelegate = timerTickDelegate;
mPlasticTimer.Start();
mThreadOperation.Execute();
}
void IThreadWaiter.Cancel()
{
mbCancelled = true;
}
void OnTimerTick()
{
if (mThreadOperation.IsRunning)
{
if (mTimerTickDelegate != null)
EditorDispatcher.Dispatch(() => mTimerTickDelegate());
return;
}
mPlasticTimer.Stop();
if (mbCancelled)
return;
EditorDispatcher.Dispatch(() => mAfterOperationDelegate());
}
bool mbCancelled = false;
IPlasticTimer mPlasticTimer;
PlasticThread mThreadOperation;
PlasticThread.Operation mTimerTickDelegate;
PlasticThread.Operation mAfterOperationDelegate;
}
}
{
"name": "Unity.PlasticSCM.Editor",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"Newtonsoft.Json.dll",
"unityplastic.dll"
],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
\ No newline at end of file
using System;
using System.IO;
using Codice.Client.Common;
using Codice.Utils;
using Unity.PlasticSCM.Editor.Tool;
namespace Unity.PlasticSCM.Editor
{
internal static class UnityConfigurationChecker
{
internal static bool NeedsConfiguration()
{
string plasticClientBinDir = PlasticInstallPath.GetClientBinDir();
if (string.IsNullOrEmpty(plasticClientBinDir))
return true;
SetupUnityEditionToken.FromPlasticInstallation(plasticClientBinDir);
return ConfigurationChecker.NeedConfiguration();
}
}
internal static class SetupUnityEditionToken
{
internal static void CreateCloudEditionTokenIfNeeded()
{
string toolPath = PlasticInstallPath.GetPlasticExePath();
if (!string.IsNullOrEmpty(toolPath))
return;
string tokenFilePath = UserConfigFolder.GetConfigFile(
EditionToken.CLOUD_EDITION_FILE_NAME);
File.Create(tokenFilePath).Dispose();
}
internal static void FromPlasticInstallation(string plasticClientBinDir)
{
bool isCloudPlasticInstall = IsPlasticInstallOfEdition(
plasticClientBinDir,
EditionToken.CLOUD_EDITION_FILE_NAME);
bool isDvcsPlasticInstall = IsPlasticInstallOfEdition(
plasticClientBinDir,
EditionToken.DVCS_EDITION_FILE_NAME);
SetupTokenFiles(
isCloudPlasticInstall,
isDvcsPlasticInstall);
}
static void SetupTokenFiles(
bool isCloudPlasticInstall,
bool isDvcsPlasticInstall)
{
string unityCloudEditionTokenFile = UserConfigFolder.GetConfigFile(
EditionToken.CLOUD_EDITION_FILE_NAME);
string unityDvcsEditionTokenFile = UserConfigFolder.GetConfigFile(
EditionToken.DVCS_EDITION_FILE_NAME);
CreateOrDeleteTokenFile(isCloudPlasticInstall, unityCloudEditionTokenFile);
CreateOrDeleteTokenFile(isDvcsPlasticInstall, unityDvcsEditionTokenFile);
}
static void CreateOrDeleteTokenFile(bool isEdition, string editionTokenFile)
{
if (isEdition && !File.Exists(editionTokenFile))
{
File.Create(editionTokenFile).Dispose();
return;
}
if (!isEdition && File.Exists(editionTokenFile))
{
File.Delete(editionTokenFile);
return;
}
}
static bool IsPlasticInstallOfEdition(
string plasticClientBinDir,
string editionFileName)
{
return File.Exists(Path.Combine(
plasticClientBinDir,
editionFileName));
}
}
}
using UnityEditor;
namespace Unity.PlasticSCM.Editor
{
internal static class VCSPlugin
{
internal static bool IsEnabled()
{
return GetVersionControl() == "PlasticSCM";
}
internal static void Disable()
{
SetVersionControl("Visible Meta Files");
AssetDatabase.SaveAssets();
}
static string GetVersionControl()
{
#if UNITY_2020_1_OR_NEWER
return VersionControlSettings.mode;
#else
return EditorSettings.externalVersionControl;
#endif
}
static void SetVersionControl(string versionControl)
{
#if UNITY_2020_1_OR_NEWER
VersionControlSettings.mode = versionControl;
#else
EditorSettings.externalVersionControl = versionControl;
#endif
}
}
}
using System;
using UnityEditor;
using Codice.CM.Common;
using GluonGui;
using PlasticGui;
using PlasticGui.Gluon;
using PlasticGui.WorkspaceWindow;
using PlasticGui.WorkspaceWindow.Merge;
using Unity.PlasticSCM.Editor.AssetsOverlays.Cache;
using Unity.PlasticSCM.Editor.AssetUtils.Processor;
using Unity.PlasticSCM.Editor.Tool;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.Views.Changesets;
using Unity.PlasticSCM.Editor.Views.History;
using Unity.PlasticSCM.Editor.Views.IncomingChanges;
using Unity.PlasticSCM.Editor.Views.PendingChanges;
using GluonNewIncomingChangesUpdater = PlasticGui.Gluon.WorkspaceWindow.NewIncomingChangesUpdater;
using ObjectInfo = Codice.CM.Common.ObjectInfo;
namespace Unity.PlasticSCM.Editor
{
internal class ViewSwitcher :
IViewSwitcher,
IMergeViewLauncher,
IGluonViewSwitcher,
IHistoryViewLauncher
{
internal PendingChangesTab PendingChangesTabForTesting { get { return mPendingChangesTab; } }
internal IIncomingChangesTab IncomingChangesTabForTesting { get { return mIncomingChangesTab; } }
internal ViewSwitcher(
WorkspaceInfo wkInfo,
ViewHost viewHost,
bool isGluonMode,
PlasticGui.WorkspaceWindow.PendingChanges.PendingChanges pendingChanges,
NewIncomingChangesUpdater developerNewIncomingChangesUpdater,
GluonNewIncomingChangesUpdater gluonNewIncomingChangesUpdater,
IIncomingChangesNotificationPanel incomingChangesNotificationPanel,
IAssetStatusCache assetStatusCache,
EditorWindow parentWindow)
{
mWkInfo = wkInfo;
mViewHost = viewHost;
mIsGluonMode = isGluonMode;
mPendingChanges = pendingChanges;
mDeveloperNewIncomingChangesUpdater = developerNewIncomingChangesUpdater;
mGluonNewIncomingChangesUpdater = gluonNewIncomingChangesUpdater;
mIncomingChangesNotificationPanel = incomingChangesNotificationPanel;
mAssetStatusCache = assetStatusCache;
mParentWindow = parentWindow;
mPendingChangesTabButton = new TabButton();
mIncomingChangesTabButton = new TabButton();
mChangesetsTabButton = new TabButton();
mHistoryTabButton = new TabButton();
}
internal void SetPlasticGUIClient(PlasticGUIClient plasticClient)
{
mPlasticClient = plasticClient;
}
internal void ShowInitialView()
{
ShowPendingChangesView();
}
internal void AutoRefreshPendingChangesView()
{
AutoRefresh.PendingChangesView(
mPendingChangesTab);
}
internal void AutoRefreshIncomingChangesView()
{
AutoRefresh.IncomingChangesView(
mIncomingChangesTab);
}
internal void RefreshView(ViewType viewType)
{
IRefreshableView view = GetRefreshableView(viewType);
if (view == null)
return;
view.Refresh();
}
internal void OnDisable()
{
PlasticAssetsProcessor.UnRegisterViews();
if (mPendingChangesTab != null)
mPendingChangesTab.OnDisable();
if (mIncomingChangesTab != null)
mIncomingChangesTab.OnDisable();
if (mChangesetsTab != null)
mChangesetsTab.OnDisable();
if (mHistoryTab != null)
mHistoryTab.OnDisable();
}
internal void Update()
{
if (IsViewSelected(SelectedTab.PendingChanges))
{
mPendingChangesTab.Update();
return;
}
if (IsViewSelected(SelectedTab.IncomingChanges))
{
mIncomingChangesTab.Update();
return;
}
if (IsViewSelected(SelectedTab.Changesets))
{
mChangesetsTab.Update();
return;
}
if (IsViewSelected(SelectedTab.History))
{
mHistoryTab.Update();
return;
}
}
internal void TabButtonsGUI()
{
InitializeTabButtonWidth();
PendingChangesTabButtonGUI();
IncomingChangesTabButtonGUI();
ChangesetsTabButtonGUI();
HistoryTabButtonGUI();
}
internal void TabViewGUI()
{
if (IsViewSelected(SelectedTab.PendingChanges))
{
mPendingChangesTab.OnGUI();
return;
}
if (IsViewSelected(SelectedTab.IncomingChanges))
{
mIncomingChangesTab.OnGUI();
return;
}
if (IsViewSelected(SelectedTab.Changesets))
{
mChangesetsTab.OnGUI();
return;
}
if (IsViewSelected(SelectedTab.History))
{
mHistoryTab.OnGUI();
return;
}
}
void IViewSwitcher.ShowPendingChanges()
{
ShowPendingChangesView();
mParentWindow.Repaint();
}
void IViewSwitcher.ShowSyncView(string syncViewToSelect)
{
throw new NotImplementedException();
}
void IViewSwitcher.ShowBranchExplorerView()
{
//TODO: Codice
//launch plastic with branch explorer view option
}
void IViewSwitcher.DisableMergeView()
{
}
bool IViewSwitcher.IsIncomingChangesView()
{
return IsViewSelected(SelectedTab.IncomingChanges);
}
void IViewSwitcher.CloseIncomingChangesView()
{
((IViewSwitcher)this).DisableMergeView();
}
void IMergeViewLauncher.MergeFrom(ObjectInfo objectInfo, EnumMergeType mergeType)
{
((IMergeViewLauncher)this).MergeFromInterval(objectInfo, null, mergeType);
}
void IMergeViewLauncher.MergeFrom(ObjectInfo objectInfo, EnumMergeType mergeType, ShowIncomingChangesFrom from)
{
((IMergeViewLauncher)this).MergeFromInterval(objectInfo, null, mergeType);
}
void IMergeViewLauncher.MergeFromInterval(ObjectInfo objectInfo, ObjectInfo ancestorChangesetInfo, EnumMergeType mergeType)
{
if (mergeType == EnumMergeType.IncomingMerge)
{
ShowIncomingChangesView();
mParentWindow.Repaint();
return;
}
LaunchTool.OpenMerge(mWkInfo.ClientPath);
}
void IGluonViewSwitcher.ShowIncomingChangesView()
{
ShowIncomingChangesView();
mParentWindow.Repaint();
}
void IHistoryViewLauncher.ShowHistoryView(
RepositorySpec repSpec,
long itemId,
string path,
bool isDirectory)
{
ShowHistoryView(
repSpec,
itemId,
path,
isDirectory);
mParentWindow.Repaint();
}
void CloseHistoryTab()
{
ShowView(mPreviousSelectedTab);
mViewHost.RemoveRefreshableView(
ViewType.HistoryView, mHistoryTab);
mHistoryTab.OnDisable();
mHistoryTab = null;
mParentWindow.Repaint();
}
void ShowPendingChangesView()
{
if (mPendingChangesTab == null)
{
mPendingChangesTab = new PendingChangesTab(
mWkInfo,
mPlasticClient,
mIsGluonMode,
mPendingChanges,
mDeveloperNewIncomingChangesUpdater,
this,
mAssetStatusCache,
mParentWindow);
mViewHost.AddRefreshableView(
ViewType.CheckinView,
mPendingChangesTab);
PlasticAssetsProcessor.
RegisterPendingChangesView(mPendingChangesTab);
}
bool wasPendingChangesSelected =
IsViewSelected(SelectedTab.PendingChanges);
if (!wasPendingChangesSelected)
{
mPendingChangesTab.AutoRefresh();
}
SetSelectedView(SelectedTab.PendingChanges);
}
void ShowIncomingChangesView()
{
if (mIncomingChangesTab == null)
{
mIncomingChangesTab = mIsGluonMode ?
new Views.IncomingChanges.Gluon.IncomingChangesTab(
mWkInfo,
mViewHost,
mPlasticClient,
mGluonNewIncomingChangesUpdater,
(Gluon.IncomingChangesNotificationPanel)mIncomingChangesNotificationPanel,
mParentWindow) as IIncomingChangesTab :
new Views.IncomingChanges.Developer.IncomingChangesTab(
mWkInfo,
this,
mPlasticClient,
mDeveloperNewIncomingChangesUpdater,
mParentWindow);
mViewHost.AddRefreshableView(
ViewType.IncomingChangesView,
(IRefreshableView)mIncomingChangesTab);
PlasticAssetsProcessor.
RegisterIncomingChangesView(mIncomingChangesTab);
}
bool wasIncomingChangesSelected =
IsViewSelected(SelectedTab.IncomingChanges);
if (!wasIncomingChangesSelected)
mIncomingChangesTab.AutoRefresh();
SetSelectedView(SelectedTab.IncomingChanges);
}
void ShowChangesetsView()
{
if (mChangesetsTab == null)
{
mChangesetsTab = new ChangesetsTab(
mWkInfo,
mPlasticClient,
this,
this,
mParentWindow,
mIsGluonMode);
mViewHost.AddRefreshableView(
ViewType.ChangesetsView,
mChangesetsTab);
}
bool wasChangesetsSelected =
IsViewSelected(SelectedTab.Changesets);
if (!wasChangesetsSelected)
((IRefreshableView)mChangesetsTab).Refresh();
SetSelectedView(SelectedTab.Changesets);
}
void ShowHistoryView(
RepositorySpec repSpec,
long itemId,
string path,
bool isDirectory)
{
if (mHistoryTab == null)
{
mHistoryTab = new HistoryTab(
mWkInfo,
mPlasticClient,
repSpec,
mDeveloperNewIncomingChangesUpdater,
mViewHost,
mParentWindow,
mIsGluonMode);
mViewHost.AddRefreshableView(
ViewType.HistoryView, mHistoryTab);
}
mHistoryTab.RefreshForItem(
itemId,
path,
isDirectory);
SetSelectedView(SelectedTab.History);
}
void InitializeTabButtonWidth()
{
if (mTabButtonWidth != -1)
return;
mTabButtonWidth = MeasureMaxWidth.ForTexts(
UnityStyles.PlasticWindow.ActiveTabButton,
PlasticLocalization.GetString(PlasticLocalization.Name.PendingChangesViewTitle),
PlasticLocalization.GetString(PlasticLocalization.Name.IncomingChangesViewTitle),
PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetsViewTitle));
}
void ShowView(SelectedTab viewToShow)
{
switch (viewToShow)
{
case SelectedTab.PendingChanges:
ShowPendingChangesView();
break;
case SelectedTab.IncomingChanges:
ShowIncomingChangesView();
break;
case SelectedTab.Changesets:
ShowChangesetsView();
break;
}
}
IRefreshableView GetRefreshableView(ViewType viewType)
{
switch (viewType)
{
case ViewType.PendingChangesView:
return mPendingChangesTab;
case ViewType.IncomingChangesView:
return (IRefreshableView)mIncomingChangesTab;
case ViewType.ChangesetsView:
return mChangesetsTab;
case ViewType.HistoryView:
return mHistoryTab;
default:
return null;
}
}
bool IsViewSelected(SelectedTab tab)
{
return mSelectedTab == tab;
}
void SetSelectedView(SelectedTab tab)
{
if (mSelectedTab != tab)
mPreviousSelectedTab = mSelectedTab;
mSelectedTab = tab;
if (mIncomingChangesTab == null)
return;
mIncomingChangesTab.IsVisible =
tab == SelectedTab.IncomingChanges;
}
void PendingChangesTabButtonGUI()
{
bool wasPendingChangesSelected =
IsViewSelected(SelectedTab.PendingChanges);
bool isPendingChangesSelected = mPendingChangesTabButton.
DrawTabButton(
PlasticLocalization.GetString(PlasticLocalization.Name.PendingChangesViewTitle),
wasPendingChangesSelected,
mTabButtonWidth);
if (isPendingChangesSelected)
ShowPendingChangesView();
}
void IncomingChangesTabButtonGUI()
{
bool wasIncomingChangesSelected =
IsViewSelected(SelectedTab.IncomingChanges);
bool isIncomingChangesSelected = mIncomingChangesTabButton.
DrawTabButton(
PlasticLocalization.GetString(PlasticLocalization.Name.IncomingChangesViewTitle),
wasIncomingChangesSelected,
mTabButtonWidth);
if (isIncomingChangesSelected)
ShowIncomingChangesView();
}
void ChangesetsTabButtonGUI()
{
bool wasChangesetsSelected =
IsViewSelected(SelectedTab.Changesets);
bool isChangesetsSelected = mChangesetsTabButton.
DrawTabButton(
PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetsViewTitle),
wasChangesetsSelected,
mTabButtonWidth);
if (isChangesetsSelected)
ShowChangesetsView();
}
void HistoryTabButtonGUI()
{
if (mHistoryTab == null)
return;
bool wasHistorySelected =
IsViewSelected(SelectedTab.History);
bool isCloseButtonClicked;
bool isHistorySelected = mHistoryTabButton.
DrawClosableTabButton(
PlasticLocalization.GetString(PlasticLocalization.Name.FileHistory),
wasHistorySelected,
true,
mTabButtonWidth,
mParentWindow.Repaint,
out isCloseButtonClicked);
if (isCloseButtonClicked)
{
CloseHistoryTab();
return;
}
if (isHistorySelected)
SetSelectedView(SelectedTab.History);
}
enum SelectedTab
{
None = 0,
PendingChanges = 1,
IncomingChanges = 2,
Changesets = 3,
History = 4
}
PendingChangesTab mPendingChangesTab;
IIncomingChangesTab mIncomingChangesTab;
ChangesetsTab mChangesetsTab;
HistoryTab mHistoryTab;
SelectedTab mSelectedTab;
SelectedTab mPreviousSelectedTab;
float mTabButtonWidth = -1;
TabButton mPendingChangesTabButton;
TabButton mChangesetsTabButton;
TabButton mIncomingChangesTabButton;
TabButton mHistoryTabButton;
PlasticGUIClient mPlasticClient;
readonly EditorWindow mParentWindow;
readonly IAssetStatusCache mAssetStatusCache;
readonly IIncomingChangesNotificationPanel mIncomingChangesNotificationPanel;
readonly GluonNewIncomingChangesUpdater mGluonNewIncomingChangesUpdater;
readonly NewIncomingChangesUpdater mDeveloperNewIncomingChangesUpdater;
readonly PlasticGui.WorkspaceWindow.PendingChanges.PendingChanges mPendingChanges;
readonly bool mIsGluonMode;
readonly ViewHost mViewHost;
readonly WorkspaceInfo mWkInfo;
}
}
using UnityEditor.IMGUI.Controls;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
class ChangesetListViewItem : TreeViewItem
{
internal object ObjectInfo { get; private set; }
internal ChangesetListViewItem(int id, object objectInfo)
: base(id, 1)
{
ObjectInfo = objectInfo;
displayName = id.ToString();
}
}
}
using System;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal enum ChangesetsListColumn
{
Name,
CreationDate,
CreatedBy,
Comment,
Branch,
Repository,
Guid
}
[Serializable]
internal class ChangesetsListHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static ChangesetsListHeaderState GetDefault()
{
return new ChangesetsListHeaderState(BuildColumns());
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.BranchColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.GuidColumn));
return result;
}
internal static string GetColumnName(ChangesetsListColumn column)
{
switch (column)
{
case ChangesetsListColumn.Name:
return PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn);
case ChangesetsListColumn.CreationDate:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreationDateColumn);
case ChangesetsListColumn.CreatedBy:
return PlasticLocalization.GetString(PlasticLocalization.Name.CreatedByColumn);
case ChangesetsListColumn.Comment:
return PlasticLocalization.GetString(PlasticLocalization.Name.CommentColumn);
case ChangesetsListColumn.Branch:
return PlasticLocalization.GetString(PlasticLocalization.Name.BranchColumn);
case ChangesetsListColumn.Repository:
return PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryColumn);
case ChangesetsListColumn.Guid:
return PlasticLocalization.GetString(PlasticLocalization.Name.GuidColumn);
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
if (mColumsAllowedToggleVisibility != null)
TreeHeaderColumns.SetVisibilities(columns, mColumsAllowedToggleVisibility);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = UnityConstants.ChangesetsColumns.CHANGESET_NUMBER_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.CHANGESET_NUMBER_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.Name)),
allowToggleVisibility = false
},
new Column()
{
width = UnityConstants.ChangesetsColumns.CREATION_DATE_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.CREATION_DATE_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.CreationDate))
},
new Column()
{
width = UnityConstants.ChangesetsColumns.CREATED_BY_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.CREATED_BY_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.CreatedBy))
},
new Column()
{
width = UnityConstants.ChangesetsColumns.COMMENT_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.COMMENT_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.Comment))
},
new Column()
{
width = UnityConstants.ChangesetsColumns.BRANCH_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.BRANCH_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.Branch))
},
new Column()
{
width = UnityConstants.ChangesetsColumns.REPOSITORY_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.REPOSITORY_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.Repository))
},
new Column()
{
width = UnityConstants.ChangesetsColumns.GUID_WIDTH,
minWidth = UnityConstants.ChangesetsColumns.GUID_MIN_WIDTH,
headerContent = new GUIContent(
GetColumnName(ChangesetsListColumn.Guid))
}
};
}
ChangesetsListHeaderState(Column[] columns)
: base(columns)
{
if (mHeaderTitles == null)
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
if (mColumsAllowedToggleVisibility == null)
mColumsAllowedToggleVisibility = TreeHeaderColumns.GetVisibilities(columns);
}
[SerializeField]
string[] mHeaderTitles;
[SerializeField]
bool[] mColumsAllowedToggleVisibility;
}
}
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.IMGUI.Controls;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.QueryViews;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Avatar;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal class ChangesetsListView : TreeView
{
internal ChangesetsListView(
ChangesetsListHeaderState headerState,
List<string> columnNames,
ChangesetsViewMenu menu,
Action sizeChangedAction,
Action selectionChangedAction,
Action doubleClickAction)
: base(new TreeViewState())
{
mColumnNames = columnNames;
mMenu = menu;
mSizeChangedAction = sizeChangedAction;
mSelectionChangedAction = selectionChangedAction;
mDoubleClickAction = doubleClickAction;
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = true;
mCooldownFilterAction = new CooldownWindowDelayer(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
mCooldownSelectionAction = new CooldownWindowDelayer(
DelayedSelectionChanged, UnityConstants.SELECTION_DELAYED_INPUT_ACTION_INTERVAL);
}
protected override void SelectionChanged(IList<int> selectedIds)
{
mCooldownSelectionAction.Ping();
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(
TreeViewItem rootItem)
{
if (mQueryResult == null)
{
ClearRows(rootItem, mRows);
return mRows;
}
RegenerateRows(
mListViewItemIds,
mQueryResult.GetObjects(),
rootItem, mRows);
return mRows;
}
protected override void SearchChanged(string newSearch)
{
mCooldownFilterAction.Ping();
}
protected override void ContextClickedItem(int id)
{
mMenu.Popup();
Repaint();
}
public override void OnGUI(Rect rect)
{
if (Event.current.type == EventType.Layout)
{
if (IsSizeChanged(treeViewRect, mLastRect))
mSizeChangedAction();
}
mLastRect = treeViewRect;
base.OnGUI(rect);
}
protected override void RowGUI(RowGUIArgs args)
{
DrawTreeViewItem.InitializeStyles();
if (args.item is ChangesetListViewItem)
{
ChangesetListViewItem changesetListViewItem = (ChangesetListViewItem)args.item;
ChangesetInfo changesetInfo = (ChangesetInfo)changesetListViewItem.ObjectInfo;
ChangesetsListViewItemGUI(
mQueryResult,
rowHeight,
changesetListViewItem,
args,
changesetInfo.ChangesetId == mLoadedChangesetId,
Repaint);
return;
}
base.RowGUI(args);
}
protected override void DoubleClickedItem(int id)
{
if (!HasSelection())
return;
mDoubleClickAction();
}
internal void BuildModel(
ViewQueryResult queryResult,
long loadedChangesetId)
{
mListViewItemIds.Clear();
mQueryResult = queryResult;
mLoadedChangesetId = loadedChangesetId;
}
internal void Refilter()
{
if (mQueryResult == null)
return;
Filter filter = new Filter(searchString);
mQueryResult.ApplyFilter(filter, mColumnNames);
}
internal void Sort()
{
if (mQueryResult == null)
return;
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
mQueryResult.Sort(
mColumnNames[sortedColumnIdx],
sortAscending);
}
internal List<RepositorySpec> GetSelectedRepositories()
{
List<RepositorySpec> result = new List<RepositorySpec>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<object, int> item
in mListViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
RepositorySpec repSpec =
mQueryResult.GetRepositorySpec(item.Key);
result.Add(repSpec);
}
return result;
}
internal List<RepObjectInfo> GetSelectedRepObjectInfos()
{
List<RepObjectInfo> result = new List<RepObjectInfo>();
IList<int> selectedIds = GetSelection();
if (selectedIds.Count == 0)
return result;
foreach (KeyValuePair<object, int> item
in mListViewItemIds.GetInfoItems())
{
if (!selectedIds.Contains(item.Value))
continue;
RepObjectInfo repObjectInfo =
mQueryResult.GetRepObjectInfo(item.Key);
result.Add(repObjectInfo);
}
return result;
}
internal void SelectRepObjectInfos(
List<RepObjectInfo> repObjectsToSelect)
{
List<int> idsToSelect = new List<int>();
foreach (RepObjectInfo repObjectInfo in repObjectsToSelect)
{
int repObjectInfoId = GetTreeIdForItem(repObjectInfo);
if (repObjectInfoId == -1)
continue;
idsToSelect.Add(repObjectInfoId);
}
TableViewOperations.SetSelectionAndScroll(this, idsToSelect);
}
int GetTreeIdForItem(RepObjectInfo repObjectInfo)
{
foreach (KeyValuePair<object, int> item in mListViewItemIds.GetInfoItems())
{
RepObjectInfo currentRepObjectInfo =
mQueryResult.GetRepObjectInfo(item.Key);
if (!currentRepObjectInfo.Equals(repObjectInfo))
continue;
if (!currentRepObjectInfo.GUID.Equals(repObjectInfo.GUID))
continue;
return item.Value;
}
return -1;
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void DelayedSelectionChanged()
{
if (!HasSelection())
return;
mSelectionChangedAction();
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void RegenerateRows(
ListViewItemIds<object> listViewItemIds,
List<object> objectInfos,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (objectInfos.Count == 0)
return;
foreach (object objectInfo in objectInfos)
{
int objectId;
if (!listViewItemIds.TryGetInfoItemId(objectInfo, out objectId))
objectId = listViewItemIds.AddInfoItem(objectInfo);
ChangesetListViewItem changesetListViewItem =
new ChangesetListViewItem(objectId, objectInfo);
rootItem.AddChild(changesetListViewItem);
rows.Add(changesetListViewItem);
}
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void ChangesetsListViewItemGUI(
ViewQueryResult queryResult,
float rowHeight,
ChangesetListViewItem item,
RowGUIArgs args,
bool isBoldText,
Action avatarLoadedAction)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
if (visibleColumnIdx == 0)
{
cellRect.x += UnityConstants.FIRST_COLUMN_WITHOUT_ICON_INDENT;
cellRect.width -= UnityConstants.FIRST_COLUMN_WITHOUT_ICON_INDENT;
}
ChangesetsListColumn column =
(ChangesetsListColumn)args.GetColumn(visibleColumnIdx);
ChangesetsListViewItemCellGUI(
cellRect,
rowHeight,
queryResult,
item,
column,
avatarLoadedAction,
args.selected,
args.focused,
isBoldText);
}
}
static void ChangesetsListViewItemCellGUI(
Rect rect,
float rowHeight,
ViewQueryResult queryResult,
ChangesetListViewItem item,
ChangesetsListColumn column,
Action avatarLoadedAction,
bool isSelected,
bool isFocused,
bool isBoldText)
{
string columnText = RepObjectInfoView.GetColumnText(
queryResult.GetRepositorySpec(item.ObjectInfo),
queryResult.GetRepObjectInfo(item.ObjectInfo),
ChangesetsListHeaderState.GetColumnName(column));
if (column == ChangesetsListColumn.CreatedBy)
{
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
-1,
GetAvatar.ForEmail(columnText, avatarLoadedAction),
null,
columnText,
isSelected,
isFocused,
isBoldText,
false);
return;
}
if (column == ChangesetsListColumn.Branch ||
column == ChangesetsListColumn.Repository ||
column == ChangesetsListColumn.Guid)
{
DrawTreeViewItem.ForSecondaryLabel(
rect, columnText, isSelected, isFocused, isBoldText);
return;
}
DrawTreeViewItem.ForLabel(
rect, columnText, isSelected, isFocused, isBoldText);
}
static bool IsSizeChanged(
Rect currentRect, Rect lastRect)
{
if (currentRect.width != lastRect.width)
return true;
if (currentRect.height != lastRect.height)
return true;
return false;
}
Rect mLastRect;
ListViewItemIds<object> mListViewItemIds = new ListViewItemIds<object>();
List<TreeViewItem> mRows = new List<TreeViewItem>();
ViewQueryResult mQueryResult;
long mLoadedChangesetId;
readonly CooldownWindowDelayer mCooldownFilterAction;
readonly CooldownWindowDelayer mCooldownSelectionAction;
readonly Action mDoubleClickAction;
readonly Action mSelectionChangedAction;
readonly Action mSizeChangedAction;
readonly ChangesetsViewMenu mMenu;
readonly List<string> mColumnNames;
}
}
using System.Collections.Generic;
using Codice.CM.Common;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal static class ChangesetsSelection
{
internal static void SelectChangesets(
ChangesetsListView listView,
List<RepObjectInfo> csetsToSelect,
int defaultRow)
{
if (csetsToSelect == null || csetsToSelect.Count == 0)
{
TableViewOperations.SelectFirstRow(listView);
return;
}
listView.SelectRepObjectInfos(csetsToSelect);
if (listView.HasSelection())
return;
TableViewOperations.SelectDefaultRow(listView, defaultRow);
if (listView.HasSelection())
return;
TableViewOperations.SelectFirstRow(listView);
}
internal static List<RepObjectInfo> GetSelectedRepObjectInfos(
ChangesetsListView listView)
{
return listView.GetSelectedRepObjectInfos();
}
internal static int GetSelectedChangesetsCount(
ChangesetsListView listView)
{
return listView.GetSelection().Count;
}
internal static ChangesetExtendedInfo GetSelectedChangeset(
ChangesetsListView listView)
{
List<RepObjectInfo> selectedRepObjectsInfos = listView.GetSelectedRepObjectInfos();
if (selectedRepObjectsInfos.Count == 0)
return null;
return (ChangesetExtendedInfo)selectedRepObjectsInfos[0];
}
internal static RepositorySpec GetSelectedRepository(
ChangesetsListView listView)
{
List<RepositorySpec> selectedRepositories = listView.GetSelectedRepositories();
if (selectedRepositories.Count == 0)
return null;
return selectedRepositories[0];
}
}
}
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Commands;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.WorkspaceWindow.QueryViews;
using PlasticGui.WorkspaceWindow.QueryViews.Changesets;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.UI.Tree;
using Unity.PlasticSCM.Editor.Views.Diff;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal class ChangesetsTab :
IRefreshableView,
IChangesetMenuOperations,
ChangesetsViewMenu.IMenuOperations
{
internal ChangesetsTab(
WorkspaceInfo wkInfo,
IWorkspaceWindow workspaceWindow,
IViewSwitcher viewSwitcher,
IHistoryViewLauncher historyViewLauncher,
EditorWindow parentWindow,
bool isGluonMode)
{
mWkInfo = wkInfo;
mParentWindow = parentWindow;
mIsGluonMode = isGluonMode;
BuildComponents(
wkInfo, workspaceWindow, viewSwitcher,
historyViewLauncher, parentWindow);
mProgressControls = new ProgressControlsForViews();
mSplitterState = PlasticSplitterGUILayout.InitSplitterState(
new float[] { 0.50f, 0.50f },
new int[] { 100, 100 },
new int[] { 100000, 100000 }
);
((IRefreshableView)this).Refresh();
}
internal void OnDisable()
{
mDiffPanel.OnDisable();
mSearchField.downOrUpArrowKeyPressed -=
SearchField_OnDownOrUpArrowKeyPressed;
TreeHeaderSettings.Save(
mChangesetsListView.multiColumnHeader.state,
UnityConstants.CHANGESETS_TABLE_SETTINGS_NAME);
BoolSetting.Save(
mIsChangesPanelVisible,
UnityConstants.CHANGESETS_SHOW_CHANGES_SETTING_NAME);
}
internal void Update()
{
mDiffPanel.Update();
mProgressControls.UpdateProgress(mParentWindow);
}
internal void OnGUI()
{
InitializeShowChangesButtonWidth();
bool wasChangesPanelVisible = mIsChangesPanelVisible;
DoActionsToolbar(
this,
mProgressControls,
mSearchField,
mChangesetsListView,
mDateFilter,
mChangesetsLabelText,
mShowChangesButtonWidth,
wasChangesPanelVisible);
if (mIsChangesPanelVisible)
{
PlasticSplitterGUILayout.BeginVerticalSplit(mSplitterState);
}
DoChangesetsArea(
mChangesetsListView,
mProgressControls.IsOperationRunning());
if (mIsChangesPanelVisible)
{
if (!wasChangesPanelVisible)
mShouldScrollToSelection = true;
DoChangesArea(mDiffPanel);
PlasticSplitterGUILayout.EndVerticalSplit();
}
}
void IRefreshableView.Refresh()
{
string query = GetChangesetsQuery(mDateFilter);
FillChangesets(mWkInfo, query);
}
int IChangesetMenuOperations.GetSelectedChangesetsCount()
{
return ChangesetsSelection.GetSelectedChangesetsCount(mChangesetsListView);
}
void IChangesetMenuOperations.DiffChangeset()
{
LaunchDiffOperations.DiffChangeset(
ChangesetsSelection.GetSelectedRepository(mChangesetsListView),
ChangesetsSelection.GetSelectedChangeset(mChangesetsListView),
mIsGluonMode);
}
void IChangesetMenuOperations.DiffSelectedChangesets()
{
List<RepObjectInfo> selectedChangesets = ChangesetsSelection.
GetSelectedRepObjectInfos(mChangesetsListView);
if (selectedChangesets.Count < 2)
return;
LaunchDiffOperations.DiffSelectedChangesets(
ChangesetsSelection.GetSelectedRepository(mChangesetsListView),
(ChangesetExtendedInfo)selectedChangesets[0],
(ChangesetExtendedInfo)selectedChangesets[1],
mIsGluonMode);
}
void IChangesetMenuOperations.DiffWithAnotherChangeset() { }
void IChangesetMenuOperations.CreateBranch() { }
void IChangesetMenuOperations.LabelChangeset() { }
void IChangesetMenuOperations.SwitchToChangeset() { }
void IChangesetMenuOperations.MergeChangeset() {}
void IChangesetMenuOperations.CherryPickChangeset() { }
void IChangesetMenuOperations.SubtractiveChangeset() { }
void IChangesetMenuOperations.SubtractiveChangesetInterval() { }
void IChangesetMenuOperations.CherryPickChangesetInterval() { }
void IChangesetMenuOperations.MergeToChangeset() { }
void IChangesetMenuOperations.MoveChangeset() { }
void IChangesetMenuOperations.DeleteChangeset() { }
void IChangesetMenuOperations.BrowseRepositoryOnChangeset() { }
void IChangesetMenuOperations.CreateCodeReview() { }
void SearchField_OnDownOrUpArrowKeyPressed()
{
mChangesetsListView.SetFocusAndEnsureSelectedItem();
}
void FillChangesets(WorkspaceInfo wkInfo, string query)
{
if (mIsRefreshing)
return;
mIsRefreshing = true;
List<RepObjectInfo> changesetsToSelect =
ChangesetsSelection.GetSelectedRepObjectInfos(mChangesetsListView);
int defaultRow = TableViewOperations.
GetFirstSelectedRow(mChangesetsListView);
((IProgressControls)mProgressControls).ShowProgress(
PlasticLocalization.GetString(
PlasticLocalization.Name.LoadingChangesets));
long loadedChangesetId = -1;
ViewQueryResult queryResult = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
queryResult = new ViewQueryResult(
Plastic.API.FindQuery(wkInfo, query));
loadedChangesetId = GetLoadedChangesetId(
wkInfo, mIsGluonMode);
},
/*afterOperationDelegate*/ delegate
{
try
{
if (waiter.Exception != null)
{
ExceptionsHandler.DisplayException(waiter.Exception);
return;
}
int changesetsCount = GetChangesetsCount(queryResult);
mChangesetsLabelText = string.Format(
PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetsCount),
changesetsCount);
UpdateChangesetsList(
mChangesetsListView,
queryResult,
loadedChangesetId);
if (changesetsCount == 0)
{
mDiffPanel.ClearInfo();
return;
}
ChangesetsSelection.SelectChangesets(
mChangesetsListView, changesetsToSelect, defaultRow);
}
finally
{
((IProgressControls)mProgressControls).HideProgress();
mIsRefreshing = false;
}
});
}
void ChangesetsViewMenu.IMenuOperations.DiffBranch()
{
LaunchDiffOperations.DiffBranch(
ChangesetsSelection.GetSelectedRepository(mChangesetsListView),
ChangesetsSelection.GetSelectedChangeset(mChangesetsListView),
mIsGluonMode);
}
ChangesetExtendedInfo ChangesetsViewMenu.IMenuOperations.GetSelectedChangeset()
{
return ChangesetsSelection.GetSelectedChangeset(
mChangesetsListView);
}
void OnChangesetsListViewSizeChanged()
{
if (!mShouldScrollToSelection)
return;
mShouldScrollToSelection = false;
TableViewOperations.ScrollToSelection(mChangesetsListView);
}
void OnSelectionChanged()
{
List<RepObjectInfo> selectedChangesets = ChangesetsSelection.
GetSelectedRepObjectInfos(mChangesetsListView);
if (selectedChangesets.Count != 1)
return;
mDiffPanel.UpdateInfo(
MountPointWithPath.BuildWorkspaceRootMountPoint(
ChangesetsSelection.GetSelectedRepository(mChangesetsListView)),
(ChangesetExtendedInfo)selectedChangesets[0]);
}
static void UpdateChangesetsList(
ChangesetsListView changesetsListView,
ViewQueryResult queryResult,
long loadedChangesetId)
{
changesetsListView.BuildModel(
queryResult,
loadedChangesetId);
changesetsListView.Refilter();
changesetsListView.Sort();
changesetsListView.Reload();
}
static long GetLoadedChangesetId(
WorkspaceInfo wkInfo,
bool isGluonMode)
{
if (isGluonMode)
return -1;
return Plastic.API.GetLoadedChangeset(wkInfo);
}
static string GetChangesetsQuery(DateFilter dateFilter)
{
if (dateFilter.FilterType == DateFilter.Type.AllTime)
return QueryConstants.ChangesetsBeginningQuery;
string whereClause = QueryConstants.GetChangesetsDateWhereClause(
dateFilter.GetFilterDate(DateTime.UtcNow));
return string.Format("{0} {1}",
QueryConstants.ChangesetsBeginningQuery,
whereClause);
}
static int GetChangesetsCount(
ViewQueryResult queryResult)
{
if (queryResult == null)
return 0;
return queryResult.Count();
}
void DoActionsToolbar(
IRefreshableView refreshableView,
ProgressControlsForViews progressControls,
SearchField searchField,
ChangesetsListView changesetsListView,
DateFilter dateFilter,
string changesetsLabelText,
float showChangesButtonWidth,
bool wasChangesPanelVisible)
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
if (!string.IsNullOrEmpty(changesetsLabelText))
{
GUILayout.Label(
changesetsLabelText,
UnityStyles.ChangesetsTab.HeaderLabel);
}
if (progressControls.IsOperationRunning())
{
DrawProgressForViews.ForIndeterminateProgress(
progressControls.ProgressData);
}
GUILayout.FlexibleSpace();
mIsChangesPanelVisible =
DoShowChangesButton(
showChangesButtonWidth,
wasChangesPanelVisible);
GUILayout.Space(2);
DrawSearchField.For(
searchField,
changesetsListView,
UnityConstants.SEARCH_FIELD_WIDTH);
DoDateFilter(
refreshableView,
dateFilter,
progressControls.IsOperationRunning());
DoRefreshButton(
refreshableView,
progressControls.IsOperationRunning());
EditorGUILayout.EndHorizontal();
}
static void DoChangesetsArea(
ChangesetsListView changesetsListView,
bool isOperationRunning)
{
EditorGUILayout.BeginVertical();
GUI.enabled = !isOperationRunning;
Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
changesetsListView.OnGUI(rect);
GUI.enabled = true;
EditorGUILayout.EndVertical();
}
static void DoChangesArea(DiffPanel diffPanel)
{
EditorGUILayout.BeginVertical();
diffPanel.OnGUI();
EditorGUILayout.EndVertical();
}
static bool DoShowChangesButton(
float showChangesButtonWidth,
bool wasChecked)
{
string buttonText = wasChecked ?
PlasticLocalization.GetString(PlasticLocalization.Name.HideChanges) :
PlasticLocalization.GetString(PlasticLocalization.Name.ShowChanges);
GUIContent buttonContent = new GUIContent(buttonText);
GUIStyle buttonStyle = EditorStyles.toolbarButton;
Rect toggleRect = GUILayoutUtility.GetRect(
buttonContent, buttonStyle,
GUILayout.Width(showChangesButtonWidth));
bool isChecked = GUI.Toggle(
toggleRect, wasChecked, buttonContent, buttonStyle);
return isChecked;
}
static void DoDateFilter(
IRefreshableView refreshableView,
DateFilter dateFilter,
bool isOperationRunning)
{
GUI.enabled = !isOperationRunning;
EditorGUI.BeginChangeCheck();
dateFilter.FilterType = (DateFilter.Type)
EditorGUILayout.EnumPopup(
dateFilter.FilterType,
EditorStyles.toolbarDropDown,
GUILayout.Width(100));
if (EditorGUI.EndChangeCheck())
{
EnumPopupSetting<DateFilter.Type>.Save(
dateFilter.FilterType,
UnityConstants.CHANGESETS_DATE_FILTER_SETTING_NAME);
refreshableView.Refresh();
}
GUI.enabled = true;
}
static void DoRefreshButton(
IRefreshableView refreshableView,
bool isOperationRunning)
{
EditorGUI.BeginDisabledGroup(isOperationRunning);
if (GUILayout.Button(new GUIContent(
Images.GetRefreshIcon()), EditorStyles.toolbarButton))
refreshableView.Refresh();
EditorGUI.EndDisabledGroup();
}
void InitializeShowChangesButtonWidth()
{
if (mShowChangesButtonWidth != -1)
return;
mShowChangesButtonWidth = MeasureMaxWidth.ForTexts(
EditorStyles.toolbarButton,
PlasticLocalization.GetString(PlasticLocalization.Name.HideChanges),
PlasticLocalization.GetString(PlasticLocalization.Name.ShowChanges));
}
void BuildComponents(
WorkspaceInfo wkInfo,
IWorkspaceWindow workspaceWindow,
IViewSwitcher viewSwitcher,
IHistoryViewLauncher historyViewLauncher,
EditorWindow parentWindow)
{
mSearchField = new SearchField();
mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
DateFilter.Type dateFilterType =
EnumPopupSetting<DateFilter.Type>.Load(
UnityConstants.CHANGESETS_DATE_FILTER_SETTING_NAME,
DateFilter.Type.LastMonth);
mDateFilter = new DateFilter(dateFilterType);
ChangesetsListHeaderState headerState =
ChangesetsListHeaderState.GetDefault();
TreeHeaderSettings.Load(headerState,
UnityConstants.CHANGESETS_TABLE_SETTINGS_NAME,
(int)ChangesetsListColumn.CreationDate, false);
mChangesetsListView = new ChangesetsListView(
headerState,
ChangesetsListHeaderState.GetColumnNames(),
new ChangesetsViewMenu(this, this),
sizeChangedAction: OnChangesetsListViewSizeChanged,
selectionChangedAction: OnSelectionChanged,
doubleClickAction: ((IChangesetMenuOperations)this).DiffChangeset);
mChangesetsListView.Reload();
mIsChangesPanelVisible = BoolSetting.Load(
UnityConstants.CHANGESETS_SHOW_CHANGES_SETTING_NAME,
true);
mDiffPanel = new DiffPanel(
wkInfo, workspaceWindow, viewSwitcher,
historyViewLauncher, parentWindow);
}
bool mIsRefreshing;
bool mShouldScrollToSelection;
bool mIsChangesPanelVisible;
float mShowChangesButtonWidth = -1;
string mChangesetsLabelText;
object mSplitterState;
DateFilter mDateFilter;
SearchField mSearchField;
ChangesetsListView mChangesetsListView;
DiffPanel mDiffPanel;
readonly bool mIsGluonMode;
readonly ProgressControlsForViews mProgressControls;
readonly EditorWindow mParentWindow;
readonly WorkspaceInfo mWkInfo;
}
}
using UnityEditor;
using UnityEngine;
using Codice.CM.Common;
using PlasticGui.WorkspaceWindow.QueryViews.Changesets;
using PlasticGui;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal class ChangesetsViewMenu
{
internal interface IMenuOperations
{
void DiffBranch();
ChangesetExtendedInfo GetSelectedChangeset();
}
internal ChangesetsViewMenu(
IChangesetMenuOperations changesetMenuOperations,
IMenuOperations menuOperations)
{
mChangesetMenuOperations = changesetMenuOperations;
mMenuOperations = menuOperations;
BuildComponents();
}
internal void Popup()
{
GenericMenu menu = new GenericMenu();
UpdateMenuItems(menu);
menu.ShowAsContext();
}
void DiffChangesetMenuItem_Click()
{
mChangesetMenuOperations.DiffChangeset();
}
void DiffSelectedChangesetsMenuItem_Click()
{
mChangesetMenuOperations.DiffSelectedChangesets();
}
void DiffBranchMenuItem_Click()
{
mMenuOperations.DiffBranch();
}
void UpdateMenuItems(GenericMenu menu)
{
ChangesetExtendedInfo singleSeletedChangeset = mMenuOperations.GetSelectedChangeset();
ChangesetMenuOperations operations = ChangesetMenuUpdater.GetAvailableMenuOperations(
mChangesetMenuOperations.GetSelectedChangesetsCount());
AddDiffChangesetMenuItem(
mDiffChangesetMenuItemContent,
menu,
singleSeletedChangeset,
operations,
DiffChangesetMenuItem_Click);
AddDiffSelectedChangesetsMenuItem(
mDiffSelectedChangesetsMenuItemContent,
menu,
operations,
DiffSelectedChangesetsMenuItem_Click);
if (IsOnMainBranch(singleSeletedChangeset))
return;
menu.AddSeparator(string.Empty);
AddDiffBranchMenuItem(
mDiffBranchMenuItemContent,
menu,
singleSeletedChangeset,
operations,
DiffBranchMenuItem_Click);
}
static void AddDiffChangesetMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
ChangesetExtendedInfo changeset,
ChangesetMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
string changesetName =
changeset != null ?
changeset.ChangesetId.ToString() :
string.Empty;
menuItemContent.text =
PlasticLocalization.GetString(PlasticLocalization.Name.AnnotateDiffChangesetMenuItem,
changesetName);
if (operations.HasFlag(ChangesetMenuOperations.DiffChangeset))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(
menuItemContent);
}
static void AddDiffSelectedChangesetsMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
ChangesetMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
if (operations.HasFlag(ChangesetMenuOperations.DiffSelectedChangesets))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(menuItemContent);
}
static void AddDiffBranchMenuItem(
GUIContent menuItemContent,
GenericMenu menu,
ChangesetExtendedInfo changeset,
ChangesetMenuOperations operations,
GenericMenu.MenuFunction menuFunction)
{
string branchName = GetBranchName(changeset);
menuItemContent.text =
PlasticLocalization.GetString(PlasticLocalization.Name.AnnotateDiffBranchMenuItem,
branchName);
if (operations.HasFlag(ChangesetMenuOperations.DiffChangeset))
{
menu.AddItem(
menuItemContent,
false,
menuFunction);
return;
}
menu.AddDisabledItem(
menuItemContent);
}
void BuildComponents()
{
mDiffChangesetMenuItemContent = new GUIContent();
mDiffSelectedChangesetsMenuItemContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.ChangesetMenuItemDiffSelected));
mDiffBranchMenuItemContent = new GUIContent();
}
static string GetBranchName(ChangesetExtendedInfo changesetInfo)
{
if (changesetInfo == null)
return string.Empty;
string branchName = changesetInfo.BranchName;
int lastIndex = changesetInfo.BranchName.LastIndexOf("/");
if (lastIndex == -1)
return branchName;
return branchName.Substring(lastIndex + 1);
}
static bool IsOnMainBranch(ChangesetExtendedInfo singleSeletedChangeset)
{
if (singleSeletedChangeset == null)
return false;
return singleSeletedChangeset.BranchName == MAIN_BRANCH_NAME;
}
GUIContent mDiffChangesetMenuItemContent;
GUIContent mDiffSelectedChangesetsMenuItemContent;
GUIContent mDiffBranchMenuItemContent;
readonly IChangesetMenuOperations mChangesetMenuOperations;
readonly IMenuOperations mMenuOperations;
const string MAIN_BRANCH_NAME = "/main";
}
}
using System;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
internal class DateFilter
{
internal enum Type
{
LastWeek,
Last15Days,
LastMonth,
Last3Months,
LastYear,
AllTime
}
internal Type FilterType;
internal DateFilter(Type filterType)
{
FilterType = filterType;
}
internal DateTime GetFilterDate(DateTime referenceDate)
{
switch (FilterType)
{
case DateFilter.Type.LastWeek:
return referenceDate.AddDays(-7);
case DateFilter.Type.Last15Days:
return referenceDate.AddDays(-15);
case DateFilter.Type.LastMonth:
return referenceDate.AddMonths(-1);
case DateFilter.Type.Last3Months:
return referenceDate.AddMonths(-3);
case DateFilter.Type.LastYear:
return referenceDate.AddYears(-1);
}
return DateTime.MinValue;
}
}
}
using Codice.CM.Common;
using Unity.PlasticSCM.Editor.Tool;
namespace Unity.PlasticSCM.Editor.Views.Changesets
{
static class LaunchDiffOperations
{
internal static void DiffChangeset(
RepositorySpec repSpec,
long changesetId,
bool isGluonMode)
{
if (changesetId == -1)
return;
string changesetFullSpec = GetChangesetFullSpec(
repSpec, changesetId);
LaunchTool.OpenChangesetDiffs(
changesetFullSpec,
isGluonMode);
}
internal static void DiffChangeset(
RepositorySpec repSpec,
ChangesetInfo changesetInfo,
bool isGluonMode)
{
if (changesetInfo == null)
return;
string changesetFullSpec = GetChangesetFullSpec(
repSpec, changesetInfo.ChangesetId);
LaunchTool.OpenChangesetDiffs(
changesetFullSpec,
isGluonMode);
}
internal static void DiffSelectedChangesets(
RepositorySpec repSpec,
ChangesetInfo cset1,
ChangesetInfo cset2,
bool isGluonMode)
{
ChangesetInfo srcChangesetInfo;
ChangesetInfo dstChangesetInfo;
GetSrcAndDstCangesets(
cset1,
cset2,
out srcChangesetInfo,
out dstChangesetInfo);
string srcChangesetFullSpec = GetChangesetFullSpec(
repSpec, srcChangesetInfo.ChangesetId);
string dstChangesetFullSpec = GetChangesetFullSpec(
repSpec, dstChangesetInfo.ChangesetId);
LaunchTool.OpenSelectedChangesetsDiffs(
srcChangesetFullSpec,
dstChangesetFullSpec,
isGluonMode);
}
internal static void DiffBranch(
RepositorySpec repSpec,
ChangesetExtendedInfo changesetExtendedInfo,
bool isGluonMode)
{
if (changesetExtendedInfo == null)
return;
string branchFullSpec = GetBranchFullSpec(
repSpec, changesetExtendedInfo);
LaunchTool.OpenBranchDiffs(
branchFullSpec,
isGluonMode);
}
static void GetSrcAndDstCangesets(
ChangesetInfo cset1,
ChangesetInfo cset2,
out ChangesetInfo srcChangesetInfo,
out ChangesetInfo dstChangesetInfo)
{
if (cset1.LocalTimeStamp < cset2.LocalTimeStamp)
{
srcChangesetInfo = cset1;
dstChangesetInfo = cset2;
return;
}
srcChangesetInfo = cset2;
dstChangesetInfo = cset1;
}
static string GetChangesetFullSpec(
RepositorySpec repSpec,
long changesetId)
{
return string.Format("cs:{0}@{1}",
changesetId, repSpec.ToString());
}
static string GetBranchFullSpec(
RepositorySpec repSpec,
ChangesetExtendedInfo changesetExtendedInfo)
{
return string.Format("br:{0}@{1}",
changesetExtendedInfo.BranchName,
repSpec.ToString());
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using Codice.Client.BaseCommands;
using Codice.Client.Commands;
using Codice.Client.Commands.CheckIn;
using Codice.Client.Common;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using Codice.Client.GameUI.Checkin;
using PlasticGui;
using PlasticGui.Configuration.CloudEdition;
using PlasticGui.Help.Conditions;
using PlasticGui.SwitcherWindow.Repositories;
using PlasticGui.SwitcherWindow.Workspaces;
using PlasticGui.WebApi;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
{
internal class CreateWorkspaceView :
IPlasticDialogCloser,
IWorkspacesRefreshableView
{
internal interface ICreateWorkspaceListener
{
void OnWorkspaceCreated(WorkspaceInfo wkInfo, bool isGluonMode);
}
internal CreateWorkspaceView(
EditorWindow parentWindow,
ICreateWorkspaceListener listener,
PlasticAPI plasticApi,
IPlasticWebRestApi plasticWebRestApi,
string workspacePath)
{
mParentWindow = parentWindow;
mCreateWorkspaceListener = listener;
mWorkspacePath = workspacePath;
mPlasticWebRestApi = plasticWebRestApi;
mProgressControls = new ProgressControlsForViews();
mWorkspaceOperations = new WorkspaceOperations(this, mProgressControls);
mCreateWorkspaceState = CreateWorkspaceViewState.BuildForProjectDefaults();
Initialize(plasticApi, plasticWebRestApi);
}
internal void Update()
{
mProgressControls.UpdateProgress(mParentWindow);
}
internal void OnGUI()
{
if (Event.current.type == EventType.Layout)
{
mProgressControls.ProgressData.CopyInto(
mCreateWorkspaceState.ProgressData);
}
string repositoryName = mCreateWorkspaceState.RepositoryName;
DrawCreateWorkspace.ForState(
CreateRepository,
ValidateAndCreateWorkspace,
mParentWindow,
mPlasticWebRestApi,
mDefaultServer,
ref mCreateWorkspaceState);
if (repositoryName == mCreateWorkspaceState.RepositoryName)
return;
OnRepositoryChanged(
mDialogUserAssistant,
mCreateWorkspaceState,
mWorkspacePath);
}
void Initialize(PlasticAPI plasticApi, IPlasticWebRestApi plasticWebRestApi)
{
((IProgressControls)mProgressControls).ShowProgress(string.Empty);
WorkspaceInfo[] allWorkspaces = null;
IList allRepositories = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
mDefaultServer = GetDefaultServer.ToCreateWorkspace(plasticWebRestApi);
allWorkspaces = plasticApi.GetAllWorkspacesArray();
allRepositories = plasticApi.GetAllRepositories(
mDefaultServer, true);
},
/*afterOperationDelegate*/ delegate
{
((IProgressControls)mProgressControls).HideProgress();
if (waiter.Exception != null)
{
DisplayException(mProgressControls, waiter.Exception);
return;
}
string serverSpecPart = string.Format("@{0}",
mDefaultServer);
mCreateWorkspaceState.RepositoryName = ValidRepositoryName.Get(
string.Format("{0}{1}",
mCreateWorkspaceState.RepositoryName,
serverSpecPart),
allRepositories);
mCreateWorkspaceState.WorkspaceName =
mCreateWorkspaceState.RepositoryName.Replace(
serverSpecPart, string.Empty);
mDialogUserAssistant = new CreateWorkspaceDialogUserAssistant(
mWorkspacePath,
allWorkspaces);
OnRepositoryChanged(
mDialogUserAssistant,
mCreateWorkspaceState,
mWorkspacePath);
});
}
static void OnRepositoryChanged(
CreateWorkspaceDialogUserAssistant dialogUserAssistant,
CreateWorkspaceViewState createWorkspaceState,
string workspacePath)
{
if (dialogUserAssistant == null)
return;
dialogUserAssistant.RepositoryChanged(
createWorkspaceState.RepositoryName,
createWorkspaceState.WorkspaceName,
workspacePath);
createWorkspaceState.WorkspaceName =
dialogUserAssistant.GetProposedWorkspaceName();
}
void CreateRepository(
RepositoryCreationData data)
{
if (!data.Result)
return;
((IProgressControls)mProgressControls).ShowProgress(
PlasticLocalization.GetString(
PlasticLocalization.Name.CreatingRepository,
data.RepName));
RepositoryInfo createdRepository = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
createdRepository = Plastic.API.CreateRepository(
data.ServerName, data.RepName);
},
/*afterOperationDelegate*/ delegate
{
((IProgressControls)mProgressControls).HideProgress();
if (waiter.Exception != null)
{
DisplayException(mProgressControls, waiter.Exception);
return;
}
if (createdRepository == null)
return;
mCreateWorkspaceState.RepositoryName =
createdRepository.GetRepSpec().ToString();
});
}
void ValidateAndCreateWorkspace(
CreateWorkspaceViewState state)
{
mWkCreationData = BuildCreationDataFromState(
state, mWorkspacePath);
WorkspaceCreationValidation.AsyncValidation(
mWkCreationData, this, mProgressControls);
// validation calls IPlasticDialogCloser.CloseDialog()
// when the validation is ok
}
void IPlasticDialogCloser.CloseDialog()
{
((IProgressControls)mProgressControls).ShowProgress(string.Empty);
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
RepositorySpec repSpec = new SpecGenerator().GenRepositorySpec(
false, mWkCreationData.Repository);
bool repositoryExist = Plastic.API.CheckRepositoryExists(
repSpec.Server, repSpec.Name);
if (!repositoryExist)
Plastic.API.CreateRepository(repSpec.Server, repSpec.Name);
},
/*afterOperationDelegate*/ delegate
{
((IProgressControls)mProgressControls).HideProgress();
if (waiter.Exception != null)
{
DisplayException(mProgressControls, waiter.Exception);
return;
}
mWkCreationData.Result = true;
mWorkspaceOperations.CreateWorkspace(mWkCreationData);
// the operation calls IWorkspacesRefreshableView.RefreshAndSelect
// when the workspace is created
});
}
void IWorkspacesRefreshableView.RefreshAndSelect(WorkspaceInfo wkInfo)
{
PerformInitialCheckin.IfRepositoryIsEmpty(
wkInfo, mWkCreationData.Repository,
mWkCreationData.IsGluonWorkspace, Plastic.API,
mProgressControls, mCreateWorkspaceListener);
}
static WorkspaceCreationData BuildCreationDataFromState(
CreateWorkspaceViewState state,
string workspacePath)
{
return new WorkspaceCreationData(
state.WorkspaceName,
workspacePath,
state.RepositoryName,
state.WorkspaceMode ==
CreateWorkspaceViewState.WorkspaceModes.Gluon,
false);
}
static void DisplayException(
IProgressControls progressControls,
Exception ex)
{
ExceptionsHandler.LogException(
"CreateWorkspaceView", ex);
progressControls.ShowError(
ExceptionsHandler.GetCorrectExceptionMessage(ex));
}
static class PerformInitialCheckin
{
internal static void IfRepositoryIsEmpty(
WorkspaceInfo wkInfo,
string repository,
bool isGluonWorkspace,
IPlasticAPI plasticApi,
IProgressControls progressControls,
ICreateWorkspaceListener createWorkspaceListener)
{
RepositoryInfo repInfo = null;
bool isEmptyRepository = false;
progressControls.ShowProgress(string.Empty);
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
RepositorySpec repSpec = new SpecGenerator().
GenRepositorySpec(false, repository);
repInfo = plasticApi.GetRepositoryInfo(repSpec);
isEmptyRepository = IsEmptyRepositoryCondition.
Evaluate(wkInfo, repSpec, plasticApi);
},
/*afterOperationDelegate*/ delegate
{
progressControls.HideProgress();
if (waiter.Exception != null)
{
DisplayException(progressControls, waiter.Exception);
return;
}
if (!SetupCloudProjectId.HasCloudProjectId())
SetupCloudProjectId.ForRepository(repInfo);
if (!isEmptyRepository)
return;
CheckinPackagesAndProjectSettingsFolders(
wkInfo, isGluonWorkspace, plasticApi,
progressControls, createWorkspaceListener);
});
}
static void CheckinPackagesAndProjectSettingsFolders(
WorkspaceInfo wkInfo,
bool isGluonWorkspace,
IPlasticAPI plasticApi,
IProgressControls progressControls,
ICreateWorkspaceListener createWorkspaceListener)
{
List<string> paths = new List<string> {
Path.Combine(wkInfo.ClientPath, "Packages"),
Path.Combine(wkInfo.ClientPath, "ProjectSettings")
};
string comment = PlasticLocalization.GetString(
PlasticLocalization.Name.UnityInitialCheckinComment);
progressControls.ShowProgress(PlasticLocalization.GetString(
PlasticLocalization.Name.UnityInitialCheckinProgress));
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
PerformAdd(paths, plasticApi);
PerformCheckinForMode(
wkInfo, paths, comment, isGluonWorkspace);
},
/*afterOperationDelegate*/ delegate
{
progressControls.HideProgress();
if (waiter.Exception != null &&
!IsMergeNeededException(waiter.Exception))
{
DisplayException(progressControls, waiter.Exception);
return;
}
createWorkspaceListener.OnWorkspaceCreated(
wkInfo, isGluonWorkspace);
});
}
static void PerformAdd(
List<string> paths,
IPlasticAPI plasticApi)
{
AddOptions options = new AddOptions();
options.AddPrivateParents = true;
options.CheckoutParent = true;
options.Recurse = true;
options.SearchForPrivatePaths = true;
options.SkipIgnored = true;
IList checkouts;
plasticApi.Add(
paths.ToArray(), options,
out checkouts);
}
static void PerformCheckinForMode(
WorkspaceInfo wkInfo,
List<string> paths,
string comment,
bool isGluonWorkspace)
{
if (isGluonWorkspace)
{
new BaseCommandsImpl().PartialCheckin(
wkInfo, paths, comment);
return;
}
CheckinParams ciParams = new CheckinParams();
ciParams.paths = paths.ToArray();
ciParams.comment = comment;
ciParams.time = DateTime.MinValue;
ciParams.flags =
CheckinFlags.Recurse |
CheckinFlags.ProcessSymlinks;
new BaseCommandsImpl().CheckIn(ciParams);
}
static bool IsMergeNeededException(Exception exception)
{
if (exception == null)
return false;
// Check the check-in exception for gluon
if (exception is CheckinConflictsException)
return true;
// Check the check-in exceptions for plastic
return exception is CmClientMergeNeededException
|| exception is CmClientUpdateMergeNeededException;
}
}
class GetDefaultServer
{
internal static string ToCreateWorkspace(IPlasticWebRestApi plasticWebRestApi)
{
string clientConfServer = Plastic.ConfigAPI.GetClientConfServer();
if (!EditionToken.IsCloudEdition())
return clientConfServer;
string cloudServer = PlasticGuiConfig.Get().
Configuration.DefaultCloudServer;
if (!string.IsNullOrEmpty(cloudServer))
return cloudServer;
CloudEditionCreds.Data config =
CloudEditionCreds.GetFromClientConf();
cloudServer = GetFirstCloudServer.
GetCloudServer(plasticWebRestApi, config.Email, config.Password);
if (string.IsNullOrEmpty(cloudServer))
return clientConfServer;
SaveCloudServer.ToPlasticGuiConfig(cloudServer);
return cloudServer;
}
}
WorkspaceCreationData mWkCreationData;
CreateWorkspaceViewState mCreateWorkspaceState;
CreateWorkspaceDialogUserAssistant mDialogUserAssistant;
string mDefaultServer;
readonly WorkspaceOperations mWorkspaceOperations;
readonly ProgressControlsForViews mProgressControls;
readonly string mWorkspacePath;
readonly ICreateWorkspaceListener mCreateWorkspaceListener;
readonly EditorWindow mParentWindow;
readonly IPlasticWebRestApi mPlasticWebRestApi;
}
}
using System.IO;
using UnityEngine;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace
{
internal class CreateWorkspaceViewState
{
internal enum WorkspaceModes
{
Developer,
Gluon
}
internal string RepositoryName { get; set; }
internal string WorkspaceName { get; set; }
internal WorkspaceModes WorkspaceMode { get; set; }
internal ProgressControlsForViews.Data ProgressData { get; set; }
internal static CreateWorkspaceViewState BuildForProjectDefaults()
{
string projectName = Application.productName;
return new CreateWorkspaceViewState()
{
RepositoryName = projectName,
WorkspaceName = projectName,
WorkspaceMode = WorkspaceModes.Developer,
ProgressData = new ProgressControlsForViews.Data()
};
}
}
}
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common;
using PlasticGui;
using PlasticGui.SwitcherWindow.Repositories;
using PlasticGui.WebApi;
using PlasticGui.WorkspaceWindow.Servers;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
{
internal class CreateRepositoryDialog :
PlasticDialog,
KnownServersListOperations.IKnownServersList
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 600, 275);
}
}
internal static RepositoryCreationData CreateRepository(
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string proposedRepositoryName,
string proposedServer,
string lastUsedRepServer,
string clientConfServer)
{
string server = CreateRepositoryDialogUserAssistant.GetProposedServer(
proposedServer, lastUsedRepServer, clientConfServer);
CreateRepositoryDialog dialog = Create(
plasticWebRestApi,
new ProgressControlsForDialogs(),
proposedRepositoryName,
server);
ResponseType dialogResult = dialog.RunModal(parentWindow);
RepositoryCreationData result = dialog.BuildCreationData();
result.Result = dialogResult == ResponseType.Ok;
return result;
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(
PlasticLocalization.Name.NewRepositoryTitle));
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.NewRepositoryExplanation));
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.CreateRepositoryDialogDetailedExplanation));
if (Event.current.type == EventType.Layout)
{
mProgressControls.ProgressData.CopyInto(mProgressData);
}
GUILayout.Space(5);
DoEntriesArea();
GUILayout.Space(10);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
DoButtonsArea();
mProgressControls.ForcedUpdateProgress(this);
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.NewRepositoryTitle);
}
void KnownServersListOperations.IKnownServersList.FillValues(List<string> values)
{
mKnownServers = values;
}
void DoEntriesArea()
{
mName = TextEntry(
PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryNameShortLabel),
mName,
REPONAME_CONTROL_NAME,
ENTRY_WIDTH,
ENTRY_X);
if (!mFocusIsAreadySet)
{
mFocusIsAreadySet = true;
GUI.FocusControl(REPONAME_CONTROL_NAME);
}
GUILayout.Space(5);
mServer = ComboBox(
PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryExplorerServerLabel),
mServer,
DROPDOWN_CONTROL_NAME,
mKnownServers,
new GenericMenu.MenuFunction2(SelectServer),
ENTRY_WIDTH,
ENTRY_X);
}
void SelectServer(object userData)
{
mServer = userData.ToString();
Repaint();
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
void DoOkButton()
{
if (!AcceptButton(PlasticLocalization.GetString(
PlasticLocalization.Name.OkButton)))
return;
OkButtonWithValidationAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
void OkButtonWithValidationAction()
{
RepositoryCreationValidation.AsyncValidation(
BuildCreationData(),
this,
mProgressControls);
}
RepositoryCreationData BuildCreationData()
{
return new RepositoryCreationData(mName, mServer);
}
static CreateRepositoryDialog Create(
IPlasticWebRestApi plasticWebRestApi,
ProgressControlsForDialogs progressControls,
string proposedRepositoryName,
string proposedServer)
{
var instance = CreateInstance<CreateRepositoryDialog>();
instance.mEnterKeyAction = instance.OkButtonWithValidationAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
instance.mPlasticWebRestApi = plasticWebRestApi;
instance.mProgressControls = progressControls;
instance.BuildComponents(proposedRepositoryName, proposedServer);
return instance;
}
void BuildComponents(string proposedRepositoryName, string proposedServer)
{
mName = proposedRepositoryName;
mServer = proposedServer;
KnownServersListOperations.GetCombinedServers(
true,
GetExtraServers(proposedServer),
mProgressControls,
this,
mPlasticWebRestApi,
CmConnection.Get().GetProfileManager());
}
static List<string> GetExtraServers(string proposedServer)
{
List<string> result = new List<string>();
if (!string.IsNullOrEmpty(proposedServer))
result.Add(proposedServer);
return result;
}
IPlasticWebRestApi mPlasticWebRestApi;
bool mFocusIsAreadySet;
string mName;
string mServer;
List<string> mKnownServers = new List<string>();
ProgressControlsForDialogs.Data mProgressData = new ProgressControlsForDialogs.Data();
ProgressControlsForDialogs mProgressControls;
const float ENTRY_WIDTH = 400;
const float ENTRY_X = 175f;
const string REPONAME_CONTROL_NAME = "CreateRepositoryDialog.RepositoryName";
const string DROPDOWN_CONTROL_NAME = "CreateRepositoryDialog.ServerDropdown";
}
}
using System;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
{
internal enum RepositoriesListColumn
{
Name,
Server
}
[Serializable]
internal class RepositoriesListHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static RepositoriesListHeaderState GetDefault()
{
return new RepositoriesListHeaderState(BuildColumns());
}
internal static List<string> GetColumnNames()
{
List<string> result = new List<string>();
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn));
result.Add(PlasticLocalization.GetString(PlasticLocalization.Name.ServerColumn));
return result;
}
static string GetColumnName(RepositoriesListColumn column)
{
switch (column)
{
case RepositoriesListColumn.Name:
return PlasticLocalization.GetString(PlasticLocalization.Name.NameColumn);
case RepositoriesListColumn.Server:
return PlasticLocalization.GetString(PlasticLocalization.Name.ServerColumn);
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 320,
headerContent = new GUIContent(
GetColumnName(RepositoriesListColumn.Name)),
minWidth = 200,
allowToggleVisibility = false,
},
new Column()
{
width = 200,
headerContent = new GUIContent(
GetColumnName(RepositoriesListColumn.Server)),
minWidth = 200,
allowToggleVisibility = false,
}
};
}
RepositoriesListHeaderState(Column[] columns)
: base(columns)
{
if (mHeaderTitles == null)
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
}
[SerializeField]
string[] mHeaderTitles;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.SwitcherWindow.Repositories;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
{
internal class RepositoriesListView :
TreeView,
IPlasticTable<RepositoryInfo>
{
internal RepositoriesListView(
RepositoriesListHeaderState headerState,
List<string> columnNames,
Action doubleClickAction)
: base(new TreeViewState())
{
mColumnNames = columnNames;
mDoubleClickAction = doubleClickAction;
multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
mColumnComparers = RepositoriesTableDefinition.BuildColumnComparers();
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
showAlternatingRowBackgrounds = true;
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override IList<TreeViewItem> BuildRows(
TreeViewItem rootItem)
{
RegenerateRows(
this, mRepositories, rootItem, mRows);
return mRows;
}
protected override void SearchChanged(string newSearch)
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
protected override void DoubleClickedItem(int id)
{
mDoubleClickAction();
}
protected override void RowGUI(RowGUIArgs args)
{
if (args.item is RepositoryListViewItem)
{
RepositoryListViewItemGUI(
(RepositoryListViewItem)args.item,
args,
rowHeight);
return;
}
base.RowGUI(args);
}
internal string GetSelectedRepository()
{
IList<TreeViewItem> selectedItems = FindRows(GetSelection());
if (selectedItems.Count == 0)
return null;
return ((RepositoryListViewItem)selectedItems[0])
.Repository.GetRepSpec().ToString();
}
void IPlasticTable<RepositoryInfo>.Fill(
List<RepositoryInfo> entries,
List<RepositoryInfo> entriesToSelect)
{
mUnfilteredRepositories = entries;
Refilter();
Sort();
Reload();
}
void Refilter()
{
mRepositories = RepositoriesTableDefinition.TableFilter.Filter(
searchString,
mUnfilteredRepositories);
}
void Sort()
{
int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
IComparer<RepositoryInfo> comparer = mColumnComparers[
mColumnNames[sortedColumnIdx]];
mRepositories.Sort(new SortOrderComparer<RepositoryInfo>(
comparer, sortAscending));
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
static void RegenerateRows(
RepositoriesListView listView,
IList repositories,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (repositories.Count == 0)
return;
for (int i = 0; i < repositories.Count; i++)
{
RepositoryListViewItem repositoryListViewItem =
new RepositoryListViewItem(i + 1, (RepositoryInfo)repositories[i]);
rootItem.AddChild(repositoryListViewItem);
rows.Add(repositoryListViewItem);
}
listView.SetSelection(new List<int> { 1 });
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void RepositoryListViewItemGUI(
RepositoryListViewItem item,
RowGUIArgs args,
float rowHeight)
{
for (int visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
{
Rect cellRect = args.GetCellRect(visibleColumnIdx);
RepositoriesListColumn column =
(RepositoriesListColumn)args.GetColumn(visibleColumnIdx);
RepositoryListViewItemCellGUI(
cellRect,
item,
column,
rowHeight,
args.selected,
args.focused);
}
}
static void RepositoryListViewItemCellGUI(
Rect rect,
RepositoryListViewItem item,
RepositoriesListColumn column,
float rowHeight,
bool isSelected,
bool isFocused)
{
if (column == RepositoriesListColumn.Name)
{
DrawTreeViewItem.ForItemCell(
rect,
rowHeight,
0,
Images.GetImage(Images.Name.IconRepository),
null,
item.Repository.Name,
isSelected,
isFocused,
false,
false);
return;
}
DrawTreeViewItem.ForSecondaryLabel(
rect,
item.Repository.Server,
isSelected,
isFocused,
false);
}
List<TreeViewItem> mRows = new List<TreeViewItem>();
List<RepositoryInfo> mUnfilteredRepositories = new List<RepositoryInfo>();
List<RepositoryInfo> mRepositories = new List<RepositoryInfo>();
readonly Dictionary<string, IComparer<RepositoryInfo>> mColumnComparers;
readonly List<string> mColumnNames;
readonly Action mDoubleClickAction;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Common;
using PlasticGui;
using PlasticGui.SwitcherWindow.Repositories;
using PlasticGui.WebApi;
using PlasticGui.WorkspaceWindow.Servers;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.Views.CreateWorkspace.Dialogs
{
internal class RepositoryExplorerDialog :
PlasticDialog,
KnownServersListOperations.IKnownServersList
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 750, 450);
}
}
internal static string BrowseRepository(
EditorWindow parentWindow,
IPlasticWebRestApi plasticWebRestApi,
string defaultServer)
{
RepositoryExplorerDialog dialog = Create(
plasticWebRestApi,
new ProgressControlsForDialogs(),
defaultServer,
new UnityPlasticGuiMessage(parentWindow));
ResponseType dialogResult = dialog.RunModal(parentWindow);
if (dialogResult != ResponseType.Ok)
return null;
return dialog.mRepositoriesListView.GetSelectedRepository();
}
void OnDisable()
{
mSearchField.downOrUpArrowKeyPressed -=
SearchField_OnDownOrUpArrowKeyPressed;
}
protected override void SaveSettings()
{
TreeHeaderSettings.Save(
mRepositoriesListView.multiColumnHeader.state,
UnityConstants.REPOSITORIES_TABLE_SETTINGS_NAME);
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(PlasticLocalization.Name.ChooseRepositoryTitle));
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.SelectRepositoryBelow));
if (Event.current.type == EventType.Layout)
{
mProgressControls.ProgressData.CopyInto(
mState.ProgressData);
}
bool isEnabled = !mProgressControls.ProgressData.IsWaitingAsyncResult;
DoToolbarArea(
mSearchField,
mRepositoriesListView,
isEnabled,
Refresh,
OnServerSelected,
ref mState);
GUILayout.Space(10);
DoListArea(
mRepositoriesListView,
isEnabled);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
DoButtonsArea();
mProgressControls.ForcedUpdateProgress(this);
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(PlasticLocalization.Name.ExploreRepositories);
}
void SearchField_OnDownOrUpArrowKeyPressed()
{
mRepositoriesListView.SetFocusAndEnsureSelectedItem();
}
void Refresh()
{
mFillRepositoriesTable.FillTable(
mRepositoriesListView,
null,
mProgressControls,
null,
new FillRepositoriesTable.SaveLastUsedServer(true),
mGuiMessage,
null,
null,
null,
mRepositoriesListView.searchString,
mState.Server,
false,
false,
true);
}
void KnownServersListOperations.IKnownServersList.FillValues(
List<string> values)
{
mState.AvailableServers = values;
Refresh();
}
void OnServerSelected(object server)
{
mState.Server = server.ToString();
Repaint();
Refresh();
}
static void DoToolbarArea(
SearchField searchField,
RepositoriesListView listView,
bool isEnabled,
Action refreshAction,
GenericMenu.MenuFunction2 selectServerAction,
ref State state)
{
GUILayout.BeginHorizontal();
GUILayout.Label(
PlasticLocalization.GetString(PlasticLocalization.Name.RepositoryExplorerServerLabel));
GUI.enabled = isEnabled;
state.Server = DoDropDownTextField(
state.Server,
state.AvailableServers,
selectServerAction,
refreshAction);
var refreshText = PlasticLocalization.GetString(PlasticLocalization.Name.RefreshButton);
if (GUILayout.Button(refreshText, EditorStyles.miniButton))
refreshAction();
GUILayout.FlexibleSpace();
DrawSearchField.For(
searchField, listView, SEARCH_FIELD_WIDTH);
GUI.enabled = true;
GUILayout.EndHorizontal();
}
static void DoListArea(
RepositoriesListView listView,
bool isEnabled)
{
GUI.enabled = isEnabled;
Rect treeRect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
listView.OnGUI(treeRect);
GUI.enabled = true;
}
static string DoDropDownTextField(
string text,
List<string> options,
GenericMenu.MenuFunction2 selectServerAction,
Action enterKeyAction)
{
bool isEnterKeyPressed = false;
Event e = Event.current;
if (Keyboard.IsReturnOrEnterKeyPressed(e))
{
isEnterKeyPressed = true;
}
string result = DropDownTextField.DoDropDownTextField(
text,
DROPDOWN_CONTROL_NAME,
options,
selectServerAction,
GUILayout.Width(DROPDOWN_WIDTH));
if (isEnterKeyPressed &&
GUI.GetNameOfFocusedControl() == DROPDOWN_CONTROL_NAME)
{
e.Use();
enterKeyAction();
}
return result;
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
void DoOkButton()
{
if (!AcceptButton(PlasticLocalization.GetString(
PlasticLocalization.Name.OkButton)))
return;
OkButtonAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
static RepositoryExplorerDialog Create(
IPlasticWebRestApi plasticWebRestApi,
ProgressControlsForDialogs progressControls,
string defaultServer,
GuiMessage.IGuiMessage guiMessage)
{
var instance = CreateInstance<RepositoryExplorerDialog>();
instance.mGuiMessage = guiMessage;
instance.mEscapeKeyAction = instance.CancelButtonAction;
instance.mProgressControls = progressControls;
instance.BuildComponents(defaultServer, plasticWebRestApi);
return instance;
}
void BuildComponents(
string defaultServer,
IPlasticWebRestApi plasticWebRestApi)
{
mSearchField = new SearchField();
mSearchField.downOrUpArrowKeyPressed += SearchField_OnDownOrUpArrowKeyPressed;
RepositoriesListHeaderState headerState =
RepositoriesListHeaderState.GetDefault();
TreeHeaderSettings.Load(headerState,
UnityConstants.REPOSITORIES_TABLE_SETTINGS_NAME,
(int)RepositoriesListColumn.Name);
mRepositoriesListView = new RepositoriesListView(
headerState,
RepositoriesListHeaderState.GetColumnNames(),
OkButtonAction);
mRepositoriesListView.Reload();
mFillRepositoriesTable = new FillRepositoriesTable(
new LocalRepositoriesProvider());
mState = new State()
{
Server = defaultServer,
ProgressData = new ProgressControlsForDialogs.Data()
};
KnownServersListOperations.GetCombinedServers(
true,
new List<string>(),
mProgressControls,
this,
plasticWebRestApi,
CmConnection.Get().GetProfileManager());
}
SearchField mSearchField;
RepositoriesListView mRepositoriesListView;
ProgressControlsForDialogs mProgressControls;
FillRepositoriesTable mFillRepositoriesTable;
State mState;
GuiMessage.IGuiMessage mGuiMessage;
const string DROPDOWN_CONTROL_NAME = "RepositoryExplorerDialog.ServerDropdown";
const float DROPDOWN_WIDTH = 250;
const float SEARCH_FIELD_WIDTH = 450;
class State
{
internal List<string> AvailableServers { get; set; }
internal string Server { get; set; }
internal ProgressControlsForDialogs.Data ProgressData { get; set; }
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment