1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "dbfindex.hxx"
32 #include <tools/config.hxx>
33 #include <sfx2/app.hxx>
34 #include "moduledbu.hxx"
35 #include "dbu_dlg.hrc"
36 #include "dbfindex.hrc"
37 #include <osl/diagnose.h>
38 #include <unotools/localfilehelper.hxx>
39 #include <tools/urlobj.hxx>
40 #include <unotools/pathoptions.hxx>
41 #include <ucbhelper/content.hxx>
42 #include <svl/filenotation.hxx>
43 #include <rtl/strbuf.hxx>
46 //.........................................................................
49 //.........................................................................
51 using namespace ::com::sun::star::uno
;
52 using namespace ::com::sun::star::ucb
;
53 using namespace ::svt
;
55 const rtl::OString
aGroupIdent(RTL_CONSTASCII_STRINGPARAM("dBase III"));
57 //////////////////////////////////////////////////////////////////////////
58 // Klasse ODbaseIndexDialog
59 DBG_NAME(ODbaseIndexDialog
)
60 //-------------------------------------------------------------------------
61 ODbaseIndexDialog::ODbaseIndexDialog( Window
* pParent
, String aDataSrcName
)
62 : ModalDialog( pParent
, ModuleRes(DLG_DBASE_INDEXES
) ),
63 aPB_OK( this, ModuleRes( PB_OK
) ),
64 aPB_CANCEL( this, ModuleRes( PB_CANCEL
) ),
65 aPB_HELP( this, ModuleRes( PB_HELP
) ),
66 m_FT_Tables( this, ModuleRes( FT_TABLES
) ),
67 aCB_Tables( this, ModuleRes( CB_TABLES
) ),
68 m_FL_Indexes( this, ModuleRes( FL_INDEXES
) ),
69 m_FT_TableIndexes( this, ModuleRes( FT_TABLEINDEXES
) ),
70 aLB_TableIndexes( this, ModuleRes( LB_TABLEINDEXES
) ),
71 m_FT_AllIndexes( this, ModuleRes( FT_ALLINDEXES
) ),
72 aLB_FreeIndexes( this, ModuleRes( LB_FREEINDEXES
) ),
73 aIB_Add( this, ModuleRes( IB_ADD
) ),
74 aIB_Remove( this, ModuleRes( IB_REMOVE
) ),
75 aIB_AddAll( this, ModuleRes( IB_ADDALL
) ),
76 aIB_RemoveAll( this, ModuleRes( IB_REMOVEALL
) ),
78 m_bCaseSensitiv(sal_True
)
80 DBG_CTOR(ODbaseIndexDialog
,NULL
);
82 aCB_Tables
.SetSelectHdl( LINK(this, ODbaseIndexDialog
, TableSelectHdl
) );
83 aIB_Add
.SetClickHdl( LINK(this, ODbaseIndexDialog
, AddClickHdl
) );
84 aIB_Remove
.SetClickHdl( LINK(this, ODbaseIndexDialog
, RemoveClickHdl
) );
85 aIB_AddAll
.SetClickHdl( LINK(this, ODbaseIndexDialog
, AddAllClickHdl
) );
86 aIB_RemoveAll
.SetClickHdl( LINK(this, ODbaseIndexDialog
, RemoveAllClickHdl
) );
87 aPB_OK
.SetClickHdl( LINK(this, ODbaseIndexDialog
, OKClickHdl
) );
89 aLB_FreeIndexes
.SetSelectHdl( LINK(this, ODbaseIndexDialog
, OnListEntrySelected
) );
90 aLB_TableIndexes
.SetSelectHdl( LINK(this, ODbaseIndexDialog
, OnListEntrySelected
) );
92 aCB_Tables
.SetDropDownLineCount(8);
98 //-------------------------------------------------------------------------
99 ODbaseIndexDialog::~ODbaseIndexDialog()
102 DBG_DTOR(ODbaseIndexDialog
,NULL
);
105 //-------------------------------------------------------------------------
106 sal_Bool
ODbaseIndexDialog::GetTable(const String
& _rName
, TableInfoListIterator
& _rPosition
)
108 for ( _rPosition
= m_aTableInfoList
.begin();
109 _rPosition
!= m_aTableInfoList
.end();
115 if (_rPosition
->aTableName
.Equals(_rName
))
120 if (_rPosition
->aTableName
.EqualsIgnoreCaseAscii(_rName
))
127 //-------------------------------------------------------------------------
128 void ODbaseIndexDialog::checkButtons()
130 aIB_Add
.Enable(0 != aLB_FreeIndexes
.GetSelectEntryCount());
131 aIB_AddAll
.Enable(0 != aLB_FreeIndexes
.GetEntryCount());
133 aIB_Remove
.Enable(0 != aLB_TableIndexes
.GetSelectEntryCount());
134 aIB_RemoveAll
.Enable(0 != aLB_TableIndexes
.GetEntryCount());
137 //-------------------------------------------------------------------------
138 OTableIndex
ODbaseIndexDialog::implRemoveIndex(const String
& _rName
, TableIndexList
& _rList
, ListBox
& _rDisplay
, sal_Bool _bMustExist
)
144 TableIndexListIterator aSearch
;
145 for ( aSearch
= _rList
.begin();
146 aSearch
!= _rList
.end();
150 if ( m_bCaseSensitiv
? aSearch
->GetIndexFileName().Equals(_rName
) : aSearch
->GetIndexFileName().EqualsIgnoreCaseAscii(_rName
) )
154 _rList
.erase(aSearch
);
155 _rDisplay
.RemoveEntry( _rName
);
157 // adjust selection if necessary
158 if ((sal_uInt32
)nPos
== _rList
.size())
159 _rDisplay
.SelectEntryPos((sal_uInt16
)nPos
-1);
161 _rDisplay
.SelectEntryPos((sal_uInt16
)nPos
);
168 OSL_ENSURE(!_bMustExist
|| (aSearch
!= _rList
.end()), "ODbaseIndexDialog::implRemoveIndex : did not find the index!");
172 //-------------------------------------------------------------------------
173 void ODbaseIndexDialog::implInsertIndex(const OTableIndex
& _rIndex
, TableIndexList
& _rList
, ListBox
& _rDisplay
)
175 _rList
.push_front( _rIndex
);
176 _rDisplay
.InsertEntry( _rIndex
.GetIndexFileName() );
177 _rDisplay
.SelectEntryPos(0);
180 //-------------------------------------------------------------------------
181 OTableIndex
ODbaseIndexDialog::RemoveTableIndex( const String
& _rTableName
, const String
& _rIndexName
, sal_Bool _bMustExist
)
185 // does the table exist ?
186 TableInfoListIterator aTablePos
;
187 if (!GetTable(_rTableName
, aTablePos
))
190 return implRemoveIndex(_rIndexName
, aTablePos
->aIndexList
, aLB_TableIndexes
, _bMustExist
);
193 //-------------------------------------------------------------------------
194 void ODbaseIndexDialog::InsertTableIndex( const String
& _rTableName
, const OTableIndex
& _rIndex
)
196 TableInfoListIterator aTablePos
;
197 if (!GetTable(_rTableName
, aTablePos
))
200 implInsertIndex(_rIndex
, aTablePos
->aIndexList
, aLB_TableIndexes
);
203 //-------------------------------------------------------------------------
204 IMPL_LINK( ODbaseIndexDialog
, OKClickHdl
, PushButton
*, /*pButton*/ )
206 // let all tables write their INF file
208 for ( ConstTableInfoListIterator aLoop
= m_aTableInfoList
.begin();
209 aLoop
!= m_aTableInfoList
.end();
212 aLoop
->WriteInfFile(m_aDSN
);
218 //-------------------------------------------------------------------------
219 IMPL_LINK( ODbaseIndexDialog
, AddClickHdl
, PushButton
*, /*pButton*/ )
221 String aSelection
= aLB_FreeIndexes
.GetSelectEntry();
222 String aTableName
= aCB_Tables
.GetText();
223 OTableIndex aIndex
= RemoveFreeIndex( aSelection
, sal_True
);
224 InsertTableIndex( aTableName
, aIndex
);
230 //-------------------------------------------------------------------------
231 IMPL_LINK( ODbaseIndexDialog
, RemoveClickHdl
, PushButton
*, /*pButton*/ )
233 String aSelection
= aLB_TableIndexes
.GetSelectEntry();
234 String aTableName
= aCB_Tables
.GetText();
235 OTableIndex aIndex
= RemoveTableIndex( aTableName
, aSelection
, sal_True
);
236 InsertFreeIndex( aIndex
);
242 //-------------------------------------------------------------------------
243 IMPL_LINK( ODbaseIndexDialog
, AddAllClickHdl
, PushButton
*, /*pButton*/ )
245 sal_uInt16 nCnt
= aLB_FreeIndexes
.GetEntryCount();
246 String aTableName
= aCB_Tables
.GetText();
248 for( sal_uInt16 nPos
= 0; nPos
< nCnt
; ++nPos
)
249 InsertTableIndex( aTableName
, RemoveFreeIndex( aLB_FreeIndexes
.GetEntry(0), sal_True
) );
255 //-------------------------------------------------------------------------
256 IMPL_LINK( ODbaseIndexDialog
, RemoveAllClickHdl
, PushButton
*, /*pButton*/ )
258 sal_uInt16 nCnt
= aLB_TableIndexes
.GetEntryCount();
259 String aTableName
= aCB_Tables
.GetText();
261 for( sal_uInt16 nPos
= 0; nPos
< nCnt
; ++nPos
)
262 InsertFreeIndex( RemoveTableIndex( aTableName
, aLB_TableIndexes
.GetEntry(0), sal_True
) );
268 //-------------------------------------------------------------------------
269 IMPL_LINK( ODbaseIndexDialog
, OnListEntrySelected
, ListBox
*, /*NOTINTERESTEDIN*/ )
275 //-------------------------------------------------------------------------
276 IMPL_LINK( ODbaseIndexDialog
, TableSelectHdl
, ComboBox
*, pComboBox
)
279 TableInfoListIterator aTablePos
;
280 if (!GetTable(pComboBox
->GetText(), aTablePos
))
283 // fill the listbox for the indexes
284 aLB_TableIndexes
.Clear();
285 for ( ConstTableIndexListIterator aLoop
= aTablePos
->aIndexList
.begin();
286 aLoop
!= aTablePos
->aIndexList
.end();
289 aLB_TableIndexes
.InsertEntry( aLoop
->GetIndexFileName() );
291 if ( aTablePos
->aIndexList
.size() )
292 aLB_TableIndexes
.SelectEntryPos(0);
298 //-------------------------------------------------------------------------
299 void ODbaseIndexDialog::Init()
302 m_FL_Indexes
.Disable();
303 m_FT_TableIndexes
.Disable();
304 aLB_TableIndexes
.Disable();
305 m_FT_AllIndexes
.Disable();
306 aLB_FreeIndexes
.Disable();
308 aIB_Remove
.Disable();
309 aIB_AddAll
.Disable();
310 aIB_RemoveAll
.Disable();
312 ///////////////////////////////////////////////////////////////////////////
313 // Alle Indizes werden erst einmal zur Liste der freien Indizes hinzugefuegt.
314 // Dann wird fuer jede Tabelle in der Inf-Datei nachgeschaut, welche Indizes sie besitzt.
315 // Diese Indizes werden aus der Liste der freien Indizes entfernt
316 // und in die Indexliste der Tabelle eingetragen
318 ///////////////////////////////////////////////////////////////////////////
319 // if the string does not contain a path, cut the string
321 aURL
.SetSmartProtocol(INET_PROT_FILE
);
323 SvtPathOptions aPathOptions
;
324 m_aDSN
= aPathOptions
.SubstituteVariable(m_aDSN
);
326 aURL
.SetSmartURL(m_aDSN
);
329 // String aFileName = aURL.PathToFileName();
330 m_aDSN
= aURL
.GetMainURL(INetURLObject::NO_DECODE
);
331 ::ucbhelper::Content aFile
;
332 sal_Bool bFolder
=sal_True
;
335 aFile
= ::ucbhelper::Content(m_aDSN
,Reference
< ::com::sun::star::ucb::XCommandEnvironment
>());
336 bFolder
= aFile
.isFolder();
343 ///////////////////////////////////////////////////////////////////////////
344 // first assume for all indexes they're free
346 Sequence
< ::rtl::OUString
> aFolderContent( ::utl::LocalFileHelper::GetFolderContents(m_aDSN
,bFolder
));
348 ::rtl::OUString
aIndexExt(RTL_CONSTASCII_USTRINGPARAM("ndx"));
349 ::rtl::OUString
aTableExt(RTL_CONSTASCII_USTRINGPARAM("dbf"));
351 ::std::vector
< String
> aUsedIndexes
;
354 const ::rtl::OUString
*pBegin
= aFolderContent
.getConstArray();
355 const ::rtl::OUString
*pEnd
= pBegin
+ aFolderContent
.getLength();
356 aURL
.SetSmartProtocol(INET_PROT_FILE
);
357 for(;pBegin
!= pEnd
;++pBegin
)
360 ::utl::LocalFileHelper::ConvertURLToPhysicalName(pBegin
->getStr(),aName
);
361 aURL
.SetSmartURL(aName
);
362 aExt
= aURL
.getExtension();
363 if(aExt
== aIndexExt
.getStr())
365 m_aFreeIndexList
.push_back( OTableIndex(aURL
.getName()) );
367 else if(aExt
== aTableExt
.getStr())
369 m_aTableInfoList
.push_back( OTableInfo(aURL
.getName()) );
370 OTableInfo
& rTabInfo
= m_aTableInfoList
.back();
373 aURL
.setExtension(String::CreateFromAscii("inf"));
374 OFileNotation
aTransformer(aURL
.GetURLNoPass(), OFileNotation::N_URL
);
375 Config
aInfFile( aTransformer
.get(OFileNotation::N_SYSTEM
) );
376 aInfFile
.SetGroup( aGroupIdent
);
378 ///////////////////////////////////////////////////////////////////////////
379 // fill the indexes list
381 sal_uInt16 nKeyCnt
= aInfFile
.GetKeyCount();
382 rtl::OString aKeyName
;
385 for( sal_uInt16 nKey
= 0; nKey
< nKeyCnt
; nKey
++ )
387 // does the key point to an index file ?
388 aKeyName
= aInfFile
.GetKeyName( nKey
);
389 aNDX
= aKeyName
.copy(0,3);
391 // yes -> add to the tables index list
392 if (aNDX
.equalsL(RTL_CONSTASCII_STRINGPARAM("NDX")))
394 aEntry
= rtl::OStringToOUString(aInfFile
.ReadKey(aKeyName
), osl_getThreadTextEncoding());
395 rTabInfo
.aIndexList
.push_back( OTableIndex( aEntry
) );
397 // and remove it from the free index list
398 aUsedIndexes
.push_back(aEntry
);
399 // do this later below. We may not have encountered the index file, yet, thus we may not
400 // know the index as beeing free, yet
407 for ( ::std::vector
< String
>::const_iterator aUsedIndex
= aUsedIndexes
.begin();
408 aUsedIndex
!= aUsedIndexes
.end();
411 RemoveFreeIndex( *aUsedIndex
, sal_False
);
413 if (m_aTableInfoList
.size())
416 m_FL_Indexes
.Enable();
417 m_FT_TableIndexes
.Enable();
418 aLB_TableIndexes
.Enable();
419 m_FT_AllIndexes
.Enable();
420 aLB_FreeIndexes
.Enable();
426 //-------------------------------------------------------------------------
427 void ODbaseIndexDialog::SetCtrls()
430 for ( ConstTableInfoListIterator aLoop
= m_aTableInfoList
.begin();
431 aLoop
!= m_aTableInfoList
.end();
434 aCB_Tables
.InsertEntry( aLoop
->aTableName
);
436 // Den ersten Datensatz ins Edit stellen
437 if( m_aTableInfoList
.size() )
439 const OTableInfo
& rTabInfo
= m_aTableInfoList
.front();
440 aCB_Tables
.SetText( rTabInfo
.aTableName
);
442 // ListBox der Tabellenindizes aufbauen
443 for ( ConstTableIndexListIterator aIndex
= rTabInfo
.aIndexList
.begin();
444 aIndex
!= rTabInfo
.aIndexList
.end();
447 aLB_TableIndexes
.InsertEntry( aIndex
->GetIndexFileName() );
449 if( rTabInfo
.aIndexList
.size() )
450 aLB_TableIndexes
.SelectEntryPos( 0 );
454 // ListBox freie Indizes
455 for ( ConstTableIndexListIterator aFree
= m_aFreeIndexList
.begin();
456 aFree
!= m_aFreeIndexList
.end();
459 aLB_FreeIndexes
.InsertEntry( aFree
->GetIndexFileName() );
461 if( m_aFreeIndexList
.size() )
462 aLB_FreeIndexes
.SelectEntryPos( 0 );
465 TableSelectHdl(&aCB_Tables
);
469 //////////////////////////////////////////////////////////////////////////
471 //-------------------------------------------------------------------------
472 void OTableInfo::WriteInfFile( const String
& rDSN
) const
476 aURL
.SetSmartProtocol(INET_PROT_FILE
);
479 SvtPathOptions aPathOptions
;
480 aDsn
= aPathOptions
.SubstituteVariable(aDsn
);
482 aURL
.SetSmartURL(aDsn
);
483 aURL
.Append(aTableName
);
484 aURL
.setExtension(String::CreateFromAscii("inf"));
486 OFileNotation
aTransformer(aURL
.GetURLNoPass(), OFileNotation::N_URL
);
487 Config
aInfFile( aTransformer
.get(OFileNotation::N_SYSTEM
) );
488 aInfFile
.SetGroup( aGroupIdent
);
490 // Erst einmal alle Tabellenindizes loeschen
492 sal_uInt16 nKeyCnt
= aInfFile
.GetKeyCount();
495 while( nKey
< nKeyCnt
)
497 // Verweist der Key auf ein Indexfile?...
498 rtl::OString aKeyName
= aInfFile
.GetKeyName( nKey
);
499 aNDX
= aKeyName
.copy(0,3);
501 //...wenn ja, Indexfile loeschen, nKey steht dann auf nachfolgendem Key
502 if (aNDX
.equalsL(RTL_CONSTASCII_STRINGPARAM("NDX")))
504 aInfFile
.DeleteKey(aKeyName
);
512 // Jetzt alle gespeicherten Indizes hinzufuegen
514 for ( ConstTableIndexListIterator aIndex
= aIndexList
.begin();
515 aIndex
!= aIndexList
.end();
519 rtl::OStringBuffer
aKeyName(RTL_CONSTASCII_STRINGPARAM("NDX"));
520 if( nPos
> 0 ) // Erster Index erhaelt keine Ziffer
521 aKeyName
.append(static_cast<sal_Int32
>(nPos
));
523 aKeyName
.makeStringAndClear(),
524 rtl::OUStringToOString(aIndex
->GetIndexFileName(),
525 osl_getThreadTextEncoding()));
530 // Falls nur noch [dbase] in INF-File steht, Datei loeschen
535 ::ucbhelper::Content
aContent(aURL
.GetURLNoPass(),Reference
<XCommandEnvironment
>());
536 aContent
.executeCommand( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("delete")),makeAny( sal_Bool( sal_True
) ) );
538 catch (const Exception
& e
)
540 (void)e
; // make compiler happy
541 // simply silent this. The strange algorithm here does a lot of things even if no files at all were
542 // created or accessed, so it's possible that the file we're trying to delete does not even exist,
543 // and this is a valid condition.
548 //.........................................................................
550 //.........................................................................
552 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */