xref: /AOO41X/main/dbaccess/source/ui/dlg/dbfindex.cxx (revision 96de54900b79e13b861fbc62cbf36018b54e21b7)
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_dbaccess.hxx"
26 
27 #ifndef _DBAUI_DBFINDEX_HXX_
28 #include "dbfindex.hxx"
29 #endif
30 
31 #ifndef _CONFIG_HXX
32 #include <tools/config.hxx>
33 #endif
34 #ifndef _SFXAPP_HXX //autogen
35 #include <sfx2/app.hxx>
36 #endif
37 #ifndef _DBAUI_MODULE_DBU_HXX_
38 #include "moduledbu.hxx"
39 #endif
40 #ifndef _DBU_DLG_HRC_
41 #include "dbu_dlg.hrc"
42 #endif
43 #ifndef _DBAUI_DBF_INDEXES_HRC_
44 #include "dbfindex.hrc"
45 #endif
46 #ifndef _TOOLS_DEBUG_HXX
47 #include <tools/debug.hxx>
48 #endif
49 #ifndef _UNOTOOLS_LOCALFILEHELPER_HXX
50 #include <unotools/localfilehelper.hxx>
51 #endif
52 #ifndef _URLOBJ_HXX
53 #include <tools/urlobj.hxx>
54 #endif
55 #ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
56 #include <unotools/pathoptions.hxx>
57 #endif
58 #ifndef _UCBHELPER_CONTENT_HXX
59 #include <ucbhelper/content.hxx>
60 #endif
61 #ifndef SVTOOLS_FILENOTATION_HXX_
62 #include <svl/filenotation.hxx>
63 #endif
64 
65 
66 //.........................................................................
67 namespace dbaui
68 {
69 //.........................................................................
70 
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::ucb;
73 using namespace ::svt;
74 
75 const ByteString aGroupIdent("dBase III");
76 
77 //////////////////////////////////////////////////////////////////////////
78 // Klasse ODbaseIndexDialog
DBG_NAME(ODbaseIndexDialog)79 DBG_NAME(ODbaseIndexDialog)
80 //-------------------------------------------------------------------------
81 ODbaseIndexDialog::ODbaseIndexDialog( Window * pParent, String aDataSrcName )
82     : ModalDialog( pParent, ModuleRes(DLG_DBASE_INDEXES) ),
83     aPB_OK(             this, ModuleRes( PB_OK ) ),
84     aPB_CANCEL(         this, ModuleRes( PB_CANCEL ) ),
85     aPB_HELP(           this, ModuleRes( PB_HELP ) ),
86     m_FT_Tables(        this, ModuleRes( FT_TABLES ) ),
87     aCB_Tables(         this, ModuleRes( CB_TABLES ) ),
88     m_FL_Indexes(       this, ModuleRes( FL_INDEXES ) ),
89     m_FT_TableIndexes(  this, ModuleRes( FT_TABLEINDEXES ) ),
90     aLB_TableIndexes(   this, ModuleRes( LB_TABLEINDEXES ) ),
91     m_FT_AllIndexes(    this, ModuleRes( FT_ALLINDEXES ) ),
92     aLB_FreeIndexes(    this, ModuleRes( LB_FREEINDEXES ) ),
93     aIB_Add(            this, ModuleRes( IB_ADD ) ),
94     aIB_Remove(         this, ModuleRes( IB_REMOVE ) ),
95     aIB_AddAll(         this, ModuleRes( IB_ADDALL ) ),
96     aIB_RemoveAll(      this, ModuleRes( IB_REMOVEALL ) ),
97     m_aDSN(aDataSrcName),
98     m_bCaseSensitiv(sal_True)
99 {
100     DBG_CTOR(ODbaseIndexDialog,NULL);
101 
102     aCB_Tables.SetSelectHdl( LINK(this, ODbaseIndexDialog, TableSelectHdl) );
103     aIB_Add.SetClickHdl( LINK(this, ODbaseIndexDialog, AddClickHdl) );
104     aIB_Remove.SetClickHdl( LINK(this, ODbaseIndexDialog, RemoveClickHdl) );
105     aIB_AddAll.SetClickHdl( LINK(this, ODbaseIndexDialog, AddAllClickHdl) );
106     aIB_RemoveAll.SetClickHdl( LINK(this, ODbaseIndexDialog, RemoveAllClickHdl) );
107     aPB_OK.SetClickHdl( LINK(this, ODbaseIndexDialog, OKClickHdl) );
108 
109     aLB_FreeIndexes.SetSelectHdl( LINK(this, ODbaseIndexDialog, OnListEntrySelected) );
110     aLB_TableIndexes.SetSelectHdl( LINK(this, ODbaseIndexDialog, OnListEntrySelected) );
111 
112     aCB_Tables.SetDropDownLineCount(8);
113     Init();
114     SetCtrls();
115     FreeResource();
116 
117     // set Hi contrast bitmaps
118     aIB_Add.SetModeImage(       ModuleRes(IMG_ONE_LEFT_H),BMP_COLOR_HIGHCONTRAST);
119     aIB_AddAll.SetModeImage(    ModuleRes(IMG_ALL_LEFT_H),BMP_COLOR_HIGHCONTRAST);
120     aIB_Remove.SetModeImage(    ModuleRes(IMG_ONE_RIGHT_H),BMP_COLOR_HIGHCONTRAST);
121     aIB_RemoveAll.SetModeImage( ModuleRes(IMG_ALL_RIGHT_H),BMP_COLOR_HIGHCONTRAST);
122 }
123 
124 //-------------------------------------------------------------------------
~ODbaseIndexDialog()125 ODbaseIndexDialog::~ODbaseIndexDialog()
126 {
127 
128     DBG_DTOR(ODbaseIndexDialog,NULL);
129 }
130 
131 //-------------------------------------------------------------------------
GetTable(const String & _rName,TableInfoListIterator & _rPosition)132 sal_Bool ODbaseIndexDialog::GetTable(const String& _rName, TableInfoListIterator& _rPosition)
133 {
134     for (   _rPosition = m_aTableInfoList.begin();
135             _rPosition != m_aTableInfoList.end();
136             ++_rPosition
137         )
138     {
139         if (m_bCaseSensitiv)
140         {
141             if (_rPosition->aTableName.Equals(_rName))
142                 return sal_True;
143         }
144         else
145         {
146             if (_rPosition->aTableName.EqualsIgnoreCaseAscii(_rName))
147                 return sal_True;
148         }
149     }
150     return sal_False;
151 }
152 
153 //-------------------------------------------------------------------------
checkButtons()154 void ODbaseIndexDialog::checkButtons()
155 {
156     aIB_Add.Enable(0 != aLB_FreeIndexes.GetSelectEntryCount());
157     aIB_AddAll.Enable(0 != aLB_FreeIndexes.GetEntryCount());
158 
159     aIB_Remove.Enable(0 != aLB_TableIndexes.GetSelectEntryCount());
160     aIB_RemoveAll.Enable(0 != aLB_TableIndexes.GetEntryCount());
161 }
162 
163 //-------------------------------------------------------------------------
implRemoveIndex(const String & _rName,TableIndexList & _rList,ListBox & _rDisplay,sal_Bool _bMustExist)164 OTableIndex ODbaseIndexDialog::implRemoveIndex(const String& _rName, TableIndexList& _rList, ListBox& _rDisplay, sal_Bool _bMustExist)
165 {
166     OTableIndex aReturn;
167 
168     sal_Int32 nPos = 0;
169 
170     TableIndexListIterator aSearch;
171     for (   aSearch = _rList.begin();
172             aSearch != _rList.end();
173             ++aSearch, ++nPos
174         )
175     {
176         if ( m_bCaseSensitiv ? aSearch->GetIndexFileName().Equals(_rName) : aSearch->GetIndexFileName().EqualsIgnoreCaseAscii(_rName) )
177         {
178             aReturn = *aSearch;
179 
180             _rList.erase(aSearch);
181             _rDisplay.RemoveEntry( _rName );
182 
183             // adjust selection if necessary
184             if ((sal_uInt32)nPos == _rList.size())
185                 _rDisplay.SelectEntryPos((sal_uInt16)nPos-1);
186             else
187                 _rDisplay.SelectEntryPos((sal_uInt16)nPos);
188 
189             break;
190         }
191     }
192 
193     (void)_bMustExist;
194     DBG_ASSERT(!_bMustExist || (aSearch != _rList.end()), "ODbaseIndexDialog::implRemoveIndex : did not find the index!");
195     return aReturn;
196 }
197 
198 //-------------------------------------------------------------------------
implInsertIndex(const OTableIndex & _rIndex,TableIndexList & _rList,ListBox & _rDisplay)199 void ODbaseIndexDialog::implInsertIndex(const OTableIndex& _rIndex, TableIndexList& _rList, ListBox& _rDisplay)
200 {
201     _rList.push_front( _rIndex );
202     _rDisplay.InsertEntry( _rIndex.GetIndexFileName() );
203     _rDisplay.SelectEntryPos(0);
204 }
205 
206 //-------------------------------------------------------------------------
RemoveTableIndex(const String & _rTableName,const String & _rIndexName,sal_Bool _bMustExist)207 OTableIndex ODbaseIndexDialog::RemoveTableIndex( const String& _rTableName, const String& _rIndexName, sal_Bool _bMustExist )
208 {
209     OTableIndex aReturn;
210 
211     // does the table exist ?
212     TableInfoListIterator aTablePos;
213     if (!GetTable(_rTableName, aTablePos))
214         return aReturn;
215 
216     return implRemoveIndex(_rIndexName, aTablePos->aIndexList, aLB_TableIndexes, _bMustExist);
217 }
218 
219 //-------------------------------------------------------------------------
InsertTableIndex(const String & _rTableName,const OTableIndex & _rIndex)220 void ODbaseIndexDialog::InsertTableIndex( const String& _rTableName, const OTableIndex& _rIndex)
221 {
222     TableInfoListIterator aTablePos;
223     if (!GetTable(_rTableName, aTablePos))
224         return;
225 
226     implInsertIndex(_rIndex, aTablePos->aIndexList, aLB_TableIndexes);
227 }
228 
229 //-------------------------------------------------------------------------
230 IMPL_LINK( ODbaseIndexDialog, OKClickHdl, PushButton*, /*pButton*/ )
231 {
232     // let all tables write their INF file
233 
234     for (   ConstTableInfoListIterator aLoop = m_aTableInfoList.begin();
235             aLoop != m_aTableInfoList.end();
236             ++aLoop
237         )
238         aLoop->WriteInfFile(m_aDSN);
239 
240     EndDialog();
241     return 0;
242 }
243 
244 //-------------------------------------------------------------------------
245 IMPL_LINK( ODbaseIndexDialog, AddClickHdl, PushButton*, /*pButton*/ )
246 {
247     String aSelection = aLB_FreeIndexes.GetSelectEntry();
248     String aTableName = aCB_Tables.GetText();
249     OTableIndex aIndex = RemoveFreeIndex( aSelection, sal_True );
250     InsertTableIndex( aTableName, aIndex );
251 
252     checkButtons();
253     return 0;
254 }
255 
256 //-------------------------------------------------------------------------
257 IMPL_LINK( ODbaseIndexDialog, RemoveClickHdl, PushButton*, /*pButton*/ )
258 {
259     String aSelection = aLB_TableIndexes.GetSelectEntry();
260     String aTableName = aCB_Tables.GetText();
261     OTableIndex aIndex = RemoveTableIndex( aTableName, aSelection, sal_True );
262     InsertFreeIndex( aIndex );
263 
264     checkButtons();
265     return 0;
266 }
267 
268 //-------------------------------------------------------------------------
269 IMPL_LINK( ODbaseIndexDialog, AddAllClickHdl, PushButton*, /*pButton*/ )
270 {
271     sal_uInt16 nCnt = aLB_FreeIndexes.GetEntryCount();
272     String aTableName = aCB_Tables.GetText();
273     String aEntry;
274 
275     for( sal_uInt16 nPos = 0; nPos < nCnt; ++nPos )
276         InsertTableIndex( aTableName, RemoveFreeIndex( aLB_FreeIndexes.GetEntry(0), sal_True ) );
277 
278     checkButtons();
279     return 0;
280 }
281 
282 //-------------------------------------------------------------------------
283 IMPL_LINK( ODbaseIndexDialog, RemoveAllClickHdl, PushButton*, /*pButton*/ )
284 {
285     sal_uInt16 nCnt = aLB_TableIndexes.GetEntryCount();
286     String aTableName = aCB_Tables.GetText();
287     String aEntry;
288 
289     for( sal_uInt16 nPos = 0; nPos < nCnt; ++nPos )
290         InsertFreeIndex( RemoveTableIndex( aTableName, aLB_TableIndexes.GetEntry(0), sal_True ) );
291 
292     checkButtons();
293     return 0;
294 }
295 
296 //-------------------------------------------------------------------------
297 IMPL_LINK( ODbaseIndexDialog, OnListEntrySelected, ListBox*, /*NOTINTERESTEDIN*/ )
298 {
299     checkButtons();
300     return 0;
301 }
302 
303 //-------------------------------------------------------------------------
IMPL_LINK(ODbaseIndexDialog,TableSelectHdl,ComboBox *,pComboBox)304 IMPL_LINK( ODbaseIndexDialog, TableSelectHdl, ComboBox*, pComboBox )
305 {
306     // search the table
307     TableInfoListIterator aTablePos;
308     if (!GetTable(pComboBox->GetText(), aTablePos))
309         return 0L;
310 
311     // fill the listbox for the indexes
312     aLB_TableIndexes.Clear();
313     for (   ConstTableIndexListIterator aLoop = aTablePos->aIndexList.begin();
314             aLoop != aTablePos->aIndexList.end();
315             ++aLoop
316         )
317         aLB_TableIndexes.InsertEntry( aLoop->GetIndexFileName() );
318 
319     if ( aTablePos->aIndexList.size() )
320         aLB_TableIndexes.SelectEntryPos(0);
321 
322     checkButtons();
323     return 0;
324 }
325 
326 //-------------------------------------------------------------------------
Init()327 void ODbaseIndexDialog::Init()
328 {
329     aPB_OK.Disable();
330     m_FL_Indexes.Disable();
331     m_FT_TableIndexes.Disable();
332     aLB_TableIndexes.Disable();
333     m_FT_AllIndexes.Disable();
334     aLB_FreeIndexes.Disable();
335     aIB_Add.Disable();
336     aIB_Remove.Disable();
337     aIB_AddAll.Disable();
338     aIB_RemoveAll.Disable();
339 
340     ///////////////////////////////////////////////////////////////////////////
341     // Alle Indizes werden erst einmal zur Liste der freien Indizes hinzugefuegt.
342     // Dann wird fuer jede Tabelle in der Inf-Datei nachgeschaut, welche Indizes sie besitzt.
343     // Diese Indizes werden aus der Liste der freien Indizes entfernt
344     // und in die Indexliste der Tabelle eingetragen
345 
346     ///////////////////////////////////////////////////////////////////////////
347     // if the string does not contain a path, cut the string
348     INetURLObject aURL;
349     aURL.SetSmartProtocol(INET_PROT_FILE);
350     {
351         SvtPathOptions aPathOptions;
352         m_aDSN = aPathOptions.SubstituteVariable(m_aDSN);
353     }
354     aURL.SetSmartURL(m_aDSN);
355 
356 
357     //  String aFileName = aURL.PathToFileName();
358     m_aDSN = aURL.GetMainURL(INetURLObject::NO_DECODE);
359     ::ucbhelper::Content aFile;
360     sal_Bool bFolder=sal_True;
361     try
362     {
363         aFile = ::ucbhelper::Content(m_aDSN,Reference< ::com::sun::star::ucb::XCommandEnvironment >());
364         bFolder = aFile.isFolder();
365     }
366     catch(Exception&)
367     {
368         return;
369     }
370 
371     ///////////////////////////////////////////////////////////////////////////
372     // first assume for all indexes they're free
373 
374     Sequence< ::rtl::OUString> aFolderContent( ::utl::LocalFileHelper::GetFolderContents(m_aDSN,bFolder));
375 
376     ::rtl::OUString aIndexExt = ::rtl::OUString::createFromAscii("ndx");
377     ::rtl::OUString aTableExt = ::rtl::OUString::createFromAscii("dbf");
378 
379     ::std::vector< String > aUsedIndexes;
380 
381     String aExt;
382     const ::rtl::OUString *pBegin = aFolderContent.getConstArray();
383     const ::rtl::OUString *pEnd   = pBegin + aFolderContent.getLength();
384     aURL.SetSmartProtocol(INET_PROT_FILE);
385     for(;pBegin != pEnd;++pBegin)
386     {
387         String aName;
388         ::utl::LocalFileHelper::ConvertURLToPhysicalName(pBegin->getStr(),aName);
389         aURL.SetSmartURL(aName);
390         aExt = aURL.getExtension();
391         if(aExt == aIndexExt.getStr())
392         {
393             m_aFreeIndexList.push_back( OTableIndex(aURL.getName()) );
394         }
395         else if(aExt == aTableExt.getStr())
396         {
397             m_aTableInfoList.push_back( OTableInfo(aURL.getName()) );
398             OTableInfo& rTabInfo = m_aTableInfoList.back();
399 
400             // open the INF file
401             aURL.setExtension(String::CreateFromAscii("inf"));
402             OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
403             Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
404             aInfFile.SetGroup( aGroupIdent );
405 
406             ///////////////////////////////////////////////////////////////////////////
407             // fill the indexes list
408             ByteString aNDX;
409             sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
410             ByteString aKeyName;
411             String aEntry;
412 
413             for( sal_uInt16 nKey = 0; nKey < nKeyCnt; nKey++ )
414             {
415                 // does the key point to an index file ?
416                 aKeyName = aInfFile.GetKeyName( nKey );
417                 aNDX = aKeyName.Copy(0,3);
418 
419                 // yes -> add to the tables index list
420                 if (aNDX == "NDX" )
421                 {
422                     aEntry = String(aInfFile.ReadKey(aKeyName), gsl_getSystemTextEncoding());
423                     rTabInfo.aIndexList.push_back( OTableIndex( aEntry ) );
424 
425                     // and remove it from the free index list
426                     aUsedIndexes.push_back(aEntry);
427                         // do this later below. We may not have encountered the index file, yet, thus we may not
428                         // know the index as beeing free, yet
429                 }
430 
431             }
432         }
433     }
434 
435     for (   ::std::vector< String >::const_iterator aUsedIndex = aUsedIndexes.begin();
436             aUsedIndex != aUsedIndexes.end();
437             ++aUsedIndex
438         )
439         RemoveFreeIndex( *aUsedIndex, sal_False );
440 
441     if (m_aTableInfoList.size())
442     {
443         aPB_OK.Enable();
444         m_FL_Indexes.Enable();
445         m_FT_TableIndexes.Enable();
446         aLB_TableIndexes.Enable();
447         m_FT_AllIndexes.Enable();
448         aLB_FreeIndexes.Enable();
449     }
450 
451     checkButtons();
452 }
453 
454 //-------------------------------------------------------------------------
SetCtrls()455 void ODbaseIndexDialog::SetCtrls()
456 {
457     // ComboBox Tabellen
458     for (   ConstTableInfoListIterator aLoop = m_aTableInfoList.begin();
459             aLoop != m_aTableInfoList.end();
460             ++aLoop
461         )
462         aCB_Tables.InsertEntry( aLoop->aTableName );
463 
464     // Den ersten Datensatz ins Edit stellen
465     if( m_aTableInfoList.size() )
466     {
467         const OTableInfo& rTabInfo = m_aTableInfoList.front();
468         aCB_Tables.SetText( rTabInfo.aTableName );
469 
470         // ListBox der Tabellenindizes aufbauen
471         for (   ConstTableIndexListIterator aIndex = rTabInfo.aIndexList.begin();
472                 aIndex != rTabInfo.aIndexList.end();
473                 ++aIndex
474             )
475             aLB_TableIndexes.InsertEntry( aIndex->GetIndexFileName() );
476 
477         if( rTabInfo.aIndexList.size() )
478             aLB_TableIndexes.SelectEntryPos( 0 );
479 
480     }
481 
482     // ListBox freie Indizes
483     for (   ConstTableIndexListIterator aFree = m_aFreeIndexList.begin();
484             aFree != m_aFreeIndexList.end();
485             ++aFree
486         )
487         aLB_FreeIndexes.InsertEntry( aFree->GetIndexFileName() );
488 
489     if( m_aFreeIndexList.size() )
490         aLB_FreeIndexes.SelectEntryPos( 0 );
491 
492 
493     TableSelectHdl(&aCB_Tables);
494     checkButtons();
495 }
496 
497 //////////////////////////////////////////////////////////////////////////
498 // Klasse OTableInfo
499 //-------------------------------------------------------------------------
WriteInfFile(const String & rDSN) const500 void OTableInfo::WriteInfFile( const String& rDSN ) const
501 {
502     // INF-Datei oeffnen
503     INetURLObject aURL;
504     aURL.SetSmartProtocol(INET_PROT_FILE);
505     String aDsn = rDSN;
506     {
507         SvtPathOptions aPathOptions;
508         aDsn = aPathOptions.SubstituteVariable(aDsn);
509     }
510     aURL.SetSmartURL(aDsn);
511     aURL.Append(aTableName);
512     aURL.setExtension(String::CreateFromAscii("inf"));
513 
514     OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
515     Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
516     aInfFile.SetGroup( aGroupIdent );
517 
518     // Erst einmal alle Tabellenindizes loeschen
519     ByteString aNDX;
520     sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
521     ByteString aKeyName;
522     ByteString aEntry;
523     sal_uInt16 nKey = 0;
524 
525     while( nKey < nKeyCnt )
526     {
527         // Verweist der Key auf ein Indexfile?...
528         aKeyName = aInfFile.GetKeyName( nKey );
529         aNDX = aKeyName.Copy(0,3);
530 
531         //...wenn ja, Indexfile loeschen, nKey steht dann auf nachfolgendem Key
532         if( aNDX == "NDX" )
533         {
534             aInfFile.DeleteKey(aKeyName);
535             nKeyCnt--;
536         }
537         else
538             nKey++;
539 
540     }
541 
542     // Jetzt alle gespeicherten Indizes hinzufuegen
543     sal_uInt16 nPos = 0;
544     for (   ConstTableIndexListIterator aIndex = aIndexList.begin();
545             aIndex != aIndexList.end();
546             ++aIndex, ++nPos
547         )
548     {
549         aKeyName = "NDX";
550         if( nPos > 0 )  // Erster Index erhaelt keine Ziffer
551             aKeyName += ByteString::CreateFromInt32( nPos );
552         aInfFile.WriteKey( aKeyName, ByteString(aIndex->GetIndexFileName(), gsl_getSystemTextEncoding()) );
553     }
554 
555     aInfFile.Flush();
556 
557     // Falls nur noch [dbase] in INF-File steht, Datei loeschen
558     if(!nPos)
559     {
560         try
561         {
562             ::ucbhelper::Content aContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
563             aContent.executeCommand( rtl::OUString::createFromAscii( "delete" ),makeAny( sal_Bool( sal_True ) ) );
564         }
565         catch (const Exception& e )
566         {
567             (void)e;  // make compiler happy
568             // simply silent this. The strange algorithm here does a lot of things even if no files at all were
569             // created or accessed, so it's possible that the file we're trying to delete does not even exist,
570             // and this is a valid condition.
571             // 2003-05-15 - #109677# - fs@openoffice.org
572         }
573     }
574 }
575 
576 //.........................................................................
577 }   // namespace dbaui
578 //.........................................................................
579 
580