Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/basctl/source/basicide/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 41 kB image not shown  

Quelle  moduldlg.cxx   Sprache: C

 
/* -*- 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 <sal/config.h>

#include <strings.hrc>
#include <iderid.hxx>
#include <bitmaps.hlst>

#include "moduldlg.hxx"
#include <localizationmgr.hxx>
#include <basidesh.hxx>
#include <basobj.hxx>

#include <basic/basmgr.hxx>
#include <com/sun/star/script/XLibraryContainerPassword.hpp>
#include <com/sun/star/script/XLibraryContainer2.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <comphelper/processfactory.hxx>
#include <sfx2/app.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/frame.hxx>
#include <sfx2/request.hxx>
#include <sfx2/sfxsids.hrc>
#include <svl/stritem.hxx>
#include <vcl/transfer.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <tools/debug.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <xmlscript/xmldlg_imexp.hxx>
#include <com/sun/star/uno/XComponentContext.hpp>

namespace basctl
{

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::resource;

IMPL_LINK(ObjectPage, EditingEntryHdl, const weld::TreeIter&, rEntry, bool)
{
    bool bRet = false;

    sal_uInt16 nDepth = m_xBasicBox->get_iter_depth(rEntry);
    if (nDepth >= 2)
    {
        EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(&rEntry);
        const ScriptDocument& aDocument( aDesc.GetDocument() );
        const OUString& aLibName( aDesc.GetLibName() );
        Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
        Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ) );
        if ( !( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
                ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) ) )
        {
            // allow editing only for libraries, which are not readonly
            bRet = true;
        }
    }

    return bRet;
}

IMPL_LINK(ObjectPage, EditedEntryHdl, const IterString&, rIterString, bool)
{
    const weld::TreeIter& rEntry = rIterString.first;
    OUString sNewText = rIterString.second;

    if ( !IsValidSbxName(sNewText) )
    {
        std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                    VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
        xError->run();
        return false;
    }

    OUString aCurText(m_xBasicBox->get_text(rEntry));
    if ( aCurText == sNewText )
        // nothing to do
        return true;

    EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(&rEntry);
    const ScriptDocument& aDocument( aDesc.GetDocument() );
    DBG_ASSERT( aDocument.isValid(), "ExtTreeListBox::EditedEntry: no document!" );
    if ( !aDocument.isValid() )
        return false;
    const OUString& aLibName( aDesc.GetLibName() );
    EntryType eType = aDesc.GetType();

    bool bSuccess = eType == OBJ_TYPE_MODULE ?
        RenameModule(m_pDialog->getDialog(), aDocument, aLibName, aCurText, sNewText) :
        RenameDialog(m_pDialog->getDialog(), aDocument, aLibName, aCurText, sNewText);

    if ( !bSuccess )
        return false;

    MarkDocumentModified( aDocument );

    if (SfxDispatcher* pDispatcher = GetDispatcher())
    {
        SbxItem aSbxItem(SID_BASICIDE_ARG_SBX, aDocument, aLibName, sNewText, SbTreeListBox::ConvertType(eType));
        pDispatcher->ExecuteList( SID_BASICIDE_SBXRENAMED,
                            SfxCallMode::SYNCHRON, { &aSbxItem });
    }

    // OV-Bug?!
    m_xBasicBox->set_text(rEntry, sNewText);
    m_xBasicBox->set_cursor(rEntry);
    m_xBasicBox->unselect(rEntry);
    m_xBasicBox->select(rEntry); // so that handler is called => update edit

    return true;
}

void Shell::CopyDialogResources(
    Reference< io::XInputStreamProvider >& io_xISP,
    ScriptDocument const& rSourceDoc,
    OUString const& rSourceLibName,
    ScriptDocument const& rDestDoc,
    OUString const& rDestLibName,
    std::u16string_view rDlgName
)
{
    if ( !io_xISP.is() )
        return;

    // Get StringResourceManager
    Reference< container::XNameContainer > xSourceDialogLib( rSourceDoc.getLibrary( E_DIALOGS, rSourceLibName, true ) );
    Reference< XStringResourceManager > xSourceMgr =
        LocalizationMgr::getStringResourceFromDialogLibrary( xSourceDialogLib );
    if( !xSourceMgr.is() )
        return;
    bool bSourceLocalized = xSourceMgr->getLocales().hasElements();

    Reference< container::XNameContainer > xDestDialogLib( rDestDoc.getLibrary( E_DIALOGS, rDestLibName, true ) );
    Reference< XStringResourceManager > xDestMgr =
        LocalizationMgr::getStringResourceFromDialogLibrary( xDestDialogLib );
    if( !xDestMgr.is() )
        return;
    bool bDestLocalized = xDestMgr->getLocales().hasElements();

    if( !bSourceLocalized && !bDestLocalized )
        return;

    // create dialog model
    const Reference< XComponentContext >& xContext = comphelper::getProcessComponentContext();
    Reference< container::XNameContainer > xDialogModel( xContext->getServiceManager()->createInstanceWithContext
        ( u"com.sun.star.awt.UnoControlDialogModel"_ustr, xContext ), UNO_QUERY );
    Reference< io::XInputStream > xInput( io_xISP->createInputStream() );
    ::xmlscript::importDialogModel( xInput, xDialogModel, xContext, rSourceDoc.isDocument() ? rSourceDoc.getDocument() : Reference< frame::XModel >() );

    if( !xDialogModel.is() )
        return;

    if( bSourceLocalized && bDestLocalized )
    {
        LocalizationMgr::copyResourceForDroppedDialog( xDialogModel, rDlgName, xDestMgr, xSourceMgr );
    }
    else if( bSourceLocalized )
    {
        LocalizationMgr::resetResourceForDialog( xDialogModel, xSourceMgr );
    }
    else if( bDestLocalized )
    {
        LocalizationMgr::setResourceIDsForDialog( xDialogModel, xDestMgr );
    }
    io_xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, rDestDoc.isDocument() ? rDestDoc.getDocument() : Reference< frame::XModel >() );
}

void OrganizeDialog::SetCurrentEntry(const css::uno::Reference<css::frame::XFrame>&&nbsp;xDocFrame)
{
    if (!xDocFrame)
        return;
    Reference<css::frame::XController> xController(xDocFrame->getController());
    if (!xController)
        return;
    Reference<css::frame::XModel> xModel(xController->getModel());
    if (!xModel)
        return;
    EntryDescriptor aDesc(ScriptDocument(xModel), LIBRARY_LOCATION_DOCUMENT, OUString(), OUString(), OUString(), OBJ_TYPE_DOCUMENT);
    m_xModulePage->SetCurrentEntry(aDesc);
    m_xDialogPage->SetCurrentEntry(aDesc);
}

// OrganizeDialog
OrganizeDialog::OrganizeDialog(weld::Window* pParent, const css::uno::Reference<css::frame::XFrame>& xDocFrame, sal_Int16 tabId)
    : GenericDialogController(pParent, u"modules/BasicIDE/ui/organizedialog.ui"_ustr, u"OrganizeDialog"_ustr)
    , m_xTabCtrl(m_xBuilder->weld_notebook(u"tabcontrol"_ustr))
    , m_xModulePage(new ObjectPage(m_xTabCtrl->get_page(u"modules"_ustr), u"ModulePage"_ustr, BrowseMode::Modules, this))
    , m_xDialogPage(new ObjectPage(m_xTabCtrl->get_page(u"dialogs"_ustr), u"DialogPage"_ustr, BrowseMode::Dialogs, this))
    , m_xLibPage(new LibPage(m_xTabCtrl->get_page(u"libraries"_ustr), this))
{
    m_xTabCtrl->connect_enter_page(LINK(this, OrganizeDialog, ActivatePageHdl));

    SetCurrentEntry(xDocFrame);

    OUString sPage;
    if (tabId == 0)
        sPage = "modules";
    else if (tabId == 1)
        sPage = "dialogs";
    else
        sPage = "libraries";
    m_xTabCtrl->set_current_page(sPage);
    ActivatePageHdl(sPage);

    if (SfxDispatcher* pDispatcher = GetDispatcher())
        pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );
}

IMPL_LINK(OrganizeDialog, ActivatePageHdl, const OUString&, rPage, void)
{
    if (rPage == "modules")
        m_xModulePage->ActivatePage();
    else if (rPage == "dialogs")
        m_xDialogPage->ActivatePage();
    else if (rPage == "libraries")
        m_xLibPage->ActivatePage();
}

OrganizeDialog::~OrganizeDialog()
{
}

OrganizePage::OrganizePage(weld::Container* pParent, const OUString& rUIFile, const OUString &rName, OrganizeDialog* pDialog)
    : m_pDialog(pDialog)
    , m_xBuilder(Application::CreateBuilder(pParent, rUIFile))
    , m_xContainer(m_xBuilder->weld_container(rName))
{
}

OrganizePage::~OrganizePage()
{
}

class SbTreeListBoxDropTarget : public DropTargetHelper
{
private:
    SbTreeListBox& m_rTreeView;

    virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override
    {
        // to enable the autoscroll when we're close to the edges
        weld::TreeView& rWidget = m_rTreeView.get_widget();
        rWidget.get_dest_row_at_pos(rEvt.maPosPixel, nullptr, true);

        weld::TreeView* pSource = rWidget.get_drag_source();
        if (!pSource)
            return DND_ACTION_NONE;

        // tdf#145722 only return a DND_ACTION_MOVE possibility if that
        // is requested as an option
        const bool bCheckForMove = rEvt.mnAction & DND_ACTION_MOVE;

        sal_Int8 nMode = DND_ACTION_NONE;

        std::unique_ptr<weld::TreeIter> xEntry(pSource->make_iterator());
        if (pSource->get_selected(xEntry.get()))
        {
            sal_uInt16 nDepth = pSource->get_iter_depth(*xEntry);
            if (nDepth >= 2)
            {
                nMode = DND_ACTION_COPY;
                if (bCheckForMove)
                {
                    EntryDescriptor aDesc = m_rTreeView.GetEntryDescriptor(xEntry.get());
                    const ScriptDocument& aDocument( aDesc.GetDocument() );
                    const OUString& aLibName( aDesc.GetLibName() );
                    // allow MOVE mode only for libraries, which are not readonly
                    Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
                    Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ) );
                    if ( !( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
                            ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) ) )
                    {
                        // Only allow copy for localized libraries
                        bool bAllowMove = true;
                        if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
                        {
                            // Get StringResourceManager
                            Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, aLibName, true ) );
                            Reference< XStringResourceManager > xSourceMgr =
                                LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
                            if( xSourceMgr.is() )
                                bAllowMove = ( xSourceMgr->getLocales().getLength() == 0 );
                        }
                        if( bAllowMove )
                            nMode |= DND_ACTION_MOVE;
                    }
                }
            }
        }
        return nMode;
    }

    virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override
    {
        weld::TreeView& rWidget = m_rTreeView.get_widget();
        weld::TreeView* pSource = rWidget.get_drag_source();
        if (!pSource)
            return DND_ACTION_NONE;

        std::unique_ptr<weld::TreeIter> xEntry(rWidget.make_iterator());
        bool bEntry = rWidget.get_dest_row_at_pos(rEvt.maPosPixel, xEntry.get(), true);

        // don't drop on a BasicManager (nDepth == 0)
        sal_uInt16 nDepth = bEntry ? m_rTreeView.get_iter_depth(*xEntry) : 0;
        bool bValid = nDepth != 0;
        // don't drop in the same library
        std::unique_ptr<weld::TreeIter> xSelected(pSource->make_iterator());
        bool bSelected = pSource->get_selected(xSelected.get());
        if (!bSelected)
            bValid = false;
        else if (nDepth == 1)
        {
            std::unique_ptr<weld::TreeIter> xSelParent(pSource->make_iterator(xSelected.get()));
            if (pSource->iter_parent(*xSelParent) && pSource->iter_compare(*xEntry, *xSelParent) == 0)
                bValid = false;
        }
        else if (nDepth == 2)
        {
            std::unique_ptr<weld::TreeIter> xParent(pSource->make_iterator(xEntry.get()));
            std::unique_ptr<weld::TreeIter> xSelParent(pSource->make_iterator(xSelected.get()));
            if (pSource->iter_parent(*xParent) && pSource->iter_parent(*xSelParent) && pSource->iter_compare(*xParent, *xSelParent) == 0)
                bValid = false;
        }

        // don't drop on a library, which is not loaded, readonly or password protected
        // or which already has a module/dialog with this name
        if ( bValid && ( nDepth > 0 ) )
        {
            // get source module/dialog name
            EntryDescriptor aSourceDesc = m_rTreeView.GetEntryDescriptor(xSelected.get());
            const OUString& aSourceName = aSourceDesc.GetName();
            EntryType eSourceType = aSourceDesc.GetType();

            // get target shell and target library name
            EntryDescriptor aDestDesc = m_rTreeView.GetEntryDescriptor(xEntry.get());
            ScriptDocument const& rDestDoc = aDestDesc.GetDocument();
            const OUString& aDestLibName = aDestDesc.GetLibName();

            // check if module library is not loaded, readonly or password protected
            Reference< script::XLibraryContainer2 > xModLibContainer( rDestDoc.getLibraryContainer( E_SCRIPTS ) );
            if ( xModLibContainer.is() && xModLibContainer->hasByName( aDestLibName ) )
            {
                if ( !xModLibContainer->isLibraryLoaded( aDestLibName ) )
                    bValid = false;

                if ( xModLibContainer->isLibraryReadOnly( aDestLibName ) )
                    bValid = false;

                Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
                if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aDestLibName ) && !xPasswd->isLibraryPasswordVerified( aDestLibName ) )
                    bValid = false;
            }

            // check if dialog library is not loaded or readonly
            Reference< script::XLibraryContainer2 > xDlgLibContainer( rDestDoc.getLibraryContainer( E_DIALOGS ) );
            if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aDestLibName ) )
            {
                if ( !xDlgLibContainer->isLibraryLoaded( aDestLibName ) )
                    bValid = false;

                if ( xDlgLibContainer->isLibraryReadOnly( aDestLibName ) )
                    bValid = false;
            }

            // check, if module/dialog with this name is already existing in target library
            if ( ( eSourceType == OBJ_TYPE_MODULE && rDestDoc.hasModule( aDestLibName, aSourceName ) ) ||
                ( eSourceType == OBJ_TYPE_DIALOG && rDestDoc.hasDialog( aDestLibName, aSourceName ) ) )
            {
                bValid = false;
            }
        }

        if (bValid)
            NotifyCopyingMoving(*xEntry, rEvt.mnAction & DND_ACTION_MOVE);

        return DND_ACTION_NONE;
    }

    void NotifyCopyingMoving(const weld::TreeIter& rTarget, bool bMove)
    {
        sal_uInt16 nDepth = m_rTreeView.get_iter_depth(rTarget);
        std::unique_ptr<weld::TreeIter> xNewParent(m_rTreeView.make_iterator(&rTarget));
        int nNewChildPos = 0;
        DBG_ASSERT( nDepth, "Depth?" );
        if ( nDepth >= 2 )
        {
            // Target = module/dialog => put module/dialog under the superordinate Basic
            m_rTreeView.iter_parent(*xNewParent);
            nNewChildPos = m_rTreeView.get_iter_index_in_parent(rTarget) + 1;
        }

        // get target shell and target library name
        EntryDescriptor aDestDesc = m_rTreeView.GetEntryDescriptor(xNewParent.get());
        const ScriptDocument& rDestDoc( aDestDesc.GetDocument() );
        const OUString& aDestLibName( aDestDesc.GetLibName() );

        // get source shell, library name and module/dialog name
        std::unique_ptr<weld::TreeIter> xSelected(m_rTreeView.make_iterator());
        if (!m_rTreeView.get_selected(xSelected.get()))
            return;
        EntryDescriptor aSourceDesc = m_rTreeView.GetEntryDescriptor(xSelected.get());
        const ScriptDocument& rSourceDoc( aSourceDesc.GetDocument() );
        const OUString& aSourceLibName( aSourceDesc.GetLibName() );
        const OUString& aSourceName( aSourceDesc.GetName() );
        EntryType eType = aSourceDesc.GetType();

        // get dispatcher
        SfxDispatcher* pDispatcher = GetDispatcher();

        if ( bMove )    // move
        {
            // remove source module/dialog window
            if ( rSourceDoc != rDestDoc || aSourceLibName != aDestLibName )
            {
                if( pDispatcher )
                {
                    SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rSourceDoc, aSourceLibName, aSourceName, SbTreeListBox::ConvertType(eType) );
                    pDispatcher->ExecuteList( SID_BASICIDE_SBXDELETED,
                          SfxCallMode::SYNCHRON, { &aSbxItem });
                }
            }

            try
            {
                if ( eType == OBJ_TYPE_MODULE ) // module
                {
                    // get module
                    OUString aModule;
                    if ( rSourceDoc.getModule( aSourceLibName, aSourceName, aModule ) )
                    {
                        // remove module from source library
                        if ( rSourceDoc.removeModule( aSourceLibName, aSourceName ) )
                        {
                            MarkDocumentModified( rSourceDoc );

                            // insert module into target library
                            if ( rDestDoc.insertModule( aDestLibName, aSourceName, aModule ) )
                                MarkDocumentModified( rDestDoc );
                        }
                    }
                }
                else if ( eType == OBJ_TYPE_DIALOG )    // dialog
                {
                    // get dialog
                    Reference< io::XInputStreamProvider > xISP;
                    if ( rSourceDoc.getDialog( aSourceLibName, aSourceName, xISP ) )
                    {
                        Shell::CopyDialogResources( xISP, rSourceDoc,
                            aSourceLibName, rDestDoc, aDestLibName, aSourceName );

                        // remove dialog from source library
                        if (RemoveDialog(rSourceDoc, aSourceLibName, aSourceName))
                        {
                            MarkDocumentModified(rSourceDoc);

                            // insert dialog into target library
                            if ( rDestDoc.insertDialog( aDestLibName, aSourceName, xISP ) )
                                MarkDocumentModified(rDestDoc);
                        }
                    }
                }
            }
            catch (const uno::Exception& )
            {
                DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            }
        }
        else    // copy
        {
            try
            {
                if ( eType == OBJ_TYPE_MODULE ) // module
                {
                    // get module
                    OUString aModule;
                    if ( rSourceDoc.getModule( aSourceLibName, aSourceName, aModule ) )
                    {
                        // insert module into target library
                        if ( rDestDoc.insertModule( aDestLibName, aSourceName, aModule ) )
                            MarkDocumentModified( rDestDoc );
                    }
                }
                else if ( eType == OBJ_TYPE_DIALOG )    // dialog
                {
                    // get dialog
                    Reference< io::XInputStreamProvider > xISP;
                    if ( rSourceDoc.getDialog( aSourceLibName, aSourceName, xISP ) )
                    {
                        Shell::CopyDialogResources( xISP, rSourceDoc,
                            aSourceLibName, rDestDoc, aDestLibName, aSourceName );

                        // insert dialog into target library
                        if ( rDestDoc.insertDialog( aDestLibName, aSourceName, xISP ) )
                            MarkDocumentModified( rDestDoc );
                    }
                }
            }
            catch ( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            }
        }

        OUString sText(m_rTreeView.get_text(*xSelected));
        OUString sId(m_rTreeView.get_id(*xSelected));
        /// if copying then clone the userdata
        if (Entry* pEntry = bMove ? nullptr : weld::fromId<Entry*>(sId))
        {
            assert(pEntry->GetType() != OBJ_TYPE_DOCUMENT);
            std::unique_ptr<Entry> xNewUserData(std::make_unique<Entry>(*pEntry));
            sId = weld::toId(xNewUserData.release());
        }
        std::unique_ptr<weld::TreeIter> xRet(m_rTreeView.make_iterator());
        m_rTreeView.get_widget().insert(xNewParent.get(), nNewChildPos, &sText, &sId, nullptr, nullptr, false, xRet.get());
        if (eType == OBJ_TYPE_MODULE)
            m_rTreeView.get_widget().set_image(*xRet, RID_BMP_MODULE);
        else if (eType == OBJ_TYPE_DIALOG)
            m_rTreeView.get_widget().set_image(*xRet, RID_BMP_DIALOG);
        if (!m_rTreeView.get_row_expanded(*xNewParent))
            m_rTreeView.expand_row(*xNewParent);
        m_rTreeView.select(*xRet);

        if (bMove)
            m_rTreeView.remove(*xSelected);

        // create target module/dialog window
        if ( rSourceDoc != rDestDoc || aSourceLibName != aDestLibName )
        {
            if( pDispatcher )
            {
                SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDestDoc, aDestLibName, aSourceName, SbTreeListBox::ConvertType(eType) );
                pDispatcher->ExecuteList( SID_BASICIDE_SBXINSERTED,
                                      SfxCallMode::SYNCHRON, { &aSbxItem });
            }
        }
    }

public:
    SbTreeListBoxDropTarget(SbTreeListBox& rTreeView)
        : DropTargetHelper(rTreeView.get_widget().get_drop_target())
        , m_rTreeView(rTreeView)
    {
    }
};

// ObjectPage
ObjectPage::ObjectPage(weld::Container* pParent, const OUString &rName, BrowseMode nMode, OrganizeDialog* pDialog)
    : OrganizePage(pParent, "modules/BasicIDE/ui/" + rName.toAsciiLowerCase() + ".ui",
        rName, pDialog)
    , m_xBasicBox(new SbTreeListBox(m_xBuilder->weld_tree_view(u"library"_ustr), pDialog->getDialog()))
    , m_xEditButton(m_xBuilder->weld_button(u"edit"_ustr))
    , m_xNewModButton(m_xBuilder->weld_button(u"newmodule"_ustr))
    , m_xNewDlgButton(m_xBuilder->weld_button(u"newdialog"_ustr))
    , m_xDelButton(m_xBuilder->weld_button(u"delete"_ustr))
{
    Size aSize(m_xBasicBox->get_approximate_digit_width() * 40,
               m_xBasicBox->get_height_rows(14));
    m_xBasicBox->set_size_request(aSize.Width(), aSize.Height());

    // tdf#93476 The dialogs should be listed alphabetically
    m_xBasicBox->make_sorted();

    m_xEditButton->connect_clicked( LINK( this, ObjectPage, ButtonHdl ) );
    m_xDelButton->connect_clicked( LINK( this, ObjectPage, ButtonHdl ) );
    m_xBasicBox->connect_changed( LINK( this, ObjectPage, BasicBoxHighlightHdl ) );

    if( nMode & BrowseMode::Modules )
    {
        m_xNewModButton->connect_clicked( LINK( this, ObjectPage, ButtonHdl ) );
        m_xNewDlgButton->hide();
    }
    else if ( nMode & BrowseMode::Dialogs )
    {
        m_xNewDlgButton->connect_clicked( LINK( this, ObjectPage, ButtonHdl ) );
        m_xNewModButton->hide();
    }

    m_xDropTarget.reset(new SbTreeListBoxDropTarget(*m_xBasicBox));
    // tdf#145722 explicitly claim COPY and MOVE are options
    rtl::Reference<TransferDataContainer> xHelper(new TransferDataContainer);
    m_xBasicBox->get_widget().enable_drag_source(xHelper, DND_ACTION_COPYMOVE);

    m_xBasicBox->connect_editing(LINK(this, ObjectPage, EditingEntryHdl),
                                 LINK(this, ObjectPage, EditedEntryHdl));

    m_xBasicBox->SetMode( nMode );
    m_xBasicBox->ScanAllEntries();

    m_xEditButton->grab_focus();
    CheckButtons();
}

ObjectPage::~ObjectPage()
{
}

void ObjectPage::ActivatePage()
{
    m_xBasicBox->UpdateEntries();
    CheckButtons();
}

void ObjectPage::CheckButtons()
{
    // enable/disable edit button
    std::unique_ptr<weld::TreeIter> xCurEntry(m_xBasicBox->make_iterator());
    if (!m_xBasicBox->get_cursor(xCurEntry.get()))
        xCurEntry.reset();
    EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(xCurEntry.get());
    const ScriptDocument& aDocument( aDesc.GetDocument() );
    const OUString& aLibName( aDesc.GetLibName() );
    const OUString& aLibSubName( aDesc.GetLibSubName() );
    bool bVBAEnabled = aDocument.isInVBAMode();
    BrowseMode nMode = m_xBasicBox->GetMode();

    sal_uInt16 nDepth = xCurEntry ? m_xBasicBox->get_iter_depth(*xCurEntry) : 0;
    if ( nDepth >= 2 )
    {
        if( bVBAEnabled && ( nMode & BrowseMode::Modules ) && ( nDepth == 2 ) )
            m_xEditButton->set_sensitive(false);
        else
            m_xEditButton->set_sensitive(true);
    }
    else
        m_xEditButton->set_sensitive(false);

    // enable/disable new module/dialog buttons
    LibraryLocation eLocation( aDesc.GetLocation() );
    bool bReadOnly = false;
    if ( nDepth > 0 )
    {
        Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
        Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ) );
        if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
             ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) )
        {
            bReadOnly = true;
        }
    }
    if ( bReadOnly || eLocation == LIBRARY_LOCATION_SHARE )
    {
        m_xNewModButton->set_sensitive(false);
        m_xNewDlgButton->set_sensitive(false);
    }
    else
    {
        m_xNewModButton->set_sensitive(true);
        m_xNewDlgButton->set_sensitive(true);
    }

    // enable/disable delete button
    if ( nDepth >= 2 && !bReadOnly && eLocation != LIBRARY_LOCATION_SHARE )
    {
        if( bVBAEnabled && ( nMode & BrowseMode::Modules ) && ( ( nDepth == 2 ) || aLibSubName == IDEResId(RID_STR_DOCUMENT_OBJECTS) ) )
            m_xDelButton->set_sensitive(false);
        else
            m_xDelButton->set_sensitive(true);
    }
    else
        m_xDelButton->set_sensitive(false);
}

IMPL_LINK_NOARG(ObjectPage, BasicBoxHighlightHdl, weld::TreeView&, void)
{
    CheckButtons();
}

IMPL_LINK(ObjectPage, ButtonHdl, weld::Button&, rButton, void)
{
    if (&rButton == m_xEditButton.get())
    {
        SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
        SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
        SfxGetpApp()->ExecuteSlot( aRequest );

        SfxDispatcher* pDispatcher = GetDispatcher();

        std::unique_ptr<weld::TreeIter> xCurEntry(m_xBasicBox->make_iterator());
        if (!m_xBasicBox->get_cursor(xCurEntry.get()))
            return;
        if (m_xBasicBox->get_iter_depth(*xCurEntry) >= 2)
        {
            EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(xCurEntry.get());
            if ( pDispatcher )
            {
                OUString aModName( aDesc.GetName() );
                // extract the module name from the string like "Sheet1 (Example1)"
                if( aDesc.GetLibSubName() == IDEResId(RID_STR_DOCUMENT_OBJECTS) )
                {
                    aModName = aModName.getToken( 0, ' ' );
                }
                SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDesc.GetDocument(), aDesc.GetLibName(),
                                  aModName, SbTreeListBox::ConvertType( aDesc.GetType() ) );
                pDispatcher->ExecuteList(SID_BASICIDE_SHOWSBX,
                        SfxCallMode::SYNCHRON, { &aSbxItem });
            }
        }
        else    // only Lib selected
        {
            DBG_ASSERT( m_xBasicBox->get_iter_depth(*xCurEntry) == 1, "No LibEntry?!" );
            ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
            std::unique_ptr<weld::TreeIter> xParentEntry(m_xBasicBox->make_iterator(xCurEntry.get()));
            if (m_xBasicBox->iter_parent(*xParentEntry))
            {
                DocumentEntry* pDocumentEntry = weld::fromId<DocumentEntry*>(m_xBasicBox->get_id(*xParentEntry));
                if (pDocumentEntry)
                    aDocument = pDocumentEntry->GetDocument();
            }
            SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( aDocument.getDocumentOrNull() ) );
            OUString aLibName(m_xBasicBox->get_text(*xCurEntry));
            SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
            if ( pDispatcher )
            {
                pDispatcher->ExecuteList(SID_BASICIDE_LIBSELECTED,
                    SfxCallMode::ASYNCHRON, { &aDocItem, &aLibNameItem });
            }
        }
        EndTabDialog();
    }
    else if (&rButton == m_xNewModButton.get())
        NewModule();
    else if (&rButton == m_xNewDlgButton.get())
        NewDialog();
    else if (&rButton == m_xDelButton.get())
        DeleteCurrent();
}

bool ObjectPage::GetSelection( ScriptDocument& rDocument, OUString& rLibName )
{
    bool bRet = false;

    std::unique_ptr<weld::TreeIter> xCurEntry(m_xBasicBox->make_iterator());
    if (!m_xBasicBox->get_cursor(xCurEntry.get()))
        xCurEntry.reset();
    EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(xCurEntry.get());
    rDocument = aDesc.GetDocument();
    rLibName = aDesc.GetLibName();
    if ( rLibName.isEmpty() )
        rLibName = "Standard" ;

    DBG_ASSERT( rDocument.isAlive(), "ObjectPage::GetSelection: no or dead ScriptDocument in the selection!" );
    if ( !rDocument.isAlive() )
        return false;

    // check if the module library is loaded
    bool bOK = true;
    OUString aLibName( rLibName );
    Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS  ) );
    if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
    {
        // check password
        Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
        if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
        {
            OUString aPassword;
            bOK = QueryPassword(m_pDialog->getDialog(), xModLibContainer, rLibName, aPassword);
        }

        // load library
        if ( bOK )
            xModLibContainer->loadLibrary( aLibName );
    }

    // check if the dialog library is loaded
    Reference< script::XLibraryContainer > xDlgLibContainer( rDocument.getLibraryContainer( E_DIALOGS ) );
    if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && !xDlgLibContainer->isLibraryLoaded( aLibName ) )
    {
        // load library
        if ( bOK )
            xDlgLibContainer->loadLibrary( aLibName );
    }

    if ( bOK )
        bRet = true;

    return bRet;
}

void ObjectPage::NewModule()
{
    ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
    OUString aLibName;

    if ( GetSelection( aDocument, aLibName ) )
    {
        createModImpl(m_pDialog->getDialog(), aDocument,
                      *m_xBasicBox, aLibName, OUString(), true);
    }
}

void ObjectPage::NewDialog()
{
    ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
    OUString aLibName;

    if ( !GetSelection( aDocument, aLibName ) )
        return;

    aDocument.getOrCreateLibrary( E_DIALOGS, aLibName );

    NewObjectDialog aNewDlg(m_pDialog->getDialog(), ObjectMode::Dialog, true);
    aNewDlg.SetObjectName(aDocument.createObjectName(E_DIALOGS, aLibName));

    if (aNewDlg.run() == RET_CANCEL)
        return;

    OUString aDlgName = aNewDlg.GetObjectName();
    if (aDlgName.isEmpty())
        aDlgName = aDocument.createObjectName( E_DIALOGS, aLibName);

    if ( aDocument.hasDialog( aLibName, aDlgName ) )
    {
        std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                    VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
        xError->run();
    }
    else
    {
        Reference< io::XInputStreamProvider > xISP;
        if ( !aDocument.createDialog( aLibName, aDlgName, xISP ) )
            return;

        SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDocument, aLibName, aDlgName, SBX_TYPE_DIALOG );
        if (SfxDispatcher* pDispatcher = GetDispatcher())
        {
            pDispatcher->ExecuteList( SID_BASICIDE_SBXINSERTED,
                SfxCallMode::SYNCHRON, { &aSbxItem });
        }
        LibraryLocation eLocation = aDocument.getLibraryLocation( aLibName );
        std::unique_ptr<weld::TreeIter> xIter(m_xBasicBox->make_iterator());
        bool bRootEntry = m_xBasicBox->FindRootEntry(aDocument, eLocation, *xIter);
        if (bRootEntry)
        {
            if (!m_xBasicBox->get_row_expanded(*xIter))
                m_xBasicBox->expand_row(*xIter);
            bool bLibEntry = m_xBasicBox->FindEntry(aLibName, OBJ_TYPE_LIBRARY, *xIter);
            DBG_ASSERT( bLibEntry, "LibEntry not found!" );
            if (bLibEntry)
            {
                if (!m_xBasicBox->get_row_expanded(*xIter))
                    m_xBasicBox->expand_row(*xIter);
                std::unique_ptr<weld::TreeIter> xSubRootEntry(m_xBasicBox->make_iterator(xIter.get()));
                bool bDlgEntry = m_xBasicBox->FindEntry(aDlgName, OBJ_TYPE_DIALOG, *xIter);
                if (!bDlgEntry)
                {
                    m_xBasicBox->AddEntry(aDlgName, RID_BMP_DIALOG, xSubRootEntry.get(), false,
                                       std::make_unique<Entry>(OBJ_TYPE_DIALOG), xIter.get());
                    assert(xIter && "Insert entry failed!");
                }
                m_xBasicBox->set_cursor(*xIter);
                m_xBasicBox->select(*xIter);
            }
        }
    }
}

void ObjectPage::DeleteCurrent()
{
    std::unique_ptr<weld::TreeIter> xCurEntry(m_xBasicBox->make_iterator());
    if (!m_xBasicBox->get_cursor(xCurEntry.get()))
        xCurEntry.reset();
    DBG_ASSERT( xCurEntry, "No current entry!" );
    if (!xCurEntry)
        return;
    EntryDescriptor aDesc( m_xBasicBox->GetEntryDescriptor( xCurEntry.get() ) );
    const ScriptDocument& aDocument( aDesc.GetDocument() );
    DBG_ASSERT( aDocument.isAlive(), "ObjectPage::DeleteCurrent: no document!" );
    if ( !aDocument.isAlive() )
        return;
    const OUString& aLibName( aDesc.GetLibName() );
    const OUString& aName( aDesc.GetName() );
    EntryType eType = aDesc.GetType();

    if ( !(( eType == OBJ_TYPE_MODULE && QueryDelModule(aName, m_pDialog->getDialog()) ) ||
         ( eType == OBJ_TYPE_DIALOG && QueryDelDialog(aName, m_pDialog->getDialog()) )) )
        return;

    m_xBasicBox->remove(*xCurEntry);
    if (m_xBasicBox->get_cursor(xCurEntry.get()))
        m_xBasicBox->select(*xCurEntry);
    if (SfxDispatcher* pDispatcher = GetDispatcher())
    {
        SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDocument, aLibName, aName, SbTreeListBox::ConvertType( eType ) );
        pDispatcher->ExecuteList( SID_BASICIDE_SBXDELETED,
                              SfxCallMode::SYNCHRON, { &aSbxItem });
    }

    try
    {
        bool bSuccess = false;
        if ( eType == OBJ_TYPE_MODULE )
            bSuccess = aDocument.removeModule( aLibName, aName );
        else if ( eType == OBJ_TYPE_DIALOG )
            bSuccess = RemoveDialog( aDocument, aLibName, aName );

        if ( bSuccess )
            MarkDocumentModified( aDocument );
    }
    catch (const container::NoSuchElementException& )
    {
        DBG_UNHANDLED_EXCEPTION("basctl.basicide");
    }
}

void ObjectPage::EndTabDialog()
{
    m_pDialog->response(RET_OK);
}

LibDialog::LibDialog(weld::Window* pParent)
    : GenericDialogController(pParent, u"modules/BasicIDE/ui/importlibdialog.ui"_ustr, u"ImportLibDialog"_ustr)
    , m_xStorageFrame(m_xBuilder->weld_frame(u"storageframe"_ustr))
    , m_xLibBox(m_xBuilder->weld_tree_view(u"entries"_ustr))
    , m_xReferenceBox(m_xBuilder->weld_check_button(u"ref"_ustr))
    , m_xReplaceBox(m_xBuilder->weld_check_button(u"replace"_ustr))
{
    m_xLibBox->set_size_request(m_xLibBox->get_approximate_digit_width() * 28,
                                m_xLibBox->get_height_rows(8));
    m_xLibBox->enable_toggle_buttons(weld::ColumnToggleType::Check);
    // tdf#93476 The libraries should be listed alphabetically
    m_xLibBox->make_sorted();
}

LibDialog::~LibDialog()
{
}

void LibDialog::SetStorageName( std::u16string_view rName )
{
    OUString aName = IDEResId(RID_STR_FILENAME) + rName;
    m_xStorageFrame->set_label(aName);
}

// Helper function
SbModule* createModImpl(weld::Window* pWin, const ScriptDocument& rDocument,
    SbTreeListBox& rBasicBox, const OUString& rLibName, const OUString& _aModName, bool bMain )
{
    OSL_ENSURE( rDocument.isAlive(), "createModImpl: invalid document!" );
    if ( !rDocument.isAlive() )
        return nullptr;

    SbModule* pModule = nullptr;

    OUString aLibName( rLibName );
    if ( aLibName.isEmpty() )
        aLibName = "Standard" ;
    rDocument.getOrCreateLibrary( E_SCRIPTS, aLibName );
    OUString aModName = _aModName;
    if ( aModName.isEmpty() )
        aModName = rDocument.createObjectName( E_SCRIPTS, aLibName );

    NewObjectDialog aNewDlg(pWin, ObjectMode::Module, true);
    aNewDlg.SetObjectName(aModName);

    if (aNewDlg.run() != RET_CANCEL)
    {
        if (!aNewDlg.GetObjectName().isEmpty())
            aModName = aNewDlg.GetObjectName();

        try
        {
            OUString sModuleCode;
            // the module has existed
            if( rDocument.hasModule( aLibName, aModName ) )
                return nullptr;
            if (!rDocument.createModule(aLibName, aModName, bMain, sModuleCode))
                return nullptr;
            BasicManager* pBasMgr = rDocument.getBasicManager();
            StarBASIC* pBasic = pBasMgr? pBasMgr->GetLib( aLibName ) : nullptr;
            if ( pBasic )
                pModule = pBasic->FindModule( aModName );
            SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName, SBX_TYPE_MODULE );
            if (SfxDispatcher* pDispatcher = GetDispatcher())
            {
                pDispatcher->ExecuteList( SID_BASICIDE_SBXINSERTED,
                      SfxCallMode::SYNCHRON, { &aSbxItem });
            }
            LibraryLocation eLocation = rDocument.getLibraryLocation( aLibName );
            std::unique_ptr<weld::TreeIter> xIter(rBasicBox.make_iterator());
            bool bRootEntry = rBasicBox.FindRootEntry(rDocument, eLocation, *xIter);
            if (bRootEntry)
            {
                if (!rBasicBox.get_row_expanded(*xIter))
                    rBasicBox.expand_row(*xIter);
                bool bLibEntry = rBasicBox.FindEntry(aLibName, OBJ_TYPE_LIBRARY, *xIter);
                DBG_ASSERT( bLibEntry, "LibEntry not found!" );
                if (bLibEntry)
                {
                    if (!rBasicBox.get_row_expanded(*xIter))
                        rBasicBox.expand_row(*xIter);
                    std::unique_ptr<weld::TreeIter> xSubRootEntry(rBasicBox.make_iterator(xIter.get()));
                    if (pBasic && rDocument.isInVBAMode())
                    {
                        // add the new module in the "Modules" entry
                        std::unique_ptr<weld::TreeIter> xLibSubEntry(rBasicBox.make_iterator(xIter.get()));
                        bool bLibSubEntry = rBasicBox.FindEntry(IDEResId(RID_STR_NORMAL_MODULES) , OBJ_TYPE_NORMAL_MODULES, *xLibSubEntry);
                        if (bLibSubEntry)
                        {
                            if (!rBasicBox.get_row_expanded(*xLibSubEntry))
                                rBasicBox.expand_row(*xLibSubEntry);
                            rBasicBox.copy_iterator(*xLibSubEntry, *xSubRootEntry);
                        }
                    }

                    std::unique_ptr<weld::TreeIter> xEntry(rBasicBox.make_iterator(xSubRootEntry.get()));
                    bool bEntry = rBasicBox.FindEntry(aModName, OBJ_TYPE_MODULE, *xEntry);
                    if (!bEntry)
                    {
                        rBasicBox.AddEntry(aModName, RID_BMP_MODULE, xSubRootEntry.get(), false,
                                           std::make_unique<Entry>(OBJ_TYPE_MODULE), xEntry.get());
                    }
                    rBasicBox.set_cursor(*xEntry);
                    rBasicBox.select(*xEntry);
                }
            }
        }
        catch (const container::ElementExistException& )
        {
            std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(pWin,
                                                        VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
            xError->run();
        }
        catch (const container::NoSuchElementException& )
        {
            DBG_UNHANDLED_EXCEPTION("basctl.basicide");
        }
    }
    return pModule;
}


// namespace basctl

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=94 H=100 G=96

¤ Dauer der Verarbeitung: 0.18 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.