<commit_before>/*
 * Vulkan Samples
 *
 * Copyright (C) 2015-2016 Valve Corporation
 * Copyright (C) 2015-2016 LunarG, Inc.
 *
 * 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>
#include <string>
#include <sstream>
#include <vector>

#define GLM_FORCE_RADIANS
//#include "glm/glm.hpp"
//#include "glm/gtc/matrix_transform.hpp"
#include "linmath.h"

#ifdef _WIN32
#pragma comment(linker, "/subsystem:console")
#define WIN32_LEAN_AND_MEAN
#define VK_USE_PLATFORM_WIN32_KHR
#define NOMINMAX /* Don't let Windows define min() or max() */
#define APP_NAME_STR_LEN 80
#elif defined(__ANDROID__)
// Include files for Android
#include <unistd.h>
#include <android/log.h>
#include "vulkan_wrapper.h" // Include Vulkan_wrapper and dynamically load symbols.
#else //__ANDROID__
#define VK_USE_PLATFORM_XCB_KHR
#include <unistd.h>
#include "vulkan/vk_sdk_platform.h"
#endif // _WIN32

#include <vulkan/vulkan.h>

/* Number of descriptor sets needs to be the same at alloc,       */
/* pipeline layout creation, and descriptor set layout creation   */
#define NUM_DESCRIPTOR_SETS 1

/* Number of samples needs to be the same at image creation,      */
/* renderpass creation and pipeline creation.                     */
#define NUM_SAMPLES VK_SAMPLE_COUNT_1_BIT

/* Number of viewports and number of scissors have to be the same */
/* at pipeline creation and in any call to set them dynamically   */
/* They also have to be the same as each other                    */
#define NUM_VIEWPORTS 1
#define NUM_SCISSORS NUM_VIEWPORTS

/* Amount of time, in nanoseconds, to wait for a command buffer to complete */
#define FENCE_TIMEOUT 100000000

#define GET_INSTANCE_PROC_ADDR(inst, entrypoint)                               \
    {                                                                          \
        info.fp##entrypoint =                                                  \
            (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \
        if (info.fp##entrypoint == NULL) {                                     \
            std::cout << "vkGetDeviceProcAddr failed to find vk" #entrypoint;  \
            exit(-1);                                                          \
        }                                                                      \
    }

#define GET_DEVICE_PROC_ADDR(dev, entrypoint)                                  \
    {                                                                          \
        info.fp##entrypoint =                                                  \
            (PFN_vk##entrypoint)vkGetDeviceProcAddr(dev, "vk" #entrypoint);    \
        if (info.fp##entrypoint == NULL) {                                     \
            std::cout << "vkGetDeviceProcAddr failed to find vk" #entrypoint;  \
            exit(-1);                                                          \
        }                                                                      \
    }

#if defined(NDEBUG) && defined(__GNUC__)
#define U_ASSERT_ONLY __attribute__((unused))
#else
#define U_ASSERT_ONLY
#endif

std::string get_base_data_dir();
std::string get_data_dir(std::string filename);

/*
 * structure to track all objects related to a texture.
 */
struct texture_object {
    VkSampler sampler;

    VkImage image;
    VkImageLayout imageLayout;

    VkDeviceMemory mem;
    VkImageView view;
    int32_t tex_width, tex_height;
};

/*
 * Keep each of our swap chain buffers' image, command buffer and view in one
 * spot
 */
typedef struct _swap_chain_buffers {
    VkImage image;
    VkImageView view;
} swap_chain_buffer;

/*
 * A layer can expose extensions, keep track of those
 * extensions here.
 */
typedef struct {
    VkLayerProperties properties;
    std::vector<VkExtensionProperties> extensions;
} layer_properties;

/*
 * Structure for tracking information used / created / modified
 * by utility functions.
 */
struct sample_info {
#ifdef _WIN32
#define APP_NAME_STR_LEN 80
    HINSTANCE connection;        // hInstance - Windows Instance
    char name[APP_NAME_STR_LEN]; // Name to put on the window/icon
    HWND window;                 // hWnd - window handle
#elif defined(__ANDROID__)
    PFN_vkCreateAndroidSurfaceKHR fpCreateAndroidSurfaceKHR;
#else  // _WIN32
    xcb_connection_t *connection;
    xcb_screen_t *screen;
    xcb_window_t window;
    xcb_intern_atom_reply_t *atom_wm_delete_window;
#endif // _WIN32
    VkSurfaceKHR surface;
    bool prepared;
    bool use_staging_buffer;
    bool save_images;

    std::vector<const char *> instance_layer_names;
    std::vector<const char *> instance_extension_names;
    std::vector<layer_properties> instance_layer_properties;
    std::vector<VkExtensionProperties> instance_extension_properties;
    VkInstance inst;

    std::vector<const char *> device_layer_names;
    std::vector<const char *> device_extension_names;
    std::vector<layer_properties> device_layer_properties;
    std::vector<VkExtensionProperties> device_extension_properties;
    std::vector<VkPhysicalDevice> gpus;
    VkDevice device;
    VkQueue queue;
    uint32_t graphics_queue_family_index;
    VkPhysicalDeviceProperties gpu_props;
    std::vector<VkQueueFamilyProperties> queue_props;
    VkPhysicalDeviceMemoryProperties memory_properties;

    VkFramebuffer *framebuffers;
    int width, height;
    VkFormat format;

    uint32_t swapchainImageCount;
    VkSwapchainKHR swap_chain;
    std::vector<swap_chain_buffer> buffers;
    VkSemaphore presentCompleteSemaphore;

    VkCommandPool cmd_pool;

    struct {
        VkFormat format;

        VkImage image;
        VkDeviceMemory mem;
        VkImageView view;
    } depth;

    std::vector<struct texture_object> textures;

    struct {
        VkBuffer buf;
        VkDeviceMemory mem;
        VkDescriptorBufferInfo buffer_info;
    } uniform_data;

    struct {
        VkDescriptorImageInfo image_info;
    } texture_data;
    VkDeviceMemory stagingMemory;
    VkImage stagingImage;

    struct {
        VkBuffer buf;
        VkDeviceMemory mem;
        VkDescriptorBufferInfo buffer_info;
    } vertex_buffer;
    VkVertexInputBindingDescription vi_binding;
    VkVertexInputAttributeDescription vi_attribs[2];

    /*************
    glm::mat4 Projection;
    glm::mat4 View;
    glm::mat4 Model;
    glm::mat4 Clip;
    glm::mat4 MVP;
    *************/

    mat4x4 Projection;
    mat4x4 View;
    mat4x4 Model;
    mat4x4 Clip;
    mat4x4 MVP;

    VkCommandBuffer cmd; // Buffer for initialization commands
    VkPipelineLayout pipeline_layout;
    std::vector<VkDescriptorSetLayout> desc_layout;
    VkPipelineCache pipelineCache;
    VkRenderPass render_pass;
    VkPipeline pipeline;

    VkPipelineShaderStageCreateInfo shaderStages[2];

    VkDescriptorPool desc_pool;
    std::vector<VkDescriptorSet> desc_set;

    PFN_vkCreateDebugReportCallbackEXT dbgCreateDebugReportCallback;
    PFN_vkDestroyDebugReportCallbackEXT dbgDestroyDebugReportCallback;
    PFN_vkDebugReportMessageEXT dbgBreakCallback;
    std::vector<VkDebugReportCallbackEXT> debug_report_callbacks;

    uint32_t current_buffer;
    uint32_t queue_count;

    VkViewport viewport;
    VkRect2D scissor;
};
void process_command_line_args(struct sample_info &info, int argc,
                               char *argv[]);
bool memory_type_from_properties(struct sample_info &info, uint32_t typeBits,
                                 VkFlags requirements_mask,
                                 uint32_t *typeIndex);

void set_image_layout(struct sample_info &demo, VkImage image,
                      VkImageAspectFlags aspectMask,
                      VkImageLayout old_image_layout,
                      VkImageLayout new_image_layout);

bool read_ppm(char const *const filename, int &width, int &height,
              uint64_t rowPitch, unsigned char *dataPtr);
void write_ppm(struct sample_info &info, const char *basename);
void extract_version(uint32_t version, uint32_t &major, uint32_t &minor,
                     uint32_t &patch);
bool GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader,
               std::vector<unsigned int> &spirv);
void init_glslang();
void finalize_glslang();
void wait_seconds(int seconds);
void print_UUID(uint8_t *pipelineCacheUUID);
std::string get_file_directory();

typedef unsigned long long timestamp_t;
timestamp_t get_milliseconds();

// Main entry point of samples
int sample_main(int argc, char *argv[]);

#ifdef __ANDROID__
// Android specific definitions & helpers.
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
// Replace printf to logcat output.
#define printf(...) __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__);

bool Android_process_command();
ANativeWindow* AndroidGetApplicationWindow();
FILE* AndroidFopen(const char* fname, const char* mode);
void AndroidGetWindowSize(int32_t *width, int32_t *height);
bool AndroidLoadFile(const char* filePath, std::string *data);

#ifndef VK_API_VERSION_1_0
// On Android, NDK would include slightly older version of headers that is missing the definition.
#define VK_API_VERSION_1_0 VK_API_VERSION
#endif

#endif
<commit_msg>Update util.hpp<commit_after>/*
 * Vulkan Samples
 *
 * Copyright (C) 2015-2016 Valve Corporation
 * Copyright (C) 2015-2016 LunarG, Inc.
 *
 * 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>
#include <string>
#include <sstream>
#include <vector>

#include "linmath.h"

#ifdef _WIN32
#pragma comment(linker, "/subsystem:console")
#define WIN32_LEAN_AND_MEAN
#define VK_USE_PLATFORM_WIN32_KHR
#define NOMINMAX /* Don't let Windows define min() or max() */
#define APP_NAME_STR_LEN 80
#elif defined(__ANDROID__)
// Include files for Android
#include <unistd.h>
#include <android/log.h>
#include "vulkan_wrapper.h" // Include Vulkan_wrapper and dynamically load symbols.
#else //__ANDROID__
#define VK_USE_PLATFORM_XCB_KHR
#include <unistd.h>
#include "vulkan/vk_sdk_platform.h"
#endif // _WIN32

#include <vulkan/vulkan.h>

/* Number of descriptor sets needs to be the same at alloc,       */
/* pipeline layout creation, and descriptor set layout creation   */
#define NUM_DESCRIPTOR_SETS 1

/* Number of samples needs to be the same at image creation,      */
/* renderpass creation and pipeline creation.                     */
#define NUM_SAMPLES VK_SAMPLE_COUNT_1_BIT

/* Number of viewports and number of scissors have to be the same */
/* at pipeline creation and in any call to set them dynamically   */
/* They also have to be the same as each other                    */
#define NUM_VIEWPORTS 1
#define NUM_SCISSORS NUM_VIEWPORTS

/* Amount of time, in nanoseconds, to wait for a command buffer to complete */
#define FENCE_TIMEOUT 100000000

#define GET_INSTANCE_PROC_ADDR(inst, entrypoint)                               \
    {                                                                          \
        info.fp##entrypoint =                                                  \
            (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \
        if (info.fp##entrypoint == NULL) {                                     \
            std::cout << "vkGetDeviceProcAddr failed to find vk" #entrypoint;  \
            exit(-1);                                                          \
        }                                                                      \
    }

#define GET_DEVICE_PROC_ADDR(dev, entrypoint)                                  \
    {                                                                          \
        info.fp##entrypoint =                                                  \
            (PFN_vk##entrypoint)vkGetDeviceProcAddr(dev, "vk" #entrypoint);    \
        if (info.fp##entrypoint == NULL) {                                     \
            std::cout << "vkGetDeviceProcAddr failed to find vk" #entrypoint;  \
            exit(-1);                                                          \
        }                                                                      \
    }

#if defined(NDEBUG) && defined(__GNUC__)
#define U_ASSERT_ONLY __attribute__((unused))
#else
#define U_ASSERT_ONLY
#endif

std::string get_base_data_dir();
std::string get_data_dir(std::string filename);

/*
 * structure to track all objects related to a texture.
 */
struct texture_object {
    VkSampler sampler;

    VkImage image;
    VkImageLayout imageLayout;

    VkDeviceMemory mem;
    VkImageView view;
    int32_t tex_width, tex_height;
};

/*
 * Keep each of our swap chain buffers' image, command buffer and view in one
 * spot
 */
typedef struct _swap_chain_buffers {
    VkImage image;
    VkImageView view;
} swap_chain_buffer;

/*
 * A layer can expose extensions, keep track of those
 * extensions here.
 */
typedef struct {
    VkLayerProperties properties;
    std::vector<VkExtensionProperties> extensions;
} layer_properties;

/*
 * Structure for tracking information used / created / modified
 * by utility functions.
 */
struct sample_info {
#ifdef _WIN32
#define APP_NAME_STR_LEN 80
    HINSTANCE connection;        // hInstance - Windows Instance
    char name[APP_NAME_STR_LEN]; // Name to put on the window/icon
    HWND window;                 // hWnd - window handle
#elif defined(__ANDROID__)
    PFN_vkCreateAndroidSurfaceKHR fpCreateAndroidSurfaceKHR;
#else  // _WIN32
    xcb_connection_t *connection;
    xcb_screen_t *screen;
    xcb_window_t window;
    xcb_intern_atom_reply_t *atom_wm_delete_window;
#endif // _WIN32
    VkSurfaceKHR surface;
    bool prepared;
    bool use_staging_buffer;
    bool save_images;

    std::vector<const char *> instance_layer_names;
    std::vector<const char *> instance_extension_names;
    std::vector<layer_properties> instance_layer_properties;
    std::vector<VkExtensionProperties> instance_extension_properties;
    VkInstance inst;

    std::vector<const char *> device_layer_names;
    std::vector<const char *> device_extension_names;
    std::vector<layer_properties> device_layer_properties;
    std::vector<VkExtensionProperties> device_extension_properties;
    std::vector<VkPhysicalDevice> gpus;
    VkDevice device;
    VkQueue queue;
    uint32_t graphics_queue_family_index;
    VkPhysicalDeviceProperties gpu_props;
    std::vector<VkQueueFamilyProperties> queue_props;
    VkPhysicalDeviceMemoryProperties memory_properties;

    VkFramebuffer *framebuffers;
    int width, height;
    VkFormat format;

    uint32_t swapchainImageCount;
    VkSwapchainKHR swap_chain;
    std::vector<swap_chain_buffer> buffers;
    VkSemaphore presentCompleteSemaphore;

    VkCommandPool cmd_pool;

    struct {
        VkFormat format;

        VkImage image;
        VkDeviceMemory mem;
        VkImageView view;
    } depth;

    std::vector<struct texture_object> textures;

    struct {
        VkBuffer buf;
        VkDeviceMemory mem;
        VkDescriptorBufferInfo buffer_info;
    } uniform_data;

    struct {
        VkDescriptorImageInfo image_info;
    } texture_data;
    VkDeviceMemory stagingMemory;
    VkImage stagingImage;

    struct {
        VkBuffer buf;
        VkDeviceMemory mem;
        VkDescriptorBufferInfo buffer_info;
    } vertex_buffer;
    VkVertexInputBindingDescription vi_binding;
    VkVertexInputAttributeDescription vi_attribs[2];

    /*************
    glm::mat4 Projection;
    glm::mat4 View;
    glm::mat4 Model;
    glm::mat4 Clip;
    glm::mat4 MVP;
    *************/

    mat4x4 Projection;
    mat4x4 View;
    mat4x4 Model;
    mat4x4 Clip;
    mat4x4 MVP;

    VkCommandBuffer cmd; // Buffer for initialization commands
    VkPipelineLayout pipeline_layout;
    std::vector<VkDescriptorSetLayout> desc_layout;
    VkPipelineCache pipelineCache;
    VkRenderPass render_pass;
    VkPipeline pipeline;

    VkPipelineShaderStageCreateInfo shaderStages[2];

    VkDescriptorPool desc_pool;
    std::vector<VkDescriptorSet> desc_set;

    PFN_vkCreateDebugReportCallbackEXT dbgCreateDebugReportCallback;
    PFN_vkDestroyDebugReportCallbackEXT dbgDestroyDebugReportCallback;
    PFN_vkDebugReportMessageEXT dbgBreakCallback;
    std::vector<VkDebugReportCallbackEXT> debug_report_callbacks;

    uint32_t current_buffer;
    uint32_t queue_count;

    VkViewport viewport;
    VkRect2D scissor;
};
void process_command_line_args(struct sample_info &info, int argc,
                               char *argv[]);
bool memory_type_from_properties(struct sample_info &info, uint32_t typeBits,
                                 VkFlags requirements_mask,
                                 uint32_t *typeIndex);

void set_image_layout(struct sample_info &demo, VkImage image,
                      VkImageAspectFlags aspectMask,
                      VkImageLayout old_image_layout,
                      VkImageLayout new_image_layout);

bool read_ppm(char const *const filename, int &width, int &height,
              uint64_t rowPitch, unsigned char *dataPtr);
void write_ppm(struct sample_info &info, const char *basename);
void extract_version(uint32_t version, uint32_t &major, uint32_t &minor,
                     uint32_t &patch);
bool GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader,
               std::vector<unsigned int> &spirv);
void init_glslang();
void finalize_glslang();
void wait_seconds(int seconds);
void print_UUID(uint8_t *pipelineCacheUUID);
std::string get_file_directory();

typedef unsigned long long timestamp_t;
timestamp_t get_milliseconds();

// Main entry point of samples
int sample_main(int argc, char *argv[]);

#ifdef __ANDROID__
// Android specific definitions & helpers.
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
// Replace printf to logcat output.
#define printf(...) __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__);

bool Android_process_command();
ANativeWindow* AndroidGetApplicationWindow();
FILE* AndroidFopen(const char* fname, const char* mode);
void AndroidGetWindowSize(int32_t *width, int32_t *height);
bool AndroidLoadFile(const char* filePath, std::string *data);

#ifndef VK_API_VERSION_1_0
// On Android, NDK would include slightly older version of headers that is missing the definition.
#define VK_API_VERSION_1_0 VK_API_VERSION
#endif

#endif
<|endoftext|>


<commit_before>#include <QPushButton>
#include <QDebug>
#include <QContextMenuEvent>
#include <QMenu>
#include <QHeaderView>
#include "../model/modadapter.h"
#include "astreewidget.h"
#include "astreeitem.h"

AsTreeWidget::AsTreeWidget(QWidget* parent): QTreeWidget(parent)
{
    setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, &AsTreeWidget::customContextMenuRequested, this, &AsTreeWidget::showContextMenu);
    header()->setStretchLastSection(false);
    setExpandsOnDoubleClick(false);
}

void AsTreeWidget::update()
{
    for (AsTreeItem* treeItem : items)
    {
        treeItem->update();
    }
}

void AsTreeWidget::showContextMenu(const QPoint& point)
{
    AsTreeItem* item = (AsTreeItem*) itemAt(point);
    if (item != nullptr)
    {
        QMenu menu(this);
        ISyncItem* syncItem = item->syncItem();
        IRepository* repository = dynamic_cast<IRepository*>(syncItem);
        if(repository != nullptr)
        {
            menu.addAction("Force join", [=] ()
            {
                repository->join();
            });
            menu.addAction("Force start", [=] ()
            {
                repository->start();
            });
            menu.addAction("Recheck", [=] ()
            {
                syncItem->check();
            });
        }
        else
        {
            const ModAdapter* modAdapter = dynamic_cast<ModAdapter*>(syncItem);
            menu.addAction("Recheck", [=] () {
                modAdapter->forceCheck();
            });
        }
        menu.exec(QCursor::pos());
    }
}

void AsTreeWidget::setRepositories(QList<IRepository*> repositories)
{
    clear();
    items.clear();
    addRepositories(repositories);
    header()->resizeSections(QHeaderView::ResizeToContents);
    header()->resizeSection(2, header()->sectionSize(2) + 50); //Status
    header()->resizeSection(4, header()->sectionSize(4) + 25); //Size
    //Hack to make name column take remaining space
    header()->setSectionResizeMode(1, QHeaderView::Stretch);
    header()->sectionSize(1); //This is required!
    header()->setSectionResizeMode(1, QHeaderView::Interactive);
}

void AsTreeWidget::addRepositories(QList<IRepository*> repositories)
{
    for (IRepository* repo : repositories)
    {
        QCheckBox* repoCheckBox = new QCheckBox(this);

        QPushButton* startButton = new QPushButton("Start Game", this);
        QPushButton* joinButton = new QPushButton("Join Server", this);
        AsTreeItem* repoItem = new AsTreeItem(this, repo, repoCheckBox, startButton, joinButton);
        addTopLevelItem(repoItem);

        connect(startButton, &QPushButton::pressed, [=] () {
            repo->start();
        });
        connect(joinButton, &QPushButton::pressed, [=] () {
            repo->join();
        });
        connect(this, &AsTreeWidget::itemClicked, [=] (QTreeWidgetItem* item, int) {
            if (item->isExpanded())
            {
                collapseItem(item);
                return;
            }
            expandItem(item);
        });

        setItemWidget(repoItem, 0, repoCheckBox);
        setItemWidget(repoItem, 5, startButton);
        setItemWidget(repoItem, 6, joinButton);
        items.append(repoItem);
        for (ISyncItem* mod : repo->uiMods())
        {
            QCheckBox* modCheckBox = new QCheckBox(this);
            AsTreeItem* modItem = new AsTreeItem(repoItem, mod, modCheckBox);
            setItemWidget(modItem, 0, modCheckBox);
            repoItem->addChild(modItem);
            items.append(modItem);
        }
    }
}
<commit_msg>Fixed expand bug<commit_after>#include <QPushButton>
#include <QDebug>
#include <QContextMenuEvent>
#include <QMenu>
#include <QHeaderView>
#include "../model/modadapter.h"
#include "astreewidget.h"
#include "astreeitem.h"

AsTreeWidget::AsTreeWidget(QWidget* parent): QTreeWidget(parent)
{
    setContextMenuPolicy(Qt::CustomContextMenu);
    setExpandsOnDoubleClick(false);
    header()->setStretchLastSection(false);

    connect(this, &AsTreeWidget::customContextMenuRequested, this, &AsTreeWidget::showContextMenu);
    connect(this, &AsTreeWidget::itemClicked, [=] (QTreeWidgetItem* item, int) {
        if (item->isExpanded())
        {
            collapseItem(item);
            return;
        }
        expandItem(item);
    });
}

void AsTreeWidget::update()
{
    for (AsTreeItem* treeItem : items)
    {
        treeItem->update();
    }
}

void AsTreeWidget::showContextMenu(const QPoint& point)
{
    AsTreeItem* item = (AsTreeItem*) itemAt(point);
    if (item != nullptr)
    {
        QMenu menu(this);
        ISyncItem* syncItem = item->syncItem();
        IRepository* repository = dynamic_cast<IRepository*>(syncItem);
        if(repository != nullptr)
        {
            menu.addAction("Force join", [=] ()
            {
                repository->join();
            });
            menu.addAction("Force start", [=] ()
            {
                repository->start();
            });
            menu.addAction("Recheck", [=] ()
            {
                syncItem->check();
            });
        }
        else
        {
            const ModAdapter* modAdapter = dynamic_cast<ModAdapter*>(syncItem);
            menu.addAction("Recheck", [=] () {
                modAdapter->forceCheck();
            });
        }
        menu.exec(QCursor::pos());
    }
}

void AsTreeWidget::setRepositories(QList<IRepository*> repositories)
{
    clear();
    items.clear();
    addRepositories(repositories);
    header()->resizeSections(QHeaderView::ResizeToContents);
    header()->resizeSection(2, header()->sectionSize(2) + 50); //Status
    header()->resizeSection(4, header()->sectionSize(4) + 25); //Size
    //Hack to make name column take remaining space
    header()->setSectionResizeMode(1, QHeaderView::Stretch);
    header()->sectionSize(1); //This is required!
    header()->setSectionResizeMode(1, QHeaderView::Interactive);
}

void AsTreeWidget::addRepositories(QList<IRepository*> repositories)
{
    for (IRepository* repo : repositories)
    {
        QCheckBox* repoCheckBox = new QCheckBox(this);

        QPushButton* startButton = new QPushButton("Start Game", this);
        QPushButton* joinButton = new QPushButton("Join Server", this);
        AsTreeItem* repoItem = new AsTreeItem(this, repo, repoCheckBox, startButton, joinButton);
        addTopLevelItem(repoItem);

        connect(startButton, &QPushButton::pressed, [=] () {
            repo->start();
        });
        connect(joinButton, &QPushButton::pressed, [=] () {
            repo->join();
        });

        setItemWidget(repoItem, 0, repoCheckBox);
        setItemWidget(repoItem, 5, startButton);
        setItemWidget(repoItem, 6, joinButton);
        items.append(repoItem);
        for (ISyncItem* mod : repo->uiMods())
        {
            QCheckBox* modCheckBox = new QCheckBox(this);
            AsTreeItem* modItem = new AsTreeItem(repoItem, mod, modCheckBox);
            setItemWidget(modItem, 0, modCheckBox);
            repoItem->addChild(modItem);
            items.append(modItem);
        }
    }
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkXYZMolReader2.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkXYZMolReader2.h"

#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"

#include "vtkMolecule.h"
#include "vtkPeriodicTable.h"

#include "vtkStreamingDemandDrivenPipeline.h"

#include <math.h>
#include <string.h>

#include <sstream>
//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkXYZMolReader2);

//----------------------------------------------------------------------------
vtkXYZMolReader2::vtkXYZMolReader2()
  : FileName(NULL)
{
  this->SetNumberOfInputPorts(0);
  this->NumberOfTimeSteps = 0;
  this->NumberOfAtoms = 0;
}

//----------------------------------------------------------------------------
vtkXYZMolReader2::~vtkXYZMolReader2()
{
  this->SetFileName(NULL);
}

//----------------------------------------------------------------------------
vtkMolecule *vtkXYZMolReader2::GetOutput()
{
  return vtkMolecule::SafeDownCast(this->GetOutputDataObject(0));
}

//----------------------------------------------------------------------------
void vtkXYZMolReader2::SetOutput(vtkMolecule *output)
{
  this->GetExecutive()->SetOutputData(0, output);
}

int vtkXYZMolReader2::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  vtkInformation* outInfo = outputVector->GetInformationObject(0);

  if (!this->FileName)
    {
    return 0;
    }

  ifstream file_in(this->FileName);

  if(!file_in.is_open())
    {
    vtkErrorMacro ("vtkXYZMolReader2 error opening file: " << this->FileName);
    return 0;
    }

  while(file_in)
    {
    int natoms;
    istream::pos_type current_pos = file_in.tellg();
    std::string title;
    getline(file_in, title); // first title line
    std::istringstream tmp(title);
    tmp >> natoms;
    if (!file_in)
      break; // reached after last timestep

    file_positions.push_back(current_pos);

    if (!this->NumberOfAtoms) // first read
      {
      this->NumberOfAtoms = natoms;
      }
    else
      {
// do a consistency check with previous step. Assume there should be same # of atoms
      if(this->NumberOfAtoms != natoms)
      vtkWarningMacro ("XYZMolReader2 has different number of atoms at each timestep "
                      << this->NumberOfAtoms << " " << natoms);
      }

    getline(file_in, title);  // second title line
    if(!title.empty())
      {
      // second title line may have a time index, time value and E?
      // search now for an optional "time = value" field and assign it if found
      std::size_t found = title.find(std::string("time"));
      if (found!=std::string::npos)
        {
        std::istringstream tmp(&title[found+6]);
        double timeValue;
        tmp >> timeValue;
        this->TimeSteps.push_back(timeValue);
        }
      }
    else
      {
      this->TimeSteps.push_back(this->NumberOfTimeSteps);
      }

    this->NumberOfTimeSteps++;
    for(int i=0; i < natoms; i++)
      {
      getline(file_in, title); // for each atom a line with symbol, x, y, z
      }
    }
  file_in.close();

  outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),
    &this->TimeSteps[0], this->NumberOfTimeSteps);
  double timeRange[2];
  timeRange[0] = this->TimeSteps[0];
  timeRange[1] = this->TimeSteps[this->NumberOfTimeSteps - 1];
  outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2);
  return 1;
}

int vtkXYZMolReader2::RequestData(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkMolecule *output = vtkMolecule::SafeDownCast
    (vtkDataObject::GetData(outputVector));

  if (!output)
    {
    vtkErrorMacro(<<"vtkXYZMolReader2 does not have a vtkMolecule "
                  "as output.");
    return 1;
    }

  if (!this->FileName)
    {
    return 0;
    }

  ifstream file_in(this->FileName);

  if(!file_in.is_open())
    {
    vtkErrorMacro ("vtkXYZMolReader2 error opening file: " << this->FileName);
    return 0;
    }

  int timestep=0;
  std::vector<double>::iterator it = this->TimeSteps.begin();

  if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()))
    {
    // Get the requested time step.
    double requestedTimeStep =
      outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());

    //find the timestep with the closest value
    if(requestedTimeStep < *it)
      {
      requestedTimeStep = *it;
      vtkWarningMacro ("XYZMolReader2 using its first timestep value of "
                      << requestedTimeStep);
      }
    for (it = this->TimeSteps.begin(); it < this->TimeSteps.end(); it++, timestep++)
      {
      if ((*it > requestedTimeStep))
        break;
      }

    if(it != this->TimeSteps.end())
      {
      it--;
      timestep--;
      if(fabs(*it - requestedTimeStep) > fabs(*(it+1) - requestedTimeStep))
        {
        // closer to next timestep value
        timestep++;
        it++;
        }
      }
    else
      {
      it--; timestep--;
      }
    }
  else
    {
    timestep = 0;
    }

  file_in.seekg(file_positions[timestep]);
  int nbAtoms;
  std::string title;
  getline(file_in, title); // first title line
  std::istringstream tmp(title);
  tmp >> nbAtoms;

  if(nbAtoms != this->NumberOfAtoms)
    {
    vtkErrorMacro ("vtkXYZMolReader2 error reading file: " << this->FileName
                     << " Premature EOF while reading molecule.");
    file_in.close();
    return 0;
    }

  getline(file_in, title);  // second title line

// construct vtkMolecule
  output->Initialize();

  vtkPeriodicTable *pT = vtkPeriodicTable::New();
  for(int i = 0; i < this->NumberOfAtoms; i++)
    {
    char atomType[16];
    float x, y, z;
    getline(file_in, title);  // an atom's position line
    std::istringstream tmp(title);
    tmp >> atomType >> x >> y >> z;
    if (!tmp) // checking we are at end of line
      {
      vtkErrorMacro ("vtkXYZMolReader2 error reading file: " << this->FileName
                     << " Problem reading atoms' positions.");
      file_in.close();
      return 0;
      }
    output->AppendAtom(pT->GetAtomicNumber(atomType), x, y, z);
    }
  pT->Delete();
  file_in.close();

  return 1;
}

//----------------------------------------------------------------------------
void vtkXYZMolReader2::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "Number of Atoms: " << this->NumberOfAtoms << endl;
  os << indent << "Number of TimeSteps: " << this->NumberOfTimeSteps;
}
<commit_msg>removed shadow var and clean up the scanning of atoms<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkXYZMolReader2.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkXYZMolReader2.h"

#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"

#include "vtkMolecule.h"
#include "vtkPeriodicTable.h"

#include "vtkStreamingDemandDrivenPipeline.h"

#include <math.h>
#include <string.h>

#include <sstream>
//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkXYZMolReader2);

//----------------------------------------------------------------------------
vtkXYZMolReader2::vtkXYZMolReader2()
  : FileName(NULL)
{
  this->SetNumberOfInputPorts(0);
  this->NumberOfTimeSteps = 0;
  this->NumberOfAtoms = 0;
}

//----------------------------------------------------------------------------
vtkXYZMolReader2::~vtkXYZMolReader2()
{
  this->SetFileName(NULL);
}

//----------------------------------------------------------------------------
vtkMolecule *vtkXYZMolReader2::GetOutput()
{
  return vtkMolecule::SafeDownCast(this->GetOutputDataObject(0));
}

//----------------------------------------------------------------------------
void vtkXYZMolReader2::SetOutput(vtkMolecule *output)
{
  this->GetExecutive()->SetOutputData(0, output);
}

int vtkXYZMolReader2::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  vtkInformation* outInfo = outputVector->GetInformationObject(0);

  if (!this->FileName)
    {
    return 0;
    }

  ifstream file_in(this->FileName);

  if(!file_in.is_open())
    {
    vtkErrorMacro ("vtkXYZMolReader2 error opening file: " << this->FileName);
    return 0;
    }

  while(file_in)
    {
    int natoms;
    istream::pos_type current_pos = file_in.tellg();
    file_in >> natoms;
    file_in.get();  // end of line char
    if (!file_in)
      break; // reached after last timestep

    file_positions.push_back(current_pos);

    if (!this->NumberOfAtoms) // first read
      {
      this->NumberOfAtoms = natoms;
      }
    else
      {
// do a consistency check with previous step. Assume there should be same # of atoms
      if(this->NumberOfAtoms != natoms)
      vtkWarningMacro ("XYZMolReader2 has different number of atoms at each timestep "
                      << this->NumberOfAtoms << " " << natoms);
      }
    std::string title;
    getline(file_in, title);  // second title line
    if(!title.empty())
      {
      // second title line may have a time index, time value and E?
      // search now for an optional "time = value" field and assign it if found
      std::size_t found = title.find(std::string("time"));
      if (found!=std::string::npos)
        {
        std::istringstream tmp(&title[found+6]);
        double timeValue;
        tmp >> timeValue;
        this->TimeSteps.push_back(timeValue);
        }
      }
    else
      {
      this->TimeSteps.push_back(this->NumberOfTimeSteps);
      }

    this->NumberOfTimeSteps++;
    for(int i=0; i < natoms; i++)
      {
      getline(file_in, title); // for each atom a line with symbol, x, y, z
      }
    }
  file_in.close();

  outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),
    &this->TimeSteps[0], this->NumberOfTimeSteps);
  double timeRange[2];
  timeRange[0] = this->TimeSteps[0];
  timeRange[1] = this->TimeSteps[this->NumberOfTimeSteps - 1];
  outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2);
  return 1;
}

int vtkXYZMolReader2::RequestData(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkMolecule *output = vtkMolecule::SafeDownCast
    (vtkDataObject::GetData(outputVector));

  if (!output)
    {
    vtkErrorMacro(<<"vtkXYZMolReader2 does not have a vtkMolecule "
                  "as output.");
    return 1;
    }

  if (!this->FileName)
    {
    return 0;
    }

  ifstream file_in(this->FileName);

  if(!file_in.is_open())
    {
    vtkErrorMacro ("vtkXYZMolReader2 error opening file: " << this->FileName);
    return 0;
    }

  int timestep=0;
  std::vector<double>::iterator it = this->TimeSteps.begin();

  if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()))
    {
    // Get the requested time step.
    double requestedTimeStep =
      outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());

    //find the timestep with the closest value
    if(requestedTimeStep < *it)
      {
      requestedTimeStep = *it;
      vtkWarningMacro ("XYZMolReader2 using its first timestep value of "
                      << requestedTimeStep);
      }
    for (it = this->TimeSteps.begin(); it < this->TimeSteps.end(); it++, timestep++)
      {
      if ((*it > requestedTimeStep))
        break;
      }

    if(it != this->TimeSteps.end())
      {
      it--;
      timestep--;
      if(fabs(*it - requestedTimeStep) > fabs(*(it+1) - requestedTimeStep))
        {
        // closer to next timestep value
        timestep++;
        it++;
        }
      }
    else
      {
      it--; timestep--;
      }
    }
  else
    {
    timestep = 0;
    }

  file_in.seekg(file_positions[timestep]);
  int nbAtoms;

  file_in >> nbAtoms;
  file_in.get(); // end of line char

  if(nbAtoms != this->NumberOfAtoms)
    {
    vtkErrorMacro ("vtkXYZMolReader2 error reading file: " << this->FileName
                     << " Premature EOF while reading molecule.");
    file_in.close();
    return 0;
    }
  std::string title;
  getline(file_in, title);  // second title line

// construct vtkMolecule
  output->Initialize();

  vtkPeriodicTable *pT = vtkPeriodicTable::New();
  for(int i = 0; i < this->NumberOfAtoms; i++)
    {
    char atomType[16];
    float x, y, z;
    file_in >> atomType >> x >> y >> z;
    if (file_in.fail()) // checking we are at end of line
      {
      vtkErrorMacro ("vtkXYZMolReader2 error reading file: " << this->FileName
                     << " Problem reading atoms' positions.");
      file_in.close();
      return 0;
      }
    output->AppendAtom(pT->GetAtomicNumber(atomType), x, y, z);
    }
  pT->Delete();
  file_in.close();

  return 1;
}

//----------------------------------------------------------------------------
void vtkXYZMolReader2::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "Number of Atoms: " << this->NumberOfAtoms << endl;
  os << indent << "Number of TimeSteps: " << this->NumberOfTimeSteps;
}
<|endoftext|>


<commit_before>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 1.2.0, packaged on September 2009.

 http://glc-lib.sourceforge.net

 GLC-lib is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 GLC-lib 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GLC-lib; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*****************************************************************************/

//! \file glc_factory.cpp implementation of the GLC_Factory class.

#include "glc_factory.h"
#include "io/glc_objtoworld.h"
#include "io/glc_stltoworld.h"
#include "io/glc_offtoworld.h"
#include "io/glc_3dstoworld.h"
#include "io/glc_3dxmltoworld.h"
#include "io/glc_colladatoworld.h"

#include "viewport/glc_panmover.h"
#include "viewport/glc_zoommover.h"
#include "viewport/glc_settargetmover.h"
#include "viewport/glc_trackballmover.h"
#include "viewport/glc_turntablemover.h"
#include "viewport/glc_repcrossmover.h"
#include "viewport/glc_reptrackballmover.h"

// init static member
GLC_Factory* GLC_Factory::m_pFactory= NULL;

//////////////////////////////////////////////////////////////////////
// static method
//////////////////////////////////////////////////////////////////////
// Return the unique instance of the factory
GLC_Factory* GLC_Factory::instance(const QGLContext *pContext)
{
	if(m_pFactory == NULL)
	{
		m_pFactory= new GLC_Factory(pContext);
	}
	return m_pFactory;
}

//////////////////////////////////////////////////////////////////////
// Constructor destructor
//////////////////////////////////////////////////////////////////////

// Protected constructor
GLC_Factory::GLC_Factory(const QGLContext *pContext)
: m_pQGLContext(const_cast<QGLContext*>(pContext))
{

}

// Destructor
GLC_Factory::~GLC_Factory()
{
	m_pFactory= NULL;
}

//////////////////////////////////////////////////////////////////////
// Create functions
//////////////////////////////////////////////////////////////////////

// Create a GLC_Point
GLC_3DRep GLC_Factory::createPoint(const GLC_Point3d &coord) const
{
	GLC_3DRep newPoint(new GLC_Point(coord));
	return newPoint;
}
// Create a GLC_Point
GLC_3DRep GLC_Factory::createPoint(double x, double y, double z) const
{
	GLC_3DRep newPoint(new GLC_Point(x, y, z));
	return newPoint;
}

// Create a GLC_PointSprite
GLC_3DRep GLC_Factory::createPointSprite(float size, GLC_Material* pMaterial) const
{
	GLC_3DRep newPoint(new GLC_PointSprite(size, pMaterial));
	return newPoint;
}

// Create a GLC_Line
GLC_3DRep GLC_Factory::createLine(const GLC_Point3d& point1, const GLC_Point3d& point2) const
{
	GLC_3DRep newPoint(new GLC_Line(point1, point2));
	return newPoint;
}

//  Create a GLC_Circle
GLC_3DRep GLC_Factory::createCircle(double radius, double angle) const
{
	GLC_3DRep newCircle(new GLC_Circle(radius, angle));
	return newCircle;
}
// Create a GLC_Box
GLC_3DRep GLC_Factory::createBox(double lx, double ly, double lz) const
{

	GLC_3DRep newBox(new GLC_Box(lx, ly, lz));
	return newBox;
}

// Create a GLC_Box
GLC_3DViewInstance GLC_Factory::createBox(const GLC_BoundingBox& boundingBox) const
{
	const double lx= boundingBox.upperCorner().X() - boundingBox.lowerCorner().X();
	const double ly= boundingBox.upperCorner().Y() - boundingBox.lowerCorner().Y();
	const double lz= boundingBox.upperCorner().Z() - boundingBox.lowerCorner().Z();
	GLC_Box* pBox= new GLC_Box(lx, ly, lz);
	GLC_3DViewInstance newBox(pBox);
	newBox.translate(boundingBox.center().X(), boundingBox.center().Y()
					, boundingBox.center().Z());
	return newBox;
}

// Create a GLC_Cylinder
GLC_3DRep GLC_Factory::createCylinder(double radius, double length) const
{

	GLC_3DRep newCylinder(new GLC_Cylinder(radius, length));
	return newCylinder;
}

// Create a GLC_Rectangle
GLC_3DRep GLC_Factory::createRectangle(double l1, double l2)
{
	GLC_3DRep newRectangle(new GLC_Rectangle(l1, l2));
	return newRectangle;
}

// Create a GLC_World* with a QFile
GLC_World* GLC_Factory::createWorld(QFile &file, QStringList* pAttachedFileName) const
{
	GLC_World* pWorld= NULL;
	if (QFileInfo(file).suffix().toLower() == "obj")
	{
		GLC_ObjToWorld objToWorld(m_pQGLContext);
		connect(&objToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= objToWorld.CreateWorldFromObj(file);
		if (NULL != pAttachedFileName)
		{
			(*pAttachedFileName)= objToWorld.listOfAttachedFileName();
		}
	}
	else if (QFileInfo(file).suffix().toLower() == "stl")
	{
		GLC_StlToWorld stlToWorld;
		connect(&stlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= stlToWorld.CreateWorldFromStl(file);
	}
	else if (QFileInfo(file).suffix().toLower() == "off")
	{
		GLC_OffToWorld offToWorld;
		connect(&offToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= offToWorld.CreateWorldFromOff(file);
	}
	else if (QFileInfo(file).suffix().toLower() == "3ds")
	{
		GLC_3dsToWorld studioToWorld(m_pQGLContext);
		connect(&studioToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= studioToWorld.CreateWorldFrom3ds(file);
		if (NULL != pAttachedFileName)
		{
			(*pAttachedFileName)= studioToWorld.listOfAttachedFileName();
		}
	}
	else if (QFileInfo(file).suffix().toLower() == "3dxml")
	{
		GLC_3dxmlToWorld d3dxmlToWorld(m_pQGLContext);
		connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= d3dxmlToWorld.createWorldFrom3dxml(file, false);
		if (NULL != pAttachedFileName)
		{
			(*pAttachedFileName)= d3dxmlToWorld.listOfAttachedFileName();
		}
	}
	else if (QFileInfo(file).suffix().toLower() == "dae")
	{
		GLC_ColladaToWorld colladaToWorld(m_pQGLContext);
		connect(&colladaToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= colladaToWorld.CreateWorldFromCollada(file);
		if (NULL != pAttachedFileName)
		{
			(*pAttachedFileName)= colladaToWorld.listOfAttachedFileName();
		}
	}

	return pWorld;
}

// Create a GLC_World containing only the 3dxml structure
GLC_World* GLC_Factory::createWorldStructureFrom3dxml(QFile &file) const
{
	GLC_World* pWorld= NULL;

	if (QFileInfo(file).suffix().toLower() == "3dxml")
	{
		GLC_3dxmlToWorld d3dxmlToWorld(m_pQGLContext);
		connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= d3dxmlToWorld.createWorldFrom3dxml(file, true);
	}

	return pWorld;
}

// Create 3DRep from 3dxml or 3DRep file
GLC_3DRep GLC_Factory::create3DrepFromFile(const QString& fileName) const
{
	GLC_3DRep rep;

	if ((QFileInfo(fileName).suffix().toLower() == "3dxml") || (QFileInfo(fileName).suffix().toLower() == "3drep"))
	{
		GLC_3dxmlToWorld d3dxmlToWorld(m_pQGLContext);
		connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		rep= d3dxmlToWorld.create3DrepFrom3dxmlRep(fileName);
	}

	return rep;

}

// Create a GLC_Material
GLC_Material* GLC_Factory::createMaterial() const
{
	return new GLC_Material();
}

// Create a GLC_Material
GLC_Material* GLC_Factory::createMaterial(const GLfloat *pAmbiantColor) const
{
	return new GLC_Material("Material", pAmbiantColor);
}
// Create a GLC_Material
GLC_Material* GLC_Factory::createMaterial(const QColor &color) const
{
	return new GLC_Material(color);
}

GLC_Material* GLC_Factory::createMaterial(GLC_Texture* pTexture) const
{
	return new GLC_Material(pTexture, "TextureMaterial");
}
// create a material textured with a image file name
GLC_Material* GLC_Factory::createMaterial(const QString &textureFullFileName) const
{
	GLC_Texture* pTexture= createTexture(textureFullFileName);
	return createMaterial(pTexture);
}

// create a material textured with a QImage
GLC_Material* GLC_Factory::createMaterial(const QImage &image) const
{
	GLC_Texture* pTexture= createTexture(image);
	return createMaterial(pTexture);
}

// Create a GLC_Texture

GLC_Texture* GLC_Factory::createTexture(const QString &textureFullFileName) const
{
	return new GLC_Texture(m_pQGLContext, textureFullFileName);
}

// Create a GLC_Texture with a QImage
GLC_Texture* GLC_Factory::createTexture(const QImage & image) const
{
	return new GLC_Texture(m_pQGLContext, image);
}

// Create the default mover controller
GLC_MoverController GLC_Factory::createDefaultMoverController(const QColor& color, GLC_Viewport* pViewport)
{
	GLC_MoverController defaultController;

	//////////////////////////////////////////////////////////////////////
	// Pan Mover
	//////////////////////////////////////////////////////////////////////
	// Create Pan Mover representation
	GLC_RepMover* pRepMover= new GLC_RepCrossMover(pViewport);
	pRepMover->setMainColor(color);
	QList<GLC_RepMover*> listOfRep;
	listOfRep.append(pRepMover);
	// Create the Pan Mover
	GLC_Mover* pMover= new GLC_PanMover(pViewport, listOfRep);
	// Add the Pan Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::Pan);

	//////////////////////////////////////////////////////////////////////
	// Zoom Mover
	//////////////////////////////////////////////////////////////////////
	// Copy the pan Mover representation
	pRepMover= pRepMover->clone();
	listOfRep.clear();
	listOfRep.append(pRepMover);
	// Create the Zoom Mover
	pMover= new GLC_ZoomMover(pViewport, listOfRep);
	// Add the Zoom Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::Zoom);

	//////////////////////////////////////////////////////////////////////
	// Set Target Mover
	//////////////////////////////////////////////////////////////////////
	// Create the Zoom Mover
	pMover= new GLC_SetTargetMover(pViewport);
	// Add the Zoom Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::Target);

	//////////////////////////////////////////////////////////////////////
	// Track Ball Mover
	//////////////////////////////////////////////////////////////////////
	// Copy the pan Mover representation
	pRepMover= pRepMover->clone();
	listOfRep.clear();
	listOfRep.append(pRepMover);
	// Create the track ball representation
	pRepMover= new GLC_RepTrackBallMover(pViewport);
	pRepMover->setMainColor(color);
	listOfRep.append(pRepMover);
	// Create the Track Ball Mover
	pMover= new GLC_TrackBallMover(pViewport, listOfRep);
	// Add the Track ball Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::TrackBall);

	//////////////////////////////////////////////////////////////////////
	// Turn Table Mover
	//////////////////////////////////////////////////////////////////////
	// Create the Turn Table Mover
	pMover= new GLC_TurnTableMover(pViewport);
	// Add the Turn Table Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::TurnTable);

	return defaultController;
}
<commit_msg>Update call of refactored GLC_Vector3d methods.<commit_after>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 1.2.0, packaged on September 2009.

 http://glc-lib.sourceforge.net

 GLC-lib is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 GLC-lib 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GLC-lib; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*****************************************************************************/

//! \file glc_factory.cpp implementation of the GLC_Factory class.

#include "glc_factory.h"
#include "io/glc_objtoworld.h"
#include "io/glc_stltoworld.h"
#include "io/glc_offtoworld.h"
#include "io/glc_3dstoworld.h"
#include "io/glc_3dxmltoworld.h"
#include "io/glc_colladatoworld.h"

#include "viewport/glc_panmover.h"
#include "viewport/glc_zoommover.h"
#include "viewport/glc_settargetmover.h"
#include "viewport/glc_trackballmover.h"
#include "viewport/glc_turntablemover.h"
#include "viewport/glc_repcrossmover.h"
#include "viewport/glc_reptrackballmover.h"

// init static member
GLC_Factory* GLC_Factory::m_pFactory= NULL;

//////////////////////////////////////////////////////////////////////
// static method
//////////////////////////////////////////////////////////////////////
// Return the unique instance of the factory
GLC_Factory* GLC_Factory::instance(const QGLContext *pContext)
{
	if(m_pFactory == NULL)
	{
		m_pFactory= new GLC_Factory(pContext);
	}
	return m_pFactory;
}

//////////////////////////////////////////////////////////////////////
// Constructor destructor
//////////////////////////////////////////////////////////////////////

// Protected constructor
GLC_Factory::GLC_Factory(const QGLContext *pContext)
: m_pQGLContext(const_cast<QGLContext*>(pContext))
{

}

// Destructor
GLC_Factory::~GLC_Factory()
{
	m_pFactory= NULL;
}

//////////////////////////////////////////////////////////////////////
// Create functions
//////////////////////////////////////////////////////////////////////

// Create a GLC_Point
GLC_3DRep GLC_Factory::createPoint(const GLC_Point3d &coord) const
{
	GLC_3DRep newPoint(new GLC_Point(coord));
	return newPoint;
}
// Create a GLC_Point
GLC_3DRep GLC_Factory::createPoint(double x, double y, double z) const
{
	GLC_3DRep newPoint(new GLC_Point(x, y, z));
	return newPoint;
}

// Create a GLC_PointSprite
GLC_3DRep GLC_Factory::createPointSprite(float size, GLC_Material* pMaterial) const
{
	GLC_3DRep newPoint(new GLC_PointSprite(size, pMaterial));
	return newPoint;
}

// Create a GLC_Line
GLC_3DRep GLC_Factory::createLine(const GLC_Point3d& point1, const GLC_Point3d& point2) const
{
	GLC_3DRep newPoint(new GLC_Line(point1, point2));
	return newPoint;
}

//  Create a GLC_Circle
GLC_3DRep GLC_Factory::createCircle(double radius, double angle) const
{
	GLC_3DRep newCircle(new GLC_Circle(radius, angle));
	return newCircle;
}
// Create a GLC_Box
GLC_3DRep GLC_Factory::createBox(double lx, double ly, double lz) const
{

	GLC_3DRep newBox(new GLC_Box(lx, ly, lz));
	return newBox;
}

// Create a GLC_Box
GLC_3DViewInstance GLC_Factory::createBox(const GLC_BoundingBox& boundingBox) const
{
	const double lx= boundingBox.upperCorner().x() - boundingBox.lowerCorner().x();
	const double ly= boundingBox.upperCorner().y() - boundingBox.lowerCorner().y();
	const double lz= boundingBox.upperCorner().z() - boundingBox.lowerCorner().z();
	GLC_Box* pBox= new GLC_Box(lx, ly, lz);
	GLC_3DViewInstance newBox(pBox);
	newBox.translate(boundingBox.center().x(), boundingBox.center().y()
					, boundingBox.center().z());
	return newBox;
}

// Create a GLC_Cylinder
GLC_3DRep GLC_Factory::createCylinder(double radius, double length) const
{

	GLC_3DRep newCylinder(new GLC_Cylinder(radius, length));
	return newCylinder;
}

// Create a GLC_Rectangle
GLC_3DRep GLC_Factory::createRectangle(double l1, double l2)
{
	GLC_3DRep newRectangle(new GLC_Rectangle(l1, l2));
	return newRectangle;
}

// Create a GLC_World* with a QFile
GLC_World* GLC_Factory::createWorld(QFile &file, QStringList* pAttachedFileName) const
{
	GLC_World* pWorld= NULL;
	if (QFileInfo(file).suffix().toLower() == "obj")
	{
		GLC_ObjToWorld objToWorld(m_pQGLContext);
		connect(&objToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= objToWorld.CreateWorldFromObj(file);
		if (NULL != pAttachedFileName)
		{
			(*pAttachedFileName)= objToWorld.listOfAttachedFileName();
		}
	}
	else if (QFileInfo(file).suffix().toLower() == "stl")
	{
		GLC_StlToWorld stlToWorld;
		connect(&stlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= stlToWorld.CreateWorldFromStl(file);
	}
	else if (QFileInfo(file).suffix().toLower() == "off")
	{
		GLC_OffToWorld offToWorld;
		connect(&offToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= offToWorld.CreateWorldFromOff(file);
	}
	else if (QFileInfo(file).suffix().toLower() == "3ds")
	{
		GLC_3dsToWorld studioToWorld(m_pQGLContext);
		connect(&studioToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= studioToWorld.CreateWorldFrom3ds(file);
		if (NULL != pAttachedFileName)
		{
			(*pAttachedFileName)= studioToWorld.listOfAttachedFileName();
		}
	}
	else if (QFileInfo(file).suffix().toLower() == "3dxml")
	{
		GLC_3dxmlToWorld d3dxmlToWorld(m_pQGLContext);
		connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= d3dxmlToWorld.createWorldFrom3dxml(file, false);
		if (NULL != pAttachedFileName)
		{
			(*pAttachedFileName)= d3dxmlToWorld.listOfAttachedFileName();
		}
	}
	else if (QFileInfo(file).suffix().toLower() == "dae")
	{
		GLC_ColladaToWorld colladaToWorld(m_pQGLContext);
		connect(&colladaToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= colladaToWorld.CreateWorldFromCollada(file);
		if (NULL != pAttachedFileName)
		{
			(*pAttachedFileName)= colladaToWorld.listOfAttachedFileName();
		}
	}

	return pWorld;
}

// Create a GLC_World containing only the 3dxml structure
GLC_World* GLC_Factory::createWorldStructureFrom3dxml(QFile &file) const
{
	GLC_World* pWorld= NULL;

	if (QFileInfo(file).suffix().toLower() == "3dxml")
	{
		GLC_3dxmlToWorld d3dxmlToWorld(m_pQGLContext);
		connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		pWorld= d3dxmlToWorld.createWorldFrom3dxml(file, true);
	}

	return pWorld;
}

// Create 3DRep from 3dxml or 3DRep file
GLC_3DRep GLC_Factory::create3DrepFromFile(const QString& fileName) const
{
	GLC_3DRep rep;

	if ((QFileInfo(fileName).suffix().toLower() == "3dxml") || (QFileInfo(fileName).suffix().toLower() == "3drep"))
	{
		GLC_3dxmlToWorld d3dxmlToWorld(m_pQGLContext);
		connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
		rep= d3dxmlToWorld.create3DrepFrom3dxmlRep(fileName);
	}

	return rep;

}

// Create a GLC_Material
GLC_Material* GLC_Factory::createMaterial() const
{
	return new GLC_Material();
}

// Create a GLC_Material
GLC_Material* GLC_Factory::createMaterial(const GLfloat *pAmbiantColor) const
{
	return new GLC_Material("Material", pAmbiantColor);
}
// Create a GLC_Material
GLC_Material* GLC_Factory::createMaterial(const QColor &color) const
{
	return new GLC_Material(color);
}

GLC_Material* GLC_Factory::createMaterial(GLC_Texture* pTexture) const
{
	return new GLC_Material(pTexture, "TextureMaterial");
}
// create a material textured with a image file name
GLC_Material* GLC_Factory::createMaterial(const QString &textureFullFileName) const
{
	GLC_Texture* pTexture= createTexture(textureFullFileName);
	return createMaterial(pTexture);
}

// create a material textured with a QImage
GLC_Material* GLC_Factory::createMaterial(const QImage &image) const
{
	GLC_Texture* pTexture= createTexture(image);
	return createMaterial(pTexture);
}

// Create a GLC_Texture

GLC_Texture* GLC_Factory::createTexture(const QString &textureFullFileName) const
{
	return new GLC_Texture(m_pQGLContext, textureFullFileName);
}

// Create a GLC_Texture with a QImage
GLC_Texture* GLC_Factory::createTexture(const QImage & image) const
{
	return new GLC_Texture(m_pQGLContext, image);
}

// Create the default mover controller
GLC_MoverController GLC_Factory::createDefaultMoverController(const QColor& color, GLC_Viewport* pViewport)
{
	GLC_MoverController defaultController;

	//////////////////////////////////////////////////////////////////////
	// Pan Mover
	//////////////////////////////////////////////////////////////////////
	// Create Pan Mover representation
	GLC_RepMover* pRepMover= new GLC_RepCrossMover(pViewport);
	pRepMover->setMainColor(color);
	QList<GLC_RepMover*> listOfRep;
	listOfRep.append(pRepMover);
	// Create the Pan Mover
	GLC_Mover* pMover= new GLC_PanMover(pViewport, listOfRep);
	// Add the Pan Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::Pan);

	//////////////////////////////////////////////////////////////////////
	// Zoom Mover
	//////////////////////////////////////////////////////////////////////
	// Copy the pan Mover representation
	pRepMover= pRepMover->clone();
	listOfRep.clear();
	listOfRep.append(pRepMover);
	// Create the Zoom Mover
	pMover= new GLC_ZoomMover(pViewport, listOfRep);
	// Add the Zoom Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::Zoom);

	//////////////////////////////////////////////////////////////////////
	// Set Target Mover
	//////////////////////////////////////////////////////////////////////
	// Create the Zoom Mover
	pMover= new GLC_SetTargetMover(pViewport);
	// Add the Zoom Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::Target);

	//////////////////////////////////////////////////////////////////////
	// Track Ball Mover
	//////////////////////////////////////////////////////////////////////
	// Copy the pan Mover representation
	pRepMover= pRepMover->clone();
	listOfRep.clear();
	listOfRep.append(pRepMover);
	// Create the track ball representation
	pRepMover= new GLC_RepTrackBallMover(pViewport);
	pRepMover->setMainColor(color);
	listOfRep.append(pRepMover);
	// Create the Track Ball Mover
	pMover= new GLC_TrackBallMover(pViewport, listOfRep);
	// Add the Track ball Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::TrackBall);

	//////////////////////////////////////////////////////////////////////
	// Turn Table Mover
	//////////////////////////////////////////////////////////////////////
	// Create the Turn Table Mover
	pMover= new GLC_TurnTableMover(pViewport);
	// Add the Turn Table Mover to the controller
	defaultController.addMover(pMover, GLC_MoverController::TurnTable);

	return defaultController;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/utils/SkCustomTypeface.h"
#include "tools/Resources.h"

static sk_sp<SkTypeface> make_tf() {
    SkCustomTypefaceBuilder builder;
    SkFont font;
    font.setSize(1.0f);
    font.setHinting(SkFontHinting::kNone);

    // Steal the first 128 chars from the default font
    for (SkGlyphID index = 0; index <= 127; ++index) {
        SkGlyphID glyph = font.unicharToGlyph(index);

        SkScalar width;
        font.getWidths(&glyph, 1, &width);
        SkPath path;
        font.getPath(glyph, &path);

        // we use the charcode to be our glyph index, since we have no cmap table
        builder.setGlyph(index, width, path);
    }

    return builder.detach();
}

#include "include/core/SkTextBlob.h"

class UserFontGM : public skiagm::GM {
    sk_sp<SkTypeface> fTF;
    sk_sp<SkTextBlob> fBlob;

    SkPath fPath;
public:
    UserFontGM() {}

    void onOnceBeforeDraw() override {
        fTF = make_tf();

        SkFont font(fTF);
        font.setSize(100);
        font.setEdging(SkFont::Edging::kAntiAlias);

        fBlob = SkTextBlob::MakeFromString("User Typeface", font);
    }

    bool runAsBench() const override { return true; }

    SkString onShortName() override { return SkString("user_typeface"); }

    SkISize onISize() override { return {512, 512}; }

    void onDraw(SkCanvas* canvas) override {
        SkScalar x = 20,
                 y = 250;

        SkPaint paint;
        paint.setStyle(SkPaint::kStroke_Style);
        canvas->drawRect(fBlob->bounds().makeOffset(x, y), paint);

        paint.setStyle(SkPaint::kFill_Style);
        paint.setColor(SK_ColorRED);
        canvas->drawTextBlob(fBlob, x, y, paint);
    }
};
DEF_GM(return new UserFontGM;)
<commit_msg>extend custom typeface gm<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/utils/SkCustomTypeface.h"
#include "tools/Resources.h"

static sk_sp<SkTypeface> make_tf() {
    SkCustomTypefaceBuilder builder;
    SkFont font;
    font.setSize(1.0f);
    font.setHinting(SkFontHinting::kNone);

    // Steal the first 128 chars from the default font
    for (SkGlyphID index = 0; index <= 127; ++index) {
        SkGlyphID glyph = font.unicharToGlyph(index);

        SkScalar width;
        font.getWidths(&glyph, 1, &width);
        SkPath path;
        font.getPath(glyph, &path);

        // we use the charcode to be our glyph index, since we have no cmap table
        builder.setGlyph(index, width, path);
    }

    return builder.detach();
}

#include "include/core/SkTextBlob.h"

class UserFontGM : public skiagm::GM {
    sk_sp<SkTypeface> fTF;

public:
    UserFontGM() {}

    void onOnceBeforeDraw() override {
        fTF = make_tf();
    }

    static sk_sp<SkTextBlob> make_blob(sk_sp<SkTypeface> tf, float size) {
        SkFont font(tf);
        font.setSize(size);
        font.setEdging(SkFont::Edging::kAntiAlias);
        return SkTextBlob::MakeFromString("Typeface", font);
    }

    bool runAsBench() const override { return true; }

    SkString onShortName() override { return SkString("user_typeface"); }

    SkISize onISize() override { return {810, 512}; }

    void onDraw(SkCanvas* canvas) override {
        auto waterfall = [&](sk_sp<SkTypeface> tf) {
            SkPaint paint;
            paint.setAntiAlias(true);

            float x = 20,
                  y = 16;
            for (float size = 9; size <= 100; size *= 1.25f) {
                auto blob = make_blob(tf, size);

                paint.setColor(0xFFCCCCCC);
                paint.setStyle(SkPaint::kStroke_Style);
                canvas->drawRect(blob->bounds().makeOffset(x, y), paint);

                paint.setStyle(SkPaint::kFill_Style);
                paint.setColor(SK_ColorBLACK);
                canvas->drawTextBlob(blob, x, y, paint);

                y += size * 1.5f;
            }
        };

        waterfall(nullptr);
        canvas->translate(400, 0);
        waterfall(fTF);
    }
};
DEF_GM(return new UserFontGM;)
<|endoftext|>


<commit_before>/**
 * @file llurldispatcher.cpp
 * @brief Central registry for all URL handlers
 *
 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */
#include "llviewerprecompiledheaders.h"

#include "llurldispatcher.h"

// viewer includes
#include "llagent.h"			// teleportViaLocation()
#include "llcommandhandler.h"
#include "llfloaterhelpbrowser.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterworldmap.h"
#include "llpanellogin.h"
#include "llregionhandle.h"
#include "llslurl.h"
#include "llstartup.h"			// gStartupState
#include "llweb.h"
#include "llworldmapmessage.h"
#include "llurldispatcherlistener.h"
#include "llviewernetwork.h"
#include "llviewercontrol.h"

// library includes
#include "llnotificationsutil.h"
#include "llsd.h"

static LLURLDispatcherListener sURLDispatcherListener;

class LLURLDispatcherImpl
{
public:
	static bool dispatch(const LLSLURL& slurl,
						 const std::string& nav_type,
						 LLMediaCtrl* web,
						 bool trusted_browser);
		// returns true if handled or explicitly blocked.

	static bool dispatchRightClick(const LLSLURL& slurl);

private:
	static bool dispatchCore(const LLSLURL& slurl,
							 const std::string& nav_type,
							 bool right_mouse,
							 LLMediaCtrl* web,
							 bool trusted_browser);
		// handles both left and right click

	static bool dispatchHelp(const LLSLURL& slurl, bool right_mouse);
		// Handles sl://app.floater.html.help by showing Help floater.
		// Returns true if handled.

	static bool dispatchApp(const LLSLURL& slurl,
							const std::string& nav_type,
							bool right_mouse,
							LLMediaCtrl* web,
							bool trusted_browser);
		// Handles secondlife:///app/agent/<agent_id>/about and similar
		// by showing panel in Search floater.
		// Returns true if handled or explicitly blocked.

	static bool dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse);
		// handles secondlife://Ahern/123/45/67/
		// Returns true if handled.

	static void regionHandleCallback(U64 handle, const LLSLURL& slurl,
		const LLUUID& snapshot_id, bool teleport);
		// Called by LLWorldMap when a location has been resolved to a
	    // region name

	static void regionNameCallback(U64 handle, const LLSLURL& slurl,
		const LLUUID& snapshot_id, bool teleport);
		// Called by LLWorldMap when a region name has been resolved to a
		// location in-world, used by places-panel display.

	friend class LLTeleportHandler;
};

// static
bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl,
									   const std::string& nav_type,
									   bool right_mouse,
									   LLMediaCtrl* web,
									   bool trusted_browser)
{
	//if (dispatchHelp(slurl, right_mouse)) return true;
	switch(slurl.getType())
	{
		case LLSLURL::APP:
			return dispatchApp(slurl, nav_type, right_mouse, web, trusted_browser);
		case LLSLURL::LOCATION:
			return dispatchRegion(slurl, nav_type, right_mouse);
		default:
			return false;
	}

	/*
	// Inform the user we can't handle this
	std::map<std::string, std::string> args;
	args["SLURL"] = slurl;
	r;
	*/
}

// static
bool LLURLDispatcherImpl::dispatch(const LLSLURL& slurl,
								   const std::string& nav_type,
								   LLMediaCtrl* web,
								   bool trusted_browser)
{
	const bool right_click = false;
	return dispatchCore(slurl, nav_type, right_click, web, trusted_browser);
}

// static
bool LLURLDispatcherImpl::dispatchRightClick(const LLSLURL& slurl)
{
	const bool right_click = true;
	LLMediaCtrl* web = NULL;
	const bool trusted_browser = false;
	return dispatchCore(slurl, "clicked", right_click, web, trusted_browser);
}

// static
bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl,
									  const std::string& nav_type,
									  bool right_mouse,
									  LLMediaCtrl* web,
									  bool trusted_browser)
{
	llinfos << "cmd: " << slurl.getAppCmd() << " path: " << slurl.getAppPath() << " query: " << slurl.getAppQuery() << llendl;
	const LLSD& query_map = LLURI::queryMap(slurl.getAppQuery());

// <FS:AW handle hop app teleports properly>
// 	bool handled = LLCommandDispatcher::dispatch(
// 			slurl.getAppCmd(), slurl.getAppPath(), query_map, web, nav_type, trusted_browser);
	LLSD path;
#ifdef OPENSIM // <FS:AW optional opensim support>
	if ("teleport" == slurl.getAppCmd())
	{
		path = LLSD::emptyArray();
		path.append(slurl.getGrid());
		for(int i=0; slurl.getAppPath().size() > i; i++)
		{
			path.append(slurl.getAppPath()[i].asString());
		}
	}
	else
#endif // OPENSIM // <FS:AW optional opensim support>
	{
		path = slurl.getAppPath();
	}

	bool handled = LLCommandDispatcher::dispatch(
			slurl.getAppCmd(), path, query_map, web, nav_type, trusted_browser);
// </FS:AW handle hop app teleports properly>

	// alert if we didn't handle this secondlife:///app/ SLURL
	// (but still return true because it is a valid app SLURL)
	if (! handled)
	{
		LLNotificationsUtil::add("UnsupportedCommandSLURL");
	}
	return true;
}

// static
bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse)
{
	if(slurl.getType() != LLSLURL::LOCATION)
    {
		return false;
    }
	// Before we're logged in, need to update the startup screen
	// to tell the user where they are going.
	if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
	{
		// We're at the login screen, so make sure user can see
		// the login location box to know where they are going.

		LLPanelLogin::setLocation(slurl);
		return true;
	}
// <FS:AW hypergrid support >
// 	LLWorldMapMessage::getInstance()->sendNamedRegionRequest(slurl.getRegion(),
//
// 									  LLURLDispatcherImpl::regionNameCallback,
// 									  slurl.getSLURLString(),
	LLSLURL hyper = slurl;
#ifdef OPENSIM // <FS:AW optional opensim support>
	std::string grid = slurl.getGrid();
	std::string current_grid = LLGridManager::getInstance()->getGrid();

	std::string gatekeeper = LLGridManager::getInstance()->getGatekeeper(grid);

	std::string current = LLGridManager::getInstance()->getGrid();
	if((grid != current ) && (!LLGridManager::getInstance()->isInOpenSim() || (!slurl.getHypergrid() && gatekeeper.empty())))
	{
		std::string dest = hyper.getSLURLString();
		if (!dest.empty())
		{
			LLSD args;
			args["SLURL"] = dest;
			args["GRID"] = slurl.getGrid();
			args["CURRENT_GRID"] = current_grid;
			LLNotificationsUtil::add("CantTeleportToGrid", args);
			return true;
		}
	}
	else if(!gatekeeper.empty())
	{
		hyper = LLSLURL(gatekeeper + ":" + slurl.getRegion(), slurl.getPosition(), true);
	}

#endif //OPENSIM
// </FS:AW optional opensim support>
	// Request a region handle by name
	LLWorldMapMessage::getInstance()->sendNamedRegionRequest(hyper.getRegion(), LLURLDispatcherImpl::regionNameCallback, hyper.getSLURLString(), LLUI::sSettingGroups["config"]->getBOOL("SLURLTeleportDirectly"));	// don't teleport
	return true;
}

/*static*/
void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
{

  if(slurl.getType() == LLSLURL::LOCATION)
    {
      regionHandleCallback(region_handle, slurl, snapshot_id, teleport);
    }
}

/* static */
void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
{
 // <FS:AW optional opensim support>
#ifndef OPENSIM
  // we can't teleport cross grid at this point
	if (LLGridManager::getInstance()->getGrid(slurl.getGrid()) != LLGridManager::getInstance()->getGrid())
	{
		LLSD args;
		args["SLURL"] = slurl.getLocationString();
		args["CURRENT_GRID"] = LLGridManager::getInstance()->getGridLabel();
		args["GRID"] = LLGridManager::getInstance()->getGridLabel(slurl.getGrid());
		LLNotificationsUtil::add("CantTeleportToGrid", args);
		return;
	}

#endif // OPENSIM
// </FS:AW optional opensim support>

	LLVector3d global_pos = from_region_handle(region_handle);
	global_pos += LLVector3d(slurl.getPosition());

	if (teleport)
	{
		gAgent.teleportViaLocation(global_pos);
		LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
		if(instance)
		{
			instance->trackLocation(global_pos);
		}
	}
	else
	{
		LLSD key;
		key["type"] = "remote_place";
		key["x"] = global_pos.mdV[VX];
		key["y"] = global_pos.mdV[VY];
		key["z"] = global_pos.mdV[VZ];

		// <FS:Ansariel> FIRE-817: Separate place details floater
		//LLFloaterSidePanelContainer::showPanel("places", key);
		if (gSavedSettings.getBOOL("FSUseStandalonePlaceDetailsFloater"))
		{
			LLFloaterReg::showInstance("fs_placedetails", key);
		}
		else
		{
			LLFloaterSidePanelContainer::showPanel("places", key);
		}
		// </FS:Ansariel>
	}
}

//---------------------------------------------------------------------------
// Teleportation links are handled here because they are tightly coupled
// to SLURL parsing and sim-fragment parsing
class LLTeleportHandler : public LLCommandHandler
{
public:
	// Teleport requests *must* come from a trusted browser
	// inside the app, otherwise a malicious web page could
	// cause a constant teleport loop.  JC
	LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_BLOCK) { }

	bool handle(const LLSD& tokens, const LLSD& query_map,
				LLMediaCtrl* web)
	{
		// construct a "normal" SLURL, resolve the region to
		// a global position, and teleport to it
		if (tokens.size() < 1) return false;
 // <FS:AW optional opensim support>
#ifdef OPENSIM
		LLSLURL slurl(tokens, true);

		std::string grid = slurl.getGrid();
		std::string gatekeeper = LLGridManager::getInstance()->getGatekeeper(grid);
		std::string region_name = slurl.getRegion();
		std::string dest;
		std::string current = LLGridManager::getInstance()->getGrid();
		if((grid != current) && (!LLGridManager::getInstance()->isInOpenSim() || (!slurl.getHypergrid() && gatekeeper.empty())))
		{
			dest = slurl.getSLURLString();
			if (!dest.empty())
			{
				LLSD args;
				args["SLURL"] = dest;
				args["GRID"] = grid;
				args["CURRENT_GRID"] = current;
				LLNotificationsUtil::add("CantTeleportToGrid", args);
				return true;
			}
		}
		else if(!gatekeeper.empty() && gatekeeper != LLGridManager::getInstance()->getGatekeeper())
		{
			region_name = gatekeeper + ":" + region_name;
		}

		dest = "hop://" + current + "/" + region_name;

		for(int i=2; tokens.size() > i; i++)
		{
			dest.append("/" + tokens[i].asString());
		}

		LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name,
			LLURLDispatcherImpl::regionHandleCallback,
			LLSLURL(dest).getSLURLString(),
			true);	// teleport
#else // OPENSIM
		LLVector3 coords(128, 128, 0);
		if (tokens.size() <= 4)
		{
			coords = LLVector3(tokens[1].asReal(),
							   tokens[2].asReal(),
							   tokens[3].asReal());
		}

		// Region names may be %20 escaped.

		std::string region_name = LLURI::unescape(tokens[0]);

		LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, LLURLDispatcherImpl::regionHandleCallback, LLSLURL(region_name, coords).getSLURLString(), true);// teleport
#endif // OPENSIM
// </FS:AW optional opensim support>

		return true;
	}
};
LLTeleportHandler gTeleportHandler;

//---------------------------------------------------------------------------

// static
bool LLURLDispatcher::dispatch(const std::string& slurl,
							   const std::string& nav_type,
							   LLMediaCtrl* web,
							   bool trusted_browser)
{
	return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), nav_type, web, trusted_browser);
}

// static
bool LLURLDispatcher::dispatchRightClick(const std::string& slurl)
{
	return LLURLDispatcherImpl::dispatchRightClick(LLSLURL(slurl));
}

// static
bool LLURLDispatcher::dispatchFromTextEditor(const std::string& slurl)
{
	// *NOTE: Text editors are considered sources of trusted URLs
	// in order to make avatar profile links in chat history work.
	// While a malicious resident could chat an app SLURL, the
	// receiving resident will see it and must affirmatively
	// click on it.
	// *TODO: Make this trust model more refined.  JC
	const bool trusted_browser = true;
	LLMediaCtrl* web = NULL;
	return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), "clicked", web, trusted_browser);
}

<commit_msg>Remove an unnecessary variable from llurldispatcher.cpp<commit_after>/**
 * @file llurldispatcher.cpp
 * @brief Central registry for all URL handlers
 *
 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */
#include "llviewerprecompiledheaders.h"

#include "llurldispatcher.h"

// viewer includes
#include "llagent.h"			// teleportViaLocation()
#include "llcommandhandler.h"
#include "llfloaterhelpbrowser.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterworldmap.h"
#include "llpanellogin.h"
#include "llregionhandle.h"
#include "llslurl.h"
#include "llstartup.h"			// gStartupState
#include "llweb.h"
#include "llworldmapmessage.h"
#include "llurldispatcherlistener.h"
#include "llviewernetwork.h"
#include "llviewercontrol.h"

// library includes
#include "llnotificationsutil.h"
#include "llsd.h"

static LLURLDispatcherListener sURLDispatcherListener;

class LLURLDispatcherImpl
{
public:
	static bool dispatch(const LLSLURL& slurl,
						 const std::string& nav_type,
						 LLMediaCtrl* web,
						 bool trusted_browser);
		// returns true if handled or explicitly blocked.

	static bool dispatchRightClick(const LLSLURL& slurl);

private:
	static bool dispatchCore(const LLSLURL& slurl,
							 const std::string& nav_type,
							 bool right_mouse,
							 LLMediaCtrl* web,
							 bool trusted_browser);
		// handles both left and right click

	static bool dispatchHelp(const LLSLURL& slurl, bool right_mouse);
		// Handles sl://app.floater.html.help by showing Help floater.
		// Returns true if handled.

	static bool dispatchApp(const LLSLURL& slurl,
							const std::string& nav_type,
							bool right_mouse,
							LLMediaCtrl* web,
							bool trusted_browser);
		// Handles secondlife:///app/agent/<agent_id>/about and similar
		// by showing panel in Search floater.
		// Returns true if handled or explicitly blocked.

	static bool dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse);
		// handles secondlife://Ahern/123/45/67/
		// Returns true if handled.

	static void regionHandleCallback(U64 handle, const LLSLURL& slurl,
		const LLUUID& snapshot_id, bool teleport);
		// Called by LLWorldMap when a location has been resolved to a
	    // region name

	static void regionNameCallback(U64 handle, const LLSLURL& slurl,
		const LLUUID& snapshot_id, bool teleport);
		// Called by LLWorldMap when a region name has been resolved to a
		// location in-world, used by places-panel display.

	friend class LLTeleportHandler;
};

// static
bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl,
									   const std::string& nav_type,
									   bool right_mouse,
									   LLMediaCtrl* web,
									   bool trusted_browser)
{
	//if (dispatchHelp(slurl, right_mouse)) return true;
	switch(slurl.getType())
	{
		case LLSLURL::APP:
			return dispatchApp(slurl, nav_type, right_mouse, web, trusted_browser);
		case LLSLURL::LOCATION:
			return dispatchRegion(slurl, nav_type, right_mouse);
		default:
			return false;
	}

	/*
	// Inform the user we can't handle this
	std::map<std::string, std::string> args;
	args["SLURL"] = slurl;
	r;
	*/
}

// static
bool LLURLDispatcherImpl::dispatch(const LLSLURL& slurl,
								   const std::string& nav_type,
								   LLMediaCtrl* web,
								   bool trusted_browser)
{
	const bool right_click = false;
	return dispatchCore(slurl, nav_type, right_click, web, trusted_browser);
}

// static
bool LLURLDispatcherImpl::dispatchRightClick(const LLSLURL& slurl)
{
	const bool right_click = true;
	LLMediaCtrl* web = NULL;
	const bool trusted_browser = false;
	return dispatchCore(slurl, "clicked", right_click, web, trusted_browser);
}

// static
bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl,
									  const std::string& nav_type,
									  bool right_mouse,
									  LLMediaCtrl* web,
									  bool trusted_browser)
{
	llinfos << "cmd: " << slurl.getAppCmd() << " path: " << slurl.getAppPath() << " query: " << slurl.getAppQuery() << llendl;
	const LLSD& query_map = LLURI::queryMap(slurl.getAppQuery());

// <FS:AW handle hop app teleports properly>
// 	bool handled = LLCommandDispatcher::dispatch(
// 			slurl.getAppCmd(), slurl.getAppPath(), query_map, web, nav_type, trusted_browser);
	LLSD path;
#ifdef OPENSIM // <FS:AW optional opensim support>
	if ("teleport" == slurl.getAppCmd())
	{
		path = LLSD::emptyArray();
		path.append(slurl.getGrid());
		for(int i=0; slurl.getAppPath().size() > i; i++)
		{
			path.append(slurl.getAppPath()[i].asString());
		}
	}
	else
#endif // OPENSIM // <FS:AW optional opensim support>
	{
		path = slurl.getAppPath();
	}

	bool handled = LLCommandDispatcher::dispatch(
			slurl.getAppCmd(), path, query_map, web, nav_type, trusted_browser);
// </FS:AW handle hop app teleports properly>

	// alert if we didn't handle this secondlife:///app/ SLURL
	// (but still return true because it is a valid app SLURL)
	if (! handled)
	{
		LLNotificationsUtil::add("UnsupportedCommandSLURL");
	}
	return true;
}

// static
bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse)
{
	if(slurl.getType() != LLSLURL::LOCATION)
    {
		return false;
    }
	// Before we're logged in, need to update the startup screen
	// to tell the user where they are going.
	if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
	{
		// We're at the login screen, so make sure user can see
		// the login location box to know where they are going.

		LLPanelLogin::setLocation(slurl);
		return true;
	}
// <FS:AW hypergrid support >
// 	LLWorldMapMessage::getInstance()->sendNamedRegionRequest(slurl.getRegion(),
//
// 									  LLURLDispatcherImpl::regionNameCallback,
// 									  slurl.getSLURLString(),
	LLSLURL hyper = slurl;
#ifdef OPENSIM // <FS:AW optional opensim support>
	std::string grid = slurl.getGrid();
	std::string current_grid = LLGridManager::getInstance()->getGrid();
	std::string gatekeeper = LLGridManager::getInstance()->getGatekeeper(grid);

	if ((grid != current_grid)
		&& (!LLGridManager::getInstance()->isInOpenSim() || (!slurl.getHypergrid() && gatekeeper.empty())))
	{
		std::string dest = hyper.getSLURLString();
		if (!dest.empty())
		{
			LLSD args;
			args["SLURL"] = dest;
			args["GRID"] = grid;
			args["CURRENT_GRID"] = current_grid;
			LLNotificationsUtil::add("CantTeleportToGrid", args);
			return true;
		}
	}
	else if(!gatekeeper.empty())
	{
		hyper = LLSLURL(gatekeeper + ":" + slurl.getRegion(), slurl.getPosition(), true);
	}

#endif //OPENSIM
// </FS:AW optional opensim support>
	// Request a region handle by name
	LLWorldMapMessage::getInstance()->sendNamedRegionRequest(hyper.getRegion(), LLURLDispatcherImpl::regionNameCallback, hyper.getSLURLString(), LLUI::sSettingGroups["config"]->getBOOL("SLURLTeleportDirectly"));	// don't teleport
	return true;
}

/*static*/
void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
{

  if(slurl.getType() == LLSLURL::LOCATION)
    {
      regionHandleCallback(region_handle, slurl, snapshot_id, teleport);
    }
}

/* static */
void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
{
 // <FS:AW optional opensim support>
#ifndef OPENSIM
  // we can't teleport cross grid at this point
	if (LLGridManager::getInstance()->getGrid(slurl.getGrid()) != LLGridManager::getInstance()->getGrid())
	{
		LLSD args;
		args["SLURL"] = slurl.getLocationString();
		args["CURRENT_GRID"] = LLGridManager::getInstance()->getGridLabel();
		args["GRID"] = LLGridManager::getInstance()->getGridLabel(slurl.getGrid());
		LLNotificationsUtil::add("CantTeleportToGrid", args);
		return;
	}

#endif // OPENSIM
// </FS:AW optional opensim support>

	LLVector3d global_pos = from_region_handle(region_handle);
	global_pos += LLVector3d(slurl.getPosition());

	if (teleport)
	{
		gAgent.teleportViaLocation(global_pos);
		LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
		if(instance)
		{
			instance->trackLocation(global_pos);
		}
	}
	else
	{
		LLSD key;
		key["type"] = "remote_place";
		key["x"] = global_pos.mdV[VX];
		key["y"] = global_pos.mdV[VY];
		key["z"] = global_pos.mdV[VZ];

		// <FS:Ansariel> FIRE-817: Separate place details floater
		//LLFloaterSidePanelContainer::showPanel("places", key);
		if (gSavedSettings.getBOOL("FSUseStandalonePlaceDetailsFloater"))
		{
			LLFloaterReg::showInstance("fs_placedetails", key);
		}
		else
		{
			LLFloaterSidePanelContainer::showPanel("places", key);
		}
		// </FS:Ansariel>
	}
}

//---------------------------------------------------------------------------
// Teleportation links are handled here because they are tightly coupled
// to SLURL parsing and sim-fragment parsing
class LLTeleportHandler : public LLCommandHandler
{
public:
	// Teleport requests *must* come from a trusted browser
	// inside the app, otherwise a malicious web page could
	// cause a constant teleport loop.  JC
	LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_BLOCK) { }

	bool handle(const LLSD& tokens, const LLSD& query_map,
				LLMediaCtrl* web)
	{
		// construct a "normal" SLURL, resolve the region to
		// a global position, and teleport to it
		if (tokens.size() < 1) return false;
 // <FS:AW optional opensim support>
#ifdef OPENSIM
		LLSLURL slurl(tokens, true);

		std::string grid = slurl.getGrid();
		std::string gatekeeper = LLGridManager::getInstance()->getGatekeeper(grid);
		std::string region_name = slurl.getRegion();
		std::string dest;
		std::string current = LLGridManager::getInstance()->getGrid();
		if((grid != current) && (!LLGridManager::getInstance()->isInOpenSim() || (!slurl.getHypergrid() && gatekeeper.empty())))
		{
			dest = slurl.getSLURLString();
			if (!dest.empty())
			{
				LLSD args;
				args["SLURL"] = dest;
				args["GRID"] = grid;
				args["CURRENT_GRID"] = current;
				LLNotificationsUtil::add("CantTeleportToGrid", args);
				return true;
			}
		}
		else if(!gatekeeper.empty() && gatekeeper != LLGridManager::getInstance()->getGatekeeper())
		{
			region_name = gatekeeper + ":" + region_name;
		}

		dest = "hop://" + current + "/" + region_name;

		for(int i=2; tokens.size() > i; i++)
		{
			dest.append("/" + tokens[i].asString());
		}

		LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name,
			LLURLDispatcherImpl::regionHandleCallback,
			LLSLURL(dest).getSLURLString(),
			true);	// teleport
#else // OPENSIM
		LLVector3 coords(128, 128, 0);
		if (tokens.size() <= 4)
		{
			coords = LLVector3(tokens[1].asReal(),
							   tokens[2].asReal(),
							   tokens[3].asReal());
		}

		// Region names may be %20 escaped.

		std::string region_name = LLURI::unescape(tokens[0]);

		LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, LLURLDispatcherImpl::regionHandleCallback, LLSLURL(region_name, coords).getSLURLString(), true);// teleport
#endif // OPENSIM
// </FS:AW optional opensim support>

		return true;
	}
};
LLTeleportHandler gTeleportHandler;

//---------------------------------------------------------------------------

// static
bool LLURLDispatcher::dispatch(const std::string& slurl,
							   const std::string& nav_type,
							   LLMediaCtrl* web,
							   bool trusted_browser)
{
	return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), nav_type, web, trusted_browser);
}

// static
bool LLURLDispatcher::dispatchRightClick(const std::string& slurl)
{
	return LLURLDispatcherImpl::dispatchRightClick(LLSLURL(slurl));
}

// static
bool LLURLDispatcher::dispatchFromTextEditor(const std::string& slurl)
{
	// *NOTE: Text editors are considered sources of trusted URLs
	// in order to make avatar profile links in chat history work.
	// While a malicious resident could chat an app SLURL, the
	// receiving resident will see it and must affirmatively
	// click on it.
	// *TODO: Make this trust model more refined.  JC
	const bool trusted_browser = true;
	LLMediaCtrl* web = NULL;
	return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), "clicked", web, trusted_browser);
}

<|endoftext|>