fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / dbaccess / source / ui / dlg / dbfindex.cxx
blobf767f4ea31e92b10eea2d6122cf236c3d9f1c5e8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "dbfindex.hxx"
21 #include <comphelper/processfactory.hxx>
22 #include <tools/config.hxx>
23 #include <sfx2/app.hxx>
24 #include "moduledbu.hxx"
25 #include "dbu_dlg.hrc"
26 #include <osl/diagnose.h>
27 #include <unotools/localfilehelper.hxx>
28 #include <tools/urlobj.hxx>
29 #include <unotools/pathoptions.hxx>
30 #include <ucbhelper/content.hxx>
31 #include <svl/filenotation.hxx>
32 #include <rtl/strbuf.hxx>
34 namespace dbaui
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::ucb;
38 using namespace ::svt;
40 const OString aGroupIdent("dBase III");
43 ODbaseIndexDialog::ODbaseIndexDialog(vcl::Window * pParent, const OUString& aDataSrcName)
44 : ModalDialog(pParent, "DBaseIndexDialog", "dbaccess/ui/dbaseindexdialog.ui")
45 , m_aDSN(aDataSrcName)
46 , m_bCaseSensitiv(true)
48 get(m_pPB_OK, "ok");
49 get(m_pCB_Tables, "table");
50 get(m_pIndexes, "frame");
51 get(m_pLB_TableIndexes, "tableindex");
52 get(m_pLB_FreeIndexes, "freeindex");
53 Size aSize(LogicToPixel(Size(76, 98), MAP_APPFONT));
54 m_pLB_TableIndexes->set_height_request(aSize.Height());
55 m_pLB_TableIndexes->set_width_request(aSize.Width());
56 m_pLB_FreeIndexes->set_height_request(aSize.Height());
57 m_pLB_FreeIndexes->set_width_request(aSize.Width());
58 get(m_pAdd, "add");
59 get(m_pAddAll, "addall");
60 get(m_pRemove, "remove");
61 get(m_pRemoveAll, "removeall");
64 m_pCB_Tables->SetSelectHdl( LINK(this, ODbaseIndexDialog, TableSelectHdl) );
65 m_pAdd->SetClickHdl( LINK(this, ODbaseIndexDialog, AddClickHdl) );
66 m_pRemove->SetClickHdl( LINK(this, ODbaseIndexDialog, RemoveClickHdl) );
67 m_pAddAll->SetClickHdl( LINK(this, ODbaseIndexDialog, AddAllClickHdl) );
68 m_pRemoveAll->SetClickHdl( LINK(this, ODbaseIndexDialog, RemoveAllClickHdl) );
69 m_pPB_OK->SetClickHdl( LINK(this, ODbaseIndexDialog, OKClickHdl) );
71 m_pLB_FreeIndexes->SetSelectHdl( LINK(this, ODbaseIndexDialog, OnListEntrySelected) );
72 m_pLB_TableIndexes->SetSelectHdl( LINK(this, ODbaseIndexDialog, OnListEntrySelected) );
74 m_pCB_Tables->SetDropDownLineCount(8);
75 Init();
76 SetCtrls();
79 ODbaseIndexDialog::~ODbaseIndexDialog()
81 disposeOnce();
84 void ODbaseIndexDialog::dispose()
86 m_pPB_OK.clear();
87 m_pCB_Tables.clear();
88 m_pIndexes.clear();
89 m_pLB_TableIndexes.clear();
90 m_pLB_FreeIndexes.clear();
91 m_pAdd.clear();
92 m_pRemove.clear();
93 m_pAddAll.clear();
94 m_pRemoveAll.clear();
95 ModalDialog::dispose();
98 bool ODbaseIndexDialog::GetTable(const OUString& _rName, TableInfoList::iterator& _rPosition)
100 for ( _rPosition = m_aTableInfoList.begin();
101 _rPosition != m_aTableInfoList.end();
102 ++_rPosition
105 if (m_bCaseSensitiv)
107 if (_rPosition->aTableName == _rName)
108 return true;
110 else
112 if (_rPosition->aTableName.equalsIgnoreAsciiCase(_rName))
113 return true;
116 return false;
119 void ODbaseIndexDialog::checkButtons()
121 m_pAdd->Enable(0 != m_pLB_FreeIndexes->GetSelectEntryCount());
122 m_pAddAll->Enable(0 != m_pLB_FreeIndexes->GetEntryCount());
124 m_pRemove->Enable(0 != m_pLB_TableIndexes->GetSelectEntryCount());
125 m_pRemoveAll->Enable(0 != m_pLB_TableIndexes->GetEntryCount());
128 OTableIndex ODbaseIndexDialog::implRemoveIndex(const OUString& _rName, TableIndexList& _rList, ListBox& _rDisplay, bool _bMustExist)
130 OTableIndex aReturn;
132 sal_Int32 nPos = 0;
134 TableIndexList::iterator aSearch;
135 for ( aSearch = _rList.begin();
136 aSearch != _rList.end();
137 ++aSearch, ++nPos
140 if ( m_bCaseSensitiv ? aSearch->GetIndexFileName() == _rName : aSearch->GetIndexFileName().equalsIgnoreAsciiCase(_rName) )
142 aReturn = *aSearch;
144 _rList.erase(aSearch);
145 _rDisplay.RemoveEntry( _rName );
147 // adjust selection if necessary
148 if ((sal_uInt32)nPos == _rList.size())
149 _rDisplay.SelectEntryPos((sal_uInt16)nPos-1);
150 else
151 _rDisplay.SelectEntryPos((sal_uInt16)nPos);
153 break;
157 (void)_bMustExist;
158 OSL_ENSURE(!_bMustExist || (aSearch != _rList.end()), "ODbaseIndexDialog::implRemoveIndex : did not find the index!");
159 return aReturn;
162 void ODbaseIndexDialog::implInsertIndex(const OTableIndex& _rIndex, TableIndexList& _rList, ListBox& _rDisplay)
164 _rList.push_front( _rIndex );
165 _rDisplay.InsertEntry( _rIndex.GetIndexFileName() );
166 _rDisplay.SelectEntryPos(0);
169 OTableIndex ODbaseIndexDialog::RemoveTableIndex( const OUString& _rTableName, const OUString& _rIndexName, bool _bMustExist )
171 OTableIndex aReturn;
173 // does the table exist ?
174 TableInfoList::iterator aTablePos;
175 if (!GetTable(_rTableName, aTablePos))
176 return aReturn;
178 return implRemoveIndex(_rIndexName, aTablePos->aIndexList, *m_pLB_TableIndexes, _bMustExist);
181 void ODbaseIndexDialog::InsertTableIndex( const OUString& _rTableName, const OTableIndex& _rIndex)
183 TableInfoList::iterator aTablePos;
184 if (!GetTable(_rTableName, aTablePos))
185 return;
187 implInsertIndex(_rIndex, aTablePos->aIndexList, *m_pLB_TableIndexes);
190 IMPL_LINK( ODbaseIndexDialog, OKClickHdl, PushButton*, /*pButton*/ )
192 // let all tables write their INF file
194 for ( TableInfoList::const_iterator aLoop = m_aTableInfoList.begin();
195 aLoop != m_aTableInfoList.end();
196 ++aLoop
198 aLoop->WriteInfFile(m_aDSN);
200 EndDialog();
201 return 0;
204 IMPL_LINK( ODbaseIndexDialog, AddClickHdl, PushButton*, /*pButton*/ )
206 OUString aSelection = m_pLB_FreeIndexes->GetSelectEntry();
207 OUString aTableName = m_pCB_Tables->GetText();
208 OTableIndex aIndex = RemoveFreeIndex( aSelection, true );
209 InsertTableIndex( aTableName, aIndex );
211 checkButtons();
212 return 0;
215 IMPL_LINK( ODbaseIndexDialog, RemoveClickHdl, PushButton*, /*pButton*/ )
217 OUString aSelection = m_pLB_TableIndexes->GetSelectEntry();
218 OUString aTableName = m_pCB_Tables->GetText();
219 OTableIndex aIndex = RemoveTableIndex( aTableName, aSelection, true );
220 InsertFreeIndex( aIndex );
222 checkButtons();
223 return 0;
226 IMPL_LINK( ODbaseIndexDialog, AddAllClickHdl, PushButton*, /*pButton*/ )
228 sal_uInt16 nCnt = m_pLB_FreeIndexes->GetEntryCount();
229 OUString aTableName = m_pCB_Tables->GetText();
231 for( sal_uInt16 nPos = 0; nPos < nCnt; ++nPos )
232 InsertTableIndex( aTableName, RemoveFreeIndex( m_pLB_FreeIndexes->GetEntry(0), true ) );
234 checkButtons();
235 return 0;
238 IMPL_LINK( ODbaseIndexDialog, RemoveAllClickHdl, PushButton*, /*pButton*/ )
240 sal_uInt16 nCnt = m_pLB_TableIndexes->GetEntryCount();
241 OUString aTableName = m_pCB_Tables->GetText();
243 for( sal_uInt16 nPos = 0; nPos < nCnt; ++nPos )
244 InsertFreeIndex( RemoveTableIndex( aTableName, m_pLB_TableIndexes->GetEntry(0), true ) );
246 checkButtons();
247 return 0;
250 IMPL_LINK( ODbaseIndexDialog, OnListEntrySelected, ListBox*, /*NOTINTERESTEDIN*/ )
252 checkButtons();
253 return 0;
256 IMPL_LINK( ODbaseIndexDialog, TableSelectHdl, ComboBox*, pComboBox )
258 // search the table
259 TableInfoList::iterator aTablePos;
260 if (!GetTable(pComboBox->GetText(), aTablePos))
261 return 0L;
263 // fill the listbox for the indexes
264 m_pLB_TableIndexes->Clear();
265 for ( TableIndexList::const_iterator aLoop = aTablePos->aIndexList.begin();
266 aLoop != aTablePos->aIndexList.end();
267 ++aLoop
269 m_pLB_TableIndexes->InsertEntry( aLoop->GetIndexFileName() );
271 if ( aTablePos->aIndexList.size() )
272 m_pLB_TableIndexes->SelectEntryPos(0);
274 checkButtons();
275 return 0;
278 void ODbaseIndexDialog::Init()
280 m_pPB_OK->Disable();
281 m_pIndexes->Disable();
283 // All indices are first added to a list of free indices.
284 // Afterwards, check the index of each table in the Inf-file.
285 // These indices are removed from the list of free indices and
286 // entered in the indexlist of the table.
288 // if the string does not contain a path, cut the string
289 INetURLObject aURL;
290 aURL.SetSmartProtocol(INetProtocol::File);
292 SvtPathOptions aPathOptions;
293 m_aDSN = aPathOptions.SubstituteVariable(m_aDSN);
295 aURL.SetSmartURL(m_aDSN);
297 // String aFileName = aURL.PathToFileName();
298 m_aDSN = aURL.GetMainURL(INetURLObject::NO_DECODE);
299 ::ucbhelper::Content aFile;
300 bool bFolder=true;
303 aFile = ::ucbhelper::Content(m_aDSN,Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext());
304 bFolder = aFile.isFolder();
306 catch(Exception&)
308 return;
311 // first assume for all indexes they're free
313 Sequence< OUString> aFolderContent( ::utl::LocalFileHelper::GetFolderContents(m_aDSN,bFolder));
315 OUString aIndexExt("ndx");
316 OUString aTableExt("dbf");
318 ::std::vector< OUString > aUsedIndexes;
320 const OUString *pBegin = aFolderContent.getConstArray();
321 const OUString *pEnd = pBegin + aFolderContent.getLength();
322 aURL.SetSmartProtocol(INetProtocol::File);
323 for(;pBegin != pEnd;++pBegin)
325 OUString aName;
326 ::utl::LocalFileHelper::ConvertURLToPhysicalName(pBegin->getStr(),aName);
327 aURL.SetSmartURL(aName);
328 OUString aExt = aURL.getExtension();
329 if (aExt == aIndexExt)
331 m_aFreeIndexList.push_back( OTableIndex(aURL.getName()) );
333 else if (aExt == aTableExt)
335 m_aTableInfoList.push_back( OTableInfo(aURL.getName()) );
336 OTableInfo& rTabInfo = m_aTableInfoList.back();
338 // open the INF file
339 aURL.setExtension("inf");
340 OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
341 Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
342 aInfFile.SetGroup( aGroupIdent );
344 // fill the indexes list
345 OString aNDX;
346 sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
347 OString aKeyName;
348 OUString aEntry;
350 for( sal_uInt16 nKey = 0; nKey < nKeyCnt; nKey++ )
352 // does the key point to an index file ?
353 aKeyName = aInfFile.GetKeyName( nKey );
354 aNDX = aKeyName.copy(0,3);
356 // yes -> add to the tables index list
357 if (aNDX == "NDX")
359 aEntry = OStringToOUString(aInfFile.ReadKey(aKeyName), osl_getThreadTextEncoding());
360 rTabInfo.aIndexList.push_back( OTableIndex( aEntry ) );
362 // and remove it from the free index list
363 aUsedIndexes.push_back(aEntry);
364 // do this later below. We may not have encountered the index file, yet, thus we may not
365 // know the index as being free, yet
371 for ( ::std::vector< OUString >::const_iterator aUsedIndex = aUsedIndexes.begin();
372 aUsedIndex != aUsedIndexes.end();
373 ++aUsedIndex
375 RemoveFreeIndex( *aUsedIndex, false );
377 if (m_aTableInfoList.size())
379 m_pPB_OK->Enable();
380 m_pIndexes->Enable();
383 checkButtons();
386 void ODbaseIndexDialog::SetCtrls()
388 // ComboBox tables
389 for ( TableInfoList::const_iterator aLoop = m_aTableInfoList.begin();
390 aLoop != m_aTableInfoList.end();
391 ++aLoop
393 m_pCB_Tables->InsertEntry( aLoop->aTableName );
395 // put the first dataset into Edit
396 if( m_aTableInfoList.size() )
398 const OTableInfo& rTabInfo = m_aTableInfoList.front();
399 m_pCB_Tables->SetText( rTabInfo.aTableName );
401 // build ListBox of the table indices
402 for ( TableIndexList::const_iterator aIndex = rTabInfo.aIndexList.begin();
403 aIndex != rTabInfo.aIndexList.end();
404 ++aIndex
406 m_pLB_TableIndexes->InsertEntry( aIndex->GetIndexFileName() );
408 if( rTabInfo.aIndexList.size() )
409 m_pLB_TableIndexes->SelectEntryPos( 0 );
412 // ListBox of the free indices
413 for ( TableIndexList::const_iterator aFree = m_aFreeIndexList.begin();
414 aFree != m_aFreeIndexList.end();
415 ++aFree
417 m_pLB_FreeIndexes->InsertEntry( aFree->GetIndexFileName() );
419 if( m_aFreeIndexList.size() )
420 m_pLB_FreeIndexes->SelectEntryPos( 0 );
422 TableSelectHdl(m_pCB_Tables);
423 checkButtons();
426 void OTableInfo::WriteInfFile( const OUString& rDSN ) const
428 // open INF file
429 INetURLObject aURL;
430 aURL.SetSmartProtocol(INetProtocol::File);
431 OUString aDsn = rDSN;
433 SvtPathOptions aPathOptions;
434 aDsn = aPathOptions.SubstituteVariable(aDsn);
436 aURL.SetSmartURL(aDsn);
437 aURL.Append(aTableName);
438 aURL.setExtension("inf");
440 OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
441 Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
442 aInfFile.SetGroup( aGroupIdent );
444 // first, delete all table indices
445 OString aNDX;
446 sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
447 sal_uInt16 nKey = 0;
449 while( nKey < nKeyCnt )
451 // Does the key point to an index file?...
452 OString aKeyName = aInfFile.GetKeyName( nKey );
453 aNDX = aKeyName.copy(0,3);
455 //...if yes, delete index file, nKey is at subsequent key
456 if (aNDX == "NDX")
458 aInfFile.DeleteKey(aKeyName);
459 nKeyCnt--;
461 else
462 nKey++;
466 // now add all saved indices
467 sal_uInt16 nPos = 0;
468 for ( TableIndexList::const_iterator aIndex = aIndexList.begin();
469 aIndex != aIndexList.end();
470 ++aIndex, ++nPos
473 OStringBuffer aKeyName("NDX");
474 if( nPos > 0 ) // first index contains no number
475 aKeyName.append(static_cast<sal_Int32>(nPos));
476 aInfFile.WriteKey(
477 aKeyName.makeStringAndClear(),
478 OUStringToOString(aIndex->GetIndexFileName(),
479 osl_getThreadTextEncoding()));
482 aInfFile.Flush();
484 // if only [dbase] is left in INF-file, delete file
485 if(!nPos)
489 ::ucbhelper::Content aContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>(), comphelper::getProcessComponentContext());
490 aContent.executeCommand( OUString("delete"), makeAny( true ) );
492 catch (const Exception& e )
494 (void)e; // make compiler happy
495 // simply silent this. The strange algorithm here does a lot of
496 // things even if no files at all were created or accessed, so it's
497 // possible that the file we're trying to delete does not even
498 // exist, and this is a valid condition.
503 } // namespace
505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */