// Author: Vadim Zeitlin
// Modified by:
// Created: 04/01/98
-// RCS-ID:
+// RCS-ID: $Id$
// Copyright:
-// Licence: wxWindows licence
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#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 __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 2 simple classes which just put in the listbox the strings (text or
+// 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;
};
// ----------------------------------------------------------------------------
// Define a new application type
// ----------------------------------------------------------------------------
+
class DnDApp : public wxApp
-{
+{
public:
- bool OnInit();
+ bool OnInit();
};
IMPLEMENT_APP(DnDApp);
// Define a new frame type
// ----------------------------------------------------------------------------
class DnDFrame : public wxFrame
-{
+{
public:
- DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
- ~DnDFrame();
+ 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);
+ 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);
- void OnMouseBtnDown(wxMouseEvent& event);
+ void OnLeftDown(wxMouseEvent& event);
+ void OnRightDown(wxMouseEvent& event);
- bool OnClose();
-
- 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;
};
// ----------------------------------------------------------------------------
// IDs for the menu commands
// ----------------------------------------------------------------------------
+
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(OnMouseBtnDown)
- EVT_RIGHT_DOWN(OnMouseBtnDown)
- EVT_MIDDLE_DOWN(OnMouseBtnDown)
+ 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
-bool DnDApp::OnInit(void)
+ // `Main program' equivalent, creating windows and returning main app frame
+bool DnDApp::OnInit()
{
- // create the main frame window
- DnDFrame *frame = new DnDFrame(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)
m_strText("wxWindows drag & drop works :-)")
{
+ // frame icon and status bar
+ SetIcon(wxICON(mondrian));
-#ifdef __WXMSW__
- // frame icon and status bar
- SetIcon(wxIcon("mondrian"));
-#endif
-
- 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");
-
- 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");
-
- wxMenuBar *menu_bar = new wxMenuBar;
- menu_bar->Append(file_menu, "&File");
- menu_bar->Append(log_menu, "&Log");
- menu_bar->Append(help_menu, "&Help");
-
- SetMenuBar(menu_bar);
-
- // make a panel with 3 subwindows
- wxPoint pos(0, 0);
- wxSize size(400, 200);
-
- 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_ctrlLog = new wxTextCtrl(this, -1, "", pos, size,
- wxTE_MULTILINE | wxTE_READONLY |
- wxSUNKEN_BORDER| wxHSCROLL);
-
- // redirect log messages to the text window (don't forget to delete it!)
+ 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");
+
+ 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 *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(clip_menu, "&Clipboard");
+ menu_bar->Append(help_menu, "&Help");
+
+ SetMenuBar(menu_bar);
+
+ // make a panel with 3 subwindows
+ wxPoint pos(0, 0);
+ wxSize size(400, 200);
+
+ 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_ctrlLog = new wxTextCtrl(this, -1, "", pos, size,
+ wxTE_MULTILINE | wxTE_READONLY |
+ wxSUNKEN_BORDER );
+
+#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_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile));
+ m_ctrlText->SetDropTarget(new DnDText(m_ctrlText));
- wxLayoutConstraints *c;
+ wxLayoutConstraints *c;
// Top-left listbox
c = new wxLayoutConstraints;
- c->left.SameAs (this, wxLeft);
- c->top.SameAs (this, wxTop);
+ c->left.SameAs(this, wxLeft);
+ c->top.SameAs(this, wxTop);
c->right.PercentOf(this, wxRight, 50);
c->height.PercentOf(this, wxHeight, 40);
m_ctrlFile->SetConstraints(c);
c->right.SameAs (this, wxRight);
c->height.PercentOf(this, wxHeight, 40);
c->top.SameAs(m_ctrlText, wxBottom);
-
m_ctrlLog->SetConstraints(c);
SetAutoLayout(TRUE);
void DnDFrame::OnQuit(wxCommandEvent& /* event */)
{
- Close(TRUE);
+ Close(TRUE);
+}
+
+void DnDFrame::OnPaint(wxPaintEvent& /*event*/)
+{
+ 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-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 consists of 3 parts: the bottom pane is for "
-"debug messages, so that you can see what's going on inside. "
-"The top part is split into 2 listboxes, the left one accepts "
-"files and the right one accepts text."
-"\n\n"
-"To test wxDropTarget: open wordpad (write.exe), select some text in "
-"it and drag it to the right listbox (you'll notice the usual visual "
-"feedback, i.e. the cursor will change). Also, try dragging some "
-"files (you can select several at once) from Windows Explorer (or "
-"File Manager) to the left pane. Hold down Ctrl/Shift keys when "
-"you drop text (doesn't 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 it to wordpad or any other droptarget accepting "
-"text (and of course you can just drag it to the right pane). Due to "
-"a lot of trace messages, the cursor might take some time to change, "
-"don't release the mouse button until it does. You can change the "
-"string being dragged in in \"File|Test drag...\" dialog."
-"\n\n"
-"Please send all questions/bug reports/suggestions &c to "
-"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();
+}
+
+void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
+{
+ 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::OnRightDown(wxMouseEvent &event )
+{
+ wxMenu *menu = new wxMenu;
+
+ menu->Append(Menu_Drag, "&Test drag...");
+ menu->Append(Menu_About, "&About");
+ menu->Append(Menu_Quit, "E&xit");
+
+ PopupMenu( menu, event.GetX(), event.GetY() );
}
-bool DnDFrame::OnClose()
-{
- return TRUE;
+DnDFrame::~DnDFrame()
+{
+#if wxUSE_STD_IOSTREAM
+ if ( m_pLog != NULL ) {
+ if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog )
+ delete m_pLog;
+ }
+#endif
}
-void DnDFrame::OnMouseBtnDown(wxMouseEvent& /* event */ )
+// ---------------------------------------------------------------------------
+// clipboard
+// ---------------------------------------------------------------------------
+
+void DnDFrame::OnCopy(wxCommandEvent& WXUNUSED(event))
{
- if ( !m_strText.IsEmpty() ) {
- // start drag operation
- wxTextDataObject data(m_strText);
- wxDropSource dragSource(data, this);
- const char *pc;
-
- switch ( dragSource.DoDragDrop(TRUE) ) {
- case wxDropSource::Error: pc = "Error!"; break;
- case wxDropSource::None: pc = "Nothing"; break;
- case wxDropSource::Copy: pc = "Copied"; break;
- case wxDropSource::Move: pc = "Moved"; break;
- case wxDropSource::Cancel: pc = "Cancelled"; break;
- default: pc = "Huh?"; break;
+ if ( !wxTheClipboard->Open() )
+ {
+ wxLogError("Can't open clipboard.");
+
+ return;
}
- SetStatusText(wxString("Drag result: ") + pc);
- }
+ 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());
+ }
+
+ 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;
}