]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/dnd/dnd.cpp
* New wxStreams (to be documented), new classes: wxBufferedStreams,
[wxWidgets.git] / samples / dnd / dnd.cpp
index abc81422cae2b25c02c9aacda20a96c257ff9666..92b29d29e749dff6570ac2d9eac4b973d94ff860 100644 (file)
 #include "wx/wx.h"
 #endif
 
-#include  "wx/intl.h"
-#include  "wx/log.h"
+#include "wx/intl.h"
+#include "wx/log.h"
 
-#include  "wx/dnd.h"
+#include "wx/dnd.h"
 
-#ifdef __WXGTK__
-#include "mondrian.xpm"
+#ifdef __WXMOTIF__
+    #error Sorry, drag and drop is not yet implemented on wxMotif.
 #endif
 
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+    #include "mondrian.xpm"
+#endif
+
+#include "wx/clipbrd.h"
+
 // ----------------------------------------------------------------------------
 // Derive two simple classes which just put in the listbox the strings (text or
 // file names) we drop on them
 // ----------------------------------------------------------------------------
 
+typedef long wxDropPointCoord;
+
 class DnDText : public wxTextDropTarget
 {
 public:
-  DnDText(wxListBox *pOwner) { m_pOwner = pOwner; }
+    DnDText(wxListBox *pOwner) { m_pOwner = pOwner; }
 
-  virtual bool OnDropText(long x, long y, const char *psz );
+    virtual bool OnDropText(wxDropPointCoord x, wxDropPointCoord y,
+                            const wxChar* psz);
 
 private:
-  wxListBox *m_pOwner;
+    wxListBox *m_pOwner;
 };
 
 class DnDFile : public wxFileDropTarget
 {
 public:
-  DnDFile(wxListBox *pOwner) { m_pOwner = pOwner; }
+    DnDFile(wxListBox *pOwner) { m_pOwner = pOwner; }
 
-  virtual bool OnDropFiles(long x, long y,
-                           size_t nFiles, const char * const aszFiles[] );
+  virtual bool OnDropFiles(wxDropPointCoord x, wxDropPointCoord y,
+                           size_t nFiles, const wxChar* const aszFiles[] );
 
 private:
-  wxListBox *m_pOwner;
+    wxListBox *m_pOwner;
 };
 
 // ----------------------------------------------------------------------------
@@ -63,7 +72,7 @@ private:
 class DnDApp : public wxApp
 {
 public:
-  bool OnInit();
+    bool OnInit();
 };
 
 IMPLEMENT_APP(DnDApp);
@@ -74,31 +83,31 @@ IMPLEMENT_APP(DnDApp);
 class DnDFrame : public wxFrame
 {
 public:
-  DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
- ~DnDFrame();
-
-  void OnPaint(wxPaintEvent& event);
-  void OnQuit (wxCommandEvent& event);
-  void OnAbout(wxCommandEvent& event);
-  void OnDrag (wxCommandEvent& event);
-  void OnHelp (wxCommandEvent& event);
-  void OnLogClear(wxCommandEvent& event);
+    DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
+    ~DnDFrame();
 
-  void OnLeftDown(wxMouseEvent& event);
-  void OnRightDown(wxMouseEvent& event);
+    void OnPaint(wxPaintEvent& event);
+    void OnQuit (wxCommandEvent& event);
+    void OnAbout(wxCommandEvent& event);
+    void OnDrag (wxCommandEvent& event);
+    void OnHelp (wxCommandEvent& event);
+    void OnLogClear(wxCommandEvent& event);
+    void OnCopy(wxCommandEvent& event);
+    void OnPaste(wxCommandEvent& event);
 
-  bool OnClose();
+    void OnLeftDown(wxMouseEvent& event);
+    void OnRightDown(wxMouseEvent& event);
 
-  DECLARE_EVENT_TABLE()
+    DECLARE_EVENT_TABLE()
 
 private:
-  wxListBox  *m_ctrlFile,
-             *m_ctrlText;
-  wxTextCtrl *m_ctrlLog;
+        wxListBox  *m_ctrlFile,
+        *m_ctrlText;
+        wxTextCtrl *m_ctrlLog;
 
-  wxLog *m_pLog, *m_pLogPrev;
+        wxLog *m_pLog, *m_pLogPrev;
 
-  wxString m_strText;
+        wxString m_strText;
 };
 
 // ----------------------------------------------------------------------------
@@ -107,37 +116,43 @@ private:
 
 enum
 {
-  Menu_Quit = 1,
-  Menu_Drag,
-  Menu_About = 101,
-  Menu_Help,
-  Menu_Clear,
+    Menu_Quit = 1,
+    Menu_Drag,
+    Menu_About = 101,
+    Menu_Help,
+    Menu_Clear,
+    Menu_Copy,
+    Menu_Paste
 };
 
 BEGIN_EVENT_TABLE(DnDFrame, wxFrame)
-  EVT_MENU(Menu_Quit,  DnDFrame::OnQuit)
-  EVT_MENU(Menu_About, DnDFrame::OnAbout)
-  EVT_MENU(Menu_Drag,  DnDFrame::OnDrag)
-  EVT_MENU(Menu_Help,  DnDFrame::OnHelp)
-  EVT_MENU(Menu_Clear, DnDFrame::OnLogClear)
-  EVT_LEFT_DOWN(       DnDFrame::OnLeftDown)
-  EVT_RIGHT_DOWN(      DnDFrame::OnRightDown)
-  EVT_PAINT(           DnDFrame::OnPaint)
+    EVT_MENU(Menu_Quit,  DnDFrame::OnQuit)
+    EVT_MENU(Menu_About, DnDFrame::OnAbout)
+    EVT_MENU(Menu_Drag,  DnDFrame::OnDrag)
+    EVT_MENU(Menu_Help,  DnDFrame::OnHelp)
+    EVT_MENU(Menu_Clear, DnDFrame::OnLogClear)
+    EVT_MENU(Menu_Copy,  DnDFrame::OnCopy)
+    EVT_MENU(Menu_Paste, DnDFrame::OnPaste)
+
+    EVT_LEFT_DOWN(       DnDFrame::OnLeftDown)
+    EVT_RIGHT_DOWN(      DnDFrame::OnRightDown)
+    EVT_PAINT(           DnDFrame::OnPaint)
 END_EVENT_TABLE()
 
-// `Main program' equivalent, creating windows and returning main app frame
+    // `Main program' equivalent, creating windows and returning main app frame
 bool DnDApp::OnInit()
 {
-  // create the main frame window
-  DnDFrame *frame = new DnDFrame((wxFrame  *) NULL, "Drag & Drop wxWindows App",
-                                 50, 50, 450, 340);
+    // create the main frame window
+    DnDFrame *frame = new DnDFrame((wxFrame  *) NULL,
+                                   "Drag-and-Drop/Clipboard wxWindows Sample",
+                                   50, 50, 450, 340);
 
-  // activate it
-  frame->Show(TRUE);
+    // activate it
+    frame->Show(TRUE);
 
-  SetTopWindow(frame);
+    SetTopWindow(frame);
 
-  return TRUE;
+    return TRUE;
 }
 
 DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
@@ -145,55 +160,59 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
           m_strText("wxWindows drag & drop works :-)")
 
 {
-//  SetBackgroundColour(* wxWHITE);
+    // frame icon and status bar
+    SetIcon(wxICON(mondrian));
 
-  // frame icon and status bar
-  SetIcon(wxICON(mondrian));
+    CreateStatusBar();
 
-//  const int widths[] = { -1 };
-  CreateStatusBar();
+    // construct menu
+    wxMenu *file_menu = new wxMenu;
+    file_menu->Append(Menu_Drag, "&Test drag...");
+    file_menu->AppendSeparator();
+    file_menu->Append(Menu_Quit, "E&xit");
 
-  // construct menu
-  wxMenu *file_menu = new wxMenu;
-  file_menu->Append(Menu_Drag, "&Test drag...");
-  file_menu->AppendSeparator();
-  file_menu->Append(Menu_Quit, "E&xit");
+    wxMenu *log_menu = new wxMenu;
+    log_menu->Append(Menu_Clear, "Clear");
 
-  wxMenu *log_menu = new wxMenu;
-  log_menu->Append(Menu_Clear, "Clear");
+    wxMenu *help_menu = new wxMenu;
+    help_menu->Append(Menu_Help, "&Help...");
+    help_menu->AppendSeparator();
+    help_menu->Append(Menu_About, "&About");
 
-  wxMenu *help_menu = new wxMenu;
-  help_menu->Append(Menu_Help, "&Help...");
-  help_menu->AppendSeparator();
-  help_menu->Append(Menu_About, "&About");
+    wxMenu *clip_menu = new wxMenu;
+    clip_menu->Append(Menu_Copy, "&Copy\tCtrl+C");
+    clip_menu->Append(Menu_Paste, "&Paste\tCtrl+V");
 
-  wxMenuBar *menu_bar = new wxMenuBar;
-  menu_bar->Append(file_menu, "&File");
-  menu_bar->Append(log_menu,  "&Log");
-  menu_bar->Append(help_menu, "&Help");
+    wxMenuBar *menu_bar = new wxMenuBar;
+    menu_bar->Append(file_menu, "&File");
+    menu_bar->Append(log_menu,  "&Log");
+    menu_bar->Append(clip_menu, "&Clipboard");
+    menu_bar->Append(help_menu, "&Help");
 
-  SetMenuBar(menu_bar);
+    SetMenuBar(menu_bar);
 
-  // make a panel with 3 subwindows
-  wxPoint pos(0, 0);
-  wxSize  size(400, 200);
+    // make a panel with 3 subwindows
+    wxPoint pos(0, 0);
+    wxSize  size(400, 200);
 
-  wxString strFile("Drop files here!"), strText("Drop text on me");
+    wxString strFile("Drop files here!"), strText("Drop text on me");
 
-  m_ctrlFile  = new wxListBox(this, -1, pos, size, 1, &strFile, wxLB_HSCROLL);
-  m_ctrlText  = new wxListBox(this, -1, pos, size, 1, &strText, wxLB_HSCROLL);
+    m_ctrlFile  = new wxListBox(this, -1, pos, size, 1, &strFile, wxLB_HSCROLL);
+    m_ctrlText  = new wxListBox(this, -1, pos, size, 1, &strText, wxLB_HSCROLL);
 
-  m_ctrlLog   = new wxTextCtrl(this, -1, "", pos, size,
+    m_ctrlLog   = new wxTextCtrl(this, -1, "", pos, size,
                                wxTE_MULTILINE | wxTE_READONLY |
                                wxSUNKEN_BORDER );
 
-  // redirect log messages to the text window (don't forget to delete it!)
+#if wxUSE_STD_IOSTREAM  
+// redirect log messages to the text window (don't forget to delete it!)
   m_pLog = new wxLogTextCtrl(m_ctrlLog);
   m_pLogPrev = wxLog::SetActiveTarget(m_pLog);
+#endif
 
   // associate drop targets with 2 text controls
   m_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile));
-  m_ctrlText->SetDropTarget( new DnDText(m_ctrlText) );
+  m_ctrlText->SetDropTarget(new DnDText(m_ctrlText));
 
   wxLayoutConstraints *c;
 
@@ -226,146 +245,199 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
 
 void DnDFrame::OnQuit(wxCommandEvent& /* event */)
 {
-  Close(TRUE);
+    Close(TRUE);
 }
 
 void DnDFrame::OnPaint(wxPaintEvent& /*event*/)
 {
-  int w = 0;
-  int h = 0;
-  GetClientSize( &w, &h );
+    int w = 0;
+    int h = 0;
+    GetClientSize( &w, &h );
 
-  wxPaintDC dc(this);
-  dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL, FALSE, "charter" ) );
-  dc.DrawText( "Drag text from here!", 20, h-22 );
+    wxPaintDC dc(this);
+    dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL, FALSE, "charter" ) );
+    dc.DrawText( "Drag text from here!", 20, h-35 );
 }
 
 void DnDFrame::OnDrag(wxCommandEvent& /* event */)
 {
-  wxString strText = wxGetTextFromUser
-  (
-    "After you enter text in this dialog, press any mouse\n"
-    "button in the bottom (empty) part of the frame and \n"
-    "drag it anywhere - you will be in fact dragging the\n"
-    "text object containing this text",
-    "Please enter some text", m_strText, this
-  );
-
-  m_strText = strText;
+    wxString strText = wxGetTextFromUser
+        (
+         "After you enter text in this dialog, press any mouse\n"
+         "button in the bottom (empty) part of the frame and \n"
+         "drag it anywhere - you will be in fact dragging the\n"
+         "text object containing this text",
+         "Please enter some text", m_strText, this
+        );
+
+    m_strText = strText;
 }
 
 void DnDFrame::OnAbout(wxCommandEvent& /* event */)
 {
-  wxMessageDialog dialog(this,
-                         "Drag-&-Drop Demo\n"
-                         "Please see \"Help|Help...\" for details\n"
-                         "Copyright (c) 1998 Vadim Zeitlin",
-                         "About wxDnD");
-
-  dialog.ShowModal();
+    wxMessageBox("Drag-&-Drop Demo\n"
+                 "Please see \"Help|Help...\" for details\n"
+                 "Copyright (c) 1998 Vadim Zeitlin",
+                 "About wxDnD",
+                 wxICON_INFORMATION | wxOK,
+                 this);
 }
 
 void DnDFrame::OnHelp(wxCommandEvent& /* event */)
 {
-  wxMessageDialog dialog(this,
-"This small program demonstrates drag & drop support in wxWindows. The program window\n"
-"consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
-"going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
-"and the right one accepts text.\n"
-"\n"
-"To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
-"the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
-"Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
-"File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
-"work with files) and see what changes.\n"
-"\n"
-"To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
-"it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
-"to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
-"change, don't release the mouse button until it does. You can change the string being\n"
-"dragged in in \"File|Test drag...\" dialog.\n"
-"\n"
-"\n"
-"Please send all questions/bug reports/suggestions &c to \n"
-"Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
-                        "wxDnD Help");
-
-  dialog.ShowModal();
+    wxMessageDialog dialog(this,
+            "This small program demonstrates drag & drop support in wxWindows. The program window\n"
+            "consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
+            "going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
+            "and the right one accepts text.\n"
+            "\n"
+            "To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
+            "the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
+            "Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
+            "File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
+            "work with files) and see what changes.\n"
+            "\n"
+            "To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
+            "it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
+            "to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
+            "change, don't release the mouse button until it does. You can change the string being\n"
+            "dragged in in \"File|Test drag...\" dialog.\n"
+            "\n"
+            "\n"
+            "Please send all questions/bug reports/suggestions &c to \n"
+            "Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
+            "wxDnD Help");
+
+    dialog.ShowModal();
 }
 
 void DnDFrame::OnLogClear(wxCommandEvent& /* event */ )
 {
-  m_ctrlLog->Clear();
+    m_ctrlLog->Clear();
 }
 
-bool DnDFrame::OnClose()
+void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
 {
-  return TRUE;
+    if ( !m_strText.IsEmpty() ) 
+    {
+        // start drag operation
+#ifdef __WXMSW__
+        wxTextDataObject textData(m_strText);
+        wxDropSource dragSource( textData, this );
+#else
+        wxDropSource dragSource( new wxTextDataObject (m_strText), this, wxIcon(mondrian_xpm) );
+#endif
+        const char *pc;
+
+        switch ( dragSource.DoDragDrop(TRUE) ) 
+        {
+            case wxDragError:   pc = "Error!";    break;
+            case wxDragNone:    pc = "Nothing";   break;
+            case wxDragCopy:    pc = "Copied";    break;
+            case wxDragMove:    pc = "Moved";     break;
+            case wxDragCancel:  pc = "Cancelled"; break;
+            default:            pc = "Huh?";      break;
+        }
+
+        SetStatusText(wxString("Drag result: ") + pc);
+    }
 }
 
-void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
+void DnDFrame::OnRightDown(wxMouseEvent &event )
 {
-  if ( !m_strText.IsEmpty() ) 
-  {
-    // start drag operation
-    wxTextDataObject textData(m_strText);
-    wxDropSource dragSource( textData, this );
+    wxMenu *menu = new wxMenu;
 
-//    wxDropSource dragSource( new wxTextDataObject (m_strText), this );
-    const char *pc;
+    menu->Append(Menu_Drag, "&Test drag...");
+    menu->Append(Menu_About, "&About");
+    menu->Append(Menu_Quit, "E&xit");
 
-    switch ( dragSource.DoDragDrop(TRUE) ) 
-    {
-      case wxDragError:   pc = "Error!";    break;
-      case wxDragNone:    pc = "Nothing";   break;
-      case wxDragCopy:    pc = "Copied";    break;
-      case wxDragMove:    pc = "Moved";     break;
-      case wxDragCancel:  pc = "Cancelled"; break;
-      default:                    pc = "Huh?";      break;
-    }
+    PopupMenu( menu, event.GetX(), event.GetY() );
+}
 
-    SetStatusText(wxString("Drag result: ") + pc);
-  }
+DnDFrame::~DnDFrame()
+{
+#if wxUSE_STD_IOSTREAM  
+    if ( m_pLog != NULL ) {
+        if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog )
+            delete m_pLog;
+    }
+#endif
 }
 
-void DnDFrame::OnRightDown(wxMouseEvent &event )
+// ---------------------------------------------------------------------------
+// clipboard
+// ---------------------------------------------------------------------------
+
+void DnDFrame::OnCopy(wxCommandEvent& WXUNUSED(event))
 {
-  wxMenu *menu = new wxMenu;
+    if ( !wxTheClipboard->Open() )
+    {
+        wxLogError("Can't open clipboard.");
 
-  menu->Append(Menu_Drag, "&Test drag...");
-  menu->Append(Menu_About, "&About");
-  menu->Append(Menu_Quit, "E&xit");
+        return;
+    }
+
+    if ( !wxTheClipboard->AddData(new wxTextDataObject(m_strText)) )
+    {
+        wxLogError("Can't copy data to the clipboard");
+    }
+    else
+    {
+        wxLogMessage("Text '%s' put on the clipboard", m_strText.c_str());
+    }
 
-  PopupMenu( menu, event.GetX(), event.GetY() );
+    wxTheClipboard->Close();
 }
 
-DnDFrame::~DnDFrame()
+void DnDFrame::OnPaste(wxCommandEvent& WXUNUSED(event))
 {
-  if ( m_pLog != NULL ) {
-    if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog )
-      delete m_pLog;
-  }
+    if ( !wxTheClipboard->Open() )
+    {
+        wxLogError("Can't open clipboard.");
+
+        return;
+    }
+
+    if ( !wxTheClipboard->IsSupported(wxDF_TEXT) )
+    {
+        wxLogWarning("No text data on clipboard");
+
+        return;
+    }
+
+    wxTextDataObject text;
+    if ( !wxTheClipboard->GetData(&text) )
+    {
+        wxLogError("Can't paste data from the clipboard");
+    }
+    else
+    {
+        wxLogMessage("Text '%s' pasted from the clipboard",
+                     text.GetText().c_str());
+    }
+
+    wxTheClipboard->Close();
 }
 
 // ----------------------------------------------------------------------------
 // Notifications called by the base class
 // ----------------------------------------------------------------------------
-bool DnDText::OnDropText(long, long, const char *psz)
+bool DnDText::OnDropText( wxDropPointCoord, wxDropPointCoord, const wxChar *psz )
 {
-  m_pOwner->Append(psz);
+    m_pOwner->Append(psz);
 
-  return TRUE;
+    return TRUE;
 }
 
-bool DnDFile::OnDropFiles(long, long, size_t nFiles,
-                          const char * const aszFiles[])
+bool DnDFile::OnDropFiles( wxDropPointCoord, wxDropPointCoord, size_t nFiles,
+                           const wxChar* const aszFiles[])
 {
-  wxString str;
-  str.Printf("%d files dropped", nFiles);
-  m_pOwner->Append(str);
-  for ( size_t n = 0; n < nFiles; n++ ) {
-    m_pOwner->Append(aszFiles[n]);
-  }
-
-  return TRUE;
+    wxString str;
+    str.Printf( _T("%d files dropped"), nFiles);
+    m_pOwner->Append(str);
+    for ( size_t n = 0; n < nFiles; n++ ) {
+        m_pOwner->Append(aszFiles[n]);
+    }
+
+    return TRUE;
 }