]> git.saurik.com Git - wxWidgets.git/blame - user/wxFile/filectrl.cpp
tree control and dc::drawlines bug
[wxWidgets.git] / user / wxFile / filectrl.cpp
CommitLineData
c801d85f
KB
1/*
2 * Author: Robert Roebling
3 *
4 * Copyright: (C) 1997,1998 Robert Roebling
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the wxWindows Licence, which
8 * you have received with this library (see Licence.htm).
9 *
10 */
11
12
13#ifdef __GNUG__
14#pragma implementation "filectrl.h"
15#endif
16
17#include "filectrl.h"
18
19#include "wx/dnd.h"
20
21#include "sys/types.h"
22#include "sys/stat.h"
23#include "dirent.h"
24#include "pwd.h"
25#include "grp.h"
26#include "time.h"
27
28#include "folder.xpm"
29#include "txt.xpm"
30#include "list.xpm"
31#include "find.xpm"
32
33//-----------------------------------------------------------------------------
34// wxFileData
35//-----------------------------------------------------------------------------
36
37IMPLEMENT_DYNAMIC_CLASS(wxFileData,wxObject);
38
39wxFileData::wxFileData( const wxString &name, const wxString &fname )
40{
41 m_name = name;
42 m_fileName = fname;
43
44 struct stat buff;
45 stat( m_fileName.GetData(), &buff );
46 struct stat lbuff;
47 lstat( m_fileName.GetData(), &lbuff );
48
49 struct tm *t = localtime( &lbuff.st_mtime );
50// struct passwd *user = getpwuid( buff.st_uid );
51// struct group *grp = getgrgid( buff.st_gid );
52
53 m_isDir = S_ISDIR( buff.st_mode );
54 m_isLink = S_ISLNK( lbuff.st_mode );
55 m_isExe = ((buff.st_mode & S_IXUSR ) == S_IXUSR );
56
57 m_size = buff.st_size;
58
59 m_hour = t->tm_hour;
60 m_minute = t->tm_min;
61 m_month = t->tm_mon+1;
62 m_day = t->tm_mday;
63 m_year = t->tm_year;
64
65 m_permissions.sprintf( "%c%c%c",
66 ((( buff.st_mode & S_IRUSR ) == S_IRUSR ) ? 'r' : '-'),
67 ((( buff.st_mode & S_IWUSR ) == S_IWUSR ) ? 'w' : '-'),
68 ((( buff.st_mode & S_IXUSR ) == S_IXUSR ) ? 'x' : '-') );
69};
70
71wxString wxFileData::GetName(void) const
72{
73 return m_name;
74};
75
76wxString wxFileData::GetFullName(void) const
77{
78 return m_fileName;
79};
80
81wxString wxFileData::GetHint(void) const
82{
83 wxString s = m_fileName;
84 s += " ";
85 if (m_isDir) s += "<DIR> ";
86 else if (m_isLink) s += "<LINK> ";
87 else
88 {
89 s += LongToString( m_size );
90 s += " bytes ";
91 };
92 s += IntToString( m_day );
93 s += ".";
94 s += IntToString( m_month );
95 s += ".";
96 s += IntToString( m_year );
97 s += " ";
98 s += IntToString( m_hour );
99 s += ":";
100 s += IntToString( m_minute );
101 s += " ";
102 s += m_permissions;
103 return s;
104};
105
106wxString wxFileData::GetEntry( const int num )
107{
108 wxString s;
109 switch (num)
110 {
111 case 0:
112 s = m_name;
113 break;
114 case 1:
115 if (m_isDir) s = "<DIR>";
116 else if (m_isLink) s = "<LINK>";
117 else s = LongToString( m_size );
118 break;
119 case 2:
120 if (m_day < 10) s = "0"; else s = "";
121 s += IntToString( m_day );
122 s += ".";
123 if (m_month < 10) s += "0";
124 s += IntToString( m_month );
125 s += ".";
126 if (m_year < 10) s += "0"; // this should happen real soon...
127 s += IntToString( m_year );
128 break;
129 case 3:
130 if (m_hour < 10) s = "0"; else s = "";
131 s += IntToString( m_hour );
132 s += ":";
133 if (m_minute < 10) s += "0";
134 s += IntToString( m_minute );
135 break;
136 case 4:
137 s = m_permissions;
138 break;
139 default:
140 s = "No entry";
141 break;
142 };
143 return s;
144};
145
146bool wxFileData::IsDir( void )
147{
148 return m_isDir;
149};
150
151bool wxFileData::IsExe( void )
152{
153 return m_isExe;
154};
155
156bool wxFileData::IsLink( void )
157{
158 return m_isLink;
159};
160
161long wxFileData::GetSize( void )
162{
163 return m_size;
164};
165
166bool wxFileData::NewNameIsLegal( const wxString &s )
167{
168 wxString fileName = wxPathOnly( m_fileName );
169 fileName += "/";
170 fileName += s;
171 return (!wxFileExists( fileName ));
172};
173
174bool wxFileData::Rename( const wxString &s )
175{
176 wxString fileName = wxPathOnly( m_fileName );
177 fileName += "/";
178 fileName += s;
179 bool ret = wxRenameFile( m_fileName, fileName );
180 if (ret)
181 {
182 m_fileName = fileName;
183 m_name = s;
184 };
185 return ret;
186};
187
188void wxFileData::MakeItem( wxListItem &item )
189{
190 item.m_text = m_name;
191 item.m_colour = wxBLACK;
192 if (IsExe()) item.m_colour = wxRED;
193 if (IsDir()) item.m_colour = wxBLUE;
194 if (IsLink())
195 {
196 wxColour *dg = wxTheColourDatabase->FindColour( "MEDIUM GREY" );
197 item.m_colour = dg;
198 };
199 item.m_data = (long)this;
200};
201
202//-----------------------------------------------------------------------------
203// wxFileCtrl
204//-----------------------------------------------------------------------------
205
206IMPLEMENT_DYNAMIC_CLASS(wxFileCtrl,wxListCtrl);
207
208BEGIN_EVENT_TABLE(wxFileCtrl,wxListCtrl)
209 EVT_SET_FOCUS (wxFileCtrl::OnSetFocus)
210END_EVENT_TABLE()
211
212wxFileCtrl *wxFileCtrl::m_lastFocus = NULL;
213
214wxFileCtrl::wxFileCtrl( void )
215{
216 m_dirName = "/";
217 m_showHidden = FALSE;
218};
219
220wxFileCtrl::wxFileCtrl( wxWindow *win, const wxWindowID id, const wxString &dirName,
221 const wxPoint &pos, const wxSize &size,
222 const long style, const wxString &name ) :
223 wxListCtrl( win, id, pos, size, style, name )
224{
225 wxImageList *imageList = new wxImageList();
226 imageList->Add( wxBitmap( folder_xpm ) );
227 imageList->Add( wxBitmap( txt_xpm ) );
228 imageList->Add( wxBitmap( list_xpm ) );
229 imageList->Add( wxBitmap( find_xpm ) );
230
231 SetImageList( imageList, wxIMAGE_LIST_NORMAL );
232
233 m_dirName = dirName;
234 m_showHidden = FALSE;
235 Update();
236
237 m_lastFocus = this;
238
239 SetDropTarget( new wxTextDropTarget() );
240};
241
242void wxFileCtrl::ChangeToListMode()
243{
244 SetSingleStyle( wxLC_LIST );
245 Update();
246};
247
248void wxFileCtrl::ChangeToReportMode()
249{
250 SetSingleStyle( wxLC_REPORT );
251 Update();
252};
253
254void wxFileCtrl::ChangeToIconMode()
255{
256 SetSingleStyle( wxLC_ICON );
257 Update();
258};
259
260void wxFileCtrl::ShowHidden( bool show )
261{
262 m_showHidden = show;
263 Update();
264};
265
266int ListCompare( const long data1, const long data2, const long WXUNUSED(data) )
267{
268 wxFileData *fd1 = (wxFileData*)data1 ;
269 wxFileData *fd2 = (wxFileData*)data2 ;
270 if (fd1->IsDir() && !fd2->IsDir()) return -1;
271 if (fd2->IsDir() && !fd1->IsDir()) return 1;
272 return strcmp( fd1->GetName(), fd2->GetName() );
273};
274
275void wxFileCtrl::Update( void )
276{
277 DeleteAllItems();
278 for (int i = 0; i < 5; i++) DeleteColumn( 0 );
279 long my_style = GetWindowStyleFlag();
280 if (my_style & wxLC_REPORT)
281 {
282 InsertColumn( 0, "Name", wxLIST_FORMAT_LEFT, 110 );
283 InsertColumn( 1, "Size", wxLIST_FORMAT_LEFT, 60 );
284 InsertColumn( 2, "Date", wxLIST_FORMAT_LEFT, 55 );
285 InsertColumn( 3, "Time", wxLIST_FORMAT_LEFT, 50 );
286 InsertColumn( 4, "Permissions", wxLIST_FORMAT_LEFT, 120 );
287 };
288 wxFileData *fd = NULL;
289 wxListItem item;
290 item.m_mask = wxLIST_MASK_TEXT + wxLIST_MASK_DATA;
291 if (my_style & wxLC_ICON) item.m_mask += wxLIST_MASK_IMAGE;
292 item.m_itemId = 0;
293 item.m_col = 0;
294 wxString s;
295 wxString res = m_dirName + "/*";
296 char *f = wxFindFirstFile( res.GetData(), 0 );
297 while (f)
298 {
299 res = wxFileNameFromPath( f );
300 fd = new wxFileData( res, f );
301 s = fd->GetName();
302 if (m_showHidden || (s[0] != '.'))
303 {
304 fd->MakeItem( item );
305 if (my_style & wxLC_REPORT)
306 {
307 InsertItem( item );
308 for (int i = 1; i < 5; i++) SetItem( item.m_itemId, i, fd->GetEntry( i) );
309 }
310 else if (my_style & wxLC_LIST)
311 {
312 InsertItem( item );
313 }
314 else if (my_style & wxLC_ICON)
315 {
316 if (fd->IsDir()) item.m_image = 0; else item.m_image = 1;
317 InsertItem( item );
318 };
319 item.m_itemId++;
320 };
321 f = wxFindNextFile();
322 };
323 SortItems( ListCompare, 0 );
c801d85f
KB
324};
325
326
327int wxFileCtrl::FillList( wxStringList &list )
328{
329 long index = -1;
330 int count = 0;
331 wxString s;
332 for (;;)
333 {
334 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
335 if (index == -1) break;
336 wxListItem item;
337 item.m_itemId = index;
338 GetItem( item );
339 wxFileData *fd = (wxFileData*)item.m_data;
340 list.Add( fd->GetFullName() );
341 index++;
342 count++;
343 };
344 if (count == 0)
345 {
346 index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED );
347 if (index == -1) return 0;
348 wxListItem item;
349 item.m_itemId = index;
350 GetItem( item );
351 wxFileData *fd = (wxFileData*)item.m_data;
352 list.Add( fd->GetFullName() );
353 count = 1;
354 };
355 return count;
356};
357
358void wxFileCtrl::DeleteFiles(void)
359{
360/*
361 wxStringList list;
362 int count = FillList( list );
363 if (count > 0)
364 {
365 wxString s = "Delete ";
366 s += wxIntToString( count );
367 s += " selected file";
368 if (count > 1) s += "s";
369 s += " or director";
370 if (count > 1) s += "ies?"; else s+= "y?";
371 if (wxYES == wxMessageBox( s, "Delete", wxYES_NO ))
372 wxDeleteStatusDia( NULL, &list );
373 };
374*/
375};
376
377void wxFileCtrl::CopyFiles( char *WXUNUSED(dest) )
378{
379/*
380 wxStringList list;
381 int count = FillList( list );
382 wxString s = dest;
383 int ret = 0; // 0 = nix, 1 = copy, 2 = move
384 wxCopyMoveDia( (wxFrame*)GetParent(), count, &ret, &s );
385 if (ret == 1)
386 wxCopyStatusDia( NULL, s, &list );
387*/
388};
389
390void wxFileCtrl::MoveFiles( char *WXUNUSED(dest) )
391{
392};
393
394void wxFileCtrl::RenameFile(void)
395{
396};
397
398void wxFileCtrl::MakeDir(void)
399{
400/*
401 wxString s = wxGetTextFromUser( "Enter new directory name:", "Make directory" );
402 if (s.IsNull()) return;
403 if (s == "") return;
404 if ((s == ".") || (s == ".."))
405 {
406 wxMessageBox( "This was obviously an invalid directory name.", "Go away." );
407 return;
408 };
409 wxString dir;
410 GetDir( dir );
411 dir += "/";
412 dir += s;
413 if (wxFileExists( dir ))
414 {
415 wxMessageBox( "Filename exists already. Cannot create directoy.", "Make directory" );
416 return;
417 };
418 wxMkdir( dir );
419 Update();
420*/
421};
422
423void wxFileCtrl::GoToParentDir(void)
424{
425 wxString s = m_dirName;
426 int pos = s.Last( '/' );
427 if ((pos >= 0) && (s != "/"))
428 {
429 s.Remove( pos, s.Length()-pos );
430 if (s.Length() == 0) s = "/";
431 m_dirName = s;
432 Update();
433 };
434};
435
436void wxFileCtrl::GoToHomeDir(void)
437{
438 wxString s = wxGetUserHome( wxString() );
439 m_dirName = s;
440 Update();
441};
442
443void wxFileCtrl::GoToDir( const wxString &dir )
444{
445 m_dirName = dir;
446 Update();
447};
448
449void wxFileCtrl::GetDir( wxString &dir )
450{
451 dir = m_dirName;
452};
453
454/*
455void wxFileCtrl::OnDropFiles( int WXUNUSED(n), char **WXUNUSED(data), int WXUNUSED(x), int WXUNUSED(y) )
456{
457 wxString destDir;
458 wxPoint pt( x, y );
459 int flag = wxLIST_HITTEST_ONITEM;
460 long hit = HitTest( pt, flag );
461 if (hit > -1)
462 {
463 wxListItem li;
464 li.m_itemId = hit;
465 GetItem( li );
466 wxFileData *fd = (wxFileData*)li.m_data;
467 if (fd->IsDir()) fd->GetFullName( destDir );
468 };
469 if (destDir.IsNull()) destDir = m_dirName;
470 int ret = 0; // 0 = nix, 1 = copy, 2 = move
471 wxCopyMoveDia( (wxFrame*)GetParent(), n, &ret, &destDir );
472 if (ret == 1)
473 {
474 wxStringList slist;
475 for (int i = 0; i < n; i++) slist.Add( data[i] );
476 wxCopyStatusDia( NULL, destDir.GetData(), &slist );
477 Update();
478 };
479};
480*/
481
482void wxFileCtrl::OnListDeleteItem( wxListEvent &event )
483{
484 wxFileData *fd = (wxFileData*)event.m_item.m_data;
485 delete fd;
486};
487
488void wxFileCtrl::OnListKeyDown( wxListEvent &event )
489{
490 wxFileData *fd = (wxFileData*)event.m_item.m_data;
491 if (fd->IsDir())
492 {
493 m_dirName = fd->GetFullName();
494 Update();
495 Refresh();
496 return;
497 };
498 if (fd->IsExe())
499 {
500 wxExecute( fd->GetFullName() );
501 return;
502 };
503};
504
505void wxFileCtrl::OnListEndLabelEdit( wxListEvent &event )
506{
507 wxFileData *fd = (wxFileData*)event.m_item.m_data;
508 wxString newName = event.m_item.m_text;
509 if (fd->NewNameIsLegal( newName ))
510 {
511 if (fd->Rename( newName ))
512 {
513 Update();
514 }
515 else
516 {
517 wxString s = "Could not rename file to ";
518 s += newName;
519 s += ".";
520 wxMessageBox( s, "FileMaker", wxOK );
521 };
522 }
523 else
524 {
525 wxString s = "File name ";
526 s += newName;
527 s += " exists already or is invalid.\n";
528 s += "Could not rename file.";
529 wxMessageBox( s, "FileMaker", wxOK );
530 };
531 return;
532};
533
534void wxFileCtrl::OnSetFocus( wxFocusEvent &event )
535{
536 m_lastFocus = this;
537 event.Skip();
538};
539
540