]> git.saurik.com Git - wxWidgets.git/blame - samples/dnd/dnd.cpp
Added the forgotten file txtstrm.tex
[wxWidgets.git] / samples / dnd / dnd.cpp
CommitLineData
43d811ea 1/////////////////////////////////////////////////////////////////////////////
457814b5
JS
2// Name: dnd.cpp
3// Purpose: Drag and drop sample
4// Author: Vadim Zeitlin
43d811ea
JS
5// Modified by:
6// Created: 04/01/98
8bbe427f 7// RCS-ID: $Id$
43d811ea 8// Copyright:
8bbe427f 9// Licence: wxWindows licence
43d811ea
JS
10/////////////////////////////////////////////////////////////////////////////
11
c50f1fb9 12#include "wx/wxprec.h"
457814b5
JS
13
14#ifdef __BORLANDC__
15#pragma hdrstop
16#endif
17
18#ifndef WX_PRECOMP
c50f1fb9 19#include "wx/wx.h"
457814b5
JS
20#endif
21
c50f1fb9
VZ
22#include "wx/intl.h"
23#include "wx/log.h"
457814b5 24
c50f1fb9 25#include "wx/dnd.h"
457814b5 26
acbd13a3 27#ifdef __WXMOTIF__
c50f1fb9 28 #error Sorry, drag and drop is not yet implemented on wxMotif.
acbd13a3
JS
29#endif
30
31#if defined(__WXGTK__) || defined(__WXMOTIF__)
c50f1fb9 32 #include "mondrian.xpm"
47908e25
RR
33#endif
34
c50f1fb9
VZ
35#include "wx/clipbrd.h"
36
457814b5 37// ----------------------------------------------------------------------------
2845ddc2 38// Derive two simple classes which just put in the listbox the strings (text or
457814b5
JS
39// file names) we drop on them
40// ----------------------------------------------------------------------------
ab8884ac 41
8dbf4589 42typedef long wxDropPointCoord;
88ac883a 43
457814b5
JS
44class DnDText : public wxTextDropTarget
45{
46public:
c50f1fb9 47 DnDText(wxListBox *pOwner) { m_pOwner = pOwner; }
457814b5 48
c50f1fb9
VZ
49 virtual bool OnDropText(wxDropPointCoord x, wxDropPointCoord y,
50 const wxChar* psz);
457814b5
JS
51
52private:
c50f1fb9 53 wxListBox *m_pOwner;
457814b5
JS
54};
55
56class DnDFile : public wxFileDropTarget
57{
58public:
c50f1fb9 59 DnDFile(wxListBox *pOwner) { m_pOwner = pOwner; }
457814b5 60
88ac883a 61 virtual bool OnDropFiles(wxDropPointCoord x, wxDropPointCoord y,
b03b33e2 62 size_t nFiles, const wxChar* const aszFiles[] );
457814b5
JS
63
64private:
c50f1fb9 65 wxListBox *m_pOwner;
457814b5
JS
66};
67
68// ----------------------------------------------------------------------------
69// Define a new application type
70// ----------------------------------------------------------------------------
ab8884ac 71
457814b5 72class DnDApp : public wxApp
8bbe427f 73{
457814b5 74public:
c50f1fb9 75 bool OnInit();
457814b5
JS
76};
77
78IMPLEMENT_APP(DnDApp);
79
80// ----------------------------------------------------------------------------
81// Define a new frame type
82// ----------------------------------------------------------------------------
83class DnDFrame : public wxFrame
8bbe427f 84{
457814b5 85public:
c50f1fb9
VZ
86 DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
87 ~DnDFrame();
457814b5 88
c50f1fb9
VZ
89 void OnPaint(wxPaintEvent& event);
90 void OnQuit (wxCommandEvent& event);
91 void OnAbout(wxCommandEvent& event);
92 void OnDrag (wxCommandEvent& event);
93 void OnHelp (wxCommandEvent& event);
94 void OnLogClear(wxCommandEvent& event);
95 void OnCopy(wxCommandEvent& event);
96 void OnPaste(wxCommandEvent& event);
43d811ea 97
c50f1fb9
VZ
98 void OnLeftDown(wxMouseEvent& event);
99 void OnRightDown(wxMouseEvent& event);
8bbe427f 100
c50f1fb9 101 DECLARE_EVENT_TABLE()
457814b5
JS
102
103private:
c50f1fb9
VZ
104 wxListBox *m_ctrlFile,
105 *m_ctrlText;
106 wxTextCtrl *m_ctrlLog;
457814b5 107
c50f1fb9 108 wxLog *m_pLog, *m_pLogPrev;
43d811ea 109
c50f1fb9 110 wxString m_strText;
457814b5
JS
111};
112
113// ----------------------------------------------------------------------------
114// IDs for the menu commands
115// ----------------------------------------------------------------------------
ab8884ac 116
457814b5
JS
117enum
118{
c50f1fb9
VZ
119 Menu_Quit = 1,
120 Menu_Drag,
121 Menu_About = 101,
122 Menu_Help,
123 Menu_Clear,
124 Menu_Copy,
125 Menu_Paste
457814b5
JS
126};
127
128BEGIN_EVENT_TABLE(DnDFrame, wxFrame)
c50f1fb9
VZ
129 EVT_MENU(Menu_Quit, DnDFrame::OnQuit)
130 EVT_MENU(Menu_About, DnDFrame::OnAbout)
131 EVT_MENU(Menu_Drag, DnDFrame::OnDrag)
132 EVT_MENU(Menu_Help, DnDFrame::OnHelp)
133 EVT_MENU(Menu_Clear, DnDFrame::OnLogClear)
134 EVT_MENU(Menu_Copy, DnDFrame::OnCopy)
135 EVT_MENU(Menu_Paste, DnDFrame::OnPaste)
136
137 EVT_LEFT_DOWN( DnDFrame::OnLeftDown)
138 EVT_RIGHT_DOWN( DnDFrame::OnRightDown)
139 EVT_PAINT( DnDFrame::OnPaint)
457814b5
JS
140END_EVENT_TABLE()
141
c50f1fb9 142 // `Main program' equivalent, creating windows and returning main app frame
8bbe427f 143bool DnDApp::OnInit()
457814b5 144{
c50f1fb9
VZ
145 // create the main frame window
146 DnDFrame *frame = new DnDFrame((wxFrame *) NULL,
147 "Drag-and-Drop/Clipboard wxWindows Sample",
148 50, 50, 450, 340);
457814b5 149
c50f1fb9
VZ
150 // activate it
151 frame->Show(TRUE);
457814b5 152
c50f1fb9 153 SetTopWindow(frame);
457814b5 154
c50f1fb9 155 return TRUE;
457814b5
JS
156}
157
158DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
43d811ea
JS
159 : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h)),
160 m_strText("wxWindows drag & drop works :-)")
161
457814b5 162{
c50f1fb9
VZ
163 // frame icon and status bar
164 SetIcon(wxICON(mondrian));
165
166 CreateStatusBar();
167
168 // construct menu
169 wxMenu *file_menu = new wxMenu;
170 file_menu->Append(Menu_Drag, "&Test drag...");
171 file_menu->AppendSeparator();
172 file_menu->Append(Menu_Quit, "E&xit");
173
174 wxMenu *log_menu = new wxMenu;
175 log_menu->Append(Menu_Clear, "Clear");
176
177 wxMenu *help_menu = new wxMenu;
178 help_menu->Append(Menu_Help, "&Help...");
179 help_menu->AppendSeparator();
180 help_menu->Append(Menu_About, "&About");
181
182 wxMenu *clip_menu = new wxMenu;
183 clip_menu->Append(Menu_Copy, "&Copy\tCtrl+C");
184 clip_menu->Append(Menu_Paste, "&Paste\tCtrl+V");
185
186 wxMenuBar *menu_bar = new wxMenuBar;
187 menu_bar->Append(file_menu, "&File");
188 menu_bar->Append(log_menu, "&Log");
189 menu_bar->Append(clip_menu, "&Clipboard");
190 menu_bar->Append(help_menu, "&Help");
191
192 SetMenuBar(menu_bar);
193
194 // make a panel with 3 subwindows
195 wxPoint pos(0, 0);
196 wxSize size(400, 200);
197
198 wxString strFile("Drop files here!"), strText("Drop text on me");
199
200 m_ctrlFile = new wxListBox(this, -1, pos, size, 1, &strFile, wxLB_HSCROLL);
201 m_ctrlText = new wxListBox(this, -1, pos, size, 1, &strText, wxLB_HSCROLL);
202
203 m_ctrlLog = new wxTextCtrl(this, -1, "", pos, size,
8bbe427f 204 wxTE_MULTILINE | wxTE_READONLY |
5b077d48 205 wxSUNKEN_BORDER );
457814b5 206
8dbf4589
RR
207#if wxUSE_STD_IOSTREAM
208// redirect log messages to the text window (don't forget to delete it!)
43d811ea
JS
209 m_pLog = new wxLogTextCtrl(m_ctrlLog);
210 m_pLogPrev = wxLog::SetActiveTarget(m_pLog);
8dbf4589 211#endif
457814b5
JS
212
213 // associate drop targets with 2 text controls
bb14db2d 214 m_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile));
88ac883a 215 m_ctrlText->SetDropTarget(new DnDText(m_ctrlText));
457814b5 216
bb14db2d 217 wxLayoutConstraints *c;
457814b5 218
40e1a9c0 219 // Top-left listbox
457814b5 220 c = new wxLayoutConstraints;
8bbe427f
VZ
221 c->left.SameAs(this, wxLeft);
222 c->top.SameAs(this, wxTop);
457814b5 223 c->right.PercentOf(this, wxRight, 50);
43d811ea 224 c->height.PercentOf(this, wxHeight, 40);
457814b5
JS
225 m_ctrlFile->SetConstraints(c);
226
40e1a9c0 227 // Top-right listbox
457814b5
JS
228 c = new wxLayoutConstraints;
229 c->left.SameAs (m_ctrlFile, wxRight);
230 c->top.SameAs (this, wxTop);
231 c->right.SameAs (this, wxRight);
43d811ea 232 c->height.PercentOf(this, wxHeight, 40);
457814b5
JS
233 m_ctrlText->SetConstraints(c);
234
40e1a9c0 235 // Lower text control
457814b5
JS
236 c = new wxLayoutConstraints;
237 c->left.SameAs (this, wxLeft);
238 c->right.SameAs (this, wxRight);
43d811ea
JS
239 c->height.PercentOf(this, wxHeight, 40);
240 c->top.SameAs(m_ctrlText, wxBottom);
457814b5
JS
241 m_ctrlLog->SetConstraints(c);
242
243 SetAutoLayout(TRUE);
244}
245
246void DnDFrame::OnQuit(wxCommandEvent& /* event */)
247{
c50f1fb9 248 Close(TRUE);
457814b5
JS
249}
250
b527aac5
RR
251void DnDFrame::OnPaint(wxPaintEvent& /*event*/)
252{
c50f1fb9
VZ
253 int w = 0;
254 int h = 0;
255 GetClientSize( &w, &h );
8bbe427f 256
c50f1fb9
VZ
257 wxPaintDC dc(this);
258 dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL, FALSE, "charter" ) );
259 dc.DrawText( "Drag text from here!", 20, h-35 );
b527aac5
RR
260}
261
43d811ea
JS
262void DnDFrame::OnDrag(wxCommandEvent& /* event */)
263{
c50f1fb9
VZ
264 wxString strText = wxGetTextFromUser
265 (
266 "After you enter text in this dialog, press any mouse\n"
267 "button in the bottom (empty) part of the frame and \n"
268 "drag it anywhere - you will be in fact dragging the\n"
269 "text object containing this text",
270 "Please enter some text", m_strText, this
271 );
272
273 m_strText = strText;
43d811ea
JS
274}
275
457814b5
JS
276void DnDFrame::OnAbout(wxCommandEvent& /* event */)
277{
c50f1fb9
VZ
278 wxMessageBox("Drag-&-Drop Demo\n"
279 "Please see \"Help|Help...\" for details\n"
280 "Copyright (c) 1998 Vadim Zeitlin",
281 "About wxDnD",
282 wxICON_INFORMATION | wxOK,
283 this);
457814b5
JS
284}
285
286void DnDFrame::OnHelp(wxCommandEvent& /* event */)
287{
c50f1fb9
VZ
288 wxMessageDialog dialog(this,
289 "This small program demonstrates drag & drop support in wxWindows. The program window\n"
290 "consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
291 "going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
292 "and the right one accepts text.\n"
293 "\n"
294 "To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
295 "the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
296 "Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
297 "File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
298 "work with files) and see what changes.\n"
299 "\n"
300 "To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
301 "it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
302 "to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
303 "change, don't release the mouse button until it does. You can change the string being\n"
304 "dragged in in \"File|Test drag...\" dialog.\n"
305 "\n"
306 "\n"
307 "Please send all questions/bug reports/suggestions &c to \n"
308 "Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
309 "wxDnD Help");
310
311 dialog.ShowModal();
457814b5
JS
312}
313
e3e65dac 314void DnDFrame::OnLogClear(wxCommandEvent& /* event */ )
43d811ea 315{
c50f1fb9 316 m_ctrlLog->Clear();
43d811ea
JS
317}
318
30dea054 319void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
43d811ea 320{
c50f1fb9
VZ
321 if ( !m_strText.IsEmpty() )
322 {
323 // start drag operation
0c77152e 324#ifdef __WXMSW__
c50f1fb9
VZ
325 wxTextDataObject textData(m_strText);
326 wxDropSource dragSource( textData, this );
0c77152e 327#else
c50f1fb9 328 wxDropSource dragSource( new wxTextDataObject (m_strText), this, wxIcon(mondrian_xpm) );
0c77152e 329#endif
c50f1fb9
VZ
330 const char *pc;
331
332 switch ( dragSource.DoDragDrop(TRUE) )
333 {
334 case wxDragError: pc = "Error!"; break;
335 case wxDragNone: pc = "Nothing"; break;
336 case wxDragCopy: pc = "Copied"; break;
337 case wxDragMove: pc = "Moved"; break;
338 case wxDragCancel: pc = "Cancelled"; break;
339 default: pc = "Huh?"; break;
340 }
341
342 SetStatusText(wxString("Drag result: ") + pc);
43d811ea 343 }
43d811ea
JS
344}
345
30dea054
RR
346void DnDFrame::OnRightDown(wxMouseEvent &event )
347{
c50f1fb9 348 wxMenu *menu = new wxMenu;
8bbe427f 349
c50f1fb9
VZ
350 menu->Append(Menu_Drag, "&Test drag...");
351 menu->Append(Menu_About, "&About");
352 menu->Append(Menu_Quit, "E&xit");
8bbe427f 353
c50f1fb9 354 PopupMenu( menu, event.GetX(), event.GetY() );
30dea054
RR
355}
356
457814b5
JS
357DnDFrame::~DnDFrame()
358{
8dbf4589 359#if wxUSE_STD_IOSTREAM
c50f1fb9
VZ
360 if ( m_pLog != NULL ) {
361 if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog )
362 delete m_pLog;
363 }
8dbf4589 364#endif
c50f1fb9
VZ
365}
366
367// ---------------------------------------------------------------------------
368// clipboard
369// ---------------------------------------------------------------------------
370
371void DnDFrame::OnCopy(wxCommandEvent& WXUNUSED(event))
372{
373 if ( !wxTheClipboard->Open() )
374 {
b56baa2d 375 wxLogError(_T("Can't open clipboard."));
c50f1fb9
VZ
376
377 return;
378 }
379
380 if ( !wxTheClipboard->AddData(new wxTextDataObject(m_strText)) )
381 {
b56baa2d 382 wxLogError(_T("Can't copy data to the clipboard"));
c50f1fb9
VZ
383 }
384 else
385 {
b56baa2d 386 wxLogMessage(_T("Text '%s' put on the clipboard"), m_strText.c_str());
c50f1fb9
VZ
387 }
388
389 wxTheClipboard->Close();
390}
391
392void DnDFrame::OnPaste(wxCommandEvent& WXUNUSED(event))
393{
394 if ( !wxTheClipboard->Open() )
395 {
b56baa2d 396 wxLogError(_T("Can't open clipboard."));
c50f1fb9
VZ
397
398 return;
399 }
400
401 if ( !wxTheClipboard->IsSupported(wxDF_TEXT) )
402 {
b56baa2d 403 wxLogWarning(_T("No text data on clipboard"));
c50f1fb9
VZ
404
405 return;
406 }
407
408 wxTextDataObject text;
409 if ( !wxTheClipboard->GetData(&text) )
410 {
b56baa2d 411 wxLogError(_T("Can't paste data from the clipboard"));
c50f1fb9
VZ
412 }
413 else
414 {
b56baa2d 415 wxLogMessage(_T("Text '%s' pasted from the clipboard"),
c50f1fb9
VZ
416 text.GetText().c_str());
417 }
418
419 wxTheClipboard->Close();
457814b5
JS
420}
421
422// ----------------------------------------------------------------------------
423// Notifications called by the base class
424// ----------------------------------------------------------------------------
88ac883a 425bool DnDText::OnDropText( wxDropPointCoord, wxDropPointCoord, const wxChar *psz )
457814b5 426{
c50f1fb9 427 m_pOwner->Append(psz);
457814b5 428
c50f1fb9 429 return TRUE;
457814b5
JS
430}
431
88ac883a 432bool DnDFile::OnDropFiles( wxDropPointCoord, wxDropPointCoord, size_t nFiles,
b03b33e2 433 const wxChar* const aszFiles[])
457814b5 434{
c50f1fb9
VZ
435 wxString str;
436 str.Printf( _T("%d files dropped"), nFiles);
437 m_pOwner->Append(str);
438 for ( size_t n = 0; n < nFiles; n++ ) {
439 m_pOwner->Append(aszFiles[n]);
440 }
441
442 return TRUE;
457814b5 443}