remove trailing whitespace at end of lines
[reactos.git] / rosapps / mc / pc / drive.c
1 /* Ch-Drive command for Windows NT and OS/2
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
17 Bug:
18 the code will not work if you have more drives than those that
19 can fit in a panel.
20 */
21
22 #include <config.h>
23 #ifdef _OS_NT
24 #include <windows.h>
25 #include "util_win32.h"
26 #endif
27 #include <string.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <ctype.h>
31 #include "../src/tty.h"
32 #include "../src/mad.h"
33 #include "../src/util.h"
34 #include "../src/win.h"
35 #include "../src/color.h"
36 #include "../src/dlg.h"
37 #include "../src/widget.h"
38 #include "../src/dialog.h"
39 #include "../src/dir.h"
40 #include "../src/panel.h"
41 #include "../src/main.h"
42 #include "../src/cmd.h"
43
44 struct Dlg_head *drive_dlg;
45 WPanel *this_panel;
46
47 static int drive_dlg_callback (Dlg_head *h, int Par, int Msg);
48 static void drive_dlg_refresh (void);
49 static void drive_cmd(void);
50
51 #define B_DRIVE_BASE 100
52 #define MAX_LGH 13 /* Length for drives */
53
54 static void drive_cmd()
55 {
56 int i, nNewDrive, nDrivesAvail;
57 char szTempBuf[7], szDrivesAvail[27*4], *p;
58
59 /* Dialogbox position */
60 int x_pos;
61 int y_pos = (LINES-6)/2-3;
62 int y_height;
63 int x_width;
64
65 int m_drv;
66
67 /* Get drives name and count */
68 #ifdef _OS_NT
69 GetLogicalDriveStrings (255, szDrivesAvail);
70 for (nDrivesAvail = 0, p = szDrivesAvail; *p; nDrivesAvail++)
71 p+=4;
72 #else
73 unsigned long uDriveNum, uDriveMap;
74 nDrivesAvail = 0;
75 p = szDrivesAvail;
76 DosQueryCurrentDisk(&uDriveNum, &uDriveMap);
77 for (i = 0; i < 26; i++) {
78 if ( uDriveMap & (1 << i) ) {
79 *p = 'A' + i;
80 p += 4;
81 nDrivesAvail++;
82 }
83 }
84 *p = 0;
85 #endif
86
87 /* Create Dialog */
88 do_refresh ();
89
90 m_drv = ((nDrivesAvail > MAX_LGH) ? MAX_LGH: nDrivesAvail);
91 /* Center on x, relative to panel */
92 x_pos = this_panel->widget.x + (this_panel->widget.cols - m_drv*3)/2 + 2;
93
94 if (nDrivesAvail > MAX_LGH) {
95 y_height = 8;
96 x_width = 33;
97 } else {
98 y_height = 6;
99 x_width = (nDrivesAvail - 1) * 2 + 9;
100 }
101
102 drive_dlg = create_dlg (y_pos, x_pos, y_height, x_width, dialog_colors,
103 drive_dlg_callback, _("[ChDrive]"),_("drive"), DLG_NONE);
104
105 x_set_dialog_title (drive_dlg, _("Change Drive") );
106
107 if (nDrivesAvail>MAX_LGH) {
108 for (i = 0; i < nDrivesAvail - MAX_LGH; i++) {
109 p -= 4;
110 sprintf(szTempBuf, "&%c", *p);
111 add_widgetl(drive_dlg,
112 button_new (5,
113 (m_drv-i-1)*2+4 - (MAX_LGH*2 - nDrivesAvail) * 2,
114 B_DRIVE_BASE + nDrivesAvail - i - 1,
115 HIDDEN_BUTTON,
116 szTempBuf, 0, NULL, NULL),
117 XV_WLAY_RIGHTOF);
118 }
119 }
120
121 /* Add a button for each drive */
122 for (i = 0; i < m_drv; i++) {
123 p -= 4;
124 sprintf (szTempBuf, "&%c", *p);
125 add_widgetl(drive_dlg,
126 button_new (3, (m_drv-i-1)*2+4, B_DRIVE_BASE+m_drv-i-1,
127 HIDDEN_BUTTON, szTempBuf, 0, NULL, NULL),
128 XV_WLAY_RIGHTOF);
129 }
130
131 run_dlg(drive_dlg);
132
133 /* do action */
134 if (drive_dlg->ret_value != B_CANCEL) {
135 int errocc = 0; /* no error */
136 int rtn;
137 char drvLetter;
138
139 /* Set the Panel to Directory listing mode first */
140 int is_right=(this_panel==right_panel);
141
142 set_display_type (is_right?1:0, view_listing);
143 this_panel=is_right?right_panel:left_panel;
144 /* */
145
146 nNewDrive = drive_dlg->ret_value - B_DRIVE_BASE;
147 drvLetter = (char) *(szDrivesAvail + (nNewDrive*4));
148 #ifdef _OS_NT
149 if (win32_GetPlatform() == OS_WinNT) { /* Windows NT */
150 rtn = _chdrive(drvLetter - 'A' + 1);
151 } else { /* Windows 95 */
152 rtn = 1;
153 SetCurrentDirectory(szDrivesAvail+(nNewDrive*4));
154 }
155 #else
156 rtn = DosSetDefaultDisk(nNewDrive + 1);
157 #endif
158 if (rtn == -1)
159 errocc = 1;
160 else {
161 getcwd (this_panel->cwd, sizeof (this_panel->cwd)-2);
162 if (toupper(drvLetter) == toupper(*(this_panel->cwd))) {
163 clean_dir (&this_panel->dir, this_panel->count);
164 this_panel->count = do_load_dir(&this_panel->dir,
165 this_panel->sort_type,
166 this_panel->reverse,
167 this_panel->case_sensitive,
168 this_panel->filter);
169 this_panel->top_file = 0;
170 this_panel->selected = 0;
171 this_panel->marked = 0;
172 this_panel->total = 0;
173 show_dir(this_panel);
174 reread_cmd();
175 } else
176 errocc = 1;
177 }
178 if (errocc)
179 message (1, _(" Error "), _(" Can't access drive %c: "),
180 *(szDrivesAvail+(nNewDrive*4)) );
181 }
182 destroy_dlg (drive_dlg);
183 repaint_screen ();
184 }
185
186
187 void drive_cmd_a()
188 {
189 this_panel = left_panel;
190 drive_cmd();
191 }
192
193 void drive_cmd_b()
194 {
195 this_panel = right_panel;
196 drive_cmd();
197 }
198
199 void drive_chg(WPanel *panel)
200 {
201 this_panel = panel;
202 drive_cmd();
203 }
204
205 static int drive_dlg_callback (Dlg_head *h, int Par, int Msg)
206 {
207 switch (Msg) {
208 #ifndef HAVE_X
209 case DLG_DRAW:
210 drive_dlg_refresh ();
211 break;
212 #endif
213 }
214 return 0;
215 }
216
217 static void drive_dlg_refresh (void)
218 {
219 attrset (dialog_colors[0]);
220 dlg_erase (drive_dlg);
221 draw_box (drive_dlg, 1, 1, drive_dlg->lines-2, drive_dlg->cols-2);
222
223 attrset (dialog_colors[2]);
224 dlg_move (drive_dlg, 1, drive_dlg->cols/2 - 7);
225 addstr (_(" Change Drive "));
226 }