linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06363
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3161: Drag & drop text into text input fields
------------------------------------------------------------
revno: 3161
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Fri 2012-12-21 23:50:48 +0100
message:
Drag & drop text into text input fields
modified:
changelog.txt
dwt/include/dwt/widgets/TextBox.h
dwt/src/Application.cpp
dwt/src/widgets/TextBox.cpp
win32/main.cpp
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt 2012-12-20 19:38:26 +0000
+++ changelog.txt 2012-12-21 22:50:48 +0000
@@ -12,6 +12,7 @@
* [L#311818] Share file name duplicates due to directory merges (poy)
* [L#311818] Share file name duplicates due to case differences (poy)
* [L#311818] Reject file lists that contain duplicate items (poy)
+* Drag & drop text into text input fields (poy)
Note: The hash registry will be upgraded when running this version for the
first time. Make sure all your drives are connected to avoid re-hashing.
=== modified file 'dwt/include/dwt/widgets/TextBox.h'
--- dwt/include/dwt/widgets/TextBox.h 2012-02-09 19:45:38 +0000
+++ dwt/include/dwt/widgets/TextBox.h 2012-12-21 22:50:48 +0000
@@ -153,6 +153,9 @@
unsigned getLineCount() const;
+ virtual int charFromPos(const ScreenCoordinate& pt) = 0;
+ virtual int lineFromPos(const ScreenCoordinate& pt) = 0;
+
virtual tstring textUnderCursor(const ScreenCoordinate& p, bool includeSpaces = false) = 0;
virtual tstring getSelection() const = 0;
=== modified file 'dwt/src/Application.cpp'
--- dwt/src/Application.cpp 2012-11-05 20:39:11 +0000
+++ dwt/src/Application.cpp 2012-12-21 22:50:48 +0000
@@ -250,8 +250,14 @@
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
dwt::Application::init(nCmdShow);
+ auto hr = ::OleInitialize(nullptr);
+ if(FAILED(hr))
+ return hr;
+
int ret = dwtMain(dwt::Application::instance()); // Call library user's startup function.
+ ::OleUninitialize();
+
dwt::Application::uninit();
return ret;
=== modified file 'dwt/src/widgets/TextBox.cpp'
--- dwt/src/widgets/TextBox.cpp 2012-03-05 20:48:24 +0000
+++ dwt/src/widgets/TextBox.cpp 2012-12-21 22:50:48 +0000
@@ -59,10 +59,121 @@
{
}
+class Dropper : public IDropTarget {
+public:
+ Dropper(TextBoxBase* const w) : IDropTarget(), w(w), ref(0), dragging(false) { }
+
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] _COM_Outptr_*/ void __RPC_FAR *__RPC_FAR *ppvObject)
+ {
+ if(!ppvObject) { return E_POINTER; }
+ if(IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDropTarget)) {
+ *ppvObject = this;
+ AddRef();
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+ }
+
+ virtual ULONG STDMETHODCALLTYPE AddRef( void)
+ {
+ return ++ref;
+ }
+
+ virtual ULONG STDMETHODCALLTYPE Release( void)
+ {
+ if(--ref == 0) { delete this; }
+ return ref;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE DragEnter(
+ /* [unique][in] __RPC__in_opt*/ IDataObject *pDataObj,
+ /* [in] */ DWORD /*grfKeyState*/,
+ /* [in] */ POINTL /*pt*/,
+ /* [out][in] __RPC__inout*/ DWORD *pdwEffect)
+ {
+ if(w->hasStyle(ES_READONLY)) { return S_OK; }
+ FORMATETC formatetc { CF_UNICODETEXT, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ dragging = pDataObj->QueryGetData(&formatetc) == S_OK;
+ if(dragging) {
+ w->setFocus(); // focus to display the caret
+ *pdwEffect = DROPEFFECT_COPY;
+ } else {
+ *pdwEffect = DROPEFFECT_NONE;
+ }
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE DragOver(
+ /* [in] */ DWORD /*grfKeyState*/,
+ /* [in] */ POINTL pt,
+ /* [out][in] __RPC__inout*/ DWORD *pdwEffect)
+ {
+ if(dragging) {
+ moveCaret(pt);
+ *pdwEffect = DROPEFFECT_COPY;
+ } else {
+ *pdwEffect = DROPEFFECT_NONE;
+ }
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE DragLeave( void)
+ {
+ dragging = false;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Drop(
+ /* [unique][in] __RPC__in_opt*/ IDataObject *pDataObj,
+ /* [in] */ DWORD /*grfKeyState*/,
+ /* [in] */ POINTL pt,
+ /* [out][in] __RPC__inout*/ DWORD *pdwEffect)
+ {
+ if(dragging) {
+ FORMATETC formatetc { CF_UNICODETEXT, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM stgmedium;
+ if(pDataObj->GetData(&formatetc, &stgmedium) == S_OK) {
+ if(stgmedium.tymed == TYMED_HGLOBAL && stgmedium.hGlobal) {
+ auto text = reinterpret_cast<LPCTSTR>(::GlobalLock(stgmedium.hGlobal));
+ if(text) {
+ moveCaret(pt);
+ w->replaceSelection(text);
+ ::GlobalUnlock(stgmedium.hGlobal);
+ }
+ }
+ ::ReleaseStgMedium(&stgmedium);
+ }
+ *pdwEffect = DROPEFFECT_COPY;
+ } else {
+ *pdwEffect = DROPEFFECT_NONE;
+ }
+ return S_OK;
+ }
+
+private:
+ inline void moveCaret(const POINTL& pt) {
+ auto pos = w->charFromPos(ScreenCoordinate(Point(pt.x, pt.y)));
+ w->setSelection(pos, pos);
+ }
+
+ TextBoxBase* const w;
+ ULONG ref;
+ bool dragging;
+};
+
void TextBoxBase::create(const Seed& cs) {
lines = cs.lines;
menuSeed = cs.menuSeed;
BaseType::create(cs);
+
+ auto dropper = new Dropper(this);
+ if(::RegisterDragDrop(handle(), dropper) == S_OK) {
+ onDestroy([this] { ::RevokeDragDrop(handle()); });
+ } else {
+ delete dropper;
+ }
}
TextBox::Seed::Seed(const tstring& caption) :
=== modified file 'win32/main.cpp'
--- win32/main.cpp 2012-12-08 17:44:30 +0000
+++ win32/main.cpp 2012-12-21 22:50:48 +0000
@@ -122,10 +122,6 @@
return 1;
}
- HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if(FAILED(hr))
- return hr;
-
try {
std::string module = File(Text::fromT(app.getModuleFileName()), File::READ, File::OPEN).read();
TigerTree tth(TigerTree::calcBlockSize(module.size(), 1));
@@ -172,8 +168,6 @@
shutdown();
- ::CoUninitialize();
-
return 0;
}