Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "JoinTableView.hxx"
21 : #include <osl/diagnose.h>
22 : #include "querycontroller.hxx"
23 : #include "JoinDesignView.hxx"
24 : #include "dbu_qry.hrc"
25 : #include "TableWindow.hxx"
26 : #include "TableWindowListBox.hxx"
27 : #include "TableConnection.hxx"
28 : #include "TableConnectionData.hxx"
29 : #include "ConnectionLine.hxx"
30 : #include "ConnectionLineData.hxx"
31 : #include "browserids.hxx"
32 : #include <svl/urlbmk.hxx>
33 : #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
34 : #include "QueryMoveTabWinUndoAct.hxx"
35 : #include "QuerySizeTabWinUndoAct.hxx"
36 : #include <vcl/svapp.hxx>
37 : #include <vcl/settings.hxx>
38 : #include "TableWindowData.hxx"
39 : #include "JAccess.hxx"
40 : #include <com/sun/star/accessibility/XAccessible.hpp>
41 : #include <com/sun/star/accessibility/AccessibleRole.hpp>
42 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
43 : #include "UITools.hxx"
44 : #include <cppuhelper/exc_hlp.hxx>
45 : #include <comphelper/processfactory.hxx>
46 : #include <tools/diagnose_ex.h>
47 : #include <boost/bind.hpp>
48 : #include <boost/scoped_ptr.hpp>
49 : #include <algorithm>
50 : #include <functional>
51 :
52 : using namespace dbaui;
53 : using namespace ::com::sun::star::uno;
54 : using namespace ::com::sun::star::sdbc;
55 : using namespace ::com::sun::star::accessibility;
56 : using namespace ::com::sun::star::container;
57 : using namespace ::com::sun::star::lang;
58 :
59 : #define LINE_SIZE 50
60 : // Constants for the window layout
61 : #define TABWIN_SPACING_X 17
62 : #define TABWIN_SPACING_Y 17
63 :
64 : #define TABWIN_WIDTH_STD 120
65 : #define TABWIN_HEIGHT_STD 120
66 :
67 0 : OScrollWindowHelper::OScrollWindowHelper( vcl::Window* pParent) : Window( pParent)
68 : ,m_aHScrollBar( this, WB_HSCROLL|WB_REPEAT|WB_DRAG )
69 : ,m_aVScrollBar( this, WB_VSCROLL|WB_REPEAT|WB_DRAG )
70 0 : ,m_pCornerWindow(new ScrollBarBox(this, WB_3DLOOK))
71 0 : ,m_pTableView(NULL)
72 : {
73 :
74 : // ScrollBars
75 :
76 0 : GetHScrollBar().SetRange( Range(0, 1000) );
77 0 : GetVScrollBar().SetRange( Range(0, 1000) );
78 :
79 0 : GetHScrollBar().SetLineSize( LINE_SIZE );
80 0 : GetVScrollBar().SetLineSize( LINE_SIZE );
81 :
82 0 : GetHScrollBar().Show();
83 0 : GetVScrollBar().Show();
84 0 : m_pCornerWindow->Show();
85 :
86 : // normally we should be SCROLL_PANE
87 0 : SetAccessibleRole(AccessibleRole::SCROLL_PANE);
88 0 : }
89 :
90 0 : OScrollWindowHelper::~OScrollWindowHelper()
91 : {
92 0 : boost::scoped_ptr<vcl::Window> aTemp(m_pCornerWindow);
93 0 : m_pCornerWindow = NULL;
94 0 : m_pTableView = NULL;
95 0 : }
96 :
97 0 : void OScrollWindowHelper::setTableView(OJoinTableView* _pTableView)
98 : {
99 0 : m_pTableView = _pTableView;
100 : // ScrollBars
101 0 : GetHScrollBar().SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
102 0 : GetVScrollBar().SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
103 0 : }
104 :
105 0 : void OScrollWindowHelper::resetRange(const Point& _aSize)
106 : {
107 0 : Point aPos = PixelToLogic(_aSize);
108 0 : GetHScrollBar().SetRange( Range(0, aPos.X() + TABWIN_SPACING_X) );
109 0 : GetVScrollBar().SetRange( Range(0, aPos.Y() + TABWIN_SPACING_Y) );
110 0 : }
111 :
112 0 : void OScrollWindowHelper::Resize()
113 : {
114 0 : Window::Resize();
115 :
116 0 : Size aTotalOutputSize = GetOutputSizePixel();
117 0 : long nHScrollHeight = GetHScrollBar().GetSizePixel().Height();
118 0 : long nVScrollWidth = GetVScrollBar().GetSizePixel().Width();
119 :
120 0 : GetHScrollBar().SetPosSizePixel(
121 0 : Point( 0, aTotalOutputSize.Height()-nHScrollHeight ),
122 0 : Size( aTotalOutputSize.Width()-nVScrollWidth, nHScrollHeight )
123 0 : );
124 :
125 0 : GetVScrollBar().SetPosSizePixel(
126 0 : Point( aTotalOutputSize.Width()-nVScrollWidth, 0 ),
127 0 : Size( nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight )
128 0 : );
129 :
130 : m_pCornerWindow->SetPosSizePixel(
131 0 : Point( aTotalOutputSize.Width() - nVScrollWidth, aTotalOutputSize.Height() - nHScrollHeight),
132 : Size( nVScrollWidth, nHScrollHeight )
133 0 : );
134 :
135 0 : GetHScrollBar().SetPageSize( aTotalOutputSize.Width() );
136 0 : GetHScrollBar().SetVisibleSize( aTotalOutputSize.Width() );
137 :
138 0 : GetVScrollBar().SetPageSize( aTotalOutputSize.Height() );
139 0 : GetVScrollBar().SetVisibleSize( aTotalOutputSize.Height() );
140 :
141 : // adjust the ranges of the scrollbars if necessary
142 0 : long lRange = GetHScrollBar().GetRange().Max() - GetHScrollBar().GetRange().Min();
143 0 : if (m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() > lRange)
144 0 : GetHScrollBar().SetRangeMax(m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() + GetHScrollBar().GetRange().Min());
145 :
146 0 : lRange = GetVScrollBar().GetRange().Max() - GetVScrollBar().GetRange().Min();
147 0 : if (m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() > lRange)
148 0 : GetVScrollBar().SetRangeMax(m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() + GetVScrollBar().GetRange().Min());
149 :
150 0 : m_pTableView->SetPosSizePixel(Point( 0, 0 ),Size( aTotalOutputSize.Width()-nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight ));
151 0 : }
152 :
153 : // class OJoinTableView
154 :
155 0 : OJoinTableView::OJoinTableView( vcl::Window* pParent, OJoinDesignView* pView )
156 : :Window( pParent,WB_BORDER )
157 : ,DropTargetHelper(this)
158 : ,m_aDragOffset( Point(0,0) )
159 : ,m_aScrollOffset( Point(0,0) )
160 : ,m_pDragWin( NULL )
161 : ,m_pSizingWin( NULL )
162 : ,m_pSelectedConn( NULL )
163 : ,m_bTrackingInitiallyMoved(false)
164 : ,m_pLastFocusTabWin(NULL)
165 : ,m_pView( pView )
166 0 : ,m_pAccessible(NULL)
167 : {
168 0 : SetSizePixel( Size(1000, 1000) );
169 :
170 0 : InitColors();
171 :
172 0 : m_aDragScrollTimer.SetTimeoutHdl(LINK(this, OJoinTableView, OnDragScrollTimer));
173 0 : }
174 :
175 0 : OJoinTableView::~OJoinTableView()
176 : {
177 0 : if( m_pAccessible )
178 : {
179 0 : m_pAccessible->clearTableView();
180 0 : m_pAccessible = NULL;
181 : }
182 : // delete lists
183 0 : clearLayoutInformation();
184 0 : }
185 :
186 0 : IMPL_LINK( OJoinTableView, ScrollHdl, ScrollBar*, pScrollBar )
187 : {
188 : // move all windows
189 0 : ScrollPane( pScrollBar->GetDelta(), (pScrollBar == &GetHScrollBar()), false );
190 :
191 0 : return 0;
192 : }
193 :
194 0 : void OJoinTableView::Resize()
195 : {
196 0 : Window::Resize();
197 0 : m_aOutputSize = GetSizePixel();
198 :
199 : // tab win positions may not be up-to-date
200 0 : if (m_aTableMap.empty())
201 : // no tab wins ...
202 0 : return;
203 :
204 : // we have at least one table so resize it
205 0 : m_aScrollOffset.X() = GetHScrollBar().GetThumbPos();
206 0 : m_aScrollOffset.Y() = GetVScrollBar().GetThumbPos();
207 :
208 0 : OTableWindow* pCheck = m_aTableMap.begin()->second;
209 0 : Point aRealPos = pCheck->GetPosPixel();
210 0 : Point aAssumedPos = pCheck->GetData()->GetPosition() - GetScrollOffset();
211 :
212 0 : if (aRealPos == aAssumedPos)
213 : // all ok
214 0 : return;
215 :
216 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
217 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
218 0 : for(;aIter != aEnd;++aIter)
219 : {
220 0 : OTableWindow* pCurrent = aIter->second;
221 0 : Point aPos(pCurrent->GetData()->GetPosition() - GetScrollOffset());
222 0 : pCurrent->SetPosPixel(aPos);
223 : }
224 : }
225 :
226 0 : sal_uLong OJoinTableView::GetTabWinCount()
227 : {
228 0 : return m_aTableMap.size();
229 : }
230 :
231 0 : bool OJoinTableView::RemoveConnection( OTableConnection* _pConn,bool _bDelete )
232 : {
233 0 : DeselectConn(_pConn);
234 :
235 : // to force a redraw
236 0 : _pConn->InvalidateConnection();
237 :
238 0 : m_pView->getController().removeConnectionData( _pConn->GetData() );
239 :
240 : m_vTableConnection.erase(
241 0 : ::std::find(m_vTableConnection.begin(),m_vTableConnection.end(),_pConn) );
242 :
243 0 : modified();
244 0 : if ( m_pAccessible )
245 : m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
246 : makeAny(_pConn->GetAccessible()),
247 0 : Any());
248 0 : if ( _bDelete )
249 : {
250 0 : delete _pConn;
251 : }
252 :
253 0 : return true;
254 : }
255 :
256 0 : OTableWindow* OJoinTableView::GetTabWindow( const OUString& rName )
257 : {
258 0 : OTableWindowMap::iterator aIter = m_aTableMap.find(rName);
259 :
260 0 : return aIter == m_aTableMap.end() ? NULL : aIter->second;
261 : }
262 :
263 0 : TTableWindowData::value_type OJoinTableView::createTableWindowData(const OUString& _rComposedName
264 : ,const OUString& _sTableName
265 : ,const OUString& _rWinName)
266 : {
267 0 : TTableWindowData::value_type pData( CreateImpl(_rComposedName, _sTableName,_rWinName) );
268 0 : OJoinDesignView* pParent = getDesignView();
269 : try
270 : {
271 0 : if ( !pData->init(pParent->getController().getConnection(),allowQueries()) )
272 : {
273 0 : if ( pData->isValid() )
274 0 : onNoColumns_throw();
275 : else
276 0 : pData.reset();
277 : }
278 : }
279 0 : catch ( const SQLException& )
280 : {
281 : ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ),
282 0 : pParent, pParent->getController().getORB() );
283 : }
284 0 : catch( const WrappedTargetException& e )
285 : {
286 0 : SQLException aSql;
287 0 : if ( e.TargetException >>= aSql )
288 0 : ::dbaui::showError( ::dbtools::SQLExceptionInfo( aSql ), pParent, pParent->getController().getORB() );
289 : }
290 0 : catch( const Exception& )
291 : {
292 : DBG_UNHANDLED_EXCEPTION();
293 : }
294 0 : return pData;
295 : }
296 :
297 0 : OTableWindowData* OJoinTableView::CreateImpl(const OUString& _rComposedName
298 : ,const OUString& _sTableName
299 : ,const OUString& _rWinName)
300 : {
301 0 : return new OTableWindowData( NULL,_rComposedName,_sTableName, _rWinName );
302 : }
303 :
304 0 : void OJoinTableView::AddTabWin(const OUString& _rComposedName, const OUString& rWinName, bool /*bNewTable*/)
305 : {
306 : OSL_ENSURE(!_rComposedName.isEmpty(),"There must be a table name supplied!");
307 :
308 0 : TTableWindowData::value_type pNewTabWinData(createTableWindowData( _rComposedName, rWinName,rWinName ));
309 :
310 : // insert new window in window list
311 0 : OTableWindow* pNewTabWin = createWindow( pNewTabWinData );
312 0 : if ( pNewTabWin->Init() )
313 : {
314 0 : m_pView->getController().getTableWindowData().push_back( pNewTabWinData);
315 : // when we already have a table with this name insert the full qualified one instead
316 0 : if(m_aTableMap.find(rWinName) != m_aTableMap.end())
317 0 : m_aTableMap[_rComposedName] = pNewTabWin;
318 : else
319 0 : m_aTableMap[rWinName] = pNewTabWin;
320 :
321 0 : SetDefaultTabWinPosSize( pNewTabWin );
322 0 : pNewTabWin->Show();
323 :
324 0 : modified();
325 0 : if ( m_pAccessible )
326 : m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
327 : Any(),
328 0 : makeAny(pNewTabWin->GetAccessible()));
329 : }
330 : else
331 : {
332 0 : pNewTabWin->clearListBox();
333 0 : delete pNewTabWin;
334 0 : }
335 0 : }
336 :
337 0 : void OJoinTableView::RemoveTabWin( OTableWindow* pTabWin )
338 : {
339 : // first delete all connections of this window to others
340 0 : bool bRemove = true;
341 0 : TTableWindowData::value_type pData = pTabWin->GetData();
342 0 : sal_Int32 nCount = m_vTableConnection.size();
343 0 : ::std::vector<OTableConnection*>::reverse_iterator aIter = m_vTableConnection.rbegin();
344 0 : while(aIter != m_vTableConnection.rend() && bRemove)
345 : {
346 0 : OTableConnection* pTabConn = (*aIter);
347 0 : if(
348 0 : ( pData == pTabConn->GetData()->getReferencingTable()) ||
349 0 : ( pData == pTabConn->GetData()->getReferencedTable())
350 : )
351 : {
352 0 : bRemove = RemoveConnection( pTabConn ,true);
353 0 : aIter = m_vTableConnection.rbegin();
354 : }
355 : else
356 0 : ++aIter;
357 : }
358 :
359 : // then delete the window itself
360 0 : if ( bRemove )
361 : {
362 0 : if ( m_pAccessible )
363 : m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
364 : makeAny(pTabWin->GetAccessible()),Any()
365 0 : );
366 :
367 0 : pTabWin->Hide();
368 0 : OJoinController& rController = m_pView->getController();
369 0 : TTableWindowData::iterator aFind = ::std::find(rController.getTableWindowData().begin(), rController.getTableWindowData().end(), pData);
370 0 : if(aFind != rController.getTableWindowData().end())
371 : {
372 0 : rController.getTableWindowData().erase(aFind);
373 0 : rController.setModified(sal_True);
374 : }
375 :
376 0 : OUString aWinName = pTabWin->GetWinName();
377 0 : if(m_aTableMap.find(aWinName) != m_aTableMap.end())
378 0 : m_aTableMap.erase( aWinName );
379 : else
380 0 : m_aTableMap.erase( pTabWin->GetComposedName() );
381 :
382 0 : if (pTabWin == m_pLastFocusTabWin)
383 0 : m_pLastFocusTabWin = NULL;
384 :
385 0 : pTabWin->clearListBox();
386 0 : delete pTabWin;
387 :
388 : }
389 0 : if ( (sal_Int32)m_vTableConnection.size() < (nCount-1) ) // if some connections could be removed
390 0 : modified();
391 0 : }
392 :
393 : namespace
394 : {
395 0 : bool isScrollAllowed( OJoinTableView* _pView,long nDelta, bool bHoriz)
396 : {
397 : // adjust ScrollBar-Positions
398 0 : ScrollBar& rBar = bHoriz ? _pView->GetHScrollBar() : _pView->GetVScrollBar() ;
399 :
400 0 : long nOldThumbPos = rBar.GetThumbPos();
401 0 : long nNewThumbPos = nOldThumbPos + nDelta;
402 0 : if( nNewThumbPos < 0 )
403 0 : nNewThumbPos = 0;
404 0 : else if( nNewThumbPos > rBar.GetRangeMax() )
405 0 : nNewThumbPos = rBar.GetRangeMax();
406 :
407 0 : if ( bHoriz )
408 : {
409 0 : if( nNewThumbPos == _pView->GetScrollOffset().X() )
410 0 : return false;
411 : }
412 0 : else if ( nNewThumbPos == _pView->GetScrollOffset().Y() )
413 0 : return false;
414 :
415 0 : return true;
416 : }
417 0 : bool getMovementImpl(OJoinTableView* _pView,const Point& _rPoint,const Size& _rSize,long& _nScrollX,long& _nScrollY)
418 : {
419 0 : _nScrollY = _nScrollX = 0;
420 : // data about the tab win
421 0 : Point aUpperLeft = _rPoint;
422 : // normalize with respect to visibility
423 0 : aUpperLeft -= _pView->GetScrollOffset();
424 0 : Point aLowerRight(aUpperLeft.X() + _rSize.Width(), aUpperLeft.Y() + _rSize.Height());
425 :
426 : // data about ourself
427 0 : Size aSize = _pView->getRealOutputSize(); //GetOutputSizePixel();
428 :
429 0 : bool bVisbile = true;
430 0 : bool bFitsHor = (aUpperLeft.X() >= 0) && (aLowerRight.X() <= aSize.Width());
431 0 : bool bFitsVert= (aUpperLeft.Y() >= 0) && (aLowerRight.Y() <= aSize.Height());
432 0 : if (!bFitsHor || !bFitsVert)
433 : {
434 0 : if (!bFitsHor)
435 : {
436 : // ensure the visibility of the right border
437 0 : if ( aLowerRight.X() > aSize.Width() )
438 0 : _nScrollX = aLowerRight.X() - aSize.Width() + TABWIN_SPACING_X;
439 :
440 : // ensure the visibility of the left border (higher priority)
441 0 : if ( aUpperLeft.X() < 0 )
442 0 : _nScrollX = aUpperLeft.X() - TABWIN_SPACING_X;
443 : }
444 :
445 0 : if (!bFitsVert)
446 : {
447 : // lower border
448 0 : if ( aLowerRight.Y() > aSize.Height() )
449 0 : _nScrollY = aLowerRight.Y() - aSize.Height() + TABWIN_SPACING_Y;
450 : // upper border
451 0 : if ( aUpperLeft.Y() < 0 )
452 0 : _nScrollY = aUpperLeft.Y() - TABWIN_SPACING_Y;
453 : }
454 :
455 0 : if ( _nScrollX ) // aSize.Width() > _rSize.Width() &&
456 0 : bVisbile = isScrollAllowed(_pView,_nScrollX, true);
457 :
458 0 : if ( _nScrollY ) // aSize.Height() > _rSize.Height() &&
459 0 : bVisbile = bVisbile && isScrollAllowed(_pView,_nScrollY, false);
460 :
461 0 : if ( bVisbile )
462 : {
463 0 : sal_Int32 nHRangeMax = _pView->GetHScrollBar().GetRangeMax();
464 0 : sal_Int32 nVRangeMax = _pView->GetVScrollBar().GetRangeMax();
465 :
466 0 : if ( aSize.Width() + _pView->GetHScrollBar().GetThumbPos() + _nScrollX > nHRangeMax )
467 0 : bVisbile = false;
468 0 : if ( bVisbile && aSize.Height() + _pView->GetVScrollBar().GetThumbPos() + _nScrollY > nVRangeMax )
469 0 : bVisbile = false;
470 : }
471 : }
472 :
473 0 : return bVisbile;
474 : }
475 : } // end of ano namespace
476 :
477 0 : bool OJoinTableView::isMovementAllowed(const Point& _rPoint,const Size& _rSize)
478 : {
479 : long nX,nY;
480 0 : return getMovementImpl(this,_rPoint,_rSize,nX,nY);
481 : }
482 :
483 0 : void OJoinTableView::EnsureVisible(const OTableWindow* _pWin)
484 : {
485 : // data about the tab win
486 0 : TTableWindowData::value_type pData = _pWin->GetData();
487 0 : EnsureVisible( pData->GetPosition() , pData->GetSize());
488 0 : Invalidate(INVALIDATE_NOCHILDREN);
489 0 : }
490 :
491 0 : void OJoinTableView::EnsureVisible(const Point& _rPoint,const Size& _rSize)
492 : {
493 : long nScrollX,nScrollY;
494 :
495 0 : if ( getMovementImpl(this,_rPoint,_rSize,nScrollX,nScrollY) )
496 : {
497 0 : bool bVisbile = true;
498 0 : if (nScrollX)
499 0 : bVisbile = ScrollPane(nScrollX, true, true);
500 :
501 0 : if (nScrollY)
502 0 : bVisbile = bVisbile && ScrollPane(nScrollY, false, true);
503 : }
504 0 : }
505 :
506 0 : void OJoinTableView::SetDefaultTabWinPosSize( OTableWindow* pTabWin )
507 : {
508 : // determine position:
509 : // the window is divided into lines with height TABWIN_SPACING_Y+TABWIN_HEIGHT_STD.
510 : // Then for each line is checked, if there is space for another window.
511 : // If there is no space, the next line is checked.
512 0 : Size aOutSize = GetSizePixel();
513 0 : Point aNewPos( 0,0 );
514 0 : sal_uInt16 nRow = 0;
515 0 : bool bEnd = false;
516 0 : while( !bEnd )
517 : {
518 : // Set new position to start of line
519 0 : aNewPos.X() = TABWIN_SPACING_X;
520 0 : aNewPos.Y() = (nRow+1) * TABWIN_SPACING_Y;
521 :
522 : // determine rectangle for the corresponding line
523 0 : Rectangle aRowRect( Point(0,0), aOutSize );
524 0 : aRowRect.Top() = nRow * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
525 0 : aRowRect.Bottom() = (nRow+1) * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
526 :
527 : // check occupied areas of this line
528 : OTableWindow* pOtherTabWin;
529 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
530 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
531 0 : for(;aIter != aEnd;++aIter)
532 : {
533 0 : pOtherTabWin = aIter->second;
534 0 : Rectangle aOtherTabWinRect( pOtherTabWin->GetPosPixel(), pOtherTabWin->GetSizePixel() );
535 :
536 0 : if(
537 0 : ( (aOtherTabWinRect.Top()>aRowRect.Top()) && (aOtherTabWinRect.Top()<aRowRect.Bottom()) ) ||
538 0 : ( (aOtherTabWinRect.Bottom()>aRowRect.Top()) && (aOtherTabWinRect.Bottom()<aRowRect.Bottom()) )
539 : )
540 : {
541 : // TabWin is in the line
542 0 : if( aOtherTabWinRect.Right()>aNewPos.X() )
543 0 : aNewPos.X() = aOtherTabWinRect.Right() + TABWIN_SPACING_X;
544 : }
545 : }
546 :
547 : // Is there space left in this line?
548 0 : if( (aNewPos.X()+TABWIN_WIDTH_STD)<aRowRect.Right() )
549 : {
550 0 : aNewPos.Y() = aRowRect.Top() + TABWIN_SPACING_Y;
551 0 : bEnd = true;
552 : }
553 : else
554 : {
555 0 : if( (aRowRect.Bottom()+aRowRect.GetHeight()) > aOutSize.Height() )
556 : {
557 : // insert it in the first row
558 0 : sal_Int32 nCount = m_aTableMap.size() % (nRow+1);
559 0 : ++nCount;
560 0 : aNewPos.Y() = nCount * TABWIN_SPACING_Y + (nCount-1)*CalcZoom(TABWIN_HEIGHT_STD);
561 0 : bEnd = true;
562 : }
563 : else
564 0 : nRow++;
565 :
566 : }
567 : }
568 :
569 : // determine size
570 0 : Size aNewSize( CalcZoom(TABWIN_WIDTH_STD), CalcZoom(TABWIN_HEIGHT_STD) );
571 :
572 : // check if the new position in inside the scrollbars ranges
573 0 : Point aBottom(aNewPos);
574 0 : aBottom.X() += aNewSize.Width();
575 0 : aBottom.Y() += aNewSize.Height();
576 :
577 0 : if(!GetHScrollBar().GetRange().IsInside(aBottom.X()))
578 0 : GetHScrollBar().SetRange( Range(0, aBottom.X()) );
579 0 : if(!GetVScrollBar().GetRange().IsInside(aBottom.Y()))
580 0 : GetVScrollBar().SetRange( Range(0, aBottom.Y()) );
581 :
582 0 : pTabWin->SetPosSizePixel( aNewPos, aNewSize );
583 0 : }
584 :
585 0 : void OJoinTableView::DataChanged(const DataChangedEvent& rDCEvt)
586 : {
587 0 : if (rDCEvt.GetType() == DATACHANGED_SETTINGS)
588 : {
589 : // consider the worst case: the colors changed, so adjust me
590 0 : InitColors();
591 0 : Invalidate(INVALIDATE_NOCHILDREN);
592 : // due to the Invalidate, the connections are redrawn, so that they are also pictured in the new colors
593 : }
594 0 : }
595 :
596 0 : void OJoinTableView::InitColors()
597 : {
598 : // the colors for the illustration should be the system colors
599 0 : StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
600 0 : SetBackground(Wallpaper(Color(aSystemStyle.GetDialogColor())));
601 0 : }
602 :
603 0 : void OJoinTableView::BeginChildMove( OTableWindow* pTabWin, const Point& rMousePos )
604 : {
605 :
606 0 : if (m_pView->getController().isReadOnly())
607 0 : return;
608 :
609 0 : m_pDragWin = pTabWin;
610 0 : SetPointer(Pointer(POINTER_MOVE));
611 0 : Point aMousePos = ScreenToOutputPixel( rMousePos );
612 0 : m_aDragOffset = aMousePos - pTabWin->GetPosPixel();
613 0 : m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
614 0 : m_bTrackingInitiallyMoved = false;
615 0 : StartTracking();
616 : }
617 :
618 0 : void OJoinTableView::NotifyTitleClicked( OTableWindow* pTabWin, const Point rMousePos )
619 : {
620 0 : DeselectConn(GetSelectedConn());
621 0 : BeginChildMove(pTabWin, rMousePos);
622 0 : }
623 :
624 0 : void OJoinTableView::BeginChildSizing( OTableWindow* pTabWin, const Pointer& rPointer )
625 : {
626 :
627 0 : if (m_pView->getController().isReadOnly())
628 0 : return;
629 :
630 0 : SetPointer( rPointer );
631 0 : m_pSizingWin = pTabWin;
632 0 : StartTracking();
633 : }
634 :
635 0 : bool OJoinTableView::ScrollPane( long nDelta, bool bHoriz, bool bPaintScrollBars )
636 : {
637 0 : bool bRet = true;
638 :
639 : // adjust ScrollBar-Positions
640 0 : if( bPaintScrollBars )
641 : {
642 0 : if( bHoriz )
643 : {
644 0 : long nOldThumbPos = GetHScrollBar().GetThumbPos();
645 0 : long nNewThumbPos = nOldThumbPos + nDelta;
646 0 : if( nNewThumbPos < 0 )
647 : {
648 0 : nNewThumbPos = 0;
649 0 : bRet = false;
650 : }
651 0 : if( nNewThumbPos > GetHScrollBar().GetRange().Max() )
652 : {
653 0 : nNewThumbPos = GetHScrollBar().GetRange().Max();
654 0 : bRet = false;
655 : }
656 0 : GetHScrollBar().SetThumbPos( nNewThumbPos );
657 0 : nDelta = GetHScrollBar().GetThumbPos() - nOldThumbPos;
658 : }
659 : else
660 : {
661 0 : long nOldThumbPos = GetVScrollBar().GetThumbPos();
662 0 : long nNewThumbPos = nOldThumbPos+nDelta;
663 0 : if( nNewThumbPos < 0 )
664 : {
665 0 : nNewThumbPos = 0;
666 0 : bRet = false;
667 : }
668 0 : if( nNewThumbPos > GetVScrollBar().GetRange().Max() )
669 : {
670 0 : nNewThumbPos = GetVScrollBar().GetRange().Max();
671 0 : bRet = false;
672 : }
673 0 : GetVScrollBar().SetThumbPos( nNewThumbPos );
674 0 : nDelta = GetVScrollBar().GetThumbPos() - nOldThumbPos;
675 : }
676 : }
677 :
678 : // If ScrollOffset hitting borders, no redrawing.
679 0 : if( (GetHScrollBar().GetThumbPos()==m_aScrollOffset.X()) &&
680 0 : (GetVScrollBar().GetThumbPos()==m_aScrollOffset.Y()) )
681 0 : return false;
682 :
683 : // set ScrollOffset anew
684 0 : if (bHoriz)
685 0 : m_aScrollOffset.X() = GetHScrollBar().GetThumbPos();
686 : else
687 0 : m_aScrollOffset.Y() = GetVScrollBar().GetThumbPos();
688 :
689 : // move all windows
690 : OTableWindow* pTabWin;
691 0 : Point aPos;
692 :
693 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
694 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
695 0 : for(;aIter != aEnd;++aIter)
696 : {
697 0 : pTabWin = aIter->second;
698 0 : aPos = pTabWin->GetPosPixel();
699 :
700 0 : if( bHoriz )
701 0 : aPos.X() -= nDelta;
702 0 : else aPos.Y() -= nDelta;
703 :
704 0 : pTabWin->SetPosPixel( aPos );
705 : }
706 :
707 0 : Invalidate(); // INVALIDATE_NOCHILDREN
708 :
709 0 : return bRet;
710 : }
711 :
712 0 : void OJoinTableView::Tracking( const TrackingEvent& rTEvt )
713 : {
714 0 : HideTracking();
715 :
716 0 : if (rTEvt.IsTrackingEnded())
717 : {
718 0 : if( m_pDragWin )
719 : {
720 0 : if (m_aDragScrollTimer.IsActive())
721 0 : m_aDragScrollTimer.Stop();
722 :
723 : // adjust position of child after moving
724 : // windows are not allowed to leave display range
725 0 : Point aDragWinPos = rTEvt.GetMouseEvent().GetPosPixel() - m_aDragOffset;
726 0 : Size aDragWinSize = m_pDragWin->GetSizePixel();
727 0 : if( aDragWinPos.X() < 0 )
728 0 : aDragWinPos.X() = 0;
729 0 : if( aDragWinPos.Y() < 0 )
730 0 : aDragWinPos.Y() = 0;
731 0 : if( (aDragWinPos.X() + aDragWinSize.Width()) > m_aOutputSize.Width() )
732 0 : aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width() - 1;
733 0 : if( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() )
734 0 : aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height() - 1;
735 0 : if( aDragWinPos.X() < 0 )
736 0 : aDragWinPos.X() = 0;
737 0 : if( aDragWinPos.Y() < 0 )
738 0 : aDragWinPos.Y() = 0;
739 : // TODO : don't position window anew, if it is leaving range, but just expand the range
740 :
741 : // position window
742 0 : EndTracking();
743 0 : m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
744 : // check, if I really moved
745 : // (this prevents setting the modified-Flag, when there actually was no change0
746 0 : TTableWindowData::value_type pData = m_pDragWin->GetData();
747 0 : if ( ! (pData && pData->HasPosition() && (pData->GetPosition() == aDragWinPos)))
748 : {
749 : // old logic coordinates
750 0 : Point ptOldPos = m_pDragWin->GetPosPixel() + Point(GetHScrollBar().GetThumbPos(), GetVScrollBar().GetThumbPos());
751 : // new positioning
752 0 : m_pDragWin->SetPosPixel(aDragWinPos);
753 0 : TabWinMoved(m_pDragWin, ptOldPos);
754 :
755 0 : m_pDragWin->GrabFocus();
756 : }
757 0 : m_pDragWin = NULL;
758 0 : SetPointer(Pointer(POINTER_ARROW));
759 : }
760 : // else we handle the resizing
761 0 : else if( m_pSizingWin )
762 : {
763 0 : SetPointer( Pointer() );
764 0 : EndTracking();
765 :
766 : // old physical coordinates
767 :
768 0 : Size szOld = m_pSizingWin->GetSizePixel();
769 0 : Point ptOld = m_pSizingWin->GetPosPixel();
770 0 : Size aNewSize(CalcZoom(m_aSizingRect.GetSize().Width()),CalcZoom(m_aSizingRect.GetSize().Height()));
771 0 : m_pSizingWin->SetPosSizePixel( m_aSizingRect.TopLeft(), aNewSize );
772 0 : TabWinSized(m_pSizingWin, ptOld, szOld);
773 :
774 0 : m_pSizingWin->Invalidate( m_aSizingRect );
775 0 : m_pSizingWin = NULL;
776 : }
777 : }
778 0 : else if (rTEvt.IsTrackingCanceled())
779 : {
780 0 : if (m_aDragScrollTimer.IsActive())
781 0 : m_aDragScrollTimer.Stop();
782 0 : EndTracking();
783 : }
784 : else
785 : {
786 0 : if( m_pDragWin )
787 : {
788 0 : m_ptPrevDraggingPos = rTEvt.GetMouseEvent().GetPosPixel();
789 : // scroll at window borders
790 0 : ScrollWhileDragging();
791 : }
792 :
793 0 : if( m_pSizingWin )
794 : {
795 0 : Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
796 0 : m_aSizingRect = m_pSizingWin->getSizingRect(aMousePos,m_aOutputSize);
797 0 : Update();
798 0 : ShowTracking( m_aSizingRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
799 : }
800 : }
801 0 : }
802 :
803 0 : void OJoinTableView::ConnDoubleClicked( OTableConnection* /*pConnection*/ )
804 : {
805 0 : }
806 :
807 0 : void OJoinTableView::MouseButtonDown( const MouseEvent& rEvt )
808 : {
809 0 : GrabFocus();
810 0 : Window::MouseButtonDown(rEvt);
811 0 : }
812 :
813 0 : void OJoinTableView::MouseButtonUp( const MouseEvent& rEvt )
814 : {
815 0 : Window::MouseButtonUp(rEvt);
816 : // Has a connection been selected?
817 0 : if( !m_vTableConnection.empty() )
818 : {
819 0 : DeselectConn(GetSelectedConn());
820 :
821 0 : ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
822 0 : ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
823 0 : for(;aIter != aEnd;++aIter)
824 : {
825 0 : if( (*aIter)->CheckHit(rEvt.GetPosPixel()) )
826 : {
827 0 : SelectConn((*aIter));
828 :
829 : // Double-click
830 0 : if( rEvt.GetClicks() == 2 )
831 0 : ConnDoubleClicked( (*aIter) );
832 :
833 0 : break;
834 : }
835 : }
836 : }
837 0 : }
838 :
839 0 : void OJoinTableView::KeyInput( const KeyEvent& rEvt )
840 : {
841 0 : sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
842 0 : bool bShift = rEvt.GetKeyCode().IsShift();
843 0 : bool bCtrl = rEvt.GetKeyCode().IsMod1();
844 :
845 0 : if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
846 : {
847 0 : if (GetSelectedConn())
848 0 : RemoveConnection( GetSelectedConn() ,true);
849 : }
850 : else
851 0 : Window::KeyInput( rEvt );
852 0 : }
853 :
854 0 : void OJoinTableView::DeselectConn(OTableConnection* pConn)
855 : {
856 0 : if (!pConn || !pConn->IsSelected())
857 0 : return;
858 :
859 : // deselect the corresponding entries in the ListBox of the table window
860 0 : OTableWindow* pWin = pConn->GetSourceWin();
861 0 : if (pWin && pWin->GetListBox())
862 0 : pWin->GetListBox()->SelectAll(false);
863 :
864 0 : pWin = pConn->GetDestWin();
865 0 : if (pWin && pWin->GetListBox())
866 0 : pWin->GetListBox()->SelectAll(false);
867 :
868 0 : pConn->Deselect();
869 0 : m_pSelectedConn = NULL;
870 : }
871 :
872 0 : void OJoinTableView::SelectConn(OTableConnection* pConn)
873 : {
874 0 : DeselectConn(GetSelectedConn());
875 :
876 0 : pConn->Select();
877 0 : m_pSelectedConn = pConn;
878 0 : GrabFocus(); // has to be called here because a table window may still be focused
879 :
880 : // select the concerned entries in the windows
881 0 : OTableWindow* pConnSource = pConn->GetSourceWin();
882 0 : OTableWindow* pConnDest = pConn->GetDestWin();
883 0 : if (pConnSource && pConnDest)
884 : {
885 0 : OTableWindowListBox* pSourceBox = pConnSource->GetListBox();
886 0 : OTableWindowListBox* pDestBox = pConnDest->GetListBox();
887 0 : if (pSourceBox && pDestBox)
888 : {
889 0 : pSourceBox->SelectAll(false);
890 0 : pDestBox->SelectAll(false);
891 :
892 0 : SvTreeListEntry* pFirstSourceVisible = pSourceBox->GetFirstEntryInView();
893 0 : SvTreeListEntry* pFirstDestVisible = pDestBox->GetFirstEntryInView();
894 :
895 0 : const ::std::vector<OConnectionLine*>& rLines = pConn->GetConnLineList();
896 0 : ::std::vector<OConnectionLine*>::const_reverse_iterator aIter = rLines.rbegin();
897 0 : for(;aIter != rLines.rend();++aIter)
898 : {
899 0 : if ((*aIter)->IsValid())
900 : {
901 0 : SvTreeListEntry* pSourceEntry = pSourceBox->GetEntryFromText((*aIter)->GetData()->GetSourceFieldName());
902 0 : if (pSourceEntry)
903 : {
904 0 : pSourceBox->Select(pSourceEntry, true);
905 0 : pSourceBox->MakeVisible(pSourceEntry);
906 : }
907 :
908 0 : SvTreeListEntry* pDestEntry = pDestBox->GetEntryFromText((*aIter)->GetData()->GetDestFieldName());
909 0 : if (pDestEntry)
910 : {
911 0 : pDestBox->Select(pDestEntry, true);
912 0 : pDestBox->MakeVisible(pDestEntry);
913 : }
914 :
915 : }
916 : }
917 :
918 0 : if ((pFirstSourceVisible != pSourceBox->GetFirstEntryInView())
919 0 : || (pFirstDestVisible != pDestBox->GetFirstEntryInView()))
920 : // scrolling was done -> redraw
921 0 : Invalidate(INVALIDATE_NOCHILDREN);
922 : }
923 : }
924 0 : }
925 :
926 0 : void OJoinTableView::Paint( const Rectangle& rRect )
927 : {
928 0 : DrawConnections( rRect );
929 0 : }
930 :
931 0 : void OJoinTableView::InvalidateConnections()
932 : {
933 : // draw Joins
934 : ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),
935 0 : ::std::mem_fun(& OTableConnection::InvalidateConnection));
936 0 : }
937 :
938 0 : void OJoinTableView::DrawConnections( const Rectangle& rRect )
939 : {
940 : // draw Joins
941 0 : ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),boost::bind( &OTableConnection::Draw, _1, boost::cref( rRect )));
942 : // finally redraw the selected one above all others
943 0 : if (GetSelectedConn())
944 0 : GetSelectedConn()->Draw( rRect );
945 0 : }
946 :
947 0 : ::std::vector<OTableConnection*>::const_iterator OJoinTableView::getTableConnections(const OTableWindow* _pFromWin) const
948 : {
949 : return ::std::find_if( m_vTableConnection.begin(),
950 : m_vTableConnection.end(),
951 0 : ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
952 : }
953 :
954 0 : sal_Int32 OJoinTableView::getConnectionCount(const OTableWindow* _pFromWin) const
955 : {
956 : return ::std::count_if( m_vTableConnection.begin(),
957 : m_vTableConnection.end(),
958 0 : ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
959 : }
960 :
961 0 : bool OJoinTableView::ExistsAConn(const OTableWindow* pFrom) const
962 : {
963 0 : return getTableConnections(pFrom) != m_vTableConnection.end();
964 : }
965 :
966 0 : void OJoinTableView::ClearAll()
967 : {
968 0 : SetUpdateMode(false);
969 :
970 0 : HideTabWins();
971 :
972 : // and the same with the Connections
973 0 : ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
974 0 : ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
975 0 : for(;aIter != aEnd;++aIter)
976 0 : RemoveConnection( *aIter ,true);
977 0 : m_vTableConnection.clear();
978 :
979 0 : m_pLastFocusTabWin = NULL;
980 0 : m_pSelectedConn = NULL;
981 :
982 : // scroll to the upper left
983 0 : ScrollPane(-GetScrollOffset().X(), true, true);
984 0 : ScrollPane(-GetScrollOffset().Y(), false, true);
985 0 : Invalidate();
986 0 : }
987 :
988 0 : bool OJoinTableView::ScrollWhileDragging()
989 : {
990 : OSL_ENSURE(m_pDragWin != NULL, "OJoinTableView::ScrollWhileDragging must not be called when a window is being dragged !");
991 :
992 : // kill the timer
993 0 : if (m_aDragScrollTimer.IsActive())
994 0 : m_aDragScrollTimer.Stop();
995 :
996 0 : Point aDragWinPos = m_ptPrevDraggingPos - m_aDragOffset;
997 0 : Size aDragWinSize = m_pDragWin->GetSizePixel();
998 0 : Point aLowerRight(aDragWinPos.X() + aDragWinSize.Width(), aDragWinPos.Y() + aDragWinSize.Height());
999 :
1000 0 : if (!m_bTrackingInitiallyMoved && (aDragWinPos == m_pDragWin->GetPosPixel()))
1001 0 : return true;
1002 :
1003 : // avoid illustration errors (when scrolling with active TrackingRect)
1004 0 : HideTracking();
1005 :
1006 0 : bool bScrolling = false;
1007 0 : bool bNeedScrollTimer = false;
1008 :
1009 : // scroll at window borders
1010 : // TODO : only catch, if window would disappear completely (don't, if there is still a pixel visible)
1011 0 : if( aDragWinPos.X() < 5 )
1012 : {
1013 0 : bScrolling = ScrollPane( -LINE_SIZE, true, true );
1014 0 : if( !bScrolling && (aDragWinPos.X()<0) )
1015 0 : aDragWinPos.X() = 0;
1016 :
1017 : // do I need further (timer controlled) scrolling ?
1018 0 : bNeedScrollTimer = bScrolling && (aDragWinPos.X() < 5);
1019 : }
1020 :
1021 0 : if( aLowerRight.X() > m_aOutputSize.Width() - 5 )
1022 : {
1023 0 : bScrolling = ScrollPane( LINE_SIZE, true, true ) ;
1024 0 : if( !bScrolling && ( aLowerRight.X() > m_aOutputSize.Width() ) )
1025 0 : aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width();
1026 :
1027 : // do I need further (timer controlled) scrolling ?
1028 0 : bNeedScrollTimer = bScrolling && (aLowerRight.X() > m_aOutputSize.Width() - 5);
1029 : }
1030 :
1031 0 : if( aDragWinPos.Y() < 5 )
1032 : {
1033 0 : bScrolling = ScrollPane( -LINE_SIZE, false, true );
1034 0 : if( !bScrolling && (aDragWinPos.Y()<0) )
1035 0 : aDragWinPos.Y() = 0;
1036 :
1037 0 : bNeedScrollTimer = bScrolling && (aDragWinPos.Y() < 5);
1038 : }
1039 :
1040 0 : if( aLowerRight.Y() > m_aOutputSize.Height() - 5 )
1041 : {
1042 0 : bScrolling = ScrollPane( LINE_SIZE, false, true );
1043 0 : if( !bScrolling && ( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() ) )
1044 0 : aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height();
1045 :
1046 0 : bNeedScrollTimer = bScrolling && (aLowerRight.Y() > m_aOutputSize.Height() - 5);
1047 : }
1048 :
1049 : // resetting timer, if still necessary
1050 0 : if (bNeedScrollTimer)
1051 : {
1052 0 : m_aDragScrollTimer.SetTimeout(100);
1053 0 : m_aDragScrollTimer.Start();
1054 : }
1055 :
1056 : // redraw DraggingRect
1057 0 : m_aDragRect = Rectangle(m_ptPrevDraggingPos - m_aDragOffset, m_pDragWin->GetSizePixel());
1058 0 : Update();
1059 0 : ShowTracking( m_aDragRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
1060 :
1061 0 : return bScrolling;
1062 : }
1063 :
1064 0 : IMPL_LINK_NOARG(OJoinTableView, OnDragScrollTimer)
1065 : {
1066 0 : ScrollWhileDragging();
1067 0 : return 0L;
1068 : }
1069 :
1070 0 : void OJoinTableView::invalidateAndModify(SfxUndoAction *_pAction)
1071 : {
1072 0 : Invalidate(INVALIDATE_NOCHILDREN);
1073 0 : m_pView->getController().addUndoActionAndInvalidate(_pAction);
1074 0 : }
1075 :
1076 0 : void OJoinTableView::TabWinMoved(OTableWindow* ptWhich, const Point& ptOldPosition)
1077 : {
1078 0 : Point ptThumbPos(GetHScrollBar().GetThumbPos(), GetVScrollBar().GetThumbPos());
1079 0 : ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel() + ptThumbPos);
1080 :
1081 0 : invalidateAndModify(new OJoinMoveTabWinUndoAct(this, ptOldPosition, ptWhich));
1082 0 : }
1083 :
1084 0 : void OJoinTableView::TabWinSized(OTableWindow* ptWhich, const Point& ptOldPosition, const Size& szOldSize)
1085 : {
1086 0 : ptWhich->GetData()->SetSize(ptWhich->GetSizePixel());
1087 0 : ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel());
1088 :
1089 0 : invalidateAndModify(new OJoinSizeTabWinUndoAct(this, ptOldPosition, szOldSize, ptWhich));
1090 0 : }
1091 :
1092 0 : bool OJoinTableView::IsAddAllowed()
1093 : {
1094 :
1095 : // not, if Db readonly
1096 0 : if (m_pView->getController().isReadOnly())
1097 0 : return false;
1098 :
1099 : try
1100 : {
1101 0 : Reference< XConnection> xConnection = m_pView->getController().getConnection();
1102 0 : if(!xConnection.is())
1103 0 : return false;
1104 : // not, if too many tables already
1105 0 : Reference < XDatabaseMetaData > xMetaData( xConnection->getMetaData() );
1106 :
1107 0 : sal_Int32 nMax = xMetaData.is() ? xMetaData->getMaxTablesInSelect() : 0;
1108 0 : if (nMax && nMax <= (sal_Int32)m_aTableMap.size())
1109 0 : return false;
1110 : }
1111 0 : catch(SQLException&)
1112 : {
1113 0 : return false;
1114 : }
1115 :
1116 0 : return true;
1117 : }
1118 :
1119 0 : void OJoinTableView::executePopup(const Point& _aPos,OTableConnection* _pSelConnection)
1120 : {
1121 0 : PopupMenu aContextMenu( ModuleRes( RID_MENU_JOINVIEW_CONNECTION ) );
1122 0 : switch (aContextMenu.Execute(this, _aPos))
1123 : {
1124 : case SID_DELETE:
1125 0 : RemoveConnection( _pSelConnection ,true);
1126 0 : break;
1127 : case ID_QUERY_EDIT_JOINCONNECTION:
1128 0 : ConnDoubleClicked( _pSelConnection ); // is the same as double clicked
1129 0 : break;
1130 0 : }
1131 0 : }
1132 :
1133 0 : void OJoinTableView::Command(const CommandEvent& rEvt)
1134 : {
1135 :
1136 0 : bool bHandled = false;
1137 :
1138 0 : switch (rEvt.GetCommand())
1139 : {
1140 : case COMMAND_CONTEXTMENU:
1141 : {
1142 0 : if( m_vTableConnection.empty() )
1143 0 : return;
1144 :
1145 0 : OTableConnection* pSelConnection = GetSelectedConn();
1146 : // when it wasn't a mouse event use the selected connection
1147 0 : if (!rEvt.IsMouseEvent())
1148 : {
1149 0 : if( pSelConnection )
1150 : {
1151 0 : const ::std::vector<OConnectionLine*>& rLines = pSelConnection->GetConnLineList();
1152 0 : ::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(rLines.begin(), rLines.end(),::std::mem_fun(&OConnectionLine::IsValid));
1153 0 : if( aIter != rLines.end() )
1154 0 : executePopup((*aIter)->getMidPoint(),pSelConnection);
1155 : }
1156 : }
1157 : else
1158 : {
1159 0 : DeselectConn(pSelConnection);
1160 :
1161 0 : const Point& aMousePos = rEvt.GetMousePosPixel();
1162 0 : ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
1163 0 : ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
1164 0 : for(;aIter != aEnd;++aIter)
1165 : {
1166 0 : if( (*aIter)->CheckHit(aMousePos) )
1167 : {
1168 0 : SelectConn(*aIter);
1169 0 : if(!getDesignView()->getController().isReadOnly() && getDesignView()->getController().isConnected())
1170 0 : executePopup(rEvt.GetMousePosPixel(),*aIter);
1171 0 : break;
1172 : }
1173 : }
1174 : }
1175 0 : bHandled = true;
1176 : }
1177 : }
1178 0 : if (!bHandled)
1179 0 : Window::Command(rEvt);
1180 : }
1181 :
1182 0 : OTableConnection* OJoinTableView::GetTabConn(const OTableWindow* pLhs,const OTableWindow* pRhs,bool _bSupressCrossOrNaturalJoin,const OTableConnection* _rpFirstAfter) const
1183 : {
1184 0 : OTableConnection* pConn = NULL;
1185 : OSL_ENSURE(pRhs || pLhs, "OJoinTableView::GetTabConn : invalid args !");
1186 : // only one NULL-arg allowed
1187 :
1188 0 : if ((!pLhs || pLhs->ExistsAConn()) && (!pRhs || pRhs->ExistsAConn()))
1189 : {
1190 0 : bool bFoundStart = _rpFirstAfter ? sal_False : sal_True;
1191 :
1192 0 : ::std::vector<OTableConnection*>::const_iterator aIter = m_vTableConnection.begin();
1193 0 : ::std::vector<OTableConnection*>::const_iterator aEnd = m_vTableConnection.end();
1194 0 : for(;aIter != aEnd;++aIter)
1195 : {
1196 0 : OTableConnection* pData = *aIter;
1197 :
1198 0 : if ( ( (pData->GetSourceWin() == pLhs)
1199 0 : && ( (pData->GetDestWin() == pRhs)
1200 0 : || (NULL == pRhs)
1201 : )
1202 : )
1203 0 : || ( (pData->GetSourceWin() == pRhs)
1204 0 : && ( (pData->GetDestWin() == pLhs)
1205 0 : || (NULL == pLhs)
1206 : )
1207 : )
1208 : )
1209 : {
1210 0 : if ( _bSupressCrossOrNaturalJoin )
1211 : {
1212 0 : if ( supressCrossNaturalJoin(pData->GetData()) )
1213 0 : continue;
1214 : }
1215 0 : if (bFoundStart)
1216 : {
1217 0 : pConn = pData;
1218 0 : break;
1219 : }
1220 :
1221 0 : if (!pConn)
1222 : // used as fallback : if there is no conn after _rpFirstAfter the first conn between the two tables
1223 : // will be used
1224 0 : pConn = pData;
1225 :
1226 0 : if (pData == _rpFirstAfter)
1227 0 : bFoundStart = true;
1228 : }
1229 : }
1230 : }
1231 0 : return pConn;
1232 : }
1233 :
1234 0 : bool OJoinTableView::PreNotify(NotifyEvent& rNEvt)
1235 : {
1236 0 : bool bHandled = false;
1237 0 : switch (rNEvt.GetType())
1238 : {
1239 : case EVENT_COMMAND:
1240 : {
1241 0 : const CommandEvent* pCommand = rNEvt.GetCommandEvent();
1242 0 : if (pCommand->GetCommand() == COMMAND_WHEEL)
1243 : {
1244 0 : const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
1245 0 : if (pData->GetMode() == CommandWheelMode::SCROLL)
1246 : {
1247 0 : if (pData->GetDelta() > 0)
1248 0 : ScrollPane(-10 * pData->GetScrollLines(), pData->IsHorz(), true);
1249 : else
1250 0 : ScrollPane(10 * pData->GetScrollLines(), pData->IsHorz(), true);
1251 0 : bHandled = true;
1252 : }
1253 : }
1254 : }
1255 0 : break;
1256 : case EVENT_KEYINPUT:
1257 : {
1258 0 : if (m_aTableMap.empty())
1259 : // no tab wins -> no conns -> no traveling
1260 0 : break;
1261 :
1262 0 : const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
1263 0 : if (!pKeyEvent->GetKeyCode().IsMod1())
1264 : {
1265 0 : switch (pKeyEvent->GetKeyCode().GetCode())
1266 : {
1267 : case KEY_TAB:
1268 : {
1269 0 : if (!HasChildPathFocus())
1270 0 : break;
1271 :
1272 0 : bool bForward = !pKeyEvent->GetKeyCode().IsShift();
1273 : // is there an active tab win ?
1274 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
1275 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
1276 0 : for(;aIter != aEnd;++aIter)
1277 0 : if (aIter->second && aIter->second->HasChildPathFocus())
1278 0 : break;
1279 :
1280 0 : OTableWindow* pNextWin = NULL;
1281 0 : OTableConnection* pNextConn = NULL;
1282 :
1283 0 : if (aIter != m_aTableMap.end())
1284 : { // there is a currently active tab win
1285 : // check if there is an "overflow" and we should select a conn instead of a win
1286 0 : if (!m_vTableConnection.empty())
1287 : {
1288 0 : if ((aIter->second == m_aTableMap.rbegin()->second) && bForward)
1289 : // the last win is active and we're travelling forward -> select the first conn
1290 0 : pNextConn = *m_vTableConnection.begin();
1291 0 : if ((aIter == m_aTableMap.begin()) && !bForward)
1292 : // the first win is active an we're traveling backward -> select the last conn
1293 0 : pNextConn = *m_vTableConnection.rbegin();
1294 : }
1295 :
1296 0 : if (!pNextConn)
1297 : {
1298 : // no conn for any reason -> select the next or previous tab win
1299 0 : if(bForward)
1300 : {
1301 0 : if ( aIter->second == m_aTableMap.rbegin()->second )
1302 0 : pNextWin = m_aTableMap.begin()->second;
1303 : else
1304 : {
1305 0 : ++aIter;
1306 0 : pNextWin = aIter->second;
1307 : }
1308 : }
1309 : else
1310 : {
1311 0 : if (aIter == m_aTableMap.begin())
1312 0 : pNextWin = m_aTableMap.rbegin()->second;
1313 : else
1314 : {
1315 0 : --aIter;
1316 0 : pNextWin = aIter->second;
1317 : }
1318 : }
1319 : }
1320 : }
1321 : else
1322 : { // no active tab win -> travel the connections
1323 : // find the currently selected conn within the conn list
1324 0 : sal_Int32 i(0);
1325 0 : for ( ::std::vector<OTableConnection*>::iterator connectionIter = m_vTableConnection.begin();
1326 0 : connectionIter != m_vTableConnection.end();
1327 : ++connectionIter, ++i
1328 : )
1329 : {
1330 0 : if ( (*connectionIter) == GetSelectedConn() )
1331 0 : break;
1332 : }
1333 0 : if (i == sal_Int32(m_vTableConnection.size() - 1) && bForward)
1334 : // the last conn is active and we're travelling forward -> select the first win
1335 0 : pNextWin = m_aTableMap.begin()->second;
1336 0 : if ((i == 0) && !bForward && !m_aTableMap.empty())
1337 : // the first conn is active and we're travelling backward -> select the last win
1338 0 : pNextWin = m_aTableMap.rbegin()->second;
1339 :
1340 0 : if (pNextWin)
1341 0 : DeselectConn(GetSelectedConn());
1342 : else
1343 : // no win for any reason -> select the next or previous conn
1344 0 : if (i < (sal_Int32)m_vTableConnection.size())
1345 : // there is a currently active conn
1346 0 : pNextConn = m_vTableConnection[(i + (bForward ? 1 : m_vTableConnection.size() - 1)) % m_vTableConnection.size()];
1347 : else
1348 : { // no tab win selected, no conn selected
1349 0 : if (!m_vTableConnection.empty())
1350 0 : pNextConn = m_vTableConnection[bForward ? 0 : m_vTableConnection.size() - 1];
1351 0 : else if (!m_aTableMap.empty())
1352 : {
1353 0 : if(bForward)
1354 0 : pNextWin = m_aTableMap.begin()->second;
1355 : else
1356 0 : pNextWin = m_aTableMap.rbegin()->second;
1357 : }
1358 : }
1359 : }
1360 :
1361 : // now select the object
1362 0 : if (pNextWin)
1363 : {
1364 0 : if (pNextWin->GetListBox())
1365 0 : pNextWin->GetListBox()->GrabFocus();
1366 : else
1367 0 : pNextWin->GrabFocus();
1368 0 : EnsureVisible(pNextWin);
1369 : }
1370 0 : else if (pNextConn)
1371 : {
1372 0 : GrabFocus();
1373 : // necessary : a conn may be selected even if a tab win has the focus, in this case
1374 : // the next travel would select the same conn again if we would not reset the focus ...
1375 0 : SelectConn(pNextConn);
1376 : }
1377 : }
1378 0 : break;
1379 : case KEY_RETURN:
1380 : {
1381 0 : if (!pKeyEvent->GetKeyCode().IsShift() && GetSelectedConn() && HasFocus())
1382 0 : ConnDoubleClicked(GetSelectedConn());
1383 0 : break;
1384 : }
1385 : }
1386 : }
1387 : }
1388 0 : break;
1389 : case EVENT_GETFOCUS:
1390 : {
1391 0 : if (m_aTableMap.empty())
1392 : // no tab wins -> no conns -> no focus change
1393 0 : break;
1394 0 : vcl::Window* pSource = rNEvt.GetWindow();
1395 0 : if (pSource)
1396 : {
1397 0 : vcl::Window* pSearchFor = NULL;
1398 0 : if (pSource->GetParent() == this)
1399 : // it may be one of the tab wins
1400 0 : pSearchFor = pSource;
1401 0 : else if (pSource->GetParent() && (pSource->GetParent()->GetParent() == this))
1402 : // it may be one of th list boxes of one of the tab wins
1403 0 : pSearchFor = pSource->GetParent();
1404 :
1405 0 : if (pSearchFor)
1406 : {
1407 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
1408 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
1409 0 : for(;aIter != aEnd;++aIter)
1410 : {
1411 0 : if (aIter->second == pSearchFor)
1412 : {
1413 0 : m_pLastFocusTabWin = aIter->second;
1414 0 : break;
1415 : }
1416 : }
1417 : }
1418 : }
1419 : }
1420 0 : break;
1421 : }
1422 :
1423 0 : if (!bHandled)
1424 0 : return Window::PreNotify(rNEvt);
1425 0 : return true;
1426 : }
1427 :
1428 0 : void OJoinTableView::GrabTabWinFocus()
1429 : {
1430 0 : if (m_pLastFocusTabWin && m_pLastFocusTabWin->IsVisible())
1431 : {
1432 0 : if (m_pLastFocusTabWin->GetListBox())
1433 0 : m_pLastFocusTabWin->GetListBox()->GrabFocus();
1434 : else
1435 0 : m_pLastFocusTabWin->GrabFocus();
1436 : }
1437 0 : else if (!m_aTableMap.empty() && m_aTableMap.begin()->second && m_aTableMap.begin()->second->IsVisible())
1438 : {
1439 0 : OTableWindow* pFirstWin = m_aTableMap.begin()->second;
1440 0 : if (pFirstWin->GetListBox())
1441 0 : pFirstWin->GetListBox()->GrabFocus();
1442 : else
1443 0 : pFirstWin->GrabFocus();
1444 : }
1445 0 : }
1446 :
1447 0 : void OJoinTableView::StateChanged( StateChangedType nType )
1448 : {
1449 0 : Window::StateChanged( nType );
1450 :
1451 0 : if ( nType == StateChangedType::ZOOM )
1452 : {
1453 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1454 :
1455 0 : vcl::Font aFont = rStyleSettings.GetGroupFont();
1456 0 : if ( IsControlFont() )
1457 0 : aFont.Merge( GetControlFont() );
1458 0 : SetZoomedPointFont( aFont );
1459 :
1460 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
1461 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
1462 0 : for(;aIter != aEnd;++aIter)
1463 : {
1464 0 : aIter->second->SetZoom(GetZoom());
1465 0 : Size aSize(CalcZoom(aIter->second->GetSizePixel().Width()),CalcZoom(aIter->second->GetSizePixel().Height()));
1466 0 : aIter->second->SetSizePixel(aSize);
1467 : }
1468 0 : Resize();
1469 : }
1470 0 : }
1471 :
1472 0 : void OJoinTableView::HideTabWins()
1473 : {
1474 0 : SetUpdateMode(false);
1475 :
1476 0 : OTableWindowMap& rTabWins = GetTabWinMap();
1477 :
1478 : // working on a copy because the real list will be cleared in inner calls
1479 0 : OTableWindowMap aCopy(rTabWins);
1480 0 : OTableWindowMap::iterator aIter = aCopy.begin();
1481 0 : OTableWindowMap::iterator aEnd = aCopy.end();
1482 0 : for(;aIter != aEnd;++aIter)
1483 0 : RemoveTabWin(aIter->second);
1484 :
1485 0 : m_pView->getController().setModified(sal_True);
1486 :
1487 0 : SetUpdateMode(true);
1488 :
1489 0 : }
1490 :
1491 0 : sal_Int8 OJoinTableView::AcceptDrop( const AcceptDropEvent& /*_rEvt*/ )
1492 : {
1493 0 : return DND_ACTION_NONE;
1494 : }
1495 :
1496 0 : sal_Int8 OJoinTableView::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
1497 : {
1498 0 : return DND_ACTION_NONE;
1499 : }
1500 :
1501 0 : void OJoinTableView::dragFinished( )
1502 : {
1503 0 : }
1504 :
1505 0 : void OJoinTableView::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
1506 : {
1507 0 : }
1508 :
1509 0 : void OJoinTableView::clearLayoutInformation()
1510 : {
1511 0 : m_pLastFocusTabWin = NULL;
1512 0 : m_pSelectedConn = NULL;
1513 : // delete lists
1514 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
1515 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
1516 0 : for(;aIter != aEnd;++aIter)
1517 : {
1518 0 : if ( aIter->second )
1519 0 : aIter->second->clearListBox();
1520 0 : boost::scoped_ptr<vcl::Window> aTemp(aIter->second);
1521 0 : aIter->second = NULL;
1522 0 : }
1523 :
1524 0 : m_aTableMap.clear();
1525 :
1526 0 : ::std::vector<OTableConnection*>::const_iterator aIter2 = m_vTableConnection.begin();
1527 0 : ::std::vector<OTableConnection*>::const_iterator aEnd2 = m_vTableConnection.end();
1528 0 : for(;aIter2 != aEnd2;++aIter2)
1529 0 : delete *aIter2;
1530 :
1531 0 : m_vTableConnection.clear();
1532 0 : }
1533 :
1534 0 : void OJoinTableView::lookForUiActivities()
1535 : {
1536 0 : }
1537 :
1538 0 : void OJoinTableView::LoseFocus()
1539 : {
1540 0 : DeselectConn(GetSelectedConn());
1541 0 : Window::LoseFocus();
1542 0 : }
1543 :
1544 0 : void OJoinTableView::GetFocus()
1545 : {
1546 0 : Window::GetFocus();
1547 0 : if ( !m_aTableMap.empty() && !GetSelectedConn() )
1548 0 : GrabTabWinFocus();
1549 0 : }
1550 :
1551 0 : Reference< XAccessible > OJoinTableView::CreateAccessible()
1552 : {
1553 0 : m_pAccessible = new OJoinDesignViewAccess(this);
1554 0 : return m_pAccessible;
1555 : }
1556 :
1557 0 : void OJoinTableView::modified()
1558 : {
1559 0 : OJoinController& rController = m_pView->getController();
1560 0 : rController.setModified( sal_True );
1561 0 : rController.InvalidateFeature(ID_BROWSER_ADDTABLE);
1562 0 : rController.InvalidateFeature(SID_RELATION_ADD_RELATION);
1563 0 : }
1564 :
1565 0 : void OJoinTableView::addConnection(OTableConnection* _pConnection,bool _bAddData)
1566 : {
1567 0 : if ( _bAddData )
1568 : {
1569 : #if OSL_DEBUG_LEVEL > 0
1570 : TTableConnectionData& rTabConnDataList = m_pView->getController().getTableConnectionData();
1571 : OSL_ENSURE( ::std::find(rTabConnDataList.begin(), rTabConnDataList.end(),_pConnection->GetData()) == rTabConnDataList.end(),"Data already in vector!");
1572 : #endif
1573 0 : m_pView->getController().getTableConnectionData().push_back(_pConnection->GetData());
1574 : }
1575 0 : m_vTableConnection.push_back(_pConnection);
1576 0 : _pConnection->RecalcLines();
1577 0 : _pConnection->InvalidateConnection();
1578 :
1579 0 : modified();
1580 0 : if ( m_pAccessible )
1581 : m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
1582 : Any(),
1583 0 : makeAny(_pConnection->GetAccessible()));
1584 0 : }
1585 :
1586 0 : bool OJoinTableView::allowQueries() const
1587 : {
1588 0 : return true;
1589 : }
1590 :
1591 0 : void OJoinTableView::onNoColumns_throw()
1592 : {
1593 : OSL_FAIL( "OTableWindow::onNoColumns_throw: cannot really handle this!" );
1594 0 : throw SQLException();
1595 : }
1596 :
1597 0 : bool OJoinTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& ) const
1598 : {
1599 0 : return false;
1600 72 : }
1601 :
1602 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|