<commit_before>#include <iostream>

#include "base/str.h"
#include "base/cc.h"
#include "base/filesystem.h"

#include "api/app.h"
#include "api/main.h"
#include "api/rencache.h"
#include "api/image.h"
#include "api/font.h"

#include "libride/document.h"

#include "ride/theme.h"
#include "ride/view.h"

#include "logo_256text_png.h"

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

ListSettings list_settings_from_theme(const Theme& theme)
{
    return {theme.sort_files, theme.directories_first};
}

struct Node
{
    std::string name;
    std::string path;
    vec2<pix> position;

    int depth;

    Node(const std::string& n, const std::string p)
        : name(n)
        , path(p)
        , position{0_px, 0_px}
        , depth{0}
    {}

    virtual ~Node() {}

    bool IsHidden() const
    {
        if(name.empty()) { return false; }
        else { return name[0] == '.'; }
    }

    virtual bool OnClick(bool is_doubleclick, filesystem* fs, const Theme& theme) = 0;
    virtual void Add(std::vector<Node*>* ret, int depth) = 0;
    virtual Color GetColor(const Theme&) const = 0;
};

struct FileNode : public Node
{
    explicit FileNode(const FileEntry& f) : Node(f.name, f.path) {}

    Color GetColor(const Theme& theme) const override
    {
        return IsHidden() ? theme.filesys_hidden_color : theme.filesys_file_color;
    }

    bool OnClick(bool is_doubleclick, filesystem*, const Theme&) override
    {
        if(is_doubleclick)
        {
            std::cout << "Open or focus " << path << "\n";
        }
        return false;
    }
    void Add(std::vector<Node*>* ret, int d) override
    {
        ret->emplace_back(this);
        depth = d;
    }
};

std::vector<std::shared_ptr<Node>> Create(const std::vector<FileEntry>& files);

struct DirectoryNode : public Node
{
    std::string base_name;
    bool is_open = false;

    std::vector<std::shared_ptr<Node>> children;

    explicit DirectoryNode(const FileEntry& f) : Node(f.name, f.path), base_name(Str{} << f.name << "/")
    {
        UpdateName();
    }

    void UpdateName()
    {
        if(is_open) { name = Str{} << "- " << base_name; }
        else        { name = Str{} << "+ " << base_name; }
    }

    Color GetColor(const Theme& theme) const override
    {
        return IsHidden() ? theme.filesys_hidden_color : theme.filesys_folder_color;
    }

    bool OnClick(bool, filesystem* filesystem, const Theme& theme) override
    {
        if(is_open)
        {
            is_open = false;
            children.clear();
        }
        else
        {
            is_open = true;
            auto folders_and_files = filesystem->list(path, list_settings_from_theme(theme));
            if(folders_and_files)
            {
                children = Create(*folders_and_files);
            }
        }

        UpdateName();
        return true;
    }
    void Add(std::vector<Node*>* ret, int d) override
    {
        ret->emplace_back(this);
        for(auto c: children)
        {
            c->Add(ret, d+1);
        }
        depth = d;
    }
};

std::shared_ptr<Node> Create(const FileEntry& f)
{
    if(f.is_directory) { return std::make_shared<DirectoryNode>(f); }
    else { return std::make_shared<FileNode>(f); }
}

std::vector<std::shared_ptr<Node>> Create(const std::vector<FileEntry>& files)
{
    std::vector<std::shared_ptr<Node>> entries;

    for(const auto& e: files)
    {
        entries.emplace_back(Create(e));
    }

    return entries;
}

struct ViewFilesystem : public View
{
    std::shared_ptr<Font> font;
    //std::shared_ptr<Theme> theme;
    filesystem* fs;
    std::string root;

    std::vector<std::shared_ptr<Node>> roots;
    std::vector<Node*> entries; // stored in roots

    Node* node_hovering = nullptr;
    vec2<pix> last_mouse = {0_px, 0_px};
    pix body_width = 0_px;

    std::vector<Node*> CreateEntries()
    {
        std::vector<Node*> ret;
        for(auto r: roots)
        {
            r->Add(&ret, 0);
        }

        return ret;
    }

    void update_rects_for_entries()
    {
        body_width = 0_px;
        for(std::size_t index = 0; index < entries.size(); index += 1)
        {
            auto* e = entries[index];
            const auto p = vec2<pix>
            {
                theme->filesys_left_padding + static_cast<double>(e->depth) * theme->filesys_indent,
                LineNumberToY(index)
            };

            const auto width = app->to_pix(font->get_width(e->name));
            const auto total_width = width + p.x;

            if(total_width > body_width)
            {
                body_width = total_width;
            }

            e->position = p;
        }
    }

    void Populate()
    {
        node_hovering = nullptr;
        entries = CreateEntries();
        update_rects_for_entries();
        update_hover();
        // ViewChanged();
    }

    void setup()
    {
        auto folders_and_files = fs->list(root, list_settings_from_theme(*theme));
        if(folders_and_files)
        {
            roots = Create(*folders_and_files);
        }
        Populate();
    }

    pix calculate_line_height() const
    {
        return app->to_pix(font->get_height()) + theme->line_spacing;
    }

    pix LineNumberToY(std::size_t line) const
    {
        return static_cast<double>(line) * calculate_line_height();
    }

    scroll_size calculate_scroll_size() override
    {
        return
        {
            body_width,
            static_cast<double>(entries.size()) * calculate_line_height()
        };
    }

    rect<pix> hit_rect_for_node(Node* node)
    {
        assert(node);
        const auto height = app->to_pix(font->get_height());
        const auto spacing = theme->line_spacing;
        const auto half_spacing = spacing / 2.0;

        return
        {
            position.x,
            node->position.y,
            client_size.width,
            height + spacing
        };
    }

    void draw_body(const rect<pix>& main_view_rect, RenCache* cache) override
    {
        cache->draw_rect(app->to_dip(main_view_rect), theme->filesys_background_color);

        if(node_hovering)
        {
            cache->draw_rect(app->to_dip(hit_rect_for_node(node_hovering)), theme->filesys_hover_color);
        }

        for(const auto& e: entries)
        {
            cache->draw_text
            (
                font,
                e->name,
                app->to_dip(main_view_rect.x + e->position.x - scroll.x),
                app->to_dip(main_view_rect.y + e->position.y - scroll.y),
                e->GetColor(*theme)
            );
        }
    }

    /*

    int GetLineNumberTop()
    {
        int top = GetClientTop();
        const auto line_top = static_cast<int>(std::floor(static_cast<float>(top) / static_cast<float>(font->line_height)));
        return line_top;
    }

    int GetLineNumberBottom()
    {
        int bottom = GetClientBottom();
        const auto line_bottom = static_cast<int>(std::ceil(static_cast<float>(bottom) / static_cast<float>(font->line_height)));
        return line_bottom;
    }
    */

    Node* get_node_under_cursor(const vec2<pix> relative_mouse)
    {
        const auto p = vec2<pix>{relative_mouse.x + scroll.x, relative_mouse.y + scroll.y};

        // todo(Gustav): guesstimate entry from y coordinate and then do the checks to avoid checking all the items...
        for(const auto& e: entries)
        {
            if(hit_rect_for_node(e).contains(p))
            {
                return e;
            }
        }

        return nullptr;
    }

    void on_mouse_pressed(MouseButton button, pix x, pix y, int clicks) override
    {
        if(button != MouseButton::left) { return; }
        if(clicks > 2) { return; }

        auto* node = get_node_under_cursor({x, y});
        if(node)
        {
            if(node->OnClick(clicks == 2, fs, *theme))
            {
                Populate();
            }
        }
    }

    void on_mouse_moved(const vec2<pix>& new_mouse) override
    {
        last_mouse = new_mouse;
        update_hover();
    }

    void update_hover()
    {
        node_hovering = get_node_under_cursor(last_mouse);
    }
};

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

struct ViewDoc : View
{
    Document doc;
    std::shared_ptr<Font> font;

    pix calculate_line_height()
    {
        return  app->to_pix(font->get_height()) + theme->line_spacing;
    }

    pix get_document_height()
    {
        const auto lines = doc.GetNumberOfLines();
        const auto spacing = calculate_line_height();

        // todo(Gustav): fix cast here
        return spacing * static_cast<double>(lines);
    }

    pix get_document_width()
    {
        const auto longest_line = std::max_element
        (
            doc.lines.begin(), doc.lines.end(),
            [](const std::string& lhs, const std::string& rhs) -> bool
            {
                return lhs.length() < rhs.length();
            }
        );

        if(longest_line == doc.lines.end())
        {
            return 0_px;
        }

        return app->to_pix(font->get_width(*longest_line));
    }

    scroll_size calculate_scroll_size() override
    {
        const auto line_height = calculate_line_height();

        const auto w = get_document_width();
        const auto h = get_document_height() - line_height;

        return {w, h};
    }

    void draw_body(const rect<pix>& main_view_rect, RenCache* cache) override
    {
        const auto lines = doc.GetNumberOfLines();

        const auto min_gutter_width = app->to_pix(font->get_width( (Str{} << (lines+1)).ToString().c_str() ));
        const auto gutter_width = min_gutter_width + theme->gutter_spacing_left + theme->gutter_spacing_right;

        auto view_rect = main_view_rect;
        const auto gutter_rect = view_rect.cut_left(gutter_width);

        const auto spacing = calculate_line_height();

        cache->draw_rect(app->to_dip(main_view_rect), theme->edit_background);
        cache->draw_rect(app->to_dip(gutter_rect), theme->gutter_background);

        for(int line_index=0; line_index<lines; line_index += 1)
        {
            const auto y = static_cast<double>(line_index) * spacing - scroll.y;

            cache->draw_text
            (
                font,
                (Str{} << line_index+1).ToString(),
                app->to_dip(main_view_rect.x + theme->gutter_spacing_left),
                app->to_dip(main_view_rect.y + y),
                theme->gutter_color
            );

            {
                const auto text_scope = ClipScope(cache, app->to_dip(view_rect));
                cache->draw_text
                (
                    font,
                    doc.GetLineAt(line_index),
                    app->to_dip(main_view_rect.x + gutter_width + theme->text_spacing - scroll.x),
                    app->to_dip(main_view_rect.y + y),
                    theme->plain_text_color
                );
            }
        }
    }
};

struct RideApp : App
{
    vec2<pix> mouse = {pix{0}, pix{0}};

    std::shared_ptr<Image> logo;
    std::shared_ptr<Font> font;
    std::unique_ptr<filesystem> fs;

    Theme theme;

    ViewDoc root;
    ViewFilesystem browser;

    void setup_view(View* view)
    {
        view->theme = &theme;
        view->app = this;
    }

    RideApp()
        : logo(load_shared(LOGO_256TEXT_PNG))
        , font(load_font(Font::default_font, pix{12}))
        , fs(create_local_filesystem())
    {
        setup_view(&root);
        root.font = font;
        root.doc.LoadFile(fs.get(), __FILE__);

        setup_view(&browser);
        browser.font = font;
        browser.fs = fs.get();
        if(auto cd = fs->get_current_directory(); cd)
        {
            browser.root = *cd;
            browser.setup();
        }
    }

    void on_mouse_moved(const vec2<pix>& new_mouse, pix xrel, pix yrel) override
    {
        mouse = new_mouse;

        View* view = get_mouse_hovering_view();
        if(view == nullptr) { return; }
        view->on_mouse_moved(new_mouse);
    }

    void draw(RenCache* cache) override
    {
        auto rect = ::rect<pix>::from_size(client_size);
        cache->draw_rect(to_dip(rect), theme.window_background_color);

        cache->draw_image(logo, to_dip(pix{10}), to_dip(pix{10}), theme.logo_color);

        const auto browser_rect = rect.cut_left(150_px);

        const auto border_size = 3_px;

        browser.set_rect(browser_rect.Inset(border_size));
        root.set_rect(rect.Inset(border_size));

        browser.draw(cache);
        root.draw(cache);

        #if 0
        cache->draw_rect
        (
            to_dip
            (
                ::rect<pix>
                {
                    mouse,
                    ::size<pix>
                    {
                        pix{10},
                        pix{10}
                    }
                }
            ),
            Color::rgb(0, 0, 255, 255)
        );
        #endif
    }

    View* get_mouse_hovering_view()
    {
        if( root.get_rect().contains(mouse))
        {
            return &root;
        }
        else if( browser.get_rect().contains(mouse))
        {
            return &browser;
        }
        else return nullptr;
    }

    void on_mouse_pressed(MouseButton button, pix x, pix y, int clicks) override
    {
        View* view = get_mouse_hovering_view();
        if(view == nullptr) { return; }

        view->on_mouse_pressed(button, x, y, clicks);
    }

    void on_mouse_wheel(int dx, int dy) override
    {
        View* view = get_mouse_hovering_view();
        if(view)
        {
            view->on_mouse_wheel(dx, dy);
        }
        else
        {
            std::cout << "Not hovering...\n";
        }

    }
};

int main(int argc, char** argv)
{
    return run_main(argc, argv, [](const StartupArguments&) -> std::unique_ptr<App> { return std::make_unique<RideApp>();});
}

<commit_msg>feat(treeview): make sure the user can't scroll outside the body<commit_after>#include <iostream>

#include "base/str.h"
#include "base/cc.h"
#include "base/filesystem.h"

#include "api/app.h"
#include "api/main.h"
#include "api/rencache.h"
#include "api/image.h"
#include "api/font.h"

#include "libride/document.h"

#include "ride/theme.h"
#include "ride/view.h"

#include "logo_256text_png.h"

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

ListSettings list_settings_from_theme(const Theme& theme)
{
    return {theme.sort_files, theme.directories_first};
}

struct Node
{
    std::string name;
    std::string path;
    vec2<pix> position;

    int depth;

    Node(const std::string& n, const std::string p)
        : name(n)
        , path(p)
        , position{0_px, 0_px}
        , depth{0}
    {}

    virtual ~Node() {}

    bool IsHidden() const
    {
        if(name.empty()) { return false; }
        else { return name[0] == '.'; }
    }

    virtual bool OnClick(bool is_doubleclick, filesystem* fs, const Theme& theme) = 0;
    virtual void Add(std::vector<Node*>* ret, int depth) = 0;
    virtual Color GetColor(const Theme&) const = 0;
};

struct FileNode : public Node
{
    explicit FileNode(const FileEntry& f) : Node(f.name, f.path) {}

    Color GetColor(const Theme& theme) const override
    {
        return IsHidden() ? theme.filesys_hidden_color : theme.filesys_file_color;
    }

    bool OnClick(bool is_doubleclick, filesystem*, const Theme&) override
    {
        if(is_doubleclick)
        {
            std::cout << "Open or focus " << path << "\n";
        }
        return false;
    }
    void Add(std::vector<Node*>* ret, int d) override
    {
        ret->emplace_back(this);
        depth = d;
    }
};

std::vector<std::shared_ptr<Node>> Create(const std::vector<FileEntry>& files);

struct DirectoryNode : public Node
{
    std::string base_name;
    bool is_open = false;

    std::vector<std::shared_ptr<Node>> children;

    explicit DirectoryNode(const FileEntry& f) : Node(f.name, f.path), base_name(Str{} << f.name << "/")
    {
        UpdateName();
    }

    void UpdateName()
    {
        if(is_open) { name = Str{} << "- " << base_name; }
        else        { name = Str{} << "+ " << base_name; }
    }

    Color GetColor(const Theme& theme) const override
    {
        return IsHidden() ? theme.filesys_hidden_color : theme.filesys_folder_color;
    }

    bool OnClick(bool, filesystem* filesystem, const Theme& theme) override
    {
        if(is_open)
        {
            is_open = false;
            children.clear();
        }
        else
        {
            is_open = true;
            auto folders_and_files = filesystem->list(path, list_settings_from_theme(theme));
            if(folders_and_files)
            {
                children = Create(*folders_and_files);
            }
        }

        UpdateName();
        return true;
    }
    void Add(std::vector<Node*>* ret, int d) override
    {
        ret->emplace_back(this);
        for(auto c: children)
        {
            c->Add(ret, d+1);
        }
        depth = d;
    }
};

std::shared_ptr<Node> Create(const FileEntry& f)
{
    if(f.is_directory) { return std::make_shared<DirectoryNode>(f); }
    else { return std::make_shared<FileNode>(f); }
}

std::vector<std::shared_ptr<Node>> Create(const std::vector<FileEntry>& files)
{
    std::vector<std::shared_ptr<Node>> entries;

    for(const auto& e: files)
    {
        entries.emplace_back(Create(e));
    }

    return entries;
}

pix keep_above_zero(pix p)
{
    if(p.value > 0) { return p; }
    else return 0_px;
}

struct ViewFilesystem : public View
{
    std::shared_ptr<Font> font;
    //std::shared_ptr<Theme> theme;
    filesystem* fs;
    std::string root;

    std::vector<std::shared_ptr<Node>> roots;
    std::vector<Node*> entries; // stored in roots

    Node* node_hovering = nullptr;
    vec2<pix> last_mouse = {0_px, 0_px};
    pix body_width = 0_px;

    std::vector<Node*> CreateEntries()
    {
        std::vector<Node*> ret;
        for(auto r: roots)
        {
            r->Add(&ret, 0);
        }

        return ret;
    }

    void update_rects_for_entries()
    {
        body_width = 0_px;
        for(std::size_t index = 0; index < entries.size(); index += 1)
        {
            auto* e = entries[index];
            const auto p = vec2<pix>
            {
                theme->filesys_left_padding + static_cast<double>(e->depth) * theme->filesys_indent,
                LineNumberToY(index)
            };

            const auto width = app->to_pix(font->get_width(e->name));
            const auto total_width = width + p.x;

            if(total_width > body_width)
            {
                body_width = total_width;
            }

            e->position = p;
        }
    }

    void Populate()
    {
        node_hovering = nullptr;
        entries = CreateEntries();
        update_rects_for_entries();
        update_hover();
        // ViewChanged();
    }

    void setup()
    {
        auto folders_and_files = fs->list(root, list_settings_from_theme(*theme));
        if(folders_and_files)
        {
            roots = Create(*folders_and_files);
        }
        Populate();
    }

    pix calculate_line_height() const
    {
        return app->to_pix(font->get_height()) + theme->line_spacing;
    }

    pix LineNumberToY(std::size_t line) const
    {
        return static_cast<double>(line) * calculate_line_height();
    }

    scroll_size calculate_scroll_size() override
    {
        return
        {
            // todo(Gustav): is this correct?
            keep_above_zero(body_width - client_size.width),
            keep_above_zero(static_cast<double>(entries.size()) * calculate_line_height() - client_size.height)
        };
    }

    rect<pix> hit_rect_for_node(Node* node)
    {
        assert(node);
        const auto height = app->to_pix(font->get_height());
        const auto spacing = theme->line_spacing;
        const auto half_spacing = spacing / 2.0;

        return
        {
            position.x,
            node->position.y,
            client_size.width,
            height + spacing
        };
    }

    void draw_body(const rect<pix>& main_view_rect, RenCache* cache) override
    {
        cache->draw_rect(app->to_dip(main_view_rect), theme->filesys_background_color);

        if(node_hovering)
        {
            cache->draw_rect(app->to_dip(hit_rect_for_node(node_hovering)), theme->filesys_hover_color);
        }

        for(const auto& e: entries)
        {
            cache->draw_text
            (
                font,
                e->name,
                app->to_dip(main_view_rect.x + e->position.x - scroll.x),
                app->to_dip(main_view_rect.y + e->position.y - scroll.y),
                e->GetColor(*theme)
            );
        }
    }

    /*

    int GetLineNumberTop()
    {
        int top = GetClientTop();
        const auto line_top = static_cast<int>(std::floor(static_cast<float>(top) / static_cast<float>(font->line_height)));
        return line_top;
    }

    int GetLineNumberBottom()
    {
        int bottom = GetClientBottom();
        const auto line_bottom = static_cast<int>(std::ceil(static_cast<float>(bottom) / static_cast<float>(font->line_height)));
        return line_bottom;
    }
    */

    Node* get_node_under_cursor(const vec2<pix> relative_mouse)
    {
        const auto p = vec2<pix>{relative_mouse.x + scroll.x, relative_mouse.y + scroll.y};

        // todo(Gustav): guesstimate entry from y coordinate and then do the checks to avoid checking all the items...
        for(const auto& e: entries)
        {
            if(hit_rect_for_node(e).contains(p))
            {
                return e;
            }
        }

        return nullptr;
    }

    void on_mouse_pressed(MouseButton button, pix x, pix y, int clicks) override
    {
        if(button != MouseButton::left) { return; }
        if(clicks > 2) { return; }

        auto* node = get_node_under_cursor({x, y});
        if(node)
        {
            if(node->OnClick(clicks == 2, fs, *theme))
            {
                Populate();
            }
        }
    }

    void on_mouse_moved(const vec2<pix>& new_mouse) override
    {
        last_mouse = new_mouse;
        update_hover();
    }

    void update_hover()
    {
        node_hovering = get_node_under_cursor(last_mouse);
    }
};

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

struct ViewDoc : View
{
    Document doc;
    std::shared_ptr<Font> font;

    pix calculate_line_height()
    {
        return  app->to_pix(font->get_height()) + theme->line_spacing;
    }

    pix get_document_height()
    {
        const auto lines = doc.GetNumberOfLines();
        const auto spacing = calculate_line_height();

        // todo(Gustav): fix cast here
        return spacing * static_cast<double>(lines);
    }

    pix get_document_width()
    {
        const auto longest_line = std::max_element
        (
            doc.lines.begin(), doc.lines.end(),
            [](const std::string& lhs, const std::string& rhs) -> bool
            {
                return lhs.length() < rhs.length();
            }
        );

        if(longest_line == doc.lines.end())
        {
            return 0_px;
        }

        return app->to_pix(font->get_width(*longest_line));
    }

    scroll_size calculate_scroll_size() override
    {
        const auto line_height = calculate_line_height();

        const auto w = get_document_width();
        const auto h = get_document_height() - line_height;

        return {w, h};
    }

    void draw_body(const rect<pix>& main_view_rect, RenCache* cache) override
    {
        const auto lines = doc.GetNumberOfLines();

        const auto min_gutter_width = app->to_pix(font->get_width( (Str{} << (lines+1)).ToString().c_str() ));
        const auto gutter_width = min_gutter_width + theme->gutter_spacing_left + theme->gutter_spacing_right;

        auto view_rect = main_view_rect;
        const auto gutter_rect = view_rect.cut_left(gutter_width);

        const auto spacing = calculate_line_height();

        cache->draw_rect(app->to_dip(main_view_rect), theme->edit_background);
        cache->draw_rect(app->to_dip(gutter_rect), theme->gutter_background);

        for(int line_index=0; line_index<lines; line_index += 1)
        {
            const auto y = static_cast<double>(line_index) * spacing - scroll.y;

            cache->draw_text
            (
                font,
                (Str{} << line_index+1).ToString(),
                app->to_dip(main_view_rect.x + theme->gutter_spacing_left),
                app->to_dip(main_view_rect.y + y),
                theme->gutter_color
            );

            {
                const auto text_scope = ClipScope(cache, app->to_dip(view_rect));
                cache->draw_text
                (
                    font,
                    doc.GetLineAt(line_index),
                    app->to_dip(main_view_rect.x + gutter_width + theme->text_spacing - scroll.x),
                    app->to_dip(main_view_rect.y + y),
                    theme->plain_text_color
                );
            }
        }
    }
};

struct RideApp : App
{
    vec2<pix> mouse = {pix{0}, pix{0}};

    std::shared_ptr<Image> logo;
    std::shared_ptr<Font> font;
    std::unique_ptr<filesystem> fs;

    Theme theme;

    ViewDoc root;
    ViewFilesystem browser;

    void setup_view(View* view)
    {
        view->theme = &theme;
        view->app = this;
    }

    RideApp()
        : logo(load_shared(LOGO_256TEXT_PNG))
        , font(load_font(Font::default_font, pix{12}))
        , fs(create_local_filesystem())
    {
        setup_view(&root);
        root.font = font;
        root.doc.LoadFile(fs.get(), __FILE__);

        setup_view(&browser);
        browser.font = font;
        browser.fs = fs.get();
        if(auto cd = fs->get_current_directory(); cd)
        {
            browser.root = *cd;
            browser.setup();
        }
    }

    void on_mouse_moved(const vec2<pix>& new_mouse, pix xrel, pix yrel) override
    {
        mouse = new_mouse;

        View* view = get_mouse_hovering_view();
        if(view == nullptr) { return; }
        view->on_mouse_moved(new_mouse);
    }

    void draw(RenCache* cache) override
    {
        auto rect = ::rect<pix>::from_size(client_size);
        cache->draw_rect(to_dip(rect), theme.window_background_color);

        cache->draw_image(logo, to_dip(pix{10}), to_dip(pix{10}), theme.logo_color);

        const auto browser_rect = rect.cut_left(150_px);

        const auto border_size = 3_px;

        browser.set_rect(browser_rect.Inset(border_size));
        root.set_rect(rect.Inset(border_size));

        browser.draw(cache);
        root.draw(cache);

        #if 0
        cache->draw_rect
        (
            to_dip
            (
                ::rect<pix>
                {
                    mouse,
                    ::size<pix>
                    {
                        pix{10},
                        pix{10}
                    }
                }
            ),
            Color::rgb(0, 0, 255, 255)
        );
        #endif
    }

    View* get_mouse_hovering_view()
    {
        if( root.get_rect().contains(mouse))
        {
            return &root;
        }
        else if( browser.get_rect().contains(mouse))
        {
            return &browser;
        }
        else return nullptr;
    }

    void on_mouse_pressed(MouseButton button, pix x, pix y, int clicks) override
    {
        View* view = get_mouse_hovering_view();
        if(view == nullptr) { return; }

        view->on_mouse_pressed(button, x, y, clicks);
    }

    void on_mouse_wheel(int dx, int dy) override
    {
        View* view = get_mouse_hovering_view();
        if(view)
        {
            view->on_mouse_wheel(dx, dy);
        }
        else
        {
            std::cout << "Not hovering...\n";
        }

    }
};

int main(int argc, char** argv)
{
    return run_main(argc, argv, [](const StartupArguments&) -> std::unique_ptr<App> { return std::make_unique<RideApp>();});
}

<|endoftext|>


<commit_before>/*
 * pab.cpp
 *
 * Copyright (C) 1999 Don Sanders <dsanders@kde.org>
 */
#include "abbrowser.h"
#include "browserentryeditor.h"

#include <qkeycode.h>

#include <kiconloader.h>
#include <klocale.h>
#include <kglobal.h>
#include <kmenubar.h>
#include <kconfig.h>
#include <kaccel.h>
#include <kdebug.h>

#include "undo.h"
#include "browserwidget.h"
#include "entry.h"

Pab::Pab() : KMainWindow(0)
{
  setCaption( i18n( "Address Book Browser" ));
  document = new ContactEntryList();
  view = new PabWidget( document, this, "Abbrowser" );

  // tell the KMainWindow that this is indeed the main widget
  setCentralWidget(view);

  // create a popup menu -- in this case, the File menu
  QPopupMenu* p = new QPopupMenu;
  p->insertItem(i18n("&Sync"), this, SLOT(save()), CTRL+Key_S);
  p->insertItem(i18n("&New Contact"), this, SLOT(newContact()), CTRL+Key_N);
  /*  p->insertItem(i18n("New &Group"), this, SLOT(newGroup()), CTRL+Key_G); */
  p->insertSeparator();
  p->insertItem(i18n("&Send Mail"), view, SLOT(sendMail()), CTRL+Key_Return);
  p->insertSeparator();
  p->insertItem(i18n("&Properties"), view, SLOT(properties()));
  p->insertItem(i18n("&Delete\tDel"));
  p->insertSeparator();
  p->insertItem(i18n("&Quit"), kapp, SLOT(quit()), CTRL+Key_Q);

  edit = new QPopupMenu;
  undoId = edit->insertItem(i18n("Undo"), this, SLOT(undo()),
			    KStdAccel::key(KStdAccel::Undo));
  redoId = edit->insertItem(i18n("Redo"), this, SLOT(redo()),
			    KStdAccel::key(KStdAccel::Redo));
  edit->insertSeparator();
  edit->insertItem(i18n("Cut"), view, SLOT(cut()), CTRL+Key_X);
  edit->insertItem(i18n("Copy"), view, SLOT(copy()), CTRL+Key_C);
  edit->insertItem(i18n("Paste"), view, SLOT(paste()), CTRL+Key_V);
  edit->insertSeparator();
  edit->insertItem(i18n("Select All"), view, SLOT(selectAll()), CTRL+Key_A);
  edit->setItemEnabled( undoId, false );
  edit->setItemEnabled( redoId, false );
  QObject::connect( edit, SIGNAL( aboutToShow() ), this, SLOT( updateEditMenu() ));

  QPopupMenu* v = new QPopupMenu;
  v->insertItem(i18n("Choose Fields..."), view, SLOT(showSelectNameDialog()) );
  v->insertItem(i18n("Options..."), view, SLOT(viewOptions()) );
  v->insertSeparator();
  v->insertItem(i18n("Restore defaults"), view, SLOT(defaultSettings()) );
  //  v->insertSeparator();
  //  v->insertItem(i18n("Refresh"), view, SLOT(refresh()), Key_F5 );

  // put our newly created menu into the main menu bar
  menuBar()->insertItem(i18n("&File"), p);
  menuBar()->insertItem(i18n("&Edit"), edit);
  menuBar()->insertItem(i18n("&View"), v);
  menuBar()->insertSeparator();

  // KDE will generate a short help menu automagically
  p = helpMenu( i18n("Abbrowser --- KDE Address Book\n\n"
		     "(c) 2000AD The KDE PIM Team \n"));

  menuBar()->insertItem(i18n("&Help"), p);

  toolBar()->insertButton(BarIcon("filenew"),   // icon
			  0,                  // button id
			  SIGNAL(clicked()),  // action
			  this, SLOT(newContact()), // result
			  true, i18n("Add a new entry"));      // tooltip text
  toolBar()->insertButton(BarIcon("pencil"),   // icon
			  0,                  // button id
			  SIGNAL(clicked()),  // action
			  view, SLOT(properties()), // result
			  true, i18n("Change this entry"));      // tooltip text
  toolBar()->insertButton(BarIcon("eraser"),   // icon
			  0,                  // button id
			  SIGNAL(clicked()),  // action
			  view, SLOT(clear()), // result
			  true, i18n("Remove this entry"));      // tooltip text
  toolBar()->insertSeparator();
  toolBar()->insertButton(BarIcon("filemail"),   // icon
			  0,                  // button id
			  SIGNAL(clicked()),  // action
			  view, SLOT(sendMail()), // result
			  true, i18n("Send email"));      // tooltip text
  toolBar()->setFullSize(true);

  // we do want a status bar
  statusBar()->show();
  connect( kapp, SIGNAL( aboutToQuit() ), this, SLOT( saveConfig() ) );
  resize( sizeHint() );
  readConfig();
}

void Pab::newContact()
{
  ContactDialog *cd = new PabNewContactDialog( i18n( "Address Book Entry Editor" ), this, 0 );
  connect( cd, SIGNAL( add( ContactEntry* ) ),
	   view, SLOT( addNewEntry( ContactEntry* ) ));
  cd->show();
}

void Pab::addEmail( QString addr )
{
  view->addEmail( addr );
  return;
}

void Pab::save()
{
  document->commit();
  document->refresh();
  view->saveConfig();
  view->readConfig();
  view->reconstructListView();
  //xxx  document->save( "entries.txt" );
    UndoStack::instance()->clear();
    RedoStack::instance()->clear();
}

void Pab::readConfig()
{
  KConfig *config = kapp->config();
  int w, h;
  config->setGroup("Geometry");
   QString str = config->readEntry("Browser", "");
   if (!str.isEmpty() && str.find(',')>=0)
   {
     sscanf(str.local8Bit(),"%d,%d",&w,&h);
     resize(w,h);
   }
}

void Pab::saveConfig()
{
  view->saveConfig();
  KConfig *config = kapp->config();

  config->setGroup("Geometry");
  QRect r = geometry();
  QString s;
  s.sprintf("%i,%i", r.width(), r.height());
  config->writeEntry("Browser", s);
  config->sync();
}

Pab::~Pab()
{
  saveConfig();
  delete document;
}

void Pab::saveCe() {
  kdDebug() << "saveCe()" << endl;
  //xxx  ce->save( "entry.txt" );
}

void Pab::saveProperties(KConfig *)
{
	// the 'config' object points to the session managed
	// config file.  anything you write here will be available
	// later when this app is restored
  //what I want to save
  //windowsize
  //background image/underlining color/alternating color1,2
  //chosen fields
  //chosen fieldsWidths

	// e.g., config->writeEntry("key", var);
}

void Pab::readProperties(KConfig *)
{
	// the 'config' object points to the session managed
	// config file.  this function is automatically called whenever
	// the app is being restored.  read in here whatever you wrote
	// in 'saveProperties'

	// e.g., var = config->readEntry("key");
}

void Pab::undo()
{
  kdDebug() << "Pab::undo()" << endl;
  UndoStack::instance()->undo();
}

void Pab::redo()
{
  RedoStack::instance()->redo();
}

void Pab::updateEditMenu()
{
  kdDebug() << "UpdateEditMenu()" << endl;
  UndoStack *undo = UndoStack::instance();
  RedoStack *redo = RedoStack::instance();

  if (undo->isEmpty())
    edit->changeItem( undoId, i18n( "Undo" ) );
  else
    edit->changeItem( undoId, i18n( "Undo" ) + " " + undo->top()->name() );
  edit->setItemEnabled( undoId, !undo->isEmpty() );

  if (redo->isEmpty())
    edit->changeItem( redoId, i18n( "Redo" ) );
  else
    edit->changeItem( redoId, i18n( "Redo" ) + " " + redo->top()->name() );
  edit->setItemEnabled( redoId, !redo->isEmpty() );
}
<commit_msg>     toolBar()->insertSeparator(); -    toolBar()->insertButton(BarIcon("filemail"),   // icon +    toolBar()->insertButton(BarIcon("mail_send"),   // icon<commit_after>/*
 * pab.cpp
 *
 * Copyright (C) 1999 Don Sanders <dsanders@kde.org>
 */
#include "abbrowser.h"
#include "browserentryeditor.h"

#include <qkeycode.h>

#include <kiconloader.h>
#include <klocale.h>
#include <kglobal.h>
#include <kmenubar.h>
#include <kconfig.h>
#include <kaccel.h>
#include <kdebug.h>

#include "undo.h"
#include "browserwidget.h"
#include "entry.h"

Pab::Pab() : KMainWindow(0)
{
  setCaption( i18n( "Address Book Browser" ));
  document = new ContactEntryList();
  view = new PabWidget( document, this, "Abbrowser" );

  // tell the KMainWindow that this is indeed the main widget
  setCentralWidget(view);

  // create a popup menu -- in this case, the File menu
  QPopupMenu* p = new QPopupMenu;
  p->insertItem(i18n("&Sync"), this, SLOT(save()), CTRL+Key_S);
  p->insertItem(i18n("&New Contact"), this, SLOT(newContact()), CTRL+Key_N);
  /*  p->insertItem(i18n("New &Group"), this, SLOT(newGroup()), CTRL+Key_G); */
  p->insertSeparator();
  p->insertItem(i18n("&Send Mail"), view, SLOT(sendMail()), CTRL+Key_Return);
  p->insertSeparator();
  p->insertItem(i18n("&Properties"), view, SLOT(properties()));
  p->insertItem(i18n("&Delete\tDel"));
  p->insertSeparator();
  p->insertItem(i18n("&Quit"), kapp, SLOT(quit()), CTRL+Key_Q);

  edit = new QPopupMenu;
  undoId = edit->insertItem(i18n("Undo"), this, SLOT(undo()),
			    KStdAccel::key(KStdAccel::Undo));
  redoId = edit->insertItem(i18n("Redo"), this, SLOT(redo()),
			    KStdAccel::key(KStdAccel::Redo));
  edit->insertSeparator();
  edit->insertItem(i18n("Cut"), view, SLOT(cut()), CTRL+Key_X);
  edit->insertItem(i18n("Copy"), view, SLOT(copy()), CTRL+Key_C);
  edit->insertItem(i18n("Paste"), view, SLOT(paste()), CTRL+Key_V);
  edit->insertSeparator();
  edit->insertItem(i18n("Select All"), view, SLOT(selectAll()), CTRL+Key_A);
  edit->setItemEnabled( undoId, false );
  edit->setItemEnabled( redoId, false );
  QObject::connect( edit, SIGNAL( aboutToShow() ), this, SLOT( updateEditMenu() ));

  QPopupMenu* v = new QPopupMenu;
  v->insertItem(i18n("Choose Fields..."), view, SLOT(showSelectNameDialog()) );
  v->insertItem(i18n("Options..."), view, SLOT(viewOptions()) );
  v->insertSeparator();
  v->insertItem(i18n("Restore defaults"), view, SLOT(defaultSettings()) );
  //  v->insertSeparator();
  //  v->insertItem(i18n("Refresh"), view, SLOT(refresh()), Key_F5 );

  // put our newly created menu into the main menu bar
  menuBar()->insertItem(i18n("&File"), p);
  menuBar()->insertItem(i18n("&Edit"), edit);
  menuBar()->insertItem(i18n("&View"), v);
  menuBar()->insertSeparator();

  // KDE will generate a short help menu automagically
  p = helpMenu( i18n("Abbrowser --- KDE Address Book\n\n"
		     "(c) 2000AD The KDE PIM Team \n"));

  menuBar()->insertItem(i18n("&Help"), p);

  toolBar()->insertButton(BarIcon("filenew"),   // icon
			  0,                  // button id
			  SIGNAL(clicked()),  // action
			  this, SLOT(newContact()), // result
			  true, i18n("Add a new entry"));      // tooltip text
  toolBar()->insertButton(BarIcon("pencil"),   // icon
			  0,                  // button id
			  SIGNAL(clicked()),  // action
			  view, SLOT(properties()), // result
			  true, i18n("Change this entry"));      // tooltip text
  toolBar()->insertButton(BarIcon("eraser"),   // icon
			  0,                  // button id
			  SIGNAL(clicked()),  // action
			  view, SLOT(clear()), // result
			  true, i18n("Remove this entry"));      // tooltip text
  toolBar()->insertSeparator();
  toolBar()->insertButton(BarIcon("mail_send"),   // icon
			  0,                  // button id
			  SIGNAL(clicked()),  // action
			  view, SLOT(sendMail()), // result
			  true, i18n("Send email"));      // tooltip text
  toolBar()->setFullSize(true);

  // we do want a status bar
  statusBar()->show();
  connect( kapp, SIGNAL( aboutToQuit() ), this, SLOT( saveConfig() ) );
  resize( sizeHint() );
  readConfig();
}

void Pab::newContact()
{
  ContactDialog *cd = new PabNewContactDialog( i18n( "Address Book Entry Editor" ), this, 0 );
  connect( cd, SIGNAL( add( ContactEntry* ) ),
	   view, SLOT( addNewEntry( ContactEntry* ) ));
  cd->show();
}

void Pab::addEmail( QString addr )
{
  view->addEmail( addr );
  return;
}

void Pab::save()
{
  document->commit();
  document->refresh();
  view->saveConfig();
  view->readConfig();
  view->reconstructListView();
  //xxx  document->save( "entries.txt" );
    UndoStack::instance()->clear();
    RedoStack::instance()->clear();
}

void Pab::readConfig()
{
  KConfig *config = kapp->config();
  int w, h;
  config->setGroup("Geometry");
   QString str = config->readEntry("Browser", "");
   if (!str.isEmpty() && str.find(',')>=0)
   {
     sscanf(str.local8Bit(),"%d,%d",&w,&h);
     resize(w,h);
   }
}

void Pab::saveConfig()
{
  view->saveConfig();
  KConfig *config = kapp->config();

  config->setGroup("Geometry");
  QRect r = geometry();
  QString s;
  s.sprintf("%i,%i", r.width(), r.height());
  config->writeEntry("Browser", s);
  config->sync();
}

Pab::~Pab()
{
  saveConfig();
  delete document;
}

void Pab::saveCe() {
  kdDebug() << "saveCe()" << endl;
  //xxx  ce->save( "entry.txt" );
}

void Pab::saveProperties(KConfig *)
{
	// the 'config' object points to the session managed
	// config file.  anything you write here will be available
	// later when this app is restored
  //what I want to save
  //windowsize
  //background image/underlining color/alternating color1,2
  //chosen fields
  //chosen fieldsWidths

	// e.g., config->writeEntry("key", var);
}

void Pab::readProperties(KConfig *)
{
	// the 'config' object points to the session managed
	// config file.  this function is automatically called whenever
	// the app is being restored.  read in here whatever you wrote
	// in 'saveProperties'

	// e.g., var = config->readEntry("key");
}

void Pab::undo()
{
  kdDebug() << "Pab::undo()" << endl;
  UndoStack::instance()->undo();
}

void Pab::redo()
{
  RedoStack::instance()->redo();
}

void Pab::updateEditMenu()
{
  kdDebug() << "UpdateEditMenu()" << endl;
  UndoStack *undo = UndoStack::instance();
  RedoStack *redo = RedoStack::instance();

  if (undo->isEmpty())
    edit->changeItem( undoId, i18n( "Undo" ) );
  else
    edit->changeItem( undoId, i18n( "Undo" ) + " " + undo->top()->name() );
  edit->setItemEnabled( undoId, !undo->isEmpty() );

  if (redo->isEmpty())
    edit->changeItem( redoId, i18n( "Redo" ) );
  else
    edit->changeItem( redoId, i18n( "Redo" ) + " " + redo->top()->name() );
  edit->setItemEnabled( redoId, !redo->isEmpty() );
}
<|endoftext|>


<commit_before>// AGAIN the contents of iterbase are completely subject to change, do not rely
// on any of this.  Users of the library must consider all of this undocumented
//

#include <enumerate.hpp>
#include <internal/iterbase.hpp>
#include <iterator>
#include <list>
#include <string>
#include <type_traits>
#include <vector>

#include "catch.hpp"
#include "helpers.hpp"

namespace it = iter::impl;

using IVec = std::vector<int>;

template <typename T>
using hrai = it::has_random_access_iter<T>;
TEST_CASE("Detects random access iterators correctly", "[iterbase]") {
  REQUIRE(hrai<std::vector<int>>::value);
  REQUIRE(hrai<std::string>::value);
  REQUIRE(hrai<int[10]>::value);

  REQUIRE_FALSE(hrai<std::list<int>>::value);
  REQUIRE_FALSE(hrai<decltype(iter::enumerate(std::list<int>{}))>::value);
  REQUIRE_FALSE(hrai<itertest::BasicIterable<int>>::value);
}

TEST_CASE("Detects correct iterator types", "[iterbase]") {
  REQUIRE((std::is_same<it::iterator_type<IVec>, IVec::iterator>::value));
  REQUIRE((std::is_same<it::iterator_type<IVec>, IVec::iterator>::value));
  REQUIRE((std::is_same<it::iterator_deref<IVec>,
      IVec::iterator::reference>::value));
  REQUIRE((std::is_same<it::const_iterator_deref<IVec>,
      IVec::iterator::reference>::value));
  REQUIRE((std::is_same<it::iterator_traits_deref<IVec>,
      IVec::iterator::value_type>::value));

  REQUIRE(
      (std::is_same<it::iterator_arrow<IVec>, IVec::iterator::pointer>::value));
  REQUIRE((std::is_same<it::iterator_arrow<int[10]>, int*>::value));
}

TEST_CASE("advance, next, size", "[iterbase]") {
  IVec v = {2, 4, 6, 8, 10, 12, 14, 16, 18};
  auto itr = std::begin(v);
  REQUIRE(it::apply_arrow(itr) == &v[0]);

  it::dumb_advance_unsafe(itr, 3);
  REQUIRE(itr == (std::begin(v) + 3));
  REQUIRE(it::dumb_next(std::begin(v), 3) == std::begin(v) + 3);
  REQUIRE(it::dumb_size(v) == v.size());
}

TEST_CASE("are_same", "[iterbase]") {
  REQUIRE((it::are_same<int, int, int, int>::value));
  REQUIRE_FALSE((it::are_same<double, int, int, int>::value));
  REQUIRE_FALSE((it::are_same<int, int, int, double>::value));
  REQUIRE_FALSE((it::are_same<int, double, int, int>::value));
}

TEST_CASE("DerefHolder lvalue reference", "[iterbase]") {
  it::DerefHolder<int&> dh;
  int a = 2;
  int b = 5;
  REQUIRE_FALSE(dh);
  dh.reset(a);
  REQUIRE(dh);

  REQUIRE(dh.get_ptr() == &a);
  REQUIRE(&dh.get() == &a);
  dh.reset(b);
  REQUIRE(dh.get_ptr() == &b);
  REQUIRE(&dh.get() == &b);
}

TEST_CASE("DerefHolder non-reference", "[iterbase]") {
  it::DerefHolder<int> dh;
  int a = 2;
  int b = 5;
  REQUIRE_FALSE(dh);
  dh.reset(std::move(a));
  REQUIRE(dh.get() == 2);
  REQUIRE(&dh.get() != &a);

  dh.reset(std::move(b));
  REQUIRE(dh.get() == 5);
}

TEST_CASE("get_begin returns correct type", "[iterbase]") {
  std::vector<int> v;
  REQUIRE((std::is_same<decltype(it::get_begin(v)), decltype(v.begin())>{}));
}

namespace NS1 {

  struct Dummy {
    auto begin() {
      return 0;
    }
    auto end() {
      return 0;
    }
  };

  template <typename T>
  auto begin(T& t) {
    return t.begin();
  }

  template <typename T>
  auto end(T& t) {
    return t.end();
  }

}  // namespace NS1

TEST_CASE("Detects is_iterable with ADL conflicts", "[iterbase]") {
  REQUIRE(iter::impl::is_iterable<NS1::Dummy>);
  REQUIRE(iter::impl::is_iterable<std::vector<NS1::Dummy>>);
}<commit_msg>Tests that arrays are iterable<commit_after>// AGAIN the contents of iterbase are completely subject to change, do not rely
// on any of this.  Users of the library must consider all of this undocumented
//

#include <enumerate.hpp>
#include <internal/iterbase.hpp>
#include <iterator>
#include <list>
#include <string>
#include <type_traits>
#include <vector>

#include "catch.hpp"
#include "helpers.hpp"

namespace it = iter::impl;

using IVec = std::vector<int>;

template <typename T>
using hrai = it::has_random_access_iter<T>;
TEST_CASE("Detects random access iterators correctly", "[iterbase]") {
  REQUIRE(hrai<std::vector<int>>::value);
  REQUIRE(hrai<std::string>::value);
  REQUIRE(hrai<int[10]>::value);

  REQUIRE_FALSE(hrai<std::list<int>>::value);
  REQUIRE_FALSE(hrai<decltype(iter::enumerate(std::list<int>{}))>::value);
  REQUIRE_FALSE(hrai<itertest::BasicIterable<int>>::value);
}

TEST_CASE("Detects correct iterator types", "[iterbase]") {
  REQUIRE((std::is_same<it::iterator_type<IVec>, IVec::iterator>::value));
  REQUIRE((std::is_same<it::iterator_type<IVec>, IVec::iterator>::value));
  REQUIRE((std::is_same<it::iterator_deref<IVec>,
      IVec::iterator::reference>::value));
  REQUIRE((std::is_same<it::const_iterator_deref<IVec>,
      IVec::iterator::reference>::value));
  REQUIRE((std::is_same<it::iterator_traits_deref<IVec>,
      IVec::iterator::value_type>::value));

  REQUIRE(
      (std::is_same<it::iterator_arrow<IVec>, IVec::iterator::pointer>::value));
  REQUIRE((std::is_same<it::iterator_arrow<int[10]>, int*>::value));
}

TEST_CASE("advance, next, size", "[iterbase]") {
  IVec v = {2, 4, 6, 8, 10, 12, 14, 16, 18};
  auto itr = std::begin(v);
  REQUIRE(it::apply_arrow(itr) == &v[0]);

  it::dumb_advance_unsafe(itr, 3);
  REQUIRE(itr == (std::begin(v) + 3));
  REQUIRE(it::dumb_next(std::begin(v), 3) == std::begin(v) + 3);
  REQUIRE(it::dumb_size(v) == v.size());
}

TEST_CASE("are_same", "[iterbase]") {
  REQUIRE((it::are_same<int, int, int, int>::value));
  REQUIRE_FALSE((it::are_same<double, int, int, int>::value));
  REQUIRE_FALSE((it::are_same<int, int, int, double>::value));
  REQUIRE_FALSE((it::are_same<int, double, int, int>::value));
}

TEST_CASE("DerefHolder lvalue reference", "[iterbase]") {
  it::DerefHolder<int&> dh;
  int a = 2;
  int b = 5;
  REQUIRE_FALSE(dh);
  dh.reset(a);
  REQUIRE(dh);

  REQUIRE(dh.get_ptr() == &a);
  REQUIRE(&dh.get() == &a);
  dh.reset(b);
  REQUIRE(dh.get_ptr() == &b);
  REQUIRE(&dh.get() == &b);
}

TEST_CASE("DerefHolder non-reference", "[iterbase]") {
  it::DerefHolder<int> dh;
  int a = 2;
  int b = 5;
  REQUIRE_FALSE(dh);
  dh.reset(std::move(a));
  REQUIRE(dh.get() == 2);
  REQUIRE(&dh.get() != &a);

  dh.reset(std::move(b));
  REQUIRE(dh.get() == 5);
}

TEST_CASE("get_begin returns correct type", "[iterbase]") {
  std::vector<int> v;
  REQUIRE((std::is_same<decltype(it::get_begin(v)), decltype(v.begin())>{}));
}

namespace NS1 {

  struct Dummy {
    auto begin() {
      return 0;
    }
    auto end() {
      return 0;
    }
  };

  template <typename T>
  auto begin(T& t) {
    return t.begin();
  }

  template <typename T>
  auto end(T& t) {
    return t.end();
  }

}  // namespace NS1

TEST_CASE("Detects is_iterable with ADL conflicts", "[iterbase]") {
  int a[1]{};
  const int b[1]{};
  REQUIRE(iter::impl::is_iterable<NS1::Dummy>);
  REQUIRE(iter::impl::is_iterable<std::vector<NS1::Dummy>>);
  REQUIRE(iter::impl::is_iterable<decltype(a)>);
  REQUIRE(iter::impl::is_iterable<decltype(b)>);
}
<|endoftext|>


<commit_before>#pragma once

#include <Python.h>

#include <iostream>
#include <string>
#include <vector>
#include <map>

// #define PY_MODULE(name, kwargs...) struct __attribute__((annotate("pymodule:" #name ":" #kwargs))) {}
#define PY_EXPORT __attribute__((annotate("pyexport")))
#define PY_ARGS   __attribute__((annotate("pyargs")))
#define PY_KWARGS __attribute__((annotate("pykwargs")))
#define PY_SYMIDENT __attribute__((annotate("pysymident")))
#define PY_CONVERTER(pytype) __attribute__((annotate("py:convert:" #pytype)))
#define PY_MODULE(name) namespace __attribute__((annotate("py:module:" #name))) {}
#define PY_DOCSTRING(text) namespace __attribute__((annotate("pydocstring:" text))) { }
#define PY_OPERATOR(name) __attribute__((annotate("pyoperator:" #name)))
#define PY_GETTER(name) __attribute__((annotate("pygetter:"#name)))
#define PY_SETTER(name) __attribute__((annotate("pysetter:"#name)))

#ifndef PY_NO_KEYWORDS
	#define pyexport PY_EXPORT
	#define pymodule PY_MODULE
	#define pydocstring PY_DOCSTRING
	#define pyoperator PY_OPERATOR
	#define pygetter PY_GETTER
	#define pysetter PY_SETTER
#endif

class PY_SYMIDENT SymbolIdentitiesPrivate
{
	// magic declarations
	// do not remove
	typedef struct S                 DummyType;
	typedef std::string              StringType;
	typedef std::vector<S>           VectorType;
	typedef std::map<S, S>           MapType;
};

template <class T>
struct PyConversion
{
	static_assert(sizeof(T) != sizeof(T),
	              "No specialization of PyConversion<> was found for this type. "
	              "This indicates a problem with your inputs to autobind.");
	// static T load(PyObject *);
	// static PyObject *dump(const T &);
};

namespace python
{
	namespace protocols
	{
		namespace detail
		{
			struct UnimplTag { };

			template <class U, U>
			class Check
			{

			};

			// based on http://www.gockelhut.com/c++/articles/has_member
			template <class T, class NameGetter>
			class HasMemberImpl
			{
				typedef char matched;
				typedef long unmatched;

				template <class C>
				static matched f(typename NameGetter::template get<C> *);

				template <class C>
				static unmatched f(...);

			public:
				static const bool value = (sizeof(f<T>(0)) == sizeof(matched));
			};

			template <class T, class NameGetter>
			class HasMember: public std::integral_constant<
				bool,
				HasMemberImpl<T, NameGetter>::value
			>
			{ };

			struct CheckHasRepr
			{
				template <class T, std::string(T::*)() const = &T::repr>
				struct get { };
			};

			template <class T>
			class HasRepr: public HasMember<T, CheckHasRepr> { };
			struct CheckHasStr
			{
				template <class T, std::string(T::*)() const = &T::str>
				struct get { };
			};

			template <class T>
			class HasStr: public HasMember<T, CheckHasStr> { };
		}

		template <class T, class Enable=void>
		struct Str: public detail::UnimplTag
		{

		};

		template <class T>
		struct Str<T, typename std::enable_if<detail::HasStr<T>::value>::type>
		{
			static std::string convert(const T &x)
			{
				return x.str();
			}
		};

		template <class T, class Enable=void>
		struct Repr: public detail::UnimplTag
		{
		};

		template <class T>
		struct Repr<T, typename std::enable_if<detail::HasRepr<T>::value>::type>
		{
			static std::string convert(const T &x)
			{
				return x.repr();
			}
		};

		namespace detail
		{
			template <class T, class U, class Enable=void>
			struct StrConverter;

			template <class T, class U>
			struct StrConverter<T, U, typename std::enable_if<std::is_base_of<UnimplTag, Str<T>>::value>::type>
			{
				static reprfunc get() { return 0; }
			};

			template <class T, class U>
			struct StrConverter<T, U, typename std::enable_if<!std::is_base_of<UnimplTag, Str<T>>::value>::type>
			{
				static PyObject *converter(U *self)
				{
					auto result = Str<T>::convert(self->object);
					return PyConversion<decltype(result)>::dump(result);
				}

				static reprfunc get() { return (reprfunc) &converter; }
			};

			template <class T, class U, class Enable=void>
			struct ReprConverter;

			template <class T, class U>
			struct ReprConverter<T, U, typename std::enable_if<std::is_base_of<UnimplTag, Repr<T>>::value>::type>
			{
				static reprfunc get() { return 0; }
			};

			template <class T, class U>
			struct ReprConverter<T, U, typename std::enable_if<!std::is_base_of<UnimplTag, Repr<T>>::value>::type>
			{
				static PyObject *converter(U *self)
				{
					auto result = Repr<T>::convert(self->object);
					return PyConversion<decltype(result)>::dump(result);
				}

				static reprfunc get() { return (reprfunc) &converter; }
			};

		}

	}

	namespace
	{
		void disposePyObject(PyObject *o)
		{
			Py_XDECREF(o);
		}

		std::shared_ptr<PyObject> borrow(PyObject *o)
		{
			Py_XINCREF(o);
			return std::shared_ptr<PyObject>(o, disposePyObject);
		}

	}

	inline bool isinstance(PyObject &obj, PyObject &ty)
	{
		return PyObject_IsInstance(&obj, &ty);
	}

	class Exception: public std::exception
	{
	public:
		const char *what() const throw()
		{
			return "<python exception>";
		}
	};

	class IteratorRef
	{
		std::shared_ptr<PyObject> _iter;
	public:
		IteratorRef(PyObject &obj)
		: _iter(borrow(PyObject_GetIter(&obj)))
		{
			if(!_iter)
			{
				throw Exception();
			}
		}

		operator bool() const
		{
			return _iter != nullptr;
		}

		std::shared_ptr<PyObject> next()
		{
			if(auto result = PyIter_Next(_iter.get()))
			{
				return borrow(result);
			}
			else
			{
				_iter = nullptr;
				return {};
			}
		}
	};

	inline IteratorRef iter(PyObject &obj)
	{
		return IteratorRef(obj);
	}

	class ListRef
	{
		std::shared_ptr<PyObject> _obj;
	public:
		ListRef(std::shared_ptr<PyObject> p)
		: _obj(p) { }

		size_t size() const
		{
			auto res = PySequence_Size(_obj.get());
			if(res < 0)
			{
				throw Exception();
			}

			return res;
		}

		template <class T>
		void set(size_t index, const T &value)
		{
			if(PySequence_SetItem(_obj.get(), index, PyConversion<T>::dump(value)) == -1)
			{
				throw Exception();
			}
		}

		template <class T>
		T get(size_t index) const
		{
			return PyConversion<T>::load(PySequence_GetItem(_obj.get(), index));
		}

		template <class T>
		void append(const T &item)
		{
			if(PyList_Append(_obj.get(), PyConversion<T>::dump(item)))
			{
				throw python::Exception();
			}
		}
	};

};

template <>
struct PyConversion<python::ListRef>
{
	static python::ListRef load(PyObject *o)
	{
		return python::ListRef(python::borrow(o));
	}
};

template <>
struct PyConversion<python::IteratorRef>
{
	static python::IteratorRef load(PyObject *o)
	{
		return python::iter(*o);
	}
};

template <>
struct PyConversion<int>
{
	static int load(PyObject *o)
	{
		int res = PyLong_AsLong(o);
		if(PyErr_Occurred())
		{
			throw python::Exception();
		}
		return res;
	}

	static PyObject *dump(int i)
	{
		auto res = PyLong_FromLong(i);
		if(!res)
		{
			throw python::Exception();
		}

		return res;
	}
};

template <class T>
struct PyConversion<std::vector<T> >
{
	static std::vector<T> load(PyObject *obj)
	{
		auto it = python::iter(*obj);

		std::vector<T> result;

		while(auto value = it.next())
		{
			result.push_back(PyConversion<T>::load(value.get()));
		}

		return result;
	}

	static PyObject *dump(const std::vector<T> &v)
	{
		auto lst = PyList_New(0);
		auto lref = PyConversion<python::ListRef>::load(lst);

		for(const auto &item : v)
		{
			lref.append(item);
		}

		return lst;
	}
};

template <>
struct PyConversion<std::string>
{
	static std::string load(PyObject *obj)
	{
		if(auto res = PyUnicode_AsUTF8(obj))
		{
			return res;
		}
		else
		{
			throw python::Exception();
		}
	}

	static PyObject *dump(const std::string &s)
	{
		auto res = PyUnicode_DecodeUTF8(s.c_str(), s.size(), "surrogateescape");
		if(!res)
		{
			throw python::Exception();
		}
		return res;
	}
};

<commit_msg>Allow PyConversion<> to be used prior to autobind generating its definition.<commit_after>#pragma once

#include <Python.h>

#include <iostream>
#include <string>
#include <vector>
#include <map>

// #define PY_MODULE(name, kwargs...) struct __attribute__((annotate("pymodule:" #name ":" #kwargs))) {}
#define PY_EXPORT __attribute__((annotate("pyexport")))
#define PY_ARGS   __attribute__((annotate("pyargs")))
#define PY_KWARGS __attribute__((annotate("pykwargs")))
#define PY_SYMIDENT __attribute__((annotate("pysymident")))
#define PY_CONVERTER(pytype) __attribute__((annotate("py:convert:" #pytype)))
#define PY_MODULE(name) namespace __attribute__((annotate("py:module:" #name))) {}
#define PY_DOCSTRING(text) namespace __attribute__((annotate("pydocstring:" text))) { }
#define PY_OPERATOR(name) __attribute__((annotate("pyoperator:" #name)))
#define PY_GETTER(name) __attribute__((annotate("pygetter:"#name)))
#define PY_SETTER(name) __attribute__((annotate("pysetter:"#name)))

#ifndef PY_NO_KEYWORDS
	#define pyexport PY_EXPORT
	#define pymodule PY_MODULE
	#define pydocstring PY_DOCSTRING
	#define pyoperator PY_OPERATOR
	#define pygetter PY_GETTER
	#define pysetter PY_SETTER
#endif

class PY_SYMIDENT SymbolIdentitiesPrivate
{
	// magic declarations
	// do not remove
	typedef struct S                 DummyType;
	typedef std::string              StringType;
	typedef std::vector<S>           VectorType;
	typedef std::map<S, S>           MapType;
};

template <class T>
struct PyConversion
{
#ifndef AUTOBIND_RUN
	static_assert(sizeof(T) != sizeof(T),
	              "No specialization of PyConversion<> was found for this type. "
	              "This indicates a problem with your inputs to autobind.");
	// static T load(PyObject *);
	// static PyObject *dump(const T &);
#else
	// prevents compile errors while running autobind about missing specializations that
	// will be automatically filled in later.
	static T &load(PyObject *);
	static PyObject *dump(const T &);
#endif
};

namespace python
{
	namespace protocols
	{
		namespace detail
		{
			struct UnimplTag { };

			template <class U, U>
			class Check
			{

			};

			// based on http://www.gockelhut.com/c++/articles/has_member
			template <class T, class NameGetter>
			class HasMemberImpl
			{
				typedef char matched;
				typedef long unmatched;

				template <class C>
				static matched f(typename NameGetter::template get<C> *);

				template <class C>
				static unmatched f(...);

			public:
				static const bool value = (sizeof(f<T>(0)) == sizeof(matched));
			};

			template <class T, class NameGetter>
			class HasMember: public std::integral_constant<
				bool,
				HasMemberImpl<T, NameGetter>::value
			>
			{ };

			struct CheckHasRepr
			{
				template <class T, std::string(T::*)() const = &T::repr>
				struct get { };
			};

			template <class T>
			class HasRepr: public HasMember<T, CheckHasRepr> { };
			struct CheckHasStr
			{
				template <class T, std::string(T::*)() const = &T::str>
				struct get { };
			};

			template <class T>
			class HasStr: public HasMember<T, CheckHasStr> { };
		}

		template <class T, class Enable=void>
		struct Str: public detail::UnimplTag
		{

		};

		template <class T>
		struct Str<T, typename std::enable_if<detail::HasStr<T>::value>::type>
		{
			static std::string convert(const T &x)
			{
				return x.str();
			}
		};

		template <class T, class Enable=void>
		struct Repr: public detail::UnimplTag
		{
		};

		template <class T>
		struct Repr<T, typename std::enable_if<detail::HasRepr<T>::value>::type>
		{
			static std::string convert(const T &x)
			{
				return x.repr();
			}
		};

		template <class T, class Enable=void>
		struct Buffer: public detail::UnimplTag
		{
			static int getBuffer(T &x, Py_buffer *view, int flags);
			static void releaseBuffer(T &x, Py_buffer *view);

		};

		#define ENABLE_IF(x...) typename std::enable_if<x >::type
		#define IS_UNIMPL(x...) std::is_base_of<UnimplTag, x >::value
		namespace detail
		{

			template <class T, class U, class Enable=void>
			struct BufferProcs
			{
				static int getbuffer(U *exporter,
				                     Py_buffer *view,
				                     int flags)
				{
					view->obj = reinterpret_cast<PyObject*>(exporter);
					int r =  Buffer<T>::getBuffer(exporter->object,
					                              view,
					                              flags);
					Py_XINCREF(view->obj);
					return r;
				}

				static void releasebuffer(U *exporter,
				                          Py_buffer *view)
				{
					Buffer<T>::releaseBuffer(exporter->object,
					                         view);
				}

				static PyBufferProcs *get()
				{
					static PyBufferProcs result = {
						(getbufferproc) &getbuffer,
						(releasebufferproc) &releasebuffer
					};

					return &result;
				}
			};

			template <class T, class U>
			struct BufferProcs<T, U, ENABLE_IF(IS_UNIMPL(Buffer<T>))>
			{
				static PyBufferProcs *get()
				{
					return 0;
				}
			};

			template <class T, class U, class Enable=void>
			struct StrConverter;

			template <class T, class U>
			struct StrConverter<T, U, ENABLE_IF(IS_UNIMPL(Str<T>))>
			{
				static reprfunc get() { return 0; }
			};

			template <class T, class U>
			struct StrConverter<T, U, typename std::enable_if<!std::is_base_of<UnimplTag, Str<T>>::value>::type>
			{
				static PyObject *converter(U *self)
				{
					auto result = Str<T>::convert(self->object);
					return PyConversion<decltype(result)>::dump(result);
				}

				static reprfunc get() { return (reprfunc) &converter; }
			};

			template <class T, class U, class Enable=void>
			struct ReprConverter;

			template <class T, class U>
			struct ReprConverter<T, U, typename std::enable_if<std::is_base_of<UnimplTag, Repr<T>>::value>::type>
			{
				static reprfunc get() { return 0; }
			};

			template <class T, class U>
			struct ReprConverter<T, U, typename std::enable_if<!std::is_base_of<UnimplTag, Repr<T>>::value>::type>
			{
				static PyObject *converter(U *self)
				{
					auto result = Repr<T>::convert(self->object);
					return PyConversion<decltype(result)>::dump(result);
				}

				static reprfunc get() { return (reprfunc) &converter; }
			};
		}

		#undef ENABLE_IF
		#undef IS_UNIMPL

	}

	namespace
	{
		void disposePyObject(PyObject *o)
		{
			Py_XDECREF(o);
		}

		void keepPyObject(PyObject *o) { }

		std::shared_ptr<PyObject> borrow(PyObject *o)
		{
			Py_XINCREF(o);
			return std::shared_ptr<PyObject>(o, disposePyObject);
		}

		std::shared_ptr<PyObject> getNone()
		{
			Py_XINCREF(Py_None);
			return std::shared_ptr<PyObject>(Py_None, disposePyObject);
		}

	}

	inline bool isinstance(PyObject &obj, PyObject &ty)
	{
		return PyObject_IsInstance(&obj, &ty);
	}

	class Exception: public std::exception
	{
	public:
		const char *what() const throw()
		{
			return "<python exception>";
		}
	};

	class IteratorRef
	{
		std::shared_ptr<PyObject> _iter;
	public:
		IteratorRef(PyObject &obj)
		: _iter(borrow(PyObject_GetIter(&obj)))
		{
			if(!_iter)
			{
				throw Exception();
			}
		}

		operator bool() const
		{
			return _iter != nullptr;
		}

		std::shared_ptr<PyObject> next()
		{
			if(auto result = PyIter_Next(_iter.get()))
			{
				return borrow(result);
			}
			else
			{
				_iter = nullptr;
				return {};
			}
		}
	};

	inline IteratorRef iter(PyObject &obj)
	{
		return IteratorRef(obj);
	}

	class ListRef
	{
		std::shared_ptr<PyObject> _obj;
	public:
		ListRef(std::shared_ptr<PyObject> p)
		: _obj(p) { }

		size_t size() const
		{
			auto res = PySequence_Size(_obj.get());
			if(res < 0)
			{
				throw Exception();
			}

			return res;
		}

		template <class T>
		void set(size_t index, const T &value)
		{
			if(PySequence_SetItem(_obj.get(), index, PyConversion<T>::dump(value)) == -1)
			{
				throw Exception();
			}
		}

		template <class T>
		T get(size_t index) const
		{
			return PyConversion<T>::load(PySequence_GetItem(_obj.get(), index));
		}

		template <class T>
		void append(const T &item)
		{
			if(PyList_Append(_obj.get(), PyConversion<T>::dump(item)))
			{
				throw python::Exception();
			}
		}
	};

	class ObjectRef
	{
		std::shared_ptr<PyObject> _obj;
	public:
		ObjectRef(std::shared_ptr<PyObject> p)
		: _obj(p) { }

		ObjectRef()
		: _obj(getNone()) { } // for STL containers

		static ObjectRef none()
		{
			return ObjectRef(getNone());
		}

		bool operator <(const ObjectRef &other) const
		{
			int rv = PyObject_RichCompareBool(_obj.get(), other._obj.get(), Py_LT);
			if(rv < 0)
			{
				throw python::Exception();
			}
			else
			{
				return rv != 0;
			}
		}

		bool operator ==(const ObjectRef &other)
		{
			int rv = PyObject_RichCompareBool(_obj.get(), other._obj.get(), Py_EQ);
			if(rv < 0)
			{
				throw python::Exception();
			}
			else
			{
				return rv != 0;
			}
		}

		const std::shared_ptr<PyObject> &pyObject() const
		{
			return _obj;
		}
	};

	template <class T>
	class Handle
	{
		ObjectRef _obj; // held to ensure refcount remains > 0
		T &_ref;
	public:

		Handle(const ObjectRef &r)
		: _obj(r)
		, _ref(PyConversion<T>::load(r.pyObject().get()))
		{ }

		T &operator *() const
		{
			return _ref;
		}

		T *operator ->() const
		{
			return &_ref;
		}

		T &data() const
		{
			return _ref;
		}
	};

};

template <class T>
struct PyConversion<python::Handle<T>>
{
	static python::Handle<T> load(PyObject *obj)
	{
		return python::Handle<T>(python::ObjectRef(python::borrow(obj)));
	}
};

template <>
struct PyConversion<python::ListRef>
{
	static python::ListRef load(PyObject *o)
	{
		return python::ListRef(python::borrow(o));
	}
};

template <>
struct PyConversion<python::ObjectRef>
{
	static python::ObjectRef load(PyObject *o)
	{
		return python::ObjectRef(python::borrow(o));
	}

	static PyObject *dump(const python::ObjectRef &oref)
	{
		auto result = oref.pyObject().get();
		Py_XINCREF(result);
		return result;
	}
};

template <>
struct PyConversion<python::IteratorRef>
{
	static python::IteratorRef load(PyObject *o)
	{
		return python::iter(*o);
	}
};

template <>
struct PyConversion<int>
{
	static int load(PyObject *o)
	{
		int res = PyLong_AsLong(o);
		if(PyErr_Occurred())
		{
			throw python::Exception();
		}
		return res;
	}

	static PyObject *dump(int i)
	{
		auto res = PyLong_FromLong(i);
		if(!res)
		{
			throw python::Exception();
		}

		return res;
	}
};

template <class T>
struct PyConversion<std::vector<T> >
{
	static std::vector<T> load(PyObject *obj)
	{
		auto it = python::iter(*obj);

		std::vector<T> result;

		while(auto value = it.next())
		{
			result.push_back(PyConversion<T>::load(value.get()));
		}

		return result;
	}

	static PyObject *dump(const std::vector<T> &v)
	{
		auto lst = PyList_New(0);
		auto lref = PyConversion<python::ListRef>::load(lst);

		for(const auto &item : v)
		{
			lref.append(item);
		}

		return lst;
	}
};

template <>
struct PyConversion<std::string>
{
	static std::string load(PyObject *obj)
	{
		if(auto res = PyUnicode_AsUTF8(obj))
		{
			return res;
		}
		else
		{
			throw python::Exception();
		}
	}

	static PyObject *dump(const std::string &s)
	{
		auto res = PyUnicode_DecodeUTF8(s.c_str(), s.size(), "surrogateescape");
		if(!res)
		{
			throw python::Exception();
		}
		return res;
	}
};

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ofaitem.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 18:09:48 $
 *
 *  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 _OFF_OFAITEM_HXX
#define _OFF_OFAITEM_HXX

// include ----------------------------------------------------------------

#ifndef _SFXPOOLITEM_HXX
#include <svtools/poolitem.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

// class OfaPtrItem ------------------------------------------------------

class SVX_DLLPUBLIC OfaPtrItem : public SfxPoolItem
{
private:
    void* pPtr;

public:
                             OfaPtrItem( USHORT nWhich, void *pPtr );
                             OfaPtrItem( const OfaPtrItem& );

    virtual int              operator==( const SfxPoolItem& ) const;
    virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const;

    void*                    GetValue() const { return pPtr; }
    void                     SetValue( void* pNewPtr ) { pPtr = pNewPtr; }
};
/*
class SvxDashListPtrItem : public OfaPtrItem
{
    public:
                             TYPEINFO();

                             SvxDashListPtrItem( USHORT nWhich, SvxDashListItem* pPtr );
                             SvxDashListPtrItem( const DashListPtrItem& );

    virtual int              operator==( const SfxPoolItem& ) const;
    virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const;

    virtual sal_Bool         QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const;
    virtual sal_Bool         PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 );

    SvxDashListPtrItem*      GetValue() const { return OfaPtrItem::GetValue(); }
};
*/
#endif
<commit_msg>INTEGRATION: CWS aw024 (1.4.196); FILE MERGED 2005/09/18 00:17:30 aw 1.4.196.2: RESYNC: (1.4-1.5); FILE MERGED 2005/05/19 12:29:33 aw 1.4.196.1: #i39529#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ofaitem.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 12:41:24 $
 *
 *  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 _OFF_OFAITEM_HXX
#define _OFF_OFAITEM_HXX

// include ----------------------------------------------------------------

#ifndef _SFXPOOLITEM_HXX
#include <svtools/poolitem.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

// class OfaPtrItem ------------------------------------------------------

class SVX_DLLPUBLIC OfaPtrItem : public SfxPoolItem
{
private:
    void* pPtr;

public:
                             OfaPtrItem( USHORT nWhich, void *pPtr );
                             OfaPtrItem( const OfaPtrItem& );

    virtual int              operator==( const SfxPoolItem& ) const;
    virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const;

    void*                    GetValue() const { return pPtr; }
    void                     SetValue( void* pNewPtr ) { pPtr = pNewPtr; }
};

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: unofill.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2003-10-06 15:30:30 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVX_UNOFILL_HXX_
#define _SVX_UNOFILL_HXX_

#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HPP_
#include <com/sun/star/uno/XInterface.hpp>
#endif

class SdrModel;

::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoGradientTable_createInstance( SdrModel* pModel );
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoHatchTable_createInstance( SdrModel* pModel );
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoBitmapTable_createInstance( SdrModel* pModel );
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoTransGradientTable_createInstance( SdrModel* pModel );
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoMarkerTable_createInstance( SdrModel* pModel );
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoDashTable_createInstance( SdrModel* pModel );

#endif // _SVX_UNOFILL_HXX_

<commit_msg>INTEGRATION: CWS visibility01 (1.2.510); FILE MERGED 2004/11/19 12:54:34 mmeeks 1.2.510.1: Issue number: #i35758# Submitted by: mnicel Reviewed by:  mmeeks<commit_after>/*************************************************************************
 *
 *  $RCSfile: unofill.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 15:44:08 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVX_UNOFILL_HXX_
#define _SVX_UNOFILL_HXX_

#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HPP_
#include <com/sun/star/uno/XInterface.hpp>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

class SdrModel;

SVX_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoGradientTable_createInstance( SdrModel* pModel );
SVX_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoHatchTable_createInstance( SdrModel* pModel );
SVX_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoBitmapTable_createInstance( SdrModel* pModel );
SVX_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoTransGradientTable_createInstance( SdrModel* pModel );
SVX_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoMarkerTable_createInstance( SdrModel* pModel );
SVX_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvxUnoDashTable_createInstance( SdrModel* pModel );

#endif // _SVX_UNOFILL_HXX_

<|endoftext|>


<commit_before><commit_msg>Solve LCSubstring No.79 in Cpp<commit_after>
class Solution {
public:
    /**
     * @param A, B: Two string.
     * @return: the length of the longest common substring.
     */
    int longestCommonSubstring(string &A, string &B) {
        // write your code here

        int l_a=A.length();
        int l_b=B.length();
        int lcs_lg[l_a+3][l_b+3];

        //int lcs_lg[1111][1111];

        for (int i=0;i<l_a+2;++i)
            for (int j=0;j<l_b+2;++j)
                lcs_lg[i][j]=0;
        int max_lcs=0;

        for (int i=0;i<l_a;++i)
            for (int j=0;j<l_b;++j){
                if (A[i]==B[j]){
                    lcs_lg[i+1][j+1]=lcs_lg[i][j]+1;
                    max_lcs=max(max_lcs,lcs_lg[i+1][j+1]);
            }
        }

        return max_lcs;
};

};

// Total Runtime: 15 ms<|endoftext|>


<commit_before>#include <cassert>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <sstream>
#include <cstring>
#include <chrono>
#include <fstream>
//#include <GL/glut.h>
#include "World.H"
#include "Unit.H"
#include "Marine.H"
#include "Tank.H"

using namespace std;

int main(int argc, char *argv[])
{
  if (argc != 1 && argc != 10) {
    cerr << "usage: " << argv[0] << " width height delay seed marines tanks redpol bluepol bounce" << endl;
    cerr << "       delay in ms, seed=0: use time, policies: 0 weakest/1 closest/2 most dangerous" << endl;
    exit(1);
  }

  double width  = 700;
  double height = 700;

  int delay = 100;     // frame delay in ms
  int seed = 0;    // for rng, 0: use time

  int n_marines = 100;
  int n_tanks   = 100;

  AttackPolicy red_policy = ATTACK_MOST_DANGEROUS;
  AttackPolicy blue_policy = ATTACK_MOST_DANGEROUS;

  bool bounce = true;

  if (argc == 10) {
    // todo : error handling
    int i = 1;
    width = atoi(argv[i++]);
    height = atoi(argv[i++]);
    delay = atoi(argv[i++]);
    seed = atoi(argv[i++]);
    n_marines = atoi(argv[i++]);
    n_tanks = atoi(argv[i++]);
    red_policy = (AttackPolicy)atoi(argv[i++]);
    blue_policy = (AttackPolicy)atoi(argv[i++]);
    bounce = atoi(argv[i++]);
  }

  if (seed == 0) {
    // rng seed dependent on wallclock time
    unsigned long long millis =
      std::chrono::duration_cast<std::chrono::milliseconds>
      (std::chrono::system_clock::now().time_since_epoch()).count();

    seed = millis;
  }

  cout << "width: "    << width     << endl;
  cout << "height: "   << height    << endl;
  cout << "delay: "    << delay     << endl;
  cout << "seed: "     << seed      << endl;
  cout << "marines: "  << n_marines << endl;
  cout << "tanks: "    << n_tanks   << endl;
  cout << "redpol: "   << apol2str(red_policy) << endl;
  cout << "bluepol: "  << apol2str(blue_policy) << endl;
  cout << "bounce:  "  << bounce << endl;

  // set up world
  World *world = new World(width, height, seed);

  // populate with units

  // get unit sizes - a bit awkward, could be data members
  Marine *m = new Marine(RED, Vec2(0, 0), ATTACK_WEAKEST, false);
  double mr = m->radius;
  delete m;
  Tank *t = new Tank(RED, Vec2(0, 0), ATTACK_WEAKEST, false);
  double tr = t->radius;
  delete t;

  AttackPolicy red_marine_policy  = red_policy;
  AttackPolicy blue_marine_policy = blue_policy;
  AttackPolicy red_tank_policy    = red_policy;
  AttackPolicy blue_tank_policy   = blue_policy;

  // create marines
  for (int i=0; i < n_marines; ++i) {
    Unit *u = new Marine(RED, world->rnd_pos(mr), red_marine_policy, bounce);
    u->heading = world->rnd_heading();
    u->current_speed = u->max_speed;
    world->units.push_back(u);

    // mirrored
    Unit *v = new Marine(BLUE, world->mirror(u->pos), blue_marine_policy, bounce);
    v->heading = Vec2(-u->heading.x, -u->heading.y);
    v->current_speed = v->max_speed;
    world->units.push_back(v);
  }

  // create tanks
  for (int i=0; i < n_tanks; ++i) {
    Unit *u = new Tank(RED, world->rnd_pos(tr), red_tank_policy, bounce);
    u->heading = world->rnd_heading();
    u->current_speed = u->max_speed;
    world->units.push_back(u);

    // mirrored
    Unit *v = new Tank(BLUE, world->mirror(u->pos), blue_tank_policy, bounce);
    v->heading = Vec2(-u->heading.x, -u->heading.y);
    v->current_speed = v->max_speed;
    world->units.push_back(v);
  }
   while(true){
      cout << "." << flush;
      //world->attacks.clear();
      world->step();

      int red_score = world->red_score();
      if (red_score >= 0) {
         ofstream myfile;
         myfile.open ("Results.txt");
         myfile << "game over: ";
         cout << "game over: ";
         if (red_score == 2) {
            myfile << "RED wins\n";
            cout << "RED wins" << endl;
         } else if (red_score == 1) {
            myfile << "Draw\n";
            cout << "draw" << endl;
         } else {
            myfile << "BLUE wins\n";
            cout << "BLUE wins" << endl;
         }
         myfile.close();
         delete world;
         exit(0);
      }
   }

  return 0;
}<commit_msg>Made changes to Main to fix writing to file<commit_after>#include <cassert>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <sstream>
#include <cstring>
#include <chrono>
#include <fstream>
//#include <GL/glut.h>
#include "World.H"
#include "Unit.H"
#include "Marine.H"
#include "Tank.H"

using namespace std;

int main(int argc, char *argv[])
{
  if (argc != 1 && argc != 10) {
    cerr << "usage: " << argv[0] << " width height delay seed marines tanks redpol bluepol bounce" << endl;
    cerr << "       delay in ms, seed=0: use time, policies: 0 weakest/1 closest/2 most dangerous" << endl;
    exit(1);
  }

  double width  = 700;
  double height = 700;

  int delay = 100;     // frame delay in ms
  int seed = 0;    // for rng, 0: use time

  int n_marines = 100;
  int n_tanks   = 100;

  AttackPolicy red_policy = ATTACK_MOST_DANGEROUS;
  AttackPolicy blue_policy = ATTACK_MOST_DANGEROUS;

  bool bounce = true;

  if (argc == 10) {
    // todo : error handling
    int i = 1;
    width = atoi(argv[i++]);
    height = atoi(argv[i++]);
    delay = atoi(argv[i++]);
    seed = atoi(argv[i++]);
    n_marines = atoi(argv[i++]);
    n_tanks = atoi(argv[i++]);
    red_policy = (AttackPolicy)atoi(argv[i++]);
    blue_policy = (AttackPolicy)atoi(argv[i++]);
    bounce = atoi(argv[i++]);
  }

  if (seed == 0) {
    // rng seed dependent on wallclock time
    unsigned long long millis =
      std::chrono::duration_cast<std::chrono::milliseconds>
      (std::chrono::system_clock::now().time_since_epoch()).count();

    seed = millis;
  }

  cout << "width: "    << width     << endl;
  cout << "height: "   << height    << endl;
  cout << "delay: "    << delay     << endl;
  cout << "seed: "     << seed      << endl;
  cout << "marines: "  << n_marines << endl;
  cout << "tanks: "    << n_tanks   << endl;
  cout << "redpol: "   << apol2str(red_policy) << endl;
  cout << "bluepol: "  << apol2str(blue_policy) << endl;
  cout << "bounce:  "  << bounce << endl;

  // set up world
  World *world = new World(width, height, seed);

  // populate with units

  // get unit sizes - a bit awkward, could be data members
  Marine *m = new Marine(RED, Vec2(0, 0), ATTACK_WEAKEST, false);
  double mr = m->radius;
  delete m;
  Tank *t = new Tank(RED, Vec2(0, 0), ATTACK_WEAKEST, false);
  double tr = t->radius;
  delete t;

  AttackPolicy red_marine_policy  = red_policy;
  AttackPolicy blue_marine_policy = blue_policy;
  AttackPolicy red_tank_policy    = red_policy;
  AttackPolicy blue_tank_policy   = blue_policy;

  // create marines
  for (int i=0; i < n_marines; ++i) {
    Unit *u = new Marine(RED, world->rnd_pos(mr), red_marine_policy, bounce);
    u->heading = world->rnd_heading();
    u->current_speed = u->max_speed;
    world->units.push_back(u);

    // mirrored
    Unit *v = new Marine(BLUE, world->mirror(u->pos), blue_marine_policy, bounce);
    v->heading = Vec2(-u->heading.x, -u->heading.y);
    v->current_speed = v->max_speed;
    world->units.push_back(v);
  }

  // create tanks
  for (int i=0; i < n_tanks; ++i) {
    Unit *u = new Tank(RED, world->rnd_pos(tr), red_tank_policy, bounce);
    u->heading = world->rnd_heading();
    u->current_speed = u->max_speed;
    world->units.push_back(u);

    // mirrored
    Unit *v = new Tank(BLUE, world->mirror(u->pos), blue_tank_policy, bounce);
    v->heading = Vec2(-u->heading.x, -u->heading.y);
    v->current_speed = v->max_speed;
    world->units.push_back(v);
  }
   while(true){
      cout << "." << flush;
      //world->attacks.clear();
      world->step();

      int red_score = world->red_score();
      if (red_score >= 0) {
         ofstream results;
         results.open ("Results.txt", ios::app | ios::out);
         results << "game over: ";
         cout << "game over: ";
         if (red_score == 2) {
            results << "RED wins\n";
            cout << "RED wins" << endl;
         } else if (red_score == 1) {
            results << "Draw\n";
            cout << "draw" << endl;
         } else {
            results << "BLUE wins\n";
            cout << "BLUE wins" << endl;
         }
         results.close();
         delete world;
         exit(0);
      }
   }

  return 0;
}
<|endoftext|>