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