Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / basctl / source / basicide / bastypes.cxx
blob7653875224160f6e196f2c3b73228398abbf5666
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 <strings.hrc>
21 #include <helpids.h>
23 #include "baside2.hxx"
24 #include <baside3.hxx>
25 #include <iderdll.hxx>
26 #include "iderdll2.hxx"
28 #include <basic/basmgr.hxx>
29 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
30 #include <sfx2/dispatch.hxx>
31 #include <sfx2/passwd.hxx>
32 #include <svl/intitem.hxx>
33 #include <svl/stritem.hxx>
34 #include <svl/srchdefs.hxx>
35 #include <vcl/weld.hxx>
37 namespace basctl
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star;
43 BaseWindow::BaseWindow( vcl::Window* pParent, const ScriptDocument& rDocument, const OUString& aLibName, const OUString& aName )
44 :Window( pParent, WinBits( WB_3DLOOK ) )
45 ,m_aDocument( rDocument )
46 ,m_aLibName( aLibName )
47 ,m_aName( aName )
49 pShellHScrollBar = nullptr;
50 pShellVScrollBar = nullptr;
51 nStatus = 0;
54 BaseWindow::~BaseWindow()
56 disposeOnce();
59 void BaseWindow::dispose()
61 if ( pShellVScrollBar )
62 pShellVScrollBar->SetScrollHdl( Link<ScrollBar*,void>() );
63 if ( pShellHScrollBar )
64 pShellHScrollBar->SetScrollHdl( Link<ScrollBar*,void>() );
65 pShellVScrollBar.clear();
66 pShellHScrollBar.clear();
67 vcl::Window::dispose();
71 void BaseWindow::Init()
73 if ( pShellVScrollBar )
74 pShellVScrollBar->SetScrollHdl( LINK( this, BaseWindow, ScrollHdl ) );
75 if ( pShellHScrollBar )
76 pShellHScrollBar->SetScrollHdl( LINK( this, BaseWindow, ScrollHdl ) );
77 DoInit(); // virtual...
81 void BaseWindow::DoInit()
82 { }
85 void BaseWindow::GrabScrollBars( ScrollBar* pHScroll, ScrollBar* pVScroll )
87 pShellHScrollBar = pHScroll;
88 pShellVScrollBar = pVScroll;
89 // Init(); // does not make sense, leads to flickering and errors...
93 IMPL_LINK( BaseWindow, ScrollHdl, ScrollBar *, pCurScrollBar, void )
95 DoScroll( pCurScrollBar );
98 void BaseWindow::ExecuteCommand (SfxRequest&)
99 { }
101 void BaseWindow::ExecuteGlobal (SfxRequest&)
105 bool BaseWindow::EventNotify( NotifyEvent& rNEvt )
107 bool bDone = false;
109 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
111 KeyEvent aKEvt = *rNEvt.GetKeyEvent();
112 vcl::KeyCode aCode = aKEvt.GetKeyCode();
113 sal_uInt16 nCode = aCode.GetCode();
115 switch ( nCode )
117 case KEY_PAGEUP:
118 case KEY_PAGEDOWN:
120 if ( aCode.IsMod1() )
122 if (Shell* pShell = GetShell())
123 pShell->NextPage( nCode == KEY_PAGEUP );
124 bDone = true;
127 break;
131 return bDone || Window::EventNotify( rNEvt );
135 void BaseWindow::DoScroll( ScrollBar* )
140 void BaseWindow::StoreData()
144 bool BaseWindow::CanClose()
146 return true;
149 bool BaseWindow::AllowUndo()
151 return true;
155 void BaseWindow::UpdateData()
159 OUString BaseWindow::GetTitle()
161 return OUString();
164 OUString BaseWindow::CreateQualifiedName()
166 OUString aName;
167 if ( !m_aLibName.isEmpty() )
169 LibraryLocation eLocation = m_aDocument.getLibraryLocation( m_aLibName );
170 aName = m_aDocument.getTitle(eLocation) + "." + m_aLibName + "." +
171 GetTitle();
173 return aName;
176 void BaseWindow::SetReadOnly (bool)
180 bool BaseWindow::IsReadOnly ()
182 return false;
185 void BaseWindow::BasicStarted()
189 void BaseWindow::BasicStopped()
193 bool BaseWindow::IsModified ()
195 return true;
198 ::svl::IUndoManager* BaseWindow::GetUndoManager()
200 return nullptr;
203 SearchOptionFlags BaseWindow::GetSearchOptions()
205 return SearchOptionFlags::NONE;
208 sal_uInt16 BaseWindow::StartSearchAndReplace (SvxSearchItem const&, bool)
210 return 0;
213 void BaseWindow::OnNewDocument ()
216 void BaseWindow::InsertLibInfo () const
218 if (ExtraData* pData = GetExtraData())
219 pData->GetLibInfo().InsertInfo(m_aDocument, m_aLibName, m_aName, GetType());
222 bool BaseWindow::Is (
223 ScriptDocument const& rDocument,
224 OUString const& rLibName, OUString const& rName,
225 ItemType eType, bool bFindSuspended
228 if (bFindSuspended || !IsSuspended())
230 // any non-suspended window is ok
231 if (rLibName.isEmpty() || rName.isEmpty() || eType == TYPE_UNKNOWN)
232 return true;
233 // ok if the parameters match
234 if (m_aDocument == rDocument && m_aLibName == rLibName && m_aName == rName && GetType() == eType)
235 return true;
237 return false;
240 bool BaseWindow::HasActiveEditor () const
242 return false;
246 // DockingWindow
249 // style bits for DockingWindow
250 WinBits const DockingWindow::StyleBits =
251 WB_BORDER | WB_3DLOOK | WB_CLIPCHILDREN |
252 WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_DOCKABLE;
254 DockingWindow::DockingWindow (vcl::Window* pParent) :
255 ::DockingWindow(pParent, StyleBits),
256 pLayout(nullptr),
257 nShowCount(0)
260 DockingWindow::DockingWindow (Layout* pParent) :
261 ::DockingWindow(pParent, StyleBits),
262 pLayout(pParent),
263 nShowCount(0)
266 DockingWindow::~DockingWindow()
268 disposeOnce();
271 void DockingWindow::dispose()
273 pLayout.clear();
274 ::DockingWindow::dispose();
277 // Sets the position and the size of the docking window. This property is saved
278 // when the window is floating. Called by Layout.
279 void DockingWindow::ResizeIfDocking (Point const& rPos, Size const& rSize)
281 tools::Rectangle const rRect(rPos, rSize);
282 if (rRect != aDockingRect)
284 // saving the position and the size
285 aDockingRect = rRect;
286 // resizing if actually docking
287 if (!IsFloatingMode())
288 SetPosSizePixel(rPos, rSize);
291 void DockingWindow::ResizeIfDocking (Size const& rSize)
293 ResizeIfDocking(aDockingRect.TopLeft(), rSize);
296 // Sets the parent Layout window.
297 // The physical parent is set only when the window is docking.
298 void DockingWindow::SetLayoutWindow (Layout* pLayout_)
300 pLayout = pLayout_;
301 if (!IsFloatingMode())
302 SetParent(pLayout);
306 // Increases the "show" reference count.
307 // The window is shown when the reference count is positive.
308 void DockingWindow::Show (bool bShow) // = true
310 if (bShow)
312 if (++nShowCount == 1)
313 ::DockingWindow::Show();
315 else
317 if (--nShowCount == 0)
318 ::DockingWindow::Hide();
322 // Decreases the "show" reference count.
323 // The window is hidden when the reference count reaches zero.
324 void DockingWindow::Hide ()
326 Show(false);
329 bool DockingWindow::Docking( const Point& rPos, tools::Rectangle& rRect )
331 if (aDockingRect.IsInside(rPos))
333 rRect.SetSize(aDockingRect.GetSize());
334 return false; // dock
336 else // adjust old size
338 if (!aFloatingRect.IsEmpty())
339 rRect.SetSize(aFloatingRect.GetSize());
340 return true; // float
344 void DockingWindow::EndDocking( const tools::Rectangle& rRect, bool bFloatMode )
346 if ( bFloatMode )
347 ::DockingWindow::EndDocking( rRect, bFloatMode );
348 else
350 SetFloatingMode(false);
351 DockThis();
355 void DockingWindow::ToggleFloatingMode()
357 if (IsFloatingMode())
359 if (!aFloatingRect.IsEmpty())
360 SetPosSizePixel(
361 GetParent()->ScreenToOutputPixel(aFloatingRect.TopLeft()),
362 aFloatingRect.GetSize()
365 DockThis();
368 bool DockingWindow::PrepareToggleFloatingMode()
370 if (IsFloatingMode())
372 // memorize position and size on the desktop...
373 aFloatingRect = tools::Rectangle(
374 GetParent()->OutputToScreenPixel(GetPosPixel()),
375 GetSizePixel()
378 return true;
381 void DockingWindow::StartDocking()
383 if (IsFloatingMode())
385 aFloatingRect = tools::Rectangle(
386 GetParent()->OutputToScreenPixel(GetPosPixel()),
387 GetSizePixel()
392 void DockingWindow::DockThis ()
394 // resizing when floating -> docking
395 if (!IsFloatingMode())
397 Point const aPos = aDockingRect.TopLeft();
398 Size const aSize = aDockingRect.GetSize();
399 if (aSize != GetSizePixel() || aPos != GetPosPixel())
400 SetPosSizePixel(aPos, aSize);
403 if (pLayout)
405 if (!IsFloatingMode() && GetParent() != pLayout)
406 SetParent(pLayout);
407 pLayout->ArrangeWindows();
411 ExtendedEdit::ExtendedEdit(vcl::Window* pParent, WinBits nStyle)
412 : Edit(pParent, nStyle)
414 aAcc.SetSelectHdl( LINK( this, ExtendedEdit, EditAccHdl ) );
415 Control::SetGetFocusHdl( LINK( this, ExtendedEdit, ImplGetFocusHdl ) );
416 Control::SetLoseFocusHdl( LINK( this, ExtendedEdit, ImplLoseFocusHdl ) );
419 IMPL_LINK_NOARG(ExtendedEdit, ImplGetFocusHdl, Control&, void)
421 Application::InsertAccel( &aAcc );
424 IMPL_LINK_NOARG(ExtendedEdit, ImplLoseFocusHdl, Control&, void)
426 Application::RemoveAccel( &aAcc );
429 IMPL_LINK( ExtendedEdit, EditAccHdl, Accelerator&, rAcc, void )
431 aAccHdl.Call( rAcc );
434 TabBar::TabBar( vcl::Window* pParent ) :
435 ::TabBar( pParent, WinBits( WB_3DLOOK | WB_SCROLL | WB_BORDER | WB_SIZEABLE | WB_DRAG ) )
437 EnableEditMode();
439 SetHelpId( HID_BASICIDE_TABBAR );
442 void TabBar::MouseButtonDown( const MouseEvent& rMEvt )
444 if ( rMEvt.IsLeft() && ( rMEvt.GetClicks() == 2 ) && !IsInEditMode() )
446 if (SfxDispatcher* pDispatcher = GetDispatcher())
447 pDispatcher->Execute( SID_BASICIDE_MODULEDLG );
449 else
451 ::TabBar::MouseButtonDown( rMEvt ); // base class version
455 void TabBar::Command( const CommandEvent& rCEvt )
457 if ( ( rCEvt.GetCommand() == CommandEventId::ContextMenu ) && !IsInEditMode() )
459 Point aPos( rCEvt.IsMouseEvent() ? rCEvt.GetMousePosPixel() : Point(1,1) );
460 if ( rCEvt.IsMouseEvent() ) // select right tab
462 Point aP = PixelToLogic( aPos );
463 MouseEvent aMouseEvent( aP, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT );
464 ::TabBar::MouseButtonDown( aMouseEvent ); // base class
466 if (SfxDispatcher* pDispatcher = GetDispatcher())
467 pDispatcher->ExecutePopup("tabbar", this, &aPos);
471 TabBarAllowRenamingReturnCode TabBar::AllowRenaming()
473 bool const bValid = IsValidSbxName(GetEditText());
475 if ( !bValid )
477 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(),
478 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
479 xError->run();
482 return bValid ? TABBAR_RENAMING_YES : TABBAR_RENAMING_NO;
486 void TabBar::EndRenaming()
488 if ( !IsEditModeCanceled() )
490 SfxUInt16Item aID( SID_BASICIDE_ARG_TABID, GetEditPageId() );
491 SfxStringItem aNewName( SID_BASICIDE_ARG_MODULENAME, GetEditText() );
492 if (SfxDispatcher* pDispatcher = GetDispatcher())
493 pDispatcher->ExecuteList( SID_BASICIDE_NAMECHANGEDONTAB,
494 SfxCallMode::SYNCHRON, { &aID, &aNewName });
499 namespace
502 // helper class for sorting TabBar
503 struct TabBarSortHelper
505 sal_uInt16 nPageId;
506 OUString aPageText;
508 bool operator < (TabBarSortHelper const& rComp) const
510 return aPageText.compareToIgnoreAsciiCase(rComp.aPageText) < 0;
514 } // namespace
516 void TabBar::Sort()
518 if (Shell* pShell = GetShell())
520 Shell::WindowTable& aWindowTable = pShell->GetWindowTable();
521 TabBarSortHelper aTabBarSortHelper;
522 std::vector<TabBarSortHelper> aModuleList;
523 std::vector<TabBarSortHelper> aDialogList;
524 sal_uInt16 nPageCount = GetPageCount();
525 sal_uInt16 i;
527 // create module and dialog lists for sorting
528 for ( i = 0; i < nPageCount; i++)
530 sal_uInt16 nId = GetPageId( i );
531 aTabBarSortHelper.nPageId = nId;
532 aTabBarSortHelper.aPageText = GetPageText( nId );
533 BaseWindow* pWin = aWindowTable[ nId ].get();
535 if (dynamic_cast<ModulWindow*>(pWin))
537 aModuleList.push_back( aTabBarSortHelper );
539 else if (dynamic_cast<DialogWindow*>(pWin))
541 aDialogList.push_back( aTabBarSortHelper );
545 // sort module and dialog lists by page text
546 std::sort( aModuleList.begin() , aModuleList.end() );
547 std::sort( aDialogList.begin() , aDialogList.end() );
550 sal_uInt16 nModules = sal::static_int_cast<sal_uInt16>( aModuleList.size() );
551 sal_uInt16 nDialogs = sal::static_int_cast<sal_uInt16>( aDialogList.size() );
553 // move module pages to new positions
554 for (i = 0; i < nModules; i++)
556 MovePage( aModuleList[i].nPageId , i );
559 // move dialog pages to new positions
560 for (i = 0; i < nDialogs; i++)
562 MovePage( aDialogList[i].nPageId , nModules + i );
567 void CutLines( OUString& rStr, sal_Int32 nStartLine, sal_Int32 nLines )
569 sal_Int32 nStartPos = 0;
570 sal_Int32 nLine = 0;
571 while ( nLine < nStartLine )
573 nStartPos = searchEOL( rStr, nStartPos );
574 if( nStartPos == -1 )
575 break;
576 nStartPos++; // not the \n.
577 nLine++;
580 SAL_WARN_IF( nStartPos == -1, "basctl.basicide", "CutLines: Start line not found!" );
582 if ( nStartPos == -1 )
583 return;
585 sal_Int32 nEndPos = nStartPos;
587 for ( sal_Int32 i = 0; i < nLines; i++ )
588 nEndPos = searchEOL( rStr, nEndPos+1 );
590 if ( nEndPos == -1 ) // might happen at the last line
591 nEndPos = rStr.getLength();
592 else
593 nEndPos++;
595 OUString aEndStr = rStr.copy( nEndPos );
596 rStr = rStr.copy( 0, nStartPos );
597 rStr += aEndStr;
599 // erase trailing empty lines
601 sal_Int32 n = nStartPos;
602 sal_Int32 nLen = rStr.getLength();
603 while ( ( n < nLen ) && ( rStr[ n ] == LINE_SEP ||
604 rStr[ n ] == LINE_SEP_CR ) )
606 n++;
609 if ( n > nStartPos )
611 aEndStr = rStr.copy( n );
612 rStr = rStr.copy( 0, nStartPos );
613 rStr += aEndStr;
618 sal_uInt32 CalcLineCount( SvStream& rStream )
620 sal_uInt32 nLFs = 0;
621 sal_uInt32 nCRs = 0;
622 char c;
624 rStream.Seek( 0 );
625 rStream.ReadChar( c );
626 while ( !rStream.eof() )
628 if ( c == '\n' )
629 nLFs++;
630 else if ( c == '\r' )
631 nCRs++;
632 rStream.ReadChar( c );
635 rStream.Seek( 0 );
636 if ( nLFs > nCRs )
637 return nLFs;
638 return nCRs;
642 // LibInfo
645 LibInfo::LibInfo ()
648 LibInfo::~LibInfo ()
651 void LibInfo::InsertInfo (
652 ScriptDocument const& rDocument,
653 OUString const& rLibName,
654 OUString const& rCurrentName,
655 ItemType eCurrentType
658 Key aKey(rDocument, rLibName);
659 m_aMap.erase(aKey);
660 m_aMap.emplace(aKey, Item(rCurrentName, eCurrentType));
663 void LibInfo::RemoveInfoFor (ScriptDocument const& rDocument)
665 Map::iterator it;
666 for (it = m_aMap.begin(); it != m_aMap.end(); ++it)
667 if (it->first.GetDocument() == rDocument)
668 break;
669 if (it != m_aMap.end())
670 m_aMap.erase(it);
673 LibInfo::Item const* LibInfo::GetInfo (
674 ScriptDocument const& rDocument, OUString const& rLibName
677 Map::iterator it = m_aMap.find(Key(rDocument, rLibName));
678 return it != m_aMap.end() ? &it->second : nullptr;
681 LibInfo::Key::Key (ScriptDocument const& rDocument, OUString const& rLibName) :
682 m_aDocument(rDocument), m_aLibName(rLibName)
685 LibInfo::Key::~Key ()
688 bool LibInfo::Key::operator == (Key const& rKey) const
690 return m_aDocument == rKey.m_aDocument && m_aLibName == rKey.m_aLibName;
693 size_t LibInfo::Key::Hash::operator () (Key const& rKey) const
695 return rKey.m_aDocument.hashCode() + rKey.m_aLibName.hashCode();
698 LibInfo::Item::Item (
699 OUString const& rCurrentName,
700 ItemType eCurrentType
702 m_aCurrentName(rCurrentName),
703 m_eCurrentType(eCurrentType)
706 LibInfo::Item::~Item ()
709 bool QueryDel(const OUString& rName, const OUString &rStr, weld::Widget* pParent)
711 OUStringBuffer aNameBuf( rName );
712 aNameBuf.append('\'');
713 aNameBuf.insert(0, '\'');
714 OUString aQuery = rStr.replaceAll("XX", aNameBuf.makeStringAndClear());
715 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pParent,
716 VclMessageType::Question, VclButtonsType::YesNo, aQuery));
717 return (xQueryBox->run() == RET_YES);
720 bool QueryDelMacro( const OUString& rName, weld::Widget* pParent )
722 return QueryDel( rName, IDEResId( RID_STR_QUERYDELMACRO ), pParent );
725 bool QueryReplaceMacro( const OUString& rName, weld::Widget* pParent )
727 return QueryDel( rName, IDEResId( RID_STR_QUERYREPLACEMACRO ), pParent );
730 bool QueryDelDialog( const OUString& rName, weld::Widget* pParent )
732 return QueryDel( rName, IDEResId( RID_STR_QUERYDELDIALOG ), pParent );
735 bool QueryDelLib( const OUString& rName, bool bRef, weld::Widget* pParent )
737 return QueryDel( rName, IDEResId( bRef ? RID_STR_QUERYDELLIBREF : RID_STR_QUERYDELLIB ), pParent );
740 bool QueryDelModule( const OUString& rName, weld::Widget* pParent )
742 return QueryDel( rName, IDEResId( RID_STR_QUERYDELMODULE ), pParent );
745 bool QueryPassword( const Reference< script::XLibraryContainer >& xLibContainer, const OUString& rLibName, OUString& rPassword, bool bRepeat, bool bNewTitle )
747 bool bOK = false;
748 sal_uInt16 nRet = 0;
752 // password dialog
753 vcl::Window* pWin = Application::GetDefDialogParent();
754 SfxPasswordDialog aDlg(pWin ? pWin->GetFrameWeld() : nullptr);
755 aDlg.SetMinLen(1);
757 // set new title
758 if ( bNewTitle )
760 OUString aTitle(IDEResId(RID_STR_ENTERPASSWORD));
761 aTitle = aTitle.replaceAll("XX", rLibName);
762 aDlg.set_title(aTitle);
765 // execute dialog
766 nRet = aDlg.execute();
768 // verify password
769 if ( nRet == RET_OK )
771 if ( xLibContainer.is() && xLibContainer->hasByName( rLibName ) )
773 Reference< script::XLibraryContainerPassword > xPasswd( xLibContainer, UNO_QUERY );
774 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( rLibName ) && !xPasswd->isLibraryPasswordVerified( rLibName ) )
776 rPassword = aDlg.GetPassword();
777 // OUString aOUPassword( rPassword );
778 bOK = xPasswd->verifyLibraryPassword( rLibName, rPassword );
780 if ( !bOK )
782 vcl::Window* pParent = Application::GetDefDialogParent();
783 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pParent ? pParent->GetFrameWeld() : nullptr,
784 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_WRONGPASSWORD)));
785 xErrorBox->run();
791 while ( bRepeat && !bOK && nRet == RET_OK );
793 return bOK;
797 } // namespace basctl
799 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */