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 <strings.hrc>
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>
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
)
49 pShellHScrollBar
= nullptr;
50 pShellVScrollBar
= nullptr;
54 BaseWindow::~BaseWindow()
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()
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
&)
101 void BaseWindow::ExecuteGlobal (SfxRequest
&)
105 bool BaseWindow::EventNotify( NotifyEvent
& rNEvt
)
109 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
111 KeyEvent aKEvt
= *rNEvt
.GetKeyEvent();
112 vcl::KeyCode aCode
= aKEvt
.GetKeyCode();
113 sal_uInt16 nCode
= aCode
.GetCode();
120 if ( aCode
.IsMod1() )
122 if (Shell
* pShell
= GetShell())
123 pShell
->NextPage( nCode
== KEY_PAGEUP
);
131 return bDone
|| Window::EventNotify( rNEvt
);
135 void BaseWindow::DoScroll( ScrollBar
* )
140 void BaseWindow::StoreData()
144 bool BaseWindow::CanClose()
149 bool BaseWindow::AllowUndo()
155 void BaseWindow::UpdateData()
159 OUString
BaseWindow::GetTitle()
164 OUString
BaseWindow::CreateQualifiedName()
167 if ( !m_aLibName
.isEmpty() )
169 LibraryLocation eLocation
= m_aDocument
.getLibraryLocation( m_aLibName
);
170 aName
= m_aDocument
.getTitle(eLocation
) + "." + m_aLibName
+ "." +
176 void BaseWindow::SetReadOnly (bool)
180 bool BaseWindow::IsReadOnly ()
185 void BaseWindow::BasicStarted()
189 void BaseWindow::BasicStopped()
193 bool BaseWindow::IsModified ()
198 ::svl::IUndoManager
* BaseWindow::GetUndoManager()
203 SearchOptionFlags
BaseWindow::GetSearchOptions()
205 return SearchOptionFlags::NONE
;
208 sal_uInt16
BaseWindow::StartSearchAndReplace (SvxSearchItem
const&, bool)
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
)
233 // ok if the parameters match
234 if (m_aDocument
== rDocument
&& m_aLibName
== rLibName
&& m_aName
== rName
&& GetType() == eType
)
240 bool BaseWindow::HasActiveEditor () const
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
),
260 DockingWindow::DockingWindow (Layout
* pParent
) :
261 ::DockingWindow(pParent
, StyleBits
),
266 DockingWindow::~DockingWindow()
271 void DockingWindow::dispose()
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_
)
301 if (!IsFloatingMode())
306 // Increases the "show" reference count.
307 // The window is shown when the reference count is positive.
308 void DockingWindow::Show (bool bShow
) // = true
312 if (++nShowCount
== 1)
313 ::DockingWindow::Show();
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 ()
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
)
347 ::DockingWindow::EndDocking( rRect
, bFloatMode
);
350 SetFloatingMode(false);
355 void DockingWindow::ToggleFloatingMode()
357 if (IsFloatingMode())
359 if (!aFloatingRect
.IsEmpty())
361 GetParent()->ScreenToOutputPixel(aFloatingRect
.TopLeft()),
362 aFloatingRect
.GetSize()
368 bool DockingWindow::PrepareToggleFloatingMode()
370 if (IsFloatingMode())
372 // memorize position and size on the desktop...
373 aFloatingRect
= tools::Rectangle(
374 GetParent()->OutputToScreenPixel(GetPosPixel()),
381 void DockingWindow::StartDocking()
383 if (IsFloatingMode())
385 aFloatingRect
= tools::Rectangle(
386 GetParent()->OutputToScreenPixel(GetPosPixel()),
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
);
405 if (!IsFloatingMode() && GetParent() != 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
) )
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
);
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());
477 std::unique_ptr
<weld::MessageDialog
> xError(Application::CreateMessageDialog(GetFrameWeld(),
478 VclMessageType::Warning
, VclButtonsType::Ok
, IDEResId(RID_STR_BADSBXNAME
)));
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
});
502 // helper class for sorting TabBar
503 struct TabBarSortHelper
508 bool operator < (TabBarSortHelper
const& rComp
) const
510 return aPageText
.compareToIgnoreAsciiCase(rComp
.aPageText
) < 0;
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();
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;
571 while ( nLine
< nStartLine
)
573 nStartPos
= searchEOL( rStr
, nStartPos
);
574 if( nStartPos
== -1 )
576 nStartPos
++; // not the \n.
580 SAL_WARN_IF( nStartPos
== -1, "basctl.basicide", "CutLines: Start line not found!" );
582 if ( nStartPos
== -1 )
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();
595 OUString aEndStr
= rStr
.copy( nEndPos
);
596 rStr
= rStr
.copy( 0, nStartPos
);
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
) )
611 aEndStr
= rStr
.copy( n
);
612 rStr
= rStr
.copy( 0, nStartPos
);
618 sal_uInt32
CalcLineCount( SvStream
& rStream
)
625 rStream
.ReadChar( c
);
626 while ( !rStream
.eof() )
630 else if ( c
== '\r' )
632 rStream
.ReadChar( c
);
651 void LibInfo::InsertInfo (
652 ScriptDocument
const& rDocument
,
653 OUString
const& rLibName
,
654 OUString
const& rCurrentName
,
655 ItemType eCurrentType
658 Key
aKey(rDocument
, rLibName
);
660 m_aMap
.emplace(aKey
, Item(rCurrentName
, eCurrentType
));
663 void LibInfo::RemoveInfoFor (ScriptDocument
const& rDocument
)
666 for (it
= m_aMap
.begin(); it
!= m_aMap
.end(); ++it
)
667 if (it
->first
.GetDocument() == rDocument
)
669 if (it
!= m_aMap
.end())
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
)
753 vcl::Window
* pWin
= Application::GetDefDialogParent();
754 SfxPasswordDialog
aDlg(pWin
? pWin
->GetFrameWeld() : nullptr);
760 OUString
aTitle(IDEResId(RID_STR_ENTERPASSWORD
));
761 aTitle
= aTitle
.replaceAll("XX", rLibName
);
762 aDlg
.set_title(aTitle
);
766 nRet
= aDlg
.execute();
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
);
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
)));
791 while ( bRepeat
&& !bOK
&& nRet
== RET_OK
);
797 } // namespace basctl
799 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */