]> git.saurik.com Git - wxWidgets.git/blame - src/os2/dnd.cpp
just added a comment
[wxWidgets.git] / src / os2 / dnd.cpp
CommitLineData
0e320a79 1///////////////////////////////////////////////////////////////////////////////
cb7d7375 2// Name: src/os2/dnd.cpp
0e320a79 3// Purpose: wxDropTarget, wxDropSource, wxDataObject implementation
6dddc146 4// Author: David Webster
0e320a79 5// Modified by:
6dddc146 6// Created: 10/21/99
0e320a79
DW
7// RCS-ID: $Id$
8// Copyright: (c) 1998 AUTHOR
65571936 9// Licence: wxWindows licence
0e320a79
DW
10///////////////////////////////////////////////////////////////////////////////
11
6670f564
WS
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#if wxUSE_DRAG_AND_DROP
16
0e320a79
DW
17#include "wx/window.h"
18#include "wx/app.h"
19#include "wx/gdicmn.h"
e6ebb514 20#include "wx/dnd.h"
0e320a79 21
55945915
SN
22#define INCL_PM
23#define INCL_DOS
24#include <os2.h>
25
0e320a79
DW
26// ----------------------------------------------------------------------------
27// global
28// ----------------------------------------------------------------------------
29
4fd899b6
DW
30/////////////////////////////////////////////////////////////////////////////
31// Private functions
32/////////////////////////////////////////////////////////////////////////////
33
9923c37d 34#if 0
4fd899b6
DW
35static wxDragResult ConvertDragEffectToResult (
36 DWORD dwEffect
37)
38{
39 switch (dwEffect)
40 {
41 case DO_COPY:
42 return wxDragCopy;
43
44 case DO_LINK:
45 return wxDragLink;
46
47 case DO_MOVE:
48 return wxDragMove;
49
50 default:
51 case DO_DEFAULT:
52 return wxDragNone;
53 }
54} // end of ConvertDragEffectToResult
55
56static DWORD ConvertDragResultToEffect (
57 wxDragResult eResult
58)
59{
60 switch (eResult)
61 {
62 case wxDragCopy:
63 return DO_COPY;
64
65 case wxDragLink:
66 return DO_LINK;
67
68 case wxDragMove:
69 return DO_MOVE;
70
71 default:
72 case wxDragNone:
73 return DO_DEFAULT;
74 }
75} // end of ConvertDragResultToEffect
9923c37d 76#endif
4fd899b6
DW
77
78class CIDropTarget
79{
80public:
81 CIDropTarget(wxDropTarget* pTarget)
82 {
83 m_pTarget = pTarget;
84 m_pDragItem = NULL;
85 }
86 virtual ~CIDropTarget() { }
87
88 //
89 // Accessors for CDropTarget
90 //
91 void Free(void) { ::DrgFreeDraginfo(m_pDragInfo); }
92 PDRAGINFO GetDataSource(void) { return m_pDragInfo; }
93 void SetDataSource(PDRAGINFO pDragInfo) { m_pDragInfo = pDragInfo; }
94 void SetHWND(HWND hWnd) { m_hWnd = hWnd; }
95
96 //
97 // CIDropTarget methods
98 //
99 bool DragLeave(void);
100 MRESULT DragOver(void);
101 MRESULT Drop(void);
102
103protected:
104
105 PDRAGINFO m_pDragInfo;
106 PDRAGITEM m_pDragItem; // !NULL between DragEnter and DragLeave/Drop
107 wxDropTarget* m_pTarget; // the real target (we're just a proxy)
108 HWND m_hWnd; // window we're associated with
109}; // end of CLASS CIDropTarget
110
111bool CIDropTarget::DragLeave()
112{
113 //
114 // Remove the UI feedback
115 //
116 m_pTarget->OnLeave();
117
118 //
119 // Release the held object
120 //
121 Free();
d0ee33f5 122 return true;
4fd899b6
DW
123} // end of CIDropTarget::DragLeave
124
125MRESULT CIDropTarget::DragOver ()
126{
127 char zBuffer[128];
128 ULONG ulBytes;
322d45dd 129 USHORT uOp = 0;
4fd899b6
DW
130 USHORT uIndicator;
131 ULONG ulItems;
132 ULONG i;
133
134 ::DrgAccessDraginfo(m_pDragInfo);
135 switch(m_pDragInfo->usOperation)
136 {
137 case DO_UNKNOWN:
138 Free();
139 return (MRFROM2SHORT(DOR_NODROPOP, 0));
140
141 case DO_DEFAULT:
142 m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, 0);
143 ulBytes = ::DrgQueryStrName( m_pDragItem->hstrContainerName
144 ,128
145 ,zBuffer
146 );
147 if (!ulBytes)
148 return (MRFROM2SHORT(DOR_NODROPOP, 0));
149 else
150 uOp = DO_MOVE;
151 break;
152
153 case DO_COPY:
154 case DO_MOVE:
155 uOp = m_pDragInfo->usOperation;
156 break;
157 }
158 uIndicator = DOR_DROP;
159 ulItems = (ULONG)::DrgQueryDragitemCount(m_pDragInfo);
160 for (i = 0; i < ulItems; i++)
161 {
162 m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, i);
163 if (((m_pDragItem->fsSupportedOps & DO_COPYABLE) &&
164 (uOp == (USHORT)DO_COPY)) ||
165 ((m_pDragItem->fsSupportedOps & DO_MOVEABLE) &&
166 (uOp == (USHORT)DO_COPY)))
167 {
168 if (::DrgVerifyRMF(m_pDragItem, "DRM_OS2FILE", "DRF_UNKNOWN"))
169 uIndicator = (USHORT)DOR_DROP;
170 else
171 uIndicator = (USHORT)DOR_NEVERDROP;
172 }
173 }
174 Free();
175 return (MRFROM2SHORT(uIndicator, uOp));
176} // end of CIDropTarget::DragOver
177
178// #pragma page "CIDropTarget::Drop"
179/////////////////////////////////////////////////////////////////////////////
180//
181// CIDropTarget::Drop
182//
183// Instructs the drop target to paste data that was just now dropped on it.
184//
185// PARAMETERS
186// pIDataSource -- the data to paste
187// dwKeyState -- kbd & mouse state
188// pt -- mouse coordinates
189// pdwEffect -- effect flag
190//
191// RETURN VALUE
192// STDMETHODIMP S_OK
193//
194/////////////////////////////////////////////////////////////////////////////
195MRESULT CIDropTarget::Drop ()
196{
197 char zBuffer[128];
198 ULONG ulBytes;
322d45dd 199 USHORT uOp = 0;
4fd899b6
DW
200 USHORT uIndicator;
201 ULONG ulItems;
202 ULONG i;
203
204 ::DrgAccessDraginfo(m_pDragInfo);
205 switch(m_pDragInfo->usOperation)
206 {
207 case DO_UNKNOWN:
208 Free();
209 return (MRFROM2SHORT(DOR_NODROPOP, 0));
210
211 case DO_DEFAULT:
212 m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, 0);
213 ulBytes = ::DrgQueryStrName( m_pDragItem->hstrContainerName
214 ,128
215 ,zBuffer
216 );
217 if (!ulBytes)
218 return (MRFROM2SHORT(DOR_NODROPOP, 0));
219 else
220 uOp = DO_MOVE;
221 break;
222
223 case DO_COPY:
224 case DO_MOVE:
225 uOp = m_pDragInfo->usOperation;
226 break;
227 }
228 uIndicator = DOR_DROP;
229 ulItems = (ULONG)::DrgQueryDragitemCount(m_pDragInfo);
230 for (i = 0; i < ulItems; i++)
231 {
232 m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, i);
233 if (((m_pDragItem->fsSupportedOps & DO_COPYABLE) &&
234 (uOp == (USHORT)DO_COPY)) ||
235 ((m_pDragItem->fsSupportedOps & DO_MOVEABLE) &&
236 (uOp == (USHORT)DO_COPY)))
237 {
238 if (::DrgVerifyRMF(m_pDragItem, "DRM_OS2FILE", "DRF_UNKNOWN"))
239 uIndicator = (USHORT)DOR_DROP;
240 else
241 uIndicator = (USHORT)DOR_NEVERDROP;
242 }
243 }
244
245 //
246 // First ask the drop target if it wants data
247 //
248 if (m_pTarget->OnDrop( m_pDragInfo->xDrop
249 ,m_pDragInfo->yDrop
250 ))
251 {
d0ee33f5 252 wxDragResult eRc = wxDragNone;
4fd899b6
DW
253
254 //
255 // And now it has the data
256 //
257 eRc = m_pTarget->OnData( m_pDragInfo->xDrop
258 ,m_pDragInfo->yDrop
259 ,eRc
260 );
261 }
d0ee33f5 262 //else: OnDrop() returned false, no need to copy data
4fd899b6
DW
263
264 //
265 // Release the held object
266 //
267 Free();
268 return (MRFROM2SHORT(uIndicator, uOp));
269} // end of CIDropTarget::Drop
270
0e320a79
DW
271// ----------------------------------------------------------------------------
272// wxDropTarget
273// ----------------------------------------------------------------------------
274
4fd899b6 275wxDropTarget::wxDropTarget (
6dddc146
DW
276 wxDataObject* pDataObject
277)
0e320a79 278{
4fd899b6
DW
279 m_dataObject = pDataObject;
280 m_pDropTarget = new CIDropTarget(this);
281} // end of wxDropTarget::wxDropTarget
0e320a79
DW
282
283wxDropTarget::~wxDropTarget()
284{
4fd899b6
DW
285 Release();
286} // end of wxDropTarget::~wxDropTarget
0e320a79 287
4fd899b6 288bool wxDropTarget::GetData ()
6dddc146 289{
4fd899b6 290 wxDataFormat vFormat = GetSupportedFormat(m_pDropTarget->GetDataSource());
0e320a79 291
4fd899b6
DW
292 if (vFormat == wxDF_INVALID)
293 {
d0ee33f5 294 return false;
4fd899b6
DW
295 }
296 //
297 // Under OS/2 we already have the data via the attached DRAGITEM's
298 //
d0ee33f5 299 return true;
4fd899b6
DW
300} // end of wxDropTarget::GetData
301
302wxDataFormat wxDropTarget::GetSupportedFormat (
303 PDRAGINFO pDataSource
304) const
0e320a79 305{
4fd899b6
DW
306 PDRAGITEM pDragItem;
307 wxDataFormat vFormat;
308 wxDataFormat* pFormats;
309 ULONG ulFormats = m_dataObject->GetFormatCount(wxDataObject::Set);
310 ULONG ulItems = (ULONG)::DrgQueryDragitemCount(pDataSource);
311 ULONG i;
312 ULONG n;
313 wxString sMechanism;
314 wxString sFormat;
d0ee33f5 315 bool bValid = false;
0e320a79 316
4fd899b6
DW
317 pFormats = ulFormats == 1 ? &vFormat : new wxDataFormat[ulFormats];
318 m_dataObject->GetAllFormats( pFormats
319 ,wxDataObject::Set
320 );
321
322 for (n = 0; n < ulFormats; n++)
323 {
324 switch(pFormats[n].GetType())
325 {
326 case wxDF_TEXT:
327 case wxDF_FILENAME:
328 case wxDF_HTML:
0fba44b4
DW
329 sMechanism = _T("DRM_OS2FILE");
330 sFormat = _T("DRF_TEXT");
4fd899b6
DW
331 break;
332
333 case wxDF_OEMTEXT:
0fba44b4
DW
334 sMechanism = _T("DRM_OS2FILE");
335 sFormat = _T("DRF_OEMTEXT");
4fd899b6
DW
336 break;
337
338 case wxDF_BITMAP:
0fba44b4
DW
339 sMechanism = _T("DRM_OS2FILE");
340 sFormat = _T("DRF_BITMAP");
4fd899b6
DW
341 break;
342
343 case wxDF_METAFILE:
344 case wxDF_ENHMETAFILE:
0fba44b4
DW
345 sMechanism = _T("DRM_OS2FILE");
346 sFormat = _T("DRF_METAFILE");
4fd899b6
DW
347 break;
348
349 case wxDF_TIFF:
0fba44b4
DW
350 sMechanism = _T("DRM_OS2FILE");
351 sFormat = _T("DRF_TIFF");
4fd899b6
DW
352 break;
353
354 case wxDF_SYLK:
0fba44b4
DW
355 sMechanism = _T("DRM_OS2FILE");
356 sFormat = _T("DRF_SYLK");
4fd899b6
DW
357 break;
358
359 case wxDF_DIF:
0fba44b4
DW
360 sMechanism = _T("DRM_OS2FILE");
361 sFormat = _T("DRF_DIF");
4fd899b6
DW
362 break;
363
364 case wxDF_DIB:
0fba44b4
DW
365 sMechanism = _T("DRM_OS2FILE");
366 sFormat = _T("DRF_DIB");
4fd899b6
DW
367 break;
368
369 case wxDF_PALETTE:
370 case wxDF_PENDATA:
371 case wxDF_RIFF:
372 case wxDF_WAVE:
373 case wxDF_UNICODETEXT:
374 case wxDF_LOCALE:
0fba44b4
DW
375 sMechanism = _T("DRM_OS2FILE");
376 sFormat = _T("DRF_UNKNOWN");
4fd899b6
DW
377 break;
378
379 case wxDF_PRIVATE:
0fba44b4
DW
380 sMechanism = _T("DRM_OBJECT");
381 sFormat = _T("DRF_UNKNOWN");
4fd899b6
DW
382 break;
383 }
384 for (i = 0; i < ulItems; i++)
385 {
386 pDragItem = ::DrgQueryDragitemPtr(pDataSource, i);
0fba44b4 387 if (::DrgVerifyRMF(pDragItem, (PSZ)sMechanism.c_str(), (PSZ)sFormat.c_str()))
4fd899b6 388 {
d0ee33f5 389 bValid = true;
4fd899b6
DW
390 break;
391 }
392 }
393 if (bValid)
394 {
395 vFormat = pFormats[n];
396 break;
397 }
398 }
399 if (pFormats != &vFormat)
400 {
401 //
402 // Free memory if we allocated it
403 //
404 delete [] pFormats;
405 }
406 return (n < ulFormats ? vFormat : wxFormatInvalid);
407} // end of wxDropTarget::GetSupportedFormat
408
409bool wxDropTarget::IsAcceptedData (
410 PDRAGINFO pDataSource
411) const
0e320a79 412{
4fd899b6
DW
413 return (GetSupportedFormat(pDataSource) != wxDF_INVALID);
414} // end of wxDropTarget::IsAcceptedData
0e320a79 415
4fd899b6 416void wxDropTarget::Release ()
0e320a79 417{
4fd899b6
DW
418 m_pDropTarget->Free();
419} // end of wxDropTarget::Release
420
0e320a79 421
4fd899b6
DW
422wxDragResult wxDropTarget::OnData (
423 wxCoord WXUNUSED(vX)
424, wxCoord WXUNUSED(y)
425, wxDragResult WXUNUSED(vResult)
004fd0c8
DW
426)
427{
004fd0c8 428 return (wxDragResult)0;
4fd899b6 429} // end of wxDropTarget::OnData
004fd0c8 430
4fd899b6
DW
431bool wxDropTarget::OnDrop (
432 wxCoord WXUNUSED(x)
433, wxCoord WXUNUSED(y)
6dddc146
DW
434)
435{
d0ee33f5 436 return true;
4fd899b6 437} // end of wxDropTarget::OnDrop
0e320a79 438
0e320a79
DW
439//-------------------------------------------------------------------------
440// wxDropSource
441//-------------------------------------------------------------------------
442
cb7d7375 443wxDropSource::wxDropSource ( wxWindow* WXUNUSED(pWin) )
0e320a79 444{
4fd899b6
DW
445 Init();
446} // end of wxDropSource::wxDropSource
0e320a79 447
cb7d7375 448wxDropSource::wxDropSource ( wxDataObject& rData, wxWindow* WXUNUSED(pWin) )
0e320a79 449{
4fd899b6
DW
450 Init();
451 SetData(rData);
452} // end of wxDropSource::wxDropSource
0e320a79 453
4fd899b6 454wxDropSource::~wxDropSource ()
0e320a79 455{
4fd899b6
DW
456 ::DrgFreeDraginfo(m_pDragInfo);
457} // end of wxDropSource::~wxDropSource
0e320a79 458
4fd899b6 459wxDragResult wxDropSource::DoDragDrop (
2245b2b2 460 int WXUNUSED(flags)
6dddc146 461)
0e320a79 462{
4fd899b6
DW
463 //
464 // Need to specify drag items in derived classes that know their data types
465 // before calling DoDragDrop
466 //
467 if (::DrgDrag( m_pWindow->GetHWND()
468 ,m_pDragInfo
469 ,&m_vDragImage
470 ,m_ulItems
471 ,VK_BUTTON2
472 ,NULL
473 ) != NULLHANDLE)
474 {
475 switch(m_pDragInfo->usOperation)
476 {
477 case DO_COPY:
478 return wxDragCopy;
479
480 case DO_MOVE:
481 return wxDragCopy;
482
483 case DO_LINK:
484 return wxDragCopy;
485
486 default:
487 return wxDragNone;
488 }
489 }
6dddc146 490 return wxDragError;
4fd899b6 491} // end of wxDropSource::DoDragDrop
6dddc146 492
4fd899b6
DW
493bool wxDropSource::GiveFeedback (
494 wxDragResult eEffect
495)
0e320a79 496{
4fd899b6
DW
497 const wxCursor& rCursor = GetCursor(eEffect);
498
499 if (rCursor.Ok())
500 {
501 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)rCursor.GetHCURSOR());
502 m_vDragImage.hImage = (LHANDLE)rCursor.GetHCURSOR();
503 switch(eEffect)
504 {
505 case wxDragCopy:
506 m_pDragInfo->usOperation = DO_COPY;
507 break;
508
509 case wxDragMove:
510 m_pDragInfo->usOperation = DO_MOVE;
511 break;
512
513 case wxDragLink:
514 m_pDragInfo->usOperation = DO_LINK;
515 break;
9923c37d
DW
516
517 case wxDragNone:
518 case wxDragCancel:
519 case wxDragError:
520 break;
4fd899b6 521 }
d0ee33f5 522 return true;
4fd899b6
DW
523 }
524 else
525 {
d0ee33f5 526 return false;
4fd899b6
DW
527 }
528} // end of GuiAdvDnd_CDropSource::GiveFeedback
529
530void wxDropSource::Init ()
531{
532 m_pDragInfo = ::DrgAllocDraginfo(m_ulItems);
533
534 //
535 // Set a default drag image struct with what we know so far
536 //
537 m_vDragImage.cb = sizeof(DRAGIMAGE);
538 m_vDragImage.cptl = 0; // non-zero if fl is DRG_POLYGON
539 m_vDragImage.hImage = 0; // Set in GiveFeedback
540 m_vDragImage.sizlStretch.cx = 20L;
541 m_vDragImage.sizlStretch.cy = 20L;
542 m_vDragImage.fl = DRG_ICON | DRG_STRETCH;
543 m_vDragImage.cxOffset = 0;
544 m_vDragImage.cyOffset = 0;
545
cb7d7375
WS
546 HSTR hStrType = ::DrgAddStrHandle(DRT_UNKNOWN);
547 HSTR hStrRMF;
548 HSTR hStrContainer;
549 wxChar zFormats[128];
550 wxChar zContainer[128];
551 USHORT uSize = (USHORT)(GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1);
552 wxChar* pzBuffer = new wxChar[uSize];
4fd899b6
DW
553
554 memset(pzBuffer, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()));
555 pzBuffer[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0';
556 GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat()
557 ,(void*)pzBuffer
558 );
559
0fba44b4
DW
560 wxStrcpy(zFormats, _T("<DRM_OS2FILE, DRF_UNKNOWN>"));
561 wxStrcpy(zContainer, GetDataObject()->GetPreferredFormat().GetId());
4fd899b6 562
0fba44b4
DW
563 hStrRMF = ::DrgAddStrHandle((PSZ)zFormats);
564 hStrContainer = ::DrgAddStrHandle((PSZ)zContainer);
4fd899b6
DW
565
566 m_pDragItem = new DRAGITEM[m_ulItems];
55945915 567 for (ULONG i = 0; i < m_ulItems; i++)
4fd899b6
DW
568 {
569 m_pDragItem[i].hwndItem = m_pWindow->GetHWND();
570 m_pDragItem[i].hstrType = hStrType;
571 m_pDragItem[i].hstrRMF = hStrRMF;
572 m_pDragItem[i].hstrContainerName = hStrContainer;
573 m_pDragItem[i].fsControl = 0;
574 m_pDragItem[i].fsSupportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;
0fba44b4 575 m_pDragItem[i].hstrSourceName = ::DrgAddStrHandle((PSZ)pzBuffer);
4fd899b6
DW
576 m_pDragItem[i].hstrTargetName = m_pDragItem[i].hstrSourceName;
577 m_pDragItem[i].ulItemID = i;
578 ::DrgSetDragitem( m_pDragInfo
579 ,&m_pDragItem[i]
580 ,sizeof(DRAGITEM)
581 ,0
582 );
583 }
584 delete [] pzBuffer;
585 delete [] m_pDragItem;
586} // end of wxDropSource::Init
0e320a79 587
7e99520b 588#endif //wxUSE_DRAG_AND_DROP