mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-27 02:56:01 +01:00
Simplified the logic updating the TabPages.
- The new logic of adding/removing tabs in the ChangeToNewTabs method also fixes tab-title flickering when we move from the Home node to a disconnected host. - Renamed enum members Tab.Overview to Tab.Search and Tab.Settings to Tab.General since the pages mapped to them are TabPageSearch and TabPageGeneral respectively. - Do not call directly UpdateToolbarsCore but rather UpdateToolbars since the latter takes account of the queued requested updates. Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
This commit is contained in:
parent
b267007bdc
commit
edea57ebf3
@ -663,7 +663,7 @@ namespace XenAdmin.Controls.XenSearch
|
||||
{
|
||||
if (Program.MainWindow.SelectObject(ixmo)
|
||||
&& Program.MainWindow.TheTabControl.TabPages.Contains(Program.MainWindow.TabPageGeneral))
|
||||
Program.MainWindow.SwitchToTab(MainWindow.Tab.Settings);
|
||||
Program.MainWindow.SwitchToTab(MainWindow.Tab.General);
|
||||
};
|
||||
GridImageItem _statusItem = new GridImageItem(
|
||||
"foo",
|
||||
|
@ -73,11 +73,9 @@ namespace XenAdmin.Dialogs
|
||||
vm.Locked = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (Program.MainWindow.SelectObject(vm))
|
||||
{
|
||||
// Select VM's settings (a.k.a. 'general') tab
|
||||
if (Program.MainWindow.SelectObject(this.vm))
|
||||
Program.MainWindow.SwitchToTab(MainWindow.Tab.Settings);
|
||||
Program.MainWindow.SwitchToTab(MainWindow.Tab.General);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +106,7 @@ namespace XenAdmin
|
||||
internal readonly UsbPage UsbPage = new UsbPage();
|
||||
|
||||
private ActionBase statusBarAction = null;
|
||||
|
||||
private bool IgnoreTabChanges = false;
|
||||
private bool ToolbarsEnabled;
|
||||
|
||||
@ -337,10 +338,6 @@ namespace XenAdmin
|
||||
// Using the Load event ensures that the handle has been
|
||||
// created:
|
||||
base.OnLoad(e);
|
||||
|
||||
NewTabs[0] = TabPageHome;
|
||||
NewTabCount = 1;
|
||||
ChangeToNewTabs();
|
||||
}
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
@ -1349,12 +1346,18 @@ namespace XenAdmin
|
||||
{
|
||||
ToolStrip.ResumeLayout();
|
||||
}
|
||||
|
||||
// Save and restore focus on treeView, since selecting tabs in ChangeToNewTabs() has the
|
||||
// unavoidable side-effect of giving them focus - this is irritating if trying to navigate
|
||||
// the tree using the keyboard.
|
||||
|
||||
navigationPane.SaveAndRestoreTreeViewFocus(ChangeToNewTabs);
|
||||
}
|
||||
|
||||
private static int TOOLBAR_HEIGHT = 31;
|
||||
|
||||
/// <summary>
|
||||
/// Updates the toolbar buttons. Also updates which tabs are visible.
|
||||
/// Updates the toolbar buttons.
|
||||
/// </summary>
|
||||
private void UpdateToolbarsCore()
|
||||
{
|
||||
@ -1384,7 +1387,10 @@ namespace XenAdmin
|
||||
|
||||
ForceRebootToolbarButton.Available = ((ForceVMRebootCommand)ForceRebootToolbarButton.Command).ShowOnMainToolBar;
|
||||
ForceShutdownToolbarButton.Available = ((ForceVMShutDownCommand)ForceShutdownToolbarButton.Command).ShowOnMainToolBar;
|
||||
}
|
||||
|
||||
private List<TabPage> GetNewTabPages()
|
||||
{
|
||||
IXenConnection selectionConnection = SelectionManager.Selection.GetConnectionOfFirstItem();
|
||||
Pool selectionPool = selectionConnection == null ? null : Helpers.GetPool(selectionConnection);
|
||||
|
||||
@ -1412,21 +1418,46 @@ namespace XenAdmin
|
||||
|
||||
bool selectedTemplateHasProvisionXML = SelectionManager.Selection.FirstIsTemplate && ((VM)SelectionManager.Selection[0].XenObject).HasProvisionXML();
|
||||
|
||||
NewTabCount = 0;
|
||||
ShowTab(TabPageHome, !SearchMode && show_home);
|
||||
ShowTab(TabPageGeneral, !multi && !SearchMode && (isVMSelected || (isHostSelected && (isHostLive || !is_connected)) || isPoolSelected || isSRSelected || isVdiSelected || isDockerContainerSelected));
|
||||
ShowTab(TabPageBallooning, !multi && !SearchMode && (isVMSelected || (isHostSelected && isHostLive) || isPoolSelected));
|
||||
ShowTab(TabPageStorage, !multi && !SearchMode && (isRealVMSelected || (isTemplateSelected && !selectedTemplateHasProvisionXML)));
|
||||
ShowTab(TabPageSR, !multi && !SearchMode && isSRSelected);
|
||||
ShowTab(TabPagePhysicalStorage, !multi && !SearchMode && ((isHostSelected && isHostLive) || isPoolSelected));
|
||||
ShowTab(TabPageNetwork, !multi && !SearchMode && (isVMSelected || (isHostSelected && isHostLive) || isPoolSelected));
|
||||
ShowTab(TabPageNICs, !multi && !SearchMode && ((isHostSelected && isHostLive)));
|
||||
ShowTab(TabPageDockerProcess, !multi && !SearchMode && isDockerContainerSelected && !(SelectionManager.Selection.First as DockerContainer).Parent.IsWindows());
|
||||
ShowTab(TabPageDockerDetails, !multi && !SearchMode && isDockerContainerSelected);
|
||||
var newTabs = new List<TabPage>();
|
||||
|
||||
if (!SearchMode && show_home)
|
||||
newTabs.Add(TabPageHome);
|
||||
|
||||
if (!multi && !SearchMode && (isVMSelected || (isHostSelected && (isHostLive || !is_connected)) ||
|
||||
isPoolSelected || isSRSelected || isVdiSelected || isDockerContainerSelected))
|
||||
newTabs.Add(TabPageGeneral);
|
||||
|
||||
if (!multi && !SearchMode && (isVMSelected || (isHostSelected && isHostLive) || isPoolSelected))
|
||||
newTabs.Add(TabPageBallooning);
|
||||
|
||||
if (!multi && !SearchMode && (isRealVMSelected || (isTemplateSelected && !selectedTemplateHasProvisionXML)))
|
||||
newTabs.Add(TabPageStorage);
|
||||
|
||||
if (!multi && !SearchMode && isSRSelected)
|
||||
newTabs.Add(TabPageSR);
|
||||
|
||||
if (!multi && !SearchMode && ((isHostSelected && isHostLive) || isPoolSelected))
|
||||
newTabs.Add(TabPagePhysicalStorage);
|
||||
|
||||
if (!multi && !SearchMode && (isVMSelected || (isHostSelected && isHostLive) || isPoolSelected))
|
||||
newTabs.Add(TabPageNetwork);
|
||||
|
||||
if (!multi && !SearchMode && isHostSelected && isHostLive)
|
||||
newTabs.Add(TabPageNICs);
|
||||
|
||||
if (!multi && !SearchMode && isDockerContainerSelected && !(SelectionManager.Selection.First as DockerContainer).Parent.IsWindows())
|
||||
newTabs.Add(TabPageDockerProcess);
|
||||
|
||||
if (!multi && !SearchMode && isDockerContainerSelected)
|
||||
newTabs.Add(TabPageDockerDetails);
|
||||
|
||||
bool isPoolOrLiveStandaloneHost = isPoolSelected || (isHostSelected && isHostLive && selectionPool == null);
|
||||
ShowTab(TabPageGPU, !multi && !SearchMode && ((isHostSelected && isHostLive) || isPoolOrLiveStandaloneHost) && Helpers.ClearwaterSp1OrGreater(selectionConnection) && !Helpers.FeatureForbidden(selectionConnection, Host.RestrictGpu));
|
||||
ShowTab(TabPageUSB, !multi && !SearchMode && (isHostSelected && isHostLive && (((Host)SelectionManager.Selection.First).PUSBs.Count > 0)) && !Helpers.FeatureForbidden(selectionConnection, Host.RestrictUsbPassthrough));
|
||||
|
||||
if (!multi && !SearchMode && ((isHostSelected && isHostLive) || isPoolOrLiveStandaloneHost) && Helpers.ClearwaterSp1OrGreater(selectionConnection) && !Helpers.FeatureForbidden(selectionConnection, Host.RestrictGpu))
|
||||
newTabs.Add(TabPageGPU);
|
||||
|
||||
if (!multi && !SearchMode && (isHostSelected && isHostLive && (((Host)SelectionManager.Selection.First).PUSBs.Count > 0)) && !Helpers.FeatureForbidden(selectionConnection, Host.RestrictUsbPassthrough))
|
||||
newTabs.Add(TabPageUSB);
|
||||
|
||||
var consoleFeatures = new List<TabPageFeature>();
|
||||
var otherFeatures = new List<TabPageFeature>();
|
||||
@ -1435,35 +1466,43 @@ namespace XenAdmin
|
||||
GetFeatureTabPages(SelectionManager.Selection.FirstAsXenObject, out consoleFeatures, out otherFeatures);
|
||||
|
||||
foreach (var f in consoleFeatures)
|
||||
ShowTab(f.TabPage, true);
|
||||
newTabs.Add(f.TabPage);
|
||||
|
||||
ShowTab(TabPageConsole, consoleFeatures.Count == 0 && !multi && !SearchMode && (isRealVMSelected || (isHostSelected && isHostLive)));
|
||||
ShowTab(TabPageCvmConsole, consoleFeatures.Count == 0 && !multi && !SearchMode && isHostLive && hasManyControlDomains);
|
||||
ShowTab(TabPagePeformance, !multi && !SearchMode && (isRealVMSelected || (isHostSelected && isHostLive)));
|
||||
ShowTab(ha_upsell ? TabPageHAUpsell : TabPageHA, !multi && !SearchMode && isPoolSelected);
|
||||
ShowTab(TabPageSnapshots, !multi && !SearchMode && isRealVMSelected);
|
||||
if (consoleFeatures.Count == 0 && !multi && !SearchMode && (isRealVMSelected || (isHostSelected && isHostLive)))
|
||||
newTabs.Add(TabPageConsole);
|
||||
|
||||
if (consoleFeatures.Count == 0 && !multi && !SearchMode && isHostLive && hasManyControlDomains)
|
||||
newTabs.Add(TabPageCvmConsole);
|
||||
|
||||
if (!multi && !SearchMode && (isRealVMSelected || (isHostSelected && isHostLive)))
|
||||
newTabs.Add(TabPagePeformance);
|
||||
|
||||
if (!multi && !SearchMode && isPoolSelected)
|
||||
newTabs.Add(ha_upsell ? TabPageHAUpsell : TabPageHA);
|
||||
|
||||
if(!multi && !SearchMode && isRealVMSelected)
|
||||
newTabs.Add(TabPageSnapshots);
|
||||
|
||||
//Any Clearwater XenServer, or WLB is not licensed on XenServer, the WLB tab and any WLB menu items disappear completely.
|
||||
if(!(SelectionManager.Selection.All(s => Helpers.IsClearwater(s.Connection)) || wlb_upsell ))
|
||||
ShowTab(TabPageWLB, !multi && !SearchMode && isPoolSelected);
|
||||
if (!(SelectionManager.Selection.All(s => Helpers.IsClearwater(s.Connection)) || wlb_upsell)
|
||||
&& !multi && !SearchMode && isPoolSelected)
|
||||
newTabs.Add(TabPageWLB);
|
||||
|
||||
ShowTab(ad_upsell ? TabPageADUpsell : TabPageAD, !multi && !SearchMode && (isPoolSelected || isHostSelected && isHostLive));
|
||||
if (!multi && !SearchMode && (isPoolSelected || isHostSelected && isHostLive))
|
||||
newTabs.Add(ad_upsell ? TabPageADUpsell : TabPageAD);
|
||||
|
||||
ShowTab(TabPagePvs, !multi && !SearchMode && isPoolOrLiveStandaloneHost && !Helpers.FeatureForbidden(SelectionManager.Selection.FirstAsXenObject, Host.RestrictPvsCache)
|
||||
&& Helpers.PvsCacheCapability(selectionConnection));
|
||||
if (!multi && !SearchMode && isPoolOrLiveStandaloneHost && !Helpers.FeatureForbidden(SelectionManager.Selection.FirstAsXenObject, Host.RestrictPvsCache)
|
||||
&& Helpers.PvsCacheCapability(selectionConnection))
|
||||
newTabs.Add(TabPagePvs);
|
||||
|
||||
foreach (var f in otherFeatures)
|
||||
ShowTab(f.TabPage, true);
|
||||
newTabs.Add(f.TabPage);
|
||||
|
||||
ShowTab(TabPageSearch, true);
|
||||
newTabs.Add(TabPageSearch);
|
||||
|
||||
// N.B. Change NewTabs definition if you add more tabs here.
|
||||
|
||||
// Save and restore focus on treeView, since selecting tabs in ChangeToNewTabs() has the
|
||||
// unavoidable side-effect of giving them focus - this is irritating if trying to navigate
|
||||
// the tree using the keyboard.
|
||||
|
||||
navigationPane.SaveAndRestoreTreeViewFocus(ChangeToNewTabs);
|
||||
return newTabs;
|
||||
}
|
||||
|
||||
private void GetFeatureTabPages(IXenObject xenObject, out List<TabPageFeature> consoleFeatures, out List<TabPageFeature> otherFeatures)
|
||||
@ -1502,90 +1541,41 @@ namespace XenAdmin
|
||||
}
|
||||
}
|
||||
|
||||
private readonly TabPage[] NewTabs = new TabPage[512];
|
||||
int NewTabCount;
|
||||
private void ShowTab(TabPage page, bool visible)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
NewTabs[NewTabCount] = page;
|
||||
NewTabCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeToNewTabs()
|
||||
{
|
||||
TabPage new_selected_page = NewSelectedPage();
|
||||
var newTabs = GetNewTabPages();
|
||||
|
||||
var pageToSelect = GetLastSelectedPage(SelectionManager.Selection.First);
|
||||
if (pageToSelect != null && !newTabs.Contains(pageToSelect))
|
||||
pageToSelect = null;
|
||||
|
||||
TheTabControl.SuspendLayout();
|
||||
IgnoreTabChanges = true;
|
||||
|
||||
try
|
||||
{
|
||||
TabControl.TabPageCollection p = TheTabControl.TabPages;
|
||||
int i = 0; // Index into NewTabs
|
||||
int m = 0; // Index into p
|
||||
|
||||
while (i < NewTabCount)
|
||||
foreach (TabPage page in TheTabControl.TabPages)
|
||||
{
|
||||
if (m == p.Count)
|
||||
{
|
||||
p.Add(NewTabs[i]);
|
||||
if (new_selected_page == NewTabs[i])
|
||||
TheTabControl.SelectedTab = new_selected_page;
|
||||
m++;
|
||||
i++;
|
||||
}
|
||||
else if (p[m] == NewTabs[i])
|
||||
{
|
||||
if (new_selected_page == NewTabs[i])
|
||||
TheTabControl.SelectedTab = new_selected_page;
|
||||
m++;
|
||||
i++;
|
||||
}
|
||||
else if (NewTabs.Contains(p[m]))
|
||||
{
|
||||
p.Insert(m, NewTabs[i]);
|
||||
if (new_selected_page == NewTabs[i])
|
||||
TheTabControl.SelectedTab = new_selected_page;
|
||||
m++;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TheTabControl.SelectedTab == p[m] && new_selected_page == NewTabs[i])
|
||||
{
|
||||
// This clause is deliberately targeted at the case when you go from
|
||||
// Overview:Home to Host:Overview.
|
||||
p.Insert(m, NewTabs[i]);
|
||||
TheTabControl.SelectedTab = new_selected_page;
|
||||
m++;
|
||||
i++;
|
||||
}
|
||||
p.Remove(p[m]);
|
||||
}
|
||||
if (!newTabs.Contains(page))
|
||||
TheTabControl.TabPages.Remove(page);
|
||||
}
|
||||
|
||||
// Remove any tabs that are left at the end of the list.
|
||||
while (m < p.Count)
|
||||
int m = 0; // Index into TheTabControl.TabPages
|
||||
|
||||
foreach (var newTab in newTabs)
|
||||
{
|
||||
TabPage removed = p[p.Count - 1];
|
||||
p.Remove(removed);
|
||||
int index = NewTabsIndexOf(removed);
|
||||
if (index != -1)
|
||||
{
|
||||
// If this is a tab that we want, then we've got it in the list twice -- one
|
||||
// reference was here when we entered this function, and is the one that we're
|
||||
// pointing at now, and the other reference we've inserted through the loop above.
|
||||
// This is bad -- p.Remove(removed) above has now invalidated removed.Parent
|
||||
// (removed is still in the list through the other reference). Fix this up by
|
||||
// removing the other reference too and starting over.
|
||||
// We can't do the Remove call in the loop above, because this has a poor visual
|
||||
// effect.
|
||||
p.Remove(removed);
|
||||
p.Insert(index, removed);
|
||||
if (new_selected_page == removed)
|
||||
TheTabControl.SelectedTab = removed;
|
||||
}
|
||||
var index = TheTabControl.TabPages.IndexOf(newTab);
|
||||
if (index < 0)
|
||||
TheTabControl.TabPages.Insert(m, newTab);
|
||||
|
||||
m++;
|
||||
|
||||
if (newTab == pageToSelect)
|
||||
TheTabControl.SelectedTab = newTab;
|
||||
}
|
||||
|
||||
if (pageToSelect == null)
|
||||
TheTabControl.SelectedTab = TheTabControl.TabPages[0];
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -1596,17 +1586,6 @@ namespace XenAdmin
|
||||
}
|
||||
}
|
||||
|
||||
private TabPage NewSelectedPage()
|
||||
{
|
||||
Object o = SelectionManager.Selection.First;
|
||||
IXenObject s = o as IXenObject;
|
||||
|
||||
TabPage last_selected_page = GetLastSelectedPage(o);
|
||||
return last_selected_page != null && NewTabs.Contains(last_selected_page)
|
||||
? last_selected_page
|
||||
: NewTabs[0];
|
||||
}
|
||||
|
||||
private void SetLastSelectedPage(object o, TabPage p)
|
||||
{
|
||||
if (SearchMode)
|
||||
@ -1629,19 +1608,9 @@ namespace XenAdmin
|
||||
: selectedTabs.ContainsKey(o) ? selectedTabs[o] : null;
|
||||
}
|
||||
|
||||
private int NewTabsIndexOf(TabPage tp)
|
||||
{
|
||||
for (int i = 0; i < NewTabCount; i++)
|
||||
{
|
||||
if (NewTabs[i] == tp)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void pluginManager_PluginsChanged()
|
||||
{
|
||||
UpdateToolbarsCore();
|
||||
UpdateToolbars();
|
||||
|
||||
foreach (ToolStripMenuItem menu in MainMenuBar.Items)
|
||||
{
|
||||
@ -2123,20 +2092,17 @@ namespace XenAdmin
|
||||
/// </summary>
|
||||
public enum Tab
|
||||
{
|
||||
Overview, Home, Settings, Storage, Network, Console, CvmConsole, Performance, NICs, SR, DockerProcess, DockerDetails, USB
|
||||
Home, General, Storage, Network, Console, CvmConsole, Performance, NICs, SR, DockerProcess, DockerDetails, USB, Search
|
||||
}
|
||||
|
||||
public void SwitchToTab(Tab tab)
|
||||
{
|
||||
switch (tab)
|
||||
{
|
||||
case Tab.Overview:
|
||||
TheTabControl.SelectedTab = TabPageSearch;
|
||||
break;
|
||||
case Tab.Home:
|
||||
TheTabControl.SelectedTab = TabPageHome;
|
||||
break;
|
||||
case Tab.Settings:
|
||||
case Tab.General:
|
||||
TheTabControl.SelectedTab = TabPageGeneral;
|
||||
break;
|
||||
case Tab.Storage:
|
||||
@ -2169,6 +2135,9 @@ namespace XenAdmin
|
||||
case Tab.USB:
|
||||
TheTabControl.SelectedTab = TabPageUSB;
|
||||
break;
|
||||
case Tab.Search:
|
||||
TheTabControl.SelectedTab = TabPageSearch;
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@ -2857,7 +2826,7 @@ namespace XenAdmin
|
||||
|
||||
searchMode = value;
|
||||
navigationPane.InSearchMode = value;
|
||||
UpdateToolbarsCore();
|
||||
UpdateToolbars();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +266,7 @@ namespace XenAdmin.XenSearch
|
||||
{
|
||||
if (Program.MainWindow.SelectObject(o) && Program.MainWindow.TheTabControl.TabPages.Contains(Program.MainWindow.TabPageGeneral))
|
||||
{
|
||||
Program.MainWindow.SwitchToTab(MainWindow.Tab.Settings);
|
||||
Program.MainWindow.SwitchToTab(MainWindow.Tab.General);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user