From f315788df5c22a18f3a02ce2cd431b4ac346fcab Mon Sep 17 00:00:00 2001
From: Fons Rademakers <Fons.Rademakers@cern.ch>
Date: Tue, 6 May 2008 14:29:46 +0000
Subject: [PATCH] From Bertrand: - Added information on the types of volumes
 returned by   TWinNTSystem::GetVolumes():   - Type of drive: local,
 removable, network, CD/DVD   - File System: NTFS, AFS, NFS - Adapted
 TGFSCombobox and TGFileBrowser accordingly to these new info - Added two new
 icons to represent Network drives on Windows

git-svn-id: http://root.cern.ch/svn/root/trunk@23664 27541ba8-7e3a-0410-8455-c3a389f83636
---
 core/winnt/src/TWinNTSystem.cxx  | 64 ++++++++++++++++++++++++++++++--
 gui/gui/src/TGFSComboBox.cxx     | 62 +++++++++++++++++++++++--------
 gui/gui/src/TGFileBrowser.cxx    | 40 +++++++++++++++-----
 gui/gui/src/TRootBrowserLite.cxx |  2 +-
 icons/netdisk_s.xpm              | 55 +++++++++++++++++++++++++++
 icons/netdisk_t.xpm              | 39 +++++++++++++++++++
 6 files changed, 234 insertions(+), 28 deletions(-)
 create mode 100644 icons/netdisk_s.xpm
 create mode 100644 icons/netdisk_t.xpm

diff --git a/core/winnt/src/TWinNTSystem.cxx b/core/winnt/src/TWinNTSystem.cxx
index 068c027a302..a1e955c60ed 100644
--- a/core/winnt/src/TWinNTSystem.cxx
+++ b/core/winnt/src/TWinNTSystem.cxx
@@ -1928,26 +1928,84 @@ TList *TWinNTSystem::GetVolumes(Option_t *opt) const
    // Get list of volumes (drives) mounted on the system.
    // The returned TList must be deleted by the user using "delete".
 
-   int drive, curdrive;
+   Int_t   drive, curdrive;
+   UInt_t  type;
+   TString sDrive, sType;
+   char    szFs[32];
 
    if (!opt || !strlen(opt)) {
       return 0;
    }
+
    TList *drives = new TList();
    drives->SetOwner();
    // Save current drive
    curdrive = _getdrive();
    if (strstr(opt, "cur")) {
-      drives->Add(new TObjString(Form("%c:", (curdrive + 'A' - 1))));
+      *szFs='\0';
+      sDrive.Form("%c:", (curdrive + 'A' - 1));
+      sType.Form("Unknown Drive (%s)", sDrive.Data());
+      GetVolumeInformation(Form("%s\\", sDrive.Data()), NULL, 0, NULL, NULL, 
+                           NULL, (LPSTR)szFs, 32);
+      type = ::GetDriveType(sDrive.Data());
+      switch (type) {
+         case DRIVE_UNKNOWN:
+         case DRIVE_NO_ROOT_DIR:
+            break;
+         case DRIVE_REMOVABLE:
+            sType.Form("Removable Disk (%s)", sDrive.Data());
+            break;
+         case DRIVE_FIXED:
+            sType.Form("Local Disk (%s)", sDrive.Data());
+            break;
+         case DRIVE_REMOTE:
+            sType.Form("Network Drive (%s) (%s)", szFs, sDrive.Data());
+            break;
+         case DRIVE_CDROM:
+            sType.Form("CD/DVD Drive (%s)", sDrive.Data());
+            break;
+         case DRIVE_RAMDISK:
+            sType.Form("RAM Disk (%s)", sDrive.Data());
+            break;
+      }
+      drives->Add(new TNamed(sDrive.Data(), sType.Data()));
    }
    else if (strstr(opt, "all")) {
       // If we can switch to the drive, it exists
       // but skip floppy drives...
+      UINT nOldErrorMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); 
       for( drive = 3; drive <= 26; ++drive ) {
          if( !_chdrive( drive ) ) {
-            drives->Add(new TObjString(Form("%c:", (drive + 'A' - 1))));
+            *szFs='\0';
+            sDrive.Form("%c:", (drive + 'A' - 1));
+            sType.Form("Unknown Drive (%s)", sDrive.Data());
+            GetVolumeInformation(Form("%s\\", sDrive.Data()), NULL, 0, NULL,
+                                 NULL, NULL, (LPSTR)szFs, 32);
+            type = ::GetDriveType(sDrive.Data());
+            switch (type) {
+               case DRIVE_UNKNOWN:
+               case DRIVE_NO_ROOT_DIR:
+                  break;
+               case DRIVE_REMOVABLE:
+                  sType.Form("Removable Disk (%s)", sDrive.Data());
+                  break;
+               case DRIVE_FIXED:
+                  sType.Form("Local Disk (%s)", sDrive.Data());
+                  break;
+               case DRIVE_REMOTE:
+                  sType.Form("Network Drive (%s) (%s)", szFs, sDrive.Data());
+                  break;
+               case DRIVE_CDROM:
+                  sType.Form("CD/DVD Drive (%s)", sDrive.Data());
+                  break;
+               case DRIVE_RAMDISK:
+                  sType.Form("RAM Disk (%s)", sDrive.Data());
+                  break;
+            }
+            drives->Add(new TNamed(sDrive.Data(), sType.Data()));
          }
       }
+      ::SetErrorMode(nOldErrorMode);
       // Restore original drive
       _chdrive( curdrive );
    }
diff --git a/gui/gui/src/TGFSComboBox.cxx b/gui/gui/src/TGFSComboBox.cxx
index e64fd7c7ce6..80290377583 100644
--- a/gui/gui/src/TGFSComboBox.cxx
+++ b/gui/gui/src/TGFSComboBox.cxx
@@ -35,7 +35,6 @@
 #include "TGResourcePool.h"
 #include "TGPicture.h"
 #include "TSystem.h"
-#include "TObjString.h"
 #include "Riostream.h"
 
 const TGFont *TGTreeLBEntry::fgDefaultFont = 0;
@@ -232,16 +231,39 @@ TGFSComboBox::TGFSComboBox(const TGWindow *parent, Int_t id, UInt_t options,
    Int_t idx = 0;
    TList *volumes = gSystem->GetVolumes("all");
    TList *curvol  = gSystem->GetVolumes("cur");
-   TString curdrive;
+   TString infos;
+   const char *curdrive = "";
    if (volumes && curvol) {
-      curdrive = ((TObjString *)(curvol->At(0)))->GetString();
-      gLbc[idx].fName = StrDup(Form("Drive %s", curdrive.Data()));
-      gLbc[idx].fPath = StrDup(Form("%s\\", curdrive.Data()));
-      gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
-      gLbc[idx].fId     = 1000;
-      gLbc[idx].fIndent = 0; 
-      gLbc[idx].fFlags  = 0;
-      ++idx;
+      TNamed *named = (TNamed *)curvol->At(0);
+      if (named) {
+         curdrive = named->GetName();
+         infos = named->GetTitle();
+         gLbc[idx].fName = StrDup(infos.Data());
+         gLbc[idx].fPath = StrDup(Form("%s\\", curdrive));
+         if (infos.Contains("Removable"))
+            gLbc[idx].fPixmap = StrDup("fdisk_t.xpm");
+         else if (infos.Contains("Local"))
+            gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
+         else if (infos.Contains("CD"))
+            gLbc[idx].fPixmap = StrDup("cdrom_t.xpm");
+         else if (infos.Contains("Network"))
+            gLbc[idx].fPixmap = StrDup("netdisk_t.xpm");
+         else
+            gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
+         gLbc[idx].fId     = 1000;
+         gLbc[idx].fIndent = 0; 
+         gLbc[idx].fFlags  = 0;
+         ++idx;
+      }
+      else {
+         gLbc[idx].fName = StrDup("Root");
+         gLbc[idx].fPath = StrDup("/");
+         gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
+         gLbc[idx].fId     = 1000;
+         gLbc[idx].fIndent = 1; 
+         gLbc[idx].fFlags  = 0;
+         ++idx;
+      }
    }
    else {
       gLbc[idx].fName = StrDup("Root");
@@ -288,13 +310,23 @@ TGFSComboBox::TGFSComboBox(const TGWindow *parent, Int_t id, UInt_t options,
 
    if (volumes && curvol) {
       TIter next(volumes);
-      TObjString *drive;
-      while ((drive = (TObjString *)next())) {
-         if (drive->GetString() == curdrive)
+      TNamed *drive;
+      while ((drive = (TNamed *)next())) {
+         if (!strcmp(drive->GetName(), curdrive))
             continue;
-         gLbc[idx].fName   = StrDup(Form("Drive %s", drive->GetName()));
+         infos = drive->GetTitle();
+         gLbc[idx].fName   = StrDup(drive->GetTitle());
          gLbc[idx].fPath   = StrDup(Form("%s\\", drive->GetName()));
-         gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
+         if (infos.Contains("Removable"))
+            gLbc[idx].fPixmap = StrDup("fdisk_t.xpm");
+         else if (infos.Contains("Local"))
+            gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
+         else if (infos.Contains("CD"))
+            gLbc[idx].fPixmap = StrDup("cdrom_t.xpm");
+         else if (infos.Contains("Network"))
+            gLbc[idx].fPixmap = StrDup("netdisk_t.xpm");
+         else
+            gLbc[idx].fPixmap = StrDup("hdisk_t.xpm");
          gLbc[idx].fId     = (idx+1) * 1000;
          gLbc[idx].fIndent = 0;
          gLbc[idx].fFlags  = 0;
diff --git a/gui/gui/src/TGFileBrowser.cxx b/gui/gui/src/TGFileBrowser.cxx
index 03ecff341bd..eadd61ac7c5 100644
--- a/gui/gui/src/TGFileBrowser.cxx
+++ b/gui/gui/src/TGFileBrowser.cxx
@@ -352,12 +352,18 @@ void TGFileBrowser::BrowseObj(TObject *obj)
       TList *volumes = gSystem->GetVolumes("all");
       TList *curvol  = gSystem->GetVolumes("cur");
       if (volumes && curvol) {
-         TString curdrive = ((TObjString *)(curvol->At(0)))->GetString();
+         const char *curdrive;
+         TNamed *named = (TNamed *)curvol->At(0);
+         if (named)
+            curdrive = named->GetName();
+         else
+            curdrive = StrDup("C:");
          TIter next(volumes);
-         TObjString *drive;
-         while ((drive = (TObjString *)next())) {
-            AddFSDirectory(Form("%s\\", drive->GetName()), 0, 
-                 (drive->GetString() == curdrive) ? "SetRootDir" : "Add");
+         TNamed *drive;
+         while ((drive = (TNamed *)next())) {
+            AddFSDirectory(Form("%s\\", drive->GetName()), drive->GetTitle(), 
+                           (strcmp(drive->GetName(), curdrive) == 0) ? 
+                           "SetRootDir" : "Add");
          }
          delete volumes;
          delete curvol;
@@ -491,19 +497,20 @@ void TGFileBrowser::Refresh(Bool_t /*force*/)
 /**************************************************************************/
 
 //______________________________________________________________________________
-void TGFileBrowser::AddFSDirectory(const char *entry, const char * /*path*/, 
+void TGFileBrowser::AddFSDirectory(const char *entry, const char *path, 
                                    Option_t *opt)
 {
    // Add file system directory in the list tree.
 
+   TGListTreeItem *item = 0;
    if ((opt == 0) || (strlen(opt) == 0)) {
       if (fRootDir == 0 && !fListTree->FindChildByName(0, rootdir))
-         fRootDir = fListTree->AddItem(0, rootdir);
+         item = fRootDir = fListTree->AddItem(0, rootdir);
       return;
    }
    if (strstr(opt, "SetRootDir")) {
       if (!fListTree->FindChildByName(0, entry))
-         fRootDir = fListTree->AddItem(0, entry);
+         item = fRootDir = fListTree->AddItem(0, entry);
    } 
    else if (strstr(opt, "Add")) {
       // MT: i give up! wanted to place entries for selected
@@ -511,7 +518,22 @@ void TGFileBrowser::AddFSDirectory(const char *entry, const char * /*path*/,
       // TGListTreeItem *lti = fListTree->AddItem(0, entry);
       //
       if (!fListTree->FindChildByName(0, entry))
-         fListTree->AddItem(0, entry);
+         item = fListTree->AddItem(0, entry);
+   }
+   if (item && path) {
+      TString infos = path;
+      item->SetTipText(path);
+      TGPicture *pic = 0;
+      if (infos.Contains("Removable"))
+         pic = (TGPicture *)gClient->GetPicture("fdisk_t.xpm");
+      else if (infos.Contains("Local"))
+         pic = (TGPicture *)gClient->GetPicture("hdisk_t.xpm");
+      else if (infos.Contains("CD"))
+         pic = (TGPicture *)gClient->GetPicture("cdrom_t.xpm");
+      else if (infos.Contains("Network"))
+         pic = (TGPicture *)gClient->GetPicture("netdisk_t.xpm");
+      if (pic)
+         item->SetPictures(pic, pic);
    }
 }
 
diff --git a/gui/gui/src/TRootBrowserLite.cxx b/gui/gui/src/TRootBrowserLite.cxx
index 69fe5377dda..dda778d15ef 100644
--- a/gui/gui/src/TRootBrowserLite.cxx
+++ b/gui/gui/src/TRootBrowserLite.cxx
@@ -1078,7 +1078,7 @@ void TRootBrowserLite::CreateBrowser(const char *name)
 
    fComboLayout = new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 0, 0, 2, 2);
    fToolBar->AddFrame(fFSComboBox, fComboLayout);
-   fFSComboBox->Resize(150, fFSComboBox->GetDefaultHeight());
+   fFSComboBox->Resize(190, fFSComboBox->GetDefaultHeight());
    fFSComboBox->Associate(this);
 
    int spacing = 8;
diff --git a/icons/netdisk_s.xpm b/icons/netdisk_s.xpm
new file mode 100644
index 00000000000..5c81e2e2539
--- /dev/null
+++ b/icons/netdisk_s.xpm
@@ -0,0 +1,55 @@
+/* XPM */
+static char *01netdisk_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"    32    32       16            1",
+/* colors */
+"` c None s None",
+". c #808080",
+"# c #a0a080",
+"a c #606040",
+"b c #000000",
+"c c #c0c0ff",
+"d c #808000",
+"e c #008000",
+"f c #c08000",
+"g c #ffc040",
+"h c #ffff00",
+"i c #00ff00",
+"j c #ffff80",
+"k c #206000",
+"l c #0060ff",
+"m c #006000",
+/* pixels */
+"````````````````````````````````",
+"````````````````````````````````",
+"````````````````````````````````",
+"````````````````````````````````",
+"````````````````````````````````",
+"````````````````````````````````",
+"````aaaaaaaaaaaaaaaaaaaaaaaaaa``",
+"```a.........................ab`",
+"``.#########################.ab`",
+"`.`````````````````````````#.ab`",
+"`.``cccccccccc########iie.##.ab`",
+"`.`cccccccccccc#######eek.##.ab`",
+"`.`ccccccccccc#########...##.ab`",
+"`.`caaaaaaaaaaaaaaaaaaaaa.##.ab`",
+"`.`c`````````````````````.##.ab`",
+"`.`caaaaaaaaaaaaaaaaaaaaa.##.ab`",
+"`.`c`````````````````````.##.ab`",
+"`.`#########################ab``",
+"`..........................ab```",
+"``bbbbbbbbbbbbbbbbbbbbbbbbbb````",
+"``````````````b.b```````````````",
+"``````````````.cb```````````````",
+"``````````````.cb```````````````",
+".`..........dddddb............`.",
+"c`ccccccccccdjhgfbcccccccccccc`c",
+"b`bbbbbbbbbbdhgffbbbbbbbbbbbbb`b",
+"````````````bbbbbb``````````````",
+"````````````````````````````````",
+"````````````````````````````````",
+"````````````````````````````````",
+"````````````````````````````````",
+"````````````````````````````````"
+};
diff --git a/icons/netdisk_t.xpm b/icons/netdisk_t.xpm
new file mode 100644
index 00000000000..baa4db6d3be
--- /dev/null
+++ b/icons/netdisk_t.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char *01netdisk16_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"    16    16       16            1",
+/* colors */
+"` c None s None",
+". c #c0c0ff",
+"# c #000000",
+"a c #808080",
+"b c #606040",
+"c c #a0a080",
+"d c #808000",
+"e c #008000",
+"f c #ffff00",
+"g c #00ff00",
+"h c #0040ff",
+"i c #006000",
+"j c #006040",
+"k c #004080",
+"l c #0060ff",
+"m c #004040",
+/* pixels */
+"````````````````",
+"````````````````",
+"``aaaaaaaaaaaaa`",
+"`b.....cccccccb#",
+"a````````````ab#",
+"a.........ge.ab#",
+"a............ab#",
+"a.bbbbbbbbbb.ab#",
+"a.``````````.a#`",
+"`#############``",
+"```````##```````",
+"```````.#```````",
+"......ddd#......",
+"######f`d#######",
+"``````####``````",
+"````````````````"
+};
-- 
GitLab