home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / generic / dirdlgg.cpp < prev    next >
C/C++ Source or Header  |  2003-01-03  |  11KB  |  318 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        dirdlg.cpp
  3. // Purpose:     wxDirDialog
  4. // Author:      Harm van der Heijden, Robert Roebling & Julian Smart
  5. // Modified by:
  6. // Created:     12/12/98
  7. // RCS-ID:      $Id: dirdlgg.cpp,v 1.38.2.2 2002/12/29 07:48:18 RL Exp $
  8. // Copyright:   (c) Harm van der Heijden, Robert Roebling, Julian Smart
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13. #pragma implementation "dirdlgg.h"
  14. #endif
  15.  
  16.  
  17. // For compilers that support precompilation, includes "wx.h".
  18. #include "wx/wxprec.h"
  19.  
  20. #ifdef __BORLANDC__
  21. #pragma hdrstop
  22. #endif
  23.  
  24. #include "wx/defs.h"
  25.  
  26. #if wxUSE_DIRDLG
  27.  
  28. #ifndef WX_PRECOMP
  29.     #include "wx/textctrl.h"
  30.     #include "wx/button.h"
  31.     #include "wx/checkbox.h"
  32.     #include "wx/sizer.h"
  33.     #include "wx/intl.h"
  34.     #include "wx/log.h"
  35.     #include "wx/msgdlg.h"
  36. #endif
  37.  
  38. #include "wx/statline.h"
  39. #include "wx/dirctrl.h"
  40. #include "wx/generic/dirdlgg.h"
  41. #include "wx/artprov.h"
  42. #include "wx/bmpbuttn.h"
  43.  
  44. //-----------------------------------------------------------------------------
  45. // wxGenericDirDialog
  46. //-----------------------------------------------------------------------------
  47.  
  48. static const int ID_DIRCTRL = 1000;
  49. static const int ID_TEXTCTRL = 1001;
  50. static const int ID_OK = 1002;
  51. static const int ID_CANCEL = 1003;
  52. static const int ID_NEW = 1004;
  53. static const int ID_SHOW_HIDDEN = 1005;
  54. static const int ID_GO_HOME = 1006;
  55.  
  56. BEGIN_EVENT_TABLE(wxGenericDirDialog, wxDialog)
  57.     EVT_CLOSE                (wxGenericDirDialog::OnCloseWindow)
  58.     EVT_BUTTON               (wxID_OK,        wxGenericDirDialog::OnOK)
  59.     EVT_BUTTON               (ID_NEW,         wxGenericDirDialog::OnNew)
  60.     EVT_BUTTON               (ID_GO_HOME,     wxGenericDirDialog::OnGoHome)
  61.     EVT_TREE_KEY_DOWN        (-1,             wxGenericDirDialog::OnTreeKeyDown)
  62.     EVT_TREE_SEL_CHANGED     (-1,             wxGenericDirDialog::OnTreeSelected)
  63.     EVT_TEXT_ENTER           (ID_TEXTCTRL,    wxGenericDirDialog::OnOK)
  64.     EVT_CHECKBOX             (ID_SHOW_HIDDEN, wxGenericDirDialog::OnShowHidden)
  65. END_EVENT_TABLE()
  66.  
  67. wxGenericDirDialog::wxGenericDirDialog(wxWindow* parent, const wxString& title,
  68.                                        const wxString& defaultPath, long style,
  69.                                        const wxPoint& pos, const wxSize& sz, 
  70.                                        const wxString& name):
  71.                 wxDialog(parent, ID_DIRCTRL, title, pos, sz, style, name)
  72. {
  73.     wxBusyCursor cursor;
  74.  
  75.     m_path = defaultPath;
  76.     if (m_path == wxT("~"))
  77.         wxGetHomeDir(&m_path);
  78.     if (m_path == wxT("."))
  79.         m_path = wxGetCwd();
  80.  
  81.     wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
  82.  
  83.     // 0) 'New' and 'Home' Buttons
  84.     wxSizer* buttonsizer = new wxBoxSizer( wxHORIZONTAL );
  85.  
  86.     // VS: 'Home directory' concept is unknown to MS-DOS
  87. #ifndef __DOS__
  88.     wxBitmapButton* homeButton = 
  89.         new wxBitmapButton(this, ID_GO_HOME,
  90.                            wxArtProvider::GetBitmap(wxART_GO_HOME, wxART_CMN_DIALOG));
  91.     buttonsizer->Add( homeButton, 0, wxLEFT|wxRIGHT, 10 );
  92. #endif
  93.     
  94.     // I'm not convinced we need a New button, and we tend to get annoying
  95.     // accidental-editing with label editing enabled.
  96.     if (style & wxDD_NEW_DIR_BUTTON)
  97.     {
  98.         wxBitmapButton* newButton = 
  99.             new wxBitmapButton(this, ID_NEW,
  100.                             wxArtProvider::GetBitmap(wxART_NEW_DIR, wxART_CMN_DIALOG));
  101.         buttonsizer->Add( newButton, 0, wxRIGHT, 10 );
  102. #if wxUSE_TOOLTIPS
  103.         newButton->SetToolTip(_("Create new directory"));
  104. #endif    
  105.     }
  106.  
  107. #if wxUSE_TOOLTIPS
  108.     homeButton->SetToolTip(_("Go to home directory"));
  109. #endif
  110.  
  111.     topsizer->Add( buttonsizer, 0, wxTOP | wxALIGN_RIGHT, 10 );
  112.  
  113.     // 1) dir ctrl
  114.     m_dirCtrl = NULL; // this is neccessary, event handler called from 
  115.                       // wxGenericDirCtrl would crash otherwise!
  116.     long dirStyle = wxDIRCTRL_DIR_ONLY|wxSUNKEN_BORDER;
  117.     
  118. #ifdef __WXMSW__
  119.     if (style & wxDD_NEW_DIR_BUTTON)
  120.     {
  121.         // Only under Windows do we need the wxTR_EDIT_LABEL tree control style
  122.         // before we can call EditLabel (required for "New directory")
  123.         dirStyle |= wxDIRCTRL_EDIT_LABELS;
  124.     }
  125. #endif    
  126.  
  127.     m_dirCtrl = new wxGenericDirCtrl(this, ID_DIRCTRL,
  128.                                      m_path, wxPoint(5, 5),
  129.                                      wxSize(300, 200), 
  130.                                      dirStyle);
  131.  
  132.     topsizer->Add( m_dirCtrl, 1, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 );
  133.  
  134.     // Make the an option depending on a flag?
  135.     wxCheckBox* check = new wxCheckBox( this, ID_SHOW_HIDDEN, _("Show hidden directories") );
  136.     topsizer->Add( check, 0, wxLEFT|wxTOP | wxALIGN_RIGHT, 5 );
  137.  
  138.     // 2) text ctrl
  139.     m_input = new wxTextCtrl( this, ID_TEXTCTRL, m_path, wxDefaultPosition );
  140.     topsizer->Add( m_input, 0, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 );
  141.  
  142. #if wxUSE_STATLINE
  143.     // 3) Static line
  144.     topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 );
  145. #endif
  146.  
  147.     // 4) Buttons
  148.     buttonsizer = new wxBoxSizer( wxHORIZONTAL );
  149.     
  150.     // OK and Cancel button should be at the right bottom
  151.     wxButton* okButton = new wxButton(this, wxID_OK, _("OK"));
  152.     buttonsizer->Add( okButton, 0, wxLEFT|wxRIGHT, 10 );
  153.     wxButton* cancelButton = new wxButton(this, wxID_CANCEL, _("Cancel"));
  154.     buttonsizer->Add( cancelButton, 0, wxLEFT|wxRIGHT, 10 );
  155.  
  156.     topsizer->Add( buttonsizer, 0, wxALL | wxALIGN_RIGHT, 10 );
  157.  
  158.     okButton->SetDefault();
  159.     m_dirCtrl->SetFocus();
  160.  
  161.     SetAutoLayout( TRUE );
  162.     SetSizer( topsizer );
  163.  
  164.     topsizer->SetSizeHints( this );
  165.     topsizer->Fit( this );
  166.  
  167.     Centre( wxBOTH );
  168. }
  169.  
  170. void wxGenericDirDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
  171. {
  172.     EndModal(wxID_CANCEL);
  173. }
  174.  
  175. void wxGenericDirDialog::OnOK(wxCommandEvent& WXUNUSED(event))
  176. {
  177.     m_path = m_input->GetValue();
  178.     // Does the path exist? (User may have typed anything in m_input)
  179.     if (wxPathExists(m_path)) {
  180.         // OK, path exists, we're done.
  181.         EndModal(wxID_OK);
  182.         return;
  183.     }
  184.     // Interact with user, find out if the dir is a typo or to be created
  185.     wxString msg;
  186.     msg.Printf(_("The directory '%s' does not exist\nCreate it now?"), 
  187.                m_path.c_str());
  188.     wxMessageDialog dialog(this, msg, _("Directory does not exist"), 
  189.                            wxYES_NO | wxICON_WARNING);
  190.  
  191.     if ( dialog.ShowModal() == wxID_YES ) {
  192.         // Okay, let's make it
  193.         wxLogNull log;
  194.         if (wxMkdir(m_path)) {
  195.             // The new dir was created okay.
  196.             EndModal(wxID_OK);
  197.             return;
  198.         }
  199.         else {
  200.             // Trouble...
  201.             msg.Printf(_("Failed to create directory '%s'\n(Do you have the required permissions?)"), 
  202.                        m_path.c_str());
  203.             wxMessageDialog errmsg(this, msg, _("Error creating directory"), wxOK | wxICON_ERROR);
  204.             errmsg.ShowModal();
  205.             // We still don't have a valid dir. Back to the main dialog.
  206.         }
  207.     }
  208.     // User has answered NO to create dir.
  209. }
  210.  
  211. void wxGenericDirDialog::SetPath(const wxString& path)
  212. {
  213.     m_dirCtrl->SetPath(path);
  214.     m_path = path;
  215. }
  216.  
  217. wxString wxGenericDirDialog::GetPath(void) const
  218. {
  219.     return m_path;
  220. }
  221.  
  222. int wxGenericDirDialog::ShowModal()
  223. {
  224.     m_input->SetValue( m_path );
  225.     return wxDialog::ShowModal();
  226. }
  227.  
  228. void wxGenericDirDialog::OnTreeSelected( wxTreeEvent &event )
  229. {
  230.     if (!m_dirCtrl)
  231.         return;
  232.  
  233.     wxDirItemData *data = (wxDirItemData*)m_dirCtrl->GetTreeCtrl()->GetItemData(event.GetItem());
  234.     if (data)
  235.        m_input->SetValue( data->m_path );
  236. };
  237.  
  238. void wxGenericDirDialog::OnTreeKeyDown( wxTreeEvent &WXUNUSED(event) )
  239. {
  240.     if (!m_dirCtrl)
  241.         return;
  242.  
  243.     wxDirItemData *data = (wxDirItemData*)m_dirCtrl->GetTreeCtrl()->GetItemData(m_dirCtrl->GetTreeCtrl()->GetSelection());
  244.     if (data)
  245.         m_input->SetValue( data->m_path );
  246. };
  247.  
  248. void wxGenericDirDialog::OnShowHidden( wxCommandEvent& event )
  249. {
  250.     if (!m_dirCtrl)
  251.         return;
  252.  
  253.     m_dirCtrl->ShowHidden( event.GetInt() != 0 );
  254. }
  255.  
  256. void wxGenericDirDialog::OnNew( wxCommandEvent& WXUNUSED(event) )
  257. {
  258.     wxTreeItemId id = m_dirCtrl->GetTreeCtrl()->GetSelection();
  259.     if ((id == m_dirCtrl->GetTreeCtrl()->GetRootItem()) ||
  260.         (m_dirCtrl->GetTreeCtrl()->GetItemParent(id) == m_dirCtrl->GetTreeCtrl()->GetRootItem()))
  261.     {
  262.         wxMessageDialog msg(this, _("You cannot add a new directory to this section."),
  263.                             _("Create directory"), wxOK | wxICON_INFORMATION );
  264.         msg.ShowModal();
  265.         return;
  266.     }
  267.  
  268.     wxTreeItemId parent = id ; // m_dirCtrl->GetTreeCtrl()->GetItemParent( id );
  269.     wxDirItemData *data = (wxDirItemData*)m_dirCtrl->GetTreeCtrl()->GetItemData( parent );
  270.     wxASSERT( data );
  271.  
  272.     wxString new_name( _("NewName") );
  273.     wxString path( data->m_path );
  274.     if (path.Last() != wxFILE_SEP_PATH)
  275.         path += wxFILE_SEP_PATH;
  276.     path += new_name;
  277.     if (wxFileExists(path))
  278.     {
  279.         // try NewName0, NewName1 etc.
  280.         int i = 0;
  281.         do {
  282.             new_name = _("NewName");
  283.             wxString num;
  284.             num.Printf( wxT("%d"), i );
  285.             new_name += num;
  286.  
  287.             path = data->m_path;
  288.             if (path.Last() != wxFILE_SEP_PATH)
  289.                 path += wxFILE_SEP_PATH;
  290.             path += new_name;
  291.             i++;
  292.         } while (wxFileExists(path));
  293.     }
  294.  
  295.     wxLogNull log;
  296.     if (!wxMkdir(path))
  297.     {
  298.         wxMessageDialog dialog(this, _("Operation not permitted."), _("Error"), wxOK | wxICON_ERROR );
  299.         dialog.ShowModal();
  300.         return;
  301.     }
  302.  
  303.     wxDirItemData *new_data = new wxDirItemData( path, new_name, TRUE );
  304.  
  305.     // TODO: THIS CODE DOESN'T WORK YET. We need to avoid duplication of the first child
  306.     // of the parent.
  307.     wxTreeItemId new_id = m_dirCtrl->GetTreeCtrl()->AppendItem( parent, new_name, 0, 0, new_data );
  308.     m_dirCtrl->GetTreeCtrl()->EnsureVisible( new_id );
  309.     m_dirCtrl->GetTreeCtrl()->EditLabel( new_id );
  310. }
  311.  
  312. void wxGenericDirDialog::OnGoHome(wxCommandEvent& WXUNUSED(event))
  313. {
  314.     SetPath(wxGetUserHome());
  315. }
  316.  
  317. #endif // wxUSE_DIRDLG
  318.