diff options
Diffstat (limited to 'basctl/source/basicide/baside3.cxx')
-rw-r--r-- | basctl/source/basicide/baside3.cxx | 1383 |
1 files changed, 1383 insertions, 0 deletions
diff --git a/basctl/source/basicide/baside3.cxx b/basctl/source/basicide/baside3.cxx new file mode 100644 index 000000000..1424573b0 --- /dev/null +++ b/basctl/source/basicide/baside3.cxx @@ -0,0 +1,1383 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <strings.hrc> +#include <helpids.h> +#include <iderid.hxx> + +#include <accessibledialogwindow.hxx> +#include <baside3.hxx> +#include <basidesh.hxx> +#include <bastype2.hxx> +#include <basobj.hxx> +#include <dlged.hxx> +#include <dlgeddef.hxx> +#include <dlgedmod.hxx> +#include <dlgedview.hxx> +#include <iderdll.hxx> +#include <localizationmgr.hxx> +#include <managelang.hxx> + +#include <com/sun/star/script/XLibraryContainer2.hpp> +#include <com/sun/star/resource/StringResourceWithLocation.hpp> +#include <com/sun/star/ucb/SimpleFileAccess.hpp> +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker3.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#include <comphelper/processfactory.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/filedlghelper.hxx> +#include <sfx2/request.hxx> +#include <sfx2/viewfrm.hxx> +#include <svl/visitem.hxx> +#include <svl/whiter.hxx> +#include <svx/svdundo.hxx> +#include <svx/svxids.hrc> +#include <tools/diagnose_ex.h> +#include <tools/urlobj.hxx> +#include <vcl/commandevent.hxx> +#include <vcl/weld.hxx> +#include <vcl/settings.hxx> +#include <vcl/stdtext.hxx> +#include <vcl/svapp.hxx> +#include <xmlscript/xmldlg_imexp.hxx> + +namespace basctl +{ + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::resource; +using namespace ::com::sun::star::ui::dialogs; + +#ifdef _WIN32 +OUStringLiteral const FilterMask_All = u"*.*"; +#else +constexpr OUStringLiteral FilterMask_All = u"*"; +#endif + +DialogWindow::DialogWindow(DialogWindowLayout* pParent, ScriptDocument const& rDocument, + const OUString& aLibName, const OUString& aName, + css::uno::Reference<css::container::XNameContainer> const& xDialogModel) + : BaseWindow(pParent, rDocument, aLibName, aName) + ,m_rLayout(*pParent) + ,m_pEditor(new DlgEditor(*this, m_rLayout, rDocument.isDocument() + ? rDocument.getDocument() + : Reference<frame::XModel>(), xDialogModel)) + ,m_pUndoMgr(new SfxUndoManager) + ,m_nControlSlotId(SID_INSERT_SELECT) +{ + InitSettings(); + + m_pEditor->GetModel().SetNotifyUndoActionHdl( + &DialogWindow::NotifyUndoActionHdl + ); + + SetHelpId( HID_BASICIDE_DIALOGWINDOW ); + + // set readonly mode for readonly libraries + Reference< script::XLibraryContainer2 > xDlgLibContainer( GetDocument().getLibraryContainer( E_DIALOGS ), UNO_QUERY ); + if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) + SetReadOnly(true); + + if ( rDocument.isDocument() && rDocument.isReadOnly() ) + SetReadOnly(true); +} + +void DialogWindow::dispose() +{ + m_pEditor.reset(); + BaseWindow::dispose(); +} + +void DialogWindow::LoseFocus() +{ + if ( IsModified() ) + StoreData(); + + Window::LoseFocus(); +} + +void DialogWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) +{ + m_pEditor->Paint(rRenderContext, rRect); +} + +void DialogWindow::Resize() +{ + if (GetHScrollBar() && GetVScrollBar()) + { + m_pEditor->SetScrollBars( GetHScrollBar(), GetVScrollBar() ); + } +} + +void DialogWindow::MouseButtonDown( const MouseEvent& rMEvt ) +{ + m_pEditor->MouseButtonDown( rMEvt ); + + if (SfxBindings* pBindings = GetBindingsPtr()) + pBindings->Invalidate( SID_SHOW_PROPERTYBROWSER ); +} + +void DialogWindow::MouseButtonUp( const MouseEvent& rMEvt ) +{ + m_pEditor->MouseButtonUp( rMEvt ); + if( (m_pEditor->GetMode() == DlgEditor::INSERT) && !m_pEditor->IsCreateOK() ) + { + m_nControlSlotId = SID_INSERT_SELECT; + m_pEditor->SetMode( DlgEditor::SELECT ); + Shell::InvalidateControlSlots(); + } + if (SfxBindings* pBindings = GetBindingsPtr()) + { + pBindings->Invalidate( SID_SHOW_PROPERTYBROWSER ); + pBindings->Invalidate( SID_DOC_MODIFIED ); + pBindings->Invalidate( SID_SAVEDOC ); + pBindings->Invalidate( SID_COPY ); + pBindings->Invalidate( SID_CUT ); + } +} + +void DialogWindow::MouseMove( const MouseEvent& rMEvt ) +{ + m_pEditor->MouseMove( rMEvt ); +} + +void DialogWindow::KeyInput( const KeyEvent& rKEvt ) +{ + SfxBindings* pBindings = GetBindingsPtr(); + + if( rKEvt.GetKeyCode() == KEY_BACKSPACE ) + { + if (SfxDispatcher* pDispatcher = GetDispatcher()) + pDispatcher->Execute( SID_BACKSPACE ); + } + else + { + if( pBindings && rKEvt.GetKeyCode() == KEY_TAB ) + pBindings->Invalidate( SID_SHOW_PROPERTYBROWSER ); + + if( !m_pEditor->KeyInput( rKEvt ) ) + { + if( !SfxViewShell::Current()->KeyInput( rKEvt ) ) + Window::KeyInput( rKEvt ); + } + } + + // may be KEY_TAB, KEY_BACKSPACE, KEY_ESCAPE + if( pBindings ) + { + pBindings->Invalidate( SID_COPY ); + pBindings->Invalidate( SID_CUT ); + } +} + +void DialogWindow::Command( const CommandEvent& rCEvt ) +{ + if ( ( rCEvt.GetCommand() == CommandEventId::Wheel ) || + ( rCEvt.GetCommand() == CommandEventId::StartAutoScroll ) || + ( rCEvt.GetCommand() == CommandEventId::AutoScroll ) ) + { + HandleScrollCommand( rCEvt, GetHScrollBar(), GetVScrollBar() ); + } + else if ( rCEvt.GetCommand() == CommandEventId::ContextMenu ) + { + if (GetDispatcher()) + { + SdrView& rView = GetView(); + if( !rCEvt.IsMouseEvent() && rView.AreObjectsMarked() ) + { + tools::Rectangle aMarkedRect( rView.GetMarkedRect() ); + Point MarkedCenter( aMarkedRect.Center() ); + Point PosPixel( LogicToPixel( MarkedCenter ) ); + SfxDispatcher::ExecutePopup( this, &PosPixel ); + } + else + { + SfxDispatcher::ExecutePopup(); + } + + } + } + else + BaseWindow::Command( rCEvt ); +} + + +void DialogWindow::NotifyUndoActionHdl( std::unique_ptr<SdrUndoAction> ) +{ + // #i120515# pUndoAction needs to be deleted, this hand over is an ownership + // change. As long as it does not get added to the undo manager, it needs at + // least to be deleted. +} + +void DialogWindow::DoInit() +{ + GetHScrollBar()->Show(); + GetVScrollBar()->Show(); + m_pEditor->SetScrollBars( GetHScrollBar(), GetVScrollBar() ); +} + +void DialogWindow::DoScroll( ScrollBar* ) +{ + m_pEditor->DoScroll(); +} + +void DialogWindow::GetState( SfxItemSet& rSet ) +{ + SfxWhichIter aIter(rSet); + bool bIsCalc = false; + if ( GetDocument().isDocument() ) + { + Reference< frame::XModel > xModel= GetDocument().getDocument(); + if ( xModel.is() ) + { + Reference< lang::XServiceInfo > xServiceInfo ( xModel, UNO_QUERY ); + if ( xServiceInfo.is() && xServiceInfo->supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) ) + bIsCalc = true; + } + } + + for ( sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich() ) + { + switch ( nWh ) + { + case SID_PASTE: + { + if ( !IsPasteAllowed() ) + rSet.DisableItem( nWh ); + + if ( IsReadOnly() ) + rSet.DisableItem( nWh ); + } + break; + case SID_COPY: + { + // any object selected? + if ( !m_pEditor->GetView().AreObjectsMarked() ) + rSet.DisableItem( nWh ); + } + break; + case SID_CUT: + case SID_DELETE: + case SID_BACKSPACE: + { + // any object selected? + if ( !m_pEditor->GetView().AreObjectsMarked() ) + rSet.DisableItem( nWh ); + + if ( IsReadOnly() ) + rSet.DisableItem( nWh ); + } + break; + case SID_REDO: + { + if ( !m_pUndoMgr->GetUndoActionCount() ) + rSet.DisableItem( nWh ); + } + break; + + case SID_DIALOG_TESTMODE: + { + // is the IDE still active? + bool const bBool = GetShell()->GetFrame() && + m_pEditor->GetMode() == DlgEditor::TEST; + rSet.Put(SfxBoolItem(SID_DIALOG_TESTMODE, bBool)); + } + break; + + case SID_CHOOSE_CONTROLS: + { + if ( IsReadOnly() ) + rSet.DisableItem( nWh ); + } + break; + + case SID_SHOW_PROPERTYBROWSER: + { + Shell* pShell = GetShell(); + SfxViewFrame* pViewFrame = pShell ? pShell->GetViewFrame() : nullptr; + if ( pViewFrame && !pViewFrame->HasChildWindow( SID_SHOW_PROPERTYBROWSER ) && !m_pEditor->GetView().AreObjectsMarked() ) + rSet.DisableItem( nWh ); + + if ( IsReadOnly() ) + rSet.DisableItem( nWh ); + } + break; + case SID_INSERT_FORM_RADIO: + case SID_INSERT_FORM_CHECK: + case SID_INSERT_FORM_LIST: + case SID_INSERT_FORM_COMBO: + case SID_INSERT_FORM_VSCROLL: + case SID_INSERT_FORM_HSCROLL: + case SID_INSERT_FORM_SPIN: + { + if ( !bIsCalc || IsReadOnly() ) + rSet.DisableItem( nWh ); + else + rSet.Put( SfxBoolItem( nWh, m_nControlSlotId == nWh ) ); + } + break; + + case SID_INSERT_SELECT: + case SID_INSERT_PUSHBUTTON: + case SID_INSERT_RADIOBUTTON: + case SID_INSERT_CHECKBOX: + case SID_INSERT_LISTBOX: + case SID_INSERT_COMBOBOX: + case SID_INSERT_GROUPBOX: + case SID_INSERT_EDIT: + case SID_INSERT_FIXEDTEXT: + case SID_INSERT_IMAGECONTROL: + case SID_INSERT_PROGRESSBAR: + case SID_INSERT_HSCROLLBAR: + case SID_INSERT_VSCROLLBAR: + case SID_INSERT_HFIXEDLINE: + case SID_INSERT_VFIXEDLINE: + case SID_INSERT_DATEFIELD: + case SID_INSERT_TIMEFIELD: + case SID_INSERT_NUMERICFIELD: + case SID_INSERT_CURRENCYFIELD: + case SID_INSERT_FORMATTEDFIELD: + case SID_INSERT_PATTERNFIELD: + case SID_INSERT_FILECONTROL: + case SID_INSERT_SPINBUTTON: + case SID_INSERT_GRIDCONTROL: + case SID_INSERT_HYPERLINKCONTROL: + case SID_INSERT_TREECONTROL: + { + if ( IsReadOnly() ) + rSet.DisableItem( nWh ); + else + rSet.Put( SfxBoolItem( nWh, m_nControlSlotId == nWh ) ); + } + break; + case SID_SHOWLINES: + { + // if this is not a module window hide the + // setting, doesn't make sense for example if the + // dialog editor is open + rSet.DisableItem(nWh); + rSet.Put(SfxVisibilityItem(nWh, false)); + break; + } + case SID_SELECTALL: + { + rSet.DisableItem( nWh ); + } + break; + } + } +} + +void DialogWindow::ExecuteCommand( SfxRequest& rReq ) +{ + const sal_uInt16 nSlotId(rReq.GetSlot()); + SdrObjKind nInsertObj(SdrObjKind::NONE); + + switch ( nSlotId ) + { + case SID_CUT: + if ( !IsReadOnly() ) + { + GetEditor().Cut(); + if (SfxBindings* pBindings = GetBindingsPtr()) + pBindings->Invalidate( SID_DOC_MODIFIED ); + } + break; + case SID_DELETE: + if ( !IsReadOnly() ) + { + GetEditor().Delete(); + if (SfxBindings* pBindings = GetBindingsPtr()) + pBindings->Invalidate( SID_DOC_MODIFIED ); + } + break; + case SID_COPY: + GetEditor().Copy(); + break; + case SID_PASTE: + if ( !IsReadOnly() ) + { + GetEditor().Paste(); + if (SfxBindings* pBindings = GetBindingsPtr()) + pBindings->Invalidate( SID_DOC_MODIFIED ); + } + break; + + case SID_INSERT_FORM_RADIO: + nInsertObj = SdrObjKind::BasicDialogFormRadio; + break; + case SID_INSERT_FORM_CHECK: + nInsertObj = SdrObjKind::BasicDialogFormCheck; + break; + case SID_INSERT_FORM_LIST: + nInsertObj = SdrObjKind::BasicDialogFormList; + break; + case SID_INSERT_FORM_COMBO: + nInsertObj = SdrObjKind::BasicDialogFormCombo; + break; + case SID_INSERT_FORM_SPIN: + nInsertObj = SdrObjKind::BasicDialogFormSpin; + break; + case SID_INSERT_FORM_VSCROLL: + nInsertObj = SdrObjKind::BasicDialogFormVerticalScroll; + break; + case SID_INSERT_FORM_HSCROLL: + nInsertObj = SdrObjKind::BasicDialogFormHorizontalScroll; + break; + case SID_INSERT_PUSHBUTTON: + nInsertObj = SdrObjKind::BasicDialogPushButton; + break; + case SID_INSERT_RADIOBUTTON: + nInsertObj = SdrObjKind::BasicDialogRadioButton; + break; + case SID_INSERT_CHECKBOX: + nInsertObj = SdrObjKind::BasicDialogCheckbox; + break; + case SID_INSERT_LISTBOX: + nInsertObj = SdrObjKind::BasicDialogListbox; + break; + case SID_INSERT_COMBOBOX: + nInsertObj = SdrObjKind::BasicDialogCombobox; + break; + case SID_INSERT_GROUPBOX: + nInsertObj = SdrObjKind::BasicDialogGroupBox; + break; + case SID_INSERT_EDIT: + nInsertObj = SdrObjKind::BasicDialogEdit; + break; + case SID_INSERT_FIXEDTEXT: + nInsertObj = SdrObjKind::BasicDialogFixedText; + break; + case SID_INSERT_IMAGECONTROL: + nInsertObj = SdrObjKind::BasicDialogImageControl; + break; + case SID_INSERT_PROGRESSBAR: + nInsertObj = SdrObjKind::BasicDialogProgressbar; + break; + case SID_INSERT_HSCROLLBAR: + nInsertObj = SdrObjKind::BasicDialogHorizontalScrollbar; + break; + case SID_INSERT_VSCROLLBAR: + nInsertObj = SdrObjKind::BasicDialogVerticalScrollbar; + break; + case SID_INSERT_HFIXEDLINE: + nInsertObj = SdrObjKind::BasicDialogHorizontalFixedLine; + break; + case SID_INSERT_VFIXEDLINE: + nInsertObj = SdrObjKind::BasicDialogVerticalFixedLine; + break; + case SID_INSERT_DATEFIELD: + nInsertObj = SdrObjKind::BasicDialogDateField; + break; + case SID_INSERT_TIMEFIELD: + nInsertObj = SdrObjKind::BasicDialogTimeField; + break; + case SID_INSERT_NUMERICFIELD: + nInsertObj = SdrObjKind::BasicDialogNumericField; + break; + case SID_INSERT_CURRENCYFIELD: + nInsertObj = SdrObjKind::BasicDialogCurencyField; + break; + case SID_INSERT_FORMATTEDFIELD: + nInsertObj = SdrObjKind::BasicDialogFormattedField; + break; + case SID_INSERT_PATTERNFIELD: + nInsertObj = SdrObjKind::BasicDialogPatternField; + break; + case SID_INSERT_FILECONTROL: + nInsertObj = SdrObjKind::BasicDialogFileControl; + break; + case SID_INSERT_SPINBUTTON: + nInsertObj = SdrObjKind::BasicDialogSpinButton; + break; + case SID_INSERT_GRIDCONTROL: + nInsertObj = SdrObjKind::BasicDialogGridControl; + break; + case SID_INSERT_HYPERLINKCONTROL: + nInsertObj = SdrObjKind::BasicDialogHyperlinkControl; + break; + case SID_INSERT_TREECONTROL: + nInsertObj = SdrObjKind::BasicDialogTreeControl; + break; + case SID_INSERT_SELECT: + m_nControlSlotId = nSlotId; + GetEditor().SetMode( DlgEditor::SELECT ); + Shell::InvalidateControlSlots(); + break; + + case SID_DIALOG_TESTMODE: + { + DlgEditor::Mode eOldMode = GetEditor().GetMode(); + GetEditor().SetMode( DlgEditor::TEST ); + GetEditor().SetMode( eOldMode ); + rReq.Done(); + if (SfxBindings* pBindings = GetBindingsPtr()) + pBindings->Invalidate( SID_DIALOG_TESTMODE ); + return; + } + case SID_EXPORT_DIALOG: + SaveDialog(); + break; + + case SID_IMPORT_DIALOG: + ImportDialog(); + break; + + case SID_BASICIDE_DELETECURRENT: + if (QueryDelDialog(m_aName, GetFrameWeld())) + { + if (RemoveDialog(m_aDocument, m_aLibName, m_aName)) + { + MarkDocumentModified(m_aDocument); + GetShell()->RemoveWindow(this, true); + } + } + break; + } + + if ( nInsertObj != SdrObjKind::NONE ) + { + m_nControlSlotId = nSlotId; + GetEditor().SetMode( DlgEditor::INSERT ); + GetEditor().SetInsertObj( nInsertObj ); + + if ( rReq.GetModifier() & KEY_MOD1 ) + { + GetEditor().CreateDefaultObject(); + if (SfxBindings* pBindings = GetBindingsPtr()) + pBindings->Invalidate( SID_DOC_MODIFIED ); + } + + Shell::InvalidateControlSlots(); + } + + rReq.Done(); +} + +Reference< container::XNameContainer > const & DialogWindow::GetDialog() const +{ + return m_pEditor->GetDialog(); +} + +bool DialogWindow::RenameDialog( const OUString& rNewName ) +{ + if (!basctl::RenameDialog(GetFrameWeld(), GetDocument(), GetLibName(), GetName(), rNewName)) + return false; + + if (SfxBindings* pBindings = GetBindingsPtr()) + pBindings->Invalidate( SID_DOC_MODIFIED ); + + return true; +} + +void DialogWindow::DisableBrowser() +{ + m_rLayout.DisablePropertyBrowser(); +} + +void DialogWindow::UpdateBrowser() +{ + m_rLayout.UpdatePropertyBrowser(); +} + +void DialogWindow::SaveDialog() +{ + Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext()); + sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD, + FileDialogFlags::NONE, this->GetFrameWeld()); + aDlg.SetContext(sfx2::FileDialogHelper::BasicExportDialog); + Reference<XFilePicker3> xFP = aDlg.GetFilePicker(); + + Reference< XFilePickerControlAccess > xFPControl(xFP, UNO_QUERY); + xFPControl->enableControl(ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, false); + Any aValue; + aValue <<= true; + xFPControl->setValue(ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue); + + xFP->setDefaultName( GetName() ); + + OUString aDialogStr(IDEResId(RID_STR_STDDIALOGNAME)); + xFP->appendFilter( aDialogStr, "*.xdl" ); + xFP->appendFilter( IDEResId(RID_STR_FILTER_ALLFILES), FilterMask_All ); + xFP->setCurrentFilter( aDialogStr ); + + if( aDlg.Execute() != ERRCODE_NONE ) + return; + + Sequence< OUString > aPaths = xFP->getSelectedFiles(); + + // export dialog model to xml + Reference< container::XNameContainer > xDialogModel = GetDialog(); + Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, GetDocument().isDocument() ? GetDocument().getDocument() : Reference< frame::XModel >() ); + Reference< XInputStream > xInput( xISP->createInputStream() ); + + Reference< XSimpleFileAccess3 > xSFI( SimpleFileAccess::create(xContext) ); + + Reference< XOutputStream > xOutput; + try + { + if( xSFI->exists( aPaths[0] ) ) + xSFI->kill( aPaths[0] ); + xOutput = xSFI->openFileWrite( aPaths[0] ); + } + catch(const Exception& ) + {} + + if( xOutput.is() ) + { + Sequence< sal_Int8 > bytes; + sal_Int32 nRead = xInput->readBytes( bytes, xInput->available() ); + for (;;) + { + if( nRead ) + xOutput->writeBytes( bytes ); + + nRead = xInput->readBytes( bytes, 1024 ); + if (! nRead) + break; + } + + // With resource? + Reference< beans::XPropertySet > xDialogModelPropSet( xDialogModel, UNO_QUERY ); + Reference< resource::XStringResourceResolver > xStringResourceResolver; + if( xDialogModelPropSet.is() ) + { + try + { + Any aResourceResolver = xDialogModelPropSet->getPropertyValue( "ResourceResolver" ); + aResourceResolver >>= xStringResourceResolver; + } + catch(const beans::UnknownPropertyException& ) + {} + } + + bool bResource = false; + if( xStringResourceResolver.is() ) + { + Sequence< lang::Locale > aLocaleSeq = xStringResourceResolver->getLocales(); + if( aLocaleSeq.hasElements() ) + bResource = true; + } + + if( bResource ) + { + INetURLObject aURLObj(u""); + aURLObj.removeExtension(); + OUString aDialogName( aURLObj.getName() ); + aURLObj.removeSegment(); + OUString aURL( aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); + OUString aComment = "# " + aDialogName + " strings" ; + Reference< task::XInteractionHandler > xDummyHandler; + + // Remove old properties files in case of overwriting Dialog files + if( xSFI->isFolder( aURL ) ) + { + Sequence< OUString > aContentSeq = xSFI->getFolderContents( aURL, false ); + + OUString aDialogName_ = aDialogName + "_" ; + sal_Int32 nCount = aContentSeq.getLength(); + const OUString* pFiles = aContentSeq.getConstArray(); + for( int i = 0 ; i < nCount ; i++ ) + { + OUString aCompleteName = pFiles[i]; + OUString aPureName; + OUString aExtension; + sal_Int32 iDot = aCompleteName.lastIndexOf( '.' ); + sal_Int32 iSlash = aCompleteName.lastIndexOf( '/' ); + if( iDot != -1 ) + { + sal_Int32 iCopyFrom = (iSlash != -1) ? iSlash + 1 : 0; + aPureName = aCompleteName.copy( iCopyFrom, iDot-iCopyFrom ); + aExtension = aCompleteName.copy( iDot + 1 ); + } + + if( aExtension == "properties" || aExtension == "default" ) + { + if( aPureName.startsWith( aDialogName_ ) ) + { + try + { + xSFI->kill( aCompleteName ); + } + catch(const uno::Exception& ) + {} + } + } + } + } + + Reference< XStringResourceWithLocation > xStringResourceWithLocation = + StringResourceWithLocation::create( xContext, aURL, false/*bReadOnly*/, + xStringResourceResolver->getDefaultLocale(), aDialogName, aComment, xDummyHandler ); + + // Add locales + Sequence< lang::Locale > aLocaleSeq = xStringResourceResolver->getLocales(); + const lang::Locale* pLocales = aLocaleSeq.getConstArray(); + sal_Int32 nLocaleCount = aLocaleSeq.getLength(); + for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ ) + { + const lang::Locale& rLocale = pLocales[ iLocale ]; + xStringResourceWithLocation->newLocale( rLocale ); + } + + LocalizationMgr::copyResourceForDialog( xDialogModel, + xStringResourceResolver, xStringResourceWithLocation ); + + xStringResourceWithLocation->store(); + } + } + else + { + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), + VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_COULDNTWRITE))); + xBox->run(); + } +} + +static std::vector< lang::Locale > implGetLanguagesOnlyContainedInFirstSeq + ( const Sequence< lang::Locale >& aFirstSeq, const Sequence< lang::Locale >& aSecondSeq ) +{ + std::vector< lang::Locale > avRet; + + const lang::Locale* pFirst = aFirstSeq.getConstArray(); + const lang::Locale* pSecond = aSecondSeq.getConstArray(); + sal_Int32 nFirstCount = aFirstSeq.getLength(); + sal_Int32 nSecondCount = aSecondSeq.getLength(); + + for( sal_Int32 iFirst = 0 ; iFirst < nFirstCount ; iFirst++ ) + { + const lang::Locale& rFirstLocale = pFirst[ iFirst ]; + + bool bAlsoContainedInSecondSeq = false; + for( sal_Int32 iSecond = 0 ; iSecond < nSecondCount ; iSecond++ ) + { + const lang::Locale& rSecondLocale = pSecond[ iSecond ]; + + bool bMatch = localesAreEqual( rFirstLocale, rSecondLocale ); + if( bMatch ) + { + bAlsoContainedInSecondSeq = true; + break; + } + } + + if( !bAlsoContainedInSecondSeq ) + avRet.push_back( rFirstLocale ); + } + + return avRet; +} + +namespace { + +class NameClashQueryBox +{ +private: + std::unique_ptr<weld::MessageDialog> m_xQueryBox; +public: + NameClashQueryBox(weld::Window* pParent, const OUString& rTitle, const OUString& rMessage) + : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question, VclButtonsType::NONE, rMessage)) + { + if (!rTitle.isEmpty()) + m_xQueryBox->set_title(rTitle); + m_xQueryBox->add_button(IDEResId(RID_STR_DLGIMP_CLASH_RENAME), RET_YES); + m_xQueryBox->add_button(IDEResId(RID_STR_DLGIMP_CLASH_REPLACE), RET_NO); + m_xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL); + m_xQueryBox->set_default_response(RET_YES); + } + short run() { return m_xQueryBox->run(); } +}; + +class LanguageMismatchQueryBox +{ +private: + std::unique_ptr<weld::MessageDialog> m_xQueryBox; +public: + LanguageMismatchQueryBox(weld::Window* pParent, const OUString& rTitle, const OUString& rMessage) + : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question, VclButtonsType::NONE, rMessage)) + { + if (!rTitle.isEmpty()) + m_xQueryBox->set_title(rTitle); + m_xQueryBox->add_button(IDEResId(RID_STR_DLGIMP_MISMATCH_ADD), RET_YES); + m_xQueryBox->add_button(IDEResId(RID_STR_DLGIMP_MISMATCH_OMIT), RET_NO); + m_xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL); + m_xQueryBox->add_button(GetStandardText(StandardButtonType::Help), RET_HELP); + m_xQueryBox->set_default_response(RET_YES); + } + short run() { return m_xQueryBox->run(); } +}; + +} + +bool implImportDialog(weld::Window* pWin, const ScriptDocument& rDocument, const OUString& aLibName) +{ + bool bDone = false; + + Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext()); + sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, + FileDialogFlags::NONE, pWin); + aDlg.SetContext(sfx2::FileDialogHelper::BasicImportDialog); + Reference<XFilePicker3> xFP = aDlg.GetFilePicker(); + + Reference< XFilePickerControlAccess > xFPControl(xFP, UNO_QUERY); + xFPControl->enableControl(ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, false); + Any aValue; + aValue <<= true; + xFPControl->setValue(ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue); + + OUString aDialogStr(IDEResId(RID_STR_STDDIALOGNAME)); + xFP->appendFilter( aDialogStr, "*.xdl" ); + xFP->appendFilter( IDEResId(RID_STR_FILTER_ALLFILES), FilterMask_All ); + xFP->setCurrentFilter( aDialogStr ); + + if( aDlg.Execute() == ERRCODE_NONE ) + { + Sequence< OUString > aPaths = xFP->getSelectedFiles(); + + OUString aBasePath; + OUString aOUCurPath( aPaths[0] ); + sal_Int32 iSlash = aOUCurPath.lastIndexOf( '/' ); + if( iSlash != -1 ) + aBasePath = aOUCurPath.copy( 0, iSlash + 1 ); + + try + { + // create dialog model + Reference< container::XNameContainer > xDialogModel( + xContext->getServiceManager()->createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", xContext), + UNO_QUERY_THROW ); + + Reference< XSimpleFileAccess3 > xSFI( SimpleFileAccess::create(xContext) ); + + Reference< XInputStream > xInput; + if( xSFI->exists( aOUCurPath ) ) + xInput = xSFI->openFileRead( aOUCurPath ); + + ::xmlscript::importDialogModel( xInput, xDialogModel, xContext, rDocument.isDocument() ? rDocument.getDocument() : Reference< frame::XModel >() ); + + OUString aXmlDlgName; + Reference< beans::XPropertySet > xDialogModelPropSet( xDialogModel, UNO_QUERY ); + assert(xDialogModelPropSet.is()); + try + { + Any aXmlDialogNameAny = xDialogModelPropSet->getPropertyValue( DLGED_PROP_NAME ); + aXmlDialogNameAny >>= aXmlDlgName; + } + catch(const beans::UnknownPropertyException& ) + { + TOOLS_WARN_EXCEPTION("basctl", ""); + } + assert( !aXmlDlgName.isEmpty() ); + + bool bDialogAlreadyExists = rDocument.hasDialog( aLibName, aXmlDlgName ); + + OUString aNewDlgName = aXmlDlgName; + enum NameClashMode + { + NO_CLASH, + CLASH_OVERWRITE_DIALOG, + CLASH_RENAME_DIALOG, + }; + NameClashMode eNameClashMode = NO_CLASH; + if( bDialogAlreadyExists ) + { + OUString aQueryBoxTitle(IDEResId(RID_STR_DLGIMP_CLASH_TITLE)); + OUString aQueryBoxText(IDEResId(RID_STR_DLGIMP_CLASH_TEXT)); + aQueryBoxText = aQueryBoxText.replaceAll("$(ARG1)", aXmlDlgName); + + NameClashQueryBox aQueryBox(pWin, aQueryBoxTitle, aQueryBoxText); + sal_uInt16 nRet = aQueryBox.run(); + if( nRet == RET_YES ) + { + // RET_YES == Rename, see NameClashQueryBox::NameClashQueryBox + eNameClashMode = CLASH_RENAME_DIALOG; + + aNewDlgName = rDocument.createObjectName( E_DIALOGS, aLibName ); + } + else if( nRet == RET_NO ) + { + // RET_NO == Replace, see NameClashQueryBox::NameClashQueryBox + eNameClashMode = CLASH_OVERWRITE_DIALOG; + } + else if( nRet == RET_CANCEL ) + { + return bDone; + } + } + + Shell* pShell = GetShell(); + assert(pShell); + + // Resource? + css::lang::Locale aLocale = Application::GetSettings().GetUILanguageTag().getLocale(); + Reference< task::XInteractionHandler > xDummyHandler; + Reference< XStringResourceWithLocation > xImportStringResource = + StringResourceWithLocation::create( xContext, aBasePath, true/*bReadOnly*/, + aLocale, aXmlDlgName, OUString(), xDummyHandler ); + + Sequence< lang::Locale > aImportLocaleSeq = xImportStringResource->getLocales(); + sal_Int32 nImportLocaleCount = aImportLocaleSeq.getLength(); + + Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, true ) ); + Reference< resource::XStringResourceManager > xLibStringResourceManager = LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib ); + sal_Int32 nLibLocaleCount = 0; + Sequence< lang::Locale > aLibLocaleSeq; + if( xLibStringResourceManager.is() ) + { + aLibLocaleSeq = xLibStringResourceManager->getLocales(); + nLibLocaleCount = aLibLocaleSeq.getLength(); + } + + // Check language matches + std::vector< lang::Locale > aOnlyInImportLanguages = + implGetLanguagesOnlyContainedInFirstSeq( aImportLocaleSeq, aLibLocaleSeq ); + int nOnlyInImportLanguageCount = aOnlyInImportLanguages.size(); + + // For now: Keep languages from lib + bool bLibLocalized = (nLibLocaleCount > 0); + bool bImportLocalized = (nImportLocaleCount > 0); + + bool bAddDialogLanguagesToLib = false; + if( nOnlyInImportLanguageCount > 0 ) + { + OUString aQueryBoxTitle(IDEResId(RID_STR_DLGIMP_MISMATCH_TITLE)); + OUString aQueryBoxText(IDEResId(RID_STR_DLGIMP_MISMATCH_TEXT)); + LanguageMismatchQueryBox aQueryBox(pWin, aQueryBoxTitle, aQueryBoxText); + sal_uInt16 nRet = aQueryBox.run(); + if( nRet == RET_YES ) + { + // RET_YES == Add, see LanguageMismatchQueryBox::LanguageMismatchQueryBox + bAddDialogLanguagesToLib = true; + } + // RET_NO == Omit, see LanguageMismatchQueryBox::LanguageMismatchQueryBox + // -> nothing to do here + //else if( RET_NO == nRet ) + //{ + //} + else if( nRet == RET_CANCEL ) + { + return bDone; + } + } + + if( bImportLocalized ) + { + bool bCopyResourcesForDialog = true; + if( bAddDialogLanguagesToLib ) + { + const std::shared_ptr<LocalizationMgr>& pCurMgr = pShell->GetCurLocalizationMgr(); + + lang::Locale aFirstLocale = aOnlyInImportLanguages[0]; + if( nOnlyInImportLanguageCount > 1 ) + { + // Check if import default belongs to only import languages and use it then + lang::Locale aImportDefaultLocale = xImportStringResource->getDefaultLocale(); + lang::Locale aTmpLocale; + for( int i = 0 ; i < nOnlyInImportLanguageCount ; ++i ) + { + aTmpLocale = aOnlyInImportLanguages[i]; + if( localesAreEqual( aImportDefaultLocale, aTmpLocale ) ) + { + aFirstLocale = aImportDefaultLocale; + break; + } + } + } + + pCurMgr->handleAddLocales( {aFirstLocale} ); + + if( nOnlyInImportLanguageCount > 1 ) + { + Sequence< lang::Locale > aRemainingLocaleSeq( nOnlyInImportLanguageCount - 1 ); + auto pRemainingLocaleSeq = aRemainingLocaleSeq.getArray(); + lang::Locale aTmpLocale; + int iSeq = 0; + for( int i = 0 ; i < nOnlyInImportLanguageCount ; ++i ) + { + aTmpLocale = aOnlyInImportLanguages[i]; + if( !localesAreEqual( aFirstLocale, aTmpLocale ) ) + pRemainingLocaleSeq[iSeq++] = aTmpLocale; + } + pCurMgr->handleAddLocales( aRemainingLocaleSeq ); + } + } + else if( !bLibLocalized ) + { + LocalizationMgr::resetResourceForDialog( xDialogModel, xImportStringResource ); + bCopyResourcesForDialog = false; + } + + if( bCopyResourcesForDialog ) + { + LocalizationMgr::copyResourceForDroppedDialog( xDialogModel, aXmlDlgName, + xLibStringResourceManager, xImportStringResource ); + } + } + else if( bLibLocalized ) + { + LocalizationMgr::setResourceIDsForDialog( xDialogModel, xLibStringResourceManager ); + } + + + LocalizationMgr::setStringResourceAtDialog( rDocument, aLibName, aNewDlgName, xDialogModel ); + + if( eNameClashMode == CLASH_OVERWRITE_DIALOG ) + { + if (basctl::RemoveDialog( rDocument, aLibName, aNewDlgName ) ) + { + BaseWindow* pDlgWin = pShell->FindDlgWin( rDocument, aLibName, aNewDlgName, false, true ); + if( pDlgWin != nullptr ) + pShell->RemoveWindow( pDlgWin, false ); + MarkDocumentModified( rDocument ); + } + else + { + // TODO: Assertion? + return bDone; + } + } + + if( eNameClashMode == CLASH_RENAME_DIALOG ) + { + bool bRenamed = false; + if( xDialogModelPropSet.is() ) + { + try + { + xDialogModelPropSet->setPropertyValue( DLGED_PROP_NAME, Any(aNewDlgName) ); + bRenamed = true; + } + catch(const beans::UnknownPropertyException& ) + {} + } + + + if( bRenamed ) + { + LocalizationMgr::renameStringResourceIDs( rDocument, aLibName, aNewDlgName, xDialogModel ); + } + else + { + // TODO: Assertion? + return bDone; + } + } + + Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, rDocument.isDocument() ? rDocument.getDocument() : Reference< frame::XModel >() ); + bool bSuccess = rDocument.insertDialog( aLibName, aNewDlgName, xISP ); + if( bSuccess ) + { + VclPtr<DialogWindow> pNewDlgWin = pShell->CreateDlgWin( rDocument, aLibName, aNewDlgName ); + pShell->SetCurWindow( pNewDlgWin, true ); + } + + bDone = true; + } + catch(const Exception& ) + {} + } + + return bDone; +} + +void DialogWindow::ImportDialog() +{ + const ScriptDocument& rDocument = GetDocument(); + OUString aLibName = GetLibName(); + implImportDialog(GetFrameWeld(), rDocument, aLibName); +} + +DlgEdModel& DialogWindow::GetModel() const +{ + return m_pEditor->GetModel(); +} + +DlgEdPage& DialogWindow::GetPage() const +{ + return m_pEditor->GetPage(); +} + +DlgEdView& DialogWindow::GetView() const +{ + return m_pEditor->GetView(); +} + +bool DialogWindow::IsModified() +{ + return m_pEditor->IsModified(); +} + +SfxUndoManager* DialogWindow::GetUndoManager() +{ + return m_pUndoMgr.get(); +} + +OUString DialogWindow::GetTitle() +{ + return GetName(); +} + +EntryDescriptor DialogWindow::CreateEntryDescriptor() +{ + ScriptDocument aDocument( GetDocument() ); + OUString aLibName( GetLibName() ); + LibraryLocation eLocation = aDocument.getLibraryLocation( aLibName ); + return EntryDescriptor( aDocument, eLocation, aLibName, OUString(), GetName(), OBJ_TYPE_DIALOG ); +} + +void DialogWindow::SetReadOnly (bool bReadOnly) +{ + m_pEditor->SetMode(bReadOnly ? DlgEditor::READONLY : DlgEditor::SELECT); +} + +bool DialogWindow::IsReadOnly () +{ + return m_pEditor->GetMode() == DlgEditor::READONLY; +} + +bool DialogWindow::IsPasteAllowed() +{ + return m_pEditor->IsPasteAllowed(); +} + +void DialogWindow::StoreData() +{ + if ( !IsModified() ) + return; + + try + { + Reference< container::XNameContainer > xLib = GetDocument().getLibrary( E_DIALOGS, GetLibName(), true ); + + if( xLib.is() ) + { + Reference< container::XNameContainer > xDialogModel = m_pEditor->GetDialog(); + + if( xDialogModel.is() ) + { + Reference< XComponentContext > xContext( + comphelper::getProcessComponentContext() ); + Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, GetDocument().isDocument() ? GetDocument().getDocument() : Reference< frame::XModel >() ); + xLib->replaceByName( GetName(), Any( xISP ) ); + } + } + } + catch (const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("basctl.basicide"); + } + MarkDocumentModified( GetDocument() ); + m_pEditor->ClearModifyFlag(); +} + +void DialogWindow::Activating () +{ + UpdateBrowser(); + Show(); +} + +void DialogWindow::Deactivating() +{ + Hide(); + if ( IsModified() ) + MarkDocumentModified( GetDocument() ); + DisableBrowser(); +} + +sal_Int32 DialogWindow::countPages( Printer* ) +{ + return 1; +} + +void DialogWindow::printPage( sal_Int32 nPage, Printer* pPrinter ) +{ + DlgEditor::printPage( nPage, pPrinter, CreateQualifiedName() ); +} + +void DialogWindow::DataChanged( const DataChangedEvent& rDCEvt ) +{ + if( (rDCEvt.GetType()==DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) + { + InitSettings(); + Invalidate(); + } + else + BaseWindow::DataChanged( rDCEvt ); +} + +void DialogWindow::InitSettings() +{ + // FIXME RenderContext + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + vcl::Font aFont = rStyleSettings.GetFieldFont(); + SetPointFont(*GetOutDev(), aFont); + + SetTextColor( rStyleSettings.GetFieldTextColor() ); + SetTextFillColor(); + + SetBackground( rStyleSettings.GetFieldColor() ); +} + +css::uno::Reference< css::accessibility::XAccessible > DialogWindow::CreateAccessible() +{ + return new AccessibleDialogWindow(this); +} + +OString DialogWindow::GetHid () const +{ + return HID_BASICIDE_DIALOGWINDOW; +} +ItemType DialogWindow::GetType () const +{ + return TYPE_DIALOG; +} + + +// DialogWindowLayout + + +DialogWindowLayout::DialogWindowLayout (vcl::Window* pParent, ObjectCatalog& rObjectCatalog_) : + Layout(pParent), + rObjectCatalog(rObjectCatalog_), + pPropertyBrowser(nullptr) +{ + ShowPropertyBrowser(); +} + +DialogWindowLayout::~DialogWindowLayout() +{ + disposeOnce(); +} + +void DialogWindowLayout::dispose() +{ + if (pPropertyBrowser) + Remove(pPropertyBrowser); + pPropertyBrowser.disposeAndClear(); + Layout::dispose(); +} + +// shows the property browser (and creates if necessary) +void DialogWindowLayout::ShowPropertyBrowser () +{ + // not exists? + if (!pPropertyBrowser) + { + // creating + pPropertyBrowser = VclPtr<PropBrw>::Create(*this); + pPropertyBrowser->Show(); + // after OnFirstSize(): + if (HasSize()) + AddPropertyBrowser(); + // updating if necessary + UpdatePropertyBrowser(); + } + else + pPropertyBrowser->Show(); + // refreshing the button state + if (SfxBindings* pBindings = GetBindingsPtr()) + pBindings->Invalidate(SID_SHOW_PROPERTYBROWSER); +} + +// disables the property browser +void DialogWindowLayout::DisablePropertyBrowser () +{ + if (pPropertyBrowser) + pPropertyBrowser->Update(nullptr); +} + +// updates the property browser +void DialogWindowLayout::UpdatePropertyBrowser () +{ + if (pPropertyBrowser) + pPropertyBrowser->Update(GetShell()); +} + +void DialogWindowLayout::Activating (BaseWindow& rChild) +{ + assert(dynamic_cast<DialogWindow*>(&rChild)); + rObjectCatalog.SetLayoutWindow(this); + rObjectCatalog.UpdateEntries(); + rObjectCatalog.Show(); + if (pPropertyBrowser) + pPropertyBrowser->Show(); + Layout::Activating(rChild); +} + +void DialogWindowLayout::Deactivating () +{ + Layout::Deactivating(); + rObjectCatalog.Hide(); + if (pPropertyBrowser) + pPropertyBrowser->Hide(); +} + +void DialogWindowLayout::ExecuteGlobal (SfxRequest& rReq) +{ + switch (rReq.GetSlot()) + { + case SID_SHOW_PROPERTYBROWSER: + // toggling property browser + if (pPropertyBrowser && pPropertyBrowser->IsVisible()) + pPropertyBrowser->Hide(); + else + ShowPropertyBrowser(); + ArrangeWindows(); + // refreshing the button state + if (SfxBindings* pBindings = GetBindingsPtr()) + pBindings->Invalidate(SID_SHOW_PROPERTYBROWSER); + break; + } +} + +void DialogWindowLayout::GetState (SfxItemSet& rSet, unsigned nWhich) +{ + switch (nWhich) + { + case SID_SHOW_PROPERTYBROWSER: + rSet.Put(SfxBoolItem(nWhich, pPropertyBrowser && pPropertyBrowser->IsVisible())); + break; + + case SID_BASICIDE_CHOOSEMACRO: + rSet.Put(SfxVisibilityItem(nWhich, false)); + break; + } +} + +void DialogWindowLayout::OnFirstSize (tools::Long const nWidth, tools::Long const nHeight) +{ + AddToLeft(&rObjectCatalog, Size(nWidth * 0.25, nHeight * 0.35)); + if (pPropertyBrowser) + AddPropertyBrowser(); +} + +void DialogWindowLayout::AddPropertyBrowser () { + Size const aSize = GetOutputSizePixel(); + AddToLeft(pPropertyBrowser, Size(aSize.Width() * 0.25, aSize.Height() * 0.65)); +} + + +} // namespace basctl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |