/************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_dbaccess.hxx" #ifndef DBAUI_TABLEWINDOWLISTBOX_HXX #include "TableWindowListBox.hxx" #endif #ifndef DBAUI_TABLEWINDOW_HXX #include "TableWindow.hxx" #endif #ifndef DBAUI_QUERYDESIGNVIEW_HXX #include "QueryDesignView.hxx" #endif #ifndef DBAUI_QUERYTABLEVIEW_HXX #include "QueryTableView.hxx" #endif #ifndef DBAUI_QUERYCONTROLLER_HXX #include "querycontroller.hxx" #endif #ifndef DBAUI_JOINEXCHANGE_HXX #include "JoinExchange.hxx" #endif #ifndef _TOOLS_DEBUG_HXX #include #endif #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_ #include #endif #ifndef _SVX_DBEXCH_HRC #include #endif #ifndef _SV_SVAPP_HXX #include #endif 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().clearOccuredError()); // 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 = rController.getConnection(); if(xConnection.is()) { Reference 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); // bHandled = sal_True; } break; } if (rCode.IsMod1() || rCode.IsMod2() || rCode.IsShift()) break; if (FirstSelected()) static_cast(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 ); // m_aScrollTimer.Start(); } 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 ); // m_aScrollTimer.Start(); } 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()) { // #100271# OJ 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().setErrorOccured(::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(); DBG_ASSERT(pParent != NULL, "OTableWindowListBox::OnDoubleClick : habe kein Parent !"); static_cast(pParent)->OnEntryDoubleClicked(GetHdlEntry()); return 0; } // ----------------------------------------------------------------------------- void OTableWindowListBox::Command(const CommandEvent& rEvt) { switch (rEvt.GetCommand()) { case COMMAND_CONTEXTMENU: { static_cast(Window::GetParent())->Command(rEvt); break; } default: SvTreeListBox::Command(rEvt); } } // -----------------------------------------------------------------------------