A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections;
3using System.Collections.Generic;
4
5using UnityEditor;
6
7using Codice.Client.BaseCommands;
8using Codice.Client.Commands.CheckIn;
9using Codice.Client.Common;
10using Codice.Client.Common.Threading;
11using Codice.CM.Common;
12using Codice.CM.Common.Replication;
13using GluonGui.WorkspaceWindow.Views;
14using GluonGui;
15using GluonGui.WorkspaceWindow.Views.WorkspaceExplorer.Explorer;
16using PlasticGui;
17using PlasticGui.WorkspaceWindow;
18using PlasticGui.WorkspaceWindow.Topbar;
19using PlasticGui.WorkspaceWindow.Replication;
20using PlasticGui.WorkspaceWindow.Update;
21using Unity.PlasticSCM.Editor.AssetUtils;
22using Unity.PlasticSCM.Editor.Configuration;
23using Unity.PlasticSCM.Editor.Developer.UpdateReport;
24using Unity.PlasticSCM.Editor.UI;
25using Unity.PlasticSCM.Editor.UI.Progress;
26using Unity.PlasticSCM.Editor.UI.StatusBar;
27
28using IGluonUpdateReport = PlasticGui.Gluon.IUpdateReport;
29using IGluonWorkspaceStatusChangeListener = PlasticGui.Gluon.IWorkspaceStatusChangeListener;
30using GluonUpdateReportDialog = Unity.PlasticSCM.Editor.Gluon.UpdateReport.UpdateReportDialog;
31
32namespace Unity.PlasticSCM.Editor
33{
34 internal class WorkspaceWindow :
35 IWorkspaceWindow,
36 IRefreshView,
37 IUpdateReport,
38 IGluonUpdateReport,
39 IGluonWorkspaceStatusChangeListener
40 {
41 internal WorkspaceStatusString.Data WorkspaceStatus { get; private set; }
42 internal string ServerDisplayName { get; private set; }
43
44 internal OperationProgressData Progress { get { return mOperationProgressData; } }
45
46 internal IProgressOperationHandler DeveloperProgressOperationHandler
47 {
48 get { return mDeveloperProgressOperationHandler; }
49 }
50
51 internal Gluon.ProgressOperationHandler GluonProgressOperationHandler
52 {
53 get { return mGluonProgressOperationHandler; }
54 }
55
56 internal WorkspaceWindow(
57 WorkspaceInfo wkInfo,
58 ViewHost viewHost,
59 ViewSwitcher switcher,
60 StatusBar statusBar,
61 IMergeViewLauncher mergeViewLauncher,
62 NewIncomingChangesUpdater developerNewIncomingChangesUpdater,
63 ShelvedChangesUpdater shelvedChangesUpdater,
64 EditorWindow parentWindow)
65 {
66 mWkInfo = wkInfo;
67 mViewHost = viewHost;
68 mSwitcher = switcher;
69 mStatusBar = statusBar;
70 mMergeViewLauncher = mergeViewLauncher;
71 mDeveloperNewIncomingChangesUpdater = developerNewIncomingChangesUpdater;
72 mShelvedChangesUpdater = shelvedChangesUpdater;
73 mPlasticWindow = parentWindow;
74 mGuiMessage = new UnityPlasticGuiMessage();
75
76 mDeveloperProgressOperationHandler = new Developer.ProgressOperationHandler(mWkInfo, this);
77 mGluonProgressOperationHandler = new Gluon.ProgressOperationHandler(this);
78 mOperationProgressData = new OperationProgressData();
79
80 ((IWorkspaceWindow)this).UpdateTitle();
81 }
82
83 internal void SetUpdateNotifierForTesting(UpdateNotifier updateNotifier)
84 {
85 mUpdateNotifierForTesting = updateNotifier;
86 }
87
88 internal void RegisterPendingChangesProgressControls(
89 ProgressControlsForViews progressControls)
90 {
91 mProgressControls = progressControls;
92 }
93
94 internal bool IsOperationInProgress()
95 {
96 return mDeveloperProgressOperationHandler.IsOperationInProgress()
97 || mGluonProgressOperationHandler.IsOperationInProgress();
98 }
99
100 internal void CancelCurrentOperation()
101 {
102 if (mDeveloperProgressOperationHandler.IsOperationInProgress())
103 {
104 mDeveloperProgressOperationHandler.CancelCheckinProgress();
105 return;
106 }
107
108 if (mGluonProgressOperationHandler.IsOperationInProgress())
109 {
110 mGluonProgressOperationHandler.CancelUpdateProgress();
111 return;
112 }
113 }
114
115 internal void OnParentUpdated(double elapsedSeconds)
116 {
117 if (IsOperationInProgress() || mRequestedRepaint)
118 {
119 if (mDeveloperProgressOperationHandler.IsOperationInProgress())
120 mDeveloperProgressOperationHandler.Update(elapsedSeconds);
121
122 mPlasticWindow.Repaint();
123
124 mRequestedRepaint = false;
125 }
126 }
127
128 internal void RequestRepaint()
129 {
130 mRequestedRepaint = true;
131 }
132
133 internal void UpdateWorkspace()
134 {
135 UpdateWorkspaceOperation update = new UpdateWorkspaceOperation(
136 mWkInfo, this, mSwitcher, mMergeViewLauncher, this,
137 mDeveloperNewIncomingChangesUpdater,
138 mShelvedChangesUpdater,
139 null);
140
141 update.Run(
142 UpdateWorkspaceOperation.UpdateType.UpdateToLatest,
143 RefreshAsset.UnityAssetDatabase,
144 ShowWorkspaceUpdateSuccess);
145 }
146
147 internal void UpdateWorkspaceForMode(bool isGluonMode)
148 {
149 if (isGluonMode)
150 {
151 PartialUpdateWorkspace();
152 return;
153 }
154
155 UpdateWorkspace();
156 }
157
158 void IWorkspaceWindow.RefreshView(ViewType viewType)
159 {
160 mSwitcher.RefreshView(viewType);
161 }
162
163 void IWorkspaceWindow.RefreshWorkingObjectViews(
164 ViewType viewType,
165 WorkingObjectInfo workingObjectInfo)
166 {
167 mSwitcher.RefreshWorkingObjectInfoForSelectedView(
168 viewType,
169 workingObjectInfo);
170 }
171
172 void IWorkspaceWindow.UpdateTitle()
173 {
174 RefreshWorkspaceStatus();
175 }
176
177 bool IWorkspaceWindow.IsOperationInProgress()
178 {
179 return IsOperationInProgress();
180 }
181
182 bool IWorkspaceWindow.CheckOperationInProgress()
183 {
184 return ((IProgressOperationHandler)mDeveloperProgressOperationHandler).CheckOperationInProgress();
185 }
186
187 void IWorkspaceWindow.ShowUpdateProgress(string title, UpdateNotifier notifier)
188 {
189 mDeveloperProgressOperationHandler.ShowUpdateProgress(title, mUpdateNotifierForTesting ?? notifier);
190 }
191
192 void IWorkspaceWindow.EndUpdateProgress()
193 {
194 mDeveloperProgressOperationHandler.EndUpdateProgress();
195 }
196
197 void IWorkspaceWindow.ShowCheckinProgress()
198 {
199 mDeveloperProgressOperationHandler.ShowCheckinProgress();
200 }
201
202 void IWorkspaceWindow.EndCheckinProgress()
203 {
204 mDeveloperProgressOperationHandler.EndCheckinProgress();
205 }
206
207 void IWorkspaceWindow.RefreshCheckinProgress(
208 CheckinStatus checkinStatus,
209 BuildProgressSpeedAndRemainingTime.ProgressData progressData)
210 {
211 mDeveloperProgressOperationHandler.
212 RefreshCheckinProgress(checkinStatus, progressData);
213 }
214
215 bool IWorkspaceWindow.HasCheckinCancelled()
216 {
217 return mDeveloperProgressOperationHandler.HasCheckinCancelled();
218 }
219
220 void IWorkspaceWindow.ShowReplicationProgress(
221 IReplicationOperation replicationOperation)
222 {
223 throw new NotImplementedException();
224 }
225
226 void IWorkspaceWindow.RefreshReplicationProgress(
227 BranchReplicationData replicationData,
228 ReplicationStatus replicationStatus,
229 int current,
230 int total)
231 {
232 throw new NotImplementedException();
233 }
234
235 void IWorkspaceWindow.EndReplicationProgress(ReplicationStatus replicationStatus)
236 {
237 throw new NotImplementedException();
238 }
239
240 void IWorkspaceWindow.ShowProgress()
241 {
242 mDeveloperProgressOperationHandler.ShowProgress();
243 }
244
245 void IWorkspaceWindow.ShowProgress(IProgressOperation progressOperation)
246 {
247 throw new NotImplementedException();
248 }
249
250 void IWorkspaceWindow.RefreshProgress(ProgressData progressData)
251 {
252 mDeveloperProgressOperationHandler.RefreshProgress(progressData);
253 }
254
255 void IWorkspaceWindow.EndProgress()
256 {
257 mDeveloperProgressOperationHandler.EndProgress();
258 }
259
260 EncryptionConfigurationDialogData IWorkspaceWindow.RequestEncryptionPassword(string server)
261 {
262 return EncryptionConfigurationDialog.RequestEncryptionPassword(server, mPlasticWindow);
263 }
264
265 void IWorkspaceWindow.RegisterView(
266 ViewType type,
267 IDisposable disposable,
268 IRefreshableView refreshable,
269 IWorkingObjectRefreshableView workingObjectRefreshableView)
270 {
271 }
272
273 void IWorkspaceWindow.UnregisterView(
274 ViewType type,
275 IDisposable disposable,
276 IRefreshableView refreshable,
277 IWorkingObjectRefreshableView workingObjectRefreshableView)
278 {
279 }
280
281 List<IDisposable> IWorkspaceWindow.GetRegisteredViews()
282 {
283 return new List<IDisposable>();
284 }
285
286 void IRefreshView.ForType(ViewType viewType)
287 {
288 mSwitcher.RefreshView(viewType);
289 }
290
291 void IUpdateReport.Show(WorkspaceInfo wkInfo, IList reportLines)
292 {
293 UpdateReportDialog.ShowReportDialog(
294 wkInfo,
295 reportLines,
296 mPlasticWindow);
297 }
298
299 void IGluonUpdateReport.AppendReport(string updateReport)
300 {
301 }
302
303 void IGluonWorkspaceStatusChangeListener.OnWorkspaceStatusChanged()
304 {
305 RefreshWorkspaceStatus();
306 RefreshWorkingObject();
307 }
308
309 UpdateReportResult IGluonUpdateReport.ShowUpdateReport(
310 WorkspaceInfo wkInfo, List<ErrorMessage> errors)
311 {
312 return GluonUpdateReportDialog.ShowUpdateReport(
313 wkInfo, errors, mPlasticWindow);
314 }
315
316 void ShowWorkspaceUpdateSuccess()
317 {
318 mStatusBar.Notify(
319 new GUIContentNotification(
320 PlasticLocalization.Name.WorkspaceUpdateCompleted.GetString()),
321 MessageType.None,
322 Images.GetStepOkIcon());
323 }
324
325 void RefreshWorkspaceStatus()
326 {
327 WorkspaceStatusString.Data status = null;
328
329 IThreadWaiter waiter = ThreadWaiter.GetWaiter();
330 waiter.Execute(
331 /*threadOperationDelegate*/ delegate
332 {
333 status = WorkspaceStatusString.GetSelectorData(mWkInfo);
334 },
335 /*afterOperationDelegate*/ delegate
336 {
337 if (waiter.Exception != null)
338 return;
339
340 WorkspaceStatus = status;
341
342 ServerDisplayName = ResolveServer.ToDisplayString(status.Server);
343
344 RequestRepaint();
345 });
346 }
347
348 void RefreshWorkingObject()
349 {
350 // For partial workspaces the calculation of the working object is just
351 // supported for branches, not for changesets
352 if (mSwitcher.State.SelectedTab != ViewSwitcher.SelectedTab.Branches)
353 return;
354
355 WorkingObjectInfo workingObjectInfo = null;
356
357 IThreadWaiter waiter = ThreadWaiter.GetWaiter();
358 waiter.Execute(
359 /*threadOperationDelegate*/ delegate
360 {
361 workingObjectInfo = WorkingObjectInfo.Calculate(mWkInfo);
362 },
363 /*afterOperationDelegate*/ delegate
364 {
365 if (waiter.Exception != null)
366 return;
367
368 mSwitcher.BranchesTab.SetWorkingObjectInfo(workingObjectInfo);
369 });
370 }
371
372 void PartialUpdateWorkspace()
373 {
374 mProgressControls.ShowProgress(PlasticLocalization.GetString(
375 PlasticLocalization.Name.UpdatingWorkspace));
376
377 ((IUpdateProgress)mGluonProgressOperationHandler).ShowCancelableProgress();
378
379 OutOfDateUpdater outOfDateUpdater = new OutOfDateUpdater(mWkInfo, null);
380
381 BuildProgressSpeedAndRemainingTime.ProgressData progressData =
382 new BuildProgressSpeedAndRemainingTime.ProgressData(DateTime.Now);
383
384 IThreadWaiter waiter = ThreadWaiter.GetWaiter();
385 waiter.Execute(
386 /*threadOperationDelegate*/ delegate
387 {
388 outOfDateUpdater.Execute();
389 },
390 /*afterOperationDelegate*/ delegate
391 {
392 mProgressControls.HideProgress();
393
394 ((IUpdateProgress)mGluonProgressOperationHandler).EndProgress();
395
396 mViewHost.RefreshView(ViewType.CheckinView);
397 mViewHost.RefreshView(ViewType.IncomingChangesView);
398
399 RefreshAsset.UnityAssetDatabase();
400
401 if (waiter.Exception != null)
402 {
403 ExceptionsHandler.DisplayException(waiter.Exception);
404 return;
405 }
406
407 ShowUpdateReportDialog(
408 mWkInfo, mViewHost, outOfDateUpdater.Progress, mProgressControls,
409 mGuiMessage, mGluonProgressOperationHandler, this);
410 },
411 /*timerTickDelegate*/ delegate
412 {
413 UpdateProgress progress = outOfDateUpdater.Progress;
414
415 if (progress == null)
416 return;
417
418 if (progress.IsCanceled)
419 {
420 mProgressControls.ShowNotification(
421 PlasticLocalization.GetString(PlasticLocalization.Name.Canceling));
422 }
423
424 ((IUpdateProgress)mGluonProgressOperationHandler).RefreshProgress(
425 progress,
426 UpdateProgressDataCalculator.CalculateProgressForWorkspaceUpdate(
427 mWkInfo.ClientPath, progress, progressData));
428 });
429 }
430
431 static void ShowUpdateReportDialog(
432 WorkspaceInfo wkInfo,
433 ViewHost viewHost,
434 UpdateProgress progress,
435 IProgressControls progressControls,
436 GuiMessage.IGuiMessage guiMessage,
437 IUpdateProgress updateProgress,
438 IGluonUpdateReport updateReport)
439 {
440 if (progress.ErrorMessages.Count == 0)
441 return;
442
443 UpdateReportResult updateReportResult =
444 updateReport.ShowUpdateReport(wkInfo, progress.ErrorMessages);
445
446 if (!updateReportResult.IsUpdateForcedRequested())
447 return;
448
449 UpdateForcedOperation updateForced = new UpdateForcedOperation(
450 wkInfo, viewHost, progress, progressControls,
451 guiMessage, updateProgress, updateReport);
452
453 updateForced.UpdateForced(
454 updateReportResult.UpdateForcedPaths,
455 updateReportResult.UnaffectedErrors);
456 }
457
458 bool mRequestedRepaint;
459
460 UpdateNotifier mUpdateNotifierForTesting;
461 IProgressControls mProgressControls;
462
463 readonly OperationProgressData mOperationProgressData;
464 readonly Developer.ProgressOperationHandler mDeveloperProgressOperationHandler;
465 readonly Gluon.ProgressOperationHandler mGluonProgressOperationHandler;
466 readonly GuiMessage.IGuiMessage mGuiMessage;
467 readonly EditorWindow mPlasticWindow;
468 readonly NewIncomingChangesUpdater mDeveloperNewIncomingChangesUpdater;
469 readonly ShelvedChangesUpdater mShelvedChangesUpdater;
470 readonly IMergeViewLauncher mMergeViewLauncher;
471 readonly ViewSwitcher mSwitcher;
472 readonly StatusBar mStatusBar;
473 readonly ViewHost mViewHost;
474 readonly WorkspaceInfo mWkInfo;
475 }
476}