Update ooo320-m1
[ooovba.git] / dbaccess / source / ui / dlg / dbfindex.cxx
blob1e591d7c237b2aa26164266575dc19f3feab3f0b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dbfindex.cxx,v $
10 * $Revision: 1.26 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #ifndef _DBAUI_DBFINDEX_HXX_
35 #include "dbfindex.hxx"
36 #endif
38 #ifndef _CONFIG_HXX
39 #include <tools/config.hxx>
40 #endif
41 #ifndef _SFXAPP_HXX //autogen
42 #include <sfx2/app.hxx>
43 #endif
44 #ifndef _DBAUI_MODULE_DBU_HXX_
45 #include "moduledbu.hxx"
46 #endif
47 #ifndef _DBU_DLG_HRC_
48 #include "dbu_dlg.hrc"
49 #endif
50 #ifndef _DBAUI_DBF_INDEXES_HRC_
51 #include "dbfindex.hrc"
52 #endif
53 #ifndef _TOOLS_DEBUG_HXX
54 #include <tools/debug.hxx>
55 #endif
56 #ifndef _UNOTOOLS_LOCALFILEHELPER_HXX
57 #include <unotools/localfilehelper.hxx>
58 #endif
59 #ifndef _URLOBJ_HXX
60 #include <tools/urlobj.hxx>
61 #endif
62 #ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
63 #include <svtools/pathoptions.hxx>
64 #endif
65 #ifndef _UCBHELPER_CONTENT_HXX
66 #include <ucbhelper/content.hxx>
67 #endif
68 #ifndef SVTOOLS_FILENOTATION_HXX_
69 #include <svtools/filenotation.hxx>
70 #endif
73 //.........................................................................
74 namespace dbaui
76 //.........................................................................
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::ucb;
80 using namespace ::svt;
82 const ByteString aGroupIdent("dBase III");
84 //////////////////////////////////////////////////////////////////////////
85 // Klasse ODbaseIndexDialog
86 DBG_NAME(ODbaseIndexDialog)
87 //-------------------------------------------------------------------------
88 ODbaseIndexDialog::ODbaseIndexDialog( Window * pParent, String aDataSrcName )
89 : ModalDialog( pParent, ModuleRes(DLG_DBASE_INDEXES) ),
90 aPB_OK( this, ModuleRes( PB_OK ) ),
91 aPB_CANCEL( this, ModuleRes( PB_CANCEL ) ),
92 aPB_HELP( this, ModuleRes( PB_HELP ) ),
93 m_FT_Tables( this, ModuleRes( FT_TABLES ) ),
94 aCB_Tables( this, ModuleRes( CB_TABLES ) ),
95 m_FL_Indexes( this, ModuleRes( FL_INDEXES ) ),
96 m_FT_TableIndexes( this, ModuleRes( FT_TABLEINDEXES ) ),
97 aLB_TableIndexes( this, ModuleRes( LB_TABLEINDEXES ) ),
98 m_FT_AllIndexes( this, ModuleRes( FT_ALLINDEXES ) ),
99 aLB_FreeIndexes( this, ModuleRes( LB_FREEINDEXES ) ),
100 aIB_Add( this, ModuleRes( IB_ADD ) ),
101 aIB_Remove( this, ModuleRes( IB_REMOVE ) ),
102 aIB_AddAll( this, ModuleRes( IB_ADDALL ) ),
103 aIB_RemoveAll( this, ModuleRes( IB_REMOVEALL ) ),
104 m_aDSN(aDataSrcName),
105 m_bCaseSensitiv(sal_True)
107 DBG_CTOR(ODbaseIndexDialog,NULL);
109 aCB_Tables.SetSelectHdl( LINK(this, ODbaseIndexDialog, TableSelectHdl) );
110 aIB_Add.SetClickHdl( LINK(this, ODbaseIndexDialog, AddClickHdl) );
111 aIB_Remove.SetClickHdl( LINK(this, ODbaseIndexDialog, RemoveClickHdl) );
112 aIB_AddAll.SetClickHdl( LINK(this, ODbaseIndexDialog, AddAllClickHdl) );
113 aIB_RemoveAll.SetClickHdl( LINK(this, ODbaseIndexDialog, RemoveAllClickHdl) );
114 aPB_OK.SetClickHdl( LINK(this, ODbaseIndexDialog, OKClickHdl) );
116 aLB_FreeIndexes.SetSelectHdl( LINK(this, ODbaseIndexDialog, OnListEntrySelected) );
117 aLB_TableIndexes.SetSelectHdl( LINK(this, ODbaseIndexDialog, OnListEntrySelected) );
119 aCB_Tables.SetDropDownLineCount(8);
120 Init();
121 SetCtrls();
122 FreeResource();
124 // set Hi contrast bitmaps
125 aIB_Add.SetModeImage( ModuleRes(IMG_ONE_LEFT_H),BMP_COLOR_HIGHCONTRAST);
126 aIB_AddAll.SetModeImage( ModuleRes(IMG_ALL_LEFT_H),BMP_COLOR_HIGHCONTRAST);
127 aIB_Remove.SetModeImage( ModuleRes(IMG_ONE_RIGHT_H),BMP_COLOR_HIGHCONTRAST);
128 aIB_RemoveAll.SetModeImage( ModuleRes(IMG_ALL_RIGHT_H),BMP_COLOR_HIGHCONTRAST);
131 //-------------------------------------------------------------------------
132 ODbaseIndexDialog::~ODbaseIndexDialog()
135 DBG_DTOR(ODbaseIndexDialog,NULL);
138 //-------------------------------------------------------------------------
139 sal_Bool ODbaseIndexDialog::GetTable(const String& _rName, TableInfoListIterator& _rPosition)
141 for ( _rPosition = m_aTableInfoList.begin();
142 _rPosition != m_aTableInfoList.end();
143 ++_rPosition
146 if (m_bCaseSensitiv)
148 if (_rPosition->aTableName.Equals(_rName))
149 return sal_True;
151 else
153 if (_rPosition->aTableName.EqualsIgnoreCaseAscii(_rName))
154 return sal_True;
157 return sal_False;
160 //-------------------------------------------------------------------------
161 void ODbaseIndexDialog::checkButtons()
163 aIB_Add.Enable(0 != aLB_FreeIndexes.GetSelectEntryCount());
164 aIB_AddAll.Enable(0 != aLB_FreeIndexes.GetEntryCount());
166 aIB_Remove.Enable(0 != aLB_TableIndexes.GetSelectEntryCount());
167 aIB_RemoveAll.Enable(0 != aLB_TableIndexes.GetEntryCount());
170 //-------------------------------------------------------------------------
171 OTableIndex ODbaseIndexDialog::implRemoveIndex(const String& _rName, TableIndexList& _rList, ListBox& _rDisplay, sal_Bool _bMustExist)
173 OTableIndex aReturn;
175 sal_Int32 nPos = 0;
177 TableIndexListIterator aSearch;
178 for ( aSearch = _rList.begin();
179 aSearch != _rList.end();
180 ++aSearch, ++nPos
183 if ( m_bCaseSensitiv ? aSearch->GetIndexFileName().Equals(_rName) : aSearch->GetIndexFileName().EqualsIgnoreCaseAscii(_rName) )
185 aReturn = *aSearch;
187 _rList.erase(aSearch);
188 _rDisplay.RemoveEntry( _rName );
190 // adjust selection if necessary
191 if ((sal_uInt32)nPos == _rList.size())
192 _rDisplay.SelectEntryPos((sal_uInt16)nPos-1);
193 else
194 _rDisplay.SelectEntryPos((sal_uInt16)nPos);
196 break;
200 (void)_bMustExist;
201 DBG_ASSERT(!_bMustExist || (aSearch != _rList.end()), "ODbaseIndexDialog::implRemoveIndex : did not find the index!");
202 return aReturn;
205 //-------------------------------------------------------------------------
206 void ODbaseIndexDialog::implInsertIndex(const OTableIndex& _rIndex, TableIndexList& _rList, ListBox& _rDisplay)
208 _rList.push_front( _rIndex );
209 _rDisplay.InsertEntry( _rIndex.GetIndexFileName() );
210 _rDisplay.SelectEntryPos(0);
213 //-------------------------------------------------------------------------
214 OTableIndex ODbaseIndexDialog::RemoveTableIndex( const String& _rTableName, const String& _rIndexName, sal_Bool _bMustExist )
216 OTableIndex aReturn;
218 // does the table exist ?
219 TableInfoListIterator aTablePos;
220 if (!GetTable(_rTableName, aTablePos))
221 return aReturn;
223 return implRemoveIndex(_rIndexName, aTablePos->aIndexList, aLB_TableIndexes, _bMustExist);
226 //-------------------------------------------------------------------------
227 void ODbaseIndexDialog::InsertTableIndex( const String& _rTableName, const OTableIndex& _rIndex)
229 TableInfoListIterator aTablePos;
230 if (!GetTable(_rTableName, aTablePos))
231 return;
233 implInsertIndex(_rIndex, aTablePos->aIndexList, aLB_TableIndexes);
236 //-------------------------------------------------------------------------
237 IMPL_LINK( ODbaseIndexDialog, OKClickHdl, PushButton*, /*pButton*/ )
239 // let all tables write their INF file
241 for ( ConstTableInfoListIterator aLoop = m_aTableInfoList.begin();
242 aLoop != m_aTableInfoList.end();
243 ++aLoop
245 aLoop->WriteInfFile(m_aDSN);
247 EndDialog();
248 return 0;
251 //-------------------------------------------------------------------------
252 IMPL_LINK( ODbaseIndexDialog, AddClickHdl, PushButton*, /*pButton*/ )
254 String aSelection = aLB_FreeIndexes.GetSelectEntry();
255 String aTableName = aCB_Tables.GetText();
256 OTableIndex aIndex = RemoveFreeIndex( aSelection, sal_True );
257 InsertTableIndex( aTableName, aIndex );
259 checkButtons();
260 return 0;
263 //-------------------------------------------------------------------------
264 IMPL_LINK( ODbaseIndexDialog, RemoveClickHdl, PushButton*, /*pButton*/ )
266 String aSelection = aLB_TableIndexes.GetSelectEntry();
267 String aTableName = aCB_Tables.GetText();
268 OTableIndex aIndex = RemoveTableIndex( aTableName, aSelection, sal_True );
269 InsertFreeIndex( aIndex );
271 checkButtons();
272 return 0;
275 //-------------------------------------------------------------------------
276 IMPL_LINK( ODbaseIndexDialog, AddAllClickHdl, PushButton*, /*pButton*/ )
278 sal_uInt16 nCnt = aLB_FreeIndexes.GetEntryCount();
279 String aTableName = aCB_Tables.GetText();
280 String aEntry;
282 for( sal_uInt16 nPos = 0; nPos < nCnt; ++nPos )
283 InsertTableIndex( aTableName, RemoveFreeIndex( aLB_FreeIndexes.GetEntry(0), sal_True ) );
285 checkButtons();
286 return 0;
289 //-------------------------------------------------------------------------
290 IMPL_LINK( ODbaseIndexDialog, RemoveAllClickHdl, PushButton*, /*pButton*/ )
292 sal_uInt16 nCnt = aLB_TableIndexes.GetEntryCount();
293 String aTableName = aCB_Tables.GetText();
294 String aEntry;
296 for( sal_uInt16 nPos = 0; nPos < nCnt; ++nPos )
297 InsertFreeIndex( RemoveTableIndex( aTableName, aLB_TableIndexes.GetEntry(0), sal_True ) );
299 checkButtons();
300 return 0;
303 //-------------------------------------------------------------------------
304 IMPL_LINK( ODbaseIndexDialog, OnListEntrySelected, ListBox*, /*NOTINTERESTEDIN*/ )
306 checkButtons();
307 return 0;
310 //-------------------------------------------------------------------------
311 IMPL_LINK( ODbaseIndexDialog, TableSelectHdl, ComboBox*, pComboBox )
313 // search the table
314 TableInfoListIterator aTablePos;
315 if (!GetTable(pComboBox->GetText(), aTablePos))
316 return 0L;
318 // fill the listbox for the indexes
319 aLB_TableIndexes.Clear();
320 for ( ConstTableIndexListIterator aLoop = aTablePos->aIndexList.begin();
321 aLoop != aTablePos->aIndexList.end();
322 ++aLoop
324 aLB_TableIndexes.InsertEntry( aLoop->GetIndexFileName() );
326 if ( aTablePos->aIndexList.size() )
327 aLB_TableIndexes.SelectEntryPos(0);
329 checkButtons();
330 return 0;
333 //-------------------------------------------------------------------------
334 void ODbaseIndexDialog::Init()
336 aPB_OK.Disable();
337 m_FL_Indexes.Disable();
338 m_FT_TableIndexes.Disable();
339 aLB_TableIndexes.Disable();
340 m_FT_AllIndexes.Disable();
341 aLB_FreeIndexes.Disable();
342 aIB_Add.Disable();
343 aIB_Remove.Disable();
344 aIB_AddAll.Disable();
345 aIB_RemoveAll.Disable();
347 ///////////////////////////////////////////////////////////////////////////
348 // Alle Indizes werden erst einmal zur Liste der freien Indizes hinzugefuegt.
349 // Dann wird fuer jede Tabelle in der Inf-Datei nachgeschaut, welche Indizes sie besitzt.
350 // Diese Indizes werden aus der Liste der freien Indizes entfernt
351 // und in die Indexliste der Tabelle eingetragen
353 ///////////////////////////////////////////////////////////////////////////
354 // if the string does not contain a path, cut the string
355 INetURLObject aURL;
356 aURL.SetSmartProtocol(INET_PROT_FILE);
358 SvtPathOptions aPathOptions;
359 m_aDSN = aPathOptions.SubstituteVariable(m_aDSN);
361 aURL.SetSmartURL(m_aDSN);
364 // String aFileName = aURL.PathToFileName();
365 m_aDSN = aURL.GetMainURL(INetURLObject::NO_DECODE);
366 ::ucbhelper::Content aFile;
367 sal_Bool bFolder=sal_True;
370 aFile = ::ucbhelper::Content(m_aDSN,Reference< ::com::sun::star::ucb::XCommandEnvironment >());
371 bFolder = aFile.isFolder();
373 catch(Exception&)
375 return;
378 ///////////////////////////////////////////////////////////////////////////
379 // first assume for all indexes they're free
381 Sequence< ::rtl::OUString> aFolderContent( ::utl::LocalFileHelper::GetFolderContents(m_aDSN,bFolder));
383 ::rtl::OUString aIndexExt = ::rtl::OUString::createFromAscii("ndx");
384 ::rtl::OUString aTableExt = ::rtl::OUString::createFromAscii("dbf");
386 ::std::vector< String > aUsedIndexes;
388 String aExt;
389 const ::rtl::OUString *pBegin = aFolderContent.getConstArray();
390 const ::rtl::OUString *pEnd = pBegin + aFolderContent.getLength();
391 aURL.SetSmartProtocol(INET_PROT_FILE);
392 for(;pBegin != pEnd;++pBegin)
394 String aName;
395 ::utl::LocalFileHelper::ConvertURLToPhysicalName(pBegin->getStr(),aName);
396 aURL.SetSmartURL(aName);
397 aExt = aURL.getExtension();
398 if(aExt == aIndexExt.getStr())
400 m_aFreeIndexList.push_back( OTableIndex(aURL.getName()) );
402 else if(aExt == aTableExt.getStr())
404 m_aTableInfoList.push_back( OTableInfo(aURL.getName()) );
405 OTableInfo& rTabInfo = m_aTableInfoList.back();
407 // open the INF file
408 aURL.setExtension(String::CreateFromAscii("inf"));
409 OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
410 Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
411 aInfFile.SetGroup( aGroupIdent );
413 ///////////////////////////////////////////////////////////////////////////
414 // fill the indexes list
415 ByteString aNDX;
416 sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
417 ByteString aKeyName;
418 String aEntry;
420 for( sal_uInt16 nKey = 0; nKey < nKeyCnt; nKey++ )
422 // does the key point to an index file ?
423 aKeyName = aInfFile.GetKeyName( nKey );
424 aNDX = aKeyName.Copy(0,3);
426 // yes -> add to the tables index list
427 if (aNDX == "NDX" )
429 aEntry = String(aInfFile.ReadKey(aKeyName), gsl_getSystemTextEncoding());
430 rTabInfo.aIndexList.push_back( OTableIndex( aEntry ) );
432 // and remove it from the free index list
433 aUsedIndexes.push_back(aEntry);
434 // do this later below. We may not have encountered the index file, yet, thus we may not
435 // know the index as beeing free, yet
442 for ( ::std::vector< String >::const_iterator aUsedIndex = aUsedIndexes.begin();
443 aUsedIndex != aUsedIndexes.end();
444 ++aUsedIndex
446 RemoveFreeIndex( *aUsedIndex, sal_False );
448 if (m_aTableInfoList.size())
450 aPB_OK.Enable();
451 m_FL_Indexes.Enable();
452 m_FT_TableIndexes.Enable();
453 aLB_TableIndexes.Enable();
454 m_FT_AllIndexes.Enable();
455 aLB_FreeIndexes.Enable();
458 checkButtons();
461 //-------------------------------------------------------------------------
462 void ODbaseIndexDialog::SetCtrls()
464 // ComboBox Tabellen
465 for ( ConstTableInfoListIterator aLoop = m_aTableInfoList.begin();
466 aLoop != m_aTableInfoList.end();
467 ++aLoop
469 aCB_Tables.InsertEntry( aLoop->aTableName );
471 // Den ersten Datensatz ins Edit stellen
472 if( m_aTableInfoList.size() )
474 const OTableInfo& rTabInfo = m_aTableInfoList.front();
475 aCB_Tables.SetText( rTabInfo.aTableName );
477 // ListBox der Tabellenindizes aufbauen
478 for ( ConstTableIndexListIterator aIndex = rTabInfo.aIndexList.begin();
479 aIndex != rTabInfo.aIndexList.end();
480 ++aIndex
482 aLB_TableIndexes.InsertEntry( aIndex->GetIndexFileName() );
484 if( rTabInfo.aIndexList.size() )
485 aLB_TableIndexes.SelectEntryPos( 0 );
489 // ListBox freie Indizes
490 for ( ConstTableIndexListIterator aFree = m_aFreeIndexList.begin();
491 aFree != m_aFreeIndexList.end();
492 ++aFree
494 aLB_FreeIndexes.InsertEntry( aFree->GetIndexFileName() );
496 if( m_aFreeIndexList.size() )
497 aLB_FreeIndexes.SelectEntryPos( 0 );
500 TableSelectHdl(&aCB_Tables);
501 checkButtons();
504 //////////////////////////////////////////////////////////////////////////
505 // Klasse OTableInfo
506 //-------------------------------------------------------------------------
507 void OTableInfo::WriteInfFile( const String& rDSN ) const
509 // INF-Datei oeffnen
510 INetURLObject aURL;
511 aURL.SetSmartProtocol(INET_PROT_FILE);
512 String aDsn = rDSN;
514 SvtPathOptions aPathOptions;
515 aDsn = aPathOptions.SubstituteVariable(aDsn);
517 aURL.SetSmartURL(aDsn);
518 aURL.Append(aTableName);
519 aURL.setExtension(String::CreateFromAscii("inf"));
521 OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
522 Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
523 aInfFile.SetGroup( aGroupIdent );
525 // Erst einmal alle Tabellenindizes loeschen
526 ByteString aNDX;
527 sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
528 ByteString aKeyName;
529 ByteString aEntry;
530 sal_uInt16 nKey = 0;
532 while( nKey < nKeyCnt )
534 // Verweist der Key auf ein Indexfile?...
535 aKeyName = aInfFile.GetKeyName( nKey );
536 aNDX = aKeyName.Copy(0,3);
538 //...wenn ja, Indexfile loeschen, nKey steht dann auf nachfolgendem Key
539 if( aNDX == "NDX" )
541 aInfFile.DeleteKey(aKeyName);
542 nKeyCnt--;
544 else
545 nKey++;
549 // Jetzt alle gespeicherten Indizes hinzufuegen
550 sal_uInt16 nPos = 0;
551 for ( ConstTableIndexListIterator aIndex = aIndexList.begin();
552 aIndex != aIndexList.end();
553 ++aIndex, ++nPos
556 aKeyName = "NDX";
557 if( nPos > 0 ) // Erster Index erhaelt keine Ziffer
558 aKeyName += ByteString::CreateFromInt32( nPos );
559 aInfFile.WriteKey( aKeyName, ByteString(aIndex->GetIndexFileName(), gsl_getSystemTextEncoding()) );
562 aInfFile.Flush();
564 // Falls nur noch [dbase] in INF-File steht, Datei loeschen
565 if(!nPos)
569 ::ucbhelper::Content aContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
570 aContent.executeCommand( rtl::OUString::createFromAscii( "delete" ),makeAny( sal_Bool( sal_True ) ) );
572 catch (const Exception& e )
574 (void)e; // make compiler happy
575 // simply silent this. The strange algorithm here does a lot of things even if no files at all were
576 // created or accessed, so it's possible that the file we're trying to delete does not even exist,
577 // and this is a valid condition.
578 // 2003-05-15 - #109677# - fs@openoffice.org
583 //.........................................................................
584 } // namespace dbaui
585 //.........................................................................