1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_dbaccess.hxx" 30*cdf0e10cSrcweir #ifndef DBAUI_QUERYVIEWSWITCH_HXX 31*cdf0e10cSrcweir #include "QueryViewSwitch.hxx" 32*cdf0e10cSrcweir #endif 33*cdf0e10cSrcweir #ifndef DBAUI_QUERYDESIGNVIEW_HXX 34*cdf0e10cSrcweir #include "QueryDesignView.hxx" 35*cdf0e10cSrcweir #endif 36*cdf0e10cSrcweir #ifndef DBAUI_QUERYVIEW_TEXT_HXX 37*cdf0e10cSrcweir #include "QueryTextView.hxx" 38*cdf0e10cSrcweir #endif 39*cdf0e10cSrcweir #ifndef DBAUI_QUERYCONTAINERWINDOW_HXX 40*cdf0e10cSrcweir #include "querycontainerwindow.hxx" 41*cdf0e10cSrcweir #endif 42*cdf0e10cSrcweir #ifndef _DBU_QRY_HRC_ 43*cdf0e10cSrcweir #include "dbu_qry.hrc" 44*cdf0e10cSrcweir #endif 45*cdf0e10cSrcweir #ifndef DBACCESS_UI_BROWSER_ID_HXX 46*cdf0e10cSrcweir #include "browserids.hxx" 47*cdf0e10cSrcweir #endif 48*cdf0e10cSrcweir #ifndef DBAUI_QYDLGTAB_HXX 49*cdf0e10cSrcweir #include "adtabdlg.hxx" 50*cdf0e10cSrcweir #endif 51*cdf0e10cSrcweir #ifndef DBAUI_QUERYCONTROLLER_HXX 52*cdf0e10cSrcweir #include "querycontroller.hxx" 53*cdf0e10cSrcweir #endif 54*cdf0e10cSrcweir #ifndef DBAUI_SQLEDIT_HXX 55*cdf0e10cSrcweir #include "sqledit.hxx" 56*cdf0e10cSrcweir #endif 57*cdf0e10cSrcweir #ifndef DBAUI_QUERYCONTAINERWINDOW_HXX 58*cdf0e10cSrcweir #include "querycontainerwindow.hxx" 59*cdf0e10cSrcweir #endif 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir using namespace dbaui; 62*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 63*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir DBG_NAME(OQueryViewSwitch) 66*cdf0e10cSrcweir OQueryViewSwitch::OQueryViewSwitch(OQueryContainerWindow* _pParent, OQueryController& _rController,const Reference< XMultiServiceFactory >& _rFactory) 67*cdf0e10cSrcweir : m_bAddTableDialogWasVisible(sal_False) 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir DBG_CTOR(OQueryViewSwitch,NULL); 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir m_pTextView = new OQueryTextView(_pParent); 72*cdf0e10cSrcweir m_pDesignView = new OQueryDesignView( _pParent, _rController, _rFactory ); 73*cdf0e10cSrcweir } 74*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 75*cdf0e10cSrcweir OQueryViewSwitch::~OQueryViewSwitch() 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir DBG_DTOR(OQueryViewSwitch,NULL); 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir ::std::auto_ptr<Window> aTemp(m_pTextView); 80*cdf0e10cSrcweir m_pTextView = NULL; 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir ::std::auto_ptr<Window> aTemp(m_pDesignView); 84*cdf0e10cSrcweir m_pDesignView = NULL; 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir } 87*cdf0e10cSrcweir // ------------------------------------------------------------------------- 88*cdf0e10cSrcweir void OQueryViewSwitch::Construct() 89*cdf0e10cSrcweir { 90*cdf0e10cSrcweir m_pDesignView->Construct( ); 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 93*cdf0e10cSrcweir void OQueryViewSwitch::initialize() 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir // initially be in SQL mode 96*cdf0e10cSrcweir m_pTextView->Show(); 97*cdf0e10cSrcweir m_pDesignView->initialize(); 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir // ------------------------------------------------------------------------- 100*cdf0e10cSrcweir void OQueryViewSwitch::resizeDocumentView(Rectangle& _rPlayground) 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir m_pTextView->SetPosSizePixel( _rPlayground.TopLeft(), _rPlayground.GetSize() ); 103*cdf0e10cSrcweir m_pDesignView->SetPosSizePixel( _rPlayground.TopLeft(), _rPlayground.GetSize() ); 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir // just for completeness: there is no space left, we occupied it all ... 106*cdf0e10cSrcweir _rPlayground.SetPos( _rPlayground.BottomRight() ); 107*cdf0e10cSrcweir _rPlayground.SetSize( Size( 0, 0 ) ); 108*cdf0e10cSrcweir } 109*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 110*cdf0e10cSrcweir sal_Bool OQueryViewSwitch::checkStatement() 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 113*cdf0e10cSrcweir return m_pTextView->checkStatement(); 114*cdf0e10cSrcweir return m_pDesignView->checkStatement(); 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 117*cdf0e10cSrcweir ::rtl::OUString OQueryViewSwitch::getStatement() 118*cdf0e10cSrcweir { 119*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 120*cdf0e10cSrcweir return m_pTextView->getStatement(); 121*cdf0e10cSrcweir return m_pDesignView->getStatement(); 122*cdf0e10cSrcweir } 123*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 124*cdf0e10cSrcweir void OQueryViewSwitch::setReadOnly(sal_Bool _bReadOnly) 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 127*cdf0e10cSrcweir m_pTextView->setReadOnly(_bReadOnly); 128*cdf0e10cSrcweir else 129*cdf0e10cSrcweir m_pDesignView->setReadOnly(_bReadOnly); 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 132*cdf0e10cSrcweir void OQueryViewSwitch::clear() 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 135*cdf0e10cSrcweir m_pTextView->clear(); 136*cdf0e10cSrcweir else 137*cdf0e10cSrcweir m_pDesignView->clear(); 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 140*cdf0e10cSrcweir void OQueryViewSwitch::GrabFocus() 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir if ( m_pTextView && m_pTextView->IsVisible() ) 143*cdf0e10cSrcweir m_pTextView->GrabFocus(); 144*cdf0e10cSrcweir else if ( m_pDesignView && m_pDesignView->IsVisible() ) 145*cdf0e10cSrcweir m_pDesignView->GrabFocus(); 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 148*cdf0e10cSrcweir void OQueryViewSwitch::setStatement(const ::rtl::OUString& _rsStatement) 149*cdf0e10cSrcweir { 150*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 151*cdf0e10cSrcweir m_pTextView->setStatement(_rsStatement); 152*cdf0e10cSrcweir else 153*cdf0e10cSrcweir m_pDesignView->setStatement(_rsStatement); 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 156*cdf0e10cSrcweir void OQueryViewSwitch::copy() 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 159*cdf0e10cSrcweir m_pTextView->copy(); 160*cdf0e10cSrcweir else 161*cdf0e10cSrcweir m_pDesignView->copy(); 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 164*cdf0e10cSrcweir sal_Bool OQueryViewSwitch::isCutAllowed() 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 167*cdf0e10cSrcweir return m_pTextView->isCutAllowed(); 168*cdf0e10cSrcweir return m_pDesignView->isCutAllowed(); 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 171*cdf0e10cSrcweir sal_Bool OQueryViewSwitch::isCopyAllowed() 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 174*cdf0e10cSrcweir return m_pTextView->isCopyAllowed(); 175*cdf0e10cSrcweir return m_pDesignView->isCopyAllowed(); 176*cdf0e10cSrcweir } 177*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 178*cdf0e10cSrcweir sal_Bool OQueryViewSwitch::isPasteAllowed() 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 181*cdf0e10cSrcweir return m_pTextView->isPasteAllowed(); 182*cdf0e10cSrcweir return m_pDesignView->isPasteAllowed(); 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 185*cdf0e10cSrcweir void OQueryViewSwitch::cut() 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 188*cdf0e10cSrcweir m_pTextView->cut(); 189*cdf0e10cSrcweir else 190*cdf0e10cSrcweir m_pDesignView->cut(); 191*cdf0e10cSrcweir } 192*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 193*cdf0e10cSrcweir void OQueryViewSwitch::paste() 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir if(m_pTextView->IsVisible()) 196*cdf0e10cSrcweir m_pTextView->paste(); 197*cdf0e10cSrcweir else 198*cdf0e10cSrcweir m_pDesignView->paste(); 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 201*cdf0e10cSrcweir OQueryContainerWindow* OQueryViewSwitch::getContainer() const 202*cdf0e10cSrcweir { 203*cdf0e10cSrcweir Window* pDesignParent = getDesignView() ? getDesignView()->GetParent() : NULL; 204*cdf0e10cSrcweir return static_cast< OQueryContainerWindow* >( pDesignParent ); 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 208*cdf0e10cSrcweir void OQueryViewSwitch::impl_forceSQLView() 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir OAddTableDlg* pAddTabDialog( getAddTableDialog() ); 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir // hide the "Add Table" dialog 213*cdf0e10cSrcweir m_bAddTableDialogWasVisible = pAddTabDialog ? pAddTabDialog->IsVisible() : false; 214*cdf0e10cSrcweir if ( m_bAddTableDialogWasVisible ) 215*cdf0e10cSrcweir pAddTabDialog->Hide(); 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir // tell the views they're in/active 218*cdf0e10cSrcweir m_pDesignView->stopTimer(); 219*cdf0e10cSrcweir m_pTextView->getSqlEdit()->startTimer(); 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir // set the most recent statement at the text view 222*cdf0e10cSrcweir m_pTextView->clear(); 223*cdf0e10cSrcweir m_pTextView->setStatement(static_cast<OQueryController&>(m_pDesignView->getController()).getStatement()); 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 227*cdf0e10cSrcweir void OQueryViewSwitch::forceInitialView() 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir OQueryController& rQueryController( static_cast< OQueryController& >( m_pDesignView->getController() ) ); 230*cdf0e10cSrcweir const sal_Bool bGraphicalDesign = rQueryController.isGraphicalDesign(); 231*cdf0e10cSrcweir if ( !bGraphicalDesign ) 232*cdf0e10cSrcweir impl_forceSQLView(); 233*cdf0e10cSrcweir else 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir // tell the text view it's inactive now 236*cdf0e10cSrcweir m_pTextView->getSqlEdit()->stopTimer(); 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir // update the "Add Table" dialog 239*cdf0e10cSrcweir OAddTableDlg* pAddTabDialog( getAddTableDialog() ); 240*cdf0e10cSrcweir if ( pAddTabDialog ) 241*cdf0e10cSrcweir pAddTabDialog->Update(); 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir // initialize the design view 244*cdf0e10cSrcweir m_pDesignView->initByFieldDescriptions( rQueryController.getFieldInformation() ); 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir // tell the design view it's active now 247*cdf0e10cSrcweir m_pDesignView->startTimer(); 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir impl_postViewSwitch( bGraphicalDesign, true ); 251*cdf0e10cSrcweir } 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 254*cdf0e10cSrcweir bool OQueryViewSwitch::switchView( ::dbtools::SQLExceptionInfo* _pErrorInfo ) 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir sal_Bool bRet = sal_True; 257*cdf0e10cSrcweir sal_Bool bGraphicalDesign = static_cast<OQueryController&>(m_pDesignView->getController()).isGraphicalDesign(); 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir if ( !bGraphicalDesign ) 260*cdf0e10cSrcweir { 261*cdf0e10cSrcweir impl_forceSQLView(); 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir else 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir // tell the text view it's inactive now 266*cdf0e10cSrcweir m_pTextView->getSqlEdit()->stopTimer(); 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir // update the "Add Table" dialog 269*cdf0e10cSrcweir OAddTableDlg* pAddTabDialog( getAddTableDialog() ); 270*cdf0e10cSrcweir if ( pAddTabDialog ) 271*cdf0e10cSrcweir pAddTabDialog->Update(); 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir // initialize the design view 274*cdf0e10cSrcweir bRet = m_pDesignView->initByParseIterator( _pErrorInfo ); 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir // tell the design view it's active now 277*cdf0e10cSrcweir m_pDesignView->startTimer(); 278*cdf0e10cSrcweir } 279*cdf0e10cSrcweir 280*cdf0e10cSrcweir return impl_postViewSwitch( bGraphicalDesign, bRet ); 281*cdf0e10cSrcweir } 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 284*cdf0e10cSrcweir bool OQueryViewSwitch::impl_postViewSwitch( const bool i_bGraphicalDesign, const bool i_bSuccess ) 285*cdf0e10cSrcweir { 286*cdf0e10cSrcweir if ( i_bSuccess ) 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir m_pTextView->Show ( !i_bGraphicalDesign ); 289*cdf0e10cSrcweir m_pDesignView->Show ( i_bGraphicalDesign ); 290*cdf0e10cSrcweir OAddTableDlg* pAddTabDialog( getAddTableDialog() ); 291*cdf0e10cSrcweir if ( pAddTabDialog ) 292*cdf0e10cSrcweir if ( i_bGraphicalDesign && m_bAddTableDialogWasVisible ) 293*cdf0e10cSrcweir pAddTabDialog->Show(); 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir GrabFocus(); 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir OQueryContainerWindow* pContainer = getContainer(); 299*cdf0e10cSrcweir if ( pContainer ) 300*cdf0e10cSrcweir pContainer->Resize(); 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir m_pDesignView->getController().ClearUndoManager(); 303*cdf0e10cSrcweir m_pDesignView->getController().InvalidateAll(); 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir return i_bSuccess; 306*cdf0e10cSrcweir } 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 309*cdf0e10cSrcweir OAddTableDlg* OQueryViewSwitch::getAddTableDialog() 310*cdf0e10cSrcweir { 311*cdf0e10cSrcweir if ( !m_pDesignView ) 312*cdf0e10cSrcweir return NULL; 313*cdf0e10cSrcweir return m_pDesignView->getController().getAddTableDialog(); 314*cdf0e10cSrcweir } 315*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 316*cdf0e10cSrcweir sal_Bool OQueryViewSwitch::isSlotEnabled(sal_Int32 _nSlotId) 317*cdf0e10cSrcweir { 318*cdf0e10cSrcweir return m_pDesignView->isSlotEnabled(_nSlotId); 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 321*cdf0e10cSrcweir void OQueryViewSwitch::setSlotEnabled(sal_Int32 _nSlotId,sal_Bool _bEnable) 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir m_pDesignView->setSlotEnabled(_nSlotId,_bEnable); 324*cdf0e10cSrcweir } 325*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 326*cdf0e10cSrcweir void OQueryViewSwitch::SaveUIConfig() 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir if(m_pDesignView->IsVisible()) 329*cdf0e10cSrcweir m_pDesignView->SaveUIConfig(); 330*cdf0e10cSrcweir } 331*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 332*cdf0e10cSrcweir void OQueryViewSwitch::SetPosSizePixel( Point _rPt,Size _rSize) 333*cdf0e10cSrcweir { 334*cdf0e10cSrcweir m_pDesignView->SetPosSizePixel( _rPt,_rSize); 335*cdf0e10cSrcweir m_pDesignView->Resize(); 336*cdf0e10cSrcweir m_pTextView->SetPosSizePixel( _rPt,_rSize); 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 339*cdf0e10cSrcweir Reference< XMultiServiceFactory > OQueryViewSwitch::getORB() const 340*cdf0e10cSrcweir { 341*cdf0e10cSrcweir return m_pDesignView->getORB(); 342*cdf0e10cSrcweir } 343*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 344*cdf0e10cSrcweir bool OQueryViewSwitch::reset( ::dbtools::SQLExceptionInfo* _pErrorInfo ) 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir m_pDesignView->reset(); 347*cdf0e10cSrcweir if ( !m_pDesignView->initByParseIterator( _pErrorInfo ) ) 348*cdf0e10cSrcweir return false; 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir if ( switchView( _pErrorInfo ) ) 351*cdf0e10cSrcweir return false; 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir return true; 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 356*cdf0e10cSrcweir void OQueryViewSwitch::setNoneVisbleRow(sal_Int32 _nRows) 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir if(m_pDesignView) 359*cdf0e10cSrcweir m_pDesignView->setNoneVisbleRow(_nRows); 360*cdf0e10cSrcweir } 361*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 362