summaryrefslogtreecommitdiff
path: root/dbaccess/source/ui/querydesign
diff options
context:
space:
mode:
Diffstat (limited to 'dbaccess/source/ui/querydesign')
-rw-r--r--dbaccess/source/ui/querydesign/ConnectionLine.cxx385
-rw-r--r--dbaccess/source/ui/querydesign/ConnectionLineAccess.cxx251
-rw-r--r--dbaccess/source/ui/querydesign/ConnectionLineData.cxx104
-rw-r--r--dbaccess/source/ui/querydesign/JAccess.cxx131
-rw-r--r--dbaccess/source/ui/querydesign/JoinController.cxx475
-rw-r--r--dbaccess/source/ui/querydesign/JoinDesignView.cxx128
-rw-r--r--dbaccess/source/ui/querydesign/JoinExchange.cxx179
-rw-r--r--dbaccess/source/ui/querydesign/JoinTableView.cxx1717
-rw-r--r--dbaccess/source/ui/querydesign/QTableConnection.cxx99
-rw-r--r--dbaccess/source/ui/querydesign/QTableConnection.hxx59
-rw-r--r--dbaccess/source/ui/querydesign/QTableConnectionData.cxx169
-rw-r--r--dbaccess/source/ui/querydesign/QTableConnectionData.hxx91
-rw-r--r--dbaccess/source/ui/querydesign/QTableWindow.cxx241
-rw-r--r--dbaccess/source/ui/querydesign/QTableWindow.hxx94
-rw-r--r--dbaccess/source/ui/querydesign/QTableWindowData.cxx60
-rw-r--r--dbaccess/source/ui/querydesign/QTableWindowData.hxx55
-rw-r--r--dbaccess/source/ui/querydesign/Query.hrc35
-rw-r--r--dbaccess/source/ui/querydesign/QueryAddTabConnUndoAction.hxx63
-rw-r--r--dbaccess/source/ui/querydesign/QueryDesignFieldUndoAct.hxx161
-rw-r--r--dbaccess/source/ui/querydesign/QueryDesignUndoAction.hxx50
-rw-r--r--dbaccess/source/ui/querydesign/QueryDesignView.cxx3217
-rw-r--r--dbaccess/source/ui/querydesign/QueryMoveTabWinUndoAct.cxx52
-rw-r--r--dbaccess/source/ui/querydesign/QueryMoveTabWinUndoAct.hxx68
-rw-r--r--dbaccess/source/ui/querydesign/QuerySizeTabWinUndoAct.hxx86
-rw-r--r--dbaccess/source/ui/querydesign/QueryTabConnUndoAction.cxx139
-rw-r--r--dbaccess/source/ui/querydesign/QueryTabConnUndoAction.hxx59
-rw-r--r--dbaccess/source/ui/querydesign/QueryTabWinShowUndoAct.hxx66
-rw-r--r--dbaccess/source/ui/querydesign/QueryTabWinUndoAct.cxx137
-rw-r--r--dbaccess/source/ui/querydesign/QueryTabWinUndoAct.hxx87
-rw-r--r--dbaccess/source/ui/querydesign/QueryTableView.cxx1035
-rw-r--r--dbaccess/source/ui/querydesign/QueryTextView.cxx153
-rw-r--r--dbaccess/source/ui/querydesign/QueryViewSwitch.cxx344
-rw-r--r--dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx2834
-rw-r--r--dbaccess/source/ui/querydesign/SelectionBrowseBox.hxx347
-rw-r--r--dbaccess/source/ui/querydesign/TableConnection.cxx246
-rw-r--r--dbaccess/source/ui/querydesign/TableConnectionData.cxx198
-rw-r--r--dbaccess/source/ui/querydesign/TableFieldDescription.cxx242
-rw-r--r--dbaccess/source/ui/querydesign/TableFieldInfo.cxx57
-rw-r--r--dbaccess/source/ui/querydesign/TableFieldInfo.hxx55
-rw-r--r--dbaccess/source/ui/querydesign/TableWindow.cxx803
-rw-r--r--dbaccess/source/ui/querydesign/TableWindowAccess.cxx294
-rw-r--r--dbaccess/source/ui/querydesign/TableWindowData.cxx156
-rw-r--r--dbaccess/source/ui/querydesign/TableWindowListBox.cxx402
-rw-r--r--dbaccess/source/ui/querydesign/TableWindowTitle.cxx210
-rw-r--r--dbaccess/source/ui/querydesign/class.jpgbin0 -> 224242 bytes
-rw-r--r--dbaccess/source/ui/querydesign/makefile.mk89
-rw-r--r--dbaccess/source/ui/querydesign/query.src426
-rw-r--r--dbaccess/source/ui/querydesign/querycontainerwindow.cxx265
-rw-r--r--dbaccess/source/ui/querydesign/querycontroller.cxx1868
-rw-r--r--dbaccess/source/ui/querydesign/querydlg.cxx375
-rw-r--r--dbaccess/source/ui/querydesign/querydlg.hrc61
-rw-r--r--dbaccess/source/ui/querydesign/querydlg.hxx108
-rw-r--r--dbaccess/source/ui/querydesign/querydlg.src195
-rw-r--r--dbaccess/source/ui/querydesign/queryview.cxx58
54 files changed, 19279 insertions, 0 deletions
diff --git a/dbaccess/source/ui/querydesign/ConnectionLine.cxx b/dbaccess/source/ui/querydesign/ConnectionLine.cxx
new file mode 100644
index 000000000000..91d67b82108c
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/ConnectionLine.cxx
@@ -0,0 +1,385 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "ConnectionLine.hxx"
+#include "ConnectionLineData.hxx"
+#include "TableWindow.hxx"
+#include "TableWindowListBox.hxx"
+#include "TableConnection.hxx"
+#include <vcl/svapp.hxx>
+#ifndef _INC_MATH
+#include <math.h>
+#endif
+#include <osl/diagnose.h>
+#include <vcl/lineinfo.hxx>
+
+
+using namespace dbaui;
+const long DESCRIPT_LINE_WIDTH = 15;
+const long HIT_SENSITIVE_RADIUS = 5;
+
+namespace
+{
+ /** calcRect creates a new rectangle with the given points
+ @param _rBase the base point
+ @param _aVector the vector which will be added
+ */
+ inline Rectangle calcRect(const Point& _rBase,const Point& _aVector)
+ {
+ return Rectangle( _rBase - _aVector, _rBase + _aVector );
+ }
+ // -----------------------------------------------------------------------------
+ /** GetTextPos calculate the rectangle for the connection to be drawn
+ @param _pWin the table window where to draw it
+ @param _aConnPos the connection point
+ @param _aDescrLinePos the description line pos
+ */
+ Rectangle GetTextPos(const OTableWindow* _pWin, const Point& _aConnPos,const Point& _aDescrLinePos)
+ {
+ OTableWindowListBox* pListBox = _pWin ? _pWin->GetListBox() : NULL;
+ OSL_ENSURE(_pWin && pListBox, "OConnectionLine::GetSourceTextPos : invalid call !");
+
+ Rectangle aReturn;
+ if ( pListBox )
+ {
+ const long nRowHeight = pListBox->GetEntryHeight();
+ aReturn.Top() = _aConnPos.Y() - nRowHeight;
+ aReturn.Bottom() = aReturn.Top() + nRowHeight;
+ if (_aDescrLinePos.X() < _aConnPos.X())
+ {
+ aReturn.Left() = _aDescrLinePos.X();
+ aReturn.Right() = aReturn.Left() + _aConnPos.X() - _aDescrLinePos.X();
+ }
+ else
+ {
+ aReturn.Left() = _aConnPos.X();
+ aReturn.Right() = aReturn.Left() + _aDescrLinePos.X() - _aConnPos.X();
+ }
+ }
+
+ return aReturn;
+ }
+ // -----------------------------------------------------------------------------
+ /** calcPointsYValue calculate the points Y value in relation to the listbox entry
+ @param _pWin the corresponding window
+ @param _pEntry the source or dest entry
+ @param _rNewConPos (in/out) the connection pos
+ @param _rNewDescrPos (in/out) the description pos
+ */
+ void calcPointsYValue(const OTableWindow* _pWin,SvLBoxEntry* _pEntry,Point& _rNewConPos,Point& _rNewDescrPos)
+ {
+ const OTableWindowListBox* pListBox = _pWin->GetListBox();
+ _rNewConPos.Y() = _pWin->GetPosPixel().Y();
+ if ( _pEntry )
+ {
+ const long nRowHeight = pListBox->GetEntryHeight();
+ _rNewConPos.Y() += pListBox->GetPosPixel().Y();
+ long nEntryPos = pListBox->GetEntryPosition( _pEntry ).Y();
+
+ if( nEntryPos >= 0 )
+ {
+ _rNewConPos.Y() += nEntryPos;
+ _rNewConPos.Y() += (long)( 0.5 * nRowHeight );
+ }
+ else
+ _rNewConPos.Y() -= (long)( 0.5 * nRowHeight );
+
+ long nListBoxBottom = _pWin->GetPosPixel().Y()
+ + pListBox->GetPosPixel().Y()
+ + pListBox->GetSizePixel().Height();
+ if( _rNewConPos.Y() > nListBoxBottom )
+ _rNewConPos.Y() = nListBoxBottom + 2;
+ }
+ else
+ _rNewConPos.Y() += static_cast<sal_Int32>(pListBox->GetPosPixel().Y()*0.5);
+
+ _rNewDescrPos.Y() = _rNewConPos.Y();
+ }
+ // -----------------------------------------------------------------------------
+}
+
+//========================================================================
+// class OConnectionLine
+//========================================================================
+DBG_NAME(OConnectionLine)
+//------------------------------------------------------------------------
+OConnectionLine::OConnectionLine( OTableConnection* _pConn, OConnectionLineDataRef _pLineData )
+ : m_pTabConn( _pConn )
+ ,m_pData( _pLineData )
+{
+ DBG_CTOR(OConnectionLine,NULL);
+}
+
+//------------------------------------------------------------------------
+OConnectionLine::OConnectionLine( const OConnectionLine& _rLine )
+{
+ DBG_CTOR(OConnectionLine,NULL);
+ m_pData = new OConnectionLineData( *_rLine.GetData() );
+ *this = _rLine;
+}
+
+//------------------------------------------------------------------------
+OConnectionLine::~OConnectionLine()
+{
+ DBG_DTOR(OConnectionLine,NULL);
+}
+
+//------------------------------------------------------------------------
+OConnectionLine& OConnectionLine::operator=( const OConnectionLine& rLine )
+{
+ if( &rLine != this )
+ {
+ // da mir die Daten nicht gehoeren, loesche ich die alten nicht
+ m_pData->CopyFrom(*rLine.GetData());
+ // CopyFrom ist virtuell, damit ist es kein Problem, wenn m_pData von einem von OTableConnectionData abgeleiteten Typ ist
+
+ m_pTabConn = rLine.m_pTabConn;
+ m_aSourceConnPos = rLine.m_aSourceConnPos;
+ m_aDestConnPos = rLine.m_aDestConnPos;
+ m_aSourceDescrLinePos = rLine.m_aSourceDescrLinePos;
+ m_aDestDescrLinePos = rLine.m_aDestDescrLinePos;
+ }
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+Rectangle OConnectionLine::GetBoundingRect()
+{
+ //////////////////////////////////////////////////////////////////////
+ // Umgebendes Rechteck bestimmen
+ Rectangle aBoundingRect( Point(0,0), Point(0,0) );
+ if( !IsValid() )
+ return aBoundingRect;
+
+ Point aTopLeft;
+ Point aBottomRight;
+
+ if( m_aSourceDescrLinePos.Y() <= m_aDestDescrLinePos.Y() )
+ {
+ aTopLeft.Y() = m_aSourceDescrLinePos.Y();
+ aBottomRight.Y() = m_aDestDescrLinePos.Y();
+ }
+ else
+ {
+ aTopLeft.Y() = m_aDestDescrLinePos.Y();
+ aBottomRight.Y() = m_aSourceDescrLinePos.Y();
+ }
+
+ if( m_aSourceDescrLinePos.X() <= m_aDestDescrLinePos.X() )
+ {
+ aTopLeft.X() = m_aSourceDescrLinePos.X();
+ aBottomRight.X() = m_aDestDescrLinePos.X();
+ }
+ else
+ {
+ aTopLeft.X() = m_aDestDescrLinePos.X();
+ aBottomRight.X() = m_aSourceDescrLinePos.X();
+ }
+
+ const OTableWindow* pSourceWin = m_pTabConn->GetSourceWin();
+ const OTableWindow* pDestWin = m_pTabConn->GetDestWin();
+ //////////////////////////////////////////////////////////////////////
+ // Linie verlaeuft in z-Form
+ if( pSourceWin == pDestWin || Abs(m_aSourceConnPos.X() - m_aDestConnPos.X()) > Abs(m_aSourceDescrLinePos.X() - m_aDestDescrLinePos.X()) )
+ {
+ aTopLeft.X() -= DESCRIPT_LINE_WIDTH;
+ aBottomRight.X() += DESCRIPT_LINE_WIDTH;
+ }
+
+ aBoundingRect = Rectangle( aTopLeft-Point(2,17), aBottomRight+Point(2,2) );
+
+ return aBoundingRect;
+}
+// -----------------------------------------------------------------------------
+void calcPointX1(const OTableWindow* _pWin,Point& _rNewConPos,Point& _rNewDescrPos)
+{
+ _rNewConPos.X() = _pWin->GetPosPixel().X() + _pWin->GetSizePixel().Width();
+ _rNewDescrPos.X() = _rNewConPos.X();
+ _rNewConPos.X() += DESCRIPT_LINE_WIDTH;
+}
+// -----------------------------------------------------------------------------
+void calcPointX2(const OTableWindow* _pWin,Point& _rNewConPos,Point& _rNewDescrPos)
+{
+ _rNewConPos.X() = _pWin->GetPosPixel().X();
+ _rNewDescrPos.X() = _rNewConPos.X();
+ _rNewConPos.X() -= DESCRIPT_LINE_WIDTH;
+}
+//------------------------------------------------------------------------
+sal_Bool OConnectionLine::RecalcLine()
+{
+ //////////////////////////////////////////////////////////////////////
+ // Fenster und Entries muessen gesetzt sein
+ const OTableWindow* pSourceWin = m_pTabConn->GetSourceWin();
+ const OTableWindow* pDestWin = m_pTabConn->GetDestWin();
+
+ if( !pSourceWin || !pDestWin )
+ return sal_False;
+
+ SvLBoxEntry* pSourceEntry = pSourceWin->GetListBox()->GetEntryFromText( GetData()->GetSourceFieldName() );
+ SvLBoxEntry* pDestEntry = pDestWin->GetListBox()->GetEntryFromText( GetData()->GetDestFieldName() );
+
+ //////////////////////////////////////////////////////////////////////
+ // X-Koordinaten bestimmen
+ Point aSourceCenter( 0, 0 );
+ Point aDestCenter( 0, 0 );
+
+ aSourceCenter.X() = pSourceWin->GetPosPixel().X() + (long)( 0.5*pSourceWin->GetSizePixel().Width() );
+ aDestCenter.X() = pDestWin->GetPosPixel().X() + (long)( 0.5*pDestWin->GetSizePixel().Width() );
+
+ const OTableWindow* pFirstWin = pDestWin;
+ const OTableWindow* pSecondWin = pSourceWin;
+ Point* pFirstConPos = &m_aDestConnPos;
+ Point* pFirstDescrPos = &m_aDestDescrLinePos;
+ Point* pSecondConPos = &m_aSourceConnPos;
+ Point* pSecondDescrPos = &m_aSourceDescrLinePos;
+ if( aDestCenter.X() > aSourceCenter.X() )
+ {
+ pFirstWin = pSourceWin;
+ pSecondWin = pDestWin;
+ pFirstConPos = &m_aSourceConnPos;
+ pFirstDescrPos = &m_aSourceDescrLinePos;
+ pSecondConPos = &m_aDestConnPos;
+ pSecondDescrPos = &m_aDestDescrLinePos;
+ }
+
+ if ( pFirstWin == pSecondWin && pSourceEntry != pDestEntry )
+ calcPointX2(pFirstWin,*pFirstConPos,*pFirstDescrPos);
+ else
+ calcPointX1(pFirstWin,*pFirstConPos,*pFirstDescrPos);
+ calcPointX2(pSecondWin,*pSecondConPos,*pSecondDescrPos);
+
+ //////////////////////////////////////////////////////////////////////
+ // aSourceConnPosY bestimmen
+ calcPointsYValue(pSourceWin,pSourceEntry,m_aSourceConnPos,m_aSourceDescrLinePos);
+
+ //////////////////////////////////////////////////////////////////////
+ // aDestConnPosY bestimmen
+ calcPointsYValue(pDestWin,pDestEntry,m_aDestConnPos,m_aDestDescrLinePos);
+
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------
+void OConnectionLine::Draw( OutputDevice* pOutDev )
+{
+ const sal_uInt16 nRectSize = 3;
+
+ //////////////////////////////////////////////////////////////////////
+ // Neue Dimensionen berechnen
+ if( !RecalcLine() )
+ return;
+
+ //////////////////////////////////////////////////////////////////////
+ // Zeichnen der Linien
+ if (m_pTabConn->IsSelected())
+ pOutDev->SetLineColor(Application::GetSettings().GetStyleSettings().GetHighlightColor());
+ else
+ pOutDev->SetLineColor(Application::GetSettings().GetStyleSettings().GetWindowTextColor());
+
+ LineInfo aLineInfo;
+ if ( m_pTabConn->IsSelected() )
+ aLineInfo.SetWidth(3);
+ Polygon aPoly;
+ aPoly.Insert(0,m_aSourceDescrLinePos);
+ aPoly.Insert(1,m_aSourceConnPos);
+ aPoly.Insert(2,m_aDestConnPos);
+ aPoly.Insert(3,m_aDestDescrLinePos);
+ pOutDev->DrawPolyLine(aPoly,aLineInfo);
+
+ //////////////////////////////////////////////////////////////////////
+ // draw the connection rectangles
+ pOutDev->SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
+
+ Point aVector(nRectSize,nRectSize);
+ pOutDev->DrawRect( calcRect(m_aSourceDescrLinePos,aVector) );
+ pOutDev->DrawRect( calcRect( m_aDestDescrLinePos,aVector) );
+}
+// -----------------------------------------------------------------------------
+sal_Bool OConnectionLine::IsValid() const
+{
+ return m_pData.is();
+}
+//------------------------------------------------------------------------
+double dist_Euklid(const Point &p1, const Point& p2,const Point& pM, Point& q)
+{
+ Point v(p2 - p1);
+ Point w(pM - p1);
+ double a = sqrt((double)(v.X()*v.X() + v.Y()*v.Y()));
+ double l = (v.X() * w.Y() - v.Y() * w.X()) / a;
+ double a2 = w.X()*v.X()+w.Y()*v.Y();
+ a = a2 / (a * a);
+ q.X() = long(p1.X() + a * v.X());
+ q.Y() = long(p1.Y() + a * v.Y());
+ return l;
+}
+//------------------------------------------------------------------------
+bool OConnectionLine::CheckHit( const Point& rMousePos ) const
+{
+ //////////////////////////////////////////////////////////////////////
+ /*
+ Vorgehensweise beim HitTest:
+ Es wird der Abstand nach Euklid berechnet.
+ */
+ Point q;
+ double l = fabs(dist_Euklid(m_aSourceConnPos,m_aDestConnPos,rMousePos,q));
+ if( l < HIT_SENSITIVE_RADIUS)
+ {
+ if(::std::min(m_aSourceConnPos.X(),m_aDestConnPos.X()) <= q.X() && ::std::min(m_aSourceConnPos.Y(),m_aDestConnPos.Y()) <= q.Y()
+ && q.X() <= ::std::max(m_aDestConnPos.X(),m_aSourceConnPos.X()) && q.Y() <= ::std::max(m_aDestConnPos.Y(),m_aSourceConnPos.Y()))
+ return true;
+ }
+
+ return false;
+}
+// -----------------------------------------------------------------------------
+Rectangle OConnectionLine::GetSourceTextPos() const
+{
+ return GetTextPos(m_pTabConn->GetSourceWin(),m_aSourceConnPos,m_aSourceDescrLinePos);
+}
+// -----------------------------------------------------------------------------
+Rectangle OConnectionLine::GetDestTextPos() const
+{
+ return GetTextPos(m_pTabConn->GetDestWin(),m_aDestConnPos,m_aDestDescrLinePos);
+}
+// -----------------------------------------------------------------------------
+Point OConnectionLine::getMidPoint() const
+{
+ Point aDest = m_aDestConnPos - m_aSourceConnPos;
+ aDest.X() /= 2;
+ aDest.Y() /= 2;
+
+ return m_aSourceConnPos + aDest;
+}
+// -----------------------------------------------------------------------------
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/ConnectionLineAccess.cxx b/dbaccess/source/ui/querydesign/ConnectionLineAccess.cxx
new file mode 100644
index 000000000000..a1297dfc68b0
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/ConnectionLineAccess.cxx
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "ConnectionLineAccess.hxx"
+#include "JoinTableView.hxx"
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#include <toolkit/awt/vclxwindow.hxx>
+#include "TableConnection.hxx"
+#include "TableWindow.hxx"
+#include <comphelper/uno3.hxx>
+#include "JoinDesignView.hxx"
+#include "JoinController.hxx"
+#include <comphelper/sequence.hxx>
+
+namespace dbaui
+{
+ using namespace ::com::sun::star::accessibility;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star;
+
+ OConnectionLineAccess::OConnectionLineAccess(OTableConnection* _pLine)
+ : VCLXAccessibleComponent(_pLine->GetComponentInterface().is() ? _pLine->GetWindowPeer() : NULL)
+ ,m_pLine(_pLine)
+ {
+ }
+ // -----------------------------------------------------------------------------
+ void SAL_CALL OConnectionLineAccess::disposing()
+ {
+ m_pLine = NULL;
+ VCLXAccessibleComponent::disposing();
+ }
+ // -----------------------------------------------------------------------------
+ Any SAL_CALL OConnectionLineAccess::queryInterface( const Type& aType ) throw (RuntimeException)
+ {
+ Any aRet(VCLXAccessibleComponent::queryInterface( aType ));
+ return aRet.hasValue() ? aRet : OConnectionLineAccess_BASE::queryInterface( aType );
+ }
+ // -----------------------------------------------------------------------------
+ Sequence< Type > SAL_CALL OConnectionLineAccess::getTypes( ) throw (RuntimeException)
+ {
+ return ::comphelper::concatSequences(VCLXAccessibleComponent::getTypes(),OConnectionLineAccess_BASE::getTypes());
+ }
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OConnectionLineAccess::getImplementationName() throw(RuntimeException)
+ {
+ return getImplementationName_Static();
+ }
+ // -----------------------------------------------------------------------------
+ // XServiceInfo - static methods
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString OConnectionLineAccess::getImplementationName_Static(void) throw( RuntimeException )
+ {
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.ConnectionLineAccessibility"));
+ }
+ // -----------------------------------------------------------------------------
+ // XAccessibleContext
+ sal_Int32 SAL_CALL OConnectionLineAccess::getAccessibleChildCount( ) throw (RuntimeException)
+ {
+ return 0;
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessible > SAL_CALL OConnectionLineAccess::getAccessibleChild( sal_Int32 /*i*/ ) throw (RuntimeException)
+ {
+ return Reference< XAccessible >();
+ }
+ // -----------------------------------------------------------------------------
+ sal_Int32 SAL_CALL OConnectionLineAccess::getAccessibleIndexInParent( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ sal_Int32 nIndex = -1;
+ if( m_pLine )
+ {
+ // search the postion of our table window in the table window map
+ nIndex = m_pLine->GetParent()->GetTabWinMap()->size();
+ const ::std::vector<OTableConnection*>* pVec = m_pLine->GetParent()->getTableConnections();
+ ::std::vector<OTableConnection*>::const_iterator aIter = pVec->begin();
+ ::std::vector<OTableConnection*>::const_iterator aEnd = pVec->end();
+ for (; aIter != aEnd && (*aIter) != m_pLine; ++nIndex,++aIter)
+ ;
+ nIndex = ( aIter != aEnd ) ? nIndex : -1;
+ }
+ return nIndex;
+ }
+ // -----------------------------------------------------------------------------
+ sal_Int16 SAL_CALL OConnectionLineAccess::getAccessibleRole( ) throw (RuntimeException)
+ {
+ return AccessibleRole::UNKNOWN; // ? or may be an AccessibleRole::WINDOW
+ }
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OConnectionLineAccess::getAccessibleDescription( ) throw (RuntimeException)
+ {
+ static ::rtl::OUString sDescription(RTL_CONSTASCII_USTRINGPARAM("Relation"));
+ return sDescription;
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessibleRelationSet > SAL_CALL OConnectionLineAccess::getAccessibleRelationSet( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return this;
+ }
+ // -----------------------------------------------------------------------------
+ // XAccessibleComponent
+ sal_Bool SAL_CALL OConnectionLineAccess::contains( const awt::Point& _aPoint ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ Point aPoint(_aPoint.X,_aPoint.Y);
+ return m_pLine ? m_pLine->CheckHit(aPoint) : sal_False;
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessible > SAL_CALL OConnectionLineAccess::getAccessibleAtPoint( const awt::Point& /*_aPoint*/ ) throw (RuntimeException)
+ {
+ return Reference< XAccessible >();
+ }
+ // -----------------------------------------------------------------------------
+ awt::Rectangle SAL_CALL OConnectionLineAccess::getBounds( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ Rectangle aRect(m_pLine ? m_pLine->GetBoundingRect() : Rectangle());
+ return awt::Rectangle(aRect.getX(),aRect.getY(),aRect.getWidth(),aRect.getHeight());
+ }
+ // -----------------------------------------------------------------------------
+ awt::Point SAL_CALL OConnectionLineAccess::getLocation( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ Point aPoint(m_pLine ? m_pLine->GetBoundingRect().TopLeft() : Point());
+ return awt::Point(aPoint.X(),aPoint.Y());
+ }
+ // -----------------------------------------------------------------------------
+ awt::Point SAL_CALL OConnectionLineAccess::getLocationOnScreen( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ Point aPoint(m_pLine ? m_pLine->GetParent()->ScreenToOutputPixel(m_pLine->GetBoundingRect().TopLeft()) : Point());
+ return awt::Point(aPoint.X(),aPoint.Y());
+ }
+ // -----------------------------------------------------------------------------
+ awt::Size SAL_CALL OConnectionLineAccess::getSize( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ Size aSize(m_pLine ? m_pLine->GetBoundingRect().GetSize() : Size());
+ return awt::Size(aSize.Width(),aSize.Height());
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool SAL_CALL OConnectionLineAccess::isShowing( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return m_pLine ? m_pLine->GetParent()->GetWindowRegionPixel().IsInside(m_pLine->GetBoundingRect()) : sal_False;
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool SAL_CALL OConnectionLineAccess::isVisible( ) throw (RuntimeException)
+ {
+ return sal_True;
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool SAL_CALL OConnectionLineAccess::isFocusTraversable( ) throw (RuntimeException)
+ {
+ return sal_True;
+ }
+ // -----------------------------------------------------------------------------
+ // XAccessibleRelationSet
+ // -----------------------------------------------------------------------------
+ sal_Int32 SAL_CALL OConnectionLineAccess::getRelationCount( ) throw (RuntimeException)
+ {
+ return 1;
+ }
+ // -----------------------------------------------------------------------------
+ AccessibleRelation SAL_CALL OConnectionLineAccess::getRelation( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if( nIndex < 0 || nIndex >= getRelationCount() )
+ throw IndexOutOfBoundsException();
+
+ Sequence< Reference<XInterface> > aSeq(m_pLine ? 2 : 0);
+ if( m_pLine )
+ {
+ aSeq[0] = m_pLine->GetSourceWin()->GetAccessible();
+ aSeq[1] = m_pLine->GetDestWin()->GetAccessible();
+ }
+
+ return AccessibleRelation(AccessibleRelationType::CONTROLLED_BY,aSeq);
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool SAL_CALL OConnectionLineAccess::containsRelation( sal_Int16 aRelationType ) throw (RuntimeException)
+ {
+ return AccessibleRelationType::CONTROLLED_BY == aRelationType;
+ }
+ // -----------------------------------------------------------------------------
+ AccessibleRelation SAL_CALL OConnectionLineAccess::getRelationByType( sal_Int16 aRelationType ) throw (RuntimeException)
+ {
+ if( AccessibleRelationType::CONTROLLED_BY == aRelationType )
+ return getRelation(0);
+ return AccessibleRelation();
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessible > OTableConnection::CreateAccessible()
+ {
+ return new OConnectionLineAccess(this);
+ }
+ // -----------------------------------------------------------------------------
+ OTableConnection::~OTableConnection()
+ {
+ DBG_DTOR(OTableConnection,NULL);
+ //////////////////////////////////////////////////////////////////////
+ // clear vector
+ clearLineData();
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool OConnectionLineAccess::isEditable() const
+ {
+
+ return m_pLine ? !m_pLine->GetParent()->getDesignView()->getController().isReadOnly() : sal_False;
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessibleContext > SAL_CALL OConnectionLineAccess::getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ return this;
+ }
+ // -----------------------------------------------------------------------------
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/ConnectionLineData.cxx b/dbaccess/source/ui/querydesign/ConnectionLineData.cxx
new file mode 100644
index 000000000000..49360b0959b5
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/ConnectionLineData.cxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "ConnectionLineData.hxx"
+#include <tools/debug.hxx>
+
+
+using namespace dbaui;
+DBG_NAME(OConnectionLineData)
+//==================================================================
+//class OConnectionLineData
+//==================================================================
+//------------------------------------------------------------------------
+OConnectionLineData::OConnectionLineData()
+{
+ DBG_CTOR(OConnectionLineData,NULL);
+}
+
+//------------------------------------------------------------------------
+OConnectionLineData::OConnectionLineData( const ::rtl::OUString& rSourceFieldName, const ::rtl::OUString& rDestFieldName )
+ :m_aSourceFieldName( rSourceFieldName )
+ ,m_aDestFieldName( rDestFieldName )
+{
+ DBG_CTOR(OConnectionLineData,NULL);
+}
+
+//------------------------------------------------------------------------
+OConnectionLineData::OConnectionLineData( const OConnectionLineData& rConnLineData )
+ : ::salhelper::SimpleReferenceObject()
+{
+ DBG_CTOR(OConnectionLineData,NULL);
+ *this = rConnLineData;
+}
+
+//------------------------------------------------------------------------
+OConnectionLineData::~OConnectionLineData()
+{
+ DBG_DTOR(OConnectionLineData,NULL);
+}
+
+//------------------------------------------------------------------------
+void OConnectionLineData::CopyFrom(const OConnectionLineData& rSource)
+{
+ *this = rSource;
+ // hier ziehe ich mich auf das (nicht-virtuelle) operator= zurueck, das nur meine Members kopiert
+}
+
+//------------------------------------------------------------------------
+OConnectionLineData& OConnectionLineData::operator=( const OConnectionLineData& rConnLineData )
+{
+ if (&rConnLineData == this)
+ return *this;
+
+ m_aSourceFieldName = rConnLineData.GetSourceFieldName();
+ m_aDestFieldName = rConnLineData.GetDestFieldName();
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+bool OConnectionLineData::Reset()
+{
+ m_aDestFieldName = m_aSourceFieldName = ::rtl::OUString();
+ return true;
+}
+// -----------------------------------------------------------------------------
+namespace dbaui
+{
+//-------------------------------------------------------------------------
+bool operator==(const OConnectionLineData& lhs, const OConnectionLineData& rhs)
+{
+ return (lhs.m_aSourceFieldName == rhs.m_aSourceFieldName)
+ && (lhs.m_aDestFieldName == rhs.m_aDestFieldName);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/JAccess.cxx b/dbaccess/source/ui/querydesign/JAccess.cxx
new file mode 100644
index 000000000000..90feae92b25d
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/JAccess.cxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "JAccess.hxx"
+#include "JoinTableView.hxx"
+#include "JoinTableView.hxx"
+#include "TableWindow.hxx"
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include "JoinDesignView.hxx"
+#include "JoinController.hxx"
+#include "TableConnection.hxx"
+
+namespace dbaui
+{
+ using namespace ::com::sun::star::accessibility;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+
+ OJoinDesignViewAccess::OJoinDesignViewAccess(OJoinTableView* _pTableView)
+ :VCLXAccessibleComponent(_pTableView->GetComponentInterface().is() ? _pTableView->GetWindowPeer() : NULL)
+ ,m_pTableView(_pTableView)
+ {
+ }
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OJoinDesignViewAccess::getImplementationName() throw(RuntimeException)
+ {
+ return getImplementationName_Static();
+ }
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString OJoinDesignViewAccess::getImplementationName_Static(void) throw( RuntimeException )
+ {
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.JoinViewAccessibility"));
+ }
+ // -----------------------------------------------------------------------------
+ void OJoinDesignViewAccess::clearTableView()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_pTableView = NULL;
+ }
+ // -----------------------------------------------------------------------------
+ // XAccessibleContext
+ sal_Int32 SAL_CALL OJoinDesignViewAccess::getAccessibleChildCount( ) throw (RuntimeException)
+ {
+ // TODO may be this will change to only visible windows
+ // this is the same assumption mt implements
+ ::osl::MutexGuard aGuard( m_aMutex );
+ sal_Int32 nChildCount = 0;
+ if ( m_pTableView )
+ nChildCount = m_pTableView->GetTabWinCount() + m_pTableView->getTableConnections()->size();
+ return nChildCount;
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessible > SAL_CALL OJoinDesignViewAccess::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException)
+ {
+ Reference< XAccessible > aRet;
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if(i >= 0 && i < getAccessibleChildCount() && m_pTableView )
+ {
+ // check if we should return a table window or a connection
+ sal_Int32 nTableWindowCount = m_pTableView->GetTabWinCount();
+ if( i < nTableWindowCount )
+ {
+ OJoinTableView::OTableWindowMap::iterator aIter = m_pTableView->GetTabWinMap()->begin();
+ for (sal_Int32 j=i; j; ++aIter,--j)
+ ;
+ aRet = aIter->second->GetAccessible();
+ }
+ else if( size_t(i - nTableWindowCount) < m_pTableView->getTableConnections()->size() )
+ aRet = (*m_pTableView->getTableConnections())[i - nTableWindowCount]->GetAccessible();
+ }
+ else
+ throw IndexOutOfBoundsException();
+ return aRet;
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool OJoinDesignViewAccess::isEditable() const
+ {
+ return m_pTableView && !m_pTableView->getDesignView()->getController().isReadOnly();
+ }
+ // -----------------------------------------------------------------------------
+ sal_Int16 SAL_CALL OJoinDesignViewAccess::getAccessibleRole( ) throw (RuntimeException)
+ {
+ return AccessibleRole::VIEW_PORT;
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessibleContext > SAL_CALL OJoinDesignViewAccess::getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ return this;
+ }
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+ // XInterface
+ // -----------------------------------------------------------------------------
+ IMPLEMENT_FORWARD_XINTERFACE2( OJoinDesignViewAccess, VCLXAccessibleComponent, OJoinDesignViewAccess_BASE )
+ // -----------------------------------------------------------------------------
+ // XTypeProvider
+ // -----------------------------------------------------------------------------
+ IMPLEMENT_FORWARD_XTYPEPROVIDER2( OJoinDesignViewAccess, VCLXAccessibleComponent, OJoinDesignViewAccess_BASE )
+}
+
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/JoinController.cxx b/dbaccess/source/ui/querydesign/JoinController.cxx
new file mode 100644
index 000000000000..f4552253d84f
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/JoinController.cxx
@@ -0,0 +1,475 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include <sfx2/sfxsids.hrc>
+#include "dbu_qry.hrc"
+#include "browserids.hxx"
+#include <comphelper/types.hxx>
+#include "dbustrings.hrc"
+#include <connectivity/dbtools.hxx>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <comphelper/extract.hxx>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#include <com/sun/star/sdbcx/XDrop.hpp>
+#include <com/sun/star/sdbcx/XAlterTable.hpp>
+#include <com/sun/star/sdbcx/XAppend.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <connectivity/dbexception.hxx>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <comphelper/streamsection.hxx>
+#include <comphelper/basicio.hxx>
+#include <comphelper/seqstream.hxx>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include "sqlmessage.hxx"
+#include "JoinController.hxx"
+#include <vcl/msgbox.hxx>
+#include "TableWindowData.hxx"
+#include "TableWindow.hxx"
+#include "TableConnectionData.hxx"
+#include "adtabdlg.hxx"
+#include <vcl/waitobj.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include "UITools.hxx"
+#include <osl/diagnose.h>
+
+#include <boost/optional.hpp>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::dbtools;
+using namespace ::comphelper;
+
+// .............................................................................
+namespace dbaui
+{
+// .............................................................................
+
+// =============================================================================
+// = AddTableDialogContext
+// =============================================================================
+class AddTableDialogContext : public IAddTableDialogContext
+{
+ OJoinController& m_rController;
+
+public:
+ AddTableDialogContext( OJoinController& _rController )
+ :m_rController( _rController )
+ {
+ }
+
+ // IAddTableDialogContext
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
+ getConnection() const;
+ virtual bool allowViews() const;
+ virtual bool allowQueries() const;
+ virtual bool allowAddition() const;
+ virtual void addTableWindow( const String& _rQualifiedTableName, const String& _rAliasName );
+ virtual void onWindowClosing( const Window* _pWindow );
+
+private:
+ OJoinTableView* getTableView() const;
+};
+
+// -----------------------------------------------------------------------------
+Reference< XConnection > AddTableDialogContext::getConnection() const
+{
+ return m_rController.getConnection();
+}
+
+// -----------------------------------------------------------------------------
+bool AddTableDialogContext::allowViews() const
+{
+ return m_rController.allowViews();
+}
+
+// -----------------------------------------------------------------------------
+bool AddTableDialogContext::allowQueries() const
+{
+ return m_rController.allowQueries();
+}
+
+// -----------------------------------------------------------------------------
+bool AddTableDialogContext::allowAddition() const
+{
+ return const_cast< OJoinController& >( m_rController ).getJoinView()->getTableView()->IsAddAllowed();
+}
+
+// -----------------------------------------------------------------------------
+void AddTableDialogContext::addTableWindow( const String& _rQualifiedTableName, const String& _rAliasName )
+{
+ getTableView()->AddTabWin( _rQualifiedTableName, _rAliasName, sal_True );
+}
+
+// -----------------------------------------------------------------------------
+void AddTableDialogContext::onWindowClosing( const Window* _pWindow )
+{
+ if ( !m_rController.getView() )
+ return;
+
+ ::dbaui::notifySystemWindow(
+ m_rController.getView(), const_cast< Window* >( _pWindow ), ::comphelper::mem_fun( &TaskPaneList::RemoveWindow ) );
+
+ m_rController.InvalidateFeature( ID_BROWSER_ADDTABLE );
+ m_rController.getView()->GrabFocus();
+}
+
+// -----------------------------------------------------------------------------
+OJoinTableView* AddTableDialogContext::getTableView() const
+{
+ if ( m_rController.getJoinView() )
+ return m_rController.getJoinView()->getTableView();
+ return NULL;
+}
+
+// =============================================================================
+// = OJoinController
+// =============================================================================
+
+DBG_NAME(OJoinController)
+// -----------------------------------------------------------------------------
+OJoinController::OJoinController(const Reference< XMultiServiceFactory >& _rM)
+ :OJoinController_BASE(_rM)
+ ,m_pAddTableDialog(NULL)
+{
+ DBG_CTOR(OJoinController,NULL);
+}
+// -----------------------------------------------------------------------------
+OJoinController::~OJoinController()
+{
+ DBG_DTOR(OJoinController,NULL);
+}
+
+// -----------------------------------------------------------------------------
+void SAL_CALL OJoinController::disposing( const EventObject& _rSource ) throw(RuntimeException)
+{
+ OJoinController_BASE::disposing( _rSource );
+}
+
+// -----------------------------------------------------------------------------
+OJoinDesignView* OJoinController::getJoinView()
+{
+ return static_cast< OJoinDesignView* >( getView() );
+}
+
+// -----------------------------------------------------------------------------
+void OJoinController::disposing()
+{
+ {
+ ::std::auto_ptr< Window > pEnsureDelete( m_pAddTableDialog );
+ m_pAddTableDialog = NULL;
+ }
+
+ OJoinController_BASE::disposing();
+
+ clearView();
+
+ m_vTableConnectionData.clear();
+ m_vTableData.clear();
+}
+// -----------------------------------------------------------------------------
+void OJoinController::reconnect( sal_Bool _bUI )
+{
+ OJoinController_BASE::reconnect( _bUI );
+ if ( isConnected() && m_pAddTableDialog )
+ m_pAddTableDialog->Update();
+}
+
+// -----------------------------------------------------------------------------
+void OJoinController::impl_onModifyChanged()
+{
+ OJoinController_BASE::impl_onModifyChanged();
+ InvalidateFeature( SID_RELATION_ADD_RELATION );
+}
+// -----------------------------------------------------------------------------
+void OJoinController::SaveTabWinPosSize(OTableWindow* pTabWin, long nOffsetX, long nOffsetY)
+{
+ // die Daten zum Fenster
+ TTableWindowData::value_type pData = pTabWin->GetData();
+ OSL_ENSURE(pData != NULL, "SaveTabWinPosSize : TabWin hat keine Daten !");
+
+ // Position & Size der Daten neu setzen (aus den aktuellen Fenster-Parametern)
+ Point aPos = pTabWin->GetPosPixel();
+ aPos.X() += nOffsetX;
+ aPos.Y() += nOffsetY;
+ pData->SetPosition(aPos);
+ pData->SetSize(pTabWin->GetSizePixel());
+
+}
+// -----------------------------------------------------------------------------
+FeatureState OJoinController::GetState(sal_uInt16 _nId) const
+{
+ FeatureState aReturn;
+ // (disabled automatically)
+ aReturn.bEnabled = sal_True;
+
+ switch (_nId)
+ {
+ case ID_BROWSER_EDITDOC:
+ aReturn.bChecked = isEditable();
+ break;
+ case ID_BROWSER_ADDTABLE:
+ aReturn.bEnabled = ( getView() != NULL )
+ && const_cast< OJoinController* >( this )->getJoinView()->getTableView()->IsAddAllowed();
+ aReturn.bChecked = aReturn.bEnabled && m_pAddTableDialog != NULL && m_pAddTableDialog->IsVisible() ;
+ if ( aReturn.bEnabled )
+ aReturn.sTitle = OAddTableDlg::getDialogTitleForContext( impl_getDialogContext() );
+ break;
+
+ default:
+ aReturn = OJoinController_BASE::GetState(_nId);
+ }
+ return aReturn;
+}
+
+// -----------------------------------------------------------------------------
+AddTableDialogContext& OJoinController::impl_getDialogContext() const
+{
+ if ( !m_pDialogContext.get() )
+ {
+ OJoinController* pNonConstThis = const_cast< OJoinController* >( this );
+ pNonConstThis->m_pDialogContext.reset( new AddTableDialogContext( *pNonConstThis ) );
+ }
+ return *m_pDialogContext;
+}
+
+// -----------------------------------------------------------------------------
+void OJoinController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs)
+{
+ switch(_nId)
+ {
+ case ID_BROWSER_EDITDOC:
+ if(isEditable())
+ { // the state should be changed to not editable
+ switch (saveModified())
+ {
+ case RET_CANCEL:
+ // don't change anything here so return
+ return;
+ case RET_NO:
+ reset();
+ setModified(sal_False); // and we are not modified yet
+ break;
+ default:
+ break;
+ }
+ }
+ setEditable(!isEditable());
+ getJoinView()->setReadOnly(!isEditable());
+ InvalidateAll();
+ return;
+ case ID_BROWSER_ADDTABLE:
+ if ( !m_pAddTableDialog )
+ m_pAddTableDialog = new OAddTableDlg( getView(), impl_getDialogContext() );
+
+ if ( m_pAddTableDialog->IsVisible() )
+ {
+ m_pAddTableDialog->Show( sal_False );
+ getView()->GrabFocus();
+ }
+ else
+ {
+ {
+ WaitObject aWaitCursor( getView() );
+ m_pAddTableDialog->Update();
+ }
+ m_pAddTableDialog->Show( sal_True );
+ ::dbaui::notifySystemWindow(getView(),m_pAddTableDialog,::comphelper::mem_fun(&TaskPaneList::AddWindow));
+ }
+ break;
+ default:
+ OJoinController_BASE::Execute(_nId,aArgs);
+ }
+ InvalidateFeature(_nId);
+}
+// -----------------------------------------------------------------------------
+void OJoinController::SaveTabWinsPosSize( OJoinTableView::OTableWindowMap* pTabWinList, long nOffsetX, long nOffsetY )
+{
+ // Das Loeschen und Neuanlegen der alten Implementation ist unter dem aktuellen Modell nicht mehr richtig : Die TabWins
+ // habe einen Zeiger auf ihre Daten, verwaltet werden sie aber von mir. Wenn ich die alten loesche, haben die TabWins
+ // ploetzlich Zeiger auf nicht mehr existente Objekte.
+ // Wenn die TabWins ein SetData haetten, koennte ich mir das sparen ... haben sie aber nicht, ausserdem muesste ich dann immer
+ // noch Informationen, die sich eigentlich nicht geaendert haben, auch neu setzen.
+ // Also loesche ich die TabWinDatas nicht, sondern aktualisiere sie nur.
+ OSL_ENSURE(m_vTableData.size() == pTabWinList->size(),
+ "OJoinController::SaveTabWinsPosSize : inkonsistenter Zustand : sollte genausviel TabWinDatas haben wie TabWins !");
+
+ OJoinTableView::OTableWindowMap::iterator aIter = pTabWinList->begin();
+ OJoinTableView::OTableWindowMap::iterator aEnd = pTabWinList->end();
+ for(;aIter != aEnd;++aIter)
+ SaveTabWinPosSize(aIter->second, nOffsetX, nOffsetY);
+}
+// -----------------------------------------------------------------------------
+void OJoinController::removeConnectionData(const TTableConnectionData::value_type& _pData)
+{
+ m_vTableConnectionData.erase( ::std::remove(m_vTableConnectionData.begin(),m_vTableConnectionData.end(),_pData),m_vTableConnectionData.end());
+}
+// -----------------------------------------------------------------------------
+void OJoinController::describeSupportedFeatures()
+{
+ OJoinController_BASE::describeSupportedFeatures();
+ implDescribeSupportedFeature( ".uno:Redo", ID_BROWSER_REDO, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:Save", ID_BROWSER_SAVEDOC, CommandGroup::DOCUMENT );
+ implDescribeSupportedFeature( ".uno:Undo", ID_BROWSER_UNDO, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:AddTable", ID_BROWSER_ADDTABLE,CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:EditDoc", ID_BROWSER_EDITDOC, CommandGroup::EDIT );
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL OJoinController::suspend(sal_Bool _bSuspend) throw( RuntimeException )
+{
+ if ( getBroadcastHelper().bInDispose || getBroadcastHelper().bDisposed )
+ return sal_True;
+
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+ if ( getView() && getView()->IsInModalMode() )
+ return sal_False;
+ sal_Bool bCheck = sal_True;
+ if ( _bSuspend )
+ {
+ bCheck = saveModified() != RET_CANCEL;
+ if ( bCheck )
+ OSingleDocumentController::suspend(_bSuspend);
+ }
+ return bCheck;
+}
+// -----------------------------------------------------------------------------
+void OJoinController::loadTableWindows( const ::comphelper::NamedValueCollection& i_rViewSettings )
+{
+ m_vTableData.clear();
+
+ m_aMinimumTableViewSize = Point();
+
+ Sequence< PropertyValue > aWindowData;
+ aWindowData = i_rViewSettings.getOrDefault( "Tables", aWindowData );
+
+ const PropertyValue* pTablesIter = aWindowData.getConstArray();
+ const PropertyValue* pTablesEnd = pTablesIter + aWindowData.getLength();
+ for ( ; pTablesIter != pTablesEnd; ++pTablesIter )
+ {
+ ::comphelper::NamedValueCollection aSingleTableData( pTablesIter->Value );
+ loadTableWindow( aSingleTableData );
+ }
+ if ( m_aMinimumTableViewSize != Point() )
+ {
+ getJoinView()->getScrollHelper()->resetRange( m_aMinimumTableViewSize );
+ }
+}
+
+// -----------------------------------------------------------------------------
+void OJoinController::loadTableWindow( const ::comphelper::NamedValueCollection& i_rTableWindowSettings )
+{
+ sal_Int32 nX = -1, nY = -1, nHeight = -1, nWidth = -1;
+
+ ::rtl::OUString sComposedName,sTableName,sWindowName;
+ sal_Bool bShowAll = false;
+
+ sComposedName = i_rTableWindowSettings.getOrDefault( "ComposedName", sComposedName );
+ sTableName = i_rTableWindowSettings.getOrDefault( "TableName", sTableName );
+ sWindowName = i_rTableWindowSettings.getOrDefault( "WindowName", sWindowName );
+ nY = i_rTableWindowSettings.getOrDefault( "WindowTop", nY );
+ nX = i_rTableWindowSettings.getOrDefault( "WindowLeft", nX );
+ nWidth = i_rTableWindowSettings.getOrDefault( "WindowWidth", nWidth );
+ nHeight = i_rTableWindowSettings.getOrDefault( "WindowHeight", nHeight );
+ bShowAll = i_rTableWindowSettings.getOrDefault( "ShowAll", bShowAll );
+
+ TTableWindowData::value_type pData = createTableWindowData(sComposedName,sTableName,sWindowName);
+ if ( pData )
+ {
+ pData->SetPosition(Point(nX,nY));
+ pData->SetSize( Size( nWidth, nHeight ) );
+ pData->ShowAll(bShowAll);
+ m_vTableData.push_back(pData);
+ if ( m_aMinimumTableViewSize.X() < (nX+nWidth) )
+ m_aMinimumTableViewSize.X() = (nX+nWidth);
+ if ( m_aMinimumTableViewSize.Y() < (nY+nHeight) )
+ m_aMinimumTableViewSize.Y() = (nY+nHeight);
+ }
+}
+// -----------------------------------------------------------------------------
+void OJoinController::saveTableWindows( ::comphelper::NamedValueCollection& o_rViewSettings ) const
+{
+ if ( !m_vTableData.empty() )
+ {
+ ::comphelper::NamedValueCollection aAllTablesData;
+
+ TTableWindowData::const_iterator aIter = m_vTableData.begin();
+ TTableWindowData::const_iterator aEnd = m_vTableData.end();
+ for ( sal_Int32 i = 1; aIter != aEnd; ++aIter, ++i )
+ {
+ ::comphelper::NamedValueCollection aWindowData;
+ aWindowData.put( "ComposedName", (*aIter)->GetComposedName() );
+ aWindowData.put( "TableName", (*aIter)->GetTableName() );
+ aWindowData.put( "WindowName", (*aIter)->GetWinName() );
+ aWindowData.put( "WindowTop", static_cast<sal_Int32>((*aIter)->GetPosition().Y()) );
+ aWindowData.put( "WindowLeft", static_cast<sal_Int32>((*aIter)->GetPosition().X()) );
+ aWindowData.put( "WindowWidth", static_cast<sal_Int32>((*aIter)->GetSize().Width()) );
+ aWindowData.put( "WindowHeight", static_cast<sal_Int32>((*aIter)->GetSize().Height()) );
+ aWindowData.put( "ShowAll", (*aIter)->IsShowAll() );
+
+ const ::rtl::OUString sTableName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Table" ) ) + ::rtl::OUString::valueOf( i ) );
+ aAllTablesData.put( sTableName, aWindowData.getPropertyValues() );
+ }
+
+ o_rViewSettings.put( "Tables", aAllTablesData.getPropertyValues() );
+ }
+}
+// -----------------------------------------------------------------------------
+TTableWindowData::value_type OJoinController::createTableWindowData(const ::rtl::OUString& _sComposedName,const ::rtl::OUString& _sTableName,const ::rtl::OUString& _sWindowName)
+{
+ OJoinDesignView* pView = getJoinView();
+ if( pView )
+ return pView->getTableView()->createTableWindowData(_sComposedName,_sTableName,_sWindowName);
+ OSL_FAIL("We should never ever reach this point!");
+
+ return TTableWindowData::value_type();
+}
+// .............................................................................
+} // namespace dbaui
+// .............................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/JoinDesignView.cxx b/dbaccess/source/ui/querydesign/JoinDesignView.cxx
new file mode 100644
index 000000000000..397bb804c829
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/JoinDesignView.cxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "JoinDesignView.hxx"
+#include "JoinTableView.hxx"
+#include "JoinController.hxx"
+#include <svl/undo.hxx>
+#include "adtabdlg.hxx"
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include "browserids.hxx"
+#include "dbu_qry.hrc"
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include "TableConnection.hxx"
+#include "ConnectionLine.hxx"
+#include "ConnectionLineData.hxx"
+#include "TableConnectionData.hxx"
+#include "dbustrings.hrc"
+#include <comphelper/extract.hxx>
+#include "UITools.hxx"
+#include "JoinTableView.hxx"
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::i18n;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+
+namespace dbaui
+{
+
+// =============================================================================
+// = OJoinDesignView
+// =============================================================================
+// -----------------------------------------------------------------------------
+OJoinDesignView::OJoinDesignView(Window* _pParent, OJoinController& _rController,const Reference< XMultiServiceFactory >& _rFactory)
+ :ODataView( _pParent, _rController, _rFactory )
+ ,m_pTableView(NULL)
+ ,m_rController( _rController )
+{
+ m_pScrollWindow = new OScrollWindowHelper(this);
+}
+// -----------------------------------------------------------------------------
+OJoinDesignView::~OJoinDesignView()
+{
+ ::std::auto_ptr<Window> aT3(m_pScrollWindow);
+ m_pScrollWindow = NULL;
+ ::std::auto_ptr<Window> aT2(m_pTableView);
+ m_pTableView = NULL;
+}
+// -------------------------------------------------------------------------
+void OJoinDesignView::Construct()
+{
+ m_pScrollWindow->setTableView(m_pTableView);
+ m_pScrollWindow->Show();
+ m_pTableView->Show();
+
+ SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor()) );
+
+ ODataView::Construct();
+}
+// -----------------------------------------------------------------------------
+void OJoinDesignView::initialize()
+{
+}
+// -------------------------------------------------------------------------
+void OJoinDesignView::resizeDocumentView(Rectangle& _rPlayground)
+{
+ m_pScrollWindow->SetPosSizePixel( _rPlayground.TopLeft(), _rPlayground.GetSize() );
+
+ // just for completeness: there is no space left, we occupied it all ...
+ _rPlayground.SetPos( _rPlayground.BottomRight() );
+ _rPlayground.SetSize( Size( 0, 0 ) );
+}
+// -----------------------------------------------------------------------------
+void OJoinDesignView::setReadOnly(sal_Bool /*_bReadOnly*/)
+{
+}
+// -----------------------------------------------------------------------------
+void OJoinDesignView::SaveTabWinUIConfig(OTableWindow* pWin)
+{
+ getController().SaveTabWinPosSize(pWin, m_pScrollWindow->GetHScrollBar()->GetThumbPos(), m_pScrollWindow->GetVScrollBar()->GetThumbPos());
+}
+// -----------------------------------------------------------------------------
+void OJoinDesignView::KeyInput( const KeyEvent& rEvt )
+{
+ if ( m_pTableView && m_pTableView->IsVisible() )
+ m_pTableView->KeyInput( rEvt );
+ else
+ ODataView::KeyInput(rEvt);
+}
+// -----------------------------------------------------------------------------
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/JoinExchange.cxx b/dbaccess/source/ui/querydesign/JoinExchange.cxx
new file mode 100644
index 000000000000..75d69afa5b09
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/JoinExchange.cxx
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "JoinExchange.hxx"
+#include <sot/formats.hxx>
+#include <svx/dbexch.hrc>
+#include <cppuhelper/typeprovider.hxx>
+#include <sot/formats.hxx>
+
+namespace dbaui
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::datatransfer;
+
+ String OJoinExchObj::m_sJoinFormat;
+ //==================================================================
+ // class OJoinExchObj
+ //==================================================================
+ DBG_NAME(OJoinExchObj)
+ //------------------------------------------------------------------------
+ OJoinExchObj::OJoinExchObj(const OJoinExchangeData& jxdSource,sal_Bool _bFirstEntry)
+ :m_bFirstEntry(_bFirstEntry)
+ ,m_jxdSourceDescription(jxdSource)
+ ,m_pDragListener(NULL)
+ {
+ DBG_CTOR(OJoinExchObj,NULL);
+ // Verfuegbare Typen in Liste einfuegen
+ }
+
+ //------------------------------------------------------------------------
+ OJoinExchObj::~OJoinExchObj()
+ {
+ DBG_DTOR(OJoinExchObj,NULL);
+ }
+
+ //------------------------------------------------------------------------
+ void OJoinExchObj::StartDrag( Window* _pWindow, sal_Int8 _nDragSourceActions, IDragTransferableListener* _pListener )
+ {
+ m_pDragListener = _pListener;
+ TransferableHelper::StartDrag(_pWindow, _nDragSourceActions);
+ }
+
+ //------------------------------------------------------------------------
+ void OJoinExchObj::DragFinished( sal_Int8 /*nDropAction*/ )
+ {
+ if (m_pDragListener)
+ m_pDragListener->dragFinished();
+ m_pDragListener = NULL;
+ }
+
+ //------------------------------------------------------------------------
+ sal_Bool OJoinExchObj::isFormatAvailable( const DataFlavorExVector& _rFormats ,SotFormatStringId _nSlotID)
+ {
+ DataFlavorExVector::const_iterator aCheckEnd = _rFormats.end();
+ for ( DataFlavorExVector::const_iterator aCheck = _rFormats.begin();
+ aCheck != aCheckEnd;
+ ++aCheck
+ )
+ {
+ if ( _nSlotID == aCheck->mnSotId )
+ return sal_True;
+ }
+ return sal_False;
+ }
+
+ //------------------------------------------------------------------------
+ OJoinExchangeData OJoinExchObj::GetSourceDescription(const Reference< XTransferable >& _rxObject)
+ {
+ OJoinExchangeData aReturn;
+ Reference< XUnoTunnel > xTunnel(_rxObject, UNO_QUERY);
+ if (xTunnel.is())
+ {
+ OJoinExchObj* pImplementation = reinterpret_cast<OJoinExchObj*>(xTunnel->getSomething(getUnoTunnelImplementationId()));
+ if (pImplementation)
+ aReturn = pImplementation->m_jxdSourceDescription;
+ }
+ return aReturn;
+ }
+
+ //------------------------------------------------------------------------
+ Sequence< sal_Int8 > OJoinExchObj::getUnoTunnelImplementationId()
+ {
+ static ::cppu::OImplementationId * pId = 0;
+ if (! pId)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static ::cppu::OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+ }
+
+ //------------------------------------------------------------------------
+ sal_Int64 SAL_CALL OJoinExchObj::getSomething( const Sequence< sal_Int8 >& _rIdentifier ) throw(RuntimeException)
+ {
+ if (_rIdentifier.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), _rIdentifier.getConstArray(), 16 ) )
+ return reinterpret_cast<sal_Int64>(this);
+
+ return 0;
+ }
+
+ //------------------------------------------------------------------------
+ void OJoinExchObj::AddSupportedFormats()
+ {
+ AddFormat( SOT_FORMATSTR_ID_SBA_JOIN );
+ if ( m_bFirstEntry )
+ AddFormat( SOT_FORMATSTR_ID_SBA_TABID );
+ }
+
+ //------------------------------------------------------------------------
+ sal_Bool OJoinExchObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
+ {
+ sal_uInt32 nFormat = SotExchange::GetFormat(rFlavor);
+ if ( SOT_FORMATSTR_ID_SBA_JOIN == nFormat )
+ // this is a HACK
+ // we don't really copy our data, the instances using us have to call GetSourceDescription ....
+ // if, one day, we have a _lot_ of time, this hack should be removed ....
+ return sal_True;
+
+ return sal_False;
+ }
+
+ //------------------------------------------------------------------------
+ Any SAL_CALL OJoinExchObj::queryInterface( const Type& _rType ) throw(RuntimeException)
+ {
+ Any aReturn = TransferableHelper::queryInterface(_rType);
+ if (!aReturn.hasValue())
+ aReturn = OJoinExchObj_Base::queryInterface(_rType);
+ return aReturn;
+ }
+
+ //------------------------------------------------------------------------
+ void SAL_CALL OJoinExchObj::acquire( ) throw()
+ {
+ TransferableHelper::acquire( );
+ }
+
+ //------------------------------------------------------------------------
+ void SAL_CALL OJoinExchObj::release( ) throw()
+ {
+ TransferableHelper::release( );
+ }
+
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/JoinTableView.cxx b/dbaccess/source/ui/querydesign/JoinTableView.cxx
new file mode 100644
index 000000000000..f2d906e5017a
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/JoinTableView.cxx
@@ -0,0 +1,1717 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "JoinTableView.hxx"
+#include <osl/diagnose.h>
+#include "querycontroller.hxx"
+#include "JoinDesignView.hxx"
+#include "dbu_qry.hrc"
+#include "TableWindow.hxx"
+#include "TableWindowListBox.hxx"
+#include "TableConnection.hxx"
+#include "TableConnectionData.hxx"
+#include "ConnectionLine.hxx"
+#include "ConnectionLineData.hxx"
+#include "browserids.hxx"
+#include <svl/urlbmk.hxx>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include "QueryMoveTabWinUndoAct.hxx"
+#include "QuerySizeTabWinUndoAct.hxx"
+#include <vcl/svapp.hxx>
+#include "TableWindowData.hxx"
+#include "JAccess.hxx"
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include "UITools.hxx"
+#include <cppuhelper/exc_hlp.hxx>
+#include <tools/diagnose_ex.h>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <functional>
+
+using namespace dbaui;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+#define LINE_SIZE 50
+////////////////////////////////////////////////////////////////
+// Konstanten fuer das Fensterlayout
+#define TABWIN_SPACING_X 17
+#define TABWIN_SPACING_Y 17
+
+#define TABWIN_WIDTH_STD 120
+#define TABWIN_HEIGHT_STD 120
+
+DBG_NAME(OScrollWindowHelper)
+OScrollWindowHelper::OScrollWindowHelper( Window* pParent) : Window( pParent)
+ ,m_aHScrollBar( this, WB_HSCROLL|WB_REPEAT|WB_DRAG )
+ ,m_aVScrollBar( this, WB_VSCROLL|WB_REPEAT|WB_DRAG )
+ ,m_pCornerWindow(new ScrollBarBox(this, WB_3DLOOK))
+ ,m_pTableView(NULL)
+{
+ DBG_CTOR(OScrollWindowHelper,NULL);
+
+ //////////////////////////////////////////////////////////////////////
+ // ScrollBars
+
+ GetHScrollBar()->SetRange( Range(0, 1000) );
+ GetVScrollBar()->SetRange( Range(0, 1000) );
+
+ GetHScrollBar()->SetLineSize( LINE_SIZE );
+ GetVScrollBar()->SetLineSize( LINE_SIZE );
+
+ GetHScrollBar()->Show();
+ GetVScrollBar()->Show();
+ m_pCornerWindow->Show();
+
+ // normally we should be SCROLL_PANE
+ SetAccessibleRole(AccessibleRole::SCROLL_PANE);
+}
+
+// -----------------------------------------------------------------------------
+OScrollWindowHelper::~OScrollWindowHelper()
+{
+ DBG_DTOR(OScrollWindowHelper,NULL);
+ ::std::auto_ptr<Window> aTemp(m_pCornerWindow);
+ m_pCornerWindow = NULL;
+ m_pTableView = NULL;
+}
+
+// -----------------------------------------------------------------------------
+void OScrollWindowHelper::setTableView(OJoinTableView* _pTableView)
+{
+ m_pTableView = _pTableView;
+ //////////////////////////////////////////////////////////////////////
+ // ScrollBars
+ GetHScrollBar()->SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
+ GetVScrollBar()->SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
+}
+// -----------------------------------------------------------------------------
+void OScrollWindowHelper::resetRange(const Point& _aSize)
+{
+ Point aPos = PixelToLogic(_aSize);
+ GetHScrollBar()->SetRange( Range(0, aPos.X() + TABWIN_SPACING_X) );
+ GetVScrollBar()->SetRange( Range(0, aPos.Y() + TABWIN_SPACING_Y) );
+}
+//------------------------------------------------------------------------------
+void OScrollWindowHelper::Resize()
+{
+ Window::Resize();
+
+ Size aTotalOutputSize = GetOutputSizePixel();
+ long nHScrollHeight = GetHScrollBar()->GetSizePixel().Height();
+ long nVScrollWidth = GetVScrollBar()->GetSizePixel().Width();
+
+ GetHScrollBar()->SetPosSizePixel(
+ Point( 0, aTotalOutputSize.Height()-nHScrollHeight ),
+ Size( aTotalOutputSize.Width()-nVScrollWidth, nHScrollHeight )
+ );
+
+ GetVScrollBar()->SetPosSizePixel(
+ Point( aTotalOutputSize.Width()-nVScrollWidth, 0 ),
+ Size( nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight )
+ );
+
+ m_pCornerWindow->SetPosSizePixel(
+ Point( aTotalOutputSize.Width() - nVScrollWidth, aTotalOutputSize.Height() - nHScrollHeight),
+ Size( nVScrollWidth, nHScrollHeight )
+ );
+
+ GetHScrollBar()->SetPageSize( aTotalOutputSize.Width() );
+ GetHScrollBar()->SetVisibleSize( aTotalOutputSize.Width() );
+
+ GetVScrollBar()->SetPageSize( aTotalOutputSize.Height() );
+ GetVScrollBar()->SetVisibleSize( aTotalOutputSize.Height() );
+
+ // adjust the ranges of the scrollbars if neccessary
+ long lRange = GetHScrollBar()->GetRange().Max() - GetHScrollBar()->GetRange().Min();
+ if (m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() > lRange)
+ GetHScrollBar()->SetRangeMax(m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() + GetHScrollBar()->GetRange().Min());
+
+ lRange = GetVScrollBar()->GetRange().Max() - GetVScrollBar()->GetRange().Min();
+ if (m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() > lRange)
+ GetVScrollBar()->SetRangeMax(m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() + GetVScrollBar()->GetRange().Min());
+
+ m_pTableView->SetPosSizePixel(Point( 0, 0 ),Size( aTotalOutputSize.Width()-nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight ));
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//==================================================================
+// class OJoinTableView
+//==================================================================
+
+DBG_NAME(OJoinTableView);
+//------------------------------------------------------------------------------
+OJoinTableView::OJoinTableView( Window* pParent, OJoinDesignView* pView )
+ :Window( pParent,WB_BORDER )
+ ,DropTargetHelper(this)
+ ,m_aDragOffset( Point(0,0) )
+ ,m_aScrollOffset( Point(0,0) )
+ ,m_pDragWin( NULL )
+ ,m_pSizingWin( NULL )
+ ,m_pSelectedConn( NULL )
+ ,m_bTrackingInitiallyMoved(sal_False)
+ ,m_pLastFocusTabWin(NULL)
+ ,m_pView( pView )
+ ,m_pAccessible(NULL)
+{
+ DBG_CTOR(OJoinTableView,NULL);
+ SetSizePixel( Size(1000, 1000) );
+
+ InitColors();
+
+ m_aDragScrollTimer.SetTimeoutHdl(LINK(this, OJoinTableView, OnDragScrollTimer));
+}
+
+//------------------------------------------------------------------------------
+OJoinTableView::~OJoinTableView()
+{
+ DBG_DTOR(OJoinTableView,NULL);
+ if( m_pAccessible )
+ {
+ m_pAccessible->clearTableView();
+ m_pAccessible = NULL;
+ }
+ //////////////////////////////////////////////////////////////////////
+ // Listen loeschen
+ clearLayoutInformation();
+}
+//------------------------------------------------------------------------------
+IMPL_LINK( OJoinTableView, ScrollHdl, ScrollBar*, pScrollBar )
+{
+ //////////////////////////////////////////////////////////////////////
+ // Alle Fenster verschieben
+ ScrollPane( pScrollBar->GetDelta(), (pScrollBar == GetHScrollBar()), sal_False );
+
+ return 0;
+}
+//------------------------------------------------------------------------------
+void OJoinTableView::Resize()
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ Window::Resize();
+ m_aOutputSize = GetSizePixel();
+
+ // tab win positions may not be up-to-date
+ if (m_aTableMap.empty())
+ // no tab wins ...
+ return;
+
+ // we have at least one table so resize it
+ m_aScrollOffset.X() = GetHScrollBar()->GetThumbPos();
+ m_aScrollOffset.Y() = GetVScrollBar()->GetThumbPos();
+
+ OTableWindow* pCheck = m_aTableMap.begin()->second;
+ Point aRealPos = pCheck->GetPosPixel();
+ Point aAssumedPos = pCheck->GetData()->GetPosition() - GetScrollOffset();
+
+ if (aRealPos == aAssumedPos)
+ // all ok
+ return;
+
+ OTableWindowMapIterator aIter = m_aTableMap.begin();
+ OTableWindowMapIterator aEnd = m_aTableMap.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableWindow* pCurrent = aIter->second;
+ Point aPos(pCurrent->GetData()->GetPosition() - GetScrollOffset());
+ pCurrent->SetPosPixel(aPos);
+ }
+}
+//------------------------------------------------------------------------------
+sal_uLong OJoinTableView::GetTabWinCount()
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ return m_aTableMap.size();
+}
+
+//------------------------------------------------------------------------------
+bool OJoinTableView::RemoveConnection( OTableConnection* _pConn,sal_Bool _bDelete )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ DeselectConn(_pConn);
+
+ // to force a redraw
+ _pConn->InvalidateConnection();
+
+ m_pView->getController().removeConnectionData( _pConn->GetData() );
+
+ m_vTableConnection.erase(
+ ::std::find(m_vTableConnection.begin(),m_vTableConnection.end(),_pConn) );
+
+ modified();
+ if ( m_pAccessible )
+ m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
+ makeAny(_pConn->GetAccessible()),
+ Any());
+ if ( _bDelete )
+ {
+ delete _pConn;
+ }
+
+ return true;
+}
+
+//------------------------------------------------------------------------
+OTableWindow* OJoinTableView::GetTabWindow( const String& rName )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ OTableWindowMapIterator aIter = m_aTableMap.find(rName);
+
+ return aIter == m_aTableMap.end() ? NULL : aIter->second;
+}
+// -----------------------------------------------------------------------------
+TTableWindowData::value_type OJoinTableView::createTableWindowData(const ::rtl::OUString& _rComposedName
+ ,const ::rtl::OUString& _sTableName
+ ,const ::rtl::OUString& _rWinName)
+{
+ TTableWindowData::value_type pData( CreateImpl(_rComposedName, _sTableName,_rWinName) );
+ OJoinDesignView* pParent = getDesignView();
+ try
+ {
+ if ( !pData->init(pParent->getController().getConnection(),allowQueries()) )
+ {
+ if ( pData->isValid() )
+ onNoColumns_throw();
+ else
+ pData.reset();
+ }
+ }
+ catch ( const SQLException& )
+ {
+ ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ),
+ pParent, pParent->getController().getORB() );
+ }
+ catch( const WrappedTargetException& e )
+ {
+ SQLException aSql;
+ if ( e.TargetException >>= aSql )
+ ::dbaui::showError( ::dbtools::SQLExceptionInfo( aSql ), pParent, pParent->getController().getORB() );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return pData;
+}
+// -----------------------------------------------------------------------------
+OTableWindowData* OJoinTableView::CreateImpl(const ::rtl::OUString& _rComposedName
+ ,const ::rtl::OUString& _sTableName
+ ,const ::rtl::OUString& _rWinName)
+{
+ return new OTableWindowData( NULL,_rComposedName,_sTableName, _rWinName );
+}
+//------------------------------------------------------------------------------
+void OJoinTableView::AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& rWinName, sal_Bool /*bNewTable*/)
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ OSL_ENSURE(_rComposedName.getLength(),"There must be a table name supplied!");
+
+ TTableWindowData::value_type pNewTabWinData(createTableWindowData( _rComposedName, rWinName,rWinName ));
+
+ //////////////////////////////////////////////////////////////////
+ // Neues Fenster in Fensterliste eintragen
+ OTableWindow* pNewTabWin = createWindow( pNewTabWinData );
+ if ( pNewTabWin->Init() )
+ {
+ m_pView->getController().getTableWindowData()->push_back( pNewTabWinData);
+ // when we already have a table with this name insert the full qualified one instead
+ if(m_aTableMap.find(rWinName) != m_aTableMap.end())
+ m_aTableMap[_rComposedName] = pNewTabWin;
+ else
+ m_aTableMap[rWinName] = pNewTabWin;
+
+ SetDefaultTabWinPosSize( pNewTabWin );
+ pNewTabWin->Show();
+
+ modified();
+ if ( m_pAccessible )
+ m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
+ Any(),
+ makeAny(pNewTabWin->GetAccessible()));
+ }
+ else
+ {
+ pNewTabWin->clearListBox();
+ delete pNewTabWin;
+ }
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::RemoveTabWin( OTableWindow* pTabWin )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ //////////////////////////////////////////////////////////////////////
+ // first delete all connections of this window to others
+ bool bRemove = true;
+ TTableWindowData::value_type pData = pTabWin->GetData();
+ sal_Int32 nCount = m_vTableConnection.size();
+ ::std::vector<OTableConnection*>::reverse_iterator aIter = m_vTableConnection.rbegin();
+ while(aIter != m_vTableConnection.rend() && bRemove)
+ {
+ OTableConnection* pTabConn = (*aIter);
+ if(
+ ( pData == pTabConn->GetData()->getReferencingTable()) ||
+ ( pData == pTabConn->GetData()->getReferencedTable())
+ )
+ {
+ bRemove = RemoveConnection( pTabConn ,sal_True);
+ aIter = m_vTableConnection.rbegin();
+ }
+ else
+ ++aIter;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // then delete the window itself
+ if ( bRemove )
+ {
+ if ( m_pAccessible )
+ m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
+ makeAny(pTabWin->GetAccessible()),Any()
+ );
+
+ pTabWin->Hide();
+ OJoinController& rController = m_pView->getController();
+ TTableWindowData::iterator aFind = ::std::find(rController.getTableWindowData()->begin(),rController.getTableWindowData()->end(),pData);
+ if(aFind != rController.getTableWindowData()->end())
+ {
+ rController.getTableWindowData()->erase(aFind);
+ rController.setModified(sal_True);
+ }
+
+ String aWinName = pTabWin->GetWinName();
+ if(m_aTableMap.find(aWinName) != m_aTableMap.end())
+ m_aTableMap.erase( aWinName );
+ else
+ m_aTableMap.erase( pTabWin->GetComposedName() );
+
+ if (pTabWin == m_pLastFocusTabWin)
+ m_pLastFocusTabWin = NULL;
+
+ pTabWin->clearListBox();
+ delete pTabWin;
+
+ }
+ if ( (sal_Int32)m_vTableConnection.size() < (nCount-1) ) // if some connections could be removed
+ modified();
+}
+namespace
+{
+ // -----------------------------------------------------------------------------
+ sal_Bool isScrollAllowed( OJoinTableView* _pView,long nDelta, sal_Bool bHoriz)
+ {
+ //////////////////////////////////////////////////////////////////////
+ // adjust ScrollBar-Positions
+ ScrollBar* pBar = _pView->GetVScrollBar();
+ if( bHoriz )
+ pBar = _pView->GetHScrollBar();
+
+ long nOldThumbPos = pBar->GetThumbPos();
+ long nNewThumbPos = nOldThumbPos + nDelta;
+ if( nNewThumbPos < 0 )
+ nNewThumbPos = 0;
+ else if( nNewThumbPos > pBar->GetRangeMax() )
+ nNewThumbPos = pBar->GetRangeMax();
+
+ if ( bHoriz )
+ {
+ if( nNewThumbPos == _pView->GetScrollOffset().X() )
+ return sal_False;
+ }
+ else if ( nNewThumbPos == _pView->GetScrollOffset().Y() )
+ return sal_False;
+
+ return sal_True;
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool getMovementImpl(OJoinTableView* _pView,const Point& _rPoint,const Size& _rSize,long& _nScrollX,long& _nScrollY)
+ {
+ _nScrollY = _nScrollX = 0;
+ // data about the tab win
+ Point aUpperLeft = _rPoint;
+ // normalize with respect to visibility
+ aUpperLeft -= _pView->GetScrollOffset();
+ Point aLowerRight(aUpperLeft.X() + _rSize.Width(), aUpperLeft.Y() + _rSize.Height());
+
+ // data about ourself
+ Size aSize = _pView->getRealOutputSize(); //GetOutputSizePixel();
+
+ sal_Bool bVisbile = sal_True;
+ sal_Bool bFitsHor = (aUpperLeft.X() >= 0) && (aLowerRight.X() <= aSize.Width());
+ sal_Bool bFitsVert= (aUpperLeft.Y() >= 0) && (aLowerRight.Y() <= aSize.Height());
+ if (!bFitsHor || !bFitsVert)
+ {
+ if (!bFitsHor)
+ {
+ // ensure the visibility of the right border
+ if ( aLowerRight.X() > aSize.Width() )
+ _nScrollX = aLowerRight.X() - aSize.Width() + TABWIN_SPACING_X;
+
+ // ensure the visibility of the left border (higher priority)
+ if ( aUpperLeft.X() < 0 )
+ _nScrollX = aUpperLeft.X() - TABWIN_SPACING_X;
+ }
+
+ if (!bFitsVert)
+ {
+ // lower border
+ if ( aLowerRight.Y() > aSize.Height() )
+ _nScrollY = aLowerRight.Y() - aSize.Height() + TABWIN_SPACING_Y;
+ // upper border
+ if ( aUpperLeft.Y() < 0 )
+ _nScrollY = aUpperLeft.Y() - TABWIN_SPACING_Y;
+ }
+
+ if ( _nScrollX ) // aSize.Width() > _rSize.Width() &&
+ bVisbile = isScrollAllowed(_pView,_nScrollX, sal_True);
+
+ if ( _nScrollY ) // aSize.Height() > _rSize.Height() &&
+ bVisbile = bVisbile && isScrollAllowed(_pView,_nScrollY, sal_False);
+
+ if ( bVisbile )
+ {
+ sal_Int32 nHRangeMax = _pView->GetHScrollBar()->GetRangeMax();
+ sal_Int32 nVRangeMax = _pView->GetVScrollBar()->GetRangeMax();
+
+ if ( aSize.Width() + _pView->GetHScrollBar()->GetThumbPos() + _nScrollX > nHRangeMax )
+ bVisbile = sal_False;
+ if ( bVisbile && aSize.Height() + _pView->GetVScrollBar()->GetThumbPos() + _nScrollY > nVRangeMax )
+ bVisbile = sal_False;
+ }
+ }
+
+
+ return bVisbile;
+ }
+} // end of ano namespace
+// -----------------------------------------------------------------------------
+sal_Bool OJoinTableView::isMovementAllowed(const Point& _rPoint,const Size& _rSize)
+{
+ long nX,nY;
+ return getMovementImpl(this,_rPoint,_rSize,nX,nY);
+}
+//------------------------------------------------------------------------------
+void OJoinTableView::EnsureVisible(const OTableWindow* _pWin)
+{
+ // data about the tab win
+ TTableWindowData::value_type pData = _pWin->GetData();
+ EnsureVisible( pData->GetPosition() , pData->GetSize());
+ Invalidate(INVALIDATE_NOCHILDREN);
+}
+//------------------------------------------------------------------------------
+void OJoinTableView::EnsureVisible(const Point& _rPoint,const Size& _rSize)
+{
+ long nScrollX,nScrollY;
+
+ if ( getMovementImpl(this,_rPoint,_rSize,nScrollX,nScrollY) )
+ {
+ sal_Bool bVisbile = sal_True;
+ if (nScrollX)
+ bVisbile = ScrollPane(nScrollX, sal_True, sal_True);
+
+ if (nScrollY)
+ bVisbile = bVisbile && ScrollPane(nScrollY, sal_False, sal_True);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::SetDefaultTabWinPosSize( OTableWindow* pTabWin )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ //////////////////////////////////////////////////////////////////
+ // Position bestimmen:
+ // Das Fenster wird in Zeilen der Hoehe TABWIN_SPACING_Y+TABWIN_HEIGTH_STD aufgeteilt.
+ // Dann wird fuer jede Zeile geprueft, ob noch Platz fuer ein weiteres Fenster ist.
+ // Wenn kein Platz ist, wird die naechste Zeile ueberprueft.
+ Size aOutSize = GetSizePixel();
+ Point aNewPos( 0,0 );
+ sal_uInt16 nRow = 0;
+ sal_Bool bEnd = sal_False;
+ while( !bEnd )
+ {
+ //////////////////////////////////////////////////////////////////
+ // Neue Position auf Zeilenbeginn setzen
+ aNewPos.X() = TABWIN_SPACING_X;
+ aNewPos.Y() = (nRow+1) * TABWIN_SPACING_Y;
+
+ //////////////////////////////////////////////////////////////////
+ // Rectangle fuer die jeweilige Zeile bestimmen
+ Rectangle aRowRect( Point(0,0), aOutSize );
+ aRowRect.Top() = nRow * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
+ aRowRect.Bottom() = (nRow+1) * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
+
+ //////////////////////////////////////////////////////////////////
+ // Belegte Bereiche dieser Zeile pruefen
+ OTableWindow* pOtherTabWin;
+ OTableWindowMapIterator aIter = m_aTableMap.begin();
+ OTableWindowMapIterator aEnd = m_aTableMap.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ pOtherTabWin = aIter->second;
+ Rectangle aOtherTabWinRect( pOtherTabWin->GetPosPixel(), pOtherTabWin->GetSizePixel() );
+
+ if(
+ ( (aOtherTabWinRect.Top()>aRowRect.Top()) && (aOtherTabWinRect.Top()<aRowRect.Bottom()) ) ||
+ ( (aOtherTabWinRect.Bottom()>aRowRect.Top()) && (aOtherTabWinRect.Bottom()<aRowRect.Bottom()) )
+ )
+ {
+ //////////////////////////////////////////////////////////////////
+ // TabWin liegt in der Zeile
+ if( aOtherTabWinRect.Right()>aNewPos.X() )
+ aNewPos.X() = aOtherTabWinRect.Right() + TABWIN_SPACING_X;
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // Ist in dieser Zeile noch Platz?
+ if( (aNewPos.X()+TABWIN_WIDTH_STD)<aRowRect.Right() )
+ {
+ aNewPos.Y() = aRowRect.Top() + TABWIN_SPACING_Y;
+ bEnd = sal_True;
+ }
+ else
+ {
+ if( (aRowRect.Bottom()+aRowRect.GetHeight()) > aOutSize.Height() )
+ {
+ // insert it in the first row
+ sal_Int32 nCount = m_aTableMap.size() % (nRow+1);
+ ++nCount;
+ aNewPos.Y() = nCount * TABWIN_SPACING_Y + (nCount-1)*CalcZoom(TABWIN_HEIGHT_STD);
+ bEnd = sal_True;
+ }
+ else
+ nRow++;
+
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // Groesse bestimmen
+ Size aNewSize( CalcZoom(TABWIN_WIDTH_STD), CalcZoom(TABWIN_HEIGHT_STD) );
+
+ // check if the new position in inside the scrollbars ranges
+ Point aBottom(aNewPos);
+ aBottom.X() += aNewSize.Width();
+ aBottom.Y() += aNewSize.Height();
+
+ if(!GetHScrollBar()->GetRange().IsInside(aBottom.X()))
+ GetHScrollBar()->SetRange( Range(0, aBottom.X()) );
+ if(!GetVScrollBar()->GetRange().IsInside(aBottom.Y()))
+ GetVScrollBar()->SetRange( Range(0, aBottom.Y()) );
+
+ pTabWin->SetPosSizePixel( aNewPos, aNewSize );
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::DataChanged(const DataChangedEvent& rDCEvt)
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ if (rDCEvt.GetType() == DATACHANGED_SETTINGS)
+ {
+ // nehmen wir den worst-case an : die Farben haben sich geaendert, also
+ // mich anpassen
+ InitColors();
+ Invalidate(INVALIDATE_NOCHILDREN);
+ // durch das Invalidate werden auch die Connections neu gezeichnet, so dass die auch
+ // gleich in den neuen Farben dargestellt werden
+ }
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::InitColors()
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ // die Farben fuer die Darstellung sollten die Systemfarben sein
+ StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
+ SetBackground(Wallpaper(Color(aSystemStyle.GetDialogColor())));
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::BeginChildMove( OTableWindow* pTabWin, const Point& rMousePos )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+
+ if (m_pView->getController().isReadOnly())
+ return;
+
+ m_pDragWin = pTabWin;
+ SetPointer(Pointer(POINTER_MOVE));
+ Point aMousePos = ScreenToOutputPixel( rMousePos );
+ m_aDragOffset = aMousePos - pTabWin->GetPosPixel();
+ m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
+ m_bTrackingInitiallyMoved = sal_False;
+ StartTracking();
+}
+
+void OJoinTableView::NotifyTitleClicked( OTableWindow* pTabWin, const Point rMousePos )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ DeselectConn(GetSelectedConn());
+ BeginChildMove(pTabWin, rMousePos);
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::BeginChildSizing( OTableWindow* pTabWin, const Pointer& rPointer )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+
+ if (m_pView->getController().isReadOnly())
+ return;
+
+ SetPointer( rPointer );
+ m_pSizingWin = pTabWin;
+ StartTracking();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OJoinTableView::ScrollPane( long nDelta, sal_Bool bHoriz, sal_Bool bPaintScrollBars )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ sal_Bool bRet = sal_True;
+
+ //////////////////////////////////////////////////////////////////////
+ // ScrollBar-Positionen anpassen
+ if( bPaintScrollBars )
+ {
+ if( bHoriz )
+ {
+ long nOldThumbPos = GetHScrollBar()->GetThumbPos();
+ long nNewThumbPos = nOldThumbPos + nDelta;
+ if( nNewThumbPos < 0 )
+ {
+ nNewThumbPos = 0;
+ bRet = sal_False;
+ }
+ if( nNewThumbPos > GetHScrollBar()->GetRange().Max() )
+ {
+ nNewThumbPos = GetHScrollBar()->GetRange().Max();
+ bRet = sal_False;
+ }
+ GetHScrollBar()->SetThumbPos( nNewThumbPos );
+ nDelta = GetHScrollBar()->GetThumbPos() - nOldThumbPos;
+ }
+ else
+ {
+ long nOldThumbPos = GetVScrollBar()->GetThumbPos();
+ long nNewThumbPos = nOldThumbPos+nDelta;
+ if( nNewThumbPos < 0 )
+ {
+ nNewThumbPos = 0;
+ bRet = sal_False;
+ }
+ if( nNewThumbPos > GetVScrollBar()->GetRange().Max() )
+ {
+ nNewThumbPos = GetVScrollBar()->GetRange().Max();
+ bRet = sal_False;
+ }
+ GetVScrollBar()->SetThumbPos( nNewThumbPos );
+ nDelta = GetVScrollBar()->GetThumbPos() - nOldThumbPos;
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Wenn ScrollOffset bereits an den Grenzen liegt, kein Neuzeichnen
+ if( (GetHScrollBar()->GetThumbPos()==m_aScrollOffset.X()) &&
+ (GetVScrollBar()->GetThumbPos()==m_aScrollOffset.Y()) )
+ return sal_False;
+
+ //////////////////////////////////////////////////////////////////////
+ // ScrollOffset neu setzen
+ if (bHoriz)
+ m_aScrollOffset.X() = GetHScrollBar()->GetThumbPos();
+ else
+ m_aScrollOffset.Y() = GetVScrollBar()->GetThumbPos();
+
+ //////////////////////////////////////////////////////////////////////
+ // Alle Fenster verschieben
+ OTableWindow* pTabWin;
+ Point aPos;
+
+ OTableWindowMapIterator aIter = m_aTableMap.begin();
+ OTableWindowMapIterator aEnd = m_aTableMap.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ pTabWin = aIter->second;
+ aPos = pTabWin->GetPosPixel();
+
+ if( bHoriz )
+ aPos.X() -= nDelta;
+ else aPos.Y() -= nDelta;
+
+ pTabWin->SetPosPixel( aPos );
+ }
+
+ Invalidate(); // INVALIDATE_NOCHILDREN
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::Tracking( const TrackingEvent& rTEvt )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ HideTracking();
+
+ if (rTEvt.IsTrackingEnded())
+ {
+ if( m_pDragWin )
+ {
+ if (m_aDragScrollTimer.IsActive())
+ m_aDragScrollTimer.Stop();
+
+ //////////////////////////////////////////////////////////////////////
+ // Position des Childs nach Verschieben anpassen
+ //////////////////////////////////////////////////////////////////////
+ // Fenster duerfen nicht aus Anzeigebereich herausbewegt werden
+ Point aDragWinPos = rTEvt.GetMouseEvent().GetPosPixel() - m_aDragOffset;
+ Size aDragWinSize = m_pDragWin->GetSizePixel();
+ if( aDragWinPos.X() < 0 )
+ aDragWinPos.X() = 0;
+ if( aDragWinPos.Y() < 0 )
+ aDragWinPos.Y() = 0;
+ if( (aDragWinPos.X() + aDragWinSize.Width()) > m_aOutputSize.Width() )
+ aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width() - 1;
+ if( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() )
+ aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height() - 1;
+ if( aDragWinPos.X() < 0 )
+ aDragWinPos.X() = 0;
+ if( aDragWinPos.Y() < 0 )
+ aDragWinPos.Y() = 0;
+ // TODO : nicht das Fenster neu positionieren, wenn es uebersteht, sondern einfach meinen Bereich erweitern
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Fenster positionieren
+ EndTracking();
+ m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
+ // erst mal testen, ob ich mich ueberhaupt bewegt habe
+ // (das verhindert das Setzen des modified-Flags, wenn sich eigentlich gar nichts getan hat)
+ TTableWindowData::value_type pData = m_pDragWin->GetData();
+ if ( ! (pData && pData->HasPosition() && (pData->GetPosition() == aDragWinPos)))
+ {
+ // die alten logischen Koordinaten
+ Point ptOldPos = m_pDragWin->GetPosPixel() + Point(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
+ // neu positionieren
+ m_pDragWin->SetPosPixel(aDragWinPos);
+ TabWinMoved(m_pDragWin, ptOldPos);
+
+ m_pDragWin->GrabFocus();
+ }
+ m_pDragWin = NULL;
+ SetPointer(Pointer(POINTER_ARROW));
+ }
+ // else we handle the resizing
+ else if( m_pSizingWin )
+ {
+ SetPointer( Pointer() );
+ EndTracking();
+
+ // die alten physikalischen Koordinaten
+
+ Size szOld = m_pSizingWin->GetSizePixel();
+ Point ptOld = m_pSizingWin->GetPosPixel();
+ Size aNewSize(CalcZoom(m_aSizingRect.GetSize().Width()),CalcZoom(m_aSizingRect.GetSize().Height()));
+ m_pSizingWin->SetPosSizePixel( m_aSizingRect.TopLeft(), aNewSize );
+ TabWinSized(m_pSizingWin, ptOld, szOld);
+
+ m_pSizingWin->Invalidate( m_aSizingRect );
+ m_pSizingWin = NULL;
+ }
+ }
+ else if (rTEvt.IsTrackingCanceled())
+ {
+ if (m_aDragScrollTimer.IsActive())
+ m_aDragScrollTimer.Stop();
+ EndTracking();
+ }
+ else
+ {
+ if( m_pDragWin )
+ {
+ m_ptPrevDraggingPos = rTEvt.GetMouseEvent().GetPosPixel();
+ // an Fenstergrenzen scrollen
+ ScrollWhileDragging();
+ }
+
+ if( m_pSizingWin )
+ {
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+ m_aSizingRect = m_pSizingWin->getSizingRect(aMousePos,m_aOutputSize);
+ Update();
+ ShowTracking( m_aSizingRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::ConnDoubleClicked( OTableConnection* /*pConnection*/ )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::MouseButtonDown( const MouseEvent& rEvt )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ GrabFocus();
+ Window::MouseButtonDown(rEvt);
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::MouseButtonUp( const MouseEvent& rEvt )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ Window::MouseButtonUp(rEvt);
+ //////////////////////////////////////////////////////////////////////
+ // Wurde eine Connection ausgewaehlt?
+ if( !m_vTableConnection.empty() )
+ {
+ DeselectConn(GetSelectedConn());
+
+ ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
+ ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ if( (*aIter)->CheckHit(rEvt.GetPosPixel()) )
+ {
+ SelectConn((*aIter));
+
+ // Doppelclick
+ if( rEvt.GetClicks() == 2 )
+ ConnDoubleClicked( (*aIter) );
+
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::KeyInput( const KeyEvent& rEvt )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
+ sal_Bool bShift = rEvt.GetKeyCode().IsShift();
+ sal_Bool bCtrl = rEvt.GetKeyCode().IsMod1();
+
+ if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
+ {
+ if (GetSelectedConn())
+ RemoveConnection( GetSelectedConn() ,sal_True);
+ }
+ else
+ Window::KeyInput( rEvt );
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::DeselectConn(OTableConnection* pConn)
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ if (!pConn || !pConn->IsSelected())
+ return;
+
+ // die zugehoerigen Eitnraege in der ListBox des Tabellenfenster deselektieren
+ OTableWindow* pWin = pConn->GetSourceWin();
+ if (pWin && pWin->GetListBox())
+ pWin->GetListBox()->SelectAll(sal_False);
+
+ pWin = pConn->GetDestWin();
+ if (pWin && pWin->GetListBox())
+ pWin->GetListBox()->SelectAll(sal_False);
+
+ pConn->Deselect();
+ m_pSelectedConn = NULL;
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::SelectConn(OTableConnection* pConn)
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ DeselectConn(GetSelectedConn());
+
+ pConn->Select();
+ m_pSelectedConn = pConn;
+ GrabFocus(); // has to be called here because a table window may still be focused
+
+ // die betroffenene Eintraege in den Windows selektieren
+ OTableWindow* pConnSource = pConn->GetSourceWin();
+ OTableWindow* pConnDest = pConn->GetDestWin();
+ if (pConnSource && pConnDest)
+ {
+ OTableWindowListBox* pSourceBox = pConnSource->GetListBox();
+ OTableWindowListBox* pDestBox = pConnDest->GetListBox();
+ if (pSourceBox && pDestBox)
+ {
+ pSourceBox->SelectAll(sal_False);
+ pDestBox->SelectAll(sal_False);
+
+ SvLBoxEntry* pFirstSourceVisible = pSourceBox->GetFirstEntryInView();
+ SvLBoxEntry* pFirstDestVisible = pDestBox->GetFirstEntryInView();
+
+ const ::std::vector<OConnectionLine*>* pLines = pConn->GetConnLineList();
+ ::std::vector<OConnectionLine*>::const_reverse_iterator aIter = pLines->rbegin();
+ for(;aIter != pLines->rend();++aIter)
+ {
+ if ((*aIter)->IsValid())
+ {
+ SvLBoxEntry* pSourceEntry = pSourceBox->GetEntryFromText((*aIter)->GetData()->GetSourceFieldName());
+ if (pSourceEntry)
+ {
+ pSourceBox->Select(pSourceEntry, sal_True);
+ pSourceBox->MakeVisible(pSourceEntry);
+ }
+
+ SvLBoxEntry* pDestEntry = pDestBox->GetEntryFromText((*aIter)->GetData()->GetDestFieldName());
+ if (pDestEntry)
+ {
+ pDestBox->Select(pDestEntry, sal_True);
+ pDestBox->MakeVisible(pDestEntry);
+ }
+
+ }
+ }
+
+ if ((pFirstSourceVisible != pSourceBox->GetFirstEntryInView())
+ || (pFirstDestVisible != pDestBox->GetFirstEntryInView()))
+ // es wurde gescrollt -> neu zeichnen
+ Invalidate(INVALIDATE_NOCHILDREN);
+ }
+ }
+}
+//------------------------------------------------------------------------------
+void OJoinTableView::Paint( const Rectangle& rRect )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ DrawConnections( rRect );
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::InvalidateConnections()
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ //////////////////////////////////////////////////////////////////////
+ // Die Joins zeichnen
+ ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),
+ ::std::mem_fun(& OTableConnection::InvalidateConnection));
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::DrawConnections( const Rectangle& rRect )
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ //////////////////////////////////////////////////////////////////////
+ // Die Joins zeichnen
+ ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),boost::bind( &OTableConnection::Draw, _1, boost::cref( rRect )));
+ // zum Schluss noch mal die selektierte ueber alle anderen drueber
+ if (GetSelectedConn())
+ GetSelectedConn()->Draw( rRect );
+}
+
+
+//------------------------------------------------------------------------------
+::std::vector<OTableConnection*>::const_iterator OJoinTableView::getTableConnections(const OTableWindow* _pFromWin) const
+{
+ return ::std::find_if( m_vTableConnection.begin(),
+ m_vTableConnection.end(),
+ ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
+}
+// -----------------------------------------------------------------------------
+sal_Int32 OJoinTableView::getConnectionCount(const OTableWindow* _pFromWin) const
+{
+ return ::std::count_if( m_vTableConnection.begin(),
+ m_vTableConnection.end(),
+ ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
+}
+//------------------------------------------------------------------------------
+sal_Bool OJoinTableView::ExistsAConn(const OTableWindow* pFrom) const
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ return getTableConnections(pFrom) != m_vTableConnection.end();
+}
+//------------------------------------------------------------------------
+void OJoinTableView::ClearAll()
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ SetUpdateMode(sal_False);
+
+ HideTabWins();
+
+ // und das selbe mit den Connections
+ ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
+ ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
+ for(;aIter != aEnd;++aIter)
+ RemoveConnection( *aIter ,sal_True);
+ m_vTableConnection.clear();
+
+ m_pLastFocusTabWin = NULL;
+ m_pSelectedConn = NULL;
+
+ // scroll to the upper left
+ ScrollPane(-GetScrollOffset().X(), sal_True, sal_True);
+ ScrollPane(-GetScrollOffset().Y(), sal_False, sal_True);
+ Invalidate();
+}
+
+//------------------------------------------------------------------------
+sal_Bool OJoinTableView::ScrollWhileDragging()
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ OSL_ENSURE(m_pDragWin != NULL, "OJoinTableView::ScrollWhileDragging darf nur waehrend Dragging eines Fensters aufgerufen werden !");
+
+ // den Timer schon mal killen
+ if (m_aDragScrollTimer.IsActive())
+ m_aDragScrollTimer.Stop();
+
+ Point aDragWinPos = m_ptPrevDraggingPos - m_aDragOffset;
+ Size aDragWinSize = m_pDragWin->GetSizePixel();
+ Point aLowerRight(aDragWinPos.X() + aDragWinSize.Width(), aDragWinPos.Y() + aDragWinSize.Height());
+
+ if (!m_bTrackingInitiallyMoved && (aDragWinPos == m_pDragWin->GetPosPixel()))
+ return sal_True;
+
+ // Darstellungsfehler vermeiden (wenn bei aktivem TrackingRect gescrollt wird)
+ HideTracking();
+
+ sal_Bool bScrolling = sal_False;
+ sal_Bool bNeedScrollTimer = sal_False;
+
+ // An Fenstergrenzen scrollen
+ // TODO : nur dann abfangen, wenn das Fenster komplett verschwinden wuerde (nicht, solange noch ein Pixel sichtbar ist)
+ if( aDragWinPos.X() < 5 )
+ {
+ bScrolling = ScrollPane( -LINE_SIZE, sal_True, sal_True );
+ if( !bScrolling && (aDragWinPos.X()<0) )
+ aDragWinPos.X() = 0;
+
+ // brauche ich weiteres (timergesteuertes) Scrolling ?
+ bNeedScrollTimer = bScrolling && (aDragWinPos.X() < 5);
+ }
+
+ if( aLowerRight.X() > m_aOutputSize.Width() - 5 )
+ {
+ bScrolling = ScrollPane( LINE_SIZE, sal_True, sal_True ) ;
+ if( !bScrolling && ( aLowerRight.X() > m_aOutputSize.Width() ) )
+ aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width();
+
+ // brauche ich weiteres (timergesteuertes) Scrolling ?
+ bNeedScrollTimer = bScrolling && (aLowerRight.X() > m_aOutputSize.Width() - 5);
+ }
+
+ if( aDragWinPos.Y() < 5 )
+ {
+ bScrolling = ScrollPane( -LINE_SIZE, sal_False, sal_True );
+ if( !bScrolling && (aDragWinPos.Y()<0) )
+ aDragWinPos.Y() = 0;
+
+ bNeedScrollTimer = bScrolling && (aDragWinPos.Y() < 5);
+ }
+
+ if( aLowerRight.Y() > m_aOutputSize.Height() - 5 )
+ {
+ bScrolling = ScrollPane( LINE_SIZE, sal_False, sal_True );
+ if( !bScrolling && ( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() ) )
+ aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height();
+
+ bNeedScrollTimer = bScrolling && (aLowerRight.Y() > m_aOutputSize.Height() - 5);
+ }
+
+ // Timer neu setzen, wenn noch notwendig
+ if (bNeedScrollTimer)
+ {
+ m_aDragScrollTimer.SetTimeout(100);
+ m_aDragScrollTimer.Start();
+ }
+
+ // das DraggingRect neu zeichnen
+ m_aDragRect = Rectangle(m_ptPrevDraggingPos - m_aDragOffset, m_pDragWin->GetSizePixel());
+ Update();
+ ShowTracking( m_aDragRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+
+ return bScrolling;
+}
+
+//------------------------------------------------------------------------
+IMPL_LINK(OJoinTableView, OnDragScrollTimer, void*, EMPTYARG)
+{
+ ScrollWhileDragging();
+ return 0L;
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::invalidateAndModify(SfxUndoAction *_pAction)
+{
+ Invalidate(INVALIDATE_NOCHILDREN);
+ m_pView->getController().addUndoActionAndInvalidate(_pAction);
+}
+//------------------------------------------------------------------------
+void OJoinTableView::TabWinMoved(OTableWindow* ptWhich, const Point& ptOldPosition)
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ Point ptThumbPos(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
+ ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel() + ptThumbPos);
+
+ invalidateAndModify(new OJoinMoveTabWinUndoAct(this, ptOldPosition, ptWhich));
+}
+
+//------------------------------------------------------------------------
+void OJoinTableView::TabWinSized(OTableWindow* ptWhich, const Point& ptOldPosition, const Size& szOldSize)
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ ptWhich->GetData()->SetSize(ptWhich->GetSizePixel());
+ ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel());
+
+ invalidateAndModify(new OJoinSizeTabWinUndoAct(this, ptOldPosition, szOldSize, ptWhich));
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OJoinTableView::IsAddAllowed()
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+
+ // nicht wenn Db readonly
+ if (m_pView->getController().isReadOnly())
+ return sal_False;
+
+ try
+ {
+ Reference< XConnection> xConnection = m_pView->getController().getConnection();
+ if(!xConnection.is())
+ return sal_False;
+ // nicht wenn schon zuviele Tabellen
+ Reference < XDatabaseMetaData > xMetaData( xConnection->getMetaData() );
+
+ sal_Int32 nMax = xMetaData.is() ? xMetaData->getMaxTablesInSelect() : 0;
+ if (nMax && nMax <= (sal_Int32)m_aTableMap.size())
+ return sal_False;
+ }
+ catch(SQLException&)
+ {
+ return sal_False;
+ }
+
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::executePopup(const Point& _aPos,OTableConnection* _pSelConnection)
+{
+ PopupMenu aContextMenu( ModuleRes( RID_MENU_JOINVIEW_CONNECTION ) );
+ switch (aContextMenu.Execute(this, _aPos))
+ {
+ case SID_DELETE:
+ RemoveConnection( _pSelConnection ,sal_True);
+ break;
+ case ID_QUERY_EDIT_JOINCONNECTION:
+ ConnDoubleClicked( _pSelConnection ); // is the same as double clicked
+ break;
+ }
+}
+//------------------------------------------------------------------------------
+void OJoinTableView::Command(const CommandEvent& rEvt)
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+
+ sal_Bool bHandled = sal_False;
+
+ switch (rEvt.GetCommand())
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ if( m_vTableConnection.empty() )
+ return;
+
+ OTableConnection* pSelConnection = GetSelectedConn();
+ // when it wasn't a mouse event use the selected connection
+ if (!rEvt.IsMouseEvent())
+ {
+ if( pSelConnection )
+ {
+ const ::std::vector<OConnectionLine*>* pLines = pSelConnection->GetConnLineList();
+ ::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(pLines->begin(),pLines->end(),::std::mem_fun(&OConnectionLine::IsValid));
+ if( aIter != pLines->end() )
+ executePopup((*aIter)->getMidPoint(),pSelConnection);
+ }
+ }
+ else
+ {
+ DeselectConn(pSelConnection);
+
+ const Point& aMousePos = rEvt.GetMousePosPixel();
+ ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
+ ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ if( (*aIter)->CheckHit(aMousePos) )
+ {
+ SelectConn(*aIter);
+ if(!getDesignView()->getController().isReadOnly() && getDesignView()->getController().isConnected())
+ executePopup(rEvt.GetMousePosPixel(),*aIter);
+ break;
+ }
+ }
+ }
+ bHandled = sal_True;
+ }
+ }
+ if (!bHandled)
+ Window::Command(rEvt);
+}
+
+//------------------------------------------------------------------------------
+OTableConnection* OJoinTableView::GetTabConn(const OTableWindow* pLhs,const OTableWindow* pRhs,bool _bSupressCrossOrNaturalJoin,const OTableConnection* _rpFirstAfter) const
+{
+ OTableConnection* pConn = NULL;
+ OSL_ENSURE(pRhs || pLhs, "OJoinTableView::GetTabConn : invalid args !");
+ // only one NULL-arg allowed
+
+ if ((!pLhs || pLhs->ExistsAConn()) && (!pRhs || pRhs->ExistsAConn()))
+ {
+ sal_Bool bFoundStart = _rpFirstAfter ? sal_False : sal_True;
+
+ ::std::vector<OTableConnection*>::const_iterator aIter = m_vTableConnection.begin();
+ ::std::vector<OTableConnection*>::const_iterator aEnd = m_vTableConnection.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableConnection* pData = *aIter;
+
+ if ( ( (pData->GetSourceWin() == pLhs)
+ && ( (pData->GetDestWin() == pRhs)
+ || (NULL == pRhs)
+ )
+ )
+ || ( (pData->GetSourceWin() == pRhs)
+ && ( (pData->GetDestWin() == pLhs)
+ || (NULL == pLhs)
+ )
+ )
+ )
+ {
+ if ( _bSupressCrossOrNaturalJoin )
+ {
+ if ( supressCrossNaturalJoin(pData->GetData()) )
+ continue;
+ }
+ if (bFoundStart)
+ {
+ pConn = pData;
+ break;
+ }
+
+ if (!pConn)
+ // used as fallback : if there is no conn after _rpFirstAfter the first conn between the two tables
+ // will be used
+ pConn = pData;
+
+ if (pData == _rpFirstAfter)
+ bFoundStart = sal_True;
+ }
+ }
+ }
+ return pConn;
+}
+
+//------------------------------------------------------------------------------
+long OJoinTableView::PreNotify(NotifyEvent& rNEvt)
+{
+ sal_Bool bHandled = sal_False;
+ switch (rNEvt.GetType())
+ {
+ case EVENT_COMMAND:
+ {
+ const CommandEvent* pCommand = rNEvt.GetCommandEvent();
+ if (pCommand->GetCommand() == COMMAND_WHEEL)
+ {
+ const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
+ if (pData->GetMode() == COMMAND_WHEEL_SCROLL)
+ {
+ if (pData->GetDelta() > 0)
+ ScrollPane(-10 * pData->GetScrollLines(), pData->IsHorz(), sal_True);
+ else
+ ScrollPane(10 * pData->GetScrollLines(), pData->IsHorz(), sal_True);
+ bHandled = sal_True;
+ }
+ }
+ }
+ break;
+ case EVENT_KEYINPUT:
+ {
+ if (m_aTableMap.empty())
+ // no tab wins -> no conns -> no traveling
+ break;
+
+ const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ if (!pKeyEvent->GetKeyCode().IsMod1())
+ {
+ switch (pKeyEvent->GetKeyCode().GetCode())
+ {
+ case KEY_TAB:
+ {
+ if (!HasChildPathFocus())
+ break;
+
+ sal_Bool bForward = !pKeyEvent->GetKeyCode().IsShift();
+ // is there an active tab win ?
+ OTableWindowMapIterator aIter = m_aTableMap.begin();
+ OTableWindowMapIterator aEnd = m_aTableMap.end();
+ for(;aIter != aEnd;++aIter)
+ if (aIter->second && aIter->second->HasChildPathFocus())
+ break;
+
+ OTableWindow* pNextWin = NULL;
+ OTableConnection* pNextConn = NULL;
+
+ if (aIter != m_aTableMap.end())
+ { // there is a currently active tab win
+ // check if there is an "overflow" and we should select a conn instead of a win
+ if (!m_vTableConnection.empty())
+ {
+ if ((aIter->second == m_aTableMap.rbegin()->second) && bForward)
+ // the last win is active and we're travelling forward -> select the first conn
+ pNextConn = *m_vTableConnection.begin();
+ if ((aIter == m_aTableMap.begin()) && !bForward)
+ // the first win is active an we're traveling backward -> select the last conn
+ pNextConn = *m_vTableConnection.rbegin();
+ }
+
+ if (!pNextConn)
+ {
+ // no conn for any reason -> select the next or previous tab win
+ if(bForward)
+ {
+ if ((aIter->second == m_aTableMap.rbegin()->second))
+ pNextWin = m_aTableMap.begin()->second;
+ else
+ {
+ ++aIter;
+ pNextWin = aIter->second;
+ }
+ }
+ else
+ {
+ if (aIter == m_aTableMap.begin())
+ pNextWin = m_aTableMap.rbegin()->second;
+ else
+ {
+ --aIter;
+ pNextWin = aIter->second;
+ }
+ }
+ }
+ }
+ else
+ { // no active tab win -> travel the connections
+ // find the currently selected conn within the conn list
+ sal_Int32 i(0);
+ for ( ::std::vector<OTableConnection*>::iterator connectionIter = m_vTableConnection.begin();
+ connectionIter != m_vTableConnection.end();
+ ++connectionIter, ++i
+ )
+ {
+ if ( (*connectionIter) == GetSelectedConn() )
+ break;
+ }
+ if (i == sal_Int32(m_vTableConnection.size() - 1) && bForward)
+ // the last conn is active and we're travelling forward -> select the first win
+ pNextWin = m_aTableMap.begin()->second;
+ if ((i == 0) && !bForward && !m_aTableMap.empty())
+ // the first conn is active and we're travelling backward -> select the last win
+ pNextWin = m_aTableMap.rbegin()->second;
+
+ if (pNextWin)
+ DeselectConn(GetSelectedConn());
+ else
+ // no win for any reason -> select the next or previous conn
+ if (i < (sal_Int32)m_vTableConnection.size())
+ // there is a currently active conn
+ pNextConn = m_vTableConnection[(i + (bForward ? 1 : m_vTableConnection.size() - 1)) % m_vTableConnection.size()];
+ else
+ { // no tab win selected, no conn selected
+ if (!m_vTableConnection.empty())
+ pNextConn = m_vTableConnection[bForward ? 0 : m_vTableConnection.size() - 1];
+ else if (!m_aTableMap.empty())
+ {
+ if(bForward)
+ pNextWin = m_aTableMap.begin()->second;
+ else
+ pNextWin = m_aTableMap.rbegin()->second;
+ }
+ }
+ }
+
+ // now select the object
+ if (pNextWin)
+ {
+ if (pNextWin->GetListBox())
+ pNextWin->GetListBox()->GrabFocus();
+ else
+ pNextWin->GrabFocus();
+ EnsureVisible(pNextWin);
+ }
+ else if (pNextConn)
+ {
+ GrabFocus();
+ // neccessary : a conn may be selected even if a tab win has the focus, in this case
+ // the next travel would select the same conn again if we would not reset te focus ...
+ SelectConn(pNextConn);
+ }
+ }
+ break;
+ case KEY_RETURN:
+ {
+ if (!pKeyEvent->GetKeyCode().IsShift() && GetSelectedConn() && HasFocus())
+ ConnDoubleClicked(GetSelectedConn());
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case EVENT_GETFOCUS:
+ {
+ if (m_aTableMap.empty())
+ // no tab wins -> no conns -> no focus change
+ break;
+ Window* pSource = rNEvt.GetWindow();
+ if (pSource)
+ {
+ Window* pSearchFor = NULL;
+ if (pSource->GetParent() == this)
+ // it may be one of the tab wins
+ pSearchFor = pSource;
+ else if (pSource->GetParent() && (pSource->GetParent()->GetParent() == this))
+ // it may be one of th list boxes of one of the tab wins
+ pSearchFor = pSource->GetParent();
+
+ if (pSearchFor)
+ {
+ OTableWindowMapIterator aIter = m_aTableMap.begin();
+ OTableWindowMapIterator aEnd = m_aTableMap.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ if (aIter->second == pSearchFor)
+ {
+ m_pLastFocusTabWin = aIter->second;
+ break;
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ if (!bHandled)
+ return Window::PreNotify(rNEvt);
+ return 1L;
+}
+
+//------------------------------------------------------------------------------
+void OJoinTableView::GrabTabWinFocus()
+{
+ if (m_pLastFocusTabWin && m_pLastFocusTabWin->IsVisible())
+ {
+ if (m_pLastFocusTabWin->GetListBox())
+ m_pLastFocusTabWin->GetListBox()->GrabFocus();
+ else
+ m_pLastFocusTabWin->GrabFocus();
+ }
+ else if (!m_aTableMap.empty() && m_aTableMap.begin()->second && m_aTableMap.begin()->second->IsVisible())
+ {
+ OTableWindow* pFirstWin = m_aTableMap.begin()->second;
+ if (pFirstWin->GetListBox())
+ pFirstWin->GetListBox()->GrabFocus();
+ else
+ pFirstWin->GrabFocus();
+ }
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_ZOOM )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Font aFont = rStyleSettings.GetGroupFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+
+ OTableWindowMapIterator aIter = m_aTableMap.begin();
+ OTableWindowMapIterator aEnd = m_aTableMap.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ aIter->second->SetZoom(GetZoom());
+ Size aSize(CalcZoom(aIter->second->GetSizePixel().Width()),CalcZoom(aIter->second->GetSizePixel().Height()));
+ aIter->second->SetSizePixel(aSize);
+ }
+ Resize();
+ }
+}
+//------------------------------------------------------------------------------
+void OJoinTableView::HideTabWins()
+{
+ DBG_CHKTHIS(OJoinTableView,NULL);
+ SetUpdateMode(sal_False);
+
+ OTableWindowMap* pTabWins = GetTabWinMap();
+ if ( pTabWins )
+ {
+ // working on a copy because the real list will be cleared in inner calls
+ OTableWindowMap aCopy(*pTabWins);
+ OTableWindowMap::iterator aIter = aCopy.begin();
+ OTableWindowMap::iterator aEnd = aCopy.end();
+ for(;aIter != aEnd;++aIter)
+ RemoveTabWin(aIter->second);
+ }
+
+ m_pView->getController().setModified(sal_True);
+
+ SetUpdateMode(sal_True);
+
+}
+// -----------------------------------------------------------------------------
+sal_Int8 OJoinTableView::AcceptDrop( const AcceptDropEvent& /*_rEvt*/ )
+{
+ return DND_ACTION_NONE;
+}
+// -----------------------------------------------------------------------------
+sal_Int8 OJoinTableView::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
+{
+ return DND_ACTION_NONE;
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::dragFinished( )
+{
+}
+//------------------------------------------------------------------------------
+void OJoinTableView::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
+{
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::clearLayoutInformation()
+{
+ m_pLastFocusTabWin = NULL;
+ m_pSelectedConn = NULL;
+ //////////////////////////////////////////////////////////////////////
+ // Listen loeschen
+ OTableWindowMapIterator aIter = m_aTableMap.begin();
+ OTableWindowMapIterator aEnd = m_aTableMap.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ if ( aIter->second )
+ aIter->second->clearListBox();
+ ::std::auto_ptr<Window> aTemp(aIter->second);
+ aIter->second = NULL;
+ }
+
+ m_aTableMap.clear();
+
+ ::std::vector<OTableConnection*>::const_iterator aIter2 = m_vTableConnection.begin();
+ ::std::vector<OTableConnection*>::const_iterator aEnd2 = m_vTableConnection.end();
+ for(;aIter2 != aEnd2;++aIter2)
+ delete *aIter2;
+
+ m_vTableConnection.clear();
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::lookForUiActivities()
+{
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::LoseFocus()
+{
+ DeselectConn(GetSelectedConn());
+ Window::LoseFocus();
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::GetFocus()
+{
+ Window::GetFocus();
+ if ( !m_aTableMap.empty() && !GetSelectedConn() )
+ GrabTabWinFocus();
+}
+// -----------------------------------------------------------------------------
+Reference< XAccessible > OJoinTableView::CreateAccessible()
+{
+ m_pAccessible = new OJoinDesignViewAccess(this);
+ return m_pAccessible;
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::modified()
+{
+ OJoinController& rController = m_pView->getController();
+ rController.setModified( sal_True );
+ rController.InvalidateFeature(ID_BROWSER_ADDTABLE);
+ rController.InvalidateFeature(SID_RELATION_ADD_RELATION);
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::addConnection(OTableConnection* _pConnection,sal_Bool _bAddData)
+{
+ if ( _bAddData )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ TTableConnectionData* pTabConnDataList = m_pView->getController().getTableConnectionData();
+ OSL_ENSURE( ::std::find(pTabConnDataList->begin(),pTabConnDataList->end(),_pConnection->GetData()) == pTabConnDataList->end(),"Data already in vector!");
+#endif
+ m_pView->getController().getTableConnectionData()->push_back(_pConnection->GetData());
+ }
+ m_vTableConnection.push_back(_pConnection);
+ _pConnection->RecalcLines();
+ _pConnection->InvalidateConnection();
+
+ modified();
+ if ( m_pAccessible )
+ m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
+ Any(),
+ makeAny(_pConnection->GetAccessible()));
+}
+// -----------------------------------------------------------------------------
+bool OJoinTableView::allowQueries() const
+{
+ return true;
+}
+// -----------------------------------------------------------------------------
+void OJoinTableView::onNoColumns_throw()
+{
+ OSL_FAIL( "OTableWindow::onNoColumns_throw: cannot really handle this!" );
+ throw SQLException();
+}
+//------------------------------------------------------------------------------
+bool OJoinTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& ) const
+{
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QTableConnection.cxx b/dbaccess/source/ui/querydesign/QTableConnection.cxx
new file mode 100644
index 000000000000..8e18232e02ff
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QTableConnection.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "QTableConnection.hxx"
+#include <osl/diagnose.h>
+#include "QueryTableView.hxx"
+#include "ConnectionLine.hxx"
+using namespace dbaui;
+//========================================================================
+// class OQueryTableConnection
+//========================================================================
+DBG_NAME(OQueryTableConnection)
+
+//------------------------------------------------------------------------
+OQueryTableConnection::OQueryTableConnection(OQueryTableView* pContainer, const TTableConnectionData::value_type& pTabConnData)
+ :OTableConnection(pContainer, pTabConnData)
+ ,m_bVisited(sal_False)
+{
+ DBG_CTOR(OQueryTableConnection,NULL);
+}
+
+//------------------------------------------------------------------------
+OQueryTableConnection::OQueryTableConnection(const OQueryTableConnection& rConn)
+ :OTableConnection( rConn )
+{
+ DBG_CTOR(OQueryTableConnection,NULL);
+ // keine eigenen Members, also reicht die Basisklassenfunktionalitaet
+}
+//------------------------------------------------------------------------
+OQueryTableConnection::~OQueryTableConnection()
+{
+ DBG_DTOR(OQueryTableConnection,NULL);
+}
+
+//------------------------------------------------------------------------
+OQueryTableConnection& OQueryTableConnection::operator=(const OQueryTableConnection& rConn)
+{
+ if (&rConn == this)
+ return *this;
+
+ OTableConnection::operator=(rConn);
+ // keine eigenen Members ...
+ return *this;
+}
+
+//------------------------------------------------------------------------
+sal_Bool OQueryTableConnection::operator==(const OQueryTableConnection& rCompare)
+{
+ OSL_ENSURE(GetData() && rCompare.GetData(), "OQueryTableConnection::operator== : einer der beiden Teilnehmer hat keine Daten !");
+
+ // allzuviel brauche ich nicht vergleichen (schon gar nicht alle Member) : lediglich die Fenster, an denen wir haengen, und
+ // die Indizies in der entsprechenden Tabelle muessen uebereinstimmen
+ OQueryTableConnectionData* pMyData = static_cast<OQueryTableConnectionData*>(GetData().get());
+ OQueryTableConnectionData* pCompData = static_cast<OQueryTableConnectionData*>(rCompare.GetData().get());
+
+ // Connections werden als gleich angesehen, wenn sie in Source-/Dest-Fenstername und Source-/Dest-FieldIndex uebereinstimmen ...
+ return ( ( (pMyData->getReferencedTable() == pCompData->getReferencedTable()) &&
+ (pMyData->getReferencingTable() == pCompData->getReferencingTable()) &&
+ (pMyData->GetFieldIndex(JTCS_TO) == pCompData->GetFieldIndex(JTCS_TO)) &&
+ (pMyData->GetFieldIndex(JTCS_FROM) == pCompData->GetFieldIndex(JTCS_FROM))
+ )
+ || // ... oder diese Uebereinstimmung ueber Kreuz besteht
+ ( (pMyData->getReferencingTable() == pCompData->getReferencedTable()) &&
+ (pMyData->getReferencedTable() == pCompData->getReferencingTable()) &&
+ (pMyData->GetFieldIndex(JTCS_TO) == pCompData->GetFieldIndex(JTCS_FROM)) &&
+ (pMyData->GetFieldIndex(JTCS_FROM) == pCompData->GetFieldIndex(JTCS_TO))
+ )
+ );
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QTableConnection.hxx b/dbaccess/source/ui/querydesign/QTableConnection.hxx
new file mode 100644
index 000000000000..a2402acab43b
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QTableConnection.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERYTABLECONNECTION_HXX
+#define DBAUI_QUERYTABLECONNECTION_HXX
+
+#include "TableConnection.hxx"
+#include "QTableConnectionData.hxx"
+#include "QEnumTypes.hxx"
+
+namespace dbaui
+{
+ //==================================================================
+ class OQueryTableView;
+ class OQueryTableConnection : public OTableConnection
+ {
+ sal_Bool m_bVisited; // is true if the conn was already visited through the join algorithm
+ public:
+ OQueryTableConnection(OQueryTableView* pContainer, const TTableConnectionData::value_type& pTabConnData);
+ OQueryTableConnection(const OQueryTableConnection& rConn);
+ virtual ~OQueryTableConnection();
+
+ OQueryTableConnection& operator=(const OQueryTableConnection& rConn);
+ sal_Bool operator==(const OQueryTableConnection& rCompare);
+
+ inline ::rtl::OUString GetAliasName(EConnectionSide nWhich) const { return static_cast<OQueryTableConnectionData*>(GetData().get())->GetAliasName(nWhich); }
+
+ inline sal_Bool IsVisited() const { return m_bVisited; }
+ inline void SetVisited(sal_Bool bVisited) { m_bVisited = bVisited; }
+
+ };
+}
+#endif // DBAUI_QUERYTABLECONNECTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QTableConnectionData.cxx b/dbaccess/source/ui/querydesign/QTableConnectionData.cxx
new file mode 100644
index 000000000000..fc702cf94cfa
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QTableConnectionData.cxx
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "QTableConnectionData.hxx"
+#include <tools/debug.hxx>
+#include "QTableConnectionData.hxx"
+#include "QTableWindow.hxx"
+
+using namespace dbaui;
+
+//========================================================================
+// class OQueryTableConnectionData
+//========================================================================
+DBG_NAME(OQueryTableConnectionData)
+//------------------------------------------------------------------------
+OQueryTableConnectionData::OQueryTableConnectionData()
+ :OTableConnectionData()
+ ,m_eJoinType (INNER_JOIN)
+ ,m_bNatural(false)
+{
+ DBG_CTOR(OQueryTableConnectionData,NULL);
+}
+
+//------------------------------------------------------------------------
+OQueryTableConnectionData::OQueryTableConnectionData( const OQueryTableConnectionData& rConnData )
+ :OTableConnectionData( rConnData )
+{
+ DBG_CTOR(OQueryTableConnectionData,NULL);
+ m_nFromEntryIndex = rConnData.m_nFromEntryIndex;
+ m_nDestEntryIndex = rConnData.m_nDestEntryIndex;
+
+ m_eFromType = rConnData.m_eFromType;
+ m_eDestType = rConnData.m_eDestType;
+ m_eJoinType = rConnData.m_eJoinType;
+ m_bNatural = rConnData.m_bNatural;
+}
+
+//------------------------------------------------------------------------
+OQueryTableConnectionData::OQueryTableConnectionData(const TTableWindowData::value_type& _pReferencingTable
+ ,const TTableWindowData::value_type& _pReferencedTable
+ ,const ::rtl::OUString& rConnName)
+ :OTableConnectionData( _pReferencingTable,_pReferencedTable, rConnName )
+ ,m_nFromEntryIndex(0)
+ ,m_nDestEntryIndex(0)
+ ,m_eJoinType (INNER_JOIN)
+ ,m_bNatural(false)
+ ,m_eFromType(TAB_NORMAL_FIELD)
+ ,m_eDestType(TAB_NORMAL_FIELD)
+{
+ DBG_CTOR(OQueryTableConnectionData,NULL);
+}
+
+//------------------------------------------------------------------------
+OQueryTableConnectionData::~OQueryTableConnectionData()
+{
+ DBG_DTOR(OQueryTableConnectionData,NULL);
+}
+
+//------------------------------------------------------------------------
+OConnectionLineDataRef OQueryTableConnectionData::CreateLineDataObj()
+{
+ DBG_CHKTHIS(OQueryTableConnectionData,NULL);
+ // keine Spezialisierung bei den LineDatas, also eine Instanz der Standard-Klasse
+ return new OConnectionLineData();
+}
+
+//------------------------------------------------------------------------
+OConnectionLineDataRef OQueryTableConnectionData::CreateLineDataObj( const OConnectionLineData& rConnLineData )
+{
+ DBG_CHKTHIS(OQueryTableConnectionData,NULL);
+ return new OConnectionLineData( rConnLineData );
+}
+
+//------------------------------------------------------------------------
+void OQueryTableConnectionData::CopyFrom(const OTableConnectionData& rSource)
+{
+ DBG_CHKTHIS(OQueryTableConnectionData,NULL);
+ // wie in der Basisklasse zurueckziehen auf das (nicht-virtuelle) operator=
+ *this = (const OQueryTableConnectionData&)rSource;
+}
+
+//------------------------------------------------------------------------
+OQueryTableConnectionData& OQueryTableConnectionData::operator=(const OQueryTableConnectionData& rConnData)
+{
+ DBG_CHKTHIS(OQueryTableConnectionData,NULL);
+ if (&rConnData == this)
+ return *this;
+
+ OTableConnectionData::operator=(rConnData);
+
+ m_nFromEntryIndex = rConnData.m_nFromEntryIndex;
+ m_nDestEntryIndex = rConnData.m_nDestEntryIndex;
+
+ m_eFromType = rConnData.m_eFromType;
+ m_eDestType = rConnData.m_eDestType;
+ m_eJoinType = rConnData.m_eJoinType;
+ m_bNatural = rConnData.m_bNatural;
+
+ return *this;
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString OQueryTableConnectionData::GetAliasName(EConnectionSide nWhich) const
+{
+ DBG_CHKTHIS(OQueryTableConnectionData,NULL);
+ return nWhich == JTCS_FROM ? m_pReferencingTable->GetWinName() : m_pReferencedTable->GetWinName();
+}
+
+//------------------------------------------------------------------------------
+void OQueryTableConnectionData::InitFromDrag(const OTableFieldDescRef& rDragLeft, const OTableFieldDescRef& rDragRight)
+{
+ DBG_CHKTHIS(OQueryTableConnectionData,NULL);
+ // die Infos in rDrag in Parameter fuer das Basisklassen-Init umsetzen ...
+ OQueryTableWindow* pSourceWin = static_cast<OQueryTableWindow*>(rDragLeft->GetTabWindow());
+ OQueryTableWindow* pDestWin = static_cast<OQueryTableWindow*>(rDragRight->GetTabWindow());
+ OSL_ENSURE(pSourceWin,"NO Source window found!");
+ OSL_ENSURE(pDestWin,"NO Dest window found!");
+ m_pReferencingTable = pSourceWin->GetData();
+ m_pReferencedTable = pDestWin->GetData();
+
+ // und dann meine Members setzen
+ SetFieldIndex(JTCS_FROM, rDragLeft->GetFieldIndex());
+ SetFieldIndex(JTCS_TO, rDragRight->GetFieldIndex());
+
+ SetFieldType(JTCS_FROM, rDragLeft->GetFieldType());
+ SetFieldType(JTCS_TO, rDragRight->GetFieldType());
+
+ AppendConnLine((::rtl::OUString)rDragLeft->GetField(),(::rtl::OUString)rDragRight->GetField());
+}
+// -----------------------------------------------------------------------------
+OTableConnectionData* OQueryTableConnectionData::NewInstance() const
+{
+ return new OQueryTableConnectionData();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryTableConnectionData::Update()
+{
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QTableConnectionData.hxx b/dbaccess/source/ui/querydesign/QTableConnectionData.hxx
new file mode 100644
index 000000000000..0b4c78d394a5
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QTableConnectionData.hxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QTABLECONNECTIONDATA_HXX
+#define DBAUI_QTABLECONNECTIONDATA_HXX
+
+#include "TableConnectionData.hxx"
+#include "TableFieldDescription.hxx"
+#include "QEnumTypes.hxx"
+#include <tools/rtti.hxx>
+
+namespace dbaui
+{
+ class OQueryTableConnectionData : public OTableConnectionData
+ {
+ sal_Int32 m_nFromEntryIndex;
+ sal_Int32 m_nDestEntryIndex;
+ EJoinType m_eJoinType;
+ bool m_bNatural;
+
+ ETableFieldType m_eFromType;
+ ETableFieldType m_eDestType;
+
+ protected:
+ // fuer das Anlegen und Duplizieren von Lines vom eigenen Typ
+ virtual OConnectionLineDataRef CreateLineDataObj();
+ virtual OConnectionLineDataRef CreateLineDataObj( const OConnectionLineData& rConnLineData );
+
+ OQueryTableConnectionData& operator=( const OQueryTableConnectionData& rConnData );
+ public:
+ OQueryTableConnectionData();
+ OQueryTableConnectionData( const OQueryTableConnectionData& rConnData );
+ OQueryTableConnectionData( const TTableWindowData::value_type& _pReferencingTable,const TTableWindowData::value_type& _pReferencedTable,
+ const ::rtl::OUString& rConnName=::rtl::OUString());
+ virtual ~OQueryTableConnectionData();
+
+ virtual void CopyFrom(const OTableConnectionData& rSource);
+ virtual OTableConnectionData* NewInstance() const;
+
+
+ /** Update create a new connection
+
+ @return true if successful
+ */
+ virtual sal_Bool Update();
+
+ ::rtl::OUString GetAliasName(EConnectionSide nWhich) const;
+
+ sal_Int32 GetFieldIndex(EConnectionSide nWhich) const { return nWhich==JTCS_TO ? m_nDestEntryIndex : m_nFromEntryIndex; }
+ void SetFieldIndex(EConnectionSide nWhich, sal_Int32 nVal) { if (nWhich==JTCS_TO) m_nDestEntryIndex=nVal; else m_nFromEntryIndex=nVal; }
+
+ ETableFieldType GetFieldType(EConnectionSide nWhich) const { return nWhich==JTCS_TO ? m_eDestType : m_eFromType; }
+ void SetFieldType(EConnectionSide nWhich, ETableFieldType eType) { if (nWhich==JTCS_TO) m_eDestType=eType; else m_eFromType=eType; }
+
+ void InitFromDrag(const OTableFieldDescRef& rDragLeft, const OTableFieldDescRef& rDragRight);
+
+ EJoinType GetJoinType() const { return m_eJoinType; };
+ void SetJoinType(const EJoinType& eJT) { m_eJoinType = eJT; };
+
+ inline void setNatural(bool _bNatural) { m_bNatural = _bNatural; }
+ inline bool isNatural() const { return m_bNatural; }
+ };
+
+}
+#endif // DBAUI_QTABLECONNECTIONDATA_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QTableWindow.cxx b/dbaccess/source/ui/querydesign/QTableWindow.cxx
new file mode 100644
index 000000000000..e20ca59c5494
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QTableWindow.cxx
@@ -0,0 +1,241 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "QTableWindow.hxx"
+#include "QueryTableView.hxx"
+#include "dbustrings.hrc"
+#include <osl/diagnose.h>
+#include "dbaccess_helpid.hrc"
+#include "QueryDesignView.hxx"
+#include "browserids.hxx"
+#include "querycontroller.hxx"
+#include <vcl/image.hxx>
+#include "TableWindowListBox.hxx"
+#include "dbu_qry.hrc"
+#include "Query.hrc"
+#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include "TableFieldInfo.hxx"
+#include <comphelper/uno3.hxx>
+#include <comphelper/extract.hxx>
+#include "UITools.hxx"
+
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace dbaui;
+//========================================================================
+// class OQueryTableWindow
+//========================================================================
+DBG_NAME(OQueryTableWindow)
+//------------------------------------------------------------------------------
+OQueryTableWindow::OQueryTableWindow( Window* pParent, const TTableWindowData::value_type& pTabWinData, sal_Unicode* pszInitialAlias)
+ :OTableWindow( pParent, pTabWinData )
+ ,m_nAliasNum(0)
+{
+ DBG_CTOR(OQueryTableWindow,NULL);
+ if (pszInitialAlias != NULL)
+ m_strInitialAlias = ::rtl::OUString(pszInitialAlias);
+ else
+ m_strInitialAlias = GetAliasName();
+
+ // wenn der Tabellen- gleich dem Aliasnamen ist, dann darf ich das nicht an InitialAlias weiterreichen, denn das Anhaengen
+ // eines eventuelle Tokens nicht klappen ...
+ if (m_strInitialAlias == pTabWinData->GetTableName())
+ m_strInitialAlias = ::rtl::OUString();
+
+ SetHelpId(HID_CTL_QRYDGNTAB);
+}
+
+//------------------------------------------------------------------------------
+OQueryTableWindow::~OQueryTableWindow()
+{
+ DBG_DTOR(OQueryTableWindow,NULL);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OQueryTableWindow::Init()
+{
+ sal_Bool bSuccess = OTableWindow::Init();
+ if(!bSuccess)
+ return bSuccess;
+
+ OQueryTableView* pContainer = static_cast<OQueryTableView*>(getTableView());
+
+ // zuerst Alias bestimmen
+ ::rtl::OUString sAliasName;
+
+ TTableWindowData::value_type pWinData = GetData();
+
+ if (m_strInitialAlias.getLength() )
+ // Der Alias wurde explizit mit angegeben
+ sAliasName = m_strInitialAlias;
+ else if ( GetTable().is() )
+ GetTable()->getPropertyValue( PROPERTY_NAME ) >>= sAliasName;
+ else
+ return sal_False;
+
+ // Alias mit fortlaufender Nummer versehen
+ if (pContainer->CountTableAlias(sAliasName, m_nAliasNum))
+ {
+ sAliasName += ::rtl::OUString('_');
+ sAliasName += ::rtl::OUString::valueOf(m_nAliasNum);
+ }
+
+
+ sAliasName = String(sAliasName).EraseAllChars('"');
+ SetAliasName(sAliasName);
+ // SetAliasName reicht das als WinName weiter, dadurch benutzt es die Basisklasse
+ // reset the title
+ m_aTitle.SetText( pWinData->GetWinName() );
+ m_aTitle.Show();
+
+ if (!bSuccess)
+ { // es soll nur ein Dummy-Window aufgemacht werden ...
+ OSL_ENSURE(GetAliasName().getLength(), "OQueryTableWindow::Init : kein Alias- UND kein Tabellenname geht nicht !");
+ // .. aber das braucht wenigstens einen Alias
+
+ // ::com::sun::star::form::ListBox anlegen
+ if (!m_pListBox)
+ m_pListBox = CreateListBox();
+
+ // Titel setzen
+ m_aTitle.SetText(GetAliasName());
+ m_aTitle.Show();
+
+ clearListBox();
+ // neu zu fuellen brauche ich die nicht, da ich ja keine Tabelle habe
+ m_pListBox->Show();
+ }
+
+ getTableView()->getDesignView()->getController().InvalidateFeature(ID_BROWSER_QUERY_EXECUTE);
+ return bSuccess;
+}
+// -----------------------------------------------------------------------------
+void* OQueryTableWindow::createUserData(const Reference< XPropertySet>& _xColumn,bool _bPrimaryKey)
+{
+ OTableFieldInfo* pInfo = new OTableFieldInfo();
+ pInfo->SetKey(_bPrimaryKey ? TAB_PRIMARY_FIELD : TAB_NORMAL_FIELD);
+ if ( _xColumn.is() )
+ pInfo->SetDataType(::comphelper::getINT32(_xColumn->getPropertyValue(PROPERTY_TYPE)));
+ return pInfo;
+}
+// -----------------------------------------------------------------------------
+void OQueryTableWindow::deleteUserData(void*& _pUserData)
+{
+ delete static_cast<OTableFieldInfo*>(_pUserData);
+ _pUserData = NULL;
+}
+//------------------------------------------------------------------------------
+void OQueryTableWindow::OnEntryDoubleClicked(SvLBoxEntry* pEntry)
+{
+ OSL_ENSURE(pEntry != NULL, "OQueryTableWindow::OnEntryDoubleClicked : pEntry darf nicht NULL sein !");
+ // man koennte das auch abfragen und dann ein return hinsetzen, aber so weist es vielleicht auf Fehler bei Aufrufer hin
+
+ if (getTableView()->getDesignView()->getController().isReadOnly())
+ return;
+
+ OTableFieldInfo* pInf = static_cast<OTableFieldInfo*>(pEntry->GetUserData());
+ OSL_ENSURE(pInf != NULL, "OQueryTableWindow::OnEntryDoubleClicked : Feld hat keine FieldInfo !");
+
+ // eine DragInfo aufbauen
+ OTableFieldDescRef aInfo = new OTableFieldDesc(GetTableName(),m_pListBox->GetEntryText(pEntry));
+ aInfo->SetTabWindow(this);
+ aInfo->SetAlias(GetAliasName());
+ aInfo->SetFieldIndex(m_pListBox->GetModel()->GetAbsPos(pEntry));
+ aInfo->SetDataType(pInf->GetDataType());
+
+ // und das entsprechende Feld einfuegen
+ static_cast<OQueryTableView*>(getTableView())->InsertField(aInfo);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OQueryTableWindow::ExistsField(const ::rtl::OUString& strFieldName, OTableFieldDescRef& rInfo)
+{
+ OSL_ENSURE(m_pListBox != NULL, "OQueryTableWindow::ExistsField : habe keine ::com::sun::star::form::ListBox !");
+ OSL_ENSURE(rInfo.is(),"OQueryTableWindow::ExistsField: invlid argument for OTableFieldDescRef!");
+ Reference< XConnection> xConnection = getTableView()->getDesignView()->getController().getConnection();
+ sal_Bool bExists = sal_False;
+ if(xConnection.is())
+ {
+ SvLBoxEntry* pEntry = m_pListBox->First();
+ try
+ {
+ Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
+ ::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
+
+ while (pEntry)
+ {
+ if (bCase(strFieldName,::rtl::OUString(m_pListBox->GetEntryText(pEntry))))
+ {
+ OTableFieldInfo* pInf = static_cast<OTableFieldInfo*>(pEntry->GetUserData());
+ OSL_ENSURE(pInf != NULL, "OQueryTableWindow::ExistsField : Feld hat keine FieldInfo !");
+
+ rInfo->SetTabWindow(this);
+ rInfo->SetField(strFieldName);
+ rInfo->SetTable(GetTableName());
+ rInfo->SetAlias(GetAliasName());
+ rInfo->SetFieldIndex(m_pListBox->GetModel()->GetAbsPos(pEntry));
+ rInfo->SetDataType(pInf->GetDataType());
+ bExists = sal_True;
+ break;
+ }
+ pEntry = m_pListBox->Next(pEntry);
+ }
+ }
+ catch(SQLException&)
+ {
+ }
+ }
+
+ return bExists;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OQueryTableWindow::ExistsAVisitedConn() const
+{
+ return static_cast<const OQueryTableView*>(getTableView())->ExistsAVisitedConn(this);
+}
+
+//------------------------------------------------------------------------------
+void OQueryTableWindow::KeyInput( const KeyEvent& rEvt )
+{
+ OTableWindow::KeyInput( rEvt );
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QTableWindow.hxx b/dbaccess/source/ui/querydesign/QTableWindow.hxx
new file mode 100644
index 000000000000..16b5097ca6d0
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QTableWindow.hxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERY_TABLEWINDOW_HXX
+#define DBAUI_QUERY_TABLEWINDOW_HXX
+
+#include "TableWindow.hxx"
+#include "QTableWindowData.hxx"
+#include "TableFieldDescription.hxx"
+#include <tools/rtti.hxx>
+
+namespace dbaui
+{
+ //==================================================================
+ class OQueryTableWindow : public OTableWindow
+ {
+ sal_Int32 m_nAliasNum;
+ ::rtl::OUString m_strInitialAlias;
+ public:
+ OQueryTableWindow( Window* pParent, const TTableWindowData::value_type& pTabWinData, sal_Unicode* pszInitialAlias = NULL );
+ virtual ~OQueryTableWindow();
+
+ ::rtl::OUString GetAliasName() const
+ {
+ return static_cast<OQueryTableWindowData*>(GetData().get())->GetAliasName();
+ }
+ void SetAliasName(const ::rtl::OUString& strNewAlias)
+ {
+ static_cast<OQueryTableWindowData*>(GetData().get())->SetAliasName(strNewAlias);
+ }
+
+ // spaeter Constructor, die Basisklasse ERZEUGT beim ersten Aufruf die Listbox
+ virtual sal_Bool Init();
+
+ inline sal_Int32 GetAliasNum() const { return m_nAliasNum; }
+
+ sal_Bool ExistsField(const ::rtl::OUString& strFieldName, OTableFieldDescRef& rInfo);
+ sal_Bool ExistsAVisitedConn() const;
+
+ virtual ::rtl::OUString GetName() const { return GetWinName(); }
+
+ protected:
+ virtual void KeyInput( const KeyEvent& rEvt );
+
+ virtual void OnEntryDoubleClicked(SvLBoxEntry* pEntry);
+ // wird aus dem DoubleClickHdl der ListBox heraus aufgerufen
+ /** delete the user data with the equal type as created within createUserData
+ @param _pUserData
+ The user data store in the listbox entries. Created with a call to createUserData.
+ _pUserData may be <NULL/>.
+ */
+ virtual void deleteUserData(void*& _pUserData);
+
+ /** creates user information that will be append at the ListBoxentry
+ @param _xColumn
+ The corresponding column, can be <NULL/>.
+ @param _bPrimaryKey
+ <TRUE/> when the column belongs to the primary key
+ @return
+ the user data which will be append at the listbox entry, may be <NULL/>
+ */
+ virtual void* createUserData(const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet>& _xColumn,
+ bool _bPrimaryKey);
+ };
+}
+#endif // DBAUI_QUERY_TABLEWINDOW_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QTableWindowData.cxx b/dbaccess/source/ui/querydesign/QTableWindowData.cxx
new file mode 100644
index 000000000000..5fc047a9fbcf
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QTableWindowData.cxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "QTableWindowData.hxx"
+#include <tools/debug.hxx>
+
+
+using namespace dbaui;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+DBG_NAME(OQueryTableWindowData)
+//==================================================================
+// class OQueryTableWindowData
+//==================================================================
+//------------------------------------------------------------------------------
+OQueryTableWindowData::OQueryTableWindowData(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& rTableName, const ::rtl::OUString& rTableAlias )
+ :OTableWindowData(NULL,_rComposedName, rTableName, rTableAlias)
+{
+ DBG_CTOR(OQueryTableWindowData,NULL);
+}
+
+//------------------------------------------------------------------------------
+OQueryTableWindowData::~OQueryTableWindowData()
+{
+ DBG_DTOR(OQueryTableWindowData,NULL);
+}
+// -----------------------------------------------------------------------------
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QTableWindowData.hxx b/dbaccess/source/ui/querydesign/QTableWindowData.hxx
new file mode 100644
index 000000000000..9a54e738a764
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QTableWindowData.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERY_TABLEWINDOWDATA_HXX
+#define DBAUI_QUERY_TABLEWINDOWDATA_HXX
+
+#include "TableWindowData.hxx"
+#ifndef INCLUDED_VECTOR
+#define INCLUDED_VECTOR
+#include <vector>
+#endif
+#include <com/sun/star/io/XObjectOutputStream.hpp>
+#include <com/sun/star/io/XObjectInputStream.hpp>
+
+
+namespace dbaui
+{
+ class OQueryTableWindowData : public OTableWindowData
+ {
+ public:
+ explicit OQueryTableWindowData(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& rTableName, const ::rtl::OUString& rTableAlias);
+ virtual ~OQueryTableWindowData();
+
+ ::rtl::OUString GetAliasName() { return GetWinName(); }
+ void SetAliasName(const ::rtl::OUString& rNewAlias) { SetWinName(rNewAlias); }
+ };
+}
+#endif // DBAUI_QUERY_TABLEWINDOWDATA_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/Query.hrc b/dbaccess/source/ui/querydesign/Query.hrc
new file mode 100644
index 000000000000..6fb9bb9ac5d0
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/Query.hrc
@@ -0,0 +1,35 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERY_HRC
+#define DBAUI_QUERY_HRC
+
+#define IMG_PRIMARY_KEY 1
+#define IMG_FOREIGN_KEY 2
+
+
+#endif // DBAUI_QUERY_HRC
+
diff --git a/dbaccess/source/ui/querydesign/QueryAddTabConnUndoAction.hxx b/dbaccess/source/ui/querydesign/QueryAddTabConnUndoAction.hxx
new file mode 100644
index 000000000000..c0ef7d5ef1ef
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryAddTabConnUndoAction.hxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERYADDTABCONNUNDOACTION_HXX
+#define DBAUI_QUERYADDTABCONNUNDOACTION_HXX
+
+#include "QueryTabConnUndoAction.hxx"
+
+namespace dbaui
+{
+ // ================================================================================================
+ // OQueryAddTabConnUndoAction - Undo-Klasse fuer Einfuegen einer Connection
+
+ class OQueryTableView;
+ class OQueryAddTabConnUndoAction : public OQueryTabConnUndoAction
+ {
+ public:
+ OQueryAddTabConnUndoAction(OQueryTableView* pOwner);
+
+ virtual void Undo();
+ virtual void Redo();
+ };
+
+ // ================================================================================================
+ // OQueryDelTabConnUndoAction - Undo-Klasse fuer Einfuegen einer Connection
+
+ class OQueryDelTabConnUndoAction : public OQueryTabConnUndoAction
+ {
+ public:
+ OQueryDelTabConnUndoAction(OQueryTableView* pOwner);
+
+ virtual void Undo();
+ virtual void Redo();
+ };
+}
+#endif // DBAUI_QUERYADDTABCONNUNDOACTION_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryDesignFieldUndoAct.hxx b/dbaccess/source/ui/querydesign/QueryDesignFieldUndoAct.hxx
new file mode 100644
index 000000000000..92a79f257efd
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryDesignFieldUndoAct.hxx
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERYDESIGNFIELDUNDOACT_HXX
+#define DBAUI_QUERYDESIGNFIELDUNDOACT_HXX
+
+#include "GeneralUndo.hxx"
+#include "dbu_qry.hrc"
+#include "SelectionBrowseBox.hxx"
+
+
+namespace dbaui
+{
+ // ================================================================================================
+ // OQueryDesignFieldUndoAct - Basisklasse fuer Undos in der Feldauflistung im Abfrageentwurf
+
+
+ class OQueryDesignFieldUndoAct : public OCommentUndoAction
+ {
+ protected:
+ OSelectionBrowseBox* pOwner;
+ sal_uInt16 m_nColumnPostion;
+
+ virtual void Undo() = 0;
+ virtual void Redo() = 0;
+
+ public:
+ OQueryDesignFieldUndoAct(OSelectionBrowseBox* pSelBrwBox, sal_uInt16 nCommentID);
+ virtual ~OQueryDesignFieldUndoAct();
+
+ inline void SetColumnPosition(sal_uInt16 _nColumnPostion)
+ {
+ m_nColumnPostion = _nColumnPostion;
+ OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
+ OSL_ENSURE(m_nColumnPostion < pOwner->GetColumnCount(),"Position outside the column count!");
+ }
+ };
+
+ // ================================================================================================
+ // OTabFieldCellModifiedUndoAct - Undo-Klasse fuer Aendern einer Zelle einer Spaltenbeschreibung
+
+ class OTabFieldCellModifiedUndoAct : public OQueryDesignFieldUndoAct
+ {
+ protected:
+ String m_strNextCellContents;
+ sal_Int32 m_nCellIndex;
+
+ public:
+ OTabFieldCellModifiedUndoAct(OSelectionBrowseBox* pSelBrwBox)
+ : OQueryDesignFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_MODIFY_CELL)
+ ,m_nCellIndex(BROWSER_INVALIDID){ }
+
+ inline void SetCellContents(const String& str) { m_strNextCellContents = str; }
+ inline void SetCellIndex(sal_Int32 nIndex) { m_nCellIndex = nIndex; }
+
+ virtual void Undo();
+ virtual void Redo() { Undo(); }
+ };
+
+ // ================================================================================================
+ // OTabFieldSizedUndoAct - Undo-Klasse fuer Aendern einer Spaltenbreite
+
+ class OTabFieldSizedUndoAct : public OQueryDesignFieldUndoAct
+ {
+ protected:
+ long m_nNextWidth;
+
+ public:
+ OTabFieldSizedUndoAct(OSelectionBrowseBox* pSelBrwBox) : OQueryDesignFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_SIZE_COLUMN), m_nNextWidth(0) { }
+
+ inline void SetOriginalWidth(long nWidth) { m_nNextWidth = nWidth; }
+
+ virtual void Undo();
+ virtual void Redo() { Undo(); }
+ };
+
+ // ================================================================================================
+ // OTabFieldUndoAct - Basisklasse fuer Undos in der Feldauflistung im Abfrageentwurf, die mit Veraendern einer kompletten Feldbeschreibung zu tun haben
+
+ class OTabFieldUndoAct : public OQueryDesignFieldUndoAct
+ {
+ protected:
+ OTableFieldDescRef pDescr; // geloeschte Spaltenbeschreibung
+
+ public:
+ OTabFieldUndoAct(OSelectionBrowseBox* pSelBrwBox, sal_uInt16 nCommentID) : OQueryDesignFieldUndoAct(pSelBrwBox, nCommentID) { }
+
+ void SetTabFieldDescr(OTableFieldDescRef pDescription) { pDescr = pDescription; }
+ };
+
+ // ================================================================================================
+ // OTabFieldDelUndoAct - Undo-Klasse fuer Loeschen eines Feldes
+
+ class OTabFieldDelUndoAct : public OTabFieldUndoAct
+ {
+ protected:
+ virtual void Undo() { pOwner->EnterUndoMode();pOwner->InsertColumn(pDescr, m_nColumnPostion);pOwner->LeaveUndoMode(); }
+ virtual void Redo() { pOwner->EnterUndoMode();pOwner->RemoveColumn(pDescr->GetColumnId());pOwner->LeaveUndoMode(); }
+
+ public:
+ OTabFieldDelUndoAct(OSelectionBrowseBox* pSelBrwBox) : OTabFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_TABFIELDDELETE) { }
+ };
+
+ // ================================================================================================
+ // OTabFieldDelUndoAct - Undo-Klasse fuer Anlegen eines Feldes
+
+ class OTabFieldCreateUndoAct : public OTabFieldUndoAct
+ {
+ protected:
+ virtual void Undo() { pOwner->EnterUndoMode();pOwner->RemoveColumn(pDescr->GetColumnId());pOwner->LeaveUndoMode();}
+ virtual void Redo() { pOwner->EnterUndoMode();pOwner->InsertColumn(pDescr, m_nColumnPostion);pOwner->LeaveUndoMode();}
+
+ public:
+ OTabFieldCreateUndoAct(OSelectionBrowseBox* pSelBrwBox) : OTabFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_TABFIELDCREATE) { }
+ };
+
+ // ================================================================================================
+ // OTabFieldMovedUndoAct - Undo-class when a field was moved inside the selection
+
+ class OTabFieldMovedUndoAct : public OTabFieldUndoAct
+ {
+ protected:
+ virtual void Undo();
+ virtual void Redo()
+ {
+ Undo();
+ }
+
+ public:
+ OTabFieldMovedUndoAct(OSelectionBrowseBox* pSelBrwBox) : OTabFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_TABFIELDMOVED) { }
+ };
+}
+#endif // DBAUI_QUERYDESIGNFIELDUNDOACT_HXX
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryDesignUndoAction.hxx b/dbaccess/source/ui/querydesign/QueryDesignUndoAction.hxx
new file mode 100644
index 000000000000..f0f862cf3611
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryDesignUndoAction.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERYDESIGNUNDOACTION_HXX
+#define DBAUI_QUERYDESIGNUNDOACTION_HXX
+
+#include "GeneralUndo.hxx"
+
+namespace dbaui
+{
+ // ================================================================================================
+ // OQueryDesignUndoAction - Undo-Basisklasse fuer Aktionen im graphischen Abfrageentwurf (ohne Feldliste)
+
+ class OJoinTableView;
+ class OQueryDesignUndoAction : public OCommentUndoAction
+ {
+ protected:
+ OJoinTableView* m_pOwner; // in diesem Container spielt sich alles ab
+
+ public:
+ OQueryDesignUndoAction(OJoinTableView* pOwner, sal_uInt16 nCommentID) : OCommentUndoAction(nCommentID), m_pOwner(pOwner) { }
+ };
+}
+#endif // DBAUI_QUERYDESIGNUNDOACTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryDesignView.cxx b/dbaccess/source/ui/querydesign/QueryDesignView.cxx
new file mode 100644
index 000000000000..ccd9b3af9533
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryDesignView.cxx
@@ -0,0 +1,3217 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "QueryDesignView.hxx"
+#include "QueryTableView.hxx"
+#include "QTableWindow.hxx"
+#include <vcl/toolbox.hxx>
+#include "querycontroller.hxx"
+#include <vcl/split.hxx>
+#include <svl/undo.hxx>
+#include <tools/diagnose_ex.h>
+#include <osl/diagnose.h>
+#include "adtabdlg.hxx"
+#include <vcl/svapp.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/msgbox.hxx>
+#include "browserids.hxx"
+#include "SelectionBrowseBox.hxx"
+#include "dbu_qry.hrc"
+#include <unotools/configmgr.hxx>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/dbexception.hxx>
+#include <com/sun/star/i18n/XLocaleData.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <connectivity/PColumn.hxx>
+#include "QTableConnection.hxx"
+#include "ConnectionLine.hxx"
+#include "ConnectionLineData.hxx"
+#include "QTableConnectionData.hxx"
+#include "dbustrings.hrc"
+#include <comphelper/extract.hxx>
+#include "UITools.hxx"
+#include "querycontainerwindow.hxx"
+#include "QueryTableView.hxx"
+#include "sqlmessage.hxx"
+#include <unotools/syslocale.hxx>
+
+using namespace ::dbaui;
+using namespace ::utl;
+using namespace ::connectivity;
+using namespace ::dbtools;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::i18n;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+
+#define SQL_ISRULEOR2(pParseNode, e1,e2) ((pParseNode)->isRule() && (\
+ (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e1) || \
+ (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e2)))
+
+// here we define our functions used in the anonymous namespace to get our header file smaller
+// please look at the book LargeScale C++ to know why
+namespace
+{
+ static const ::rtl::OUString C_AND(RTL_CONSTASCII_USTRINGPARAM(" AND "));
+ static const ::rtl::OUString C_OR(RTL_CONSTASCII_USTRINGPARAM(" OR "));
+
+ // forward declarations
+ sal_Bool InsertJoin( const OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode *pNode);
+
+ SqlParseError InstallFields(OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode* pNode,
+ OJoinTableView::OTableWindowMap* pTabList );
+
+ SqlParseError GetGroupCriteria( OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode* pSelectRoot );
+
+ SqlParseError GetHavingCriteria(OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode* pSelectRoot,
+ sal_uInt16& rLevel );
+
+ SqlParseError GetOrderCriteria( OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode* pParseRoot );
+
+ SqlParseError AddFunctionCondition(OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode * pCondition,
+ const sal_uInt16 nLevel,
+ sal_Bool bHaving,
+ bool _bAddOrOnOneLine);
+
+ //------------------------------------------------------------------------------
+ ::rtl::OUString quoteTableAlias(sal_Bool _bQuote, const ::rtl::OUString& _sAliasName, const ::rtl::OUString& _sQuote)
+ {
+ ::rtl::OUString sRet;
+ if ( _bQuote && _sAliasName.getLength() )
+ {
+ sRet = ::dbtools::quoteName(_sQuote,_sAliasName);
+ const static ::rtl::OUString sTableSeparater('.');
+ sRet += sTableSeparater;
+ }
+ return sRet;
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString getTableRange(const OQueryDesignView* _pView,const ::connectivity::OSQLParseNode* _pTableRef)
+ {
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
+ ::rtl::OUString sTableRange;
+ if ( _pTableRef )
+ {
+ sTableRange = ::connectivity::OSQLParseNode::getTableRange(_pTableRef);
+ if ( !sTableRange.getLength() )
+ _pTableRef->parseNodeToStr(sTableRange,xConnection,NULL,sal_False,sal_False);
+ }
+ return sTableRange;
+ }
+ //------------------------------------------------------------------------------
+ void insertConnection(const OQueryDesignView* _pView,const EJoinType& _eJoinType,OTableFieldDescRef _aDragLeft,OTableFieldDescRef _aDragRight,bool _bNatural = false)
+ {
+ OQueryTableView* pTableView = static_cast<OQueryTableView*>(_pView->getTableView());
+ OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>( pTableView->GetTabConn(static_cast<OTableWindow*>(_aDragLeft->GetTabWindow()),static_cast<OTableWindow*>(_aDragRight->GetTabWindow()),true));
+
+ if ( !pConn )
+ {
+ OQueryTableConnectionData* pInfoData = new OQueryTableConnectionData();
+ TTableConnectionData::value_type aInfoData(pInfoData);
+ pInfoData->InitFromDrag(_aDragLeft, _aDragRight);
+ pInfoData->SetJoinType(_eJoinType);
+
+ if ( _bNatural )
+ {
+ aInfoData->ResetConnLines();
+ pInfoData->setNatural(_bNatural);
+ try
+ {
+ Reference<XNameAccess> xReferencedTableColumns(aInfoData->getReferencedTable()->getColumns());
+ Sequence< ::rtl::OUString> aSeq = aInfoData->getReferencingTable()->getColumns()->getElementNames();
+ const ::rtl::OUString* pIter = aSeq.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ if ( xReferencedTableColumns->hasByName(*pIter) )
+ aInfoData->AppendConnLine(*pIter,*pIter);
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ OQueryTableConnection aInfo(pTableView, aInfoData);
+ // da ein OQueryTableConnection-Objekt nie den Besitz der uebergebenen Daten uebernimmt, sondern sich nur den Zeiger merkt,
+ // ist dieser Zeiger auf eine lokale Variable hier unkritisch, denn aInfoData und aInfo haben die selbe Lebensdauer
+ pTableView->NotifyTabConnection( aInfo );
+ }
+ else
+ {
+ ::rtl::OUString aSourceFieldName(_aDragLeft->GetField());
+ ::rtl::OUString aDestFieldName(_aDragRight->GetField());
+ // the connection could point on the other side
+ if(pConn->GetSourceWin() == _aDragRight->GetTabWindow())
+ {
+ ::rtl::OUString aTmp(aSourceFieldName);
+ aSourceFieldName = aDestFieldName;
+ aDestFieldName = aTmp;
+ }
+ pConn->GetData()->AppendConnLine( aSourceFieldName,aDestFieldName);
+ pConn->UpdateLineList();
+ // Modified-Flag
+ // SetModified();
+ // und neu zeichnen
+ pConn->RecalcLines();
+ // fuer das unten folgende Invalidate muss ich dieser neuen Connection erst mal die Moeglichkeit geben,
+ // ihr BoundingRect zu ermitteln
+ pConn->InvalidateConnection();
+ }
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString ParseCondition( OQueryController& rController
+ ,const ::connectivity::OSQLParseNode* pCondition
+ ,const ::rtl::OUString _sDecimal
+ ,const ::com::sun::star::lang::Locale& _rLocale
+ ,sal_uInt32 _nStartIndex)
+ {
+ ::rtl::OUString aCondition;
+ Reference< XConnection> xConnection = rController.getConnection();
+ if ( xConnection.is() )
+ {
+ sal_uInt32 nCount = pCondition->count();
+ for(sal_uInt32 i = _nStartIndex ; i < nCount ; ++i)
+ pCondition->getChild(i)->parseNodeToPredicateStr(aCondition,
+ xConnection,
+ rController.getNumberFormatter(),
+ _rLocale,
+ static_cast<sal_Char>(_sDecimal.toChar()),
+ &rController.getParser().getContext());
+ }
+ return aCondition;
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError FillOuterJoins(OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode* pTableRefList)
+ {
+ SqlParseError eErrorCode = eOk;
+ sal_uInt32 nCount = pTableRefList->count();
+ sal_Bool bError = sal_False;
+ for (sal_uInt32 i=0; !bError && i < nCount; ++i)
+ {
+ const ::connectivity::OSQLParseNode* pParseNode = pTableRefList->getChild(i);
+ const ::connectivity::OSQLParseNode* pJoinNode = NULL;
+
+ if ( SQL_ISRULE( pParseNode, qualified_join ) || SQL_ISRULE( pParseNode, joined_table ) || SQL_ISRULE( pParseNode, cross_union ) )
+ pJoinNode = pParseNode;
+ else if( SQL_ISRULE(pParseNode,table_ref)
+ && pParseNode->count() == 4 ) // '{' SQL_TOKEN_OJ joined_table '}'
+ pJoinNode = pParseNode->getChild(2);
+
+ if ( pJoinNode )
+ {
+ if ( !InsertJoin(_pView,pJoinNode) )
+ bError = sal_True;
+ }
+ }
+ // check if error occurred
+ if ( bError )
+ eErrorCode = eIllegalJoin;
+
+ return eErrorCode;
+ }
+ // -----------------------------------------------------------------------------
+
+ /** FillDragInfo fills the field description out of the table
+ */
+ //------------------------------------------------------------------------------
+ SqlParseError FillDragInfo( const OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode* pColumnRef,
+ OTableFieldDescRef& _rDragInfo)
+ {
+ SqlParseError eErrorCode = eOk;
+
+ sal_Bool bErg = sal_False;
+
+ ::rtl::OUString aTableRange,aColumnName;
+ sal_uInt16 nCntAccount;
+ ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController&>(_pView->getController()).getParseIterator();
+ rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange );
+
+ if ( aTableRange.getLength() )
+ {
+ OQueryTableWindow* pSTW = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( aTableRange );
+ bErg = (pSTW && pSTW->ExistsField( aColumnName, _rDragInfo ) );
+ }
+ if ( !bErg )
+ {
+ bErg = static_cast<OQueryTableView*>(_pView->getTableView())->FindTableFromField(aColumnName, _rDragInfo, nCntAccount);
+ if ( !bErg )
+ bErg = _pView->HasFieldByAliasName(aColumnName, _rDragInfo);
+ }
+ if ( !bErg )
+ {
+ eErrorCode = eColumnNotFound;
+ String sError(ModuleRes(STR_QRY_COLUMN_NOT_FOUND));
+ sError.SearchAndReplaceAscii("$name$",aColumnName);
+ _pView->getController().appendError( sError );
+
+ try
+ {
+ Reference<XDatabaseMetaData> xMeta = _pView->getController().getConnection()->getMetaData();
+ if ( xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers() )
+ _pView->getController().appendError( String( ModuleRes( STR_QRY_CHECK_CASESENSITIVE ) ) );
+ }
+ catch(Exception&)
+ {
+ }
+ }
+
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString BuildJoinCriteria( const Reference< XConnection>& _xConnection,
+ OConnectionLineDataVec* pLineDataList,
+ OQueryTableConnectionData* pData)
+ {
+ ::rtl::OUStringBuffer aCondition;
+ if ( _xConnection.is() )
+ {
+ OConnectionLineDataVec::iterator aIter = pLineDataList->begin();
+ OConnectionLineDataVec::iterator aEnd = pLineDataList->end();
+ try
+ {
+ const Reference< XDatabaseMetaData > xMetaData = _xConnection->getMetaData();
+ const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
+ const ::rtl::OUString sEqual(RTL_CONSTASCII_USTRINGPARAM(" = "));
+
+ for(;aIter != aEnd;++aIter)
+ {
+ OConnectionLineDataRef pLineData = *aIter;
+ if(aCondition.getLength())
+ aCondition.append(C_AND);
+ aCondition.append(quoteTableAlias(sal_True,pData->GetAliasName(JTCS_FROM),aQuote));
+ aCondition.append(::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_FROM) ));
+ aCondition.append(sEqual);
+ aCondition.append(quoteTableAlias(sal_True,pData->GetAliasName(JTCS_TO),aQuote));
+ aCondition.append(::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_TO) ));
+ }
+ }
+ catch(SQLException&)
+ {
+ OSL_FAIL("Failure while building Join criteria!");
+ }
+ }
+
+ return aCondition.makeStringAndClear();
+ }
+ //------------------------------------------------------------------------------
+ /** JoinCycle looks for a join cycle and append it to the string
+ @param _xConnection the connection
+ @param _pEntryConn the table connection which holds the data
+ @param _pEntryTabTo the corresponding table window
+ @param _rJoin the String which will contain the resulting string
+ */
+ void JoinCycle( const Reference< XConnection>& _xConnection,
+ OQueryTableConnection* _pEntryConn,
+ const OQueryTableWindow* _pEntryTabTo,
+ ::rtl::OUString& _rJoin )
+ {
+ OSL_ENSURE(_pEntryConn,"TableConnection can not be null!");
+
+ OQueryTableConnectionData* pData = static_cast< OQueryTableConnectionData*>(_pEntryConn->GetData().get());
+ if ( pData->GetJoinType() != INNER_JOIN && _pEntryTabTo->ExistsAVisitedConn() )
+ {
+ sal_Bool bBrace = sal_False;
+ if(_rJoin.getLength() && _rJoin.lastIndexOf(')') == (_rJoin.getLength()-1))
+ {
+ bBrace = sal_True;
+ _rJoin = _rJoin.replaceAt(_rJoin.getLength()-1,1,::rtl::OUString(' '));
+ }
+ (_rJoin += C_AND) += BuildJoinCriteria(_xConnection,pData->GetConnLineDataList(),pData);
+ if(bBrace)
+ _rJoin += ::rtl::OUString(')');
+ _pEntryConn->SetVisited(sal_True);
+ }
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString BuildTable( const Reference< XConnection>& _xConnection,
+ const OQueryTableWindow* pEntryTab,
+ bool _bForce = false
+ )
+ {
+ ::rtl::OUString aDBName(pEntryTab->GetComposedName());
+
+ if( _xConnection.is() )
+ {
+ try
+ {
+ Reference< XDatabaseMetaData > xMetaData = _xConnection->getMetaData();
+
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ ::dbtools::qualifiedNameComponents( xMetaData, aDBName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
+ ::rtl::OUString aTableListStr = ::dbtools::composeTableNameForSelect( _xConnection, sCatalog, sSchema, sTable );
+
+ ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
+ if ( _bForce || isAppendTableAliasEnabled( _xConnection ) || pEntryTab->GetAliasName() != aDBName )
+ {
+ aTableListStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
+ if ( generateAsBeforeTableAlias( _xConnection ) )
+ aTableListStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AS "));
+ aTableListStr += ::dbtools::quoteName( aQuote, pEntryTab->GetAliasName() );
+ }
+ aDBName = aTableListStr;
+ }
+ catch(const SQLException&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ return aDBName;
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString BuildJoin( const Reference< XConnection>& _xConnection,
+ const ::rtl::OUString& rLh,
+ const ::rtl::OUString& rRh,
+ OQueryTableConnectionData* pData)
+ {
+
+ String aErg(rLh);
+ if ( pData->isNatural() && pData->GetJoinType() != CROSS_JOIN )
+ aErg.AppendAscii(" NATURAL ");
+ switch(pData->GetJoinType())
+ {
+ case LEFT_JOIN:
+ aErg.AppendAscii(" LEFT OUTER ");
+ break;
+ case RIGHT_JOIN:
+ aErg.AppendAscii(" RIGHT OUTER ");
+ break;
+ case CROSS_JOIN:
+ OSL_ENSURE(!pData->isNatural(),"OQueryDesignView::BuildJoin: This should not happen!");
+ aErg.AppendAscii(" CROSS ");
+ break;
+ case INNER_JOIN:
+ OSL_ENSURE(pData->isNatural(),"OQueryDesignView::BuildJoin: This should not happen!");
+ aErg.AppendAscii(" INNER ");
+ break;
+ default:
+ aErg.AppendAscii(" FULL OUTER ");
+ break;
+ }
+ aErg.AppendAscii("JOIN ");
+ aErg += String(rRh);
+ if ( CROSS_JOIN != pData->GetJoinType() && !pData->isNatural() )
+ {
+ aErg.AppendAscii(" ON ");
+ aErg += String(BuildJoinCriteria(_xConnection,pData->GetConnLineDataList(),pData));
+ }
+
+ return aErg;
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString BuildJoin( const Reference< XConnection>& _xConnection,
+ OQueryTableWindow* pLh,
+ OQueryTableWindow* pRh,
+ OQueryTableConnectionData* pData
+ )
+ {
+ bool bForce = pData->GetJoinType() == CROSS_JOIN || pData->isNatural();
+ return BuildJoin(_xConnection,BuildTable(_xConnection,pLh,bForce),BuildTable(_xConnection,pRh,bForce),pData);
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString BuildJoin( const Reference< XConnection>& _xConnection,
+ const ::rtl::OUString &rLh,
+ OQueryTableWindow* pRh,
+ OQueryTableConnectionData* pData
+ )
+ {
+ return BuildJoin(_xConnection,rLh,BuildTable(_xConnection,pRh),pData);
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString BuildJoin( const Reference< XConnection>& _xConnection,
+ OQueryTableWindow* pLh,
+ const ::rtl::OUString &rRh,
+ OQueryTableConnectionData* pData
+ )
+ {
+ return BuildJoin(_xConnection,BuildTable(_xConnection,pLh),rRh,pData);
+ }
+ //------------------------------------------------------------------------------
+ void GetNextJoin( const Reference< XConnection>& _xConnection,
+ OQueryTableConnection* pEntryConn,
+ OQueryTableWindow* pEntryTabTo,
+ ::rtl::OUString &aJoin)
+ {
+ OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get());
+ if ( pEntryConnData->GetJoinType() == INNER_JOIN && !pEntryConnData->isNatural() )
+ return;
+
+ if(!aJoin.getLength())
+ {
+ OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
+ aJoin = BuildJoin(_xConnection,pEntryTabFrom,pEntryTabTo,pEntryConnData);
+ }
+ else if(pEntryTabTo == pEntryConn->GetDestWin())
+ {
+ aJoin = BuildJoin(_xConnection,aJoin,pEntryTabTo,pEntryConnData);
+ }
+ else if(pEntryTabTo == pEntryConn->GetSourceWin())
+ {
+ aJoin = BuildJoin(_xConnection,pEntryTabTo,aJoin,pEntryConnData);
+ }
+
+ pEntryConn->SetVisited(sal_True);
+
+ // first search for the "to" window
+ const ::std::vector<OTableConnection*>* pConnections = pEntryConn->GetParent()->getTableConnections();
+ ::std::vector<OTableConnection*>::const_iterator aIter = pConnections->begin();
+ ::std::vector<OTableConnection*>::const_iterator aEnd = pConnections->end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter);
+ if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabTo || pNext->GetDestWin() == pEntryTabTo))
+ {
+ OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabTo ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin());
+ // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited
+ JoinCycle(_xConnection,pNext,pEntryTab,aJoin);
+ if(!pNext->IsVisited())
+ GetNextJoin(_xConnection,pNext,pEntryTab,aJoin);
+ }
+ }
+
+ // when nothing found found look for the "from" window
+ if(aIter == aEnd)
+ {
+ OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
+ aIter = pConnections->begin();
+ for(;aIter != aEnd;++aIter)
+ {
+ OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter);
+ if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabFrom || pNext->GetDestWin() == pEntryTabFrom))
+ {
+ OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabFrom ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin());
+ // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited
+ JoinCycle(_xConnection,pNext,pEntryTab,aJoin);
+ if(!pNext->IsVisited())
+ GetNextJoin(_xConnection,pNext,pEntryTab,aJoin);
+ }
+ }
+ }
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError InsertJoinConnection( const OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode *pNode,
+ const EJoinType& _eJoinType,
+ const ::connectivity::OSQLParseNode *pLeftTable,
+ const ::connectivity::OSQLParseNode *pRightTable)
+ {
+ SqlParseError eErrorCode = eOk;
+ if (pNode->count() == 3 && // Ausdruck is geklammert
+ SQL_ISPUNCTUATION(pNode->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pNode->getChild(2),")"))
+ {
+ eErrorCode = InsertJoinConnection(_pView,pNode->getChild(1), _eJoinType,pLeftTable,pRightTable);
+ }
+ else if (SQL_ISRULEOR2(pNode,search_condition,boolean_term) && // AND/OR-Verknuepfung:
+ pNode->count() == 3)
+ {
+ // nur AND Verknüpfung zulassen
+ if (!SQL_ISTOKEN(pNode->getChild(1),AND))
+ eErrorCode = eIllegalJoinCondition;
+ else if ( eOk == (eErrorCode = InsertJoinConnection(_pView,pNode->getChild(0), _eJoinType,pLeftTable,pRightTable)) )
+ eErrorCode = InsertJoinConnection(_pView,pNode->getChild(2), _eJoinType,pLeftTable,pRightTable);
+ }
+ else if (SQL_ISRULE(pNode,comparison_predicate))
+ {
+ // only the comparison of columns is allowed
+ OSL_ENSURE(pNode->count() == 3,"OQueryDesignView::InsertJoinConnection: Fehler im Parse Tree");
+ if (!(SQL_ISRULE(pNode->getChild(0),column_ref) &&
+ SQL_ISRULE(pNode->getChild(2),column_ref) &&
+ pNode->getChild(1)->getNodeType() == SQL_NODE_EQUAL))
+ {
+ String sError(ModuleRes(STR_QRY_JOIN_COLUMN_COMPARE));
+ _pView->getController().appendError( sError );
+ return eIllegalJoin;
+ }
+
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+ OTableFieldDescRef aDragRight = new OTableFieldDesc();
+ if ( eOk != ( eErrorCode = FillDragInfo(_pView,pNode->getChild(0),aDragLeft)) ||
+ eOk != ( eErrorCode = FillDragInfo(_pView,pNode->getChild(2),aDragRight)))
+ return eErrorCode;
+
+ if ( pLeftTable )
+ {
+ OQueryTableWindow* pLeftWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pLeftTable->getByRule(OSQLParseNode::table_ref) ));
+ if ( pLeftWindow == aDragLeft->GetTabWindow() )
+ insertConnection(_pView,_eJoinType,aDragLeft,aDragRight);
+ else
+ insertConnection(_pView,_eJoinType,aDragRight,aDragLeft);
+ }
+ else
+ insertConnection(_pView,_eJoinType,aDragLeft,aDragRight);
+ }
+ else
+ eErrorCode = eIllegalJoin;
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ sal_Bool GetInnerJoinCriteria( const OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode *pCondition)
+ {
+ return InsertJoinConnection(_pView,pCondition, INNER_JOIN,NULL,NULL) != eOk;
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString GenerateSelectList( const OQueryDesignView* _pView,
+ OTableFields& _rFieldList,
+ sal_Bool bAlias)
+ {
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
+ if ( !xConnection.is() )
+ return ::rtl::OUString();
+
+ ::rtl::OUStringBuffer aTmpStr,aFieldListStr;
+
+ sal_Bool bAsterix = sal_False;
+ int nVis = 0;
+ OTableFields::iterator aIter = _rFieldList.begin();
+ OTableFields::iterator aEnd = _rFieldList.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableFieldDescRef pEntryField = *aIter;
+ if ( pEntryField->IsVisible() )
+ {
+ if ( pEntryField->GetField().toChar() == '*' )
+ bAsterix = sal_True;
+ ++nVis;
+ }
+ }
+ if(nVis == 1)
+ bAsterix = sal_False;
+
+ try
+ {
+ const Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
+
+ OJoinTableView::OTableWindowMap* pTabList = _pView->getTableView()->GetTabWinMap();
+
+ const static ::rtl::OUString sFieldSeparator(RTL_CONSTASCII_USTRINGPARAM(", "));
+ const static ::rtl::OUString s_sAs(RTL_CONSTASCII_USTRINGPARAM(" AS "));
+
+ aIter = _rFieldList.begin();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableFieldDescRef pEntryField = *aIter;
+ ::rtl::OUString rFieldName = pEntryField->GetField();
+ if ( rFieldName.getLength() && pEntryField->IsVisible() )
+ {
+ aTmpStr = ::rtl::OUString();
+ const ::rtl::OUString rAlias = pEntryField->GetAlias();
+ const ::rtl::OUString rFieldAlias = pEntryField->GetFieldAlias();
+
+ aTmpStr.append(quoteTableAlias((bAlias || bAsterix),rAlias,aQuote));
+
+ // if we have a none numeric field, the table alias could be in the name
+ // otherwise we are not allowed to do this (e.g. 0.1 * PRICE )
+ if ( !pEntryField->isOtherFunction() )
+ {
+ // we have to look if we have alias.* here but before we have to check if the column doesn't already exist
+ String sTemp = rFieldName;
+ OTableFieldDescRef aInfo = new OTableFieldDesc();
+ OJoinTableView::OTableWindowMap::iterator tableIter = pTabList->begin();
+ OJoinTableView::OTableWindowMap::iterator tableEnd = pTabList->end();
+ sal_Bool bFound = sal_False;
+ for(;!bFound && tableIter != tableEnd ;++tableIter)
+ {
+ OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(tableIter->second);
+
+ bFound = pTabWin->ExistsField( rFieldName, aInfo );
+ if ( bFound )
+ rFieldName = aInfo->GetField();
+ }
+ if ( ( rFieldName.toChar() != '*' ) && ( rFieldName.indexOf( aQuote ) == -1 ) )
+ {
+ OSL_ENSURE(pEntryField->GetTable().getLength(),"No table field name!");
+ aTmpStr.append(::dbtools::quoteName(aQuote, rFieldName));
+ }
+ else
+ aTmpStr.append(rFieldName);
+ }
+ else
+ aTmpStr.append(rFieldName);
+
+ if ( pEntryField->isAggreateFunction() )
+ {
+ OSL_ENSURE(pEntryField->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-(");
+ ::rtl::OUStringBuffer aTmpStr2( pEntryField->GetFunction());
+ aTmpStr2.appendAscii("(");
+ aTmpStr2.append(aTmpStr.makeStringAndClear());
+ aTmpStr2.appendAscii(")");
+ aTmpStr = aTmpStr2;
+ }
+
+ if (rFieldAlias.getLength() &&
+ (rFieldName.toChar() != '*' ||
+ pEntryField->isNumericOrAggreateFunction() ||
+ pEntryField->isOtherFunction()))
+ {
+ aTmpStr.append(s_sAs);
+ aTmpStr.append(::dbtools::quoteName(aQuote, rFieldAlias));
+ }
+ aFieldListStr.append(aTmpStr.makeStringAndClear());
+ aFieldListStr.append(sFieldSeparator);
+ }
+ }
+ if(aFieldListStr.getLength())
+ aFieldListStr.setLength(aFieldListStr.getLength()-2);
+ }
+ catch(SQLException&)
+ {
+ OSL_FAIL("Failure while building select list!");
+ }
+ return aFieldListStr.makeStringAndClear();
+ }
+ //------------------------------------------------------------------------------
+ sal_Bool GenerateCriterias( OQueryDesignView* _pView,
+ ::rtl::OUStringBuffer& rRetStr,
+ ::rtl::OUStringBuffer& rHavingStr,
+ OTableFields& _rFieldList,
+ sal_Bool bMulti )
+ {
+ // * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ?
+ sal_Bool bCritsOnAsterikWarning = sal_False; // ** TMFS **
+
+ ::rtl::OUString aFieldName,aCriteria,aWhereStr,aHavingStr,aWork/*,aOrderStr*/;
+ // Zeilenweise werden die Ausdr"ucke mit AND verknuepft
+ sal_uInt16 nMaxCriteria = 0;
+ OTableFields::iterator aIter = _rFieldList.begin();
+ OTableFields::iterator aEnd = _rFieldList.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ nMaxCriteria = ::std::max<sal_uInt16>(nMaxCriteria,(sal_uInt16)(*aIter)->GetCriteria().size());
+ }
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
+ if(!xConnection.is())
+ return sal_False;
+ try
+ {
+ const Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
+ const IParseContext& rContext = static_cast<OQueryController&>(_pView->getController()).getParser().getContext();
+
+ for (sal_uInt16 i=0 ; i < nMaxCriteria ; i++)
+ {
+ aHavingStr = aWhereStr = ::rtl::OUString();
+
+ for(aIter = _rFieldList.begin();aIter != aEnd;++aIter)
+ {
+ OTableFieldDescRef pEntryField = *aIter;
+ aFieldName = pEntryField->GetField();
+
+ if (!aFieldName.getLength())
+ continue;
+ aCriteria = pEntryField->GetCriteria( i );
+ if ( aCriteria.getLength() )
+ {
+ // * is not allowed to contain any filter, only when used in combination an aggregate function
+ if ( aFieldName.toChar() == '*' && pEntryField->isNoneFunction() )
+ {
+ // only show the messagebox the first time
+ if (!bCritsOnAsterikWarning)
+ ErrorBox(_pView, ModuleRes( ERR_QRY_CRITERIA_ON_ASTERISK)).Execute();
+ bCritsOnAsterikWarning = sal_True;
+ continue;
+ }
+ aWork = ::rtl::OUString();
+
+
+ aWork += quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
+
+ if ( (pEntryField->GetFunctionType() & (FKT_OTHER|FKT_NUMERIC)) || (aFieldName.toChar() == '*') )
+ aWork += aFieldName;
+ else
+ aWork += ::dbtools::quoteName(aQuote, aFieldName);
+
+ if ( pEntryField->isAggreateFunction() || pEntryField->IsGroupBy() )
+ {
+ if (!aHavingStr.getLength()) // noch keine Kriterien
+ aHavingStr += ::rtl::OUString('('); // Klammern
+ else
+ aHavingStr += C_AND;
+
+ if ( pEntryField->isAggreateFunction() )
+ {
+ OSL_ENSURE(pEntryField->GetFunction().getLength(),"No function name for aggregate given!");
+ aHavingStr += pEntryField->GetFunction();
+ aHavingStr += ::rtl::OUString('('); // Klammern
+ aHavingStr += aWork;
+ aHavingStr += ::rtl::OUString(')'); // Klammern
+ }
+ else
+ aHavingStr += aWork;
+
+ ::rtl::OUString aTmp = aCriteria;
+ ::rtl::OUString aErrorMsg;
+ Reference<XPropertySet> xColumn;
+ ::std::auto_ptr< ::connectivity::OSQLParseNode> pParseNode(_pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn));
+ if (pParseNode.get())
+ {
+ if (bMulti && !(pEntryField->isOtherFunction() || (aFieldName.toChar() == '*')))
+ pParseNode->replaceNodeValue(pEntryField->GetAlias(),aFieldName);
+ ::rtl::OUString sHavingStr = aHavingStr;
+
+ sal_uInt32 nCount = pParseNode->count();
+ for( sal_uInt32 node = 1 ; node < nCount ; ++node)
+ pParseNode->getChild(node)->parseNodeToStr( sHavingStr,
+ xConnection,
+ &rContext,
+ sal_False,
+ !pEntryField->isOtherFunction());
+ aHavingStr = sHavingStr;
+ }
+ else
+ aHavingStr += aCriteria;
+ }
+ else
+ {
+ if ( !aWhereStr.getLength() ) // noch keine Kriterien
+ aWhereStr += ::rtl::OUString('('); // Klammern
+ else
+ aWhereStr += C_AND;
+
+ aWhereStr += ::rtl::OUString(' ');
+ // aCriteria could have some german numbers so I have to be sure here
+ ::rtl::OUString aTmp = aCriteria;
+ ::rtl::OUString aErrorMsg;
+ Reference<XPropertySet> xColumn;
+ ::std::auto_ptr< ::connectivity::OSQLParseNode> pParseNode( _pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn));
+ if (pParseNode.get())
+ {
+ if (bMulti && !(pEntryField->isOtherFunction() || (aFieldName.toChar() == '*')))
+ pParseNode->replaceNodeValue(pEntryField->GetAlias(),aFieldName);
+ ::rtl::OUString aWhere = aWhereStr;
+ pParseNode->parseNodeToStr( aWhere,
+ xConnection,
+ &rContext,
+ sal_False,
+ !pEntryField->isOtherFunction() );
+ aWhereStr = aWhere;
+ }
+ else
+ {
+ aWhereStr += aWork;
+ aWhereStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+ aWhereStr += aCriteria;
+ }
+ }
+ }
+ // nur einmal für jedes Feld
+ else if ( !i && pEntryField->isCondition() )
+ {
+ if (!aWhereStr.getLength()) // noch keine Kriterien
+ aWhereStr += ::rtl::OUString('('); // Klammern
+ else
+ aWhereStr += C_AND;
+ aWhereStr += pEntryField->GetField();
+ }
+ }
+ if (aWhereStr.getLength())
+ {
+ aWhereStr += ::rtl::OUString(')'); // Klammern zu fuer 'AND' Zweig
+ if (rRetStr.getLength()) // schon Feldbedingungen ?
+ rRetStr.append(C_OR);
+ else // Klammern auf fuer 'OR' Zweig
+ rRetStr.append(sal_Unicode('('));
+ rRetStr.append(aWhereStr);
+ }
+ if (aHavingStr.getLength())
+ {
+ aHavingStr += ::rtl::OUString(')'); // Klammern zu fuer 'AND' Zweig
+ if (rHavingStr.getLength()) // schon Feldbedingungen ?
+ rHavingStr.append(C_OR);
+ else // Klammern auf fuer 'OR' Zweig
+ rHavingStr.append(sal_Unicode('('));
+ rHavingStr.append(aHavingStr);
+ }
+ }
+
+ if (rRetStr.getLength())
+ rRetStr.append(sal_Unicode(')')); // Klammern zu fuer 'OR' Zweig
+ if (rHavingStr.getLength())
+ rHavingStr.append(sal_Unicode(')')); // Klammern zu fuer 'OR' Zweig
+ }
+ catch(SQLException&)
+ {
+ OSL_FAIL("Failure while building where clause!");
+ }
+ return sal_True;
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError GenerateOrder( OQueryDesignView* _pView,
+ OTableFields& _rFieldList,
+ sal_Bool bMulti,
+ ::rtl::OUString& _rsRet)
+ {
+ const OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+ Reference< XConnection> xConnection = rController.getConnection();
+ if ( !xConnection.is() )
+ return eNoConnection;
+
+ SqlParseError eErrorCode = eOk;
+
+ ::rtl::OUString aColumnName;
+ ::rtl::OUString aWorkStr;
+ try
+ {
+ const bool bColumnAliasInOrderBy = rController.getSdbMetaData().supportsColumnAliasInOrderBy();
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
+ // * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ?
+ sal_Bool bCritsOnAsterikWarning = sal_False; // ** TMFS **
+ OTableFields::iterator aIter = _rFieldList.begin();
+ OTableFields::iterator aEnd = _rFieldList.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableFieldDescRef pEntryField = *aIter;
+ EOrderDir eOrder = pEntryField->GetOrderDir();
+
+ // nur wenn eine Sortierung und ein Tabellenname vorhanden ist-> erzeugen
+ // sonst werden die Expressions vom Order By im GenerateCriteria mit erzeugt
+ if ( eOrder != ORDER_NONE )
+ {
+ aColumnName = pEntryField->GetField();
+ if(aColumnName.toChar() == '*')
+ {
+ // die entsprechende MessageBox nur beim ersten mal anzeigen
+ if (!bCritsOnAsterikWarning)
+ ErrorBox(_pView, ModuleRes( ERR_QRY_ORDERBY_ON_ASTERISK)).Execute();
+ bCritsOnAsterikWarning = sal_True;
+ continue;
+ }
+
+ if ( bColumnAliasInOrderBy && pEntryField->GetFieldAlias().getLength() )
+ {
+ aWorkStr += ::dbtools::quoteName(aQuote, pEntryField->GetFieldAlias());
+ }
+ else if ( pEntryField->isNumericOrAggreateFunction() )
+ {
+ OSL_ENSURE(pEntryField->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-(");
+ aWorkStr += pEntryField->GetFunction();
+ aWorkStr += ::rtl::OUString('(');
+ aWorkStr += quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
+ // only quote column name when we don't have a numeric
+ if ( pEntryField->isNumeric() )
+ aWorkStr += aColumnName;
+ else
+ aWorkStr += ::dbtools::quoteName(aQuote, aColumnName);
+
+ aWorkStr += ::rtl::OUString(')');
+ }
+ else if ( pEntryField->isOtherFunction() )
+ {
+ aWorkStr += aColumnName;
+ }
+ else
+ {
+ aWorkStr += quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
+ aWorkStr += ::dbtools::quoteName(aQuote, aColumnName);
+ }
+ aWorkStr += ::rtl::OUString(' ');
+ aWorkStr += String::CreateFromAscii( ";ASC;DESC" ).GetToken( (sal_uInt16)eOrder );
+ aWorkStr += ::rtl::OUString(',');
+ }
+ }
+
+ {
+ String sTemp(aWorkStr);
+ sTemp.EraseTrailingChars( ',' );
+ aWorkStr = sTemp;
+ }
+
+ if ( aWorkStr.getLength() )
+ {
+ const sal_Int32 nMaxOrder = xMetaData->getMaxColumnsInOrderBy();
+ String sToken(aWorkStr);
+ if ( nMaxOrder && nMaxOrder < sToken.GetTokenCount(',') )
+ eErrorCode = eStatementTooLong;
+ else
+ {
+ _rsRet = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ORDER BY "));
+ _rsRet += aWorkStr;
+ }
+ }
+ }
+ catch(SQLException&)
+ {
+ OSL_FAIL("Failure while building group by!");
+ }
+
+ return eErrorCode;
+ }
+
+ //------------------------------------------------------------------------------
+ void GenerateInnerJoinCriterias(const Reference< XConnection>& _xConnection,
+ ::rtl::OUString& _rJoinCrit,
+ const ::std::vector<OTableConnection*>* _pConnList)
+ {
+ ::std::vector<OTableConnection*>::const_iterator aIter = _pConnList->begin();
+ ::std::vector<OTableConnection*>::const_iterator aEnd = _pConnList->end();
+ for(;aIter != aEnd;++aIter)
+ {
+ const OQueryTableConnection* pEntryConn = static_cast<const OQueryTableConnection*>(*aIter);
+ OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get());
+ if ( pEntryConnData->GetJoinType() == INNER_JOIN && !pEntryConnData->isNatural() )
+ {
+ if(_rJoinCrit.getLength())
+ _rJoinCrit += C_AND;
+ _rJoinCrit += BuildJoinCriteria(_xConnection,pEntryConnData->GetConnLineDataList(),pEntryConnData);
+ }
+ }
+ }
+ //------------------------------------------------------------------------------
+ void searchAndAppendName(const Reference< XConnection>& _xConnection,
+ const OQueryTableWindow* _pTableWindow,
+ ::std::map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess>& _rTableNames,
+ ::rtl::OUString& _rsTableListStr
+ )
+ {
+ ::rtl::OUString sTabName(BuildTable(_xConnection,_pTableWindow));
+
+ if(_rTableNames.find(sTabName) == _rTableNames.end())
+ {
+ _rTableNames[sTabName] = sal_True;
+ _rsTableListStr += sTabName;
+ _rsTableListStr += ::rtl::OUString(',');
+ }
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString GenerateFromClause( const Reference< XConnection>& _xConnection,
+ const OQueryTableView::OTableWindowMap* pTabList,
+ const ::std::vector<OTableConnection*>* pConnList
+ )
+ {
+
+ ::rtl::OUString aTableListStr;
+ // wird gebraucht um sicher zustelllen das eine Tabelle nicht doppelt vorkommt
+ ::std::map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess> aTableNames;
+
+ // generate outer join clause in from
+ if(!pConnList->empty())
+ {
+ ::std::vector<OTableConnection*>::const_iterator aIter = pConnList->begin();
+ ::std::vector<OTableConnection*>::const_iterator aEnd = pConnList->end();
+ ::std::map<OTableWindow*,sal_Int32> aConnectionCount;
+ for(;aIter != aEnd;++aIter)
+ {
+ static_cast<OQueryTableConnection*>(*aIter)->SetVisited(sal_False);
+ if ( aConnectionCount.find((*aIter)->GetSourceWin()) == aConnectionCount.end() )
+ aConnectionCount.insert(::std::map<OTableWindow*,sal_Int32>::value_type((*aIter)->GetSourceWin(),0));
+ else
+ aConnectionCount[(*aIter)->GetSourceWin()]++;
+ if ( aConnectionCount.find((*aIter)->GetDestWin()) == aConnectionCount.end() )
+ aConnectionCount.insert(::std::map<OTableWindow*,sal_Int32>::value_type((*aIter)->GetDestWin(),0));
+ else
+ aConnectionCount[(*aIter)->GetDestWin()]++;
+ }
+ ::std::multimap<sal_Int32 , OTableWindow*> aMulti;
+ ::std::map<OTableWindow*,sal_Int32>::iterator aCountIter = aConnectionCount.begin();
+ ::std::map<OTableWindow*,sal_Int32>::iterator aCountEnd = aConnectionCount.end();
+ for(;aCountIter != aCountEnd;++aCountIter)
+ {
+ aMulti.insert(::std::multimap<sal_Int32 , OTableWindow*>::value_type(aCountIter->second,aCountIter->first));
+ }
+
+ const sal_Bool bUseEscape = ::dbtools::getBooleanDataSourceSetting( _xConnection, PROPERTY_OUTERJOINESCAPE );
+ ::std::multimap<sal_Int32 , OTableWindow*>::reverse_iterator aRIter = aMulti.rbegin();
+ ::std::multimap<sal_Int32 , OTableWindow*>::reverse_iterator aREnd = aMulti.rend();
+ for(;aRIter != aREnd;++aRIter)
+ {
+ ::std::vector<OTableConnection*>::const_iterator aConIter = aRIter->second->getTableView()->getTableConnections(aRIter->second);
+ for(;aConIter != aEnd;++aConIter)
+ {
+ OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aConIter);
+ if(!pEntryConn->IsVisited() && pEntryConn->GetSourceWin() == aRIter->second )
+ {
+ ::rtl::OUString aJoin;
+ GetNextJoin(_xConnection,pEntryConn,static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),aJoin);
+
+ if(aJoin.getLength())
+ {
+ // insert tables into table list to avoid double entries
+ OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
+ OQueryTableWindow* pEntryTabTo = static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin());
+
+ ::rtl::OUString sTabName(BuildTable(_xConnection,pEntryTabFrom));
+ if(aTableNames.find(sTabName) == aTableNames.end())
+ aTableNames[sTabName] = sal_True;
+ sTabName = BuildTable(_xConnection,pEntryTabTo);
+ if(aTableNames.find(sTabName) == aTableNames.end())
+ aTableNames[sTabName] = sal_True;
+
+ ::rtl::OUString aStr;
+ switch(static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get())->GetJoinType())
+ {
+ case LEFT_JOIN:
+ case RIGHT_JOIN:
+ case FULL_JOIN:
+ {
+ // create outer join
+ if ( bUseEscape )
+ aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("{ OJ "));
+ aStr += aJoin;
+ if ( bUseEscape )
+ aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" }"));
+ }
+ break;
+ default:
+ aStr += aJoin;
+ break;
+ }
+ aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
+ aTableListStr += aStr;
+ }
+ }
+ }
+ }
+
+ // and now all inner joins
+ aIter = pConnList->begin();
+ for(;aIter != aEnd;++aIter)
+ {
+ OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aIter);
+ if(!pEntryConn->IsVisited())
+ {
+ searchAndAppendName(_xConnection,
+ static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()),
+ aTableNames,
+ aTableListStr);
+
+ searchAndAppendName(_xConnection,
+ static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),
+ aTableNames,
+ aTableListStr);
+ }
+ }
+ }
+ // all tables that haven't a connection to anyone
+ OQueryTableView::OTableWindowMap::const_iterator aTabIter = pTabList->begin();
+ OQueryTableView::OTableWindowMap::const_iterator aTabEnd = pTabList->end();
+ for(;aTabIter != aTabEnd;++aTabIter)
+ {
+ const OQueryTableWindow* pEntryTab = static_cast<const OQueryTableWindow*>(aTabIter->second);
+ if(!pEntryTab->ExistsAConn())
+ {
+ aTableListStr += BuildTable(_xConnection,pEntryTab);
+ aTableListStr += ::rtl::OUString(',');
+ }
+ }
+
+ if(aTableListStr.getLength())
+ aTableListStr = aTableListStr.replaceAt(aTableListStr.getLength()-1,1, ::rtl::OUString() );
+ return aTableListStr;
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString GenerateGroupBy(const OQueryDesignView* _pView,OTableFields& _rFieldList, sal_Bool bMulti )
+ {
+ OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+ const Reference< XConnection> xConnection = rController.getConnection();
+ if(!xConnection.is())
+ return ::rtl::OUString();
+
+ ::std::map< rtl::OUString,bool> aGroupByNames;
+
+ ::rtl::OUString aGroupByStr;
+ try
+ {
+ const Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
+
+ OTableFields::iterator aIter = _rFieldList.begin();
+ OTableFields::iterator aEnd = _rFieldList.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableFieldDescRef pEntryField = *aIter;
+ if ( pEntryField->IsGroupBy() )
+ {
+ OSL_ENSURE(pEntryField->GetField().getLength(),"Kein FieldName vorhanden!;-(");
+ ::rtl::OUString sGroupByPart = quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
+
+ // only quote the field name when it isn't calculated
+ if ( pEntryField->isNoneFunction() )
+ {
+ sGroupByPart += ::dbtools::quoteName(aQuote, pEntryField->GetField());
+ }
+ else
+ {
+ ::rtl::OUString aTmp = pEntryField->GetField();
+ ::rtl::OUString aErrorMsg;
+ Reference<XPropertySet> xColumn;
+ ::std::auto_ptr< ::connectivity::OSQLParseNode> pParseNode(_pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn));
+ if (pParseNode.get())
+ {
+ ::rtl::OUString sGroupBy;
+ pParseNode->getChild(0)->parseNodeToStr( sGroupBy,
+ xConnection,
+ &rController.getParser().getContext(),
+ sal_False,
+ !pEntryField->isOtherFunction());
+ sGroupByPart += sGroupBy;
+ }
+ else
+ sGroupByPart += pEntryField->GetField();
+ }
+ if ( aGroupByNames.find(sGroupByPart) == aGroupByNames.end() )
+ {
+ aGroupByNames.insert(::std::map< rtl::OUString,bool>::value_type(sGroupByPart,true));
+ aGroupByStr += sGroupByPart;
+ aGroupByStr += ::rtl::OUString(',');
+ }
+ }
+ }
+ if ( aGroupByStr.getLength() )
+ {
+ aGroupByStr = aGroupByStr.replaceAt(aGroupByStr.getLength()-1,1, ::rtl::OUString(' ') );
+ ::rtl::OUString aGroupByStr2(RTL_CONSTASCII_USTRINGPARAM(" GROUP BY "));
+ aGroupByStr2 += aGroupByStr;
+ aGroupByStr = aGroupByStr2;
+ }
+ }
+ catch(SQLException&)
+ {
+ OSL_FAIL("Failure while building group by!");
+ }
+ return aGroupByStr;
+ }
+ // -----------------------------------------------------------------------------
+ SqlParseError GetORCriteria(OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode * pCondition,
+ sal_uInt16& nLevel ,
+ sal_Bool bHaving = sal_False,
+ bool bAddOrOnOneLine = false);
+ // -----------------------------------------------------------------------------
+ SqlParseError GetSelectionCriteria( OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode* pNode,
+ sal_uInt16& rLevel )
+ {
+ if (!SQL_ISRULE(pNode, select_statement))
+ return eNoSelectStatement;
+
+ // nyi: mehr Pruefung auf korrekte Struktur!
+ pNode = pNode ? pNode->getChild(3)->getChild(1) : NULL;
+ // no where clause found
+ if (!pNode || pNode->isLeaf())
+ return eOk;
+
+ // Naechster freier Satz ...
+ SqlParseError eErrorCode = eOk;
+ ::connectivity::OSQLParseNode * pCondition = pNode->getChild(1);
+ if ( pCondition ) // no where clause
+ {
+ // now we have to chech the other conditions
+ // first make the logical easier
+ ::connectivity::OSQLParseNode::negateSearchCondition(pCondition);
+ ::connectivity::OSQLParseNode *pNodeTmp = pNode->getChild(1);
+
+ ::connectivity::OSQLParseNode::disjunctiveNormalForm(pNodeTmp);
+ pNodeTmp = pNode->getChild(1);
+ ::connectivity::OSQLParseNode::absorptions(pNodeTmp);
+ pNodeTmp = pNode->getChild(1);
+ // compress sort the criteria @see http://www.openoffice.org/issues/show_bug.cgi?id=24079
+ OSQLParseNode::compress(pNodeTmp);
+ pNodeTmp = pNode->getChild(1);
+
+ // first extract the inner joins conditions
+ GetInnerJoinCriteria(_pView,pNodeTmp);
+ // now simplify again, join are checked in ComparisonPredicate
+ ::connectivity::OSQLParseNode::absorptions(pNodeTmp);
+ pNodeTmp = pNode->getChild(1);
+
+ // it could happen that pCondition is not more valid
+ eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pNodeTmp, rLevel);
+ }
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError GetANDCriteria( OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode * pCondition,
+ sal_uInt16& nLevel,
+ sal_Bool bHaving,
+ bool bAddOrOnOneLine);
+ //------------------------------------------------------------------------------
+ SqlParseError ComparisonPredicate(OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode * pCondition,
+ const sal_uInt16 nLevel,
+ sal_Bool bHaving,
+ bool bAddOrOnOneLine);
+ //------------------------------------------------------------------------------
+ SqlParseError GetORCriteria(OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode * pCondition,
+ sal_uInt16& nLevel ,
+ sal_Bool bHaving,
+ bool bAddOrOnOneLine)
+ {
+ SqlParseError eErrorCode = eOk;
+
+ // Runde Klammern um den Ausdruck
+ if (pCondition->count() == 3 &&
+ SQL_ISPUNCTUATION(pCondition->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pCondition->getChild(2),")"))
+ {
+ eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pCondition->getChild(1),nLevel,bHaving,bAddOrOnOneLine);
+ }
+ // oder Verknuepfung
+ // a searchcondition can only look like this: search_condition SQL_TOKEN_OR boolean_term
+ else if (SQL_ISRULE(pCondition,search_condition))
+ {
+ for (int i = 0; i < 3 && eErrorCode == eOk ; i+=2)
+ {
+ const ::connectivity::OSQLParseNode* pChild = pCondition->getChild(i);
+ if ( SQL_ISRULE(pChild,search_condition) )
+ eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pChild,nLevel,bHaving,bAddOrOnOneLine);
+ else
+ {
+ eErrorCode = GetANDCriteria(_pView,_pSelectionBrw,pChild, nLevel,bHaving, i == 0 ? false : bAddOrOnOneLine);
+ if ( !bAddOrOnOneLine)
+ nLevel++;
+ }
+ }
+ }
+ else
+ eErrorCode = GetANDCriteria( _pView,_pSelectionBrw,pCondition, nLevel, bHaving,bAddOrOnOneLine );
+
+ return eErrorCode;
+ }
+ //--------------------------------------------------------------------------------------------------
+ bool CheckOrCriteria(const ::connectivity::OSQLParseNode* _pCondition,::connectivity::OSQLParseNode* _pFirstColumnRef)
+ {
+ bool bRet = true;
+ ::connectivity::OSQLParseNode* pFirstColumnRef = _pFirstColumnRef;
+ for (int i = 0; i < 3 && bRet; i+=2)
+ {
+ const ::connectivity::OSQLParseNode* pChild = _pCondition->getChild(i);
+ if ( SQL_ISRULE(pChild,search_condition) )
+ bRet = CheckOrCriteria(pChild,pFirstColumnRef);
+ else
+ {
+ // this is a simple way to test columns are the same, may be we have to adjust this algo a little bit in future. :-)
+ ::connectivity::OSQLParseNode* pSecondColumnRef = pChild->getByRule(::connectivity::OSQLParseNode::column_ref);
+ if ( pFirstColumnRef && pSecondColumnRef )
+ bRet = *pFirstColumnRef == *pSecondColumnRef;
+ else if ( !pFirstColumnRef )
+ pFirstColumnRef = pSecondColumnRef;
+ }
+ }
+ return bRet;
+ }
+ //--------------------------------------------------------------------------------------------------
+ SqlParseError GetANDCriteria( OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode * pCondition,
+ sal_uInt16& nLevel,
+ sal_Bool bHaving,
+ bool bAddOrOnOneLine)
+ {
+ const ::com::sun::star::lang::Locale aLocale = _pView->getLocale();
+ const ::rtl::OUString sDecimal = _pView->getDecimalSeparator();
+
+ // ich werde ein paar Mal einen gecasteten Pointer auf meinen ::com::sun::star::sdbcx::Container brauchen
+ OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+ SqlParseError eErrorCode = eOk;
+
+ // Runde Klammern
+ if (SQL_ISRULE(pCondition,boolean_primary))
+ {
+ // check if we have to put the or criteria on one line.
+ const ::connectivity::OSQLParseNode* pSearchCondition = pCondition->getChild(1);
+ bool bMustAddOrOnOneLine = CheckOrCriteria(pSearchCondition,NULL);
+ if ( SQL_ISRULE( pSearchCondition, search_condition) ) // we have a or
+ {
+ _pSelectionBrw->DuplicateConditionLevel( nLevel);
+ eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSearchCondition->getChild(0), nLevel,bHaving,bMustAddOrOnOneLine );
+ ++nLevel;
+ eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSearchCondition->getChild(2), nLevel,bHaving,bMustAddOrOnOneLine );
+ }
+ else
+ eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSearchCondition, nLevel,bHaving,bMustAddOrOnOneLine );
+ }
+ // Das erste Element ist (wieder) eine AND-Verknuepfung
+ else if ( SQL_ISRULE(pCondition,boolean_term) )
+ {
+ OSL_ENSURE(pCondition->count() == 3,"Illegal definifiton of boolean_term");
+ eErrorCode = GetANDCriteria(_pView,_pSelectionBrw,pCondition->getChild(0), nLevel,bHaving,bAddOrOnOneLine );
+ if ( eErrorCode == eOk )
+ eErrorCode = GetANDCriteria(_pView,_pSelectionBrw,pCondition->getChild(2), nLevel,bHaving,bAddOrOnOneLine );
+ }
+ else if (SQL_ISRULE( pCondition, comparison_predicate))
+ {
+ eErrorCode = ComparisonPredicate(_pView,_pSelectionBrw,pCondition,nLevel,bHaving,bAddOrOnOneLine);
+ }
+ else if( SQL_ISRULE(pCondition,like_predicate) )
+ {
+ const ::connectivity::OSQLParseNode* pValueExp = pCondition->getChild(0);
+ if (SQL_ISRULE(pValueExp, column_ref ) )
+ {
+ ::rtl::OUString aColumnName;
+ ::rtl::OUString aCondition;
+ Reference< XConnection> xConnection = rController.getConnection();
+ if ( xConnection.is() )
+ {
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ // the international doesn't matter I have a string
+ pCondition->parseNodeToPredicateStr(aCondition,
+ xConnection,
+ rController.getNumberFormatter(),
+ aLocale,
+ static_cast<sal_Char>(sDecimal.toChar()),
+ &rController.getParser().getContext());
+
+ pValueExp->parseNodeToPredicateStr( aColumnName,
+ xConnection,
+ rController.getNumberFormatter(),
+ aLocale,
+ static_cast<sal_Char>(sDecimal.toChar()),
+ &rController.getParser().getContext());
+
+ // don't display the column name
+ aCondition = aCondition.copy(aColumnName.getLength());
+ aCondition = aCondition.trim();
+ }
+
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+ if ( eOk == ( eErrorCode = FillDragInfo(_pView,pValueExp,aDragLeft) ))
+ {
+ if ( bHaving )
+ aDragLeft->SetGroupBy(sal_True);
+ _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
+ }
+ }
+ else if(SQL_ISRULEOR2(pValueExp,general_set_fct ,set_fct_spec) ||
+ SQL_ISRULEOR2(pValueExp,position_exp,extract_exp) ||
+ SQL_ISRULEOR2(pValueExp,fold,char_substring_fct) ||
+ SQL_ISRULEOR2(pValueExp,length_exp,char_value_fct))
+ {
+ AddFunctionCondition( _pView,
+ _pSelectionBrw,
+ pCondition,
+ nLevel,
+ bHaving,
+ bAddOrOnOneLine);
+ }
+ else
+ {
+ eErrorCode = eNoColumnInLike;
+ String sError(ModuleRes(STR_QRY_LIKE_LEFT_NO_COLUMN));
+ _pView->getController().appendError( sError );
+ }
+ }
+ else if( SQL_ISRULEOR2(pCondition,test_for_null,in_predicate)
+ || SQL_ISRULEOR2(pCondition,all_or_any_predicate,between_predicate))
+ {
+ if ( SQL_ISRULEOR2(pCondition->getChild(0), set_fct_spec , general_set_fct ) )
+ {
+ AddFunctionCondition( _pView,
+ _pSelectionBrw,
+ pCondition,
+ nLevel,
+ bHaving,
+ bAddOrOnOneLine);
+ }
+ else if ( SQL_ISRULE(pCondition->getChild(0), column_ref ) )
+ {
+ // parse condition
+ ::rtl::OUString sCondition = ParseCondition(rController,pCondition,sDecimal,aLocale,1);
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+ if ( eOk == ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(0),aDragLeft)) )
+ {
+ if ( bHaving )
+ aDragLeft->SetGroupBy(sal_True);
+ _pSelectionBrw->AddCondition(aDragLeft, sCondition, nLevel,bAddOrOnOneLine);
+ }
+ }
+ else
+ {
+ // Funktions-Bedingung parsen
+ ::rtl::OUString sCondition = ParseCondition(rController,pCondition,sDecimal,aLocale,1);
+ Reference< XConnection> xConnection = rController.getConnection();
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ // the international doesn't matter I have a string
+ ::rtl::OUString sName;
+ pCondition->getChild(0)->parseNodeToPredicateStr(sName,
+ xConnection,
+ rController.getNumberFormatter(),
+ aLocale,
+ static_cast<sal_Char>(sDecimal.toChar()),
+ &rController.getParser().getContext());
+
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+ aDragLeft->SetField(sName);
+ aDragLeft->SetFunctionType(FKT_OTHER);
+
+ if ( bHaving )
+ aDragLeft->SetGroupBy(sal_True);
+ _pSelectionBrw->AddCondition(aDragLeft, sCondition, nLevel,bAddOrOnOneLine);
+ }
+ }
+ else if( SQL_ISRULEOR2(pCondition,existence_test,unique_test) )
+ {
+ // Funktions-Bedingung parsen
+ ::rtl::OUString aCondition = ParseCondition(rController,pCondition,sDecimal,aLocale,0);
+
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+ aDragLeft->SetField(aCondition);
+ aDragLeft->SetFunctionType(FKT_CONDITION);
+
+ eErrorCode = _pSelectionBrw->InsertField(aDragLeft,BROWSER_INVALIDID,sal_False,sal_True).is() ? eOk : eTooManyColumns;
+ }
+ else //! TODO not supported yet
+ eErrorCode = eStatementTooComplex;
+ // Fehler einfach weiterreichen.
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError AddFunctionCondition(OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode * pCondition,
+ const sal_uInt16 nLevel,
+ sal_Bool bHaving,
+ bool bAddOrOnOneLine)
+ {
+ SqlParseError eErrorCode = eOk;
+ OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+
+ OSQLParseNode* pFunction = pCondition->getChild(0);
+
+ OSL_ENSURE(SQL_ISRULEOR2(pFunction,general_set_fct ,set_fct_spec) ||
+ SQL_ISRULEOR2(pFunction,position_exp,extract_exp) ||
+ SQL_ISRULEOR2(pFunction,fold,char_substring_fct) ||
+ SQL_ISRULEOR2(pFunction,length_exp,char_value_fct),"Illegal call!");
+ ::rtl::OUString aCondition;
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+
+ ::rtl::OUString aColumnName;
+ Reference< XConnection> xConnection = rController.getConnection();
+ if(xConnection.is())
+ {
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ pCondition->parseNodeToPredicateStr(aCondition,
+ xConnection,
+ rController.getNumberFormatter(),
+ _pView->getLocale(),
+ static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
+ &rController.getParser().getContext());
+
+ pFunction->parseNodeToStr( aColumnName,
+ xConnection,
+ &rController.getParser().getContext(),
+ sal_True,
+ sal_True); // quote is to true because we need quoted elements inside the function
+ // don't display the column name
+ aCondition = aCondition.copy(aColumnName.getLength());
+ aCondition = aCondition.trim();
+ if ( aCondition.indexOf('=',0) == 0 ) // ignore the equal sign
+ aCondition = aCondition.copy(1);
+
+
+ if ( SQL_ISRULE(pFunction, general_set_fct ) )
+ {
+ sal_Int32 nFunctionType = FKT_AGGREGATE;
+ OSQLParseNode* pParamNode = pFunction->getChild(pFunction->count()-2);
+ if ( pParamNode && pParamNode->getTokenValue().toChar() == '*' )
+ {
+ OJoinTableView::OTableWindowMap* pTabList = _pView->getTableView()->GetTabWinMap();
+ OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin();
+ OJoinTableView::OTableWindowMap::iterator aTabEnd = pTabList->end();
+ for(;aIter != aTabEnd;++aIter)
+ {
+ OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second);
+ if (pTabWin->ExistsField( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), aDragLeft ))
+ {
+ aDragLeft->SetAlias(String());
+ aDragLeft->SetTable(String());
+ break;
+ }
+ }
+ }
+ else if( eOk != ( eErrorCode = FillDragInfo(_pView,pParamNode,aDragLeft))
+ && SQL_ISRULE(pParamNode,num_value_exp) )
+ {
+ ::rtl::OUString sParameterValue;
+ pParamNode->parseNodeToStr( sParameterValue,
+ xConnection,
+ &rController.getParser().getContext());
+ nFunctionType |= FKT_NUMERIC;
+ aDragLeft->SetField(sParameterValue);
+ eErrorCode = eOk;
+ }
+ aDragLeft->SetFunctionType(nFunctionType);
+ if ( bHaving )
+ aDragLeft->SetGroupBy(sal_True);
+ sal_Int32 nIndex = 0;
+ aDragLeft->SetFunction(aColumnName.getToken(0,'(',nIndex));
+ }
+ else
+ {
+ // bei unbekannten Funktionen wird der gesamte Text in das Field gechrieben
+ aDragLeft->SetField(aColumnName);
+ if(bHaving)
+ aDragLeft->SetGroupBy(sal_True);
+ aDragLeft->SetFunctionType(FKT_OTHER|FKT_NUMERIC);
+ }
+ _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
+ }
+
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError ComparisonPredicate(OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode * pCondition,
+ const sal_uInt16 nLevel,
+ sal_Bool bHaving
+ ,bool bAddOrOnOneLine)
+ {
+ SqlParseError eErrorCode = eOk;
+ OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+
+ OSL_ENSURE(SQL_ISRULE( pCondition, comparison_predicate),"ComparisonPredicate: pCondition ist kein ComparisonPredicate");
+ if ( SQL_ISRULE(pCondition->getChild(0), column_ref )
+ || SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref) )
+ {
+ ::rtl::OUString aCondition;
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+
+ if ( SQL_ISRULE(pCondition->getChild(0), column_ref ) && SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref ) )
+ {
+ OTableFieldDescRef aDragRight = new OTableFieldDesc();
+ if (eOk != ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(0),aDragLeft)) ||
+ eOk != ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(2),aDragRight)))
+ return eErrorCode;
+
+ OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>(
+ _pView->getTableView()->GetTabConn(static_cast<OQueryTableWindow*>(aDragLeft->GetTabWindow()),
+ static_cast<OQueryTableWindow*>(aDragRight->GetTabWindow()),
+ true));
+ if ( pConn )
+ {
+ OConnectionLineDataVec* pLineDataList = pConn->GetData()->GetConnLineDataList();
+ OConnectionLineDataVec::iterator aIter = pLineDataList->begin();
+ OConnectionLineDataVec::iterator aEnd = pLineDataList->end();
+ for(;aIter != aEnd;++aIter)
+ {
+ if((*aIter)->GetSourceFieldName() == aDragLeft->GetField() ||
+ (*aIter)->GetDestFieldName() == aDragLeft->GetField() )
+ break;
+ }
+ if(aIter != aEnd)
+ return eOk;
+ }
+ }
+
+ sal_uInt32 nPos = 0;
+ if(SQL_ISRULE(pCondition->getChild(0), column_ref ))
+ {
+ nPos = 0;
+ sal_uInt32 i=1;
+
+ // don't display the equal
+ if (pCondition->getChild(i)->getNodeType() == SQL_NODE_EQUAL)
+ i++;
+
+ // Bedingung parsen
+ aCondition = ParseCondition(rController
+ ,pCondition
+ ,_pView->getDecimalSeparator()
+ ,_pView->getLocale()
+ ,i);
+ }
+ else if( SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref ) )
+ {
+ nPos = pCondition->count()-1;
+
+ sal_Int32 i = static_cast<sal_Int32>(pCondition->count() - 2);
+ switch (pCondition->getChild(i)->getNodeType())
+ {
+ case SQL_NODE_EQUAL:
+ // don't display the equal
+ i--;
+ break;
+ case SQL_NODE_LESS:
+ // take the opposite as we change the order
+ i--;
+ aCondition = aCondition + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ break;
+ case SQL_NODE_LESSEQ:
+ // take the opposite as we change the order
+ i--;
+ aCondition = aCondition + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ break;
+ case SQL_NODE_GREAT:
+ // take the opposite as we change the order
+ i--;
+ aCondition = aCondition + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ break;
+ case SQL_NODE_GREATEQ:
+ // take the opposite as we change the order
+ i--;
+ aCondition = aCondition + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ break;
+ default:
+ break;
+ }
+
+ // go backward
+ Reference< XConnection> xConnection = rController.getConnection();
+ if(xConnection.is())
+ {
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ for (; i >= 0; i--)
+ pCondition->getChild(i)->parseNodeToPredicateStr(aCondition,
+ xConnection,
+ rController.getNumberFormatter(),
+ _pView->getLocale(),
+ static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
+ &rController.getParser().getContext());
+ }
+ }
+ // else ???
+
+
+ if( eOk == ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(nPos),aDragLeft)))
+ {
+ if(bHaving)
+ aDragLeft->SetGroupBy(sal_True);
+ _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
+ }
+ }
+ else if( SQL_ISRULEOR2(pCondition->getChild(0), set_fct_spec , general_set_fct ) )
+ {
+ AddFunctionCondition( _pView,
+ _pSelectionBrw,
+ pCondition,
+ nLevel,
+ bHaving,
+ bAddOrOnOneLine);
+ }
+ else // kann sich nur um einen Expr. Ausdruck handeln
+ {
+ ::rtl::OUString aName,aCondition;
+
+ ::connectivity::OSQLParseNode *pLhs = pCondition->getChild(0);
+ ::connectivity::OSQLParseNode *pRhs = pCondition->getChild(2);
+ // Feldnamen
+ Reference< XConnection> xConnection = rController.getConnection();
+ if(xConnection.is())
+ {
+ pLhs->parseNodeToStr(aName,
+ xConnection,
+ &rController.getParser().getContext(),
+ sal_True);
+ // Kriterium
+ aCondition = pCondition->getChild(1)->getTokenValue();
+ pRhs->parseNodeToPredicateStr(aCondition,
+ xConnection,
+ rController.getNumberFormatter(),
+ _pView->getLocale(),
+ static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
+ &rController.getParser().getContext());
+ }
+
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+ aDragLeft->SetField(aName);
+ aDragLeft->SetFunctionType(FKT_OTHER|FKT_NUMERIC);
+ // und anh"angen
+ _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
+ }
+ return eErrorCode;
+ }
+
+ //------------------------------------------------------------------------------
+ namespace
+ {
+ OQueryTableWindow* lcl_findColumnInTables( const ::rtl::OUString& _rColumName, const OJoinTableView::OTableWindowMap& _rTabList, OTableFieldDescRef& _rInfo )
+ {
+ OJoinTableView::OTableWindowMap::const_iterator aIter = _rTabList.begin();
+ OJoinTableView::OTableWindowMap::const_iterator aEnd = _rTabList.end();
+ for ( ; aIter != aEnd; ++aIter )
+ {
+ OQueryTableWindow* pTabWin = static_cast< OQueryTableWindow* >( aIter->second );
+ if ( pTabWin && pTabWin->ExistsField( _rColumName, _rInfo ) )
+ return pTabWin;
+ }
+ return NULL;
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ void InsertColumnRef(const OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode * pColumnRef,
+ ::rtl::OUString& aColumnName,
+ const ::rtl::OUString& aColumnAlias,
+ ::rtl::OUString& aTableRange,
+ OTableFieldDescRef& _raInfo,
+ OJoinTableView::OTableWindowMap* pTabList)
+ {
+
+ // Tabellennamen zusammen setzen
+ ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController&>(_pView->getController()).getParseIterator();
+ rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange );
+
+ sal_Bool bFound(sal_False);
+ OSL_ENSURE(aColumnName.getLength(),"Columnname darf nicht leer sein");
+ if (!aTableRange.getLength())
+ {
+ // SELECT column, ...
+ bFound = NULL != lcl_findColumnInTables( aColumnName, *pTabList, _raInfo );
+ if ( bFound && ( aColumnName.toChar() != '*' ) )
+ _raInfo->SetFieldAlias(aColumnAlias);
+ }
+ else
+ {
+ // SELECT range.column, ...
+ OQueryTableWindow* pTabWin = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable(aTableRange);
+
+ if (pTabWin && pTabWin->ExistsField(aColumnName, _raInfo))
+ {
+ if(aColumnName.toChar() != '*')
+ _raInfo->SetFieldAlias(aColumnAlias);
+ bFound = sal_True;
+ }
+ }
+ if (!bFound)
+ {
+ _raInfo->SetTable(::rtl::OUString());
+ _raInfo->SetAlias(::rtl::OUString());
+ _raInfo->SetField(aColumnName);
+ _raInfo->SetFieldAlias(aColumnAlias); // nyi : hier ein fortlaufendes Expr_1, Expr_2 ...
+ _raInfo->SetFunctionType(FKT_OTHER);
+ }
+ }
+ //-----------------------------------------------------------------------------
+ sal_Bool checkJoinConditions( const OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode* _pNode )
+ {
+ const ::connectivity::OSQLParseNode* pJoinNode = NULL;
+ sal_Bool bRet = sal_True;
+ if (SQL_ISRULE(_pNode,qualified_join))
+ pJoinNode = _pNode;
+ else if (SQL_ISRULE(_pNode,table_ref)
+ && _pNode->count() == 3
+ && SQL_ISPUNCTUATION(_pNode->getChild(0),"(")
+ && SQL_ISPUNCTUATION(_pNode->getChild(2),")") ) // '(' joined_table ')'
+ pJoinNode = _pNode->getChild(1);
+ else if (! ( SQL_ISRULE(_pNode, table_ref) && _pNode->count() == 2) ) // table_node table_primary_as_range_column
+ bRet = sal_False;
+
+ if (pJoinNode && !InsertJoin(_pView,pJoinNode))
+ bRet = sal_False;
+ return bRet;
+ }
+ //-----------------------------------------------------------------------------
+ sal_Bool InsertJoin(const OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode *pNode)
+ {
+ OSL_ENSURE( SQL_ISRULE( pNode, qualified_join ) || SQL_ISRULE( pNode, joined_table ) || SQL_ISRULE( pNode, cross_union ),
+ "OQueryDesignView::InsertJoin: Fehler im Parse Tree");
+
+ if (SQL_ISRULE(pNode,joined_table))
+ return InsertJoin(_pView,pNode->getChild(1));
+
+ // first check the left and right side
+ const ::connectivity::OSQLParseNode* pRightTableRef = pNode->getChild(3); // table_ref
+ if ( SQL_ISRULE(pNode, qualified_join) && SQL_ISTOKEN(pNode->getChild(1),NATURAL) )
+ pRightTableRef = pNode->getChild(4); // table_ref
+
+ if ( !checkJoinConditions(_pView,pNode->getChild(0)) || !checkJoinConditions(_pView,pRightTableRef))
+ return sal_False;
+
+ // named column join wird später vieleicht noch implementiert
+ // SQL_ISRULE(pNode->getChild(4),named_columns_join)
+ EJoinType eJoinType = INNER_JOIN;
+ bool bNatural = false;
+ if ( SQL_ISRULE(pNode, qualified_join) )
+ {
+ ::connectivity::OSQLParseNode* pJoinType = pNode->getChild(1); // join_type
+ if ( SQL_ISTOKEN(pJoinType,NATURAL) )
+ {
+ bNatural = true;
+ pJoinType = pNode->getChild(2);
+ }
+
+ if (SQL_ISRULE(pJoinType,join_type) && (!pJoinType->count() || SQL_ISTOKEN(pJoinType->getChild(0),INNER)))
+ {
+ eJoinType = INNER_JOIN;
+ }
+ else
+ {
+ if (SQL_ISRULE(pJoinType,join_type)) // eine Ebene tiefer
+ pJoinType = pJoinType->getChild(0);
+
+ if (SQL_ISTOKEN(pJoinType->getChild(0),LEFT))
+ eJoinType = LEFT_JOIN;
+ else if(SQL_ISTOKEN(pJoinType->getChild(0),RIGHT))
+ eJoinType = RIGHT_JOIN;
+ else
+ eJoinType = FULL_JOIN;
+ }
+ if ( SQL_ISRULE(pNode->getChild(4),join_condition) )
+ {
+ if ( InsertJoinConnection(_pView,pNode->getChild(4)->getChild(1), eJoinType,pNode->getChild(0),pRightTableRef) != eOk )
+ return sal_False;
+ }
+ }
+ else if ( SQL_ISRULE(pNode, cross_union) )
+ {
+ eJoinType = CROSS_JOIN;
+ pRightTableRef = pNode->getChild(pNode->count() - 1);
+ }
+ else
+ return sal_False;
+
+ if ( eJoinType == CROSS_JOIN || bNatural )
+ {
+
+ OQueryTableWindow* pLeftWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pNode->getChild(0)) );
+ OQueryTableWindow* pRightWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pRightTableRef) );
+ OSL_ENSURE(pLeftWindow && pRightWindow,"Table Windows could not be found!");
+ if ( !pLeftWindow || !pRightWindow )
+ return sal_False;
+
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+ aDragLeft->SetTabWindow(pLeftWindow);
+ aDragLeft->SetTable(pLeftWindow->GetTableName());
+ aDragLeft->SetAlias(pLeftWindow->GetAliasName());
+
+ OTableFieldDescRef aDragRight = new OTableFieldDesc();
+ aDragRight->SetTabWindow(pRightWindow);
+ aDragRight->SetTable(pRightWindow->GetTableName());
+ aDragRight->SetAlias(pRightWindow->GetAliasName());
+
+ insertConnection(_pView,eJoinType,aDragLeft,aDragRight,bNatural);
+ }
+
+
+ return sal_True;
+ }
+ //------------------------------------------------------------------------------
+ void insertUnUsedFields(OQueryDesignView* _pView,OSelectionBrowseBox* _pSelectionBrw)
+ {
+ // now we have to insert the fields which aren't in the statement
+ OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+ OTableFields& rUnUsedFields = rController.getUnUsedFields();
+ OTableFields::iterator aEnd = rUnUsedFields.end();
+ for(OTableFields::iterator aIter = rUnUsedFields.begin();aIter != aEnd;++aIter)
+ if(_pSelectionBrw->InsertField(*aIter,BROWSER_INVALIDID,sal_False,sal_False).is())
+ (*aIter) = NULL;
+ OTableFields().swap( rUnUsedFields );
+ }
+
+ //------------------------------------------------------------------------------
+ SqlParseError InitFromParseNodeImpl(OQueryDesignView* _pView,OSelectionBrowseBox* _pSelectionBrw)
+ {
+ SqlParseError eErrorCode = eOk;
+
+ OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+
+ _pSelectionBrw->PreFill();
+ _pSelectionBrw->SetReadOnly(rController.isReadOnly());
+ _pSelectionBrw->Fill();
+
+
+ ::connectivity::OSQLParseTreeIterator& aIterator = rController.getParseIterator();
+ const ::connectivity::OSQLParseNode* pParseTree = aIterator.getParseTree();
+
+ do
+ {
+ if ( !pParseTree )
+ {
+ // now we have to insert the fields which aren't in the statement
+ insertUnUsedFields(_pView,_pSelectionBrw);
+ break;
+ }
+
+ if ( !rController.isEsacpeProcessing() ) // not allowed in this mode
+ {
+ eErrorCode = eNativeMode;
+ break;
+ }
+
+ if ( !( SQL_ISRULE( pParseTree, select_statement ) ) )
+ {
+ eErrorCode = eNoSelectStatement;
+ break;
+ }
+
+ Reference< XConnection> xConnection = rController.getConnection();
+ if ( !xConnection.is() )
+ {
+ OSL_FAIL( "InitFromParseNodeImpl: no connection? no connection!" );
+ break;
+ }
+
+ const OSQLTables& aMap = aIterator.getTables();
+ ::comphelper::UStringMixLess aTmp(aMap.key_comp());
+ ::comphelper::UStringMixEqual aKeyComp( aTmp.isCaseSensitive() );
+
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ try
+ {
+ sal_Int32 nMax = xMetaData->getMaxTablesInSelect();
+ if ( nMax && nMax < (sal_Int32)aMap.size() )
+ {
+ eErrorCode = eTooManyTables;
+ break;
+ }
+
+ ::rtl::OUString sComposedName;
+ ::rtl::OUString aQualifierName;
+ ::rtl::OUString sAlias;
+
+ OQueryTableView* pTableView = static_cast<OQueryTableView*>(_pView->getTableView());
+ pTableView->clearLayoutInformation();
+ OSQLTables::const_iterator aIter = aMap.begin();
+ OSQLTables::const_iterator aEnd = aMap.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OSQLTable xTable = aIter->second;
+ Reference< XPropertySet > xTableProps( xTable, UNO_QUERY_THROW );
+
+ sAlias = aIter->first;
+
+ // check whether this is a query
+ Reference< XPropertySetInfo > xPSI = xTableProps->getPropertySetInfo();
+ bool bIsQuery = xPSI.is() && xPSI->hasPropertyByName( PROPERTY_COMMAND );
+
+ if ( bIsQuery )
+ OSL_VERIFY( xTableProps->getPropertyValue( PROPERTY_NAME ) >>= sComposedName );
+ else
+ {
+ sComposedName = ::dbtools::composeTableName( xMetaData, xTableProps, ::dbtools::eInDataManipulation, false, false, false );
+
+ // if the alias is the complete (composed) table, then shorten it
+ if ( aKeyComp( sComposedName, aIter->first ) )
+ {
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ ::dbtools::qualifiedNameComponents( xMetaData, sComposedName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
+ sAlias = sTable;
+ }
+ }
+
+ // find the existent window for this alias
+ OQueryTableWindow* pExistentWin = pTableView->FindTable( sAlias );
+ if ( !pExistentWin )
+ {
+ pTableView->AddTabWin( sComposedName, sAlias, sal_False ); // don't create data here
+ }
+ else
+ {
+ // there already exists a window for this alias ....
+ if ( !aKeyComp( pExistentWin->GetData()->GetComposedName(), sComposedName ) )
+ // ... but for another complete table name -> new window
+ pTableView->AddTabWin(sComposedName, sAlias);
+ }
+ }
+
+ // now delete the data for which we haven't any tablewindow
+ OJoinTableView::OTableWindowMap aTableMap(*pTableView->GetTabWinMap());
+ OJoinTableView::OTableWindowMap::iterator aIterTableMap = aTableMap.begin();
+ OJoinTableView::OTableWindowMap::iterator aIterTableEnd = aTableMap.end();
+ for(;aIterTableMap != aIterTableEnd;++aIterTableMap)
+ {
+ if(aMap.find(aIterTableMap->second->GetComposedName()) == aMap.end() &&
+ aMap.find(aIterTableMap->first) == aMap.end())
+ pTableView->RemoveTabWin(aIterTableMap->second);
+ }
+
+ if ( eOk == (eErrorCode = FillOuterJoins(_pView,pParseTree->getChild(3)->getChild(0)->getChild(1))) )
+ {
+ // check if we have a distinct statement
+ if(SQL_ISTOKEN(pParseTree->getChild(1),DISTINCT))
+ {
+ rController.setDistinct(sal_True);
+ rController.InvalidateFeature(SID_QUERY_DISTINCT_VALUES);
+ }
+ if ( (eErrorCode = InstallFields(_pView,pParseTree, pTableView->GetTabWinMap())) == eOk )
+ {
+ // GetSelectionCriteria must be called before GetHavingCriteria
+ sal_uInt16 nLevel=0;
+
+ if ( eOk == (eErrorCode = GetSelectionCriteria(_pView,_pSelectionBrw,pParseTree,nLevel)) )
+ {
+ if ( eOk == (eErrorCode = GetGroupCriteria(_pView,_pSelectionBrw,pParseTree)) )
+ {
+ if ( eOk == (eErrorCode = GetHavingCriteria(_pView,_pSelectionBrw,pParseTree,nLevel)) )
+ {
+ if ( eOk == (eErrorCode = GetOrderCriteria(_pView,_pSelectionBrw,pParseTree)) )
+ insertUnUsedFields(_pView,_pSelectionBrw);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch(SQLException&)
+ {
+ OSL_FAIL("getMaxTablesInSelect!");
+ }
+ }
+ while ( false );
+
+ // Durch das Neuerzeugen wurden wieder Undo-Actions in den Manager gestellt
+ rController.ClearUndoManager();
+ _pSelectionBrw->Invalidate();
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ /** fillSelectSubList
+ @return
+ <TRUE/> when columns could be inserted otherwise <FALSE/>
+ */
+ //------------------------------------------------------------------------------
+ SqlParseError fillSelectSubList( OQueryDesignView* _pView,
+ OJoinTableView::OTableWindowMap* _pTabList)
+ {
+ SqlParseError eErrorCode = eOk;
+ sal_Bool bFirstField = sal_True;
+ ::rtl::OUString sAsterix(RTL_CONSTASCII_USTRINGPARAM("*"));
+ OJoinTableView::OTableWindowMap::iterator aIter = _pTabList->begin();
+ OJoinTableView::OTableWindowMap::iterator aEnd = _pTabList->end();
+ for(;aIter != aEnd && eOk == eErrorCode ;++aIter)
+ {
+ OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second);
+ OTableFieldDescRef aInfo = new OTableFieldDesc();
+ if (pTabWin->ExistsField( sAsterix, aInfo ))
+ {
+ eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
+ bFirstField = sal_False;
+ }
+ }
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError InstallFields(OQueryDesignView* _pView,
+ const ::connectivity::OSQLParseNode* pNode,
+ OJoinTableView::OTableWindowMap* pTabList )
+ {
+ if( pNode==0 || !SQL_ISRULE(pNode,select_statement))
+ return eNoSelectStatement;
+
+ ::connectivity::OSQLParseNode* pParseTree = pNode->getChild(2); // selection
+ sal_Bool bFirstField = sal_True; // bei der Initialisierung muß auf alle Faelle das erste Feld neu aktiviert werden
+
+ SqlParseError eErrorCode = eOk;
+
+ if ( pParseTree->isRule() && SQL_ISPUNCTUATION(pParseTree->getChild(0),"*") )
+ {
+ // SELECT * ...
+ eErrorCode = fillSelectSubList(_pView,pTabList);
+ }
+ else if (SQL_ISRULE(pParseTree,scalar_exp_commalist) )
+ {
+ // SELECT column, ...
+ OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+ Reference< XConnection> xConnection = rController.getConnection();
+
+ ::rtl::OUString aColumnName,aTableRange;
+ for (sal_uInt32 i = 0; i < pParseTree->count() && eOk == eErrorCode ; ++i)
+ {
+ ::connectivity::OSQLParseNode * pColumnRef = pParseTree->getChild(i);
+
+ do {
+
+ if ( SQL_ISRULE(pColumnRef,select_sublist) )
+ {
+ eErrorCode = fillSelectSubList(_pView,pTabList);
+ break;
+ }
+
+ if ( SQL_ISRULE(pColumnRef,derived_column) )
+ {
+ ::rtl::OUString aColumnAlias(rController.getParseIterator().getColumnAlias(pColumnRef)); // kann leer sein
+ pColumnRef = pColumnRef->getChild(0);
+ OTableFieldDescRef aInfo = new OTableFieldDesc();
+
+ if ( pColumnRef->count() == 3 &&
+ SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
+ )
+ pColumnRef = pColumnRef->getChild(1);
+
+ if (SQL_ISRULE(pColumnRef,column_ref))
+ {
+ InsertColumnRef(_pView,pColumnRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList);
+ eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
+ bFirstField = sal_False;
+ }
+ else if(SQL_ISRULEOR2(pColumnRef,general_set_fct ,set_fct_spec) ||
+ SQL_ISRULEOR2(pColumnRef,position_exp,extract_exp) ||
+ SQL_ISRULEOR2(pColumnRef,fold,char_substring_fct) ||
+ SQL_ISRULEOR2(pColumnRef,length_exp,char_value_fct))
+ {
+ ::rtl::OUString aColumns;
+ pColumnRef->parseNodeToPredicateStr(aColumns,
+ xConnection,
+ rController.getNumberFormatter(),
+ _pView->getLocale(),
+ static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
+ &rController.getParser().getContext());
+
+ sal_Int32 nFunctionType = FKT_NONE;
+ ::connectivity::OSQLParseNode* pParamRef = NULL;
+ sal_Int32 nColumnRefPos = pColumnRef->count() - 2;
+ if ( nColumnRefPos >= 0 && static_cast<sal_uInt32>(nColumnRefPos) < pColumnRef->count() )
+ pParamRef = pColumnRef->getChild(nColumnRefPos);
+
+ if ( SQL_ISRULE(pColumnRef,general_set_fct)
+ && SQL_ISRULE(pParamRef,column_ref) )
+ {
+ // Parameter auf Columnref pr"ufen
+ InsertColumnRef(_pView,pParamRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList);
+ }
+ else if ( SQL_ISRULE(pColumnRef,general_set_fct) )
+ {
+ if ( pParamRef && pParamRef->getTokenValue().toChar() == '*' )
+ {
+ OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin();
+ OJoinTableView::OTableWindowMap::iterator aEnd = pTabList->end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second);
+ if (pTabWin->ExistsField( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), aInfo ))
+ {
+ aInfo->SetAlias(String());
+ aInfo->SetTable(String());
+ break;
+ }
+ }
+ }
+ else
+ {
+ ::rtl::OUString sFieldName = aColumns;
+ if ( pParamRef )
+ { // we got an aggregate function but without column name inside
+ // so we set the whole argument of the function as field name
+ nFunctionType |= FKT_NUMERIC;
+ sFieldName = ::rtl::OUString();
+ pParamRef->parseNodeToStr( sFieldName,
+ xConnection,
+ &rController.getParser().getContext(),
+ sal_True,
+ sal_True); // quote is to true because we need quoted elements inside the function
+ }
+ aInfo->SetDataType(DataType::DOUBLE);
+ aInfo->SetFieldType(TAB_NORMAL_FIELD);
+ aInfo->SetField(sFieldName);
+ }
+ aInfo->SetTabWindow(NULL);
+ aInfo->SetFieldAlias(aColumnAlias);
+ }
+ else
+ {
+ _pView->fillFunctionInfo(pColumnRef,aColumns,aInfo);
+ aInfo->SetFieldAlias(aColumnAlias);
+ }
+
+ if ( SQL_ISRULE(pColumnRef,general_set_fct) )
+ {
+ aInfo->SetFunctionType(nFunctionType|FKT_AGGREGATE);
+ String aCol(aColumns);
+ aInfo->SetFunction(aCol.GetToken(0,'(').EraseTrailingChars(' '));
+ }
+ else
+ aInfo->SetFunctionType(nFunctionType|FKT_OTHER);
+
+ eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
+ bFirstField = sal_False;
+ }
+ else
+ {
+ ::rtl::OUString aColumns;
+ pColumnRef->parseNodeToStr( aColumns,
+ xConnection,
+ &rController.getParser().getContext(),
+ sal_True,
+ sal_True); // quote is to true because we need quoted elements inside the function
+
+ aInfo->SetTabWindow( NULL );
+
+ // since we support queries in queries, the thingie might belong to an existing "table"
+ OQueryTableWindow* pExistingTable = lcl_findColumnInTables( aColumns, *pTabList, aInfo );
+ if ( pExistingTable )
+ {
+ aInfo->SetTabWindow( pExistingTable );
+ aInfo->SetTable( pExistingTable->GetTableName() );
+ aInfo->SetAlias( pExistingTable->GetAliasName() );
+ }
+
+ aInfo->SetDataType(DataType::DOUBLE);
+ aInfo->SetFieldType(TAB_NORMAL_FIELD);
+ aInfo->SetField(aColumns);
+ aInfo->SetFieldAlias(aColumnAlias);
+ aInfo->SetFunctionType(FKT_NUMERIC | FKT_OTHER);
+
+ eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
+ bFirstField = sal_False;
+ }
+
+ break;
+ }
+
+ OSL_FAIL( "InstallFields: don't know how to interpret this parse node!" );
+
+ } while ( false );
+ }
+ }
+ else
+ eErrorCode = eStatementTooComplex;
+
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError GetOrderCriteria( OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode* pParseRoot )
+ {
+ SqlParseError eErrorCode = eOk;
+ if (!pParseRoot->getChild(3)->getChild(4)->isLeaf())
+ {
+ ::connectivity::OSQLParseNode* pNode = pParseRoot->getChild(3)->getChild(4)->getChild(2);
+ ::connectivity::OSQLParseNode* pParamRef = NULL;
+
+ OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+ EOrderDir eOrderDir;
+ OTableFieldDescRef aDragLeft = new OTableFieldDesc();
+ for( sal_uInt32 i=0 ; i<pNode->count() ; i++ )
+ {
+ eOrderDir = ORDER_ASC;
+ ::connectivity::OSQLParseNode* pChild = pNode->getChild( i );
+
+ if (SQL_ISTOKEN( pChild->getChild(1), DESC ) )
+ eOrderDir = ORDER_DESC;
+
+ ::connectivity::OSQLParseNode* pArgument = pChild->getChild(0);
+
+ if(SQL_ISRULE(pArgument,column_ref))
+ {
+ if( eOk == FillDragInfo(_pView,pArgument,aDragLeft))
+ _pSelectionBrw->AddOrder( aDragLeft, eOrderDir, i);
+ else // it could be a alias name for a field
+ {
+ ::rtl::OUString aTableRange,aColumnName;
+ ::connectivity::OSQLParseTreeIterator& rParseIter = rController.getParseIterator();
+ rParseIter.getColumnRange( pArgument, aColumnName, aTableRange );
+
+ OTableFields& aList = rController.getTableFieldDesc();
+ OTableFields::iterator aIter = aList.begin();
+ OTableFields::iterator aEnd = aList.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableFieldDescRef pEntry = *aIter;
+ if(pEntry.is() && pEntry->GetFieldAlias() == aColumnName)
+ pEntry->SetOrderDir( eOrderDir );
+ }
+ }
+ }
+ else if(SQL_ISRULE(pArgument, general_set_fct ) &&
+ SQL_ISRULE(pParamRef = pArgument->getChild(pArgument->count()-2),column_ref) &&
+ eOk == FillDragInfo(_pView,pParamRef,aDragLeft))
+ _pSelectionBrw->AddOrder( aDragLeft, eOrderDir, i );
+ else if( SQL_ISRULE(pArgument, set_fct_spec ) )
+ {
+
+ Reference< XConnection> xConnection = rController.getConnection();
+ if(xConnection.is())
+ {
+ ::rtl::OUString sCondition;
+ pArgument->parseNodeToPredicateStr(sCondition,
+ xConnection,
+ rController.getNumberFormatter(),
+ _pView->getLocale(),
+ static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
+ &rController.getParser().getContext());
+ _pView->fillFunctionInfo(pArgument,sCondition,aDragLeft);
+ aDragLeft->SetFunctionType(FKT_OTHER);
+ aDragLeft->SetOrderDir(eOrderDir);
+ aDragLeft->SetVisible(sal_False);
+ _pSelectionBrw->AddOrder( aDragLeft, eOrderDir, i );
+ }
+ else
+ eErrorCode = eColumnNotFound;
+ }
+ else
+ eErrorCode = eColumnNotFound;
+ }
+ }
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError GetHavingCriteria( OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode* pSelectRoot,
+ sal_uInt16& rLevel )
+ {
+ SqlParseError eErrorCode = eOk;
+ if (!pSelectRoot->getChild(3)->getChild(3)->isLeaf())
+ eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSelectRoot->getChild(3)->getChild(3)->getChild(1),rLevel, sal_True);
+ return eErrorCode;
+ }
+ //------------------------------------------------------------------------------
+ SqlParseError GetGroupCriteria( OQueryDesignView* _pView,
+ OSelectionBrowseBox* _pSelectionBrw,
+ const ::connectivity::OSQLParseNode* pSelectRoot )
+ {
+ SqlParseError eErrorCode = eOk;
+ if (!pSelectRoot->getChild(3)->getChild(2)->isLeaf()) // opt_group_by_clause
+ {
+ OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
+ ::connectivity::OSQLParseNode* pGroupBy = pSelectRoot->getChild(3)->getChild(2)->getChild(2);
+ OTableFieldDescRef aDragInfo = new OTableFieldDesc();
+ for( sal_uInt32 i=0 ; i < pGroupBy->count() && eOk == eErrorCode; ++i )
+ {
+ ::connectivity::OSQLParseNode* pParamRef = NULL;
+ ::connectivity::OSQLParseNode* pArgument = pGroupBy->getChild( i );
+ if(SQL_ISRULE(pArgument,column_ref))
+ {
+ if ( eOk == (eErrorCode = FillDragInfo(_pView,pArgument,aDragInfo)) )
+ {
+ aDragInfo->SetGroupBy(sal_True);
+ _pSelectionBrw->AddGroupBy(aDragInfo,i);
+ }
+ }
+ else if(SQL_ISRULE(pArgument, general_set_fct ) &&
+ SQL_ISRULE(pParamRef = pArgument->getChild(pArgument->count()-2),column_ref) &&
+ eOk == FillDragInfo(_pView,pParamRef,aDragInfo))
+ {
+ aDragInfo->SetGroupBy(sal_True);
+ _pSelectionBrw->AddGroupBy( aDragInfo, i );
+ }
+ else if( SQL_ISRULE(pArgument, set_fct_spec ) )
+ {
+ Reference< XConnection> xConnection = rController.getConnection();
+ if(xConnection.is())
+ {
+ ::rtl::OUString sGroupByExpression;
+ pArgument->parseNodeToStr( sGroupByExpression,
+ xConnection,
+ &rController.getParser().getContext(),
+ sal_True,
+ sal_True); // quote is to true because we need quoted elements inside the function
+ _pView->fillFunctionInfo(pArgument,sGroupByExpression,aDragInfo);
+ aDragInfo->SetFunctionType(FKT_OTHER);
+ aDragInfo->SetGroupBy(sal_True);
+ aDragInfo->SetVisible(sal_False);
+ _pSelectionBrw->AddGroupBy( aDragInfo, i );
+ }
+ else
+ eErrorCode = eColumnNotFound;
+ }
+ }
+ }
+ return eErrorCode;
+ }
+
+ //------------------------------------------------------------------------------
+ String getParseErrorMessage( SqlParseError _eErrorCode )
+ {
+ sal_uInt16 nResId;
+ switch(_eErrorCode)
+ {
+ case eIllegalJoin:
+ nResId = STR_QRY_ILLEGAL_JOIN;
+ break;
+ case eStatementTooLong:
+ nResId = STR_QRY_TOO_LONG_STATEMENT;
+ break;
+ case eNoConnection:
+ nResId = STR_QRY_SYNTAX;
+ break;
+ case eNoSelectStatement:
+ nResId = STR_QRY_NOSELECT;
+ break;
+ case eColumnInLikeNotFound:
+ nResId = STR_QRY_SYNTAX;
+ break;
+ case eNoColumnInLike:
+ nResId = STR_QRY_SYNTAX;
+ break;
+ case eColumnNotFound:
+ nResId = STR_QRY_SYNTAX;
+ break;
+ case eNativeMode:
+ nResId = STR_QRY_NATIVE;
+ break;
+ case eTooManyTables:
+ nResId = STR_QRY_TOO_MANY_TABLES;
+ break;
+ case eTooManyConditions:
+ nResId = STR_QRY_TOOMANYCOND;
+ break;
+ case eTooManyColumns:
+ nResId = STR_QRY_TOO_MANY_COLUMNS;
+ break;
+ case eStatementTooComplex:
+ nResId = STR_QRY_TOOCOMPLEX;
+ break;
+ default:
+ nResId = STR_QRY_SYNTAX;
+ break;
+ }
+ ;
+ return String( ModuleRes( nResId ) );
+ }
+
+ //------------------------------------------------------------------------------
+ //------------------------------------------------------------------------------
+}
+// end of anonymouse namespace
+DBG_NAME(OQueryDesignView)
+
+OQueryDesignView::OQueryDesignView( OQueryContainerWindow* _pParent,
+ OQueryController& _rController,
+ const Reference< XMultiServiceFactory >& _rFactory)
+ :OQueryView( _pParent, _rController, _rFactory )
+ ,m_aSplitter( this )
+ ,m_eChildFocus(NONE)
+ ,m_bInKeyEvent(sal_False)
+ ,m_bInSplitHandler( sal_False )
+{
+ DBG_CTOR(OQueryDesignView,NULL);
+
+ try
+ {
+ SvtSysLocale aSysLocale;
+ m_aLocale = aSysLocale.GetLocaleData().getLocale();
+ m_sDecimalSep = aSysLocale.GetLocaleData().getNumDecimalSep();
+ }
+ catch(Exception&)
+ {
+ }
+
+ m_pSelectionBox = new OSelectionBrowseBox(this);
+
+ setNoneVisbleRow(static_cast<OQueryController&>(getController()).getVisibleRows());
+ m_pSelectionBox->Show();
+ // Splitter einrichten
+ m_aSplitter.SetSplitHdl(LINK(this, OQueryDesignView,SplitHdl));
+ m_aSplitter.Show();
+
+}
+// -----------------------------------------------------------------------------
+OQueryDesignView::~OQueryDesignView()
+{
+ if ( m_pTableView )
+ ::dbaui::notifySystemWindow(this,m_pTableView,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
+ ::std::auto_ptr<Window> aTemp(m_pSelectionBox);
+ m_pSelectionBox = NULL;
+
+ DBG_DTOR(OQueryDesignView,NULL);
+}
+//------------------------------------------------------------------------------
+IMPL_LINK( OQueryDesignView, SplitHdl, void*, /*p*/ )
+{
+ if (!getController().isReadOnly())
+ {
+ m_bInSplitHandler = sal_True;
+ m_aSplitter.SetPosPixel( Point( m_aSplitter.GetPosPixel().X(),m_aSplitter.GetSplitPosPixel() ) );
+ static_cast<OQueryController&>(getController()).setSplitPos(m_aSplitter.GetSplitPosPixel());
+ static_cast<OQueryController&>(getController()).setModified( sal_True );
+ Resize();
+ m_bInSplitHandler = sal_True;
+ }
+ return 0L;
+}
+// -------------------------------------------------------------------------
+void OQueryDesignView::Construct()
+{
+ m_pTableView = new OQueryTableView(m_pScrollWindow,this);
+ ::dbaui::notifySystemWindow(this,m_pTableView,::comphelper::mem_fun(&TaskPaneList::AddWindow));
+ OQueryView::Construct();
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::initialize()
+{
+ if(static_cast<OQueryController&>(getController()).getSplitPos() != -1)
+ {
+ m_aSplitter.SetPosPixel( Point( m_aSplitter.GetPosPixel().X(),static_cast<OQueryController&>(getController()).getSplitPos() ) );
+ m_aSplitter.SetSplitPosPixel(static_cast<OQueryController&>(getController()).getSplitPos());
+ }
+ m_pSelectionBox->initialize();
+ reset();
+}
+// -------------------------------------------------------------------------
+void OQueryDesignView::resizeDocumentView(Rectangle& _rPlayground)
+{
+ Point aPlaygroundPos( _rPlayground.TopLeft() );
+ Size aPlaygroundSize( _rPlayground.GetSize() );
+
+ // calc the split pos, and forward it to the controller
+ sal_Int32 nSplitPos = static_cast<OQueryController&>(getController()).getSplitPos();
+ if ( 0 != aPlaygroundSize.Height() )
+ {
+ if ( ( -1 == nSplitPos )
+ || ( nSplitPos >= aPlaygroundSize.Height() )
+ )
+ {
+ // let the selection browse box determine an optimal size
+ Size aSelectionBoxSize = m_pSelectionBox->CalcOptimalSize( aPlaygroundSize );
+ nSplitPos = aPlaygroundSize.Height() - aSelectionBoxSize.Height() - m_aSplitter.GetSizePixel().Height();
+ // still an invalid size?
+ if ( nSplitPos == -1 || nSplitPos >= aPlaygroundSize.Height() )
+ nSplitPos = sal_Int32(aPlaygroundSize.Height()*0.6);
+
+ static_cast<OQueryController&>(getController()).setSplitPos(nSplitPos);
+ }
+
+ if ( !m_bInSplitHandler )
+ { // the resize is triggered by something else than the split handler
+ // our main focus is to try to preserve the size of the selectionbrowse box
+ Size aSelBoxSize = m_pSelectionBox->GetSizePixel();
+ if ( aSelBoxSize.Height() )
+ {
+ // keep the size of the sel box constant
+ nSplitPos = aPlaygroundSize.Height() - m_aSplitter.GetSizePixel().Height() - aSelBoxSize.Height();
+
+ // and if the box is smaller than the optimal size, try to do something about it
+ Size aSelBoxOptSize = m_pSelectionBox->CalcOptimalSize( aPlaygroundSize );
+ if ( aSelBoxOptSize.Height() > aSelBoxSize.Height() )
+ {
+ nSplitPos = aPlaygroundSize.Height() - m_aSplitter.GetSizePixel().Height() - aSelBoxOptSize.Height();
+ }
+
+ static_cast< OQueryController& >(getController()).setSplitPos( nSplitPos );
+ }
+ }
+ }
+
+ // normalize the split pos
+ Point aSplitPos = Point( _rPlayground.Left(), nSplitPos );
+ Size aSplitSize = Size( _rPlayground.GetSize().Width(), m_aSplitter.GetSizePixel().Height() );
+
+ if( ( aSplitPos.Y() + aSplitSize.Height() ) > ( aPlaygroundSize.Height() ))
+ aSplitPos.Y() = aPlaygroundSize.Height() - aSplitSize.Height();
+
+ if( aSplitPos.Y() <= aPlaygroundPos.Y() )
+ aSplitPos.Y() = aPlaygroundPos.Y() + sal_Int32(aPlaygroundSize.Height() * 0.2);
+
+ // position the table
+ Size aTableViewSize(aPlaygroundSize.Width(), aSplitPos.Y() - aPlaygroundPos.Y());
+ m_pScrollWindow->SetPosSizePixel(aPlaygroundPos, aTableViewSize);
+
+ // position the selection browse box
+ Point aPos( aPlaygroundPos.X(), aSplitPos.Y() + aSplitSize.Height() );
+ m_pSelectionBox->SetPosSizePixel( aPos, Size( aPlaygroundSize.Width(), aPlaygroundSize.Height() - aSplitSize.Height() - aTableViewSize.Height() ));
+
+ // set the size of the splitter
+ m_aSplitter.SetPosSizePixel( aSplitPos, aSplitSize );
+ m_aSplitter.SetDragRectPixel( _rPlayground );
+
+ // just for completeness: there is no space left, we occupied it all ...
+ _rPlayground.SetPos( _rPlayground.BottomRight() );
+ _rPlayground.SetSize( Size( 0, 0 ) );
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::setReadOnly(sal_Bool _bReadOnly)
+{
+ m_pSelectionBox->SetReadOnly(_bReadOnly);
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::clear()
+{
+ m_pSelectionBox->ClearAll(); // clear the whole selection
+ m_pTableView->ClearAll();
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::setStatement(const ::rtl::OUString& /*_rsStatement*/)
+{
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::copy()
+{
+ if( m_eChildFocus == SELECTION)
+ m_pSelectionBox->copy();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryDesignView::isCutAllowed()
+{
+ sal_Bool bAllowed = sal_False;
+ if ( SELECTION == m_eChildFocus )
+ bAllowed = m_pSelectionBox->isCutAllowed();
+ return bAllowed;
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryDesignView::isPasteAllowed()
+{
+ sal_Bool bAllowed = sal_False;
+ if ( SELECTION == m_eChildFocus )
+ bAllowed = m_pSelectionBox->isPasteAllowed();
+ return bAllowed;
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryDesignView::isCopyAllowed()
+{
+ sal_Bool bAllowed = sal_False;
+ if ( SELECTION == m_eChildFocus )
+ bAllowed = m_pSelectionBox->isCopyAllowed();
+ return bAllowed;
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::stopTimer()
+{
+ m_pSelectionBox->stopTimer();
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::startTimer()
+{
+ m_pSelectionBox->startTimer();
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::cut()
+{
+ if( m_eChildFocus == SELECTION)
+ {
+ m_pSelectionBox->cut();
+ static_cast<OQueryController&>(getController()).setModified(sal_True);
+ }
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::paste()
+{
+ if( m_eChildFocus == SELECTION)
+ {
+ m_pSelectionBox->paste();
+ static_cast<OQueryController&>(getController()).setModified(sal_True);
+ }
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::TableDeleted(const ::rtl::OUString& rAliasName)
+{
+ // Nachricht, dass Tabelle aus dem Fenster gel"oscht wurde
+ DeleteFields(rAliasName);
+ static_cast<OQueryController&>(getController()).InvalidateFeature(ID_BROWSER_ADDTABLE); // view nochmal bescheid sagen
+}
+//------------------------------------------------------------------------------
+void OQueryDesignView::DeleteFields( const ::rtl::OUString& rAliasName )
+{
+ m_pSelectionBox->DeleteFields( rAliasName );
+}
+// -----------------------------------------------------------------------------
+bool OQueryDesignView::HasFieldByAliasName(const ::rtl::OUString& rFieldName, OTableFieldDescRef& rInfo) const
+{
+ return m_pSelectionBox->HasFieldByAliasName( rFieldName, rInfo);
+}
+// -----------------------------------------------------------------------------
+SqlParseError OQueryDesignView::InsertField( const OTableFieldDescRef& rInfo, sal_Bool bVis, sal_Bool bActivate)
+{
+ return m_pSelectionBox->InsertField( rInfo, BROWSER_INVALIDID,bVis, bActivate ).is() ? eOk : eTooManyColumns;
+}
+// -----------------------------------------------------------------------------
+sal_Int32 OQueryDesignView::getColWidth(sal_uInt16 _nColPos) const
+{
+ static sal_Int32 s_nDefaultWidth = GetTextWidth(String(RTL_CONSTASCII_USTRINGPARAM("0"))) * 15;
+ sal_Int32 nWidth = static_cast<OQueryController&>(getController()).getColWidth(_nColPos);
+ if ( !nWidth )
+ nWidth = s_nDefaultWidth;
+ return nWidth;
+}
+//------------------------------------------------------------------------------
+void OQueryDesignView::fillValidFields(const ::rtl::OUString& sAliasName, ComboBox* pFieldList)
+{
+ OSL_ENSURE(pFieldList != NULL, "OQueryDesignView::FillValidFields : What the hell do you think I can do with a NULL-ptr ? This will crash !");
+ pFieldList->Clear();
+
+ sal_Bool bAllTables = sAliasName.getLength() == 0;
+
+ OJoinTableView::OTableWindowMap* pTabWins = m_pTableView->GetTabWinMap();
+ ::rtl::OUString strCurrentPrefix;
+ ::std::vector< ::rtl::OUString> aFields;
+ OJoinTableView::OTableWindowMap::iterator aIter = pTabWins->begin();
+ OJoinTableView::OTableWindowMap::iterator aEnd = pTabWins->end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OQueryTableWindow* pCurrentWin = static_cast<OQueryTableWindow*>(aIter->second);
+ if (bAllTables || (pCurrentWin->GetAliasName() == sAliasName))
+ {
+ strCurrentPrefix = pCurrentWin->GetAliasName();
+ strCurrentPrefix += ::rtl::OUString('.');
+
+ pCurrentWin->EnumValidFields(aFields);
+
+ ::std::vector< ::rtl::OUString>::iterator aStrIter = aFields.begin();
+ ::std::vector< ::rtl::OUString>::iterator aStrEnd = aFields.end();
+ for(;aStrIter != aStrEnd;++aStrIter)
+ {
+ if (bAllTables || aStrIter->toChar() == '*')
+ pFieldList->InsertEntry(::rtl::OUString(strCurrentPrefix) += *aStrIter);
+ else
+ pFieldList->InsertEntry(*aStrIter);
+ }
+
+ if (!bAllTables)
+ // das heisst, dass ich in diesen Block kam, weil der Tabellenname genau der gesuchte war, also bin ich fertig
+ // (dadurch verhindere ich auch das doppelte Einfuegen von Feldern, wenn eine Tabelle mehrmals als TabWin vorkommt)
+ break;
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+long OQueryDesignView::PreNotify(NotifyEvent& rNEvt)
+{
+ switch (rNEvt.GetType())
+ {
+ case EVENT_GETFOCUS:
+#if OSL_DEBUG_LEVEL > 0
+ {
+ Window* pFocus = Application::GetFocusWindow();
+ (void)pFocus;
+ }
+#endif
+
+ if ( m_pSelectionBox && m_pSelectionBox->HasChildPathFocus() )
+ m_eChildFocus = SELECTION;
+ else
+ m_eChildFocus = TABLEVIEW;
+ break;
+ }
+
+ return OQueryView::PreNotify(rNEvt);
+}
+//------------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+// check if the statement is correct when not returning false
+sal_Bool OQueryDesignView::checkStatement()
+{
+ sal_Bool bRet = sal_True;
+ if ( m_pSelectionBox )
+ bRet = m_pSelectionBox->Save(); // an error occurred so we return no
+ return bRet;
+}
+//-------------------------------------------------------------------------------
+::rtl::OUString OQueryDesignView::getStatement()
+{
+ OQueryController& rController = static_cast<OQueryController&>(getController());
+ m_rController.clearError();
+ // used for fields which aren't any longer in the statement
+ OTableFields& rUnUsedFields = rController.getUnUsedFields();
+ OTableFields().swap( rUnUsedFields );
+
+ // create the select columns
+ sal_uInt32 nFieldcount = 0;
+ OTableFields& rFieldList = rController.getTableFieldDesc();
+ OTableFields::iterator aIter = rFieldList.begin();
+ OTableFields::iterator aEnd = rFieldList.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableFieldDescRef pEntryField = *aIter;
+ if ( pEntryField->GetField().getLength() && pEntryField->IsVisible() )
+ ++nFieldcount;
+ else if (pEntryField->GetField().getLength() &&
+ !pEntryField->HasCriteria() &&
+ pEntryField->isNoneFunction() &&
+ pEntryField->GetOrderDir() == ORDER_NONE &&
+ !pEntryField->IsGroupBy() &&
+ !pEntryField->GetFunction().getLength() )
+ rUnUsedFields.push_back(pEntryField);
+ }
+ if ( !nFieldcount ) // keine Felder sichtbar also zur"uck
+ {
+ rUnUsedFields = rFieldList;
+ return ::rtl::OUString();
+ }
+
+ OQueryTableView::OTableWindowMap* pTabList = m_pTableView->GetTabWinMap();
+ sal_uInt32 nTabcount = pTabList->size();
+
+ ::rtl::OUString aFieldListStr(GenerateSelectList(this,rFieldList,nTabcount>1));
+ if( !aFieldListStr.getLength() )
+ return ::rtl::OUString();
+ // Ausnahmebehandlung, wenn keine Felder angegeben worden sind
+ // Dann darf die Tabpage nicht gewechselt werden
+ // Im TabBarSelectHdl wird der SQL-::rtl::OUString auf STATEMENT_NOFIELDS abgefragt
+ // und eine Errormeldung erzeugt
+ // ----------------- Tabellenliste aufbauen ----------------------
+
+ const ::std::vector<OTableConnection*>* pConnList = m_pTableView->getTableConnections();
+ Reference< XConnection> xConnection = rController.getConnection();
+ ::rtl::OUString aTableListStr(GenerateFromClause(xConnection,pTabList,pConnList));
+ OSL_ENSURE(aTableListStr.getLength(), "OQueryDesignView::getStatement() : unerwartet : habe Felder, aber keine Tabellen !");
+ // wenn es Felder gibt, koennen die nur durch Einfuegen aus einer schon existenten Tabelle entstanden sein; wenn andererseits
+ // eine Tabelle geloescht wird, verschwinden auch die zugehoerigen Felder -> ergo KANN es das nicht geben, dass Felder
+ // existieren, aber keine Tabellen (und aFieldListStr hat schon eine Laenge, das stelle ich oben sicher)
+ ::rtl::OUStringBuffer aHavingStr,aCriteriaListStr;
+ // ----------------- Kriterien aufbauen ----------------------
+ if (!GenerateCriterias(this,aCriteriaListStr,aHavingStr,rFieldList, nTabcount > 1))
+ return ::rtl::OUString();
+
+ ::rtl::OUString aJoinCrit;
+ GenerateInnerJoinCriterias(xConnection,aJoinCrit,pConnList);
+ if(aJoinCrit.getLength())
+ {
+ ::rtl::OUString aTmp(RTL_CONSTASCII_USTRINGPARAM("( "));
+ aTmp += aJoinCrit;
+ aTmp += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" )"));
+ if(aCriteriaListStr.getLength())
+ {
+ aTmp += C_AND;
+ aTmp += aCriteriaListStr.makeStringAndClear();
+ }
+ aCriteriaListStr = aTmp;
+ }
+ // ----------------- Statement aufbauen ----------------------
+ ::rtl::OUStringBuffer aSqlCmd(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT ")));
+ if(static_cast<OQueryController&>(getController()).isDistinct())
+ aSqlCmd.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" DISTINCT ")));
+ aSqlCmd.append(aFieldListStr);
+ aSqlCmd.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM ")));
+ aSqlCmd.append(aTableListStr);
+
+ if (aCriteriaListStr.getLength())
+ {
+ aSqlCmd.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE ")));
+ aSqlCmd.append(aCriteriaListStr.makeStringAndClear());
+ }
+ // ----------------- GroupBy aufbauen und Anh"angen ------------
+ Reference<XDatabaseMetaData> xMeta;
+ if ( xConnection.is() )
+ xMeta = xConnection->getMetaData();
+ sal_Bool bUseAlias = nTabcount > 1;
+ if ( xMeta.is() )
+ bUseAlias = bUseAlias || !xMeta->supportsGroupByUnrelated();
+
+ aSqlCmd.append(GenerateGroupBy(this,rFieldList,bUseAlias));
+ // ----------------- having Anh"angen ------------
+ if(aHavingStr.getLength())
+ {
+ aSqlCmd.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" HAVING ")));
+ aSqlCmd.append(aHavingStr.makeStringAndClear());
+ }
+ // ----------------- Sortierung aufbauen und Anh"angen ------------
+ ::rtl::OUString sOrder;
+ SqlParseError eErrorCode = eOk;
+ if ( (eErrorCode = GenerateOrder(this,rFieldList,nTabcount > 1,sOrder)) == eOk)
+ aSqlCmd.append(sOrder);
+ else
+ {
+ if ( !m_rController.hasError() )
+ m_rController.appendError( getParseErrorMessage( eErrorCode ) );
+
+ m_rController.displayError();
+ }
+
+ ::rtl::OUString sSQL = aSqlCmd.makeStringAndClear();
+ if ( xConnection.is() )
+ {
+ ::connectivity::OSQLParser& rParser( rController.getParser() );
+ ::rtl::OUString sErrorMessage;
+ ::std::auto_ptr<OSQLParseNode> pParseNode( rParser.parseTree( sErrorMessage, sSQL, sal_True ) );
+ if ( pParseNode.get() )
+ {
+ OSQLParseNode* pNode = pParseNode->getChild(3)->getChild(1);
+ if ( pNode->count() > 1 )
+ {
+ ::connectivity::OSQLParseNode * pCondition = pNode->getChild(1);
+ if ( pCondition ) // no where clause
+ {
+ OSQLParseNode::compress(pCondition);
+ ::rtl::OUString sTemp;
+ pParseNode->parseNodeToStr(sTemp,xConnection);
+ sSQL = sTemp;
+ }
+ }
+ }
+ }
+ return sSQL;
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+void OQueryDesignView::setSlotEnabled(sal_Int32 _nSlotId,sal_Bool _bEnable)
+{
+ sal_uInt16 nRow;
+ switch (_nSlotId)
+ {
+ case SID_QUERY_VIEW_FUNCTIONS:
+ nRow = BROW_FUNCTION_ROW;
+ break;
+ case SID_QUERY_VIEW_TABLES:
+ nRow = BROW_TABLE_ROW;
+ break;
+ case SID_QUERY_VIEW_ALIASES:
+ nRow = BROW_COLUMNALIAS_ROW;
+ break;
+ default:
+ // ????????????
+ nRow = 0;
+ break;
+ }
+ m_pSelectionBox->SetRowVisible(nRow,_bEnable);
+ m_pSelectionBox->Invalidate();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryDesignView::isSlotEnabled(sal_Int32 _nSlotId)
+{
+ sal_uInt16 nRow;
+ switch (_nSlotId)
+ {
+ case SID_QUERY_VIEW_FUNCTIONS:
+ nRow = BROW_FUNCTION_ROW;
+ break;
+ case SID_QUERY_VIEW_TABLES:
+ nRow = BROW_TABLE_ROW;
+ break;
+ case SID_QUERY_VIEW_ALIASES:
+ nRow = BROW_COLUMNALIAS_ROW;
+ break;
+ default:
+ // ?????????
+ nRow = 0;
+ break;
+ }
+ return m_pSelectionBox->IsRowVisible(nRow);
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::SaveUIConfig()
+{
+ OQueryController& rCtrl = static_cast<OQueryController&>(getController());
+ rCtrl.SaveTabWinsPosSize( m_pTableView->GetTabWinMap(), m_pScrollWindow->GetHScrollBar()->GetThumbPos(), m_pScrollWindow->GetVScrollBar()->GetThumbPos() );
+ rCtrl.setVisibleRows( m_pSelectionBox->GetNoneVisibleRows() );
+ if ( m_aSplitter.GetSplitPosPixel() != 0 )
+ rCtrl.setSplitPos( m_aSplitter.GetSplitPosPixel() );
+}
+// -----------------------------------------------------------------------------
+OSQLParseNode* OQueryDesignView::getPredicateTreeFromEntry(OTableFieldDescRef pEntry,
+ const String& _sCriteria,
+ ::rtl::OUString& _rsErrorMessage,
+ Reference<XPropertySet>& _rxColumn) const
+{
+ OSL_ENSURE(pEntry.is(),"Entry is null!");
+ if(!pEntry.is())
+ return NULL;
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(getController()).getConnection();
+ if(!xConnection.is())
+ return NULL;
+
+ ::connectivity::OSQLParser& rParser( static_cast<OQueryController&>(getController()).getParser() );
+ OQueryTableWindow* pWin = static_cast<OQueryTableWindow*>(pEntry->GetTabWindow());
+
+ String sTest(_sCriteria);
+ // special handling for functions
+ if ( pEntry->GetFunctionType() & (FKT_OTHER | FKT_AGGREGATE | FKT_NUMERIC) )
+ {
+ // we have a function here so we have to distinguish the type of return value
+ String sFunction;
+ if ( pEntry->isNumericOrAggreateFunction() )
+ sFunction = pEntry->GetFunction();
+
+ if ( !sFunction.Len() )
+ sFunction = pEntry->GetField();
+
+ if(sFunction.GetTokenCount('(') > 1)
+ sFunction = sFunction.GetToken(0,'('); // this should be the name of the function
+
+ sal_Int32 nType = ::connectivity::OSQLParser::getFunctionReturnType(sFunction,&rParser.getContext());
+ if ( nType == DataType::OTHER || (!sFunction.Len() && pEntry->isNumericOrAggreateFunction()) )
+ {
+ // first try the international version
+ ::rtl::OUString sSql;
+ sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT * "));
+ sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM x WHERE "));
+ sSql += pEntry->GetField();
+ sSql += _sCriteria;
+ ::std::auto_ptr<OSQLParseNode> pParseNode( rParser.parseTree( _rsErrorMessage, sSql, sal_True ) );
+ nType = DataType::DOUBLE;
+ if ( pParseNode.get() )
+ {
+ OSQLParseNode* pColumnRef = pParseNode->getByRule(OSQLParseNode::column_ref);
+ if ( pColumnRef )
+ {
+ OTableFieldDescRef aField = new OTableFieldDesc();
+ if ( eOk == FillDragInfo(this,pColumnRef,aField) )
+ {
+ nType = aField->GetDataType();
+ }
+ }
+ }
+ }
+
+ Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
+ parse::OParseColumn* pColumn = new parse::OParseColumn( pEntry->GetField(),
+ ::rtl::OUString(),
+ ::rtl::OUString(),
+ ::rtl::OUString(),
+ ColumnValue::NULLABLE_UNKNOWN,
+ 0,
+ 0,
+ nType,
+ sal_False,
+ sal_False,
+ xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
+ _rxColumn = pColumn;
+ pColumn->setFunction(sal_True);
+ pColumn->setRealName(pEntry->GetField());
+ }
+ else
+ {
+ if (pWin)
+ {
+ Reference<XNameAccess> xColumns = pWin->GetOriginalColumns();
+ if (xColumns.is() && xColumns->hasByName(pEntry->GetField()))
+ xColumns->getByName(pEntry->GetField()) >>= _rxColumn;
+ }
+ }
+
+ OSQLParseNode* pParseNode = rParser.predicateTree( _rsErrorMessage,
+ sTest,
+ static_cast<OQueryController&>(getController()).getNumberFormatter(),
+ _rxColumn);
+ return pParseNode;
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::GetFocus()
+{
+ OQueryView::GetFocus();
+ if ( m_pSelectionBox && !m_pSelectionBox->HasChildPathFocus() )
+ {
+ // first we have to deactivate the current cell to refill when nescessary
+ m_pSelectionBox->DeactivateCell();
+ m_pSelectionBox->ActivateCell(m_pSelectionBox->GetCurRow(), m_pSelectionBox->GetCurColumnId());
+ m_pSelectionBox->GrabFocus();
+ }
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::reset()
+{
+ m_pTableView->ClearAll();
+ m_pTableView->ReSync();
+}
+// -----------------------------------------------------------------------------
+void OQueryDesignView::setNoneVisbleRow(sal_Int32 _nRows)
+{
+ m_pSelectionBox->SetNoneVisbleRow(_nRows);
+}
+
+// -----------------------------------------------------------------------------
+void OQueryDesignView::initByFieldDescriptions( const Sequence< PropertyValue >& i_rFieldDescriptions )
+{
+ OQueryController& rController = static_cast< OQueryController& >( getController() );
+
+ m_pSelectionBox->PreFill();
+ m_pSelectionBox->SetReadOnly( rController.isReadOnly() );
+ m_pSelectionBox->Fill();
+
+ for ( const PropertyValue* field = i_rFieldDescriptions.getConstArray();
+ field != i_rFieldDescriptions.getConstArray() + i_rFieldDescriptions.getLength();
+ ++field
+ )
+ {
+ ::rtl::Reference< OTableFieldDesc > pField( new OTableFieldDesc() );
+ pField->Load( *field, true );
+ InsertField( pField, sal_True, sal_False );
+ }
+
+ rController.ClearUndoManager();
+ m_pSelectionBox->Invalidate();
+}
+
+// -----------------------------------------------------------------------------
+bool OQueryDesignView::initByParseIterator( ::dbtools::SQLExceptionInfo* _pErrorInfo )
+{
+ SqlParseError eErrorCode = eNativeMode;
+ m_rController.clearError();
+
+ try
+ {
+ eErrorCode = InitFromParseNodeImpl( this, m_pSelectionBox );
+
+ if ( eErrorCode != eOk )
+ {
+ if ( !m_rController.hasError() )
+ m_rController.appendError( getParseErrorMessage( eErrorCode ) );
+
+ if ( _pErrorInfo )
+ {
+ *_pErrorInfo = m_rController.getError();
+ }
+ else
+ {
+ m_rController.displayError();
+ }
+ }
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return eErrorCode == eOk;
+}
+//------------------------------------------------------------------------------
+void OQueryDesignView::fillFunctionInfo( const ::connectivity::OSQLParseNode* pNode
+ ,const ::rtl::OUString& sFunctionTerm
+ ,OTableFieldDescRef& aInfo)
+{
+ // get the type out of the funtion name
+ OQueryController& rController = static_cast<OQueryController&>(getController());
+ sal_Int32 nDataType = DataType::DOUBLE;
+ ::rtl::OUString sFieldName = sFunctionTerm;
+ OSQLParseNode* pFunctionName = pNode->getChild(0);
+ if ( !SQL_ISPUNCTUATION(pFunctionName,"{") )
+ {
+ if ( SQL_ISRULEOR2(pNode,length_exp,char_value_fct) )
+ pFunctionName = pFunctionName->getChild(0);
+
+ ::rtl::OUString sFunctionName = pFunctionName->getTokenValue();
+ if ( !sFunctionName.getLength() )
+ sFunctionName = ::rtl::OStringToOUString(OSQLParser::TokenIDToStr(pFunctionName->getTokenID()),RTL_TEXTENCODING_UTF8);
+
+ nDataType = OSQLParser::getFunctionReturnType(
+ sFunctionName
+ ,&rController.getParser().getContext());
+ }
+ aInfo->SetDataType(nDataType);
+ aInfo->SetFieldType(TAB_NORMAL_FIELD);
+ aInfo->SetField(sFieldName);
+ aInfo->SetTabWindow(NULL);
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryMoveTabWinUndoAct.cxx b/dbaccess/source/ui/querydesign/QueryMoveTabWinUndoAct.cxx
new file mode 100644
index 000000000000..fb662a8b7438
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryMoveTabWinUndoAct.cxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+
+#include "QueryMoveTabWinUndoAct.hxx"
+#include "JoinTableView.hxx"
+#include "QTableWindow.hxx"
+using namespace dbaui;
+//------------------------------------------------------------------------------
+void OJoinMoveTabWinUndoAct::TogglePosition()
+{
+ Point ptFrameScrollPos(m_pOwner->GetHScrollBar()->GetThumbPos(), m_pOwner->GetVScrollBar()->GetThumbPos());
+ Point ptNext = m_pTabWin->GetPosPixel() + ptFrameScrollPos;
+
+ m_pTabWin->SetPosPixel(m_ptNextPosition - ptFrameScrollPos);
+ // sieht so aus, als wenn das ptFrameScrollPos sinnlos ist, da ich es hier abziehe und auf das ptNext aufaddiere, wo
+ // ich es das naechste Mal ja wieder abziehe ... Aber ptFrameScrollPos kann sich natuerlich beim naechsten Mal schon wieder
+ // geaendert haben ...
+ m_pOwner->EnsureVisible(m_pTabWin);
+
+ m_ptNextPosition = ptNext;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryMoveTabWinUndoAct.hxx b/dbaccess/source/ui/querydesign/QueryMoveTabWinUndoAct.hxx
new file mode 100644
index 000000000000..692bd3946fda
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryMoveTabWinUndoAct.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_OQUERYMOVETABWINUNDOACT_HXX
+#define DBAUI_OQUERYMOVETABWINUNDOACT_HXX
+
+#include "QueryDesignUndoAction.hxx"
+#include "dbu_qry.hrc"
+#include <tools/gen.hxx>
+
+namespace dbaui
+{
+
+ // ================================================================================================
+ // OQueryMoveTabWinUndoAct - Undo-Klasse fuer Verschieben eines TabWins
+ class OQueryTableWindow;
+ class OTableWindow;
+ class OJoinMoveTabWinUndoAct : public OQueryDesignUndoAction
+ {
+ Point m_ptNextPosition;
+ OTableWindow* m_pTabWin;
+
+ protected:
+ void TogglePosition();
+
+ public:
+ OJoinMoveTabWinUndoAct(OJoinTableView* pOwner, const Point& ptOriginalPosition, OTableWindow* pTabWin);
+
+ virtual void Undo() { TogglePosition(); }
+ virtual void Redo() { TogglePosition(); }
+ };
+
+ // ------------------------------------------------------------------------------------------------
+ inline OJoinMoveTabWinUndoAct::OJoinMoveTabWinUndoAct(OJoinTableView* pOwner, const Point& ptOriginalPosition, OTableWindow* pTabWin)
+ :OQueryDesignUndoAction(pOwner, STR_QUERY_UNDO_MOVETABWIN)
+ ,m_ptNextPosition(ptOriginalPosition)
+ ,m_pTabWin(pTabWin)
+ {
+ }
+}
+#endif // DBAUI_OQUERYMOVETABWINUNDOACT_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QuerySizeTabWinUndoAct.hxx b/dbaccess/source/ui/querydesign/QuerySizeTabWinUndoAct.hxx
new file mode 100644
index 000000000000..11a2fc0412de
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QuerySizeTabWinUndoAct.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERYSIZETABWINUNDOACT_HXX
+#define DBAUI_QUERYSIZETABWINUNDOACT_HXX
+
+#include "QueryDesignUndoAction.hxx"
+#include "dbu_qry.hrc"
+
+namespace dbaui
+{
+
+ // ================================================================================================
+ // OQuerySizeTabWinUndoAct - Undo-Klasse fuer Groessenveraenderung eines TabWins
+ class OTableWindow;
+ class OJoinSizeTabWinUndoAct : public OQueryDesignUndoAction
+ {
+ Point m_ptNextPosition;
+ Size m_szNextSize;
+ OTableWindow* m_pTabWin;
+
+ protected:
+ inline void ToggleSizePosition();
+
+ public:
+ OJoinSizeTabWinUndoAct(OJoinTableView* pOwner, const Point& ptOriginalPos, const Size& szOriginalSize, OTableWindow* pTabWin);
+ // Nebenbedingung : es darf nicht gescrollt worden sein, waehrend die neue Groesse/Position ermittelt wurde, das heisst, die Position
+ // hier sind physische, nicht logische Koordinaten
+ // (im Gegensatz zur QueryMoveTabWinUndoAct)
+
+ virtual void Undo() { ToggleSizePosition(); }
+ virtual void Redo() { ToggleSizePosition(); }
+ };
+
+ //------------------------------------------------------------------------------
+ inline OJoinSizeTabWinUndoAct::OJoinSizeTabWinUndoAct(OJoinTableView* pOwner, const Point& ptOriginalPos, const Size& szOriginalSize, OTableWindow* pTabWin)
+ :OQueryDesignUndoAction(pOwner, STR_QUERY_UNDO_SIZETABWIN)
+ ,m_ptNextPosition(ptOriginalPos)
+ ,m_szNextSize(szOriginalSize)
+ ,m_pTabWin(pTabWin)
+ {
+ }
+
+ //------------------------------------------------------------------------------
+ inline void OJoinSizeTabWinUndoAct::ToggleSizePosition()
+ {
+ Point ptNext = m_pTabWin->GetPosPixel();
+ Size szNext = m_pTabWin->GetSizePixel();
+
+ m_pOwner->Invalidate(INVALIDATE_NOCHILDREN);
+ m_pTabWin->SetPosSizePixel(m_ptNextPosition, m_szNextSize);
+ m_pOwner->Invalidate(INVALIDATE_NOCHILDREN);
+
+ m_ptNextPosition = ptNext;
+ m_szNextSize = szNext;
+ }
+}
+
+#endif //DBAUI_QUERYSIZETABWINUNDOACT_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryTabConnUndoAction.cxx b/dbaccess/source/ui/querydesign/QueryTabConnUndoAction.cxx
new file mode 100644
index 000000000000..6f9a45d59228
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryTabConnUndoAction.cxx
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "QueryTabConnUndoAction.hxx"
+#include "QTableConnection.hxx"
+#include <tools/debug.hxx>
+#include "QueryTableView.hxx"
+#include "QueryAddTabConnUndoAction.hxx"
+#include "QueryTabWinShowUndoAct.hxx"
+#include "dbu_qry.hrc"
+
+using namespace dbaui;
+
+DBG_NAME(OQueryTabConnUndoAction)
+// ------------------------------------------------------------------------------------------------
+OQueryTabConnUndoAction::~OQueryTabConnUndoAction()
+{
+ DBG_DTOR(OQueryTabConnUndoAction,NULL);
+ if (m_bOwnerOfConn)
+ { // ich besitze die Connection -> loeschen
+ m_pOwner->DeselectConn(m_pConnection);
+ delete m_pConnection;
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+OQueryTabConnUndoAction::OQueryTabConnUndoAction(OQueryTableView* pOwner, sal_uInt16 nCommentID)
+ :OQueryDesignUndoAction(pOwner, nCommentID)
+ ,m_pConnection(NULL)
+ ,m_bOwnerOfConn(sal_False)
+{
+ DBG_CTOR(OQueryTabConnUndoAction,NULL);
+}
+// -----------------------------------------------------------------------------
+OQueryAddTabConnUndoAction::OQueryAddTabConnUndoAction(OQueryTableView* pOwner)
+ : OQueryTabConnUndoAction(pOwner, STR_QUERY_UNDO_INSERTCONNECTION)
+{
+}
+// -----------------------------------------------------------------------------
+void OQueryAddTabConnUndoAction::Undo()
+{
+ static_cast<OQueryTableView*>(m_pOwner)->DropConnection(m_pConnection);
+ SetOwnership(sal_True);
+}
+// -----------------------------------------------------------------------------
+void OQueryAddTabConnUndoAction::Redo()
+{
+ static_cast<OQueryTableView*>(m_pOwner)->GetConnection(m_pConnection);
+ SetOwnership(sal_False);
+}
+// -----------------------------------------------------------------------------
+OQueryDelTabConnUndoAction::OQueryDelTabConnUndoAction(OQueryTableView* pOwner)
+ : OQueryTabConnUndoAction(pOwner, STR_QUERY_UNDO_REMOVECONNECTION)
+{
+}
+// -----------------------------------------------------------------------------
+void OQueryDelTabConnUndoAction::Undo()
+{
+ static_cast<OQueryTableView*>(m_pOwner)->GetConnection(m_pConnection);
+ SetOwnership(sal_False);
+}
+// -----------------------------------------------------------------------------
+void OQueryDelTabConnUndoAction::Redo()
+{
+ static_cast<OQueryTableView*>(m_pOwner)->DropConnection(m_pConnection);
+ SetOwnership(sal_True);
+}
+// -----------------------------------------------------------------------------
+OQueryTabWinShowUndoAct::OQueryTabWinShowUndoAct(OQueryTableView* pOwner)
+ : OQueryTabWinUndoAct(pOwner, STR_QUERY_UNDO_TABWINSHOW)
+{
+}
+// -----------------------------------------------------------------------------
+OQueryTabWinShowUndoAct::~OQueryTabWinShowUndoAct()
+{
+}
+// -----------------------------------------------------------------------------
+void OQueryTabWinShowUndoAct::Undo()
+{
+ static_cast<OQueryTableView*>(m_pOwner)->HideTabWin(m_pTabWin, this);
+ SetOwnership(sal_True);
+}
+// -----------------------------------------------------------------------------
+void OQueryTabWinShowUndoAct::Redo()
+{
+ static_cast<OQueryTableView*>(m_pOwner)->ShowTabWin(m_pTabWin, this,sal_True);
+ SetOwnership(sal_False);
+}
+// -----------------------------------------------------------------------------
+OQueryTabWinDelUndoAct::OQueryTabWinDelUndoAct(OQueryTableView* pOwner)
+ : OQueryTabWinUndoAct(pOwner, STR_QUERY_UNDO_TABWINDELETE)
+{
+}
+// -----------------------------------------------------------------------------
+OQueryTabWinDelUndoAct::~OQueryTabWinDelUndoAct()
+{
+}
+// -----------------------------------------------------------------------------
+void OQueryTabWinDelUndoAct::Undo()
+{
+ static_cast<OQueryTableView*>(m_pOwner)->ShowTabWin( m_pTabWin, this,sal_True );
+ SetOwnership(sal_False);
+}
+// -----------------------------------------------------------------------------
+void OQueryTabWinDelUndoAct::Redo()
+{
+ static_cast<OQueryTableView*>(m_pOwner)->HideTabWin( m_pTabWin, this );
+ SetOwnership(sal_True);
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryTabConnUndoAction.hxx b/dbaccess/source/ui/querydesign/QueryTabConnUndoAction.hxx
new file mode 100644
index 000000000000..186c522279d5
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryTabConnUndoAction.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERYTABCONNUNDOACTION_HXX
+#define DBAUI_QUERYTABCONNUNDOACTION_HXX
+
+#include "QueryDesignUndoAction.hxx"
+
+namespace dbaui
+{
+ class OQueryTableConnection;
+ class OQueryTableView;
+ class OQueryTabConnUndoAction : public OQueryDesignUndoAction
+ {
+ protected:
+ OQueryTableConnection* m_pConnection;
+ sal_Bool m_bOwnerOfConn;
+ // bin ich alleiniger Eigentuemer der Connection ? (aendert sich mit jedem Redo oder Undo)
+
+ public:
+ OQueryTabConnUndoAction(OQueryTableView* pOwner, sal_uInt16 nCommentID);
+ virtual ~OQueryTabConnUndoAction();
+
+ virtual void Undo() = 0;
+ virtual void Redo() = 0;
+
+ void SetConnection(OQueryTableConnection* pConn) { m_pConnection = pConn; }
+ // anschliessend bitte SetOwnership
+ void SetOwnership(sal_Bool bTakeIt) { m_bOwnerOfConn = bTakeIt; }
+ };
+}
+#endif // DBAUI_QUERYTABCONNUNDOACTION_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryTabWinShowUndoAct.hxx b/dbaccess/source/ui/querydesign/QueryTabWinShowUndoAct.hxx
new file mode 100644
index 000000000000..f5988bd65786
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryTabWinShowUndoAct.hxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef DBAUI_QUERYTABWINSHOWUNDOACT_HXX
+#define DBAUI_QUERYTABWINSHOWUNDOACT_HXX
+
+#include "QueryTabWinUndoAct.hxx"
+
+namespace dbaui
+{
+ // ================================================================================================
+ // OQueryTabWinShowUndoAct - Undo-Klasse fuer Anzeigen eines TabWins
+
+ class OQueryTabWinShowUndoAct : public OQueryTabWinUndoAct
+ {
+ public:
+ OQueryTabWinShowUndoAct(OQueryTableView* pOwner);
+ ~OQueryTabWinShowUndoAct();
+
+ virtual void Undo();
+ virtual void Redo();
+ };
+
+ // ================================================================================================
+ // OQueryTabWinDelUndoAct - Undo-Klasse fuer Loeschen eines TabWins
+
+ class OQueryTabWinDelUndoAct : public OQueryTabWinUndoAct
+ {
+ public:
+ OQueryTabWinDelUndoAct(OQueryTableView* pOwner);
+ ~OQueryTabWinDelUndoAct();
+
+ virtual void Undo();
+ virtual void Redo();
+ };
+}
+#endif // DBAUI_QUERYTABWINSHOWUNDOACT_HXX
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryTabWinUndoAct.cxx b/dbaccess/source/ui/querydesign/QueryTabWinUndoAct.cxx
new file mode 100644
index 000000000000..599afe015379
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryTabWinUndoAct.cxx
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "QueryTabWinUndoAct.hxx"
+#include <osl/diagnose.h>
+#include "QTableWindow.hxx"
+#include "QTableWindowData.hxx"
+#include "TableConnection.hxx"
+#include "TableConnectionData.hxx"
+#include "QueryDesignFieldUndoAct.hxx"
+#include "QueryTableView.hxx"
+
+
+using namespace dbaui;
+DBG_NAME(OQueryDesignFieldUndoAct)
+OQueryDesignFieldUndoAct::OQueryDesignFieldUndoAct(OSelectionBrowseBox* pSelBrwBox, sal_uInt16 nCommentID)
+ : OCommentUndoAction(nCommentID)
+ , pOwner(pSelBrwBox)
+ , m_nColumnPostion(BROWSER_INVALIDID)
+{
+ DBG_CTOR(OQueryDesignFieldUndoAct,NULL);
+}
+// -----------------------------------------------------------------------------
+OQueryDesignFieldUndoAct::~OQueryDesignFieldUndoAct()
+{
+ DBG_DTOR(OQueryDesignFieldUndoAct,NULL);
+ pOwner = NULL;
+}
+// -----------------------------------------------------------------------------
+
+DBG_NAME(OQueryTabWinUndoAct )
+// ------------------------------------------------------------------------------------------------
+OQueryTabWinUndoAct::OQueryTabWinUndoAct(OQueryTableView* pOwner, sal_uInt16 nCommentID)
+ :OQueryDesignUndoAction(pOwner, nCommentID)
+ ,m_pTabWin(NULL)
+{
+ DBG_CTOR(OQueryTabWinUndoAct ,NULL);
+}
+//==============================================================================
+OQueryTabWinUndoAct::~OQueryTabWinUndoAct()
+{
+ DBG_DTOR(OQueryTabWinUndoAct ,NULL);
+ if (m_bOwnerOfObjects)
+ { // wenn ich der alleinige Owner des Fenster bin, muss ich dafuer sorgen, dass es geloescht wird
+ OSL_ENSURE(m_pTabWin != NULL, "OQueryTabWinUndoAct::~OQueryTabWinUndoAct() : m_pTabWin sollte nicht NULL sein");
+ OSL_ENSURE(!m_pTabWin->IsVisible(), "OQueryTabWinUndoAct::~OQueryTabWinUndoAct() : *m_pTabWin sollte nicht sichtbar sein");
+
+ if ( m_pTabWin )
+ m_pTabWin->clearListBox();
+ delete m_pTabWin;
+
+ // und natuerlich auch die entsprechenden Connections
+ ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
+ ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ m_pOwner->DeselectConn(*aIter);
+ delete (*aIter);
+ }
+ m_vTableConnection.clear();
+ }
+}
+//------------------------------------------------------------------------------
+void OTabFieldCellModifiedUndoAct::Undo()
+{
+ pOwner->EnterUndoMode();
+ OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
+ OSL_ENSURE(m_nColumnPostion < pOwner->GetColumnCount(),"Position outside the column count!");
+ if ( m_nColumnPostion != BROWSER_INVALIDID )
+ {
+ sal_uInt16 nColumnId = pOwner->GetColumnId(m_nColumnPostion);
+ String strNext = pOwner->GetCellContents(m_nCellIndex, nColumnId);
+ pOwner->SetCellContents(m_nCellIndex, nColumnId, m_strNextCellContents);
+ m_strNextCellContents = strNext;
+ }
+ pOwner->LeaveUndoMode();
+}
+
+//------------------------------------------------------------------------------
+void OTabFieldSizedUndoAct::Undo()
+{
+ pOwner->EnterUndoMode();
+ OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
+ if ( m_nColumnPostion != BROWSER_INVALIDID )
+ {
+ sal_uInt16 nColumnId = pOwner->GetColumnId(m_nColumnPostion);
+ long nNextWidth = pOwner->GetColumnWidth(nColumnId);
+ pOwner->SetColWidth(nColumnId, m_nNextWidth);
+ m_nNextWidth = nNextWidth;
+ }
+ pOwner->LeaveUndoMode();
+}
+// -----------------------------------------------------------------------------
+void OTabFieldMovedUndoAct::Undo()
+{
+ pOwner->EnterUndoMode();
+ OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
+ if ( m_nColumnPostion != BROWSER_INVALIDID )
+ {
+ sal_uInt16 nId = pDescr->GetColumnId();
+ sal_uInt16 nOldPos = pOwner->GetColumnPos(nId);
+ pOwner->SetColumnPos(nId,m_nColumnPostion);
+ pOwner->ColumnMoved(nId,sal_False);
+ m_nColumnPostion = nOldPos;
+ }
+ pOwner->LeaveUndoMode();
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryTabWinUndoAct.hxx b/dbaccess/source/ui/querydesign/QueryTabWinUndoAct.hxx
new file mode 100644
index 000000000000..7afb6811e810
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryTabWinUndoAct.hxx
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERYTABWINUNDOACT_HXX
+#define DBAUI_QUERYTABWINUNDOACT_HXX
+
+#include "QueryDesignUndoAction.hxx"
+#ifndef INCLUDED_VECTOR
+#define INCLUDED_VECTOR
+#include <vector>
+#endif // INCLUDED_VECTOR
+
+#include <algorithm>
+
+namespace dbaui
+{
+ // ================================================================================================
+ // OQueryTabWinUndoAct - Undo-Basisklasse fuer alles, was mit Einfuegen/Entfernen von TabWIns zu tun hat zu tun hat
+
+ class OQueryTableWindow;
+ class OTableConnection;
+ class OQueryTableView;
+ class OQueryTabWinUndoAct : public OQueryDesignUndoAction
+ {
+ protected:
+ ::std::vector<OTableConnection*> m_vTableConnection;
+ OQueryTableWindow* m_pTabWin;
+ sal_Bool m_bOwnerOfObjects;
+ // bin ich alleiniger Eigentuemer der verwalteten Objekte ? (aendert sich mit jedem Redo oder Undo)
+
+ public:
+ OQueryTabWinUndoAct(OQueryTableView* pOwner, sal_uInt16 nCommentID);
+ virtual ~OQueryTabWinUndoAct();
+
+ void SetOwnership(sal_Bool bTakeIt) { m_bOwnerOfObjects = bTakeIt; }
+
+
+ virtual void Undo() = 0;
+ virtual void Redo() = 0;
+
+ // Zugriff auf das TabWin
+ void SetTabWin(OQueryTableWindow* pTW) { m_pTabWin = pTW; }
+ // anschliessend sollte das SetOwnership aufgerufen werden
+
+ // Zugriff auf die verwalteten Connections
+ sal_uInt16 ConnCount() { return (sal_uInt16)m_vTableConnection.size(); }
+
+ ::std::vector<OTableConnection*>* GetTabConnList() { return &m_vTableConnection; }
+
+ void InsertConnection( OTableConnection* pConnection ) { m_vTableConnection.push_back(pConnection); }
+ void RemoveConnection( OTableConnection* pConnection )
+ {
+ m_vTableConnection.erase(::std::remove(m_vTableConnection.begin(),m_vTableConnection.end(),pConnection),m_vTableConnection.end());
+ }
+ };
+
+
+}
+#endif // DBAUI_QUERYTABWINUNDOACT_HXX
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryTableView.cxx b/dbaccess/source/ui/querydesign/QueryTableView.cxx
new file mode 100644
index 000000000000..302b57cef86d
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryTableView.cxx
@@ -0,0 +1,1035 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+
+#include "QueryTableView.hxx"
+#include "TableFieldInfo.hxx"
+#include "TableFieldDescription.hxx"
+#include <tools/diagnose_ex.h>
+#include <osl/diagnose.h>
+#include "dbaccess_helpid.hrc"
+#include "QTableWindow.hxx"
+#include "QTableConnection.hxx"
+#include "QTableConnectionData.hxx"
+#include "QueryDesignView.hxx"
+#include "querycontroller.hxx"
+#include "QueryAddTabConnUndoAction.hxx"
+#include "QueryTabWinShowUndoAct.hxx"
+#include "browserids.hxx"
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include "JAccess.hxx"
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "dbustrings.hrc"
+#include <connectivity/dbtools.hxx>
+#include <comphelper/sequence.hxx>
+#include "querydlg.hxx"
+#include "JoinExchange.hxx"
+#include <comphelper/extract.hxx>
+#include "QueryDesignView.hxx"
+#include "dbu_qry.hrc"
+#include <vcl/msgbox.hxx>
+
+using namespace dbaui;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::accessibility;
+
+//------------------------------------------------------------------------------
+namespace
+{
+ // -----------------------------------------------------------------------------
+ sal_Bool isColumnInKeyType(const Reference<XIndexAccess>& _rxKeys,const ::rtl::OUString& _rColumnName,sal_Int32 _nKeyType)
+ {
+ sal_Bool bReturn = sal_False;
+ if(_rxKeys.is())
+ {
+ Reference<XColumnsSupplier> xColumnsSupplier;
+ // search the one and only primary key
+ const sal_Int32 nCount = _rxKeys->getCount();
+ for(sal_Int32 i=0;i< nCount;++i)
+ {
+ Reference<XPropertySet> xProp(_rxKeys->getByIndex(i),UNO_QUERY);
+ if(xProp.is())
+ {
+ sal_Int32 nKeyType = 0;
+ xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
+ if(_nKeyType == nKeyType)
+ {
+ xColumnsSupplier.set(xProp,UNO_QUERY);
+ if(xColumnsSupplier.is())
+ {
+ Reference<XNameAccess> xColumns = xColumnsSupplier->getColumns();
+ if(xColumns.is() && xColumns->hasByName(_rColumnName))
+ {
+ bReturn = sal_True;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return bReturn;
+ }
+ // -----------------------------------------------------------------------------
+ /** appends a new TabAdd Undo action at controller
+ @param _pView the view which we use
+ @param _pUndoAction the undo action which should be added
+ @param _pConnection the connection for which the undo action should be appended
+ @param _bOwner is the undo action the owner
+ */
+ // -----------------------------------------------------------------------------
+ void addUndoAction( OQueryTableView* _pView,
+ OQueryTabConnUndoAction* _pUndoAction,
+ OQueryTableConnection* _pConnection,
+ sal_Bool _bOwner = sal_False)
+ {
+ _pUndoAction->SetOwnership(_bOwner);
+ _pUndoAction->SetConnection(_pConnection);
+ _pView->getDesignView()->getController().addUndoActionAndInvalidate(_pUndoAction);
+ }
+ // -----------------------------------------------------------------------------
+ /** openJoinDialog opens the join dialog with this connection data
+ @param _pView the view which we use
+ @param _pConnectionData the connection data
+
+ @return true when OK was pressed otherwise false
+ */
+ sal_Bool openJoinDialog(OQueryTableView* _pView,const TTableConnectionData::value_type& _pConnectionData,sal_Bool _bSelectableTables)
+ {
+ OQueryTableConnectionData* pData = static_cast< OQueryTableConnectionData*>(_pConnectionData.get());
+
+ DlgQryJoin aDlg(_pView,_pConnectionData,_pView->GetTabWinMap(),_pView->getDesignView()->getController().getConnection(),_bSelectableTables);
+ sal_Bool bOk = aDlg.Execute() == RET_OK;
+ if( bOk )
+ {
+ pData->SetJoinType(aDlg.GetJoinType());
+ _pView->getDesignView()->getController().setModified(sal_True);
+ }
+
+ return bOk;
+ }
+ // -----------------------------------------------------------------------------
+ /** connectionModified adds an undo action for the modified connection and forces an redraw
+ @param _pView the view which we use
+ @param _pConnection the connection which was modified
+ @param _bAddUndo true when an undo action should be appended
+ */
+ void connectionModified(OQueryTableView* _pView,
+ OTableConnection* _pConnection,
+ sal_Bool _bAddUndo)
+ {
+ OSL_ENSURE(_pConnection,"Invalid connection!");
+ _pConnection->UpdateLineList();
+
+ // add an undo action
+ if ( _bAddUndo )
+ addUndoAction( _pView,
+ new OQueryAddTabConnUndoAction(_pView),
+ static_cast< OQueryTableConnection*>(_pConnection));
+ // redraw
+ _pConnection->RecalcLines();
+ // force an invalidation of the bounding rectangle
+ _pConnection->InvalidateConnection();
+
+ _pView->Invalidate(INVALIDATE_NOCHILDREN);
+ }
+ // -----------------------------------------------------------------------------
+ void addConnections(OQueryTableView* _pView,
+ const OQueryTableWindow& _rSource,
+ const OQueryTableWindow& _rDest,
+ const Reference<XNameAccess>& _rxSourceForeignKeyColumns)
+ {
+ if ( _rSource.GetData()->isQuery() || _rDest.GetData()->isQuery() )
+ // nothing to do if one of both denotes a query
+ return;
+
+ // we found a table in our view where we can insert some connections
+ // the key columns have a property called RelatedColumn
+ // OQueryTableConnectionData aufbauen
+ OQueryTableConnectionData* pNewConnData = new OQueryTableConnectionData( _rSource.GetData(), _rDest.GetData() );
+ TTableConnectionData::value_type aNewConnData(pNewConnData);
+
+ Reference<XIndexAccess> xReferencedKeys( _rDest.GetData()->getKeys());
+ ::rtl::OUString sRelatedColumn;
+
+ // iterate through all foreignkey columns to create the connections
+ Sequence< ::rtl::OUString> aElements(_rxSourceForeignKeyColumns->getElementNames());
+ const ::rtl::OUString* pIter = aElements.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aElements.getLength();
+ for(sal_Int32 i=0;pIter != pEnd;++pIter,++i)
+ {
+ Reference<XPropertySet> xColumn;
+ if ( !( _rxSourceForeignKeyColumns->getByName(*pIter) >>= xColumn ) )
+ {
+ OSL_FAIL( "addConnections: invalid foreign key column!" );
+ continue;
+ }
+
+ pNewConnData->SetFieldType(JTCS_FROM,TAB_NORMAL_FIELD);
+
+ xColumn->getPropertyValue(PROPERTY_RELATEDCOLUMN) >>= sRelatedColumn;
+ pNewConnData->SetFieldType(JTCS_TO,isColumnInKeyType(xReferencedKeys,sRelatedColumn,KeyType::PRIMARY) ? TAB_PRIMARY_FIELD : TAB_NORMAL_FIELD);
+
+ {
+ Sequence< sal_Int16> aFind(::comphelper::findValue(_rSource.GetOriginalColumns()->getElementNames(),*pIter,sal_True));
+ if(aFind.getLength())
+ pNewConnData->SetFieldIndex(JTCS_FROM,aFind[0]+1);
+ else
+ OSL_FAIL("Column not found!");
+ }
+ // get the position inside the tabe
+ Reference<XNameAccess> xRefColumns = _rDest.GetOriginalColumns();
+ if(xRefColumns.is())
+ {
+ Sequence< sal_Int16> aFind(::comphelper::findValue(xRefColumns->getElementNames(),sRelatedColumn,sal_True));
+ if(aFind.getLength())
+ pNewConnData->SetFieldIndex(JTCS_TO,aFind[0]+1);
+ else
+ OSL_FAIL("Column not found!");
+ }
+ pNewConnData->AppendConnLine(*pIter,sRelatedColumn);
+
+ // dann die Conn selber dazu
+ OQueryTableConnection aNewConn(_pView, aNewConnData);
+ // der Verweis auf die lokale Variable ist unkritisch, da NotifyQueryTabConn eine neue Kopie anlegt
+ // und mir hinzufuegen (wenn nicht schon existent)
+ _pView->NotifyTabConnection(aNewConn, sal_False);
+ // don't create an Undo-Action for the new connection : the connection is
+ // covered by the Undo-Action for the tabwin, as the "Undo the insert" will
+ // automatically remove all connections adjacent to the win.
+ // (Because of this automatism we would have an ownerhsip ambiguity for
+ // the connection data if we would insert the conn-Undo-Action)
+ }
+ }
+}
+//==================================================================
+// class OQueryTableView
+//==================================================================
+DBG_NAME(OQueryTableView)
+//------------------------------------------------------------------------
+OQueryTableView::OQueryTableView( Window* pParent,OQueryDesignView* pView)
+ : OJoinTableView( pParent,pView)
+{
+ DBG_CTOR(OQueryTableView,NULL);
+ SetHelpId(HID_CTL_QRYDGNTAB);
+}
+
+//------------------------------------------------------------------------
+OQueryTableView::~OQueryTableView()
+{
+ DBG_DTOR(OQueryTableView,NULL);
+}
+
+//------------------------------------------------------------------------
+sal_Int32 OQueryTableView::CountTableAlias(const String& rName, sal_Int32& rMax)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ sal_Int32 nRet = 0;
+
+ OTableWindowMapIterator aIter = GetTabWinMap()->find(rName);
+ while(aIter != GetTabWinMap()->end())
+ {
+ String aNewName;
+ aNewName = rName;
+ aNewName += '_';
+ aNewName += String::CreateFromInt32(++nRet);
+
+ aIter = GetTabWinMap()->find(aNewName);
+ }
+
+ rMax = nRet;
+
+ return nRet;
+}
+//------------------------------------------------------------------------
+void OQueryTableView::ReSync()
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ TTableWindowData* pTabWinDataList = m_pView->getController().getTableWindowData();
+ OSL_ENSURE((getTableConnections()->size()==0) && (GetTabWinMap()->size()==0),
+ "vor OQueryTableView::ReSync() bitte ClearAll aufrufen !");
+
+ // ich brauche eine Sammlung aller Fensternamen, deren Anlegen schief geht, damit ich die entsprechenden Connections
+ // gar nicht erst anlege
+ ::std::vector<String> arrInvalidTables;
+
+ TTableWindowData::reverse_iterator aIter = pTabWinDataList->rbegin();
+ // Fenster kreieren und einfuegen
+
+ for(;aIter != pTabWinDataList->rend();++aIter)
+ {
+ OQueryTableWindowData* pData = static_cast<OQueryTableWindowData*>(aIter->get());
+ OTableWindow* pTabWin = createWindow(*aIter);
+
+ // ich gehe jetzt NICHT ueber ShowTabWin, da dieses die Daten des Fensters in die Liste des Docs einfuegt, was
+ // schlecht waere, denn genau von dort hole ich sie ja gerade
+ // also Schritt fuer Schritt
+ if (!pTabWin->Init())
+ {
+ // das Initialisieren ging schief, dass heisst, dieses TabWin steht nicht zur Verfuegung, also muss ich es inklusive
+ // seiner Daten am Dokument aufraeumen
+ pTabWin->clearListBox();
+ delete pTabWin;
+ arrInvalidTables.push_back(pData->GetAliasName());
+
+ pTabWinDataList->erase( ::std::remove(pTabWinDataList->begin(),pTabWinDataList->end(),*aIter) ,pTabWinDataList->end());
+ continue;
+ }
+
+ (*GetTabWinMap())[pData->GetAliasName()] = pTabWin; // am Anfang einfuegen, da ich die DataList ja rueckwaerts durchlaufe
+ // wenn in den Daten keine Position oder Groesse steht -> Default
+ if (!pData->HasPosition() && !pData->HasSize())
+ SetDefaultTabWinPosSize(pTabWin);
+
+ pTabWin->Show();
+ }
+
+ // Verbindungen einfuegen
+ TTableConnectionData* pTabConnDataList = m_pView->getController().getTableConnectionData();
+ TTableConnectionData::reverse_iterator aConIter = pTabConnDataList->rbegin();
+
+ for(;aConIter != pTabConnDataList->rend();++aConIter)
+ {
+ OQueryTableConnectionData* pTabConnData = static_cast<OQueryTableConnectionData*>(aConIter->get());
+
+ // gibt es die beiden Tabellen zur Connection ?
+ String strTabExistenceTest = pTabConnData->getReferencingTable()->GetWinName();
+ sal_Bool bInvalid = ::std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end();
+ strTabExistenceTest = pTabConnData->getReferencedTable()->GetWinName();
+ bInvalid = bInvalid && ::std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end();
+
+ if (bInvalid)
+ { // nein -> Pech gehabt, die Connection faellt weg
+ pTabConnDataList->erase( ::std::remove(pTabConnDataList->begin(),pTabConnDataList->end(),*aConIter) ,pTabConnDataList->end());
+ continue;
+ }
+
+ // adds a new connection to join view and notifies our accessible and invaldates the controller
+ addConnection(new OQueryTableConnection(this, *aConIter));
+ }
+}
+
+//------------------------------------------------------------------------
+void OQueryTableView::ClearAll()
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ OJoinTableView::ClearAll();
+
+ SetUpdateMode(sal_True);
+ m_pView->getController().setModified(sal_True);
+}
+
+// -----------------------------------------------------------------------------
+OTableWindow* OQueryTableView::createWindow(const TTableWindowData::value_type& _pData)
+{
+ return new OQueryTableWindow(this,_pData);
+}
+
+//------------------------------------------------------------------------------
+void OQueryTableView::NotifyTabConnection(const OQueryTableConnection& rNewConn, sal_Bool _bCreateUndoAction)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ // erst mal schauen, ob ich diese Connection schon habe
+ OQueryTableConnection* pTabConn = NULL;
+ const ::std::vector<OTableConnection*>* pConnections = getTableConnections();
+ ::std::vector<OTableConnection*>::const_iterator aEnd = pConnections->end();
+ ::std::vector<OTableConnection*>::const_iterator aIter = ::std::find( pConnections->begin(),
+ aEnd,
+ static_cast<const OTableConnection*>(&rNewConn)
+ );
+ if(aIter == aEnd )
+ {
+ aIter = pConnections->begin();
+ for(;aIter != aEnd;++aIter)
+ {
+ if(*static_cast<OQueryTableConnection*>(*aIter) == rNewConn)
+ {
+ pTabConn = static_cast<OQueryTableConnection*>(*aIter);
+ break;
+ }
+ }
+ }
+ else
+ pTabConn = static_cast<OQueryTableConnection*>(*aIter);
+ // nein -> einfuegen
+ if (pTabConn == NULL)
+ {
+ // die neuen Daten ...
+ OQueryTableConnectionData* pNewData = static_cast< OQueryTableConnectionData*>(rNewConn.GetData()->NewInstance());
+ pNewData->CopyFrom(*rNewConn.GetData());
+ TTableConnectionData::value_type aData(pNewData);
+ OQueryTableConnection* pNewConn = new OQueryTableConnection(this, aData);
+ GetConnection(pNewConn);
+
+ connectionModified(this,pNewConn,_bCreateUndoAction);
+ }
+}
+// -----------------------------------------------------------------------------
+OTableWindowData* OQueryTableView::CreateImpl(const ::rtl::OUString& _rComposedName
+ ,const ::rtl::OUString& _sTableName
+ ,const ::rtl::OUString& _rWinName)
+{
+ return new OQueryTableWindowData( _rComposedName, _sTableName,_rWinName );
+}
+//------------------------------------------------------------------------------
+void OQueryTableView::AddTabWin(const ::rtl::OUString& _rTableName, const ::rtl::OUString& _rAliasName, sal_Bool bNewTable)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ // das ist die aus der Basisklasse geerbte Methode, die fuehre ich auf die an meinem Parent zurueck, die mir eventuell einen
+ // Alias dazu bastelt und das an mein anderes AddTabWin weiterreicht
+
+ // leider ist _rTableName voll qualifiziert, das OQueryDesignView erwartet aber einen String, der
+ // nur aus Schema und Tabelle besteht und keinen Katalog enthaelt.
+ Reference< XConnection> xConnection = m_pView->getController().getConnection();
+ if(!xConnection.is())
+ return;
+ try
+ {
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ ::dbtools::qualifiedNameComponents(xMetaData,
+ _rTableName,
+ sCatalog,
+ sSchema,
+ sTable,
+ ::dbtools::eInDataManipulation);
+ ::rtl::OUString sRealName(sSchema);
+ if (sRealName.getLength())
+ sRealName+= ::rtl::OUString('.');
+ sRealName += sTable;
+
+ AddTabWin(_rTableName, sRealName, _rAliasName, bNewTable);
+ }
+ catch(SQLException&)
+ {
+ OSL_FAIL("qualifiedNameComponents");
+ }
+}
+// -----------------------------------------------------------------------------
+// find the table which has a foreign key with this referencedTable name
+Reference<XPropertySet> getKeyReferencedTo(const Reference<XIndexAccess>& _rxKeys,const ::rtl::OUString& _rReferencedTable)
+{
+ if(!_rxKeys.is())
+ return Reference<XPropertySet>();
+
+ if ( !_rxKeys.is() )
+ return Reference<XPropertySet>();
+ // search the one and only primary key
+ const sal_Int32 nCount = _rxKeys->getCount();
+ for(sal_Int32 i=0;i<nCount ;++i)
+ {
+ Reference<XPropertySet> xKey(_rxKeys->getByIndex(i),UNO_QUERY);
+ if(xKey.is())
+ {
+ sal_Int32 nKeyType = 0;
+ xKey->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
+ if(KeyType::FOREIGN == nKeyType)
+ {
+ ::rtl::OUString sReferencedTable;
+ xKey->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= sReferencedTable;
+ // TODO check case
+ if(sReferencedTable == _rReferencedTable)
+ return xKey;
+ }
+ }
+ }
+ return Reference<XPropertySet>();
+}
+//------------------------------------------------------------------------------
+void OQueryTableView::AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& _rTableName, const ::rtl::OUString& strAlias, sal_Bool bNewTable)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ OSL_ENSURE(_rTableName.getLength() || strAlias.getLength(), "OQueryTableView::AddTabWin : kein Tabellen- und kein Aliasname !");
+ // wenn der Tabellenname nicht gesetzt ist, steht das fuer ein Dummy-Fenster, das braucht aber wenigstens einen Alias-Namen
+
+ // neue Datenstruktur erzeugen
+ // first check if this already hav it's data
+ sal_Bool bAppend = bNewTable;
+ TTableWindowData::value_type pNewTabWinData;
+ TTableWindowData* pWindowData = getDesignView()->getController().getTableWindowData();
+ TTableWindowData::iterator aWinIter = pWindowData->begin();
+ TTableWindowData::iterator aWinEnd = pWindowData->end();
+ for(;aWinIter != aWinEnd;++aWinIter)
+ {
+ pNewTabWinData = *aWinIter;
+ if (pNewTabWinData && pNewTabWinData->GetWinName() == strAlias && pNewTabWinData->GetComposedName() == _rComposedName && pNewTabWinData->GetTableName() == _rTableName)
+ break;
+ }
+ if ( !bAppend )
+ bAppend = ( aWinIter == aWinEnd );
+ if ( bAppend )
+ pNewTabWinData = createTableWindowData(_rComposedName, _rTableName, strAlias);
+ // die TabWinData brauche ich nicht in die entsprechende Liste der DocShell eintragen, das macht ShowTabWin
+
+ // neues Fenster erzeugen
+ OQueryTableWindow* pNewTabWin = static_cast<OQueryTableWindow*>(createWindow(pNewTabWinData));
+ // das Init kann ich hier weglassen, da das in ShowTabWin passiert
+
+ // Neue UndoAction
+ OQueryTabWinShowUndoAct* pUndoAction = new OQueryTabWinShowUndoAct(this);
+ pUndoAction->SetTabWin(pNewTabWin); // Fenster
+ sal_Bool bSuccess = ShowTabWin(pNewTabWin, pUndoAction,bAppend);
+ if(!bSuccess)
+ {
+ // reset table window
+ pUndoAction->SetTabWin(NULL);
+ pUndoAction->SetOwnership(sal_False);
+
+ delete pUndoAction;
+ return;
+ }
+
+ // Relationen zwischen den einzelnen Tabellen anzeigen
+ OTableWindowMap* pTabWins = GetTabWinMap();
+ if(bNewTable && !pTabWins->empty() && _rTableName.getLength())
+ {
+ modified();
+ if ( m_pAccessible )
+ m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
+ Any(),
+ makeAny(pNewTabWin->GetAccessible())
+ );
+
+ do {
+
+ if ( pNewTabWin->GetData()->isQuery() )
+ break;
+
+ try
+ {
+ //////////////////////////////////////////////////////////////////////
+ // find relations between the table an the tables already inserted
+ Reference< XIndexAccess> xKeyIndex = pNewTabWin->GetData()->getKeys();
+ if ( !xKeyIndex.is() )
+ break;
+
+ Reference<XNameAccess> xFKeyColumns;
+ ::rtl::OUString aReferencedTable;
+ Reference<XColumnsSupplier> xColumnsSupplier;
+
+ const sal_Int32 nKeyCount = xKeyIndex->getCount();
+ for ( sal_Int32 i=0; i<nKeyCount ; ++i )
+ {
+ Reference< XPropertySet > xProp( xKeyIndex->getByIndex(i), UNO_QUERY_THROW );
+ xColumnsSupplier.set( xProp, UNO_QUERY_THROW );
+ xFKeyColumns.set( xColumnsSupplier->getColumns(), UNO_QUERY_THROW );
+
+ sal_Int32 nKeyType = 0;
+ xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
+
+ switch ( nKeyType )
+ {
+ case KeyType::FOREIGN:
+ { // our new table has a foreign key
+ // so look if the referenced table is already in our list
+ xProp->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= aReferencedTable;
+ OSL_ENSURE(aReferencedTable.getLength(),"Foreign key without referencedTableName");
+
+ OTableWindowMap::const_iterator aIter = pTabWins->find(aReferencedTable);
+ OTableWindowMap::const_iterator aEnd = pTabWins->end();
+ if(aIter == aEnd)
+ {
+ for(aIter = pTabWins->begin();aIter != aEnd;++aIter)
+ {
+ OQueryTableWindow* pTabWinTmp = static_cast<OQueryTableWindow*>(aIter->second);
+ OSL_ENSURE( pTabWinTmp,"TableWindow is null!" );
+ if ( pTabWinTmp != pNewTabWin && pTabWinTmp->GetComposedName() == aReferencedTable )
+ break;
+ }
+ }
+ if ( aIter != aEnd && pNewTabWin != aIter->second )
+ addConnections( this, *pNewTabWin, *static_cast<OQueryTableWindow*>(aIter->second), xFKeyColumns );
+ }
+ break;
+
+ case KeyType::PRIMARY:
+ {
+ // we have a primary key so look in our list if there exsits a key which this is refered to
+ OTableWindowMap::const_iterator aIter = pTabWins->begin();
+ OTableWindowMap::const_iterator aEnd = pTabWins->end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OQueryTableWindow* pTabWinTmp = static_cast<OQueryTableWindow*>(aIter->second);
+ if ( pTabWinTmp == pNewTabWin )
+ continue;
+
+ if ( pTabWinTmp->GetData()->isQuery() )
+ continue;
+
+ OSL_ENSURE(pTabWinTmp,"TableWindow is null!");
+ Reference< XPropertySet > xFKKey = getKeyReferencedTo( pTabWinTmp->GetData()->getKeys(), pNewTabWin->GetComposedName() );
+ if ( !xFKKey.is() )
+ continue;
+
+ Reference<XColumnsSupplier> xFKColumnsSupplier( xFKKey, UNO_QUERY_THROW );
+ Reference< XNameAccess > xTColumns( xFKColumnsSupplier->getColumns(), UNO_QUERY_THROW );
+ addConnections( this, *pTabWinTmp, *pNewTabWin, xTColumns );
+ }
+ }
+ break;
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ } while ( false );
+ }
+
+ // mein Parent brauche ich, da es vom Loeschen erfahren soll
+ m_pView->getController().addUndoActionAndInvalidate( pUndoAction );
+
+ if (bSuccess && m_lnkTabWinsChangeHandler.IsSet())
+ {
+ TabWinsChangeNotification aHint(TabWinsChangeNotification::AT_ADDED_WIN, pNewTabWin->GetAliasName());
+ m_lnkTabWinsChangeHandler.Call(&aHint);
+ }
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+void OQueryTableView::AddConnection(const OJoinExchangeData& jxdSource, const OJoinExchangeData& jxdDest)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ OQueryTableWindow* pSourceWin = static_cast< OQueryTableWindow*>(jxdSource.pListBox->GetTabWin());
+ OQueryTableWindow* pDestWin = static_cast< OQueryTableWindow*>(jxdDest.pListBox->GetTabWin());
+
+ String aSourceFieldName, aDestFieldName;
+ aSourceFieldName = jxdSource.pListBox->GetEntryText(jxdSource.pEntry);
+ aDestFieldName = jxdDest.pListBox->GetEntryText(jxdDest.pEntry);
+
+ OTableConnection* pConn = GetTabConn(pSourceWin,pDestWin,true);
+ if ( !pConn )
+ {
+ // neues Daten-Objekt
+ OQueryTableConnectionData* pNewConnectionData = new OQueryTableConnectionData(pSourceWin->GetData(), pDestWin->GetData());
+ TTableConnectionData::value_type aNewConnectionData(pNewConnectionData);
+
+ sal_uInt32 nSourceFieldIndex, nDestFieldIndex;
+ ETableFieldType eSourceFieldType, eDestFieldType;
+
+ // Namen/Position/Typ der beiden betroffenen Felder besorgen ...
+ // Source
+
+ nSourceFieldIndex = jxdSource.pListBox->GetModel()->GetAbsPos(jxdSource.pEntry);
+ eSourceFieldType = static_cast< OTableFieldInfo*>(jxdSource.pEntry->GetUserData())->GetKeyType();
+
+ // Dest
+
+ nDestFieldIndex = jxdDest.pListBox->GetModel()->GetAbsPos(jxdDest.pEntry);
+ eDestFieldType = static_cast< OTableFieldInfo*>(jxdDest.pEntry->GetUserData())->GetKeyType();
+
+ // ... und setzen
+
+ pNewConnectionData->SetFieldIndex(JTCS_FROM, nSourceFieldIndex);
+ pNewConnectionData->SetFieldIndex(JTCS_TO, nDestFieldIndex);
+
+ pNewConnectionData->SetFieldType(JTCS_FROM, eSourceFieldType);
+ pNewConnectionData->SetFieldType(JTCS_TO, eDestFieldType);
+
+ pNewConnectionData->AppendConnLine( aSourceFieldName,aDestFieldName );
+
+ OQueryTableConnection aNewConnection(this, aNewConnectionData);
+ NotifyTabConnection(aNewConnection);
+ // wie immer bei NotifyTabConnection ist das Verwenden lokaler Variablen unkritisch, da sowieso eine Kopie erzeugt wird
+ }
+ else
+ {
+ // the connection could point on the other side
+ if(pConn->GetSourceWin() == pDestWin)
+ {
+ String aTmp(aSourceFieldName);
+ aSourceFieldName = aDestFieldName;
+ aDestFieldName = aTmp;
+ }
+
+ pConn->GetData()->AppendConnLine( aSourceFieldName,aDestFieldName );
+
+ connectionModified(this,pConn,sal_False);
+ }
+}
+// -----------------------------------------------------------------------------
+void OQueryTableView::ConnDoubleClicked(OTableConnection* pConnection)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ if( openJoinDialog(this,pConnection->GetData(),sal_False) )
+ {
+ connectionModified(this,pConnection,sal_False);
+ SelectConn( pConnection );
+ }
+}
+// -----------------------------------------------------------------------------
+void OQueryTableView::createNewConnection()
+{
+ TTableConnectionData::value_type pData(new OQueryTableConnectionData());
+ if( openJoinDialog(this,pData,sal_True) )
+ {
+ OTableWindowMap* pMap = GetTabWinMap();
+ OQueryTableWindow* pSourceWin = static_cast< OQueryTableWindow*>((*pMap)[pData->getReferencingTable()->GetWinName()]);
+ OQueryTableWindow* pDestWin = static_cast< OQueryTableWindow*>((*pMap)[pData->getReferencedTable()->GetWinName()]);
+ // first we have to look if the this connection already exists
+ OTableConnection* pConn = GetTabConn(pSourceWin,pDestWin,true);
+ sal_Bool bNew = sal_True;
+ if ( pConn )
+ {
+ pConn->GetData()->CopyFrom( *pData );
+ bNew = sal_False;
+ }
+ else
+ {
+ // create a new conenction and append it
+ OQueryTableConnection* pQConn = new OQueryTableConnection(this, pData);
+ GetConnection(pQConn);
+ pConn = pQConn;
+ }
+ connectionModified(this,pConn,bNew);
+ if ( !bNew && pConn == GetSelectedConn() ) // our connection was selected before so we have to reselect it
+ SelectConn( pConn );
+ }
+}
+//------------------------------------------------------------------------------
+bool OQueryTableView::RemoveConnection( OTableConnection* _pConnection,sal_Bool /*_bDelete*/ )
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+
+ // we don't want that our connection will be deleted, we put it in the undo manager
+ bool bRet = OJoinTableView::RemoveConnection( _pConnection,sal_False);
+
+ // add undo action
+ addUndoAction( this,
+ new OQueryDelTabConnUndoAction(this),
+ static_cast< OQueryTableConnection*>(_pConnection),
+ sal_True);
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+void OQueryTableView::KeyInput( const KeyEvent& rEvt )
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ OJoinTableView::KeyInput( rEvt );
+}
+
+//------------------------------------------------------------------------------
+OQueryTableWindow* OQueryTableView::FindTable(const String& rAliasName)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ OSL_ENSURE(rAliasName.Len(), "OQueryTableView::FindTable : der AliasName sollte nicht leer sein !");
+ // (nicht dass es schadet, aber es ist sinnlos und weist vielleicht auf Fehler beim Aufrufer hin)
+ OTableWindowMap::const_iterator aIter = GetTabWinMap()->find(rAliasName);
+ if(aIter != GetTabWinMap()->end())
+ return static_cast<OQueryTableWindow*>(aIter->second);
+ return NULL;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OQueryTableView::FindTableFromField(const String& rFieldName, OTableFieldDescRef& rInfo, sal_uInt16& rCnt)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ rCnt = 0;
+ OTableWindowMap::const_iterator aIter = GetTabWinMap()->begin();
+ OTableWindowMap::const_iterator aEnd = GetTabWinMap()->end();
+ for(;aIter != aEnd;++aIter)
+ {
+ if(static_cast<OQueryTableWindow*>(aIter->second)->ExistsField(rFieldName, rInfo))
+ ++rCnt;
+ }
+
+ return rCnt == 1;
+}
+
+//------------------------------------------------------------------------------
+void OQueryTableView::RemoveTabWin(OTableWindow* pTabWin)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ OSL_ENSURE(pTabWin != NULL, "OQueryTableView::RemoveTabWin : Fenster sollte ungleich NULL sein !");
+
+ // mein Parent brauche ich, da es vom Loeschen erfahren soll
+ OQueryDesignView* pParent = static_cast<OQueryDesignView*>(getDesignView());
+
+ SfxUndoManager& rUndoMgr = m_pView->getController().GetUndoManager();
+ rUndoMgr.EnterListAction( String( ModuleRes(STR_QUERY_UNDO_TABWINDELETE) ), String() );
+
+ // Undo-Action anlegen
+ OQueryTabWinDelUndoAct* pUndoAction = new OQueryTabWinDelUndoAct(this);
+ pUndoAction->SetTabWin(static_cast< OQueryTableWindow*>(pTabWin));
+
+ // und Fenster verstecken
+ HideTabWin(static_cast< OQueryTableWindow*>(pTabWin), pUndoAction);
+
+ // Undo Actions und Loeschen der Felder in SelectionBrowseBox
+ pParent->TableDeleted( static_cast< OQueryTableWindowData*>(pTabWin->GetData().get())->GetAliasName() );
+
+ m_pView->getController().addUndoActionAndInvalidate( pUndoAction );
+ rUndoMgr.LeaveListAction();
+
+ if (m_lnkTabWinsChangeHandler.IsSet())
+ {
+ TabWinsChangeNotification aHint(TabWinsChangeNotification::AT_REMOVED_WIN, static_cast< OQueryTableWindow*>(pTabWin)->GetAliasName());
+ m_lnkTabWinsChangeHandler.Call(&aHint);
+ }
+
+ modified();
+ if ( m_pAccessible )
+ m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
+ makeAny(pTabWin->GetAccessible()),
+ Any()
+ );
+}
+
+//------------------------------------------------------------------------
+void OQueryTableView::EnsureVisible(const OTableWindow* pWin)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+
+ Invalidate(INVALIDATE_NOCHILDREN);
+ OJoinTableView::EnsureVisible(pWin);
+}
+
+//------------------------------------------------------------------------
+void OQueryTableView::GetConnection(OQueryTableConnection* pConn)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ // bei mir und dem Dokument einfuegen
+
+ addConnection( pConn );
+}
+
+//------------------------------------------------------------------------
+void OQueryTableView::DropConnection(OQueryTableConnection* pConn)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ // Selektion beachten
+ // bei mir und dem Dokument rausnehmen
+ RemoveConnection( pConn ,sal_False);
+}
+
+//------------------------------------------------------------------------
+void OQueryTableView::HideTabWin( OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction )
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ OTableWindowMap* pTabWins = GetTabWinMap();
+ OSL_ENSURE(pTabWins != NULL, "OQueryTableView::HideTabWin : habe keine TabWins !");
+
+ if (pTabWin)
+ {
+ // Fenster
+ // die Position in seinen Daten speichern
+ getDesignView()->SaveTabWinUIConfig(pTabWin);
+ // (ich muss ueber das Parent gehen, da nur das die Position der Scrollbars kennt)
+ // dann aus der Liste der TabWins raus und verstecken
+ OTableWindowMap::iterator aIter = pTabWins->begin();
+ OTableWindowMap::iterator aEnd = pTabWins->end();
+ for ( ;aIter != aEnd ; ++aIter )
+ if ( aIter->second == pTabWin )
+ {
+ pTabWins->erase( aIter );
+ break;
+ }
+
+ pTabWin->Hide(); // nicht zerstoeren, steht im Undo!!
+
+ // die Daten zum TabWin muessen auch aus meiner Verantwortung entlassen werden
+ TTableWindowData* pTabWinDataList = m_pView->getController().getTableWindowData();
+ pTabWinDataList->erase( ::std::remove(pTabWinDataList->begin(),pTabWinDataList->end(),pTabWin->GetData()),pTabWinDataList->end());
+ // NICHT loeschen, da ja das TabWin selber - das noch lebt - sie auch noch braucht
+ // Entweder geht es irgendwann wieder in meine Verantwortung ueber, (ueber ShowTabWin), dann fuege ich
+ // auch die Daten wieder ein, oder die Undo-Action, die im Augenblick die alleinige Verantwortung fuer das Fenster
+ // und dessen Daten hat, wird zestoert, dann loescht es beides
+
+ if (m_pLastFocusTabWin == pTabWin)
+ m_pLastFocusTabWin = NULL;
+
+ // Verbindungen, die zum Fenster gehoeren, einsammeln und der UndoAction uebergeben
+ sal_Int16 nCnt = 0;
+ const ::std::vector<OTableConnection*>* pTabConList = getTableConnections();
+ ::std::vector<OTableConnection*>::const_iterator aIter2 = pTabConList->begin();
+ for(;aIter2 != pTabConList->end();)// the end may change
+ {
+ OQueryTableConnection* pTmpEntry = static_cast<OQueryTableConnection*>(*aIter2);
+ OSL_ENSURE(pTmpEntry,"OQueryTableConnection is null!");
+ if( pTmpEntry->GetAliasName(JTCS_FROM) == pTabWin->GetAliasName() ||
+ pTmpEntry->GetAliasName(JTCS_TO) == pTabWin->GetAliasName() )
+ {
+ // add to undo list
+ pUndoAction->InsertConnection(pTmpEntry);
+
+ // call base class because we append an undo action
+ // but this time we are in a undo action list
+ OJoinTableView::RemoveConnection(pTmpEntry,sal_False);
+ aIter2 = pTabConList->begin();
+ ++nCnt;
+ }
+ else
+ ++aIter2;
+ }
+
+ if (nCnt)
+ InvalidateConnections();
+
+ m_pView->getController().InvalidateFeature(ID_BROWSER_ADDTABLE);
+
+ // der UndoAction sagen, dass das Fenster (inklusive der Connections) jetzt in seinem Besitzt ist
+ pUndoAction->SetOwnership(sal_True);
+
+ // damit habe ich das Doc natuerlich modifiziert
+ m_pView->getController().setModified( sal_True );
+ m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
+ }
+}
+
+//------------------------------------------------------------------------
+sal_Bool OQueryTableView::ShowTabWin( OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction,sal_Bool _bAppend )
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+
+ sal_Bool bSuccess = sal_False;
+
+ if (pTabWin)
+ {
+ if (pTabWin->Init())
+ {
+ TTableWindowData::value_type pData = pTabWin->GetData();
+ OSL_ENSURE(pData != NULL, "OQueryTableView::ShowTabWin : TabWin hat keine Daten !");
+ // Wenn die Daten schon PosSize haben, diese benutzen
+ if (pData->HasPosition() && pData->HasSize())
+ {
+ Size aSize(CalcZoom(pData->GetSize().Width()),CalcZoom(pData->GetSize().Height()));
+ pTabWin->SetPosSizePixel(pData->GetPosition(), aSize);
+ }
+ else
+ // ansonsten selber eine Default-Position ermitteln
+ SetDefaultTabWinPosSize(pTabWin);
+
+ // Fenster zeigen und in Liste eintragen
+ ::rtl::OUString sName = static_cast< OQueryTableWindowData*>(pData.get())->GetAliasName();
+ OSL_ENSURE(GetTabWinMap()->find(sName) == GetTabWinMap()->end(),"Alias name already in list!");
+ GetTabWinMap()->insert(OTableWindowMap::value_type(sName,pTabWin));
+
+ pTabWin->Show();
+
+ pTabWin->Update();
+ // Das Update ist notwendig, damit die Connections an dem Fenster richtig gezeichnet werden. Klingt absurd,
+ // ich weiss. Aber die Listbox haelt sich intern ein Member, was bei ersten Zeichnen (nachdem die Listbox im Init
+ // gerade neu gefuellt wurde) initialisiert wird, und genau dieses Member wird irgendwann benoetigt fuer
+ // GetEntryPos, und dieses wiederum von der Connection, wenn sie ihren Ansatzpunkt am Fenster feststellen will.
+
+ // die Connections
+ ::std::vector<OTableConnection*>* pTableCon = pUndoAction->GetTabConnList();
+ ::std::vector<OTableConnection*>::iterator aIter = pTableCon->begin();
+ ::std::vector<OTableConnection*>::iterator aEnd = pTableCon->end();
+
+ for(;aIter != aEnd;++aIter)
+ addConnection(*aIter); // add all connections from the undo action
+
+ pTableCon->clear();
+
+ // und die Daten des Fensters ebenfalls in Liste (des Docs)
+ if(_bAppend)
+ m_pView->getController().getTableWindowData()->push_back(pTabWin->GetData());
+
+ m_pView->getController().InvalidateFeature(ID_BROWSER_ADDTABLE);
+
+ // und der UndoAction sagen, dass das Fenster jetzt meine ist ...
+ pUndoAction->SetOwnership(sal_False);
+
+ bSuccess = sal_True;
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // Initialisierung fehlgeschlagen
+ // (z.B. wenn Verbindung zur Datenbank in diesem Augenblick unterbrochen worden ist)
+ pTabWin->clearListBox();
+ delete pTabWin;
+ }
+ }
+
+ // damit habe ich das Doc natuerlich modifiziert
+ if(!m_pView->getController().isReadOnly())
+ m_pView->getController().setModified( sal_True );
+
+ m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
+
+ return bSuccess;
+}
+//------------------------------------------------------------------------
+void OQueryTableView::InsertField(const OTableFieldDescRef& rInfo)
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ OSL_ENSURE(getDesignView() != NULL, "OQueryTableView::InsertField : habe kein Parent !");
+ static_cast<OQueryDesignView*>(getDesignView())->InsertField(rInfo);
+}
+//------------------------------------------------------------------------------
+sal_Bool OQueryTableView::ExistsAVisitedConn(const OQueryTableWindow* pFrom) const
+{
+ DBG_CHKTHIS(OQueryTableView,NULL);
+ const ::std::vector<OTableConnection*>* pList = getTableConnections();
+ if (pList)
+ {
+ ::std::vector<OTableConnection*>::const_iterator aIter = pList->begin();
+ ::std::vector<OTableConnection*>::const_iterator aEnd = pList->end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OQueryTableConnection* pTemp = static_cast<OQueryTableConnection*>(*aIter);
+ if (pTemp->IsVisited() &&
+ (pFrom == static_cast< OQueryTableWindow*>(pTemp->GetSourceWin()) || pFrom == static_cast< OQueryTableWindow*>(pTemp->GetDestWin())))
+ return pTemp != NULL;
+ }
+ }
+
+ return sal_False;
+}
+// -----------------------------------------------------------------------------
+void OQueryTableView::onNoColumns_throw()
+{
+ String sError( ModuleRes( STR_STATEMENT_WITHOUT_RESULT_SET ) );
+ ::dbtools::throwSQLException( sError, ::dbtools::SQL_GENERAL_ERROR, NULL );
+}
+//------------------------------------------------------------------------------
+bool OQueryTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& _pData) const
+{
+ OQueryTableConnectionData* pQueryData = static_cast<OQueryTableConnectionData*>(_pData.get());
+ return pQueryData && (pQueryData->GetJoinType() == CROSS_JOIN);
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryTextView.cxx b/dbaccess/source/ui/querydesign/QueryTextView.cxx
new file mode 100644
index 000000000000..3f403a4c4892
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryTextView.cxx
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "QueryTextView.hxx"
+#include "querycontainerwindow.hxx"
+#include "QueryViewSwitch.hxx"
+#include "sqledit.hxx"
+#include "undosqledit.hxx"
+#include "browserids.hxx"
+#include "querycontroller.hxx"
+#include "dbu_qry.hrc"
+#include "dbustrings.hrc"
+#include <toolkit/unohlp.hxx>
+#include <vcl/split.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/types.hxx>
+#include "QueryDesignView.hxx"
+
+using namespace dbaui;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+// -----------------------------------------------------------------------------
+
+// end of temp classes
+// -------------------------------------------------------------------------
+DBG_NAME(OQueryTextView)
+OQueryTextView::OQueryTextView(OQueryContainerWindow* _pParent)
+ :Window(_pParent)
+{
+ DBG_CTOR(OQueryTextView,NULL);
+ m_pEdit = new OSqlEdit(this);
+ m_pEdit->SetRightToLeft(sal_False);
+ m_pEdit->ClearModifyFlag();
+ m_pEdit->SaveValue();
+ m_pEdit->SetPosPixel( Point( 0, 0 ) );
+ m_pEdit->Show();
+}
+// -----------------------------------------------------------------------------
+OQueryTextView::~OQueryTextView()
+{
+ DBG_DTOR(OQueryTextView,NULL);
+ ::std::auto_ptr<Window> aTemp(m_pEdit);
+ m_pEdit = NULL;
+}
+// -----------------------------------------------------------------------------
+void OQueryTextView::GetFocus()
+{
+ if ( m_pEdit )
+ m_pEdit->GrabFocus();
+}
+// -------------------------------------------------------------------------
+void OQueryTextView::Resize()
+{
+ Window::Resize();
+ m_pEdit->SetSizePixel( GetOutputSizePixel() );
+}
+// -----------------------------------------------------------------------------
+// check if the statement is correct when not returning false
+sal_Bool OQueryTextView::checkStatement()
+{
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OQueryTextView::getStatement()
+{
+ return m_pEdit->GetText();
+}
+// -----------------------------------------------------------------------------
+void OQueryTextView::setReadOnly(sal_Bool _bReadOnly)
+{
+ m_pEdit->SetReadOnly(_bReadOnly);
+}
+// -----------------------------------------------------------------------------
+void OQueryTextView::clear()
+{
+ OSqlEditUndoAct* pUndoAct = new OSqlEditUndoAct( m_pEdit );
+
+ pUndoAct->SetOriginalText( m_pEdit->GetText() );
+ getContainerWindow()->getDesignView()->getController().addUndoActionAndInvalidate( pUndoAct );
+
+ m_pEdit->SetText(String());
+}
+// -----------------------------------------------------------------------------
+void OQueryTextView::setStatement(const ::rtl::OUString& _rsStatement)
+{
+ m_pEdit->SetText(_rsStatement);
+}
+// -----------------------------------------------------------------------------
+void OQueryTextView::copy()
+{
+ if(!m_pEdit->IsInAccelAct() )
+ m_pEdit->Copy();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryTextView::isCutAllowed()
+{
+ return m_pEdit->GetSelected().Len() != 0;
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryTextView::isPasteAllowed()
+{
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryTextView::isCopyAllowed()
+{
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+void OQueryTextView::cut()
+{
+ if(!m_pEdit->IsInAccelAct() )
+ m_pEdit->Cut();
+ getContainerWindow()->getDesignView()->getController().setModified(sal_True);
+}
+// -----------------------------------------------------------------------------
+void OQueryTextView::paste()
+{
+ if(!m_pEdit->IsInAccelAct() )
+ m_pEdit->Paste();
+ getContainerWindow()->getDesignView()->getController().setModified(sal_True);
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/QueryViewSwitch.cxx b/dbaccess/source/ui/querydesign/QueryViewSwitch.cxx
new file mode 100644
index 000000000000..0ad058656489
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/QueryViewSwitch.cxx
@@ -0,0 +1,344 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "QueryViewSwitch.hxx"
+#include "QueryDesignView.hxx"
+#include "QueryTextView.hxx"
+#include "querycontainerwindow.hxx"
+#include "dbu_qry.hrc"
+#include "browserids.hxx"
+#include "adtabdlg.hxx"
+#include "querycontroller.hxx"
+#include "sqledit.hxx"
+#include "querycontainerwindow.hxx"
+
+using namespace dbaui;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+DBG_NAME(OQueryViewSwitch)
+OQueryViewSwitch::OQueryViewSwitch(OQueryContainerWindow* _pParent, OQueryController& _rController,const Reference< XMultiServiceFactory >& _rFactory)
+: m_bAddTableDialogWasVisible(sal_False)
+{
+ DBG_CTOR(OQueryViewSwitch,NULL);
+
+ m_pTextView = new OQueryTextView(_pParent);
+ m_pDesignView = new OQueryDesignView( _pParent, _rController, _rFactory );
+}
+// -----------------------------------------------------------------------------
+OQueryViewSwitch::~OQueryViewSwitch()
+{
+ DBG_DTOR(OQueryViewSwitch,NULL);
+ {
+ ::std::auto_ptr<Window> aTemp(m_pTextView);
+ m_pTextView = NULL;
+ }
+ {
+ ::std::auto_ptr<Window> aTemp(m_pDesignView);
+ m_pDesignView = NULL;
+ }
+}
+// -------------------------------------------------------------------------
+void OQueryViewSwitch::Construct()
+{
+ m_pDesignView->Construct( );
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::initialize()
+{
+ // initially be in SQL mode
+ m_pTextView->Show();
+ m_pDesignView->initialize();
+}
+// -------------------------------------------------------------------------
+void OQueryViewSwitch::resizeDocumentView(Rectangle& _rPlayground)
+{
+ m_pTextView->SetPosSizePixel( _rPlayground.TopLeft(), _rPlayground.GetSize() );
+ m_pDesignView->SetPosSizePixel( _rPlayground.TopLeft(), _rPlayground.GetSize() );
+
+ // just for completeness: there is no space left, we occupied it all ...
+ _rPlayground.SetPos( _rPlayground.BottomRight() );
+ _rPlayground.SetSize( Size( 0, 0 ) );
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryViewSwitch::checkStatement()
+{
+ if(m_pTextView->IsVisible())
+ return m_pTextView->checkStatement();
+ return m_pDesignView->checkStatement();
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OQueryViewSwitch::getStatement()
+{
+ if(m_pTextView->IsVisible())
+ return m_pTextView->getStatement();
+ return m_pDesignView->getStatement();
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::setReadOnly(sal_Bool _bReadOnly)
+{
+ if(m_pTextView->IsVisible())
+ m_pTextView->setReadOnly(_bReadOnly);
+ else
+ m_pDesignView->setReadOnly(_bReadOnly);
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::clear()
+{
+ if(m_pTextView->IsVisible())
+ m_pTextView->clear();
+ else
+ m_pDesignView->clear();
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::GrabFocus()
+{
+ if ( m_pTextView && m_pTextView->IsVisible() )
+ m_pTextView->GrabFocus();
+ else if ( m_pDesignView && m_pDesignView->IsVisible() )
+ m_pDesignView->GrabFocus();
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::setStatement(const ::rtl::OUString& _rsStatement)
+{
+ if(m_pTextView->IsVisible())
+ m_pTextView->setStatement(_rsStatement);
+ else
+ m_pDesignView->setStatement(_rsStatement);
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::copy()
+{
+ if(m_pTextView->IsVisible())
+ m_pTextView->copy();
+ else
+ m_pDesignView->copy();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryViewSwitch::isCutAllowed()
+{
+ if(m_pTextView->IsVisible())
+ return m_pTextView->isCutAllowed();
+ return m_pDesignView->isCutAllowed();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryViewSwitch::isCopyAllowed()
+{
+ if(m_pTextView->IsVisible())
+ return m_pTextView->isCopyAllowed();
+ return m_pDesignView->isCopyAllowed();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryViewSwitch::isPasteAllowed()
+{
+ if(m_pTextView->IsVisible())
+ return m_pTextView->isPasteAllowed();
+ return m_pDesignView->isPasteAllowed();
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::cut()
+{
+ if(m_pTextView->IsVisible())
+ m_pTextView->cut();
+ else
+ m_pDesignView->cut();
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::paste()
+{
+ if(m_pTextView->IsVisible())
+ m_pTextView->paste();
+ else
+ m_pDesignView->paste();
+}
+// -----------------------------------------------------------------------------
+OQueryContainerWindow* OQueryViewSwitch::getContainer() const
+{
+ Window* pDesignParent = getDesignView() ? getDesignView()->GetParent() : NULL;
+ return static_cast< OQueryContainerWindow* >( pDesignParent );
+}
+
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::impl_forceSQLView()
+{
+ OAddTableDlg* pAddTabDialog( getAddTableDialog() );
+
+ // hide the "Add Table" dialog
+ m_bAddTableDialogWasVisible = pAddTabDialog ? pAddTabDialog->IsVisible() : false;
+ if ( m_bAddTableDialogWasVisible )
+ pAddTabDialog->Hide();
+
+ // tell the views they're in/active
+ m_pDesignView->stopTimer();
+ m_pTextView->getSqlEdit()->startTimer();
+
+ // set the most recent statement at the text view
+ m_pTextView->clear();
+ m_pTextView->setStatement(static_cast<OQueryController&>(m_pDesignView->getController()).getStatement());
+}
+
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::forceInitialView()
+{
+ OQueryController& rQueryController( static_cast< OQueryController& >( m_pDesignView->getController() ) );
+ const sal_Bool bGraphicalDesign = rQueryController.isGraphicalDesign();
+ if ( !bGraphicalDesign )
+ impl_forceSQLView();
+ else
+ {
+ // tell the text view it's inactive now
+ m_pTextView->getSqlEdit()->stopTimer();
+
+ // update the "Add Table" dialog
+ OAddTableDlg* pAddTabDialog( getAddTableDialog() );
+ if ( pAddTabDialog )
+ pAddTabDialog->Update();
+
+ // initialize the design view
+ m_pDesignView->initByFieldDescriptions( rQueryController.getFieldInformation() );
+
+ // tell the design view it's active now
+ m_pDesignView->startTimer();
+ }
+
+ impl_postViewSwitch( bGraphicalDesign, true );
+}
+
+// -----------------------------------------------------------------------------
+bool OQueryViewSwitch::switchView( ::dbtools::SQLExceptionInfo* _pErrorInfo )
+{
+ sal_Bool bRet = sal_True;
+ sal_Bool bGraphicalDesign = static_cast<OQueryController&>(m_pDesignView->getController()).isGraphicalDesign();
+
+ if ( !bGraphicalDesign )
+ {
+ impl_forceSQLView();
+ }
+ else
+ {
+ // tell the text view it's inactive now
+ m_pTextView->getSqlEdit()->stopTimer();
+
+ // update the "Add Table" dialog
+ OAddTableDlg* pAddTabDialog( getAddTableDialog() );
+ if ( pAddTabDialog )
+ pAddTabDialog->Update();
+
+ // initialize the design view
+ bRet = m_pDesignView->initByParseIterator( _pErrorInfo );
+
+ // tell the design view it's active now
+ m_pDesignView->startTimer();
+ }
+
+ return impl_postViewSwitch( bGraphicalDesign, bRet );
+}
+
+// -----------------------------------------------------------------------------
+bool OQueryViewSwitch::impl_postViewSwitch( const bool i_bGraphicalDesign, const bool i_bSuccess )
+{
+ if ( i_bSuccess )
+ {
+ m_pTextView->Show ( !i_bGraphicalDesign );
+ m_pDesignView->Show ( i_bGraphicalDesign );
+ OAddTableDlg* pAddTabDialog( getAddTableDialog() );
+ if ( pAddTabDialog )
+ if ( i_bGraphicalDesign && m_bAddTableDialogWasVisible )
+ pAddTabDialog->Show();
+
+ GrabFocus();
+ }
+
+ OQueryContainerWindow* pContainer = getContainer();
+ if ( pContainer )
+ pContainer->Resize();
+
+ m_pDesignView->getController().ClearUndoManager();
+ m_pDesignView->getController().InvalidateAll();
+
+ return i_bSuccess;
+}
+
+// -----------------------------------------------------------------------------
+OAddTableDlg* OQueryViewSwitch::getAddTableDialog()
+{
+ if ( !m_pDesignView )
+ return NULL;
+ return m_pDesignView->getController().getAddTableDialog();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryViewSwitch::isSlotEnabled(sal_Int32 _nSlotId)
+{
+ return m_pDesignView->isSlotEnabled(_nSlotId);
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::setSlotEnabled(sal_Int32 _nSlotId,sal_Bool _bEnable)
+{
+ m_pDesignView->setSlotEnabled(_nSlotId,_bEnable);
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::SaveUIConfig()
+{
+ if(m_pDesignView->IsVisible())
+ m_pDesignView->SaveUIConfig();
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::SetPosSizePixel( Point _rPt,Size _rSize)
+{
+ m_pDesignView->SetPosSizePixel( _rPt,_rSize);
+ m_pDesignView->Resize();
+ m_pTextView->SetPosSizePixel( _rPt,_rSize);
+}
+// -----------------------------------------------------------------------------
+Reference< XMultiServiceFactory > OQueryViewSwitch::getORB() const
+{
+ return m_pDesignView->getORB();
+}
+// -----------------------------------------------------------------------------
+bool OQueryViewSwitch::reset( ::dbtools::SQLExceptionInfo* _pErrorInfo )
+{
+ m_pDesignView->reset();
+ if ( !m_pDesignView->initByParseIterator( _pErrorInfo ) )
+ return false;
+
+ if ( switchView( _pErrorInfo ) )
+ return false;
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+void OQueryViewSwitch::setNoneVisbleRow(sal_Int32 _nRows)
+{
+ if(m_pDesignView)
+ m_pDesignView->setNoneVisbleRow(_nRows);
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx b/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
new file mode 100644
index 000000000000..f48ff8767b50
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
@@ -0,0 +1,2834 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "SelectionBrowseBox.hxx"
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include "QueryDesignView.hxx"
+#include "querycontroller.hxx"
+#include "QueryTableView.hxx"
+#include "browserids.hxx"
+#include <comphelper/types.hxx>
+#include "TableFieldInfo.hxx"
+#include "dbu_qry.hrc"
+#include "dbaccess_helpid.hrc"
+#include <com/sun/star/container/XNameAccess.hpp>
+#include "dbustrings.hrc"
+#include "QTableWindow.hxx"
+#include "QueryTableView.hxx"
+#include <vcl/msgbox.hxx>
+#include "QueryDesignFieldUndoAct.hxx"
+#include <svx/dbexch.hrc>
+#include <comphelper/stl_types.hxx>
+#include <comphelper/extract.hxx>
+#include "sqlmessage.hxx"
+#include "UITools.hxx"
+#include <osl/diagnose.h>
+
+using namespace ::svt;
+using namespace ::dbaui;
+using namespace ::connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::accessibility;
+
+const String g_strOne = String::CreateFromAscii("1");
+const String g_strZero = String::CreateFromAscii("0");
+
+#define DEFAULT_QUERY_COLS 20
+#define DEFAULT_SIZE GetTextWidth(g_strZero) * 30
+#define CHECKBOX_SIZE 10
+#define HANDLE_ID 0
+#define HANDLE_COLUMN_WITDH 70
+
+#define SQL_ISRULEOR2(pParseNode, e1,e2) ((pParseNode)->isRule() && (\
+ (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e1) || \
+ (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e2)))
+
+
+// -----------------------------------------------------------------------------
+namespace
+{
+ sal_Bool isFieldNameAsterix(const ::rtl::OUString& _sFieldName )
+ {
+ sal_Bool bAsterix = !(_sFieldName.getLength() && _sFieldName.toChar() != '*');
+ if ( !bAsterix )
+ {
+ String sName = _sFieldName;
+ xub_StrLen nTokenCount = sName.GetTokenCount('.');
+ if ( (nTokenCount == 2 && sName.GetToken(1,'.').GetChar(0) == '*' )
+ || (nTokenCount == 3 && sName.GetToken(2,'.').GetChar(0) == '*' ) )
+ {
+ bAsterix = sal_True;
+ }
+ }
+ return bAsterix;
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool lcl_SupportsCoreSQLGrammar(const Reference< XConnection>& _xConnection)
+ {
+ sal_Bool bSupportsCoreGrammar = sal_False;
+ if ( _xConnection.is() )
+ {
+ try
+ {
+ Reference< XDatabaseMetaData > xMetaData = _xConnection->getMetaData();
+ bSupportsCoreGrammar = xMetaData.is() && xMetaData->supportsCoreSQLGrammar();
+ }
+ catch(Exception&)
+ {
+ }
+ }
+ return bSupportsCoreGrammar;
+ }
+}
+
+DBG_NAME(OSelectionBrowseBox)
+//------------------------------------------------------------------------------
+OSelectionBrowseBox::OSelectionBrowseBox( Window* pParent )
+ :EditBrowseBox( pParent,EBBF_NOROWPICTURE, WB_3DLOOK, BROWSER_COLUMNSELECTION | BROWSER_KEEPSELECTION | BROWSER_HIDESELECT |
+ BROWSER_HIDECURSOR | BROWSER_HLINESFULL | BROWSER_VLINESFULL )
+ ,m_aFunctionStrings(ModuleRes(STR_QUERY_FUNCTIONS))
+ ,m_nVisibleCount(0)
+ ,m_bOrderByUnRelated(sal_True)
+ ,m_bGroupByUnRelated(sal_True)
+ ,m_bStopTimer(sal_False)
+ ,m_bWasEditing(sal_False)
+ ,m_bDisableErrorBox(sal_False)
+ ,m_bInUndoMode(sal_False)
+{
+ DBG_CTOR(OSelectionBrowseBox,NULL);
+ SetHelpId(HID_CTL_QRYDGNCRIT);
+
+ m_nMode = BROWSER_COLUMNSELECTION | BROWSER_HIDESELECT
+ | BROWSER_KEEPSELECTION | BROWSER_HIDECURSOR
+ | BROWSER_HLINESFULL | BROWSER_VLINESFULL
+ | BROWSER_HEADERBAR_NEW ;
+
+ m_pTextCell = new Edit(&GetDataWindow(), 0);
+ m_pVisibleCell = new CheckBoxControl(&GetDataWindow());
+ m_pTableCell = new ListBoxControl(&GetDataWindow()); m_pTableCell->SetDropDownLineCount( 20 );
+ m_pFieldCell = new ComboBoxControl(&GetDataWindow()); m_pFieldCell->SetDropDownLineCount( 20 );
+ m_pOrderCell = new ListBoxControl(&GetDataWindow());
+ m_pFunctionCell = new ListBoxControl(&GetDataWindow()); m_pFunctionCell->SetDropDownLineCount( 20 );
+
+ m_pVisibleCell->SetHelpId(HID_QRYDGN_ROW_VISIBLE);
+ m_pTableCell->SetHelpId(HID_QRYDGN_ROW_TABLE);
+ m_pFieldCell->SetHelpId(HID_QRYDGN_ROW_FIELD);
+ m_pOrderCell->SetHelpId(HID_QRYDGN_ROW_ORDER);
+ m_pFunctionCell->SetHelpId(HID_QRYDGN_ROW_FUNCTION);
+
+ //////////////////////////////////////////////////////////////////////
+ // TriState der ::com::sun::star::form::CheckBox abschalten
+ m_pVisibleCell->GetBox().EnableTriState( sal_False );
+
+ Font aTitleFont = OutputDevice::GetDefaultFont( DEFAULTFONT_SANS_UNICODE,Window::GetSettings().GetLanguage(),DEFAULTFONT_FLAGS_ONLYONE);
+ aTitleFont.SetSize(Size(0, 6));
+ SetTitleFont(aTitleFont);
+
+ String aTxt(ModuleRes(STR_QUERY_SORTTEXT));
+ xub_StrLen nCount = aTxt.GetTokenCount();
+ xub_StrLen nIdx = 0;
+ for (; nIdx < nCount; nIdx++)
+ m_pOrderCell->InsertEntry(aTxt.GetToken(nIdx));
+
+ for(long i=0;i < BROW_ROW_CNT;i++)
+ m_bVisibleRow.push_back(sal_True);
+
+ m_bVisibleRow[BROW_FUNCTION_ROW] = sal_False; // zuerst ausblenden
+
+ m_timerInvalidate.SetTimeout(200);
+ m_timerInvalidate.SetTimeoutHdl(LINK(this, OSelectionBrowseBox, OnInvalidateTimer));
+ m_timerInvalidate.Start();
+}
+
+//------------------------------------------------------------------------------
+OSelectionBrowseBox::~OSelectionBrowseBox()
+{
+ DBG_DTOR(OSelectionBrowseBox,NULL);
+
+ delete m_pTextCell;
+ delete m_pVisibleCell;
+ delete m_pFieldCell;
+ delete m_pTableCell;
+ delete m_pOrderCell;
+ delete m_pFunctionCell;
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::initialize()
+{
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
+ if(xConnection.is())
+ {
+ const IParseContext& rContext = static_cast<OQueryController&>(getDesignView()->getController()).getParser().getContext();
+ IParseContext::InternationalKeyCode eFunctions[] = { IParseContext::KEY_AVG,IParseContext::KEY_COUNT,IParseContext::KEY_MAX
+ ,IParseContext::KEY_MIN,IParseContext::KEY_SUM
+ ,IParseContext::KEY_EVERY
+ ,IParseContext::KEY_ANY
+ ,IParseContext::KEY_SOME
+ ,IParseContext::KEY_STDDEV_POP
+ ,IParseContext::KEY_STDDEV_SAMP
+ ,IParseContext::KEY_VAR_SAMP
+ ,IParseContext::KEY_VAR_POP
+ ,IParseContext::KEY_COLLECT
+ ,IParseContext::KEY_FUSION
+ ,IParseContext::KEY_INTERSECTION
+ };
+
+ String sGroup = m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount() - 1);
+ m_aFunctionStrings = m_aFunctionStrings.GetToken(0);
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(eFunctions); ++i)
+ {
+ m_aFunctionStrings += String(RTL_CONSTASCII_USTRINGPARAM(";"));
+ m_aFunctionStrings += String(ByteString(rContext.getIntlKeywordAscii(eFunctions[i])),RTL_TEXTENCODING_UTF8);
+
+ }
+ m_aFunctionStrings += String(RTL_CONSTASCII_USTRINGPARAM(";"));
+ m_aFunctionStrings += sGroup;
+
+ // Diese Funktionen stehen nur unter CORE zur Verf�gung
+ if ( lcl_SupportsCoreSQLGrammar(xConnection) )
+ {
+ xub_StrLen nCount = m_aFunctionStrings.GetTokenCount();
+ for (xub_StrLen nIdx = 0; nIdx < nCount; nIdx++)
+ m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(nIdx));
+ }
+ else // sonst nur COUNT(*)
+ {
+ m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(0));
+ m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(2)); // 2 -> COUNT
+ }
+ try
+ {
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ if ( xMetaData.is() )
+ {
+ m_bOrderByUnRelated = xMetaData->supportsOrderByUnrelated();
+ m_bGroupByUnRelated = xMetaData->supportsGroupByUnrelated();
+ }
+ }
+ catch(Exception&)
+ {
+ }
+ }
+
+ Init();
+}
+//==============================================================================
+OQueryDesignView* OSelectionBrowseBox::getDesignView()
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OSL_ENSURE(static_cast<const OQueryDesignView*>(GetParent()),"Parent isn't an OQueryDesignView!");
+ return static_cast<OQueryDesignView*>(GetParent());
+}
+// -----------------------------------------------------------------------------
+OQueryDesignView* OSelectionBrowseBox::getDesignView() const
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OSL_ENSURE(static_cast<const OQueryDesignView*>(GetParent()),"Parent isn't an OQueryDesignView!");
+ return static_cast<OQueryDesignView*>(GetParent());
+}
+namespace
+{
+ class OSelectionBrwBoxHeader : public ::svt::EditBrowserHeader
+ {
+ OSelectionBrowseBox* m_pBrowseBox;
+ protected:
+ virtual void Select();
+ public:
+ OSelectionBrwBoxHeader(OSelectionBrowseBox* pParent);
+ };
+ OSelectionBrwBoxHeader::OSelectionBrwBoxHeader(OSelectionBrowseBox* pParent)
+ : ::svt::EditBrowserHeader(pParent,WB_BUTTONSTYLE|WB_DRAG)
+ ,m_pBrowseBox(pParent)
+ {
+ }
+
+ void OSelectionBrwBoxHeader::Select()
+ {
+ EditBrowserHeader::Select();
+ m_pBrowseBox->GrabFocus();
+
+ BrowserMode nMode = m_pBrowseBox->GetMode();
+ if ( 0 == m_pBrowseBox->GetSelectColumnCount() )
+ {
+ m_pBrowseBox->DeactivateCell();
+ // wenn es schon eine selektierte Spalte gibt, bin ich schon im richtigen Modus
+ if ( BROWSER_HIDESELECT == ( nMode & BROWSER_HIDESELECT ) )
+ {
+ nMode &= ~BROWSER_HIDESELECT;
+ nMode |= BROWSER_MULTISELECTION;
+ m_pBrowseBox->SetMode( nMode );
+ }
+ }
+ m_pBrowseBox->SelectColumnId( GetCurItemId() );
+ m_pBrowseBox->DeactivateCell();
+ }
+}
+
+// -----------------------------------------------------------------------------
+BrowserHeader* OSelectionBrowseBox::imp_CreateHeaderBar(BrowseBox* /*pParent*/)
+{
+ return new OSelectionBrwBoxHeader(this);
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::ColumnMoved( sal_uInt16 nColId,sal_Bool _bCreateUndo )
+{
+ EditBrowseBox::ColumnMoved( nColId );
+ // swap the two columns
+ sal_uInt16 nNewPos = GetColumnPos( nColId );
+ OTableFields& rFields = getFields();
+ if ( rFields.size() > sal_uInt16(nNewPos-1) )
+ {
+ sal_uInt16 nOldPos = 0;
+ OTableFields::iterator aEnd = rFields.end();
+ OTableFields::iterator aIter = rFields.begin();
+ for (; aIter != aEnd && ( (*aIter)->GetColumnId() != nColId ); ++aIter,++nOldPos)
+ ;
+
+ OSL_ENSURE( (nNewPos-1) != nOldPos && nOldPos < rFields.size(),"Old and new position are equal!");
+ if ( aIter != aEnd )
+ {
+ OTableFieldDescRef pOldEntry = rFields[nOldPos];
+ rFields.erase(rFields.begin() + nOldPos);
+ rFields.insert(rFields.begin() + nNewPos - 1,pOldEntry);
+
+ // create the undo action
+ if ( !m_bInUndoMode && _bCreateUndo )
+ {
+ OTabFieldMovedUndoAct* pUndoAct = new OTabFieldMovedUndoAct(this);
+ pUndoAct->SetColumnPosition( nOldPos + 1);
+ pUndoAct->SetTabFieldDescr(pOldEntry);
+
+ getDesignView()->getController().addUndoActionAndInvalidate(pUndoAct);
+ }
+ }
+ }
+ else
+ OSL_FAIL("Invalid column id!");
+}
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::Init()
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+
+ EditBrowseBox::Init();
+
+ // set the header bar
+ BrowserHeader* pNewHeaderBar = CreateHeaderBar(this);
+ pNewHeaderBar->SetMouseTransparent(sal_False);
+
+ SetHeaderBar(pNewHeaderBar);
+ SetMode(m_nMode);
+
+ Font aFont( GetDataWindow().GetFont() );
+ aFont.SetWeight( WEIGHT_NORMAL );
+ GetDataWindow().SetFont( aFont );
+
+ Size aHeight;
+ const Control* pControls[] = { m_pTextCell,m_pVisibleCell,m_pTableCell,m_pFieldCell };
+ for(sal_Size i= 0; i < SAL_N_ELEMENTS(pControls);++i)
+ {
+ const Size aTemp( pControls[i]->GetOptimalSize(WINDOWSIZE_PREFERRED) );
+ if ( aTemp.Height() > aHeight.Height() )
+ aHeight.Height() = aTemp.Height();
+ }
+ SetDataRowHeight(aHeight.Height());
+ SetTitleLines(1);
+ // Anzahl der sichtbaren Zeilen ermitteln
+ for(long i=0;i<BROW_ROW_CNT;i++)
+ {
+ if(m_bVisibleRow[i])
+ m_nVisibleCount++;
+ }
+ RowInserted(0, m_nVisibleCount, sal_False);
+ try
+ {
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
+ if(xConnection.is())
+ {
+ Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
+ m_nMaxColumns = xMetaData.is() ? xMetaData->getMaxColumnsInSelect() : 0;
+
+ }
+ else
+ m_nMaxColumns = 0;
+ }
+ catch(const SQLException&)
+ {
+ OSL_FAIL("Catched Exception when asking for database metadata options!");
+ m_nMaxColumns = 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::PreFill()
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ SetUpdateMode(sal_False);
+
+ if (GetCurRow() != 0)
+ GoToRow(0);
+
+
+ static_cast< OQueryController& >( getDesignView()->getController() ).clearFields();
+
+ DeactivateCell();
+
+ RemoveColumns();
+ InsertHandleColumn( HANDLE_COLUMN_WITDH );
+ SetUpdateMode(sal_True);
+}
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::ClearAll()
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ SetUpdateMode(sal_False);
+
+ OTableFields::reverse_iterator aIter = getFields().rbegin();
+ for ( ;aIter != getFields().rend(); ++aIter )
+ {
+ if ( !(*aIter)->IsEmpty() )
+ {
+ RemoveField( (*aIter)->GetColumnId() );
+ aIter = getFields().rbegin();
+ }
+ }
+ SetUpdateMode(sal_True);
+}
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::SetReadOnly(sal_Bool bRO)
+{
+ if (bRO)
+ {
+ DeactivateCell();
+ m_nMode &= ~BROWSER_HIDECURSOR;
+ SetMode(m_nMode);
+ }
+ else
+ {
+ m_nMode |= BROWSER_HIDECURSOR;
+ SetMode(m_nMode);
+ ActivateCell();
+ }
+}
+
+//------------------------------------------------------------------------------
+CellController* OSelectionBrowseBox::GetController(long nRow, sal_uInt16 nColId)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ if ( nColId > getFields().size() )
+ return NULL;
+ OTableFieldDescRef pEntry = getFields()[nColId-1];
+ OSL_ENSURE(pEntry.is(), "OSelectionBrowseBox::GetController : keine FieldDescription !");
+
+ if (!pEntry.is())
+ return NULL;
+
+ if (static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
+ return NULL;
+
+ long nCellIndex = GetRealRow(nRow);
+ switch (nCellIndex)
+ {
+ case BROW_FIELD_ROW:
+ return new ComboBoxCellController(m_pFieldCell);
+ case BROW_TABLE_ROW:
+ return new ListBoxCellController(m_pTableCell);
+ case BROW_VIS_ROW:
+ return new CheckBoxCellController(m_pVisibleCell);
+ case BROW_ORDER_ROW:
+ return new ListBoxCellController(m_pOrderCell);
+ case BROW_FUNCTION_ROW:
+ return new ListBoxCellController(m_pFunctionCell);
+ default:
+ return new EditCellController(m_pTextCell);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::InitController(CellControllerRef& /*rController*/, long nRow, sal_uInt16 nColId)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OSL_ENSURE(nColId != BROWSER_INVALIDID,"An Invalid Id was set!");
+ if ( nColId == BROWSER_INVALIDID )
+ return;
+ sal_uInt16 nPos = GetColumnPos(nColId);
+ if ( nPos == 0 || nPos == BROWSER_INVALIDID || nPos > getFields().size() )
+ return;
+ OTableFieldDescRef pEntry = getFields()[nPos-1];
+ OSL_ENSURE(pEntry.is(), "OSelectionBrowseBox::InitController : keine FieldDescription !");
+ long nCellIndex = GetRealRow(nRow);
+
+ switch (nCellIndex)
+ {
+ case BROW_FIELD_ROW:
+ {
+ m_pFieldCell->Clear();
+ m_pFieldCell->SetText(String());
+
+ String aField(pEntry->GetField());
+ String aTable(pEntry->GetAlias());
+
+ getDesignView()->fillValidFields(aTable, m_pFieldCell);
+
+ // * durch alias.* ersetzen
+ if ((aField.GetChar(0) == '*') && aTable.Len())
+ {
+ aField = aTable;
+ aField.AppendAscii(".*");
+ }
+ m_pFieldCell->SetText(aField);
+ } break;
+ case BROW_TABLE_ROW:
+ {
+ m_pTableCell->Clear();
+ enableControl(pEntry,m_pTableCell);
+ if ( !pEntry->isCondition() )
+ {
+ OJoinTableView::OTableWindowMap* pTabWinList = getDesignView()->getTableView()->GetTabWinMap();
+ if (pTabWinList)
+ {
+ OJoinTableView::OTableWindowMap::iterator aIter = pTabWinList->begin();
+ OJoinTableView::OTableWindowMap::iterator aEnd = pTabWinList->end();
+
+ for(;aIter != aEnd;++aIter)
+ m_pTableCell->InsertEntry(static_cast<OQueryTableWindow*>(aIter->second)->GetAliasName());
+
+ m_pTableCell->InsertEntry(String(ModuleRes(STR_QUERY_NOTABLE)), 0);
+ if (pEntry->GetAlias().getLength())
+ m_pTableCell->SelectEntry(pEntry->GetAlias());
+ else
+ m_pTableCell->SelectEntry(String(ModuleRes(STR_QUERY_NOTABLE)));
+ }
+ }
+ } break;
+ case BROW_VIS_ROW:
+ {
+ m_pVisibleCell->GetBox().Check(pEntry->IsVisible());
+ m_pVisibleCell->GetBox().SaveValue();
+
+ enableControl(pEntry,m_pTextCell);
+
+ if(!pEntry->IsVisible() && pEntry->GetOrderDir() != ORDER_NONE && !m_bOrderByUnRelated)
+ {
+ // Spalte muss sichtbar sein, um im ORDER BY aufzutauchen
+ pEntry->SetVisible(sal_True);
+ m_pVisibleCell->GetBox().Check(pEntry->IsVisible());
+ m_pVisibleCell->GetBox().SaveValue();
+ m_pVisibleCell->GetBox().Disable();
+ m_pVisibleCell->GetBox().EnableInput(sal_False);
+ String aMessage(ModuleRes(STR_QRY_ORDERBY_UNRELATED));
+ OQueryDesignView* paDView = getDesignView();
+ InfoBox(paDView, aMessage).Execute();
+ }
+ } break;
+ case BROW_ORDER_ROW:
+ m_pOrderCell->SelectEntryPos(
+ sal::static_int_cast< sal_uInt16 >(pEntry->GetOrderDir()));
+ enableControl(pEntry,m_pOrderCell);
+ break;
+ case BROW_COLUMNALIAS_ROW:
+ setTextCellContext(pEntry,pEntry->GetFieldAlias(),HID_QRYDGN_ROW_ALIAS);
+ break;
+ case BROW_FUNCTION_ROW:
+ setFunctionCell(pEntry);
+ break;
+ default:
+ {
+ sal_uInt16 nIdx = sal_uInt16(nCellIndex - BROW_CRIT1_ROW);
+ setTextCellContext(pEntry,pEntry->GetCriteria( nIdx ),HID_QRYDGN_ROW_CRIT);
+ }
+ }
+ Controller()->ClearModified();
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::notifyTableFieldChanged(const String& _sOldAlias,const String& _sAlias,sal_Bool& _bListAction,sal_uInt16 _nColumnId)
+{
+ appendUndoAction(_sOldAlias,_sAlias,BROW_TABLE_ROW,_bListAction);
+ if ( m_bVisibleRow[BROW_TABLE_ROW] )
+ RowModified(GetBrowseRow(BROW_TABLE_ROW), _nColumnId);
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::notifyFunctionFieldChanged(const String& _sOldFunctionName,const String& _sFunctionName,sal_Bool& _bListAction,sal_uInt16 _nColumnId)
+{
+ appendUndoAction(_sOldFunctionName,_sFunctionName,BROW_FUNCTION_ROW,_bListAction);
+ if ( !m_bVisibleRow[BROW_FUNCTION_ROW] )
+ SetRowVisible(BROW_FUNCTION_ROW, sal_True);
+ RowModified(GetBrowseRow(BROW_FUNCTION_ROW), _nColumnId);
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::clearEntryFunctionField(const String& _sFieldName,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction,sal_uInt16 _nColumnId)
+{
+ if ( isFieldNameAsterix( _sFieldName ) && (!_pEntry->isNoneFunction() || _pEntry->IsGroupBy()) )
+ {
+ String sFunctionName;
+ GetFunctionName(SQL_TOKEN_COUNT,sFunctionName);
+ String sOldLocalizedFunctionName = _pEntry->GetFunction();
+ if ( !sOldLocalizedFunctionName.Equals(sFunctionName) || _pEntry->IsGroupBy() )
+ {
+ // append undo action for the function field
+ _pEntry->SetFunctionType(FKT_NONE);
+ _pEntry->SetFunction(::rtl::OUString());
+ _pEntry->SetGroupBy(sal_False);
+ notifyFunctionFieldChanged(sOldLocalizedFunctionName,_pEntry->GetFunction(),_bListAction,_nColumnId);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::fillColumnRef(const OSQLParseNode* _pColumnRef, const Reference< XConnection >& _rxConnection, OTableFieldDescRef& _pEntry, sal_Bool& _bListAction )
+{
+ OSL_ENSURE(_pColumnRef,"No valid parsenode!");
+ ::rtl::OUString sColumnName,sTableRange;
+ OSQLParseTreeIterator::getColumnRange(_pColumnRef,_rxConnection,sColumnName,sTableRange);
+ return fillColumnRef(sColumnName,sTableRange,_rxConnection->getMetaData(),_pEntry,_bListAction);
+}
+// -----------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::fillColumnRef(const ::rtl::OUString& _sColumnName,const ::rtl::OUString& _sTableRange,const Reference<XDatabaseMetaData>& _xMetaData,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction)
+{
+ sal_Bool bError = sal_False;
+ ::comphelper::UStringMixEqual bCase(_xMetaData->supportsMixedCaseQuotedIdentifiers());
+ // check if the table name is the same
+ if ( _sTableRange.getLength() && (bCase(_pEntry->GetTable(),_sTableRange) || bCase(_pEntry->GetAlias(),_sTableRange)) )
+ { // a table was already inserted and the tables contains that column name
+
+ if ( !_pEntry->GetTabWindow() )
+ { // fill tab window
+ ::rtl::OUString sOldAlias = _pEntry->GetAlias();
+ if ( !fillEntryTable(_pEntry,_pEntry->GetTable()) )
+ fillEntryTable(_pEntry,_pEntry->GetAlias()); // only when the first failed
+ if ( !bCase(sOldAlias,_pEntry->GetAlias()) )
+ notifyTableFieldChanged(sOldAlias,_pEntry->GetAlias(),_bListAction,GetCurColumnId());
+ }
+ }
+ // check if the table window
+ OQueryTableWindow* pEntryTab = static_cast<OQueryTableWindow*>(_pEntry->GetTabWindow());
+ if ( !pEntryTab ) // no table found with this name so we have to travel through all tables
+ {
+ OJoinTableView::OTableWindowMap* pTabWinList = getDesignView()->getTableView()->GetTabWinMap();
+ if ( pTabWinList )
+ {
+ sal_uInt16 nTabCount = 0;
+ if ( !static_cast<OQueryTableView*>(getDesignView()->getTableView())->FindTableFromField(_sColumnName,_pEntry,nTabCount) ) // error occurred: column not in table window
+ {
+ String sErrorMsg(ModuleRes(RID_STR_FIELD_DOESNT_EXIST));
+ sErrorMsg.SearchAndReplaceAscii("$name$",_sColumnName);
+ OSQLWarningBox( this, sErrorMsg ).Execute();
+ bError = sal_True;
+ }
+ else
+ {
+ pEntryTab = static_cast<OQueryTableWindow*>(_pEntry->GetTabWindow());
+ notifyTableFieldChanged(String(),_pEntry->GetAlias(),_bListAction,GetCurColumnId());
+ }
+ }
+ }
+ if ( pEntryTab ) // here we got a valid table
+ _pEntry->SetField(_sColumnName);
+
+ return bError;
+}
+// -----------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::saveField(const String& _sFieldName,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction)
+{
+ sal_Bool bError = sal_False;
+
+ OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
+
+ // first look if the name can be found in our tables
+ sal_uInt16 nTabCount = 0;
+ String sOldAlias = _pEntry->GetAlias();
+ if ( static_cast<OQueryTableView*>(getDesignView()->getTableView())->FindTableFromField(_sFieldName,_pEntry,nTabCount) )
+ {
+ // append undo action for the alias name
+ _pEntry->SetField(_sFieldName);
+ notifyTableFieldChanged(sOldAlias,_pEntry->GetAlias(),_bListAction,GetCurColumnId());
+ clearEntryFunctionField(_sFieldName,_pEntry,_bListAction,_pEntry->GetColumnId());
+ return bError;
+ }
+
+ Reference<XConnection> xConnection( rController.getConnection() );
+ Reference< XDatabaseMetaData > xMetaData;
+ if ( xConnection.is() )
+ xMetaData = xConnection->getMetaData();
+ OSL_ENSURE( xMetaData.is(), "OSelectionBrowseBox::saveField: invalid connection/meta data!" );
+ if ( !xMetaData.is() )
+ return sal_True;
+
+ ::rtl::OUString sErrorMsg;
+ // second test if the name can be set as select columns in a pseudo statement
+ // we have to look which entries we should quote
+
+ const ::rtl::OUString sFieldAlias = _pEntry->GetFieldAlias();
+ size_t nPass = 4;
+ ::connectivity::OSQLParser& rParser( rController.getParser() );
+ OSQLParseNode* pParseNode = NULL;
+ // 4 passes in trying to interprete the field name
+ // - don't quote the field name, parse internationally
+ // - don't quote the field name, parse en-US
+ // - quote the field name, parse internationally
+ // - quote the field name, parse en-US
+ do
+ {
+ bool bQuote = ( nPass <= 2 );
+ bool bInternational = ( nPass % 2 ) == 0;
+
+ ::rtl::OUString sSql;
+ if ( bQuote )
+ sSql += ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), _sFieldName );
+ else
+ sSql += _sFieldName;
+
+ if ( _pEntry->isAggreateFunction() )
+ {
+ OSL_ENSURE(_pEntry->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-(");
+ ::rtl::OUStringBuffer aTmpStr2( _pEntry->GetFunction());
+ aTmpStr2.appendAscii("(");
+ aTmpStr2.append(sSql);
+ aTmpStr2.appendAscii(")");
+ sSql = aTmpStr2.makeStringAndClear();
+ }
+
+ sSql = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT ")) + sSql;
+ if ( sFieldAlias.getLength() )
+ { // always quote the alias name there canbe no function in it
+ sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
+ sSql += ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), sFieldAlias );
+ }
+ sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM x"));
+
+ pParseNode = rParser.parseTree( sErrorMsg, sSql, bInternational );
+ }
+ while ( ( pParseNode == NULL ) && ( --nPass > 0 ) );
+
+ if ( pParseNode == NULL )
+ {
+ // something different which we have to check (may be a select statement)
+ String sErrorMessage( ModuleRes( STR_QRY_COLUMN_NOT_FOUND ) );
+ sErrorMessage.SearchAndReplaceAscii("$name$",_sFieldName);
+ OSQLWarningBox( this, sErrorMessage ).Execute();
+ return sal_True;
+ }
+
+ // we got a valid select column
+ // find what type of column has be inserted
+ ::connectivity::OSQLParseNode* pSelection = pParseNode->getChild(2);
+ if ( SQL_ISRULE(pSelection,selection) ) // we found the asterix
+ {
+ _pEntry->SetField(_sFieldName);
+ clearEntryFunctionField(_sFieldName,_pEntry,_bListAction,_pEntry->GetColumnId());
+ } // travel through the select column parse node
+ else
+ {
+ ::comphelper::UStringMixEqual bCase(xMetaData->supportsMixedCaseQuotedIdentifiers());
+
+ OTableFieldDescRef aSelEntry = _pEntry;
+ sal_uInt16 nColumnId = aSelEntry->GetColumnId();
+
+ sal_uInt32 nCount = pSelection->count();
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ if ( i > 0 ) // may we have to append more than one field
+ {
+ sal_uInt16 nColumnPostion;
+ aSelEntry = FindFirstFreeCol(nColumnPostion);
+ if ( !aSelEntry.is() )
+ {
+ AppendNewCol(1);
+ aSelEntry = FindFirstFreeCol(nColumnPostion);
+ }
+ ++nColumnPostion;
+ nColumnId = GetColumnId(nColumnPostion);
+ }
+
+ ::connectivity::OSQLParseNode* pChild = pSelection->getChild( i );
+ OSL_ENSURE(SQL_ISRULE(pChild,derived_column), "No derived column found!");
+ // get the column alias
+ ::rtl::OUString sColumnAlias = OSQLParseTreeIterator::getColumnAlias(pChild);
+ if ( sColumnAlias.getLength() ) // we found an as clause
+ {
+ String aSelectionAlias = aSelEntry->GetFieldAlias();
+ aSelEntry->SetFieldAlias( sColumnAlias );
+ // append undo
+ appendUndoAction(aSelectionAlias,aSelEntry->GetFieldAlias(),BROW_COLUMNALIAS_ROW,_bListAction);
+ if ( m_bVisibleRow[BROW_COLUMNALIAS_ROW] )
+ RowModified(GetBrowseRow(BROW_COLUMNALIAS_ROW), nColumnId);
+ }
+
+ ::connectivity::OSQLParseNode* pColumnRef = pChild->getChild(0);
+ if (
+ pColumnRef->count() == 3 &&
+ SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
+ )
+ pColumnRef = pColumnRef->getChild(1);
+
+ if ( SQL_ISRULE(pColumnRef,column_ref) ) // we found a valid column name or more column names
+ {
+ // look if we can find the corresponding table
+ bError = fillColumnRef( pColumnRef, xConnection, aSelEntry, _bListAction );
+
+ // we found a simple column so we must clear the function fields but only when the column name is '*'
+ // and the function is different to count
+ clearEntryFunctionField(_sFieldName,aSelEntry,_bListAction,nColumnId);
+ }
+ else
+ {
+ // first check if we have a aggregate function and only a function
+ if ( SQL_ISRULE(pColumnRef,general_set_fct) )
+ {
+ String sLocalizedFunctionName;
+ if ( GetFunctionName(pColumnRef->getChild(0)->getTokenID(),sLocalizedFunctionName) )
+ {
+ String sOldLocalizedFunctionName = aSelEntry->GetFunction();
+ aSelEntry->SetFunction(sLocalizedFunctionName);
+ sal_uInt32 nFunCount = pColumnRef->count() - 1;
+ sal_Int32 nFunctionType = FKT_AGGREGATE;
+ sal_Bool bQuote = sal_False;
+ // may be there exists only one parameter which is a column, fill all information into our fields
+ if ( nFunCount == 4 && SQL_ISRULE(pColumnRef->getChild(3),column_ref) )
+ bError = fillColumnRef( pColumnRef->getChild(3), xConnection, aSelEntry, _bListAction );
+ else if ( nFunCount == 3 ) // we have a COUNT(*) here, so take the first table
+ bError = fillColumnRef( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), ::rtl::OUString(), xMetaData, aSelEntry, _bListAction );
+ else
+ {
+ nFunctionType |= FKT_NUMERIC;
+ bQuote = sal_True;
+ aSelEntry->SetDataType(DataType::DOUBLE);
+ aSelEntry->SetFieldType(TAB_NORMAL_FIELD);
+ }
+
+ // now parse the parameters
+ ::rtl::OUString sParameters;
+ for(sal_uInt32 function = 2; function < nFunCount; ++function) // we only want to parse the parameters of the function
+ pColumnRef->getChild(function)->parseNodeToStr( sParameters, xConnection, &rParser.getContext(), sal_True, bQuote );
+
+ aSelEntry->SetFunctionType(nFunctionType);
+ aSelEntry->SetField(sParameters);
+ if ( aSelEntry->IsGroupBy() )
+ {
+ sOldLocalizedFunctionName = m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount()-1);
+ aSelEntry->SetGroupBy(sal_False);
+ }
+
+ // append undo action
+ notifyFunctionFieldChanged(sOldLocalizedFunctionName,sLocalizedFunctionName,_bListAction, nColumnId);
+ }
+ else
+ OSL_FAIL("Unsupported function inserted!");
+
+ }
+ else
+ {
+ // so we first clear the function field
+ clearEntryFunctionField(_sFieldName,aSelEntry,_bListAction,nColumnId);
+ ::rtl::OUString sFunction;
+ pColumnRef->parseNodeToStr( sFunction,
+ xConnection,
+ &rController.getParser().getContext(),
+ sal_True,
+ sal_True); // quote is to true because we need quoted elements inside the function
+
+ getDesignView()->fillFunctionInfo(pColumnRef,sFunction,aSelEntry);
+
+ if( SQL_ISRULEOR2(pColumnRef,position_exp,extract_exp) ||
+ SQL_ISRULEOR2(pColumnRef,fold,char_substring_fct) ||
+ SQL_ISRULEOR2(pColumnRef,length_exp,char_value_fct) )
+ // a calculation has been found ( can be calc and function )
+ {
+ // now parse the whole statement
+ sal_uInt32 nFunCount = pColumnRef->count();
+ ::rtl::OUString sParameters;
+ for(sal_uInt32 function = 0; function < nFunCount; ++function)
+ pColumnRef->getChild(function)->parseNodeToStr( sParameters, xConnection, &rParser.getContext(), sal_True, sal_True );
+
+ sOldAlias = aSelEntry->GetAlias();
+ sal_Int32 nNewFunctionType = aSelEntry->GetFunctionType() | FKT_NUMERIC | FKT_OTHER;
+ aSelEntry->SetFunctionType(nNewFunctionType);
+ aSelEntry->SetField(sParameters);
+ }
+ else
+ {
+ aSelEntry->SetFieldAlias(sColumnAlias);
+ if ( SQL_ISRULE(pColumnRef,set_fct_spec) )
+ aSelEntry->SetFunctionType(/*FKT_NUMERIC | */FKT_OTHER);
+ else
+ {
+ if ( SQL_ISRULEOR2(pColumnRef,num_value_exp,term) || SQL_ISRULE(pColumnRef,factor) )
+ aSelEntry->SetDataType(DataType::DOUBLE);
+ else if ( SQL_ISRULE(pColumnRef,value_exp) )
+ aSelEntry->SetDataType(DataType::TIMESTAMP);
+ else
+ aSelEntry->SetDataType(DataType::VARCHAR);
+ aSelEntry->SetFunctionType(FKT_NUMERIC | FKT_OTHER);
+ }
+ }
+
+ aSelEntry->SetAlias(::rtl::OUString());
+ notifyTableFieldChanged(sOldAlias,aSelEntry->GetAlias(),_bListAction, nColumnId);
+ }
+
+ }
+ if ( i > 0 && !InsertField(aSelEntry,BROWSER_INVALIDID,sal_True,sal_False).is() ) // may we have to append more than one field
+ { // the field could not be isnerted
+ String sErrorMessage( ModuleRes( RID_STR_FIELD_DOESNT_EXIST ) );
+ sErrorMessage.SearchAndReplaceAscii("$name$",aSelEntry->GetField());
+ OSQLWarningBox( this, sErrorMessage ).Execute();
+ bError = sal_True;
+ }
+ }
+ }
+ delete pParseNode;
+
+ return bError;
+}
+//------------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::SaveModified()
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
+ OTableFieldDescRef pEntry = NULL;
+ sal_uInt16 nCurrentColumnPos = GetColumnPos(GetCurColumnId());
+ if(getFields().size() > static_cast<sal_uInt16>(nCurrentColumnPos - 1))
+ pEntry = getEntry(nCurrentColumnPos - 1);
+
+ sal_Bool bWasEmpty = pEntry.is() ? pEntry->IsEmpty() : sal_False;
+ sal_Bool bError = sal_False;
+ sal_Bool bListAction = sal_False;
+
+ if (pEntry.is() && Controller().Is() && Controller()->IsModified())
+ {
+ // fuer die Undo-Action
+ String strOldCellContents,sNewValue;
+ long nRow = GetRealRow(GetCurRow());
+ sal_Bool bAppendRow = sal_False;
+ switch (nRow)
+ {
+ case BROW_VIS_ROW:
+ {
+ sal_Bool bOldValue = m_pVisibleCell->GetBox().GetSavedValue() != STATE_NOCHECK;
+ strOldCellContents = bOldValue ? g_strOne : g_strZero;
+ sNewValue = !bOldValue ? g_strOne : g_strZero;
+ }
+ if((m_bOrderByUnRelated || pEntry->GetOrderDir() == ORDER_NONE) &&
+ (m_bGroupByUnRelated || !pEntry->IsGroupBy()))
+ {
+ pEntry->SetVisible(m_pVisibleCell->GetBox().IsChecked());
+ }
+ else
+ {
+ pEntry->SetVisible(sal_True);
+ m_pVisibleCell->GetBox().Check();
+ }
+ break;
+
+ case BROW_FIELD_ROW:
+ {
+ String aFieldName(m_pFieldCell->GetText());
+ try
+ {
+ if (!aFieldName.Len())
+ {
+ OTableFieldDescRef pNewEntry = new OTableFieldDesc();
+ pNewEntry->SetColumnId( pEntry->GetColumnId() );
+ ::std::replace(getFields().begin(),getFields().end(),pEntry,pNewEntry);
+ sal_uInt16 nCol = GetCurColumnId();
+ for (int i = 0; i < m_nVisibleCount; i++) // Spalte neu zeichnen
+ RowModified(i,nCol);
+ }
+ else
+ {
+ strOldCellContents = pEntry->GetField();
+ bListAction = sal_True;
+ if ( !m_bInUndoMode )
+ rController.GetUndoManager().EnterListAction(String(),String());
+
+ sal_uInt16 nPos = m_pFieldCell->GetEntryPos(aFieldName);
+ String aAliasName = pEntry->GetAlias();
+ if ( nPos != COMBOBOX_ENTRY_NOTFOUND && !aAliasName.Len() && aFieldName.GetTokenCount('.') > 1 )
+ { // special case, we have a table field so we must cut the table name
+ String sTableAlias = aFieldName.GetToken(0,'.');
+ pEntry->SetAlias(sTableAlias);
+ String sColumnName = aFieldName.Copy(sTableAlias.Len()+1,aFieldName.Len() - sTableAlias.Len() -1);
+ Reference<XConnection> xConnection = rController.getConnection();
+ if ( !xConnection.is() )
+ return sal_False;
+ bError = fillColumnRef( sColumnName, sTableAlias, xConnection->getMetaData(), pEntry, bListAction );
+ }
+ else
+ bError = sal_True;
+
+ if ( bError )
+ bError = saveField(aFieldName,pEntry,bListAction);
+ }
+ }
+ catch(Exception&)
+ {
+ bError = sal_True;
+ }
+ if ( bError )
+ {
+ sNewValue = aFieldName;
+ if ( !m_bInUndoMode )
+ static_cast<OQueryController&>(getDesignView()->getController()).GetUndoManager().LeaveListAction();
+ bListAction = sal_False;
+ }
+ else
+ sNewValue = pEntry->GetField();
+ rController.InvalidateFeature( ID_BROWSER_QUERY_EXECUTE );
+ }
+ break;
+
+ case BROW_TABLE_ROW:
+ {
+ String aAliasName = m_pTableCell->GetSelectEntry();
+ strOldCellContents = pEntry->GetAlias();
+ if ( m_pTableCell->GetSelectEntryPos() != 0 )
+ {
+ pEntry->SetAlias(aAliasName);
+ // we have to set the table name as well as the table window
+ OJoinTableView::OTableWindowMap* pTabWinList = getDesignView()->getTableView()->GetTabWinMap();
+ if (pTabWinList)
+ {
+ OJoinTableView::OTableWindowMapIterator aIter = pTabWinList->find(aAliasName);
+ if(aIter != pTabWinList->end())
+ {
+ OQueryTableWindow* pEntryTab = static_cast<OQueryTableWindow*>(aIter->second);
+ if (pEntryTab)
+ {
+ pEntry->SetTable(pEntryTab->GetTableName());
+ pEntry->SetTabWindow(pEntryTab);
+ }
+ }
+ }
+ }
+ else
+ {
+ pEntry->SetAlias(::rtl::OUString());
+ pEntry->SetTable(::rtl::OUString());
+ pEntry->SetTabWindow(NULL);
+ }
+ sNewValue = pEntry->GetAlias();
+
+ } break;
+
+ case BROW_ORDER_ROW:
+ {
+ strOldCellContents = String::CreateFromInt32((sal_uInt16)pEntry->GetOrderDir());
+ sal_uInt16 nIdx = m_pOrderCell->GetSelectEntryPos();
+ if (nIdx == sal_uInt16(-1))
+ nIdx = 0;
+ pEntry->SetOrderDir(EOrderDir(nIdx));
+ if(!m_bOrderByUnRelated)
+ {
+ pEntry->SetVisible(sal_True);
+ m_pVisibleCell->GetBox().Check();
+ RowModified(GetBrowseRow(BROW_VIS_ROW), GetCurColumnId());
+ }
+ sNewValue = String::CreateFromInt32((sal_uInt16)pEntry->GetOrderDir());
+ } break;
+
+ case BROW_COLUMNALIAS_ROW:
+ strOldCellContents = pEntry->GetFieldAlias();
+ pEntry->SetFieldAlias(m_pTextCell->GetText());
+ sNewValue = pEntry->GetFieldAlias();
+ break;
+ case BROW_FUNCTION_ROW:
+ {
+ strOldCellContents = pEntry->GetFunction();
+ sal_uInt16 nPos = m_pFunctionCell->GetSelectEntryPos();
+ // Diese Funktionen stehen nur unter CORE zur Verf�gung
+ String sFunctionName = m_pFunctionCell->GetEntry(nPos);
+ String sGroupFunctionName = m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount()-1);
+ sal_Bool bGroupBy = sal_False;
+ if ( sGroupFunctionName.Equals(sFunctionName) ) // check if the function name is GROUP
+ {
+ bGroupBy = sal_True;
+
+ if ( !m_bGroupByUnRelated && !pEntry->IsVisible() )
+ {
+ // we have to change the visblie flag, so we must append also an undo action
+ pEntry->SetVisible(sal_True);
+ m_pVisibleCell->GetBox().Check();
+ appendUndoAction(g_strZero,g_strOne,BROW_VIS_ROW,bListAction);
+ RowModified(GetBrowseRow(BROW_VIS_ROW), GetCurColumnId());
+ }
+
+ pEntry->SetFunction(String());
+ pEntry->SetFunctionType(pEntry->GetFunctionType() & ~FKT_AGGREGATE );
+ }
+ else if ( nPos ) // we found an aggregate function
+ {
+ pEntry->SetFunctionType(pEntry->GetFunctionType() | FKT_AGGREGATE );
+ pEntry->SetFunction(sFunctionName);
+ }
+ else
+ {
+ sFunctionName = String();
+ pEntry->SetFunction(String());
+ pEntry->SetFunctionType(pEntry->GetFunctionType() & ~FKT_AGGREGATE );
+ }
+
+ pEntry->SetGroupBy(bGroupBy);
+
+ sNewValue = sFunctionName;
+ }
+ break;
+ default:
+ {
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
+ if(!xConnection.is())
+ break;
+
+ sal_uInt16 nIdx = sal_uInt16(nRow - BROW_CRIT1_ROW);
+ String aText = m_pTextCell->GetText();
+
+ aText.EraseLeadingChars();
+ ::rtl::OUString aCrit;
+ if(aText.Len())
+ {
+ ::rtl::OUString aErrorMsg;
+ Reference<XPropertySet> xColumn;
+ OSQLParseNode* pParseNode = getDesignView()->getPredicateTreeFromEntry(pEntry,aText,aErrorMsg,xColumn);
+
+ if (pParseNode)
+ {
+ pParseNode->parseNodeToPredicateStr(aCrit,
+ xConnection,
+ static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
+ xColumn,
+ getDesignView()->getLocale(),
+ static_cast<sal_Char>(getDesignView()->getDecimalSeparator().toChar()),
+ &(static_cast<OQueryController&>(getDesignView()->getController()).getParser().getContext()));
+ delete pParseNode;
+ }
+ else
+ {
+ if(xColumn.is())
+ {
+ sal_Int32 nType = 0;
+ xColumn->getPropertyValue(PROPERTY_TYPE) >>= nType;
+ switch(nType)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ case DataType::CLOB:
+ if(aText.GetChar(0) != '\'' || aText.GetChar(aText.Len() -1) != '\'')
+ {
+ aText.SearchAndReplaceAll(String::CreateFromAscii("'"),String::CreateFromAscii("''"));
+ String aTmp(String::CreateFromAscii("'"));
+ (aTmp += aText) += String::CreateFromAscii("'");
+ aText = aTmp;
+ }
+ break;
+ default:
+ ;
+ }
+ ::connectivity::OSQLParser& rParser = static_cast<OQueryController&>(getDesignView()->getController()).getParser();
+ pParseNode = rParser.predicateTree(aErrorMsg,
+ aText,
+ static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
+ xColumn);
+ if (pParseNode)
+ {
+ pParseNode->parseNodeToPredicateStr(aCrit,
+ xConnection,
+ static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
+ xColumn,
+ getDesignView()->getLocale(),
+ static_cast<sal_Char>(getDesignView()->getDecimalSeparator().toChar()),
+ &(static_cast<OQueryController&>(getDesignView()->getController()).getParser().getContext()));
+ delete pParseNode;
+ }
+ else
+ {
+ if ( !m_bDisableErrorBox )
+ {
+ OSQLWarningBox( this, aErrorMsg ).Execute();
+ }
+ bError = sal_True;
+ }
+ }
+ else
+ {
+ if ( !m_bDisableErrorBox )
+ {
+ OSQLWarningBox( this, aErrorMsg ).Execute();
+ }
+ bError = sal_True;
+ }
+ }
+ }
+ strOldCellContents = pEntry->GetCriteria(nIdx);
+ pEntry->SetCriteria(nIdx, aCrit);
+ sNewValue = pEntry->GetCriteria(nIdx);
+ if(aCrit.getLength() && nRow >= (GetRowCount()-1))
+ bAppendRow = sal_True;
+ }
+ }
+ if(!bError && Controller())
+ Controller()->ClearModified();
+
+ RowModified(GetCurRow(), GetCurColumnId());
+
+ if ( bAppendRow )
+ {
+ RowInserted( GetRowCount()-1, 1, sal_True );
+ m_bVisibleRow.push_back(sal_True);
+ ++m_nVisibleCount;
+ }
+
+ if(!bError)
+ {
+ // und noch die Undo-Action fuer das Ganze
+ appendUndoAction(strOldCellContents,sNewValue,nRow);
+
+ }
+ }
+
+ // habe ich Daten in einer FieldDescription gespeichert, die vorher leer war und es nach den Aenderungen nicht mehr ist ?
+ if ( pEntry.is() && bWasEmpty && !pEntry->IsEmpty() && !bError )
+ {
+ // Default auf sichtbar
+ pEntry->SetVisible(sal_True);
+ appendUndoAction(g_strZero,g_strOne,BROW_VIS_ROW,bListAction);
+ RowModified(BROW_VIS_ROW, GetCurColumnId());
+
+ // wenn noetig neue freie Spalten anlegen
+ sal_uInt16 nDummy;
+ CheckFreeColumns(nDummy);
+ }
+
+ if ( bListAction && !m_bInUndoMode )
+ static_cast<OQueryController&>(getDesignView()->getController()).GetUndoManager().LeaveListAction();
+
+ return pEntry != NULL && !bError;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::SeekRow(long nRow)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ sal_Bool bRet = sal_False;
+
+ m_nSeekRow = nRow;
+ if (nRow < m_nVisibleCount )
+ bRet = sal_True;
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::PaintCell(OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId) const
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ rDev.SetClipRegion( rRect );
+
+ OTableFieldDescRef pEntry = NULL;
+ sal_uInt16 nPos = GetColumnPos(nColumnId);
+ if(getFields().size() > sal_uInt16(nPos - 1))
+ pEntry = getFields()[nPos - 1];
+
+ if (!pEntry.is())
+ return;
+
+ long nRow = GetRealRow(m_nSeekRow);
+ if (nRow == BROW_VIS_ROW)
+ PaintTristate(rDev, rRect, pEntry->IsVisible() ? STATE_CHECK : STATE_NOCHECK);
+ else
+ rDev.DrawText(rRect, GetCellText(nRow, nColumnId),TEXT_DRAW_VCENTER);
+
+ rDev.SetClipRegion( );
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::PaintStatusCell(OutputDevice& rDev, const Rectangle& rRect) const
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ Rectangle aRect(rRect);
+ aRect.TopLeft().Y() -= 2;
+ String aLabel(ModuleRes(STR_QUERY_HANDLETEXT));
+
+ // ab BROW_CRIT2_ROW werden alle Zeilen mit "oder" angegeben
+ xub_StrLen nToken = (xub_StrLen) (m_nSeekRow >= GetBrowseRow(BROW_CRIT2_ROW))
+ ?
+ xub_StrLen(BROW_CRIT2_ROW) : xub_StrLen(GetRealRow(m_nSeekRow));
+ rDev.DrawText(aRect, aLabel.GetToken(nToken),TEXT_DRAW_VCENTER);
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::RemoveColumn(sal_uInt16 _nColumnId)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
+
+ sal_uInt16 nPos = GetColumnPos(_nColumnId);
+ // das Control sollte immer genau eine Spalte mehr haben, naemlich die HandleColumn
+ OSL_ENSURE((nPos == 0) || (nPos <= getFields().size()), "OSelectionBrowseBox::RemoveColumn : invalid parameter nColId");
+ // ColId ist bei mir gleichbedeutend mit Position, und da sollte die Bedingung natuerlich zutreffen
+
+ sal_uInt16 nCurCol = GetCurColumnId();
+ long nCurrentRow = GetCurRow();
+
+ DeactivateCell();
+
+ getFields().erase( getFields().begin() + (nPos - 1) );
+ OTableFieldDescRef pEntry = new OTableFieldDesc();
+ pEntry->SetColumnId(_nColumnId);
+ getFields().push_back(pEntry);
+
+ EditBrowseBox::RemoveColumn( _nColumnId );
+ InsertDataColumn( _nColumnId , String(), DEFAULT_SIZE, HIB_STDSTYLE, HEADERBAR_APPEND);
+
+ // Neuzeichnen
+ Rectangle aInvalidRect = GetInvalidRect( _nColumnId );
+ Invalidate( aInvalidRect );
+
+ ActivateCell( nCurrentRow, nCurCol );
+
+ rController.setModified( sal_True );
+
+ invalidateUndoRedo();
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::RemoveField(sal_uInt16 nColumnId )
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
+
+ sal_uInt16 nPos = GetColumnPos(nColumnId);
+ OSL_ENSURE(getFields().size() > sal_uInt16(nPos-1),"ID is to great!");
+
+ OTableFieldDescRef pDesc = getEntry((sal_uInt32)(nPos - 1)) ;
+ pDesc->SetColWidth( (sal_uInt16)GetColumnWidth(nColumnId) ); // hat er sich vorher leider nicht gemerkt
+
+ // UndoAction erzeugen
+ if ( !m_bInUndoMode )
+ {
+ OTabFieldDelUndoAct* pUndoAction = new OTabFieldDelUndoAct( this );
+ pUndoAction->SetTabFieldDescr(pDesc);
+ pUndoAction->SetColumnPosition(nPos);
+ rController.addUndoActionAndInvalidate( pUndoAction );
+ }
+
+ RemoveColumn(nColumnId);
+
+ invalidateUndoRedo();
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::adjustSelectionMode( sal_Bool _bClickedOntoHeader, sal_Bool _bClickedOntoHandleCol )
+{
+ // wenn ein Header selectiert wird, mu� die selection angezeigt werden, sonst nicht)
+ if ( _bClickedOntoHeader )
+ {
+ if (0 == GetSelectColumnCount() )
+ // wenn es schon eine selektierte Spalte gibt, bin ich schon im richtigen Modus
+ if ( BROWSER_HIDESELECT == ( m_nMode & BROWSER_HIDESELECT ) )
+ {
+ m_nMode &= ~BROWSER_HIDESELECT;
+ m_nMode |= BROWSER_MULTISELECTION;
+ SetMode( m_nMode );
+ }
+ }
+ else if ( BROWSER_HIDESELECT != ( m_nMode & BROWSER_HIDESELECT ) )
+ {
+ if ( GetSelectColumnCount() != 0 )
+ SetNoSelection();
+
+ if ( _bClickedOntoHandleCol )
+ {
+ m_nMode |= BROWSER_HIDESELECT;
+ m_nMode &= ~BROWSER_MULTISELECTION;
+ SetMode( m_nMode );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::MouseButtonDown(const BrowserMouseEvent& rEvt)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ if( rEvt.IsLeft() )
+ {
+ sal_Bool bOnHandle = HANDLE_ID == rEvt.GetColumnId();
+ sal_Bool bOnHeader = ( rEvt.GetRow() < 0 ) && !bOnHandle;
+ adjustSelectionMode( bOnHeader, bOnHandle );
+ }
+ EditBrowseBox::MouseButtonDown(rEvt);
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::MouseButtonUp(const BrowserMouseEvent& rEvt)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ EditBrowseBox::MouseButtonUp( rEvt );
+ static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( ID_BROWSER_QUERY_EXECUTE );
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::KeyInput( const KeyEvent& rEvt )
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ if (IsColumnSelected(GetCurColumnId()))
+ {
+ if (rEvt.GetKeyCode().GetCode() == KEY_DELETE && // Delete rows
+ !rEvt.GetKeyCode().IsShift() &&
+ !rEvt.GetKeyCode().IsMod1())
+ {
+ RemoveField(GetCurColumnId());
+ return;
+ }
+ }
+ EditBrowseBox::KeyInput(rEvt);
+}
+
+
+//------------------------------------------------------------------------------
+sal_Int8 OSelectionBrowseBox::AcceptDrop( const BrowserAcceptDropEvent& rEvt )
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ sal_Int8 nDropAction = DND_ACTION_NONE;
+ if ( rEvt.GetRow() >= -1 )
+ {
+ if ( IsEditing() )
+ {
+ // allow the asterix again
+ m_bDisableErrorBox = sal_True;
+ SaveModified();
+ m_bDisableErrorBox = sal_False;
+ DeactivateCell();
+ }
+ // check if the format is already supported, if not deactivate the current cell and try again
+ if ( OJoinExchObj::isFormatAvailable(GetDataFlavors()) )
+ nDropAction = DND_ACTION_LINK;
+ }
+
+ return nDropAction;
+}
+
+//------------------------------------------------------------------------------
+sal_Int8 OSelectionBrowseBox::ExecuteDrop( const BrowserExecuteDropEvent& _rEvt )
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+
+ TransferableDataHelper aDropped(_rEvt.maDropEvent.Transferable);
+ if (!OJoinExchObj::isFormatAvailable(aDropped.GetDataFlavorExVector()))
+ {
+ OSL_FAIL("OSelectionBrowseBox::ExecuteDrop: this should never have passed AcceptDrop!");
+ return DND_ACTION_NONE;
+ }
+
+ OTableFieldDesc aInfo;
+ // Einfuegen des Feldes an der gewuenschten Position
+ OJoinExchangeData jxdSource = OJoinExchObj::GetSourceDescription(_rEvt.maDropEvent.Transferable);
+ InsertField(jxdSource);
+
+ return DND_ACTION_LINK;
+}
+
+//------------------------------------------------------------------------------
+OTableFieldDescRef OSelectionBrowseBox::AppendNewCol( sal_uInt16 nCnt)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ // es koennen mehrere angelegt werden, aber der Erste
+ // wird returnt
+ sal_uInt32 nCount = getFields().size();
+ for (sal_uInt16 i=0 ; i<nCnt ; i++)
+ {
+ OTableFieldDescRef pEmptyEntry = new OTableFieldDesc();
+ getFields().push_back(pEmptyEntry);
+ sal_uInt16 nColumnId = sal::static_int_cast< sal_uInt16 >(getFields().size());
+ pEmptyEntry->SetColumnId( nColumnId );
+
+ InsertDataColumn( nColumnId , String(), DEFAULT_SIZE, HIB_STDSTYLE, HEADERBAR_APPEND);
+ }
+
+ return getFields()[nCount];
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::DeleteFields(const String& rAliasName)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ if (!getFields().empty())
+ {
+ sal_uInt16 nColId = GetCurColumnId();
+ sal_uInt32 nRow = GetCurRow();
+
+ sal_Bool bWasEditing = IsEditing();
+ if (bWasEditing)
+ DeactivateCell();
+
+ OTableFields::reverse_iterator aIter = getFields().rbegin();
+ OTableFieldDescRef pEntry = NULL;
+ for(sal_uInt16 nPos=sal::static_int_cast< sal_uInt16 >(getFields().size());aIter != getFields().rend();++aIter,--nPos)
+ {
+ pEntry = *aIter;
+ if ( pEntry->GetAlias().equals( rAliasName ) )
+ {
+ RemoveField( GetColumnId( nPos ) );
+ break;
+ }
+ }
+
+ if (bWasEditing)
+ ActivateCell(nRow , nColId);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::SetColWidth(sal_uInt16 nColId, long nNewWidth)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ sal_Bool bWasEditing = IsEditing();
+ if (bWasEditing)
+ DeactivateCell();
+
+ // die Basisklasse machen lassen
+ SetColumnWidth(nColId, nNewWidth);
+
+ // der FieldDescription Bescheid sagen
+ OTableFieldDescRef pEntry = getEntry(GetColumnPos(nColId) - 1);
+ if (pEntry.is())
+ pEntry->SetColWidth(sal_uInt16(GetColumnWidth(nColId)));
+
+ if (bWasEditing)
+ ActivateCell(GetCurRow(), GetCurColumnId());
+}
+
+//------------------------------------------------------------------------------
+Rectangle OSelectionBrowseBox::GetInvalidRect( sal_uInt16 nColId )
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ //////////////////////////////////////////////////////////////////////
+ // Rechteck ist erst einmal der gesamte Outputbereich des Fensters
+ Rectangle aInvalidRect( Point(0,0), GetOutputSizePixel() );
+
+ //////////////////////////////////////////////////////////////////////
+ // Dann wird die linke Seite angepasst
+ Rectangle aFieldRect(GetCellRect( 0, nColId )); // used instead of GetFieldRectPixel
+ aInvalidRect.Left() = aFieldRect.Left();
+
+ return aInvalidRect;
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::InsertColumn(OTableFieldDescRef pEntry, sal_uInt16& _nColumnPostion)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ // das Control sollte immer genau eine Spalte mehr haben, naemlich die HandleColumn
+ OSL_ENSURE(_nColumnPostion == BROWSER_INVALIDID || (_nColumnPostion <= (long)getFields().size()), "OSelectionBrowseBox::InsertColumn : invalid parameter nColId.");
+ // -1 heisst ganz hinten, Count heisst ganz hinten, der Rest bezeichnet eine richtige Position
+
+ sal_uInt16 nCurCol = GetCurColumnId();
+ long nCurrentRow = GetCurRow();
+
+ DeactivateCell();
+
+ // remember the column id of the current positon
+ sal_uInt16 nColumnId = GetColumnId(_nColumnPostion);
+ // Wenn zu klein oder zu gross, auf Ende der Liste setzen
+ if ((_nColumnPostion == BROWSER_INVALIDID) || (_nColumnPostion >= getFields().size())) // Anhaengen des Feldes
+ {
+ if (FindFirstFreeCol(_nColumnPostion) == NULL) // keine freie Column mehr
+ {
+ AppendNewCol(1);
+ _nColumnPostion = sal::static_int_cast< sal_uInt16 >(
+ getFields().size());
+ }
+ else
+ ++_nColumnPostion; // innerhalb der vorgegebenen Liste
+ nColumnId = GetColumnId(_nColumnPostion);
+ pEntry->SetColumnId( nColumnId );
+ getFields()[ _nColumnPostion - 1] = pEntry;
+ }
+
+ // check if the column ids are identical, if not we have to move
+ if ( pEntry->GetColumnId() != nColumnId )
+ {
+ sal_uInt16 nOldPosition = GetColumnPos(pEntry->GetColumnId());
+ OSL_ENSURE( nOldPosition != 0,"Old position was 0. Not possible!");
+ SetColumnPos(pEntry->GetColumnId(),_nColumnPostion);
+ // we have to delete an empty field for the fields list, because the columns must have equal length
+ if ( nOldPosition > 0 && nOldPosition <= getFields().size() )
+ getFields()[nOldPosition - 1] = pEntry;
+
+ ColumnMoved(pEntry->GetColumnId(),sal_False);
+ }
+
+ if ( pEntry->GetFunctionType() & (FKT_AGGREGATE) )
+ {
+ String sFunctionName = pEntry->GetFunction();
+ if ( GetFunctionName(sal_uInt32(-1),sFunctionName) )
+ pEntry->SetFunction(sFunctionName);
+ }
+
+ nColumnId = pEntry->GetColumnId();
+
+ SetColWidth(nColumnId,getDesignView()->getColWidth(GetColumnPos(nColumnId)-1));
+ // Neuzeichnen
+ Rectangle aInvalidRect = GetInvalidRect( nColumnId );
+ Invalidate( aInvalidRect );
+
+ ActivateCell( nCurrentRow, nCurCol );
+ static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
+
+ invalidateUndoRedo();
+}
+
+//------------------------------------------------------------------------------
+OTableFieldDescRef OSelectionBrowseBox::InsertField(const OJoinExchangeData& jxdSource, sal_uInt16 _nColumnPostion, sal_Bool bVis, sal_Bool bActivate)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OQueryTableWindow* pSourceWin = static_cast<OQueryTableWindow*>(jxdSource.pListBox->GetTabWin());
+ if (!pSourceWin)
+ return NULL;
+
+ // Namen/Position des selektierten Feldes
+ String aFieldName = jxdSource.pListBox->GetEntryText(jxdSource.pEntry);
+ sal_uInt32 nFieldIndex = jxdSource.pListBox->GetModel()->GetAbsPos(jxdSource.pEntry);
+ OTableFieldInfo* pInf = static_cast<OTableFieldInfo*>(jxdSource.pEntry->GetUserData());
+
+ // eine DragInfo aufbauen, damit ich mich auf das andere InsertField zurueckziehen kann
+ OTableFieldDescRef aInfo = new OTableFieldDesc(pSourceWin->GetTableName(),aFieldName);
+ aInfo->SetTabWindow(pSourceWin);
+ aInfo->SetFieldIndex(nFieldIndex);
+ aInfo->SetFieldType(pInf->GetKeyType());
+ aInfo->SetAlias(pSourceWin->GetAliasName());
+
+ aInfo->SetDataType(pInf->GetDataType());
+ aInfo->SetVisible(bVis);
+
+ return InsertField(aInfo, _nColumnPostion, bVis, bActivate);
+}
+
+//------------------------------------------------------------------------------
+OTableFieldDescRef OSelectionBrowseBox::InsertField(const OTableFieldDescRef& _rInfo, sal_uInt16 _nColumnPostion, sal_Bool bVis, sal_Bool bActivate)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+
+ if(m_nMaxColumns && m_nMaxColumns <= FieldsCount())
+ return NULL;
+ if (bActivate)
+ SaveModified();
+
+ // Neue Spaltenbeschreibung
+ OTableFieldDescRef pEntry = _rInfo;
+ pEntry->SetVisible(bVis);
+
+ // Spalte einfuegen
+ InsertColumn( pEntry, _nColumnPostion );
+
+ if ( !m_bInUndoMode )
+ {
+ // UndoAction erzeugen
+ OTabFieldCreateUndoAct* pUndoAction = new OTabFieldCreateUndoAct( this );
+ pUndoAction->SetTabFieldDescr( pEntry );
+ pUndoAction->SetColumnPosition(_nColumnPostion);
+ getDesignView()->getController().addUndoActionAndInvalidate( pUndoAction );
+ }
+
+ return pEntry;
+}
+
+//------------------------------------------------------------------------------
+sal_uInt16 OSelectionBrowseBox::FieldsCount()
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OTableFields::iterator aIter = getFields().begin();
+ sal_uInt16 nCount = 0;
+
+ while (aIter != getFields().end())
+ {
+ if ((*aIter).is() && !(*aIter)->IsEmpty())
+ ++nCount;
+ ++aIter;
+ }
+
+ return nCount;
+}
+
+//------------------------------------------------------------------------------
+OTableFieldDescRef OSelectionBrowseBox::FindFirstFreeCol(sal_uInt16& _rColumnPosition )
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OTableFields::iterator aIter = getFields().begin();
+ OTableFields::iterator aEnd = getFields().end();
+
+ _rColumnPosition = BROWSER_INVALIDID;
+
+ while ( aIter != aEnd )
+ {
+ ++_rColumnPosition;
+ OTableFieldDescRef pEntry = (*aIter);
+ if ( pEntry.is() && pEntry->IsEmpty() )
+ return pEntry;
+ ++aIter;
+ }
+
+ return NULL;
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::CheckFreeColumns(sal_uInt16& _rColumnPosition)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ if (FindFirstFreeCol(_rColumnPosition) == NULL)
+ {
+ // es ist voll, also einen Packen Spalten anhaengen
+ AppendNewCol(DEFAULT_QUERY_COLS);
+ OSL_VERIFY(FindFirstFreeCol(_rColumnPosition).is());
+ }
+}
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::AddGroupBy( const OTableFieldDescRef& rInfo , sal_uInt32 /*_nCurrentPos*/)
+{
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
+ if(!xConnection.is())
+ return;
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OSL_ENSURE(!rInfo->IsEmpty(),"AddGroupBy:: OTableFieldDescRef sollte nicht Empty sein!");
+ OTableFieldDescRef pEntry;
+ const Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
+ const ::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
+ //sal_Bool bAppend = sal_False;
+
+ OTableFields& rFields = getFields();
+ OTableFields::iterator aIter = rFields.begin();
+ OTableFields::iterator aEnd = rFields.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ pEntry = *aIter;
+ OSL_ENSURE(pEntry.is(),"OTableFieldDescRef was null!");
+
+ const ::rtl::OUString aField = pEntry->GetField();
+ const ::rtl::OUString aAlias = pEntry->GetAlias();
+
+ if (bCase(aField,rInfo->GetField()) &&
+ bCase(aAlias,rInfo->GetAlias()) &&
+ pEntry->GetFunctionType() == rInfo->GetFunctionType() &&
+ pEntry->GetFunction() == rInfo->GetFunction())
+ {
+ if ( pEntry->isNumericOrAggreateFunction() && rInfo->IsGroupBy() )
+ {
+ pEntry->SetGroupBy(sal_False);
+ aIter = rFields.end();
+ break;
+ }
+ else
+ {
+ if ( !pEntry->IsGroupBy() && !pEntry->HasCriteria() ) // here we have a where condition which is no having clause
+ {
+ pEntry->SetGroupBy(rInfo->IsGroupBy());
+ if(!m_bGroupByUnRelated && pEntry->IsGroupBy())
+ pEntry->SetVisible(sal_True);
+ break;
+ }
+ }
+
+ }
+ }
+
+ if (aIter == rFields.end())
+ {
+ OTableFieldDescRef pTmp = InsertField(rInfo, BROWSER_INVALIDID, sal_False, sal_False );
+ if ( (pTmp->isNumericOrAggreateFunction() && rInfo->IsGroupBy()) ) // das GroupBy wird bereits von rInfo "ubernommen
+ pTmp->SetGroupBy(sal_False);
+ }
+}
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::DuplicateConditionLevel( const sal_uInt16 nLevel)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ const sal_uInt16 nNewLevel = nLevel +1;
+ OTableFields& rFields = getFields();
+ OTableFields::iterator aIter = rFields.begin();
+ OTableFields::iterator aEnd = rFields.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableFieldDescRef pEntry = *aIter;
+
+ ::rtl::OUString sValue = pEntry->GetCriteria(nLevel);
+ if ( sValue.getLength() )
+ {
+ pEntry->SetCriteria( nNewLevel, sValue);
+ if ( nNewLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1) )
+ {
+ RowInserted( GetRowCount()-1, 1, sal_True );
+ m_bVisibleRow.push_back(sal_True);
+ ++m_nVisibleCount;
+ }
+ m_bVisibleRow[BROW_CRIT1_ROW + nNewLevel] = sal_True;
+ }
+ }
+}
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::AddCondition( const OTableFieldDescRef& rInfo, const String& rValue, const sal_uInt16 nLevel,bool _bAddOrOnOneLine )
+{
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
+ if(!xConnection.is())
+ return;
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OSL_ENSURE(rInfo.is() && !rInfo->IsEmpty(),"AddCondition:: OTableFieldDescRef sollte nicht Empty sein!");
+
+ OTableFieldDescRef pLastEntry;
+ Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
+ ::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
+
+ OTableFields& rFields = getFields();
+ OTableFields::iterator aIter = rFields.begin();
+ OTableFields::iterator aEnd = rFields.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ OTableFieldDescRef pEntry = *aIter;
+ const ::rtl::OUString aField = pEntry->GetField();
+ const ::rtl::OUString aAlias = pEntry->GetAlias();
+
+ if (bCase(aField,rInfo->GetField()) &&
+ bCase(aAlias,rInfo->GetAlias()) &&
+ pEntry->GetFunctionType() == rInfo->GetFunctionType() &&
+ pEntry->GetFunction() == rInfo->GetFunction() &&
+ pEntry->IsGroupBy() == rInfo->IsGroupBy() )
+ {
+ if ( pEntry->isNumericOrAggreateFunction() && rInfo->IsGroupBy() )
+ pEntry->SetGroupBy(sal_False);
+ else
+ {
+ if(!m_bGroupByUnRelated && pEntry->IsGroupBy())
+ pEntry->SetVisible(sal_True);
+ }
+ if (!pEntry->GetCriteria(nLevel).getLength() )
+ {
+ pEntry->SetCriteria( nLevel, rValue);
+ if(nLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1))
+ {
+ RowInserted( GetRowCount()-1, 1, sal_True );
+ m_bVisibleRow.push_back(sal_True);
+ ++m_nVisibleCount;
+ }
+ m_bVisibleRow[BROW_CRIT1_ROW + nLevel] = sal_True;
+ break;
+ }
+ if ( _bAddOrOnOneLine )
+ {
+ pLastEntry = pEntry;
+ }
+ }
+ }
+ if ( pLastEntry.is() )
+ {
+ String sCriteria = rValue;
+ String sOldCriteria = pLastEntry->GetCriteria( nLevel );
+ if ( sOldCriteria.Len() )
+ {
+ sCriteria = String(RTL_CONSTASCII_USTRINGPARAM("( "));
+ sCriteria += sOldCriteria;
+ sCriteria += String(RTL_CONSTASCII_USTRINGPARAM(" OR "));
+ sCriteria += rValue;
+ sCriteria += String(RTL_CONSTASCII_USTRINGPARAM(" )"));
+ }
+ pLastEntry->SetCriteria( nLevel, sCriteria);
+ if(nLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1))
+ {
+ RowInserted( GetRowCount()-1, 1, sal_True );
+ m_bVisibleRow.push_back(sal_True);
+ ++m_nVisibleCount;
+ }
+ m_bVisibleRow[BROW_CRIT1_ROW + nLevel] = sal_True;
+ }
+
+ else if (aIter == getFields().end())
+ {
+ OTableFieldDescRef pTmp = InsertField(rInfo, BROWSER_INVALIDID, sal_False, sal_False );
+ if ( pTmp->isNumericOrAggreateFunction() && rInfo->IsGroupBy() ) // das GroupBy wird bereits von rInfo "ubernommen
+ pTmp->SetGroupBy(sal_False);
+ if ( pTmp.is() )
+ {
+ pTmp->SetCriteria( nLevel, rValue);
+ if(nLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1))
+ {
+ RowInserted( GetRowCount()-1, 1, sal_True );
+ m_bVisibleRow.push_back(sal_True);
+ ++m_nVisibleCount;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::AddOrder( const OTableFieldDescRef& rInfo, const EOrderDir eDir, sal_uInt32 _nCurrentPos)
+{
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
+ if(!xConnection.is())
+ return;
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OSL_ENSURE(!rInfo->IsEmpty(),"AddOrder:: OTableFieldDescRef sollte nicht Empty sein!");
+ OTableFieldDescRef pEntry;
+ Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
+ ::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
+
+ sal_Bool bAppend = sal_False;
+ OTableFields& rFields = getFields();
+ OTableFields::iterator aIter = rFields.begin();
+ OTableFields::iterator aEnd = rFields.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ pEntry = *aIter;
+ ::rtl::OUString aField = pEntry->GetField();
+ ::rtl::OUString aAlias = pEntry->GetAlias();
+
+ if (bCase(aField,rInfo->GetField()) &&
+ bCase(aAlias,rInfo->GetAlias()))
+ {
+ sal_uInt32 nPos = aIter - rFields.begin();
+ bAppend = _nCurrentPos > nPos;
+ if ( bAppend )
+ aIter = rFields.end();
+ else
+ {
+ if ( !m_bOrderByUnRelated )
+ pEntry->SetVisible(sal_True);
+ pEntry->SetOrderDir( eDir );
+ }
+ break;
+ }
+ }
+
+ if (aIter == rFields.end())
+ {
+ OTableFieldDescRef pTmp = InsertField(rInfo, BROWSER_INVALIDID, sal_False, sal_False );
+ if(pTmp.is())
+ {
+ if ( !m_bOrderByUnRelated && !bAppend )
+ pTmp->SetVisible(sal_True);
+ pTmp->SetOrderDir( eDir );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::ArrangeControls(sal_uInt16& nX, sal_uInt16 nY)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ EditBrowseBox::ArrangeControls(nX, nY);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::Save()
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ sal_Bool bRet = sal_True;
+ if (IsModified())
+ bRet = SaveModified();
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::CellModified()
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ long nRow = GetRealRow(GetCurRow());
+ switch (nRow)
+ {
+ case BROW_VIS_ROW:
+ {
+ OTableFieldDescRef pEntry = getEntry(GetColumnPos(GetCurColumnId()) - 1);
+
+ sal_uInt16 nIdx = m_pOrderCell->GetSelectEntryPos();
+ if(!m_bOrderByUnRelated && nIdx > 0 &&
+ nIdx != sal_uInt16(-1) &&
+ !pEntry->IsEmpty() &&
+ pEntry->GetOrderDir() != ORDER_NONE)
+ {
+ m_pVisibleCell->GetBox().Check();
+ pEntry->SetVisible(sal_True);
+ }
+ else
+ pEntry->SetVisible(m_pVisibleCell->GetBox().IsChecked());
+ }
+ break;
+ }
+ static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::Fill()
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OSL_ENSURE(ColCount() >= 1, "OSelectionBrowseBox::Fill : please call only after inserting the handle column !");
+
+ sal_uInt16 nColCount = ColCount() - 1;
+ if (nColCount < DEFAULT_QUERY_COLS)
+ AppendNewCol(DEFAULT_QUERY_COLS - nColCount);
+}
+
+//------------------------------------------------------------------------------
+Size OSelectionBrowseBox::CalcOptimalSize( const Size& _rAvailable )
+{
+ Size aReturn( _rAvailable.Width(), GetTitleHeight() );
+
+ aReturn.Height() += ( m_nVisibleCount ? m_nVisibleCount : 15 ) * GetDataRowHeight();
+ aReturn.Height() += 40; // just some space
+
+ return aReturn;
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::Command(const CommandEvent& rEvt)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ switch (rEvt.GetCommand())
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ Point aMenuPos( rEvt.GetMousePosPixel() );
+
+ if (!rEvt.IsMouseEvent())
+ {
+ if ( 1 == GetSelectColumnCount() )
+ {
+ sal_uInt16 nSelId = GetColumnId(
+ sal::static_int_cast< sal_uInt16 >(
+ FirstSelectedColumn() ) );
+ ::Rectangle aColRect( GetFieldRectPixel( 0, nSelId, sal_False ) );
+
+ aMenuPos = aColRect.TopCenter();
+ }
+ else
+ {
+ EditBrowseBox::Command(rEvt);
+ return;
+ }
+ }
+
+ sal_uInt16 nColId = GetColumnId(GetColumnAtXPosPixel( aMenuPos.X() ));
+ long nRow = GetRowAtYPosPixel( aMenuPos.Y() );
+
+ if (nRow < 0 && nColId > HANDLE_ID )
+ {
+ if ( !IsColumnSelected( nColId ) )
+ {
+ adjustSelectionMode( sal_True /* clicked onto a header */ , sal_False /* not onto the handle col */ );
+ SelectColumnId( nColId );
+ }
+
+ if (!static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
+ {
+ PopupMenu aContextMenu( ModuleRes( RID_QUERYCOLPOPUPMENU ) );
+ switch (aContextMenu.Execute(this, aMenuPos))
+ {
+ case SID_DELETE:
+ RemoveField(nColId);
+ break;
+
+ case ID_BROWSER_COLWIDTH:
+ adjustBrowseBoxColumnWidth( this, nColId );
+ break;
+ }
+ }
+ }
+ else if(nRow >= 0 && nColId <= HANDLE_ID)
+ {
+ if (!static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
+ {
+ PopupMenu aContextMenu(ModuleRes(RID_QUERYFUNCTION_POPUPMENU));
+ aContextMenu.CheckItem( ID_QUERY_FUNCTION, m_bVisibleRow[BROW_FUNCTION_ROW]);
+ aContextMenu.CheckItem( ID_QUERY_TABLENAME, m_bVisibleRow[BROW_TABLE_ROW]);
+ aContextMenu.CheckItem( ID_QUERY_ALIASNAME, m_bVisibleRow[BROW_COLUMNALIAS_ROW]);
+ aContextMenu.CheckItem( ID_QUERY_DISTINCT, static_cast<OQueryController&>(getDesignView()->getController()).isDistinct());
+
+ switch (aContextMenu.Execute(this, aMenuPos))
+ {
+ case ID_QUERY_FUNCTION:
+ SetRowVisible(BROW_FUNCTION_ROW, !IsRowVisible(BROW_FUNCTION_ROW));
+ static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_FUNCTIONS );
+ break;
+ case ID_QUERY_TABLENAME:
+ SetRowVisible(BROW_TABLE_ROW, !IsRowVisible(BROW_TABLE_ROW));
+ static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_TABLES );
+ break;
+ case ID_QUERY_ALIASNAME:
+ SetRowVisible(BROW_COLUMNALIAS_ROW, !IsRowVisible(BROW_COLUMNALIAS_ROW));
+ static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_ALIASES );
+ break;
+ case ID_QUERY_DISTINCT:
+ static_cast<OQueryController&>(getDesignView()->getController()).setDistinct(!static_cast<OQueryController&>(getDesignView()->getController()).isDistinct());
+ static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
+ static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_DISTINCT_VALUES );
+ break;
+ }
+
+ static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
+ }
+ }
+ else
+ {
+ EditBrowseBox::Command(rEvt);
+ return;
+ }
+ }
+ default:
+ EditBrowseBox::Command(rEvt);
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::IsRowVisible(sal_uInt16 _nWhich) const
+{
+ OSL_ENSURE(_nWhich<(m_bVisibleRow.size()), "OSelectionBrowseBox::IsRowVisible : invalid parameter !");
+ return m_bVisibleRow[_nWhich];
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::SetRowVisible(sal_uInt16 _nWhich, sal_Bool _bVis)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ OSL_ENSURE(_nWhich<m_bVisibleRow.size(), "OSelectionBrowseBox::SetRowVisible : invalid parameter !");
+
+ sal_Bool bWasEditing = IsEditing();
+ if (bWasEditing)
+ DeactivateCell();
+
+ // do this before removing or inserting rows, as this triggers ActivateCell-calls, which rely on m_bVisibleRow
+ m_bVisibleRow[_nWhich] = !m_bVisibleRow[_nWhich];
+
+ long nId = GetBrowseRow(_nWhich);
+ if (_bVis)
+ {
+ RowInserted(nId,1);
+ ++m_nVisibleCount;
+ }
+ else
+ {
+ RowRemoved(nId,1);
+ --m_nVisibleCount;
+ }
+
+ if (bWasEditing)
+ ActivateCell();
+}
+
+//------------------------------------------------------------------------------
+long OSelectionBrowseBox::GetBrowseRow(long nRowId) const
+{
+ sal_uInt16 nCount(0);
+ for(sal_uInt16 i = 0 ; i < nRowId ; ++i)
+ {
+ if ( m_bVisibleRow[i] )
+ ++nCount;
+ }
+ return nCount;
+}
+//------------------------------------------------------------------------------
+long OSelectionBrowseBox::GetRealRow(long nRowId) const
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ long nErg=0,i;
+ const long nCount = m_bVisibleRow.size();
+ for(i=0;i < nCount; ++i)
+ {
+ if(m_bVisibleRow[i])
+ {
+ if(nErg++ == nRowId)
+ break;
+ }
+ }
+ OSL_ENSURE(nErg <= long(m_bVisibleRow.size()),"nErg kann nicht groesser als BROW_ROW_CNT sein!");
+ return i;
+}
+static long nVisibleRowMask[] =
+ {
+ 0x0001,
+ 0x0002,
+ 0x0004,
+ 0x0008,
+ 0x0010,
+ 0x0020,
+ 0x0040,
+ 0x0080,
+ 0x0100,
+ 0x0200,
+ 0x0400,
+ 0x0800
+ };
+//------------------------------------------------------------------------------
+sal_Int32 OSelectionBrowseBox::GetNoneVisibleRows() const
+{
+ sal_Int32 nErg(0);
+ // only the first 11 row are interesting
+ sal_Int32 nSize = SAL_N_ELEMENTS(nVisibleRowMask);
+ for(sal_Int32 i=0;i<nSize;i++)
+ {
+ if(!m_bVisibleRow[i])
+ nErg |= nVisibleRowMask[i];
+ }
+ return nErg;
+}
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::SetNoneVisbleRow(long nRows)
+{
+ // only the first 11 row are interesting
+ sal_Int32 nSize = SAL_N_ELEMENTS(nVisibleRowMask);
+ for(sal_Int32 i=0;i< nSize;i++)
+ m_bVisibleRow[i] = !(nRows & nVisibleRowMask[i]);
+}
+//------------------------------------------------------------------------------
+String OSelectionBrowseBox::GetCellText(long nRow, sal_uInt16 nColId) const
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+
+ sal_uInt16 nPos = GetColumnPos(nColId);
+
+ OTableFieldDescRef pEntry = getFields()[nPos-1];
+ OSL_ENSURE(pEntry != NULL, "OSelectionBrowseBox::GetCellText : invalid column id, prepare for GPF ... ");
+ if ( pEntry->IsEmpty() )
+ return String();
+
+ String aText;
+ switch (nRow)
+ {
+ case BROW_TABLE_ROW:
+ aText = pEntry->GetAlias();
+ break;
+ case BROW_FIELD_ROW:
+ {
+ String aField = pEntry->GetField();
+ if (aField.GetChar(0) == '*') // * durch alias.* ersetzen
+ {
+ aField = pEntry->GetAlias();
+ if(aField.Len())
+ aField += '.';
+ aField += '*';
+ }
+ aText = aField;
+ } break;
+ case BROW_ORDER_ROW:
+ if (pEntry->GetOrderDir() != ORDER_NONE)
+ aText = String(ModuleRes(STR_QUERY_SORTTEXT) ).GetToken(sal::static_int_cast< sal_uInt16 >(pEntry->GetOrderDir()));
+ break;
+ case BROW_VIS_ROW:
+ break;
+ case BROW_COLUMNALIAS_ROW:
+ aText = pEntry->GetFieldAlias();
+ break;
+ case BROW_FUNCTION_ROW:
+ // we always show the group function at first
+ if ( pEntry->IsGroupBy() )
+ aText = m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount()-1);
+ else if ( pEntry->isNumericOrAggreateFunction() )
+ aText = pEntry->GetFunction();
+ break;
+ default:
+ aText = pEntry->GetCriteria(sal_uInt16(nRow - BROW_CRIT1_ROW));
+ }
+ return aText;
+}
+//------------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::GetFunctionName(sal_uInt32 _nFunctionTokenId,String& rFkt)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ sal_Bool bErg=sal_True;
+ String aText;
+ switch(_nFunctionTokenId)
+ {
+ case SQL_TOKEN_COUNT:
+ rFkt = (m_pFunctionCell->GetEntryCount() < 3) ? m_pFunctionCell->GetEntry(1) : m_pFunctionCell->GetEntry(2);
+ break;
+ case SQL_TOKEN_AVG:
+ rFkt = m_pFunctionCell->GetEntry(1);
+ break;
+ case SQL_TOKEN_MAX:
+ rFkt = m_pFunctionCell->GetEntry(3);
+ break;
+ case SQL_TOKEN_MIN:
+ rFkt = m_pFunctionCell->GetEntry(4);
+ break;
+ case SQL_TOKEN_SUM:
+ rFkt = m_pFunctionCell->GetEntry(5);
+ break;
+ case SQL_TOKEN_EVERY:
+ rFkt = m_pFunctionCell->GetEntry(6);
+ break;
+ case SQL_TOKEN_ANY:
+ rFkt = m_pFunctionCell->GetEntry(7);
+ break;
+ case SQL_TOKEN_SOME:
+ rFkt = m_pFunctionCell->GetEntry(8);
+ break;
+ case SQL_TOKEN_STDDEV_POP:
+ rFkt = m_pFunctionCell->GetEntry(9);
+ break;
+ case SQL_TOKEN_STDDEV_SAMP:
+ rFkt = m_pFunctionCell->GetEntry(10);
+ break;
+ case SQL_TOKEN_VAR_SAMP:
+ rFkt = m_pFunctionCell->GetEntry(11);
+ break;
+ case SQL_TOKEN_VAR_POP:
+ rFkt = m_pFunctionCell->GetEntry(12);
+ break;
+ case SQL_TOKEN_COLLECT:
+ rFkt = m_pFunctionCell->GetEntry(13);
+ break;
+ case SQL_TOKEN_FUSION:
+ rFkt = m_pFunctionCell->GetEntry(14);
+ break;
+ case SQL_TOKEN_INTERSECTION:
+ rFkt = m_pFunctionCell->GetEntry(15);
+ break;
+ default:
+ {
+ xub_StrLen nCount = m_aFunctionStrings.GetTokenCount();
+ xub_StrLen i;
+ for ( i = 0; i < nCount-1; i++) // Gruppierung wird nicht mit gez"ahlt
+ {
+ if(rFkt.EqualsIgnoreCaseAscii(m_aFunctionStrings.GetToken(i)))
+ {
+ rFkt = m_aFunctionStrings.GetToken(i);
+ break;
+ }
+ }
+ if(i == nCount-1)
+ bErg = sal_False;
+ }
+ }
+
+ return bErg;
+}
+//------------------------------------------------------------------------------
+String OSelectionBrowseBox::GetCellContents(sal_Int32 nCellIndex, sal_uInt16 nColId)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ if ( GetCurColumnId() == nColId && !m_bInUndoMode )
+ SaveModified();
+
+ sal_uInt16 nPos = GetColumnPos(nColId);
+ OTableFieldDescRef pEntry = getFields()[nPos - 1];
+ OSL_ENSURE(pEntry != NULL, "OSelectionBrowseBox::GetCellContents : invalid column id, prepare for GPF ... ");
+
+ switch (nCellIndex)
+ {
+ case BROW_VIS_ROW :
+ return pEntry->IsVisible() ? g_strOne : g_strZero;
+ case BROW_ORDER_ROW:
+ {
+ sal_uInt16 nIdx = m_pOrderCell->GetSelectEntryPos();
+ if (nIdx == sal_uInt16(-1))
+ nIdx = 0;
+ return String(nIdx);
+ }
+ default:
+ return GetCellText(nCellIndex, nColId);
+ }
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::SetCellContents(sal_Int32 nRow, sal_uInt16 nColId, const String& strNewText)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ sal_Bool bWasEditing = IsEditing() && (GetCurColumnId() == nColId) && IsRowVisible(static_cast<sal_uInt16>(nRow)) && (GetCurRow() == static_cast<sal_uInt16>(GetBrowseRow(nRow)));
+ if (bWasEditing)
+ DeactivateCell();
+
+ sal_uInt16 nPos = GetColumnPos(nColId);
+ OTableFieldDescRef pEntry = getEntry(nPos - 1);
+ OSL_ENSURE(pEntry != NULL, "OSelectionBrowseBox::SetCellContents : invalid column id, prepare for GPF ... ");
+
+
+ switch (nRow)
+ {
+ case BROW_VIS_ROW:
+ pEntry->SetVisible(strNewText.Equals(g_strOne));
+ break;
+ case BROW_FIELD_ROW:
+ pEntry->SetField(strNewText);
+ break;
+ case BROW_TABLE_ROW:
+ pEntry->SetAlias(strNewText);
+ break;
+ case BROW_ORDER_ROW:
+ {
+ sal_uInt16 nIdx = (sal_uInt16)strNewText.ToInt32();
+ pEntry->SetOrderDir(EOrderDir(nIdx));
+ } break;
+ case BROW_COLUMNALIAS_ROW:
+ pEntry->SetFieldAlias(strNewText);
+ break;
+ case BROW_FUNCTION_ROW:
+ {
+ String sOldFunctionName = pEntry->GetFunction();
+ String sGroupFunctionName = m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount()-1);
+ pEntry->SetFunction(strNewText);
+ // first reset this two member
+ sal_Int32 nFunctionType = pEntry->GetFunctionType();
+ nFunctionType &= ~FKT_AGGREGATE;
+ pEntry->SetFunctionType(nFunctionType);
+ if ( pEntry->IsGroupBy() && !sGroupFunctionName.EqualsIgnoreCaseAscii(strNewText) )
+ pEntry->SetGroupBy(sal_False);
+
+
+ if ( sGroupFunctionName.EqualsIgnoreCaseAscii(strNewText) )
+ pEntry->SetGroupBy(sal_True);
+ else if ( strNewText.Len() )
+ {
+ nFunctionType |= FKT_AGGREGATE;
+ pEntry->SetFunctionType(nFunctionType);
+ }
+ } break;
+ default:
+ pEntry->SetCriteria(sal_uInt16(nRow - BROW_CRIT1_ROW), strNewText);
+ }
+
+ long nCellIndex = GetRealRow(nRow);
+ if(IsRowVisible(static_cast<sal_uInt16>(nRow)))
+ RowModified(nCellIndex, nColId);
+
+ // die entsprechende Feld-Beschreibung ist jetzt leer -> Visible auf sal_False (damit das konsistent mit normalen leeren Spalten ist)
+ if (pEntry->IsEmpty())
+ pEntry->SetVisible(sal_False);
+
+ if (bWasEditing)
+ ActivateCell(nCellIndex, nColId);
+
+ static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
+}
+//------------------------------------------------------------------------------
+sal_uInt32 OSelectionBrowseBox::GetTotalCellWidth(long nRow, sal_uInt16 nColId) const
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+
+ long nRowId = GetRealRow(nRow);
+ if (nRowId == BROW_VIS_ROW)
+ return CHECKBOX_SIZE;
+ else
+ return GetDataWindow().GetTextWidth(GetCellText(nRowId, nColId));
+}
+
+//------------------------------------------------------------------------------
+void OSelectionBrowseBox::ColumnResized(sal_uInt16 nColId)
+{
+ if (static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
+ return;
+ // The resizing of columns can't be suppressed (BrowseBox doesn't support that) so we have to do this
+ // fake. It's not _that_ bad : the user may change column widths while in read-only mode to see all details
+ // but the changes aren't permanent ...
+
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ sal_uInt16 nPos = GetColumnPos(nColId);
+ OSL_ENSURE(nPos <= getFields().size(),"ColumnResized:: nColId sollte nicht groesser als List::count sein!");
+ OTableFieldDescRef pEntry = getEntry(nPos-1);
+ OSL_ENSURE(pEntry.is(), "OSelectionBrowseBox::ColumnResized : keine FieldDescription !");
+ static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
+ EditBrowseBox::ColumnResized(nColId);
+
+ if ( pEntry.is())
+ {
+ if ( !m_bInUndoMode )
+ {
+ // create the undo action
+ OTabFieldSizedUndoAct* pUndo = new OTabFieldSizedUndoAct(this);
+ pUndo->SetColumnPosition( nPos );
+ pUndo->SetOriginalWidth(pEntry->GetColWidth());
+ getDesignView()->getController().addUndoActionAndInvalidate(pUndo);
+ }
+ pEntry->SetColWidth(sal_uInt16(GetColumnWidth(nColId)));
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_uInt32 OSelectionBrowseBox::GetTotalCellWidth(long nRowId, sal_uInt16 nColId)
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ sal_uInt16 nPos = GetColumnPos(nColId);
+ OSL_ENSURE((nPos == 0) || (nPos <= getFields().size()), "OSelectionBrowseBox::GetTotalCellWidth : invalid parameter nColId");
+
+ OTableFieldDescRef pEntry = getFields()[nPos-1];
+ OSL_ENSURE(pEntry.is(), "OSelectionBrowseBox::GetTotalCellWidth : invalid FieldDescription !");
+
+ long nRow = GetRealRow(nRowId);
+ String strText(GetCellText(nRow, nColId));
+ return GetDataWindow().LogicToPixel(Size(GetDataWindow().GetTextWidth(strText),0)).Width();
+}
+
+//------------------------------------------------------------------------------
+sal_uInt16 OSelectionBrowseBox::GetDefaultColumnWidth(const String& /*rName*/) const
+{
+ DBG_CHKTHIS(OSelectionBrowseBox,NULL);
+ // die Baissklasse macht das von dem Text abhaengig, ich habe aber keine Spaltenueberschriften, daher haette ich
+ // hier gern einen anderen Default-Wert
+ return static_cast<sal_uInt16>(DEFAULT_SIZE);
+}
+//------------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::isCutAllowed()
+{
+ sal_Bool bCutAllowed = sal_False;
+ long nRow = GetRealRow(GetCurRow());
+ switch (nRow)
+ {
+ case BROW_VIS_ROW:
+ case BROW_ORDER_ROW:
+ case BROW_TABLE_ROW:
+ case BROW_FUNCTION_ROW:
+ break;
+ case BROW_FIELD_ROW:
+ bCutAllowed = m_pFieldCell->GetSelected().Len() != 0;
+ break;
+ default:
+ bCutAllowed = m_pTextCell->GetSelected().Len() != 0;
+ break;
+ }
+ return bCutAllowed;
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::cut()
+{
+ String sOldValue = GetCellContents(GetRealRow(GetCurRow()),GetCurColumnId());
+ long nRow = GetRealRow(GetCurRow());
+ switch (nRow)
+ {
+ case BROW_FIELD_ROW:
+ m_pFieldCell->Cut();
+ m_pFieldCell->SetModifyFlag();
+ break;
+ default:
+ m_pTextCell->Cut();
+ m_pTextCell->SetModifyFlag();
+ }
+ SaveModified();
+ RowModified(GetBrowseRow(nRow), GetCurColumnId());
+
+ invalidateUndoRedo();
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::paste()
+{
+ long nRow = GetRealRow(GetCurRow());
+ switch (nRow)
+ {
+ case BROW_FIELD_ROW:
+ m_pFieldCell->Paste();
+ m_pFieldCell->SetModifyFlag();
+ break;
+ default:
+ m_pTextCell->Paste();
+ m_pTextCell->SetModifyFlag();
+ }
+ RowModified(GetBrowseRow(nRow), GetCurColumnId());
+ invalidateUndoRedo();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::isPasteAllowed()
+{
+ sal_Bool bPasteAllowed = sal_True;
+ long nRow = GetRealRow(GetCurRow());
+ switch (nRow)
+ {
+ case BROW_VIS_ROW:
+ case BROW_ORDER_ROW:
+ case BROW_TABLE_ROW:
+ case BROW_FUNCTION_ROW:
+ bPasteAllowed = sal_False;
+ break;
+ }
+ return bPasteAllowed;
+}
+// -----------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::isCopyAllowed()
+{
+ return isCutAllowed();
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::copy()
+{
+ long nRow = GetRealRow(GetCurRow());
+ switch (nRow)
+ {
+ case BROW_FIELD_ROW:
+ m_pFieldCell->Copy();
+ break;
+ default:
+ m_pTextCell->Copy();
+ }
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::appendUndoAction(const String& _rOldValue,const String& _rNewValue,sal_Int32 _nRow,sal_Bool& _bListAction)
+{
+ if ( !m_bInUndoMode && !_rNewValue.Equals(_rOldValue) )
+ {
+ if ( !_bListAction )
+ {
+ _bListAction = sal_True;
+ static_cast<OQueryController&>(getDesignView()->getController()).GetUndoManager().EnterListAction(String(),String());
+ }
+ appendUndoAction(_rOldValue,_rNewValue,_nRow);
+ }
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::appendUndoAction(const String& _rOldValue,const String& _rNewValue,sal_Int32 _nRow)
+{
+ if ( !m_bInUndoMode && !_rNewValue.Equals(_rOldValue) )
+ {
+ OTabFieldCellModifiedUndoAct* pUndoAct = new OTabFieldCellModifiedUndoAct(this);
+ pUndoAct->SetCellIndex(_nRow);
+ OSL_ENSURE(GetColumnPos(GetCurColumnId()) != BROWSER_INVALIDID,"Current position isn't valid!");
+ pUndoAct->SetColumnPosition( GetColumnPos(GetCurColumnId()) );
+ pUndoAct->SetCellContents(_rOldValue);
+ getDesignView()->getController().addUndoActionAndInvalidate(pUndoAct);
+ }
+}
+// -----------------------------------------------------------------------------
+IMPL_LINK(OSelectionBrowseBox, OnInvalidateTimer, void*, EMPTYARG)
+{
+ static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature(SID_CUT);
+ static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature(SID_COPY);
+ static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature(SID_PASTE);
+ if(!m_bStopTimer)
+ m_timerInvalidate.Start();
+ return 0L;
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::stopTimer()
+{
+ m_bStopTimer = sal_True;
+ if (m_timerInvalidate.IsActive())
+ m_timerInvalidate.Stop();
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::startTimer()
+{
+ m_bStopTimer = sal_False;
+ if (!m_timerInvalidate.IsActive())
+ m_timerInvalidate.Start();
+}
+// -----------------------------------------------------------------------------
+OTableFields& OSelectionBrowseBox::getFields() const
+{
+ OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
+ return rController.getTableFieldDesc();
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::enableControl(const OTableFieldDescRef& _rEntry,Window* _pControl)
+{
+ sal_Bool bEnable = !_rEntry->isCondition();
+ _pControl->Enable(bEnable);
+ _pControl->EnableInput(bEnable);
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::setTextCellContext(const OTableFieldDescRef& _rEntry,const String& _sText,const rtl::OString& _sHelpId)
+{
+ m_pTextCell->SetText(_sText);
+ m_pTextCell->ClearModifyFlag();
+ if (!m_pTextCell->HasFocus())
+ m_pTextCell->GrabFocus();
+
+ enableControl(_rEntry,m_pTextCell);
+
+ if (m_pTextCell->GetHelpId() != _sHelpId)
+ // da TextCell in verschiedenen Kontexten verwendet wird, muss ich den gecachten HelpText loeschen
+ m_pTextCell->SetHelpText(String());
+ m_pTextCell->SetHelpId(_sHelpId);
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::invalidateUndoRedo()
+{
+ OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
+ rController.InvalidateFeature( ID_BROWSER_UNDO );
+ rController.InvalidateFeature( ID_BROWSER_REDO );
+ rController.InvalidateFeature( ID_BROWSER_QUERY_EXECUTE );
+}
+// -----------------------------------------------------------------------------
+OTableFieldDescRef OSelectionBrowseBox::getEntry(OTableFields::size_type _nPos)
+{
+ // we have to check if we need a new entry at this position
+ OTableFields& aFields = getFields();
+ OSL_ENSURE(aFields.size() > _nPos,"ColID is to great!");
+
+ OTableFieldDescRef pEntry = aFields[_nPos];
+ OSL_ENSURE(pEntry.is(),"Invalid entry!");
+ if ( !pEntry.is() )
+ {
+ pEntry = new OTableFieldDesc();
+ pEntry->SetColumnId(
+ GetColumnId(sal::static_int_cast< sal_uInt16 >(_nPos+1)));
+ aFields[_nPos] = pEntry;
+ }
+ return pEntry;
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::GetFocus()
+{
+ if(!IsEditing() && !m_bWasEditing)
+ ActivateCell();
+ EditBrowseBox::GetFocus();
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::DeactivateCell(sal_Bool _bUpdate)
+{
+ m_bWasEditing = sal_True;
+ EditBrowseBox::DeactivateCell(_bUpdate);
+ m_bWasEditing = sal_False;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OSelectionBrowseBox::GetRowDescription( sal_Int32 _nRow ) const
+{
+ String aLabel(ModuleRes(STR_QUERY_HANDLETEXT));
+
+ // ab BROW_CRIT2_ROW werden alle Zeilen mit "oder" angegeben
+ xub_StrLen nToken = (xub_StrLen) (_nRow >= GetBrowseRow(BROW_CRIT2_ROW))
+ ?
+ xub_StrLen(BROW_CRIT2_ROW) : xub_StrLen(GetRealRow(_nRow));
+ return ::rtl::OUString(aLabel.GetToken(nToken));
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OSelectionBrowseBox::GetAccessibleObjectName( ::svt::AccessibleBrowseBoxObjType _eObjType,sal_Int32 _nPosition) const
+{
+ ::rtl::OUString sRetText;
+ switch( _eObjType )
+ {
+ case ::svt::BBTYPE_ROWHEADERCELL:
+ sRetText = GetRowDescription(_nPosition);
+ break;
+ default:
+ sRetText = EditBrowseBox::GetAccessibleObjectDescription(_eObjType,_nPosition);
+ }
+ return sRetText;
+}
+// -----------------------------------------------------------------------------
+sal_Bool OSelectionBrowseBox::fillEntryTable(OTableFieldDescRef& _pEntry,const ::rtl::OUString& _sTableName)
+{
+ sal_Bool bRet = sal_False;
+ OJoinTableView::OTableWindowMap* pTabWinList = getDesignView()->getTableView()->GetTabWinMap();
+ if (pTabWinList)
+ {
+ OJoinTableView::OTableWindowMapIterator aIter = pTabWinList->find(_sTableName);
+ if(aIter != pTabWinList->end())
+ {
+ OQueryTableWindow* pEntryTab = static_cast<OQueryTableWindow*>(aIter->second);
+ if (pEntryTab)
+ {
+ _pEntry->SetTable(pEntryTab->GetTableName());
+ _pEntry->SetTabWindow(pEntryTab);
+ bRet = sal_True;
+ }
+ }
+ }
+ return bRet;
+}
+// -----------------------------------------------------------------------------
+void OSelectionBrowseBox::setFunctionCell(OTableFieldDescRef& _pEntry)
+{
+ Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
+ if ( xConnection.is() )
+ {
+ // Diese Funktionen stehen nur unter CORE zur Verf�gung
+ if ( lcl_SupportsCoreSQLGrammar(xConnection) )
+ {
+ // if we have an asterix, no other function than count is allowed
+ m_pFunctionCell->Clear();
+ m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(0));
+ if ( isFieldNameAsterix(_pEntry->GetField()) )
+ m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(2)); // 2 -> COUNT
+ else
+ {
+ xub_StrLen nCount = m_aFunctionStrings.GetTokenCount();
+ if ( _pEntry->isNumeric() )
+ --nCount;
+ for (xub_StrLen nIdx = 1; nIdx < nCount; nIdx++)
+ m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(nIdx));
+ }
+
+ if ( _pEntry->IsGroupBy() )
+ {
+ OSL_ENSURE(!_pEntry->isNumeric(),"Not allowed to combine group by and numeric values!");
+ m_pFunctionCell->SelectEntry(m_pFunctionCell->GetEntry(m_pFunctionCell->GetEntryCount() - 1));
+ }
+ else if ( m_pFunctionCell->GetEntryPos(String(_pEntry->GetFunction())) != COMBOBOX_ENTRY_NOTFOUND )
+ m_pFunctionCell->SelectEntry(String(_pEntry->GetFunction()));
+ else
+ m_pFunctionCell->SelectEntryPos(0);
+
+ enableControl(_pEntry,m_pFunctionCell);
+ }
+ else
+ {
+ // nur COUNT(*) erlaubt
+ sal_Bool bCountRemoved = !isFieldNameAsterix(_pEntry->GetField());
+ if ( bCountRemoved )
+ m_pFunctionCell->RemoveEntry(1);
+
+ if ( !bCountRemoved && m_pFunctionCell->GetEntryCount() < 2)
+ m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(2)); // 2 -> COUNT
+
+ if(m_pFunctionCell->GetEntryPos(String(_pEntry->GetFunction())) != COMBOBOX_ENTRY_NOTFOUND)
+ m_pFunctionCell->SelectEntry(_pEntry->GetFunction());
+ else
+ m_pFunctionCell->SelectEntryPos(0);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+Reference< XAccessible > OSelectionBrowseBox::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
+{
+ OTableFieldDescRef pEntry = NULL;
+ if(getFields().size() > sal_uInt16(_nColumnPos - 1))
+ pEntry = getFields()[_nColumnPos - 1];
+
+ if ( _nRow == BROW_VIS_ROW && pEntry.is() )
+ return EditBrowseBox::CreateAccessibleCheckBoxCell( _nRow, _nColumnPos,pEntry->IsVisible() ? STATE_CHECK : STATE_NOCHECK );
+
+ return EditBrowseBox::CreateAccessibleCell( _nRow, _nColumnPos );
+}
+// -----------------------------------------------------------------------------
+bool OSelectionBrowseBox::HasFieldByAliasName(const ::rtl::OUString& rFieldName, OTableFieldDescRef& rInfo) const
+{
+ OTableFields& aFields = getFields();
+ OTableFields::iterator aIter = aFields.begin();
+ OTableFields::iterator aEnd = aFields.end();
+
+ for(;aIter != aEnd;++aIter)
+ {
+ if ( (*aIter)->GetFieldAlias() == rFieldName )
+ {
+ *rInfo = *(*aIter);
+ break;
+ }
+ }
+ return aIter != aEnd;
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/SelectionBrowseBox.hxx b/dbaccess/source/ui/querydesign/SelectionBrowseBox.hxx
new file mode 100644
index 000000000000..fc361d5fc16f
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/SelectionBrowseBox.hxx
@@ -0,0 +1,347 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERYDESIGN_OSELECTIONBROWSEBOX_HXX
+#define DBAUI_QUERYDESIGN_OSELECTIONBROWSEBOX_HXX
+
+#include <svtools/editbrowsebox.hxx>
+#include "TableFieldDescription.hxx"
+#include "JoinExchange.hxx"
+#include "QEnumTypes.hxx"
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <tools/string.hxx>
+#include <svtools/transfer.hxx>
+
+namespace connectivity
+{
+ class OSQLParseNode;
+}
+
+namespace dbaui
+{
+ //==================================================================
+#define SIZ_NONE 0
+#define SIZ_TOP 1
+#define SIZ_BOTTOM 2
+#define SIZ_LEFT 4
+#define SIZ_RIGHT 8
+
+#define BROW_FIELD_ROW 0
+#define BROW_COLUMNALIAS_ROW 1
+#define BROW_TABLE_ROW 2
+#define BROW_ORDER_ROW 3
+#define BROW_VIS_ROW 4
+#define BROW_FUNCTION_ROW 5
+#define BROW_CRIT1_ROW 6
+#define BROW_CRIT2_ROW 7
+#define BROW_CRIT3_ROW 8
+#define BROW_CRIT4_ROW 9
+#define BROW_CRIT5_ROW 10
+#define BROW_CRIT6_ROW 11
+#define BROW_ROW_CNT 12
+
+ //==================================================================
+ class OQueryDesignView;
+ class OSelectionBrowseBox : public ::svt::EditBrowseBox
+ {
+ friend class OQueryDesignView;
+ ::std::vector<bool> m_bVisibleRow; // an Pos steht die RowId
+ Timer m_timerInvalidate;
+
+ long m_nSeekRow;
+ BrowserMode m_nMode; // Merken des BrowseModes
+ Edit* m_pTextCell;
+ ::svt::CheckBoxControl* m_pVisibleCell;
+ ::svt::ComboBoxControl* m_pFieldCell;
+ ::svt::ListBoxControl* m_pFunctionCell;
+ ::svt::ListBoxControl* m_pTableCell;
+ ::svt::ListBoxControl* m_pOrderCell;
+
+ OTableFieldDescRef m_pEmptyEntry; // default entry in the list may reference more than once
+
+ sal_Int32 m_nMaxColumns; // maximale Anzahl der Spalten in einem Select-Statement
+
+ String m_aFunctionStrings;
+ sal_uInt16 m_nVisibleCount; // Anzahl der max sichtbaren Zeilen
+ sal_Bool m_bOrderByUnRelated;
+ sal_Bool m_bGroupByUnRelated;
+ sal_Bool m_bStopTimer;
+ sal_Bool m_bWasEditing;
+ sal_Bool m_bDisableErrorBox;
+ sal_Bool m_bInUndoMode;
+
+ DECL_LINK(OnInvalidateTimer, void*);
+ public: OSelectionBrowseBox( Window* pParent );
+ ~OSelectionBrowseBox();
+
+ void initialize();
+ OTableFieldDescRef InsertField( const OJoinExchangeData& jxdSource, sal_uInt16 _nColumnPostion = BROWSER_INVALIDID, sal_Bool bVis=sal_True, sal_Bool bActivate=sal_True );
+ OTableFieldDescRef InsertField( const OTableFieldDescRef& rInfo, sal_uInt16 _nColumnPostion = BROWSER_INVALIDID, sal_Bool bVis=sal_True, sal_Bool bActivate=sal_True );
+ void InsertColumn( OTableFieldDescRef pEntry, sal_uInt16& _nColumnPostion );
+ void RemoveColumn( sal_uInt16 _nColumnId );
+ void DeleteFields( const String& rAliasName );
+
+ bool HasFieldByAliasName(const ::rtl::OUString& rFieldName, OTableFieldDescRef& rInfo) const;
+ // AddGroupBy:: F"ugt ein Feld mit Funktion == Grupierung. Falls das Feld schon vorhanden ist und ein Aggregate Funktion
+ // benutzt, wird das Flag nicht gesetzt
+ void AddGroupBy( const OTableFieldDescRef& rInfo,sal_uInt32 _nCurrentPos);
+ void AddCondition( const OTableFieldDescRef& rInfo,
+ const String& rValue,
+ const sal_uInt16 nLevel,
+ bool _bAddOrOnOneLine );
+ void DuplicateConditionLevel( const sal_uInt16 nLevel);
+ void AddOrder(const OTableFieldDescRef& rInfo, const EOrderDir eDir, sal_uInt32 _nCurrentPos);
+ void ClearAll();
+ OTableFieldDescRef AppendNewCol( sal_uInt16 nCnt=1 );
+ sal_Bool Save();
+ OQueryDesignView* getDesignView();
+ OQueryDesignView* getDesignView() const;
+ sal_uInt16 FieldsCount();
+
+ void SetColWidth(sal_uInt16 nColId, long lNewWidth);
+ // beachtet im Gegensatz zum SetColumnWidth der Basisklasse auch eine eventuell aktive Zelle in dieser Spalte
+
+ String GetCellContents(sal_Int32 nCellIndex, sal_uInt16 nColId);
+ void SetCellContents(sal_Int32 nCellIndex, sal_uInt16 nColId, const String& strNewText);
+ // Zelleninhalt (als String formatiert) setzen/liefern
+ sal_Int32 GetNoneVisibleRows() const;
+ void SetNoneVisbleRow(long nRows);
+ sal_Bool IsRowVisible(sal_uInt16 _nWhich) const;
+ void SetRowVisible(sal_uInt16 _nWhich, sal_Bool _bVis);
+
+ void SetReadOnly(sal_Bool bRO);
+ // calculate an optimal size. Basically, this takes into account the number of visible rows.
+ Size CalcOptimalSize( const Size& _rAvailable );
+
+ // can the current content be cut
+ sal_Bool isPasteAllowed();
+ sal_Bool isCutAllowed();
+ sal_Bool isCopyAllowed();
+ void cut();
+ void paste();
+ void copy();
+
+ virtual void GetFocus();
+ virtual void DeactivateCell(sal_Bool bUpdate = sal_True);
+ virtual void ColumnMoved( sal_uInt16 nColId ) { ColumnMoved(nColId,sal_True); }
+ void ColumnMoved( sal_uInt16 nColId,sal_Bool _bCreateUndo);
+
+ void Fill();
+ void PreFill();
+
+ /** Disables the generation of undo actions
+ */
+ inline void EnterUndoMode() { m_bInUndoMode = sal_True; }
+ /** Enables the generation of undo actions
+ */
+ inline void LeaveUndoMode() { m_bInUndoMode = sal_False; }
+
+ /** GetCellText returns the text at the given position
+ @param _nRow
+ the number of the row
+ @param _nColId
+ the ID of the column
+ @return
+ the text out of the cell
+ */
+ virtual String GetCellText(long _nRow, sal_uInt16 _nColId) const;
+
+ /** returns the description of the row.
+ @param _nRow
+ The row number.
+ @return
+ The header text of the specified row.
+ */
+ virtual ::rtl::OUString GetRowDescription( sal_Int32 _nRow ) const;
+
+ /** return the name of the specified object.
+ @param eObjType
+ The type to ask for
+ @param _nPosition
+ The position of a tablecell (index position), header bar colum/row cell
+ @return
+ The name of the specified object.
+ */
+ virtual ::rtl::OUString GetAccessibleObjectName( ::svt::AccessibleBrowseBoxObjType eObjType,sal_Int32 _nPosition = -1) const;
+
+ // IAccessibleTableProvider
+ /** Creates the accessible object of a data table cell.
+ @param nRow The row index of the cell.
+ @param nColumnId The column ID of the cell.
+ @return The XAccessible interface of the specified cell. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessibleCell( sal_Int32 nRow, sal_uInt16 nColumnId );
+
+
+ protected:
+ virtual sal_Bool SeekRow( long nRow );
+
+ virtual void PaintStatusCell(OutputDevice& rDev, const Rectangle& rRect) const;
+ virtual void PaintCell(OutputDevice& rDev, const Rectangle& rRect,
+ sal_uInt16 nColumnId ) const;
+
+ virtual sal_Int8 AcceptDrop( const BrowserAcceptDropEvent& rEvt );
+ virtual sal_Int8 ExecuteDrop( const BrowserExecuteDropEvent& rEvt );
+ virtual void MouseButtonDown( const BrowserMouseEvent& rEvt );
+ virtual void MouseButtonUp( const BrowserMouseEvent& rEvt );
+ virtual void KeyInput( const KeyEvent& rEvt );
+ virtual void Command(const CommandEvent& rEvt);
+ virtual void ArrangeControls(sal_uInt16& nX, sal_uInt16 nY);
+
+ virtual ::svt::CellController* GetController(long nRow, sal_uInt16 nCol);
+ virtual void InitController(::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol);
+ virtual void CellModified();
+ virtual sal_Bool SaveModified();
+ virtual void Init();
+ virtual sal_uInt32 GetTotalCellWidth(long nRow, sal_uInt16 nColId) const;
+ virtual void ColumnResized( sal_uInt16 nColId );
+
+ virtual sal_uInt32 GetTotalCellWidth(long nRow, sal_uInt16 nColId);
+
+ virtual sal_uInt16 GetDefaultColumnWidth(const String& rName) const;
+ // if you want to have an own header ...
+ virtual BrowserHeader* imp_CreateHeaderBar(BrowseBox* pParent);
+
+ void stopTimer();
+ void startTimer();
+
+ private:
+ OTableFieldDescRef FindFirstFreeCol(sal_uInt16& _rColumnPosition);
+ // rCol enthaelt die Nummer (in pOTableFieldDescList) der ersten Spalte, die von sich sagt, dass sie leer ist
+ // wenn es keine solche gibt, ist rCol undefiniert und der Rueckgabewert NULL
+ void CheckFreeColumns(sal_uInt16& _rColumnPosition);
+ // testet, ob es noch freie Spalten gibt, wenn nicht, wird ein neuer Packen angefuegt
+ // rCol enthaelt die Nummer der ersten freien Spalte (in pOTableFieldDescList)
+
+ void RemoveField( sal_uInt16 nId );
+ Rectangle GetInvalidRect( sal_uInt16 nColId );
+ long GetRealRow(long nRow) const;
+ long GetBrowseRow(long nRowId) const;
+ sal_Bool GetFunctionName(sal_uInt32 _nFunctionTokenId,String& rFkt);
+ void appendUndoAction(const String& _rOldValue,const String& _rNewValue,sal_Int32 _nRow,sal_Bool& _bListAction);
+ void appendUndoAction(const String& _rOldValue,const String& _rNewValue,sal_Int32 _nRow);
+ OTableFields& getFields() const;
+ void enableControl(const OTableFieldDescRef& _rEntry,Window* _pControl);
+ void setTextCellContext(const OTableFieldDescRef& _rEntry,const String& _sText,const rtl::OString& _sHelpId);
+ void invalidateUndoRedo();
+ OTableFieldDescRef getEntry(OTableFields::size_type _nPos);
+
+ void adjustSelectionMode( sal_Bool _bClickedOntoHeader, sal_Bool _bClickedOntoHandleCol );
+
+ /** save the filed change in save modified
+ @param _sFieldName
+ The field name inserted by the user.
+ @param _pEntry
+ The entry which will contain the nescessary entries.
+ @param _bListAction
+ Will be set to <TRUE/> when we are in a list action otherwise <FALSE/>
+ @return
+ <TRUE/> if an error occurred otherwise <FALSE/>
+ */
+ sal_Bool saveField(const String& _sFieldName,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction);
+
+ /** sets the table window at the _pEntry
+ @param _pEntry
+ The entry where the window should be set.
+ @param _sTableName
+ The table name to search for.
+ @return
+ <TRUE/> if the table name was set otherwise <FALSE/>
+ */
+ sal_Bool fillEntryTable(OTableFieldDescRef& _pEntry,const ::rtl::OUString& _sTableName);
+
+ /** uses the parse node to fill all information into the field
+ @param _pColumnRef
+ The parse node used to fill the info into the field.
+ @param _xMetaData
+ Use to parse the node to a string.
+ @param _pEntry
+ The entry which will contain the nescessary entries.
+ @param _bListAction
+ Will be set to <TRUE/> when we are in a list action otherwise <FALSE/>
+ @return
+ <TRUE/> if an error occurred otherwise <FALSE/>
+ */
+ sal_Bool fillColumnRef( const ::connectivity::OSQLParseNode* _pColumnRef,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
+ OTableFieldDescRef& _pEntry,
+ sal_Bool& _bListAction);
+ sal_Bool fillColumnRef( const ::rtl::OUString& _sColumnName,
+ const ::rtl::OUString& _sTableRange,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _xMetaData,
+ OTableFieldDescRef& _pEntry,
+ sal_Bool& _bListAction);
+
+
+ /** append an undo action for the table field
+ @param _sOldAlias
+ The old table alias.
+ @param _sAlias
+ The new alias name.
+ @param _bListAction
+ Will be set to <TRUE/> when we are in a list action otherwise <FALSE/>
+ */
+ void notifyTableFieldChanged(const String& _sOldAlias,const String& _sAlias,sal_Bool& _bListAction,sal_uInt16 _nColumnId);
+
+ /** append an undo action for the function field
+ @param _sOldFunctionName
+ The old value.
+ @param _sFunctionName
+ The new function name.
+ @param _bListAction
+ Will be set to <TRUE/> when we are in a list action otherwise <FALSE/>
+ */
+ void notifyFunctionFieldChanged(const String& _sOldFunctionName,const String& _sFunctionName,sal_Bool& _bListAction,sal_uInt16 _nColumnId);
+
+ /** clears the function fields of the submitted entry if it doesn't match the SQL standard and append an undo action.
+ E.q. AGGREGATE functions are only valid when the field name isn't an asterix
+ @param _sFieldName
+ The field name.
+ @param _pEntry
+ The entry to be cleared
+ @param _bListAction
+ When <TRUE/> an list action will be created.
+ */
+ void clearEntryFunctionField(const String& _sFieldName,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction,sal_uInt16 _nColumnId);
+
+ /** remove or insert the necessary function types
+ @param _pEntry
+ The currently edited entry.
+ */
+ void setFunctionCell(OTableFieldDescRef& _pEntry);
+
+ private:
+ using ::svt::EditBrowseBox::AcceptDrop;
+ using ::svt::EditBrowseBox::ExecuteDrop;
+ using ::svt::EditBrowseBox::MouseButtonDown;
+ using ::svt::EditBrowseBox::MouseButtonUp;
+ };
+}
+#endif // DBAUI_QUERYDESIGN_OSELECTIONBROWSEBOX_HXX
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableConnection.cxx b/dbaccess/source/ui/querydesign/TableConnection.cxx
new file mode 100644
index 000000000000..db6a8efd328c
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableConnection.cxx
@@ -0,0 +1,246 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "TableConnection.hxx"
+#include "ConnectionLine.hxx"
+#include "TableConnectionData.hxx"
+#include "JoinTableView.hxx"
+#include <comphelper/stl_types.hxx>
+#include "ConnectionLineAccess.hxx"
+#include <algorithm>
+
+
+using namespace dbaui;
+using namespace comphelper;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::accessibility;
+
+//========================================================================
+// class OTableConnection
+//========================================================================
+namespace dbaui
+{
+ DBG_NAME(OTableConnection)
+ //------------------------------------------------------------------------
+ OTableConnection::OTableConnection( OJoinTableView* _pContainer,const TTableConnectionData::value_type& _pTabConnData )
+ :Window(_pContainer)
+ ,m_pData( _pTabConnData )
+ ,m_pParent( _pContainer )
+ ,m_bSelected( sal_False )
+ {
+ DBG_CTOR(OTableConnection,NULL);
+ Init();
+ Show();
+ }
+
+ //------------------------------------------------------------------------
+ OTableConnection::OTableConnection( const OTableConnection& _rConn ) : Window(_rConn.m_pParent)
+ ,m_pData(_rConn.GetData()->NewInstance())
+ {
+ DBG_CTOR(OTableConnection,NULL);
+ *this = _rConn;
+ }
+
+ //------------------------------------------------------------------------
+ void OTableConnection::Init()
+ {
+ //////////////////////////////////////////////////////////////////////
+ // Linienliste mit Defaults initialisieren
+ OConnectionLineDataVec* pLineData = GetData()->GetConnLineDataList();
+ OConnectionLineDataVec::const_iterator aIter = pLineData->begin();
+ OConnectionLineDataVec::const_iterator aEnd = pLineData->end();
+ m_vConnLine.reserve(pLineData->size());
+ for(;aIter != aEnd;++aIter)
+ m_vConnLine.push_back( new OConnectionLine(this, *aIter) );
+ }
+
+ //------------------------------------------------------------------------
+ OConnectionLine* OTableConnection::CreateConnLine( const OConnectionLine& rConnLine )
+ {
+ return new OConnectionLine( rConnLine );
+ }
+ // -----------------------------------------------------------------------------
+ void OTableConnection::clearLineData()
+ {
+ ::std::vector<OConnectionLine*>::iterator aLineEnd = m_vConnLine.end();
+ for(::std::vector<OConnectionLine*>::iterator aLineIter = m_vConnLine.begin();aLineIter != aLineEnd;++aLineIter)
+ delete *aLineIter;
+ m_vConnLine.clear();
+ }
+ //------------------------------------------------------------------------
+ void OTableConnection::UpdateLineList()
+ {
+ //////////////////////////////////////////////////////////////////////
+ // Linienliste loeschen
+ clearLineData();
+
+ Init();
+ }
+
+ //------------------------------------------------------------------------
+ OTableConnection& OTableConnection::operator=( const OTableConnection& rConn )
+ {
+ if( &rConn == this )
+ return *this;
+
+ // Linienliste loeschen
+ clearLineData();
+
+ // Linienliste kopieren
+ if(! rConn.GetConnLineList()->empty() )
+ {
+ const ::std::vector<OConnectionLine*>* pLine = rConn.GetConnLineList();
+ ::std::vector<OConnectionLine*>::const_iterator aIter = pLine->begin();
+ ::std::vector<OConnectionLine*>::const_iterator aEnd = pLine->end();
+ m_vConnLine.reserve(pLine->size());
+ for(;aIter != aEnd;++aIter)
+ m_vConnLine.push_back( CreateConnLine( **aIter ));
+ }
+
+ // da mir die Daten nicht gehoeren, loesche ich die alten nicht
+ m_pData->CopyFrom(*rConn.GetData());
+ // CopyFrom ist virtuell, damit ist es kein Problem, wenn m_pData von einem von OTableConnectionData abgeleiteten Typ ist
+
+ m_bSelected = rConn.m_bSelected;
+ m_pParent = rConn.m_pParent;
+
+ return *this;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool OTableConnection::RecalcLines()
+ {
+ // call RecalcLines on each line
+ ::std::for_each(m_vConnLine.begin(),m_vConnLine.end(),::std::mem_fun(&OConnectionLine::RecalcLine));
+ return true;
+ }
+ //------------------------------------------------------------------------
+ OTableWindow* OTableConnection::GetSourceWin() const
+ {
+ TTableWindowData::value_type pRef = GetData()->getReferencingTable();
+ OTableWindow* pRet = m_pParent->GetTabWindow( pRef->GetWinName() );
+ if ( !pRet )
+ {
+ pRet = m_pParent->GetTabWindow( pRef->GetComposedName() );
+ }
+ return pRet;
+ }
+ //------------------------------------------------------------------------
+ OTableWindow* OTableConnection::GetDestWin() const
+ {
+ TTableWindowData::value_type pRef = GetData()->getReferencedTable();
+ OTableWindow* pRet = m_pParent->GetTabWindow( pRef->GetWinName() );
+ if ( !pRet )
+ {
+ pRet = m_pParent->GetTabWindow( pRef->GetComposedName() );
+ }
+ return pRet;
+ }
+
+ //------------------------------------------------------------------------
+ void OTableConnection::Select()
+ {
+ m_bSelected = sal_True;
+ m_pParent->Invalidate( GetBoundingRect(), INVALIDATE_NOCHILDREN);
+ }
+
+ //------------------------------------------------------------------------
+ void OTableConnection::Deselect()
+ {
+ m_bSelected = sal_False;
+ InvalidateConnection();
+ }
+
+ //------------------------------------------------------------------------
+ sal_Bool OTableConnection::CheckHit( const Point& rMousePos ) const
+ {
+ //////////////////////////////////////////////////////////////////////
+ // check if the point hit our line
+ ::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(m_vConnLine.begin(),
+ m_vConnLine.end(),
+ ::std::bind2nd(TConnectionLineCheckHitFunctor(),rMousePos));
+ return aIter != m_vConnLine.end();
+ }
+
+ //------------------------------------------------------------------------
+ bool OTableConnection::InvalidateConnection()
+ {
+ Rectangle rcBounding = GetBoundingRect();
+ rcBounding.Bottom() += 1;
+ rcBounding.Right() += 1;
+ // ich glaube, dass sich Invalidate und Draw(Rectangle) nicht konsistent verhalten : jedenfalls waere dadurch zu
+ // erklaeren, warum ohne diesen Fake hier beim Loeschen einer Connection ein Strich an ihrem unteren Ende stehen bleibt :
+ // Invalidate erfasst dabei offensichtlich eine Pixelzeile weniger als Draw.
+ // Oder alles haengt ganz anders zusammen ... jedenfalls klappt es so ...
+ m_pParent->Invalidate( rcBounding, INVALIDATE_NOCHILDREN );
+
+ return true;
+ }
+
+ //------------------------------------------------------------------------
+ Rectangle OTableConnection::GetBoundingRect() const
+ {
+ //////////////////////////////////////////////////////////////////////
+ // Aus allen Linien das umgebende Rechteck bestimmen
+ Rectangle aBoundingRect( Point(0,0), Point(0,0) );
+ Rectangle aTempRect;
+ ::std::vector<OConnectionLine*>::const_iterator aEnd = m_vConnLine.end();
+ for(::std::vector<OConnectionLine*>::const_iterator aIter = m_vConnLine.begin();aIter != aEnd;++aIter)
+ {
+ aTempRect = (*aIter)->GetBoundingRect();
+
+ //////////////////////////////////////////////////////////////////////
+ // Ist das BoundingRect dieser Linie gueltig?
+ if( (aTempRect.GetWidth()!=1) && (aTempRect.GetHeight()!=1) )
+ {
+ if( (aBoundingRect.GetWidth()==1) && (aBoundingRect.GetHeight()==1) )
+ aBoundingRect = aTempRect;
+ else
+ aBoundingRect.Union( aTempRect );
+ }
+ }
+
+ return aBoundingRect;
+ }
+
+ //------------------------------------------------------------------------
+ void OTableConnection::Draw( const Rectangle& /*rRect*/ )
+ {
+ //////////////////////////////////////////////////////////////////////
+ // Linien zeichnen
+ ::std::for_each(m_vConnLine.begin(),m_vConnLine.end(),TConnectionLineDrawFunctor(m_pParent));
+ }
+ // -----------------------------------------------------------------------------
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableConnectionData.cxx b/dbaccess/source/ui/querydesign/TableConnectionData.cxx
new file mode 100644
index 000000000000..d820c5efa280
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableConnectionData.cxx
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "TableConnectionData.hxx"
+#include <tools/debug.hxx>
+#include <osl/diagnose.h>
+#include <comphelper/stl_types.hxx>
+
+using namespace dbaui;
+using namespace comphelper;
+//==================================================================
+// class OTableConnectionData
+//==================================================================
+DBG_NAME(OTableConnectionData)
+//------------------------------------------------------------------------
+OTableConnectionData::OTableConnectionData()
+{
+ DBG_CTOR(OTableConnectionData,NULL);
+ Init();
+}
+// -----------------------------------------------------------------------------
+OTableConnectionData::OTableConnectionData(const TTableWindowData::value_type& _pReferencingTable
+ ,const TTableWindowData::value_type& _pReferencedTable
+ ,const String& rConnName )
+ :m_pReferencingTable(_pReferencingTable)
+ ,m_pReferencedTable(_pReferencedTable)
+ ,m_aConnName( rConnName )
+{
+ DBG_CTOR(OTableConnectionData,NULL);
+ Init();
+}
+//------------------------------------------------------------------------
+void OTableConnectionData::Init()
+{
+ //////////////////////////////////////////////////////////////////////
+ // LineDataList mit Defaults initialisieren
+ OSL_ENSURE(m_vConnLineData.size() == 0, "OTableConnectionData::Init() : nur mit leere Linienliste aufzurufen !");
+ ResetConnLines(sal_True);
+ // das legt Defaults an
+}
+//------------------------------------------------------------------------
+OTableConnectionData::OTableConnectionData( const OTableConnectionData& rConnData )
+{
+ DBG_CTOR(OTableConnectionData,NULL);
+ *this = rConnData;
+}
+//------------------------------------------------------------------------
+void OTableConnectionData::CopyFrom(const OTableConnectionData& rSource)
+{
+ *this = rSource;
+ // hier ziehe ich mich auf das (nicht-virtuelle) operator= zurueck, das nur meine Members kopiert
+}
+
+//------------------------------------------------------------------------
+OTableConnectionData::~OTableConnectionData()
+{
+ DBG_DTOR(OTableConnectionData,NULL);
+ // LineDataList loeschen
+ OConnectionLineDataVec().swap(m_vConnLineData);
+}
+
+//------------------------------------------------------------------------
+OTableConnectionData& OTableConnectionData::operator=( const OTableConnectionData& rConnData )
+{
+ if (&rConnData == this)
+ return *this;
+
+ m_pReferencingTable = rConnData.m_pReferencingTable;
+ m_pReferencedTable = rConnData.m_pReferencedTable;
+ m_aConnName = rConnData.GetConnName();
+
+ // clear line list
+ ResetConnLines(sal_False);
+
+ // und kopieren
+ OConnectionLineDataVec* pLineData = const_cast<OTableConnectionData*>(&rConnData)->GetConnLineDataList();
+
+ OConnectionLineDataVec::const_iterator aIter = pLineData->begin();
+ OConnectionLineDataVec::const_iterator aEnd = pLineData->end();
+ for(;aIter != aEnd;++aIter)
+ m_vConnLineData.push_back(new OConnectionLineData(**aIter));
+
+ return *this;
+}
+
+//------------------------------------------------------------------------
+sal_Bool OTableConnectionData::SetConnLine( sal_uInt16 nIndex, const String& rSourceFieldName, const String& rDestFieldName )
+{
+ if (sal_uInt16(m_vConnLineData.size()) < nIndex)
+ return sal_False;
+ // == ist noch erlaubt, das entspricht einem Append
+
+ if (m_vConnLineData.size() == nIndex)
+ return AppendConnLine(rSourceFieldName, rDestFieldName);
+
+ OConnectionLineDataRef pConnLineData = m_vConnLineData[nIndex];
+ OSL_ENSURE(pConnLineData != NULL, "OTableConnectionData::SetConnLine : habe ungueltiges LineData-Objekt");
+
+ pConnLineData->SetSourceFieldName( rSourceFieldName );
+ pConnLineData->SetDestFieldName( rDestFieldName );
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+sal_Bool OTableConnectionData::AppendConnLine( const ::rtl::OUString& rSourceFieldName, const ::rtl::OUString& rDestFieldName )
+{
+ OConnectionLineDataVec::iterator aIter = m_vConnLineData.begin();
+ OConnectionLineDataVec::iterator aEnd = m_vConnLineData.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ if((*aIter)->GetDestFieldName() == rDestFieldName && (*aIter)->GetSourceFieldName() == rSourceFieldName)
+ break;
+ }
+ if(aIter == aEnd)
+ {
+ OConnectionLineDataRef pNew = new OConnectionLineData(rSourceFieldName, rDestFieldName);
+ if (!pNew.is())
+ return sal_False;
+
+ m_vConnLineData.push_back(pNew);
+ }
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+void OTableConnectionData::ResetConnLines( sal_Bool /*bUseDefaults*/ )
+{
+ OConnectionLineDataVec().swap(m_vConnLineData);
+}
+
+//------------------------------------------------------------------------
+OConnectionLineDataRef OTableConnectionData::CreateLineDataObj()
+{
+ return new OConnectionLineData();
+}
+
+//------------------------------------------------------------------------
+OConnectionLineDataRef OTableConnectionData::CreateLineDataObj( const OConnectionLineData& rConnLineData )
+{
+ return new OConnectionLineData( rConnLineData );
+}
+// -----------------------------------------------------------------------------
+OTableConnectionData* OTableConnectionData::NewInstance() const
+{
+ return new OTableConnectionData();
+}
+// -----------------------------------------------------------------------------
+void OTableConnectionData::normalizeLines()
+{
+ // noch ein wenig Normalisierung auf den LineDatas : leere Lines vom Anfang an das Ende verschieben
+ sal_Int32 nCount = m_vConnLineData.size();
+ for(sal_Int32 i=0;i<nCount;)
+ {
+ if(!m_vConnLineData[i]->GetSourceFieldName().getLength() || !m_vConnLineData[i]->GetDestFieldName().getLength())
+ {
+ OConnectionLineDataRef pData = m_vConnLineData[i];
+ m_vConnLineData.erase(m_vConnLineData.begin()+i);
+ m_vConnLineData.push_back(pData);
+ --nCount;
+ }
+ else
+ ++i;
+ }
+}
+// -----------------------------------------------------------------------------
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableFieldDescription.cxx b/dbaccess/source/ui/querydesign/TableFieldDescription.cxx
new file mode 100644
index 000000000000..8edf83464b96
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableFieldDescription.cxx
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+
+#include "TableFieldDescription.hxx"
+#include <tools/debug.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <comphelper/namedvaluecollection.hxx>
+
+#include <functional>
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace comphelper;
+using namespace dbaui;
+
+DBG_NAME(OTableFieldDesc)
+//==============================================================================
+OTableFieldDesc::OTableFieldDesc()
+ :m_pTabWindow(0)
+ ,m_eDataType(1000)
+ ,m_eFunctionType( FKT_NONE )
+ ,m_eFieldType(TAB_NORMAL_FIELD)
+ ,m_eOrderDir( ORDER_NONE )
+ ,m_nIndex(0)
+ ,m_nColWidth(0)
+ ,m_nColumnId((sal_uInt16)-1)
+ ,m_bGroupBy(sal_False)
+ ,m_bVisible(sal_False)
+{
+ DBG_CTOR(OTableFieldDesc,NULL);
+}
+//------------------------------------------------------------------------------
+OTableFieldDesc::OTableFieldDesc(const OTableFieldDesc& rRS)
+ : ::salhelper::SimpleReferenceObject()
+
+{
+ DBG_CTOR(OTableFieldDesc,NULL);
+ *this = rRS;
+}
+
+//------------------------------------------------------------------------------
+OTableFieldDesc::OTableFieldDesc(const ::rtl::OUString& rT, const ::rtl::OUString& rF )
+ :m_pTabWindow(0)
+ ,m_eFunctionType( FKT_NONE )
+ ,m_eOrderDir( ORDER_NONE )
+ ,m_nColumnId((sal_uInt16)-1)
+ ,m_bGroupBy(sal_False)
+ ,m_bVisible(sal_False)
+{
+ DBG_CTOR(OTableFieldDesc,NULL);
+ SetField( rF ); SetTable( rT );
+}
+
+//------------------------------------------------------------------------------
+OTableFieldDesc::~OTableFieldDesc()
+{
+ DBG_DTOR(OTableFieldDesc,NULL);
+}
+//------------------------------------------------------------------------------
+OTableFieldDesc& OTableFieldDesc::operator=( const OTableFieldDesc& rRS )
+{
+ if (&rRS == this)
+ return *this;
+
+ m_aCriteria = rRS.GetCriteria();
+ m_aTableName = rRS.GetTable();
+ m_aAliasName = rRS.GetAlias(); // table range
+ m_aFieldName = rRS.GetField(); // column
+ m_aFieldAlias = rRS.GetFieldAlias(); // column alias
+ m_aFunctionName = rRS.GetFunction(); // Funktionsname
+ m_pTabWindow = rRS.GetTabWindow();
+ m_eDataType = rRS.GetDataType();
+ m_eFunctionType = rRS.GetFunctionType();
+ m_eFieldType = rRS.GetFieldType();
+ m_eOrderDir = rRS.GetOrderDir();
+ m_nIndex = rRS.GetFieldIndex();
+ m_nColWidth = rRS.GetColWidth();
+ m_nColumnId = rRS.m_nColumnId;
+ m_bGroupBy = rRS.IsGroupBy();
+ m_bVisible = rRS.IsVisible();
+
+ return *this;
+}
+//------------------------------------------------------------------------------
+sal_Bool OTableFieldDesc::operator==( const OTableFieldDesc& rDesc )
+{
+ DBG_CHKTHIS(OTableFieldDesc,NULL);
+
+ return ( m_eOrderDir != rDesc.GetOrderDir() ||
+ m_eDataType != rDesc.GetDataType() ||
+ m_aAliasName != rDesc.GetAlias() ||
+ m_aFunctionName != rDesc.GetFunction() ||
+ m_aFieldName != rDesc.GetField() ||
+ m_aTableName != rDesc.GetTable() ||
+ m_bGroupBy != rDesc.IsGroupBy() ||
+ m_aCriteria != rDesc.GetCriteria() ||
+ m_bVisible != rDesc.IsVisible() );
+
+}
+
+//------------------------------------------------------------------------------
+void OTableFieldDesc::SetCriteria( sal_uInt16 nIdx, const ::rtl::OUString& rCrit)
+{
+ DBG_CHKTHIS(OTableFieldDesc,NULL);
+ if (nIdx < m_aCriteria.size())
+ m_aCriteria[nIdx] = rCrit;
+ else
+ {
+ for(sal_Int32 i=m_aCriteria.size();i<nIdx;++i)
+ m_aCriteria.push_back( ::rtl::OUString());
+ m_aCriteria.push_back(rCrit);
+ }
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString OTableFieldDesc::GetCriteria( sal_uInt16 nIdx ) const
+{
+ DBG_CHKTHIS(OTableFieldDesc,NULL);
+ ::rtl::OUString aRetStr;
+ if( nIdx < m_aCriteria.size())
+ aRetStr = m_aCriteria[nIdx];
+
+ return aRetStr;
+}
+
+// -----------------------------------------------------------------------------
+namespace
+{
+ struct SelectPropertyValueAsString : public ::std::unary_function< PropertyValue, ::rtl::OUString >
+ {
+ ::rtl::OUString operator()( const PropertyValue& i_rPropValue ) const
+ {
+ ::rtl::OUString sValue;
+ OSL_VERIFY( i_rPropValue.Value >>= sValue );
+ return sValue;
+ }
+ };
+}
+
+// -----------------------------------------------------------------------------
+void OTableFieldDesc::Load( const ::com::sun::star::beans::PropertyValue& i_rSettings, const bool i_bIncludingCriteria )
+{
+ DBG_CHKTHIS(OTableFieldDesc,NULL);
+
+ ::comphelper::NamedValueCollection aFieldDesc( i_rSettings.Value );
+ m_aAliasName = aFieldDesc.getOrDefault( "AliasName", m_aAliasName );
+ m_aTableName = aFieldDesc.getOrDefault( "TableName", m_aTableName );
+ m_aFieldName = aFieldDesc.getOrDefault( "FieldName", m_aFieldName );
+ m_aFieldAlias = aFieldDesc.getOrDefault( "FieldAlias", m_aFieldAlias );
+ m_aFunctionName = aFieldDesc.getOrDefault( "FunctionName", m_aFunctionName );
+ m_eDataType = aFieldDesc.getOrDefault( "DataType", m_eDataType );
+ m_eFunctionType = aFieldDesc.getOrDefault( "FunctionType", m_eFunctionType );
+ m_nColWidth = aFieldDesc.getOrDefault( "ColWidth", m_nColWidth );
+ m_bGroupBy = aFieldDesc.getOrDefault( "GroupBy", m_bGroupBy );
+ m_bVisible = aFieldDesc.getOrDefault( "Visible", m_bVisible );
+
+ m_eFieldType = static_cast< ETableFieldType >( aFieldDesc.getOrDefault( "FieldType", static_cast< sal_Int32 >( m_eFieldType ) ) );
+ m_eOrderDir = static_cast< EOrderDir >( aFieldDesc.getOrDefault( "OrderDir", static_cast< sal_Int32 >( m_eOrderDir ) ) );
+
+ if ( i_bIncludingCriteria )
+ {
+ const Sequence< PropertyValue > aCriteria( aFieldDesc.getOrDefault( "Criteria", Sequence< PropertyValue >() ) );
+ m_aCriteria.resize( aCriteria.getLength() );
+ ::std::transform(
+ aCriteria.getConstArray(),
+ aCriteria.getConstArray() + aCriteria.getLength(),
+ m_aCriteria.begin(),
+ SelectPropertyValueAsString()
+ );
+ }
+}
+//------------------------------------------------------------------------------
+void OTableFieldDesc::Save( ::comphelper::NamedValueCollection& o_rSettings, const bool i_bIncludingCriteria )
+{
+ DBG_CHKTHIS(OTableFieldDesc,NULL);
+
+ o_rSettings.put( "AliasName", m_aAliasName );
+ o_rSettings.put( "TableName", m_aTableName );
+ o_rSettings.put( "FieldName", m_aFieldName );
+ o_rSettings.put( "FieldAlias", m_aFieldAlias );
+ o_rSettings.put( "FunctionName", m_aFunctionName );
+ o_rSettings.put( "DataType", m_eDataType );
+ o_rSettings.put( "FunctionType", (sal_Int32)m_eFunctionType );
+ o_rSettings.put( "FieldType", (sal_Int32)m_eFieldType );
+ o_rSettings.put( "OrderDir", (sal_Int32)m_eOrderDir );
+ o_rSettings.put( "ColWidth", m_nColWidth );
+ o_rSettings.put( "GroupBy", m_bGroupBy );
+ o_rSettings.put( "Visible", m_bVisible );
+
+ if ( i_bIncludingCriteria )
+ {
+ if ( !m_aCriteria.empty() )
+ {
+ sal_Int32 c = 0;
+ Sequence< PropertyValue > aCriteria( m_aCriteria.size() );
+ for ( ::std::vector< ::rtl::OUString >::const_iterator crit = m_aCriteria.begin();
+ crit != m_aCriteria.end();
+ ++crit, ++c
+ )
+ {
+ aCriteria[c].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Criterion_" ) ) + ::rtl::OUString::valueOf( c );
+ aCriteria[c].Value <<= *crit;
+ }
+
+ o_rSettings.put( "Criteria", aCriteria );
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableFieldInfo.cxx b/dbaccess/source/ui/querydesign/TableFieldInfo.cxx
new file mode 100644
index 000000000000..7ef432c32bd8
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableFieldInfo.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+
+#include "TableFieldInfo.hxx"
+#include <tools/debug.hxx>
+
+using namespace dbaui;
+//==================================================================
+// class OTableFieldInfo
+//==================================================================
+
+DBG_NAME(OTableFieldInfo)
+OTableFieldInfo::OTableFieldInfo() :
+ m_eDataType(1000)
+{
+ DBG_CTOR(OTableFieldInfo,NULL);
+ m_eFieldType = TAB_NORMAL_FIELD;
+}
+
+//------------------------------------------------------------------------------
+OTableFieldInfo::~OTableFieldInfo()
+{
+ DBG_DTOR(OTableFieldInfo,NULL);
+}
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableFieldInfo.hxx b/dbaccess/source/ui/querydesign/TableFieldInfo.hxx
new file mode 100644
index 000000000000..090d71735665
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableFieldInfo.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_TABLEFIELDINFO_HXX
+#define DBAUI_TABLEFIELDINFO_HXX
+
+#include "QEnumTypes.hxx"
+#include <sal/types.h>
+
+namespace dbaui
+{
+ class OTableFieldInfo
+ {
+ private:
+ ETableFieldType m_eFieldType;
+ sal_Int32 m_eDataType;
+
+ public:
+ OTableFieldInfo();
+ ~OTableFieldInfo();
+
+ inline ETableFieldType GetKeyType() const { return m_eFieldType; }
+ inline void SetKey(ETableFieldType bKey=TAB_NORMAL_FIELD) { m_eFieldType = bKey; }
+ inline sal_Int32 GetDataType() const { return m_eDataType; }
+ inline void SetDataType(sal_Int32 eTyp) { m_eDataType = eTyp; }
+ };
+}
+#endif // DBAUI_TABLEFIELDINFO_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableWindow.cxx b/dbaccess/source/ui/querydesign/TableWindow.cxx
new file mode 100644
index 000000000000..57185506f84c
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableWindow.cxx
@@ -0,0 +1,803 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "TableWindow.hxx"
+#include "TableWindowListBox.hxx"
+#include "QueryTableView.hxx"
+#include "QueryDesignView.hxx"
+#include "TableWindowData.hxx"
+#include "imageprovider.hxx"
+#include <tools/diagnose_ex.h>
+#include <osl/diagnose.h>
+#include <vcl/svapp.hxx>
+#include <vcl/wall.hxx>
+
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include "querycontroller.hxx"
+#include "dbu_qry.hrc"
+#include "dbustrings.hrc"
+#include "Query.hrc"
+#include <comphelper/extract.hxx>
+#include "UITools.hxx"
+#include "TableWindowAccess.hxx"
+#include "browserids.hxx"
+#include <connectivity/dbtools.hxx>
+
+
+using namespace dbaui;
+using namespace ::utl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::accessibility;
+
+#define TABWIN_SIZING_AREA 4
+#define LISTBOX_SCROLLING_AREA 6
+#define SCROLLING_TIMESPAN 500
+
+#define TABWIN_WIDTH_MIN 90
+#define TABWIN_HEIGHT_MIN 80
+
+//========================================================================
+// class OTableWindow
+//========================================================================
+DBG_NAME(OTableWindow)
+//------------------------------------------------------------------------------
+OTableWindow::OTableWindow( Window* pParent, const TTableWindowData::value_type& pTabWinData )
+ : ::comphelper::OContainerListener(m_aMutex)
+ ,Window( pParent, WB_3DLOOK|WB_MOVEABLE )
+ ,m_aTypeImage( this )
+ ,m_aTitle( this )
+ ,m_pListBox(NULL)
+ ,m_pAccessible(NULL)
+ ,m_pData( pTabWinData )
+ ,m_nMoveCount(0)
+ ,m_nMoveIncrement(1)
+ ,m_nSizingFlags( SIZING_NONE )
+ ,m_bActive( sal_False )
+{
+ DBG_CTOR(OTableWindow,NULL);
+
+ // Position und Groesse bestimmen
+ if( GetData()->HasPosition() )
+ SetPosPixel( GetData()->GetPosition() );
+
+ if( GetData()->HasSize() )
+ SetSizePixel( GetData()->GetSize() );
+
+ // Hintergrund setzen
+ const StyleSettings& aSystemStyle = Application::GetSettings().GetStyleSettings();
+ SetBackground(Wallpaper(aSystemStyle.GetFaceColor()));
+ // und Textfarbe (obwohl ich eigentlich keinen Text habe, aber wer weiss, was
+ // abgeleitete Klassen machen)
+ SetTextColor(aSystemStyle.GetButtonTextColor());
+
+ EnableClipSiblings();
+}
+
+//------------------------------------------------------------------------------
+OTableWindow::~OTableWindow()
+{
+ DBG_DTOR(OTableWindow,NULL);
+
+ if (m_pListBox)
+ {
+ OSL_ENSURE(m_pListBox->GetEntryCount()==0,"Forgot to call EmptyListbox()!");
+ ::std::auto_ptr<Window> aTemp(m_pListBox);
+ m_pListBox = NULL;
+ }
+ if ( m_pContainerListener.is() )
+ m_pContainerListener->dispose();
+
+ m_pAccessible = NULL;
+}
+// -----------------------------------------------------------------------------
+const OJoinTableView* OTableWindow::getTableView() const
+{
+ OSL_ENSURE(static_cast<OJoinTableView*>(GetParent()),"No OJoinTableView!");
+ return static_cast<OJoinTableView*>(GetParent());
+}
+// -----------------------------------------------------------------------------
+OJoinTableView* OTableWindow::getTableView()
+{
+ OSL_ENSURE(static_cast<OJoinTableView*>(GetParent()),"No OJoinTableView!");
+ return static_cast<OJoinTableView*>(GetParent());
+}
+// -----------------------------------------------------------------------------
+OJoinDesignView* OTableWindow::getDesignView()
+{
+ OSL_ENSURE(static_cast<OJoinDesignView*>(GetParent()->GetParent()->GetParent()),"No OJoinDesignView!");
+ return static_cast<OJoinDesignView*>(GetParent()->GetParent()->GetParent());
+}
+//------------------------------------------------------------------------------
+void OTableWindow::SetPosPixel( const Point& rNewPos )
+{
+ Point aNewPosData = rNewPos + getTableView()->GetScrollOffset();
+ GetData()->SetPosition( aNewPosData );
+ Window::SetPosPixel( rNewPos );
+}
+
+//------------------------------------------------------------------------------
+void OTableWindow::SetSizePixel( const Size& rNewSize )
+{
+ Size aOutSize(rNewSize);
+ if( aOutSize.Width() < TABWIN_WIDTH_MIN )
+ aOutSize.Width() = TABWIN_WIDTH_MIN;
+ if( aOutSize.Height() < TABWIN_HEIGHT_MIN )
+ aOutSize.Height() = TABWIN_HEIGHT_MIN;
+
+ GetData()->SetSize( aOutSize );
+ Window::SetSizePixel( aOutSize );
+}
+//------------------------------------------------------------------------------
+void OTableWindow::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
+{
+ SetPosPixel( rNewPos );
+ SetSizePixel( rNewSize );
+}
+//------------------------------------------------------------------------------
+OTableWindowListBox* OTableWindow::CreateListBox()
+{
+ return new OTableWindowListBox(this);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OTableWindow::FillListBox()
+{
+ m_pListBox->Clear();
+ if ( !m_pContainerListener.is() )
+ {
+ Reference< XContainer> xContainer(m_pData->getColumns(),UNO_QUERY);
+ if ( xContainer.is() )
+ m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
+ }
+ // mark all primary keys with special image
+ ModuleRes TmpRes(IMG_JOINS);
+ ImageList aImageList(TmpRes);
+ Image aPrimKeyImage = aImageList.GetImage(IMG_PRIMARY_KEY);
+
+ if (GetData()->IsShowAll())
+ {
+ SvLBoxEntry* pEntry = m_pListBox->InsertEntry( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")) );
+ pEntry->SetUserData( createUserData(NULL,false) );
+ }
+
+ Reference<XNameAccess> xPKeyColumns;
+ try
+ {
+ xPKeyColumns = dbtools::getPrimaryKeyColumns_throw(m_pData->getTable());
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("Exception occurred!");
+ }
+ try
+ {
+ Reference< XNameAccess > xColumns = m_pData->getColumns();
+ if( xColumns.is() )
+ {
+ Sequence< ::rtl::OUString> aColumns = xColumns->getElementNames();
+ const ::rtl::OUString* pIter = aColumns.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aColumns.getLength();
+
+ SvLBoxEntry* pEntry = NULL;
+ for (; pIter != pEnd; ++pIter)
+ {
+ bool bPrimaryKeyColumn = xPKeyColumns.is() && xPKeyColumns->hasByName( *pIter );
+ // is this column in the primary key
+ if ( bPrimaryKeyColumn )
+ pEntry = m_pListBox->InsertEntry(*pIter, aPrimKeyImage, aPrimKeyImage);
+ else
+ pEntry = m_pListBox->InsertEntry(*pIter);
+
+ Reference<XPropertySet> xColumn(xColumns->getByName(*pIter),UNO_QUERY);
+ if ( xColumn.is() )
+ pEntry->SetUserData( createUserData(xColumn,bPrimaryKeyColumn) );
+ }
+ }
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("Exception occurred!");
+ }
+
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+void* OTableWindow::createUserData(const Reference< XPropertySet>& /*_xColumn*/,bool /*_bPrimaryKey*/)
+{
+ return NULL;
+}
+// -----------------------------------------------------------------------------
+void OTableWindow::deleteUserData(void*& _pUserData)
+{
+ OSL_ENSURE(!_pUserData,"INVALID call. Need to delete the userclass!");
+ _pUserData = NULL;
+}
+//------------------------------------------------------------------------------
+void OTableWindow::clearListBox()
+{
+ if ( m_pListBox )
+ {
+ SvLBoxEntry* pEntry = m_pListBox->First();
+
+ while(pEntry)
+ {
+ void* pUserData = pEntry->GetUserData();
+ deleteUserData(pUserData);
+ SvLBoxEntry* pNextEntry = m_pListBox->Next(pEntry);
+ m_pListBox->GetModel()->Remove(pEntry);
+ pEntry = pNextEntry;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OTableWindow::impl_updateImage()
+{
+ ImageProvider aImageProvider( getDesignView()->getController().getConnection() );
+
+ Image aImage;
+ aImageProvider.getImages( GetComposedName(), m_pData->isQuery() ? DatabaseObject::QUERY : DatabaseObject::TABLE, aImage );
+
+ if ( !aImage )
+ {
+ OSL_FAIL( "OTableWindow::impl_updateImage: no images!" );
+ return;
+ }
+
+ m_aTypeImage.SetModeImage( aImage );
+ m_aTypeImage.Show();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OTableWindow::Init()
+{
+ // create list box if necessary
+ if ( !m_pListBox )
+ {
+ m_pListBox = CreateListBox();
+ OSL_ENSURE( m_pListBox != NULL, "OTableWindow::Init() : CreateListBox hat NULL geliefert !" );
+ m_pListBox->SetSelectionMode( MULTIPLE_SELECTION );
+ }
+
+ // Titel setzen
+ m_aTitle.SetText( m_pData->GetWinName() );
+ m_aTitle.Show();
+
+ m_pListBox->Show();
+
+ // die Felder in die ListBox eintragen
+ clearListBox();
+ sal_Bool bSuccess = FillListBox();
+ if ( bSuccess )
+ m_pListBox->SelectAll( sal_False );
+
+ impl_updateImage();
+
+ return bSuccess;
+}
+//------------------------------------------------------------------------------
+void OTableWindow::DataChanged(const DataChangedEvent& rDCEvt)
+{
+ if (rDCEvt.GetType() == DATACHANGED_SETTINGS)
+ {
+ // nehmen wir den worst-case an : die Farben haben sich geaendert, also
+ // mich anpassen
+ const StyleSettings& aSystemStyle = Application::GetSettings().GetStyleSettings();
+ SetBackground(Wallpaper(Color(aSystemStyle.GetFaceColor())));
+ SetTextColor(aSystemStyle.GetButtonTextColor());
+ }
+}
+//------------------------------------------------------------------------------
+void OTableWindow::Paint( const Rectangle& rRect )
+{
+ Rectangle aRect( Point(0,0), GetOutputSizePixel() );
+ Window::Paint( rRect );
+ Draw3DBorder( aRect );
+}
+
+//------------------------------------------------------------------------------
+void OTableWindow::Draw3DBorder(const Rectangle& rRect)
+{
+ // die Style-Settings des Systems fuer meine Farben
+ const StyleSettings& aSystemStyle = Application::GetSettings().GetStyleSettings();
+
+ // Schwarze Linie unten und rechts
+ SetLineColor(aSystemStyle.GetDarkShadowColor());
+ DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
+ DrawLine( rRect.BottomRight(), rRect.TopRight() );
+
+ // Dunkelgraue Linie ueber der schwarzen
+ SetLineColor(aSystemStyle.GetShadowColor());
+ Point aEHvector(1,1);
+ DrawLine( rRect.BottomLeft()+Point(1,-1), rRect.BottomRight() - aEHvector );
+ DrawLine( rRect.BottomRight() - aEHvector, rRect.TopRight()+Point(-1,1) );
+
+ // Hellgraue Linie links und oben
+ SetLineColor(aSystemStyle.GetLightColor());
+ DrawLine( rRect.BottomLeft()+Point(1,-2), rRect.TopLeft() + aEHvector );
+ DrawLine( rRect.TopLeft() + aEHvector, rRect.TopRight()+Point(-2,1) );
+}
+// -----------------------------------------------------------------------------
+Rectangle OTableWindow::getSizingRect(const Point& _rPos,const Size& _rOutputSize) const
+{
+ Rectangle aSizingRect = Rectangle( GetPosPixel(), GetSizePixel() );
+ sal_uInt16 nSizingFlags = GetSizingFlags();
+
+ if( nSizingFlags & SIZING_TOP )
+ {
+ if( _rPos.Y() < 0 )
+ aSizingRect.Top() = 0;
+ else
+ aSizingRect.Top() = _rPos.Y();
+ }
+
+ if( nSizingFlags & SIZING_BOTTOM )
+ {
+ if( _rPos.Y() > _rOutputSize.Height() )
+ aSizingRect.Bottom() = _rOutputSize.Height();
+ else
+ aSizingRect.Bottom() = _rPos.Y();
+ }
+
+
+ if( nSizingFlags & SIZING_RIGHT )
+ {
+ if( _rPos.X() > _rOutputSize.Width() )
+ aSizingRect.Right() = _rOutputSize.Width();
+ else
+ aSizingRect.Right() = _rPos.X();
+ }
+
+ if( nSizingFlags & SIZING_LEFT )
+ {
+ if( _rPos.X() < 0 )
+ aSizingRect.Left() = 0;
+ else
+ aSizingRect.Left() = _rPos.X();
+ }
+ return aSizingRect;
+}
+// -----------------------------------------------------------------------------
+void OTableWindow::setSizingFlag(const Point& _rPos)
+{
+ Size aOutSize = GetOutputSizePixel();
+ //////////////////////////////////////////////////////////////////////
+ // Flags anpassen, wenn Mauszeiger in sizingArea
+ m_nSizingFlags = SIZING_NONE;
+
+ if( _rPos.X() < TABWIN_SIZING_AREA )
+ m_nSizingFlags |= SIZING_LEFT;
+
+ if( _rPos.Y() < TABWIN_SIZING_AREA )
+ m_nSizingFlags |= SIZING_TOP;
+
+ if( _rPos.X() > aOutSize.Width()-TABWIN_SIZING_AREA )
+ m_nSizingFlags |= SIZING_RIGHT;
+
+ if( _rPos.Y() > aOutSize.Height()-TABWIN_SIZING_AREA )
+ m_nSizingFlags |= SIZING_BOTTOM;
+}
+//------------------------------------------------------------------------------
+void OTableWindow::MouseMove( const MouseEvent& rEvt )
+{
+ Window::MouseMove(rEvt);
+
+ OJoinTableView* pCont = getTableView();
+ if (pCont->getDesignView()->getController().isReadOnly())
+ return;
+
+ Point aPos = rEvt.GetPosPixel();
+ setSizingFlag(aPos);
+ Pointer aPointer;
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Mauszeiger anpassen, wenn Mauszeiger in sizingArea
+ switch( m_nSizingFlags )
+ {
+ case SIZING_TOP:
+ case SIZING_BOTTOM:
+ aPointer = Pointer( POINTER_SSIZE );
+ break;
+
+ case SIZING_LEFT:
+ case SIZING_RIGHT:
+ aPointer = Pointer( POINTER_ESIZE );
+ break;
+
+ case SIZING_LEFT+SIZING_TOP:
+ case SIZING_RIGHT+SIZING_BOTTOM:
+ aPointer = Pointer( POINTER_SESIZE );
+ break;
+
+ case SIZING_RIGHT+SIZING_TOP:
+ case SIZING_LEFT+SIZING_BOTTOM:
+ aPointer = Pointer( POINTER_NESIZE );
+ break;
+ }
+
+ SetPointer( aPointer );
+}
+
+//------------------------------------------------------------------------------
+void OTableWindow::MouseButtonDown( const MouseEvent& rEvt )
+{
+ //////////////////////////////////////////////////////////////////////
+ // Wenn sizing, dann bekommt Parent die Nachricht,
+ // dass jetzt die Fenstergroesse seines Childs veraendert wird
+ if( m_nSizingFlags )
+ getTableView()->BeginChildSizing( this, GetPointer() );
+
+ Window::MouseButtonDown( rEvt );
+}
+
+
+
+//------------------------------------------------------------------------------
+void OTableWindow::Resize()
+{
+ //////////////////////////////////////////////////////////////////////
+ // Das Fenster darf nicht verschwinden, deshalb min. Groesse setzen
+ Size aOutSize = GetOutputSizePixel();
+ aOutSize = Size(CalcZoom(aOutSize.Width()),CalcZoom(aOutSize.Height()));
+
+ long nTitleHeight = CalcZoom( GetTextHeight() )+ CalcZoom( 4 );
+
+ //////////////////////////////////////////////////////////////////////
+ // Titel und ListBox anpassen
+ long n5Pos = CalcZoom(5);
+ long nPositionX = n5Pos;
+ long nPositionY = n5Pos;
+
+ // position the image which indicates the type
+ m_aTypeImage.SetPosPixel( Point( nPositionX, nPositionY ) );
+ Size aImageSize( m_aTypeImage.GetImage().GetSizePixel() );
+ m_aTypeImage.SetSizePixel( aImageSize );
+
+ if ( nTitleHeight < aImageSize.Height() )
+ nTitleHeight = aImageSize.Height();
+
+ nPositionX += aImageSize.Width() + CalcZoom( 2 );
+ m_aTitle.SetPosSizePixel( Point( nPositionX, nPositionY ), Size( aOutSize.Width() - nPositionX - n5Pos, nTitleHeight ) );
+
+ long nTitleToList = CalcZoom( 3 );
+
+ m_pListBox->SetPosSizePixel(
+ Point( n5Pos, nPositionY + nTitleHeight + nTitleToList ),
+ Size( aOutSize.Width() - 2 * n5Pos, aOutSize.Height() - ( nPositionY + nTitleHeight + nTitleToList ) - n5Pos )
+ );
+
+ Window::Invalidate();
+}
+
+//------------------------------------------------------------------------------
+void OTableWindow::SetBoldTitle( sal_Bool bBold )
+{
+ Font aFont = m_aTitle.GetFont();
+ aFont.SetWeight( bBold?WEIGHT_BOLD:WEIGHT_NORMAL );
+ m_aTitle.SetFont( aFont );
+ m_aTitle.Invalidate();
+}
+
+//------------------------------------------------------------------------------
+void OTableWindow::GetFocus()
+{
+ Window::GetFocus();
+ // we have to forward the focus to our listbox to enable keystokes
+ if(m_pListBox)
+ m_pListBox->GrabFocus();
+}
+// -----------------------------------------------------------------------------
+void OTableWindow::setActive(sal_Bool _bActive)
+{
+ SetBoldTitle( _bActive );
+ m_bActive = _bActive;
+ if (!_bActive && m_pListBox && m_pListBox->GetSelectionCount() != 0)
+ m_pListBox->SelectAll(sal_False);
+}
+
+//------------------------------------------------------------------------------
+void OTableWindow::Remove()
+{
+ //////////////////////////////////////////////////////////////////
+ // Fenster loeschen
+ OJoinTableView* pTabWinCont = getTableView();
+ pTabWinCont->RemoveTabWin( this );
+ pTabWinCont->Invalidate();
+}
+//------------------------------------------------------------------------------
+sal_Bool OTableWindow::HandleKeyInput( const KeyEvent& rEvt )
+{
+ const KeyCode& rCode = rEvt.GetKeyCode();
+ sal_uInt16 nCode = rCode.GetCode();
+ sal_Bool bShift = rCode.IsShift();
+ sal_Bool bCtrl = rCode.IsMod1();
+
+ sal_Bool bHandle = sal_False;
+
+ if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
+ {
+ Remove();
+ bHandle = sal_True;
+ }
+ return bHandle;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OTableWindow::ExistsAConn() const
+{
+ return getTableView()->ExistsAConn(this);
+}
+//------------------------------------------------------------------------------
+void OTableWindow::EnumValidFields(::std::vector< ::rtl::OUString>& arrstrFields)
+{
+ arrstrFields.clear();
+ // diese Default-Implementierung zaehlt einfach alles auf, was es in der ListBox gibt ... fuer anderes Verhalten ueberschreiben
+ if ( m_pListBox )
+ {
+ arrstrFields.reserve(m_pListBox->GetEntryCount());
+ SvLBoxEntry* pEntryLoop = m_pListBox->First();
+ while (pEntryLoop)
+ {
+ arrstrFields.push_back(m_pListBox->GetEntryText(pEntryLoop));
+ pEntryLoop = m_pListBox->Next(pEntryLoop);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void OTableWindow::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_ZOOM )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Font aFont = rStyleSettings.GetGroupFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+
+ m_aTitle.SetZoom(GetZoom());
+ m_pListBox->SetZoom(GetZoom());
+ Resize();
+ Invalidate();
+ }
+}
+// -----------------------------------------------------------------------------
+Reference< XAccessible > OTableWindow::CreateAccessible()
+{
+ OTableWindowAccess* pAccessible = new OTableWindowAccess(this);
+ m_pAccessible = pAccessible;
+ return pAccessible;
+}
+// -----------------------------------------------------------------------------
+void OTableWindow::Command(const CommandEvent& rEvt)
+{
+ switch (rEvt.GetCommand())
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ OJoinController& rController = getDesignView()->getController();
+ if(!rController.isReadOnly() && rController.isConnected())
+ {
+ Point ptWhere;
+ if ( rEvt.IsMouseEvent() )
+ ptWhere = rEvt.GetMousePosPixel();
+ else
+ {
+ SvLBoxEntry* pCurrent = m_pListBox->GetCurEntry();
+ if ( pCurrent )
+ ptWhere = m_pListBox->GetEntryPosition(pCurrent);
+ else
+ ptWhere = m_aTitle.GetPosPixel();
+ }
+
+ PopupMenu aContextMenu(ModuleRes(RID_MENU_JOINVIEW_TABLE));
+ switch (aContextMenu.Execute(this, ptWhere))
+ {
+ case SID_DELETE:
+ Remove();
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ Window::Command(rEvt);
+ }
+}
+// -----------------------------------------------------------------------------
+long OTableWindow::PreNotify(NotifyEvent& rNEvt)
+{
+ sal_Bool bHandled = sal_False;
+ switch (rNEvt.GetType())
+ {
+ case EVENT_KEYINPUT:
+ {
+ if ( getDesignView()->getController().isReadOnly() )
+ break;
+
+ const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ const KeyCode& rCode = pKeyEvent->GetKeyCode();
+ if ( rCode.IsMod1() )
+ {
+ Point aStartPoint = GetPosPixel();
+ if ( rCode.IsShift() )
+ {
+ aStartPoint.X() = GetSizePixel().Width();
+ aStartPoint.Y() = GetSizePixel().Height();
+ }
+
+ switch( rCode.GetCode() )
+ {
+ case KEY_DOWN:
+ bHandled = sal_True;
+ aStartPoint.Y() += m_nMoveIncrement;
+ break;
+ case KEY_UP:
+ bHandled = sal_True;
+ aStartPoint.Y() += -m_nMoveIncrement;
+ break;
+ case KEY_LEFT:
+ bHandled = sal_True;
+ aStartPoint.X() += -m_nMoveIncrement;
+ break;
+ case KEY_RIGHT:
+ bHandled = sal_True;
+ aStartPoint.X() += m_nMoveIncrement;
+ break;
+ }
+ if ( bHandled )
+ {
+ if ( rCode.IsShift() )
+ {
+ OJoinTableView* pView = getTableView();
+ Point ptOld = GetPosPixel();
+ Size aSize = pView->getRealOutputSize();
+ Size aNewSize(aStartPoint.X(),aStartPoint.Y());
+ if ( ((ptOld.X() + aNewSize.Width()) <= aSize.Width())
+ && ((ptOld.Y() + aNewSize.Height()) <= aSize.Height()) )
+ {
+ if ( aNewSize.Width() < TABWIN_WIDTH_MIN )
+ aNewSize.Width() = TABWIN_WIDTH_MIN;
+ if ( aNewSize.Height() < TABWIN_HEIGHT_MIN )
+ aNewSize.Height() = TABWIN_HEIGHT_MIN;
+
+ Size szOld = GetSizePixel();
+
+ aNewSize = Size(pView->CalcZoom(aNewSize.Width()),pView->CalcZoom(aNewSize.Height()));
+ SetPosSizePixel( ptOld, aNewSize );
+ pView->TabWinSized(this, ptOld, szOld);
+ Invalidate( INVALIDATE_NOCHILDREN );
+ }
+ }
+ else
+ {
+ // remember how often the user moved our window
+ ++m_nMoveCount;
+ if( m_nMoveCount == 5 )
+ m_nMoveIncrement = 10;
+ else if( m_nMoveCount > 15 )
+ m_nMoveCount = m_nMoveIncrement = 20;
+
+ Point aOldDataPoint = GetData()->GetPosition();
+ Point aNewDataPoint = aStartPoint + getTableView()->GetScrollOffset();
+ if ( aNewDataPoint.X() > -1 && aNewDataPoint.Y() > -1 )
+ {
+ OJoinTableView* pView = getTableView();
+ if ( pView->isMovementAllowed(aNewDataPoint, GetData()->GetSize()) )
+ {
+ SetPosPixel(aStartPoint);
+
+ // aNewDataPoint can not be used here because SetPosPixel reset it
+ pView->EnsureVisible(GetData()->GetPosition(), GetData()->GetSize());
+ pView->TabWinMoved(this,aOldDataPoint);
+ Invalidate(INVALIDATE_NOCHILDREN);
+ getDesignView()->getController().setModified( sal_True );
+ }
+ else
+ {
+ m_nMoveCount = 0; // reset our movement count
+ m_nMoveIncrement = 1;
+ }
+ }
+ else
+ {
+ m_nMoveCount = 0; // reset our movement count
+ m_nMoveIncrement = 1;
+ }
+ }
+ resetSizingFlag();
+ }
+ else
+ {
+ m_nMoveCount = 0; // reset our movement count
+ m_nMoveIncrement = 1;
+ }
+ }
+ else
+ {
+ m_nMoveCount = 0; // reset our movement count
+ m_nMoveIncrement = 1;
+ }
+ }
+ break;
+ case EVENT_KEYUP:
+ {
+ const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ const KeyCode& rCode = pKeyEvent->GetKeyCode();
+ sal_uInt16 nKeyCode = rCode.GetCode();
+ if ( rCode.IsMod2() && nKeyCode != KEY_UP && nKeyCode != KEY_DOWN && nKeyCode != KEY_LEFT && nKeyCode != KEY_RIGHT )
+ {
+ m_nMoveCount = 0; // reset our movement count
+ m_nMoveIncrement = 1;
+ }
+ }
+ break;
+ }
+ if (!bHandled)
+ return Window::PreNotify(rNEvt);
+ return 1L;
+}
+// -----------------------------------------------------------------------------
+String OTableWindow::getTitle() const
+{
+ return m_aTitle.GetText();
+}
+// -----------------------------------------------------------------------------
+void OTableWindow::_elementInserted( const container::ContainerEvent& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException)
+{
+ FillListBox();
+}
+// -----------------------------------------------------------------------------
+void OTableWindow::_elementRemoved( const container::ContainerEvent& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException)
+{
+ FillListBox();
+}
+// -----------------------------------------------------------------------------
+void OTableWindow::_elementReplaced( const container::ContainerEvent& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException)
+{
+ FillListBox();
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableWindowAccess.cxx b/dbaccess/source/ui/querydesign/TableWindowAccess.cxx
new file mode 100644
index 000000000000..44b3953b57e8
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableWindowAccess.cxx
@@ -0,0 +1,294 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "TableWindowAccess.hxx"
+#include "JAccess.hxx"
+#include "TableWindow.hxx"
+#include "TableWindowListBox.hxx"
+#include "JoinDesignView.hxx"
+#include "JoinController.hxx"
+#include "JoinTableView.hxx"
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <comphelper/sequence.hxx>
+#include "dbu_qry.hrc"
+
+
+namespace dbaui
+{
+ using namespace ::com::sun::star::accessibility;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star;
+
+ OTableWindowAccess::OTableWindowAccess(OTableWindow* _pTable)
+ :VCLXAccessibleComponent(_pTable->GetComponentInterface().is() ? _pTable->GetWindowPeer() : NULL)
+ ,m_pTable(_pTable)
+ {
+ }
+ // -----------------------------------------------------------------------------
+ void SAL_CALL OTableWindowAccess::disposing()
+ {
+ m_pTable = NULL;
+ VCLXAccessibleComponent::disposing();
+ }
+ // -----------------------------------------------------------------------------
+ void OTableWindowAccess::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
+ {
+ if ( rVclWindowEvent.GetId() == VCLEVENT_OBJECT_DYING )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_pTable = NULL;
+ }
+
+ VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
+ }
+ // -----------------------------------------------------------------------------
+ Any SAL_CALL OTableWindowAccess::queryInterface( const Type& aType ) throw (RuntimeException)
+ {
+ Any aRet(VCLXAccessibleComponent::queryInterface( aType ));
+ return aRet.hasValue() ? aRet : OTableWindowAccess_BASE::queryInterface( aType );
+ }
+ // -----------------------------------------------------------------------------
+ Sequence< Type > SAL_CALL OTableWindowAccess::getTypes( ) throw (RuntimeException)
+ {
+ return ::comphelper::concatSequences(VCLXAccessibleComponent::getTypes(),OTableWindowAccess_BASE::getTypes());
+ }
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OTableWindowAccess::getImplementationName() throw(RuntimeException)
+ {
+ return getImplementationName_Static();
+ }
+ // -----------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL OTableWindowAccess::getSupportedServiceNames() throw(RuntimeException)
+ {
+ return getSupportedServiceNames_Static();
+ }
+ // -----------------------------------------------------------------------------
+ // XServiceInfo - static methods
+ Sequence< ::rtl::OUString > OTableWindowAccess::getSupportedServiceNames_Static(void) throw( RuntimeException )
+ {
+ Sequence< ::rtl::OUString > aSupported(2);
+ aSupported[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.Accessible"));
+ aSupported[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext"));
+ return aSupported;
+ }
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString OTableWindowAccess::getImplementationName_Static(void) throw( RuntimeException )
+ {
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.TableWindowAccessibility"));
+ }
+ // -----------------------------------------------------------------------------
+ // XAccessibleContext
+ sal_Int32 SAL_CALL OTableWindowAccess::getAccessibleChildCount( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ sal_Int32 nCount = 0;
+ if(m_pTable)
+ {
+ if(m_pTable->GetTitleCtrl())
+ ++nCount;
+ if(m_pTable->GetListBox())
+ ++nCount;
+ }
+ return nCount;
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessible > SAL_CALL OTableWindowAccess::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ Reference< XAccessible > aRet;
+ if(m_pTable)
+ {
+ switch(i)
+ {
+ case 0:
+ if(m_pTable->GetTitleCtrl())
+ {
+ aRet = m_pTable->GetTitleCtrl()->GetAccessible();
+ break;
+ } // fall through if title control does not exist
+ case 1:
+ if(m_pTable->GetListBox())
+ aRet = m_pTable->GetListBox()->GetAccessible();
+ break;
+ default:
+ throw IndexOutOfBoundsException();
+ }
+ }
+ return aRet;
+ }
+ // -----------------------------------------------------------------------------
+ sal_Int32 SAL_CALL OTableWindowAccess::getAccessibleIndexInParent( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ sal_Int32 nIndex = -1;
+ if( m_pTable )
+ {
+ // search the postion of our table window in the table window map
+ OJoinTableView::OTableWindowMap* pMap = m_pTable->getTableView()->GetTabWinMap();
+ OJoinTableView::OTableWindowMap::iterator aIter = pMap->begin();
+ OJoinTableView::OTableWindowMap::iterator aEnd = pMap->end();
+ for (nIndex = 0; aIter != aEnd && aIter->second != m_pTable; ++nIndex,++aIter)
+ ;
+ nIndex = aIter != aEnd ? nIndex : -1;
+ }
+ return nIndex;
+ }
+ // -----------------------------------------------------------------------------
+ sal_Int16 SAL_CALL OTableWindowAccess::getAccessibleRole( ) throw (RuntimeException)
+ {
+ return AccessibleRole::PANEL; // ? or may be an AccessibleRole::WINDOW
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessibleRelationSet > SAL_CALL OTableWindowAccess::getAccessibleRelationSet( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return this;
+ }
+ // -----------------------------------------------------------------------------
+ // XAccessibleComponent
+ Reference< XAccessible > SAL_CALL OTableWindowAccess::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ Reference< XAccessible > aRet;
+ if( m_pTable )
+ {
+ Point aPoint(_aPoint.X,_aPoint.Y);
+ Rectangle aRect(m_pTable->GetDesktopRectPixel());
+ if( aRect.IsInside(aPoint) )
+ aRet = this;
+ else if( m_pTable->GetListBox()->GetDesktopRectPixel().IsInside(aPoint))
+ aRet = m_pTable->GetListBox()->GetAccessible();
+ }
+ return aRet;
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessible > OTableWindowAccess::getParentChild(sal_Int32 _nIndex)
+ {
+ Reference< XAccessible > xReturn;
+ Reference< XAccessible > xParent = getAccessibleParent();
+ if ( xParent.is() )
+ {
+ Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext();
+ if ( xParentContext.is() )
+ {
+ xReturn = xParentContext->getAccessibleChild(_nIndex);
+ }
+ }
+ return xReturn;
+ }
+ // -----------------------------------------------------------------------------
+
+ sal_Int32 SAL_CALL OTableWindowAccess::getRelationCount( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return m_pTable ? m_pTable->getTableView()->getConnectionCount(m_pTable) : sal_Int32(0);
+ }
+ // -----------------------------------------------------------------------------
+ AccessibleRelation SAL_CALL OTableWindowAccess::getRelation( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if( nIndex < 0 || nIndex >= getRelationCount() )
+ throw IndexOutOfBoundsException();
+
+ AccessibleRelation aRet;
+ if( m_pTable )
+ {
+ OJoinTableView* pView = m_pTable->getTableView();
+ ::std::vector<OTableConnection*>::const_iterator aIter = pView->getTableConnections(m_pTable) + nIndex;
+ aRet.TargetSet.realloc(1);
+ aRet.TargetSet[0] = getParentChild(aIter - pView->getTableConnections()->begin());
+ aRet.RelationType = AccessibleRelationType::CONTROLLER_FOR;
+ }
+ return aRet;
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool SAL_CALL OTableWindowAccess::containsRelation( sal_Int16 aRelationType ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return AccessibleRelationType::CONTROLLER_FOR == aRelationType
+ && m_pTable && m_pTable->getTableView()->ExistsAConn(m_pTable);
+ }
+ // -----------------------------------------------------------------------------
+ AccessibleRelation SAL_CALL OTableWindowAccess::getRelationByType( sal_Int16 aRelationType ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if( AccessibleRelationType::CONTROLLER_FOR == aRelationType && m_pTable)
+ {
+ OJoinTableView* pView = m_pTable->getTableView();
+ const ::std::vector<OTableConnection*>* pConnectionList = pView->getTableConnections();
+
+ ::std::vector<OTableConnection*>::const_iterator aIter = pView->getTableConnections(m_pTable);
+ ::std::vector<OTableConnection*>::const_iterator aEnd = pConnectionList->end();
+ ::std::vector< Reference<XInterface> > aRelations;
+ aRelations.reserve(5); // just guessing
+ for (; aIter != aEnd ; ++aIter )
+ aRelations.push_back(getParentChild(aIter - pConnectionList->begin()));
+
+ Reference<XInterface> *pRelations = aRelations.empty() ? 0 : &aRelations[0];
+ Sequence< Reference<XInterface> > aSeq(pRelations, aRelations.size());
+ return AccessibleRelation(AccessibleRelationType::CONTROLLER_FOR,aSeq);
+ }
+ return AccessibleRelation();
+ }
+ // -----------------------------------------------------------------------------
+ sal_Bool OTableWindowAccess::isEditable() const
+ {
+ return m_pTable && !m_pTable->getTableView()->getDesignView()->getController().isReadOnly();
+ }
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OTableWindowAccess::getTitledBorderText( ) throw (RuntimeException)
+ {
+ return getAccessibleName( );
+ }
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL OTableWindowAccess::getAccessibleName( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ ::rtl::OUString sAccessibleName;
+ if ( m_pTable )
+ sAccessibleName = m_pTable->getTitle();
+ return sAccessibleName;
+ }
+ // -----------------------------------------------------------------------------
+ Reference< XAccessibleContext > SAL_CALL OTableWindowAccess::getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ return this;
+ }
+ // -----------------------------------------------------------------------------
+
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableWindowData.cxx b/dbaccess/source/ui/querydesign/TableWindowData.cxx
new file mode 100644
index 000000000000..56cad8c62fff
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableWindowData.cxx
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "TableWindowData.hxx"
+#include <tools/debug.hxx>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+
+using namespace dbaui;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+
+//==================================================================
+// class OTableWindowData
+//==================================================================
+DBG_NAME(OTableWindowData)
+//------------------------------------------------------------------------------
+OTableWindowData::OTableWindowData( const Reference< XPropertySet>& _xTable
+ ,const ::rtl::OUString& _rComposedName
+ ,const ::rtl::OUString& rTableName
+ ,const ::rtl::OUString& rWinName )
+ :m_xTable(_xTable)
+ ,m_aTableName( rTableName )
+ ,m_aWinName( rWinName )
+ ,m_sComposedName(_rComposedName)
+ ,m_aPosition( Point(-1,-1) )
+ ,m_aSize( Size(-1,-1) )
+ ,m_bShowAll( sal_True )
+ ,m_bIsQuery(false)
+ ,m_bIsValid(true)
+{
+ DBG_CTOR(OTableWindowData,NULL);
+ if( !m_aWinName.getLength() )
+ m_aWinName = m_aTableName;
+
+ listen();
+}
+
+//------------------------------------------------------------------------------
+OTableWindowData::~OTableWindowData()
+{
+ DBG_DTOR(OTableWindowData,NULL);
+ Reference<XComponent> xComponent( m_xTable, UNO_QUERY );
+ if ( xComponent.is() )
+ stopComponentListening( xComponent );
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OTableWindowData::HasPosition() const
+{
+ return ( (m_aPosition.X() != -1) && (m_aPosition.Y() != -1) );
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OTableWindowData::HasSize() const
+{
+ return ( (m_aSize.Width() != -1) && (m_aSize.Height() !=-1) );
+}
+// -----------------------------------------------------------------------------
+void OTableWindowData::_disposing( const ::com::sun::star::lang::EventObject& /*_rSource*/ )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ // it doesn't matter which one was disposed
+ m_xColumns.clear();
+ m_xKeys.clear();
+ m_xTable.clear();
+}
+// -----------------------------------------------------------------------------
+bool OTableWindowData::init(const Reference< XConnection >& _xConnection,bool _bAllowQueries)
+{
+ OSL_ENSURE(!m_xTable.is(),"We are already connected to a table!");
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ Reference< XQueriesSupplier > xSupQueries( _xConnection, UNO_QUERY_THROW );
+ Reference< XNameAccess > xQueries( xSupQueries->getQueries(), UNO_QUERY_THROW );
+ bool bIsKnownQuery = _bAllowQueries && xQueries->hasByName( m_sComposedName );
+
+ Reference< XTablesSupplier > xSupTables( _xConnection, UNO_QUERY_THROW );
+ Reference< XNameAccess > xTables( xSupTables->getTables(), UNO_QUERY_THROW );
+ bool bIsKnownTable = xTables->hasByName( m_sComposedName );
+
+ if ( bIsKnownQuery )
+ m_xTable.set( xQueries->getByName( m_sComposedName ), UNO_QUERY );
+ else if ( bIsKnownTable )
+ m_xTable.set( xTables->getByName( m_sComposedName ), UNO_QUERY );
+ else
+ m_bIsValid = false;
+
+ // if we survived so far, we know whether it's a query
+ m_bIsQuery = bIsKnownQuery;
+
+ listen();
+
+ Reference< XIndexAccess > xColumnsAsIndex( m_xColumns,UNO_QUERY );
+ return xColumnsAsIndex.is() && ( xColumnsAsIndex->getCount() > 0 );
+}
+// -----------------------------------------------------------------------------
+void OTableWindowData::listen()
+{
+ if ( m_xTable.is() )
+ {
+ // listen for the object being disposed
+ Reference<XComponent> xComponent( m_xTable, UNO_QUERY );
+ if ( xComponent.is() )
+ startComponentListening( xComponent );
+
+ // obtain the columns
+ Reference< XColumnsSupplier > xColumnsSups( m_xTable, UNO_QUERY);
+ if ( xColumnsSups.is() )
+ m_xColumns = xColumnsSups->getColumns();
+
+ Reference<XKeysSupplier> xKeySup(m_xTable,UNO_QUERY);
+ if ( xKeySup.is() )
+ m_xKeys = xKeySup->getKeys();
+ }
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableWindowListBox.cxx b/dbaccess/source/ui/querydesign/TableWindowListBox.cxx
new file mode 100644
index 000000000000..9d0f29701421
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableWindowListBox.cxx
@@ -0,0 +1,402 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "TableWindowListBox.hxx"
+#include "TableWindow.hxx"
+#include "QueryDesignView.hxx"
+#include "QueryTableView.hxx"
+#include "querycontroller.hxx"
+#include "JoinExchange.hxx"
+#include <osl/diagnose.h>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include <svx/dbexch.hrc>
+#include <vcl/svapp.hxx>
+
+using namespace dbaui;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::datatransfer;
+
+OJoinExchangeData::OJoinExchangeData(OTableWindowListBox* pBox)
+ : pListBox(pBox)
+ , pEntry(pBox->FirstSelected())
+{ }
+
+const sal_uLong SCROLLING_TIMESPAN = 500;
+const long LISTBOX_SCROLLING_AREA = 6;
+//==================================================================
+// class OTableWindowListBox
+//==================================================================
+DBG_NAME(OTableWindowListBox)
+//------------------------------------------------------------------------------
+OTableWindowListBox::OTableWindowListBox( OTableWindow* pParent )
+ :SvTreeListBox( pParent, WB_HASBUTTONS | WB_BORDER)
+ ,m_aMousePos( Point(0,0) )
+ ,m_pTabWin( pParent )
+ ,m_nDropEvent(0)
+ ,m_nUiEvent(0)
+ ,m_bReallyScrolled( sal_False )
+{
+ DBG_CTOR(OTableWindowListBox,NULL);
+ m_aScrollTimer.SetTimeout( SCROLLING_TIMESPAN );
+ SetDoubleClickHdl( LINK(this, OTableWindowListBox, OnDoubleClick) );
+
+ SetSelectionMode(SINGLE_SELECTION);
+
+ SetHighlightRange( );
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowListBox::dragFinished( )
+{
+ // first show the error msg when existing
+ m_pTabWin->getDesignView()->getController().showError(m_pTabWin->getDesignView()->getController().clearOccurredError());
+ // second look for ui activities which should happen after d&d
+ if (m_nUiEvent)
+ Application::RemoveUserEvent(m_nUiEvent);
+ m_nUiEvent = Application::PostUserEvent(LINK(this, OTableWindowListBox, LookForUiHdl));
+}
+
+//------------------------------------------------------------------------------
+OTableWindowListBox::~OTableWindowListBox()
+{
+ DBG_DTOR(OTableWindowListBox,NULL);
+ if (m_nDropEvent)
+ Application::RemoveUserEvent(m_nDropEvent);
+ if (m_nUiEvent)
+ Application::RemoveUserEvent(m_nUiEvent);
+ if( m_aScrollTimer.IsActive() )
+ m_aScrollTimer.Stop();
+ m_pTabWin = NULL;
+}
+
+//------------------------------------------------------------------------------
+SvLBoxEntry* OTableWindowListBox::GetEntryFromText( const String& rEntryText )
+{
+ //////////////////////////////////////////////////////////////////////
+ // Liste durchiterieren
+ SvTreeList* pTreeList = GetModel();
+ SvLBoxEntry* pEntry = (SvLBoxEntry*)pTreeList->First();
+ OJoinDesignView* pView = m_pTabWin->getDesignView();
+ OJoinController& rController = pView->getController();
+
+ sal_Bool bCase = sal_False;
+ try
+ {
+ Reference<XConnection> xConnection = rController.getConnection();
+ if(xConnection.is())
+ {
+ Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
+ if(xMeta.is())
+ bCase = xMeta->supportsMixedCaseQuotedIdentifiers();
+ }
+ while( pEntry )
+ {
+ if((bCase ? rEntryText == GetEntryText(pEntry) : rEntryText.EqualsIgnoreCaseAscii(GetEntryText(pEntry))))
+ {
+ return pEntry;
+ }
+ pEntry = (SvLBoxEntry*)pTreeList->Next( pEntry );
+ }
+ }
+ catch(SQLException&)
+ {
+ }
+
+ return NULL;
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowListBox::NotifyScrolled()
+{
+ m_bReallyScrolled = sal_True;
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowListBox::NotifyEndScroll()
+{
+ if (m_bReallyScrolled)
+ // die Verbindungen, die diese Tabelle eventuell hat, muessen neu gezeichnet werden
+ m_pTabWin->getTableView()->Invalidate(INVALIDATE_NOCHILDREN);
+ // ohne das INVALIDATE_NOCHILDREN wuerden auch alle Tabellen neu gezeichnet werden,
+ // sprich : es flackert
+ m_bReallyScrolled = sal_False;
+}
+
+//------------------------------------------------------------------------------
+long OTableWindowListBox::PreNotify(NotifyEvent& rNEvt)
+{
+ sal_Bool bHandled = sal_False;
+ switch (rNEvt.GetType())
+ {
+ case EVENT_KEYINPUT:
+ {
+ const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ const KeyCode& rCode = pKeyEvent->GetKeyCode();
+
+ if (rCode.GetCode() != KEY_RETURN)
+ {
+ if(m_pTabWin)
+ {
+ bHandled = m_pTabWin->HandleKeyInput(*pKeyEvent);
+ }
+ break;
+ }
+
+ if (rCode.IsMod1() || rCode.IsMod2() || rCode.IsShift())
+ break;
+ if (FirstSelected())
+ static_cast<OTableWindow*>(Window::GetParent())->OnEntryDoubleClicked(FirstSelected());
+ }
+ break;
+ }
+
+ if (!bHandled)
+ return SvTreeListBox::PreNotify(rNEvt);
+ return 1L;
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( OTableWindowListBox, ScrollUpHdl, SvTreeListBox*, /*pBox*/ )
+{
+ SvLBoxEntry* pEntry = GetEntry( m_aMousePos );
+ if( !pEntry )
+ return 0;
+
+ if( pEntry != Last() )
+ {
+ ScrollOutputArea( -1 );
+ pEntry = GetEntry( m_aMousePos );
+ Select( pEntry, sal_True );
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( OTableWindowListBox, ScrollDownHdl, SvTreeListBox*, /*pBox*/ )
+{
+ SvLBoxEntry* pEntry = GetEntry( m_aMousePos );
+ if( !pEntry )
+ return 0;
+
+ if( pEntry != Last() )
+ {
+ ScrollOutputArea( 1 );
+ pEntry = GetEntry( m_aMousePos );
+ Select( pEntry, sal_True );
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowListBox::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
+{
+ OJoinTableView* pCont = m_pTabWin->getTableView();
+ if (!pCont->getDesignView()->getController().isReadOnly() && pCont->getDesignView()->getController().isConnected())
+ {
+ // asterix was not allowed to be copied to selection browsebox
+ sal_Bool bFirstNotAllowed = FirstSelected() == First() && m_pTabWin->GetData()->IsShowAll();
+ EndSelection();
+ // create a description of the source
+ OJoinExchangeData jxdSource(this);
+ // put it into a exchange object
+ OJoinExchObj* pJoin = new OJoinExchObj(jxdSource,bFirstNotAllowed);
+ Reference< XTransferable > xEnsureDelete(pJoin);
+ pJoin->StartDrag(this, DND_ACTION_LINK, this);
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Int8 OTableWindowListBox::AcceptDrop( const AcceptDropEvent& _rEvt )
+{
+ sal_Int8 nDND_Action = DND_ACTION_NONE;
+ // check the format
+ if ( !OJoinExchObj::isFormatAvailable(GetDataFlavorExVector(),SOT_FORMATSTR_ID_SBA_TABID) // this means that the first entry is to be draged
+ && OJoinExchObj::isFormatAvailable(GetDataFlavorExVector(),SOT_FORMATSTR_ID_SBA_JOIN) )
+ { // don't drop into the window if it's the drag source itself
+
+ // remove the selection if the dragging operation is leaving the window
+ if (_rEvt.mbLeaving)
+ SelectAll(sal_False);
+ else
+ {
+ // hit test
+ m_aMousePos = _rEvt.maPosPixel;
+ Size aOutputSize = GetOutputSizePixel();
+ SvLBoxEntry* pEntry = GetEntry( m_aMousePos );
+ if( !pEntry )
+ return DND_ACTION_NONE;
+
+ // Scrolling Areas
+ Rectangle aBottomScrollArea( Point(0, aOutputSize.Height()-LISTBOX_SCROLLING_AREA),
+ Size(aOutputSize.Width(), LISTBOX_SCROLLING_AREA) );
+ Rectangle aTopScrollArea( Point(0,0), Size(aOutputSize.Width(), LISTBOX_SCROLLING_AREA) );
+
+ // Wenn Zeiger auf der oberen ScrollingArea steht, nach oben scrollen
+ if( aBottomScrollArea.IsInside(m_aMousePos) )
+ {
+ if( !m_aScrollTimer.IsActive() )
+ {
+ m_aScrollTimer.SetTimeoutHdl( LINK(this, OTableWindowListBox, ScrollUpHdl) );
+ ScrollUpHdl( this );
+ }
+ }
+
+ // Wenn Zeiger auf der oberen ScrollingArea steht, nach unten scrollen
+ else if( aTopScrollArea.IsInside(m_aMousePos) )
+ {
+ if( !m_aScrollTimer.IsActive() )
+ {
+ m_aScrollTimer.SetTimeoutHdl( LINK(this, OTableWindowListBox, ScrollDownHdl) );
+ ScrollDownHdl( this );
+ }
+ }
+ else
+ {
+ if( m_aScrollTimer.IsActive() )
+ m_aScrollTimer.Stop();
+ }
+
+ // Beim Drag automatisch den richtigen Eintrag selektieren
+ if ((FirstSelected() != pEntry) || (FirstSelected() && NextSelected(FirstSelected())))
+ SelectAll(sal_False);
+ Select(pEntry, sal_True);
+
+ // Auf den ersten Eintrag (*) kann nicht gedroppt werden
+ if(!( m_pTabWin->GetData()->IsShowAll() && (pEntry==First()) ))
+ nDND_Action = DND_ACTION_LINK;
+ }
+ }
+ return nDND_Action;
+}
+// -----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+IMPL_LINK( OTableWindowListBox, LookForUiHdl, void *, /*EMPTY_ARG*/)
+{
+ m_nUiEvent = 0;
+ m_pTabWin->getTableView()->lookForUiActivities();
+ return 0L;
+}
+//------------------------------------------------------------------------------
+IMPL_LINK( OTableWindowListBox, DropHdl, void *, /*EMPTY_ARG*/)
+{
+ // create the connection
+ m_nDropEvent = 0;
+ OSL_ENSURE(m_pTabWin,"No TableWindow!");
+ try
+ {
+ OJoinTableView* pCont = m_pTabWin->getTableView();
+ OSL_ENSURE(pCont,"No QueryTableView!");
+ pCont->AddConnection(m_aDropInfo.aSource, m_aDropInfo.aDest);
+ }
+ catch(const SQLException& e)
+ {
+ // remember the exception so that we can show them later when d&d is finished
+ m_pTabWin->getDesignView()->getController().setErrorOccurred(::dbtools::SQLExceptionInfo(e));
+ }
+ return 0L;
+}
+//------------------------------------------------------------------------------
+sal_Int8 OTableWindowListBox::ExecuteDrop( const ExecuteDropEvent& _rEvt )
+{
+ TransferableDataHelper aDropped(_rEvt.maDropEvent.Transferable);
+ if ( OJoinExchObj::isFormatAvailable(aDropped.GetDataFlavorExVector()))
+ { // don't drop into the window if it's the drag source itself
+ m_aDropInfo.aSource = OJoinExchangeData(this);
+ m_aDropInfo.aDest = OJoinExchObj::GetSourceDescription(_rEvt.maDropEvent.Transferable);
+
+ if (m_nDropEvent)
+ Application::RemoveUserEvent(m_nDropEvent);
+ m_nDropEvent = Application::PostUserEvent(LINK(this, OTableWindowListBox, DropHdl));
+
+ return DND_ACTION_LINK;
+ }
+ return DND_ACTION_NONE;
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowListBox::LoseFocus()
+{
+ if(m_pTabWin)
+ m_pTabWin->setActive(sal_False);
+ SvTreeListBox::LoseFocus();
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowListBox::GetFocus()
+{
+ if(m_pTabWin)
+ m_pTabWin->setActive();
+
+ if (GetCurEntry() != NULL)
+ {
+ if ( GetSelectionCount() == 0 || GetCurEntry() != FirstSelected() )
+ {
+ if ( FirstSelected() )
+ Select(FirstSelected(), sal_False);
+ Select(GetCurEntry(), sal_True);
+ }
+ else
+ ShowFocusRect(FirstSelected());
+ }
+ SvTreeListBox::GetFocus();
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( OTableWindowListBox, OnDoubleClick, SvTreeListBox *, /*pBox*/ )
+{
+ // meinem Elter Bescheid sagen
+ Window* pParent = Window::GetParent();
+ OSL_ENSURE(pParent != NULL, "OTableWindowListBox::OnDoubleClick : habe kein Parent !");
+
+ static_cast<OTableWindow*>(pParent)->OnEntryDoubleClicked(GetHdlEntry());
+
+ return 0;
+}
+// -----------------------------------------------------------------------------
+void OTableWindowListBox::Command(const CommandEvent& rEvt)
+{
+ switch (rEvt.GetCommand())
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ static_cast<OTableWindow*>(Window::GetParent())->Command(rEvt);
+ break;
+ }
+ default:
+ SvTreeListBox::Command(rEvt);
+ }
+}
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/TableWindowTitle.cxx b/dbaccess/source/ui/querydesign/TableWindowTitle.cxx
new file mode 100644
index 000000000000..6c740fb6c52d
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/TableWindowTitle.cxx
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "TableWindowTitle.hxx"
+#include "TableWindow.hxx"
+#include "QueryTableView.hxx"
+#include <vcl/svapp.hxx>
+#include <vcl/help.hxx>
+#include <vcl/menu.hxx>
+#include <tools/debug.hxx>
+#include "dbustrings.hrc"
+#include <sfx2/cntids.hrc>
+#include "TableWindowListBox.hxx"
+#include "TableConnection.hxx"
+#include "dbu_qry.hrc"
+#include "QueryDesignView.hxx"
+#include "JoinController.hxx"
+
+#include <algorithm>
+
+using namespace dbaui;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+//==================================================================
+// class OTableWindowTitle
+//==================================================================
+DBG_NAME(OTableWindowTitle)
+//------------------------------------------------------------------------------
+OTableWindowTitle::OTableWindowTitle( OTableWindow* pParent ) :
+ FixedText( pParent, WB_3DLOOK|WB_LEFT|WB_NOLABEL|WB_VCENTER )
+ ,m_pTabWin( pParent )
+{
+ DBG_CTOR(OTableWindowTitle,NULL);
+ // Hintergrund- und Textfarbe setzen
+ StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
+ SetBackground(Wallpaper(Color(aSystemStyle.GetFaceColor())));
+ SetTextColor(aSystemStyle.GetButtonTextColor());
+
+ Font aFont( GetFont() );
+ aFont.SetTransparent( sal_True );
+ SetFont( aFont );
+}
+
+//------------------------------------------------------------------------------
+OTableWindowTitle::~OTableWindowTitle()
+{
+ DBG_DTOR(OTableWindowTitle,NULL);
+ m_pTabWin = NULL;
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowTitle::GetFocus()
+{
+ if(m_pTabWin)
+ m_pTabWin->GetFocus();
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowTitle::LoseFocus()
+{
+ m_pTabWin->LoseFocus();
+}
+//------------------------------------------------------------------------------
+void OTableWindowTitle::RequestHelp( const HelpEvent& rHEvt )
+{
+ if(m_pTabWin)
+ {
+ String aHelpText = m_pTabWin->GetComposedName();
+ if( aHelpText.Len())
+ {
+ // Hilfe anzeigen
+ Rectangle aItemRect(Point(0,0),GetSizePixel());
+ aItemRect = LogicToPixel( aItemRect );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ if( rHEvt.GetMode() == HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aHelpText);
+ else
+ Help::ShowQuickHelp( this, aItemRect, aHelpText );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowTitle::Command( const CommandEvent& rEvt )
+{
+ switch( rEvt.GetCommand() )
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ GrabFocus();
+ if ( m_pTabWin )
+ m_pTabWin->Command( rEvt );
+ else
+ Control::Command(rEvt);
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowTitle::KeyInput( const KeyEvent& rEvt )
+{
+ if ( m_pTabWin )
+ m_pTabWin->KeyInput( rEvt );
+}
+
+//------------------------------------------------------------------------------
+void OTableWindowTitle::MouseButtonDown( const MouseEvent& rEvt )
+{
+ if( rEvt.IsLeft() )
+ {
+ if( rEvt.GetClicks() == 2)
+ {
+ Size aSize(GetTextWidth(GetText()) + 20,
+ m_pTabWin->GetSizePixel().Height() - m_pTabWin->GetListBox()->GetSizePixel().Height());
+
+ aSize.Height() += (m_pTabWin->GetListBox()->GetEntryCount() + 2) * m_pTabWin->GetListBox()->GetEntryHeight();
+ if(m_pTabWin->GetSizePixel() != aSize)
+ {
+ m_pTabWin->SetSizePixel(aSize);
+
+ OJoinTableView* pView = static_cast<OJoinTableView*>(m_pTabWin->getTableView());
+ OSL_ENSURE(pView,"No OJoinTableView!");
+ const ::std::vector<OTableConnection*>* pConns = pView->getTableConnections();
+ ::std::for_each(pConns->begin(),
+ pConns->end(),
+ ::std::mem_fun(&OTableConnection::RecalcLines));
+
+ pView->InvalidateConnections();
+ pView->getDesignView()->getController().setModified(sal_True);
+ pView->Invalidate(INVALIDATE_NOCHILDREN);
+ }
+ }
+ else
+ {
+ Point aPos = rEvt.GetPosPixel();
+ aPos = OutputToScreenPixel( aPos );
+ OJoinTableView* pView = static_cast<OJoinTableView*>(m_pTabWin->getTableView());
+ OSL_ENSURE(pView,"No OJoinTableView!");
+ pView->NotifyTitleClicked( static_cast<OTableWindow*>(GetParent()), aPos );
+ }
+ GrabFocus();
+ }
+ else
+ Control::MouseButtonDown( rEvt );
+}
+
+
+//------------------------------------------------------------------------------
+void OTableWindowTitle::DataChanged(const DataChangedEvent& rDCEvt)
+{
+ if (rDCEvt.GetType() == DATACHANGED_SETTINGS)
+ {
+ // nehmen wir den worst-case an : die Farben haben sich geaendert, also
+ // mich anpassen
+ StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
+ SetBackground(Wallpaper(Color(aSystemStyle.GetFaceColor())));
+ SetTextColor(aSystemStyle.GetButtonTextColor());
+ }
+}
+// -----------------------------------------------------------------------------
+void OTableWindowTitle::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_ZOOM )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Font aFont = rStyleSettings.GetGroupFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+
+ Resize();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/class.jpg b/dbaccess/source/ui/querydesign/class.jpg
new file mode 100644
index 000000000000..b1a3b6d272ad
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/class.jpg
Binary files differ
diff --git a/dbaccess/source/ui/querydesign/makefile.mk b/dbaccess/source/ui/querydesign/makefile.mk
new file mode 100644
index 000000000000..a4a39c36a79c
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJINC=$(PRJ)$/source
+PRJNAME=dbaccess
+TARGET=querydesign
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+EXCEPTIONSFILES =\
+ $(SLO)$/ConnectionLine.obj \
+ $(SLO)$/ConnectionLineAccess.obj \
+ $(SLO)$/JAccess.obj \
+ $(SLO)$/JoinController.obj \
+ $(SLO)$/JoinDesignView.obj \
+ $(SLO)$/JoinExchange.obj \
+ $(SLO)$/JoinTableView.obj \
+ $(SLO)$/QTableConnection.obj \
+ $(SLO)$/QTableConnectionData.obj \
+ $(SLO)$/QTableWindow.obj \
+ $(SLO)$/QTableWindowData.obj \
+ $(SLO)$/QueryDesignView.obj \
+ $(SLO)$/QueryMoveTabWinUndoAct.obj \
+ $(SLO)$/QueryTabConnUndoAction.obj \
+ $(SLO)$/QueryTabWinUndoAct.obj \
+ $(SLO)$/QueryTableView.obj \
+ $(SLO)$/QueryTextView.obj \
+ $(SLO)$/QueryViewSwitch.obj \
+ $(SLO)$/SelectionBrowseBox.obj \
+ $(SLO)$/TableConnection.obj \
+ $(SLO)$/TableConnectionData.obj \
+ $(SLO)$/TableFieldDescription.obj \
+ $(SLO)$/TableWindow.obj \
+ $(SLO)$/TableWindowAccess.obj \
+ $(SLO)$/TableWindowData.obj \
+ $(SLO)$/TableWindowListBox.obj \
+ $(SLO)$/TableWindowTitle.obj \
+ $(SLO)$/querycontainerwindow.obj \
+ $(SLO)$/querycontroller.obj \
+ $(SLO)$/querydlg.obj \
+ $(SLO)$/queryview.obj
+
+SLOFILES =\
+ $(EXCEPTIONSFILES) \
+ $(SLO)$/ConnectionLineData.obj \
+ $(SLO)$/TableFieldInfo.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES = query.src \
+ querydlg.src \
+
+# --- Targets -------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
+$(SRS)$/$(TARGET).srs: $(SOLARINCDIR)$/svx$/globlmn.hrc
+
+
diff --git a/dbaccess/source/ui/querydesign/query.src b/dbaccess/source/ui/querydesign/query.src
new file mode 100644
index 000000000000..aae5a07545ae
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/query.src
@@ -0,0 +1,426 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _DBU_QRY_HRC_
+#include "dbu_qry.hrc"
+#endif
+#ifndef DBAUI_QUERY_HRC
+#include "Query.hrc"
+#endif
+#ifndef _GLOBLMN_HRC
+#include <svx/globlmn.hrc>
+#endif
+#ifndef _CNTIDS_HRC
+#include <sfx2/cntids.hrc>
+#endif
+#ifndef DBACCESS_UI_BROWSER_ID_HXX
+#include "browserids.hxx"
+#endif
+#ifndef _DBA_DBACCESS_HELPID_HRC_
+#include "dbaccess_helpid.hrc"
+#endif
+#ifndef DBAUI_TOOLBOX_HXX
+#include "toolbox.hrc"
+#endif
+
+#define MN_EDIT 20
+#define MN_VIEW 21
+#define MN_EXTRA 22
+#define MN_INSERT 23
+#define MN_WIN 30
+#define MN_HELP 31
+
+Menu RID_MENU_JOINVIEW_CONNECTION
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ ITEM_EDIT_DELETE
+ };
+ MenuItem
+ {
+ MID_DBUI_QUERY_EDIT_JOINCONNECTION
+ };
+ };
+};
+
+Menu RID_MENU_JOINVIEW_TABLE
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ ITEM_EDIT_DELETE
+ };
+ };
+};
+
+Menu RID_QUERYCOLPOPUPMENU
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ MID_COLUMN_WIDTH
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ ITEM_EDIT_DELETE
+ };
+ };
+};
+
+ImageList IMG_JOINS
+{
+ Prefix = "jo";
+ MaskColor = Color { Red = 0xffff; Green = 0x0000; Blue = 0xffff; };
+ IdList = {
+ IMG_PRIMARY_KEY; IMG_FOREIGN_KEY;
+ };
+ IdCount = { 2; };
+};
+
+String STR_QUERY_UNDO_TABWINSHOW
+{
+ Text [ en-US ] = "Add Table Window" ;
+};
+
+String STR_QUERY_UNDO_MOVETABWIN
+{
+ Text [ en-US ] = "Move table window" ;
+};
+String STR_QUERY_UNDO_INSERTCONNECTION
+{
+ Text [ en-US ] = "Insert Join" ;
+};
+
+String STR_QUERY_UNDO_REMOVECONNECTION
+{
+ Text [ en-US ] = "Delete Join" ;
+};
+
+String STR_QUERY_UNDO_SIZETABWIN
+{
+ Text [ en-US ] = "Resize table window" ;
+};
+String STR_QUERY_UNDO_TABFIELDDELETE
+{
+ Text [ en-US ] = "Delete Column" ;
+};
+
+String STR_QUERY_UNDO_TABFIELDMOVED
+{
+ Text [ en-US ] = "Move column";
+};
+
+String STR_QUERY_UNDO_TABFIELDCREATE
+{
+ Text [ en-US ] = "Add Column" ;
+};
+
+String RID_STR_TABLE_DOESNT_EXIST
+{
+ Text [ en-US ] = "Invalid expression, table '$name$' does not exist.";
+};
+
+String RID_STR_FIELD_DOESNT_EXIST
+{
+ Text [ en-US ] = "Invalid expression, field name '$name$' does not exist.";
+};
+
+String RID_STR_TOMUCHTABLES
+{
+ Text [ en-US ] = "The query covers #num# tables. The selected database type, however, can only process a maximum of #maxnum# table(s) per statement.";
+};
+
+String STR_QUERY_UNDO_TABWINDELETE
+{
+ Text [ en-US ] = "Delete Table Window" ;
+};
+
+String STR_QUERY_UNDO_MODIFY_CELL
+{
+ Text [ en-US ] = "Edit Column Description";
+};
+
+String STR_QUERY_UNDO_SIZE_COLUMN
+{
+ Text [ en-US ] = "Adjust column width";
+};
+
+String STR_QUERY_SORTTEXT
+{
+ Text [ en-US ] = "(not sorted);ascending;descending" ;
+};
+
+String STR_QUERY_FUNCTIONS
+{
+ Text [ en-US ] = "(no function);Group";
+};
+
+String STR_QUERY_NOTABLE
+{
+ Text [ en-US ] = "(no table)";
+};
+
+String STR_QRY_ORDERBY_UNRELATED
+{
+ Text [ en-US ] = "The database only supports sorting for visible fields.";
+};
+
+Menu RID_QUERYFUNCTION_POPUPMENU
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = ID_QUERY_FUNCTION ;
+ HelpID = HID_QUERY_FUNCTION;
+ Text [ en-US ] = "Functions";
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = ID_QUERY_TABLENAME ;
+ HelpID = HID_QUERY_TABLENAME ;
+ Text [ en-US ] = "Table Name";
+ };
+ MenuItem
+ {
+ Identifier = ID_QUERY_ALIASNAME ;
+ HelpID = HID_QUERY_ALIASNAME ;
+ Text [ en-US ] = "Alias";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = ID_QUERY_DISTINCT ;
+ HelpID = HID_QUERY_DISTINCT ;
+ Text [ en-US ] = "Distinct Values";
+ };
+ };
+};
+
+String STR_QUERY_HANDLETEXT
+{
+ Text [ en-US ] = "Field;Alias;Table;Sort;Visible;Function;Criterion;Or;Or";
+};
+
+String STR_QRY_TOO_MANY_COLUMNS
+{
+ Text [ en-US ] = "There are too many columns.";
+};
+
+ErrorBox ERR_QRY_CRITERIA_ON_ASTERISK
+{
+ Message [ en-US ] = "A condition cannot be applied to field [*]" ;
+};
+
+String STR_QRY_TOO_LONG_STATEMENT
+{
+ Text [ en-US ] = "The SQL statement created is too long.";
+};
+
+String STR_QRY_TOOCOMPLEX
+{
+ Text [ en-US ] = "Query is too complex" ;
+};
+
+String STR_QRY_NOSELECT
+{
+ Text [ en-US ] = "Nothing has been selected." ;
+};
+
+String STR_QRY_TOOMANYCOND
+{
+ Text [ en-US ] = "Too many search criteria" ;
+};
+
+String STR_QRY_SYNTAX
+{
+ Text [ en-US ] = "SQL syntax error" ;
+};
+
+ErrorBox ERR_QRY_ORDERBY_ON_ASTERISK
+{
+ Message [ en-US ] = "[*] cannot be used as a sort criterion.";
+};
+
+String STR_QUERY_TRUE
+{
+ Text [ en-US ] = "TRUE" ;
+};
+
+String STR_QUERY_FALSE
+{
+ Text [ en-US ] = "FALSE" ;
+};
+
+String STR_QRY_TOO_MANY_TABLES
+{
+ Text [ en-US ] = "There are too many tables.";
+};
+
+String STR_QRY_NATIVE
+{
+ Text [ en-US ] = "The statement will not be applied when querying in the SQL dialect of the database." ;
+};
+
+ErrorBox ERR_QRY_AMB_FIELD
+{
+ Message [ en-US ] = "Field name not found or not unique" ;
+};
+
+String STR_QRY_ILLEGAL_JOIN
+{
+ Text [ en-US ] = "Join could not be processed" ;
+};
+
+String STR_SVT_SQL_SYNTAX_ERROR
+{
+ Text [ en-US ] = "Syntax error in SQL statement" ;
+};
+
+String STR_QUERYDESIGN_NO_VIEW_SUPPORT
+{
+ Text [ en-US ] = "This database does not support table views.";
+};
+
+String STR_NO_ALTER_VIEW_SUPPORT
+{
+ Text [ en-US ] = "This database does not support altering of existing table views.";
+};
+
+String STR_QUERYDESIGN_NO_VIEW_ASK
+{
+ Text [ en-US ] = "Do you want to create a query instead?";
+};
+
+ErrorBox ERR_QRY_NOSTATEMENT
+{
+ Message [ en-US ] = "No query could be created.";
+};
+
+ErrorBox ERR_QRY_NOCRITERIA
+{
+ Message [ en-US ] = "No query could be created because no fields were selected.";
+};
+
+/*
+ The menubar resource has become obsolete - you can now find the menubar definition at: <project>/uiconfig/dbquery/menubar/menubar.xml
+ */
+
+String STR_DATASOURCE_DELETED
+{
+ Text [ en-US ] = "The corresponding data source has been deleted. Therefore, data relevant to that data source cannot be saved.";
+};
+
+String STR_QRY_COLUMN_NOT_FOUND
+{
+ Text [ en-US ] = "The column '$name$' is unknown.";
+};
+
+String STR_QRY_JOIN_COLUMN_COMPARE
+{
+ Text [ en-US ] = "Columns can only be compared using '='.";
+};
+
+String STR_QRY_LIKE_LEFT_NO_COLUMN
+{
+ Text [ en-US ] = "You must use a column name before 'LIKE'.";
+};
+
+String STR_QRY_CHECK_CASESENSITIVE
+{
+ Text [ en-US ] = "The column could not be found. Please note that the database is case-sensitive.";
+};
+
+String STR_QUERYDESIGN
+{
+ Text [ en-US ] = " - %PRODUCTNAME Base: Query Design";
+};
+
+String STR_VIEWDESIGN
+{
+ Text [ en-US ] = " - %PRODUCTNAME Base: View Design";
+};
+
+String STR_QUERY_SAVEMODIFIED
+{
+ Text [ en-US ] = "$object$ has been changed.\nDo you want to save the changes?" ;
+ Text [ x-comment ] = "For $object$, one of the values of the RSC_QUERY_OBJECT_TYPE resource will be inserted.";
+};
+
+String STR_ERROR_PARSING_STATEMENT
+{
+ Text [ en-US ] = "$object$ is based on an SQL command which could not be parsed.";
+ Text [ x-comment ] = "For $object$, one of the values of the RSC_QUERY_OBJECT_TYPE resource "
+ "(except \"SQL command\", which doesn't make sense here) will be inserted.";
+};
+
+String STR_INFO_OPENING_IN_SQL_VIEW
+{
+ Text [ en-US ] = "$object$ will be opened in SQL view.";
+ Text [ x-comment ] = "For $object$, one of the values of the RSC_QUERY_OBJECT_TYPE resource "
+ "(except \"SQL command\", which doesn't make sense here) will be inserted.";
+};
+
+Resource RSC_QUERY_OBJECT_TYPE
+{
+ String 1
+ {
+ Text [ en-US ] = "The table view";
+ };
+ String 2
+ {
+ Text [ en-US ] = "The query";
+ };
+ String 3
+ {
+ Text [ en-US ] = "The SQL statement";
+ };
+};
+
+String STR_STATEMENT_WITHOUT_RESULT_SET
+{
+ Text [ en-US ] = "The query does not create a result set, and thus cannot be part of another query.";
+};
+
+String STR_NO_DATASOURCE_OR_CONNECTION
+{
+ Text [ en-US ] = "Both the ActiveConnection and the DataSourceName parameter are missing or wrong - cannot initialize the query designer.";
+};
diff --git a/dbaccess/source/ui/querydesign/querycontainerwindow.cxx b/dbaccess/source/ui/querydesign/querycontainerwindow.cxx
new file mode 100644
index 000000000000..15fbc7611c75
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/querycontainerwindow.cxx
@@ -0,0 +1,265 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+
+#include "querycontainerwindow.hxx"
+#include "QueryDesignView.hxx"
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include "JoinController.hxx"
+#include <toolkit/unohlp.hxx>
+#include "dbustrings.hrc"
+#include <sfx2/sfxsids.hrc>
+#include <vcl/fixed.hxx>
+#include "UITools.hxx"
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//.........................................................................
+namespace dbaui
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::frame;
+ using namespace ::com::sun::star::beans;
+
+ //=====================================================================
+ //= OQueryContainerWindow
+ //=====================================================================
+ DBG_NAME(OQueryContainerWindow)
+ OQueryContainerWindow::OQueryContainerWindow(Window* pParent, OQueryController& _rController,const Reference< XMultiServiceFactory >& _rFactory)
+ :ODataView( pParent, _rController, _rFactory )
+ ,m_pViewSwitch(NULL)
+ ,m_pBeamer(NULL)
+ {
+ DBG_CTOR(OQueryContainerWindow,NULL);
+ m_pViewSwitch = new OQueryViewSwitch( this, _rController, _rFactory );
+
+ m_pSplitter = new Splitter(this,WB_VSCROLL);
+ m_pSplitter->Hide();
+ m_pSplitter->SetSplitHdl( LINK( this, OQueryContainerWindow, SplitHdl ) );
+ m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) );
+ }
+ // -----------------------------------------------------------------------------
+ OQueryContainerWindow::~OQueryContainerWindow()
+ {
+ DBG_DTOR(OQueryContainerWindow,NULL);
+ {
+ ::std::auto_ptr<OQueryViewSwitch> aTemp(m_pViewSwitch);
+ m_pViewSwitch = NULL;
+ }
+ if ( m_pBeamer )
+ ::dbaui::notifySystemWindow(this,m_pBeamer,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
+ m_pBeamer = NULL;
+ if ( m_xBeamer.is() )
+ {
+ Reference< ::com::sun::star::util::XCloseable > xCloseable(m_xBeamer,UNO_QUERY);
+ m_xBeamer = NULL;
+ if(xCloseable.is())
+ xCloseable->close(sal_False); // false - holds the owner ship of this frame
+ }
+
+ ::std::auto_ptr<Window> aTemp(m_pSplitter);
+ m_pSplitter = NULL;
+
+ }
+ // -----------------------------------------------------------------------------
+ bool OQueryContainerWindow::switchView( ::dbtools::SQLExceptionInfo* _pErrorInfo )
+ {
+ return m_pViewSwitch->switchView( _pErrorInfo );
+ }
+
+ // -----------------------------------------------------------------------------
+ void OQueryContainerWindow::forceInitialView()
+ {
+ return m_pViewSwitch->forceInitialView();
+ }
+
+ // -----------------------------------------------------------------------------
+ void OQueryContainerWindow::resizeAll( const Rectangle& _rPlayground )
+ {
+ Rectangle aPlayground( _rPlayground );
+
+ if ( m_pBeamer && m_pBeamer->IsVisible() )
+ {
+ // calc pos and size of the splitter
+ Point aSplitPos = m_pSplitter->GetPosPixel();
+ Size aSplitSize = m_pSplitter->GetOutputSizePixel();
+ aSplitSize.Width() = aPlayground.GetWidth();
+
+ if ( aSplitPos.Y() <= aPlayground.Top() )
+ aSplitPos.Y() = aPlayground.Top() + sal_Int32( aPlayground.GetHeight() * 0.2 );
+
+ if ( aSplitPos.Y() + aSplitSize.Height() > aPlayground.GetHeight() )
+ aSplitPos.Y() = aPlayground.GetHeight() - aSplitSize.Height();
+
+ // set pos and size of the splitter
+ m_pSplitter->SetPosSizePixel( aSplitPos, aSplitSize );
+ m_pSplitter->SetDragRectPixel( aPlayground );
+
+ // set pos and size of the beamer
+ Size aBeamerSize( aPlayground.GetWidth(), aSplitPos.Y() );
+ m_pBeamer->SetPosSizePixel( aPlayground.TopLeft(), aBeamerSize );
+
+ // shrink the playground by the size which is occupied by the beamer
+ aPlayground.Top() = aSplitPos.Y() + aSplitSize.Height();
+ }
+
+ ODataView::resizeAll( aPlayground );
+ }
+
+ // -----------------------------------------------------------------------------
+ void OQueryContainerWindow::resizeDocumentView( Rectangle& _rPlayground )
+ {
+ m_pViewSwitch->SetPosSizePixel( _rPlayground.TopLeft(), Size( _rPlayground.GetWidth(), _rPlayground.GetHeight() ) );
+
+ ODataView::resizeDocumentView( _rPlayground );
+ }
+
+ // -----------------------------------------------------------------------------
+ void OQueryContainerWindow::GetFocus()
+ {
+ ODataView::GetFocus();
+ if(m_pViewSwitch)
+ m_pViewSwitch->GrabFocus();
+ }
+ // -----------------------------------------------------------------------------
+ IMPL_LINK( OQueryContainerWindow, SplitHdl, void*, /*p*/ )
+ {
+ m_pSplitter->SetPosPixel( Point( m_pSplitter->GetPosPixel().X(),m_pSplitter->GetSplitPosPixel() ) );
+ Resize();
+
+ return 0L;
+ }
+
+ // -----------------------------------------------------------------------------
+ void OQueryContainerWindow::Construct()
+ {
+ m_pViewSwitch->Construct();
+ }
+
+ // -----------------------------------------------------------------------------
+ void OQueryContainerWindow::disposingPreview()
+ {
+ if ( m_pBeamer )
+ {
+ // here I know that we will be destroyed from the frame
+ ::dbaui::notifySystemWindow(this,m_pBeamer,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
+ m_pBeamer = NULL;
+ m_xBeamer = NULL;
+ m_pSplitter->Hide();
+ Resize();
+ }
+ }
+ // -----------------------------------------------------------------------------
+ long OQueryContainerWindow::PreNotify( NotifyEvent& rNEvt )
+ {
+ sal_Bool bHandled = sal_False;
+ switch (rNEvt.GetType())
+ {
+ case EVENT_GETFOCUS:
+ if ( m_pViewSwitch )
+ {
+ OJoinController& rController = m_pViewSwitch->getDesignView()->getController();
+ rController.InvalidateFeature(SID_CUT);
+ rController.InvalidateFeature(SID_COPY);
+ rController.InvalidateFeature(SID_PASTE);
+ }
+ }
+ return bHandled ? 1L : ODataView::PreNotify(rNEvt);
+ }
+ // -----------------------------------------------------------------------------
+ void OQueryContainerWindow::showPreview(const Reference<XFrame>& _xFrame)
+ {
+ if(!m_pBeamer)
+ {
+ m_pBeamer = new OBeamer(this);
+
+ ::dbaui::notifySystemWindow(this,m_pBeamer,::comphelper::mem_fun(&TaskPaneList::AddWindow));
+
+ Reference < XFrame > xBeamerFrame( m_pViewSwitch->getORB()->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Frame"))),UNO_QUERY );
+ m_xBeamer.set( xBeamerFrame );
+ OSL_ENSURE(m_xBeamer.is(),"No frame created!");
+ m_xBeamer->initialize( VCLUnoHelper::GetInterface ( m_pBeamer ) );
+
+ // notify layout manager to not create internal toolbars
+ Reference < XPropertySet > xPropSet( xBeamerFrame, UNO_QUERY );
+ try
+ {
+ const ::rtl::OUString aLayoutManager( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ));
+ Reference < XPropertySet > xLMPropSet(xPropSet->getPropertyValue( aLayoutManager ),UNO_QUERY);
+
+ if ( xLMPropSet.is() )
+ {
+ const ::rtl::OUString aAutomaticToolbars( RTL_CONSTASCII_USTRINGPARAM( "AutomaticToolbars" ));
+ xLMPropSet->setPropertyValue( aAutomaticToolbars, Any( sal_False ));
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ m_xBeamer->setName(FRAME_NAME_QUERY_PREVIEW);
+
+ // append our frame
+ Reference < XFramesSupplier > xSup(_xFrame,UNO_QUERY);
+ Reference < XFrames > xFrames = xSup->getFrames();
+ xFrames->append( m_xBeamer );
+
+ Size aSize = GetOutputSizePixel();
+ Size aBeamer(aSize.Width(),sal_Int32(aSize.Height()*0.33));
+
+ const long nFrameHeight = LogicToPixel( Size( 0, 3 ), MAP_APPFONT ).Height();
+ Point aPos(0,aBeamer.Height()+nFrameHeight);
+
+ m_pBeamer->SetPosSizePixel(Point(0,0),aBeamer);
+ m_pBeamer->Show();
+
+ m_pSplitter->SetPosSizePixel( Point(0,aBeamer.Height()), Size(aSize.Width(),nFrameHeight) );
+ // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide
+ m_pSplitter->SetSplitPosPixel( aBeamer.Height() );
+ m_pViewSwitch->SetPosSizePixel(aPos,Size(aBeamer.Width(),aSize.Height() - aBeamer.Height()-nFrameHeight));
+
+ m_pSplitter->Show();
+
+ Resize();
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+
+//.........................................................................
+} // namespace dbaui
+//.........................................................................
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/querycontroller.cxx b/dbaccess/source/ui/querydesign/querycontroller.cxx
new file mode 100644
index 000000000000..054c854e846a
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/querycontroller.cxx
@@ -0,0 +1,1868 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+
+#include "adtabdlg.hxx"
+#include "browserids.hxx"
+#include "dbu_qry.hrc"
+#include "dbu_reghelper.hxx"
+#include "dbustrings.hrc"
+#include "defaultobjectnamecheck.hxx"
+#include "dlgsave.hxx"
+#include "localresaccess.hxx"
+#include "QTableWindow.hxx"
+#include "QTableWindowData.hxx"
+#include "querycontainerwindow.hxx"
+#include "querycontroller.hxx"
+#include "QueryDesignView.hxx"
+#include "QueryTableView.hxx"
+#include "QueryTextView.hxx"
+#include "queryview.hxx"
+#include "QueryViewSwitch.hxx"
+#include "sqlmessage.hxx"
+#include "TableConnectionData.hxx"
+#include "TableFieldDescription.hxx"
+#include "UITools.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XLoadEventListener.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
+#include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbcx/XAppend.hpp>
+#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
+#include <com/sun/star/sdbcx/XDrop.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/util/VetoException.hpp>
+#include <com/sun/star/frame/XUntitledNumbers.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/basicio.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/seqstream.hxx>
+#include <comphelper/streamsection.hxx>
+#include <comphelper/types.hxx>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svtools/localresaccess.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/diagnose_ex.h>
+#include <osl/diagnose.h>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+
+extern "C" void SAL_CALL createRegistryInfo_OQueryControl()
+{
+ static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::OQueryController > aAutoRegistration;
+}
+namespace dbaui
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::frame;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::lang;
+
+ class OViewController : public OQueryController
+ {
+ //------------------------------------------------------------------------------
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw( RuntimeException )
+ {
+ return getImplementationName_Static();
+ }
+ //-------------------------------------------------------------------------
+ virtual Sequence< ::rtl::OUString> SAL_CALL getSupportedServiceNames() throw(RuntimeException)
+ {
+ return getSupportedServiceNames_Static();
+ }
+ public:
+ OViewController(const Reference< XMultiServiceFactory >& _rM) : OQueryController(_rM){}
+
+ // need by registration
+ static ::rtl::OUString getImplementationName_Static() throw( RuntimeException )
+ {
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.OViewDesign"));
+ }
+ static Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void) throw( RuntimeException )
+ {
+ Sequence< ::rtl::OUString> aSupported(1);
+ aSupported.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.ViewDesign"));
+ return aSupported;
+ }
+ static Reference< XInterface > SAL_CALL Create(const Reference< XMultiServiceFactory >& _rM)
+ {
+ return *(new OViewController(_rM));
+ }
+ };
+}
+extern "C" void SAL_CALL createRegistryInfo_OViewControl()
+{
+ static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::OViewController > aAutoRegistration;
+}
+
+namespace dbaui
+{
+ using namespace ::connectivity;
+#if OSL_DEBUG_LEVEL > 1
+ namespace
+ {
+ // -----------------------------------------------------------------------------
+ void insertParseTree(SvTreeListBox* _pBox,::connectivity::OSQLParseNode* _pNode,SvLBoxEntry* _pParent = NULL)
+ {
+ ::rtl::OUString rString;
+ if (!_pNode->isToken())
+ {
+ // Regelnamen als rule: ...
+ rString = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RULE_ID: "));
+ rString += ::rtl::OUString::valueOf( (sal_Int32)_pNode->getRuleID());
+ rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("("));
+ rString += OSQLParser::RuleIDToStr(_pNode->getRuleID());
+ rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+
+
+ _pParent = _pBox->InsertEntry(rString,_pParent);
+
+ // einmal auswerten wieviel Subtrees dieser Knoten besitzt
+ sal_uInt32 nStop = _pNode->count();
+ // hol dir den ersten Subtree
+ for(sal_uInt32 i=0;i<nStop;++i)
+ insertParseTree(_pBox,_pNode->getChild(i),_pParent);
+ }
+ else
+ {
+ // ein Token gefunden
+ // tabs fuer das Einruecken entsprechend nLevel
+
+ switch (_pNode->getNodeType())
+ {
+
+ case SQL_NODE_KEYWORD:
+ {
+ rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_KEYWORD:"));
+ ::rtl::OString sT = OSQLParser::TokenIDToStr(_pNode->getTokenID());
+ rString += ::rtl::OUString(sT,sT.getLength(),RTL_TEXTENCODING_UTF8);
+ break;}
+
+ case SQL_NODE_COMPARISON:
+ {
+ rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_COMPARISON:"));
+ rString += _pNode->getTokenValue(); // haenge Nodevalue an
+ // und beginne neu Zeile
+ break;}
+
+ case SQL_NODE_NAME:
+ {
+ rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_NAME:"));
+ rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\""));
+ rString += _pNode->getTokenValue();
+ rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\""));
+ break;}
+
+ case SQL_NODE_STRING:
+ {
+ rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_STRING:'"));
+ rString += _pNode->getTokenValue();
+ break;}
+
+ case SQL_NODE_INTNUM:
+ {
+ rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_INTNUM:"));
+ rString += _pNode->getTokenValue();
+ break;}
+
+ case SQL_NODE_APPROXNUM:
+ {
+ rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_APPROXNUM:"));
+ rString += _pNode->getTokenValue();
+ break;}
+
+ case SQL_NODE_PUNCTUATION:
+ {
+ rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_PUNCTUATION:"));
+ rString += _pNode->getTokenValue(); // haenge Nodevalue an
+ break;}
+
+ case SQL_NODE_AMMSC:
+ {
+ rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_AMMSC:"));
+ rString += _pNode->getTokenValue(); // haenge Nodevalue an
+ break;}
+
+ default:
+ OSL_FAIL("OSQLParser::ShowParseTree: unzulaessiger NodeType");
+ rString += _pNode->getTokenValue();
+ }
+ _pBox->InsertEntry(rString,_pParent);
+ }
+ }
+ }
+#endif // OSL_DEBUG_LEVEL
+
+ namespace
+ {
+ // -----------------------------------------------------------------------------
+ String lcl_getObjectResourceString( sal_uInt16 _nResId, sal_Int32 _nCommandType )
+ {
+ String sMessageText = String( ModuleRes( _nResId ) );
+ String sObjectType;
+ {
+ LocalResourceAccess aLocalRes( RSC_QUERY_OBJECT_TYPE, RSC_RESOURCE );
+ sObjectType = String( ModuleRes( (sal_uInt16)( _nCommandType + 1 ) ) );
+ }
+ sMessageText.SearchAndReplace( String::CreateFromAscii( "$object$" ), sObjectType );
+ return sMessageText;
+ }
+ }
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::awt;
+using namespace ::dbtools;
+
+using namespace ::comphelper;
+
+namespace
+{
+ void ensureToolbars( OQueryController& _rController, sal_Bool _bDesign )
+ {
+ Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager = _rController.getLayoutManager( _rController.getFrame() );
+ if ( xLayoutManager.is() )
+ {
+ xLayoutManager->lock();
+ static ::rtl::OUString s_sDesignToolbar(RTL_CONSTASCII_USTRINGPARAM("private:resource/toolbar/designobjectbar"));
+ static ::rtl::OUString s_sSqlToolbar(RTL_CONSTASCII_USTRINGPARAM("private:resource/toolbar/sqlobjectbar"));
+ if ( _bDesign )
+ {
+ xLayoutManager->destroyElement( s_sSqlToolbar );
+ xLayoutManager->createElement( s_sDesignToolbar );
+ }
+ else
+ {
+ xLayoutManager->destroyElement( s_sDesignToolbar );
+ xLayoutManager->createElement( s_sSqlToolbar );
+ }
+ xLayoutManager->unlock();
+ xLayoutManager->doLayout();
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OQueryController::getImplementationName() throw( RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString OQueryController::getImplementationName_Static() throw( RuntimeException )
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.OQueryDesign"));
+}
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString> OQueryController::getSupportedServiceNames_Static(void) throw( RuntimeException )
+{
+ Sequence< ::rtl::OUString> aSupported(1);
+ aSupported.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.QueryDesign"));
+ return aSupported;
+}
+//-------------------------------------------------------------------------
+Sequence< ::rtl::OUString> SAL_CALL OQueryController::getSupportedServiceNames() throw(RuntimeException)
+{
+ return getSupportedServiceNames_Static();
+}
+// -------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL OQueryController::Create(const Reference<XMultiServiceFactory >& _rxFactory)
+{
+ return *(new OQueryController(_rxFactory));
+}
+DBG_NAME(OQueryController);
+// -----------------------------------------------------------------------------
+OQueryController::OQueryController(const Reference< XMultiServiceFactory >& _rM)
+ :OJoinController(_rM)
+ ,OQueryController_PBase( getBroadcastHelper() )
+ ,m_pParseContext( new svxform::OSystemParseContext )
+ ,m_aSqlParser( _rM, m_pParseContext )
+ ,m_pSqlIterator(NULL)
+ ,m_nVisibleRows(0x400)
+ ,m_nSplitPos(-1)
+ ,m_nCommandType( CommandType::QUERY )
+ ,m_bGraphicalDesign(sal_False)
+ ,m_bDistinct(sal_False)
+ ,m_bViewAlias(sal_False)
+ ,m_bViewTable(sal_False)
+ ,m_bViewFunction(sal_False)
+ ,m_bEscapeProcessing(sal_True)
+{
+ DBG_CTOR(OQueryController,NULL);
+ InvalidateAll();
+
+ registerProperty( PROPERTY_ACTIVECOMMAND, PROPERTY_ID_ACTIVECOMMAND, PropertyAttribute::READONLY | PropertyAttribute::BOUND,
+ &m_sStatement, ::getCppuType( &m_sStatement ) );
+ registerProperty( PROPERTY_ESCAPE_PROCESSING, PROPERTY_ID_ESCAPE_PROCESSING, PropertyAttribute::READONLY | PropertyAttribute::BOUND,
+ &m_bEscapeProcessing, ::getCppuType( &m_bEscapeProcessing ) );
+}
+
+// -----------------------------------------------------------------------------
+OQueryController::~OQueryController()
+{
+ DBG_DTOR(OQueryController,NULL);
+ if ( !getBroadcastHelper().bDisposed && !getBroadcastHelper().bInDispose )
+ {
+ OSL_FAIL("Please check who doesn't dispose this component!");
+ // increment ref count to prevent double call of Dtor
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2( OQueryController, OJoinController, OQueryController_PBase )
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( OQueryController, OJoinController, OQueryController_PBase )
+
+//-------------------------------------------------------------------------
+Reference< XPropertySetInfo > SAL_CALL OQueryController::getPropertySetInfo() throw(RuntimeException)
+{
+ Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL OQueryController::convertFastPropertyValue( Any& o_rConvertedValue, Any& o_rOldValue, sal_Int32 i_nHandle, const Any& i_rValue ) throw (IllegalArgumentException)
+{
+ return OPropertyContainer::convertFastPropertyValue( o_rConvertedValue, o_rOldValue, i_nHandle, i_rValue );
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL OQueryController::setFastPropertyValue_NoBroadcast( sal_Int32 i_nHandle, const Any& i_rValue ) throw ( Exception )
+{
+ OPropertyContainer::setFastPropertyValue_NoBroadcast( i_nHandle, i_rValue );
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL OQueryController::getFastPropertyValue( Any& o_rValue, sal_Int32 i_nHandle ) const
+{
+ switch ( i_nHandle )
+ {
+ case PROPERTY_ID_CURRENT_QUERY_DESIGN:
+ {
+ ::comphelper::NamedValueCollection aCurrentDesign;
+ aCurrentDesign.put( "GraphicalDesign", isGraphicalDesign() );
+ aCurrentDesign.put( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, m_bEscapeProcessing );
+
+ if ( isGraphicalDesign() )
+ {
+ getContainer()->SaveUIConfig();
+ saveViewSettings( aCurrentDesign, true );
+ aCurrentDesign.put( "Statement", m_sStatement );
+ }
+ else
+ {
+ aCurrentDesign.put( "Statement", getContainer()->getStatement() );
+ }
+
+ o_rValue <<= aCurrentDesign.getPropertyValues();
+ }
+ break;
+
+ default:
+ OPropertyContainer::getFastPropertyValue( o_rValue, i_nHandle );
+ break;
+ }
+}
+
+//-------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OQueryController::getInfoHelper()
+{
+ return *const_cast< OQueryController* >( this )->getArrayHelper();
+}
+
+//--------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OQueryController::createArrayHelper( ) const
+{
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+
+ // one additional property:
+ const sal_Int32 nLength = aProps.getLength();
+ aProps.realloc( nLength + 1 );
+ aProps[ nLength ] = Property(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CurrentQueryDesign" ) ),
+ PROPERTY_ID_CURRENT_QUERY_DESIGN,
+ ::cppu::UnoType< Sequence< PropertyValue > >::get(),
+ PropertyAttribute::READONLY
+ );
+
+ ::std::sort(
+ aProps.getArray(),
+ aProps.getArray() + aProps.getLength(),
+ ::comphelper::PropertyCompareByName()
+ );
+
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+
+// -----------------------------------------------------------------------------
+void OQueryController::deleteIterator()
+{
+ if(m_pSqlIterator)
+ {
+ delete m_pSqlIterator->getParseTree();
+ m_pSqlIterator->dispose();
+ delete m_pSqlIterator;
+ m_pSqlIterator = NULL;
+ }
+}
+// -----------------------------------------------------------------------------
+void OQueryController::disposing()
+{
+ OQueryController_PBase::disposing();
+
+ deleteIterator();
+
+ delete m_pParseContext;
+
+ clearFields();
+ OTableFields().swap(m_vUnUsedFieldsDesc);
+
+ ::comphelper::disposeComponent(m_xComposer);
+ OJoinController::disposing();
+ OQueryController_PBase::disposing();
+}
+// -----------------------------------------------------------------------------
+void OQueryController::clearFields()
+{
+ OTableFields().swap(m_vTableFieldDesc);
+}
+// -----------------------------------------------------------------------------
+FeatureState OQueryController::GetState(sal_uInt16 _nId) const
+{
+ FeatureState aReturn;
+ aReturn.bEnabled = sal_True;
+ // (disabled automatically)
+
+ switch (_nId)
+ {
+ case ID_BROWSER_EDITDOC:
+ if ( editingCommand() )
+ aReturn.bEnabled = sal_False;
+ else if ( editingView() && !m_xAlterView.is() )
+ aReturn.bEnabled = sal_False;
+ else
+ aReturn = OJoinController::GetState( _nId );
+ break;
+
+ case ID_BROWSER_ESACPEPROCESSING:
+ aReturn.bChecked = !m_bEscapeProcessing;
+ aReturn.bEnabled = ( m_pSqlIterator != NULL ) && !m_bGraphicalDesign;
+ break;
+ case SID_RELATION_ADD_RELATION:
+ aReturn.bEnabled = isEditable() && m_bGraphicalDesign && m_vTableData.size() > 1;
+ break;
+ case ID_BROWSER_SAVEASDOC:
+ aReturn.bEnabled = !editingCommand() && !editingView() && (!m_bGraphicalDesign || !(m_vTableFieldDesc.empty() || m_vTableData.empty()));
+ break;
+ case ID_BROWSER_SAVEDOC:
+ aReturn.bEnabled = impl_isModified() && (!m_bGraphicalDesign || !(m_vTableFieldDesc.empty() || m_vTableData.empty()));
+ break;
+ case SID_PRINTDOCDIRECT:
+ break;
+ case ID_BROWSER_CUT:
+ aReturn.bEnabled = isEditable() && getContainer() && getContainer()->isCutAllowed();
+ break;
+ case ID_BROWSER_COPY:
+ aReturn.bEnabled = getContainer() && getContainer()->isCopyAllowed();
+ break;
+ case ID_BROWSER_PASTE:
+ aReturn.bEnabled = isEditable() && getContainer() && getContainer()->isPasteAllowed();
+ break;
+ case ID_BROWSER_SQL:
+ aReturn.bEnabled = m_bEscapeProcessing && m_pSqlIterator;
+ aReturn.bChecked = m_bGraphicalDesign;
+ break;
+ case SID_BROWSER_CLEAR_QUERY:
+ aReturn.bEnabled = isEditable() && (m_sStatement.getLength() || !m_vTableData.empty());
+ break;
+ case SID_QUERY_VIEW_FUNCTIONS:
+ case SID_QUERY_VIEW_TABLES:
+ case SID_QUERY_VIEW_ALIASES:
+ aReturn.bChecked = getContainer() && getContainer()->isSlotEnabled(_nId);
+ aReturn.bEnabled = m_bGraphicalDesign;
+ break;
+ case SID_QUERY_DISTINCT_VALUES:
+ aReturn.bEnabled = m_bGraphicalDesign && isEditable();
+ aReturn.bChecked = m_bDistinct;
+ break;
+ case ID_BROWSER_QUERY_EXECUTE:
+ aReturn.bEnabled = sal_True;
+ break;
+ case SID_DB_QUERY_PREVIEW:
+ aReturn.bEnabled = sal_True;
+ aReturn.bChecked = getContainer() && getContainer()->getPreviewFrame().is();
+ break;
+#if OSL_DEBUG_LEVEL > 1
+ case ID_EDIT_QUERY_SQL:
+ break;
+ case ID_EDIT_QUERY_DESIGN:
+ break;
+#endif
+ case ID_BROWSER_ADDTABLE:
+ if ( !m_bGraphicalDesign )
+ {
+ aReturn.bEnabled = sal_False;
+ break;
+ }
+ // run through
+ default:
+ aReturn = OJoinController::GetState(_nId);
+ break;
+ }
+ return aReturn;
+}
+// -----------------------------------------------------------------------------
+void OQueryController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs)
+{
+ switch(_nId)
+ {
+ case ID_BROWSER_ESACPEPROCESSING:
+ setEscapeProcessing_fireEvent( !m_bEscapeProcessing );
+ if ( !editingView() )
+ setModified(sal_True);
+ InvalidateFeature(ID_BROWSER_SQL);
+ break;
+ case ID_BROWSER_SAVEASDOC:
+ case ID_BROWSER_SAVEDOC:
+ doSaveAsDoc(ID_BROWSER_SAVEASDOC == _nId);
+ break;
+ case SID_RELATION_ADD_RELATION:
+ {
+ OJoinDesignView* pView = getJoinView();
+ if( pView )
+ static_cast<OQueryTableView*>(pView->getTableView())->createNewConnection();
+ }
+ break;
+ case SID_PRINTDOCDIRECT:
+ break;
+ case ID_BROWSER_CUT:
+ getContainer()->cut();
+ break;
+ case ID_BROWSER_COPY:
+ getContainer()->copy();
+ break;
+ case ID_BROWSER_PASTE:
+ getContainer()->paste();
+ break;
+ case ID_BROWSER_SQL:
+ {
+ if ( !getContainer()->checkStatement() )
+ break;
+ SQLExceptionInfo aError;
+ try
+ {
+ ::rtl::OUString aErrorMsg;
+ setStatement_fireEvent( getContainer()->getStatement() );
+ if(!m_sStatement.getLength() && m_pSqlIterator)
+ {
+ // change the view of the data
+ delete m_pSqlIterator->getParseTree();
+ m_pSqlIterator->setParseTree(NULL);
+ m_bGraphicalDesign = !m_bGraphicalDesign;
+ impl_setViewMode( &aError );
+ }
+ else
+ {
+ ::connectivity::OSQLParseNode* pNode = m_aSqlParser.parseTree(aErrorMsg,m_sStatement,m_bGraphicalDesign);
+ if ( pNode )
+ {
+ delete m_pSqlIterator->getParseTree();
+ m_pSqlIterator->setParseTree(pNode);
+ m_pSqlIterator->traverseAll();
+
+ if ( m_pSqlIterator->hasErrors() )
+ {
+ aError = m_pSqlIterator->getErrors();
+ }
+ else
+ {
+ const OSQLTables& xTabs = m_pSqlIterator->getTables();
+ if ( m_pSqlIterator->getStatementType() != SQL_STATEMENT_SELECT || xTabs.begin() == xTabs.end() )
+ {
+ aError = SQLException(
+ String( ModuleRes( STR_QRY_NOSELECT ) ),
+ NULL,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) ),
+ 1000,
+ Any()
+ );
+ }
+ else
+ {
+ // change the view of the data
+ m_bGraphicalDesign = !m_bGraphicalDesign;
+ ::rtl::OUString sNewStatement;
+ pNode->parseNodeToStr( sNewStatement, getConnection() );
+ setStatement_fireEvent( sNewStatement );
+ getContainer()->SaveUIConfig();
+ m_vTableConnectionData.clear();
+ impl_setViewMode( &aError );
+ }
+ }
+ }
+ else
+ {
+ aError = SQLException(
+ String( ModuleRes( STR_QRY_SYNTAX ) ),
+ NULL,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) ),
+ 1000,
+ Any()
+ );
+ }
+ }
+ }
+ catch(const SQLException&)
+ {
+ aError = ::cppu::getCaughtException();
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ if ( aError.isValid() )
+ showError( aError );
+
+ if(m_bGraphicalDesign)
+ {
+ InvalidateFeature(ID_BROWSER_ADDTABLE);
+ InvalidateFeature(SID_RELATION_ADD_RELATION);
+ }
+ }
+ break;
+ case SID_BROWSER_CLEAR_QUERY:
+ {
+ GetUndoManager().EnterListAction( String( ModuleRes(STR_QUERY_UNDO_TABWINDELETE) ), String() );
+ getContainer()->clear();
+ GetUndoManager().LeaveListAction();
+
+ setStatement_fireEvent( ::rtl::OUString() );
+ if(m_bGraphicalDesign)
+ InvalidateFeature(ID_BROWSER_ADDTABLE);
+ }
+ break;
+ case SID_QUERY_VIEW_FUNCTIONS:
+ case SID_QUERY_VIEW_TABLES:
+ case SID_QUERY_VIEW_ALIASES:
+ getContainer()->setSlotEnabled(_nId,!getContainer()->isSlotEnabled(_nId));
+ setModified(sal_True);
+ break;
+ case SID_QUERY_DISTINCT_VALUES:
+ m_bDistinct = !m_bDistinct;
+ setModified(sal_True);
+ break;
+ case ID_BROWSER_QUERY_EXECUTE:
+ if ( getContainer()->checkStatement() )
+ executeQuery();
+ break;
+ case SID_DB_QUERY_PREVIEW:
+ try
+ {
+ Reference< ::com::sun::star::util::XCloseable > xCloseFrame( getContainer()->getPreviewFrame(), UNO_QUERY );
+ if ( xCloseFrame.is() )
+ {
+ try
+ {
+ xCloseFrame->close( sal_True );
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL( "OQueryController::Execute(SID_DB_QUERY_PREVIEW): *nobody* is expected to veto closing the preview frame!" );
+ }
+ }
+ else
+ Execute(ID_BROWSER_QUERY_EXECUTE,Sequence< PropertyValue >());
+ }
+ catch(const Exception&)
+ {
+ }
+ break;
+ case ID_QUERY_ZOOM_IN:
+ {
+ }
+ break;
+ case ID_QUERY_ZOOM_OUT:
+ {
+ }
+ break;
+#if OSL_DEBUG_LEVEL > 1
+ case ID_EDIT_QUERY_DESIGN:
+ case ID_EDIT_QUERY_SQL:
+ {
+ ::rtl::OUString aErrorMsg;
+ setStatement_fireEvent( getContainer()->getStatement() );
+ ::connectivity::OSQLParseNode* pNode = m_aSqlParser.parseTree( aErrorMsg, m_sStatement, m_bGraphicalDesign );
+ if ( pNode )
+ {
+ Window* pView = getView();
+ ModalDialog* pWindow = new ModalDialog( pView, WB_STDMODAL | WB_SIZEMOVE | WB_CENTER );
+ pWindow->SetSizePixel( ::Size( pView->GetSizePixel().Width() / 2, pView->GetSizePixel().Height() / 2 ) );
+ SvTreeListBox* pTreeBox = new SvTreeListBox( pWindow, WB_BORDER | WB_HASLINES | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HASLINESATROOT | WB_VSCROLL );
+ pTreeBox->SetPosSizePixel( ::Point( 6, 6 ), ::Size( pWindow->GetSizePixel().Width() - 12, pWindow->GetSizePixel().Height() - 12 ));
+ pTreeBox->SetNodeDefaultImages();
+
+ if ( _nId == ID_EDIT_QUERY_DESIGN )
+ {
+ ::connectivity::OSQLParseNode* pTemp = pNode ? pNode->getChild(3)->getChild(1) : NULL;
+ // no where clause found
+ if ( pTemp && !pTemp->isLeaf() )
+ {
+ ::connectivity::OSQLParseNode * pCondition = pTemp->getChild(1);
+ if ( pCondition ) // no where clause
+ {
+ ::connectivity::OSQLParseNode::negateSearchCondition(pCondition);
+ ::connectivity::OSQLParseNode *pNodeTmp = pTemp->getChild(1);
+
+ ::connectivity::OSQLParseNode::disjunctiveNormalForm(pNodeTmp);
+ pNodeTmp = pTemp->getChild(1);
+ ::connectivity::OSQLParseNode::absorptions(pNodeTmp);
+ pNodeTmp = pTemp->getChild(1);
+ OSQLParseNode::compress(pNodeTmp);
+ pNodeTmp = pTemp->getChild(1);
+ }
+ ::rtl::OUString sTemp;
+ pNode->parseNodeToStr(sTemp,getConnection());
+ getContainer()->setStatement(sTemp);
+ }
+ }
+
+ insertParseTree(pTreeBox,pNode);
+
+ pTreeBox->Show();
+ pWindow->Execute();
+
+ delete pTreeBox;
+ delete pWindow;
+ delete pNode;
+ }
+ break;
+ }
+#endif
+ default:
+ OJoinController::Execute(_nId,aArgs);
+ return; // else we would invalidate twice
+ }
+ InvalidateFeature(_nId);
+}
+
+// -----------------------------------------------------------------------------
+void OQueryController::impl_showAutoSQLViewError( const ::com::sun::star::uno::Any& _rErrorDetails )
+{
+ SQLContext aErrorContext;
+ aErrorContext.Message = lcl_getObjectResourceString( STR_ERROR_PARSING_STATEMENT, m_nCommandType );
+ aErrorContext.Context = *this;
+ aErrorContext.Details = lcl_getObjectResourceString( STR_INFO_OPENING_IN_SQL_VIEW, m_nCommandType );
+ aErrorContext.NextException = _rErrorDetails;
+ showError( aErrorContext );
+}
+
+// -----------------------------------------------------------------------------
+bool OQueryController::impl_setViewMode( ::dbtools::SQLExceptionInfo* _pErrorInfo )
+{
+ OSL_PRECOND( getContainer(), "OQueryController::impl_setViewMode: illegal call!" );
+
+ bool wasModified = isModified();
+
+ SQLExceptionInfo aError;
+ bool bSuccess = getContainer()->switchView( &aError );
+ if ( !bSuccess )
+ {
+ m_bGraphicalDesign = !m_bGraphicalDesign;
+ // restore old state
+ getContainer()->switchView( NULL );
+ // don't pass &aError here, this would overwrite the error which the first switchView call
+ // returned in this location.
+ if ( _pErrorInfo )
+ *_pErrorInfo = aError;
+ else
+ showError( aError );
+ }
+ else
+ {
+ ensureToolbars( *this, m_bGraphicalDesign );
+ }
+
+ setModified( wasModified );
+ return bSuccess;
+}
+
+// -----------------------------------------------------------------------------
+void OQueryController::impl_initialize()
+{
+ OJoinController::impl_initialize();
+
+ const NamedValueCollection& rArguments( getInitParams() );
+
+ ::rtl::OUString sCommand;
+ m_nCommandType = CommandType::QUERY;
+
+ // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
+ // ° reading parameters
+ // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
+ // legacy parameters first (later overwritten by regular parameters)
+ ::rtl::OUString sIndependentSQLCommand;
+ if ( rArguments.get_ensureType( "IndependentSQLCommand", sIndependentSQLCommand ) )
+ {
+ OSL_FAIL( "OQueryController::impl_initialize: IndependentSQLCommand is regognized for compatibility only!" );
+ sCommand = sIndependentSQLCommand;
+ m_nCommandType = CommandType::COMMAND;
+ }
+
+ ::rtl::OUString sCurrentQuery;
+ if ( rArguments.get_ensureType( "CurrentQuery", sCurrentQuery ) )
+ {
+ OSL_FAIL( "OQueryController::impl_initialize: CurrentQuery is regognized for compatibility only!" );
+ sCommand = sCurrentQuery;
+ m_nCommandType = CommandType::QUERY;
+ }
+
+ sal_Bool bCreateView( sal_False );
+ if ( rArguments.get_ensureType( "CreateView", bCreateView ) && bCreateView )
+ {
+ OSL_FAIL( "OQueryController::impl_initialize: CurrentQuery is regognized for compatibility only!" );
+ m_nCommandType = CommandType::TABLE;
+ }
+
+ // non-legacy parameters which overwrite the legacy parameters
+ rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND, sCommand );
+ rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND_TYPE, m_nCommandType );
+
+ // translate Command/Type into proper members
+ // TODO/Later: all this (including those members) should be hidden behind some abstact interface,
+ // which is implemented for all the three commands
+ switch ( m_nCommandType )
+ {
+ case CommandType::QUERY:
+ m_sName = sCommand;
+ break;
+ case CommandType::TABLE:
+ m_sName = sCommand;
+ break;
+ case CommandType::COMMAND:
+ setStatement_fireEvent( sCommand );
+ m_sName = ::rtl::OUString();
+ break;
+ default:
+ OSL_FAIL( "OQueryController::impl_initialize: logic error in code!" );
+ throw RuntimeException();
+ }
+
+ // more legacy parameters
+ sal_Bool bGraphicalDesign( sal_True );
+ if ( rArguments.get_ensureType( (::rtl::OUString)PROPERTY_QUERYDESIGNVIEW, bGraphicalDesign ) )
+ {
+ OSL_FAIL( "OQueryController::impl_initialize: QueryDesignView is regognized for compatibility only!" );
+ m_bGraphicalDesign = bGraphicalDesign;
+ }
+
+ // more non-legacy
+ rArguments.get_ensureType( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN, m_bGraphicalDesign );
+
+ bool bEscapeProcessing( sal_True );
+ if ( rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, bEscapeProcessing ) )
+ {
+ setEscapeProcessing_fireEvent( bEscapeProcessing );
+
+ OSL_ENSURE( m_bEscapeProcessing || !m_bGraphicalDesign, "OQueryController::impl_initialize: can't do the graphical design without escape processing!" );
+ if ( !m_bEscapeProcessing )
+ m_bGraphicalDesign = false;
+ }
+
+ // .................................................................................................................
+ // . initial design
+ bool bForceInitialDesign = false;
+ Sequence< PropertyValue > aCurrentQueryDesignProps;
+ aCurrentQueryDesignProps = rArguments.getOrDefault( "CurrentQueryDesign", aCurrentQueryDesignProps );
+
+ if ( aCurrentQueryDesignProps.getLength() )
+ {
+ ::comphelper::NamedValueCollection aCurrentQueryDesign( aCurrentQueryDesignProps );
+ if ( aCurrentQueryDesign.has( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN ) )
+ {
+ aCurrentQueryDesign.get_ensureType( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN, m_bGraphicalDesign );
+ }
+ if ( aCurrentQueryDesign.has( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING ) )
+ {
+ aCurrentQueryDesign.get_ensureType( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, m_bEscapeProcessing );
+ }
+ if ( aCurrentQueryDesign.has( "Statement" ) )
+ {
+ ::rtl::OUString sStatement;
+ aCurrentQueryDesign.get_ensureType( "Statement", sStatement );
+ aCurrentQueryDesign.remove( "Statement" );
+ setStatement_fireEvent( sStatement );
+ }
+
+ loadViewSettings( aCurrentQueryDesign );
+
+ bForceInitialDesign = true;
+ }
+
+ // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
+ if ( !ensureConnected( sal_False ) )
+ { // we have no connection so what else should we do
+ m_bGraphicalDesign = sal_False;
+ if ( editingView() )
+ {
+ connectionLostMessage();
+ throw SQLException();
+ }
+ }
+
+ // check the view capabilities
+ if ( isConnected() && editingView() )
+ {
+ Reference< XViewsSupplier > xViewsSup( getConnection(), UNO_QUERY );
+ Reference< XNameAccess > xViews;
+ if ( xViewsSup.is() )
+ xViews = xViewsSup->getViews();
+
+ if ( !xViews.is() )
+ { // we can't create views so we ask if the user wants to create a query instead
+ m_nCommandType = CommandType::QUERY;
+ sal_Bool bClose = sal_False;
+ {
+ String aTitle( ModuleRes( STR_QUERYDESIGN_NO_VIEW_SUPPORT ) );
+ String aMessage( ModuleRes( STR_QUERYDESIGN_NO_VIEW_ASK ) );
+ ODataView* pWindow = getView();
+ OSQLMessageBox aDlg( pWindow, aTitle, aMessage, WB_YES_NO | WB_DEF_YES, OSQLMessageBox::Query );
+ bClose = aDlg.Execute() == RET_NO;
+ }
+ if ( bClose )
+ throw VetoException();
+ }
+
+ // now if we are to edit an existing view, check whether this is possible
+ if ( m_sName.getLength() )
+ {
+ Any aView( xViews->getByName( m_sName ) );
+ // will throw if there is no such view
+ if ( !( aView >>= m_xAlterView ) )
+ {
+ throw IllegalArgumentException(
+ ::rtl::OUString( String( ModuleRes( STR_NO_ALTER_VIEW_SUPPORT ) ) ),
+ *this,
+ 1
+ );
+ }
+ }
+ }
+
+ OSL_ENSURE(getDataSource().is(),"OQueryController::impl_initialize: need a datasource!");
+
+ try
+ {
+ getContainer()->initialize();
+ impl_reset( bForceInitialDesign );
+
+ SQLExceptionInfo aError;
+ const bool bAttemptedGraphicalDesign = m_bGraphicalDesign;
+
+ if ( bForceInitialDesign )
+ {
+ getContainer()->forceInitialView();
+ }
+ else
+ {
+ impl_setViewMode( &aError );
+ }
+
+ if ( aError.isValid() && bAttemptedGraphicalDesign && !m_bGraphicalDesign )
+ {
+ // we tried initializing the graphical view, this failed, and we were automatically switched to SQL
+ // view => tell this to the user
+ if ( !editingView() )
+ {
+ impl_showAutoSQLViewError( aError.get() );
+ }
+ }
+
+ ClearUndoManager();
+
+ if ( ( m_bGraphicalDesign )
+ && ( ( !m_sName.getLength() && !editingCommand() )
+ || ( !m_sStatement.getLength() && editingCommand() )
+ )
+ )
+ {
+ Application::PostUserEvent( LINK( this, OQueryController, OnExecuteAddTable ) );
+ }
+
+ setModified(sal_False);
+ }
+ catch(const SQLException& e)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ // we caught an exception so we switch to text only mode
+ {
+ m_bGraphicalDesign = sal_False;
+ getContainer()->initialize();
+ ODataView* pWindow = getView();
+ OSQLMessageBox(pWindow,e).Execute();
+ }
+ throw;
+ }
+}
+
+// -----------------------------------------------------------------------------
+void OQueryController::onLoadedMenu(const Reference< ::com::sun::star::frame::XLayoutManager >& /*_xLayoutManager*/)
+{
+ ensureToolbars( *this, m_bGraphicalDesign );
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString OQueryController::getPrivateTitle( ) const
+{
+ ::rtl::OUString sName = m_sName;
+ if ( !sName.getLength() )
+ {
+ if ( !editingCommand() )
+ {
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+ String aDefaultName = String( ModuleRes( editingView() ? STR_VIEW_TITLE : STR_QRY_TITLE ) );
+ sName = aDefaultName.GetToken(0,' ');
+ sName += ::rtl::OUString::valueOf(getCurrentStartNumber());
+ }
+ }
+ return sName;
+}
+// -----------------------------------------------------------------------------
+void OQueryController::setQueryComposer()
+{
+ if(isConnected())
+ {
+ Reference< XSQLQueryComposerFactory > xFactory(getConnection(), UNO_QUERY);
+ OSL_ENSURE(xFactory.is(),"Connection doesn't support a querycomposer");
+ if ( xFactory.is() && getContainer() )
+ {
+ try
+ {
+ m_xComposer = xFactory->createQueryComposer();
+ getContainer()->setStatement(m_sStatement);
+ }
+ catch(const Exception&)
+ {
+ m_xComposer = NULL;
+ }
+ OSL_ENSURE(m_xComposer.is(),"No querycomposer available!");
+ Reference<XTablesSupplier> xTablesSup(getConnection(), UNO_QUERY);
+ deleteIterator();
+ m_pSqlIterator = new ::connectivity::OSQLParseTreeIterator( getConnection(), xTablesSup->getTables(), m_aSqlParser, NULL );
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryController::Construct(Window* pParent)
+{
+ // TODO: we have to check if we should create the text- or the design- view
+
+ setView( * new OQueryContainerWindow( pParent, *this, getORB() ) );
+
+ return OJoinController::Construct(pParent);
+}
+
+// -----------------------------------------------------------------------------
+OJoinDesignView* OQueryController::getJoinView()
+{
+ return getContainer()->getDesignView();
+}
+// -----------------------------------------------------------------------------
+void OQueryController::describeSupportedFeatures()
+{
+ OJoinController::describeSupportedFeatures();
+ implDescribeSupportedFeature( ".uno:SaveAs", ID_BROWSER_SAVEASDOC, CommandGroup::DOCUMENT );
+ implDescribeSupportedFeature( ".uno:SbaNativeSql", ID_BROWSER_ESACPEPROCESSING,CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DBViewFunctions", SID_QUERY_VIEW_FUNCTIONS, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:DBViewTableNames", SID_QUERY_VIEW_TABLES, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:DBViewAliases", SID_QUERY_VIEW_ALIASES, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:DBDistinctValues", SID_QUERY_DISTINCT_VALUES, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DBChangeDesignMode",ID_BROWSER_SQL, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:DBClearQuery", SID_BROWSER_CLEAR_QUERY, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:SbaExecuteSql", ID_BROWSER_QUERY_EXECUTE, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:DBAddRelation", SID_RELATION_ADD_RELATION, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:DBQueryPreview", SID_DB_QUERY_PREVIEW, CommandGroup::VIEW );
+
+#if OSL_DEBUG_LEVEL > 1
+ implDescribeSupportedFeature( ".uno:DBShowParseTree", ID_EDIT_QUERY_SQL );
+ implDescribeSupportedFeature( ".uno:DBMakeDisjunct", ID_EDIT_QUERY_DESIGN );
+#endif
+}
+// -----------------------------------------------------------------------------
+void OQueryController::impl_onModifyChanged()
+{
+ OJoinController::impl_onModifyChanged();
+ InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
+ InvalidateFeature(ID_BROWSER_SAVEASDOC);
+ InvalidateFeature(ID_BROWSER_QUERY_EXECUTE);
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OQueryController::disposing( const EventObject& Source ) throw(RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ if ( getContainer() && Source.Source.is() )
+ {
+ if ( Source.Source == m_aCurrentFrame.getFrame() )
+ { // our frame is being disposed -> close the preview window (if we have one)
+ Reference< XFrame > xPreviewFrame( getContainer()->getPreviewFrame() );
+ ::comphelper::disposeComponent( xPreviewFrame );
+ }
+ else if ( Source.Source == getContainer()->getPreviewFrame() )
+ {
+ getContainer()->disposingPreview();
+ }
+ }
+
+ OJoinController::disposing(Source);
+}
+// -----------------------------------------------------------------------------
+void OQueryController::reconnect(sal_Bool _bUI)
+{
+ deleteIterator();
+ ::comphelper::disposeComponent(m_xComposer);
+
+ OJoinController::reconnect( _bUI );
+
+ if (isConnected())
+ {
+ setQueryComposer();
+ }
+ else
+ {
+ if(m_bGraphicalDesign)
+ {
+ m_bGraphicalDesign = sal_False;
+ // don't call Execute(SQL) because this changes the sql statement
+ impl_setViewMode( NULL );
+ }
+ InvalidateAll();
+ }
+}
+
+// -----------------------------------------------------------------------------
+void OQueryController::saveViewSettings( ::comphelper::NamedValueCollection& o_rViewSettings, const bool i_includingCriteria ) const
+{
+ saveTableWindows( o_rViewSettings );
+
+ OTableFields::const_iterator field = m_vTableFieldDesc.begin();
+ OTableFields::const_iterator fieldEnd = m_vTableFieldDesc.end();
+
+ ::comphelper::NamedValueCollection aAllFieldsData;
+ ::comphelper::NamedValueCollection aFieldData;
+ for ( sal_Int32 i = 1; field != fieldEnd; ++field, ++i )
+ {
+ if ( !(*field)->IsEmpty() )
+ {
+ aFieldData.clear();
+ (*field)->Save( aFieldData, i_includingCriteria );
+
+ const ::rtl::OUString sFieldSettingName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Field" ) ) + ::rtl::OUString::valueOf( i );
+ aAllFieldsData.put( sFieldSettingName, aFieldData.getPropertyValues() );
+ }
+ }
+
+ o_rViewSettings.put( "Fields", aAllFieldsData.getPropertyValues() );
+ o_rViewSettings.put( "SplitterPosition", m_nSplitPos );
+ o_rViewSettings.put( "VisibleRows", m_nVisibleRows );
+}
+// -----------------------------------------------------------------------------
+void OQueryController::loadViewSettings( const ::comphelper::NamedValueCollection& o_rViewSettings )
+{
+ loadTableWindows( o_rViewSettings );
+
+ m_nSplitPos = o_rViewSettings.getOrDefault( "SplitterPosition", m_nSplitPos );
+ m_nVisibleRows = o_rViewSettings.getOrDefault( "VisibleRows", m_nVisibleRows );
+ m_aFieldInformation = o_rViewSettings.getOrDefault( "Fields", m_aFieldInformation );
+}
+// -----------------------------------------------------------------------------
+sal_Int32 OQueryController::getColWidth(sal_uInt16 _nColPos) const
+{
+ if ( _nColPos < m_aFieldInformation.getLength() )
+ {
+ ::std::auto_ptr<OTableFieldDesc> pField( new OTableFieldDesc());
+ pField->Load( m_aFieldInformation[ _nColPos ], false );
+ return pField->GetColWidth();
+ }
+ return 0;
+}
+// -----------------------------------------------------------------------------
+Reference<XNameAccess> OQueryController::getObjectContainer() const
+{
+ Reference< XNameAccess > xElements;
+ if ( editingView() )
+ {
+ Reference< XViewsSupplier > xViewsSupp( getConnection(), UNO_QUERY );
+ if ( xViewsSupp.is() )
+ xElements = xViewsSupp->getViews();
+ }
+ else
+ {
+ Reference< XQueriesSupplier > xQueriesSupp( getConnection(), UNO_QUERY );
+ if ( xQueriesSupp.is() )
+ xElements = xQueriesSupp->getQueries();
+ else
+ {
+ Reference< XQueryDefinitionsSupplier > xQueryDefsSupp( getDataSource(), UNO_QUERY );
+ if ( xQueryDefsSupp.is() )
+ xElements = xQueryDefsSupp->getQueryDefinitions();
+ }
+ }
+
+ OSL_ENSURE( xElements.is(), "OQueryController::getObjectContainer: unable to obtain the container!" );
+ return xElements;
+}
+
+// -----------------------------------------------------------------------------
+void OQueryController::executeQuery()
+{
+ // we don't need to check the connection here because we already check the composer
+ // which can't live without his connection
+ ::rtl::OUString sTranslatedStmt = translateStatement( false );
+
+ ::rtl::OUString sDataSourceName = getDataSourceName();
+ if ( sDataSourceName.getLength() && sTranslatedStmt.getLength() )
+ {
+ try
+ {
+ getContainer()->showPreview( getFrame() );
+ InvalidateFeature(SID_DB_QUERY_PREVIEW);
+
+ URL aWantToDispatch;
+ aWantToDispatch.Complete = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".component:DB/DataSourceBrowser"));
+
+ ::rtl::OUString sFrameName( FRAME_NAME_QUERY_PREVIEW );
+ sal_Int32 nSearchFlags = FrameSearchFlag::CHILDREN;
+
+ Reference< XDispatch> xDisp;
+ Reference< XDispatchProvider> xProv( getFrame()->findFrame( sFrameName, nSearchFlags ), UNO_QUERY );
+ if(!xProv.is())
+ {
+ xProv.set( getFrame(), UNO_QUERY );
+ if (xProv.is())
+ xDisp = xProv->queryDispatch(aWantToDispatch, sFrameName, nSearchFlags);
+ }
+ else
+ {
+ xDisp = xProv->queryDispatch(aWantToDispatch, sFrameName, FrameSearchFlag::SELF);
+ }
+ if (xDisp.is())
+ {
+ Sequence< PropertyValue> aProps(9);
+ aProps[0].Name = PROPERTY_DATASOURCENAME;
+ aProps[0].Value <<= sDataSourceName;
+
+ aProps[1].Name = PROPERTY_COMMAND_TYPE;
+ aProps[1].Value <<= CommandType::COMMAND;
+
+ aProps[2].Name = PROPERTY_COMMAND;
+ aProps[2].Value <<= sTranslatedStmt;
+
+ aProps[3].Name = PROPERTY_ENABLE_BROWSER;
+ aProps[3].Value = ::cppu::bool2any(sal_False);
+
+ aProps[4].Name = PROPERTY_ACTIVE_CONNECTION;
+ aProps[4].Value <<= getConnection();
+
+ aProps[5].Name = PROPERTY_UPDATE_CATALOGNAME;
+ aProps[5].Value <<= m_sUpdateCatalogName;
+
+ aProps[6].Name = PROPERTY_UPDATE_SCHEMANAME;
+ aProps[6].Value <<= m_sUpdateSchemaName;
+
+ aProps[7].Name = PROPERTY_UPDATE_TABLENAME;
+ aProps[7].Value <<= m_sUpdateTableName;
+
+ aProps[8].Name = PROPERTY_ESCAPE_PROCESSING;
+ aProps[8].Value = ::cppu::bool2any(m_bEscapeProcessing);
+
+ xDisp->dispatch(aWantToDispatch, aProps);
+ // check the state of the beamer
+ // be notified when the beamer frame is closed
+ Reference< XComponent > xComponent( getFrame()->findFrame( sFrameName, nSearchFlags ), UNO_QUERY );
+ if (xComponent.is())
+ {
+ OSL_ENSURE(Reference< XFrame >(xComponent, UNO_QUERY).get() == getContainer()->getPreviewFrame().get(),
+ "OQueryController::executeQuery: oops ... which window do I have here?");
+ Reference< XEventListener> xEvtL((::cppu::OWeakObject*)this,UNO_QUERY);
+ xComponent->addEventListener(xEvtL);
+ }
+ }
+ else
+ {
+ OSL_FAIL("Couldn't create a beamer window!");
+ }
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("Couldn't create a beamer window!");
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryController::askForNewName(const Reference<XNameAccess>& _xElements,sal_Bool _bSaveAs)
+{
+ OSL_ENSURE( !editingCommand(), "OQueryController::askForNewName: not to be called when designing an independent statement!" );
+ if ( editingCommand() )
+ return sal_False;
+
+ OSL_PRECOND( _xElements.is(), "OQueryController::askForNewName: invalid container!" );
+ if ( !_xElements.is() )
+ return sal_False;
+
+ sal_Bool bRet = sal_True;
+ sal_Bool bNew = _bSaveAs || !_xElements->hasByName( m_sName );
+ if(bNew)
+ {
+ String aDefaultName;
+ if ( ( _bSaveAs && !bNew ) || ( bNew && m_sName.getLength() ) )
+ aDefaultName = String( m_sName );
+ else
+ {
+ String sName = String( ModuleRes( editingView() ? STR_VIEW_TITLE : STR_QRY_TITLE ) );
+ aDefaultName = sName.GetToken(0,' ');
+ aDefaultName = ::dbtools::createUniqueName(_xElements,aDefaultName);
+ }
+
+ DynamicTableOrQueryNameCheck aNameChecker( getConnection(), CommandType::QUERY );
+ OSaveAsDlg aDlg(
+ getView(),
+ m_nCommandType,
+ getORB(),
+ getConnection(),
+ aDefaultName,
+ aNameChecker,
+ SAD_DEFAULT );
+
+ bRet = ( aDlg.Execute() == RET_OK );
+ if ( bRet )
+ {
+ m_sName = aDlg.getName();
+ if ( editingView() )
+ {
+ m_sUpdateCatalogName = aDlg.getCatalog();
+ m_sUpdateSchemaName = aDlg.getSchema();
+ }
+ }
+ }
+ return bRet;
+}
+// -----------------------------------------------------------------------------
+bool OQueryController::doSaveAsDoc(sal_Bool _bSaveAs)
+{
+ OSL_ENSURE(isEditable(),"Slot ID_BROWSER_SAVEDOC should not be enabled!");
+ if ( !editingCommand() && !haveDataSource() )
+ {
+ String aMessage(ModuleRes(STR_DATASOURCE_DELETED));
+ OSQLWarningBox( getView(), aMessage ).Execute();
+ return false;
+ }
+
+ Reference< XNameAccess > xElements = getObjectContainer();
+ if ( !xElements.is() )
+ return false;
+
+ if ( !getContainer()->checkStatement() )
+ return false;
+
+ ::rtl::OUString sTranslatedStmt = translateStatement();
+ if ( editingCommand() )
+ {
+ setModified( sal_False );
+ // this is all we need to do here. translateStatement implicitly set our m_sStatement, and
+ // notified it, and that's all
+ return true;
+ }
+
+ if ( !sTranslatedStmt.getLength() )
+ return false;
+
+ // first we need a name for our query so ask the user
+ // did we get a name
+ ::rtl::OUString sOriginalName( m_sName );
+ if ( !askForNewName( xElements, _bSaveAs ) || !m_sName.getLength() )
+ return false;
+
+ SQLExceptionInfo aInfo;
+ bool bSuccess = false;
+ bool bNew = false;
+ try
+ {
+ bNew = ( _bSaveAs )
+ || ( !xElements->hasByName( m_sName ) );
+
+ Reference<XPropertySet> xQuery;
+ if ( bNew ) // just to make sure the query already exists
+ {
+ // drop the query, in case it already exists
+ if ( xElements->hasByName( m_sName ) )
+ {
+ Reference< XDrop > xNameCont( xElements, UNO_QUERY );
+ if ( xNameCont.is() )
+ xNameCont->dropByName( m_sName );
+ else
+ {
+ Reference< XNameContainer > xCont( xElements, UNO_QUERY );
+ if ( xCont.is() )
+ xCont->removeByName( m_sName );
+ }
+ }
+
+ // create a new (empty, uninitialized) query resp. view
+ Reference< XDataDescriptorFactory > xFact( xElements, UNO_QUERY );
+ if ( xFact.is() )
+ {
+ xQuery = xFact->createDataDescriptor();
+ // to set the name is only allowed when the query is new
+ xQuery->setPropertyValue( PROPERTY_NAME, makeAny( m_sName ) );
+ }
+ else
+ {
+ Reference< XSingleServiceFactory > xSingleFac( xElements, UNO_QUERY );
+ if ( xSingleFac.is() )
+ xQuery = xQuery.query( xSingleFac->createInstance() );
+ }
+ }
+ else
+ {
+ xElements->getByName( m_sName ) >>= xQuery;
+ }
+ if ( !xQuery.is() )
+ throw RuntimeException();
+
+ // the new commands
+ if ( editingView() && !bNew )
+ {
+ OSL_ENSURE( xQuery == m_xAlterView, "OQueryController::doSaveAsDoc: already have another alterable view ...!?" );
+ m_xAlterView.set( xQuery, UNO_QUERY_THROW );
+ m_xAlterView->alterCommand( sTranslatedStmt );
+ }
+ else
+ { // we're creating a query, or a *new* view
+ xQuery->setPropertyValue( PROPERTY_COMMAND, makeAny( sTranslatedStmt ) );
+
+ if ( editingView() )
+ {
+ xQuery->setPropertyValue( PROPERTY_CATALOGNAME, makeAny( m_sUpdateCatalogName ) );
+ xQuery->setPropertyValue( PROPERTY_SCHEMANAME, makeAny( m_sUpdateSchemaName ) );
+ }
+
+ if ( editingQuery() )
+ {
+ xQuery->setPropertyValue( PROPERTY_UPDATE_TABLENAME, makeAny( m_sUpdateTableName ) );
+ xQuery->setPropertyValue( PROPERTY_ESCAPE_PROCESSING,::cppu::bool2any( m_bEscapeProcessing ) );
+
+ xQuery->setPropertyValue( PROPERTY_LAYOUTINFORMATION, getViewData() );
+ }
+ }
+
+ if ( bNew )
+ {
+ Reference< XAppend > xAppend( xElements, UNO_QUERY );
+ if ( xAppend.is() )
+ {
+ xAppend->appendByDescriptor( xQuery );
+ }
+ else
+ {
+ Reference< XNameContainer > xCont( xElements, UNO_QUERY );
+ if ( xCont.is() )
+ xCont->insertByName( m_sName, makeAny( xQuery ) );
+ }
+
+ if ( editingView() )
+ {
+ Reference< XPropertySet > xViewProps;
+ if ( xElements->hasByName( m_sName ) )
+ xViewProps.set( xElements->getByName( m_sName ), UNO_QUERY );
+
+ if ( !xViewProps.is() ) // correct name and try again
+ m_sName = ::dbtools::composeTableName( getMetaData(), xQuery, ::dbtools::eInDataManipulation, false, false, false );
+
+ OSL_ENSURE( xElements->hasByName( m_sName ), "OQueryController::doSaveAsDoc: newly creaed view does not exist!" );
+
+ if ( xElements->hasByName( m_sName ) )
+ m_xAlterView.set( xElements->getByName( m_sName ), UNO_QUERY );
+
+ // now check if our datasource has set a tablefilter and if so, append the new table name to it
+ ::dbaui::appendToFilter( getConnection(), m_sName, getORB(), getView() );
+ }
+ Reference< XTitleChangeListener> xEventListener(impl_getTitleHelper_throw(),UNO_QUERY);
+ if ( xEventListener.is() )
+ {
+ TitleChangedEvent aEvent;
+ xEventListener->titleChanged(aEvent);
+ }
+ releaseNumberForComponent();
+ }
+
+ setModified( sal_False );
+ bSuccess = true;
+
+ }
+ catch(const SQLException&)
+ {
+ if ( !bNew )
+ m_sName = sOriginalName;
+ aInfo = SQLExceptionInfo( ::cppu::getCaughtException() );
+ }
+ catch(const Exception&)
+ {
+ if ( !bNew )
+ m_sName = sOriginalName;
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ showError( aInfo );
+
+ // update the title of our window
+ //updateTitle();
+
+ // if we successfully saved a view we were creating, then close the designer
+ if ( bSuccess && editingView() && !m_xAlterView.is() )
+ {
+ closeTask();
+ }
+
+ if ( bSuccess && editingView() )
+ InvalidateFeature( ID_BROWSER_EDITDOC );
+
+ return bSuccess;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OQueryController::translateStatement( bool _bFireStatementChange )
+{
+ // now set the properties
+ setStatement_fireEvent( getContainer()->getStatement(), _bFireStatementChange );
+ ::rtl::OUString sTranslatedStmt;
+ if(m_sStatement.getLength() && m_xComposer.is() && m_bEscapeProcessing)
+ {
+ try
+ {
+ ::rtl::OUString aErrorMsg;
+
+ ::connectivity::OSQLParseNode* pNode = m_aSqlParser.parseTree( aErrorMsg, m_sStatement, m_bGraphicalDesign );
+ if(pNode)
+ {
+ pNode->parseNodeToStr( sTranslatedStmt, getConnection() );
+ delete pNode;
+ }
+
+ m_xComposer->setQuery(sTranslatedStmt);
+ sTranslatedStmt = m_xComposer->getComposedQuery();
+ }
+ catch(const SQLException& e)
+ {
+ ::dbtools::SQLExceptionInfo aInfo(e);
+ showError(aInfo);
+ // an error occurred so we clear the statement
+ sTranslatedStmt = ::rtl::OUString();
+ }
+ }
+ else if(!m_sStatement.getLength())
+ {
+ ModuleRes aModuleRes(STR_QRY_NOSELECT);
+ String sTmpStr(aModuleRes);
+ ::rtl::OUString sError(sTmpStr);
+ showError(SQLException(sError,NULL,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000") ),1000,Any()));
+ }
+ else
+ sTranslatedStmt = m_sStatement;
+
+ return sTranslatedStmt;
+}
+// -----------------------------------------------------------------------------
+short OQueryController::saveModified()
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+ short nRet = RET_YES;
+ if ( !isConnected() || !isModified() )
+ return nRet;
+
+ if ( !m_bGraphicalDesign
+ || ( !m_vTableFieldDesc.empty()
+ && !m_vTableData.empty()
+ )
+ )
+ {
+ String sMessageText( lcl_getObjectResourceString( STR_QUERY_SAVEMODIFIED, m_nCommandType ) );
+ QueryBox aQry( getView(), WB_YES_NO_CANCEL | WB_DEF_YES, sMessageText );
+
+ nRet = aQry.Execute();
+ if ( ( nRet == RET_YES )
+ && !doSaveAsDoc( sal_False )
+ )
+ {
+ nRet = RET_CANCEL;
+ }
+ }
+ return nRet;
+}
+// -----------------------------------------------------------------------------
+void OQueryController::impl_reset( const bool i_bForceCurrentControllerSettings )
+{
+ bool bValid = false;
+
+ Sequence< PropertyValue > aLayoutInformation;
+ // get command from the query if a query name was supplied
+ if ( !i_bForceCurrentControllerSettings && !editingCommand() )
+ {
+ if ( m_sName.getLength() )
+ {
+ Reference< XNameAccess > xQueries = getObjectContainer();
+ if ( xQueries.is() )
+ {
+ Reference< XPropertySet > xProp;
+ if( xQueries->hasByName( m_sName ) && ( xQueries->getByName( m_sName ) >>= xProp ) && xProp.is() )
+ {
+ ::rtl::OUString sNewStatement;
+ xProp->getPropertyValue( PROPERTY_COMMAND ) >>= sNewStatement;
+ setStatement_fireEvent( sNewStatement );
+
+ sal_Bool bNewEscapeProcessing( sal_True );
+ if ( editingQuery() )
+ {
+ xProp->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bNewEscapeProcessing;
+ setEscapeProcessing_fireEvent( bNewEscapeProcessing );
+ }
+
+ m_bGraphicalDesign = m_bGraphicalDesign && m_bEscapeProcessing;
+ bValid = true;
+
+ try
+ {
+ if ( editingQuery() )
+ xProp->getPropertyValue( PROPERTY_LAYOUTINFORMATION ) >>= aLayoutInformation;
+ }
+ catch( const Exception& )
+ {
+ OSL_FAIL( "OQueryController::impl_reset: could not retrieve the layout information from the query!" );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ bValid = true;
+ // assume that we got all necessary information during initialization
+ }
+
+ if ( bValid )
+ {
+ // load the layoutInformation
+ if ( aLayoutInformation.getLength() )
+ {
+ try
+ {
+ loadViewSettings( aLayoutInformation );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ if ( m_sStatement.getLength() )
+ {
+ setQueryComposer();
+
+ bool bError( false );
+
+ if ( !m_pSqlIterator )
+ {
+ bError = true;
+ }
+ else if ( m_bEscapeProcessing )
+ {
+ ::rtl::OUString aErrorMsg;
+ ::std::auto_ptr< ::connectivity::OSQLParseNode > pNode(
+ m_aSqlParser.parseTree( aErrorMsg, m_sStatement, m_bGraphicalDesign ) );
+
+ if ( pNode.get() )
+ {
+ delete m_pSqlIterator->getParseTree();
+ m_pSqlIterator->setParseTree( pNode.release() );
+ m_pSqlIterator->traverseAll();
+ if ( m_pSqlIterator->hasErrors() )
+ {
+ if ( !i_bForceCurrentControllerSettings && m_bGraphicalDesign && !editingView() )
+ {
+ impl_showAutoSQLViewError( makeAny( m_pSqlIterator->getErrors() ) );
+ }
+ bError = true;
+ }
+ }
+ else
+ {
+ if ( !i_bForceCurrentControllerSettings && !editingView() )
+ {
+ String aTitle(ModuleRes(STR_SVT_SQL_SYNTAX_ERROR));
+ OSQLMessageBox aDlg(getView(),aTitle,aErrorMsg);
+ aDlg.Execute();
+ }
+ bError = true;
+ }
+ }
+
+ if ( bError )
+ {
+ m_bGraphicalDesign = sal_False;
+ if ( editingView() )
+ // if we're editing a view whose statement could not be parsed, default to "no escape processing"
+ setEscapeProcessing_fireEvent( sal_False );
+ }
+ }
+ }
+
+ if(!m_pSqlIterator)
+ setQueryComposer();
+ OSL_ENSURE(m_pSqlIterator,"No SQLIterator set!");
+
+ getContainer()->setNoneVisbleRow(m_nVisibleRows);
+}
+
+// -----------------------------------------------------------------------------
+void OQueryController::reset()
+{
+ impl_reset();
+ getContainer()->reset( NULL );
+ ClearUndoManager();
+}
+
+// -----------------------------------------------------------------------------
+void OQueryController::setStatement_fireEvent( const ::rtl::OUString& _rNewStatement, bool _bFireStatementChange )
+{
+ Any aOldValue = makeAny( m_sStatement );
+ m_sStatement = _rNewStatement;
+ Any aNewValue = makeAny( m_sStatement );
+
+ sal_Int32 nHandle = PROPERTY_ID_ACTIVECOMMAND;
+ if ( _bFireStatementChange )
+ fire( &nHandle, &aNewValue, &aOldValue, 1, sal_False );
+}
+
+// -----------------------------------------------------------------------------
+void OQueryController::setEscapeProcessing_fireEvent( const sal_Bool _bEscapeProcessing )
+{
+ if ( _bEscapeProcessing == m_bEscapeProcessing )
+ return;
+
+ Any aOldValue = makeAny( m_bEscapeProcessing );
+ m_bEscapeProcessing = _bEscapeProcessing;
+ Any aNewValue = makeAny( m_bEscapeProcessing );
+
+ sal_Int32 nHandle = PROPERTY_ID_ESCAPE_PROCESSING;
+ fire( &nHandle, &aNewValue, &aOldValue, 1, sal_False );
+}
+
+// -----------------------------------------------------------------------------
+IMPL_LINK( OQueryController, OnExecuteAddTable, void*, /*pNotInterestedIn*/ )
+{
+ Execute( ID_BROWSER_ADDTABLE,Sequence<PropertyValue>() );
+ return 0L;
+}
+
+// -----------------------------------------------------------------------------
+bool OQueryController::allowViews() const
+{
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+bool OQueryController::allowQueries() const
+{
+ OSL_ENSURE( getSdbMetaData().isConnected(), "OQueryController::allowQueries: illegal call!" );
+ if ( !getSdbMetaData().supportsSubqueriesInFrom() )
+ return false;
+
+ const NamedValueCollection& rArguments( getInitParams() );
+ sal_Int32 nCommandType = rArguments.getOrDefault( (::rtl::OUString)PROPERTY_COMMAND_TYPE, (sal_Int32)CommandType::QUERY );
+ sal_Bool bCreatingView = ( nCommandType == CommandType::TABLE );
+ return !bCreatingView;
+}
+
+// -----------------------------------------------------------------------------
+Any SAL_CALL OQueryController::getViewData() throw( RuntimeException )
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+
+ getContainer()->SaveUIConfig();
+
+ ::comphelper::NamedValueCollection aViewSettings;
+ saveViewSettings( aViewSettings, false );
+
+ return makeAny( aViewSettings.getPropertyValues() );
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OQueryController::restoreViewData(const Any& /*Data*/) throw( RuntimeException )
+{
+ // TODO
+}
+
+// -----------------------------------------------------------------------------
+} // namespace dbaui
+// -----------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/querydlg.cxx b/dbaccess/source/ui/querydesign/querydlg.cxx
new file mode 100644
index 000000000000..2b9e70e8d07b
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/querydlg.cxx
@@ -0,0 +1,375 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "querydlg.hxx"
+#include "dbu_qry.hrc"
+#include "querydlg.hrc"
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include "QTableConnectionData.hxx"
+#include "querycontroller.hxx"
+#include "QueryTableView.hxx"
+#include "QueryDesignView.hxx"
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include "RelationControl.hxx"
+#include <vcl/msgbox.hxx>
+
+using namespace dbaui;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdbc;
+
+namespace dbaui
+{
+class OJoinControl : public Window
+{
+public:
+ FixedLine aFL_Join;
+ FixedText aFT_Title;
+ ListBox aLB_JoinType;
+ CheckBox m_aCBNatural;
+
+ OJoinControl(Window* _pParent,const ResId& _rResId);
+};
+OJoinControl::OJoinControl(Window* _pParent,const ResId& _rResId)
+ : Window(_pParent,_rResId)
+ ,aFL_Join( this, ResId( FL_JOIN,*_rResId.GetResMgr() ) )
+ ,aFT_Title( this, ResId(FT_LISTBOXTITLE,*_rResId.GetResMgr()) )
+ ,aLB_JoinType( this, ResId(LB_JOINTYPE,*_rResId.GetResMgr()) )
+ ,m_aCBNatural( this, ResId(CB_NATURAL,*_rResId.GetResMgr()) )
+{
+ FreeResource();
+}
+// -----------------------------------------------------------------------------
+} // dbaui
+// -----------------------------------------------------------------------------
+DBG_NAME(DlgQryJoin)
+DlgQryJoin::DlgQryJoin( OQueryTableView * pParent,
+ const TTableConnectionData::value_type& _pData,
+ OJoinTableView::OTableWindowMap* _pTableMap,
+ const Reference< XConnection >& _xConnection,
+ sal_Bool _bAllowTableSelect)
+ :ModalDialog( pParent, ModuleRes(DLG_QRY_JOIN) )
+ ,aML_HelpText( this, ModuleRes(ML_HELPTEXT) )
+ ,aPB_OK( this, ModuleRes( PB_OK ) )
+ ,aPB_CANCEL( this, ModuleRes( PB_CANCEL ) )
+ ,aPB_HELP( this, ModuleRes( PB_HELP ) )
+ ,m_pJoinControl( NULL )
+ ,m_pTableControl( NULL )
+ ,m_pTableMap(_pTableMap)
+ ,m_pTableView(pParent)
+ ,eJoinType(static_cast<OQueryTableConnectionData*>(_pData.get())->GetJoinType())
+ ,m_pOrigConnData(_pData)
+ ,m_xConnection(_xConnection)
+{
+ DBG_CTOR(DlgQryJoin,NULL);
+
+ aML_HelpText.SetControlBackground( GetSettings().GetStyleSettings().GetFaceColor() );
+ //////////////////////////////////////////////////////////////////////
+ // Connection kopieren
+ m_pConnData.reset(_pData->NewInstance());
+ m_pConnData->CopyFrom(*_pData);
+
+ m_pTableControl = new OTableListBoxControl(this,ModuleRes(WND_CONTROL),m_pTableMap,this);
+
+ m_pJoinControl = new OJoinControl(m_pTableControl,ModuleRes(WND_JOIN_CONTROL));
+
+ m_pJoinControl->Show();
+ m_pJoinControl->m_aCBNatural.Check(static_cast<OQueryTableConnectionData*>(m_pConnData.get())->isNatural());
+ m_pTableControl->Show();
+
+ if( _bAllowTableSelect )
+ {
+ m_pTableControl->Init( m_pConnData );
+ m_pTableControl->fillListBoxes();
+ }
+ else
+ {
+ m_pTableControl->fillAndDisable(m_pConnData);
+ m_pTableControl->Init( m_pConnData );
+ }
+
+ m_pTableControl->lateUIInit(m_pJoinControl);
+
+ sal_Bool bSupportFullJoin = sal_False;
+ Reference<XDatabaseMetaData> xMeta;
+ try
+ {
+ xMeta = m_xConnection->getMetaData();
+ if ( xMeta.is() )
+ bSupportFullJoin = xMeta->supportsFullOuterJoins();
+ }
+ catch(SQLException&)
+ {
+ }
+ sal_Bool bSupportOuterJoin = sal_False;
+ try
+ {
+ if ( xMeta.is() )
+ bSupportOuterJoin= xMeta->supportsOuterJoins();
+ }
+ catch(SQLException&)
+ {
+ }
+
+ setJoinType(eJoinType);
+
+ aPB_OK.SetClickHdl( LINK(this, DlgQryJoin, OKClickHdl) );
+
+ m_pJoinControl->aLB_JoinType.SetSelectHdl(LINK(this,DlgQryJoin,LBChangeHdl));
+ m_pJoinControl->m_aCBNatural.SetToggleHdl(LINK(this,DlgQryJoin,NaturalToggleHdl));
+
+ if ( static_cast<OQueryTableView*>(pParent)->getDesignView()->getController().isReadOnly() )
+ {
+ m_pJoinControl->aLB_JoinType.Disable();
+ m_pJoinControl->m_aCBNatural.Disable();
+ m_pTableControl->Disable();
+ }
+ else
+ {
+ const sal_uInt16 nCount = m_pJoinControl->aLB_JoinType.GetEntryCount();
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ const long nJoinTyp = reinterpret_cast<long>(m_pJoinControl->aLB_JoinType.GetEntryData(i));
+ if ( !bSupportFullJoin && nJoinTyp == ID_FULL_JOIN )
+ m_pJoinControl->aLB_JoinType.RemoveEntry(i);
+ else if ( !bSupportOuterJoin && (nJoinTyp == ID_LEFT_JOIN || nJoinTyp == ID_RIGHT_JOIN) )
+ m_pJoinControl->aLB_JoinType.RemoveEntry(i);
+ }
+
+ m_pTableControl->NotifyCellChange();
+ m_pTableControl->enableRelation(!static_cast<OQueryTableConnectionData*>(m_pConnData.get())->isNatural() && eJoinType != CROSS_JOIN );
+ }
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+DlgQryJoin::~DlgQryJoin()
+{
+ DBG_DTOR(DlgQryJoin,NULL);
+ delete m_pJoinControl;
+ delete m_pTableControl;
+}
+// -----------------------------------------------------------------------------
+IMPL_LINK( DlgQryJoin, LBChangeHdl, ListBox*, /*pListBox*/ )
+{
+ DBG_CHKTHIS(DlgQryJoin,NULL);
+ if (m_pJoinControl->aLB_JoinType.GetSelectEntryPos() == m_pJoinControl->aLB_JoinType.GetSavedValue() )
+ return 1;
+
+ m_pJoinControl->aLB_JoinType.SaveValue();
+ aML_HelpText.SetText(String());
+
+ m_pTableControl->enableRelation(true);
+
+ String sFirstWinName = m_pConnData->getReferencingTable()->GetWinName();
+ String sSecondWinName = m_pConnData->getReferencedTable()->GetWinName();
+ const EJoinType eOldJoinType = eJoinType;
+ sal_uInt16 nResId = 0;
+ const sal_uInt16 nPos = m_pJoinControl->aLB_JoinType.GetSelectEntryPos();
+ const long nJoinType = reinterpret_cast<long>(m_pJoinControl->aLB_JoinType.GetEntryData(nPos));
+ sal_Bool bAddHint = sal_True;
+ switch ( nJoinType )
+ {
+ default:
+ case ID_INNER_JOIN:
+ nResId = STR_QUERY_INNER_JOIN;
+ bAddHint = sal_False;
+ eJoinType = INNER_JOIN;
+ break;
+ case ID_LEFT_JOIN:
+ nResId = STR_QUERY_LEFTRIGHT_JOIN;
+ eJoinType = LEFT_JOIN;
+ break;
+ case ID_RIGHT_JOIN:
+ {
+ nResId = STR_QUERY_LEFTRIGHT_JOIN;
+ eJoinType = RIGHT_JOIN;
+ String sTemp = sFirstWinName;
+ sFirstWinName = sSecondWinName;
+ sSecondWinName = sTemp;
+ }
+ break;
+ case ID_FULL_JOIN:
+ nResId = STR_QUERY_FULL_JOIN;
+ eJoinType = FULL_JOIN;
+ break;
+ case ID_CROSS_JOIN:
+ {
+ nResId = STR_QUERY_CROSS_JOIN;
+ eJoinType = CROSS_JOIN;
+
+ m_pConnData->ResetConnLines();
+ m_pTableControl->lateInit();
+ m_pJoinControl->m_aCBNatural.Check(sal_False);
+ m_pTableControl->enableRelation(false);
+ ::rtl::OUString sEmpty;
+ m_pConnData->AppendConnLine(sEmpty,sEmpty);
+ aPB_OK.Enable(sal_True);
+ }
+ break;
+ }
+
+ m_pJoinControl->m_aCBNatural.Enable(eJoinType != CROSS_JOIN);
+
+ if ( eJoinType != eOldJoinType && eOldJoinType == CROSS_JOIN )
+ {
+ m_pConnData->ResetConnLines();
+ }
+ if ( eJoinType != CROSS_JOIN )
+ {
+ m_pTableControl->NotifyCellChange();
+ NaturalToggleHdl(&m_pJoinControl->m_aCBNatural);
+ }
+
+ m_pTableControl->Invalidate();
+
+ String sHelpText = String( ModuleRes( nResId ) );
+ if( nPos )
+ {
+ sHelpText.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%1" ) ), sFirstWinName );
+ sHelpText.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%2" ) ), sSecondWinName );
+ }
+ if ( bAddHint )
+ {
+ sHelpText += String( RTL_CONSTASCII_USTRINGPARAM( "\n" ) );
+ sHelpText += String( ModuleRes( STR_JOIN_TYPE_HINT ) );
+ }
+
+ aML_HelpText.SetText( sHelpText );
+ return 1;
+}
+// -----------------------------------------------------------------------------
+
+IMPL_LINK( DlgQryJoin, OKClickHdl, Button*, /*pButton*/ )
+{
+ DBG_CHKTHIS(DlgQryJoin,NULL);
+
+ m_pConnData->Update();
+ m_pOrigConnData->CopyFrom( *m_pConnData );
+
+ EndDialog(RET_OK);
+ return 1;
+}
+// -----------------------------------------------------------------------------
+
+IMPL_LINK( DlgQryJoin, NaturalToggleHdl, CheckBox*, /*pButton*/ )
+{
+ DBG_CHKTHIS(DlgQryJoin,NULL);
+ sal_Bool bChecked = m_pJoinControl->m_aCBNatural.IsChecked();
+ static_cast<OQueryTableConnectionData*>(m_pConnData.get())->setNatural(bChecked);
+ m_pTableControl->enableRelation(!bChecked);
+ if ( bChecked )
+ {
+ m_pConnData->ResetConnLines();
+ try
+ {
+ Reference<XNameAccess> xReferencedTableColumns(m_pConnData->getReferencedTable()->getColumns());
+ Sequence< ::rtl::OUString> aSeq = m_pConnData->getReferencingTable()->getColumns()->getElementNames();
+ const ::rtl::OUString* pIter = aSeq.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ if ( xReferencedTableColumns->hasByName(*pIter) )
+ m_pConnData->AppendConnLine(*pIter,*pIter);
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ m_pTableControl->NotifyCellChange();
+ m_pTableControl->Invalidate();
+ }
+
+ return 1;
+}
+// -----------------------------------------------------------------------------
+TTableConnectionData::value_type DlgQryJoin::getConnectionData() const
+{
+ return m_pConnData;
+}
+// -----------------------------------------------------------------------------
+void DlgQryJoin::setValid(sal_Bool _bValid)
+{
+ aPB_OK.Enable(_bValid || eJoinType == CROSS_JOIN );
+}
+// -----------------------------------------------------------------------------
+void DlgQryJoin::notifyConnectionChange( )
+{
+ setJoinType( static_cast<OQueryTableConnectionData*>(m_pConnData.get())->GetJoinType() );
+ m_pJoinControl->m_aCBNatural.Check(static_cast<OQueryTableConnectionData*>(m_pConnData.get())->isNatural());
+ NaturalToggleHdl(&m_pJoinControl->m_aCBNatural);
+}
+// -----------------------------------------------------------------------------
+void DlgQryJoin::setJoinType(EJoinType _eNewJoinType)
+{
+ eJoinType = _eNewJoinType;
+ m_pJoinControl->m_aCBNatural.Enable(eJoinType != CROSS_JOIN);
+
+ long nJoinType = 0;
+ switch ( eJoinType )
+ {
+ default:
+ case INNER_JOIN:
+ nJoinType = ID_INNER_JOIN;
+ break;
+ case LEFT_JOIN:
+ nJoinType = ID_LEFT_JOIN;
+ break;
+ case RIGHT_JOIN:
+ nJoinType = ID_RIGHT_JOIN;
+ break;
+ case FULL_JOIN:
+ nJoinType = ID_FULL_JOIN;
+ break;
+ case CROSS_JOIN:
+ nJoinType = ID_CROSS_JOIN;
+ break;
+ }
+
+ const sal_uInt16 nCount = m_pJoinControl->aLB_JoinType.GetEntryCount();
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ if ( nJoinType == reinterpret_cast<long>(m_pJoinControl->aLB_JoinType.GetEntryData(i)) )
+ {
+ m_pJoinControl->aLB_JoinType.SelectEntryPos(i);
+ break;
+ }
+ }
+
+ LBChangeHdl(&m_pJoinControl->aLB_JoinType);
+}
+// -----------------------------------------------------------------------------
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/querydlg.hrc b/dbaccess/source/ui/querydesign/querydlg.hrc
new file mode 100644
index 000000000000..0112fe1ffa56
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/querydlg.hrc
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef DBAUI_QUERYDLG_HRC
+#define DBAUI_QUERYDLG_HRC
+
+#ifndef DBACCESS_SOURCE_UI_INC_RELATIONCONTROL_HRC
+#include "RelationControl.hrc"
+#endif
+
+#define FL_JOIN 1
+#define FT_LISTBOXTITLE 2
+
+#define LB_JOINTYPE 1
+
+#define GB_FIELDS 1
+
+#define CB_NATURAL 1
+
+#define PB_OK 1
+#define PB_CANCEL 2
+#define PB_HELP 3
+#define ML_HELPTEXT 4
+
+#define WND_JOIN_CONTROL 1
+#define WND_CONTROL 2
+
+#define ID_INNER_JOIN 1
+#define ID_LEFT_JOIN 2
+#define ID_RIGHT_JOIN 3
+#define ID_FULL_JOIN 4
+#define ID_CROSS_JOIN 5
+
+#endif // DBAUI_QUERYDLG_HRC
+
+
+
diff --git a/dbaccess/source/ui/querydesign/querydlg.hxx b/dbaccess/source/ui/querydesign/querydlg.hxx
new file mode 100644
index 000000000000..21f4aea129ef
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/querydlg.hxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DBAUI_QUERYDLG_HXX
+#define DBAUI_QUERYDLG_HXX
+#include <vcl/dialog.hxx>
+
+#include <vcl/button.hxx>
+
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+
+#include "QEnumTypes.hxx"
+
+#include "RelControliFace.hxx"
+#include "JoinTableView.hxx"
+
+
+namespace dbaui
+{
+ class OQueryTableConnectionData;
+ class OTableListBoxControl;
+ class OQueryTableView;
+ class OJoinControl;
+ class DlgQryJoin : public ModalDialog
+ ,public IRelationControlInterface
+ {
+ protected:
+ FixedText aML_HelpText;
+ OKButton aPB_OK;
+ CancelButton aPB_CANCEL;
+ HelpButton aPB_HELP;
+
+ OJoinControl* m_pJoinControl;
+ OTableListBoxControl* m_pTableControl;
+ OJoinTableView::OTableWindowMap* m_pTableMap;
+ OQueryTableView* m_pTableView;
+
+ EJoinType eJoinType;
+ TTableConnectionData::value_type m_pConnData; // enth"alt linke und rechte Tabelle
+ TTableConnectionData::value_type m_pOrigConnData;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_xConnection;
+
+
+ DECL_LINK( OKClickHdl, Button* );
+ DECL_LINK( LBChangeHdl, ListBox* );
+ DECL_LINK( NaturalToggleHdl, CheckBox* );
+
+ /** setJoinType enables and set the new join type
+ @param _eNewJoinType the new jointype
+ */
+ void setJoinType(EJoinType _eNewJoinType);
+ public:
+ DlgQryJoin( OQueryTableView * pParent,
+ const TTableConnectionData::value_type& pData,
+ OJoinTableView::OTableWindowMap* _pTableMap,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection,
+ sal_Bool _bAllowTableSelect);
+ virtual ~DlgQryJoin();
+ EJoinType GetJoinType() const { return eJoinType; };
+
+ /** getConnectionData returns the current connection data
+ @return the current connectiondata
+ */
+ virtual TTableConnectionData::value_type getConnectionData() const;
+
+ /** setValid set the valid inside, can be used for OK buttons
+ @param _bValid true when the using control allows an update
+ */
+ virtual void setValid(sal_Bool _bValid);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > getConnection() { return m_xConnection; }
+
+ /** notifyConnectionChange is callback which is called when the table selection has changed and a new connection exists
+ @param _pConnectionData the connection which exists between the new tables
+ */
+ virtual void notifyConnectionChange();
+ };
+}
+#endif // DBAUI_QUERYDLG_HXX
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/ui/querydesign/querydlg.src b/dbaccess/source/ui/querydesign/querydlg.src
new file mode 100644
index 000000000000..e0aec2c49d84
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/querydlg.src
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _DBU_QRY_HRC_
+#include "dbu_qry.hrc"
+#endif
+#ifndef DBAUI_QUERYDLG_HRC
+#include "querydlg.hrc"
+#endif
+#include "dbaccess_helpid.hrc"
+
+ModalDialog DLG_QRY_JOIN
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ HelpId = HID_DLG_QRY_JOIN ;
+ Size = MAP_APPFONT ( 265, 219 ) ;
+
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+
+ Window WND_JOIN_CONTROL
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 203, 44 );
+ DialogControl = TRUE;
+ HelpId = HID_DLG_QRY_JOIN_CONTROL ;
+ FixedLine FL_JOIN
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 191 , 8 ) ;
+ Text [ en-US ] = "Options";
+ };
+
+ FixedText FT_LISTBOXTITLE
+ {
+ Pos = MAP_APPFONT ( 12 , 16 ) ;
+ Size = MAP_APPFONT ( 89 , 8 ) ;
+
+ Text [ en-US ] = "~Type";
+ };
+
+ ListBox LB_JOINTYPE
+ {
+ Pos = MAP_APPFONT ( 101 , 15 ) ;
+ Size = MAP_APPFONT ( 90 , 60 ) ;
+ HelpId = HID_DLG_QRY_JOINTYPE ;
+
+ DropDown = TRUE;
+ DDExtraWidth = TRUE;
+ StringList [ en-US ] =
+ {
+ < "Inner join" ; ID_INNER_JOIN; > ;
+ < "Left join" ; ID_LEFT_JOIN; > ;
+ < "Right join" ; ID_RIGHT_JOIN; > ;
+ < "Full (outer) join" ; ID_FULL_JOIN; > ;
+ < "Cross join" ; ID_CROSS_JOIN; > ;
+ };
+ };
+ CheckBox CB_NATURAL
+ {
+ HelpID = "dbaccess:CheckBox:DLG_QRY_JOIN:CB_NATURAL";
+ Pos = MAP_APPFONT ( 101 , 31 ) ;
+ Size = MAP_APPFONT ( 89 , 8 ) ;
+
+ Text [ en-US ] = "Natural";
+ };
+ };
+
+ Window WND_CONTROL
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 203, 153 );
+ DialogControl = TRUE;
+ HelpId = HID_DLG_QRY_WINDOW_CONTROL ;
+
+ FixedLine FL_INVOLVED_TABLES
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 191 , 8 ) ;
+ Text [ en-US ] = "Tables involved";
+ };
+
+ ListBox LB_LEFT_TABLE
+ {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 12, 14 );
+ Size = MAP_APPFONT( 87, 60 );
+ HelpId = HID_DLG_QRY_LEFT_TABLE ;
+ DropDown = TRUE;
+ TabStop = TRUE;
+ };
+
+ ListBox LB_RIGHT_TABLE
+ {
+ Border = TRUE;
+ Pos = MAP_APPFONT( 104, 14 );
+ Size = MAP_APPFONT( 87, 60 );
+ HelpId = HID_DLG_QRY_RIGHT_TABLE ;
+ DropDown = TRUE;
+ TabStop = TRUE;
+ };
+
+ FixedLine FL_INVOLVED_FIELDS
+ {
+ Pos = MAP_APPFONT ( 6 , 29 ) ;
+ Size = MAP_APPFONT ( 191 , 8 ) ;
+ Text [ en-US ] = "Fields involved";
+ };
+ };
+
+ FixedText ML_HELPTEXT
+ {
+ Pos = MAP_APPFONT ( 12 , 159 ) ;
+ Size = MAP_APPFONT ( 179 , 49 ) ;
+ UniqueId = HID_DLG_QRY_HELPTEXT ;
+ SVLook = TRUE;
+ WordBreak = TRUE;
+ };
+
+ OKButton PB_OK
+ {
+ Pos = MAP_APPFONT ( 206 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton PB_CANCEL
+ {
+ Pos = MAP_APPFONT ( 206 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton PB_HELP
+ {
+ Pos = MAP_APPFONT ( 206 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+
+ Text [ en-US ] = "Join Properties";
+};
+
+String STR_JOIN_TYPE_HINT
+{
+ Text [ en-US ] = "Please note that some databases may not support this join type.";
+};
+
+String STR_QUERY_INNER_JOIN
+{
+ Text [ en-US ] = "Includes only records for which the contents of the related fields of both tables are identical.";
+};
+
+String STR_QUERY_LEFTRIGHT_JOIN
+{
+ Text [ en-US ] = "Contains ALL records from table '%1' but only records from table '%2' where the values in the related fields are matching.";
+};
+
+String STR_QUERY_FULL_JOIN
+{
+ Text [ en-US ] = "Contains ALL records from '%1' and from '%2'.";
+};
+
+String STR_QUERY_CROSS_JOIN
+{
+ Text [ en-US ] = "Contains the cartesian product of ALL records from '%1' and from '%2'.";
+};
+
+String STR_QUERY_NATURAL_JOIN
+{
+ Text [ en-US ] = "Contains only one column for each pair of equally-named columns from '%1' and from '%2'.";
+};
diff --git a/dbaccess/source/ui/querydesign/queryview.cxx b/dbaccess/source/ui/querydesign/queryview.cxx
new file mode 100644
index 000000000000..dea455795484
--- /dev/null
+++ b/dbaccess/source/ui/querydesign/queryview.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_dbaccess.hxx"
+#include "queryview.hxx"
+#include "dbu_qry.hrc"
+#include "querycontroller.hxx"
+
+
+using namespace dbaui;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+DBG_NAME(OQueryView)
+// -------------------------------------------------------------------------
+OQueryView::OQueryView(Window* _pParent, OQueryController& _rController,const Reference< XMultiServiceFactory >& _rFactory)
+ :OJoinDesignView( _pParent, _rController, _rFactory )
+{
+ DBG_CTOR(OQueryView,NULL);
+
+}
+// -----------------------------------------------------------------------------
+OQueryView::~OQueryView()
+{
+
+ DBG_DTOR(OQueryView,NULL);
+}
+// -----------------------------------------------------------------------------
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */