xref: /trunk/main/dbaccess/source/ui/querydesign/TableWindow.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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