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( 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<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( 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(sal_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()), sal_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,sal_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, sal_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 ,sal_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 : sal_Bool isScrollAllowed( OJoinTableView* _pView,long nDelta, sal_Bool bHoriz)
396 : {
397 : // adjust ScrollBar-Positions
398 0 : ScrollBar* pBar = _pView->GetVScrollBar();
399 0 : if( bHoriz )
400 0 : pBar = _pView->GetHScrollBar();
401 :
402 0 : long nOldThumbPos = pBar->GetThumbPos();
403 0 : long nNewThumbPos = nOldThumbPos + nDelta;
404 0 : if( nNewThumbPos < 0 )
405 0 : nNewThumbPos = 0;
406 0 : else if( nNewThumbPos > pBar->GetRangeMax() )
407 0 : nNewThumbPos = pBar->GetRangeMax();
408 :
409 0 : if ( bHoriz )
410 : {
411 0 : if( nNewThumbPos == _pView->GetScrollOffset().X() )
412 0 : return sal_False;
413 : }
414 0 : else if ( nNewThumbPos == _pView->GetScrollOffset().Y() )
415 0 : return sal_False;
416 :
417 0 : return sal_True;
418 : }
419 0 : sal_Bool getMovementImpl(OJoinTableView* _pView,const Point& _rPoint,const Size& _rSize,long& _nScrollX,long& _nScrollY)
420 : {
421 0 : _nScrollY = _nScrollX = 0;
422 : // data about the tab win
423 0 : Point aUpperLeft = _rPoint;
424 : // normalize with respect to visibility
425 0 : aUpperLeft -= _pView->GetScrollOffset();
426 0 : Point aLowerRight(aUpperLeft.X() + _rSize.Width(), aUpperLeft.Y() + _rSize.Height());
427 :
428 : // data about ourself
429 0 : Size aSize = _pView->getRealOutputSize(); //GetOutputSizePixel();
430 :
431 0 : sal_Bool bVisbile = sal_True;
432 0 : sal_Bool bFitsHor = (aUpperLeft.X() >= 0) && (aLowerRight.X() <= aSize.Width());
433 0 : sal_Bool bFitsVert= (aUpperLeft.Y() >= 0) && (aLowerRight.Y() <= aSize.Height());
434 0 : if (!bFitsHor || !bFitsVert)
435 : {
436 0 : if (!bFitsHor)
437 : {
438 : // ensure the visibility of the right border
439 0 : if ( aLowerRight.X() > aSize.Width() )
440 0 : _nScrollX = aLowerRight.X() - aSize.Width() + TABWIN_SPACING_X;
441 :
442 : // ensure the visibility of the left border (higher priority)
443 0 : if ( aUpperLeft.X() < 0 )
444 0 : _nScrollX = aUpperLeft.X() - TABWIN_SPACING_X;
445 : }
446 :
447 0 : if (!bFitsVert)
448 : {
449 : // lower border
450 0 : if ( aLowerRight.Y() > aSize.Height() )
451 0 : _nScrollY = aLowerRight.Y() - aSize.Height() + TABWIN_SPACING_Y;
452 : // upper border
453 0 : if ( aUpperLeft.Y() < 0 )
454 0 : _nScrollY = aUpperLeft.Y() - TABWIN_SPACING_Y;
455 : }
456 :
457 0 : if ( _nScrollX ) // aSize.Width() > _rSize.Width() &&
458 0 : bVisbile = isScrollAllowed(_pView,_nScrollX, sal_True);
459 :
460 0 : if ( _nScrollY ) // aSize.Height() > _rSize.Height() &&
461 0 : bVisbile = bVisbile && isScrollAllowed(_pView,_nScrollY, sal_False);
462 :
463 0 : if ( bVisbile )
464 : {
465 0 : sal_Int32 nHRangeMax = _pView->GetHScrollBar()->GetRangeMax();
466 0 : sal_Int32 nVRangeMax = _pView->GetVScrollBar()->GetRangeMax();
467 :
468 0 : if ( aSize.Width() + _pView->GetHScrollBar()->GetThumbPos() + _nScrollX > nHRangeMax )
469 0 : bVisbile = sal_False;
470 0 : if ( bVisbile && aSize.Height() + _pView->GetVScrollBar()->GetThumbPos() + _nScrollY > nVRangeMax )
471 0 : bVisbile = sal_False;
472 : }
473 : }
474 :
475 0 : return bVisbile;
476 : }
477 : } // end of ano namespace
478 :
479 0 : sal_Bool OJoinTableView::isMovementAllowed(const Point& _rPoint,const Size& _rSize)
480 : {
481 : long nX,nY;
482 0 : return getMovementImpl(this,_rPoint,_rSize,nX,nY);
483 : }
484 :
485 0 : void OJoinTableView::EnsureVisible(const OTableWindow* _pWin)
486 : {
487 : // data about the tab win
488 0 : TTableWindowData::value_type pData = _pWin->GetData();
489 0 : EnsureVisible( pData->GetPosition() , pData->GetSize());
490 0 : Invalidate(INVALIDATE_NOCHILDREN);
491 0 : }
492 :
493 0 : void OJoinTableView::EnsureVisible(const Point& _rPoint,const Size& _rSize)
494 : {
495 : long nScrollX,nScrollY;
496 :
497 0 : if ( getMovementImpl(this,_rPoint,_rSize,nScrollX,nScrollY) )
498 : {
499 0 : sal_Bool bVisbile = sal_True;
500 0 : if (nScrollX)
501 0 : bVisbile = ScrollPane(nScrollX, sal_True, sal_True);
502 :
503 0 : if (nScrollY)
504 0 : bVisbile = bVisbile && ScrollPane(nScrollY, sal_False, sal_True);
505 : }
506 0 : }
507 :
508 0 : void OJoinTableView::SetDefaultTabWinPosSize( OTableWindow* pTabWin )
509 : {
510 : // determine position:
511 : // the window is divided into lines with height TABWIN_SPACING_Y+TABWIN_HEIGHT_STD.
512 : // Then for each line is checked, if there is space for another window.
513 : // If there is no space, the next line is checked.
514 0 : Size aOutSize = GetSizePixel();
515 0 : Point aNewPos( 0,0 );
516 0 : sal_uInt16 nRow = 0;
517 0 : sal_Bool bEnd = sal_False;
518 0 : while( !bEnd )
519 : {
520 : // Set new position to start of line
521 0 : aNewPos.X() = TABWIN_SPACING_X;
522 0 : aNewPos.Y() = (nRow+1) * TABWIN_SPACING_Y;
523 :
524 : // determine rectangle for the corresponding line
525 0 : Rectangle aRowRect( Point(0,0), aOutSize );
526 0 : aRowRect.Top() = nRow * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
527 0 : aRowRect.Bottom() = (nRow+1) * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
528 :
529 : // check occupied areas of this line
530 : OTableWindow* pOtherTabWin;
531 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
532 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
533 0 : for(;aIter != aEnd;++aIter)
534 : {
535 0 : pOtherTabWin = aIter->second;
536 0 : Rectangle aOtherTabWinRect( pOtherTabWin->GetPosPixel(), pOtherTabWin->GetSizePixel() );
537 :
538 0 : if(
539 0 : ( (aOtherTabWinRect.Top()>aRowRect.Top()) && (aOtherTabWinRect.Top()<aRowRect.Bottom()) ) ||
540 0 : ( (aOtherTabWinRect.Bottom()>aRowRect.Top()) && (aOtherTabWinRect.Bottom()<aRowRect.Bottom()) )
541 : )
542 : {
543 : // TabWin is in the line
544 0 : if( aOtherTabWinRect.Right()>aNewPos.X() )
545 0 : aNewPos.X() = aOtherTabWinRect.Right() + TABWIN_SPACING_X;
546 : }
547 : }
548 :
549 : // Is there space left in this line?
550 0 : if( (aNewPos.X()+TABWIN_WIDTH_STD)<aRowRect.Right() )
551 : {
552 0 : aNewPos.Y() = aRowRect.Top() + TABWIN_SPACING_Y;
553 0 : bEnd = sal_True;
554 : }
555 : else
556 : {
557 0 : if( (aRowRect.Bottom()+aRowRect.GetHeight()) > aOutSize.Height() )
558 : {
559 : // insert it in the first row
560 0 : sal_Int32 nCount = m_aTableMap.size() % (nRow+1);
561 0 : ++nCount;
562 0 : aNewPos.Y() = nCount * TABWIN_SPACING_Y + (nCount-1)*CalcZoom(TABWIN_HEIGHT_STD);
563 0 : bEnd = sal_True;
564 : }
565 : else
566 0 : nRow++;
567 :
568 : }
569 : }
570 :
571 : // determine size
572 0 : Size aNewSize( CalcZoom(TABWIN_WIDTH_STD), CalcZoom(TABWIN_HEIGHT_STD) );
573 :
574 : // check if the new position in inside the scrollbars ranges
575 0 : Point aBottom(aNewPos);
576 0 : aBottom.X() += aNewSize.Width();
577 0 : aBottom.Y() += aNewSize.Height();
578 :
579 0 : if(!GetHScrollBar()->GetRange().IsInside(aBottom.X()))
580 0 : GetHScrollBar()->SetRange( Range(0, aBottom.X()) );
581 0 : if(!GetVScrollBar()->GetRange().IsInside(aBottom.Y()))
582 0 : GetVScrollBar()->SetRange( Range(0, aBottom.Y()) );
583 :
584 0 : pTabWin->SetPosSizePixel( aNewPos, aNewSize );
585 0 : }
586 :
587 0 : void OJoinTableView::DataChanged(const DataChangedEvent& rDCEvt)
588 : {
589 0 : if (rDCEvt.GetType() == DATACHANGED_SETTINGS)
590 : {
591 : // consider the worst case: the colors changed, so adjust me
592 0 : InitColors();
593 0 : Invalidate(INVALIDATE_NOCHILDREN);
594 : // due to the Invalidate, the connections are redrawn, so that they are also pictured in the new colors
595 : }
596 0 : }
597 :
598 0 : void OJoinTableView::InitColors()
599 : {
600 : // the colors for the illustration should be the system colors
601 0 : StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
602 0 : SetBackground(Wallpaper(Color(aSystemStyle.GetDialogColor())));
603 0 : }
604 :
605 0 : void OJoinTableView::BeginChildMove( OTableWindow* pTabWin, const Point& rMousePos )
606 : {
607 :
608 0 : if (m_pView->getController().isReadOnly())
609 0 : return;
610 :
611 0 : m_pDragWin = pTabWin;
612 0 : SetPointer(Pointer(POINTER_MOVE));
613 0 : Point aMousePos = ScreenToOutputPixel( rMousePos );
614 0 : m_aDragOffset = aMousePos - pTabWin->GetPosPixel();
615 0 : m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
616 0 : m_bTrackingInitiallyMoved = sal_False;
617 0 : StartTracking();
618 : }
619 :
620 0 : void OJoinTableView::NotifyTitleClicked( OTableWindow* pTabWin, const Point rMousePos )
621 : {
622 0 : DeselectConn(GetSelectedConn());
623 0 : BeginChildMove(pTabWin, rMousePos);
624 0 : }
625 :
626 0 : void OJoinTableView::BeginChildSizing( OTableWindow* pTabWin, const Pointer& rPointer )
627 : {
628 :
629 0 : if (m_pView->getController().isReadOnly())
630 0 : return;
631 :
632 0 : SetPointer( rPointer );
633 0 : m_pSizingWin = pTabWin;
634 0 : StartTracking();
635 : }
636 :
637 0 : sal_Bool OJoinTableView::ScrollPane( long nDelta, sal_Bool bHoriz, sal_Bool bPaintScrollBars )
638 : {
639 0 : sal_Bool bRet = sal_True;
640 :
641 : // adjust ScrollBar-Positions
642 0 : if( bPaintScrollBars )
643 : {
644 0 : if( bHoriz )
645 : {
646 0 : long nOldThumbPos = GetHScrollBar()->GetThumbPos();
647 0 : long nNewThumbPos = nOldThumbPos + nDelta;
648 0 : if( nNewThumbPos < 0 )
649 : {
650 0 : nNewThumbPos = 0;
651 0 : bRet = sal_False;
652 : }
653 0 : if( nNewThumbPos > GetHScrollBar()->GetRange().Max() )
654 : {
655 0 : nNewThumbPos = GetHScrollBar()->GetRange().Max();
656 0 : bRet = sal_False;
657 : }
658 0 : GetHScrollBar()->SetThumbPos( nNewThumbPos );
659 0 : nDelta = GetHScrollBar()->GetThumbPos() - nOldThumbPos;
660 : }
661 : else
662 : {
663 0 : long nOldThumbPos = GetVScrollBar()->GetThumbPos();
664 0 : long nNewThumbPos = nOldThumbPos+nDelta;
665 0 : if( nNewThumbPos < 0 )
666 : {
667 0 : nNewThumbPos = 0;
668 0 : bRet = sal_False;
669 : }
670 0 : if( nNewThumbPos > GetVScrollBar()->GetRange().Max() )
671 : {
672 0 : nNewThumbPos = GetVScrollBar()->GetRange().Max();
673 0 : bRet = sal_False;
674 : }
675 0 : GetVScrollBar()->SetThumbPos( nNewThumbPos );
676 0 : nDelta = GetVScrollBar()->GetThumbPos() - nOldThumbPos;
677 : }
678 : }
679 :
680 : // If ScrollOffset hitting borders, no redrawing.
681 0 : if( (GetHScrollBar()->GetThumbPos()==m_aScrollOffset.X()) &&
682 0 : (GetVScrollBar()->GetThumbPos()==m_aScrollOffset.Y()) )
683 0 : return sal_False;
684 :
685 : // set ScrollOffset anew
686 0 : if (bHoriz)
687 0 : m_aScrollOffset.X() = GetHScrollBar()->GetThumbPos();
688 : else
689 0 : m_aScrollOffset.Y() = GetVScrollBar()->GetThumbPos();
690 :
691 : // move all windows
692 : OTableWindow* pTabWin;
693 0 : Point aPos;
694 :
695 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
696 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
697 0 : for(;aIter != aEnd;++aIter)
698 : {
699 0 : pTabWin = aIter->second;
700 0 : aPos = pTabWin->GetPosPixel();
701 :
702 0 : if( bHoriz )
703 0 : aPos.X() -= nDelta;
704 0 : else aPos.Y() -= nDelta;
705 :
706 0 : pTabWin->SetPosPixel( aPos );
707 : }
708 :
709 0 : Invalidate(); // INVALIDATE_NOCHILDREN
710 :
711 0 : return bRet;
712 : }
713 :
714 0 : void OJoinTableView::Tracking( const TrackingEvent& rTEvt )
715 : {
716 0 : HideTracking();
717 :
718 0 : if (rTEvt.IsTrackingEnded())
719 : {
720 0 : if( m_pDragWin )
721 : {
722 0 : if (m_aDragScrollTimer.IsActive())
723 0 : m_aDragScrollTimer.Stop();
724 :
725 : // adjust position of child after moving
726 : // windows are not allowed to leave display range
727 0 : Point aDragWinPos = rTEvt.GetMouseEvent().GetPosPixel() - m_aDragOffset;
728 0 : Size aDragWinSize = m_pDragWin->GetSizePixel();
729 0 : if( aDragWinPos.X() < 0 )
730 0 : aDragWinPos.X() = 0;
731 0 : if( aDragWinPos.Y() < 0 )
732 0 : aDragWinPos.Y() = 0;
733 0 : if( (aDragWinPos.X() + aDragWinSize.Width()) > m_aOutputSize.Width() )
734 0 : aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width() - 1;
735 0 : if( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() )
736 0 : aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height() - 1;
737 0 : if( aDragWinPos.X() < 0 )
738 0 : aDragWinPos.X() = 0;
739 0 : if( aDragWinPos.Y() < 0 )
740 0 : aDragWinPos.Y() = 0;
741 : // TODO : don't position window anew, if it is leaving range, but just expand the range
742 :
743 : // position window
744 0 : EndTracking();
745 0 : m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
746 : // check, if I really moved
747 : // (this prevents setting the modified-Flag, when there actually was no change0
748 0 : TTableWindowData::value_type pData = m_pDragWin->GetData();
749 0 : if ( ! (pData && pData->HasPosition() && (pData->GetPosition() == aDragWinPos)))
750 : {
751 : // old logic coordinates
752 0 : Point ptOldPos = m_pDragWin->GetPosPixel() + Point(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
753 : // new positioning
754 0 : m_pDragWin->SetPosPixel(aDragWinPos);
755 0 : TabWinMoved(m_pDragWin, ptOldPos);
756 :
757 0 : m_pDragWin->GrabFocus();
758 : }
759 0 : m_pDragWin = NULL;
760 0 : SetPointer(Pointer(POINTER_ARROW));
761 : }
762 : // else we handle the resizing
763 0 : else if( m_pSizingWin )
764 : {
765 0 : SetPointer( Pointer() );
766 0 : EndTracking();
767 :
768 : // old physical coordinates
769 :
770 0 : Size szOld = m_pSizingWin->GetSizePixel();
771 0 : Point ptOld = m_pSizingWin->GetPosPixel();
772 0 : Size aNewSize(CalcZoom(m_aSizingRect.GetSize().Width()),CalcZoom(m_aSizingRect.GetSize().Height()));
773 0 : m_pSizingWin->SetPosSizePixel( m_aSizingRect.TopLeft(), aNewSize );
774 0 : TabWinSized(m_pSizingWin, ptOld, szOld);
775 :
776 0 : m_pSizingWin->Invalidate( m_aSizingRect );
777 0 : m_pSizingWin = NULL;
778 : }
779 : }
780 0 : else if (rTEvt.IsTrackingCanceled())
781 : {
782 0 : if (m_aDragScrollTimer.IsActive())
783 0 : m_aDragScrollTimer.Stop();
784 0 : EndTracking();
785 : }
786 : else
787 : {
788 0 : if( m_pDragWin )
789 : {
790 0 : m_ptPrevDraggingPos = rTEvt.GetMouseEvent().GetPosPixel();
791 : // scroll at window borders
792 0 : ScrollWhileDragging();
793 : }
794 :
795 0 : if( m_pSizingWin )
796 : {
797 0 : Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
798 0 : m_aSizingRect = m_pSizingWin->getSizingRect(aMousePos,m_aOutputSize);
799 0 : Update();
800 0 : ShowTracking( m_aSizingRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
801 : }
802 : }
803 0 : }
804 :
805 0 : void OJoinTableView::ConnDoubleClicked( OTableConnection* /*pConnection*/ )
806 : {
807 0 : }
808 :
809 0 : void OJoinTableView::MouseButtonDown( const MouseEvent& rEvt )
810 : {
811 0 : GrabFocus();
812 0 : Window::MouseButtonDown(rEvt);
813 0 : }
814 :
815 0 : void OJoinTableView::MouseButtonUp( const MouseEvent& rEvt )
816 : {
817 0 : Window::MouseButtonUp(rEvt);
818 : // Has a connection been selected?
819 0 : if( !m_vTableConnection.empty() )
820 : {
821 0 : DeselectConn(GetSelectedConn());
822 :
823 0 : ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
824 0 : ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
825 0 : for(;aIter != aEnd;++aIter)
826 : {
827 0 : if( (*aIter)->CheckHit(rEvt.GetPosPixel()) )
828 : {
829 0 : SelectConn((*aIter));
830 :
831 : // Double-click
832 0 : if( rEvt.GetClicks() == 2 )
833 0 : ConnDoubleClicked( (*aIter) );
834 :
835 0 : break;
836 : }
837 : }
838 : }
839 0 : }
840 :
841 0 : void OJoinTableView::KeyInput( const KeyEvent& rEvt )
842 : {
843 0 : sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
844 0 : sal_Bool bShift = rEvt.GetKeyCode().IsShift();
845 0 : sal_Bool bCtrl = rEvt.GetKeyCode().IsMod1();
846 :
847 0 : if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
848 : {
849 0 : if (GetSelectedConn())
850 0 : RemoveConnection( GetSelectedConn() ,sal_True);
851 : }
852 : else
853 0 : Window::KeyInput( rEvt );
854 0 : }
855 :
856 0 : void OJoinTableView::DeselectConn(OTableConnection* pConn)
857 : {
858 0 : if (!pConn || !pConn->IsSelected())
859 0 : return;
860 :
861 : // deselect the corresponding entries in the ListBox of the table window
862 0 : OTableWindow* pWin = pConn->GetSourceWin();
863 0 : if (pWin && pWin->GetListBox())
864 0 : pWin->GetListBox()->SelectAll(false);
865 :
866 0 : pWin = pConn->GetDestWin();
867 0 : if (pWin && pWin->GetListBox())
868 0 : pWin->GetListBox()->SelectAll(false);
869 :
870 0 : pConn->Deselect();
871 0 : m_pSelectedConn = NULL;
872 : }
873 :
874 0 : void OJoinTableView::SelectConn(OTableConnection* pConn)
875 : {
876 0 : DeselectConn(GetSelectedConn());
877 :
878 0 : pConn->Select();
879 0 : m_pSelectedConn = pConn;
880 0 : GrabFocus(); // has to be called here because a table window may still be focused
881 :
882 : // select the concerned entries in the windows
883 0 : OTableWindow* pConnSource = pConn->GetSourceWin();
884 0 : OTableWindow* pConnDest = pConn->GetDestWin();
885 0 : if (pConnSource && pConnDest)
886 : {
887 0 : OTableWindowListBox* pSourceBox = pConnSource->GetListBox();
888 0 : OTableWindowListBox* pDestBox = pConnDest->GetListBox();
889 0 : if (pSourceBox && pDestBox)
890 : {
891 0 : pSourceBox->SelectAll(false);
892 0 : pDestBox->SelectAll(false);
893 :
894 0 : SvTreeListEntry* pFirstSourceVisible = pSourceBox->GetFirstEntryInView();
895 0 : SvTreeListEntry* pFirstDestVisible = pDestBox->GetFirstEntryInView();
896 :
897 0 : const ::std::vector<OConnectionLine*>* pLines = pConn->GetConnLineList();
898 0 : ::std::vector<OConnectionLine*>::const_reverse_iterator aIter = pLines->rbegin();
899 0 : for(;aIter != pLines->rend();++aIter)
900 : {
901 0 : if ((*aIter)->IsValid())
902 : {
903 0 : SvTreeListEntry* pSourceEntry = pSourceBox->GetEntryFromText((*aIter)->GetData()->GetSourceFieldName());
904 0 : if (pSourceEntry)
905 : {
906 0 : pSourceBox->Select(pSourceEntry, true);
907 0 : pSourceBox->MakeVisible(pSourceEntry);
908 : }
909 :
910 0 : SvTreeListEntry* pDestEntry = pDestBox->GetEntryFromText((*aIter)->GetData()->GetDestFieldName());
911 0 : if (pDestEntry)
912 : {
913 0 : pDestBox->Select(pDestEntry, true);
914 0 : pDestBox->MakeVisible(pDestEntry);
915 : }
916 :
917 : }
918 : }
919 :
920 0 : if ((pFirstSourceVisible != pSourceBox->GetFirstEntryInView())
921 0 : || (pFirstDestVisible != pDestBox->GetFirstEntryInView()))
922 : // scrolling was done -> redraw
923 0 : Invalidate(INVALIDATE_NOCHILDREN);
924 : }
925 : }
926 0 : }
927 :
928 0 : void OJoinTableView::Paint( const Rectangle& rRect )
929 : {
930 0 : DrawConnections( rRect );
931 0 : }
932 :
933 0 : void OJoinTableView::InvalidateConnections()
934 : {
935 : // draw Joins
936 : ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),
937 0 : ::std::mem_fun(& OTableConnection::InvalidateConnection));
938 0 : }
939 :
940 0 : void OJoinTableView::DrawConnections( const Rectangle& rRect )
941 : {
942 : // draw Joins
943 0 : ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),boost::bind( &OTableConnection::Draw, _1, boost::cref( rRect )));
944 : // finally redraw the selected one above all others
945 0 : if (GetSelectedConn())
946 0 : GetSelectedConn()->Draw( rRect );
947 0 : }
948 :
949 0 : ::std::vector<OTableConnection*>::const_iterator OJoinTableView::getTableConnections(const OTableWindow* _pFromWin) const
950 : {
951 : return ::std::find_if( m_vTableConnection.begin(),
952 : m_vTableConnection.end(),
953 0 : ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
954 : }
955 :
956 0 : sal_Int32 OJoinTableView::getConnectionCount(const OTableWindow* _pFromWin) const
957 : {
958 : return ::std::count_if( m_vTableConnection.begin(),
959 : m_vTableConnection.end(),
960 0 : ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
961 : }
962 :
963 0 : sal_Bool OJoinTableView::ExistsAConn(const OTableWindow* pFrom) const
964 : {
965 0 : return getTableConnections(pFrom) != m_vTableConnection.end();
966 : }
967 :
968 0 : void OJoinTableView::ClearAll()
969 : {
970 0 : SetUpdateMode(false);
971 :
972 0 : HideTabWins();
973 :
974 : // and the same with the Connections
975 0 : ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
976 0 : ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
977 0 : for(;aIter != aEnd;++aIter)
978 0 : RemoveConnection( *aIter ,sal_True);
979 0 : m_vTableConnection.clear();
980 :
981 0 : m_pLastFocusTabWin = NULL;
982 0 : m_pSelectedConn = NULL;
983 :
984 : // scroll to the upper left
985 0 : ScrollPane(-GetScrollOffset().X(), sal_True, sal_True);
986 0 : ScrollPane(-GetScrollOffset().Y(), sal_False, sal_True);
987 0 : Invalidate();
988 0 : }
989 :
990 0 : sal_Bool OJoinTableView::ScrollWhileDragging()
991 : {
992 : OSL_ENSURE(m_pDragWin != NULL, "OJoinTableView::ScrollWhileDragging must not be called when a window is being dragged !");
993 :
994 : // kill the timer
995 0 : if (m_aDragScrollTimer.IsActive())
996 0 : m_aDragScrollTimer.Stop();
997 :
998 0 : Point aDragWinPos = m_ptPrevDraggingPos - m_aDragOffset;
999 0 : Size aDragWinSize = m_pDragWin->GetSizePixel();
1000 0 : Point aLowerRight(aDragWinPos.X() + aDragWinSize.Width(), aDragWinPos.Y() + aDragWinSize.Height());
1001 :
1002 0 : if (!m_bTrackingInitiallyMoved && (aDragWinPos == m_pDragWin->GetPosPixel()))
1003 0 : return sal_True;
1004 :
1005 : // avoid illustration errors (when scrolling with active TrackingRect)
1006 0 : HideTracking();
1007 :
1008 0 : sal_Bool bScrolling = sal_False;
1009 0 : sal_Bool bNeedScrollTimer = sal_False;
1010 :
1011 : // scroll at window borders
1012 : // TODO : only catch, if window would disappear completely (don't, if there is still a pixel visible)
1013 0 : if( aDragWinPos.X() < 5 )
1014 : {
1015 0 : bScrolling = ScrollPane( -LINE_SIZE, sal_True, sal_True );
1016 0 : if( !bScrolling && (aDragWinPos.X()<0) )
1017 0 : aDragWinPos.X() = 0;
1018 :
1019 : // do I need further (timer controlled) scrolling ?
1020 0 : bNeedScrollTimer = bScrolling && (aDragWinPos.X() < 5);
1021 : }
1022 :
1023 0 : if( aLowerRight.X() > m_aOutputSize.Width() - 5 )
1024 : {
1025 0 : bScrolling = ScrollPane( LINE_SIZE, sal_True, sal_True ) ;
1026 0 : if( !bScrolling && ( aLowerRight.X() > m_aOutputSize.Width() ) )
1027 0 : aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width();
1028 :
1029 : // do I need further (timer controlled) scrolling ?
1030 0 : bNeedScrollTimer = bScrolling && (aLowerRight.X() > m_aOutputSize.Width() - 5);
1031 : }
1032 :
1033 0 : if( aDragWinPos.Y() < 5 )
1034 : {
1035 0 : bScrolling = ScrollPane( -LINE_SIZE, sal_False, sal_True );
1036 0 : if( !bScrolling && (aDragWinPos.Y()<0) )
1037 0 : aDragWinPos.Y() = 0;
1038 :
1039 0 : bNeedScrollTimer = bScrolling && (aDragWinPos.Y() < 5);
1040 : }
1041 :
1042 0 : if( aLowerRight.Y() > m_aOutputSize.Height() - 5 )
1043 : {
1044 0 : bScrolling = ScrollPane( LINE_SIZE, sal_False, sal_True );
1045 0 : if( !bScrolling && ( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() ) )
1046 0 : aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height();
1047 :
1048 0 : bNeedScrollTimer = bScrolling && (aLowerRight.Y() > m_aOutputSize.Height() - 5);
1049 : }
1050 :
1051 : // resetting timer, if still necessary
1052 0 : if (bNeedScrollTimer)
1053 : {
1054 0 : m_aDragScrollTimer.SetTimeout(100);
1055 0 : m_aDragScrollTimer.Start();
1056 : }
1057 :
1058 : // redraw DraggingRect
1059 0 : m_aDragRect = Rectangle(m_ptPrevDraggingPos - m_aDragOffset, m_pDragWin->GetSizePixel());
1060 0 : Update();
1061 0 : ShowTracking( m_aDragRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
1062 :
1063 0 : return bScrolling;
1064 : }
1065 :
1066 0 : IMPL_LINK_NOARG(OJoinTableView, OnDragScrollTimer)
1067 : {
1068 0 : ScrollWhileDragging();
1069 0 : return 0L;
1070 : }
1071 :
1072 0 : void OJoinTableView::invalidateAndModify(SfxUndoAction *_pAction)
1073 : {
1074 0 : Invalidate(INVALIDATE_NOCHILDREN);
1075 0 : m_pView->getController().addUndoActionAndInvalidate(_pAction);
1076 0 : }
1077 :
1078 0 : void OJoinTableView::TabWinMoved(OTableWindow* ptWhich, const Point& ptOldPosition)
1079 : {
1080 0 : Point ptThumbPos(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
1081 0 : ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel() + ptThumbPos);
1082 :
1083 0 : invalidateAndModify(new OJoinMoveTabWinUndoAct(this, ptOldPosition, ptWhich));
1084 0 : }
1085 :
1086 0 : void OJoinTableView::TabWinSized(OTableWindow* ptWhich, const Point& ptOldPosition, const Size& szOldSize)
1087 : {
1088 0 : ptWhich->GetData()->SetSize(ptWhich->GetSizePixel());
1089 0 : ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel());
1090 :
1091 0 : invalidateAndModify(new OJoinSizeTabWinUndoAct(this, ptOldPosition, szOldSize, ptWhich));
1092 0 : }
1093 :
1094 0 : sal_Bool OJoinTableView::IsAddAllowed()
1095 : {
1096 :
1097 : // not, if Db readonly
1098 0 : if (m_pView->getController().isReadOnly())
1099 0 : return sal_False;
1100 :
1101 : try
1102 : {
1103 0 : Reference< XConnection> xConnection = m_pView->getController().getConnection();
1104 0 : if(!xConnection.is())
1105 0 : return sal_False;
1106 : // not, if too many tables already
1107 0 : Reference < XDatabaseMetaData > xMetaData( xConnection->getMetaData() );
1108 :
1109 0 : sal_Int32 nMax = xMetaData.is() ? xMetaData->getMaxTablesInSelect() : 0;
1110 0 : if (nMax && nMax <= (sal_Int32)m_aTableMap.size())
1111 0 : return sal_False;
1112 : }
1113 0 : catch(SQLException&)
1114 : {
1115 0 : return sal_False;
1116 : }
1117 :
1118 0 : return sal_True;
1119 : }
1120 :
1121 0 : void OJoinTableView::executePopup(const Point& _aPos,OTableConnection* _pSelConnection)
1122 : {
1123 0 : PopupMenu aContextMenu( ModuleRes( RID_MENU_JOINVIEW_CONNECTION ) );
1124 0 : switch (aContextMenu.Execute(this, _aPos))
1125 : {
1126 : case SID_DELETE:
1127 0 : RemoveConnection( _pSelConnection ,sal_True);
1128 0 : break;
1129 : case ID_QUERY_EDIT_JOINCONNECTION:
1130 0 : ConnDoubleClicked( _pSelConnection ); // is the same as double clicked
1131 0 : break;
1132 0 : }
1133 0 : }
1134 :
1135 0 : void OJoinTableView::Command(const CommandEvent& rEvt)
1136 : {
1137 :
1138 0 : sal_Bool bHandled = sal_False;
1139 :
1140 0 : switch (rEvt.GetCommand())
1141 : {
1142 : case COMMAND_CONTEXTMENU:
1143 : {
1144 0 : if( m_vTableConnection.empty() )
1145 0 : return;
1146 :
1147 0 : OTableConnection* pSelConnection = GetSelectedConn();
1148 : // when it wasn't a mouse event use the selected connection
1149 0 : if (!rEvt.IsMouseEvent())
1150 : {
1151 0 : if( pSelConnection )
1152 : {
1153 0 : const ::std::vector<OConnectionLine*>* pLines = pSelConnection->GetConnLineList();
1154 0 : ::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(pLines->begin(),pLines->end(),::std::mem_fun(&OConnectionLine::IsValid));
1155 0 : if( aIter != pLines->end() )
1156 0 : executePopup((*aIter)->getMidPoint(),pSelConnection);
1157 : }
1158 : }
1159 : else
1160 : {
1161 0 : DeselectConn(pSelConnection);
1162 :
1163 0 : const Point& aMousePos = rEvt.GetMousePosPixel();
1164 0 : ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
1165 0 : ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
1166 0 : for(;aIter != aEnd;++aIter)
1167 : {
1168 0 : if( (*aIter)->CheckHit(aMousePos) )
1169 : {
1170 0 : SelectConn(*aIter);
1171 0 : if(!getDesignView()->getController().isReadOnly() && getDesignView()->getController().isConnected())
1172 0 : executePopup(rEvt.GetMousePosPixel(),*aIter);
1173 0 : break;
1174 : }
1175 : }
1176 : }
1177 0 : bHandled = sal_True;
1178 : }
1179 : }
1180 0 : if (!bHandled)
1181 0 : Window::Command(rEvt);
1182 : }
1183 :
1184 0 : OTableConnection* OJoinTableView::GetTabConn(const OTableWindow* pLhs,const OTableWindow* pRhs,bool _bSupressCrossOrNaturalJoin,const OTableConnection* _rpFirstAfter) const
1185 : {
1186 0 : OTableConnection* pConn = NULL;
1187 : OSL_ENSURE(pRhs || pLhs, "OJoinTableView::GetTabConn : invalid args !");
1188 : // only one NULL-arg allowed
1189 :
1190 0 : if ((!pLhs || pLhs->ExistsAConn()) && (!pRhs || pRhs->ExistsAConn()))
1191 : {
1192 0 : sal_Bool bFoundStart = _rpFirstAfter ? sal_False : sal_True;
1193 :
1194 0 : ::std::vector<OTableConnection*>::const_iterator aIter = m_vTableConnection.begin();
1195 0 : ::std::vector<OTableConnection*>::const_iterator aEnd = m_vTableConnection.end();
1196 0 : for(;aIter != aEnd;++aIter)
1197 : {
1198 0 : OTableConnection* pData = *aIter;
1199 :
1200 0 : if ( ( (pData->GetSourceWin() == pLhs)
1201 0 : && ( (pData->GetDestWin() == pRhs)
1202 0 : || (NULL == pRhs)
1203 : )
1204 : )
1205 0 : || ( (pData->GetSourceWin() == pRhs)
1206 0 : && ( (pData->GetDestWin() == pLhs)
1207 0 : || (NULL == pLhs)
1208 : )
1209 : )
1210 : )
1211 : {
1212 0 : if ( _bSupressCrossOrNaturalJoin )
1213 : {
1214 0 : if ( supressCrossNaturalJoin(pData->GetData()) )
1215 0 : continue;
1216 : }
1217 0 : if (bFoundStart)
1218 : {
1219 0 : pConn = pData;
1220 0 : break;
1221 : }
1222 :
1223 0 : if (!pConn)
1224 : // used as fallback : if there is no conn after _rpFirstAfter the first conn between the two tables
1225 : // will be used
1226 0 : pConn = pData;
1227 :
1228 0 : if (pData == _rpFirstAfter)
1229 0 : bFoundStart = sal_True;
1230 : }
1231 : }
1232 : }
1233 0 : return pConn;
1234 : }
1235 :
1236 0 : bool OJoinTableView::PreNotify(NotifyEvent& rNEvt)
1237 : {
1238 0 : sal_Bool bHandled = sal_False;
1239 0 : switch (rNEvt.GetType())
1240 : {
1241 : case EVENT_COMMAND:
1242 : {
1243 0 : const CommandEvent* pCommand = rNEvt.GetCommandEvent();
1244 0 : if (pCommand->GetCommand() == COMMAND_WHEEL)
1245 : {
1246 0 : const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
1247 0 : if (pData->GetMode() == COMMAND_WHEEL_SCROLL)
1248 : {
1249 0 : if (pData->GetDelta() > 0)
1250 0 : ScrollPane(-10 * pData->GetScrollLines(), pData->IsHorz(), sal_True);
1251 : else
1252 0 : ScrollPane(10 * pData->GetScrollLines(), pData->IsHorz(), sal_True);
1253 0 : bHandled = sal_True;
1254 : }
1255 : }
1256 : }
1257 0 : break;
1258 : case EVENT_KEYINPUT:
1259 : {
1260 0 : if (m_aTableMap.empty())
1261 : // no tab wins -> no conns -> no traveling
1262 0 : break;
1263 :
1264 0 : const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
1265 0 : if (!pKeyEvent->GetKeyCode().IsMod1())
1266 : {
1267 0 : switch (pKeyEvent->GetKeyCode().GetCode())
1268 : {
1269 : case KEY_TAB:
1270 : {
1271 0 : if (!HasChildPathFocus())
1272 0 : break;
1273 :
1274 0 : sal_Bool bForward = !pKeyEvent->GetKeyCode().IsShift();
1275 : // is there an active tab win ?
1276 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
1277 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
1278 0 : for(;aIter != aEnd;++aIter)
1279 0 : if (aIter->second && aIter->second->HasChildPathFocus())
1280 0 : break;
1281 :
1282 0 : OTableWindow* pNextWin = NULL;
1283 0 : OTableConnection* pNextConn = NULL;
1284 :
1285 0 : if (aIter != m_aTableMap.end())
1286 : { // there is a currently active tab win
1287 : // check if there is an "overflow" and we should select a conn instead of a win
1288 0 : if (!m_vTableConnection.empty())
1289 : {
1290 0 : if ((aIter->second == m_aTableMap.rbegin()->second) && bForward)
1291 : // the last win is active and we're travelling forward -> select the first conn
1292 0 : pNextConn = *m_vTableConnection.begin();
1293 0 : if ((aIter == m_aTableMap.begin()) && !bForward)
1294 : // the first win is active an we're traveling backward -> select the last conn
1295 0 : pNextConn = *m_vTableConnection.rbegin();
1296 : }
1297 :
1298 0 : if (!pNextConn)
1299 : {
1300 : // no conn for any reason -> select the next or previous tab win
1301 0 : if(bForward)
1302 : {
1303 0 : if ( aIter->second == m_aTableMap.rbegin()->second )
1304 0 : pNextWin = m_aTableMap.begin()->second;
1305 : else
1306 : {
1307 0 : ++aIter;
1308 0 : pNextWin = aIter->second;
1309 : }
1310 : }
1311 : else
1312 : {
1313 0 : if (aIter == m_aTableMap.begin())
1314 0 : pNextWin = m_aTableMap.rbegin()->second;
1315 : else
1316 : {
1317 0 : --aIter;
1318 0 : pNextWin = aIter->second;
1319 : }
1320 : }
1321 : }
1322 : }
1323 : else
1324 : { // no active tab win -> travel the connections
1325 : // find the currently selected conn within the conn list
1326 0 : sal_Int32 i(0);
1327 0 : for ( ::std::vector<OTableConnection*>::iterator connectionIter = m_vTableConnection.begin();
1328 0 : connectionIter != m_vTableConnection.end();
1329 : ++connectionIter, ++i
1330 : )
1331 : {
1332 0 : if ( (*connectionIter) == GetSelectedConn() )
1333 0 : break;
1334 : }
1335 0 : if (i == sal_Int32(m_vTableConnection.size() - 1) && bForward)
1336 : // the last conn is active and we're travelling forward -> select the first win
1337 0 : pNextWin = m_aTableMap.begin()->second;
1338 0 : if ((i == 0) && !bForward && !m_aTableMap.empty())
1339 : // the first conn is active and we're travelling backward -> select the last win
1340 0 : pNextWin = m_aTableMap.rbegin()->second;
1341 :
1342 0 : if (pNextWin)
1343 0 : DeselectConn(GetSelectedConn());
1344 : else
1345 : // no win for any reason -> select the next or previous conn
1346 0 : if (i < (sal_Int32)m_vTableConnection.size())
1347 : // there is a currently active conn
1348 0 : pNextConn = m_vTableConnection[(i + (bForward ? 1 : m_vTableConnection.size() - 1)) % m_vTableConnection.size()];
1349 : else
1350 : { // no tab win selected, no conn selected
1351 0 : if (!m_vTableConnection.empty())
1352 0 : pNextConn = m_vTableConnection[bForward ? 0 : m_vTableConnection.size() - 1];
1353 0 : else if (!m_aTableMap.empty())
1354 : {
1355 0 : if(bForward)
1356 0 : pNextWin = m_aTableMap.begin()->second;
1357 : else
1358 0 : pNextWin = m_aTableMap.rbegin()->second;
1359 : }
1360 : }
1361 : }
1362 :
1363 : // now select the object
1364 0 : if (pNextWin)
1365 : {
1366 0 : if (pNextWin->GetListBox())
1367 0 : pNextWin->GetListBox()->GrabFocus();
1368 : else
1369 0 : pNextWin->GrabFocus();
1370 0 : EnsureVisible(pNextWin);
1371 : }
1372 0 : else if (pNextConn)
1373 : {
1374 0 : GrabFocus();
1375 : // necessary : a conn may be selected even if a tab win has the focus, in this case
1376 : // the next travel would select the same conn again if we would not reset te focus ...
1377 0 : SelectConn(pNextConn);
1378 : }
1379 : }
1380 0 : break;
1381 : case KEY_RETURN:
1382 : {
1383 0 : if (!pKeyEvent->GetKeyCode().IsShift() && GetSelectedConn() && HasFocus())
1384 0 : ConnDoubleClicked(GetSelectedConn());
1385 0 : break;
1386 : }
1387 : }
1388 : }
1389 : }
1390 0 : break;
1391 : case EVENT_GETFOCUS:
1392 : {
1393 0 : if (m_aTableMap.empty())
1394 : // no tab wins -> no conns -> no focus change
1395 0 : break;
1396 0 : Window* pSource = rNEvt.GetWindow();
1397 0 : if (pSource)
1398 : {
1399 0 : Window* pSearchFor = NULL;
1400 0 : if (pSource->GetParent() == this)
1401 : // it may be one of the tab wins
1402 0 : pSearchFor = pSource;
1403 0 : else if (pSource->GetParent() && (pSource->GetParent()->GetParent() == this))
1404 : // it may be one of th list boxes of one of the tab wins
1405 0 : pSearchFor = pSource->GetParent();
1406 :
1407 0 : if (pSearchFor)
1408 : {
1409 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
1410 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
1411 0 : for(;aIter != aEnd;++aIter)
1412 : {
1413 0 : if (aIter->second == pSearchFor)
1414 : {
1415 0 : m_pLastFocusTabWin = aIter->second;
1416 0 : break;
1417 : }
1418 : }
1419 : }
1420 : }
1421 : }
1422 0 : break;
1423 : }
1424 :
1425 0 : if (!bHandled)
1426 0 : return Window::PreNotify(rNEvt);
1427 0 : return true;
1428 : }
1429 :
1430 0 : void OJoinTableView::GrabTabWinFocus()
1431 : {
1432 0 : if (m_pLastFocusTabWin && m_pLastFocusTabWin->IsVisible())
1433 : {
1434 0 : if (m_pLastFocusTabWin->GetListBox())
1435 0 : m_pLastFocusTabWin->GetListBox()->GrabFocus();
1436 : else
1437 0 : m_pLastFocusTabWin->GrabFocus();
1438 : }
1439 0 : else if (!m_aTableMap.empty() && m_aTableMap.begin()->second && m_aTableMap.begin()->second->IsVisible())
1440 : {
1441 0 : OTableWindow* pFirstWin = m_aTableMap.begin()->second;
1442 0 : if (pFirstWin->GetListBox())
1443 0 : pFirstWin->GetListBox()->GrabFocus();
1444 : else
1445 0 : pFirstWin->GrabFocus();
1446 : }
1447 0 : }
1448 :
1449 0 : void OJoinTableView::StateChanged( StateChangedType nType )
1450 : {
1451 0 : Window::StateChanged( nType );
1452 :
1453 0 : if ( nType == STATE_CHANGE_ZOOM )
1454 : {
1455 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1456 :
1457 0 : Font aFont = rStyleSettings.GetGroupFont();
1458 0 : if ( IsControlFont() )
1459 0 : aFont.Merge( GetControlFont() );
1460 0 : SetZoomedPointFont( aFont );
1461 :
1462 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
1463 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
1464 0 : for(;aIter != aEnd;++aIter)
1465 : {
1466 0 : aIter->second->SetZoom(GetZoom());
1467 0 : Size aSize(CalcZoom(aIter->second->GetSizePixel().Width()),CalcZoom(aIter->second->GetSizePixel().Height()));
1468 0 : aIter->second->SetSizePixel(aSize);
1469 : }
1470 0 : Resize();
1471 : }
1472 0 : }
1473 :
1474 0 : void OJoinTableView::HideTabWins()
1475 : {
1476 0 : SetUpdateMode(false);
1477 :
1478 0 : OTableWindowMap* pTabWins = GetTabWinMap();
1479 0 : if ( pTabWins )
1480 : {
1481 : // working on a copy because the real list will be cleared in inner calls
1482 0 : OTableWindowMap aCopy(*pTabWins);
1483 0 : OTableWindowMap::iterator aIter = aCopy.begin();
1484 0 : OTableWindowMap::iterator aEnd = aCopy.end();
1485 0 : for(;aIter != aEnd;++aIter)
1486 0 : RemoveTabWin(aIter->second);
1487 : }
1488 :
1489 0 : m_pView->getController().setModified(sal_True);
1490 :
1491 0 : SetUpdateMode(true);
1492 :
1493 0 : }
1494 :
1495 0 : sal_Int8 OJoinTableView::AcceptDrop( const AcceptDropEvent& /*_rEvt*/ )
1496 : {
1497 0 : return DND_ACTION_NONE;
1498 : }
1499 :
1500 0 : sal_Int8 OJoinTableView::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
1501 : {
1502 0 : return DND_ACTION_NONE;
1503 : }
1504 :
1505 0 : void OJoinTableView::dragFinished( )
1506 : {
1507 0 : }
1508 :
1509 0 : void OJoinTableView::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
1510 : {
1511 0 : }
1512 :
1513 0 : void OJoinTableView::clearLayoutInformation()
1514 : {
1515 0 : m_pLastFocusTabWin = NULL;
1516 0 : m_pSelectedConn = NULL;
1517 : // delete lists
1518 0 : OTableWindowMap::iterator aIter = m_aTableMap.begin();
1519 0 : OTableWindowMap::iterator aEnd = m_aTableMap.end();
1520 0 : for(;aIter != aEnd;++aIter)
1521 : {
1522 0 : if ( aIter->second )
1523 0 : aIter->second->clearListBox();
1524 0 : boost::scoped_ptr<Window> aTemp(aIter->second);
1525 0 : aIter->second = NULL;
1526 0 : }
1527 :
1528 0 : m_aTableMap.clear();
1529 :
1530 0 : ::std::vector<OTableConnection*>::const_iterator aIter2 = m_vTableConnection.begin();
1531 0 : ::std::vector<OTableConnection*>::const_iterator aEnd2 = m_vTableConnection.end();
1532 0 : for(;aIter2 != aEnd2;++aIter2)
1533 0 : delete *aIter2;
1534 :
1535 0 : m_vTableConnection.clear();
1536 0 : }
1537 :
1538 0 : void OJoinTableView::lookForUiActivities()
1539 : {
1540 0 : }
1541 :
1542 0 : void OJoinTableView::LoseFocus()
1543 : {
1544 0 : DeselectConn(GetSelectedConn());
1545 0 : Window::LoseFocus();
1546 0 : }
1547 :
1548 0 : void OJoinTableView::GetFocus()
1549 : {
1550 0 : Window::GetFocus();
1551 0 : if ( !m_aTableMap.empty() && !GetSelectedConn() )
1552 0 : GrabTabWinFocus();
1553 0 : }
1554 :
1555 0 : Reference< XAccessible > OJoinTableView::CreateAccessible()
1556 : {
1557 0 : m_pAccessible = new OJoinDesignViewAccess(this);
1558 0 : return m_pAccessible;
1559 : }
1560 :
1561 0 : void OJoinTableView::modified()
1562 : {
1563 0 : OJoinController& rController = m_pView->getController();
1564 0 : rController.setModified( sal_True );
1565 0 : rController.InvalidateFeature(ID_BROWSER_ADDTABLE);
1566 0 : rController.InvalidateFeature(SID_RELATION_ADD_RELATION);
1567 0 : }
1568 :
1569 0 : void OJoinTableView::addConnection(OTableConnection* _pConnection,sal_Bool _bAddData)
1570 : {
1571 0 : if ( _bAddData )
1572 : {
1573 : #if OSL_DEBUG_LEVEL > 0
1574 : TTableConnectionData* pTabConnDataList = m_pView->getController().getTableConnectionData();
1575 : OSL_ENSURE( ::std::find(pTabConnDataList->begin(),pTabConnDataList->end(),_pConnection->GetData()) == pTabConnDataList->end(),"Data already in vector!");
1576 : #endif
1577 0 : m_pView->getController().getTableConnectionData()->push_back(_pConnection->GetData());
1578 : }
1579 0 : m_vTableConnection.push_back(_pConnection);
1580 0 : _pConnection->RecalcLines();
1581 0 : _pConnection->InvalidateConnection();
1582 :
1583 0 : modified();
1584 0 : if ( m_pAccessible )
1585 : m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
1586 : Any(),
1587 0 : makeAny(_pConnection->GetAccessible()));
1588 0 : }
1589 :
1590 0 : bool OJoinTableView::allowQueries() const
1591 : {
1592 0 : return true;
1593 : }
1594 :
1595 0 : void OJoinTableView::onNoColumns_throw()
1596 : {
1597 : OSL_FAIL( "OTableWindow::onNoColumns_throw: cannot really handle this!" );
1598 0 : throw SQLException();
1599 : }
1600 :
1601 0 : bool OJoinTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& ) const
1602 : {
1603 0 : return false;
1604 0 : }
1605 :
1606 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|