1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dbfindex.cxx,v $
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"
39 #include <tools/config.hxx>
41 #ifndef _SFXAPP_HXX //autogen
42 #include <sfx2/app.hxx>
44 #ifndef _DBAUI_MODULE_DBU_HXX_
45 #include "moduledbu.hxx"
48 #include "dbu_dlg.hrc"
50 #ifndef _DBAUI_DBF_INDEXES_HRC_
51 #include "dbfindex.hrc"
53 #ifndef _TOOLS_DEBUG_HXX
54 #include <tools/debug.hxx>
56 #ifndef _UNOTOOLS_LOCALFILEHELPER_HXX
57 #include <unotools/localfilehelper.hxx>
60 #include <tools/urlobj.hxx>
62 #ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
63 #include <svtools/pathoptions.hxx>
65 #ifndef _UCBHELPER_CONTENT_HXX
66 #include <ucbhelper/content.hxx>
68 #ifndef SVTOOLS_FILENOTATION_HXX_
69 #include <svtools/filenotation.hxx>
73 //.........................................................................
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);
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();
148 if (_rPosition
->aTableName
.Equals(_rName
))
153 if (_rPosition
->aTableName
.EqualsIgnoreCaseAscii(_rName
))
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
)
177 TableIndexListIterator aSearch
;
178 for ( aSearch
= _rList
.begin();
179 aSearch
!= _rList
.end();
183 if ( m_bCaseSensitiv
? aSearch
->GetIndexFileName().Equals(_rName
) : aSearch
->GetIndexFileName().EqualsIgnoreCaseAscii(_rName
) )
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);
194 _rDisplay
.SelectEntryPos((sal_uInt16
)nPos
);
201 DBG_ASSERT(!_bMustExist
|| (aSearch
!= _rList
.end()), "ODbaseIndexDialog::implRemoveIndex : did not find the index!");
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
)
218 // does the table exist ?
219 TableInfoListIterator aTablePos
;
220 if (!GetTable(_rTableName
, aTablePos
))
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
))
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();
245 aLoop
->WriteInfFile(m_aDSN
);
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
);
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
);
275 //-------------------------------------------------------------------------
276 IMPL_LINK( ODbaseIndexDialog
, AddAllClickHdl
, PushButton
*, /*pButton*/ )
278 sal_uInt16 nCnt
= aLB_FreeIndexes
.GetEntryCount();
279 String aTableName
= aCB_Tables
.GetText();
282 for( sal_uInt16 nPos
= 0; nPos
< nCnt
; ++nPos
)
283 InsertTableIndex( aTableName
, RemoveFreeIndex( aLB_FreeIndexes
.GetEntry(0), sal_True
) );
289 //-------------------------------------------------------------------------
290 IMPL_LINK( ODbaseIndexDialog
, RemoveAllClickHdl
, PushButton
*, /*pButton*/ )
292 sal_uInt16 nCnt
= aLB_TableIndexes
.GetEntryCount();
293 String aTableName
= aCB_Tables
.GetText();
296 for( sal_uInt16 nPos
= 0; nPos
< nCnt
; ++nPos
)
297 InsertFreeIndex( RemoveTableIndex( aTableName
, aLB_TableIndexes
.GetEntry(0), sal_True
) );
303 //-------------------------------------------------------------------------
304 IMPL_LINK( ODbaseIndexDialog
, OnListEntrySelected
, ListBox
*, /*NOTINTERESTEDIN*/ )
310 //-------------------------------------------------------------------------
311 IMPL_LINK( ODbaseIndexDialog
, TableSelectHdl
, ComboBox
*, pComboBox
)
314 TableInfoListIterator aTablePos
;
315 if (!GetTable(pComboBox
->GetText(), aTablePos
))
318 // fill the listbox for the indexes
319 aLB_TableIndexes
.Clear();
320 for ( ConstTableIndexListIterator aLoop
= aTablePos
->aIndexList
.begin();
321 aLoop
!= aTablePos
->aIndexList
.end();
324 aLB_TableIndexes
.InsertEntry( aLoop
->GetIndexFileName() );
326 if ( aTablePos
->aIndexList
.size() )
327 aLB_TableIndexes
.SelectEntryPos(0);
333 //-------------------------------------------------------------------------
334 void ODbaseIndexDialog::Init()
337 m_FL_Indexes
.Disable();
338 m_FT_TableIndexes
.Disable();
339 aLB_TableIndexes
.Disable();
340 m_FT_AllIndexes
.Disable();
341 aLB_FreeIndexes
.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
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();
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
;
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
)
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();
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
416 sal_uInt16 nKeyCnt
= aInfFile
.GetKeyCount();
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
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();
446 RemoveFreeIndex( *aUsedIndex
, sal_False
);
448 if (m_aTableInfoList
.size())
451 m_FL_Indexes
.Enable();
452 m_FT_TableIndexes
.Enable();
453 aLB_TableIndexes
.Enable();
454 m_FT_AllIndexes
.Enable();
455 aLB_FreeIndexes
.Enable();
461 //-------------------------------------------------------------------------
462 void ODbaseIndexDialog::SetCtrls()
465 for ( ConstTableInfoListIterator aLoop
= m_aTableInfoList
.begin();
466 aLoop
!= m_aTableInfoList
.end();
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();
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();
494 aLB_FreeIndexes
.InsertEntry( aFree
->GetIndexFileName() );
496 if( m_aFreeIndexList
.size() )
497 aLB_FreeIndexes
.SelectEntryPos( 0 );
500 TableSelectHdl(&aCB_Tables
);
504 //////////////////////////////////////////////////////////////////////////
506 //-------------------------------------------------------------------------
507 void OTableInfo::WriteInfFile( const String
& rDSN
) const
511 aURL
.SetSmartProtocol(INET_PROT_FILE
);
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
527 sal_uInt16 nKeyCnt
= aInfFile
.GetKeyCount();
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
541 aInfFile
.DeleteKey(aKeyName
);
549 // Jetzt alle gespeicherten Indizes hinzufuegen
551 for ( ConstTableIndexListIterator aIndex
= aIndexList
.begin();
552 aIndex
!= aIndexList
.end();
557 if( nPos
> 0 ) // Erster Index erhaelt keine Ziffer
558 aKeyName
+= ByteString::CreateFromInt32( nPos
);
559 aInfFile
.WriteKey( aKeyName
, ByteString(aIndex
->GetIndexFileName(), gsl_getSystemTextEncoding()) );
564 // Falls nur noch [dbase] in INF-File steht, Datei loeschen
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 //.........................................................................
585 //.........................................................................