xref: /AOO41X/main/dbaccess/source/ui/querydesign/TableWindow.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 #ifndef DBAUI_TABLEWINDOW_HXX
31 #include "TableWindow.hxx"
32 #endif
33 #ifndef DBAUI_TABLEWINDOWLISTBOX_HXX
34 #include "TableWindowListBox.hxx"
35 #endif
36 #ifndef DBAUI_QUERYTABLEVIEW_HXX
37 #include "QueryTableView.hxx"
38 #endif
39 #ifndef DBAUI_QUERYDESIGNVIEW_HXX
40 #include "QueryDesignView.hxx"
41 #endif
42 #ifndef DBAUI_TABLEWINDOWDATA_HXX
43 #include "TableWindowData.hxx"
44 #endif
45 #ifndef DBACCESS_IMAGEPROVIDER_HXX
46 #include "imageprovider.hxx"
47 #endif
48 #ifndef _TOOLS_DEBUG_HXX
49 #include <tools/debug.hxx>
50 #endif
51 #ifndef TOOLS_DIAGNOSE_EX_H
52 #include <tools/diagnose_ex.h>
53 #endif
54 #ifndef _SV_SVAPP_HXX
55 #include <vcl/svapp.hxx>
56 #endif
57 #ifndef _SV_WALL_HXX
58 #include <vcl/wall.hxx>
59 #endif
60 
61 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
62 #include <com/sun/star/container/XNameAccess.hpp>
63 #include <com/sun/star/beans/XPropertySet.hpp>
64 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
65 #include <com/sun/star/accessibility/AccessibleRole.hpp>
66 #include "querycontroller.hxx"
67 #include "dbu_qry.hrc"
68 #include "dbustrings.hrc"
69 #include "Query.hrc"
70 #include <comphelper/extract.hxx>
71 #include "UITools.hxx"
72 #include "TableWindowAccess.hxx"
73 #include "browserids.hxx"
74 #include <connectivity/dbtools.hxx>
75 
76 
77 using namespace dbaui;
78 using namespace ::utl;
79 using namespace ::com::sun::star;
80 using namespace ::com::sun::star::sdb;
81 using namespace ::com::sun::star::sdbc;
82 using namespace ::com::sun::star::sdbcx;
83 using namespace ::com::sun::star::uno;
84 using namespace ::com::sun::star::beans;
85 using namespace ::com::sun::star::container;
86 using namespace ::com::sun::star::lang;
87 using namespace ::com::sun::star::accessibility;
88 
89 #define TABWIN_SIZING_AREA		4
90 #define LISTBOX_SCROLLING_AREA	6
91 #define SCROLLING_TIMESPAN		500
92 
93 #define TABWIN_WIDTH_MIN	90
94 #define TABWIN_HEIGHT_MIN	80
95 
96 //========================================================================
97 // class OTableWindow
98 //========================================================================
99 DBG_NAME(OTableWindow)
100 //------------------------------------------------------------------------------
101 OTableWindow::OTableWindow( Window* pParent, const TTableWindowData::value_type& pTabWinData )
102 		  : ::comphelper::OContainerListener(m_aMutex)
103           ,Window( pParent, WB_3DLOOK|WB_MOVEABLE )
104           ,m_aTypeImage( this )
105 		  ,m_aTitle( this )
106 		  ,m_pListBox(NULL)
107 		  ,m_pAccessible(NULL)
108           ,m_pData( pTabWinData )
109 		  ,m_nMoveCount(0)
110 		  ,m_nMoveIncrement(1)
111           ,m_nSizingFlags( SIZING_NONE )
112 		  ,m_bActive( sal_False )
113 {
114 	DBG_CTOR(OTableWindow,NULL);
115 
116     // Position und Groesse bestimmen
117 	if( GetData()->HasPosition() )
118 		SetPosPixel( GetData()->GetPosition() );
119 
120 	if( GetData()->HasSize() )
121 		SetSizePixel( GetData()->GetSize() );
122 
123 	// Hintergrund setzen
124 	const StyleSettings&  aSystemStyle = Application::GetSettings().GetStyleSettings();
125 	SetBackground(Wallpaper(aSystemStyle.GetFaceColor()));
126 	// und Textfarbe (obwohl ich eigentlich keinen Text habe, aber wer weiss, was
127 	// abgeleitete Klassen machen)
128 	SetTextColor(aSystemStyle.GetButtonTextColor());
129 
130 	EnableClipSiblings();
131 }
132 
133 //------------------------------------------------------------------------------
134 OTableWindow::~OTableWindow()
135 {
136 	DBG_DTOR(OTableWindow,NULL);
137 
138 	if (m_pListBox)
139 	{
140 		OSL_ENSURE(m_pListBox->GetEntryCount()==0,"Forgot to call EmptyListbox()!");
141 		::std::auto_ptr<Window> aTemp(m_pListBox);
142 		m_pListBox = NULL;
143 	} // if (m_pListBox)
144     if ( m_pContainerListener.is() )
145         m_pContainerListener->dispose();
146 
147 	m_pAccessible = NULL;
148 }
149 // -----------------------------------------------------------------------------
150 const OJoinTableView* OTableWindow::getTableView() const
151 {
152 	OSL_ENSURE(static_cast<OJoinTableView*>(GetParent()),"No OJoinTableView!");
153 	return static_cast<OJoinTableView*>(GetParent());
154 }
155 // -----------------------------------------------------------------------------
156 OJoinTableView* OTableWindow::getTableView()
157 {
158 	OSL_ENSURE(static_cast<OJoinTableView*>(GetParent()),"No OJoinTableView!");
159 	return static_cast<OJoinTableView*>(GetParent());
160 }
161 // -----------------------------------------------------------------------------
162 OJoinDesignView* OTableWindow::getDesignView()
163 {
164 	OSL_ENSURE(static_cast<OJoinDesignView*>(GetParent()->GetParent()->GetParent()),"No OJoinDesignView!");
165 	return static_cast<OJoinDesignView*>(GetParent()->GetParent()->GetParent());
166 }
167 //------------------------------------------------------------------------------
168 void OTableWindow::SetPosPixel( const Point& rNewPos )
169 {
170 	Point aNewPosData = rNewPos + getTableView()->GetScrollOffset();
171 	GetData()->SetPosition( aNewPosData );
172 	Window::SetPosPixel( rNewPos );
173 }
174 
175 //------------------------------------------------------------------------------
176 void OTableWindow::SetSizePixel( const Size& rNewSize )
177 {
178 	Size aOutSize(rNewSize);
179 	if( aOutSize.Width() < TABWIN_WIDTH_MIN )
180 		aOutSize.Width() = TABWIN_WIDTH_MIN;
181 	if( aOutSize.Height() < TABWIN_HEIGHT_MIN )
182 		aOutSize.Height() = TABWIN_HEIGHT_MIN;
183 
184 	GetData()->SetSize( aOutSize );
185 	Window::SetSizePixel( aOutSize );
186 }
187 //------------------------------------------------------------------------------
188 void OTableWindow::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
189 {
190 	SetPosPixel( rNewPos );
191 	SetSizePixel( rNewSize );
192 }
193 //------------------------------------------------------------------------------
194 OTableWindowListBox* OTableWindow::CreateListBox()
195 {
196 	return new OTableWindowListBox(this);
197 }
198 
199 //------------------------------------------------------------------------------
200 sal_Bool OTableWindow::FillListBox()
201 {
202     m_pListBox->Clear();
203     if ( !m_pContainerListener.is() )
204     {
205         Reference< XContainer> xContainer(m_pData->getColumns(),UNO_QUERY);
206         if ( xContainer.is() )
207             m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
208     }
209 	// mark all primary keys with special image
210     ModuleRes TmpRes(isHiContrast(m_pListBox) ? IMG_JOINS_H : IMG_JOINS);
211 	ImageList aImageList(TmpRes);
212 	Image aPrimKeyImage = aImageList.GetImage(IMG_PRIMARY_KEY);
213 
214 	if (GetData()->IsShowAll())
215 	{
216 		SvLBoxEntry* pEntry = m_pListBox->InsertEntry( ::rtl::OUString::createFromAscii("*") );
217 		pEntry->SetUserData( createUserData(NULL,false) );
218 	}
219 
220 	Reference<XNameAccess> xPKeyColumns;
221 	try
222 	{
223         xPKeyColumns = dbtools::getPrimaryKeyColumns_throw(m_pData->getTable());
224 	}
225 	catch(Exception&)
226 	{
227 		OSL_ENSURE(0,"Exception occured!");
228 	}
229 	try
230 	{
231         Reference< XNameAccess > xColumns = m_pData->getColumns();
232 		if( xColumns.is() )
233 		{
234 			Sequence< ::rtl::OUString> aColumns = xColumns->getElementNames();
235 			const ::rtl::OUString* pIter = aColumns.getConstArray();
236 			const ::rtl::OUString* pEnd = pIter + aColumns.getLength();
237 
238 			SvLBoxEntry* pEntry = NULL;
239 			for (; pIter != pEnd; ++pIter)
240 			{
241 				bool bPrimaryKeyColumn = xPKeyColumns.is() && xPKeyColumns->hasByName( *pIter );
242 				// is this column in the primary key
243 				if ( bPrimaryKeyColumn )
244 					pEntry = m_pListBox->InsertEntry(*pIter, aPrimKeyImage, aPrimKeyImage);
245 				else
246 					pEntry = m_pListBox->InsertEntry(*pIter);
247 
248                 Reference<XPropertySet> xColumn(xColumns->getByName(*pIter),UNO_QUERY);
249 				if ( xColumn.is() )
250 					pEntry->SetUserData( createUserData(xColumn,bPrimaryKeyColumn) );
251 			}
252 		}
253 	}
254 	catch(Exception&)
255 	{
256 		OSL_ENSURE(0,"Exception occured!");
257 	}
258 
259 	return sal_True;
260 }
261 // -----------------------------------------------------------------------------
262 void* OTableWindow::createUserData(const Reference< XPropertySet>& /*_xColumn*/,bool /*_bPrimaryKey*/)
263 {
264 	return NULL;
265 }
266 // -----------------------------------------------------------------------------
267 void OTableWindow::deleteUserData(void*& _pUserData)
268 {
269 	OSL_ENSURE(!_pUserData,"INVALID call. Need to delete the userclass!");
270 	_pUserData = NULL;
271 }
272 //------------------------------------------------------------------------------
273 void OTableWindow::clearListBox()
274 {
275 	if ( m_pListBox )
276 	{
277 		SvLBoxEntry* pEntry = m_pListBox->First();
278 
279 		while(pEntry)
280 		{
281 			void* pUserData = pEntry->GetUserData();
282 			deleteUserData(pUserData);
283 			SvLBoxEntry* pNextEntry = m_pListBox->Next(pEntry);
284 			m_pListBox->GetModel()->Remove(pEntry);
285 			pEntry = pNextEntry;
286 		}
287 	}
288 }
289 
290 //------------------------------------------------------------------------------
291 void OTableWindow::impl_updateImage()
292 {
293     ImageProvider aImageProvider( getDesignView()->getController().getConnection() );
294 
295     Image aImage, aImageHC;
296     aImageProvider.getImages( GetComposedName(), m_pData->isQuery() ? DatabaseObject::QUERY : DatabaseObject::TABLE, aImage, aImageHC );
297 
298     if ( !aImage || !aImageHC )
299     {
300         OSL_ENSURE( false, "OTableWindow::impl_updateImage: no images!" );
301         return;
302     }
303 
304     m_aTypeImage.SetModeImage( aImage, BMP_COLOR_NORMAL );
305     m_aTypeImage.SetModeImage( aImageHC, BMP_COLOR_HIGHCONTRAST );
306     m_aTypeImage.Show();
307 }
308 
309 //------------------------------------------------------------------------------
310 sal_Bool OTableWindow::Init()
311 {
312 	// create list box if necessary
313 	if ( !m_pListBox )
314 	{
315 		m_pListBox = CreateListBox();
316 		DBG_ASSERT( m_pListBox != NULL, "OTableWindow::Init() : CreateListBox hat NULL geliefert !" );
317 		m_pListBox->SetSelectionMode( MULTIPLE_SELECTION );
318 	}
319 
320 	// Titel setzen
321 	m_aTitle.SetText( m_pData->GetWinName() );
322 	m_aTitle.Show();
323 
324 	m_pListBox->Show();
325 
326 	// die Felder in die ListBox eintragen
327 	clearListBox();
328     sal_Bool bSuccess = FillListBox();
329 	if ( bSuccess )
330 		m_pListBox->SelectAll( sal_False );
331 
332     impl_updateImage();
333 
334 	return bSuccess;
335 }
336 //------------------------------------------------------------------------------
337 void OTableWindow::DataChanged(const DataChangedEvent& rDCEvt)
338 {
339 	if (rDCEvt.GetType() == DATACHANGED_SETTINGS)
340 	{
341 		// nehmen wir den worst-case an : die Farben haben sich geaendert, also
342 		// mich anpassen
343 		const StyleSettings&  aSystemStyle = Application::GetSettings().GetStyleSettings();
344 		SetBackground(Wallpaper(Color(aSystemStyle.GetFaceColor())));
345 		SetTextColor(aSystemStyle.GetButtonTextColor());
346 	}
347 }
348 //------------------------------------------------------------------------------
349 void OTableWindow::Paint( const Rectangle& rRect )
350 {
351 	Rectangle aRect( Point(0,0), GetOutputSizePixel() );
352 	Window::Paint( rRect );
353 	Draw3DBorder( aRect );
354 }
355 
356 //------------------------------------------------------------------------------
357 void OTableWindow::Draw3DBorder(const Rectangle& rRect)
358 {
359 	// die Style-Settings des Systems fuer meine Farben
360 	const StyleSettings& aSystemStyle = Application::GetSettings().GetStyleSettings();
361 
362 	// Schwarze Linie unten und rechts
363 	SetLineColor(aSystemStyle.GetDarkShadowColor());
364 	DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
365 	DrawLine( rRect.BottomRight(), rRect.TopRight() );
366 
367 	// Dunkelgraue Linie ueber der schwarzen
368 	SetLineColor(aSystemStyle.GetShadowColor());
369 	Point aEHvector(1,1);
370 	DrawLine( rRect.BottomLeft()+Point(1,-1), rRect.BottomRight() - aEHvector );
371 	DrawLine( rRect.BottomRight() - aEHvector, rRect.TopRight()+Point(-1,1) );
372 
373 	// Hellgraue Linie links und oben
374 	SetLineColor(aSystemStyle.GetLightColor());
375 	DrawLine( rRect.BottomLeft()+Point(1,-2), rRect.TopLeft() + aEHvector );
376 	DrawLine( rRect.TopLeft() + aEHvector, rRect.TopRight()+Point(-2,1) );
377 }
378 // -----------------------------------------------------------------------------
379 Rectangle OTableWindow::getSizingRect(const Point& _rPos,const Size& _rOutputSize) const
380 {
381 	Rectangle aSizingRect = Rectangle( GetPosPixel(), GetSizePixel() );
382 	sal_uInt16 nSizingFlags = GetSizingFlags();
383 
384 	if( nSizingFlags & SIZING_TOP )
385 	{
386 		if( _rPos.Y() < 0 )
387 			aSizingRect.Top() = 0;
388 		else
389 			aSizingRect.Top() = _rPos.Y();
390 	}
391 
392 	if( nSizingFlags & SIZING_BOTTOM )
393 	{
394 		if( _rPos.Y() > _rOutputSize.Height() )
395 			aSizingRect.Bottom() = _rOutputSize.Height();
396 		else
397 			aSizingRect.Bottom() = _rPos.Y();
398 	}
399 
400 
401 	if( nSizingFlags & SIZING_RIGHT )
402 	{
403 		if( _rPos.X() > _rOutputSize.Width() )
404 			aSizingRect.Right() = _rOutputSize.Width();
405 		else
406 			aSizingRect.Right() = _rPos.X();
407 	}
408 
409 	if( nSizingFlags & SIZING_LEFT )
410 	{
411 		if( _rPos.X() < 0 )
412 			aSizingRect.Left() = 0;
413 		else
414 			aSizingRect.Left() = _rPos.X();
415 	}
416 	return aSizingRect;
417 }
418 // -----------------------------------------------------------------------------
419 void OTableWindow::setSizingFlag(const Point& _rPos)
420 {
421 	Size	aOutSize = GetOutputSizePixel();
422 	//////////////////////////////////////////////////////////////////////
423 	// Flags anpassen, wenn Mauszeiger in sizingArea
424 	m_nSizingFlags = SIZING_NONE;
425 
426 	if( _rPos.X() < TABWIN_SIZING_AREA )
427 		m_nSizingFlags |= SIZING_LEFT;
428 
429 	if( _rPos.Y() < TABWIN_SIZING_AREA )
430 		m_nSizingFlags |= SIZING_TOP;
431 
432 	if( _rPos.X() > aOutSize.Width()-TABWIN_SIZING_AREA )
433 		m_nSizingFlags |= SIZING_RIGHT;
434 
435 	if( _rPos.Y() > aOutSize.Height()-TABWIN_SIZING_AREA )
436 		m_nSizingFlags |= SIZING_BOTTOM;
437 }
438 //------------------------------------------------------------------------------
439 void OTableWindow::MouseMove( const MouseEvent& rEvt )
440 {
441 	Window::MouseMove(rEvt);
442 
443 	OJoinTableView* pCont = getTableView();
444 	if (pCont->getDesignView()->getController().isReadOnly())
445 		return;
446 
447 	Point	aPos = rEvt.GetPosPixel();
448 	setSizingFlag(aPos);
449 	Pointer	aPointer;
450 
451 
452 	//////////////////////////////////////////////////////////////////////
453 	// Mauszeiger anpassen, wenn Mauszeiger in sizingArea
454 	switch( m_nSizingFlags )
455 	{
456 	case SIZING_TOP:
457 	case SIZING_BOTTOM:
458 		aPointer = Pointer( POINTER_SSIZE );
459 		break;
460 
461 	case SIZING_LEFT:
462 	case SIZING_RIGHT:
463 		aPointer = Pointer( POINTER_ESIZE );
464 		break;
465 
466 	case SIZING_LEFT+SIZING_TOP:
467 	case SIZING_RIGHT+SIZING_BOTTOM:
468 		aPointer = Pointer( POINTER_SESIZE );
469 		break;
470 
471 	case SIZING_RIGHT+SIZING_TOP:
472 	case SIZING_LEFT+SIZING_BOTTOM:
473 		aPointer = Pointer( POINTER_NESIZE );
474 		break;
475 	}
476 
477 	SetPointer( aPointer );
478 }
479 
480 //------------------------------------------------------------------------------
481 void OTableWindow::MouseButtonDown( const MouseEvent& rEvt )
482 {
483 	//////////////////////////////////////////////////////////////////////
484 	// Wenn sizing, dann bekommt Parent die Nachricht,
485 	// dass jetzt die Fenstergroesse seines Childs veraendert wird
486 	if( m_nSizingFlags )
487 		getTableView()->BeginChildSizing( this, GetPointer() );
488 
489 	Window::MouseButtonDown( rEvt );
490 }
491 
492 
493 
494 //------------------------------------------------------------------------------
495 void OTableWindow::Resize()
496 {
497 	//////////////////////////////////////////////////////////////////////
498 	// Das Fenster darf nicht verschwinden, deshalb min. Groesse setzen
499 	Size	aOutSize = GetOutputSizePixel();
500 	aOutSize = Size(CalcZoom(aOutSize.Width()),CalcZoom(aOutSize.Height()));
501 
502 	long nTitleHeight = CalcZoom( GetTextHeight() )+ CalcZoom( 4 );
503 
504 	//////////////////////////////////////////////////////////////////////
505 	// Titel und ListBox anpassen
506 	long n5Pos = CalcZoom(5);
507     long nPositionX = n5Pos;
508     long nPositionY = n5Pos;
509 
510     // position the image which indicates the type
511     m_aTypeImage.SetPosPixel( Point( nPositionX, nPositionY ) );
512     Size aImageSize( m_aTypeImage.GetImage().GetSizePixel() );
513     m_aTypeImage.SetSizePixel( aImageSize );
514 
515     if ( nTitleHeight < aImageSize.Height() )
516         nTitleHeight = aImageSize.Height();
517 
518     nPositionX += aImageSize.Width() + CalcZoom( 2 );
519 	m_aTitle.SetPosSizePixel( Point( nPositionX, nPositionY ), Size( aOutSize.Width() - nPositionX - n5Pos, nTitleHeight ) );
520 
521     long nTitleToList = CalcZoom( 3 );
522 
523 	m_pListBox->SetPosSizePixel(
524         Point( n5Pos, nPositionY + nTitleHeight + nTitleToList ),
525         Size( aOutSize.Width() - 2 * n5Pos, aOutSize.Height() - ( nPositionY + nTitleHeight + nTitleToList ) - n5Pos )
526     );
527 
528     Window::Invalidate();
529 }
530 
531 //------------------------------------------------------------------------------
532 void OTableWindow::SetBoldTitle( sal_Bool bBold )
533 {
534 	Font aFont = m_aTitle.GetFont();
535 	aFont.SetWeight( bBold?WEIGHT_BOLD:WEIGHT_NORMAL );
536 	m_aTitle.SetFont( aFont );
537 	m_aTitle.Invalidate();
538 }
539 
540 //------------------------------------------------------------------------------
541 void OTableWindow::GetFocus()
542 {
543 	Window::GetFocus();
544 	// we have to forward the focus to our listbox to enable keystokes
545 	if(m_pListBox)
546 		m_pListBox->GrabFocus();
547 }
548 // -----------------------------------------------------------------------------
549 void OTableWindow::setActive(sal_Bool _bActive)
550 {
551 	SetBoldTitle( _bActive );
552 	m_bActive = _bActive;
553 	if (!_bActive && m_pListBox && m_pListBox->GetSelectionCount() != 0)
554 		m_pListBox->SelectAll(sal_False);
555 }
556 
557 //------------------------------------------------------------------------------
558 void OTableWindow::Remove()
559 {
560 	//////////////////////////////////////////////////////////////////
561 	// Fenster loeschen
562 	OJoinTableView* pTabWinCont = getTableView();
563 	pTabWinCont->RemoveTabWin( this );
564 	pTabWinCont->Invalidate();
565 }
566 //------------------------------------------------------------------------------
567 sal_Bool OTableWindow::HandleKeyInput( const KeyEvent& rEvt )
568 {
569 	const KeyCode& rCode = rEvt.GetKeyCode();
570 	sal_uInt16 nCode = rCode.GetCode();
571 	sal_Bool   bShift = rCode.IsShift();
572 	sal_Bool   bCtrl = rCode.IsMod1();
573 
574 	sal_Bool bHandle = sal_False;
575 
576 	if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
577 	{
578 		Remove();
579 		bHandle = sal_True;
580 	}
581 	return bHandle;
582 }
583 
584 //------------------------------------------------------------------------------
585 sal_Bool OTableWindow::ExistsAConn() const
586 {
587 	return getTableView()->ExistsAConn(this);
588 }
589 //------------------------------------------------------------------------------
590 void OTableWindow::EnumValidFields(::std::vector< ::rtl::OUString>& arrstrFields)
591 {
592 	arrstrFields.clear();
593 	// diese Default-Implementierung zaehlt einfach alles auf, was es in der ListBox gibt ... fuer anderes Verhalten ueberschreiben
594 	if ( m_pListBox )
595 	{
596 		arrstrFields.reserve(m_pListBox->GetEntryCount());
597 		SvLBoxEntry* pEntryLoop = m_pListBox->First();
598 		while (pEntryLoop)
599 		{
600 			arrstrFields.push_back(m_pListBox->GetEntryText(pEntryLoop));
601 			pEntryLoop = m_pListBox->Next(pEntryLoop);
602 		}
603 	}
604 }
605 // -----------------------------------------------------------------------------
606 void OTableWindow::StateChanged( StateChangedType nType )
607 {
608 	Window::StateChanged( nType );
609 
610 	if ( nType == STATE_CHANGE_ZOOM )
611 	{
612 		const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
613 
614 		Font aFont = rStyleSettings.GetGroupFont();
615 		if ( IsControlFont() )
616 			aFont.Merge( GetControlFont() );
617 		SetZoomedPointFont( aFont );
618 
619 		m_aTitle.SetZoom(GetZoom());
620 		m_pListBox->SetZoom(GetZoom());
621 		Resize();
622 		Invalidate();
623 	}
624 }
625 // -----------------------------------------------------------------------------
626 Reference< XAccessible > OTableWindow::CreateAccessible()
627 {
628 	OTableWindowAccess* pAccessible = new OTableWindowAccess(this);
629 	m_pAccessible = pAccessible;
630 	return pAccessible;
631 }
632 // -----------------------------------------------------------------------------
633 void OTableWindow::Command(const CommandEvent& rEvt)
634 {
635 	switch (rEvt.GetCommand())
636 	{
637 		case COMMAND_CONTEXTMENU:
638 		{
639 			OJoinController& rController = getDesignView()->getController();
640 			if(!rController.isReadOnly() && rController.isConnected())
641 			{
642 				Point ptWhere;
643 				if ( rEvt.IsMouseEvent() )
644 					ptWhere = rEvt.GetMousePosPixel();
645 				else
646 				{
647 					SvLBoxEntry* pCurrent = m_pListBox->GetCurEntry();
648 					if ( pCurrent )
649 						ptWhere = m_pListBox->GetEntryPosition(pCurrent);
650 					else
651 						ptWhere = m_aTitle.GetPosPixel();
652 				}
653 
654 				PopupMenu aContextMenu(ModuleRes(RID_MENU_JOINVIEW_TABLE));
655 				switch (aContextMenu.Execute(this, ptWhere))
656 				{
657 					case SID_DELETE:
658 						Remove();
659 						break;
660 				}
661 			}
662 			break;
663 		}
664 		default:
665 			Window::Command(rEvt);
666 	}
667 }
668 // -----------------------------------------------------------------------------
669 long OTableWindow::PreNotify(NotifyEvent& rNEvt)
670 {
671 	sal_Bool bHandled = sal_False;
672 	switch (rNEvt.GetType())
673 	{
674 		case EVENT_KEYINPUT:
675 		{
676 			if ( getDesignView()->getController().isReadOnly() )
677 				break;
678 
679 			const KeyEvent* pKeyEvent =	rNEvt.GetKeyEvent();
680 			const KeyCode& rCode = pKeyEvent->GetKeyCode();
681 			if ( rCode.IsMod1() )
682 			{
683 				Point aStartPoint = GetPosPixel();
684 				if ( rCode.IsShift() )
685 				{
686 					aStartPoint.X() = GetSizePixel().Width();
687 					aStartPoint.Y() = GetSizePixel().Height();
688 				}
689 
690 				switch( rCode.GetCode() )
691 				{
692 					case KEY_DOWN:
693 						bHandled = sal_True;
694 						aStartPoint.Y() += m_nMoveIncrement;
695 						break;
696 					case KEY_UP:
697 						bHandled = sal_True;
698 						aStartPoint.Y() += -m_nMoveIncrement;
699 						break;
700 					case KEY_LEFT:
701 						bHandled = sal_True;
702 						aStartPoint.X() += -m_nMoveIncrement;
703 						break;
704 					case KEY_RIGHT:
705 						bHandled = sal_True;
706 						aStartPoint.X()  += m_nMoveIncrement;
707 						break;
708 				}
709 				if ( bHandled )
710 				{
711 					if ( rCode.IsShift() )
712 					{
713 						OJoinTableView* pView = getTableView();
714 						Point ptOld = GetPosPixel();
715 						Size aSize = pView->getRealOutputSize();
716 						Size aNewSize(aStartPoint.X(),aStartPoint.Y());
717 						if (   ((ptOld.X() + aNewSize.Width())  <= aSize.Width())
718 							&& ((ptOld.Y() + aNewSize.Height()) <= aSize.Height()) )
719 						{
720 							if ( aNewSize.Width() < TABWIN_WIDTH_MIN )
721 								aNewSize.Width() = TABWIN_WIDTH_MIN;
722 							if ( aNewSize.Height() < TABWIN_HEIGHT_MIN )
723 								aNewSize.Height() = TABWIN_HEIGHT_MIN;
724 
725 							Size szOld = GetSizePixel();
726 
727 							aNewSize = Size(pView->CalcZoom(aNewSize.Width()),pView->CalcZoom(aNewSize.Height()));
728 							SetPosSizePixel( ptOld, aNewSize );
729 							pView->TabWinSized(this, ptOld, szOld);
730 							Invalidate( INVALIDATE_NOCHILDREN );
731 						}
732 					}
733 					else
734 					{
735 						// remember how often the user moved our window
736 						++m_nMoveCount;
737 						if( m_nMoveCount == 5 )
738 							m_nMoveIncrement = 10;
739 						else if( m_nMoveCount > 15 )
740 							m_nMoveCount = m_nMoveIncrement = 20;
741 
742 						Point aOldDataPoint = GetData()->GetPosition();
743 						Point aNewDataPoint = aStartPoint + getTableView()->GetScrollOffset();
744 						if ( aNewDataPoint.X() > -1 && aNewDataPoint.Y() > -1 )
745 						{
746 							OJoinTableView* pView = getTableView();
747 							if ( pView->isMovementAllowed(aNewDataPoint, GetData()->GetSize()) )
748 							{
749 								SetPosPixel(aStartPoint);
750 
751 								// aNewDataPoint can not be used here because SetPosPixel reset it
752 								pView->EnsureVisible(GetData()->GetPosition(), GetData()->GetSize());
753 								pView->TabWinMoved(this,aOldDataPoint);
754 								Invalidate(INVALIDATE_NOCHILDREN);
755 								getDesignView()->getController().setModified( sal_True );
756 							}
757 							else
758 							{
759 								m_nMoveCount		= 0; // reset our movement count
760 								m_nMoveIncrement	= 1;
761 							}
762 						}
763 						else
764 						{
765 							m_nMoveCount		= 0; // reset our movement count
766 							m_nMoveIncrement	= 1;
767 						}
768 					}
769 					resetSizingFlag();
770 				}
771 				else
772 				{
773 					m_nMoveCount		= 0; // reset our movement count
774 					m_nMoveIncrement	= 1;
775 				}
776 			}
777 			else
778 			{
779 				m_nMoveCount		= 0; // reset our movement count
780 				m_nMoveIncrement	= 1;
781 			}
782 		}
783 			break;
784 		case EVENT_KEYUP:
785 		{
786 			const KeyEvent* pKeyEvent =	rNEvt.GetKeyEvent();
787 			const KeyCode& rCode = pKeyEvent->GetKeyCode();
788 			sal_uInt16 nKeyCode = rCode.GetCode();
789 			if ( rCode.IsMod2() && nKeyCode != KEY_UP && nKeyCode != KEY_DOWN && nKeyCode != KEY_LEFT && nKeyCode != KEY_RIGHT )
790 			{
791 				m_nMoveCount		= 0; // reset our movement count
792 				m_nMoveIncrement	= 1;
793 			}
794 		}
795 			break;
796 	}
797 	if (!bHandled)
798 		return Window::PreNotify(rNEvt);
799 	return 1L;
800 }
801 // -----------------------------------------------------------------------------
802 String OTableWindow::getTitle() const
803 {
804 	return m_aTitle.GetText();
805 }
806 // -----------------------------------------------------------------------------
807 void OTableWindow::_elementInserted( const container::ContainerEvent& /*_rEvent*/ )  throw(::com::sun::star::uno::RuntimeException)
808 {
809     FillListBox();
810 }
811 // -----------------------------------------------------------------------------
812 void OTableWindow::_elementRemoved( const container::ContainerEvent& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException)
813 {
814     FillListBox();
815 }
816 // -----------------------------------------------------------------------------
817 void OTableWindow::_elementReplaced( const container::ContainerEvent& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException)
818 {
819     FillListBox();
820 }
821 // -----------------------------------------------------------------------------
822 
823