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 .
22 #include <editeng/editids.hrc>
23 #include <vcl/svapp.hxx>
24 #include <vcl/weld.hxx>
25 #include <svl/intitem.hxx>
26 #include <svx/svxdlg.hxx>
27 #include <unotools/collatorwrapper.hxx>
28 #include <svtools/collatorres.hxx>
32 #include <strings.hrc>
33 #include <swtable.hxx>
34 #include <sortopt.hxx>
39 static bool bCheck1
= true;
40 static bool bCheck2
= false;
41 static bool bCheck3
= false;
43 static sal_uInt16 nCol1
= 1;
44 static sal_uInt16 nCol2
= 1;
45 static sal_uInt16 nCol3
= 1;
47 static sal_uInt16 nType1
= 0;
48 static sal_uInt16 nType2
= 0;
49 static sal_uInt16 nType3
= 0;
51 static LanguageType nLang
= LANGUAGE_NONE
;
53 static bool bAsc1
= true;
54 static bool bAsc2
= true;
55 static bool bAsc3
= true;
56 static bool bCol
= false;
57 static bool bCsSens
= false;
59 static sal_Unicode cDeli
= '\t';
61 using namespace ::com::sun::star::lang
;
62 using namespace ::com::sun::star::uno
;
63 using namespace ::com::sun::star
;
65 // determine lines and columns for table selection
66 static bool lcl_GetSelTable( SwWrtShell
const &rSh
, sal_uInt16
& rX
, sal_uInt16
& rY
)
68 const SwTableNode
* pTableNd
= rSh
.IsCursorInTable();
72 FndBox_
aFndBox( nullptr, nullptr );
74 // look for all boxes / lines
77 ::GetTableSel( rSh
, aSelBoxes
);
78 FndPara
aPara( aSelBoxes
, &aFndBox
);
79 const SwTable
& rTable
= pTableNd
->GetTable();
80 ForEach_FndLineCopyCol( const_cast<SwTableLines
&>(rTable
.GetTabLines()), &aPara
);
82 rX
= aFndBox
.GetLines().size();
86 rY
= aFndBox
.GetLines().front()->GetBoxes().size();
91 SwSortDlg::SwSortDlg(weld::Window
* pParent
, SwWrtShell
&rShell
)
92 : GenericDialogController(pParent
, "modules/swriter/ui/sortdialog.ui", "SortDialog")
94 , m_xColLbl(m_xBuilder
->weld_label("column"))
95 , m_xKeyCB1(m_xBuilder
->weld_check_button("key1"))
96 , m_xColEdt1(m_xBuilder
->weld_spin_button("colsb1"))
97 , m_xTypDLB1(m_xBuilder
->weld_combo_box("typelb1"))
98 , m_xSortUp1RB(m_xBuilder
->weld_radio_button("up1"))
99 , m_xSortDn1RB(m_xBuilder
->weld_radio_button("down1"))
100 , m_xKeyCB2(m_xBuilder
->weld_check_button("key2"))
101 , m_xColEdt2(m_xBuilder
->weld_spin_button("colsb2"))
102 , m_xTypDLB2(m_xBuilder
->weld_combo_box("typelb2"))
103 , m_xSortUp2RB(m_xBuilder
->weld_radio_button("up2"))
104 , m_xSortDn2RB(m_xBuilder
->weld_radio_button("down2"))
105 , m_xKeyCB3(m_xBuilder
->weld_check_button("key3"))
106 , m_xColEdt3(m_xBuilder
->weld_spin_button("colsb3"))
107 , m_xTypDLB3(m_xBuilder
->weld_combo_box("typelb3"))
108 , m_xSortUp3RB(m_xBuilder
->weld_radio_button("up3"))
109 , m_xSortDn3RB(m_xBuilder
->weld_radio_button("down3"))
110 , m_xColumnRB(m_xBuilder
->weld_radio_button("columns"))
111 , m_xRowRB(m_xBuilder
->weld_radio_button("rows"))
112 , m_xDelimTabRB(m_xBuilder
->weld_radio_button("tabs"))
113 , m_xDelimFreeRB(m_xBuilder
->weld_radio_button("character"))
114 , m_xDelimEdt(m_xBuilder
->weld_entry("separator"))
115 , m_xDelimPB(m_xBuilder
->weld_button("delimpb"))
116 , m_xLangLB(new SvxLanguageBox(m_xBuilder
->weld_combo_box("langlb")))
117 , m_xCaseCB(m_xBuilder
->weld_check_button("matchcase"))
118 , m_aColText(SwResId(STR_COL
))
119 , m_aRowText(SwResId(STR_ROW
))
120 , m_aNumericText(SwResId(STR_NUMERIC
))
125 if(m_rSh
.GetSelectionType() &
126 (SelectionType::Table
|SelectionType::TableCell
) )
128 m_xColumnRB
->set_active(bCol
);
129 m_xColLbl
->set_label(bCol
? m_aRowText
: m_aColText
);
130 m_xRowRB
->set_active(!bCol
);
131 m_xDelimTabRB
->set_sensitive(false);
132 m_xDelimFreeRB
->set_sensitive(false);
133 m_xDelimEdt
->set_sensitive(false);
137 m_xColumnRB
->set_sensitive(false);
138 m_xRowRB
->set_active(true);
139 m_xColLbl
->set_label(m_aColText
);
142 // Set accessible names here because text of m_xColLbl may be changed
143 // by the if-else block above
144 m_xColEdt1
->set_accessible_name(m_xColLbl
->get_label());
145 m_xColEdt2
->set_accessible_name(m_xColLbl
->get_label());
146 m_xColEdt3
->set_accessible_name(m_xColLbl
->get_label());
149 Link
<weld::Toggleable
&,void> aLk
= LINK(this, SwSortDlg
, CheckHdl
);
150 m_xKeyCB1
->connect_toggled( aLk
);
151 m_xKeyCB2
->connect_toggled( aLk
);
152 m_xKeyCB3
->connect_toggled( aLk
);
153 m_xColumnRB
->connect_toggled( aLk
);
154 m_xRowRB
->connect_toggled( aLk
);
156 aLk
= LINK(this, SwSortDlg
, DelimHdl
);
157 m_xDelimFreeRB
->connect_toggled(aLk
);
158 m_xDelimTabRB
->connect_toggled(aLk
);
160 m_xDelimPB
->connect_clicked( LINK( this, SwSortDlg
, DelimCharHdl
));
162 m_xKeyCB1
->set_active(bCheck1
);
163 m_xKeyCB2
->set_active(bCheck2
);
164 m_xKeyCB3
->set_active(bCheck3
);
166 m_xColEdt1
->set_value(nCol1
);
167 m_xColEdt2
->set_value(nCol2
);
168 m_xColEdt3
->set_value(nCol3
);
170 // first initialise the language, then select the
171 if( LANGUAGE_NONE
== nLang
|| LANGUAGE_DONTKNOW
== nLang
)
172 nLang
= GetAppLanguage();
174 m_xLangLB
->SetLanguageList( SvxLanguageListFlags::ALL
| SvxLanguageListFlags::ONLY_KNOWN
, true );
175 m_xLangLB
->set_active_id(nLang
);
177 LanguageHdl( nullptr );
178 m_xLangLB
->connect_changed( LINK( this, SwSortDlg
, LanguageListBoxHdl
));
180 m_xSortUp1RB
->set_active(bAsc1
);
181 m_xSortDn1RB
->set_active(!bAsc1
);
182 m_xSortUp2RB
->set_active(bAsc2
);
183 m_xSortDn2RB
->set_active(!bAsc2
);
184 m_xSortUp3RB
->set_active(bAsc3
);
185 m_xSortDn3RB
->set_active(!bAsc3
);
187 m_xCaseCB
->set_active( bCsSens
);
189 m_xDelimTabRB
->set_active(cDeli
== '\t');
190 if(!m_xDelimTabRB
->get_active())
192 m_xDelimEdt
->set_text(OUString(cDeli
));
193 m_xDelimFreeRB
->set_active(true);
194 DelimHdl(*m_xDelimFreeRB
);
197 DelimHdl(*m_xDelimTabRB
);
199 if( ::lcl_GetSelTable( m_rSh
, m_nX
, m_nY
) )
201 sal_uInt16 nMax
= m_xRowRB
->get_active()? m_nY
: m_nX
;
202 m_xColEdt1
->set_max(nMax
);
203 m_xColEdt2
->set_max(nMax
);
204 m_xColEdt3
->set_max(nMax
);
208 sal_Unicode
SwSortDlg::GetDelimChar() const
210 sal_Unicode cRet
= '\t';
211 if( !m_xDelimTabRB
->get_active() )
213 OUString
aTmp(m_xDelimEdt
->get_text());
214 if( !aTmp
.isEmpty() )
220 short SwSortDlg::run()
222 short nRet
= GenericDialogController::run();
228 // pass on to the Core
229 void SwSortDlg::Apply()
232 bCheck1
= m_xKeyCB1
->get_active();
233 bCheck2
= m_xKeyCB2
->get_active();
234 bCheck3
= m_xKeyCB3
->get_active();
236 nCol1
= m_xColEdt1
->get_value();
237 nCol2
= m_xColEdt2
->get_value();
238 nCol3
= m_xColEdt3
->get_value();
240 nType1
= m_xTypDLB1
->get_active();
241 nType2
= m_xTypDLB2
->get_active();
242 nType3
= m_xTypDLB3
->get_active();
244 bAsc1
= m_xSortUp1RB
->get_active();
245 bAsc2
= m_xSortUp2RB
->get_active();
246 bAsc3
= m_xSortUp3RB
->get_active();
247 bCol
= m_xColumnRB
->get_active();
248 nLang
= m_xLangLB
->get_active_id();
249 cDeli
= GetDelimChar();
250 bCsSens
= m_xCaseCB
->get_active();
252 SwSortOptions aOptions
;
255 OUString
sEntry( m_xTypDLB1
->get_active_text() );
256 if( sEntry
== m_aNumericText
)
258 else if (!m_xTypDLB1
->get_active_id().isEmpty())
259 sEntry
= m_xTypDLB1
->get_active_id();
261 aOptions
.aKeys
.push_back(
262 SwSortKey( nCol1
, sEntry
,
263 bAsc1
? SwSortOrder::Ascending
: SwSortOrder::Descending
));
268 OUString
sEntry( m_xTypDLB2
->get_active_text() );
269 if( sEntry
== m_aNumericText
)
271 else if (!m_xTypDLB2
->get_active_id().isEmpty())
272 sEntry
= m_xTypDLB2
->get_active_id();
274 aOptions
.aKeys
.push_back(
275 SwSortKey( nCol2
, sEntry
,
276 bAsc2
? SwSortOrder::Ascending
: SwSortOrder::Descending
));
281 OUString
sEntry( m_xTypDLB3
->get_active_text() );
282 if( sEntry
== m_aNumericText
)
284 else if (!m_xTypDLB3
->get_active_id().isEmpty())
285 sEntry
= m_xTypDLB3
->get_active_id();
287 aOptions
.aKeys
.push_back(
288 SwSortKey( nCol3
, sEntry
,
289 bAsc3
? SwSortOrder::Ascending
: SwSortOrder::Descending
));
292 aOptions
.eDirection
= bCol
? SwSortDirection::Columns
: SwSortDirection::Rows
;
293 aOptions
.cDeli
= cDeli
;
294 aOptions
.nLanguage
= nLang
;
295 aOptions
.bTable
= m_rSh
.IsTableMode();
296 aOptions
.bIgnoreCase
= !bCsSens
;
300 SwWait
aWait( *m_rSh
.GetView().GetDocShell(), true );
301 m_rSh
.StartAllAction();
302 bRet
= m_rSh
.Sort( aOptions
);
305 m_rSh
.EndAllAction();
310 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(m_pParent
,
311 VclMessageType::Info
, VclButtonsType::Ok
,
312 SwResId(STR_SRTERR
)));
317 IMPL_LINK( SwSortDlg
, DelimHdl
, weld::Toggleable
&, rButton
, void )
319 bool bEnable
= &rButton
== m_xDelimFreeRB
.get() && m_xDelimFreeRB
->get_sensitive();
320 m_xDelimEdt
->set_sensitive( bEnable
);
321 m_xDelimPB
->set_sensitive( bEnable
);
324 IMPL_LINK_NOARG(SwSortDlg
, DelimCharHdl
, weld::Button
&, void)
326 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
327 SfxAllItemSet
aSet( m_rSh
.GetAttrPool() );
328 aSet
.Put( SfxInt32Item( SID_ATTR_CHAR
, GetDelimChar() ) );
329 ScopedVclPtr
<SfxAbstractDialog
> pMap(pFact
->CreateCharMapDialog(m_xDialog
.get(), aSet
, nullptr));
330 if( RET_OK
== pMap
->Execute() )
332 const SfxInt32Item
* pItem
= SfxItemSet::GetItem
<SfxInt32Item
>(pMap
->GetOutputItemSet(), SID_ATTR_CHAR
, false);
334 m_xDelimEdt
->set_text(OUString(sal_Unicode(pItem
->GetValue())));
338 IMPL_LINK( SwSortDlg
, CheckHdl
, weld::Toggleable
&, rControl
, void )
340 if (&rControl
== m_xRowRB
.get())
342 m_xColLbl
->set_label(m_aColText
);
343 m_xColEdt1
->set_max(m_nY
);
344 m_xColEdt2
->set_max(m_nY
);
345 m_xColEdt3
->set_max(m_nY
);
347 m_xColEdt1
->set_accessible_name(m_aColText
);
348 m_xColEdt2
->set_accessible_name(m_aColText
);
349 m_xColEdt3
->set_accessible_name(m_aColText
);
351 else if (&rControl
== m_xColumnRB
.get())
353 m_xColLbl
->set_label(m_aRowText
);
354 m_xColEdt1
->set_max(m_nX
);
355 m_xColEdt2
->set_max(m_nX
);
356 m_xColEdt3
->set_max(m_nX
);
358 m_xColEdt1
->set_accessible_name(m_aRowText
);
359 m_xColEdt2
->set_accessible_name(m_aRowText
);
360 m_xColEdt3
->set_accessible_name(m_aRowText
);
362 else if(!m_xKeyCB1
->get_active() &&
363 !m_xKeyCB2
->get_active() &&
364 !m_xKeyCB3
->get_active())
366 rControl
.set_active(true);
370 IMPL_LINK( SwSortDlg
, LanguageListBoxHdl
, weld::ComboBox
&, rLBox
, void )
375 void SwSortDlg::LanguageHdl(weld::ComboBox
const* pLBox
)
377 Sequence
< OUString
> aSeq( GetAppCollator().listCollatorAlgorithms(
378 LanguageTag( m_xLangLB
->get_active_id()).getLocale() ));
381 m_xColRes
.reset(new CollatorResource
);
383 const int nLstBoxCnt
= 3;
384 weld::ComboBox
* aLstArr
[ nLstBoxCnt
] = { m_xTypDLB1
.get(), m_xTypDLB2
.get(), m_xTypDLB3
.get() };
385 sal_uInt16
* const aTypeArr
[ nLstBoxCnt
] = { &nType1
, &nType2
, &nType3
};
386 OUString aOldStrArr
[ nLstBoxCnt
];
388 for( int n
= 0; n
< nLstBoxCnt
; ++n
)
390 weld::ComboBox
* pL
= aLstArr
[ n
];
391 OUString sUserData
= pL
->get_active_id();
392 if (!sUserData
.isEmpty())
393 aOldStrArr
[ n
] = sUserData
;
397 OUString sAlg
, sUINm
;
398 const sal_Int32 nEnd
= aSeq
.getLength();
399 for( sal_Int32 nCnt
= 0; nCnt
<= nEnd
; ++nCnt
)
404 sUINm
= m_xColRes
->GetTranslation( sAlg
);
407 sUINm
= sAlg
= m_aNumericText
;
409 for( int n
= 0; n
< nLstBoxCnt
; ++n
)
411 weld::ComboBox
* pL
= aLstArr
[ n
];
412 pL
->append(sAlg
, sUINm
);
413 if (pLBox
&& sAlg
== aOldStrArr
[n
])
414 pL
->set_active_id(sAlg
);
418 for( int n
= 0; n
< nLstBoxCnt
; ++n
)
420 weld::ComboBox
* pL
= aLstArr
[ n
];
422 pL
->set_active(*aTypeArr
[n
]);
423 else if (pL
->get_active() == -1)
428 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */