1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #undef SC_DLLIMPLEMENTATION
21 
22 #include <comphelper/string.hxx>
23 #include <tools/lineend.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/weld.hxx>
26 
27 #include <global.hxx>
28 #include <document.hxx>
29 #include <tabvwsh.hxx>
30 #include <viewdata.hxx>
31 #include <uiitems.hxx>
32 #include <userlist.hxx>
33 #include <rangeutl.hxx>
34 #include <crdlg.hxx>
35 #include <sc.hrc>
36 #include <globstr.hrc>
37 #include <scresid.hxx>
38 #include <tpusrlst.hxx>
39 #include <scui_def.hxx>
40 
41 #define CR  u'\x000D'
42 #define LF  u'\x000A'
43 
44 static const sal_Unicode cDelimiter = ',';
45 
46 // Benutzerdefinierte Listen:
47 
ScTpUserLists(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rCoreAttrs)48 ScTpUserLists::ScTpUserLists( weld::Container* pPage, weld::DialogController* pController,
49                               const SfxItemSet&     rCoreAttrs )
50     : SfxTabPage(pPage, pController, "modules/scalc/ui/optsortlists.ui", "OptSortLists",
51                           &rCoreAttrs )
52     , mxFtLists(m_xBuilder->weld_label("listslabel"))
53     , mxLbLists(m_xBuilder->weld_tree_view("lists"))
54     , mxFtEntries(m_xBuilder->weld_label("entrieslabel"))
55     , mxEdEntries(m_xBuilder->weld_text_view("entries"))
56     , mxFtCopyFrom(m_xBuilder->weld_label("copyfromlabel"))
57     , mxEdCopyFrom(m_xBuilder->weld_entry("copyfrom"))
58     , mxBtnNew(m_xBuilder->weld_button("new"))
59     , mxBtnDiscard(m_xBuilder->weld_button("discard"))
60     , mxBtnAdd(m_xBuilder->weld_button("add"))
61     , mxBtnModify(m_xBuilder->weld_button("modify"))
62     , mxBtnRemove(m_xBuilder->weld_button("delete"))
63     , mxBtnCopy(m_xBuilder->weld_button("copy"))
64     , aStrQueryRemove ( ScResId( STR_QUERYREMOVE ) )
65     , aStrCopyList    ( ScResId( STR_COPYLIST ) )
66     , aStrCopyFrom    ( ScResId( STR_COPYFROM ) )
67     , aStrCopyErr     ( ScResId( STR_COPYERR ) )
68     , nWhichUserLists ( GetWhich( SID_SCUSERLISTS ) )
69     , pDoc            ( nullptr )
70     , pViewData       ( nullptr )
71     , bModifyMode     ( false )
72     , bCancelMode     ( false )
73     , bCopyDone       ( false )
74     , nCancelPos      ( 0 )
75 {
76     SetExchangeSupport();
77     Init();
78     Reset(&rCoreAttrs);
79 }
80 
~ScTpUserLists()81 ScTpUserLists::~ScTpUserLists()
82 {
83 }
84 
Init()85 void ScTpUserLists::Init()
86 {
87     SfxViewShell*   pSh = SfxViewShell::Current();
88     ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( pSh );
89 
90     mxLbLists->connect_changed   ( LINK( this, ScTpUserLists, LbSelectHdl ) );
91     mxBtnNew->connect_clicked     ( LINK( this, ScTpUserLists, BtnClickHdl ) );
92     mxBtnDiscard->connect_clicked ( LINK( this, ScTpUserLists, BtnClickHdl ) );
93     mxBtnAdd->connect_clicked     ( LINK( this, ScTpUserLists, BtnClickHdl ) );
94     mxBtnModify->connect_clicked  ( LINK( this, ScTpUserLists, BtnClickHdl ) );
95     mxBtnRemove->connect_clicked  ( LINK( this, ScTpUserLists, BtnClickHdl ) );
96     mxEdEntries->connect_changed ( LINK( this, ScTpUserLists, EdEntriesModHdl ) );
97 
98     if ( pViewSh )
99     {
100         SCTAB   nStartTab   = 0;
101         SCTAB   nEndTab     = 0;
102         SCCOL   nStartCol   = 0;
103         SCROW   nStartRow   = 0;
104         SCCOL   nEndCol     = 0;
105         SCROW   nEndRow     = 0;
106 
107         pViewData = &pViewSh->GetViewData();
108         pDoc = pViewData->GetDocument();
109 
110         pViewData->GetSimpleArea( nStartCol, nStartRow, nStartTab,
111                                   nEndCol,   nEndRow,  nEndTab );
112 
113         PutInOrder( nStartCol, nEndCol );
114         PutInOrder( nStartRow, nEndRow );
115         PutInOrder( nStartTab, nEndTab );
116 
117         aStrSelectedArea = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab
118                 ).Format(ScRefFlags::RANGE_ABS_3D, pDoc);
119 
120         mxBtnCopy->connect_clicked ( LINK( this, ScTpUserLists, BtnClickHdl ) );
121         mxBtnCopy->set_sensitive(true);
122     }
123     else
124     {
125         mxBtnCopy->set_sensitive(false);
126         mxFtCopyFrom->set_sensitive(false);
127         mxEdCopyFrom->set_sensitive(false);
128     }
129 
130 }
131 
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrSet)132 std::unique_ptr<SfxTabPage> ScTpUserLists::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
133 {
134     return std::make_unique<ScTpUserLists>(pPage, pController, *rAttrSet);
135 }
136 
Reset(const SfxItemSet * rCoreAttrs)137 void ScTpUserLists::Reset( const SfxItemSet* rCoreAttrs )
138 {
139     const ScUserListItem& rUserListItem = static_cast<const ScUserListItem&>(
140                                            rCoreAttrs->Get( nWhichUserLists ));
141     const ScUserList*     pCoreList     = rUserListItem.GetUserList();
142 
143     OSL_ENSURE( pCoreList, "UserList not found :-/" );
144 
145     if ( pCoreList )
146     {
147         if ( !pUserLists )
148             pUserLists.reset( new ScUserList( *pCoreList ) );
149         else
150             *pUserLists = *pCoreList;
151 
152         if ( UpdateUserListBox() > 0 )
153         {
154             mxLbLists->select( 0 );
155             UpdateEntries( 0 );
156         }
157     }
158     else if ( !pUserLists )
159         pUserLists.reset( new ScUserList );
160 
161     mxEdCopyFrom->set_text( aStrSelectedArea );
162 
163     if ( mxLbLists->n_children() == 0 )
164     {
165         mxFtLists->set_sensitive(false);
166         mxLbLists->set_sensitive(false);
167         mxFtEntries->set_sensitive(false);
168         mxEdEntries->set_sensitive(false);
169         mxBtnRemove->set_sensitive(false);
170     }
171 
172     mxBtnNew->show();
173     mxBtnDiscard->hide();
174     mxBtnAdd->show();
175     mxBtnModify->hide();
176     mxBtnAdd->set_sensitive(false);
177     mxBtnModify->set_sensitive(false);
178 
179     if ( !bCopyDone && pViewData )
180     {
181         mxFtCopyFrom->set_sensitive(true);
182         mxEdCopyFrom->set_sensitive(true);
183         mxBtnCopy->set_sensitive(true);
184     }
185 }
186 
FillItemSet(SfxItemSet * rCoreAttrs)187 bool ScTpUserLists::FillItemSet( SfxItemSet* rCoreAttrs )
188 {
189     // Changes aren't saved?
190     // -> simulate click of Add-Button
191 
192     if ( bModifyMode || bCancelMode )
193         BtnClickHdl(*mxBtnAdd);
194 
195     const ScUserListItem& rUserListItem = static_cast<const ScUserListItem&>(
196                                            GetItemSet().Get( nWhichUserLists ));
197 
198     ScUserList* pCoreList       = rUserListItem.GetUserList();
199     bool        bDataModified   = false;
200 
201     if ( (pUserLists == nullptr) && (pCoreList == nullptr) )
202     {
203         bDataModified = false;
204     }
205     else if ( pUserLists != nullptr )
206     {
207         if ( pCoreList != nullptr )
208             bDataModified = (*pUserLists != *pCoreList);
209         else
210             bDataModified = true;
211     }
212 
213     if ( bDataModified )
214     {
215         ScUserListItem aULItem( nWhichUserLists );
216 
217         if ( pUserLists )
218             aULItem.SetUserList( *pUserLists );
219 
220         rCoreAttrs->Put( aULItem );
221     }
222 
223     return bDataModified;
224 }
225 
DeactivatePage(SfxItemSet * pSetP)226 DeactivateRC ScTpUserLists::DeactivatePage( SfxItemSet* pSetP )
227 {
228     if ( pSetP )
229         FillItemSet( pSetP );
230 
231     return DeactivateRC::LeavePage;
232 }
233 
UpdateUserListBox()234 size_t ScTpUserLists::UpdateUserListBox()
235 {
236     mxLbLists->clear();
237 
238     if ( !pUserLists ) return 0;
239 
240     size_t nCount = pUserLists->size();
241     OUString  aEntry;
242 
243     for ( size_t i=0; i<nCount; ++i )
244     {
245         aEntry = (*pUserLists)[i].GetString();
246         OSL_ENSURE( !aEntry.isEmpty(), "Empty UserList-entry :-/" );
247         mxLbLists->append_text( aEntry );
248     }
249 
250     return nCount;
251 }
252 
UpdateEntries(size_t nList)253 void ScTpUserLists::UpdateEntries( size_t nList )
254 {
255     if ( !pUserLists ) return;
256 
257     if ( nList < pUserLists->size() )
258     {
259         const ScUserListData& rList = (*pUserLists)[nList];
260         std::size_t nSubCount = rList.GetSubCount();
261         OUStringBuffer aEntryListStr;
262 
263         for ( size_t i=0; i<nSubCount; i++ )
264         {
265             if ( i!=0 )
266                 aEntryListStr.append(CR);
267             aEntryListStr.append(rList.GetSubStr(i));
268         }
269 
270         mxEdEntries->set_text(convertLineEnd(aEntryListStr.makeStringAndClear(), GetSystemLineEnd()));
271     }
272     else
273     {
274         OSL_FAIL( "Invalid ListIndex :-/" );
275     }
276 }
277 
MakeListStr(OUString & rListStr)278 void ScTpUserLists::MakeListStr( OUString& rListStr )
279 {
280     if (rListStr.isEmpty())
281         return;
282 
283     OUStringBuffer aStr;
284 
285     for(sal_Int32 nIdx=0; nIdx>=0;)
286     {
287         aStr.append(comphelper::string::strip(rListStr.getToken(0, LF, nIdx), ' '));
288         aStr.append(cDelimiter);
289     }
290 
291     aStr.strip(cDelimiter);
292     sal_Int32 nLen = aStr.getLength();
293 
294     rListStr.clear();
295 
296     // delete all duplicates of cDelimiter
297     sal_Int32 c = 0;
298     while ( c < nLen )
299     {
300         rListStr += OUStringChar(aStr[c]);
301         ++c;
302 
303         if ((c < nLen) && (aStr[c] == cDelimiter))
304         {
305             rListStr += OUStringChar(aStr[c]);
306 
307             while ((c < nLen) && (aStr[c] == cDelimiter))
308                 ++c;
309         }
310     }
311 
312 }
313 
AddNewList(const OUString & rEntriesStr)314 void ScTpUserLists::AddNewList( const OUString& rEntriesStr )
315 {
316     OUString theEntriesStr( rEntriesStr );
317 
318     if ( !pUserLists )
319         pUserLists.reset( new ScUserList );
320 
321     MakeListStr( theEntriesStr );
322 
323     pUserLists->push_back(new ScUserListData(theEntriesStr));
324 }
325 
CopyListFromArea(const ScRefAddress & rStartPos,const ScRefAddress & rEndPos)326 void ScTpUserLists::CopyListFromArea( const ScRefAddress& rStartPos,
327                                       const ScRefAddress& rEndPos )
328 {
329     if ( bCopyDone ) return;
330 
331     SCTAB   nTab            = rStartPos.Tab();
332     SCCOL   nStartCol       = rStartPos.Col();
333     SCROW   nStartRow       = rStartPos.Row();
334     SCCOL   nEndCol         = rEndPos.Col();
335     SCROW   nEndRow         = rEndPos.Row();
336     sal_uInt16  nCellDir        = SCRET_COLS;
337 
338     if ( (nStartCol != nEndCol) && (nStartRow != nEndRow) )
339     {
340         ScColOrRowDlg aDialog(GetFrameWeld(), aStrCopyList, aStrCopyFrom);
341         nCellDir = aDialog.run();
342     }
343     else if ( nStartCol != nEndCol )
344         nCellDir = SCRET_ROWS;
345     else
346         nCellDir = SCRET_COLS;
347 
348     if ( nCellDir != RET_CANCEL )
349     {
350         bool bValueIgnored = false;
351 
352         if ( nCellDir == SCRET_COLS )
353         {
354             for ( SCCOL col=nStartCol; col<=nEndCol; col++ )
355             {
356                 OUStringBuffer aStrList;
357                 for ( SCROW row=nStartRow; row<=nEndRow; row++ )
358                 {
359                     if ( pDoc->HasStringData( col, row, nTab ) )
360                     {
361                         OUString aStrField = pDoc->GetString(col, row, nTab);
362 
363                         if ( !aStrField.isEmpty() )
364                         {
365                             aStrList.append(aStrField).append("\n");
366                         }
367                     }
368                     else
369                         bValueIgnored = true;
370                 }
371                 if ( !aStrList.isEmpty() )
372                     AddNewList( aStrList.makeStringAndClear() );
373             }
374         }
375         else
376         {
377             for ( SCROW row=nStartRow; row<=nEndRow; row++ )
378             {
379                 OUStringBuffer aStrList;
380                 for ( SCCOL col=nStartCol; col<=nEndCol; col++ )
381                 {
382                     if ( pDoc->HasStringData( col, row, nTab ) )
383                     {
384                         OUString aStrField = pDoc->GetString(col, row, nTab);
385 
386                         if ( !aStrField.isEmpty() )
387                         {
388                             aStrList.append(aStrField).append("\n");
389                         }
390                     }
391                     else
392                         bValueIgnored = true;
393                 }
394                 if ( !aStrList.isEmpty() )
395                     AddNewList( aStrList.makeStringAndClear() );
396             }
397         }
398 
399         if ( bValueIgnored )
400         {
401             std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
402                                                           VclMessageType::Info, VclButtonsType::Ok,
403                                                           aStrCopyErr));
404             xInfoBox->run();
405         }
406     }
407 
408     bCopyDone = true;
409 
410 }
411 
ModifyList(size_t nSelList,const OUString & rEntriesStr)412 void ScTpUserLists::ModifyList( size_t            nSelList,
413                                 const OUString&   rEntriesStr )
414 {
415     if ( !pUserLists ) return;
416 
417     OUString theEntriesStr( rEntriesStr );
418 
419     MakeListStr( theEntriesStr );
420 
421     (*pUserLists)[nSelList].SetString( theEntriesStr );
422 }
423 
RemoveList(size_t nList)424 void ScTpUserLists::RemoveList( size_t nList )
425 {
426     if (pUserLists && nList < pUserLists->size())
427     {
428         ScUserList::iterator itr = pUserLists->begin();
429         ::std::advance(itr, nList);
430         pUserLists->erase(itr);
431     }
432 }
433 
434 // Handler:
435 
IMPL_LINK(ScTpUserLists,LbSelectHdl,weld::TreeView &,rLb,void)436 IMPL_LINK( ScTpUserLists, LbSelectHdl, weld::TreeView&, rLb, void )
437 {
438     if ( &rLb == mxLbLists.get() )
439     {
440         sal_Int32 nSelPos = mxLbLists->get_selected_index();
441         if ( nSelPos != -1 )
442         {
443             if ( !mxFtEntries->get_sensitive() )  mxFtEntries->set_sensitive(true);
444             if ( !mxEdEntries->get_sensitive() )  mxEdEntries->set_sensitive(true);
445             if ( !mxBtnRemove->get_sensitive() )  mxBtnRemove->set_sensitive(true);
446             if ( mxBtnAdd->get_sensitive() )
447             {
448                 mxBtnAdd->set_sensitive(false);
449                 mxBtnModify->set_sensitive(false);
450             }
451 
452             UpdateEntries( nSelPos );
453         }
454     }
455 }
456 
IMPL_LINK(ScTpUserLists,BtnClickHdl,weld::Button &,rBtn,void)457 IMPL_LINK( ScTpUserLists, BtnClickHdl, weld::Button&, rBtn, void )
458 {
459     if (&rBtn == mxBtnNew.get() || &rBtn == mxBtnDiscard.get())
460     {
461         if ( !bCancelMode )
462         {
463             nCancelPos = ( mxLbLists->n_children() > 0 )
464                             ? mxLbLists->get_selected_index()
465                             : 0;
466             mxLbLists->unselect_all();
467             mxFtLists->set_sensitive(false);
468             mxLbLists->set_sensitive(false);
469             mxFtEntries->set_sensitive(true);
470             mxEdEntries->set_sensitive(true);
471             mxEdEntries->set_text( EMPTY_OUSTRING );
472             mxEdEntries->grab_focus();
473             mxBtnAdd->set_sensitive(false);
474             mxBtnModify->set_sensitive(false);
475             mxBtnRemove->set_sensitive(false);
476 
477             if ( mxBtnCopy->get_sensitive() )
478             {
479                 mxBtnCopy->set_sensitive(false);
480                 mxFtCopyFrom->set_sensitive(false);
481                 mxEdCopyFrom->set_sensitive(false);
482             }
483             mxBtnNew->hide();
484             mxBtnDiscard->show();
485             bCancelMode = true;
486         }
487         else // if ( bCancelMode )
488         {
489             if ( mxLbLists->n_children() > 0 )
490             {
491                 mxLbLists->select( nCancelPos );
492                 LbSelectHdl( *mxLbLists );
493                 mxFtLists->set_sensitive(true);
494                 mxLbLists->set_sensitive(true);
495             }
496             else
497             {
498                 mxFtEntries->set_sensitive(false);
499                 mxEdEntries->set_sensitive(false);
500                 mxEdEntries->set_text( EMPTY_OUSTRING );
501                 mxBtnRemove->set_sensitive(false);
502             }
503             mxBtnAdd->set_sensitive(false);
504             mxBtnModify->set_sensitive(false);
505 
506             if ( pViewData && !bCopyDone )
507             {
508                 mxBtnCopy->set_sensitive(true);
509                 mxFtCopyFrom->set_sensitive(true);
510                 mxEdCopyFrom->set_sensitive(true);
511             }
512             mxBtnNew->show();
513             mxBtnDiscard->hide();
514             bCancelMode = false;
515             bModifyMode = false;
516         }
517     }
518     else if (&rBtn == mxBtnAdd.get() || &rBtn == mxBtnModify.get())
519     {
520         OUString theEntriesStr( mxEdEntries->get_text() );
521 
522         if ( !bModifyMode )
523         {
524             if ( !theEntriesStr.isEmpty() )
525             {
526                 AddNewList( theEntriesStr );
527                 UpdateUserListBox();
528                 mxLbLists->select( mxLbLists->n_children()-1 );
529                 LbSelectHdl( *mxLbLists );
530                 mxFtLists->set_sensitive(true);
531                 mxLbLists->set_sensitive(true);
532             }
533             else
534             {
535                 if ( mxLbLists->n_children() > 0 )
536                 {
537                     mxLbLists->select( nCancelPos );
538                     LbSelectHdl( *mxLbLists );
539                     mxLbLists->set_sensitive(true);
540                     mxLbLists->set_sensitive(true);
541                 }
542             }
543 
544             mxBtnAdd->set_sensitive(false);
545             mxBtnModify->set_sensitive(false);
546             mxBtnRemove->set_sensitive(true);
547             mxBtnNew->show();
548             mxBtnDiscard->hide();
549             bCancelMode = false;
550         }
551         else // if ( bModifyMode )
552         {
553             sal_Int32 nSelList = mxLbLists->get_selected_index();
554 
555             OSL_ENSURE( nSelList != -1 , "Modify without List :-/" );
556 
557             if ( !theEntriesStr.isEmpty() )
558             {
559                 ModifyList( nSelList, theEntriesStr );
560                 UpdateUserListBox();
561                 mxLbLists->select( nSelList );
562             }
563             else
564             {
565                 mxLbLists->select( 0 );
566                 LbSelectHdl( *mxLbLists );
567             }
568 
569             mxBtnNew->show();
570             mxBtnDiscard->hide();
571             bCancelMode = false;
572             mxBtnAdd->show();
573             mxBtnModify->show();
574             mxBtnAdd->set_sensitive(false);
575             mxBtnModify->set_sensitive(false);
576             bModifyMode = false;
577             mxBtnRemove->set_sensitive(true);
578             mxFtLists->set_sensitive(true);
579             mxLbLists->set_sensitive(true);
580         }
581 
582         if ( pViewData && !bCopyDone )
583         {
584             mxBtnCopy->set_sensitive(true);
585             mxFtCopyFrom->set_sensitive(true);
586             mxEdCopyFrom->set_sensitive(true);
587         }
588     }
589     else if ( &rBtn == mxBtnRemove.get() )
590     {
591         if ( mxLbLists->n_children() > 0 )
592         {
593             sal_Int32 nRemovePos   = mxLbLists->get_selected_index();
594             OUString aMsg = aStrQueryRemove.getToken( 0, '#' )
595                           + mxLbLists->get_text( nRemovePos )
596                           + aStrQueryRemove.getToken( 1, '#' );
597 
598             std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
599                                                            VclMessageType::Question, VclButtonsType::YesNo,
600                                                            aMsg));
601             xQueryBox->set_default_response(RET_YES);
602 
603             if (RET_YES == xQueryBox->run())
604             {
605                 RemoveList( nRemovePos );
606                 UpdateUserListBox();
607 
608                 if ( mxLbLists->n_children() > 0 )
609                 {
610                     mxLbLists->select(
611                         ( nRemovePos >= mxLbLists->n_children() )
612                             ? mxLbLists->n_children()-1
613                             : nRemovePos );
614                     LbSelectHdl( *mxLbLists );
615                 }
616                 else
617                 {
618                     mxFtLists->set_sensitive(false);
619                     mxLbLists->set_sensitive(false);
620                     mxFtEntries->set_sensitive(false);
621                     mxEdEntries->set_sensitive(false);
622                     mxEdEntries->set_text( EMPTY_OUSTRING );
623                     mxBtnRemove->set_sensitive(false);
624                 }
625             }
626 
627             if ( pViewData && !bCopyDone && !mxBtnCopy->get_sensitive() )
628             {
629                 mxBtnCopy->set_sensitive(true);
630                 mxFtCopyFrom->set_sensitive(true);
631                 mxEdCopyFrom->set_sensitive(true);
632             }
633         }
634     }
635     else if ( pViewData && (&rBtn == mxBtnCopy.get()) )
636     {
637         if ( bCopyDone )
638             return;
639 
640         ScRefAddress theStartPos;
641         ScRefAddress theEndPos;
642         OUString     theAreaStr( mxEdCopyFrom->get_text() );
643         bool     bAreaOk = false;
644 
645         if ( !theAreaStr.isEmpty() )
646         {
647             bAreaOk = ScRangeUtil::IsAbsArea( theAreaStr,
648                                              pDoc,
649                                              pViewData->GetTabNo(),
650                                              &theAreaStr,
651                                              &theStartPos,
652                                              &theEndPos,
653                                              pDoc->GetAddressConvention() );
654             if ( !bAreaOk )
655             {
656                 bAreaOk = ScRangeUtil::IsAbsPos(  theAreaStr,
657                                                  pDoc,
658                                                  pViewData->GetTabNo(),
659                                                  &theAreaStr,
660                                                  &theStartPos,
661                                                  pDoc->GetAddressConvention() );
662                 theEndPos = theStartPos;
663             }
664         }
665 
666         if ( bAreaOk )
667         {
668             CopyListFromArea( theStartPos, theEndPos );
669             UpdateUserListBox();
670             mxLbLists->select( mxLbLists->n_children()-1 );
671             LbSelectHdl( *mxLbLists );
672             mxEdCopyFrom->set_text( theAreaStr );
673             mxEdCopyFrom->set_sensitive(false);
674             mxBtnCopy->set_sensitive(false);
675             mxFtCopyFrom->set_sensitive(false);
676         }
677         else
678         {
679             std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
680                         VclMessageType::Warning, VclButtonsType::Ok,
681                         ScResId(STR_INVALID_TABREF)));
682 
683             xBox->run();
684             mxEdCopyFrom->grab_focus();
685             mxEdCopyFrom->select_region(0, -1);
686         }
687     }
688 }
689 
IMPL_LINK(ScTpUserLists,EdEntriesModHdl,weld::TextView &,rEd,void)690 IMPL_LINK( ScTpUserLists, EdEntriesModHdl, weld::TextView&, rEd, void )
691 {
692     if ( &rEd != mxEdEntries.get() )
693         return;
694 
695     if ( mxBtnCopy->get_sensitive() )
696     {
697         mxBtnCopy->set_sensitive(false);
698         mxFtCopyFrom->set_sensitive(false);
699         mxEdCopyFrom->set_sensitive(false);
700     }
701 
702     if ( !mxEdEntries->get_text().isEmpty() )
703     {
704         if ( !bCancelMode && !bModifyMode )
705         {
706             mxBtnNew->hide();
707             mxBtnDiscard->show();
708             bCancelMode = true;
709             mxBtnAdd->hide();
710             mxBtnAdd->set_sensitive(true);
711             mxBtnModify->show();
712             mxBtnModify->set_sensitive(true);
713             bModifyMode = true;
714             mxBtnRemove->set_sensitive(false);
715             mxFtLists->set_sensitive(false);
716             mxLbLists->set_sensitive(false);
717         }
718         else // if ( bCancelMode || bModifyMode )
719         {
720             if ( !mxBtnAdd->get_sensitive() )
721             {
722                 mxBtnAdd->set_sensitive(true);
723                 mxBtnModify->set_sensitive(true);
724             }
725         }
726     }
727     else
728     {
729         if ( mxBtnAdd->get_sensitive() )
730         {
731             mxBtnAdd->set_sensitive(false);
732             mxBtnModify->set_sensitive(false);
733         }
734     }
735 }
736 
737 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
738