Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  SvxNotebookbarConfigPage.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 <vcl/commandinfoprovider.hxx>
#include <vcl/event.hxx>
#include <vcl/weld.hxx>
#include <vcl/svapp.hxx>

#include <algorithm>
#include <cstddef>

#include <helpids.h>
#include <strings.hrc>

#include <cfg.hxx>
#include <SvxNotebookbarConfigPage.hxx>
#include <SvxConfigPageHelper.hxx>
#include <dialmgr.hxx>
#include <libxml/parser.h>
#include <osl/file.hxx>
#include <CustomNotebookbarGenerator.hxx>
#include <sfx2/notebookbar/SfxNotebookBar.hxx>
#include <unotools/configmgr.hxx>
#include <comphelper/processfactory.hxx>
#include <o3tl/string_view.hxx>
#include <com/sun/star/frame/theUICommandDescription.hpp>

namespace uno = css::uno;
namespace frame = css::frame;
namespace container = css::container;
namespace beans = css::beans;

static bool isCategoryAvailable(std::u16string_view sClassId, std::u16string_view sUIItemId,
                                std::u16string_view sActiveCategory, bool& isCategory)
{
    if (sUIItemId == sActiveCategory)
        return true;
    else if ((sClassId == u"GtkMenu" || sClassId == u"GtkGrid") && sUIItemId != sActiveCategory)
    {
        isCategory = false;
        return false;
    }
    return false;
}

static OUString charToString(const char* cString)
{
    return OUString(cString, strlen(cString), RTL_TEXTENCODING_UTF8);
}

static OUString getFileName(std::u16string_view aFileName)
{
    if (aFileName == u"notebookbar.ui")
        return CuiResId(RID_CUISTR_TABBED);
    else if (aFileName == u"notebookbar_compact.ui")
        return CuiResId(RID_CUISTR_TABBED_COMPACT);
    else if (aFileName == u"notebookbar_groupedbar_full.ui")
        return CuiResId(RID_CUISTR_GROUPEDBAR);
    else if (aFileName == u"notebookbar_groupedbar_compact.ui")
        return CuiResId(RID_CUISTR_GROUPEDBAR_COMPACT);
    else
        return u"None"_ustr;
}

static OUString getModuleId(std::u16string_view sModuleName)
{
    if (sModuleName == u"Writer")
        return u"com.sun.star.text.TextDocument"_ustr;
    else if (sModuleName == u"Draw")
        return u"com.sun.star.drawing.DrawingDocument"_ustr;
    else if (sModuleName == u"Impress")
        return u"com.sun.star.presentation.PresentationDocument"_ustr;
    else if (sModuleName == u"Calc")
        return u"com.sun.star.sheet.SpreadsheetDocument"_ustr;
    else
        return u"None"_ustr;
}

SvxNotebookbarConfigPage::SvxNotebookbarConfigPage(weld::Container* pPage,
                                                   weld::DialogController* pController,
                                                   const SfxItemSet& rSet)
    : SvxConfigPage(pPage, pController, rSet)
{
    m_xCommandCategoryListBox->set_visible(false);
    m_xDescriptionFieldLb->set_visible(false);
    m_xSearchEdit->set_visible(false);
    m_xDescriptionField->set_visible(false);
    m_xMoveUpButton->set_visible(false);
    m_xMoveDownButton->set_visible(false);
    m_xCommandButtons->set_visible(false);
    m_xLeftFunctionLabel->set_visible(false);
    m_xSearchLabel->set_visible(false);
    m_xCategoryLabel->set_visible(false);
    m_xCustomizeBox->set_visible(false);
    m_xCustomizeLabel->set_visible(false);

    weld::TreeView& rCommandCategoryBox = m_xFunctions->get_widget();
    rCommandCategoryBox.hide();

    m_xContentsListBox.reset(
        new SvxNotebookbarEntriesListBox(m_xBuilder->weld_tree_view(u"toolcontents"_ustr), this));
    m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(
        *this, m_xContentsListBox->get_widget(), rCommandCategoryBox, Link<intvoid>()));
    weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
    Size aSize(m_xFunctions->get_size_request());
    rTreeView.set_size_request(aSize.Width(), aSize.Height());

    rTreeView.set_hexpand(true);
    rTreeView.set_vexpand(true);
    rTreeView.set_help_id(HID_SVX_CONFIG_NOTEBOOKBAR_CONTENTS);
    rTreeView.show();
}

SvxNotebookbarConfigPage::~SvxNotebookbarConfigPage() {}

void SvxNotebookbarConfigPage::DeleteSelectedTopLevel() {}

void SvxNotebookbarConfigPage::DeleteSelectedContent() {}

void SvxNotebookbarConfigPage::Init()
{
    m_xTopLevelListBox->clear();
    m_xContentsListBox->clear();
    m_xSaveInListBox->clear();
    OUString sNotebookbarInterface = getFileName(m_sFileName);

    OUString sScopeName
        = utl::ConfigManager::getProductName() + " " + m_sAppName + " - " + sNotebookbarInterface;
    OUString sSaveInListBoxID = notebookbarTabScope;

    m_xSaveInListBox->append(sSaveInListBoxID, sScopeName);
    m_xSaveInListBox->set_active_id(sSaveInListBoxID);

    m_xTopLevelListBox->append(u"NotebookBar"_ustr, CuiResId(RID_CUISTR_ALL_COMMANDS));
    m_xTopLevelListBox->set_active_id(u"NotebookBar"_ustr);
    SelectElement();
}

SaveInData* SvxNotebookbarConfigPage::CreateSaveInData(
    const css::uno::Reference<css::ui::XUIConfigurationManager>& xCfgMgr,
    const css::uno::Reference<css::ui::XUIConfigurationManager>& xParentCfgMgr,
    const OUString& aModuleId, bool bDocConfig)
{
    return static_cast<SaveInData*>(
        new ToolbarSaveInData(xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig));
}

void SvxNotebookbarConfigPage::UpdateButtonStates() {}

short SvxNotebookbarConfigPage::QueryReset()
{
    OUString msg = CuiResId(RID_CUISTR_CONFIRM_TOOLBAR_RESET);

    OUString saveInName = m_xSaveInListBox->get_active_text();

    OUString label = SvxConfigPageHelper::replaceSaveInName(msg, saveInName);

    std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
        GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, label));
    int nValue = xQueryBox->run();
    if (nValue == RET_YES)
    {
        osl::File::remove(CustomNotebookbarGenerator::getCustomizedUIPath());

        OUString sNotebookbarInterface = getFileName(m_sFileName);
        Sequence<OUString> sSequenceEntries;
        CustomNotebookbarGenerator::setCustomizedUIItem(sSequenceEntries, sNotebookbarInterface);
        OUString sUIPath = "modules/s" + m_sAppName.toAsciiLowerCase() + "/ui/";
        sfx2::SfxNotebookBar::ReloadNotebookBar(sUIPath);
    }
    return nValue;
}

void SvxConfigPage::InsertEntryIntoNotebookbarTabUI(std::u16string_view sClassId,
                                                    const OUString& sUIItemId,
                                                    const OUString& sUIItemCommand,
                                                    weld::TreeView& rTreeView,
                                                    const weld::TreeIter& rIter)
{
    css::uno::Reference<css::container::XNameAccess> m_xCommandToLabelMap;
    const uno::Reference<uno::XComponentContext>& xContext
        = ::comphelper::getProcessComponentContext();
    uno::Reference<container::XNameAccess> xNameAccess(
        css::frame::theUICommandDescription::get(xContext));

    uno::Sequence<beans::PropertyValue> aPropSeq;

    xNameAccess->getByName(getModuleId(m_sAppName)) >>= m_xCommandToLabelMap;

    try
    {
        uno::Any aModuleVal = m_xCommandToLabelMap->getByName(sUIItemCommand);

        aModuleVal >>= aPropSeq;
    }
    catch (container::NoSuchElementException&)
    {
    }

    OUString aLabel;
    for (auto const& prop : aPropSeq)
        if (prop.Name == "Name")
            prop.Value >>= aLabel;

    OUString aName = SvxConfigPageHelper::stripHotKey(aLabel);

    if (sClassId == u"GtkSeparatorMenuItem" || sClassId == u"GtkSeparator")
    {
        rTreeView.set_text(rIter, u"--------------------------------------------"_ustr, 0);
    }
    else
    {
        if (aName.isEmpty())
            aName = sUIItemId;
        auto xImage = GetSaveInData()->GetImage(sUIItemCommand);
        if (xImage.is())
            rTreeView.set_image(rIter, xImage, -1);
        rTreeView.set_text(rIter, aName, 0);
        rTreeView.set_id(rIter, sUIItemId);
    }
}

void SvxNotebookbarConfigPage::getNodeValue(xmlNode* pNodePtr, NotebookbarEntries&&nbsp;aNodeEntries)
{
    pNodePtr = pNodePtr->xmlChildrenNode;
    while (pNodePtr)
    {
        if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("property"))))
        {
            xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("name"));
            if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>("visible"))))
            {
                xmlChar* aValue = xmlNodeGetContent(pNodePtr);
                const char* cVisibleValue = reinterpret_cast<const char*>(aValue);
                aNodeEntries.sVisibleValue = charToString(cVisibleValue);
                xmlFree(aValue);
            }
            if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>("action_name"))))
            {
                xmlChar* aValue = xmlNodeGetContent(pNodePtr);
                const char* cActionName = reinterpret_cast<const char*>(aValue);
                aNodeEntries.sActionName = charToString(cActionName);
                xmlFree(aValue);
            }
            xmlFree(UriValue);
        }
        pNodePtr = pNodePtr->next;
    }
}

void SvxNotebookbarConfigPage::searchNodeandAttribute(std::vector<NotebookbarEntries>& aEntries,
                                                      std::vector<CategoriesEntries>& aCategoryList,
                                                      OUString& sActiveCategory,
                                                      CategoriesEntries& aCurItemEntry,
                                                      xmlNode* pNodePtr, bool isCategory)
{
    pNodePtr = pNodePtr->xmlChildrenNode;
    while (pNodePtr)
    {
        if (pNodePtr->type == XML_ELEMENT_NODE)
        {
            const char* cNodeName = reinterpret_cast<const char*>(pNodePtr->name);
            if (strcmp(cNodeName, "object") == 0)
            {
                OUString sSecondVal;

                xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("id"));
                const char* cUIItemID = reinterpret_cast<const char*>(UriValue);
                OUString sUIItemId = charToString(cUIItemID);
                xmlFree(UriValue);

                UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("class"));
                const char* cClassId = reinterpret_cast<const char*>(UriValue);
                OUString sClassId = charToString(cClassId);
                xmlFree(UriValue);

                CategoriesEntries aCategoryEntry;
                if (sClassId == "sfxlo-PriorityHBox")
                {
                    aCategoryEntry.sDisplayName = sUIItemId;
                    aCategoryEntry.sUIItemId = sUIItemId;
                    aCategoryEntry.sClassType = sClassId;
                    aCategoryList.push_back(aCategoryEntry);

                    aCurItemEntry = std::move(aCategoryEntry);
                }
                else if (sClassId == "sfxlo-PriorityMergedHBox")
                {
                    aCategoryEntry.sDisplayName = aCurItemEntry.sDisplayName + " | " + sUIItemId;
                    aCategoryEntry.sUIItemId = sUIItemId;
                    aCategoryEntry.sClassType = sClassId;

                    if (aCurItemEntry.sClassType == sClassId)
                    {
                        sal_Int32 rPos = 0;
                        aCategoryEntry.sDisplayName
                            = OUString::Concat(
                                  o3tl::getToken(aCurItemEntry.sDisplayName, rPos, ' ', rPos))
                              + " | " + sUIItemId;
                    }
                    aCategoryList.push_back(aCategoryEntry);
                    aCurItemEntry = std::move(aCategoryEntry);
                }
                else if (sClassId == "svtlo-ManagedMenuButton")
                {
                    sal_Int32 rPos = 1;
                    sSecondVal = sUIItemId.getToken(rPos, ':', rPos);
                    if (!sSecondVal.isEmpty())
                    {
                        aCategoryEntry.sDisplayName
                            = aCurItemEntry.sDisplayName + " | " + sSecondVal;
                        aCategoryEntry.sUIItemId = sSecondVal;
                        aCategoryList.push_back(aCategoryEntry);
                    }
                }

                NotebookbarEntries nodeEntries;
                if (isCategoryAvailable(sClassId, sUIItemId, sActiveCategory, isCategory)
                    || isCategory)
                {
                    isCategory = true;
                    if (sClassId == "GtkMenuItem" || sClassId == "GtkToolButton"
                        || sClassId == "GtkMenuToolButton"
                        || (sClassId == "svtlo-ManagedMenuButton" && sSecondVal.isEmpty()))
                    {
                        nodeEntries.sClassId = sClassId;
                        nodeEntries.sUIItemId = sUIItemId;
                        nodeEntries.sDisplayName = sUIItemId;

                        getNodeValue(pNodePtr, nodeEntries);
                        aEntries.push_back(nodeEntries);
                    }
                    else if (sClassId == "GtkSeparatorMenuItem" || sClassId == "GtkSeparator")
                    {
                        nodeEntries.sClassId = sClassId;
                        nodeEntries.sUIItemId = sUIItemId;
                        nodeEntries.sDisplayName = "Null";
                        nodeEntries.sVisibleValue = "Null";
                        nodeEntries.sActionName = "Null";
                        aEntries.push_back(nodeEntries);
                    }
                    else if (sClassId == "sfxlo-PriorityHBox"
                             || sClassId == "sfxlo-PriorityMergedHBox"
                             || sClassId == "svtlo-ManagedMenuButton")
                    {
                        nodeEntries.sClassId = sClassId;
                        nodeEntries.sUIItemId = sUIItemId;
                        nodeEntries.sDisplayName
                            = aCategoryList[aCategoryList.size() - 1].sDisplayName;
                        nodeEntries.sVisibleValue = "Null";
                        nodeEntries.sActionName = "Null";
                        aEntries.push_back(nodeEntries);
                    }
                }
            }
            searchNodeandAttribute(aEntries, aCategoryList, sActiveCategory, aCurItemEntry,
                                   pNodePtr, isCategory);
        }
        pNodePtr = pNodePtr->next;
    }
}

void SvxNotebookbarConfigPage::FillFunctionsList(xmlNodePtr pRootNodePtr,
                                                 std::vector<NotebookbarEntries>& aEntries,
                                                 std::vector<CategoriesEntries>& aCategoryList,
                                                 OUString& sActiveCategory)
{
    CategoriesEntries aCurItemEntry;
    searchNodeandAttribute(aEntries, aCategoryList, sActiveCategory, aCurItemEntry, pRootNodePtr,
                           false);
}

void SvxNotebookbarConfigPage::SelectElement()
{
    OString sUIFileUIPath = CustomNotebookbarGenerator::getSystemPath(
        CustomNotebookbarGenerator::getCustomizedUIPath());
    xmlDocPtr pDoc = xmlParseFile(sUIFileUIPath.getStr());
    if (!pDoc)
    {
        sUIFileUIPath = CustomNotebookbarGenerator::getSystemPath(
            CustomNotebookbarGenerator::getOriginalUIPath());
        pDoc = xmlParseFile(sUIFileUIPath.getStr());
    }

    if (!pDoc)
        return;
    xmlNodePtr pNodePtr = xmlDocGetRootElement(pDoc);

    std::vector<NotebookbarEntries> aEntries;
    std::vector<CategoriesEntries> aCategoryList;
    OUString sActiveCategory = m_xTopLevelListBox->get_active_id();
    FillFunctionsList(pNodePtr, aEntries, aCategoryList, sActiveCategory);

    if (m_xTopLevelListBox->get_count() == 1)
    {
        for (const auto& rCategory : aCategoryList)
            m_xTopLevelListBox->append(rCategory.sUIItemId, rCategory.sDisplayName);
    }
    tools::ULong nStart = 0;
    if (aEntries[nStart].sClassId == "sfxlo-PriorityHBox"
        || aEntries[nStart].sClassId == "sfxlo-PriorityMergedHBox")
        nStart = 1;

    std::vector<NotebookbarEntries> aTempEntries;
    for (std::size_t nIdx = nStart; nIdx < aEntries.size(); nIdx++)
    {
        if (aEntries[nIdx].sClassId == "svtlo-ManagedMenuButton")
        {
            aTempEntries.push_back(aEntries[nIdx]);
            sal_Int32 rPos = 1;
            sActiveCategory = aEntries[nIdx].sUIItemId.getToken(rPos, ':', rPos);
            FillFunctionsList(pNodePtr, aTempEntries, aCategoryList, sActiveCategory);
        }
        else
            aTempEntries.push_back(aEntries[nIdx]);
    }

    aEntries = std::move(aTempEntries);

    static_cast<SvxNotebookbarEntriesListBox*>(m_xContentsListBox.get())->GetTooltipMap().clear();
    weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
    rTreeView.bulk_insert_for_each(
        aEntries.size(), [this, &rTreeView, &aEntries](weld::TreeIter& rIter, int nIdx) {
            if (aEntries[nIdx].sActionName != "Null")
            {
                if (aEntries[nIdx].sVisibleValue == "True")
                {
                    rTreeView.set_toggle(rIter, TRISTATE_TRUE);
                }
                else
                {
                    rTreeView.set_toggle(rIter, TRISTATE_FALSE);
                }
            }
            InsertEntryIntoNotebookbarTabUI(aEntries[nIdx].sClassId, aEntries[nIdx].sDisplayName,
                                            aEntries[nIdx].sActionName, rTreeView, rIter);
            if (aEntries[nIdx].sClassId != u"GtkSeparatorMenuItem"
                && aEntries[nIdx].sClassId != u"GtkSeparator")
            {
                static_cast<SvxNotebookbarEntriesListBox*>(m_xContentsListBox.get())
                    ->GetTooltipMap()[aEntries[nIdx].sDisplayName]
                    = aEntries[nIdx].sActionName;
            }
        });

    aEntries.clear();

    xmlFreeDoc(pDoc);
}

SvxNotebookbarEntriesListBox::SvxNotebookbarEntriesListBox(std::unique_ptr<weld::TreeView> xParent,
                                                           SvxConfigPage* pPg)
    : SvxMenuEntriesListBox(std::move(xParent), pPg)
{
    m_xControl->connect_toggled(LINK(this, SvxNotebookbarEntriesListBox, CheckButtonHdl));
    m_xControl->connect_key_press(Link<const KeyEvent&, bool>());
    m_xControl->connect_key_press(LINK(this, SvxNotebookbarEntriesListBox, KeyInputHdl));
    // remove the inherited connect_query_tooltip then add the new one
    m_xControl->connect_query_tooltip(Link<const weld::TreeIter&, OUString>());
    m_xControl->connect_query_tooltip(LINK(this, SvxNotebookbarEntriesListBox, QueryTooltip));
}

SvxNotebookbarEntriesListBox::~SvxNotebookbarEntriesListBox() {}

static void EditRegistryFile(std::u16string_view sUIItemId, const OUString& sSetEntry,
                             const OUString& sNotebookbarInterface)
{
    int nFlag = 0;
    Sequence<OUString> aOldEntries
        = CustomNotebookbarGenerator::getCustomizedUIItem(sNotebookbarInterface);
    Sequence<OUString> aNewEntries(aOldEntries.getLength() + 1);
    auto pNewEntries = aNewEntries.getArray();
    for (int nIdx = 0; nIdx < aOldEntries.getLength(); nIdx++)
    {
        sal_Int32 rPos = 0;
        std::u16string_view sFirstValue = o3tl::getToken(aOldEntries[nIdx], rPos, ',', rPos);
        if (sFirstValue == sUIItemId)
        {
            aOldEntries.getArray()[nIdx] = sSetEntry;
            nFlag = 1;
            break;
        }
        pNewEntries[nIdx] = aOldEntries[nIdx];
    }

    if (nFlag == 0)
    {
        pNewEntries[aOldEntries.getLength()] = sSetEntry;
        CustomNotebookbarGenerator::setCustomizedUIItem(aNewEntries, sNotebookbarInterface);
    }
    else
    {
        CustomNotebookbarGenerator::setCustomizedUIItem(aOldEntries, sNotebookbarInterface);
    }
}

void SvxNotebookbarEntriesListBox::ChangedVisibility(int nRow)
{
    OUString sUIItemId = m_xControl->get_selected_id();
    OUString sNotebookbarInterface = getFileName(m_pPage->GetFileName());

    OUString sVisible;
    if (m_xControl->get_toggle(nRow) == TRISTATE_TRUE)
        sVisible = "True";
    else
        sVisible = "False";
    OUString sSetEntries = sUIItemId + ",visible," + sVisible;
    Sequence<OUString> sSeqOfEntries{ sSetEntries };
    EditRegistryFile(sUIItemId, sSetEntries, sNotebookbarInterface);
    CustomNotebookbarGenerator::modifyCustomizedUIFile(sSeqOfEntries);
    OUString sUIPath = "modules/s" + m_pPage->GetAppName().toAsciiLowerCase() + "/ui/";
    sfx2::SfxNotebookBar::ReloadNotebookBar(sUIPath);
}

IMPL_LINK(SvxNotebookbarEntriesListBox, CheckButtonHdl, const weld::TreeView::iter_col&, rRowCol,
          void)
{
    ChangedVisibility(m_xControl->get_iter_index_in_parent(rRowCol.first));
}

IMPL_LINK(SvxNotebookbarEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
{
    if (rKeyEvent.GetKeyCode() == KEY_SPACE)
    {
        int nRow = m_xControl->get_selected_index();
        m_xControl->set_toggle(nRow, m_xControl->get_toggle(nRow) == TRISTATE_TRUE ? TRISTATE_FALSE
                                                                                   : TRISTATE_TRUE);
        ChangedVisibility(nRow);
        return true;
    }
    return SvxMenuEntriesListBox::KeyInputHdl(rKeyEvent);
}

IMPL_LINK(SvxNotebookbarEntriesListBox, QueryTooltip, const weld::TreeIter&, rIter, OUString)
{
    const OUString& rsCommand = m_aTooltipMap[m_xControl->get_id(rIter)];
    if (rsCommand.isEmpty())
        return OUString();
    OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(m_pPage->GetFrame()));
    auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(rsCommand, aModuleName);
    OUString sTooltipLabel = vcl::CommandInfoProvider::GetTooltipForCommand(rsCommand, aProperties,
                                                                            m_pPage->GetFrame());
    return CuiResId(RID_CUISTR_COMMANDLABEL) + ": "
           + m_xControl->get_text(rIter).replaceFirst("~""") + "\n"
           + CuiResId(RID_CUISTR_COMMANDNAME) + ": " + rsCommand + "\n"
           + CuiResId(RID_CUISTR_COMMANDTIP) + ": " + sTooltipLabel.replaceFirst("~""");
}

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

Messung V0.5
C=90 H=94 G=91

¤ Dauer der Verarbeitung: 0.17 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge