1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbui.hxx"
26
27 #ifndef DBAUI_DLGSAVE_HXX
28 #include "dlgsave.hxx"
29 #endif
30 #ifndef DBAUI_DLGSAVE_HRC
31 #include "dlgsave.hrc"
32 #endif
33 #ifndef _SV_MSGBOX_HXX //autogen
34 #include <vcl/msgbox.hxx>
35 #endif
36 #ifndef _DBU_DLG_HRC_
37 #include "dbu_dlg.hrc"
38 #endif
39 #ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_
40 #include <com/sun/star/sdb/CommandType.hpp>
41 #endif
42 #ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
43 #include <com/sun/star/sdbc/XRow.hpp>
44 #endif
45 #ifndef _DBAUI_SQLMESSAGE_HXX_
46 #include "sqlmessage.hxx"
47 #endif
48 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
49 #include <connectivity/dbtools.hxx>
50 #endif
51 #ifndef DBAUI_TOOLS_HXX
52 #include "UITools.hxx"
53 #endif
54 #ifndef _DBA_DBACCESS_HELPID_HRC_
55 #include "dbaccess_helpid.hrc"
56 #endif
57 #ifndef DBAUI_SQLNAMEEDIT_HXX
58 #include "SqlNameEdit.hxx"
59 #endif
60 #ifndef _BUTTON_HXX //autogen
61 #include <vcl/button.hxx>
62 #endif
63 #ifndef _FIXED_HXX //autogen
64 #include <vcl/fixed.hxx>
65 #endif
66 #ifndef _EDIT_HXX //autogen
67 #include <vcl/edit.hxx>
68 #endif
69 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
70 #include <com/sun/star/container/XNameAccess.hpp>
71 #endif
72 #ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
73 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
74 #endif
75 #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
76 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
77 #endif
78 #ifndef _DBAUI_MODULE_DBU_HXX_
79 #include "moduledbu.hxx"
80 #endif
81 #ifndef DBACCESS_SOURCE_UI_INC_OBJECTNAMECHECK_HXX
82 #include "objectnamecheck.hxx"
83 #endif
84 #ifndef TOOLS_DIAGNOSE_EX_H
85 #include <tools/diagnose_ex.h>
86 #endif
87
88
89 using namespace dbaui;
90 using namespace dbtools;
91 using namespace ::com::sun::star::uno;
92 using namespace ::com::sun::star::container;
93 using namespace ::com::sun::star::sdb;
94 using namespace ::com::sun::star::sdbc;
95 namespace dbaui
96 {
97 class OSaveAsDlgImpl
98 {
99 public:
100 FixedText m_aDescription;
101 FixedText m_aCatalogLbl;
102 OSQLNameComboBox m_aCatalog;
103 FixedText m_aSchemaLbl;
104 OSQLNameComboBox m_aSchema;
105 FixedText m_aLabel;
106 OSQLNameEdit m_aTitle;
107 OKButton m_aPB_OK;
108 CancelButton m_aPB_CANCEL;
109 HelpButton m_aPB_HELP;
110 String m_aQryLabel;
111 String m_sTblLabel;
112 rtl::OUString m_sCatalog;
113 rtl::OUString m_sSchema;
114 String m_aName;
115 const IObjectNameCheck&
116 m_rObjectNameCheck;
117 String m_sParentURL;
118 ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData> m_xMetaData;
119 sal_Int32 m_nType;
120 sal_Int32 m_nFlags;
121
122 OSaveAsDlgImpl( Window * pParent,const sal_Int32& _rType,
123 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _xConnection,
124 const String& rDefault,
125 const IObjectNameCheck& _rObjectNameCheck,
126 sal_Int32 _nFlags);
127 OSaveAsDlgImpl( Window * pParent,
128 const String& rDefault,
129 const IObjectNameCheck& _rObjectNameCheck,
130 sal_Int32 _nFlags);
131 };
132 // -----------------------------------------------------------------------------
133 } // dbaui
134 // -----------------------------------------------------------------------------
OSaveAsDlgImpl(Window * _pParent,const sal_Int32 & _rType,const Reference<XConnection> & _xConnection,const String & rDefault,const IObjectNameCheck & _rObjectNameCheck,sal_Int32 _nFlags)135 OSaveAsDlgImpl::OSaveAsDlgImpl( Window * _pParent,
136 const sal_Int32& _rType,
137 const Reference< XConnection>& _xConnection,
138 const String& rDefault,
139 const IObjectNameCheck& _rObjectNameCheck,
140 sal_Int32 _nFlags)
141 :m_aDescription(_pParent, ModuleRes (FT_DESCRIPTION))
142 ,m_aCatalogLbl(_pParent, ModuleRes (FT_CATALOG))
143 ,m_aCatalog(_pParent, ModuleRes (ET_CATALOG), ::rtl::OUString())
144 ,m_aSchemaLbl(_pParent, ModuleRes (FT_SCHEMA))
145 ,m_aSchema(_pParent, ModuleRes (ET_SCHEMA), ::rtl::OUString())
146 ,m_aLabel(_pParent, ModuleRes (FT_TITLE))
147 ,m_aTitle(_pParent, ModuleRes (ET_TITLE), ::rtl::OUString())
148 ,m_aPB_OK(_pParent, ModuleRes( PB_OK ) )
149 ,m_aPB_CANCEL(_pParent, ModuleRes( PB_CANCEL ))
150 ,m_aPB_HELP(_pParent, ModuleRes( PB_HELP))
151 ,m_aQryLabel(ModuleRes(STR_QRY_LABEL))
152 ,m_sTblLabel(ModuleRes(STR_TBL_LABEL))
153 ,m_aName(rDefault)
154 ,m_rObjectNameCheck( _rObjectNameCheck )
155 ,m_nType(_rType)
156 ,m_nFlags(_nFlags)
157 {
158 if ( _xConnection.is() )
159 m_xMetaData = _xConnection->getMetaData();
160
161 if ( m_xMetaData.is() )
162 {
163 ::rtl::OUString sExtraNameChars( m_xMetaData->getExtraNameCharacters() );
164 m_aCatalog.setAllowedChars( sExtraNameChars );
165 m_aSchema.setAllowedChars( sExtraNameChars );
166 m_aTitle.setAllowedChars( sExtraNameChars );
167 }
168
169 m_aCatalog.SetDropDownLineCount( 10 );
170 m_aSchema.SetDropDownLineCount( 10 );
171 }
172 // -----------------------------------------------------------------------------
OSaveAsDlgImpl(Window * _pParent,const String & rDefault,const IObjectNameCheck & _rObjectNameCheck,sal_Int32 _nFlags)173 OSaveAsDlgImpl::OSaveAsDlgImpl( Window * _pParent,
174 const String& rDefault,
175 const IObjectNameCheck& _rObjectNameCheck,
176 sal_Int32 _nFlags)
177 :m_aDescription(_pParent, ModuleRes (FT_DESCRIPTION))
178 ,m_aCatalogLbl(_pParent, ModuleRes (FT_CATALOG))
179 ,m_aCatalog(_pParent, ModuleRes (ET_CATALOG))
180 ,m_aSchemaLbl(_pParent, ModuleRes (FT_SCHEMA))
181 ,m_aSchema(_pParent, ModuleRes (ET_SCHEMA))
182 ,m_aLabel(_pParent, ModuleRes (FT_TITLE))
183 ,m_aTitle(_pParent, ModuleRes (ET_TITLE))
184 ,m_aPB_OK(_pParent, ModuleRes( PB_OK ) )
185 ,m_aPB_CANCEL(_pParent, ModuleRes( PB_CANCEL ))
186 ,m_aPB_HELP(_pParent, ModuleRes( PB_HELP))
187 ,m_aQryLabel(ModuleRes(STR_QRY_LABEL))
188 ,m_sTblLabel(ModuleRes(STR_TBL_LABEL))
189 ,m_aName(rDefault)
190 ,m_rObjectNameCheck( _rObjectNameCheck )
191 ,m_nType(CommandType::COMMAND)
192 ,m_nFlags(_nFlags)
193 {
194 m_aCatalog.SetDropDownLineCount( 10 );
195 m_aSchema.SetDropDownLineCount( 10 );
196 }
197
198 // -----------------------------------------------------------------------------
199 using namespace ::com::sun::star::lang;
200
201 //==================================================================
202 namespace
203 {
204 typedef Reference< XResultSet > (SAL_CALL XDatabaseMetaData::*FGetMetaStrings)();
205
lcl_fillComboList(ComboBox & _rList,const Reference<XConnection> & _rxConnection,FGetMetaStrings _GetAll,const::rtl::OUString & _rCurrent)206 void lcl_fillComboList( ComboBox& _rList, const Reference< XConnection >& _rxConnection,
207 FGetMetaStrings _GetAll, const ::rtl::OUString& _rCurrent )
208 {
209 try
210 {
211 Reference< XDatabaseMetaData > xMetaData( _rxConnection->getMetaData(), UNO_QUERY_THROW );
212
213 Reference< XResultSet > xRes = (xMetaData.get()->*_GetAll)();
214 Reference< XRow > xRow( xRes, UNO_QUERY_THROW );
215 ::rtl::OUString sValue;
216 while ( xRes->next() )
217 {
218 sValue = xRow->getString( 1 );
219 if ( !xRow->wasNull() )
220 _rList.InsertEntry( sValue );
221 }
222
223 sal_uInt16 nPos = _rList.GetEntryPos( String( _rCurrent ) );
224 if ( nPos != COMBOBOX_ENTRY_NOTFOUND )
225 _rList.SelectEntryPos( nPos );
226 else
227 _rList.SelectEntryPos( 0 );
228 }
229 catch( const Exception& )
230 {
231 DBG_UNHANDLED_EXCEPTION();
232 }
233 }
234 }
235
236 //==================================================================
OSaveAsDlg(Window * pParent,const sal_Int32 & _rType,const Reference<XMultiServiceFactory> & _rxORB,const Reference<XConnection> & _xConnection,const String & rDefault,const IObjectNameCheck & _rObjectNameCheck,sal_Int32 _nFlags)237 OSaveAsDlg::OSaveAsDlg( Window * pParent,
238 const sal_Int32& _rType,
239 const Reference< XMultiServiceFactory >& _rxORB,
240 const Reference< XConnection>& _xConnection,
241 const String& rDefault,
242 const IObjectNameCheck& _rObjectNameCheck,
243 sal_Int32 _nFlags)
244 :ModalDialog( pParent, ModuleRes(DLG_SAVE_AS))
245 ,m_xORB( _rxORB )
246 {
247 m_pImpl = new OSaveAsDlgImpl(this,_rType,_xConnection,rDefault,_rObjectNameCheck,_nFlags);
248
249 switch (_rType)
250 {
251 case CommandType::QUERY:
252 implInitOnlyTitle(m_pImpl->m_aQryLabel);
253 break;
254
255 case CommandType::TABLE:
256 OSL_ENSURE( m_pImpl->m_xMetaData.is(), "OSaveAsDlg::OSaveAsDlg: no meta data for entering table names: this will crash!" );
257 {
258 m_pImpl->m_aLabel.SetText(m_pImpl->m_sTblLabel);
259 Point aPos(m_pImpl->m_aPB_OK.GetPosPixel());
260 if(m_pImpl->m_xMetaData.is() && !m_pImpl->m_xMetaData->supportsCatalogsInTableDefinitions())
261 {
262 m_pImpl->m_aCatalogLbl.Hide();
263 m_pImpl->m_aCatalog.Hide();
264
265 aPos = m_pImpl->m_aLabel.GetPosPixel();
266
267 m_pImpl->m_aLabel.SetPosPixel(m_pImpl->m_aSchemaLbl.GetPosPixel());
268 m_pImpl->m_aTitle.SetPosPixel(m_pImpl->m_aSchema.GetPosPixel());
269
270 m_pImpl->m_aSchemaLbl.SetPosPixel(m_pImpl->m_aCatalogLbl.GetPosPixel());
271 m_pImpl->m_aSchema.SetPosPixel(m_pImpl->m_aCatalog.GetPosPixel());
272 }
273 else
274 {
275 // now fill the catalogs
276 lcl_fillComboList( m_pImpl->m_aCatalog, _xConnection,
277 &XDatabaseMetaData::getCatalogs, _xConnection->getCatalog() );
278 }
279
280 if ( !m_pImpl->m_xMetaData->supportsSchemasInTableDefinitions())
281 {
282 m_pImpl->m_aSchemaLbl.Hide();
283 m_pImpl->m_aSchema.Hide();
284
285 aPos = m_pImpl->m_aLabel.GetPosPixel();
286
287 m_pImpl->m_aLabel.SetPosPixel(m_pImpl->m_aSchemaLbl.GetPosPixel());
288 m_pImpl->m_aTitle.SetPosPixel(m_pImpl->m_aSchema.GetPosPixel());
289 }
290 else
291 {
292 lcl_fillComboList( m_pImpl->m_aSchema, _xConnection,
293 &XDatabaseMetaData::getSchemas, m_pImpl->m_xMetaData->getUserName() );
294 }
295
296 OSL_ENSURE(m_pImpl->m_xMetaData.is(),"The metadata can not be null!");
297 if(m_pImpl->m_aName.Search('.') != STRING_NOTFOUND)
298 {
299 ::rtl::OUString sCatalog,sSchema,sTable;
300 ::dbtools::qualifiedNameComponents(m_pImpl->m_xMetaData,
301 m_pImpl->m_aName,
302 sCatalog,
303 sSchema,
304 sTable,
305 ::dbtools::eInDataManipulation);
306
307 sal_uInt16 nPos = m_pImpl->m_aCatalog.GetEntryPos(String(sCatalog));
308 if ( nPos != COMBOBOX_ENTRY_NOTFOUND )
309 m_pImpl->m_aCatalog.SelectEntryPos(nPos);
310
311 if ( sSchema.getLength() )
312 {
313 nPos = m_pImpl->m_aSchema.GetEntryPos(String(sSchema));
314 if ( nPos != COMBOBOX_ENTRY_NOTFOUND )
315 m_pImpl->m_aSchema.SelectEntryPos(nPos);
316 }
317 m_pImpl->m_aTitle.SetText(sTable);
318 }
319 else
320 m_pImpl->m_aTitle.SetText(m_pImpl->m_aName);
321 m_pImpl->m_aTitle.SetSelection( Selection( SELECTION_MIN, SELECTION_MAX ) );
322
323 m_pImpl->m_aPB_OK.SetPosPixel(Point(m_pImpl->m_aPB_OK.GetPosPixel().X(),aPos.Y()));
324 m_pImpl->m_aPB_CANCEL.SetPosPixel(Point(m_pImpl->m_aPB_CANCEL.GetPosPixel().X(),aPos.Y()));
325 m_pImpl->m_aPB_HELP.SetPosPixel(Point(m_pImpl->m_aPB_HELP.GetPosPixel().X(),aPos.Y()));
326
327 sal_uInt16 nLength = m_pImpl->m_xMetaData.is() ? static_cast<sal_uInt16>(m_pImpl->m_xMetaData->getMaxTableNameLength()) : 0;
328 nLength = nLength ? nLength : EDIT_NOLIMIT;
329
330 m_pImpl->m_aTitle.SetMaxTextLen(nLength);
331 m_pImpl->m_aSchema.SetMaxTextLen(nLength);
332 m_pImpl->m_aCatalog.SetMaxTextLen(nLength);
333
334 sal_Bool bCheck = _xConnection.is() && isSQL92CheckEnabled(_xConnection);
335 m_pImpl->m_aTitle.setCheck(bCheck); // enable non valid sql chars as well
336 m_pImpl->m_aSchema.setCheck(bCheck); // enable non valid sql chars as well
337 m_pImpl->m_aCatalog.setCheck(bCheck); // enable non valid sql chars as well
338
339 Size aSize = GetSizePixel();
340 aSize.Height() =
341 aPos.Y() + m_pImpl->m_aPB_OK.GetSizePixel().Height() + m_pImpl->m_aTitle.GetSizePixel().Height() / 2;
342 SetSizePixel(aSize);
343 }
344 break;
345
346 default:
347 OSL_ENSURE( false, "OSaveAsDlg::OSaveAsDlg: Type not supported yet!" );
348 }
349
350 implInit();
351 }
352 // -----------------------------------------------------------------------------
OSaveAsDlg(Window * pParent,const Reference<XMultiServiceFactory> & _rxORB,const String & rDefault,const String & _sLabel,const IObjectNameCheck & _rObjectNameCheck,sal_Int32 _nFlags)353 OSaveAsDlg::OSaveAsDlg( Window * pParent,
354 const Reference< XMultiServiceFactory >& _rxORB,
355 const String& rDefault,
356 const String& _sLabel,
357 const IObjectNameCheck& _rObjectNameCheck,
358 sal_Int32 _nFlags)
359 :ModalDialog( pParent, ModuleRes(DLG_SAVE_AS))
360 ,m_xORB( _rxORB )
361 {
362 m_pImpl = new OSaveAsDlgImpl(this,rDefault,_rObjectNameCheck,_nFlags);
363 implInitOnlyTitle(_sLabel);
364 implInit();
365 }
366 // -----------------------------------------------------------------------------
~OSaveAsDlg()367 OSaveAsDlg::~OSaveAsDlg()
368 {
369 DELETEZ(m_pImpl);
370 }
371 // -----------------------------------------------------------------------------
IMPL_LINK(OSaveAsDlg,ButtonClickHdl,Button *,pButton)372 IMPL_LINK(OSaveAsDlg, ButtonClickHdl, Button *, pButton)
373 {
374 if (pButton == &m_pImpl->m_aPB_OK)
375 {
376 m_pImpl->m_aName = m_pImpl->m_aTitle.GetText();
377
378 ::rtl::OUString sNameToCheck( m_pImpl->m_aName );
379
380 if ( m_pImpl->m_nType == CommandType::TABLE )
381 {
382 sNameToCheck = ::dbtools::composeTableName(
383 m_pImpl->m_xMetaData,
384 getCatalog(),
385 getSchema(),
386 sNameToCheck,
387 sal_False, // no quoting
388 ::dbtools::eInDataManipulation
389 );
390 }
391
392 SQLExceptionInfo aNameError;
393 if ( m_pImpl->m_rObjectNameCheck.isNameValid( sNameToCheck, aNameError ) )
394 EndDialog( RET_OK );
395
396 showError( aNameError, this, m_xORB );
397 m_pImpl->m_aTitle.GrabFocus();
398 }
399 return 0;
400 }
401 // -----------------------------------------------------------------------------
402
IMPL_LINK(OSaveAsDlg,EditModifyHdl,Edit *,pEdit)403 IMPL_LINK(OSaveAsDlg, EditModifyHdl, Edit *, pEdit )
404 {
405 if (pEdit == &m_pImpl->m_aTitle)
406 m_pImpl->m_aPB_OK.Enable(0 != m_pImpl->m_aTitle.GetText().Len());
407 return 0;
408 }
409 // -----------------------------------------------------------------------------
implInitOnlyTitle(const String & _rLabel)410 void OSaveAsDlg::implInitOnlyTitle(const String& _rLabel)
411 {
412 m_pImpl->m_aLabel.SetText(_rLabel);
413 m_pImpl->m_aCatalogLbl.Hide();
414 m_pImpl->m_aCatalog.Hide();
415 m_pImpl->m_aSchemaLbl.Hide();
416 m_pImpl->m_aSchema.Hide();
417
418 Point aPos(m_pImpl->m_aSchemaLbl.GetPosPixel());
419 m_pImpl->m_aLabel.SetPosPixel(m_pImpl->m_aCatalogLbl.GetPosPixel());
420 m_pImpl->m_aTitle.SetPosPixel(m_pImpl->m_aCatalog.GetPosPixel());
421
422 m_pImpl->m_aPB_OK.SetPosPixel(Point(m_pImpl->m_aPB_OK.GetPosPixel().X(),aPos.Y()));
423 m_pImpl->m_aPB_CANCEL.SetPosPixel(Point(m_pImpl->m_aPB_CANCEL.GetPosPixel().X(),aPos.Y()));
424 m_pImpl->m_aPB_HELP.SetPosPixel(Point(m_pImpl->m_aPB_HELP.GetPosPixel().X(),aPos.Y()));
425
426 sal_Int32 nNewHeight =
427 aPos.Y() + m_pImpl->m_aPB_OK.GetSizePixel().Height() + m_pImpl->m_aTitle.GetSizePixel().Height() / 2;
428
429 SetSizePixel(Size(GetSizePixel().Width(), nNewHeight));
430
431 m_pImpl->m_aTitle.SetText(m_pImpl->m_aName);
432 m_pImpl->m_aTitle.setCheck(sal_False); // enable non valid sql chars as well
433 }
434 // -----------------------------------------------------------------------------
implInit()435 void OSaveAsDlg::implInit()
436 {
437 if ( 0 == ( m_pImpl->m_nFlags & SAD_ADDITIONAL_DESCRIPTION ) )
438 {
439 // hide the description window
440 m_pImpl->m_aDescription.Hide();
441
442 // the number of pixels we have to move the other controls
443 sal_Int32 nMoveUp = m_pImpl->m_aCatalog.GetPosPixel().Y() - m_pImpl->m_aDescription.GetPosPixel().Y();
444
445 // loop to all controls and move them ...
446 for ( Window* pChildControl = GetWindow( WINDOW_FIRSTCHILD );
447 pChildControl;
448 pChildControl= pChildControl->GetWindow( WINDOW_NEXT )
449 )
450 {
451 if ( &m_pImpl->m_aDescription != pChildControl )
452 {
453 Point aPos = pChildControl->GetPosPixel();
454 aPos.Y() -= nMoveUp;
455 pChildControl->SetPosPixel(aPos);
456 }
457 }
458
459 // change our own size accordingly
460 Size aSize = GetSizePixel();
461 aSize.Height() -= nMoveUp;
462 SetSizePixel(aSize);
463 }
464
465 if ( SAD_TITLE_PASTE_AS == ( m_pImpl->m_nFlags & SAD_TITLE_PASTE_AS ) )
466 SetText( String( ModuleRes( STR_TITLE_PASTE_AS ) ) );
467 else if ( SAD_TITLE_RENAME == ( m_pImpl->m_nFlags & SAD_TITLE_RENAME ) )
468 {
469 SetText( String( ModuleRes( STR_TITLE_RENAME ) ) );
470 m_pImpl->m_aTitle.SetHelpId(HID_DLG_RENAME);
471 }
472
473 m_pImpl->m_aPB_OK.SetClickHdl(LINK(this,OSaveAsDlg,ButtonClickHdl));
474 m_pImpl->m_aTitle.SetModifyHdl(LINK(this,OSaveAsDlg,EditModifyHdl));
475 m_pImpl->m_aTitle.GrabFocus();
476 FreeResource();
477 }
478 // -----------------------------------------------------------------------------
getName() const479 String OSaveAsDlg::getName() const { return m_pImpl->m_aName; }
getCatalog() const480 String OSaveAsDlg::getCatalog() const { return m_pImpl->m_aCatalog.IsVisible() ? m_pImpl->m_aCatalog.GetText() : String(); }
getSchema() const481 String OSaveAsDlg::getSchema() const { return m_pImpl->m_aSchema.IsVisible() ? m_pImpl->m_aSchema.GetText() : String(); }
482
483