1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/config.h>
24 #include <comphelper/string.hxx>
25 #include <vcl/msgbox.hxx>
27 #include "reffact.hxx"
28 #include "document.hxx"
29 #include "scresid.hxx"
30 #include "globstr.hrc"
31 #include "rangenam.hxx"
32 #include "globalnames.hxx"
33 #include "dbnamdlg.hxx"
34 #include <dbdocfun.hxx>
36 #define ABS_SREF SCA_VALID \
37 | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
38 #define ABS_DREF ABS_SREF \
39 | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
40 #define ABS_DREF3D ABS_DREF | SCA_TAB_3D
44 static DBSaveData
* pSaveObj
= NULL
;
46 #define ERRORBOX(s) ScopedVclPtrInstance<MessageDialog>::Create(this, s)->Execute()
53 DBSaveData( Edit
& rEd
, CheckBox
& rHdr
, CheckBox
& rTot
, CheckBox
& rSize
, CheckBox
& rFmt
,
54 CheckBox
& rStrip
, ScRange
& rArea
)
91 void DBSaveData::Save()
94 aStr
= rEdAssign
.GetText();
95 bHeader
= rBtnHeader
.IsChecked();
96 bTotals
= rBtnTotals
.IsChecked();
97 bSize
= rBtnSize
.IsChecked();
98 bFormat
= rBtnFormat
.IsChecked();
99 bStrip
= rBtnStrip
.IsChecked();
103 void DBSaveData::Restore()
108 rEdAssign
.SetText( aStr
);
109 rBtnHeader
.Check ( bHeader
);
110 rBtnTotals
.Check ( bTotals
);
111 rBtnSize
.Check ( bSize
);
112 rBtnFormat
.Check ( bFormat
);
113 rBtnStrip
.Check ( bStrip
);
120 ScDbNameDlg::ScDbNameDlg(SfxBindings
* pB
, SfxChildWindow
* pCW
, vcl::Window
* pParent
,
121 ScViewData
* ptrViewData
)
122 : ScAnyRefDlg(pB
, pCW
, pParent
,
123 "DefineDatabaseRangeDialog",
124 "modules/scalc/ui/definedatabaserangedialog.ui")
125 , pViewData(ptrViewData
)
126 , pDoc(ptrViewData
->GetDocument())
127 , bRefInputMode(false)
128 , aAddrDetails(pDoc
->GetAddressConvention(), 0, 0)
129 , aLocalDbCol(*(pDoc
->GetDBCollection()))
131 get(m_pEdName
, "entry");
132 m_pEdName
->set_height_request(m_pEdName
->GetOptimalSize().Height() + m_pEdName
->GetTextHeight() * 8);
133 get(m_pEdAssign
, "assign");
134 get(m_pAssignFrame
, "RangeFrame");
135 m_pEdAssign
->SetReferences(this, m_pAssignFrame
->get_label_widget());
136 get(m_pRbAssign
, "assignrb");
137 m_pRbAssign
->SetReferences(this, m_pEdAssign
);
138 get(m_pOptions
, "Options");
139 get(m_pBtnHeader
, "ContainsColumnLabels");
140 get(m_pBtnTotals
, "ContainsTotalsRow");
141 get(m_pBtnDoSize
, "InsertOrDeleteCells");
142 get(m_pBtnKeepFmt
, "KeepFormatting");
143 get(m_pBtnStripData
, "DontSaveImportedData");
144 get(m_pFTSource
, "Source");
145 get(m_pFTOperations
, "Operations");
147 get(m_pBtnCancel
, "cancel");
148 get(m_pBtnAdd
, "add");
149 aStrAdd
= m_pBtnAdd
->GetText();
150 aStrModify
= get
<vcl::Window
>("modify")->GetText();
151 get(m_pBtnRemove
, "delete");
152 aStrInvalid
= get
<vcl::Window
>("invalid")->GetText();
154 m_pFTSource
->SetStyle(m_pFTSource
->GetStyle() | WB_NOLABEL
);
155 m_pFTOperations
->SetStyle(m_pFTOperations
->GetStyle() | WB_NOLABEL
);
157 // damit die Strings in der Resource bei den FixedTexten bleiben koennen:
158 aStrSource
= m_pFTSource
->GetText();
159 aStrOperations
= m_pFTOperations
->GetText();
161 pSaveObj
= new DBSaveData( *m_pEdAssign
, *m_pBtnHeader
, *m_pBtnTotals
,
162 *m_pBtnDoSize
, *m_pBtnKeepFmt
, *m_pBtnStripData
, theCurArea
);
166 ScDbNameDlg::~ScDbNameDlg()
171 void ScDbNameDlg::dispose()
175 m_pAssignFrame
.clear();
179 m_pBtnHeader
.clear();
180 m_pBtnTotals
.clear();
181 m_pBtnDoSize
.clear();
182 m_pBtnKeepFmt
.clear();
183 m_pBtnStripData
.clear();
185 m_pFTOperations
.clear();
187 m_pBtnCancel
.clear();
189 m_pBtnRemove
.clear();
190 ScAnyRefDlg::dispose();
193 void ScDbNameDlg::Init()
195 m_pBtnHeader
->Check( true ); // Default: with column headers
196 m_pBtnTotals
->Check( false ); // Default: without totals row
197 m_pBtnDoSize
->Check( true );
198 m_pBtnKeepFmt
->Check( true );
200 m_pBtnOk
->SetClickHdl ( LINK( this, ScDbNameDlg
, OkBtnHdl
) );
201 m_pBtnCancel
->SetClickHdl ( LINK( this, ScDbNameDlg
, CancelBtnHdl
) );
202 m_pBtnAdd
->SetClickHdl ( LINK( this, ScDbNameDlg
, AddBtnHdl
) );
203 m_pBtnRemove
->SetClickHdl ( LINK( this, ScDbNameDlg
, RemoveBtnHdl
) );
204 m_pEdName
->SetModifyHdl ( LINK( this, ScDbNameDlg
, NameModifyHdl
) );
205 m_pEdAssign
->SetModifyHdl ( LINK( this, ScDbNameDlg
, AssModifyHdl
) );
210 if ( pViewData
&& pDoc
)
219 ScDBCollection
* pDBColl
= pDoc
->GetDBCollection();
220 ScDBData
* pDBData
= NULL
;
222 pViewData
->GetSimpleArea( nStartCol
, nStartRow
, nStartTab
,
223 nEndCol
, nEndRow
, nEndTab
);
225 theCurArea
= ScRange( ScAddress( nStartCol
, nStartRow
, nStartTab
),
226 ScAddress( nEndCol
, nEndRow
, nEndTab
) );
228 theAreaStr
= theCurArea
.Format(ABS_DREF3D
, pDoc
, aAddrDetails
);
232 // Feststellen, ob definierter DB-Bereich markiert wurde:
233 pDBData
= pDBColl
->GetDBAtCursor( nStartCol
, nStartRow
, nStartTab
, true );
236 ScAddress
& rStart
= theCurArea
.aStart
;
237 ScAddress
& rEnd
= theCurArea
.aEnd
;
244 pDBData
->GetArea( nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
246 if ( (rStart
.Tab() == nTab
)
247 && (rStart
.Col() == nCol1
) && (rStart
.Row() == nRow1
)
248 && (rEnd
.Col() == nCol2
) && (rEnd
.Row() == nRow2
) )
250 OUString aDBName
= pDBData
->GetName();
251 if ( aDBName
!= STR_DB_LOCAL_NONAME
)
252 m_pEdName
->SetText(aDBName
);
254 m_pBtnHeader
->Check( pDBData
->HasHeader() );
255 m_pBtnTotals
->Check( pDBData
->HasTotals() );
256 m_pBtnDoSize
->Check( pDBData
->IsDoSize() );
257 m_pBtnKeepFmt
->Check( pDBData
->IsKeepFmt() );
258 m_pBtnStripData
->Check( pDBData
->IsStripData() );
259 SetInfoStrings( pDBData
);
265 m_pEdAssign
->SetText( theAreaStr
);
266 m_pEdName
->GrabFocus();
272 void ScDbNameDlg::SetInfoStrings( const ScDBData
* pDBData
)
275 aBuf
.append(aStrSource
);
279 aBuf
.append(pDBData
->GetSourceString());
281 m_pFTSource
->SetText(aBuf
.makeStringAndClear());
283 aBuf
.append(aStrOperations
);
287 aBuf
.append(pDBData
->GetOperations());
289 m_pFTOperations
->SetText(aBuf
.makeStringAndClear());
292 // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
293 // neue Selektion im Referenz-Fenster angezeigt wird.
295 void ScDbNameDlg::SetReference( const ScRange
& rRef
, ScDocument
* pDocP
)
297 if ( m_pEdAssign
->IsEnabled() )
299 if ( rRef
.aStart
!= rRef
.aEnd
)
300 RefInputStart(m_pEdAssign
);
304 OUString
aRefStr(theCurArea
.Format(ABS_DREF3D
, pDocP
, aAddrDetails
));
305 m_pEdAssign
->SetRefString( aRefStr
);
306 m_pOptions
->Enable();
313 bool ScDbNameDlg::Close()
315 return DoClose( ScDbNameDlgWrapper::GetChildWindowId() );
318 void ScDbNameDlg::SetActive()
320 m_pEdAssign
->GrabFocus();
322 // kein NameModifyHdl, weil sonst Bereiche nicht geaendert werden koennen
323 // (nach dem Aufziehen der Referenz wuerde der alte Inhalt wieder angezeigt)
324 // (der ausgewaehlte DB-Name hat sich auch nicht veraendert)
329 void ScDbNameDlg::UpdateNames()
331 typedef ScDBCollection::NamedDBs DBsType
;
333 const DBsType
& rDBs
= aLocalDbCol
.getNamedDBs();
335 m_pEdName
->SetUpdateMode( false );
338 m_pEdAssign
->SetText( EMPTY_OUSTRING
);
342 DBsType::const_iterator itr
= rDBs
.begin(), itrEnd
= rDBs
.end();
343 for (; itr
!= itrEnd
; ++itr
)
344 m_pEdName
->InsertEntry(itr
->GetName());
348 m_pBtnAdd
->SetText( aStrAdd
);
349 m_pBtnAdd
->Disable();
350 m_pBtnRemove
->Disable();
353 m_pEdName
->SetUpdateMode( true );
354 m_pEdName
->Invalidate();
357 void ScDbNameDlg::UpdateDBData( const OUString
& rStrName
)
360 const ScDBData
* pData
= aLocalDbCol
.getNamedDBs().findByUpperName(ScGlobal::pCharClass
->uppercase(rStrName
));
370 pData
->GetArea( nTab
, nColStart
, nRowStart
, nColEnd
, nRowEnd
);
371 theCurArea
= ScRange( ScAddress( nColStart
, nRowStart
, nTab
),
372 ScAddress( nColEnd
, nRowEnd
, nTab
) );
373 OUString
theArea(theCurArea
.Format(ABS_DREF3D
, pDoc
, aAddrDetails
));
374 m_pEdAssign
->SetText( theArea
);
375 m_pBtnAdd
->SetText( aStrModify
);
376 m_pBtnHeader
->Check( pData
->HasHeader() );
377 m_pBtnTotals
->Check( pData
->HasTotals() );
378 m_pBtnDoSize
->Check( pData
->IsDoSize() );
379 m_pBtnKeepFmt
->Check( pData
->IsKeepFmt() );
380 m_pBtnStripData
->Check( pData
->IsStripData() );
381 SetInfoStrings( pData
);
384 m_pBtnAdd
->SetText( aStrModify
);
386 m_pBtnRemove
->Enable();
387 m_pOptions
->Enable();
390 bool ScDbNameDlg::IsRefInputMode() const
392 return bRefInputMode
;
397 IMPL_LINK_NOARG(ScDbNameDlg
, OkBtnHdl
)
401 // Der View die Aenderungen und die Remove-Liste uebergeben:
402 // beide werden nur als Referenz uebergeben, so dass an dieser
403 // Stelle keine Speicherleichen entstehen koennen:
406 ScDBDocFunc
aFunc(*pViewData
->GetDocShell());
407 aFunc
.ModifyAllDBData(aLocalDbCol
, aRemoveList
);
414 IMPL_LINK_NOARG(ScDbNameDlg
, CancelBtnHdl
)
420 IMPL_LINK_NOARG(ScDbNameDlg
, AddBtnHdl
)
422 OUString aNewName
= comphelper::string::strip(m_pEdName
->GetText(), ' ');
423 OUString aNewArea
= m_pEdAssign
->GetText();
425 if ( !aNewName
.isEmpty() && !aNewArea
.isEmpty() )
427 if ( ScRangeData::IsNameValid( aNewName
, pDoc
) && aNewName
!= STR_DB_LOCAL_NONAME
)
429 // weil jetzt editiert werden kann, muss erst geparst werden
431 OUString aText
= m_pEdAssign
->GetText();
432 if ( aTmpRange
.ParseAny( aText
, pDoc
, aAddrDetails
) & SCA_VALID
)
434 theCurArea
= aTmpRange
;
435 ScAddress aStart
= theCurArea
.aStart
;
436 ScAddress aEnd
= theCurArea
.aEnd
;
438 ScDBData
* pOldEntry
= aLocalDbCol
.getNamedDBs().findByUpperName(ScGlobal::pCharClass
->uppercase(aNewName
));
441 // Bereich veraendern
443 pOldEntry
->MoveTo( aStart
.Tab(), aStart
.Col(), aStart
.Row(),
444 aEnd
.Col(), aEnd
.Row() );
445 pOldEntry
->SetByRow( true );
446 pOldEntry
->SetHeader( m_pBtnHeader
->IsChecked() );
447 pOldEntry
->SetTotals( m_pBtnTotals
->IsChecked() );
448 pOldEntry
->SetDoSize( m_pBtnDoSize
->IsChecked() );
449 pOldEntry
->SetKeepFmt( m_pBtnKeepFmt
->IsChecked() );
450 pOldEntry
->SetStripData( m_pBtnStripData
->IsChecked() );
454 // neuen Bereich einfuegen
456 ScDBData
* pNewEntry
= new ScDBData( aNewName
, aStart
.Tab(),
457 aStart
.Col(), aStart
.Row(),
458 aEnd
.Col(), aEnd
.Row(),
459 true, m_pBtnHeader
->IsChecked(),
460 m_pBtnTotals
->IsChecked() );
461 pNewEntry
->SetDoSize( m_pBtnDoSize
->IsChecked() );
462 pNewEntry
->SetKeepFmt( m_pBtnKeepFmt
->IsChecked() );
463 pNewEntry
->SetStripData( m_pBtnStripData
->IsChecked() );
465 bool ins
= aLocalDbCol
.getNamedDBs().insert(pNewEntry
);
466 assert(ins
); (void)ins
;
471 m_pEdName
->SetText( EMPTY_OUSTRING
);
472 m_pEdName
->GrabFocus();
473 m_pBtnAdd
->SetText( aStrAdd
);
474 m_pBtnAdd
->Disable();
475 m_pBtnRemove
->Disable();
476 m_pEdAssign
->SetText( EMPTY_OUSTRING
);
477 m_pBtnHeader
->Check( true ); // Default: with column headers
478 m_pBtnTotals
->Check( false ); // Default: without totals row
479 m_pBtnDoSize
->Check( false );
480 m_pBtnKeepFmt
->Check( false );
481 m_pBtnStripData
->Check( false );
482 SetInfoStrings( NULL
); // leer
483 theCurArea
= ScRange();
490 ERRORBOX( aStrInvalid
);
491 m_pEdAssign
->SetSelection( Selection( 0, SELECTION_MAX
) );
492 m_pEdAssign
->GrabFocus();
497 ERRORBOX( ScGlobal::GetRscString(STR_INVALIDNAME
) );
498 m_pEdName
->SetSelection( Selection( 0, SELECTION_MAX
) );
499 m_pEdName
->GrabFocus();
507 class FindByName
: public ::std::unary_function
<ScDBData
, bool>
509 const OUString
& mrName
;
511 FindByName(const OUString
& rName
) : mrName(rName
) {}
512 bool operator() (const ScDBData
& r
) const
514 return r
.GetName().equals(mrName
);
520 IMPL_LINK_NOARG(ScDbNameDlg
, RemoveBtnHdl
)
522 OUString aStrEntry
= m_pEdName
->GetText();
523 ScDBCollection::NamedDBs
& rDBs
= aLocalDbCol
.getNamedDBs();
524 ScDBCollection::NamedDBs::iterator itr
=
525 ::std::find_if(rDBs
.begin(), rDBs
.end(), FindByName(aStrEntry
));
527 if (itr
!= rDBs
.end())
529 OUString aStrDelMsg
= ScGlobal::GetRscString( STR_QUERY_DELENTRY
);
532 aBuf
.append(aStrDelMsg
.getToken(0, '#'));
533 aBuf
.append(aStrEntry
);
534 aBuf
.append(aStrDelMsg
.getToken(1, '#'));
535 ScopedVclPtrInstance
< QueryBox
> aBox(this, WinBits(WB_YES_NO
|WB_DEF_YES
), aBuf
.makeStringAndClear());
537 if (RET_YES
== aBox
->Execute())
540 SCCOL nColStart
, nColEnd
;
541 SCROW nRowStart
, nRowEnd
;
542 itr
->GetArea( nTab
, nColStart
, nRowStart
, nColEnd
, nRowEnd
);
543 aRemoveList
.push_back(
544 ScRange( ScAddress( nColStart
, nRowStart
, nTab
),
545 ScAddress( nColEnd
, nRowEnd
, nTab
) ) );
551 m_pEdName
->SetText( EMPTY_OUSTRING
);
552 m_pEdName
->GrabFocus();
553 m_pBtnAdd
->SetText( aStrAdd
);
554 m_pBtnAdd
->Disable();
555 m_pBtnRemove
->Disable();
556 m_pEdAssign
->SetText( EMPTY_OUSTRING
);
557 theCurArea
= ScRange();
558 m_pBtnHeader
->Check( true ); // Default: with column headers
559 m_pBtnTotals
->Check( false ); // Default: without totals row
560 m_pBtnDoSize
->Check( false );
561 m_pBtnKeepFmt
->Check( false );
562 m_pBtnStripData
->Check( false );
563 SetInfoStrings( NULL
); // leer
572 IMPL_LINK_NOARG(ScDbNameDlg
, NameModifyHdl
)
574 OUString theName
= m_pEdName
->GetText();
575 bool bNameFound
= (COMBOBOX_ENTRY_NOTFOUND
576 != m_pEdName
->GetEntryPos( theName
));
578 if ( theName
.isEmpty() )
580 if (m_pBtnAdd
->GetText() != aStrAdd
)
581 m_pBtnAdd
->SetText( aStrAdd
);
582 m_pBtnAdd
->Disable();
583 m_pBtnRemove
->Disable();
584 m_pAssignFrame
->Disable();
585 m_pOptions
->Disable();
587 //pSaveObj->Restore();
588 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
589 //SFX_APPWINDOW->Disable(sal_False); //! allgemeine Methode im ScAnyRefDlg
590 bRefInputMode
= false;
596 if (m_pBtnAdd
->GetText() != aStrModify
)
597 m_pBtnAdd
->SetText( aStrModify
);
604 UpdateDBData( theName
);
608 if (m_pBtnAdd
->GetText() != aStrAdd
)
609 m_pBtnAdd
->SetText( aStrAdd
);
614 if ( !m_pEdAssign
->GetText().isEmpty() )
617 m_pOptions
->Enable();
621 m_pBtnAdd
->Disable();
622 m_pOptions
->Disable();
624 m_pBtnRemove
->Disable();
627 m_pAssignFrame
->Enable();
629 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
630 //SFX_APPWINDOW->Enable();
631 bRefInputMode
= true;
636 IMPL_LINK_NOARG(ScDbNameDlg
, AssModifyHdl
)
638 // hier parsen fuer Save() etc.
641 OUString aText
= m_pEdAssign
->GetText();
642 if ( aTmpRange
.ParseAny( aText
, pDoc
, aAddrDetails
) & SCA_VALID
)
643 theCurArea
= aTmpRange
;
645 if (!aText
.isEmpty() && !m_pEdName
->GetText().isEmpty())
648 m_pBtnHeader
->Enable();
649 m_pBtnTotals
->Enable();
650 m_pBtnDoSize
->Enable();
651 m_pBtnKeepFmt
->Enable();
652 m_pBtnStripData
->Enable();
653 m_pFTSource
->Enable();
654 m_pFTOperations
->Enable();
658 m_pBtnAdd
->Disable();
659 m_pBtnHeader
->Disable();
660 m_pBtnTotals
->Disable();
661 m_pBtnDoSize
->Disable();
662 m_pBtnKeepFmt
->Disable();
663 m_pBtnStripData
->Disable();
664 m_pFTSource
->Disable();
665 m_pFTOperations
->Disable();
671 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */