<commit_before>#include "PresetChooser.hpp"

namespace Slic3r { namespace GUI {

PresetChooser::PresetChooser(wxWindow* parent, Print& print) : PresetChooser(parent, print, SLIC3RAPP->settings) {}

PresetChooser::PresetChooser(wxWindow* parent, Print& print, Settings& external) :
    wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, ""),
    _settings(external), _print(print)
{
    for (auto group : { preset_t::Print, preset_t::Material, preset_t::Printer }) {
        wxString name = "";
        switch(group) {
            case preset_t::Print:
                name << _("Print settings:");
                break;
            case preset_t::Material:
                name << _("Material:");
                break;
            case preset_t::Printer:
                name << _("Printer:");
                break;
            default:
                break;
        }
//        auto* text {new wxStaticText(this, wxID_ANY, name, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT)};
//        text->SetFont(ui_settings->small_font());

        auto* choice {new wxBitmapComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY)};
        this->preset_choosers[get_preset(group)].push_back(choice);

        // setup listener.
        // On a combobox event, puts a call to _on_change_combobox() on the evt_idle stack.
        choice->Bind(wxEVT_COMBOBOX,
            [=](wxCommandEvent& e) {
                wxTheApp->CallAfter([=]() { this->_on_change_combobox(group, choice);} );
            });
    }
}

void PresetChooser::load(std::array<Presets, preset_types> presets) {
    for (const auto& group : { preset_t::Print, preset_t::Material, preset_t::Printer }) {
        auto current_list = presets.at(get_preset(group));
        if (current_list.size() > 1) {
            current_list = grep(presets.at(get_preset(group)), [] (const Preset& x) -> bool { return !x.default_preset; });
        }

        // populate the chooser
        for (auto* chooser :  this->preset_choosers[get_preset(group)]) {
            chooser->Clear();
            for (auto preset : current_list) {
                wxBitmap bitmap;
                switch (group) {
                    case preset_t::Print:
                        bitmap = wxBitmap(var("cog.png"), wxBITMAP_TYPE_PNG);
                        break;
                    case preset_t::Material:
                        if (auto config =  preset.config().lock()) {
                            if (preset.default_preset || !config->has("filament_colour"))
                                bitmap = wxBitmap(var("spool.png"), wxBITMAP_TYPE_PNG);
                        } else { // fall back if for some reason the config is dead.
                            bitmap = wxBitmap(var("spool.png"), wxBITMAP_TYPE_PNG);
                        }
                        break;
                    case preset_t::Printer:
                        bitmap = wxBitmap(var("printer_empty.png"), wxBITMAP_TYPE_PNG);
                        break;
                    default: break;
                }
                chooser->Append(preset.name, bitmap);
                __chooser_names[get_preset(group)].push_back(preset.name);
            }
        }
    }
}

void PresetChooser::_on_select_preset(preset_t preset) {
    if (preset == preset_t::Printer) {
        this->load(); // reload print/filament settings to honor compatible printers
    }
}

bool PresetChooser::prompt_unsaved_changes() {
    return true;
}

void PresetChooser::_on_change_combobox(preset_t preset, wxBitmapComboBox* choice) {

    // Prompt for unsaved changes and undo selections if cancelled and return early
    // Callback to close preset editor tab, close editor tabs, reload presets.
    wxTheApp->CallAfter([this](){

//        this->_on_select_preset(preset);
        // reload presets; removes the modified mark
        this->load();
    });
    /*
    sub _on_change_combobox {
    my ($self, $group, $choice) = @_;

    if (0) {
        # This code is disabled because wxPerl doesn't provide GetCurrentSelection
        my $current_name = $self->{preset_choosers_names}{$choice}[$choice->GetCurrentSelection];
        my $current = first { $_->name eq $current_name } @{wxTheApp->presets->{$group}};
        if (!$current->prompt_unsaved_changes($self)) {
            # Restore the previous one
            $choice->SetSelection($choice->GetCurrentSelection);
            return;
        }
    } else {
        return 0 if !$self->prompt_unsaved_changes;
    }
    wxTheApp->CallAfter(sub {
        # Close the preset editor tab if any
        if (exists $self->GetFrame->{preset_editor_tabs}{$group}) {
            my $tabpanel = $self->GetFrame->{tabpanel};
            $tabpanel->DeletePage($tabpanel->GetPageIndex($self->GetFrame->{preset_editor_tabs}{$group}));
            delete $self->GetFrame->{preset_editor_tabs}{$group};
            $tabpanel->SetSelection(0); # without this, a newly created tab will not be selected by wx
        }

        $self->_on_select_preset($group);

        # This will remove the "(modified)" mark from any dirty preset handled here.
        $self->load_presets;
    });
}
*/
}

}} // Slic3r::GUI
<commit_msg>Call _on_select_preset from _on_change_combobox<commit_after>#include "PresetChooser.hpp"

namespace Slic3r { namespace GUI {

PresetChooser::PresetChooser(wxWindow* parent, Print& print) : PresetChooser(parent, print, SLIC3RAPP->settings) {}

PresetChooser::PresetChooser(wxWindow* parent, Print& print, Settings& external) :
    wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, ""),
    _settings(external), _print(print)
{
    for (auto group : { preset_t::Print, preset_t::Material, preset_t::Printer }) {
        wxString name = "";
        switch(group) {
            case preset_t::Print:
                name << _("Print settings:");
                break;
            case preset_t::Material:
                name << _("Material:");
                break;
            case preset_t::Printer:
                name << _("Printer:");
                break;
            default:
                break;
        }
//        auto* text {new wxStaticText(this, wxID_ANY, name, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT)};
//        text->SetFont(ui_settings->small_font());

        auto* choice {new wxBitmapComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY)};
        this->preset_choosers[get_preset(group)].push_back(choice);

        // setup listener.
        // On a combobox event, puts a call to _on_change_combobox() on the evt_idle stack.
        choice->Bind(wxEVT_COMBOBOX,
            [=](wxCommandEvent& e) {
                wxTheApp->CallAfter([=]() { this->_on_change_combobox(group, choice);} );
            });
    }
}

void PresetChooser::load(std::array<Presets, preset_types> presets) {
    for (const auto& group : { preset_t::Print, preset_t::Material, preset_t::Printer }) {
        auto current_list = presets.at(get_preset(group));
        if (current_list.size() > 1) {
            current_list = grep(presets.at(get_preset(group)), [] (const Preset& x) -> bool { return !x.default_preset; });
        }

        // populate the chooser
        for (auto* chooser :  this->preset_choosers[get_preset(group)]) {
            chooser->Clear();
            for (auto preset : current_list) {
                wxBitmap bitmap;
                switch (group) {
                    case preset_t::Print:
                        bitmap = wxBitmap(var("cog.png"), wxBITMAP_TYPE_PNG);
                        break;
                    case preset_t::Material:
                        if (auto config =  preset.config().lock()) {
                            if (preset.default_preset || !config->has("filament_colour"))
                                bitmap = wxBitmap(var("spool.png"), wxBITMAP_TYPE_PNG);
                        } else { // fall back if for some reason the config is dead.
                            bitmap = wxBitmap(var("spool.png"), wxBITMAP_TYPE_PNG);
                        }
                        break;
                    case preset_t::Printer:
                        bitmap = wxBitmap(var("printer_empty.png"), wxBITMAP_TYPE_PNG);
                        break;
                    default: break;
                }
                chooser->Append(preset.name, bitmap);
                __chooser_names[get_preset(group)].push_back(preset.name);
            }
        }
    }
}

void PresetChooser::_on_select_preset(preset_t preset) {
    if (preset == preset_t::Printer) {
        this->load(); // reload print/filament settings to honor compatible printers
    }
}

bool PresetChooser::prompt_unsaved_changes() {
    return true;
}

void PresetChooser::_on_change_combobox(preset_t preset, wxBitmapComboBox* choice) {

    // Prompt for unsaved changes and undo selections if cancelled and return early
    // Callback to close preset editor tab, close editor tabs, reload presets.
    //
    if (!this->prompt_unsaved_changes()) return;
    wxTheApp->CallAfter([this,preset]()
    {
        this->_on_select_preset(preset);
        // reload presets; removes the modified mark
        this->load();
    });
    /*
    sub _on_change_combobox {
    my ($self, $group, $choice) = @_;

    if (0) {
        # This code is disabled because wxPerl doesn't provide GetCurrentSelection
        my $current_name = $self->{preset_choosers_names}{$choice}[$choice->GetCurrentSelection];
        my $current = first { $_->name eq $current_name } @{wxTheApp->presets->{$group}};
        if (!$current->prompt_unsaved_changes($self)) {
            # Restore the previous one
            $choice->SetSelection($choice->GetCurrentSelection);
            return;
        }
    } else {
        return 0 if !$self->prompt_unsaved_changes;
    }
    wxTheApp->CallAfter(sub {
        # Close the preset editor tab if any
        if (exists $self->GetFrame->{preset_editor_tabs}{$group}) {
            my $tabpanel = $self->GetFrame->{tabpanel};
            $tabpanel->DeletePage($tabpanel->GetPageIndex($self->GetFrame->{preset_editor_tabs}{$group}));
            delete $self->GetFrame->{preset_editor_tabs}{$group};
            $tabpanel->SetSelection(0); # without this, a newly created tab will not be selected by wx
        }

        $self->_on_select_preset($group);

        # This will remove the "(modified)" mark from any dirty preset handled here.
        $self->load_presets;
    });
}
*/
}

}} // Slic3r::GUI
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <iostream>             // TODO: Remove this temporary include.

#include "BitFunnel/Term.h"
#include "TermTreatments.h"

namespace BitFunnel
{
    //*************************************************************************
    //
    // TreatmentPrivateRank0
    //
    // All terms get the same treatment - a single, private, rank 0 row.
    //
    //*************************************************************************
    TreatmentPrivateRank0::TreatmentPrivateRank0()
    {
        // Same configuration for all terms - one private rank 0 row.
        m_configuration.push_front(RowConfiguration::Entry(0, 1, true));

        std::cout << "Single configuration: ";
        m_configuration.Write(std::cout);
        std::cout << std::endl;
    }

    RowConfiguration TreatmentPrivateRank0::GetTreatment(Term /*term*/) const
    {
        return m_configuration;
    }

    //*************************************************************************
    //
    // TreatmentPrivateSharedRank0
    //
    // Terms get one or more rank 0 rows that could be private or shared,
    // depending on term frequency.
    //
    //*************************************************************************
    TreatmentPrivateSharedRank0::TreatmentPrivateSharedRank0(double density, double snr)
    {
        double maxSharedRowFrequency = density / 10.0;

        // TODO: fill up vector of RowConfigurations.
        for (Term::IdfX10 idf = 0; idf < 90; ++idf)
        {
            RowConfiguration configuration;

            double frequency = pow(10, -idf / 10.0);        // TODO: use method from Term.cpp.
            //std::cout << "idf = " << (float)idf << ", ";
            //std::cout << "frequency = " << frequency << std::endl;
            if (frequency > maxSharedRowFrequency)
            {
                configuration.push_front(RowConfiguration::Entry(0, 1, true));
            }
            else
            {
                unsigned k = lround(ceil(log(frequency / snr) / log(density - frequency)) + 1);
                configuration.push_front(RowConfiguration::Entry(0, k, false));
            }

            m_configurations.push_back(configuration);

            std::cout << idf / 10.0 << ": ";
            m_configurations.back().Write(std::cout);
            std::cout << std::endl;
        }
    }

    RowConfiguration TreatmentPrivateSharedRank0::GetTreatment(Term term) const
    {
        return m_configurations[term.GetIdfSum()];
    }

    //*************************************************************************
    //
    // TreatmentPrivateSharedRank0and3
    //
    // Terms get one or more rank 0 and rank 3 rows that could be private or
    // shared, depending on term frequency.
    //
    //*************************************************************************
    TreatmentPrivateSharedRank0and3::TreatmentPrivateSharedRank0and3(double density, double snr)
    {
        double maxSharedRowFrequency = density / 10.0;

        // TODO: fill up vector of RowConfigurations.
        for (Term::IdfX10 idf = 0; idf < 90; ++idf)
        {
            RowConfiguration configuration;

            double frequency = pow(10, -idf / 10.0);    // TODO: Use method from term.cpp. Use IdfX10.
            if (frequency > maxSharedRowFrequency)
            {
                configuration.push_front(RowConfiguration::Entry(0, 1, true));
            }
            else
            {
                unsigned k = lround(ceil(log(frequency / snr) / log(density - frequency)) + 1);
                configuration.push_front(RowConfiguration::Entry(0, 1, false));
                if (k > 1)
                {
                    // TODO: compute frequency at rank.
                    Rank rank = 3;
                    double frequencyAtRank = 1 - pow(1.0 - frequency, rank + 1);    // TODO: Put this in shared function.
                    if (frequencyAtRank > maxSharedRowFrequency)
                    {
                        configuration.push_front(RowConfiguration::Entry(3, 1, true));
                    }
                    else
                    {
                        configuration.push_front(RowConfiguration::Entry(3, k - 1, false));
                    }
                }
            }

            m_configurations.push_back(configuration);

            std::cout << idf / 10.0 << ": ";
            m_configurations.back().Write(std::cout);
            std::cout << std::endl;
        }
    }

    RowConfiguration TreatmentPrivateSharedRank0and3::GetTreatment(Term term) const
    {
        return m_configurations[term.GetIdfSum()];
    }
}
<commit_msg>Add missing header.<commit_after>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <iostream>             // TODO: Remove this temporary include.
#include <math.h>

#include "BitFunnel/Term.h"
#include "TermTreatments.h"

namespace BitFunnel
{
    //*************************************************************************
    //
    // TreatmentPrivateRank0
    //
    // All terms get the same treatment - a single, private, rank 0 row.
    //
    //*************************************************************************
    TreatmentPrivateRank0::TreatmentPrivateRank0()
    {
        // Same configuration for all terms - one private rank 0 row.
        m_configuration.push_front(RowConfiguration::Entry(0, 1, true));

        std::cout << "Single configuration: ";
        m_configuration.Write(std::cout);
        std::cout << std::endl;
    }

    RowConfiguration TreatmentPrivateRank0::GetTreatment(Term /*term*/) const
    {
        return m_configuration;
    }

    //*************************************************************************
    //
    // TreatmentPrivateSharedRank0
    //
    // Terms get one or more rank 0 rows that could be private or shared,
    // depending on term frequency.
    //
    //*************************************************************************
    TreatmentPrivateSharedRank0::TreatmentPrivateSharedRank0(double density, double snr)
    {
        double maxSharedRowFrequency = density / 10.0;

        // TODO: fill up vector of RowConfigurations.
        for (Term::IdfX10 idf = 0; idf < 90; ++idf)
        {
            RowConfiguration configuration;

            double frequency = pow(10, -idf / 10.0);        // TODO: use method from Term.cpp.
            //std::cout << "idf = " << (float)idf << ", ";
            //std::cout << "frequency = " << frequency << std::endl;
            if (frequency > maxSharedRowFrequency)
            {
                configuration.push_front(RowConfiguration::Entry(0, 1, true));
            }
            else
            {
                unsigned k = lround(ceil(log(frequency / snr) / log(density - frequency)) + 1);
                configuration.push_front(RowConfiguration::Entry(0, k, false));
            }

            m_configurations.push_back(configuration);

            std::cout << idf / 10.0 << ": ";
            m_configurations.back().Write(std::cout);
            std::cout << std::endl;
        }
    }

    RowConfiguration TreatmentPrivateSharedRank0::GetTreatment(Term term) const
    {
        return m_configurations[term.GetIdfSum()];
    }

    //*************************************************************************
    //
    // TreatmentPrivateSharedRank0and3
    //
    // Terms get one or more rank 0 and rank 3 rows that could be private or
    // shared, depending on term frequency.
    //
    //*************************************************************************
    TreatmentPrivateSharedRank0and3::TreatmentPrivateSharedRank0and3(double density, double snr)
    {
        double maxSharedRowFrequency = density / 10.0;

        // TODO: fill up vector of RowConfigurations.
        for (Term::IdfX10 idf = 0; idf < 90; ++idf)
        {
            RowConfiguration configuration;

            double frequency = pow(10, -idf / 10.0);    // TODO: Use method from term.cpp. Use IdfX10.
            if (frequency > maxSharedRowFrequency)
            {
                configuration.push_front(RowConfiguration::Entry(0, 1, true));
            }
            else
            {
                unsigned k = lround(ceil(log(frequency / snr) / log(density - frequency)) + 1);
                configuration.push_front(RowConfiguration::Entry(0, 1, false));
                if (k > 1)
                {
                    // TODO: compute frequency at rank.
                    Rank rank = 3;
                    double frequencyAtRank = 1 - pow(1.0 - frequency, rank + 1);    // TODO: Put this in shared function.
                    if (frequencyAtRank > maxSharedRowFrequency)
                    {
                        configuration.push_front(RowConfiguration::Entry(3, 1, true));
                    }
                    else
                    {
                        configuration.push_front(RowConfiguration::Entry(3, k - 1, false));
                    }
                }
            }

            m_configurations.push_back(configuration);

            std::cout << idf / 10.0 << ": ";
            m_configurations.back().Write(std::cout);
            std::cout << std::endl;
        }
    }

    RowConfiguration TreatmentPrivateSharedRank0and3::GetTreatment(Term term) const
    {
        return m_configurations[term.GetIdfSum()];
    }
}
<|endoftext|>


<commit_before>#include "backend_api.h"

#include "backend.h"

void runBackend(const int mavlink_listen_port, void (*onServerStarted)(void *), void *context)
{
    dronecode_sdk::backend::DronecodeSDKBackend backend;
    backend.connect(mavlink_listen_port);
    backend.startGRPCServer();

    if (onServerStarted != nullptr) {
        onServerStarted(context);
    }

    backend.wait();
}
<commit_msg>backend: start GRPC server before connecting<commit_after>#include "backend_api.h"

#include "backend.h"

void runBackend(const int mavlink_listen_port, void (*onServerStarted)(void *), void *context)
{
    dronecode_sdk::backend::DronecodeSDKBackend backend;
    backend.startGRPCServer();
    backend.connect(mavlink_listen_port);

    if (onServerStarted != nullptr) {
        onServerStarted(context);
    }

    backend.wait();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dlged.hxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 20:18:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _BASCTL_DLGED_HXX
#define _BASCTL_DLGED_HXX

#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_DATATRANSFER_DATAFLAVOR_HPP_
#include <com/sun/star/datatransfer/DataFlavor.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATSSUPPLIER_HPP_
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#endif

#ifndef _LINK_HXX
#include <tools/link.hxx>
#endif
#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif
#ifndef _SFXHINT_HXX
#include <svtools/hint.hxx>
#endif
#ifndef _SFXBRDCST_HXX
#include <svtools/brdcst.hxx>
#endif

#define DLGED_PAGE_WIDTH_MIN    1280
#define DLGED_PAGE_HEIGHT_MIN   1024

//============================================================================
// DlgEdHint
//============================================================================

enum DlgEdHintKind
{
    DLGED_HINT_UNKNOWN,
    DLGED_HINT_WINDOWSCROLLED,
    DLGED_HINT_LAYERCHANGED,
    DLGED_HINT_OBJORDERCHANGED,
    DLGED_HINT_SELECTIONCHANGED
};

class DlgEdObj;

class DlgEdHint: public SfxHint
{
private:
    DlgEdHintKind   eHintKind;
    DlgEdObj*       pDlgEdObj;

public:
    TYPEINFO();
    DlgEdHint( DlgEdHintKind eHint );
    DlgEdHint( DlgEdHintKind eHint, DlgEdObj* pObj );
    virtual ~DlgEdHint();

    DlgEdHintKind   GetKind() const { return eHintKind; }
    DlgEdObj*       GetObject() const { return pDlgEdObj; }
};

//============================================================================
// DlgEditor
//============================================================================

enum DlgEdMode { DLGED_INSERT, DLGED_SELECT, DLGED_TEST, DLGED_READONLY };

class ScrollBar;
class DlgEdModel;
class DlgEdPage;
class DlgEdView;
class DlgEdForm;
class DlgEdFactory;
class DlgEdFunc;
class Printer;
class KeyEvent;
class MouseEvent;
class Timer;
class Window;

class DlgEditor: public SfxBroadcaster
{
private:
    DECL_LINK( PaintTimeout, Timer * );
    DECL_LINK( MarkTimeout, Timer * );

protected:
    ScrollBar*          pHScroll;
    ScrollBar*          pVScroll;
    DlgEdModel*         pDlgEdModel;
    DlgEdPage*          pDlgEdPage;
    DlgEdView*          pDlgEdView;
    DlgEdForm*          pDlgEdForm;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >     m_xUnoControlDialogModel;
    ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor >       m_ClipboardDataFlavors;
    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >  m_xSupplier;
    DlgEdFactory*       pObjFac;
    Window*             pWindow;
    DlgEdFunc*          pFunc;
    DlgEdMode           eMode;
    USHORT              eActObj;
    BOOL                bFirstDraw;
    Size                aGridSize;
    BOOL                bGridVisible;
    BOOL                bGridSnap;
    BOOL                bCreateOK;
    Timer               aPaintTimer;
    Rectangle           aPaintRect;
    BOOL                bDialogModelChanged;
    Timer               aMarkTimer;

public:
    DlgEditor();
    ~DlgEditor();

    void            SetWindow( Window* pWindow );
    Window*         GetWindow() const { return pWindow; }

    void            SetDlgEdForm( DlgEdForm* pForm ) { pDlgEdForm = pForm; }
    DlgEdForm*      GetDlgEdForm() const { return pDlgEdForm; }

    void            SetScrollBars( ScrollBar* pHScroll, ScrollBar* pVScroll );
    void            InitScrollBars();
    ScrollBar*      GetHScroll() const { return pHScroll; }
    ScrollBar*      GetVScroll() const { return pVScroll; }
    void            DoScroll( ScrollBar* pActScroll );
    void            UpdateScrollBars();

    void            SetDialog( ::com::sun::star::uno::Reference<
                        ::com::sun::star::container::XNameContainer > xUnoControlDialogModel );
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > GetDialog() const
                        {return m_xUnoControlDialogModel;}

    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > const & GetNumberFormatsSupplier();

    DlgEdModel*     GetModel()      const { return pDlgEdModel; }
    DlgEdView*      GetView()       const { return pDlgEdView; }
    DlgEdPage*      GetPage()       const { return pDlgEdPage; }

    void            ShowDialog();

    BOOL            UnmarkDialog();
    BOOL            RemarkDialog();

    void            SetDialogModelChanged( BOOL bChanged = TRUE ) { bDialogModelChanged = bChanged; }
    BOOL            IsDialogModelChanged() const { return bDialogModelChanged; }

    BOOL            IsModified() const;
    void            ClearModifyFlag();

    void            MouseButtonDown( const MouseEvent& rMEvt );
    void            MouseButtonUp( const MouseEvent& rMEvt );
    void            MouseMove( const MouseEvent& rMEvt );
    void            Paint( const Rectangle& rRect );
    BOOL            KeyInput( const KeyEvent& rKEvt );

    void            SetMode( DlgEdMode eMode );
    void            SetInsertObj( USHORT eObj );
    USHORT          GetInsertObj() const;
    void            CreateDefaultObject();
    DlgEdMode       GetMode() const { return eMode; }
    BOOL            IsCreateOK() const { return bCreateOK; }

    void            Cut();
    void            Copy();
    void            Paste();
    void            Delete();
    BOOL            IsPasteAllowed();

    void            ShowProperties();
    void            UpdatePropertyBrowserDelayed();

    void            PrintData( Printer*, const String& rTitle );    // not working yet

    bool            AdjustPageSize();
};

#endif //_BASCTL_DLGED_HXX
<commit_msg>INTEGRATION: CWS aw024 (1.15.2); FILE MERGED 2006/03/21 13:23:28 fs 1.15.2.1: #i62854# cache the editor's control container<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dlged.hxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 15:29:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _BASCTL_DLGED_HXX
#define _BASCTL_DLGED_HXX

#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XCONTROLCONTAINER_HPP_
#include <com/sun/star/awt/XControlContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_DATATRANSFER_DATAFLAVOR_HPP_
#include <com/sun/star/datatransfer/DataFlavor.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATSSUPPLIER_HPP_
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#endif

#ifndef _LINK_HXX
#include <tools/link.hxx>
#endif
#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif
#ifndef _SFXHINT_HXX
#include <svtools/hint.hxx>
#endif
#ifndef _SFXBRDCST_HXX
#include <svtools/brdcst.hxx>
#endif

#define DLGED_PAGE_WIDTH_MIN    1280
#define DLGED_PAGE_HEIGHT_MIN   1024

//============================================================================
// DlgEdHint
//============================================================================

enum DlgEdHintKind
{
    DLGED_HINT_UNKNOWN,
    DLGED_HINT_WINDOWSCROLLED,
    DLGED_HINT_LAYERCHANGED,
    DLGED_HINT_OBJORDERCHANGED,
    DLGED_HINT_SELECTIONCHANGED
};

class DlgEdObj;

class DlgEdHint: public SfxHint
{
private:
    DlgEdHintKind   eHintKind;
    DlgEdObj*       pDlgEdObj;

public:
    TYPEINFO();
    DlgEdHint( DlgEdHintKind eHint );
    DlgEdHint( DlgEdHintKind eHint, DlgEdObj* pObj );
    virtual ~DlgEdHint();

    DlgEdHintKind   GetKind() const { return eHintKind; }
    DlgEdObj*       GetObject() const { return pDlgEdObj; }
};

//============================================================================
// DlgEditor
//============================================================================

enum DlgEdMode { DLGED_INSERT, DLGED_SELECT, DLGED_TEST, DLGED_READONLY };

class ScrollBar;
class DlgEdModel;
class DlgEdPage;
class DlgEdView;
class DlgEdForm;
class DlgEdFactory;
class DlgEdFunc;
class Printer;
class KeyEvent;
class MouseEvent;
class Timer;
class Window;

class DlgEditor: public SfxBroadcaster
{
private:
    DECL_LINK( PaintTimeout, Timer * );
    DECL_LINK( MarkTimeout, Timer * );

protected:
    ScrollBar*          pHScroll;
    ScrollBar*          pVScroll;
    DlgEdModel*         pDlgEdModel;
    DlgEdPage*          pDlgEdPage;
    DlgEdView*          pDlgEdView;
    DlgEdForm*          pDlgEdForm;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >     m_xUnoControlDialogModel;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer >        m_xControlContainer;
    ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor >       m_ClipboardDataFlavors;
    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >  m_xSupplier;
    DlgEdFactory*       pObjFac;
    Window*             pWindow;
    DlgEdFunc*          pFunc;
    DlgEdMode           eMode;
    USHORT              eActObj;
    BOOL                bFirstDraw;
    Size                aGridSize;
    BOOL                bGridVisible;
    BOOL                bGridSnap;
    BOOL                bCreateOK;
    Timer               aPaintTimer;
    Rectangle           aPaintRect;
    BOOL                bDialogModelChanged;
    Timer               aMarkTimer;

public:
    DlgEditor();
    ~DlgEditor();

    void            SetWindow( Window* pWindow );
    Window*         GetWindow() const { return pWindow; }

    /** returns the control container associated with our window
        @see GetWindow
        @see SetWindow
    */
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer >
                    GetWindowControlContainer();

    void            SetDlgEdForm( DlgEdForm* pForm ) { pDlgEdForm = pForm; }
    DlgEdForm*      GetDlgEdForm() const { return pDlgEdForm; }

    void            SetScrollBars( ScrollBar* pHScroll, ScrollBar* pVScroll );
    void            InitScrollBars();
    ScrollBar*      GetHScroll() const { return pHScroll; }
    ScrollBar*      GetVScroll() const { return pVScroll; }
    void            DoScroll( ScrollBar* pActScroll );
    void            UpdateScrollBars();

    void            SetDialog( ::com::sun::star::uno::Reference<
                        ::com::sun::star::container::XNameContainer > xUnoControlDialogModel );
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > GetDialog() const
                        {return m_xUnoControlDialogModel;}

    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > const & GetNumberFormatsSupplier();

    DlgEdModel*     GetModel()      const { return pDlgEdModel; }
    DlgEdView*      GetView()       const { return pDlgEdView; }
    DlgEdPage*      GetPage()       const { return pDlgEdPage; }

    void            ShowDialog();

    BOOL            UnmarkDialog();
    BOOL            RemarkDialog();

    void            SetDialogModelChanged( BOOL bChanged = TRUE ) { bDialogModelChanged = bChanged; }
    BOOL            IsDialogModelChanged() const { return bDialogModelChanged; }

    BOOL            IsModified() const;
    void            ClearModifyFlag();

    void            MouseButtonDown( const MouseEvent& rMEvt );
    void            MouseButtonUp( const MouseEvent& rMEvt );
    void            MouseMove( const MouseEvent& rMEvt );
    void            Paint( const Rectangle& rRect );
    BOOL            KeyInput( const KeyEvent& rKEvt );

    void            SetMode( DlgEdMode eMode );
    void            SetInsertObj( USHORT eObj );
    USHORT          GetInsertObj() const;
    void            CreateDefaultObject();
    DlgEdMode       GetMode() const { return eMode; }
    BOOL            IsCreateOK() const { return bCreateOK; }

    void            Cut();
    void            Copy();
    void            Paste();
    void            Delete();
    BOOL            IsPasteAllowed();

    void            ShowProperties();
    void            UpdatePropertyBrowserDelayed();

    void            PrintData( Printer*, const String& rTitle );    // not working yet

    bool            AdjustPageSize();
};

#endif //_BASCTL_DLGED_HXX
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/display/display_controller.h"

#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ui/aura/display_manager.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"

namespace ash {
namespace test {
namespace {

gfx::Display GetPrimaryDisplay() {
  return gfx::Screen::GetDisplayNearestWindow(
      Shell::GetAllRootWindows()[0]);
}

gfx::Display GetSecondaryDisplay() {
  return gfx::Screen::GetDisplayNearestWindow(
      Shell::GetAllRootWindows()[1]);
}

void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
  DisplayController* display_controller =
      Shell::GetInstance()->display_controller();
  DisplayLayout layout = display_controller->default_display_layout();
  layout.position = position;
  display_controller->SetDefaultDisplayLayout(layout);
}

}  // namespace

typedef test::AshTestBase DisplayControllerTest;

#if defined(OS_WIN)
// TOD(oshima): Windows creates a window with smaller client area.
// Fix this and enable tests.
#define MAYBE_SecondaryDisplayLayout DISABLED_SecondaryDisplayLayout
#else
#define MAYBE_SecondaryDisplayLayout SecondaryDisplayLayout
#endif

TEST_F(DisplayControllerTest, MAYBE_SecondaryDisplayLayout) {
  UpdateDisplay("500x500,400x400");
  gfx::Display* secondary_display =
      aura::Env::GetInstance()->display_manager()->GetDisplayAt(1);
  gfx::Insets insets(5, 5, 5, 5);
  secondary_display->UpdateWorkAreaFromInsets(insets);

  // Default layout is LEFT.
  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString());

  // Layout the secondary display to the bottom of the primary.
  SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());

  // Layout the secondary display to the left of the primary.
  SetSecondaryDisplayLayout(DisplayLayout::LEFT);
  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString());

  // Layout the secondary display to the top of the primary.
  SetSecondaryDisplayLayout(DisplayLayout::TOP);
  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString());
}

// TODO(oshima,erg): I suspect this test is now failing because I've changed
// the timing of the RootWindow::Show to be synchronous. If true, this test has
// always been incorrect, but is now visibly broken now that we're processing
// X11 configuration events while waiting for the MapNotify.
TEST_F(DisplayControllerTest, DISABLED_BoundsUpdated) {
  SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
  UpdateDisplay("500x500,400x400");
  gfx::Display* secondary_display =
      aura::Env::GetInstance()->display_manager()->GetDisplayAt(1);
  gfx::Insets insets(5, 5, 5, 5);
  secondary_display->UpdateWorkAreaFromInsets(insets);

  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());

  UpdateDisplay("600x600,400x400");
  EXPECT_EQ("0,0 600x600", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,600 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,605 390x390", GetSecondaryDisplay().work_area().ToString());

  UpdateDisplay("600x600,500x500");
  EXPECT_EQ("0,0 600x600", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,600 500x500", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,605 490x490", GetSecondaryDisplay().work_area().ToString());

  UpdateDisplay("600x600");
  EXPECT_EQ("0,0 600x600", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ(1, gfx::Screen::GetNumDisplays());

  UpdateDisplay("700x700,1000x1000");
  ASSERT_EQ(2, gfx::Screen::GetNumDisplays());
  EXPECT_EQ("0,0 700x700", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,700 1000x1000", GetSecondaryDisplay().bounds().ToString());
}

}  // namespace test
}  // namespace ash
<commit_msg>Enable disabled BoundsUpdated test. Set smaller window size so that they fit actual desktop size.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/display/display_controller.h"

#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ui/aura/display_manager.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"

namespace ash {
namespace test {
namespace {

gfx::Display GetPrimaryDisplay() {
  return gfx::Screen::GetDisplayNearestWindow(
      Shell::GetAllRootWindows()[0]);
}

gfx::Display GetSecondaryDisplay() {
  return gfx::Screen::GetDisplayNearestWindow(
      Shell::GetAllRootWindows()[1]);
}

void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
  DisplayController* display_controller =
      Shell::GetInstance()->display_controller();
  DisplayLayout layout = display_controller->default_display_layout();
  layout.position = position;
  display_controller->SetDefaultDisplayLayout(layout);
}

}  // namespace

typedef test::AshTestBase DisplayControllerTest;

#if defined(OS_WIN)
// TOD(oshima): Windows creates a window with smaller client area.
// Fix this and enable tests.
#define MAYBE_SecondaryDisplayLayout DISABLED_SecondaryDisplayLayout
#define MAYBE_BoundsUpdated DISABLED_BoundsUpdated
#else
#define MAYBE_SecondaryDisplayLayout SecondaryDisplayLayout
#define MAYBE_BoundsUpdated BoundsUpdated
#endif

TEST_F(DisplayControllerTest, MAYBE_SecondaryDisplayLayout) {
  UpdateDisplay("500x500,400x400");
  gfx::Display* secondary_display =
      aura::Env::GetInstance()->display_manager()->GetDisplayAt(1);
  gfx::Insets insets(5, 5, 5, 5);
  secondary_display->UpdateWorkAreaFromInsets(insets);

  // Default layout is LEFT.
  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString());

  // Layout the secondary display to the bottom of the primary.
  SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());

  // Layout the secondary display to the left of the primary.
  SetSecondaryDisplayLayout(DisplayLayout::LEFT);
  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString());

  // Layout the secondary display to the top of the primary.
  SetSecondaryDisplayLayout(DisplayLayout::TOP);
  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString());
}

TEST_F(DisplayControllerTest, MAYBE_BoundsUpdated) {
  SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
  UpdateDisplay("200x200,300x300");
  gfx::Display* secondary_display =
      aura::Env::GetInstance()->display_manager()->GetDisplayAt(1);
  gfx::Insets insets(5, 5, 5, 5);
  secondary_display->UpdateWorkAreaFromInsets(insets);

  EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());

  UpdateDisplay("400x400,200x200");
  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,405 190x190", GetSecondaryDisplay().work_area().ToString());

  UpdateDisplay("400x400,300x300");
  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("5,405 290x290", GetSecondaryDisplay().work_area().ToString());

  UpdateDisplay("400x400");
  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ(1, gfx::Screen::GetNumDisplays());

  UpdateDisplay("500x500,700x700");
  ASSERT_EQ(2, gfx::Screen::GetNumDisplays());
  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
  EXPECT_EQ("0,500 700x700", GetSecondaryDisplay().bounds().ToString());
}

}  // namespace test
}  // namespace ash
<|endoftext|>


<commit_before>// @(#)root/base:$Name:  $:$Id: TPluginManager.cxx,v 1.17 2003/05/15 18:02:35 rdm Exp $
// Author: Fons Rademakers   26/1/2002

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TPluginManager                                                       //
//                                                                      //
// This class implements a plugin library manager. It keeps track of    //
// a list of plugin handlers. A plugin handler knows which plugin       //
// library to load to get a specific class that is used to extend the   //
// functionality of a specific base class and how to create an object   //
// of this class. For example, to extend the base class TFile to be     //
// able to read RFIO files one needs to load the plugin library         //
// libRFIO.so which defines the TRFIOFile class. This loading should    //
// be triggered when a given URI contains a regular expression defined  //
// by the handler. Handlers can be defined for example as resources     //
// in the .rootrc file, e.g.:                                           //
//                                                                      //
//   Plugin.TFile:       ^rfio:   TRFIOFile    RFIO   "<constructor>"   //
//   Plugin.TSQLServer:  ^mysql:  TMySQLServer MySQL  "<constructor>"   //
//   +Plugin.TSQLServer: ^pgsql:  TPgSQLServer PgSQL  "<constructor>"   //
//   Plugin.TVirtualFitter: *     TFitter      Minuit "TFitter(Int_t)"  //
//                                                                      //
// Where the + in front of Plugin.TSQLServer says that it extends the   //
// existing definition of TSQLServer, usefull when there is more than   //
// one plugin that can extend the same base class. The "<constructor>"  //
// should be the constructor or a static method that generates an       //
// instance of the specified class. Global methods should start with    //
// "::" in their name, like "::CreateFitter()".                         //
// Instead of being a shared library a plugin can also be a CINT        //
// script, so instead of libDialog.so one can have Dialog.C.            //
// The * is a placeholder in case there is no need for a URI to         //
// differentiate between different plugins for the same base class.     //
// For the default plugins see $ROOTSYS/etc/system.rootrc.              //
//                                                                      //
// Plugin handlers can also be registered at run time, e.g.:            //
//                                                                      //
//   gROOT->GetPluginManager()->AddHandler("TSQLServer", "^sapdb:",     //
//                                         "TSapDBServer", "SapDB",     //
//             "TSapDBServer(const char*,const char*, const char*)");   //
//                                                                      //
// A list of currently defined handlers can be printed using:           //
//                                                                      //
//   gROOT->GetPluginManager()->Print(); // use option="a" to see ctors //
//                                                                      //
// The use of the plugin library manager removes all textual references //
// to hard-coded class and library names and the resulting dependencies //
// in the base classes. The plugin manager is used to extend a.o.       //
// TFile, TSQLServer, TGrid, etc. functionality.                        //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TPluginManager.h"
#include "TEnv.h"
#include "TRegexp.h"
#include "TROOT.h"
#include "TList.h"
#include "TOrdCollection.h"
#include "Varargs.h"
#include "TClass.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TDataType.h"
#include "TMethodCall.h"
#include "TVirtualMutex.h"

ClassImp(TPluginHandler)
ClassImp(TPluginManager)

//______________________________________________________________________________
TPluginHandler::TPluginHandler(const char *base, const char *regexp,
                               const char *className, const char *pluginName,
                               const char *ctor)
{
   // Create a plugin handler. Called by TPluginManager.

   fBase     = base;
   fRegexp   = regexp;
   fClass    = className;
   fPlugin   = pluginName;
   fCtor     = ctor;
   fCallEnv  = 0;
   fCanCall  = 0;
   fIsMacro  = kFALSE;
   fIsGlobal = kFALSE;

   if (gROOT->LoadMacro(pluginName, 0, kTRUE) == 0)
      fIsMacro = kTRUE;

   if (fCtor.Contains("::")) {
      fIsGlobal = kTRUE;
      fCtor = fCtor.Strip(TString::kLeading, ':');
   }
}

//______________________________________________________________________________
TPluginHandler::~TPluginHandler()
{
   // Cleanup plugin handler object.

   delete fCallEnv;
}

//______________________________________________________________________________
Bool_t TPluginHandler::CanHandle(const char *base, const char *uri)
{
   // Check if regular expression appears in the URI, if so return kTRUE.
   // If URI = 0 always return kTRUE.

   if (fBase != base)
      return kFALSE;

   if (!uri)
      return kTRUE;

   Bool_t wildcard = kFALSE;
   if (!fRegexp.MaybeRegexp())
      wildcard = kTRUE;

   TRegexp re(fRegexp, wildcard);
   TString ruri = uri;

   if (ruri.Index(re) != kNPOS)
      return kTRUE;
   return kFALSE;
}

//______________________________________________________________________________
void TPluginHandler::SetupCallEnv()
{
   // Setup ctor or static method call environment.

   fCanCall = -1;

   // check if class exists
   TClass *cl = gROOT->GetClass(fClass);
   if (!cl) {
      Error("SetupCallEnv", "class %s not found in plugin %s", fClass.Data(),
            fPlugin.Data());
      return;
   }

   // split method and prototype strings
   TString method = fCtor(0, fCtor.Index("("));
   TString proto  = fCtor(fCtor.Index("(")+1, fCtor.Index(")")-fCtor.Index("(")-1);

   if (fIsGlobal) {
      cl = 0;
      if (fIsMacro)
         fMethod = gROOT->GetGlobalFunction(method, 0, kTRUE);  // to be fixed
      else
         fMethod = gROOT->GetGlobalFunctionWithPrototype(method, proto, kTRUE);
   } else {
      if (fIsMacro)
         fMethod = cl->GetMethodAny(method);  //to be fixed to use prototype
      else
         fMethod = cl->GetMethodWithPrototype(method, proto);
   }

   if (!fMethod) {
      Error("SetupCallEnv", "method %s not found in class %s", method.Data(),
            fClass.Data());
      return;
   }

   if (!fIsGlobal && !(fMethod->Property() & kIsPublic)) {
      Error("SetupCallEnv", "method %s is not public", method.Data());
      return;
   }

   fCallEnv = new TMethodCall;
   fCallEnv->InitWithPrototype(cl, method, proto);

   fCanCall = 1;

   return;
}

//______________________________________________________________________________
Int_t TPluginHandler::CheckPlugin()
{
   // Check if the plugin library for this handler exits. Returns 0
   // when it exists and -1 in case the plugin does not exist.

   if (fIsMacro) {
      if (gROOT->GetClass(fClass)) return 0;
      return gROOT->LoadMacro(fPlugin, 0, kTRUE);
   } else
      return gROOT->LoadClass(fClass, fPlugin, kTRUE);
}

//______________________________________________________________________________
Int_t TPluginHandler::LoadPlugin()
{
   // Load the plugin library for this handler. Returns 0 on successful loading
   // and -1 in case the library does not exist or in case of error.

   if (fIsMacro) {
      if (gROOT->GetClass(fClass)) return 0;
      return gROOT->LoadMacro(fPlugin);
   } else
      return gROOT->LoadClass(fClass, fPlugin);
}

//______________________________________________________________________________
Long_t TPluginHandler::ExecPlugin(Int_t va_(nargs), ...)
{
   // Execute ctor for this plugin and return pointer to object of specific
   // class. User must cast the returned long to the correct class.
   // This method accepts a variable number of arguments to be passed
   // to the ctor, where nargs is the number of arguments, followed
   // by nargs arguments. Returns 0 in case of error.

   if (fCtor.IsNull()) {
      Error("ExecPlugin", "no ctor specified for this handler %s", fClass.Data());
      return 0;
   }

   if (!fCallEnv && fCanCall == 0)
      SetupCallEnv();

   if (fCanCall == -1)
      return 0;

   if (nargs < fMethod->GetNargs() - fMethod->GetNargsOpt() ||
       nargs > fMethod->GetNargs()) {
      Error("ExecPlugin", "nargs (%d) not consistent with expected number of arguments ([%d-%d])",
            nargs, fMethod->GetNargs() - fMethod->GetNargsOpt(),
            fMethod->GetNargs());
      return 0;
   }

   Long_t *args = 0;

   if (nargs > 0) {
      TIter next(fMethod->GetListOfMethodArgs());
      TMethodArg *arg;

      va_list ap;
      va_start(ap, va_(nargs));

      args = new Long_t[nargs+1];
      args[nargs] = 0;   // sentinel

      for (int i = 0; i < nargs; i++) {
         union {
           float f;
           long  l;
         } u;
         arg = (TMethodArg*) next();
         TString type = arg->GetFullTypeName();
         TDataType *dt = gROOT->GetType(type);
         if (dt)
            type = dt->GetFullTypeName();
         if (arg->Property() & (kIsPointer | kIsArray | kIsReference))
            args[i] = (Long_t) va_arg(ap, void*);
         else if (type == "bool")
            args[i] = (Long_t) va_arg(ap, int);  // bool is promoted to int
         else if (type == "char" || type == "unsigned char")
            args[i] = (Long_t) va_arg(ap, int);  // char is promoted to int
         else if (type == "short" || type == "unsigned short")
            args[i] = (Long_t) va_arg(ap, int);  // short is promoted to int
         else if (type == "int" || type == "unsigned int")
            args[i] = (Long_t) va_arg(ap, int);
         else if (type == "long" || type == "unsigned long")
            args[i] = (Long_t) va_arg(ap, long);
         else if (type == "long long" || type == "unsigned long long")
            args[i] = (Long_t) va_arg(ap, long long);
         else if (type == "float") {
            u.f = (Float_t) va_arg(ap, double);  // float is promoted to double
            args[i] = (Long_t) u.l;
         } else if (type == "double") {
            u.f = (Float_t) va_arg(ap, double);
            args[i] = (Long_t) u.l;
         }
      }

      va_end(ap);

      fCallEnv->SetParamPtrs(args, nargs);
   }

   R__LOCKGUARD(gCINTMutex);
   Long_t ret;
   fCallEnv->Execute(ret);

   delete [] args;

   return ret;
}

//______________________________________________________________________________
TPluginManager::~TPluginManager()
{
   // Clean up the plugin manager.

   delete fHandlers;
}

//______________________________________________________________________________
void TPluginManager::LoadHandlersFromEnv(TEnv *env)
{
   // Load plugin handlers specified in config file, like:
   //    Plugin.TFile:       ^rfio:    TRFIOFile      RFIO  "TRFIOFile(...)"
   //    Plugin.TSQLServer:  ^mysql:   TMySQLServer   MySQL "TMySQLServer(...)"
   //    +Plugin.TSQLServer: ^pgsql:   TPgSQLServer   PgSQL "TPgSQLServer(...)"
   // The + allows the extension of an already defined resource (see TEnv).

   if (!env) return;

   TIter next(env->GetTable());
   TEnvRec *er;

   while ((er = (TEnvRec*) next())) {
      const char *s;
      if ((s = strstr(er->GetName(), "Plugin."))) {
         const char *val = env->GetValue(er->GetName(), (const char*)0);
         if (val) {
            Int_t cnt = 0;
            char *v = StrDup(val);
            s += 7;
            while (1) {
               TString regexp = strtok(!cnt ? v : 0, "; ");
               if (regexp.IsNull()) break;
               TString clss   = strtok(0, "; ");
               if (clss.IsNull()) break;
               TString plugin = strtok(0, "; ");
               if (plugin.IsNull()) break;
               strtok(0, ";\"");
               TString ctor = strtok(0, ";\"");
               AddHandler(s, regexp, clss, plugin, ctor);
               cnt++;
            }
            delete [] v;
         }
      }
   }
}

//______________________________________________________________________________
void TPluginManager::AddHandler(const char *base, const char *regexp,
                                const char *className, const char *pluginName,
                                const char *ctor)
{
   // Add plugin handler to the list of handlers. If there is already a
   // handler defined for the same base and regexp it will be replaced.

   if (!fHandlers) {
      fHandlers = new TList;
      fHandlers->IsOwner();
   }

   // make sure there is no previous handler for the same case
   RemoveHandler(base, regexp);

   TPluginHandler *h = new TPluginHandler(base, regexp, className,
                                          pluginName, ctor);
   fHandlers->Add(h);
}

//______________________________________________________________________________
void TPluginManager::RemoveHandler(const char *base, const char *regexp)
{
   // Remove handler for the specified base class and the specified
   // regexp. If regexp=0 remove all handlers for the specified base.

   if (!fHandlers) return;

   TIter next(fHandlers);
   TPluginHandler *h;

   while ((h = (TPluginHandler*) next())) {
      if (h->fBase == base) {
         if (!regexp || h->fRegexp == regexp) {
            fHandlers->Remove(h);
            delete h;
         }
      }
   }
}

//______________________________________________________________________________
TPluginHandler *TPluginManager::FindHandler(const char *base, const char *uri)
{
   // Returns the handler if there exists a handler for the specified URI.
   // The uri can be 0 in which case the first matching plugin handler
   // will be returned. Returns 0 in case handler is not found.

   if (!fHandlers) return 0;

   TIter next(fHandlers);
   TPluginHandler *h;

   while ((h = (TPluginHandler*) next())) {
      if (h->CanHandle(base, uri)) {
         if (gDebug > 0)
            Info("FindHandler", "found plugin for %s", h->GetClass());
         return h;
      }
   }

   if (gDebug > 0) {
      if (uri)
         Info("FindHandler", "did not find plugin for class %s and uri %s", base, uri);
      else
         Info("FindHandler", "did not find plugin for class %s", base);
   }

   return 0;
}

//______________________________________________________________________________
void TPluginManager::Print(Option_t *opt) const
{
   // Print list of registered plugin handlers. If option is "a" print
   // also the ctor's that will be used.

   if (!fHandlers) return;

   TIter next(fHandlers);
   TPluginHandler *h;

   printf("=====================================================================\n");
   printf("Base                 Regexp        Class              Plugin\n");
   printf("=====================================================================\n");

   while ((h = (TPluginHandler*) next())) {
      const char *exist = "";
      if (h->CheckPlugin() == -1)
         exist = " [*]";
      printf("%-20s %-13s %-18s %s%s\n", h->fBase.Data(), h->fRegexp.Data(),
             h->fClass.Data(), h->fPlugin.Data(), exist);
      if (strchr(opt, 'a'))
         printf("  [Ctor: %s]\n", h->fCtor.Data());
   }
   printf("=====================================================================\n");
   printf("[*] plugin not available\n");
   printf("=====================================================================\n\n");
}
<commit_msg>Use Long64_t instead of long long for portability reasons. On Windows Long64_t is a typedef to __int64<commit_after>// @(#)root/base:$Name:  $:$Id: TPluginManager.cxx,v 1.18 2003/05/15 19:41:38 brun Exp $
// Author: Fons Rademakers   26/1/2002

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TPluginManager                                                       //
//                                                                      //
// This class implements a plugin library manager. It keeps track of    //
// a list of plugin handlers. A plugin handler knows which plugin       //
// library to load to get a specific class that is used to extend the   //
// functionality of a specific base class and how to create an object   //
// of this class. For example, to extend the base class TFile to be     //
// able to read RFIO files one needs to load the plugin library         //
// libRFIO.so which defines the TRFIOFile class. This loading should    //
// be triggered when a given URI contains a regular expression defined  //
// by the handler. Handlers can be defined for example as resources     //
// in the .rootrc file, e.g.:                                           //
//                                                                      //
//   Plugin.TFile:       ^rfio:   TRFIOFile    RFIO   "<constructor>"   //
//   Plugin.TSQLServer:  ^mysql:  TMySQLServer MySQL  "<constructor>"   //
//   +Plugin.TSQLServer: ^pgsql:  TPgSQLServer PgSQL  "<constructor>"   //
//   Plugin.TVirtualFitter: *     TFitter      Minuit "TFitter(Int_t)"  //
//                                                                      //
// Where the + in front of Plugin.TSQLServer says that it extends the   //
// existing definition of TSQLServer, usefull when there is more than   //
// one plugin that can extend the same base class. The "<constructor>"  //
// should be the constructor or a static method that generates an       //
// instance of the specified class. Global methods should start with    //
// "::" in their name, like "::CreateFitter()".                         //
// Instead of being a shared library a plugin can also be a CINT        //
// script, so instead of libDialog.so one can have Dialog.C.            //
// The * is a placeholder in case there is no need for a URI to         //
// differentiate between different plugins for the same base class.     //
// For the default plugins see $ROOTSYS/etc/system.rootrc.              //
//                                                                      //
// Plugin handlers can also be registered at run time, e.g.:            //
//                                                                      //
//   gROOT->GetPluginManager()->AddHandler("TSQLServer", "^sapdb:",     //
//                                         "TSapDBServer", "SapDB",     //
//             "TSapDBServer(const char*,const char*, const char*)");   //
//                                                                      //
// A list of currently defined handlers can be printed using:           //
//                                                                      //
//   gROOT->GetPluginManager()->Print(); // use option="a" to see ctors //
//                                                                      //
// The use of the plugin library manager removes all textual references //
// to hard-coded class and library names and the resulting dependencies //
// in the base classes. The plugin manager is used to extend a.o.       //
// TFile, TSQLServer, TGrid, etc. functionality.                        //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TPluginManager.h"
#include "TEnv.h"
#include "TRegexp.h"
#include "TROOT.h"
#include "TList.h"
#include "TOrdCollection.h"
#include "Varargs.h"
#include "TClass.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TDataType.h"
#include "TMethodCall.h"
#include "TVirtualMutex.h"

ClassImp(TPluginHandler)
ClassImp(TPluginManager)

//______________________________________________________________________________
TPluginHandler::TPluginHandler(const char *base, const char *regexp,
                               const char *className, const char *pluginName,
                               const char *ctor)
{
   // Create a plugin handler. Called by TPluginManager.

   fBase     = base;
   fRegexp   = regexp;
   fClass    = className;
   fPlugin   = pluginName;
   fCtor     = ctor;
   fCallEnv  = 0;
   fCanCall  = 0;
   fIsMacro  = kFALSE;
   fIsGlobal = kFALSE;

   if (gROOT->LoadMacro(pluginName, 0, kTRUE) == 0)
      fIsMacro = kTRUE;

   if (fCtor.Contains("::")) {
      fIsGlobal = kTRUE;
      fCtor = fCtor.Strip(TString::kLeading, ':');
   }
}

//______________________________________________________________________________
TPluginHandler::~TPluginHandler()
{
   // Cleanup plugin handler object.

   delete fCallEnv;
}

//______________________________________________________________________________
Bool_t TPluginHandler::CanHandle(const char *base, const char *uri)
{
   // Check if regular expression appears in the URI, if so return kTRUE.
   // If URI = 0 always return kTRUE.

   if (fBase != base)
      return kFALSE;

   if (!uri)
      return kTRUE;

   Bool_t wildcard = kFALSE;
   if (!fRegexp.MaybeRegexp())
      wildcard = kTRUE;

   TRegexp re(fRegexp, wildcard);
   TString ruri = uri;

   if (ruri.Index(re) != kNPOS)
      return kTRUE;
   return kFALSE;
}

//______________________________________________________________________________
void TPluginHandler::SetupCallEnv()
{
   // Setup ctor or static method call environment.

   fCanCall = -1;

   // check if class exists
   TClass *cl = gROOT->GetClass(fClass);
   if (!cl) {
      Error("SetupCallEnv", "class %s not found in plugin %s", fClass.Data(),
            fPlugin.Data());
      return;
   }

   // split method and prototype strings
   TString method = fCtor(0, fCtor.Index("("));
   TString proto  = fCtor(fCtor.Index("(")+1, fCtor.Index(")")-fCtor.Index("(")-1);

   if (fIsGlobal) {
      cl = 0;
      if (fIsMacro)
         fMethod = gROOT->GetGlobalFunction(method, 0, kTRUE);  // to be fixed
      else
         fMethod = gROOT->GetGlobalFunctionWithPrototype(method, proto, kTRUE);
   } else {
      if (fIsMacro)
         fMethod = cl->GetMethodAny(method);  //to be fixed to use prototype
      else
         fMethod = cl->GetMethodWithPrototype(method, proto);
   }

   if (!fMethod) {
      Error("SetupCallEnv", "method %s not found in class %s", method.Data(),
            fClass.Data());
      return;
   }

   if (!fIsGlobal && !(fMethod->Property() & kIsPublic)) {
      Error("SetupCallEnv", "method %s is not public", method.Data());
      return;
   }

   fCallEnv = new TMethodCall;
   fCallEnv->InitWithPrototype(cl, method, proto);

   fCanCall = 1;

   return;
}

//______________________________________________________________________________
Int_t TPluginHandler::CheckPlugin()
{
   // Check if the plugin library for this handler exits. Returns 0
   // when it exists and -1 in case the plugin does not exist.

   if (fIsMacro) {
      if (gROOT->GetClass(fClass)) return 0;
      return gROOT->LoadMacro(fPlugin, 0, kTRUE);
   } else
      return gROOT->LoadClass(fClass, fPlugin, kTRUE);
}

//______________________________________________________________________________
Int_t TPluginHandler::LoadPlugin()
{
   // Load the plugin library for this handler. Returns 0 on successful loading
   // and -1 in case the library does not exist or in case of error.

   if (fIsMacro) {
      if (gROOT->GetClass(fClass)) return 0;
      return gROOT->LoadMacro(fPlugin);
   } else
      return gROOT->LoadClass(fClass, fPlugin);
}

//______________________________________________________________________________
Long_t TPluginHandler::ExecPlugin(Int_t va_(nargs), ...)
{
   // Execute ctor for this plugin and return pointer to object of specific
   // class. User must cast the returned long to the correct class.
   // This method accepts a variable number of arguments to be passed
   // to the ctor, where nargs is the number of arguments, followed
   // by nargs arguments. Returns 0 in case of error.

   if (fCtor.IsNull()) {
      Error("ExecPlugin", "no ctor specified for this handler %s", fClass.Data());
      return 0;
   }

   if (!fCallEnv && fCanCall == 0)
      SetupCallEnv();

   if (fCanCall == -1)
      return 0;

   if (nargs < fMethod->GetNargs() - fMethod->GetNargsOpt() ||
       nargs > fMethod->GetNargs()) {
      Error("ExecPlugin", "nargs (%d) not consistent with expected number of arguments ([%d-%d])",
            nargs, fMethod->GetNargs() - fMethod->GetNargsOpt(),
            fMethod->GetNargs());
      return 0;
   }

   Long_t *args = 0;

   if (nargs > 0) {
      TIter next(fMethod->GetListOfMethodArgs());
      TMethodArg *arg;

      va_list ap;
      va_start(ap, va_(nargs));

      args = new Long_t[nargs+1];
      args[nargs] = 0;   // sentinel

      for (int i = 0; i < nargs; i++) {
         union {
           float f;
           long  l;
         } u;
         arg = (TMethodArg*) next();
         TString type = arg->GetFullTypeName();
         TDataType *dt = gROOT->GetType(type);
         if (dt)
            type = dt->GetFullTypeName();
         if (arg->Property() & (kIsPointer | kIsArray | kIsReference))
            args[i] = (Long_t) va_arg(ap, void*);
         else if (type == "bool")
            args[i] = (Long_t) va_arg(ap, int);  // bool is promoted to int
         else if (type == "char" || type == "unsigned char")
            args[i] = (Long_t) va_arg(ap, int);  // char is promoted to int
         else if (type == "short" || type == "unsigned short")
            args[i] = (Long_t) va_arg(ap, int);  // short is promoted to int
         else if (type == "int" || type == "unsigned int")
            args[i] = (Long_t) va_arg(ap, int);
         else if (type == "long" || type == "unsigned long")
            args[i] = (Long_t) va_arg(ap, long);
         else if (type == "long long" || type == "unsigned long long")
            args[i] = (Long_t) va_arg(ap, Long64_t);
         else if (type == "float") {
            u.f = (Float_t) va_arg(ap, double);  // float is promoted to double
            args[i] = (Long_t) u.l;
         } else if (type == "double") {
            u.f = (Float_t) va_arg(ap, double);
            args[i] = (Long_t) u.l;
         }
      }

      va_end(ap);

      fCallEnv->SetParamPtrs(args, nargs);
   }

   R__LOCKGUARD(gCINTMutex);
   Long_t ret;
   fCallEnv->Execute(ret);

   delete [] args;

   return ret;
}

//______________________________________________________________________________
TPluginManager::~TPluginManager()
{
   // Clean up the plugin manager.

   delete fHandlers;
}

//______________________________________________________________________________
void TPluginManager::LoadHandlersFromEnv(TEnv *env)
{
   // Load plugin handlers specified in config file, like:
   //    Plugin.TFile:       ^rfio:    TRFIOFile      RFIO  "TRFIOFile(...)"
   //    Plugin.TSQLServer:  ^mysql:   TMySQLServer   MySQL "TMySQLServer(...)"
   //    +Plugin.TSQLServer: ^pgsql:   TPgSQLServer   PgSQL "TPgSQLServer(...)"
   // The + allows the extension of an already defined resource (see TEnv).

   if (!env) return;

   TIter next(env->GetTable());
   TEnvRec *er;

   while ((er = (TEnvRec*) next())) {
      const char *s;
      if ((s = strstr(er->GetName(), "Plugin."))) {
         const char *val = env->GetValue(er->GetName(), (const char*)0);
         if (val) {
            Int_t cnt = 0;
            char *v = StrDup(val);
            s += 7;
            while (1) {
               TString regexp = strtok(!cnt ? v : 0, "; ");
               if (regexp.IsNull()) break;
               TString clss   = strtok(0, "; ");
               if (clss.IsNull()) break;
               TString plugin = strtok(0, "; ");
               if (plugin.IsNull()) break;
               strtok(0, ";\"");
               TString ctor = strtok(0, ";\"");
               AddHandler(s, regexp, clss, plugin, ctor);
               cnt++;
            }
            delete [] v;
         }
      }
   }
}

//______________________________________________________________________________
void TPluginManager::AddHandler(const char *base, const char *regexp,
                                const char *className, const char *pluginName,
                                const char *ctor)
{
   // Add plugin handler to the list of handlers. If there is already a
   // handler defined for the same base and regexp it will be replaced.

   if (!fHandlers) {
      fHandlers = new TList;
      fHandlers->IsOwner();
   }

   // make sure there is no previous handler for the same case
   RemoveHandler(base, regexp);

   TPluginHandler *h = new TPluginHandler(base, regexp, className,
                                          pluginName, ctor);
   fHandlers->Add(h);
}

//______________________________________________________________________________
void TPluginManager::RemoveHandler(const char *base, const char *regexp)
{
   // Remove handler for the specified base class and the specified
   // regexp. If regexp=0 remove all handlers for the specified base.

   if (!fHandlers) return;

   TIter next(fHandlers);
   TPluginHandler *h;

   while ((h = (TPluginHandler*) next())) {
      if (h->fBase == base) {
         if (!regexp || h->fRegexp == regexp) {
            fHandlers->Remove(h);
            delete h;
         }
      }
   }
}

//______________________________________________________________________________
TPluginHandler *TPluginManager::FindHandler(const char *base, const char *uri)
{
   // Returns the handler if there exists a handler for the specified URI.
   // The uri can be 0 in which case the first matching plugin handler
   // will be returned. Returns 0 in case handler is not found.

   if (!fHandlers) return 0;

   TIter next(fHandlers);
   TPluginHandler *h;

   while ((h = (TPluginHandler*) next())) {
      if (h->CanHandle(base, uri)) {
         if (gDebug > 0)
            Info("FindHandler", "found plugin for %s", h->GetClass());
         return h;
      }
   }

   if (gDebug > 0) {
      if (uri)
         Info("FindHandler", "did not find plugin for class %s and uri %s", base, uri);
      else
         Info("FindHandler", "did not find plugin for class %s", base);
   }

   return 0;
}

//______________________________________________________________________________
void TPluginManager::Print(Option_t *opt) const
{
   // Print list of registered plugin handlers. If option is "a" print
   // also the ctor's that will be used.

   if (!fHandlers) return;

   TIter next(fHandlers);
   TPluginHandler *h;

   printf("=====================================================================\n");
   printf("Base                 Regexp        Class              Plugin\n");
   printf("=====================================================================\n");

   while ((h = (TPluginHandler*) next())) {
      const char *exist = "";
      if (h->CheckPlugin() == -1)
         exist = " [*]";
      printf("%-20s %-13s %-18s %s%s\n", h->fBase.Data(), h->fRegexp.Data(),
             h->fClass.Data(), h->fPlugin.Data(), exist);
      if (strchr(opt, 'a'))
         printf("  [Ctor: %s]\n", h->fCtor.Data());
   }
   printf("=====================================================================\n");
   printf("[*] plugin not available\n");
   printf("=====================================================================\n\n");
}
<|endoftext|>