Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / ui / querydesign / TableWindowListBox.cxx
blob173d85f0366c99b20d313b9d07d593ff965342bc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "TableWindowListBox.hxx"
21 #include "TableWindow.hxx"
22 #include "QueryDesignView.hxx"
23 #include "QueryTableView.hxx"
24 #include "querycontroller.hxx"
25 #include "JoinExchange.hxx"
26 #include <osl/diagnose.h>
27 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
28 #include <vcl/svapp.hxx>
30 using namespace dbaui;
31 using namespace ::com::sun::star::sdbc;
32 using namespace ::com::sun::star::uno;
33 using namespace ::com::sun::star::datatransfer;
35 OJoinExchangeData::OJoinExchangeData(OTableWindowListBox* pBox)
36 : pListBox(pBox)
37 , pEntry(pBox->FirstSelected())
38 { }
40 const sal_uLong SCROLLING_TIMESPAN = 500;
41 const long LISTBOX_SCROLLING_AREA = 6;
42 // class OTableWindowListBox
43 OTableWindowListBox::OTableWindowListBox( OTableWindow* pParent )
44 :SvTreeListBox( pParent, WB_HASBUTTONS | WB_BORDER)
45 ,m_aMousePos( Point(0,0) )
46 ,m_pTabWin( pParent )
47 ,m_nDropEvent(0)
48 ,m_nUiEvent(0)
49 ,m_bReallyScrolled( false )
51 m_aScrollTimer.SetTimeout( SCROLLING_TIMESPAN );
52 SetDoubleClickHdl( LINK(this, OTableWindowListBox, OnDoubleClick) );
54 SetSelectionMode(SINGLE_SELECTION);
56 SetHighlightRange( );
59 void OTableWindowListBox::dragFinished( )
61 // first show the error msg when existing
62 m_pTabWin->getDesignView()->getController().showError(m_pTabWin->getDesignView()->getController().clearOccurredError());
63 // second look for ui activities which should happen after d&d
64 if (m_nUiEvent)
65 Application::RemoveUserEvent(m_nUiEvent);
66 m_nUiEvent = Application::PostUserEvent(LINK(this, OTableWindowListBox, LookForUiHdl), NULL, true);
69 OTableWindowListBox::~OTableWindowListBox()
71 disposeOnce();
74 void OTableWindowListBox::dispose()
76 if (m_nDropEvent)
77 Application::RemoveUserEvent(m_nDropEvent);
78 if (m_nUiEvent)
79 Application::RemoveUserEvent(m_nUiEvent);
80 if( m_aScrollTimer.IsActive() )
81 m_aScrollTimer.Stop();
82 m_pTabWin.clear();
83 SvTreeListBox::dispose();
86 SvTreeListEntry* OTableWindowListBox::GetEntryFromText( const OUString& rEntryText )
88 // iterate through the list
89 SvTreeList* pTreeList = GetModel();
90 SvTreeListEntry* pEntry = pTreeList->First();
91 OJoinDesignView* pView = m_pTabWin->getDesignView();
92 OJoinController& rController = pView->getController();
94 try
96 bool bCase = false;
97 Reference<XConnection> xConnection = rController.getConnection();
98 if(xConnection.is())
100 Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
101 if(xMeta.is())
102 bCase = xMeta->supportsMixedCaseQuotedIdentifiers();
104 while( pEntry )
106 if((bCase ? rEntryText == GetEntryText(pEntry) : rEntryText.equalsIgnoreAsciiCase(GetEntryText(pEntry))))
108 return pEntry;
110 pEntry = pTreeList->Next(pEntry);
113 catch(SQLException&)
117 return NULL;
120 void OTableWindowListBox::NotifyScrolled()
122 m_bReallyScrolled = true;
125 void OTableWindowListBox::NotifyEndScroll()
127 if (m_bReallyScrolled)
128 // connections of this table, if any, should be redrawn
129 m_pTabWin->getTableView()->Invalidate(INVALIDATE_NOCHILDREN);
131 // without INVALIDATE_NOCHILDREN all tables would be redrawn,
132 // so: flickering
133 m_bReallyScrolled = false;
136 bool OTableWindowListBox::PreNotify(NotifyEvent& rNEvt)
138 bool bHandled = false;
139 switch (rNEvt.GetType())
141 case MouseNotifyEvent::KEYINPUT:
143 const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
144 const vcl::KeyCode& rCode = pKeyEvent->GetKeyCode();
146 if (rCode.GetCode() != KEY_RETURN)
148 if(m_pTabWin)
150 bHandled = m_pTabWin->HandleKeyInput(*pKeyEvent);
152 break;
155 if (rCode.IsMod1() || rCode.IsMod2() || rCode.IsShift())
156 break;
157 if (FirstSelected())
158 static_cast<OTableWindow*>(Window::GetParent())->OnEntryDoubleClicked(FirstSelected());
159 break;
161 default:
162 break;
165 if (!bHandled)
166 return SvTreeListBox::PreNotify(rNEvt);
167 return true;
170 IMPL_LINK_NOARG_TYPED( OTableWindowListBox, ScrollUpHdl, Timer*, void )
172 SvTreeListEntry* pEntry = GetEntry( m_aMousePos );
173 if( !pEntry )
174 return;
176 if( pEntry != Last() )
178 ScrollOutputArea( -1 );
179 pEntry = GetEntry( m_aMousePos );
180 Select( pEntry, true );
184 IMPL_LINK_NOARG_TYPED( OTableWindowListBox, ScrollDownHdl, Timer*, void )
186 SvTreeListEntry* pEntry = GetEntry( m_aMousePos );
187 if( !pEntry )
188 return;
190 if( pEntry != Last() )
192 ScrollOutputArea( 1 );
193 pEntry = GetEntry( m_aMousePos );
194 Select( pEntry, true );
198 void OTableWindowListBox::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
200 OJoinTableView* pCont = m_pTabWin->getTableView();
201 if (!pCont->getDesignView()->getController().isReadOnly() && pCont->getDesignView()->getController().isConnected())
203 // asterisk was not allowed to be copied to selection browsebox
204 bool bFirstNotAllowed = FirstSelected() == First() && m_pTabWin->GetData()->IsShowAll();
205 EndSelection();
206 // create a description of the source
207 OJoinExchangeData jxdSource(this);
208 // put it into a exchange object
209 OJoinExchObj* pJoin = new OJoinExchObj(jxdSource,bFirstNotAllowed);
210 Reference< XTransferable > xEnsureDelete(pJoin);
211 pJoin->StartDrag(this, DND_ACTION_LINK, this);
215 sal_Int8 OTableWindowListBox::AcceptDrop( const AcceptDropEvent& _rEvt )
217 sal_Int8 nDND_Action = DND_ACTION_NONE;
218 // check the format
219 if ( !OJoinExchObj::isFormatAvailable(GetDataFlavorExVector(),SotClipboardFormatId::SBA_TABID) // this means that the first entry is to be draged
220 && OJoinExchObj::isFormatAvailable(GetDataFlavorExVector(),SotClipboardFormatId::SBA_JOIN) )
221 { // don't drop into the window if it's the drag source itself
223 // remove the selection if the dragging operation is leaving the window
224 if (_rEvt.mbLeaving)
225 SelectAll(false);
226 else
228 // hit test
229 m_aMousePos = _rEvt.maPosPixel;
230 Size aOutputSize = GetOutputSizePixel();
231 SvTreeListEntry* pEntry = GetEntry( m_aMousePos );
232 if( !pEntry )
233 return DND_ACTION_NONE;
235 // Scrolling Areas
236 Rectangle aBottomScrollArea( Point(0, aOutputSize.Height()-LISTBOX_SCROLLING_AREA),
237 Size(aOutputSize.Width(), LISTBOX_SCROLLING_AREA) );
238 Rectangle aTopScrollArea( Point(0,0), Size(aOutputSize.Width(), LISTBOX_SCROLLING_AREA) );
240 // scroll up if the pointer is on the upper scroll area
241 if( aBottomScrollArea.IsInside(m_aMousePos) )
243 if( !m_aScrollTimer.IsActive() )
245 m_aScrollTimer.SetTimeoutHdl( LINK(this, OTableWindowListBox, ScrollUpHdl) );
246 ScrollUpHdl( nullptr );
250 // scroll down if the pointer is on the lower scroll area
251 else if( aTopScrollArea.IsInside(m_aMousePos) )
253 if( !m_aScrollTimer.IsActive() )
255 m_aScrollTimer.SetTimeoutHdl( LINK(this, OTableWindowListBox, ScrollDownHdl) );
256 ScrollDownHdl( nullptr );
259 else
261 if( m_aScrollTimer.IsActive() )
262 m_aScrollTimer.Stop();
265 // automatically select right entry when dragging
266 if ((FirstSelected() != pEntry) || (FirstSelected() && NextSelected(FirstSelected())))
267 SelectAll(false);
268 Select(pEntry, true);
270 // one cannot drop on the first (*) entry
271 if(!( m_pTabWin->GetData()->IsShowAll() && (pEntry==First()) ))
272 nDND_Action = DND_ACTION_LINK;
275 return nDND_Action;
278 IMPL_LINK_NOARG( OTableWindowListBox, LookForUiHdl )
280 m_nUiEvent = 0;
281 m_pTabWin->getTableView()->lookForUiActivities();
282 return 0L;
285 IMPL_LINK_NOARG( OTableWindowListBox, DropHdl )
287 // create the connection
288 m_nDropEvent = 0;
289 OSL_ENSURE(m_pTabWin,"No TableWindow!");
292 OJoinTableView* pCont = m_pTabWin->getTableView();
293 OSL_ENSURE(pCont,"No QueryTableView!");
294 pCont->AddConnection(m_aDropInfo.aSource, m_aDropInfo.aDest);
296 catch(const SQLException& e)
298 // remember the exception so that we can show them later when d&d is finished
299 m_pTabWin->getDesignView()->getController().setErrorOccurred(::dbtools::SQLExceptionInfo(e));
301 return 0L;
304 sal_Int8 OTableWindowListBox::ExecuteDrop( const ExecuteDropEvent& _rEvt )
306 TransferableDataHelper aDropped(_rEvt.maDropEvent.Transferable);
307 if ( OJoinExchObj::isFormatAvailable(aDropped.GetDataFlavorExVector()))
308 { // don't drop into the window if it's the drag source itself
309 m_aDropInfo.aSource = OJoinExchangeData(this);
310 m_aDropInfo.aDest = OJoinExchObj::GetSourceDescription(_rEvt.maDropEvent.Transferable);
312 if (m_nDropEvent)
313 Application::RemoveUserEvent(m_nDropEvent);
314 m_nDropEvent = Application::PostUserEvent(LINK(this, OTableWindowListBox, DropHdl), NULL, true);
316 return DND_ACTION_LINK;
318 return DND_ACTION_NONE;
321 void OTableWindowListBox::LoseFocus()
323 if(m_pTabWin)
324 m_pTabWin->setActive(false);
325 SvTreeListBox::LoseFocus();
328 void OTableWindowListBox::GetFocus()
330 if(m_pTabWin)
331 m_pTabWin->setActive();
333 if (GetCurEntry() != NULL)
335 if ( GetSelectionCount() == 0 || GetCurEntry() != FirstSelected() )
337 if ( FirstSelected() )
338 Select(FirstSelected(), false);
339 Select(GetCurEntry(), true);
341 else
342 ShowFocusRect(FirstSelected());
344 SvTreeListBox::GetFocus();
347 IMPL_LINK( OTableWindowListBox, OnDoubleClick, SvTreeListBox *, /*pBox*/ )
349 // tell my parent
350 vcl::Window* pParent = Window::GetParent();
351 OSL_ENSURE(pParent != NULL, "OTableWindowListBox::OnDoubleClick : habe kein Parent !");
353 static_cast<OTableWindow*>(pParent)->OnEntryDoubleClicked(GetHdlEntry());
355 return 0;
358 void OTableWindowListBox::Command(const CommandEvent& rEvt)
360 switch (rEvt.GetCommand())
362 case CommandEventId::ContextMenu:
364 static_cast<OTableWindow*>(Window::GetParent())->Command(rEvt);
365 break;
367 default:
368 SvTreeListBox::Command(rEvt);
372 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */