Midnight Commander for Win32
[reactos.git] / rosapps / mc / pc / drive.c
diff --git a/rosapps/mc/pc/drive.c b/rosapps/mc/pc/drive.c
new file mode 100644 (file)
index 0000000..2059f94
--- /dev/null
@@ -0,0 +1,226 @@
+/* Ch-Drive command for Windows NT and OS/2
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+   
+   Bug:
+       the code will not work if you have more drives than those that
+       can fit in a panel.  
+   */
+
+#include <config.h>
+#ifdef _OS_NT
+#include <windows.h>
+#include "util_win32.h"
+#endif
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "../src/tty.h"
+#include "../src/mad.h"
+#include "../src/util.h"
+#include "../src/win.h"
+#include "../src/color.h"
+#include "../src/dlg.h"
+#include "../src/widget.h"
+#include "../src/dialog.h"
+#include "../src/dir.h"
+#include "../src/panel.h"
+#include "../src/main.h"
+#include "../src/cmd.h"
+
+struct Dlg_head *drive_dlg;
+WPanel *this_panel;
+
+static int drive_dlg_callback (Dlg_head *h, int Par, int Msg);
+static void drive_dlg_refresh (void);
+static void drive_cmd(void);
+
+#define B_DRIVE_BASE 100
+#define MAX_LGH 13             /* Length for drives */
+
+static void drive_cmd()                        
+{
+    int  i, nNewDrive, nDrivesAvail;
+    char szTempBuf[7], szDrivesAvail[27*4], *p;
+
+       /* Dialogbox position */
+       int  x_pos;
+       int  y_pos = (LINES-6)/2-3;
+       int  y_height;
+       int  x_width;
+
+       int  m_drv;
+
+    /* Get drives name and count */
+#ifdef _OS_NT
+    GetLogicalDriveStrings (255, szDrivesAvail);
+    for (nDrivesAvail = 0, p = szDrivesAvail; *p; nDrivesAvail++)
+       p+=4;
+#else
+    unsigned long uDriveNum, uDriveMap;
+    nDrivesAvail = 0;
+    p = szDrivesAvail;
+    DosQueryCurrentDisk(&uDriveNum, &uDriveMap);
+    for (i = 0; i < 26; i++) {
+      if ( uDriveMap & (1 << i) ) {
+       *p = 'A' + i;
+       p += 4;
+       nDrivesAvail++;
+      }
+    }
+    *p = 0;
+#endif
+
+    /* Create Dialog */
+    do_refresh ();
+       
+    m_drv = ((nDrivesAvail > MAX_LGH) ? MAX_LGH: nDrivesAvail);
+    /* Center on x, relative to panel */
+    x_pos = this_panel->widget.x + (this_panel->widget.cols - m_drv*3)/2 + 2;
+
+    if (nDrivesAvail > MAX_LGH) {
+       y_height = 8;
+       x_width  = 33;
+    } else {
+       y_height = 6;
+       x_width  = (nDrivesAvail - 1) * 2 + 9;
+    }
+
+    drive_dlg = create_dlg (y_pos, x_pos, y_height, x_width, dialog_colors,
+       drive_dlg_callback, _("[ChDrive]"),_("drive"), DLG_NONE);
+
+    x_set_dialog_title (drive_dlg, _("Change Drive") );
+
+       if (nDrivesAvail>MAX_LGH) {
+           for (i = 0; i < nDrivesAvail - MAX_LGH; i++) {
+               p -= 4;
+               sprintf(szTempBuf, "&%c", *p);
+               add_widgetl(drive_dlg,
+                   button_new (5,
+                       (m_drv-i-1)*2+4 - (MAX_LGH*2 - nDrivesAvail) * 2,
+                       B_DRIVE_BASE + nDrivesAvail - i - 1,
+                       HIDDEN_BUTTON,
+                       szTempBuf, 0, NULL, NULL),
+                   XV_WLAY_RIGHTOF);
+               }
+       }
+
+    /* Add a button for each drive */
+    for (i = 0; i < m_drv; i++) {
+       p -= 4;
+       sprintf (szTempBuf, "&%c", *p);
+           add_widgetl(drive_dlg,
+               button_new (3, (m_drv-i-1)*2+4, B_DRIVE_BASE+m_drv-i-1,
+               HIDDEN_BUTTON, szTempBuf, 0, NULL, NULL),
+               XV_WLAY_RIGHTOF);
+    }
+
+    run_dlg(drive_dlg);   
+
+    /* do action */
+    if (drive_dlg->ret_value != B_CANCEL) {
+       int  errocc = 0; /* no error */
+       int  rtn;
+       char drvLetter;
+       
+       /* Set the Panel to Directory listing mode first */
+       int is_right=(this_panel==right_panel);
+
+       set_display_type (is_right?1:0, view_listing);
+       this_panel=is_right?right_panel:left_panel;
+       /* */
+
+       nNewDrive = drive_dlg->ret_value - B_DRIVE_BASE;
+       drvLetter =  (char) *(szDrivesAvail + (nNewDrive*4));
+#ifdef _OS_NT
+       if (win32_GetPlatform() == OS_WinNT) {  /* Windows NT */
+               rtn = _chdrive(drvLetter - 'A' + 1);
+       } else {                                /* Windows 95 */
+               rtn = 1;
+               SetCurrentDirectory(szDrivesAvail+(nNewDrive*4));
+       }
+#else
+       rtn = DosSetDefaultDisk(nNewDrive + 1);
+#endif
+       if (rtn == -1) 
+               errocc = 1;
+       else {
+               getcwd (this_panel->cwd, sizeof (this_panel->cwd)-2);
+               if (toupper(drvLetter) == toupper(*(this_panel->cwd))) {
+                       clean_dir (&this_panel->dir, this_panel->count);
+                       this_panel->count = do_load_dir(&this_panel->dir,
+                               this_panel->sort_type,
+                               this_panel->reverse,
+                               this_panel->case_sensitive,
+                               this_panel->filter);
+                       this_panel->top_file = 0;
+                       this_panel->selected = 0;
+                       this_panel->marked = 0;
+                       this_panel->total = 0;
+                       show_dir(this_panel);
+                       reread_cmd();
+               } else
+                       errocc = 1;
+       }
+    if (errocc)
+           message (1, _(" Error "), _(" Can't access drive %c: "),
+               *(szDrivesAvail+(nNewDrive*4)) );
+    }
+    destroy_dlg (drive_dlg);
+    repaint_screen ();
+}
+
+
+void drive_cmd_a()
+{
+    this_panel = left_panel;
+    drive_cmd();
+}
+
+void drive_cmd_b()
+{                                  
+    this_panel = right_panel;
+    drive_cmd();
+}
+
+void drive_chg(WPanel *panel)
+{
+    this_panel  = panel;
+    drive_cmd();
+}
+
+static int drive_dlg_callback (Dlg_head *h, int Par, int Msg)
+{
+    switch (Msg) {
+#ifndef HAVE_X
+    case DLG_DRAW:
+       drive_dlg_refresh ();
+       break;
+#endif
+    }
+    return 0;
+}
+
+static void drive_dlg_refresh (void)
+{
+    attrset (dialog_colors[0]);
+    dlg_erase (drive_dlg);
+    draw_box (drive_dlg, 1, 1, drive_dlg->lines-2, drive_dlg->cols-2);
+
+    attrset (dialog_colors[2]);
+    dlg_move (drive_dlg, 1, drive_dlg->cols/2 - 7);
+    addstr (_(" Change Drive "));
+}